Compare commits

..
30 Commits
Author SHA1 Message Date
bdew e0d3609e66 Add ability to customize on what updates DataSlotTank sends it's capacity (default unchanged - only on GUI) 2014-09-18 10:07:56 +03:00
bdew 5a1c150a03 Fixed DrawTarget.drawTextureInterpolate ignoring color parameter 2014-09-16 14:57:37 +03:00
bdew c5a7fc3d51 Fixed WidgetFluidGauge not respecting fluid color 2014-09-16 14:51:33 +03:00
bdew 9787c4836e WidgetOutputs + WidgetPowerOutput moved back to generators as it's mod-specific. WidgetRSConfig refactored from them 2014-09-16 09:44:03 +03:00
bdew cd833163af MsgOutputCfgPower/Fluid (That only had RS configuration) replaced by MsgOutputCfgRSMode 2014-09-16 09:43:13 +03:00
bdew 5a9aedb4d5 Refactoring multiblock outputs, TileOutput (&co) now has a type parameter for config object type 2014-09-04 15:54:35 +03:00
bdew 2a7bbaeb97 prevent outputs connecting back to the same structure 2014-09-03 17:37:00 +03:00
bdew 58125ee291 TileModule.getCoreAs reworked for better type safety 2014-09-03 17:36:19 +03:00
bdew d9cc8ace82 Fixed fluid config save/load 2014-09-02 17:23:36 +03:00
bdew 32617ff592 Added DataSlotInventory 2014-09-02 14:10:50 +03:00
bdew 64683a0208 Refactored output config for multiblocks, added config object for fluid outputs 2014-09-02 14:10:36 +03:00
bdew f593458511 Allow quoted strings as config keys 2014-08-31 10:44:35 +03:00
bdew e6b38472ce Ensure tanks are marked for saving when content changes 2014-08-24 09:58:51 +03:00
bdew e6c0ef2c68 Merge pull request #4 from Adaptivity/patch-1
Create ru_RU.lang
2014-08-21 13:46:48 +03:00
Anton 56110d8ec5 Create ru_RU.lang 2014-08-21 14:09:51 +04:00
bdew f000d11c54 Added ConfigSection.keys 2014-08-20 14:17:13 +03:00
bdew 913d4f48a6 Added localization file 2014-08-20 10:49:06 +03:00
bdew a25553edaf Force block update when connections change for output modules 2014-08-20 10:48:21 +03:00
bdew 82328d10ec Aded multiblock system (moved from DCM) 2014-08-14 15:13:31 +03:00
bdew 12f19fc410 BlockManager.regBlock should looke for NamedBlock trait, not SimpleBlock 2014-08-14 10:04:26 +03:00
bdew 7c275f434a bump version 2014-08-12 13:05:52 +03:00
bdew f960050f9c Added creative tabs helper 2014-08-12 12:41:23 +03:00
bdew 87dd7c34c5 Added DataSlotOption 2014-08-12 12:41:10 +03:00
bdew 9fdc6bd880 Added connected textures renderer 2014-08-11 16:51:18 +03:00
bdew 490433a7f4 Added BlockFace, HasTE can now work with BlockRef, Fixed missing copyrights 2014-08-11 16:45:01 +03:00
bdew 71bef762a6 Added BlockRef (from pressure pipes) 2014-08-07 12:46:21 +03:00
bdew 5eef56811b Fixed InventoryItemAdapter not loading properly 2014-07-29 17:19:39 +03:00
bdew 5a3fa7ef75 Added a statement to check if an API is present in configs 2014-07-29 16:19:05 +03:00
bdew 2d799bb797 Code style 2014-07-29 12:44:05 +03:00
bdew 03d9b0fef0 Rewrote networking system (experimental) 2014-07-29 12:43:53 +03:00
122 changed files with 2093 additions and 219 deletions

No files matched your search

+1 -1
View File
@@ -21,7 +21,7 @@ buildscript {
apply plugin: 'scala'
apply plugin: 'forge'
version = "1.4.0"
version = "1.4.4"
if (project.hasProperty('buildnum')) {
project.version = project.version + '.' + project.buildnum
+19
View File
@@ -0,0 +1,19 @@
bdlib.multiblock.face.north=North
bdlib.multiblock.face.south=South
bdlib.multiblock.face.east=East
bdlib.multiblock.face.west=West
bdlib.multiblock.face.up=Top
bdlib.multiblock.face.down=Bottom
bdlib.multiblock.disabled=Disabled
bdlib.multiblock.incomplete=This machine is incomplete, it requires at least:
bdlib.multiblock.notconnected=Not connected to a valid machine
bdlib.multiblock.toomanyoutputs=Too many outputs connected, unable to attach new connection
bdlib.rsmode.always=Always ON
bdlib.rsmode.never=Disabled
bdlib.rsmode.rs_on=Enable on redstone
bdlib.rsmode.rs_off=Disable on redstone
bdlib.label.empty=Empty
+18
View File
@@ -0,0 +1,18 @@
bdlib.multiblock.face.north=Север
bdlib.multiblock.face.south=Юг
bdlib.multiblock.face.east=Восток
bdlib.multiblock.face.west=Запад
bdlib.multiblock.face.up=Верх
bdlib.multiblock.face.down=Низ
bdlib.multiblock.disabled=Отключено
bdlib.multiblock.incomplete=Этот механизм не завершён, ему требуется как минимум:
bdlib.multiblock.notconnected=Не подключено к верному механизму
bdlib.multiblock.toomanyoutputs=Слишком много выходов подсоединено, нельзя установить новое соединение
bdlib.rsmode.always=Всегда ВКЛ.
bdlib.rsmode.never=Отключен
bdlib.rsmode.rs_on=Включение по сигналу красного камня
bdlib.rsmode.rs_off=Отключение по сигналу красного камня
bdlib.label.empty=Пусто
+1 -1
View File
@@ -1 +1 @@
rootProject.name='bdlib'
rootProject.name = 'bdlib'
+4 -2
View File
@@ -10,10 +10,11 @@
package net.bdew.lib
import cpw.mods.fml.common.Mod
import cpw.mods.fml.common.event.{FMLServerStartingEvent, FMLPreInitializationEvent}
import org.apache.logging.log4j.Logger
import cpw.mods.fml.common.Mod.EventHandler
import cpw.mods.fml.common.event.{FMLPreInitializationEvent, FMLServerStartingEvent}
import net.bdew.lib.multiblock.network.NetHandler
import net.minecraft.command.CommandHandler
import org.apache.logging.log4j.Logger
@Mod(modid = "bdlib", name = "BD lib", version = "BDLIB_VER", modLanguage = "scala")
object BdLib {
@@ -29,6 +30,7 @@ object BdLib {
def preInit(ev: FMLPreInitializationEvent) {
log = ev.getModLog
log.info("bdlib BDLIB_VER loaded")
NetHandler.init()
}
@EventHandler
+1 -1
View File
@@ -9,8 +9,8 @@
package net.bdew.lib
import org.lwjgl.input.Keyboard
import net.minecraft.client.Minecraft
import org.lwjgl.input.Keyboard
/**
* Misc functions and shortcuts for clientside code
+6 -5
View File
@@ -9,14 +9,15 @@
package net.bdew.lib
import net.minecraft.command.{CommandBase, ICommandSender}
import cpw.mods.fml.relauncher.FMLInjectionData
import java.io.{FileWriter, BufferedWriter, File}
import cpw.mods.fml.common.registry.GameData
import java.io.{BufferedWriter, File, FileWriter}
import com.google.common.collect.Table
import cpw.mods.fml.common.registry.GameData
import cpw.mods.fml.relauncher.FMLInjectionData
import net.minecraft.command.{CommandBase, ICommandSender}
import net.minecraft.item.ItemStack
import net.minecraftforge.oredict.OreDictionary
import net.minecraftforge.fluids.FluidRegistry
import net.minecraftforge.oredict.OreDictionary
class CommandDumpRegistry extends CommandBase {
def getCommandName = "dumpregistry"
@@ -0,0 +1,24 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib
import net.minecraft.creativetab.CreativeTabs
import net.minecraft.item.Item
class CreativeTabContainer {
class Tab(name: String, item: => Item) extends CreativeTabs(name) {
override def getTabIconItem = item
}
BdLib.logInfo("Loaded creative tabs for %s", Misc.getActiveModId)
def init() {}
}
+18 -8
View File
@@ -9,16 +9,16 @@
package net.bdew.lib
import cpw.mods.fml.common.registry.GameRegistry
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.StatCollector
import net.minecraft.item.ItemStack
import cpw.mods.fml.common.versioning.{ArtifactVersion, VersionParser}
import cpw.mods.fml.common.Loader
import net.minecraftforge.oredict.ShapedOreRecipe
import net.minecraft.world.biome.BiomeGenBase
import cpw.mods.fml.common.registry.GameRegistry
import cpw.mods.fml.common.versioning.{ArtifactVersion, VersionParser}
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.tileentity.TileEntity
import net.minecraft.util.StatCollector
import net.minecraft.world.biome.BiomeGenBase
import net.minecraftforge.common.util.ForgeDirection
import net.minecraftforge.oredict.ShapedOreRecipe
object Misc {
def iterNbtCompoundList(parent: NBTTagCompound, name: String): Iterable[NBTTagCompound] = {
@@ -26,6 +26,11 @@ object Misc {
for (i <- 0 until list.tagCount()) yield list.getCompoundTagAt(i)
}
def iterNbtIntArray(parent: NBTTagCompound, name: String): Iterable[Array[Int]] = {
val list = parent.getTagList(name, 11)
for (i <- 0 until list.tagCount()) yield list.func_150306_c(i)
}
def getActiveModId = Loader.instance().activeModContainer().getModId
def toLocal(s: String) = StatCollector.translateToLocal(s)
@@ -59,7 +64,7 @@ object Misc {
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).getOrElse(null)
def getBiomeByName(name: String) = BiomeGenBase.getBiomeGenArray.find(x => x != null && x.biomeName == name).orNull
def haveModVersion(spec: String): Boolean = {
val req = VersionParser.parseVersionReference(spec)
@@ -84,5 +89,10 @@ object Misc {
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 applyMutator[T](f: (T) => Unit, init: T): T = {
f(init)
init
}
}
+22
View File
@@ -0,0 +1,22 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.block
import net.minecraftforge.common.util.ForgeDirection
case class BlockFace(x: Int, y: Int, z: Int, face: ForgeDirection) {
def origin = BlockRef(x, y, z)
def target = origin.neighbour(face)
def opposite = face.getOpposite
}
object BlockFace {
def apply(bp: BlockRef, face: ForgeDirection) = new BlockFace(bp.x, bp.y, bp.z, face)
}
+59
View File
@@ -0,0 +1,59 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.block
import net.minecraft.block.Block
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.tileentity.TileEntity
import net.minecraft.world.IBlockAccess
import net.minecraftforge.common.util.ForgeDirection
import scala.reflect.ClassTag
case class BlockRef(x: Int, y: Int, z: Int) {
def block(w: IBlockAccess) = Option(w.getBlock(x, y, z))
def tile(w: IBlockAccess) = Option(w.getTileEntity(x, y, z))
def meta(w: IBlockAccess) = w.getBlockMetadata(x, y, z)
def 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
override def toString = "(x=%d y=%d z=%d)".format(x, y, z)
def getTile[T: ClassTag](w: IBlockAccess) = tile(w) flatMap { tile =>
val cls = implicitly[ClassTag[T]].runtimeClass
if (cls.isInstance(tile))
Some(tile.asInstanceOf[T])
else None
}
def ==(tx: Int, ty: Int, tz: Int) = x == tx && y == ty && z == tz
def getBlock[T: ClassTag](w: IBlockAccess) = block(w) flatMap { block =>
val cls = implicitly[ClassTag[T]].runtimeClass
if (cls.isInstance(block))
Some(block.asInstanceOf[T])
else None
}
def writeToNBT(tag: NBTTagCompound) {
tag.setInteger("x", x)
tag.setInteger("y", y)
tag.setInteger("z", z)
}
}
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"))
}
+6 -3
View File
@@ -9,15 +9,18 @@
package net.bdew.lib.block
import net.minecraft.block.{ITileEntityProvider, Block}
import net.minecraft.world.{IBlockAccess, World}
import net.minecraft.tileentity.TileEntity
import net.bdew.lib.BdLib
import net.minecraft.block.{Block, ITileEntityProvider}
import net.minecraft.tileentity.TileEntity
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 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)) {
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.block
import cpw.mods.fml.relauncher.{Side, SideOnly}
import net.bdew.lib.Misc
import net.minecraft.block.Block
import net.minecraft.block.material.Material
import net.minecraft.client.renderer.texture.IIconRegister
trait NamedBlock extends Block {
def name: String
}
class SimpleBlock(val name: String, material: Material) extends Block(material) with NamedBlock {
val modId = Misc.getActiveModId
setBlockName(modId + "." + name)
@SideOnly(Side.CLIENT)
override def registerBlockIcons(reg: IIconRegister) {
blockIcon = reg.registerIcon(modId + ":" + name.toLowerCase)
}
}
+8 -9
View File
@@ -9,22 +9,21 @@
package net.bdew.lib.config
import net.minecraft.item.ItemStack
import net.minecraft.block.Block
import cpw.mods.fml.common.registry.GameRegistry
import net.bdew.lib.block.HasTE
import net.bdew.lib.Misc
import net.bdew.lib.block.{HasTE, NamedBlock}
import net.minecraft.block.Block
import net.minecraft.creativetab.CreativeTabs
import net.minecraft.item.ItemStack
class BlockManager() {
def regBlockCls[T <: Block](blockCls: Class[T], name: String, addStack: Boolean = false): T = {
val block = blockCls.newInstance()
regBlock[T](block, name, addStack)
}
class BlockManager(creativeTab: CreativeTabs) {
def regBlock[T <: NamedBlock](block: T): T = regBlock(block, block.name)
def regBlock[T <: Block](block: T, name: String, addStack: Boolean = false): T = {
GameRegistry.registerBlock(block, name)
block.setCreativeTab(creativeTab)
if (addStack)
GameRegistry.registerCustomItemStack(name, new ItemStack(block))
+1 -1
View File
@@ -9,7 +9,7 @@
package net.bdew.lib.config
import net.minecraftforge.fluids.{FluidRegistry, Fluid}
import net.minecraftforge.fluids.{Fluid, FluidRegistry}
class FluidManager() {
def regFluid[T <: Fluid](fluid: T): T = {
+5 -7
View File
@@ -9,25 +9,23 @@
package net.bdew.lib.config
import net.minecraft.item.{ItemStack, Item}
import cpw.mods.fml.common.registry.GameRegistry
import net.bdew.lib.items.{NamedItem, SimpleItem}
import net.minecraft.creativetab.CreativeTabs
import net.minecraft.item.{Item, ItemStack}
class ItemManager() {
class ItemManager(creativeTab: CreativeTabs) {
def regSimpleItem(name: String): SimpleItem = regItem(new SimpleItem(name), name)
def regItem[T <: NamedItem](item: T): T = regItem[T](item, item.name)
def regItemCls[T <: Item](itemCls: Class[T], name: String, addStack: Boolean = false): T = {
val item = itemCls.newInstance()
regItem[T](item, name, addStack)
}
def regItem[T <: Item](item: T, name: String, addStack: Boolean = false): T = {
GameRegistry.registerItem(item, name)
item.setCreativeTab(creativeTab)
if (addStack)
GameRegistry.registerCustomItemStack(name, new ItemStack(item))
return item
}
def load() {}
}
+5 -4
View File
@@ -9,16 +9,17 @@
package net.bdew.lib.config
import net.bdew.lib.recipes.gencfg.ConfigSection
import net.bdew.lib.gui.{GuiHandler, GuiProvider}
import net.bdew.lib.machine.Machine
import net.bdew.lib.gui.{GuiProvider, GuiHandler}
import net.bdew.lib.recipes.gencfg.ConfigSection
import net.minecraft.creativetab.CreativeTabs
class MachineManager(val tuning: ConfigSection, guiHandler: GuiHandler) {
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")) {
machine.enabled = true
machine.regBlock()
machine.regBlock(creativeTab)
if (machine.isInstanceOf[GuiProvider])
guiHandler.register(machine.asInstanceOf[GuiProvider])
}
+3 -3
View File
@@ -9,12 +9,12 @@
package net.bdew.lib.covers
import net.bdew.lib.block.HasTE
import net.minecraft.world.{IBlockAccess, World}
import net.minecraft.entity.player.EntityPlayer
import net.bdew.lib.Misc
import net.bdew.lib.block.HasTE
import net.bdew.lib.items.ItemUtils
import net.minecraft.block.Block
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.world.{IBlockAccess, World}
trait BlockCoverable[T <: TileCoverable] extends HasTE[T] {
override def onBlockActivated(world: World, x: Int, y: Int, z: Int, player: EntityPlayer, face: Int, xoffs: Float, yoffs: Float, zoffs: Float): Boolean = {
+1 -1
View File
@@ -9,7 +9,7 @@
package net.bdew.lib.covers
import net.minecraft.item.{ItemStack, Item}
import net.minecraft.item.{Item, ItemStack}
import net.minecraft.util.IIcon
import net.minecraftforge.common.util.ForgeDirection
+2 -2
View File
@@ -9,9 +9,9 @@
package net.bdew.lib.covers
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots}
import net.bdew.lib.data.DataSlotItemStack
import net.bdew.lib.Misc
import net.bdew.lib.data.DataSlotItemStack
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind}
import net.minecraft.item.ItemStack
import net.minecraftforge.common.util.ForgeDirection
+1 -1
View File
@@ -9,8 +9,8 @@
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots, DataSlotVal}
case class DataSlotBoolean(name: String, parent: TileDataSlots, default: Boolean = false) extends DataSlotVal[Boolean] {
var cval = default
@@ -9,7 +9,7 @@
package net.bdew.lib.data
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind, DataSlotVal}
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.ForgeDirection
+1 -1
View File
@@ -9,8 +9,8 @@
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotNumeric, TileDataSlots, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots, DataSlotNumeric}
case class DataSlotFloat(name: String, parent: TileDataSlots, default: Float = 0) extends DataSlotNumeric[Float](default) {
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setFloat(name, cval)
@@ -1,3 +1,12 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.data
import java.util.UUID
+1 -1
View File
@@ -9,8 +9,8 @@
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotNumeric, TileDataSlots, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots, DataSlotNumeric}
case class DataSlotInt(name: String, parent: TileDataSlots, default: Int = 0) extends DataSlotNumeric[Int](default) {
def save(t: NBTTagCompound, kind: UpdateKind.Value) = t.setInteger(name, cval)
@@ -0,0 +1,46 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.data
import net.bdew.lib.Misc
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
import net.bdew.lib.tile.inventory.BaseInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
case class DataSlotInventory(name: String, parent: TileDataSlots, size: Int) extends DataSlot with BaseInventory {
setUpdate(UpdateKind.SAVE)
override def getSizeInventory = size
override def markDirty() = parent.dataSlotChanged(this)
override def load(t: NBTTagCompound, kind: UpdateKind.Value) {
inv = new Array[ItemStack](getSizeInventory)
for (nbtItem <- Misc.iterNbtCompoundList(t, name)) {
val slot = nbtItem.getByte("Slot")
if (slot >= 0 && slot < inv.size) {
inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem)
}
}
}
override def save(t: NBTTagCompound, kind: UpdateKind.Value) {
val itemList = new NBTTagList
for ((item, i) <- inv.view.zipWithIndex if item != null) {
val itemNbt: NBTTagCompound = new NBTTagCompound
itemNbt.setByte("Slot", i.asInstanceOf[Byte])
item.writeToNBT(itemNbt)
itemList.appendTag(itemNbt)
}
t.setTag(name, itemList)
}
}
@@ -9,9 +9,9 @@
package net.bdew.lib.data
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind, DataSlotVal}
import net.minecraft.nbt.NBTTagCompound
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
case class DataSlotItemStack(name: String, parent: TileDataSlots) extends DataSlotVal[ItemStack] {
var cval: ItemStack = null
@@ -0,0 +1,46 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.data
import net.bdew.lib.data.base.DataSlotVal
abstract class DataSlotOption[T] extends DataSlotVal[Option[T]] {
override var cval: Option[T] = None
def set(v: T) {
if (v == null) sys.error("Null should never be used with DataSlotOption")
cval = Some(v)
}
def unset() {
cval = None
}
override def isSame(v: Option[T]) = {
if (v == null) sys.error("Null should never be used with DataSlotOption")
super.isSame(v)
}
override def :=(that: Option[T]) = {
if (that == null) sys.error("Null should never be used with DataSlotOption")
super.:=(that)
}
override def :!=(that: Option[T]) = {
if (that == null) sys.error("Null should never be used with DataSlotOption")
super.:!=(that)
}
override def :==(that: Option[T]) = {
if (that == null) sys.error("Null should never be used with DataSlotOption")
super.:==(that)
}
override def update(v: Option[T]) = {
if (v == null) sys.error("Null should never be used with DataSlotOption")
super.update(v)
}
}
+1 -1
View File
@@ -9,8 +9,8 @@
package net.bdew.lib.data
import net.bdew.lib.data.base.{DataSlotVal, TileDataSlots, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots, DataSlotVal}
case class DataSlotString(name: String, parent: TileDataSlots, default: String = null) extends DataSlotVal[String] {
var cval: String = default
+19 -4
View File
@@ -9,9 +9,9 @@
package net.bdew.lib.data
import net.minecraftforge.fluids.{IFluidTank, FluidTank, FluidStack}
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots, DataSlot}
import net.minecraftforge.fluids.{FluidStack, FluidTank, IFluidTank}
abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank with DataSlot {
var oldStack: FluidStack = null
@@ -20,6 +20,8 @@ abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank w
updateKind = Set(UpdateKind.GUI, UpdateKind.SAVE)
val sendCapacityOnUpdateKind = Set(UpdateKind.GUI)
def checkUpdate() {
if (!isSame(oldStack, fluid)) {
oldStack = if (fluid == null) null else fluid.copy()
@@ -36,7 +38,7 @@ abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank w
def save(t: NBTTagCompound, k: UpdateKind.Value) {
val tag = new NBTTagCompound()
writeToNBT(tag)
if (k == UpdateKind.GUI)
if (sendCapacityOnUpdateKind.contains(k))
tag.setInteger("size", getCapacity)
t.setTag(name, tag)
}
@@ -45,9 +47,22 @@ abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank w
setFluid(null)
val tag = t.getCompoundTag(name)
readFromNBT(tag)
if (k == UpdateKind.GUI)
if (sendCapacityOnUpdateKind.contains(k))
setCapacity(tag.getInteger("size"))
}
override def setFluid(fluid: FluidStack) = execWithChangeNotify(super.setFluid(fluid))
override def setCapacity(capacity: Int) = execWithChangeNotify(super.setCapacity(capacity))
override def drain(maxDrain: Int, doDrain: Boolean) =
if (doDrain)
execWithChangeNotify(super.drain(maxDrain, true))
else
super.drain(maxDrain, false)
override def fill(resource: FluidStack, doFill: Boolean) =
if (doFill)
execWithChangeNotify(super.fill(resource, true))
else
super.fill(resource, false)
}
case class DataSlotTank(name: String, parent: TileDataSlots, size: Int) extends DataSlotTankBase(size)
@@ -9,8 +9,8 @@
package net.bdew.lib.data.base
import net.minecraft.entity.player.EntityPlayerMP
import net.bdew.lib.gui.NoInvContainer
import net.minecraft.entity.player.EntityPlayerMP
import net.minecraft.inventory.ICrafting
trait ContainerDataSlots extends NoInvContainer {
@@ -35,6 +35,12 @@ trait DataSlot {
def save(t: NBTTagCompound, kind: UpdateKind.Value)
def load(t: NBTTagCompound, kind: UpdateKind.Value)
def execWithChangeNotify[T](f: => T): T = {
val v = f
parent.dataSlotChanged(this)
v
}
def setUpdate(vals: UpdateKind.Value*): this.type = {
updateKind = vals.toSet
return this
+1 -1
View File
@@ -9,7 +9,7 @@
package net.bdew.lib.data.base
import language.implicitConversions
import scala.language.implicitConversions
/**
* Base trait for data slots that hold primitive values
@@ -9,11 +9,12 @@
package net.bdew.lib.data.base
import scala.collection.mutable
import net.minecraft.nbt.NBTTagCompound
import net.bdew.lib.tile.TileExtended
import net.minecraft.network.play.server.S35PacketUpdateTileEntity
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.network.Packet
import net.minecraft.network.play.server.S35PacketUpdateTileEntity
import scala.collection.mutable
trait TileDataSlots extends TileExtended {
val dataSlots = mutable.HashMap.empty[String, DataSlot]
+3 -3
View File
@@ -9,10 +9,10 @@
package net.bdew.lib.gui
import net.minecraft.inventory.IInventory
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.bdew.lib.items.ItemUtils
import net.minecraft.entity.player.EntityPlayer
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 = {
+4 -3
View File
@@ -9,12 +9,13 @@
package net.bdew.lib.gui
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.inventory.GuiContainer
import net.minecraft.inventory.Container
import scala.collection.mutable
import net.minecraft.client.Minecraft
import org.lwjgl.opengl.GL11
import scala.collection.mutable
abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContainer(cont) {
xSize = xSz
ySize = ySz
@@ -53,7 +54,7 @@ abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContai
widgets.handleTooltip(Point(x, y) - rect.origin, tip)
import collection.JavaConversions._
import scala.collection.JavaConversions._
if (tip.size > 0)
drawHoveringText(tip, x, y, getFontRenderer)
+1 -1
View File
@@ -9,8 +9,8 @@
package net.bdew.lib.gui
import org.lwjgl.opengl.GL11
import net.bdew.lib.Misc
import org.lwjgl.opengl.GL11
case class Color(r: Float, g: Float, b: Float, a: Float = 1) {
def this(c: (Float, Float, Float)) = this(c._1, c._2, c._3)
+2 -2
View File
@@ -9,8 +9,8 @@
package net.bdew.lib.gui
import net.minecraft.client.renderer.Tessellator
import net.minecraft.client.gui.FontRenderer
import net.minecraft.client.renderer.Tessellator
trait DrawTarget {
def getZLevel: Float
@@ -20,7 +20,7 @@ trait DrawTarget {
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))
drawTexture(r.interpolate(x1, y1, x2, y2), Texture.interpolate(t, x1, y1, x2, y2), color)
}
trait SimpleDrawTarget extends DrawTarget {
+2 -1
View File
@@ -10,10 +10,11 @@
package net.bdew.lib.gui
import cpw.mods.fml.common.network.IGuiHandler
import scala.collection.mutable
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.world.World
import scala.collection.mutable
class GuiHandler extends IGuiHandler {
val guis = mutable.Map.empty[Int, GuiProvider]
+2 -2
View File
@@ -9,9 +9,9 @@
package net.bdew.lib.gui
import net.minecraft.tileentity.TileEntity
import net.minecraft.entity.player.EntityPlayer
import cpw.mods.fml.relauncher.{Side, SideOnly}
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.tileentity.TileEntity
trait GuiProvider {
def guiId: Int
+2 -2
View File
@@ -9,9 +9,9 @@
package net.bdew.lib.gui
import net.minecraft.inventory.{Slot, Container}
import net.bdew.lib.Misc
import net.minecraft.entity.player.{EntityPlayer, InventoryPlayer, EntityPlayerMP}
import net.minecraft.entity.player.{EntityPlayer, EntityPlayerMP, InventoryPlayer}
import net.minecraft.inventory.{Container, Slot}
import net.minecraft.item.ItemStack
abstract class NoInvContainer extends Container {
+2 -2
View File
@@ -9,9 +9,9 @@
package net.bdew.lib.gui
import net.minecraft.item.ItemStack
import net.minecraft.inventory.Slot
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.inventory.Slot
import net.minecraft.item.ItemStack
trait SlotClickable extends Slot {
def onClick(button: Int, mods: Int, player: EntityPlayer): ItemStack
+1 -1
View File
@@ -9,9 +9,9 @@
package net.bdew.lib.gui
import net.minecraft.util.{IIcon, ResourceLocation}
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.texture.TextureMap
import net.minecraft.util.{IIcon, ResourceLocation}
trait Texture {
def u1: Float
+2 -1
View File
@@ -9,11 +9,12 @@
package net.bdew.lib.gui
import scala.collection.mutable
import net.bdew.lib.gui.widgets.BaseWidget
import net.minecraft.client.gui.FontRenderer
import org.lwjgl.opengl.GL11
import scala.collection.mutable
trait WidgetContainer extends DrawTarget {
val rect: Rect
val widgets = mutable.MutableList.empty[BaseWidget]
+1 -1
View File
@@ -13,7 +13,7 @@ package object gui {
type Rect = BaseRect[Float]
type Point = BasePoint[Float]
import language.implicitConversions
import scala.language.implicitConversions
implicit def awt2point(p: java.awt.Point) = BasePoint(p.x, p.y)
implicit def point2awt(p: BasePoint[Int]): java.awt.Point = new java.awt.Point(p.x, p.y)
+2 -1
View File
@@ -9,8 +9,9 @@
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{Point, Rect, WidgetContainer}
import scala.collection.mutable
import net.bdew.lib.gui.{WidgetContainer, Point, Rect}
trait BaseWidget {
val rect: Rect
@@ -9,10 +9,10 @@
package net.bdew.lib.gui.widgets
import net.minecraft.client.gui.GuiButton
import net.bdew.lib.gui.{Point, Rect}
import net.minecraft.client.Minecraft
import net.minecraft.client.audio.PositionedSoundRecord
import net.minecraft.client.gui.GuiButton
import net.minecraft.util.ResourceLocation
class WidgetButton(val rect: Rect, text: String, clicked: WidgetButton => Unit)
@@ -0,0 +1,45 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{Point, Rect, Texture}
import net.minecraft.client.Minecraft
import net.minecraft.client.audio.PositionedSoundRecord
import net.minecraft.util.ResourceLocation
import scala.collection.mutable
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)
var icon: Texture = null
var hover: String = null
override def draw(mouse: Point) {
if (rect.contains(mouse))
parent.drawTexture(rect, hoverTex)
else
parent.drawTexture(rect, baseTex)
if (icon != null)
parent.drawTexture(iconRect, icon)
}
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
if (hover != null && hover > "")
tip += hover
}
override def mouseClicked(p: Point, button: Int) {
Minecraft.getMinecraft.getSoundHandler.playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F))
clicked(this)
}
}
@@ -9,8 +9,8 @@
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui._
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 {
@@ -9,13 +9,15 @@
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{Texture, Point, Rect}
import net.bdew.lib.data.DataSlotTankBase
import scala.collection.mutable
import java.text.DecimalFormat
import net.bdew.lib.Misc
import net.bdew.lib.data.DataSlotTankBase
import net.bdew.lib.gui.{Color, Point, Rect, Texture}
import org.lwjgl.opengl.GL11
import scala.collection.mutable
class WidgetFluidGauge(val rect: Rect, overlay: Texture, dslot: DataSlotTankBase) extends Widget {
val formater = new DecimalFormat("#,###")
@@ -37,19 +39,21 @@ class WidgetFluidGauge(val rect: Rect, overlay: Texture, dslot: DataSlotTankBase
val icon = Texture(Texture.BLOCKS, fstack.getFluid.getStillIcon)
var fillHeight = if (dslot.getCapacity > 0) rect.h * fstack.amount / dslot.getCapacity else 0
var yStart: Int = 0
val color = Color.fromInt(fstack.getFluid.getColor(fstack))
while (fillHeight > 0) {
if (fillHeight > 16) {
parent.drawTexture(new Rect(rect.x, rect.y2 - 16 - yStart, rect.w, 16), icon)
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)
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
}
}
GL11.glColor3d(1, 1, 1)
GL11.glDisable(GL11.GL_BLEND)
parent.drawTexture(rect, overlay)
@@ -9,9 +9,10 @@
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui._
import scala.collection.mutable
import net.bdew.lib.data.DataSlotFloat
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.cval * 100) + "%"
@@ -10,7 +10,6 @@
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui._
import net.bdew.lib.gui.Rect
class WidgetSubcontainer(val rect: Rect) extends BaseWidget with WidgetContainer with SimpleDrawTarget {
def getZLevel = parent.getZLevel
@@ -9,8 +9,8 @@
package net.bdew.lib.gui.widgets
import net.minecraft.client.gui.{FontRenderer, GuiTextField}
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 {
+1 -1
View File
@@ -9,8 +9,8 @@
package net.bdew.lib.items
import net.minecraft.item.{ItemBlock, Item, ItemStack}
import net.minecraft.block.Block
import net.minecraft.item.{Item, ItemBlock, ItemStack}
/**
* Allows matching Items in ItemStacks in scala pattern matches
+5 -4
View File
@@ -9,13 +9,14 @@
package net.bdew.lib.items
import java.util.Random
import net.bdew.lib.Misc
import net.minecraft.entity.item.EntityItem
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.inventory.{IInventory, ISidedInventory}
import net.minecraft.item.{Item, ItemStack}
import net.minecraft.world.World
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.inventory.{ISidedInventory, IInventory}
import net.bdew.lib.Misc
import java.util.Random
import net.minecraftforge.common.util.ForgeDirection
object ItemUtils {
+2 -2
View File
@@ -9,10 +9,10 @@
package net.bdew.lib.items
import net.minecraft.item.Item
import net.minecraft.client.renderer.texture.IIconRegister
import cpw.mods.fml.relauncher.{Side, SideOnly}
import net.bdew.lib.Misc
import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.item.Item
trait NamedItem extends Item {
def name: String
@@ -9,10 +9,10 @@
package net.bdew.lib.items.inventory
import net.minecraft.entity.player.EntityPlayer
import net.bdew.lib.gui.BaseContainer
import net.minecraft.item.ItemStack
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) {
def canInteractWith(entityplayer: EntityPlayer) = entityplayer == player
@@ -9,11 +9,11 @@
package net.bdew.lib.items.inventory
import net.minecraft.item.ItemStack
import net.bdew.lib.tile.inventory.BaseInventory
import net.bdew.lib.Misc
import net.minecraft.nbt.{NBTTagList, NBTTagCompound}
import net.bdew.lib.tile.inventory.BaseInventory
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 {
def getSizeInventory = size
@@ -24,7 +24,7 @@ class InventoryItemAdapter(val player: EntityPlayer, val slot: Int, val size: In
def load() {
val tag = getStack.getTagCompound
for (nbtItem <- Misc.iterNbtCompoundList(tag, "tagName")) {
for (nbtItem <- Misc.iterNbtCompoundList(tag, tagName)) {
val slot = nbtItem.getByte("Slot")
if (slot >= 0 && slot < inv.size) {
inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem)
@@ -9,12 +9,12 @@
package net.bdew.lib.items.inventory
import net.minecraft.item.Item
import net.bdew.lib.gui.GuiProvider
import cpw.mods.fml.common.Loader
import cpw.mods.fml.relauncher.{Side, SideOnly}
import net.minecraft.entity.player.EntityPlayer
import net.bdew.lib.BdLib
import net.bdew.lib.gui.GuiProvider
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.Item
import net.minecraft.world.World
/**
+6 -4
View File
@@ -9,11 +9,12 @@
package net.bdew.lib.machine
import cpw.mods.fml.common.registry.GameRegistry
import net.bdew.lib.Misc
import net.bdew.lib.block.HasTE
import net.bdew.lib.recipes.gencfg.ConfigSection
import net.minecraft.block.Block
import cpw.mods.fml.common.registry.GameRegistry
import net.bdew.lib.block.HasTE
import net.bdew.lib.Misc
import net.minecraft.creativetab.CreativeTabs
abstract class Machine[T <: Block](val name: String, blockConstruct: => T) {
var block: T = null.asInstanceOf[T]
@@ -21,9 +22,10 @@ abstract class Machine[T <: Block](val name: String, blockConstruct: => T) {
var enabled = false
val modId = Misc.getActiveModId
def regBlock() {
def regBlock(creativeTab: CreativeTabs) {
block = blockConstruct
GameRegistry.registerBlock(block, name)
block.setCreativeTab(creativeTab)
if (block.isInstanceOf[HasTE[_]]) {
GameRegistry.registerTileEntity(block.asInstanceOf[HasTE[_]].TEClass, "%s.%s".format(modId, name))
}
@@ -0,0 +1,24 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock
import net.bdew.lib.recipes.gencfg.{ConfigSection, EntryDouble}
trait MachineCore {
var tuning: ConfigSection
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")
}
@@ -0,0 +1,36 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock
import net.bdew.lib.gui.{Color, Texture}
import net.minecraft.util.IIcon
trait ResourceProvider {
// Icons for rendering, *must* be on block spritesheet
def edge: IIcon
def disabled: IIcon
def output: IIcon
def arrowTop: IIcon
def arrowRight: IIcon
def arrowBottom: IIcon
def arrowLeft: IIcon
// Textures for GUI stuff
def btBase: Texture
def btHover: Texture
def btRsOn: Texture
def btRsOff: Texture
def btEnabled: Texture
def btDisabled: Texture
val outputColors: Map[Int, Color]
val unlocalizedOutputName: Map[Int, String]
def getModuleName(s: String): String
}
+51
View File
@@ -0,0 +1,51 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock
import net.bdew.lib.block.BlockRef
import net.bdew.lib.multiblock.tile.{TileController, TileModule}
import net.minecraft.world.World
import scala.collection.mutable
object Tools {
def canConnect(world: World, core: BlockRef, kind: String): Boolean = {
val t = core.getTile[TileController](world).getOrElse(return false)
t.getNumOfMoudules(kind) < t.cfg.modules.getOrElse(kind, return false)
}
def findConnections(world: World, start: BlockRef, kind: String) =
(start.neighbours.values flatMap { case pos =>
(pos.tile(world) flatMap {
case t: TileModule => t.connected.cval
case t: TileController => Some(pos)
case _ => None
}) filter (x => canConnect(world, x, kind))
}).toList.distinct
def getAdjancedConnected(w: World, core: BlockRef, pos: BlockRef, seen: mutable.Set[BlockRef]) =
pos.neighbours.values
.filterNot(seen.contains)
.flatMap(_.getTile[TileModule](w))
.filter(x => x.connected.contains(core))
.map(_.mypos)
def findReachableModules(world: World, core: BlockRef): Set[BlockRef] = {
val seen = mutable.Set.empty[BlockRef]
val queue = mutable.Queue.empty[BlockRef]
queue ++= getAdjancedConnected(world, core, core, seen)
while (queue.size > 0) {
val current = queue.dequeue()
seen.add(current)
queue ++= getAdjancedConnected(world, core, current, seen)
}
return seen.toSet
}
}
@@ -0,0 +1,44 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.block
import net.bdew.lib.block.{BlockRef, HasTE}
import net.bdew.lib.multiblock.ResourceProvider
import net.bdew.lib.multiblock.tile.TileController
import net.bdew.lib.render.connected.ConnectedTextureBlock
import net.minecraft.block.Block
import net.minecraft.block.material.Material
import net.minecraft.entity.player.EntityPlayer
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 {
def resources: ResourceProvider
override def edgeIcon = resources.edge
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) =
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 = {
if (player.isSneaking) return false
if (world.isRemote) return true
getTE(world, x, y, z).onClick(player)
return true
}
}
@@ -0,0 +1,69 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.block
import net.bdew.lib.block.{BlockRef, HasTE}
import net.bdew.lib.multiblock.tile.TileModule
import net.bdew.lib.multiblock.{ResourceProvider, Tools}
import net.bdew.lib.render.connected.ConnectedTextureBlock
import net.minecraft.block.Block
import net.minecraft.block.material.Material
import net.minecraft.entity.EntityLivingBase
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.util.ChatComponentTranslation
import net.minecraft.world.{IBlockAccess, World}
abstract class BlockModule[T <: TileModule](val name: String, val kind: String, material: Material, val TEClass: Class[T])
extends Block(material) with HasTE[T] with ConnectedTextureBlock {
def resources: ResourceProvider
override def edgeIcon = resources.edge
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) {
getTE(world, x, y, z).tryConnect()
}
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) {
getTE(world, x, y, z).onBreak()
super.breakBlock(world, x, y, z, block, meta)
}
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
})
}
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)
(for {
p <- te.connected.cval
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"))
}
true
}
}
@@ -0,0 +1,43 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
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.minecraft.world.IBlockAccess
import net.minecraftforge.common.util.ForgeDirection
trait BlockOutput[T <: TileOutput[_]] extends BlockModule[T] with BlockAdditionalRender {
def getAdjancedFaces(face: ForgeDirection, bp: BlockRef) = {
val sides = ConnectedHelper.faceAdjanced(face)
Seq(
(BlockFace(bp, sides.top), resources.arrowTop),
(BlockFace(bp, sides.right), resources.arrowRight),
(BlockFace(bp, sides.bottom), resources.arrowBottom),
(BlockFace(bp, sides.left), resources.arrowLeft)
)
}
def getFaceOverlays(world: IBlockAccess, x: Int, y: Int, z: Int, face: ForgeDirection): List[FaceOverlay] = {
var result = List.empty[FaceOverlay]
Option(getTE(world, x, y, z)) flatMap (_.getCore) map { core =>
val bf = BlockFace(x, y, z, face)
if (core.outputFaces.contains(bf))
result :+= FaceOverlay(resources.output, resources.outputColors(core.outputFaces(bf)))
for ((bf, icon) <- getAdjancedFaces(face, bf.origin)) {
if (core.outputFaces.contains(bf))
result :+= FaceOverlay(icon, resources.outputColors(core.outputFaces(bf)))
}
}
return result
}
}
@@ -0,0 +1,47 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.data
import net.bdew.lib.Misc
import net.bdew.lib.block.BlockFace
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
import net.minecraft.nbt.{NBTTagCompound, NBTTagIntArray, NBTTagList}
import net.minecraftforge.common.util.ForgeDirection
case class DataSlotBlockFaceMap(name: String, parent: TileDataSlots) 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 save(t: NBTTagCompound, kind: UpdateKind.Value) {
val lst = new NBTTagList()
for (x <- map) lst.appendTag(new NBTTagIntArray(ent2arr(x)))
t.setTag(name, lst)
}
def load(t: NBTTagCompound, kind: UpdateKind.Value) {
map.clear()
map ++= Misc.iterNbtIntArray(t, name) map arr2ent
}
def updated() = parent.dataSlotChanged(this)
}
object DataSlotBlockFaceMap {
import scala.language.implicitConversions
implicit def dsbfm2map(v: DataSlotBlockFaceMap) = v.map
}
@@ -0,0 +1,60 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.data
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
case class DataSlotOutputConfig(name: String, parent: TileDataSlots, slots: Int) extends DataSlot {
val map = collection.mutable.Map.empty[Int, OutputConfig]
setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
def inverted = map.map(_.swap)
def save(t: NBTTagCompound, kind: UpdateKind.Value) {
for ((n, x) <- map) {
val tmp = new NBTTagCompound()
x.write(tmp)
val kind = x match {
case _: OutputConfigPower => "power"
case _: OutputConfigFluid => "fluid"
case _ => sys.error("Unknown output config kind: " + x)
}
tmp.setString("kind", kind)
t.setTag(name + "_" + n, tmp)
}
}
def load(t: NBTTagCompound, kind: UpdateKind.Value) {
map.clear()
for (i <- 0 until slots) {
if (t.hasKey(name + "_" + i)) {
val cfg = t.getCompoundTag(name + "_" + i)
val cfgObj = cfg.getString("kind") match {
case "power" => new OutputConfigPower
case "fluid" => new OutputConfigFluid
case _ => new OutputConfigInvalid
}
cfgObj.read(cfg)
map += i -> cfgObj
}
}
}
def updated() = parent.dataSlotChanged(this)
}
object DataSlotOutputConfig {
import scala.language.implicitConversions
implicit def dsbfm2map(v: DataSlotOutputConfig) = v.map
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.data
import net.bdew.lib.Misc
import net.bdew.lib.block.BlockRef
import net.bdew.lib.data.DataSlotOption
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind}
import net.minecraft.nbt.NBTTagCompound
case class DataSlotPos(name: String, parent: TileDataSlots) extends DataSlotOption[BlockRef] {
setUpdate(UpdateKind.SAVE, UpdateKind.WORLD)
def save(t: NBTTagCompound, kind: UpdateKind.Value) {
cval map (x => t.setTag(name, Misc.applyMutator(x.writeToNBT, new NBTTagCompound)))
}
def load(t: NBTTagCompound, kind: UpdateKind.Value) {
cval = if (t.hasKey(name))
Some(BlockRef.fromNBT(t.getCompoundTag(name)))
else
None
}
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.data
import net.bdew.lib.Misc
import net.bdew.lib.block.BlockRef
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
import net.minecraft.nbt.{NBTTagCompound, NBTTagList}
case class DataSlotPosSet(name: String, parent: TileDataSlots) extends DataSlot {
val set = collection.mutable.Set.empty[BlockRef]
setUpdate(UpdateKind.SAVE, UpdateKind.WORLD)
def save(t: NBTTagCompound, kind: UpdateKind.Value) {
val lst = new NBTTagList()
for (x <- set) lst.appendTag(Misc.applyMutator(x.writeToNBT, new NBTTagCompound))
t.setTag(name, lst)
}
def load(t: NBTTagCompound, kind: UpdateKind.Value) {
set.clear()
set ++= Misc.iterNbtCompoundList(t, name) map BlockRef.fromNBT
}
def updated() = parent.dataSlotChanged(this)
}
object DataSlotPosSet {
import scala.language.implicitConversions
implicit def dsps2set(v: DataSlotPosSet) = v.set
}
@@ -0,0 +1,26 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.data
import net.bdew.lib.multiblock.network.MsgOutputCfg
import net.minecraft.nbt.NBTTagCompound
import sun.reflect.generics.reflectiveObjects.NotImplementedException
abstract class OutputConfig {
def read(t: NBTTagCompound)
def write(t: NBTTagCompound)
def handleConfigPacket(m: MsgOutputCfg)
}
class OutputConfigInvalid extends OutputConfig {
def read(t: NBTTagCompound) {}
def write(t: NBTTagCompound) = throw new NotImplementedException
def handleConfigPacket(m: MsgOutputCfg) = throw new NotImplementedException
}
@@ -0,0 +1,39 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.multiblock.data
import net.bdew.lib.multiblock.network.MsgOutputCfg
import net.minecraft.nbt.NBTTagCompound
class OutputConfigFluid extends OutputConfig with OutputConfigRSControllable {
var avg = 0.0
var rsMode = RSMode.ALWAYS
final val decay = 0.5
def updateAvg(v: Double) {
avg = avg * decay + (1 - decay) * v
}
def read(t: NBTTagCompound) {
avg = t.getDouble("avg")
rsMode = RSMode(t.getInteger("rsMode"))
}
def write(t: NBTTagCompound) {
t.setDouble("avg", avg)
t.setInteger("rsMode", rsMode.id)
}
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))
}
}
@@ -0,0 +1,41 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
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 {
var avg = 0.0
var rsMode = RSMode.ALWAYS
final val decay = 0.5
def updateAvg(v: Double) {
avg = avg * decay + (1 - decay) * v
}
def read(t: NBTTagCompound) {
avg = t.getDouble("avg")
rsMode = RSMode(t.getInteger("rsMode"))
unit = t.getString("unit")
}
def write(t: NBTTagCompound) {
t.setDouble("avg", avg)
t.setInteger("rsMode", rsMode.id)
t.setString("unit", unit)
}
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))
}
}
@@ -0,0 +1,18 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.multiblock.data
import net.bdew.lib.multiblock.network.MsgOutputCfg
case class MsgOutputCfgRSMode(output: Int, rsMode: RSMode.Value) extends MsgOutputCfg
trait OutputConfigRSControllable extends OutputConfig {
var rsMode: RSMode.Value
}
@@ -0,0 +1,17 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.data
object RSMode extends Enumeration {
val ALWAYS = Value(0, "ALWAYS")
val RS_ON = Value(1, "RS_ON")
val RS_OFF = Value(2, "RS_OFF")
val NEVER = Value(3, "NEVER")
}
@@ -0,0 +1,28 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.gui
import net.bdew.lib.gui.widgets.Widget
import net.bdew.lib.gui.{Color, Point, Rect, Texture}
import scala.collection.mutable
class WidgetInfo(val rect: Rect, icon: Texture, text: => String, tooltip: => String) extends Widget {
final val iconRect = Rect(1, 1, 8, 8)
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
if (iconRect.contains(p) && tooltip != null) tip += tooltip
}
override def draw(mouse: Point) {
parent.drawTexture(iconRect + rect.origin, icon)
parent.drawText(text, rect.origin +(12, 1), Color.darkgray, false)
}
}
@@ -0,0 +1,52 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.gui
import net.bdew.lib.Misc
import net.bdew.lib.gui.widgets.Widget
import net.bdew.lib.gui.{Point, Rect, Texture}
import net.bdew.lib.multiblock.interact.CIOutputFaces
import net.bdew.lib.render.connected.BlockAdditionalRender
import scala.collection.mutable
class WidgetOutputIcon(p: Point, te: CIOutputFaces, output: Int) extends Widget {
val rect = new Rect(p, 16, 16)
override def draw(mouse: Point) {
val faces = te.outputFaces.inverted
if (faces.isDefinedAt(output)) {
val bf = faces(output)
bf.origin.block(te.getWorldObj) map { block =>
parent.drawTexture(rect, Texture(Texture.BLOCKS, block.getIcon(te.getWorldObj, bf.origin.x, bf.origin.y, bf.origin.z, bf.face.ordinal())))
if (block.isInstanceOf[BlockAdditionalRender]) {
for (over <- block.asInstanceOf[BlockAdditionalRender].getFaceOverlays(te.getWorldObj, bf.origin.x, bf.origin.y, bf.origin.z, bf.face))
parent.drawTexture(rect, Texture(Texture.BLOCKS, over.icon), over.color)
}
}
} else {
parent.drawTexture(rect, Texture(Texture.BLOCKS, te.resources.disabled), te.resources.outputColors(output))
}
}
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
val faces = te.outputFaces.inverted
tip += Misc.toLocal(te.resources.unlocalizedOutputName(output))
if (faces.isDefinedAt(output)) {
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))
}
} else {
tip += Misc.toLocal("bdlib.multiblock.disabled")
}
}
}
@@ -0,0 +1,47 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.multiblock.gui
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.interact.CIOutputFaces
import net.bdew.lib.multiblock.network.NetHandler
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 icons = Map(
RSMode.ALWAYS -> te.resources.btEnabled,
RSMode.NEVER -> te.resources.btDisabled,
RSMode.RS_ON -> te.resources.btRsOn,
RSMode.RS_OFF -> te.resources.btRsOff
)
val next = Map(
RSMode.ALWAYS -> RSMode.RS_ON,
RSMode.RS_ON -> RSMode.RS_OFF,
RSMode.RS_OFF -> RSMode.NEVER,
RSMode.NEVER -> RSMode.ALWAYS
)
override def draw(mouse: Point) {
bt.icon = icons(cfg.rsMode)
bt.hover = Misc.toLocal("bdlib.rsmode." + cfg.rsMode.toString.toLowerCase)
super.draw(mouse)
}
def clicked(b: WidgetButtonIcon) {
NetHandler.sendToServer(MsgOutputCfgRSMode(output, next(cfg.rsMode)))
}
}
@@ -0,0 +1,19 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.interact
import net.bdew.lib.multiblock.tile.TileController
import net.minecraftforge.fluids.{Fluid, FluidStack, FluidTankInfo}
trait CIFluidInput extends TileController {
def inputFluid(resource: FluidStack, doFill: Boolean): Int
def canInputFluid(fluid: Fluid): Boolean
def getTankInfo: Array[FluidTankInfo]
}
@@ -0,0 +1,19 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.multiblock.interact
import net.minecraftforge.fluids.{Fluid, FluidStack, FluidTankInfo}
trait CIFluidOutput extends CIOutputFaces {
def outputFluid(resource: FluidStack, doDrain: Boolean): FluidStack
def outputFluid(ammount: Int, doDrain: Boolean): FluidStack
def canOutputFluid(fluid: Fluid): Boolean
def getTankInfo: Array[FluidTankInfo]
}
@@ -0,0 +1,71 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.interact
import net.bdew.lib.block.{BlockFace, BlockRef}
import net.bdew.lib.multiblock.data._
import net.bdew.lib.multiblock.tile.{TileController, TileModule}
import net.minecraft.util.ChatComponentTranslation
import net.minecraftforge.common.util.ForgeDirection
trait CIOutputFaces extends TileController {
val maxOutputs: Int
val outputFaces = new DataSlotBlockFaceMap("outputs", this)
val outputConfig = new DataSlotOutputConfig("cfg", this, maxOutputs)
def newOutput(bp: BlockRef, face: ForgeDirection, cfg: OutputConfig): Int = {
val bf = BlockFace(bp, face)
if (outputFaces.contains(bf)) {
println("Adding already registered output??? " + bf.toString)
return outputFaces(bf)
}
val rv = outputFaces.inverted
for (i <- 0 until maxOutputs if !rv.contains(i)) {
outputFaces += (bf -> i)
outputConfig += i -> cfg
outputFaces.updated()
return i
}
val pl = getWorldObj.getClosestPlayer(bf.x, bf.y, bf.z, 10)
if (pl != null) pl.addChatMessage(new ChatComponentTranslation("bdlib.multiblock.toomanyoutputs"))
return -1
}
serverTick.listen(doOutputs)
override def moduleRemoved(module: TileModule) {
for ((bf, n) <- outputFaces if bf.origin == module.mypos) {
outputFaces -= bf
outputConfig -= n
}
outputFaces.updated()
outputConfig.updated()
super.moduleRemoved(module)
}
def doOutputs() {
for {
(x, n) <- outputFaces
t <- x.origin.getTile[MIOutput[_]](getWorldObj)
} {
if (!outputConfig.isDefinedAt(n) || !t.outputConfigType.isInstance(outputConfig(n)))
outputConfig(n) = t.makeCfgObject(x.face)
t.doOutput(x.face, outputConfig(n).asInstanceOf[t.OCType])
}
}
def removeOutput(bp: BlockRef, face: ForgeDirection) {
val bf = BlockFace(bp, face)
outputConfig -= outputFaces(bf)
outputFaces -= bf
outputFaces.updated()
}
}
@@ -0,0 +1,14 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.interact
trait CIPowerProducer extends CIOutputFaces {
def extract(v: Float, simulate: Boolean): Float
}
@@ -0,0 +1,16 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.interact
import net.minecraft.inventory.Container
trait ContainerOutputFaces extends Container {
def te: CIOutputFaces
}
@@ -0,0 +1,23 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.interact
import net.bdew.lib.multiblock.data.OutputConfig
import net.bdew.lib.multiblock.tile.TileModule
import net.minecraftforge.common.util.ForgeDirection
trait MIOutput[T <: OutputConfig] extends TileModule {
val outputConfigType: Class[T]
type OCType = T
def doOutput(face: ForgeDirection, cfg: OCType)
def makeCfgObject(face: ForgeDirection): OutputConfig
}
@@ -0,0 +1,16 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.network
import net.bdew.lib.network.Message
abstract class MsgOutputCfg extends Message {
val output: Int
}
@@ -0,0 +1,23 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.network
import net.bdew.lib.multiblock.interact.ContainerOutputFaces
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()
}
}
@@ -0,0 +1,21 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* http://bdew.net/minecraft-mod-public-license/
*/
package net.bdew.lib.multiblock.tile
import net.bdew.lib.multiblock.data.{OutputConfigRSControllable, RSMode}
import net.minecraft.tileentity.TileEntity
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)
}
}
@@ -0,0 +1,91 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.tile
import net.bdew.lib.BdLib
import net.bdew.lib.block.BlockRef
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind}
import net.bdew.lib.multiblock.block.BlockModule
import net.bdew.lib.multiblock.data.DataSlotPosSet
import net.bdew.lib.multiblock.{MachineCore, ResourceProvider, Tools}
import net.minecraft.entity.player.EntityPlayer
trait TileController extends TileDataSlots {
val modules = new DataSlotPosSet("modules", this).setUpdate(UpdateKind.WORLD, UpdateKind.SAVE, UpdateKind.RENDER)
def resources: ResourceProvider
def cfg: MachineCore
var acceptNewModules = true
var revalidateOnNextTick = true
var modulesChanged = true
lazy val mypos = BlockRef(xCoord, yCoord, zCoord)
def getNumOfMoudules(kind: String) = modules.map(_.getTile[TileModule](getWorldObj)).flatten.count(_.kind == kind)
def onModulesChanged()
def onClick(player: EntityPlayer)
def moduleConnected(module: TileModule): Boolean = {
if (acceptNewModules) {
modules.add(BlockRef(module.xCoord, module.yCoord, module.zCoord))
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
modulesChanged = true
return true
} else false
}
def moduleRemoved(module: TileModule) {
modules.remove(BlockRef(module.xCoord, module.yCoord, module.zCoord))
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
revalidateOnNextTick = true
modulesChanged = true
}
def onBreak() {
acceptNewModules = false
for (x <- modules.flatMap(_.getTile[TileModule](getWorldObj)))
x.coreRemoved()
modules.clear()
}
def validateModules() {
modules.filter(x => {
!x.getTile[TileModule](getWorldObj).isDefined || !x.getBlock[BlockModule[TileModule]](getWorldObj).isDefined
}).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))
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)) })
}
serverTick.listen(() => {
if (revalidateOnNextTick) {
revalidateOnNextTick = false
validateModules()
}
if (modulesChanged) {
modulesChanged = false
onModulesChanged()
lastChange = getWorldObj.getTotalWorldTime
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
}
})
}
@@ -0,0 +1,31 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.tile
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.util.{ChatComponentTranslation, ChatStyle, EnumChatFormatting}
abstract class TileControllerGui extends TileController {
def openGui(player: EntityPlayer)
def onClick(player: EntityPlayer) = {
val missing = cfg.required.filter({ case (mod, cnt) => getNumOfMoudules(mod) < cnt })
if (missing.size > 0) {
player.addChatMessage(new ChatComponentTranslation("bdlib.multiblock.incomplete")
.setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED)))
for ((mod, cnt) <- missing)
player.addChatMessage(
new ChatComponentTranslation("- %s %s", Integer.valueOf(cnt),
new ChatComponentTranslation(resources.getModuleName(mod)))
.setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED)))
} else openGui(player)
}
}
@@ -0,0 +1,57 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.tile
import net.bdew.lib.block.BlockRef
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind}
import net.bdew.lib.multiblock.Tools
import net.bdew.lib.multiblock.data.DataSlotPos
import scala.reflect.ClassTag
trait TileModule extends TileDataSlots {
val kind: String
val connected = new DataSlotPos("connected", this).setUpdate(UpdateKind.WORLD, UpdateKind.SAVE, UpdateKind.RENDER)
def getCoreAs[T <: TileController : ClassTag] = connected flatMap (_.getTile[T](getWorldObj))
def getCore = getCoreAs[TileController]
lazy val mypos = BlockRef(xCoord, yCoord, zCoord)
def connect(target: TileController) {
if (target.moduleConnected(this)) {
connected.set(target.mypos)
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
getWorldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, getBlockType)
}
}
def coreRemoved() {
connected.unset()
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
getWorldObj.notifyBlocksOfNeighborChange(xCoord, yCoord, zCoord, getBlockType)
}
def onBreak() {
getCore map (_.moduleRemoved(this))
}
def tryConnect() {
if (getCore.isEmpty) {
for {
conn <- Tools.findConnections(getWorldObj, mypos, kind).headOption
core <- conn.getTile[TileController](getWorldObj)
} {
connect(core)
}
}
}
}
@@ -0,0 +1,67 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.multiblock.tile
import net.bdew.lib.Misc
import net.bdew.lib.block.BlockFace
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] {
override def getCore = getCoreAs[CIOutputFaces]
def makeCfgObject(face: ForgeDirection): T
var rescanFaces = false
def getCfg(dir: ForgeDirection): Option[T] =
for {
core <- getCore
onum <- core.outputFaces.get(BlockFace(mypos, dir))
cfggen <- core.outputConfig.get(onum)
cfg <- Misc.asInstanceOpt(cfggen, outputConfigType)
} yield cfg
serverTick.listen(() => {
if (rescanFaces) {
rescanFaces = false
doRescanFaces()
}
})
override def tryConnect() {
super.tryConnect()
if (connected.isDefined) rescanFaces = true
}
def canConnectoToFace(d: ForgeDirection): Boolean
def onConnectionsChanged(added: Set[ForgeDirection], removed: Set[ForgeDirection]) {}
def doRescanFaces() {
getCore map { core =>
val connections = (
ForgeDirection.VALID_DIRECTIONS
filterNot { dir => core.modules.contains(mypos.neighbour(dir)) }
filter canConnectoToFace
).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))
toAdd.foreach(x => core.newOutput(mypos, x, makeCfgObject(x)))
if (toAdd.size > 0 || toRemove.size > 0) {
onConnectionsChanged(toAdd, toRemove)
getWorldObj.markBlockForUpdate(xCoord, yCoord, zCoord)
}
}
}
}
+12
View File
@@ -0,0 +1,12 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
* License 1.0, or MMPL. Please check the contents of the license located in
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.network
abstract class Message extends Serializable
+25 -25
View File
@@ -9,63 +9,63 @@
package net.bdew.lib.network
import cpw.mods.fml.common.network.{FMLOutboundHandler, NetworkRegistry}
import java.util
import cpw.mods.fml.common.network.{FMLEmbeddedChannel, FMLOutboundHandler, NetworkRegistry}
import cpw.mods.fml.relauncher.Side
import net.minecraft.nbt.NBTTagCompound
import io.netty.channel.{ChannelFutureListener, ChannelHandler}
import net.bdew.lib.{BdLib, Misc}
import net.minecraft.entity.player.EntityPlayerMP
import io.netty.channel.{ChannelHandler, ChannelFutureListener}
class NetChannel(val name: String) {
val channels = NetworkRegistry.INSTANCE.newChannel(name, new NBTMessageToMessageCodec)
var channels: util.EnumMap[Side, FMLEmbeddedChannel] = null
var serverHandlers = Map.empty[String, (NBTTagCompound, EntityPlayerMP) => Unit]
var clientHandlers = Map.empty[String, (NBTTagCompound) => Unit]
def init() {
channels = NetworkRegistry.INSTANCE.newChannel(name, new SerializedMessageCodec)
BdLib.logInfo("Initialized network channel '%s' for mod '%s'", name, Misc.getActiveModId)
addHandler(Side.SERVER, new NetChannelServerHandler(this))
addHandler(Side.CLIENT, new NetChannelClientHandler(this))
}
def regServerHandler(id: String, callable: (NBTTagCompound, EntityPlayerMP) => Unit) =
if (serverHandlers.contains(id))
sys.error("Command name already in use: %s".format(name))
else
serverHandlers += (id -> callable)
var clientChain = PartialFunction.empty[Message, Unit]
var serverChain = PartialFunction.empty[(Message, EntityPlayerMP), Unit]
def regClientHandler(id: String, callable: (NBTTagCompound) => Unit) =
if (clientHandlers.contains(id))
sys.error("Command name already in use: %s".format(name))
else
clientHandlers += (id -> callable)
def regServerHandler(f: PartialFunction[(Message, EntityPlayerMP), Unit]) =
serverChain = serverChain.orElse(f)
addHandler(Side.SERVER, new NetChannelServerHandler(this))
addHandler(Side.CLIENT, new NetChannelClientHandler(this))
def regClientHandler(f: PartialFunction[Message, Unit]) =
clientChain = clientChain.orElse(f)
def addHandler(side: Side, handler: ChannelHandler) {
private def addHandler(side: Side, handler: ChannelHandler) {
val ch = channels.get(side)
val name = ch.findChannelHandlerNameForType(classOf[NBTMessageToMessageCodec])
val name = ch.findChannelHandlerNameForType(classOf[SerializedMessageCodec])
ch.pipeline().addAfter(name, side + "Handler", handler)
}
def sendToAll(message: NBTTagCompound) {
def sendToAll(message: Message) {
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL)
channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
}
def sendTo(message: NBTTagCompound, player: EntityPlayerMP) {
def sendTo(message: Message, player: EntityPlayerMP) {
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER)
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player)
channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
}
def sendToAllAround(message: NBTTagCompound, point: NetworkRegistry.TargetPoint) {
def sendToAllAround(message: Message, point: NetworkRegistry.TargetPoint) {
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT)
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point)
channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
}
def sendToDimension(message: NBTTagCompound, dimensionId: Int) {
def sendToDimension(message: Message, dimensionId: Int) {
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION)
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(new Integer(dimensionId))
channels.get(Side.SERVER).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
}
def sendToServer(message: NBTTagCompound) {
def sendToServer(message: Message) {
channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER)
channels.get(Side.CLIENT).writeAndFlush(message).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE)
}
@@ -10,15 +10,17 @@
package net.bdew.lib.network
import io.netty.channel.{ChannelHandlerContext, SimpleChannelInboundHandler}
import net.minecraft.nbt.NBTTagCompound
import net.bdew.lib.BdLib
class NetChannelClientHandler(ch: NetChannel) extends SimpleChannelInboundHandler[NBTTagCompound] {
def channelRead0(ctx: ChannelHandlerContext, msg: NBTTagCompound) {
val cmd = msg.getString("_cmd")
ch.clientHandlers.getOrElse(cmd, {
BdLib.log.error("Unknown command: '%s' from server".format(cmd))
return
})(msg)
class NetChannelClientHandler(ch: NetChannel) extends SimpleChannelInboundHandler[Message] {
def channelRead0(ctx: ChannelHandlerContext, msg: Message) {
try {
if (ch.clientChain.isDefinedAt(msg))
ch.clientChain(msg)
else
BdLib.logWarn("Unable to handle message from server: %s", msg)
} catch {
case e: Throwable => BdLib.logErrorException("Error handling packet", e)
}
}
}
@@ -9,19 +9,21 @@
package net.bdew.lib.network
import io.netty.channel.{ChannelHandlerContext, SimpleChannelInboundHandler}
import net.minecraft.nbt.NBTTagCompound
import cpw.mods.fml.common.network.NetworkRegistry
import net.minecraft.network.NetHandlerPlayServer
import io.netty.channel.{ChannelHandlerContext, SimpleChannelInboundHandler}
import net.bdew.lib.BdLib
import net.minecraft.network.NetHandlerPlayServer
class NetChannelServerHandler(ch: NetChannel) extends SimpleChannelInboundHandler[NBTTagCompound] {
def channelRead0(ctx: ChannelHandlerContext, msg: NBTTagCompound) {
val cmd = msg.getString("_cmd")
val nh = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get.asInstanceOf[NetHandlerPlayServer].playerEntity
ch.serverHandlers.getOrElse(cmd, {
BdLib.log.error("Unknown command: '%s' from '%s'".format(cmd, nh.getCommandSenderName))
return
})(msg, nh)
class NetChannelServerHandler(ch: NetChannel) extends SimpleChannelInboundHandler[Message] {
def channelRead0(ctx: ChannelHandlerContext, msg: Message) {
try {
val player = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get.asInstanceOf[NetHandlerPlayServer].playerEntity
if (ch.serverChain.isDefinedAt(msg, player))
ch.serverChain(msg, player)
else
BdLib.logWarn("Unable to handle message from user %s: %s", player.getDisplayName, msg)
} catch {
case e: Throwable => BdLib.logErrorException("Error handling packet", e)
}
}
}
@@ -9,30 +9,31 @@
package net.bdew.lib.network
import io.netty.handler.codec.MessageToMessageCodec
import cpw.mods.fml.common.network.internal.FMLProxyPacket
import net.minecraft.nbt.{CompressedStreamTools, NBTTagCompound}
import io.netty.channel.ChannelHandlerContext
import java.io.{ObjectInputStream, ObjectOutputStream}
import java.util
import java.io.{DataInputStream, DataOutputStream}
import io.netty.buffer.{ByteBufInputStream, ByteBufOutputStream, Unpooled}
import cpw.mods.fml.common.network.NetworkRegistry
import cpw.mods.fml.common.network.internal.FMLProxyPacket
import io.netty.buffer.{ByteBufInputStream, ByteBufOutputStream, Unpooled}
import io.netty.channel.ChannelHandler.Sharable
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.MessageToMessageCodec
import net.bdew.lib.BdLib
@Sharable
class NBTMessageToMessageCodec extends MessageToMessageCodec[FMLProxyPacket, NBTTagCompound] {
def encode(ctx: ChannelHandlerContext, msg: NBTTagCompound, out: util.List[AnyRef]) {
class SerializedMessageCodec extends MessageToMessageCodec[FMLProxyPacket, Message] {
def encode(ctx: ChannelHandlerContext, msg: Message, out: util.List[AnyRef]) {
val buff = Unpooled.buffer()
val writer = new DataOutputStream(new ByteBufOutputStream(buff))
CompressedStreamTools.write(msg, writer)
val writer = new ObjectOutputStream(new ByteBufOutputStream(buff))
writer.writeObject(msg)
val pkt = new FMLProxyPacket(buff, ctx.channel.attr(NetworkRegistry.FML_CHANNEL).get)
out.add(pkt)
}
def decode(ctx: ChannelHandlerContext, msg: FMLProxyPacket, out: util.List[AnyRef]) {
try {
val stream = new DataInputStream(new ByteBufInputStream(msg.payload()))
out.add(CompressedStreamTools.read(stream))
val reader = new ObjectInputStream(new ByteBufInputStream(msg.payload()))
out.add(reader.readObject())
} catch {
case e: Throwable => BdLib.log.error("Error decoding packet", e)
}
+2 -2
View File
@@ -9,10 +9,10 @@
package net.bdew.lib.power
import net.minecraft.nbt.NBTTagCompound
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind, DataSlot}
import net.bdew.lib.Misc
import net.bdew.lib.data.base.{DataSlot, TileDataSlots, UpdateKind}
import net.bdew.lib.machine.PoweredMachine
import net.minecraft.nbt.NBTTagCompound
case class DataSlotPower(name: String, parent: TileDataSlots) extends DataSlot {
updateKind = Set(UpdateKind.GUI, UpdateKind.SAVE)
+1 -1
View File
@@ -9,9 +9,9 @@
package net.bdew.lib.power
import net.minecraft.item.{ItemStack, Item}
import net.bdew.lib.Misc
import net.minecraft.entity.EntityLivingBase
import net.minecraft.item.{Item, ItemStack}
import net.minecraft.nbt.NBTTagCompound
trait ItemPoweredBase extends Item {
@@ -9,11 +9,11 @@
package net.bdew.lib.power
import net.bdew.lib.tile.TileExtended
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots}
import net.bdew.lib.tile.inventory.{BreakableInventoryTile, SidedInventory, PersistentInventoryTile}
import net.bdew.lib.data.DataSlotFloat
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind}
import net.bdew.lib.machine.ProcessorMachine
import net.bdew.lib.tile.TileExtended
import net.bdew.lib.tile.inventory.{BreakableInventoryTile, PersistentInventoryTile, SidedInventory}
abstract class TileBaseProcessor extends TileExtended
with TileDataSlots
+1 -1
View File
@@ -9,8 +9,8 @@
package net.bdew.lib.power
import net.bdew.lib.tile.TileExtended
import net.bdew.lib.machine.PoweredMachine
import net.bdew.lib.tile.TileExtended
trait TilePoweredBase extends TileExtended {
def power: DataSlotPower
Loaded 100 of 122 files, more files were not shown because too many files have changed in this diff. Show more