mirror of
https://github.com/GTNewHorizons/bdlib.git
synced 2026-10-26 14:23:54 +00:00
[ci skip] spotlessApply with the new settings
This commit is contained in:
1 parent
d60edbb369
commit
071ca10757
171 files changed
+3310
-1438
No files matched your search
@@ -21,8 +21,10 @@ object ApiReporter extends ICrashCallable {
|
||||
val mods = new util.ArrayList[ModContainer]
|
||||
val nameLookup = new util.HashMap[String, ModContainer]
|
||||
ModAPIManager.INSTANCE.injectAPIModContainers(mods, nameLookup)
|
||||
(for (mod <- mods.sortBy(_.getModId.toLowerCase(Locale.US))) yield
|
||||
"\t\t* %s (%s) from %s".format(mod.getModId, mod.getVersion,
|
||||
(for (mod <- mods.sortBy(_.getModId.toLowerCase(Locale.US)))
|
||||
yield "\t\t* %s (%s) from %s".format(
|
||||
mod.getModId,
|
||||
mod.getVersion,
|
||||
if (mod.getSource.isDirectory)
|
||||
mod.getSource
|
||||
else
|
||||
|
||||
@@ -10,18 +10,35 @@
|
||||
package net.bdew.lib
|
||||
|
||||
import cpw.mods.fml.common.Mod.EventHandler
|
||||
import cpw.mods.fml.common.event.{FMLPreInitializationEvent, FMLServerStartingEvent, FMLServerStoppingEvent}
|
||||
import cpw.mods.fml.common.event.{
|
||||
FMLPreInitializationEvent,
|
||||
FMLServerStartingEvent,
|
||||
FMLServerStoppingEvent
|
||||
}
|
||||
import cpw.mods.fml.common.{FMLCommonHandler, Mod}
|
||||
import net.bdew.lib.multiblock.data.MsgOutputCfgRSMode
|
||||
import net.bdew.lib.multiblock.network.{MsgOutputCfg, MsgOutputCfgSlot, NetHandler}
|
||||
import net.bdew.lib.network.{BaseMessage, NetworkSecurityLoader, SerializedMessageCodec}
|
||||
import net.bdew.lib.multiblock.network.{
|
||||
MsgOutputCfg,
|
||||
MsgOutputCfgSlot,
|
||||
NetHandler
|
||||
}
|
||||
import net.bdew.lib.network.{
|
||||
BaseMessage,
|
||||
NetworkSecurityLoader,
|
||||
SerializedMessageCodec
|
||||
}
|
||||
import net.bdew.lib.tooltip.TooltipHandler
|
||||
import net.minecraft.command.CommandHandler
|
||||
import org.apache.logging.log4j.Logger
|
||||
|
||||
import java.io.File
|
||||
|
||||
@Mod(modid = "bdlib", name = "BD lib", version = "GRADLETOKEN_VERSION", modLanguage = "scala")
|
||||
@Mod(
|
||||
modid = "bdlib",
|
||||
name = "BD lib",
|
||||
version = "GRADLETOKEN_VERSION",
|
||||
modLanguage = "scala"
|
||||
)
|
||||
object BdLib {
|
||||
var log: Logger = null
|
||||
var configDir: File = null
|
||||
@@ -30,8 +47,10 @@ object BdLib {
|
||||
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: _*))
|
||||
def logWarnException(msg: String, t: Throwable, args: Any*) = log.warn(msg.format(args: _*), t)
|
||||
def logErrorException(msg: String, t: Throwable, args: Any*) = log.error(msg.format(args: _*), t)
|
||||
def logWarnException(msg: String, t: Throwable, args: Any*) =
|
||||
log.warn(msg.format(args: _*), t)
|
||||
def logErrorException(msg: String, t: Throwable, args: Any*) =
|
||||
log.error(msg.format(args: _*), t)
|
||||
|
||||
val onServerStarting = Event[FMLServerStartingEvent]
|
||||
val onServerStopping = Event[FMLServerStoppingEvent]
|
||||
@@ -56,7 +75,8 @@ object BdLib {
|
||||
|
||||
@EventHandler
|
||||
def serverStarting(event: FMLServerStartingEvent) {
|
||||
val commandHandler = event.getServer.getCommandManager.asInstanceOf[CommandHandler]
|
||||
val commandHandler =
|
||||
event.getServer.getCommandManager.asInstanceOf[CommandHandler]
|
||||
commandHandler.registerCommand(CommandDumpRegistry)
|
||||
commandHandler.registerCommand(CommandOreDistribution)
|
||||
onServerStarting.trigger(event)
|
||||
|
||||
@@ -13,9 +13,8 @@ import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.texture.TextureMap
|
||||
import org.lwjgl.input.Keyboard
|
||||
|
||||
/**
|
||||
* Misc functions and shortcuts for client-side code
|
||||
*/
|
||||
/** Misc functions and shortcuts for client-side code
|
||||
*/
|
||||
object Client {
|
||||
def minecraft = Minecraft.getMinecraft
|
||||
def fontRenderer = Minecraft.getMinecraft.fontRenderer
|
||||
@@ -24,8 +23,14 @@ object Client {
|
||||
def player = Minecraft.getMinecraft.thePlayer
|
||||
def textureManager = Minecraft.getMinecraft.getTextureManager
|
||||
|
||||
def blockMissingIcon = textureManager.getTexture(TextureMap.locationBlocksTexture).asInstanceOf[TextureMap].getAtlasSprite("missingno")
|
||||
def itemMissingIcon = textureManager.getTexture(TextureMap.locationItemsTexture).asInstanceOf[TextureMap].getAtlasSprite("missingno")
|
||||
def blockMissingIcon = textureManager
|
||||
.getTexture(TextureMap.locationBlocksTexture)
|
||||
.asInstanceOf[TextureMap]
|
||||
.getAtlasSprite("missingno")
|
||||
def itemMissingIcon = textureManager
|
||||
.getTexture(TextureMap.locationItemsTexture)
|
||||
.asInstanceOf[TextureMap]
|
||||
.getAtlasSprite("missingno")
|
||||
|
||||
def shiftDown: Boolean = {
|
||||
return Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54)
|
||||
|
||||
@@ -25,24 +25,47 @@ object CommandDumpRegistry extends CommandBase {
|
||||
def getCommandUsage(c: ICommandSender) = "dumpregistry"
|
||||
|
||||
def processCommand(sender: ICommandSender, params: Array[String]) {
|
||||
val mcHome = FMLInjectionData.data()(6).asInstanceOf[File] //is there a better way to get this?
|
||||
val mcHome =
|
||||
FMLInjectionData
|
||||
.data()(6)
|
||||
.asInstanceOf[File] // is there a better way to get this?
|
||||
val dumpFile = new File(mcHome, "registry.dump")
|
||||
val dumpWriter = new BufferedWriter(new FileWriter(dumpFile))
|
||||
import scala.collection.JavaConversions._
|
||||
try {
|
||||
dumpWriter.write("==== BLOCKS ====\n")
|
||||
dumpWriter.write(GameData.getBlockRegistry.map(GameData.getBlockRegistry.getNameForObject).toList.sorted.mkString("\n"))
|
||||
dumpWriter.write(
|
||||
GameData.getBlockRegistry
|
||||
.map(GameData.getBlockRegistry.getNameForObject)
|
||||
.toList
|
||||
.sorted
|
||||
.mkString("\n")
|
||||
)
|
||||
dumpWriter.write("\n\n")
|
||||
|
||||
dumpWriter.write("==== ITEMS ====\n")
|
||||
dumpWriter.write(GameData.getItemRegistry.map(GameData.getItemRegistry.getNameForObject).toList.sorted.mkString("\n"))
|
||||
dumpWriter.write(
|
||||
GameData.getItemRegistry
|
||||
.map(GameData.getItemRegistry.getNameForObject)
|
||||
.toList
|
||||
.sorted
|
||||
.mkString("\n")
|
||||
)
|
||||
dumpWriter.write("\n\n")
|
||||
|
||||
dumpWriter.write("==== CUSTOM STACKS ====\n")
|
||||
val stacksField = classOf[GameData].getDeclaredField("customItemStacks")
|
||||
stacksField.setAccessible(true)
|
||||
val stacksData = stacksField.get(null).asInstanceOf[Table[String, String, ItemStack]]
|
||||
dumpWriter.write(stacksData.cellSet().map(x => x.getRowKey + ":" + x.getColumnKey).toList.sorted.mkString("\n"))
|
||||
val stacksData =
|
||||
stacksField.get(null).asInstanceOf[Table[String, String, ItemStack]]
|
||||
dumpWriter.write(
|
||||
stacksData
|
||||
.cellSet()
|
||||
.map(x => x.getRowKey + ":" + x.getColumnKey)
|
||||
.toList
|
||||
.sorted
|
||||
.mkString("\n")
|
||||
)
|
||||
dumpWriter.write("\n\n")
|
||||
|
||||
dumpWriter.write("==== ORE DICT ====\n")
|
||||
@@ -55,16 +78,26 @@ object CommandDumpRegistry extends CommandBase {
|
||||
dumpWriter.write("\n\n")
|
||||
|
||||
dumpWriter.write("==== FLUIDS ====\n")
|
||||
dumpWriter.write(FluidRegistry.getRegisteredFluids.map(_._1).toList.sorted.mkString("\n"))
|
||||
dumpWriter.write(
|
||||
FluidRegistry.getRegisteredFluids.map(_._1).toList.sorted.mkString("\n")
|
||||
)
|
||||
dumpWriter.write("\n\n")
|
||||
|
||||
CommandBase.func_152373_a(sender, this, "Registry dumped to " + dumpFile.getCanonicalPath)
|
||||
CommandBase.func_152373_a(
|
||||
sender,
|
||||
this,
|
||||
"Registry dumped to " + dumpFile.getCanonicalPath
|
||||
)
|
||||
} catch {
|
||||
case e: Throwable =>
|
||||
CommandBase.func_152373_a(sender, this, "Failed to save registry dump: " + e)
|
||||
CommandBase.func_152373_a(
|
||||
sender,
|
||||
this,
|
||||
"Failed to save registry dump: " + e
|
||||
)
|
||||
BdLib.logErrorException("Failed to save registry dump", e)
|
||||
} finally {
|
||||
dumpWriter.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,10 +30,12 @@ object CommandOreDistribution extends CommandBase {
|
||||
try {
|
||||
s.toInt
|
||||
} catch {
|
||||
case e: NumberFormatException => throw new WrongUsageException("bdlib.oredistribution.usage")
|
||||
case e: NumberFormatException =>
|
||||
throw new WrongUsageException("bdlib.oredistribution.usage")
|
||||
}
|
||||
|
||||
def wrapColor(s: String, c: EnumChatFormatting) = c + s + EnumChatFormatting.RESET
|
||||
def wrapColor(s: String, c: EnumChatFormatting) =
|
||||
c + s + EnumChatFormatting.RESET
|
||||
|
||||
def processCommand(sender: ICommandSender, baseParams: Array[String]) {
|
||||
val (flags, params) = baseParams.partition(_.startsWith("--"))
|
||||
@@ -44,12 +46,13 @@ object CommandOreDistribution extends CommandBase {
|
||||
val (startX, startZ, world) =
|
||||
sender match {
|
||||
case p: EntityPlayerMP => (p.posX.toInt, p.posZ.toInt, p.worldObj)
|
||||
case _ => (0, 0, sender.getEntityWorld)
|
||||
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
|
||||
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))
|
||||
@@ -57,25 +60,41 @@ object CommandOreDistribution extends CommandBase {
|
||||
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.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 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
|
||||
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)
|
||||
val kinds =
|
||||
mutable.Map.empty[String, Set[(Item, Int)]].withDefaultValue(Set.empty)
|
||||
|
||||
for {
|
||||
x <- startX - radius to startX + radius
|
||||
@@ -83,7 +102,10 @@ object CommandOreDistribution extends CommandBase {
|
||||
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))
|
||||
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
|
||||
@@ -95,21 +117,39 @@ object CommandOreDistribution extends CommandBase {
|
||||
|
||||
if (toFile) {
|
||||
// === OUTPUT TO FILE ===
|
||||
val mcHome = FMLInjectionData.data()(6).asInstanceOf[File] //is there a better way to get this?
|
||||
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.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.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.write(
|
||||
" - %s@%s".format(
|
||||
GameData.getItemRegistry.getNameForObject(item),
|
||||
dmg
|
||||
)
|
||||
)
|
||||
dumpWriter.newLine()
|
||||
}
|
||||
dumpWriter.newLine()
|
||||
@@ -119,13 +159,29 @@ object CommandOreDistribution extends CommandBase {
|
||||
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.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)
|
||||
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)
|
||||
CommandBase.func_152373_a(
|
||||
sender,
|
||||
this,
|
||||
"bdlib.oredistribution.error",
|
||||
e.toString
|
||||
)
|
||||
BdLib.logErrorException("Failed to save ore distribution dump", e)
|
||||
} finally {
|
||||
dumpWriter.close()
|
||||
@@ -133,16 +189,32 @@ object CommandOreDistribution extends CommandBase {
|
||||
} 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))
|
||||
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)
|
||||
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))
|
||||
CommandBase.func_152373_a(
|
||||
sender,
|
||||
this,
|
||||
"bdlib.oredistribution.entry",
|
||||
" *",
|
||||
wrapColor(id, EnumChatFormatting.YELLOW),
|
||||
DecFormat.round(num),
|
||||
DecFormat.short(100f * num / total)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,13 @@ object DecFormat {
|
||||
def dec2(x: Float) = dec2Fmt.format(x).replace('\u00A0', ' ')
|
||||
def dec2(x: Int) = dec2Fmt.format(x).replace('\u00A0', ' ')
|
||||
|
||||
def short(x: Double) = (if (x > 10) thousandsFmt.format(x) else if (x > 1) dec1Fmt.format(x) else dec2Fmt.format(x)).replace('\u00A0', ' ')
|
||||
def short(x: Float) = (if (x > 10) thousandsFmt.format(x) else if (x > 1) dec1Fmt.format(x) else dec2Fmt.format(x)).replace('\u00A0', ' ')
|
||||
def short(x: Int) = (if (x > 10) thousandsFmt.format(x) else if (x > 1) dec1Fmt.format(x) else dec2Fmt.format(x)).replace('\u00A0', ' ')
|
||||
def short(x: Double) = (if (x > 10) thousandsFmt.format(x)
|
||||
else if (x > 1) dec1Fmt.format(x)
|
||||
else dec2Fmt.format(x)).replace('\u00A0', ' ')
|
||||
def short(x: Float) = (if (x > 10) thousandsFmt.format(x)
|
||||
else if (x > 1) dec1Fmt.format(x)
|
||||
else dec2Fmt.format(x)).replace('\u00A0', ' ')
|
||||
def short(x: Int) = (if (x > 10) thousandsFmt.format(x)
|
||||
else if (x > 1) dec1Fmt.format(x)
|
||||
else dec2Fmt.format(x)).replace('\u00A0', ' ')
|
||||
}
|
||||
@@ -31,4 +31,4 @@ object Event {
|
||||
def apply() = new Event0
|
||||
def apply[T] = new Event1[T]
|
||||
def apply[T, R] = new Event2[T, R]
|
||||
}
|
||||
}
|
||||
@@ -25,15 +25,18 @@ import net.minecraftforge.fluids.{Fluid, FluidStack}
|
||||
import net.minecraftforge.oredict.ShapedOreRecipe
|
||||
|
||||
object Misc {
|
||||
def getActiveModId = Option(Loader.instance().activeModContainer().getModId) getOrElse "<UNKNOWN>"
|
||||
def getActiveModId = Option(
|
||||
Loader.instance().activeModContainer().getModId
|
||||
) getOrElse "<UNKNOWN>"
|
||||
|
||||
def toLocal(s: String) = StatCollector.translateToLocal(s)
|
||||
def toLocalF(s: String, params: Any*) = StatCollector.translateToLocal(s).format(params: _*)
|
||||
def toLocalF(s: String, params: Any*) =
|
||||
StatCollector.translateToLocal(s).format(params: _*)
|
||||
def hasLocal(s: String) = StatCollector.canTranslate(s)
|
||||
|
||||
def flattenRecipe(pattern: Seq[String], items: Map[Char, AnyRef]) =
|
||||
pattern ++ items.flatMap {
|
||||
case (k, v) => Seq(new Character(k), v)
|
||||
pattern ++ items.flatMap { case (k, v) =>
|
||||
Seq(new Character(k), v)
|
||||
}
|
||||
|
||||
def wrapTag(n: String, f: (NBTTagCompound) => Any)(t: NBTTagCompound) {
|
||||
@@ -42,23 +45,42 @@ object Misc {
|
||||
t.setTag(n, p)
|
||||
}
|
||||
|
||||
def addRecipe(result: ItemStack, pattern: Seq[String], items: Map[Char, AnyRef]) =
|
||||
def addRecipe(
|
||||
result: ItemStack,
|
||||
pattern: Seq[String],
|
||||
items: Map[Char, AnyRef]
|
||||
) =
|
||||
GameRegistry.addRecipe(result, flattenRecipe(pattern, items): _*)
|
||||
|
||||
def addRecipeOD(result: ItemStack, pattern: Seq[String], items: Map[Char, AnyRef]) =
|
||||
GameRegistry.addRecipe(new ShapedOreRecipe(result, flattenRecipe(pattern, items): _*))
|
||||
def addRecipeOD(
|
||||
result: ItemStack,
|
||||
pattern: Seq[String],
|
||||
items: Map[Char, AnyRef]
|
||||
) =
|
||||
GameRegistry.addRecipe(
|
||||
new ShapedOreRecipe(result, flattenRecipe(pattern, items): _*)
|
||||
)
|
||||
|
||||
def min[T: Ordering](values: T*) = values.min
|
||||
def max[T: Ordering](values: T*) = values.max
|
||||
|
||||
def clamp[T](value: T, min: T, max: T)(implicit o: Ordering[T]): T = if (o.gt(value, max)) max else if (o.lt(value, min)) min else value
|
||||
def clamp[T](value: T, min: T, max: T)(implicit o: Ordering[T]): T =
|
||||
if (o.gt(value, max)) max else if (o.lt(value, min)) min else value
|
||||
|
||||
def iterSome[T](list: Seq[T], indexes: Iterable[Int]): Iterable[T] = for (i <- indexes) yield list(i)
|
||||
def iterSomeEnum[T](list: Seq[T], indexes: Iterable[Int]): Iterable[(Int, T)] = for (i <- indexes) yield i -> list(i)
|
||||
def iterSome[T](list: Seq[T], indexes: Iterable[Int]): Iterable[T] = for (
|
||||
i <- indexes
|
||||
) yield list(i)
|
||||
def iterSomeEnum[T](
|
||||
list: Seq[T],
|
||||
indexes: Iterable[Int]
|
||||
): Iterable[(Int, T)] = for (i <- indexes) yield i -> list(i)
|
||||
|
||||
def filterType[T](from: Iterable[_], cls: Class[T]) = from.filter(cls.isInstance).asInstanceOf[Iterable[T]]
|
||||
def filterType[T](from: Iterable[_], cls: Class[T]) =
|
||||
from.filter(cls.isInstance).asInstanceOf[Iterable[T]]
|
||||
|
||||
def getBiomeByName(name: String) = BiomeGenBase.getBiomeGenArray.find(x => x != null && x.biomeName == name).orNull
|
||||
def getBiomeByName(name: String) = BiomeGenBase.getBiomeGenArray
|
||||
.find(x => x != null && x.biomeName == name)
|
||||
.orNull
|
||||
|
||||
private lazy val modLookup = {
|
||||
val mods = new util.ArrayList[ModContainer]
|
||||
@@ -73,7 +95,9 @@ object Misc {
|
||||
|
||||
def haveModVersion(modId: String) = {
|
||||
val spec = VersionParser.parseVersionReference(modId)
|
||||
modLookup.contains(spec.getLabel) && spec.containsVersion(modLookup(spec.getLabel).getProcessedVersion)
|
||||
modLookup.contains(spec.getLabel) && spec.containsVersion(
|
||||
modLookup(spec.getLabel).getProcessedVersion
|
||||
)
|
||||
}
|
||||
|
||||
def getModVersion(modId: String) =
|
||||
@@ -95,9 +119,18 @@ object Misc {
|
||||
def asInstanceOpt[T](cls: Class[T])(v: Any) =
|
||||
if (cls.isInstance(v)) Some(v.asInstanceOf[T]) else None
|
||||
|
||||
def getNeighbourTile[T](origin: TileEntity, dir: ForgeDirection, cls: Class[T]) =
|
||||
Option(origin.getWorldObj.getTileEntity(origin.xCoord + dir.offsetX,
|
||||
origin.yCoord + dir.offsetY, origin.zCoord + dir.offsetZ)) flatMap (asInstanceOpt(_, cls))
|
||||
def getNeighbourTile[T](
|
||||
origin: TileEntity,
|
||||
dir: ForgeDirection,
|
||||
cls: Class[T]
|
||||
) =
|
||||
Option(
|
||||
origin.getWorldObj.getTileEntity(
|
||||
origin.xCoord + dir.offsetX,
|
||||
origin.yCoord + dir.offsetY,
|
||||
origin.zCoord + dir.offsetZ
|
||||
)
|
||||
) flatMap (asInstanceOpt(_, cls))
|
||||
|
||||
@inline def applyMutator[T](f: (T) => Unit, init: T): T = {
|
||||
f(init)
|
||||
@@ -132,34 +165,36 @@ object Misc {
|
||||
Client.blockMissingIcon
|
||||
|
||||
def getFluidIcon(f: Fluid): IIcon =
|
||||
if (f != null) getFluidIcon(new FluidStack(f, 1)) else Client.blockMissingIcon
|
||||
if (f != null) getFluidIcon(new FluidStack(f, 1))
|
||||
else Client.blockMissingIcon
|
||||
|
||||
def getFluidColor(fs: FluidStack): Int =
|
||||
if (fs != null && fs.getFluid != null) fs.getFluid.getColor(fs) else 0xFFFFFF
|
||||
if (fs != null && fs.getFluid != null) fs.getFluid.getColor(fs)
|
||||
else 0xffffff
|
||||
|
||||
def getFluidColor(f: Fluid): Int =
|
||||
if (f != null) getFluidColor(new FluidStack(f, 1)) else 0xFFFFFF
|
||||
if (f != null) getFluidColor(new FluidStack(f, 1)) else 0xffffff
|
||||
|
||||
lazy val lineSeparator = System.getProperty("line.separator")
|
||||
|
||||
/**
|
||||
* Provides something like java try-with-resources in scala
|
||||
*/
|
||||
/** Provides something like java try-with-resources in scala
|
||||
*/
|
||||
def withAutoClose[T <: AutoCloseable, R](o: T)(f: T => R): R = {
|
||||
val res = try {
|
||||
f(o)
|
||||
} catch {
|
||||
case t1: Throwable =>
|
||||
if (o != null) {
|
||||
try {
|
||||
o.close()
|
||||
} catch {
|
||||
case t2: Throwable =>
|
||||
t1.addSuppressed(t2)
|
||||
val res =
|
||||
try {
|
||||
f(o)
|
||||
} catch {
|
||||
case t1: Throwable =>
|
||||
if (o != null) {
|
||||
try {
|
||||
o.close()
|
||||
} catch {
|
||||
case t2: Throwable =>
|
||||
t1.addSuppressed(t2)
|
||||
}
|
||||
}
|
||||
}
|
||||
throw t1
|
||||
}
|
||||
throw t1
|
||||
}
|
||||
if (o != null)
|
||||
o.close()
|
||||
res
|
||||
@@ -172,4 +207,3 @@ object Misc {
|
||||
"%s:%s/%s".format(domain, name, path.mkString("/")).toLowerCase(Locale.US)
|
||||
|
||||
}
|
||||
|
||||
@@ -18,5 +18,6 @@ case class BlockFace(x: Int, y: Int, z: Int, face: ForgeDirection) {
|
||||
}
|
||||
|
||||
object BlockFace {
|
||||
def apply(bp: BlockRef, face: ForgeDirection) = new BlockFace(bp.x, bp.y, bp.z, face)
|
||||
def apply(bp: BlockRef, face: ForgeDirection) =
|
||||
new BlockFace(bp.x, bp.y, bp.z, face)
|
||||
}
|
||||
@@ -18,16 +18,21 @@ import net.minecraftforge.common.util.ForgeDirection
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
case class BlockRef(x: Int, y: Int, z: Int) {
|
||||
def isValid(w: IBlockAccess) = y >= 0 && y < 256 // hardcoded because getHeight is unavailable on servers :(
|
||||
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 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)
|
||||
|
||||
def neighbour(side: ForgeDirection) = BlockRef(x + side.offsetX, y + side.offsetY, z + side.offsetZ)
|
||||
def neighbours = ForgeDirection.VALID_DIRECTIONS.map(x => x -> neighbour(x)).toMap
|
||||
def neighbour(side: ForgeDirection) =
|
||||
BlockRef(x + side.offsetX, y + side.offsetY, z + side.offsetZ)
|
||||
def neighbours =
|
||||
ForgeDirection.VALID_DIRECTIONS.map(x => x -> neighbour(x)).toMap
|
||||
|
||||
override def toString = "(x=%d y=%d z=%d)".format(x, y, z)
|
||||
|
||||
@@ -58,4 +63,4 @@ object BlockRef {
|
||||
def fromTile(te: TileEntity) = BlockRef(te.xCoord, te.yCoord, te.zCoord)
|
||||
def fromNBT(tag: NBTTagCompound) =
|
||||
BlockRef(tag.getInteger("x"), tag.getInteger("y"), tag.getInteger("z"))
|
||||
}
|
||||
}
|
||||
@@ -12,10 +12,9 @@ package net.bdew.lib.block
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.item.ItemBlock
|
||||
|
||||
/**
|
||||
* If defined on a block - defines a custom ItemBlock class that will be used when registering
|
||||
* Supported by BlockManager and Machine
|
||||
*/
|
||||
/** If defined on a block - defines a custom ItemBlock class that will be used
|
||||
* when registering Supported by BlockManager and Machine
|
||||
*/
|
||||
trait HasItemBlock extends Block {
|
||||
def ItemBlockClass: Class[_ <: ItemBlock]
|
||||
}
|
||||
@@ -17,14 +17,21 @@ import net.minecraft.world.{IBlockAccess, World}
|
||||
trait HasTE[T] extends Block with ITileEntityProvider {
|
||||
val TEClass: Class[_ <: TileEntity]
|
||||
|
||||
def createNewTileEntity(world: World, meta: Int): TileEntity = TEClass.newInstance()
|
||||
def createNewTileEntity(world: World, meta: Int): TileEntity =
|
||||
TEClass.newInstance()
|
||||
|
||||
def getTE(w: IBlockAccess, ref: BlockRef): T = getTE(w, ref.x, ref.y, ref.z)
|
||||
|
||||
def getTE(w: IBlockAccess, x: Int, y: Int, z: Int): T = {
|
||||
var t = w.getTileEntity(x, y, z)
|
||||
if ((t == null) || !TEClass.isInstance(t)) {
|
||||
BdLib.logError("Tile entity for block %s at (%d,%d,%d) is corrupt or missing - recreating", this, x, y, z)
|
||||
BdLib.logError(
|
||||
"Tile entity for block %s at (%d,%d,%d) is corrupt or missing - recreating",
|
||||
this,
|
||||
x,
|
||||
y,
|
||||
z
|
||||
)
|
||||
w match {
|
||||
case ww: World =>
|
||||
t = createNewTileEntity(ww, w.getBlockMetadata(x, y, z))
|
||||
|
||||
@@ -17,13 +17,26 @@ import net.minecraft.item.{ItemBlock, ItemStack}
|
||||
|
||||
trait BlockTooltip extends Block with HasItemBlock {
|
||||
override val ItemBlockClass: Class[_ <: ItemBlock] = classOf[ItemBlockTooltip]
|
||||
def getTooltip(stack: ItemStack, player: EntityPlayer, advanced: Boolean): List[String]
|
||||
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 = {
|
||||
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))
|
||||
list
|
||||
.asInstanceOf[util.List[String]]
|
||||
.addAll(
|
||||
b.asInstanceOf[BlockTooltip].getTooltip(stack, player, advanced)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -20,91 +20,162 @@ import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.MovingObjectPosition
|
||||
import net.minecraft.world.World
|
||||
|
||||
/**
|
||||
* Mixin for blocks to keep their data when broken
|
||||
* Must have a TileEntity that extends TileKeepData
|
||||
*/
|
||||
/** Mixin for blocks to keep their data when broken Must have a TileEntity that
|
||||
* extends TileKeepData
|
||||
*/
|
||||
trait BlockKeepData extends Block with HasItemBlock {
|
||||
this: HasTE[_ <: TileKeepData] =>
|
||||
|
||||
override val ItemBlockClass: Class[_ <: ItemBlockKeepData] = classOf[ItemBlockKeepData]
|
||||
override val ItemBlockClass: Class[_ <: ItemBlockKeepData] =
|
||||
classOf[ItemBlockKeepData]
|
||||
|
||||
def getSavedBlock(world: World, x: Int, y: Int, z: Int, metadata: Int) = {
|
||||
val stack = new ItemStack(getItemDropped(metadata, world.rand, 0), 1, damageDropped(metadata))
|
||||
val stack = new ItemStack(
|
||||
getItemDropped(metadata, world.rand, 0),
|
||||
1,
|
||||
damageDropped(metadata)
|
||||
)
|
||||
getTE(world, x, y, z).saveToItem(stack)
|
||||
stack
|
||||
}
|
||||
|
||||
override def getDrops(world: World, x: Int, y: Int, z: Int, metadata: Int, fortune: Int): util.ArrayList[ItemStack] = {
|
||||
override def getDrops(
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
metadata: Int,
|
||||
fortune: Int
|
||||
): util.ArrayList[ItemStack] = {
|
||||
val drops = new util.ArrayList[ItemStack]()
|
||||
drops.add(getSavedBlock(world, x, y, z, metadata))
|
||||
drops
|
||||
}
|
||||
|
||||
override def removedByPlayer(world: World, player: EntityPlayer, x: Int, y: Int, z: Int, willHarvest: Boolean): Boolean =
|
||||
override def removedByPlayer(
|
||||
world: World,
|
||||
player: EntityPlayer,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
willHarvest: Boolean
|
||||
): Boolean =
|
||||
if (willHarvest)
|
||||
true
|
||||
else
|
||||
super.removedByPlayer(world, player, x, y, z, willHarvest)
|
||||
|
||||
override def harvestBlock(world: World, player: EntityPlayer, x: Int, y: Int, z: Int, meta: Int): Unit = {
|
||||
override def harvestBlock(
|
||||
world: World,
|
||||
player: EntityPlayer,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
meta: Int
|
||||
): Unit = {
|
||||
super.harvestBlock(world, player, x, y, z, meta)
|
||||
world.setBlockToAir(x, y, z)
|
||||
}
|
||||
|
||||
override def getPickBlock(target: MovingObjectPosition, world: World, x: Int, y: Int, z: Int, player: EntityPlayer): ItemStack = {
|
||||
override def getPickBlock(
|
||||
target: MovingObjectPosition,
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
player: EntityPlayer
|
||||
): ItemStack = {
|
||||
getSavedBlock(world, x, y, z, world.getBlockMetadata(x, y, z))
|
||||
}
|
||||
|
||||
/**
|
||||
* Override for special actions on placing
|
||||
* ItemStack might or might not contain actual data
|
||||
* Called with the TE created and added to world, after onBlockPlacedBy & co
|
||||
*/
|
||||
def restoreTileEntity(world: World, x: Int, y: Int, z: Int, is: ItemStack, player: EntityPlayer) = getTE(world, x, y, z).loadFromItem(is)
|
||||
/** Override for special actions on placing ItemStack might or might not
|
||||
* contain actual data Called with the TE created and added to world, after
|
||||
* onBlockPlacedBy & co
|
||||
*/
|
||||
def restoreTileEntity(
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
is: ItemStack,
|
||||
player: EntityPlayer
|
||||
) = getTE(world, x, y, z).loadFromItem(is)
|
||||
}
|
||||
|
||||
/**
|
||||
* Mixin for tile entities to keep their data when broken
|
||||
* Block class has to extend BlockKeepData
|
||||
*/
|
||||
/** Mixin for tile entities to keep their data when broken Block class has to
|
||||
* extend BlockKeepData
|
||||
*/
|
||||
trait TileKeepData extends TileExtended {
|
||||
/**
|
||||
* Override to modify data that will be stored in an item
|
||||
* @param t Automatically serialized data
|
||||
* @return Modified serialized data
|
||||
*/
|
||||
|
||||
/** Override to modify data that will be stored in an item
|
||||
* @param t
|
||||
* Automatically serialized data
|
||||
* @return
|
||||
* Modified serialized data
|
||||
*/
|
||||
def afterTileBreakSave(t: NBTTagCompound) = t
|
||||
|
||||
/**
|
||||
* Override to modify data that will be load from an item
|
||||
* After the tile entity is fully constructed and added to world
|
||||
* @param t Automatically serialized data
|
||||
* @return Modified serialized data
|
||||
*/
|
||||
/** Override to modify data that will be load from an item After the tile
|
||||
* entity is fully constructed and added to world
|
||||
* @param t
|
||||
* Automatically serialized data
|
||||
* @return
|
||||
* Modified serialized data
|
||||
*/
|
||||
def beforeTileBreakLoad(t: NBTTagCompound) = t
|
||||
|
||||
final def saveToItem(is: ItemStack): Unit = {
|
||||
if (!is.hasTagCompound) is.setTagCompound(new NBTTagCompound)
|
||||
is.getTagCompound.setTag("data", afterTileBreakSave(NBT.from(persistSave.trigger)))
|
||||
is.getTagCompound.setTag(
|
||||
"data",
|
||||
afterTileBreakSave(NBT.from(persistSave.trigger))
|
||||
)
|
||||
}
|
||||
|
||||
final def loadFromItem(is: ItemStack): Unit = {
|
||||
if (is.hasTagCompound && is.getTagCompound.hasKey("data")) {
|
||||
persistLoad.trigger(beforeTileBreakLoad(is.getTagCompound.getCompoundTag("data")))
|
||||
persistLoad.trigger(
|
||||
beforeTileBreakLoad(is.getTagCompound.getCompoundTag("data"))
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom ItemBlock that handles loading data to the Tile Entity
|
||||
*/
|
||||
/** Custom ItemBlock that handles loading data to the Tile Entity
|
||||
*/
|
||||
class ItemBlockKeepData(b: Block) extends ItemBlockTooltip(b) {
|
||||
override def placeBlockAt(stack: ItemStack, player: EntityPlayer, world: World, x: Int, y: Int, z: Int, side: Int, hitX: Float, hitY: Float, hitZ: Float, metadata: Int): Boolean = {
|
||||
if (super.placeBlockAt(stack, player, world, x, y, z, side, hitX, hitY, hitZ, metadata)) {
|
||||
override def placeBlockAt(
|
||||
stack: ItemStack,
|
||||
player: EntityPlayer,
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
side: Int,
|
||||
hitX: Float,
|
||||
hitY: Float,
|
||||
hitZ: Float,
|
||||
metadata: Int
|
||||
): Boolean = {
|
||||
if (
|
||||
super.placeBlockAt(
|
||||
stack,
|
||||
player,
|
||||
world,
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
side,
|
||||
hitX,
|
||||
hitY,
|
||||
hitZ,
|
||||
metadata
|
||||
)
|
||||
) {
|
||||
if (!world.isRemote && b.isInstanceOf[BlockKeepData])
|
||||
b.asInstanceOf[BlockKeepData].restoreTileEntity(world, x, y, z, stack, player)
|
||||
b.asInstanceOf[BlockKeepData]
|
||||
.restoreTileEntity(world, x, y, z, stack, player)
|
||||
true
|
||||
} else false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,9 @@ trait NamedBlock extends Block {
|
||||
def name: String
|
||||
}
|
||||
|
||||
class SimpleBlock(val name: String, material: Material) extends Block(material) with NamedBlock {
|
||||
class SimpleBlock(val name: String, material: Material)
|
||||
extends Block(material)
|
||||
with NamedBlock {
|
||||
val modId = Misc.getActiveModId
|
||||
setBlockName(modId + "." + name)
|
||||
|
||||
|
||||
@@ -21,14 +21,24 @@ import net.minecraft.tileentity.TileEntity
|
||||
class BlockManager(creativeTab: CreativeTabs) {
|
||||
def regBlock[T <: NamedBlock](block: T): T = regBlock(block, block.name)
|
||||
|
||||
def regSpecial[T <: NamedBlock](block: T, addStack: Boolean = false, skipTileEntityReg: Boolean = false): T =
|
||||
def regSpecial[T <: NamedBlock](
|
||||
block: T,
|
||||
addStack: Boolean = false,
|
||||
skipTileEntityReg: Boolean = false
|
||||
): T =
|
||||
regBlock(block, block.name, addStack, skipTileEntityReg)
|
||||
|
||||
def regBlock[T <: Block](block: T, name: String, addStack: Boolean = false, skipTileEntityReg: Boolean = false): T = {
|
||||
val itemClass: Class[_ <: ItemBlock] = if (block.isInstanceOf[HasItemBlock])
|
||||
block.asInstanceOf[HasItemBlock].ItemBlockClass
|
||||
else
|
||||
classOf[ItemBlock]
|
||||
def regBlock[T <: Block](
|
||||
block: T,
|
||||
name: String,
|
||||
addStack: Boolean = false,
|
||||
skipTileEntityReg: Boolean = false
|
||||
): T = {
|
||||
val itemClass: Class[_ <: ItemBlock] =
|
||||
if (block.isInstanceOf[HasItemBlock])
|
||||
block.asInstanceOf[HasItemBlock].ItemBlockClass
|
||||
else
|
||||
classOf[ItemBlock]
|
||||
|
||||
GameRegistry.registerBlock(block, itemClass, name)
|
||||
|
||||
@@ -38,17 +48,28 @@ class BlockManager(creativeTab: CreativeTabs) {
|
||||
GameRegistry.registerCustomItemStack(name, new ItemStack(block))
|
||||
|
||||
if (block.isInstanceOf[HasTE[_]] && !skipTileEntityReg)
|
||||
GameRegistry.registerTileEntity(block.asInstanceOf[HasTE[_]].TEClass,
|
||||
"%s.%s".format(Misc.getActiveModId, name))
|
||||
GameRegistry.registerTileEntity(
|
||||
block.asInstanceOf[HasTE[_]].TEClass,
|
||||
"%s.%s".format(Misc.getActiveModId, name)
|
||||
)
|
||||
|
||||
return block
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a legacy TE name->class mapping. Stolen from GameRegistry.registerTileEntityWithAlternatives
|
||||
*/
|
||||
def registerLegacyTileEntity(name: String, cls: Class[_ <: TileEntity]): Unit = {
|
||||
val teMappings: java.util.Map[String, Class[_]] = ObfuscationReflectionHelper.getPrivateValue(classOf[TileEntity], null, "field_" + "145855_i", "nameToClassMap")
|
||||
/** 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)
|
||||
}
|
||||
|
||||
@@ -15,11 +15,16 @@ import net.minecraft.creativetab.CreativeTabs
|
||||
import net.minecraft.item.{Item, ItemStack}
|
||||
|
||||
class ItemManager(creativeTab: CreativeTabs) {
|
||||
def regSimpleItem(name: String): SimpleItem = regItem(new SimpleItem(name), name)
|
||||
def regSimpleItem(name: String): SimpleItem =
|
||||
regItem(new SimpleItem(name), name)
|
||||
|
||||
def regItem[T <: NamedItem](item: T): T = regItem[T](item, item.name)
|
||||
|
||||
def regItem[T <: Item](item: T, name: String, addStack: Boolean = false): T = {
|
||||
def regItem[T <: Item](
|
||||
item: T,
|
||||
name: String,
|
||||
addStack: Boolean = false
|
||||
): T = {
|
||||
GameRegistry.registerItem(item, name)
|
||||
item.setCreativeTab(creativeTab)
|
||||
if (addStack)
|
||||
|
||||
@@ -17,7 +17,11 @@ import net.bdew.lib.multiblock.block.BlockModule
|
||||
import net.bdew.lib.recipes.gencfg.ConfigSection
|
||||
import net.minecraft.creativetab.CreativeTabs
|
||||
|
||||
class MachineManager(val tuning: ConfigSection, guiHandler: GuiHandler, creativeTab: CreativeTabs) {
|
||||
class MachineManager(
|
||||
val tuning: ConfigSection,
|
||||
guiHandler: GuiHandler,
|
||||
creativeTab: CreativeTabs
|
||||
) {
|
||||
def registerMachine[R <: Machine[_]](machine: R): R = {
|
||||
machine.tuning = tuning.getSection(machine.name)
|
||||
if (machine.tuning.getBoolean("Enabled")) {
|
||||
@@ -38,9 +42,10 @@ trait MachineManagerMultiblock extends MachineManager {
|
||||
override def registerMachine[R <: Machine[_]](machine: R): R = {
|
||||
super.registerMachine(machine)
|
||||
if (machine.enabled) {
|
||||
Misc.asInstanceOpt(machine, classOf[MachineCore]) foreach { controllerMachine =>
|
||||
controllers += controllerMachine
|
||||
controllerMachine.getController.machine = controllerMachine
|
||||
Misc.asInstanceOpt(machine, classOf[MachineCore]) foreach {
|
||||
controllerMachine =>
|
||||
controllers += controllerMachine
|
||||
controllerMachine.getController.machine = controllerMachine
|
||||
}
|
||||
}
|
||||
machine
|
||||
@@ -48,7 +53,7 @@ trait MachineManagerMultiblock extends MachineManager {
|
||||
|
||||
def getMachinesForBlock(b: BlockModule[_]): Map[MachineCore, (Int, Int)] = {
|
||||
(for (machine <- controllers; max <- machine.modules.get(b.kind)) yield {
|
||||
machine ->(machine.required.getOrElse(b.kind, 0), max)
|
||||
machine -> (machine.required.getOrElse(b.kind, 0), max)
|
||||
}).toMap
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,13 @@ trait BlockCoverable[T <: TileCoverable] extends HasTE[T] {
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def getRenderType = CoverRenderer.id
|
||||
|
||||
private def getCoverItem(w: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection): Option[(ItemCover, ItemStack, TileCoverable)] = {
|
||||
private def getCoverItem(
|
||||
w: IBlockAccess,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
side: ForgeDirection
|
||||
): Option[(ItemCover, ItemStack, TileCoverable)] = {
|
||||
val te = getTE(w, x, y, z)
|
||||
for {
|
||||
coverStack <- Option(te.covers(side).value)
|
||||
@@ -33,7 +39,17 @@ trait BlockCoverable[T <: TileCoverable] extends HasTE[T] {
|
||||
} yield (coverItem, coverStack, te)
|
||||
}
|
||||
|
||||
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, face: Int, xOffs: Float, yOffs: Float, zOffs: Float): Boolean = {
|
||||
override def onBlockActivated(
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
player: EntityPlayer,
|
||||
face: Int,
|
||||
xOffs: Float,
|
||||
yOffs: Float,
|
||||
zOffs: Float
|
||||
): Boolean = {
|
||||
val te = getTE(world, x, y, z)
|
||||
val side = Misc.forgeDirection(face)
|
||||
|
||||
@@ -58,20 +74,37 @@ trait BlockCoverable[T <: TileCoverable] extends HasTE[T] {
|
||||
activeStack <- Option(player.getCurrentEquippedItem)
|
||||
activeItem <- Option(activeStack.getItem)
|
||||
coverItem <- Misc.asInstanceOpt(activeItem, classOf[ItemCover])
|
||||
if te.isValidCover(side, activeStack) && coverItem.isValidTile(te, activeStack)
|
||||
if te.isValidCover(side, activeStack) && coverItem.isValidTile(
|
||||
te,
|
||||
activeStack
|
||||
)
|
||||
} {
|
||||
if (!world.isRemote && player.isInstanceOf[EntityPlayerMP]) {
|
||||
for {
|
||||
oldCover <- Option(te.covers(side).value)
|
||||
oldItem <- Misc.asInstanceOpt(oldCover.getItem, classOf[ItemCover])
|
||||
} {
|
||||
ItemUtils.throwItemAt(world, te.xCoord + side.offsetX, te.yCoord + side.offsetY, te.zCoord + side.offsetZ, oldItem.onRemove(oldCover))
|
||||
ItemUtils.throwItemAt(
|
||||
world,
|
||||
te.xCoord + side.offsetX,
|
||||
te.yCoord + side.offsetY,
|
||||
te.zCoord + side.offsetZ,
|
||||
oldItem.onRemove(oldCover)
|
||||
)
|
||||
}
|
||||
|
||||
te.covers(side) := coverItem.onInstall(te, side, activeStack.splitStack(1), player.asInstanceOf[EntityPlayerMP])
|
||||
te.covers(side) := coverItem.onInstall(
|
||||
te,
|
||||
side,
|
||||
activeStack.splitStack(1),
|
||||
player.asInstanceOf[EntityPlayerMP]
|
||||
)
|
||||
|
||||
if (activeStack.stackSize <= 0)
|
||||
player.inventory.setInventorySlotContents(player.inventory.currentItem, null)
|
||||
player.inventory.setInventorySlotContents(
|
||||
player.inventory.currentItem,
|
||||
null
|
||||
)
|
||||
|
||||
te.onCoversChanged()
|
||||
coverChanged(world, x, y, z, side)
|
||||
@@ -89,7 +122,13 @@ trait BlockCoverable[T <: TileCoverable] extends HasTE[T] {
|
||||
|
||||
override def canProvidePower = true
|
||||
|
||||
override def isProvidingWeakPower(w: IBlockAccess, x: Int, y: Int, z: Int, side: Int): Int = {
|
||||
override def isProvidingWeakPower(
|
||||
w: IBlockAccess,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
side: Int
|
||||
): Int = {
|
||||
val direction = Misc.forgeDirection(side).getOpposite
|
||||
for ((item, stack, te) <- getCoverItem(w, x, y, z, direction)) {
|
||||
if (item.isEmittingSignal(te, direction, stack)) return 15
|
||||
@@ -97,16 +136,35 @@ trait BlockCoverable[T <: TileCoverable] extends HasTE[T] {
|
||||
0
|
||||
}
|
||||
|
||||
def coverChanged(w: World, x: Int, y: Int, z: Int, side: ForgeDirection): Unit = {
|
||||
def coverChanged(
|
||||
w: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
side: ForgeDirection
|
||||
): Unit = {
|
||||
val pos = BlockRef(x, y, z).neighbour(side)
|
||||
w.notifyBlockOfNeighborChange(pos.x, pos.y, pos.z, pos.block(w).orNull)
|
||||
}
|
||||
|
||||
def getCoverIcon(w: IBlockAccess, x: Int, y: Int, z: Int, side: ForgeDirection): Option[IIcon] =
|
||||
def getCoverIcon(
|
||||
w: IBlockAccess,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
side: ForgeDirection
|
||||
): Option[IIcon] =
|
||||
for ((item, stack, te) <- getCoverItem(w, x, y, z, side))
|
||||
yield item.getCoverIcon(te, side, stack)
|
||||
|
||||
override def breakBlock(world: World, x: Int, y: Int, z: Int, block: Block, meta: Int) {
|
||||
override def breakBlock(
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
block: Block,
|
||||
meta: Int
|
||||
) {
|
||||
if (!world.isRemote) {
|
||||
val te = getTE(world, x, y, z)
|
||||
for {
|
||||
|
||||
@@ -18,18 +18,39 @@ import net.minecraft.world.IBlockAccess
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
object CoverRenderer extends BaseBlockRenderHandler {
|
||||
override def renderInventoryBlock(block: Block, metadata: Int, modelId: Int, renderer: RenderBlocks) =
|
||||
override def renderInventoryBlock(
|
||||
block: Block,
|
||||
metadata: Int,
|
||||
modelId: Int,
|
||||
renderer: RenderBlocks
|
||||
) =
|
||||
RenderUtils.renderSimpleBlockItem(block, metadata, renderer)
|
||||
|
||||
override def renderWorldBlock(world: IBlockAccess, x: Int, y: Int, z: Int, block: Block, modelId: Int, renderer: RenderBlocks) = {
|
||||
override def renderWorldBlock(
|
||||
world: IBlockAccess,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
block: Block,
|
||||
modelId: Int,
|
||||
renderer: RenderBlocks
|
||||
) = {
|
||||
renderer.renderStandardBlock(block, x, y, z)
|
||||
if (!renderer.hasOverrideBlockTexture)
|
||||
for {
|
||||
blockCov <- Misc.asInstanceOpt(block, classOf[BlockCoverable[_]])
|
||||
face <- ForgeDirection.VALID_DIRECTIONS
|
||||
icon <- blockCov.getCoverIcon(world, x, y, z, face)
|
||||
if block.shouldSideBeRendered(world, x + face.offsetX, y + face.offsetY, z + face.offsetZ, face.ordinal())
|
||||
} ConnectedHelper.draw(face, 8).doDraw(ConnectedHelper.Vec3F(x, y, z), icon)
|
||||
if block.shouldSideBeRendered(
|
||||
world,
|
||||
x + face.offsetX,
|
||||
y + face.offsetY,
|
||||
z + face.offsetZ,
|
||||
face.ordinal()
|
||||
)
|
||||
} ConnectedHelper
|
||||
.draw(face, 8)
|
||||
.doDraw(ConnectedHelper.Vec3F(x, y, z), icon)
|
||||
true
|
||||
}
|
||||
}
|
||||
@@ -15,68 +15,111 @@ import net.minecraft.util.IIcon
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
trait ItemCover extends Item {
|
||||
/**
|
||||
* @return true if tickCover should be called
|
||||
*/
|
||||
|
||||
/** @return
|
||||
* true if tickCover should be called
|
||||
*/
|
||||
def isCoverTicking: Boolean
|
||||
|
||||
/**
|
||||
* @param te Host TileEntity
|
||||
* @param side Side the cover is installed on
|
||||
* @param cover Cover ItemStack
|
||||
* @return Icon to render, MUST be on terrain sprite sheet (0), not item!
|
||||
*/
|
||||
def getCoverIcon(te: TileCoverable, side: ForgeDirection, cover: ItemStack): IIcon
|
||||
/** @param te
|
||||
* Host TileEntity
|
||||
* @param side
|
||||
* Side the cover is installed on
|
||||
* @param cover
|
||||
* Cover ItemStack
|
||||
* @return
|
||||
* Icon to render, MUST be on terrain sprite sheet (0), not item!
|
||||
*/
|
||||
def getCoverIcon(
|
||||
te: TileCoverable,
|
||||
side: ForgeDirection,
|
||||
cover: ItemStack
|
||||
): IIcon
|
||||
|
||||
/**
|
||||
* Perform tick, called on server only
|
||||
* @param te Host TileEntity
|
||||
* @param side Side the cover is installed on
|
||||
* @param cover Cover ItemStack
|
||||
*/
|
||||
def tickCover(te: TileCoverable, side: ForgeDirection, cover: ItemStack): Unit = {}
|
||||
/** Perform tick, called on server only
|
||||
* @param te
|
||||
* Host TileEntity
|
||||
* @param side
|
||||
* Side the cover is installed on
|
||||
* @param cover
|
||||
* Cover ItemStack
|
||||
*/
|
||||
def tickCover(
|
||||
te: TileCoverable,
|
||||
side: ForgeDirection,
|
||||
cover: ItemStack
|
||||
): Unit = {}
|
||||
|
||||
/**
|
||||
* Checks if this cover can be installed on a specific TE
|
||||
* @param te Potential host TileEntity
|
||||
* @param cover Cover ItemStack
|
||||
* @return true if can be installed
|
||||
*/
|
||||
/** Checks if this cover can be installed on a specific TE
|
||||
* @param te
|
||||
* Potential host TileEntity
|
||||
* @param cover
|
||||
* Cover ItemStack
|
||||
* @return
|
||||
* true if can be installed
|
||||
*/
|
||||
def isValidTile(te: TileCoverable, cover: ItemStack): Boolean
|
||||
|
||||
/**
|
||||
* Handle click on covered side - called on both client and server
|
||||
* @param te Host TileEntity
|
||||
* @param side Side the cover is installed on
|
||||
* @param cover Cover ItemStack
|
||||
* @param player Player clicking the cover
|
||||
* @return true if click was handled by cover
|
||||
*/
|
||||
def clickCover(te: TileCoverable, side: ForgeDirection, cover: ItemStack, player: EntityPlayer): Boolean = false
|
||||
/** Handle click on covered side - called on both client and server
|
||||
* @param te
|
||||
* Host TileEntity
|
||||
* @param side
|
||||
* Side the cover is installed on
|
||||
* @param cover
|
||||
* Cover ItemStack
|
||||
* @param player
|
||||
* Player clicking the cover
|
||||
* @return
|
||||
* true if click was handled by cover
|
||||
*/
|
||||
def clickCover(
|
||||
te: TileCoverable,
|
||||
side: ForgeDirection,
|
||||
cover: ItemStack,
|
||||
player: EntityPlayer
|
||||
): Boolean = false
|
||||
|
||||
/**
|
||||
* Check if cover is emitting RS signal
|
||||
* @param te Host TileEntity
|
||||
* @param side Side the cover is installed on
|
||||
* @param cover Cover ItemStack
|
||||
* @return true if cover is emitting RS signal
|
||||
*/
|
||||
def isEmittingSignal(te: TileCoverable, side: ForgeDirection, cover: ItemStack): Boolean = false
|
||||
/** Check if cover is emitting RS signal
|
||||
* @param te
|
||||
* Host TileEntity
|
||||
* @param side
|
||||
* Side the cover is installed on
|
||||
* @param cover
|
||||
* Cover ItemStack
|
||||
* @return
|
||||
* true if cover is emitting RS signal
|
||||
*/
|
||||
def isEmittingSignal(
|
||||
te: TileCoverable,
|
||||
side: ForgeDirection,
|
||||
cover: ItemStack
|
||||
): Boolean = false
|
||||
|
||||
/**
|
||||
* Called when cover is installed on a block - called only on server
|
||||
* @param te Host TileEntity
|
||||
* @param side Side the cover is installed on
|
||||
* @param cover Cover ItemStack - do not modify!
|
||||
* @param player Player entity doing the installation
|
||||
* @return cover ItemStack - copy if modified
|
||||
*/
|
||||
def onInstall(te:TileCoverable, side: ForgeDirection, cover: ItemStack, player: EntityPlayerMP): ItemStack = cover
|
||||
/** Called when cover is installed on a block - called only on server
|
||||
* @param te
|
||||
* Host TileEntity
|
||||
* @param side
|
||||
* Side the cover is installed on
|
||||
* @param cover
|
||||
* Cover ItemStack - do not modify!
|
||||
* @param player
|
||||
* Player entity doing the installation
|
||||
* @return
|
||||
* cover ItemStack - copy if modified
|
||||
*/
|
||||
def onInstall(
|
||||
te: TileCoverable,
|
||||
side: ForgeDirection,
|
||||
cover: ItemStack,
|
||||
player: EntityPlayerMP
|
||||
): ItemStack = cover
|
||||
|
||||
/**
|
||||
* Called when cover is removed from block or block is destroyed - called only on server
|
||||
* @param cover Cover ItemStack - do not modify!
|
||||
* @return cover ItemStack - copy if modified
|
||||
*/
|
||||
/** Called when cover is removed from block or block is destroyed - called
|
||||
* only on server
|
||||
* @param cover
|
||||
* Cover ItemStack - do not modify!
|
||||
* @return
|
||||
* cover ItemStack - copy if modified
|
||||
*/
|
||||
def onRemove(cover: ItemStack): ItemStack = cover
|
||||
}
|
||||
@@ -19,24 +19,26 @@ import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
trait TileCoverable extends TileDataSlots {
|
||||
val covers = (ForgeDirection.VALID_DIRECTIONS map { x =>
|
||||
x -> DataSlotItemStack("cover_" + x.toString.toLowerCase(Locale.US), this).setUpdate(UpdateKind.SAVE, UpdateKind.WORLD, UpdateKind.RENDER)
|
||||
x -> DataSlotItemStack("cover_" + x.toString.toLowerCase(Locale.US), this)
|
||||
.setUpdate(UpdateKind.SAVE, UpdateKind.WORLD, UpdateKind.RENDER)
|
||||
}).toMap
|
||||
|
||||
/**
|
||||
* Checks if a specific cover can be installed here
|
||||
*/
|
||||
/** Checks if a specific cover can be installed here
|
||||
*/
|
||||
def isValidCover(side: ForgeDirection, cover: ItemStack): Boolean
|
||||
|
||||
/**
|
||||
* Called when new covers are installed
|
||||
*/
|
||||
/** Called when new covers are installed
|
||||
*/
|
||||
def onCoversChanged() {}
|
||||
|
||||
def tickCovers() =
|
||||
for {
|
||||
(dir, coverSlot) <- covers
|
||||
coverStack <- Option(coverSlot.value)
|
||||
coverItem <- Option(coverStack.getItem) flatMap (Misc.asInstanceOpt(_, classOf[ItemCover]))
|
||||
coverItem <- Option(coverStack.getItem) flatMap (Misc.asInstanceOpt(
|
||||
_,
|
||||
classOf[ItemCover]
|
||||
))
|
||||
} {
|
||||
coverItem.tickCover(this, dir, coverStack)
|
||||
}
|
||||
|
||||
@@ -12,8 +12,14 @@ package net.bdew.lib.data
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotBoolean(name: String, parent: DataSlotContainer, 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)
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) =
|
||||
t.setBoolean(name, value)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value =
|
||||
t.getBoolean(name)
|
||||
}
|
||||
@@ -13,8 +13,11 @@ 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: DataSlotContainer) 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))
|
||||
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))
|
||||
}
|
||||
@@ -12,7 +12,12 @@ package net.bdew.lib.data
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotDouble(name: String, parent: DataSlotContainer, 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)
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value =
|
||||
t.getDouble(name)
|
||||
}
|
||||
@@ -12,7 +12,11 @@ package net.bdew.lib.data
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotFloat(name: String, parent: DataSlotContainer, 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)
|
||||
}
|
||||
@@ -13,7 +13,8 @@ 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] {
|
||||
case class DataSlotFluidOption(name: String, parent: DataSlotContainer)
|
||||
extends DataSlotOption[Fluid] {
|
||||
setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
|
||||
|
||||
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
|
||||
@@ -16,21 +16,29 @@ 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: DataSlotContainer) 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) = {
|
||||
value = if (t.hasKey(name + "_uid") || t.hasKey(name + "_name")) {
|
||||
val uId = if (t.hasKey(name + "_uid")) UUID.fromString(t.getString(name + "_uid")) else null
|
||||
val uName = if (t.hasKey(name + "_name")) t.getString(name + "_name") else null
|
||||
val uId =
|
||||
if (t.hasKey(name + "_uid")) UUID.fromString(t.getString(name + "_uid"))
|
||||
else null
|
||||
val uName =
|
||||
if (t.hasKey(name + "_name")) t.getString(name + "_name") else null
|
||||
new GameProfile(uId, uName)
|
||||
} else null
|
||||
}
|
||||
|
||||
override def save(t: NBTTagCompound, kind: UpdateKind.Value) = {
|
||||
if (value != null) {
|
||||
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))
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,13 @@ package net.bdew.lib.data
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotNumeric, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
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)
|
||||
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)
|
||||
}
|
||||
@@ -14,7 +14,9 @@ import net.bdew.lib.tile.inventory.BaseInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
|
||||
|
||||
case class DataSlotInventory(name: String, parent: DataSlotContainer, 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
|
||||
@@ -42,5 +44,3 @@ case class DataSlotInventory(name: String, parent: DataSlotContainer, size: Int)
|
||||
t.setTag(name, itemList)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,8 @@ 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: DataSlotContainer) extends DataSlotVal[ItemStack] {
|
||||
case class DataSlotItemStack(name: String, parent: DataSlotContainer)
|
||||
extends DataSlotVal[ItemStack] {
|
||||
var value: ItemStack = null
|
||||
|
||||
override def update(v: ItemStack) = {
|
||||
@@ -28,5 +29,6 @@ case class DataSlotItemStack(name: String, parent: DataSlotContainer) extends Da
|
||||
if (value != null) value.writeToNBT(tag)
|
||||
t.setTag(name, tag)
|
||||
}
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value = ItemStack.loadItemStackFromNBT(t.getCompoundTag(name))
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) = value =
|
||||
ItemStack.loadItemStackFromNBT(t.getCompoundTag(name))
|
||||
}
|
||||
@@ -9,14 +9,23 @@
|
||||
|
||||
package net.bdew.lib.data
|
||||
|
||||
import java.io.{ByteArrayInputStream, ByteArrayOutputStream, DataInputStream, DataOutputStream}
|
||||
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 {
|
||||
case class DataSlotMovingAverage(
|
||||
name: String,
|
||||
parent: DataSlotContainer,
|
||||
size: Int
|
||||
) extends DataSlot {
|
||||
val values = mutable.Queue.empty[Double]
|
||||
var average: Double = 0
|
||||
|
||||
@@ -53,7 +62,9 @@ case class DataSlotMovingAverage(name: String, parent: DataSlotContainer, size:
|
||||
} else {
|
||||
values.clear()
|
||||
if (t.hasKey(name)) {
|
||||
val i = new DataInputStream(new ByteArrayInputStream(t.getByteArray(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()
|
||||
|
||||
@@ -12,8 +12,14 @@ package net.bdew.lib.data
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, DataSlotVal, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotString(name: String, parent: DataSlotContainer, 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
|
||||
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
|
||||
}
|
||||
@@ -13,7 +13,10 @@ import net.bdew.lib.data.base.{DataSlot, DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.fluids._
|
||||
|
||||
abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank with DataSlot {
|
||||
abstract class DataSlotTankBase(sz: Int)
|
||||
extends FluidTank(sz)
|
||||
with IFluidTank
|
||||
with DataSlot {
|
||||
var oldStack: FluidStack = null
|
||||
|
||||
parent.onServerTick(checkUpdate)
|
||||
@@ -51,12 +54,19 @@ abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank w
|
||||
setCapacity(tag.getInteger("size"))
|
||||
}
|
||||
|
||||
override def setFluid(fluid: FluidStack) = execWithChangeNotify(super.setFluid(fluid))
|
||||
override def setCapacity(capacity: Int) = execWithChangeNotify(super.setCapacity(capacity))
|
||||
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)
|
||||
execWithChangeNotifyConditional[FluidStack](super.drain(maxDrain, true), _ != null)
|
||||
execWithChangeNotifyConditional[FluidStack](
|
||||
super.drain(maxDrain, true),
|
||||
_ != null
|
||||
)
|
||||
else
|
||||
super.drain(maxDrain, false)
|
||||
|
||||
@@ -67,10 +77,17 @@ abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank w
|
||||
super.fill(resource, false)
|
||||
}
|
||||
|
||||
case class DataSlotTank(name: String, parent: DataSlotContainer, size: Int) extends DataSlotTankBase(size)
|
||||
case class DataSlotTank(name: String, parent: DataSlotContainer, size: Int)
|
||||
extends DataSlotTankBase(size)
|
||||
|
||||
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)
|
||||
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.getFluid != filterFluid)) return 0
|
||||
|
||||
@@ -21,14 +21,19 @@ trait ContainerDataSlots extends NoInvContainer {
|
||||
super.addCraftingToCrafters(crafter)
|
||||
if (crafter.isInstanceOf[EntityPlayerMP]) {
|
||||
val pkt = dataSource.getDataSlotPacket
|
||||
crafter.asInstanceOf[EntityPlayerMP].playerNetServerHandler.sendPacket(pkt)
|
||||
crafter
|
||||
.asInstanceOf[EntityPlayerMP]
|
||||
.playerNetServerHandler
|
||||
.sendPacket(pkt)
|
||||
}
|
||||
}
|
||||
|
||||
override def detectAndSendChanges() {
|
||||
super.detectAndSendChanges()
|
||||
// only send updates every 10 ticks
|
||||
if (dataSource.lastChange >= lastSentChange + 10 || (dataSource.lastChange > lastSentChange && lastSentChange + 10 < dataSource.getWorldObj.getTotalWorldTime)) {
|
||||
if (
|
||||
dataSource.lastChange >= lastSentChange + 10 || (dataSource.lastChange > lastSentChange && lastSentChange + 10 < dataSource.getWorldObj.getTotalWorldTime)
|
||||
) {
|
||||
lastSentChange = dataSource.lastChange
|
||||
val pkt = dataSource.getDataSlotPacket
|
||||
|
||||
|
||||
@@ -11,20 +11,18 @@ package net.bdew.lib.data.base
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
/**
|
||||
* Base trait for all data slots
|
||||
*/
|
||||
/** Base trait for all data slots
|
||||
*/
|
||||
trait DataSlot {
|
||||
/**
|
||||
* Tile Entity that owns this slot
|
||||
* Accessed in constructor, so should be in parameters or a lazy val, otherwise will crash
|
||||
*/
|
||||
|
||||
/** Tile Entity that owns this slot Accessed in constructor, so should be in
|
||||
* parameters or a lazy val, otherwise will crash
|
||||
*/
|
||||
val parent: DataSlotContainer
|
||||
|
||||
/**
|
||||
* Unique name
|
||||
* Accessed in constructor, so should be in parameters or a lazy val, otherwise will crash
|
||||
*/
|
||||
/** Unique name Accessed in constructor, so should be in parameters or a lazy
|
||||
* val, otherwise will crash
|
||||
*/
|
||||
val name: String
|
||||
|
||||
parent.dataSlots += (name -> this)
|
||||
@@ -41,7 +39,10 @@ trait DataSlot {
|
||||
v
|
||||
}
|
||||
|
||||
def execWithChangeNotifyConditional[T](f: => T, condition: T => Boolean): T = {
|
||||
def execWithChangeNotifyConditional[T](
|
||||
f: => T,
|
||||
condition: T => Boolean
|
||||
): T = {
|
||||
val v = f
|
||||
if (condition(v))
|
||||
parent.dataSlotChanged(this)
|
||||
|
||||
@@ -14,37 +14,32 @@ 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
|
||||
*/
|
||||
/** 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
|
||||
*/
|
||||
/** Called when a dataslot value changes
|
||||
*/
|
||||
def dataSlotChanged(slot: DataSlot): Unit
|
||||
|
||||
/**
|
||||
* Register a function to run on every server tick
|
||||
*/
|
||||
/** Register a function to run on every server tick
|
||||
*/
|
||||
def onServerTick(f: () => Unit): Unit
|
||||
|
||||
/**
|
||||
* List of dataslots in this container
|
||||
*/
|
||||
/** List of dataslots in this container
|
||||
*/
|
||||
val dataSlots = mutable.HashMap.empty[String, DataSlot]
|
||||
|
||||
/**
|
||||
* The value of getTotalWorldTime when the last change happened
|
||||
*/
|
||||
/** The value of getTotalWorldTime when the last change happened
|
||||
*/
|
||||
var lastChange = 0L
|
||||
|
||||
/**
|
||||
* The value of getTotalWorldTime when the last GUI packet was sent happened
|
||||
*/
|
||||
/** The value of getTotalWorldTime when the last GUI packet was sent happened
|
||||
*/
|
||||
var lastGuiPacket = 0L
|
||||
|
||||
final val TRACE = false
|
||||
@@ -73,5 +68,3 @@ trait DataSlotContainer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@
|
||||
|
||||
package net.bdew.lib.data.base
|
||||
|
||||
/**
|
||||
* Base class for data slots that hold numeric values
|
||||
* adds convenience operators to modify the value
|
||||
*/
|
||||
/** Base class for data slots that hold numeric values adds convenience
|
||||
* operators to modify the value
|
||||
*/
|
||||
|
||||
abstract class DataSlotNumeric[T](default: T)(implicit n: Numeric[T]) extends DataSlotVal[T] {
|
||||
abstract class DataSlotNumeric[T](default: T)(implicit n: Numeric[T])
|
||||
extends DataSlotVal[T] {
|
||||
var value = default
|
||||
def +=(that: T) = update(n.plus(value, that))
|
||||
def -=(that: T) = update(n.minus(value, that))
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
|
||||
package net.bdew.lib.data.base
|
||||
|
||||
/**
|
||||
* Base class for data slots that hold values with ordering operators, adds more convenience operators
|
||||
* TODO: Do i need this? normal operators can be used with the implicit conversion
|
||||
*/
|
||||
abstract class DataSlotOrdered[T](implicit n: Ordering[T]) extends DataSlotVal[T] {
|
||||
/** Base class for data slots that hold values with ordering operators, adds
|
||||
* more convenience operators TODO: Do i need this? normal operators can be
|
||||
* used with the implicit conversion
|
||||
*/
|
||||
abstract class DataSlotOrdered[T](implicit n: Ordering[T])
|
||||
extends DataSlotVal[T] {
|
||||
def :>(that: T) = n.compare(value, that) > 0
|
||||
def :<(that: T) = n.compare(value, that) < 0
|
||||
def :>=(that: T) = n.compare(value, that) >= 0
|
||||
|
||||
@@ -11,10 +11,10 @@ package net.bdew.lib.data.base
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
/**
|
||||
* Base trait for data slots that hold primitive values
|
||||
* Defines some convenience operators to access the value and an implicit conversion to the value
|
||||
*/
|
||||
/** Base trait for data slots that hold primitive values Defines some
|
||||
* convenience operators to access the value and an implicit conversion to the
|
||||
* value
|
||||
*/
|
||||
|
||||
trait DataSlotVal[T] extends DataSlot {
|
||||
var value: T
|
||||
@@ -36,4 +36,4 @@ trait DataSlotVal[T] extends DataSlot {
|
||||
|
||||
object DataSlotVal {
|
||||
implicit def slot2val[T](slot: DataSlotVal[T]): T = slot.value
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,14 @@ trait TileDataSlots extends TileExtended with DataSlotContainer {
|
||||
handleClientUpdate.listen { tag =>
|
||||
doLoad(UpdateKind.WORLD, tag)
|
||||
if (dataSlots.values.exists(_.updateKind.contains(UpdateKind.RENDER)))
|
||||
getWorldObj.markBlockRangeForRenderUpdate(xCoord, yCoord, zCoord, xCoord, yCoord, zCoord)
|
||||
getWorldObj.markBlockRangeForRenderUpdate(
|
||||
xCoord,
|
||||
yCoord,
|
||||
zCoord,
|
||||
xCoord,
|
||||
yCoord,
|
||||
zCoord
|
||||
)
|
||||
}
|
||||
|
||||
override def getWorldObject = getWorldObj
|
||||
|
||||
@@ -14,4 +14,4 @@ object UpdateKind extends Enumeration {
|
||||
val GUI = Value("GUI")
|
||||
val SAVE = Value("SAVE")
|
||||
val RENDER = Value("RENDER")
|
||||
}
|
||||
}
|
||||
@@ -15,20 +15,30 @@ import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
abstract class BaseContainer(te: IInventory) extends NoInvContainer {
|
||||
override def transferStackInSlot(player: EntityPlayer, slot: Int): ItemStack = {
|
||||
override def transferStackInSlot(
|
||||
player: EntityPlayer,
|
||||
slot: Int
|
||||
): ItemStack = {
|
||||
var stack = getSlot(slot).getStack
|
||||
if (getSlot(slot).inventory == player.inventory) {
|
||||
stack = ItemUtils.addStackToSlots(stack, te, 0 until te.getSizeInventory, true)
|
||||
stack =
|
||||
ItemUtils.addStackToSlots(stack, te, 0 until te.getSizeInventory, true)
|
||||
} else {
|
||||
stack = ItemUtils.addStackToSlots(stack, player.inventory, 9 until player.inventory.mainInventory.length, true)
|
||||
stack = ItemUtils.addStackToSlots(
|
||||
stack,
|
||||
player.inventory,
|
||||
9 until player.inventory.mainInventory.length,
|
||||
true
|
||||
)
|
||||
// Only put in hotbar if the rest is full
|
||||
if (stack != null)
|
||||
stack = ItemUtils.addStackToSlots(stack, player.inventory, 0 until 9, true)
|
||||
stack =
|
||||
ItemUtils.addStackToSlots(stack, player.inventory, 0 until 9, true)
|
||||
}
|
||||
getSlot(slot).putStack(stack)
|
||||
return null
|
||||
}
|
||||
|
||||
override def canInteractWith(player: EntityPlayer) = te.isUseableByPlayer(player)
|
||||
override def canInteractWith(player: EntityPlayer) =
|
||||
te.isUseableByPlayer(player)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@ 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.lt(p.x, x2) && n.lt(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)
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ import org.lwjgl.opengl.GL11
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContainer(cont) {
|
||||
abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int)
|
||||
extends GuiContainer(cont) {
|
||||
xSize = xSz
|
||||
ySize = ySz
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@ package net.bdew.lib.gui
|
||||
import net.minecraft.inventory.{IInventory, Slot}
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
class BaseSlot(inv: IInventory, slot: Int, x: Int, y: Int) extends Slot(inv, slot, x, y) {
|
||||
class BaseSlot(inv: IInventory, slot: Int, x: Int, y: Int)
|
||||
extends Slot(inv, slot, x, y) {
|
||||
override def getBackgroundIconIndex = {
|
||||
// Workaround for bug in GuiContainer, color isn't reset if previous slot had an item with color.
|
||||
GL11.glColor4d(1, 1, 1, 1)
|
||||
|
||||
@@ -28,11 +28,12 @@ case class Color(r: Float, g: Float, b: Float, a: Float = 1) {
|
||||
}
|
||||
|
||||
object Color {
|
||||
def fromRGB(r: Int, g: Int, b: Int, a: Int = 255) = Color(r / 255F, g / 255F, b / 255F, a / 255F)
|
||||
def fromRGB(r: Int, g: Int, b: Int, a: Int = 255) =
|
||||
Color(r / 255f, g / 255f, b / 255f, a / 255f)
|
||||
def fromInt(v: Int) = Color(
|
||||
((v >> 16) & 0xFF) / 255F,
|
||||
((v >> 8) & 0xFF) / 255F,
|
||||
(v & 0xFF) / 255F
|
||||
((v >> 16) & 0xff) / 255f,
|
||||
((v >> 8) & 0xff) / 255f,
|
||||
(v & 0xff) / 255f
|
||||
)
|
||||
final val white = Color(1, 1, 1)
|
||||
final val black = Color(0, 0, 0)
|
||||
@@ -43,7 +44,7 @@ object Color {
|
||||
final val cyan = Color(0, 1, 1)
|
||||
final val magenta = Color(1, 0, 1)
|
||||
|
||||
final val gray = Color(0.5F, 0.5F, 0.5F)
|
||||
final val lightGray = Color(0.75F, 0.75F, 0.75F)
|
||||
final val darkGray = Color(0.25F, 0.25F, 0.25F)
|
||||
final val gray = Color(0.5f, 0.5f, 0.5f)
|
||||
final val lightGray = Color(0.75f, 0.75f, 0.75f)
|
||||
final val darkGray = Color(0.25f, 0.25f, 0.25f)
|
||||
}
|
||||
@@ -19,8 +19,20 @@ trait DrawTarget {
|
||||
def drawText(text: String, p: Point, color: Color, shadow: Boolean)
|
||||
def drawTextMultiline(text: String, r: Rect, color: Color)
|
||||
|
||||
def drawTextureInterpolate(r: Rect, t: Texture, x1: Float, y1: Float, x2: Float, y2: Float, color: Color = Color.white) =
|
||||
drawTexture(r.interpolate(x1, y1, x2, y2), Texture.interpolate(t, x1, y1, x2, y2), color)
|
||||
def drawTextureInterpolate(
|
||||
r: Rect,
|
||||
t: Texture,
|
||||
x1: Float,
|
||||
y1: Float,
|
||||
x2: Float,
|
||||
y2: Float,
|
||||
color: Color = Color.white
|
||||
) =
|
||||
drawTexture(
|
||||
r.interpolate(x1, y1, x2, y2),
|
||||
Texture.interpolate(t, x1, y1, x2, y2),
|
||||
color
|
||||
)
|
||||
}
|
||||
|
||||
trait SimpleDrawTarget extends DrawTarget {
|
||||
@@ -42,5 +54,11 @@ trait SimpleDrawTarget extends DrawTarget {
|
||||
getFontRenderer.drawString(text, p.x.round, p.y.round, color.asARGB, shadow)
|
||||
|
||||
def drawTextMultiline(text: String, r: Rect, color: Color) =
|
||||
getFontRenderer.drawSplitString(text, r.x.round, r.y.round, r.w.round, color.asARGB)
|
||||
getFontRenderer.drawSplitString(
|
||||
text,
|
||||
r.x.round,
|
||||
r.y.round,
|
||||
r.w.round,
|
||||
color.asARGB
|
||||
)
|
||||
}
|
||||
@@ -20,13 +20,30 @@ class GuiHandler extends IGuiHandler {
|
||||
|
||||
def register(p: GuiProvider) = {
|
||||
if (GUIs.isDefinedAt(p.guiId))
|
||||
sys.error("GUI ID Collision - %d was registered for %s and attempted to register by %s".format(p.guiId, GUIs(p.guiId), p))
|
||||
sys.error(
|
||||
"GUI ID Collision - %d was registered for %s and attempted to register by %s"
|
||||
.format(p.guiId, GUIs(p.guiId), p)
|
||||
)
|
||||
GUIs += (p.guiId -> p)
|
||||
}
|
||||
|
||||
def getServerGuiElement(ID: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef =
|
||||
def getServerGuiElement(
|
||||
ID: Int,
|
||||
player: EntityPlayer,
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int
|
||||
): AnyRef =
|
||||
GUIs(ID).getContainer(world.getTileEntity(x, y, z), player)
|
||||
|
||||
def getClientGuiElement(ID: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef =
|
||||
def getClientGuiElement(
|
||||
ID: Int,
|
||||
player: EntityPlayer,
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int
|
||||
): AnyRef =
|
||||
GUIs(ID).getGui(world.getTileEntity(x, y, z), player)
|
||||
}
|
||||
@@ -10,7 +10,11 @@
|
||||
package net.bdew.lib.gui
|
||||
|
||||
import net.bdew.lib.Misc
|
||||
import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP, InventoryPlayer}
|
||||
import net.minecraft.entity.player.{
|
||||
EntityPlayer,
|
||||
EntityPlayerMP,
|
||||
InventoryPlayer
|
||||
}
|
||||
import net.minecraft.inventory.{Container, Slot}
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
@@ -20,22 +24,37 @@ abstract class NoInvContainer extends Container {
|
||||
|
||||
def players = Misc.filterType(crafters, classOf[EntityPlayerMP])
|
||||
|
||||
protected def bindPlayerInventory(inv: InventoryPlayer, xOffs: Int, yOffsInv: Int, yOffsHotbar: Int) {
|
||||
protected def bindPlayerInventory(
|
||||
inv: InventoryPlayer,
|
||||
xOffs: Int,
|
||||
yOffsInv: Int,
|
||||
yOffsHotbar: Int
|
||||
) {
|
||||
for (i <- 0 until 3; j <- 0 until 9)
|
||||
addSlotToContainer(new Slot(inv, j + i * 9 + 9, xOffs + j * 18, yOffsInv + i * 18))
|
||||
addSlotToContainer(
|
||||
new Slot(inv, j + i * 9 + 9, xOffs + j * 18, yOffsInv + i * 18)
|
||||
)
|
||||
|
||||
for (i <- 0 until 9)
|
||||
addSlotToContainer(new Slot(inv, i, xOffs + i * 18, yOffsHotbar))
|
||||
}
|
||||
|
||||
override def slotClick(slotNum: Int, button: Int, modifiers: Int, player: EntityPlayer): ItemStack = {
|
||||
override def slotClick(
|
||||
slotNum: Int,
|
||||
button: Int,
|
||||
modifiers: Int,
|
||||
player: EntityPlayer
|
||||
): ItemStack = {
|
||||
if (inventorySlots.isDefinedAt(slotNum)) {
|
||||
val slot = getSlot(slotNum)
|
||||
if (slot != null && slot.isInstanceOf[SlotClickable])
|
||||
return slot.asInstanceOf[SlotClickable].onClick(button, modifiers, player)
|
||||
return slot
|
||||
.asInstanceOf[SlotClickable]
|
||||
.onClick(button, modifiers, player)
|
||||
}
|
||||
return super.slotClick(slotNum, button, modifiers, player)
|
||||
}
|
||||
|
||||
override def transferStackInSlot(player: EntityPlayer, slot: Int): ItemStack = null
|
||||
override def transferStackInSlot(player: EntityPlayer, slot: Int): ItemStack =
|
||||
null
|
||||
}
|
||||
@@ -12,6 +12,8 @@ package net.bdew.lib.gui
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
class SlotValidating(inv: IInventory, slot: Int, x: Int, y: Int) extends BaseSlot(inv, slot, x, y) {
|
||||
override def isItemValid(stack: ItemStack) = inventory.isItemValidForSlot(getSlotIndex, stack)
|
||||
}
|
||||
class SlotValidating(inv: IInventory, slot: Int, x: Int, y: Int)
|
||||
extends BaseSlot(inv, slot, x, y) {
|
||||
override def isItemValid(stack: ItemStack) =
|
||||
inventory.isItemValidForSlot(getSlotIndex, stack)
|
||||
}
|
||||
@@ -30,7 +30,8 @@ class InterpolatedTexture(val texture: Texture, rect: Rect) extends Texture {
|
||||
def v2 = rect.y2 * (texture.v2 - texture.v1) + texture.v1
|
||||
}
|
||||
|
||||
class IconWrapper(val resource: ResourceLocation, aIcon: IIcon) extends Texture {
|
||||
class IconWrapper(val resource: ResourceLocation, aIcon: IIcon)
|
||||
extends Texture {
|
||||
val icon = if (aIcon == null) {
|
||||
if (resource == Texture.ITEMS) Client.itemMissingIcon
|
||||
else if (resource == Texture.BLOCKS) Client.blockMissingIcon
|
||||
@@ -44,7 +45,8 @@ class IconWrapper(val resource: ResourceLocation, aIcon: IIcon) extends Texture
|
||||
def bind() = Minecraft.getMinecraft.renderEngine.bindTexture(resource)
|
||||
}
|
||||
|
||||
class Sprite(val resource: ResourceLocation, r: Rect, scale: Int = 256) extends Texture {
|
||||
class Sprite(val resource: ResourceLocation, r: Rect, scale: Int = 256)
|
||||
extends Texture {
|
||||
val rect = Rect(r.x / scale, r.y / scale, r.w / scale, r.h / scale)
|
||||
def u1 = rect.x1
|
||||
def u2 = rect.x2
|
||||
@@ -53,8 +55,10 @@ class Sprite(val resource: ResourceLocation, r: Rect, scale: Int = 256) extends
|
||||
def bind() = Minecraft.getMinecraft.renderEngine.bindTexture(resource)
|
||||
}
|
||||
|
||||
class ScaledResourceLocation(path: String, val scale: Int = 256) extends ResourceLocation(path) {
|
||||
def this(domain: String, path: String, scale: Int) = this(domain + ":" + path, scale)
|
||||
class ScaledResourceLocation(path: String, val scale: Int = 256)
|
||||
extends ResourceLocation(path) {
|
||||
def this(domain: String, path: String, scale: Int) =
|
||||
this(domain + ":" + path, scale)
|
||||
def this(domain: String, path: String) = this(domain + ":" + path, 256)
|
||||
}
|
||||
|
||||
@@ -67,27 +71,76 @@ object Texture {
|
||||
|
||||
// From a ResourceLocation and position, scale optional
|
||||
def apply(res: ResourceLocation, r: Rect) = new Sprite(res, r)
|
||||
def apply(res: ResourceLocation, r: Rect, scale: Int) = new Sprite(res, r, scale)
|
||||
def apply(res: ResourceLocation, u1: Float, v1: Float, w: Float, h: Float) = new Sprite(res, Rect(u1, v1, w, h))
|
||||
def apply(res: ResourceLocation, u1: Float, v1: Float, w: Float, h: Float, scale: Int) = new Sprite(res, Rect(u1, v1, w, h), scale)
|
||||
def apply(res: ResourceLocation, r: Rect, scale: Int) =
|
||||
new Sprite(res, r, scale)
|
||||
def apply(res: ResourceLocation, u1: Float, v1: Float, w: Float, h: Float) =
|
||||
new Sprite(res, Rect(u1, v1, w, h))
|
||||
def apply(
|
||||
res: ResourceLocation,
|
||||
u1: Float,
|
||||
v1: Float,
|
||||
w: Float,
|
||||
h: Float,
|
||||
scale: Int
|
||||
) = new Sprite(res, Rect(u1, v1, w, h), scale)
|
||||
|
||||
// From a path (with optional domain) and position, no scale
|
||||
def apply(path: String, r: Rect) = new Sprite(new ResourceLocation(path), r)
|
||||
def apply(path: String, u1: Float, v1: Float, w: Float, h: Float) = new Sprite(new ResourceLocation(path), Rect(u1, v1, w, h))
|
||||
def apply(domain: String, path: String, r: Rect) = new Sprite(new ResourceLocation(domain, path), r)
|
||||
def apply(domain: String, path: String, u1: Float, v1: Float, w: Float, h: Float) = new Sprite(new ResourceLocation(domain, path), Rect(u1, v1, w, h))
|
||||
def apply(path: String, u1: Float, v1: Float, w: Float, h: Float) =
|
||||
new Sprite(new ResourceLocation(path), Rect(u1, v1, w, h))
|
||||
def apply(domain: String, path: String, r: Rect) =
|
||||
new Sprite(new ResourceLocation(domain, path), r)
|
||||
def apply(
|
||||
domain: String,
|
||||
path: String,
|
||||
u1: Float,
|
||||
v1: Float,
|
||||
w: Float,
|
||||
h: Float
|
||||
) = new Sprite(new ResourceLocation(domain, path), Rect(u1, v1, w, h))
|
||||
|
||||
// From a path (with optional domain), position and scale
|
||||
def apply(path: String, r: Rect, scale: Int) = new Sprite(new ResourceLocation(path), r, scale)
|
||||
def apply(path: String, u1: Float, v1: Float, w: Float, h: Float, scale: Int) = new Sprite(new ResourceLocation(path), Rect(u1, v1, w, h), scale)
|
||||
def apply(domain: String, path: String, r: Rect, scale: Int) = new Sprite(new ResourceLocation(domain, path), r, scale)
|
||||
def apply(domain: String, path: String, u1: Float, v1: Float, w: Float, h: Float, scale: Int) = new Sprite(new ResourceLocation(domain, path), Rect(u1, v1, w, h), scale)
|
||||
def apply(path: String, r: Rect, scale: Int) =
|
||||
new Sprite(new ResourceLocation(path), r, scale)
|
||||
def apply(
|
||||
path: String,
|
||||
u1: Float,
|
||||
v1: Float,
|
||||
w: Float,
|
||||
h: Float,
|
||||
scale: Int
|
||||
) = new Sprite(new ResourceLocation(path), Rect(u1, v1, w, h), scale)
|
||||
def apply(domain: String, path: String, r: Rect, scale: Int) =
|
||||
new Sprite(new ResourceLocation(domain, path), r, scale)
|
||||
def apply(
|
||||
domain: String,
|
||||
path: String,
|
||||
u1: Float,
|
||||
v1: Float,
|
||||
w: Float,
|
||||
h: Float,
|
||||
scale: Int
|
||||
) = new Sprite(new ResourceLocation(domain, path), Rect(u1, v1, w, h), scale)
|
||||
|
||||
// From a ScaledResourceLocation and position
|
||||
def apply(res: ScaledResourceLocation, r: Rect) = new Sprite(res, r, res.scale)
|
||||
def apply(res: ScaledResourceLocation, u1: Float, v1: Float, w: Float, h: Float) = new Sprite(res, Rect(u1, v1, w, h), res.scale)
|
||||
def apply(res: ScaledResourceLocation, r: Rect) =
|
||||
new Sprite(res, r, res.scale)
|
||||
def apply(
|
||||
res: ScaledResourceLocation,
|
||||
u1: Float,
|
||||
v1: Float,
|
||||
w: Float,
|
||||
h: Float
|
||||
) = new Sprite(res, Rect(u1, v1, w, h), res.scale)
|
||||
|
||||
// A fraction of another Texture, parameters should be between 0 and 1
|
||||
def interpolate(texture: Texture, rect: Rect) = new InterpolatedTexture(texture, rect)
|
||||
def interpolate(texture: Texture, u1: Float, v1: Float, u2: Float, v2: Float) = new InterpolatedTexture(texture, Rect(u1, v1, u2 - u1, v2 - v1))
|
||||
def interpolate(texture: Texture, rect: Rect) =
|
||||
new InterpolatedTexture(texture, rect)
|
||||
def interpolate(
|
||||
texture: Texture,
|
||||
u1: Float,
|
||||
v1: Float,
|
||||
u2: Float,
|
||||
v2: Float
|
||||
) = new InterpolatedTexture(texture, Rect(u1, v1, u2 - u1, v2 - v1))
|
||||
}
|
||||
@@ -78,7 +78,9 @@ trait WidgetContainer extends DrawTarget {
|
||||
def getOffsetFromWindow: Point
|
||||
}
|
||||
|
||||
class WidgetContainerWindow(val parent: BaseScreen, xSz: Int, ySz: Int) extends WidgetContainer with SimpleDrawTarget {
|
||||
class WidgetContainerWindow(val parent: BaseScreen, xSz: Int, ySz: Int)
|
||||
extends WidgetContainer
|
||||
with SimpleDrawTarget {
|
||||
def getZLevel = parent.getZLevel
|
||||
def getFontRenderer = parent.getFontRenderer
|
||||
def getOffsetFromWindow = Point(0, 0)
|
||||
|
||||
@@ -15,19 +15,25 @@ package object gui {
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
implicit def awt2point(p: java.awt.Point): BasePoint[Int] = BasePoint(p.x, p.y)
|
||||
implicit def point2awt(p: BasePoint[Int]): java.awt.Point = new java.awt.Point(p.x, p.y)
|
||||
implicit def tuple2point[T: Numeric](p: (T, T)): BasePoint[T] = BasePoint(p._1, p._2)
|
||||
implicit def awt2point(p: java.awt.Point): BasePoint[Int] =
|
||||
BasePoint(p.x, p.y)
|
||||
implicit def point2awt(p: BasePoint[Int]): java.awt.Point =
|
||||
new java.awt.Point(p.x, p.y)
|
||||
implicit def tuple2point[T: Numeric](p: (T, T)): BasePoint[T] =
|
||||
BasePoint(p._1, p._2)
|
||||
|
||||
// Converts different kinds of Point/Rect as long as there's an implicit for the underlying type
|
||||
|
||||
implicit def pointConvert[T, R](a: BasePoint[R])(implicit f: R => T, n: Numeric[T]): BasePoint[T] =
|
||||
implicit def pointConvert[T, R](
|
||||
a: BasePoint[R]
|
||||
)(implicit f: R => T, n: Numeric[T]): BasePoint[T] =
|
||||
BasePoint[T](f(a.x), f(a.y))
|
||||
|
||||
implicit def rectConvert[T, R](a: BaseRect[R])(implicit f: R => T, n: Numeric[T]): BaseRect[T] =
|
||||
implicit def rectConvert[T, R](
|
||||
a: BaseRect[R]
|
||||
)(implicit f: R => T, n: Numeric[T]): BaseRect[T] =
|
||||
BaseRect[T](f(a.x), f(a.y), f(a.w), f(a.h))
|
||||
|
||||
def Rect(x: Float, y: Float, w: Float, h: Float) = BaseRect(x, y, w, h)
|
||||
def Point(x: Float, y: Float) = BasePoint(x, y)
|
||||
}
|
||||
|
||||
@@ -16,12 +16,26 @@ import net.minecraft.client.gui.GuiButton
|
||||
import net.minecraft.util.ResourceLocation
|
||||
|
||||
class WidgetButton(val rect: Rect, text: String, clicked: WidgetButton => Unit)
|
||||
extends GuiButton(0, rect.x.round, rect.y.round, rect.w.round, rect.h.round, text) with Widget {
|
||||
extends GuiButton(
|
||||
0,
|
||||
rect.x.round,
|
||||
rect.y.round,
|
||||
rect.w.round,
|
||||
rect.h.round,
|
||||
text
|
||||
)
|
||||
with Widget {
|
||||
|
||||
override def mouseClicked(p: Point, button: Int) {
|
||||
Minecraft.getMinecraft.getSoundHandler.playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F))
|
||||
Minecraft.getMinecraft.getSoundHandler.playSound(
|
||||
PositionedSoundRecord.func_147674_a(
|
||||
new ResourceLocation("gui.button.press"),
|
||||
1.0f
|
||||
)
|
||||
)
|
||||
clicked(this)
|
||||
}
|
||||
|
||||
override def draw(mouse: Point) = drawButton(Minecraft.getMinecraft, mouse.x.round, mouse.y.round)
|
||||
override def draw(mouse: Point) =
|
||||
drawButton(Minecraft.getMinecraft, mouse.x.round, mouse.y.round)
|
||||
}
|
||||
@@ -16,9 +16,14 @@ import net.minecraft.util.ResourceLocation
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class WidgetButtonIcon(p: Point, clicked: WidgetButtonIcon => Unit, baseTex: Texture, hoverTex: Texture) extends Widget {
|
||||
class WidgetButtonIcon(
|
||||
p: Point,
|
||||
clicked: WidgetButtonIcon => Unit,
|
||||
baseTex: Texture,
|
||||
hoverTex: Texture
|
||||
) extends Widget {
|
||||
val rect = new Rect(p, 16, 16)
|
||||
val iconRect = new Rect(p +(1, 1), 14, 14)
|
||||
val iconRect = new Rect(p + (1, 1), 14, 14)
|
||||
|
||||
var icon: Texture = null
|
||||
var hover: String = null
|
||||
@@ -39,7 +44,12 @@ class WidgetButtonIcon(p: Point, clicked: WidgetButtonIcon => Unit, baseTex: Tex
|
||||
}
|
||||
|
||||
override def mouseClicked(p: Point, button: Int) {
|
||||
Minecraft.getMinecraft.getSoundHandler.playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F))
|
||||
Minecraft.getMinecraft.getSoundHandler.playSound(
|
||||
PositionedSoundRecord.func_147674_a(
|
||||
new ResourceLocation("gui.button.press"),
|
||||
1.0f
|
||||
)
|
||||
)
|
||||
clicked(this)
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,8 @@ package net.bdew.lib.gui.widgets
|
||||
|
||||
import net.bdew.lib.gui.{Color, Point, Rect}
|
||||
|
||||
class WidgetDynLabel(text: => String, x: Int, y: Int, color: Color) extends Widget {
|
||||
class WidgetDynLabel(text: => String, x: Int, y: Int, color: Color)
|
||||
extends Widget {
|
||||
val rect = new Rect(x, y, 0, 0)
|
||||
override def draw(mouse: Point) {
|
||||
parent.drawText(text, rect.origin, color, false)
|
||||
|
||||
@@ -12,7 +12,14 @@ package net.bdew.lib.gui.widgets
|
||||
import net.bdew.lib.data.base.DataSlotNumeric
|
||||
import net.bdew.lib.gui._
|
||||
|
||||
class WidgetFillDataSlot[T](val rect: Rect, val texture: Texture, dir: Direction.Direction, dSlot: DataSlotNumeric[T], maxVal: T)(implicit num: Numeric[T]) extends Widget {
|
||||
class WidgetFillDataSlot[T](
|
||||
val rect: Rect,
|
||||
val texture: Texture,
|
||||
dir: Direction.Direction,
|
||||
dSlot: DataSlotNumeric[T],
|
||||
maxVal: T
|
||||
)(implicit num: Numeric[T])
|
||||
extends Widget {
|
||||
|
||||
import num.mkNumericOps
|
||||
|
||||
@@ -30,5 +37,3 @@ class WidgetFillDataSlot[T](val rect: Rect, val texture: Texture, dir: Direction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,18 @@ import org.lwjgl.opengl.GL11
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class WidgetFluidGauge(val rect: Rect, overlay: Texture, dSlot: DataSlotTankBase) extends Widget {
|
||||
class WidgetFluidGauge(
|
||||
val rect: Rect,
|
||||
overlay: Texture,
|
||||
dSlot: DataSlotTankBase
|
||||
) extends Widget {
|
||||
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
|
||||
if (dSlot.getFluid != null) {
|
||||
tip += dSlot.getFluid.getFluid.getLocalizedName(dSlot.getFluid)
|
||||
tip += "%s/%s mB".format(DecFormat.round(dSlot.getFluidAmount), DecFormat.round(dSlot.getCapacity))
|
||||
tip += "%s/%s mB".format(
|
||||
DecFormat.round(dSlot.getFluidAmount),
|
||||
DecFormat.round(dSlot.getCapacity)
|
||||
)
|
||||
} else {
|
||||
tip += Misc.toLocal("bdlib.label.empty")
|
||||
}
|
||||
@@ -34,15 +41,29 @@ class WidgetFluidGauge(val rect: Rect, overlay: Texture, dSlot: DataSlotTankBase
|
||||
if (fStack != null) {
|
||||
val color = Color.fromInt(Misc.getFluidColor(fStack))
|
||||
val icon = Texture(Texture.BLOCKS, Misc.getFluidIcon(fStack))
|
||||
var fillHeight = if (dSlot.getCapacity > 0) rect.h * fStack.amount / dSlot.getCapacity else 0
|
||||
var fillHeight =
|
||||
if (dSlot.getCapacity > 0) rect.h * fStack.amount / dSlot.getCapacity
|
||||
else 0
|
||||
var yStart: Int = 0
|
||||
|
||||
while (fillHeight > 0) {
|
||||
if (fillHeight > 16) {
|
||||
parent.drawTexture(new Rect(rect.x, rect.y2 - 16 - yStart, rect.w, 16), icon, color)
|
||||
parent.drawTexture(
|
||||
new Rect(rect.x, rect.y2 - 16 - yStart, rect.w, 16),
|
||||
icon,
|
||||
color
|
||||
)
|
||||
fillHeight -= 16
|
||||
} else {
|
||||
parent.drawTextureInterpolate(new Rect(rect.x, rect.y2 - 16 - yStart, rect.w, 16), icon, 0, 1 - fillHeight / 16, 1, 1, color)
|
||||
parent.drawTextureInterpolate(
|
||||
new Rect(rect.x, rect.y2 - 16 - yStart, rect.w, 16),
|
||||
icon,
|
||||
0,
|
||||
1 - fillHeight / 16,
|
||||
1,
|
||||
1,
|
||||
color
|
||||
)
|
||||
fillHeight = 0
|
||||
}
|
||||
yStart = yStart + 16
|
||||
|
||||
@@ -14,6 +14,14 @@ import net.bdew.lib.gui._
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class WidgetProgressBar(rect: Rect, texture: Texture, dSlot: DataSlotFloat) extends WidgetFillDataSlot[Float](rect, texture, Direction.RIGHT, dSlot, 1) {
|
||||
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) = tip += "%.0f".format(dSlot.value * 100) + "%"
|
||||
class WidgetProgressBar(rect: Rect, texture: Texture, dSlot: DataSlotFloat)
|
||||
extends WidgetFillDataSlot[Float](
|
||||
rect,
|
||||
texture,
|
||||
Direction.RIGHT,
|
||||
dSlot,
|
||||
1
|
||||
) {
|
||||
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) =
|
||||
tip += "%.0f".format(dSlot.value * 100) + "%"
|
||||
}
|
||||
@@ -11,7 +11,10 @@ package net.bdew.lib.gui.widgets
|
||||
|
||||
import net.bdew.lib.gui._
|
||||
|
||||
class WidgetSubContainer(val rect: Rect) extends BaseWidget with WidgetContainer with SimpleDrawTarget {
|
||||
class WidgetSubContainer(val rect: Rect)
|
||||
extends BaseWidget
|
||||
with WidgetContainer
|
||||
with SimpleDrawTarget {
|
||||
def getZLevel = parent.getZLevel
|
||||
def getFontRenderer = parent.getFontRenderer
|
||||
def getOffsetFromWindow = parent.getOffsetFromWindow + rect.origin
|
||||
|
||||
@@ -12,7 +12,15 @@ package net.bdew.lib.gui.widgets
|
||||
import net.bdew.lib.gui.{Point, Rect}
|
||||
import net.minecraft.client.gui.{FontRenderer, GuiTextField}
|
||||
|
||||
class WidgetTextEdit(val rect: Rect, fr: FontRenderer) extends GuiTextField(fr, rect.x.round, rect.y.round, rect.w.round, rect.h.round) with Widget {
|
||||
class WidgetTextEdit(val rect: Rect, fr: FontRenderer)
|
||||
extends GuiTextField(
|
||||
fr,
|
||||
rect.x.round,
|
||||
rect.y.round,
|
||||
rect.w.round,
|
||||
rect.h.round
|
||||
)
|
||||
with Widget {
|
||||
|
||||
override def mouseClicked(p: Point, button: Int) = {
|
||||
val pp = p + rect.origin
|
||||
|
||||
@@ -52,9 +52,13 @@ object ChatHelper {
|
||||
}
|
||||
|
||||
implicit def str2chat(s: String): ChatComponentText = new ChatComponentText(s)
|
||||
implicit def str2rich(s: String): RichChatComponent = new RichChatComponent(new ChatComponentText(s))
|
||||
implicit def pimpIChatComponent(v: IChatComponent): RichChatComponent = new RichChatComponent(v)
|
||||
implicit def str2rich(s: String): RichChatComponent = new RichChatComponent(
|
||||
new ChatComponentText(s)
|
||||
)
|
||||
implicit def pimpIChatComponent(v: IChatComponent): RichChatComponent =
|
||||
new RichChatComponent(v)
|
||||
|
||||
def C(s: String) = new ChatComponentText(s)
|
||||
def L(s: String, params: IChatComponent*) = new ChatComponentTranslation(s, params: _*)
|
||||
def L(s: String, params: IChatComponent*) =
|
||||
new ChatComponentTranslation(s, params: _*)
|
||||
}
|
||||
@@ -12,9 +12,8 @@ package net.bdew.lib.items
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.item.{Item, ItemBlock, ItemStack}
|
||||
|
||||
/**
|
||||
* Allows matching Items in ItemStacks in scala pattern matches
|
||||
*/
|
||||
/** Allows matching Items in ItemStacks in scala pattern matches
|
||||
*/
|
||||
object IStack {
|
||||
def unapply(x: ItemStack): Option[Item] =
|
||||
if (x == null || x.getItem == null)
|
||||
@@ -23,9 +22,8 @@ object IStack {
|
||||
Some(x.getItem)
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows matching Blocks in ItemStacks in scala pattern matches
|
||||
*/
|
||||
/** Allows matching Blocks in ItemStacks in scala pattern matches
|
||||
*/
|
||||
object IStackBlock {
|
||||
def unapply(x: ItemStack): Option[Block] =
|
||||
if (x == null || x.getItem == null || !x.getItem.isInstanceOf[ItemBlock])
|
||||
|
||||
@@ -34,7 +34,9 @@ object ItemUtils {
|
||||
|
||||
def dropItemToPlayer(world: World, player: EntityPlayer, stack: ItemStack) {
|
||||
if ((stack == null) || world.isRemote) return
|
||||
world.spawnEntityInWorld(new EntityItem(world, player.posX, player.posY, player.posZ, stack))
|
||||
world.spawnEntityInWorld(
|
||||
new EntityItem(world, player.posX, player.posY, player.posZ, stack)
|
||||
)
|
||||
}
|
||||
|
||||
def isSameItem(stack1: ItemStack, stack2: ItemStack): Boolean = {
|
||||
@@ -47,13 +49,28 @@ object ItemUtils {
|
||||
return ItemStack.areItemStackTagsEqual(stack2, stack1)
|
||||
}
|
||||
|
||||
def addStackToSlots(stack: ItemStack, inv: IInventory, slots: Iterable[Int], checkValid: Boolean): ItemStack = {
|
||||
def addStackToSlots(
|
||||
stack: ItemStack,
|
||||
inv: IInventory,
|
||||
slots: Iterable[Int],
|
||||
checkValid: Boolean
|
||||
): ItemStack = {
|
||||
if (stack == null) return null
|
||||
|
||||
// Try merging into existing slots
|
||||
for (slot <- slots if (!checkValid || inv.isItemValidForSlot(slot, stack)) && isSameItem(stack, inv.getStackInSlot(slot))) {
|
||||
for (
|
||||
slot <- slots
|
||||
if (!checkValid || inv.isItemValidForSlot(slot, stack)) && isSameItem(
|
||||
stack,
|
||||
inv.getStackInSlot(slot)
|
||||
)
|
||||
) {
|
||||
val target = inv.getStackInSlot(slot)
|
||||
val toAdd = Misc.min(target.getMaxStackSize - target.stackSize, inv.getInventoryStackLimit - target.stackSize, stack.stackSize)
|
||||
val toAdd = Misc.min(
|
||||
target.getMaxStackSize - target.stackSize,
|
||||
inv.getInventoryStackLimit - target.stackSize,
|
||||
stack.stackSize
|
||||
)
|
||||
if (toAdd >= stack.stackSize) {
|
||||
target.stackSize += stack.stackSize
|
||||
stack.stackSize = 0
|
||||
@@ -67,9 +84,16 @@ object ItemUtils {
|
||||
}
|
||||
|
||||
// Now find empty slots and stick any leftovers there
|
||||
for (slot <- slots if (!checkValid || inv.isItemValidForSlot(slot, stack)) && inv.getStackInSlot(slot) == null) {
|
||||
for (
|
||||
slot <- slots
|
||||
if (!checkValid || inv.isItemValidForSlot(slot, stack)) && inv
|
||||
.getStackInSlot(slot) == null
|
||||
) {
|
||||
if (inv.getInventoryStackLimit < stack.stackSize) {
|
||||
inv.setInventorySlotContents(slot, stack.splitStack(inv.getInventoryStackLimit))
|
||||
inv.setInventorySlotContents(
|
||||
slot,
|
||||
stack.splitStack(inv.getInventoryStackLimit)
|
||||
)
|
||||
} else {
|
||||
inv.setInventorySlotContents(slot, stack.copy())
|
||||
stack.stackSize = 0
|
||||
@@ -86,7 +110,8 @@ object ItemUtils {
|
||||
getOrElse (0 until inv.getSizeInventory))
|
||||
|
||||
def findItemInInventory(inv: IInventory, item: Item) =
|
||||
Range(0, inv.getSizeInventory).map(x => x -> inv.getStackInSlot(x))
|
||||
Range(0, inv.getSizeInventory)
|
||||
.map(x => x -> inv.getStackInSlot(x))
|
||||
.find({ case (slot, stack) => stack != null && stack.getItem == item })
|
||||
.map({ case (slot, stack) => slot })
|
||||
|
||||
@@ -102,4 +127,4 @@ object ItemUtils {
|
||||
newSize
|
||||
newStack
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,8 +14,14 @@ import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.Slot
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
class ContainerItemInventory(inv: InventoryItemAdapter, player: EntityPlayer) extends BaseContainer(inv) {
|
||||
override def slotClick(slotNum: Int, button: Int, modifiers: Int, player: EntityPlayer): ItemStack = {
|
||||
class ContainerItemInventory(inv: InventoryItemAdapter, player: EntityPlayer)
|
||||
extends BaseContainer(inv) {
|
||||
override def slotClick(
|
||||
slotNum: Int,
|
||||
button: Int,
|
||||
modifiers: Int,
|
||||
player: EntityPlayer
|
||||
): ItemStack = {
|
||||
if (slotNum > 0 && slotNum < inventorySlots.size()) {
|
||||
val slot = inventorySlots.asInstanceOf[java.util.List[Slot]].get(slotNum)
|
||||
if (slot.isSlotInInventory(inv.player.inventory, inv.slot))
|
||||
|
||||
@@ -14,7 +14,12 @@ import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
|
||||
|
||||
class InventoryItemAdapter(val player: EntityPlayer, val slot: Int, val size: Int, val tagName: String) extends BaseInventory {
|
||||
class InventoryItemAdapter(
|
||||
val player: EntityPlayer,
|
||||
val slot: Int,
|
||||
val size: Int,
|
||||
val tagName: String
|
||||
) extends BaseInventory {
|
||||
def getSizeInventory = size
|
||||
def getStack = player.inventory.getStackInSlot(slot)
|
||||
|
||||
|
||||
@@ -17,10 +17,9 @@ import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.Item
|
||||
import net.minecraft.world.World
|
||||
|
||||
/**
|
||||
* Mixin for items that have an internal inventory
|
||||
* Subclasses are responsible for registering themselves with the GuiHandler of their mod
|
||||
*/
|
||||
/** Mixin for items that have an internal inventory Subclasses are responsible
|
||||
* for registering themselves with the GuiHandler of their mod
|
||||
*/
|
||||
trait ItemInventory extends Item with GuiProvider {
|
||||
type TEClass = Any
|
||||
def guiId: Int
|
||||
@@ -30,9 +29,17 @@ trait ItemInventory extends Item with GuiProvider {
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
def makeGui(inv: InventoryItemAdapter, player: EntityPlayer): AnyRef
|
||||
def makeContainer(inv: InventoryItemAdapter, player: EntityPlayer): ContainerItemInventory
|
||||
def makeContainer(
|
||||
inv: InventoryItemAdapter,
|
||||
player: EntityPlayer
|
||||
): ContainerItemInventory
|
||||
|
||||
def makeAdaptor(player: EntityPlayer) = new InventoryItemAdapter(player, player.inventory.currentItem, invSize, invTagName)
|
||||
def makeAdaptor(player: EntityPlayer) = new InventoryItemAdapter(
|
||||
player,
|
||||
player.inventory.currentItem,
|
||||
invSize,
|
||||
invTagName
|
||||
)
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
def getGui(te: TEClass, player: EntityPlayer) = {
|
||||
@@ -40,7 +47,10 @@ trait ItemInventory extends Item with GuiProvider {
|
||||
if (stack.getItem == this) {
|
||||
makeGui(makeAdaptor(player), player)
|
||||
} else {
|
||||
BdLib.logWarn("Attempt to open item container GUI without active item (%s)", this)
|
||||
BdLib.logWarn(
|
||||
"Attempt to open item container GUI without active item (%s)",
|
||||
this
|
||||
)
|
||||
null
|
||||
}
|
||||
}
|
||||
@@ -50,12 +60,23 @@ trait ItemInventory extends Item with GuiProvider {
|
||||
if (stack.getItem == this) {
|
||||
makeContainer(makeAdaptor(player), player)
|
||||
} else {
|
||||
BdLib.logWarn("Attempt to open item container GUI without active item by '%s' (%s)", player.getCommandSenderName, this)
|
||||
BdLib.logWarn(
|
||||
"Attempt to open item container GUI without active item by '%s' (%s)",
|
||||
player.getCommandSenderName,
|
||||
this
|
||||
)
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
def doOpenGui(player: EntityPlayer, world: World) {
|
||||
player.openGui(modObj, guiId, world, player.posX.toInt, player.posY.toInt, player.posZ.toInt)
|
||||
player.openGui(
|
||||
modObj,
|
||||
guiId,
|
||||
world,
|
||||
player.posX.toInt,
|
||||
player.posY.toInt,
|
||||
player.posZ.toInt
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -26,16 +26,20 @@ abstract class Machine[T <: Block](val name: String, blockConstruct: => T) {
|
||||
def regBlock(creativeTab: CreativeTabs) {
|
||||
block = blockConstruct
|
||||
|
||||
val itemClass: Class[_ <: ItemBlock] = if (block.isInstanceOf[HasItemBlock])
|
||||
block.asInstanceOf[HasItemBlock].ItemBlockClass
|
||||
else
|
||||
classOf[ItemBlock]
|
||||
val itemClass: Class[_ <: ItemBlock] =
|
||||
if (block.isInstanceOf[HasItemBlock])
|
||||
block.asInstanceOf[HasItemBlock].ItemBlockClass
|
||||
else
|
||||
classOf[ItemBlock]
|
||||
|
||||
GameRegistry.registerBlock(block, itemClass, name)
|
||||
|
||||
block.setCreativeTab(creativeTab)
|
||||
if (block.isInstanceOf[HasTE[_]]) {
|
||||
GameRegistry.registerTileEntity(block.asInstanceOf[HasTE[_]].TEClass, "%s.%s".format(modId, name))
|
||||
GameRegistry.registerTileEntity(
|
||||
block.asInstanceOf[HasTE[_]].TEClass,
|
||||
"%s.%s".format(modId, name)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,10 +19,17 @@ trait MachineCore extends {
|
||||
|
||||
def getController: BlockController[_] = block
|
||||
|
||||
def cfgSectionToMap(name: String) = tuning.getSection(name).map({
|
||||
case (n, EntryDouble(v)) => n -> v.toInt
|
||||
case (n, x) => sys.error("Invalid config value in section %s%s.%s = %s".format(tuning.pfx, name, n, x))
|
||||
}).toMap
|
||||
def cfgSectionToMap(name: String) = tuning
|
||||
.getSection(name)
|
||||
.map({
|
||||
case (n, EntryDouble(v)) => n -> v.toInt
|
||||
case (n, x) =>
|
||||
sys.error(
|
||||
"Invalid config value in section %s%s.%s = %s"
|
||||
.format(tuning.pfx, name, n, x)
|
||||
)
|
||||
})
|
||||
.toMap
|
||||
|
||||
lazy val modules = cfgSectionToMap("Modules")
|
||||
lazy val required = cfgSectionToMap("Required")
|
||||
|
||||
@@ -24,13 +24,18 @@ object Tools {
|
||||
def findConnections(world: World, start: BlockRef, kind: String) =
|
||||
(start.neighbours.values flatMap { case pos =>
|
||||
(pos.tile(world) flatMap {
|
||||
case t: TileModule => t.connected.value
|
||||
case t: TileModule => t.connected.value
|
||||
case t: TileController => Some(pos)
|
||||
case _ => None
|
||||
case _ => None
|
||||
}) filter (x => canConnect(world, x, kind))
|
||||
}).toList.distinct
|
||||
|
||||
def getConnectedNeighbours(w: World, core: BlockRef, pos: BlockRef, seen: mutable.Set[BlockRef]) =
|
||||
def getConnectedNeighbours(
|
||||
w: World,
|
||||
core: BlockRef,
|
||||
pos: BlockRef,
|
||||
seen: mutable.Set[BlockRef]
|
||||
) =
|
||||
pos.neighbours.values
|
||||
.filterNot(seen.contains)
|
||||
.flatMap(_.getTile[TileModule](w))
|
||||
|
||||
@@ -21,8 +21,14 @@ import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.EnumChatFormatting
|
||||
import net.minecraft.world.{IBlockAccess, World}
|
||||
|
||||
abstract class BlockController[T <: TileController](val name: String, material: Material, val TEClass: Class[T])
|
||||
extends Block(material) with HasTE[T] with ConnectedTextureBlock with BlockTooltip {
|
||||
abstract class BlockController[T <: TileController](
|
||||
val name: String,
|
||||
material: Material,
|
||||
val TEClass: Class[T]
|
||||
) extends Block(material)
|
||||
with HasTE[T]
|
||||
with ConnectedTextureBlock
|
||||
with BlockTooltip {
|
||||
|
||||
var machine: MachineCore = null
|
||||
|
||||
@@ -30,37 +36,67 @@ abstract class BlockController[T <: TileController](val name: String, material:
|
||||
|
||||
override def edgeIcon = resources.edge
|
||||
|
||||
override def breakBlock(world: World, x: Int, y: Int, z: Int, block: Block, meta: Int) {
|
||||
override def breakBlock(
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
block: Block,
|
||||
meta: Int
|
||||
) {
|
||||
getTE(world, x, y, z).onBreak()
|
||||
super.breakBlock(world, x, y, z, block, meta)
|
||||
}
|
||||
|
||||
override def canConnect(world: IBlockAccess, origin: BlockRef, target: BlockRef) =
|
||||
override def canConnect(
|
||||
world: IBlockAccess,
|
||||
origin: BlockRef,
|
||||
target: BlockRef
|
||||
) =
|
||||
getTE(world, origin).modules.contains(target)
|
||||
|
||||
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, meta: Int, xOffs: Float, yOffs: Float, zOffs: Float): Boolean = {
|
||||
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
|
||||
getTE(world, x, y, z).onClick(player)
|
||||
return true
|
||||
}
|
||||
|
||||
override def getTooltip(stack: ItemStack, player: EntityPlayer, advanced: Boolean): List[String] = {
|
||||
List(Misc.toLocal("bdlib.multiblock.tip.controller")) ++ (
|
||||
for ((kind, max) <- machine.modules) yield {
|
||||
val name = Misc.toLocalF(resources.getModuleName(kind))
|
||||
if (machine.required.getOrElse(kind, 0) > 0) {
|
||||
Misc.toLocalF("bdlib.multiblock.tip.module.range",
|
||||
EnumChatFormatting.YELLOW + name + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + machine.required(kind).toString + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + max.toString + EnumChatFormatting.RESET)
|
||||
} else {
|
||||
Misc.toLocalF("bdlib.multiblock.tip.module.max",
|
||||
EnumChatFormatting.YELLOW + name + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + max.toString + EnumChatFormatting.RESET)
|
||||
}
|
||||
})
|
||||
override def getTooltip(
|
||||
stack: ItemStack,
|
||||
player: EntityPlayer,
|
||||
advanced: Boolean
|
||||
): List[String] = {
|
||||
List(Misc.toLocal("bdlib.multiblock.tip.controller")) ++ (for (
|
||||
(kind, max) <- machine.modules
|
||||
) yield {
|
||||
val name = Misc.toLocalF(resources.getModuleName(kind))
|
||||
if (machine.required.getOrElse(kind, 0) > 0) {
|
||||
Misc.toLocalF(
|
||||
"bdlib.multiblock.tip.module.range",
|
||||
EnumChatFormatting.YELLOW + name + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + machine
|
||||
.required(kind)
|
||||
.toString + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + max.toString + EnumChatFormatting.RESET
|
||||
)
|
||||
} else {
|
||||
Misc.toLocalF(
|
||||
"bdlib.multiblock.tip.module.max",
|
||||
EnumChatFormatting.YELLOW + name + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + max.toString + EnumChatFormatting.RESET
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,16 @@ import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.{ChatComponentTranslation, EnumChatFormatting}
|
||||
import net.minecraft.world.{IBlockAccess, World}
|
||||
|
||||
abstract class BlockModule[T <: TileModule](val name: String, val kind: String, material: Material, val TEClass: Class[T], val machines: MachineManagerMultiblock)
|
||||
extends Block(material) with HasTE[T] with ConnectedTextureBlock with BlockTooltip {
|
||||
abstract class BlockModule[T <: TileModule](
|
||||
val name: String,
|
||||
val kind: String,
|
||||
material: Material,
|
||||
val TEClass: Class[T],
|
||||
val machines: MachineManagerMultiblock
|
||||
) extends Block(material)
|
||||
with HasTE[T]
|
||||
with ConnectedTextureBlock
|
||||
with BlockTooltip {
|
||||
|
||||
def resources: ResourceProvider
|
||||
|
||||
@@ -33,28 +41,62 @@ abstract class BlockModule[T <: TileModule](val name: String, val kind: String,
|
||||
override def canPlaceBlockAt(world: World, x: Int, y: Int, z: Int): Boolean =
|
||||
Tools.findConnections(world, BlockRef(x, y, z), kind).size <= 1
|
||||
|
||||
override def onBlockPlacedBy(world: World, x: Int, y: Int, z: Int, player: EntityLivingBase, stack: ItemStack) {
|
||||
override def onBlockPlacedBy(
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
player: EntityLivingBase,
|
||||
stack: ItemStack
|
||||
) {
|
||||
getTE(world, x, y, z).tryConnect()
|
||||
}
|
||||
|
||||
override def onNeighborBlockChange(world: World, x: Int, y: Int, z: Int, block: Block) {
|
||||
override def onNeighborBlockChange(
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
block: Block
|
||||
) {
|
||||
getTE(world, x, y, z).tryConnect()
|
||||
}
|
||||
|
||||
override def breakBlock(world: World, x: Int, y: Int, z: Int, block: Block, meta: Int) {
|
||||
override def breakBlock(
|
||||
world: World,
|
||||
x: Int,
|
||||
y: Int,
|
||||
z: Int,
|
||||
block: Block,
|
||||
meta: Int
|
||||
) {
|
||||
getTE(world, x, y, z).onBreak()
|
||||
super.breakBlock(world, x, y, z, block, meta)
|
||||
}
|
||||
|
||||
override def canConnect(world: IBlockAccess, origin: BlockRef, target: BlockRef) = {
|
||||
override def canConnect(
|
||||
world: IBlockAccess,
|
||||
origin: BlockRef,
|
||||
target: BlockRef
|
||||
) = {
|
||||
val me = getTE(world, origin)
|
||||
me.connected.contains(target) ||
|
||||
(target.getTile[TileModule](world) exists { other =>
|
||||
me.getCore.isDefined && other.getCore == me.getCore
|
||||
})
|
||||
(target.getTile[TileModule](world) exists { other =>
|
||||
me.getCore.isDefined && other.getCore == me.getCore
|
||||
})
|
||||
}
|
||||
|
||||
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, meta: Int, xOffs: Float, yOffs: Float, zOffs: Float): Boolean = {
|
||||
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)
|
||||
@@ -62,27 +104,38 @@ abstract class BlockModule[T <: TileModule](val name: String, val kind: String,
|
||||
p <- te.connected.value
|
||||
bl <- p.block(world)
|
||||
} yield {
|
||||
bl.onBlockActivated(world, p.x, p.y, p.z, player, meta, 0, 0, 0)
|
||||
}) getOrElse {
|
||||
player.addChatMessage(new ChatComponentTranslation("bdlib.multiblock.notconnected"))
|
||||
bl.onBlockActivated(world, p.x, p.y, p.z, player, meta, 0, 0, 0)
|
||||
}) getOrElse {
|
||||
player.addChatMessage(
|
||||
new ChatComponentTranslation("bdlib.multiblock.notconnected")
|
||||
)
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
override def getTooltip(stack: ItemStack, player: EntityPlayer, advanced: Boolean): List[String] = {
|
||||
List(Misc.toLocal("bdlib.multiblock.tip.module")) ++ (
|
||||
for ((machine, (min, max)) <- machines.getMachinesForBlock(this)) yield {
|
||||
val name = machine.getController.getLocalizedName
|
||||
if (min > 0) {
|
||||
Misc.toLocalF("bdlib.multiblock.tip.module.range",
|
||||
EnumChatFormatting.YELLOW + name + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + min.toString + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + max.toString + EnumChatFormatting.RESET)
|
||||
} else {
|
||||
Misc.toLocalF("bdlib.multiblock.tip.module.max",
|
||||
EnumChatFormatting.YELLOW + name + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + max.toString + EnumChatFormatting.RESET)
|
||||
}
|
||||
})
|
||||
override def getTooltip(
|
||||
stack: ItemStack,
|
||||
player: EntityPlayer,
|
||||
advanced: Boolean
|
||||
): List[String] = {
|
||||
List(Misc.toLocal("bdlib.multiblock.tip.module")) ++ (for (
|
||||
(machine, (min, max)) <- machines.getMachinesForBlock(this)
|
||||
) yield {
|
||||
val name = machine.getController.getLocalizedName
|
||||
if (min > 0) {
|
||||
Misc.toLocalF(
|
||||
"bdlib.multiblock.tip.module.range",
|
||||
EnumChatFormatting.YELLOW + name + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + min.toString + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + max.toString + EnumChatFormatting.RESET
|
||||
)
|
||||
} else {
|
||||
Misc.toLocalF(
|
||||
"bdlib.multiblock.tip.module.max",
|
||||
EnumChatFormatting.YELLOW + name + EnumChatFormatting.RESET,
|
||||
EnumChatFormatting.YELLOW + max.toString + EnumChatFormatting.RESET
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -11,11 +11,17 @@ package net.bdew.lib.multiblock.block
|
||||
|
||||
import net.bdew.lib.block.{BlockFace, BlockRef}
|
||||
import net.bdew.lib.multiblock.tile.TileOutput
|
||||
import net.bdew.lib.render.connected.{BlockAdditionalRender, ConnectedHelper, FaceOverlay}
|
||||
import net.bdew.lib.render.connected.{
|
||||
BlockAdditionalRender,
|
||||
ConnectedHelper,
|
||||
FaceOverlay
|
||||
}
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
trait BlockOutput[T <: TileOutput[_]] extends BlockModule[T] with BlockAdditionalRender {
|
||||
trait BlockOutput[T <: TileOutput[_]]
|
||||
extends BlockModule[T]
|
||||
with BlockAdditionalRender {
|
||||
def getNeighbourFaces(face: ForgeDirection, bp: BlockRef) = {
|
||||
val sides = ConnectedHelper.neighbourFaces(face)
|
||||
Seq(
|
||||
@@ -26,15 +32,27 @@ trait BlockOutput[T <: TileOutput[_]] extends BlockModule[T] with BlockAdditiona
|
||||
)
|
||||
}
|
||||
|
||||
def getFaceOverlays(world: IBlockAccess, x: Int, y: Int, z: Int, face: ForgeDirection): List[FaceOverlay] = {
|
||||
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) foreach { core =>
|
||||
val bf = BlockFace(x, y, z, face)
|
||||
if (core.outputFaces.contains(bf))
|
||||
result :+= FaceOverlay(resources.output, resources.outputColors(core.outputFaces(bf)))
|
||||
result :+= FaceOverlay(
|
||||
resources.output,
|
||||
resources.outputColors(core.outputFaces(bf))
|
||||
)
|
||||
for ((bf, icon) <- getNeighbourFaces(face, bf.origin)) {
|
||||
if (core.outputFaces.contains(bf))
|
||||
result :+= FaceOverlay(icon, resources.outputColors(core.outputFaces(bf)))
|
||||
result :+= FaceOverlay(
|
||||
icon,
|
||||
resources.outputColors(core.outputFaces(bf))
|
||||
)
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
||||
@@ -16,15 +16,18 @@ import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
case class DataSlotBlockFaceMap(name: String, parent: DataSlotContainer) extends DataSlot {
|
||||
case class DataSlotBlockFaceMap(name: String, parent: DataSlotContainer)
|
||||
extends DataSlot {
|
||||
val map = collection.mutable.Map.empty[BlockFace, Int]
|
||||
|
||||
setUpdate(UpdateKind.SAVE, UpdateKind.WORLD)
|
||||
|
||||
def inverted = map.map(_.swap)
|
||||
|
||||
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)
|
||||
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._
|
||||
|
||||
@@ -44,5 +47,7 @@ object DataSlotBlockFaceMap {
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
implicit def dataSlotBlockFaceMap2map(v: DataSlotBlockFaceMap): mutable.Map[BlockFace, Int] = v.map
|
||||
implicit def dataSlotBlockFaceMap2map(
|
||||
v: DataSlotBlockFaceMap
|
||||
): mutable.Map[BlockFace, Int] = v.map
|
||||
}
|
||||
@@ -14,7 +14,11 @@ import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
case class DataSlotOutputConfig(name: String, parent: DataSlotContainer, 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)
|
||||
@@ -49,5 +53,7 @@ object DataSlotOutputConfig {
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
implicit def dataSlotOutputConfig2map(v: DataSlotOutputConfig): mutable.Map[Int, OutputConfig] = v.map
|
||||
implicit def dataSlotOutputConfig2map(
|
||||
v: DataSlotOutputConfig
|
||||
): mutable.Map[Int, OutputConfig] = v.map
|
||||
}
|
||||
@@ -15,17 +15,21 @@ import net.bdew.lib.data.DataSlotOption
|
||||
import net.bdew.lib.data.base.{DataSlotContainer, UpdateKind}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
case class DataSlotPos(name: String, parent: DataSlotContainer) 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 foreach (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) {
|
||||
value = if (t.hasKey(name))
|
||||
Some(BlockRef.fromNBT(t.getCompoundTag(name)))
|
||||
else
|
||||
None
|
||||
value =
|
||||
if (t.hasKey(name))
|
||||
Some(BlockRef.fromNBT(t.getCompoundTag(name)))
|
||||
else
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,8 @@ import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
case class DataSlotPosSet(name: String, parent: DataSlotContainer) extends DataSlot {
|
||||
case class DataSlotPosSet(name: String, parent: DataSlotContainer)
|
||||
extends DataSlot {
|
||||
val set = collection.mutable.Set.empty[BlockRef]
|
||||
|
||||
setUpdate(UpdateKind.SAVE, UpdateKind.WORLD)
|
||||
@@ -24,7 +25,10 @@ case class DataSlotPosSet(name: String, parent: DataSlotContainer) extends DataS
|
||||
import net.bdew.lib.nbt._
|
||||
|
||||
def save(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
t.setList(name, set.map(x => Misc.applyMutator(x.writeToNBT, new NBTTagCompound)))
|
||||
t.setList(
|
||||
name,
|
||||
set.map(x => Misc.applyMutator(x.writeToNBT, new NBTTagCompound))
|
||||
)
|
||||
}
|
||||
|
||||
def load(t: NBTTagCompound, kind: UpdateKind.Value) {
|
||||
@@ -39,5 +43,6 @@ object DataSlotPosSet {
|
||||
|
||||
import scala.language.implicitConversions
|
||||
|
||||
implicit def dataSlotPosSet2set(v: DataSlotPosSet): mutable.Set[BlockRef] = v.set
|
||||
implicit def dataSlotPosSet2set(v: DataSlotPosSet): mutable.Set[BlockRef] =
|
||||
v.set
|
||||
}
|
||||
@@ -30,8 +30,9 @@ class OutputConfigInvalid extends OutputConfig {
|
||||
object OutputConfigManager {
|
||||
var loaders = Map.empty[String, () => OutputConfig]
|
||||
def register(id: String, loader: () => OutputConfig) = loaders += id -> loader
|
||||
def create(id: String) = loaders.get(id).map(_.apply()).getOrElse(new OutputConfigInvalid)
|
||||
def create(id: String) =
|
||||
loaders.get(id).map(_.apply()).getOrElse(new OutputConfigInvalid)
|
||||
|
||||
register("fluid", () => new OutputConfigFluid)
|
||||
register("power", () => new OutputConfigPower)
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,7 @@ class OutputConfigFluid extends OutputConfig with OutputConfigRSControllable {
|
||||
|
||||
def handleConfigPacket(m: MsgOutputCfg) = m match {
|
||||
case MsgOutputCfgRSMode(_, r) => rsMode = r
|
||||
case _ => sys.error("Invalid output config packet %s to config %s".format(m, this))
|
||||
case _ =>
|
||||
sys.error("Invalid output config packet %s to config %s".format(m, this))
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,9 @@ trait OutputConfigSlots {
|
||||
var slot = slotsDef.default
|
||||
}
|
||||
|
||||
class OutputConfigFluidSlots(val slotsDef: SlotSet) extends OutputConfigFluid with OutputConfigSlots {
|
||||
class OutputConfigFluidSlots(val slotsDef: SlotSet)
|
||||
extends OutputConfigFluid
|
||||
with OutputConfigSlots {
|
||||
override def id = slotsDef.outputConfigId
|
||||
override def read(t: NBTTagCompound) {
|
||||
super.read(t)
|
||||
@@ -29,6 +31,6 @@ class OutputConfigFluidSlots(val slotsDef: SlotSet) extends OutputConfigFluid wi
|
||||
}
|
||||
override def handleConfigPacket(m: MsgOutputCfg) = m match {
|
||||
case MsgOutputCfgSlot(n, id) => slot = slotsDef.get(id)
|
||||
case _ => super.handleConfigPacket(m)
|
||||
case _ => super.handleConfigPacket(m)
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,8 @@ class OutputConfigItems extends OutputConfig with OutputConfigRSControllable {
|
||||
|
||||
def handleConfigPacket(m: MsgOutputCfg) = m match {
|
||||
case MsgOutputCfgRSMode(_, r) => rsMode = r
|
||||
case _ => sys.error("Invalid output config packet %s to config %s".format(m, this))
|
||||
case _ =>
|
||||
sys.error("Invalid output config packet %s to config %s".format(m, this))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,7 +12,9 @@ package net.bdew.lib.multiblock.data
|
||||
import net.bdew.lib.multiblock.network.MsgOutputCfg
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class OutputConfigPower(var unit: String = "MJ") extends OutputConfig with OutputConfigRSControllable {
|
||||
class OutputConfigPower(var unit: String = "MJ")
|
||||
extends OutputConfig
|
||||
with OutputConfigRSControllable {
|
||||
override val id = "power"
|
||||
var avg = 0.0
|
||||
var rsMode = RSMode.ALWAYS
|
||||
@@ -37,6 +39,7 @@ class OutputConfigPower(var unit: String = "MJ") extends OutputConfig with Outpu
|
||||
|
||||
def handleConfigPacket(m: MsgOutputCfg) = m match {
|
||||
case MsgOutputCfgRSMode(_, r) => rsMode = r
|
||||
case _ => sys.error("Invalid output config packet %s to config %s".format(m, this))
|
||||
case _ =>
|
||||
sys.error("Invalid output config packet %s to config %s".format(m, this))
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,9 @@ package net.bdew.lib.multiblock.data
|
||||
|
||||
import net.bdew.lib.multiblock.network.MsgOutputCfg
|
||||
|
||||
case class MsgOutputCfgRSMode(output: Int, rsMode: RSMode.Value) extends MsgOutputCfg
|
||||
case class MsgOutputCfgRSMode(output: Int, rsMode: RSMode.Value)
|
||||
extends MsgOutputCfg
|
||||
|
||||
trait OutputConfigRSControllable extends OutputConfig {
|
||||
var rsMode: RSMode.Value
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,12 @@ import net.bdew.lib.gui.{Color, Point, Rect, Texture}
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class WidgetInfoMulti(val rect: Rect, icon: Texture, text: => String, tooltip: => List[String]) extends Widget {
|
||||
class WidgetInfoMulti(
|
||||
val rect: Rect,
|
||||
icon: Texture,
|
||||
text: => String,
|
||||
tooltip: => List[String]
|
||||
) extends Widget {
|
||||
final val iconRect = Rect(1, 1, 8, 8)
|
||||
|
||||
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
|
||||
@@ -23,8 +28,9 @@ class WidgetInfoMulti(val rect: Rect, icon: Texture, text: => String, tooltip: =
|
||||
|
||||
override def draw(mouse: Point) {
|
||||
parent.drawTexture(iconRect + rect.origin, icon)
|
||||
parent.drawText(text, rect.origin +(12, 1), Color.darkGray, false)
|
||||
parent.drawText(text, rect.origin + (12, 1), Color.darkGray, false)
|
||||
}
|
||||
}
|
||||
|
||||
class WidgetInfo(rect: Rect, icon: Texture, text: => String, tooltip: => String) extends WidgetInfoMulti(rect, icon, text, List(tooltip))
|
||||
class WidgetInfo(rect: Rect, icon: Texture, text: => String, tooltip: => String)
|
||||
extends WidgetInfoMulti(rect, icon, text, List(tooltip))
|
||||
@@ -19,7 +19,8 @@ import net.bdew.lib.render.connected.BlockAdditionalRender
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class WidgetOutputIcon(p: Point, te: CIOutputFaces, output: Int) extends Widget {
|
||||
class WidgetOutputIcon(p: Point, te: CIOutputFaces, output: Int)
|
||||
extends Widget {
|
||||
val rect = new Rect(p, 16, 16)
|
||||
|
||||
override def draw(mouse: Point) {
|
||||
@@ -27,14 +28,44 @@ class WidgetOutputIcon(p: Point, te: CIOutputFaces, output: Int) extends Widget
|
||||
if (faces.isDefinedAt(output)) {
|
||||
val bf = faces(output)
|
||||
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())))
|
||||
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))
|
||||
parent.drawTexture(rect, Texture(Texture.BLOCKS, over.icon), over.color)
|
||||
for (
|
||||
over <- block
|
||||
.asInstanceOf[BlockAdditionalRender]
|
||||
.getFaceOverlays(
|
||||
te.getWorldObj,
|
||||
bf.origin.x,
|
||||
bf.origin.y,
|
||||
bf.origin.z,
|
||||
bf.face
|
||||
)
|
||||
)
|
||||
parent.drawTexture(
|
||||
rect,
|
||||
Texture(Texture.BLOCKS, over.icon),
|
||||
over.color
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
parent.drawTexture(rect, Texture(Texture.BLOCKS, te.resources.disabled), te.resources.outputColors(output))
|
||||
parent.drawTexture(
|
||||
rect,
|
||||
Texture(Texture.BLOCKS, te.resources.disabled),
|
||||
te.resources.outputColors(output)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +76,14 @@ class WidgetOutputIcon(p: Point, te: CIOutputFaces, output: Int) extends Widget
|
||||
val bf = faces(output)
|
||||
bf.origin.block(te.getWorldObj) map { block =>
|
||||
tip += block.getLocalizedName
|
||||
tip += "%d, %d, %d - %s".format(bf.x, bf.y, bf.z, Misc.toLocal("bdlib.multiblock.face." + bf.face.toString.toLowerCase(Locale.US)))
|
||||
tip += "%d, %d, %d - %s".format(
|
||||
bf.x,
|
||||
bf.y,
|
||||
bf.z,
|
||||
Misc.toLocal(
|
||||
"bdlib.multiblock.face." + bf.face.toString.toLowerCase(Locale.US)
|
||||
)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
tip += Misc.toLocal("bdlib.multiblock.disabled")
|
||||
|
||||
@@ -14,14 +14,26 @@ import java.util.Locale
|
||||
import net.bdew.lib.Misc
|
||||
import net.bdew.lib.gui.widgets.{WidgetButtonIcon, WidgetSubContainer}
|
||||
import net.bdew.lib.gui.{Point, Rect}
|
||||
import net.bdew.lib.multiblock.data.{MsgOutputCfgRSMode, OutputConfigRSControllable, RSMode}
|
||||
import net.bdew.lib.multiblock.data.{
|
||||
MsgOutputCfgRSMode,
|
||||
OutputConfigRSControllable,
|
||||
RSMode
|
||||
}
|
||||
import net.bdew.lib.multiblock.interact.CIOutputFaces
|
||||
import net.bdew.lib.multiblock.network.NetHandler
|
||||
|
||||
class WidgetRSConfig(te: CIOutputFaces, output: Int, p: Point) extends WidgetSubContainer(new Rect(p, 16, 16)) {
|
||||
class WidgetRSConfig(te: CIOutputFaces, output: Int, p: Point)
|
||||
extends WidgetSubContainer(new Rect(p, 16, 16)) {
|
||||
def cfg = te.outputConfig(output).asInstanceOf[OutputConfigRSControllable]
|
||||
|
||||
val bt = add(new WidgetButtonIcon(Point(0, 0), clicked, te.resources.btBase, te.resources.btHover))
|
||||
val bt = add(
|
||||
new WidgetButtonIcon(
|
||||
Point(0, 0),
|
||||
clicked,
|
||||
te.resources.btBase,
|
||||
te.resources.btHover
|
||||
)
|
||||
)
|
||||
|
||||
val icons = Map(
|
||||
RSMode.ALWAYS -> te.resources.btEnabled,
|
||||
@@ -39,7 +51,8 @@ class WidgetRSConfig(te: CIOutputFaces, output: Int, p: Point) extends WidgetSub
|
||||
|
||||
override def draw(mouse: Point) {
|
||||
bt.icon = icons(cfg.rsMode)
|
||||
bt.hover = Misc.toLocal("bdlib.rsmode." + cfg.rsMode.toString.toLowerCase(Locale.US))
|
||||
bt.hover =
|
||||
Misc.toLocal("bdlib.rsmode." + cfg.rsMode.toString.toLowerCase(Locale.US))
|
||||
super.draw(mouse)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,9 +14,16 @@ import net.minecraftforge.fluids.{Fluid, FluidStack, FluidTankInfo}
|
||||
|
||||
trait CIFluidOutputSelect extends CIOutputFaces {
|
||||
val outputSlotsDef: SlotSet
|
||||
def outputFluid(slot: outputSlotsDef.Slot, resource: FluidStack, doDrain: Boolean): FluidStack
|
||||
def outputFluid(slot: outputSlotsDef.Slot, amount: Int, doDrain: Boolean): FluidStack
|
||||
def outputFluid(
|
||||
slot: outputSlotsDef.Slot,
|
||||
resource: FluidStack,
|
||||
doDrain: Boolean
|
||||
): FluidStack
|
||||
def outputFluid(
|
||||
slot: outputSlotsDef.Slot,
|
||||
amount: Int,
|
||||
doDrain: Boolean
|
||||
): FluidStack
|
||||
def canOutputFluid(slot: outputSlotsDef.Slot, fluid: Fluid): Boolean
|
||||
def getTankInfo: Array[FluidTankInfo]
|
||||
}
|
||||
|
||||
@@ -35,7 +35,10 @@ trait CIOutputFaces extends TileController {
|
||||
return i
|
||||
}
|
||||
val pl = getWorldObj.getClosestPlayer(bf.x, bf.y, bf.z, 10)
|
||||
if (pl != null) pl.addChatMessage(new ChatComponentTranslation("bdlib.multiblock.toomanyoutputs"))
|
||||
if (pl != null)
|
||||
pl.addChatMessage(
|
||||
new ChatComponentTranslation("bdlib.multiblock.toomanyoutputs")
|
||||
)
|
||||
return -1
|
||||
}
|
||||
|
||||
@@ -56,7 +59,10 @@ trait CIOutputFaces extends TileController {
|
||||
(x, n) <- outputFaces
|
||||
t <- x.origin.getTile[MIOutput[_]](getWorldObj)
|
||||
} {
|
||||
if (!outputConfig.isDefinedAt(n) || !t.outputConfigType.isInstance(outputConfig(n)))
|
||||
if (
|
||||
!outputConfig
|
||||
.isDefinedAt(n) || !t.outputConfigType.isInstance(outputConfig(n))
|
||||
)
|
||||
outputConfig(n) = t.makeCfgObject(x.face)
|
||||
t.doOutput(x.face, outputConfig(n).asInstanceOf[t.OCType])
|
||||
}
|
||||
|
||||
@@ -14,10 +14,9 @@ import net.bdew.lib.network.NetChannel
|
||||
import net.minecraft.entity.player.EntityPlayerMP
|
||||
|
||||
object NetHandler extends NetChannel("bdew.multiblock") {
|
||||
regServerHandler {
|
||||
case (msg: MsgOutputCfg, p: EntityPlayerMP) =>
|
||||
val te = p.openContainer.asInstanceOf[ContainerOutputFaces].te
|
||||
te.outputConfig(msg.output).handleConfigPacket(msg)
|
||||
te.outputConfig.updated()
|
||||
regServerHandler { case (msg: MsgOutputCfg, p: EntityPlayerMP) =>
|
||||
val te = p.openContainer.asInstanceOf[ContainerOutputFaces].te
|
||||
te.outputConfig(msg.output).handleConfigPacket(msg)
|
||||
te.outputConfig.updated()
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,10 @@ trait RSControllableOutput extends TileEntity {
|
||||
def checkCanOutput(cfg: OutputConfigRSControllable): Boolean = {
|
||||
if (cfg.rsMode == RSMode.ALWAYS) return true
|
||||
if (cfg.rsMode == RSMode.NEVER) return false
|
||||
return getWorldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord) ^ (cfg.rsMode == RSMode.RS_OFF)
|
||||
return getWorldObj.isBlockIndirectlyGettingPowered(
|
||||
xCoord,
|
||||
yCoord,
|
||||
zCoord
|
||||
) ^ (cfg.rsMode == RSMode.RS_OFF)
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,8 @@ import net.bdew.lib.multiblock.{MachineCore, ResourceProvider, Tools}
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
|
||||
trait TileController extends TileDataSlots {
|
||||
val modules = new DataSlotPosSet("modules", this).setUpdate(UpdateKind.WORLD, UpdateKind.SAVE)
|
||||
val modules = new DataSlotPosSet("modules", this)
|
||||
.setUpdate(UpdateKind.WORLD, UpdateKind.SAVE)
|
||||
|
||||
def resources: ResourceProvider
|
||||
def cfg: MachineCore
|
||||
@@ -29,7 +30,8 @@ trait TileController extends TileDataSlots {
|
||||
|
||||
lazy val myPos = BlockRef(xCoord, yCoord, zCoord)
|
||||
|
||||
def getNumOfModules(kind: String) = modules.flatMap(_.getTile[TileModule](getWorldObj)).count(_.kind == kind)
|
||||
def getNumOfModules(kind: String) =
|
||||
modules.flatMap(_.getTile[TileModule](getWorldObj)).count(_.kind == kind)
|
||||
|
||||
def onModulesChanged()
|
||||
def onClick(player: EntityPlayer)
|
||||
@@ -58,22 +60,45 @@ trait TileController extends TileDataSlots {
|
||||
}
|
||||
|
||||
def validateModules() {
|
||||
modules.filter(x => {
|
||||
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)
|
||||
})
|
||||
modules
|
||||
.filter(x => {
|
||||
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)
|
||||
})
|
||||
val reachable = Tools.findReachableModules(getWorldObj, myPos)
|
||||
val toRemove = modules.filterNot(reachable.contains).flatMap(_.getTile[TileModule](getWorldObj))
|
||||
val toRemove = modules
|
||||
.filterNot(reachable.contains)
|
||||
.flatMap(_.getTile[TileModule](getWorldObj))
|
||||
acceptNewModules = false
|
||||
toRemove.foreach(moduleRemoved)
|
||||
toRemove.foreach(_.coreRemoved())
|
||||
acceptNewModules = true
|
||||
modulesChanged = true
|
||||
modules.map(x =>
|
||||
(x.getBlock[BlockModule[TileModule]](getWorldObj).orNull, x.getTile[TileModule](getWorldObj).orNull)
|
||||
).filter({ case (a, b) => a.kind != b.kind }).foreach({ case (a, b) => sys.error("Type mismatch between Block/Tile Block=%s(%s) Tile=%s(%s)".format(a.kind, a, b.kind, b)) })
|
||||
modules
|
||||
.map(x =>
|
||||
(
|
||||
x.getBlock[BlockModule[TileModule]](getWorldObj).orNull,
|
||||
x.getTile[TileModule](getWorldObj).orNull
|
||||
)
|
||||
)
|
||||
.filter({ case (a, b) => a.kind != b.kind })
|
||||
.foreach({ case (a, b) =>
|
||||
sys.error(
|
||||
"Type mismatch between Block/Tile Block=%s(%s) Tile=%s(%s)"
|
||||
.format(a.kind, a, b.kind, b)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
serverTick.listen(() => {
|
||||
|
||||
@@ -16,11 +16,18 @@ abstract class TileControllerGui extends TileController {
|
||||
|
||||
def onClick(player: EntityPlayer) = {
|
||||
import net.bdew.lib.helpers.ChatHelper._
|
||||
val missing = cfg.required.filter({ case (mod, cnt) => getNumOfModules(mod) < cnt })
|
||||
val missing = cfg.required.filter({ case (mod, cnt) =>
|
||||
getNumOfModules(mod) < cnt
|
||||
})
|
||||
if (missing.nonEmpty) {
|
||||
player.addChatMessage(L("bdlib.multiblock.incomplete").setColor(Color.RED))
|
||||
player.addChatMessage(
|
||||
L("bdlib.multiblock.incomplete").setColor(Color.RED)
|
||||
)
|
||||
for ((mod, cnt) <- missing)
|
||||
player.addChatMessage(L("- %s %s", cnt.toString, L(resources.getModuleName(mod))).setColor(Color.RED))
|
||||
player.addChatMessage(
|
||||
L("- %s %s", cnt.toString, L(resources.getModuleName(mod)))
|
||||
.setColor(Color.RED)
|
||||
)
|
||||
} else openGui(player)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,11 @@ import scala.reflect.ClassTag
|
||||
|
||||
trait TileModule extends TileDataSlots {
|
||||
val kind: String
|
||||
val connected = new DataSlotPos("connected", this).setUpdate(UpdateKind.WORLD, UpdateKind.SAVE, UpdateKind.RENDER)
|
||||
val connected = new DataSlotPos("connected", this)
|
||||
.setUpdate(UpdateKind.WORLD, UpdateKind.SAVE, UpdateKind.RENDER)
|
||||
|
||||
def getCoreAs[T <: TileController : ClassTag] = connected flatMap (_.getTile[T](getWorldObj))
|
||||
def getCoreAs[T <: TileController: ClassTag] =
|
||||
connected flatMap (_.getTile[T](getWorldObj))
|
||||
|
||||
def getCore = getCoreAs[TileController]
|
||||
|
||||
@@ -30,14 +32,24 @@ trait TileModule extends TileDataSlots {
|
||||
if (target.moduleConnected(this)) {
|
||||
connected.set(target.myPos)
|
||||
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
|
||||
getWorldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, getBlockType)
|
||||
getWorldObj.notifyBlocksOfNeighborChange(
|
||||
xCoord,
|
||||
yCoord,
|
||||
zCoord,
|
||||
getBlockType
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
def coreRemoved() {
|
||||
connected.unset()
|
||||
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
|
||||
getWorldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, getBlockType)
|
||||
getWorldObj.notifyBlocksOfNeighborChange(
|
||||
xCoord,
|
||||
yCoord,
|
||||
zCoord,
|
||||
getBlockType
|
||||
)
|
||||
}
|
||||
|
||||
def onBreak() {
|
||||
@@ -49,7 +61,8 @@ trait TileModule extends TileDataSlots {
|
||||
def tryConnect() {
|
||||
if (getCore.isEmpty) {
|
||||
for {
|
||||
conn <- Tools.findConnections(getWorldObj, myPos, kind).headOption if canConnectToCore(conn)
|
||||
conn <- Tools.findConnections(getWorldObj, myPos, kind).headOption
|
||||
if canConnectToCore(conn)
|
||||
core <- conn.getTile[TileController](getWorldObj)
|
||||
} {
|
||||
connect(core)
|
||||
|
||||
@@ -15,7 +15,9 @@ import net.bdew.lib.multiblock.data.OutputConfig
|
||||
import net.bdew.lib.multiblock.interact.{CIOutputFaces, MIOutput}
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
abstract class TileOutput[T <: OutputConfig] extends TileModule with MIOutput[T] {
|
||||
abstract class TileOutput[T <: OutputConfig]
|
||||
extends TileModule
|
||||
with MIOutput[T] {
|
||||
override def getCore = getCoreAs[CIOutputFaces]
|
||||
|
||||
def makeCfgObject(face: ForgeDirection): T
|
||||
@@ -44,7 +46,10 @@ abstract class TileOutput[T <: OutputConfig] extends TileModule with MIOutput[T]
|
||||
|
||||
def canConnectToFace(d: ForgeDirection): Boolean
|
||||
|
||||
def onConnectionsChanged(added: Set[ForgeDirection], removed: Set[ForgeDirection]) {}
|
||||
def onConnectionsChanged(
|
||||
added: Set[ForgeDirection],
|
||||
removed: Set[ForgeDirection]
|
||||
) {}
|
||||
|
||||
def doRescanFaces() {
|
||||
getCore foreach { core =>
|
||||
@@ -52,8 +57,9 @@ abstract class TileOutput[T <: OutputConfig] extends TileModule with MIOutput[T]
|
||||
ForgeDirection.VALID_DIRECTIONS
|
||||
filterNot { dir => core.modules.contains(myPos.neighbour(dir)) }
|
||||
filter canConnectToFace
|
||||
).toSet
|
||||
val known = core.outputFaces.filter(_._1.origin == myPos).map(_._1.face).toSet
|
||||
).toSet
|
||||
val known =
|
||||
core.outputFaces.filter(_._1.origin == myPos).map(_._1.face).toSet
|
||||
val toAdd = connections -- known
|
||||
val toRemove = known -- connections
|
||||
toRemove.foreach(x => core.removeOutput(myPos, x))
|
||||
|
||||
@@ -26,4 +26,4 @@ object ListElement {
|
||||
implicit val intArrayInList = ListElement(TIntArray, _.func_150306_c(_))
|
||||
implicit val doubleInList = ListElement(TDouble, _.func_150309_d(_))
|
||||
implicit val floatInList = ListElement(TFloat, _.func_150308_e(_))
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,8 @@ 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 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
|
||||
@@ -28,11 +29,15 @@ object NBT {
|
||||
}
|
||||
|
||||
// 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))
|
||||
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 _)))
|
||||
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 = {
|
||||
|
||||
@@ -29,4 +29,4 @@ class RichNBTTagCompound(tag: NBTTagCompound) {
|
||||
}
|
||||
|
||||
def toItemStack = Option(ItemStack.loadItemStackFromNBT(tag))
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,8 @@ object Type {
|
||||
override def toNBT(p: Byte): NBTTagByte = new NBTTagByte(p)
|
||||
}
|
||||
|
||||
implicit object TShort extends TypeDef(2, classOf[NBTTagShort], classOf[Short]) {
|
||||
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)
|
||||
}
|
||||
@@ -43,22 +44,26 @@ object Type {
|
||||
override def toNBT(p: Long): NBTTagLong = new NBTTagLong(p)
|
||||
}
|
||||
|
||||
implicit object TFloat extends TypeDef(5, classOf[NBTTagFloat], classOf[Float]) {
|
||||
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]) {
|
||||
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]]) {
|
||||
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]) {
|
||||
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)
|
||||
}
|
||||
@@ -67,11 +72,10 @@ object Type {
|
||||
|
||||
implicit object TCompound extends TypeDefSimple(10, classOf[NBTTagCompound])
|
||||
|
||||
implicit object TIntArray extends TypeDef(11, classOf[NBTTagIntArray], classOf[Array[Int]]) {
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,11 @@ 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] {
|
||||
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
|
||||
@@ -26,7 +30,8 @@ object TypeDef {
|
||||
var map = Map.empty[Int, TypeDef[_, _]]
|
||||
}
|
||||
|
||||
class TypeDefSimple[T <: NBTBase](id: Int, cls: Class[T]) extends TypeDef[T, T](id, cls, cls) {
|
||||
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
|
||||
}
|
||||
Loaded 100 of 171 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user