Compare commits

..
60 Commits
Author SHA1 Message Date
bdew da3e58b44b Reworked cover system to store full itemstack of the cover (for stuff like filter covers to have a place to store data) 2014-06-01 16:53:51 +03:00
bdew 5bac374211 Added cover upgrades system 2014-06-01 15:07:54 +03:00
bdew e41e203b7e Added Misc.forgeDirection, Misc.asInstanceOpt, Misc.getNeighbourTile and ItemUtils.getAccessibleSlotsFromSide helpers 2014-06-01 15:07:33 +03:00
bdew 0b87dd83e7 Fixed tile entity names not being scoped, should prevent collisions 2014-05-29 11:24:24 +03:00
bdew 49a2f0baec Fix NPE in getBiomeByName (bdew/gendustry#22) 2014-05-13 02:15:57 +03:00
bdew 2a995f1c05 Added Misc.hasLocal 2014-05-04 15:40:04 +03:00
bdew 423351bfee Added ItemUtils.copyWithRandomSize (inspired by forestry) 2014-05-04 15:39:47 +03:00
bdew 0831386798 Added hex numbers support in config parser (0x12345678) 2014-04-29 16:10:41 +03:00
bdew 0b45c61c51 ConfigSection.getColor now accepts numeric values, added Color.fromInt 2014-04-29 16:10:15 +03:00
bdew 65aa8a0f66 Use the right logger in LootListLoader, added a version of resolve to use outside config sections 2014-04-28 13:39:43 +03:00
bdew 446f2b6e60 Added loot list sections to recipe parser 2014-04-24 16:49:57 +03:00
bdew 926f006f68 Bumped version number 2014-04-02 17:52:23 +03:00
bdew 4697c96cf2 Added ItemUtils.findItemInInventory 2014-04-02 17:47:57 +03:00
bdew 8891cfff06 Added extractor (for scala pattern matching) for ItemStack 2014-03-19 11:28:34 +02:00
bdew 971fd94532 Cleanup 2014-03-18 12:01:34 +02:00
bdew a9e1e88ff2 Added object for misc clientside functions 2014-03-18 12:01:25 +02:00
bdew c9c014a3a9 Added misc method to find biome by name 2014-03-17 17:23:35 +02:00
bdew 3001309a85 Config parser/loader changes: IfOreDict can now contain only delayed statements and is a delayed statement itself (will be evaluated when loadDealayed is called)
Also 2 new terms added at parser level - delayedStatement(s) - to separate lists that require delayed statements
2014-03-13 12:02:48 +02:00
bdew 07fbbb0267 Workaround for ItemInventory crashing on servers (scala synthetic methods not keeping annotations) 2014-03-09 12:21:53 +02:00
bdew 561f176682 Added workaround for bug in GuiContainer - not resetting color when rendering background icon 2014-03-04 16:32:59 +02:00
bdew 5f9c311f41 Fixed BaseScreen not drawing the background in correct position 2014-02-27 11:13:40 +02:00
bdew c2a1cc09e3 Widget.bindTexture is useless now 2014-02-27 09:43:01 +02:00
bdew 273735a976 Widget(Dyn)Label should use DrawTarget.drawText 2014-02-27 09:35:43 +02:00
bdew 26137a88d7 Added a separate method to Widget that draws the background layer 2014-02-27 09:33:26 +02:00
bdew 81a0d00a8b Why did i make that a double? 0.o (closes #2) 2014-02-27 09:31:19 +02:00
bdew 5d7c0cd5e8 GUI/texture refactoring 2014-02-26 17:48:53 +02:00
bdew 4e2df02b8a added alpha component to Color 2014-02-24 20:52:38 +02:00
bdew 82e88157f2 Fixed drawTextureScaled and made the code more readable 2014-02-24 20:52:00 +02:00
bdew 7b588d896d Added some color constants 2014-02-24 11:43:38 +02:00
bdew 938ea4f3d5 EntryNumList can be converted used as color 2014-02-24 11:34:29 +02:00
bdew 1541b96a5a Added support for number lists in config 2014-02-24 11:28:08 +02:00
bdew 17329115a2 made ItemPreloader easier to use 2014-02-20 18:03:34 +02:00
bdew 3966305a61 Added IconPreloader 2014-02-20 12:35:58 +02:00
bdew 31573cc8fc Allow negative numbers in config (derp!) 2014-02-17 17:54:34 +02:00
bdew 563ae0a328 Use main logger as the parent for RecipeLoader 2014-02-17 17:54:13 +02:00
bdew 13cef01a2d Added helper classes for items that have and inventory and a gui 2014-02-17 12:26:20 +02:00
bdew 1296b32110 Added log object, fixed missing annotation, fixed copyright headers 2014-02-17 12:25:56 +02:00
bdew 78a69acc44 Bumping version 2014-02-01 13:06:39 +02:00
bdew e3bf80e1c9 Added WidgetDynLabel 2014-02-01 12:25:00 +02:00
bdew f4f126fed2 Added WidgetContainer.drawTextureScaled 2014-02-01 12:24:36 +02:00
bdew 97b3e0ea1d added WidgetMultipane 2014-01-26 02:17:18 +02:00
bdew 9f6e2d7533 WidgetContainer draw functions now take color 2014-01-26 02:17:04 +02:00
bdew 9819600b15 Fixed wrong mouse offset in handleTooltip 2014-01-23 17:49:36 +02:00
bdew 12a1327e53 Refactoring widget system to allow containers, added button widget 2014-01-23 17:40:03 +02:00
bdew c495fb8b33 Fixed WidgetFluidGauge not respecting it's width 2014-01-21 17:21:50 +02:00
bdew 0b94b006ec Fixed DataSlotTank not changing to empty state 2014-01-18 19:00:07 +02:00
bdew c4dbda8a20 Added ConfigSection.hasValue to check if a value is present 2014-01-17 21:41:20 +02:00
bdew 2698d93444 Split BaseContainer into NoInvContainer for stuff that doesn't need the tile to be an inventory 2014-01-17 21:40:54 +02:00
bdew b4cc77d3cc Removed redundant size field on DataSlotTank, fixed div by 0 crash with the widget 2014-01-17 21:39:25 +02:00
bdew 2c94505c97 Added UpdateKind.RENDER - data slots with this flag will cause the block to be re-rendered on the client after it's synced from the server 2014-01-15 18:08:09 +02:00
bdew 2c3607e113 Fixed config parser not recognizing ifOreDict 2014-01-14 23:49:54 +02:00
bdew b34192d8c2 Updated copyright header 2014-01-13 20:40:45 +02:00
bdew 0212f20f69 Bump version for release 2014-01-13 19:56:54 +02:00
bdew 3b31e285d2 Added a slot trait that intercepts clicks 2013-12-31 12:35:34 +02:00
bdew 041f570109 Fixed crash on dedicated servers 2013-12-24 10:25:13 +02:00
bdew 745cf43928 Split recipe loader to 2 phases, added statement to override recipes 2013-12-23 17:44:38 +02:00
bdew 914815fee7 Added enabled flag to machine class 2013-12-23 15:16:56 +02:00
bdew bed3149880 More refactoring and cleanup 2013-12-23 15:08:19 +02:00
bdew 302429f340 Refactoring, cleanup and moving stuff to bdlib 2013-12-23 13:30:07 +02:00
bdew b6fe2dc14d Switched to use the token replacement in forgegradle 2013-12-13 17:25:23 +02:00
96 changed files with 1923 additions and 279 deletions

No files matched your search

+4 -25
View File
@@ -1,10 +1,6 @@
buildscript {
repositories {
mavenCentral()
maven {
name = "bdew"
url = "http://jenkins.bdew.net/maven"
}
maven {
name = "forge"
url = "http://files.minecraftforge.net/maven"
@@ -18,7 +14,7 @@ buildscript {
apply plugin: 'forge'
apply plugin: 'scala'
version = "0.9.2"
version = "1.2.3"
if (project.hasProperty('buildnum')) {
project.version = project.version + '.' + project.buildnum
@@ -32,11 +28,11 @@ ext.versuffix = "mc164"
minecraft {
version = "1.6.4-9.11.1.964"
replace("BDLIB_VER", project.version)
}
import org.apache.tools.ant.filters.ReplaceTokens
def myTokens = [BdLibVer: project.version]
sourceSets {
main {
@@ -47,30 +43,13 @@ sourceSets {
srcDir 'resources'
}
}
processed {
scala {
srcDir 'build/stage'
}
}
}
task stage(type: Sync) {
inputs.property "tokens", myTokens
from sourceSets.main.scala
into 'build/stage'
filter(ReplaceTokens, tokens: myTokens)
}
compileScala {
source = sourceSets.processed.scala
dependsOn stage
}
processResources {
inputs.property "tokens", myTokens
inputs.property "tokens", minecraft.replacements
from(sourceSets.main.resources.srcDirs) {
include 'mcmod.info'
filter(ReplaceTokens, tokens: myTokens)
filter(ReplaceTokens, tokens: minecraft.replacements)
}
from(sourceSets.main.resources.srcDirs) {
+1 -1
View File
@@ -3,7 +3,7 @@
"modid": "bdlib",
"name": "BD Lib",
"description": "",
"version": "@BdLibVer@",
"version": "@BDLIB_VER@",
"url": "bdew.net/mods/",
"updateUrl": "",
"authorList": [
+21 -2
View File
@@ -1,11 +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
import cpw.mods.fml.common.Mod
import cpw.mods.fml.common.event.FMLPreInitializationEvent
import java.util.logging.Logger
import cpw.mods.fml.common.Mod.EventHandler
@Mod(modid = "bdlib", version = "@BdLibVer@", modLanguage = "scala")
@Mod(modid = "bdlib", name = "BD lib", version = "BDLIB_VER", modLanguage = "scala")
object BdLib {
var log: Logger = null
def logInfo(msg: String, args: Any*) = log.info(msg.format(args: _*))
def logWarn(msg: String, args: Any*) = log.warning(msg.format(args: _*))
def logError(msg: String, args: Any*) = log.severe(msg.format(args: _*))
@EventHandler
def preInit(ev: FMLPreInitializationEvent) {
ev.getModLog.info("bdlib @BdLibVer@ loaded")
log = ev.getModLog
log.info("bdlib BDLIB_VER loaded")
}
}
+29
View File
@@ -0,0 +1,29 @@
/*
* 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 org.lwjgl.input.Keyboard
import net.minecraft.client.Minecraft
/**
* Misc functions and shortcuts for clientside code
*/
object Client {
def minecraft = Minecraft.getMinecraft
def fontRenederer = Minecraft.getMinecraft.fontRenderer
def renderEngine = Minecraft.getMinecraft.renderEngine
def world = Minecraft.getMinecraft.theWorld
def player = Minecraft.getMinecraft.thePlayer
def shiftDown: Boolean = {
return Keyboard.isKeyDown(42) || Keyboard.isKeyDown(54)
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
+22 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -16,13 +16,19 @@ 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 net.minecraftforge.common.ForgeDirection
import net.minecraft.tileentity.TileEntity
object Misc {
def iterNbtList[X](list: NBTTagList) =
for (i <- 0 until list.tagCount()) yield list.tagAt(i).asInstanceOf[X]
def getActiveModId = Loader.instance().activeModContainer().getModId
def toLocal(s: String) = StatCollector.translateToLocal(s)
def toLocalF(s: String, params: Any*) = StatCollector.translateToLocal(s).format(params: _*)
def hasLocal(s: String) = StatCollector.func_94522_b(s)
def flattenRecipe(pattern: Seq[String], items: Map[Char, AnyRef]) =
pattern ++ items.map {
@@ -44,13 +50,15 @@ object Misc {
def min[T](vals: T*)(implicit o: Ordering[T]): T = vals.min(o)
def max[T](vals: T*)(implicit o: Ordering[T]): T = vals.max(o)
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 filterType[T](from: Iterable[_], cls: Class[T]) = from.filter(cls.isInstance).asInstanceOf[Iterable[T]]
def getBiomeByName(name: String) = BiomeGenBase.biomeList.find(x => x != null && x.biomeName == name).getOrElse(null)
def haveModVersion(spec: String): Boolean = {
val req = VersionParser.parseVersionReference(spec)
val modid = req.getLabel
@@ -63,4 +71,16 @@ object Misc {
return true
}
// Because writing this every time is awkward
def forgeDirection(i: Int) = ForgeDirection.values()(i)
// Easy replacement for various "if(foo.isInstanceOf[Bar]) foo.asInstanceOf[Bar]" constructs
def asInstanceOpt[T](v: Any, cls: Class[T]) =
if (cls.isInstance(v)) Some(v.asInstanceOf[T]) else None
def getNeighbourTile[T](origin: TileEntity, dir: ForgeDirection, cls: Class[T]) =
Option(origin.worldObj.getBlockTileEntity(origin.xCoord + dir.offsetX,
origin.yCoord + dir.offsetY, origin.zCoord + dir.offsetZ)) flatMap (asInstanceOpt(_, cls))
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -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.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
class BlockManager(val ids: IdManager, addOldTileNames: Boolean = true) {
def this(ids: IdManager) = this(ids, true)
def regBlockCls[T <: Block](blockCls: Class[T], name: String, addStack: Boolean = true): T = {
val block = blockCls.getConstructor(classOf[Int]).newInstance(ids.getBlockId(name): Integer)
regBlock[T](block, name, addStack)
}
def regBlock[T <: Block](block: T, name: String, addStack: Boolean = true): T = {
GameRegistry.registerBlock(block, name)
if (addStack)
GameRegistry.registerCustomItemStack(name, new ItemStack(block))
if (block.isInstanceOf[HasTE[_]])
if (addOldTileNames)
GameRegistry.registerTileEntityWithAlternatives(block.asInstanceOf[HasTE[_]].TEClass,
"%s.%s".format(Misc.getActiveModId, name), name)
else
GameRegistry.registerTileEntity(block.asInstanceOf[HasTE[_]].TEClass,
"%s.%s".format(Misc.getActiveModId, name))
return block
}
def load() {}
}
@@ -0,0 +1,20 @@
/*
* 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.config
import net.minecraftforge.fluids.{FluidRegistry, Fluid}
class FluidManager(val ids: IdManager) {
def regFluid[T <: Fluid](fluid: T): T = {
FluidRegistry.registerFluid(fluid)
return fluid
}
def load() {}
}
+46
View File
@@ -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.config
import net.minecraft.block.Block
import net.minecraft.item.Item
import net.minecraftforge.common.Configuration
class IdManager(cfg: Configuration, itemStart: Int, blockStart: Int) {
class MyIter(start: Int, check: Array[_], offset: Int = 0) {
var now = start
def next(): Int = {
while (check(now + offset) != null) now += 1
return now
}
}
def getBlockId(name: String, comment: String) = cfg.getBlock(name, blockIds.next(), comment).getInt
def getBlockId(name: String) = cfg.getBlock(name, blockIds.next()).getInt
def getItemId(name: String, comment: String) = cfg.getItem(name, itemIds.next(), comment).getInt
def getItemId(name: String) = cfg.getItem(name, itemIds.next()).getInt
val blockIds = new MyIter(blockStart, Block.blocksList)
val itemIds = new MyIter(itemStart, Item.itemsList, 256)
// figure out what's the max id we already use, because forge is stupid
// ignore ids in the top slots as they were probably assigned to resolve conflicts
import scala.collection.JavaConverters._
val maxBlock = (cfg.getCategory(Configuration.CATEGORY_BLOCK).values().asScala.map(_.getInt).filter(_ < Block.blocksList.length - 100) ++ Seq(0)).max + 1
val maxItem = (cfg.getCategory(Configuration.CATEGORY_ITEM).values().asScala.map(_.getInt).filter(_ < Item.itemsList.length - 1000) ++ Seq(0)).max + 1
if (maxBlock > blockIds.now) blockIds.now = maxBlock
if (maxItem > itemIds.now) itemIds.now = maxItem
}
+33
View File
@@ -0,0 +1,33 @@
/*
* 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.config
import net.minecraft.item.{ItemStack, Item}
import cpw.mods.fml.common.registry.GameRegistry
import net.bdew.lib.items.SimpleItem
class ItemManager(val ids: IdManager) {
def regSimpleItem(name: String): SimpleItem = regItem(new SimpleItem(ids.getItemId(name), name), name)
def regItem[T <: SimpleItem](item: T): T = regItem[T](item, item.name)
def regItemCls[T <: Item](itemCls: Class[T], name: String, addStack: Boolean = true): T = {
val item = itemCls.getConstructor(classOf[Int]).newInstance(ids.getItemId(name): Integer)
regItem[T](item, name, addStack)
}
def regItem[T <: Item](item: T, name: String, addStack: Boolean = true): T = {
GameRegistry.registerItem(item, name)
if (addStack)
GameRegistry.registerCustomItemStack(name, new ItemStack(item))
return item
}
def load() {}
}
@@ -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.config
import net.bdew.lib.recipes.gencfg.ConfigSection
import net.bdew.lib.machine.Machine
import net.bdew.lib.gui.{GuiProvider, GuiHandler}
class MachineManager(ids: IdManager, val tuning: ConfigSection, guiHandler: GuiHandler) {
def registerMachine[R <: Machine[_]](machine: R): R = {
machine.tuning = tuning.getSection(machine.name)
if (machine.tuning.getBoolean("Enabled")) {
machine.enabled = true
machine.regBlock(ids)
if (machine.isInstanceOf[GuiProvider])
guiHandler.register(machine.asInstanceOf[GuiProvider])
}
return machine
}
def load() {}
}
@@ -0,0 +1,68 @@
/*
* 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.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.items.ItemUtils
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 = {
val te = getTE(world, x, y, z)
val side = Misc.forgeDirection(face)
if (player.getCurrentEquippedItem == null && player.isSneaking) {
for (cover <- Option(te.covers(side).cval)) {
if (!world.isRemote) {
te.covers(side) := null
te.onCoversChanged()
ItemUtils.dropItemToPlayer(world, player, cover)
}
return true
}
}
for {
activeStack <- Option(player.getCurrentEquippedItem)
activeItem <- Option(activeStack.getItem)
coverItem <- Misc.asInstanceOpt(activeItem, classOf[ItemCover])
if te.isValidCover(side, activeStack) && coverItem.isValidTile(te, activeStack)
} {
if (!world.isRemote) {
for (cover <- Option(te.covers(side).cval))
ItemUtils.throwItemAt(world, te.xCoord + side.offsetX, te.yCoord + side.offsetY, te.zCoord + side.offsetZ, cover.copy())
te.covers(side) := activeStack.splitStack(1)
if (activeStack.stackSize <= 0) player.inventory.setInventorySlotContents(player.inventory.currentItem, null)
te.onCoversChanged()
}
return true
}
super.onBlockActivated(world, x, y, z, player, face, xoffs, yoffs, zoffs)
}
override def getBlockTexture(w: IBlockAccess, x: Int, y: Int, z: Int, side: Int) =
(for {
coverStack <- Option(getTE(w, x, y, z).covers(Misc.forgeDirection(side)).cval)
coverItem <- Option(coverStack.getItem) flatMap (Misc.asInstanceOpt(_, classOf[ItemCover]))
} yield coverItem.getCoverIcon(coverStack)
) getOrElse super.getBlockTexture(w, x, y, z, side)
override def breakBlock(world: World, x: Int, y: Int, z: Int, blockId: Int, meta: Int) {
if (!world.isRemote)
for ((dir, covOpt) <- getTE(world, x, y, z).covers; cover <- Option(covOpt.cval))
ItemUtils.throwItemAt(world, x, y, z, cover)
super.breakBlock(world, x, y, z, blockId, meta)
}
}
+31
View File
@@ -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.covers
import net.minecraft.item.{ItemStack, Item}
import net.minecraftforge.common.ForgeDirection
import net.minecraft.util.Icon
trait ItemCover extends Item {
/**
* @return Icon to render, MUST be on terrain spritesheet (0), not item!
*/
def getCoverIcon(stack: ItemStack): Icon
/**
* Perform tick, called on server only
*/
def tickCover(te: TileCoverable, side: ForgeDirection, cover: ItemStack)
/**
* Checks if this cover can be installed on a specific TE
*/
def isValidTile(te: TileCoverable, cover: ItemStack): Boolean
}
@@ -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.covers
import net.bdew.lib.data.base.{UpdateKind, TileDataSlots}
import net.minecraftforge.common.ForgeDirection
import net.bdew.lib.data.DataSlotItemStack
import net.bdew.lib.Misc
import net.minecraft.item.ItemStack
trait TileCoverable extends TileDataSlots {
val covers = (ForgeDirection.VALID_DIRECTIONS map { x =>
x -> DataSlotItemStack("cover_" + x.toString.toLowerCase, this).setUpdate(UpdateKind.SAVE, UpdateKind.WORLD, UpdateKind.RENDER)
}).toMap
/**
* Checks if a specific cover can be installed here
*/
def isValidCover(side: ForgeDirection, cover: ItemStack): Boolean
/**
* Called when new covers are installed
*/
def onCoversChanged() {}
def tickCovers() =
for {
(dir, coverSlot) <- covers
coverStack <- Option(coverSlot.cval)
coverItem <- Option(coverStack.getItem) flatMap (Misc.asInstanceOpt(_, classOf[ItemCover]))
} {
coverItem.tickCover(this, dir, coverStack)
}
serverTick.listen(tickCovers)
}
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
+5 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -15,7 +15,6 @@ import net.bdew.lib.data.base.{UpdateKind, TileDataSlots, DataSlot}
abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank with DataSlot {
var oldStack: FluidStack = null
var size: Int
parent.serverTick.listen(checkUpdate)
@@ -38,19 +37,20 @@ abstract class DataSlotTankBase(sz: Int) extends FluidTank(sz) with IFluidTank w
val tag = new NBTTagCompound()
writeToNBT(tag)
if (k == UpdateKind.GUI)
tag.setInteger("size", size)
tag.setInteger("size", getCapacity)
t.setCompoundTag(name, tag)
}
def load(t: NBTTagCompound, k: UpdateKind.Value) {
setFluid(null)
val tag = t.getCompoundTag(name)
readFromNBT(tag)
if (k == UpdateKind.GUI)
size = tag.getInteger("size")
setCapacity(tag.getInteger("size"))
}
}
case class DataSlotTank(name: String, parent: TileDataSlots, var size: Int) extends DataSlotTankBase(size)
case class DataSlotTank(name: String, parent: TileDataSlots, size: Int) extends DataSlotTankBase(size)
case class DataSlotTankRestricted(name: String, parent: TileDataSlots, var size: Int, fluidID: Int) extends DataSlotTankBase(size) {
def fill(amount: Int, doFill: Boolean) = super.fill(new FluidStack(fluidID, amount), doFill)
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -10,10 +10,10 @@
package net.bdew.lib.data.base
import net.minecraft.entity.player.EntityPlayerMP
import net.bdew.lib.gui.BaseContainer
import net.bdew.lib.gui.NoInvContainer
import net.minecraft.inventory.ICrafting
trait ContainerDataSlots extends BaseContainer {
trait ContainerDataSlots extends NoInvContainer {
val dataSource: TileDataSlots
var lastSentChange = dataSource.lastChange
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -31,6 +31,8 @@ trait TileDataSlots extends TileExtended {
for ((n, s) <- dataSlots if s.updateKind.contains(kind)) {
if (TRACE) printf("%s: %s L<= %s\n".format(kind, n, t.getTag(n)))
s.load(t, kind)
if (kind == UpdateKind.WORLD && s.updateKind.contains(UpdateKind.RENDER))
worldObj.markBlockForRenderUpdate(xCoord, yCoord, zCoord)
}
}
+2 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -13,4 +13,5 @@ object UpdateKind extends Enumeration {
val WORLD = Value("WORLD")
val GUI = Value("GUI")
val SAVE = Value("SAVE")
val RENDER = Value("RENDER")
}
+4 -18
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -9,26 +9,12 @@
package net.bdew.lib.gui
import net.minecraft.inventory.{IInventory, Slot, Container}
import net.minecraft.entity.player.{EntityPlayerMP, EntityPlayer, InventoryPlayer}
import net.minecraft.inventory.IInventory
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.bdew.lib.items.ItemUtils
import net.bdew.lib.Misc
abstract class BaseContainer(te: IInventory) extends Container {
import scala.collection.JavaConversions._
def players = Misc.filterType(crafters, classOf[EntityPlayerMP])
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))
for (i <- 0 until 9)
addSlotToContainer(new Slot(inv, i, xOffs + i * 18, yOffsHotbar))
}
abstract class BaseContainer(te: IInventory) extends NoInvContainer {
override def transferStackInSlot(player: EntityPlayer, slot: Int): ItemStack = {
var stack = getSlot(slot).getStack
if (getSlot(slot).inventory == player.inventory) {
+25
View File
@@ -0,0 +1,25 @@
/*
* 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
case class BasePoint[T: Numeric](x: T, y: T) {
val n = implicitly[Numeric[T]]
import n.mkNumericOps
def this(p: BasePoint[T]) = this(p.x, p.y)
def +(that: BasePoint[T]) = BasePoint(this.x + that.x, this.y + that.y)
def +(xOff: T, yOff: T) = BasePoint(this.x + xOff, this.y + yOff)
def -(that: BasePoint[T]) = BasePoint(this.x - that.x, this.y - that.y)
def -(xOff: T, yOff: T) = BasePoint(this.x - xOff, this.y - yOff)
def map[R: Numeric](f: T => R) = new BasePoint(f(x), f(y))
}
+40
View File
@@ -0,0 +1,40 @@
/*
* 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
case class BaseRect[T: Numeric](x: T, y: T, w: T, h: T) {
val n = implicitly[Numeric[T]]
import n.mkNumericOps
def this(p: BasePoint[T], w: T, h: T) = this(p.x, p.y, w, h)
def contains(p: BasePoint[T]) = n.gteq(p.x, x) && n.gteq(p.y, y) && n.lteq(p.x, x2) && n.lteq(p.y, y2)
def origin = BasePoint(x, y)
def map[R: Numeric](f: T => R) = new BaseRect(f(x), f(y), f(w), f(h))
def interpolate(xf1: Float, yf1: Float, xf2: Float, yf2: Float) =
new BaseRect[Float](
xf1 * w.toFloat() + x.toFloat(),
yf1 * h.toFloat() + y.toFloat(),
(xf2 - xf1) * w.toFloat(),
(yf2 - yf1) * h.toFloat()
)
def +(p: BasePoint[T]) = new BaseRect(origin + p, w, h)
def -(p: BasePoint[T]) = new BaseRect(origin - p, w, h)
def x1 = x
def x2 = x + w
def y1 = y
def y2 = y + h
}
+21 -40
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -12,21 +12,20 @@ package net.bdew.lib.gui
import net.minecraft.client.gui.inventory.GuiContainer
import net.minecraft.inventory.Container
import scala.collection.mutable
import net.minecraft.client.gui.GuiButton
import net.bdew.lib.gui.widgets.Widget
import net.minecraft.util.ResourceLocation
import org.lwjgl.opengl.GL11
abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContainer(cont) {
xSize = xSz
ySize = ySz
val widgets = mutable.MutableList.empty[Widget]
val texture: ResourceLocation
val widgets = new WidgetContainerWindow(this, xSz, ySz)
val background: Texture
def rect = new Rect(guiLeft, guiTop, xSize, ySize)
def getFontRenderer = fontRenderer
def getZLevel = zLevel
override def initGui() {
super.initGui()
@@ -34,44 +33,24 @@ abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContai
buttonList.clear()
}
def addButton[T <: GuiButton](w: T): T = {
buttonList.asInstanceOf[java.util.ArrayList[GuiButton]].add(w)
return w
}
def addWidget[T <: Widget](w: T): T = {
widgets += w
w.parent = this
return w
}
protected override def keyTyped(c: Char, i: Int) {
for (w <- widgets)
if (w.keyTyped(c, i))
return
super.keyTyped(c, i)
}
protected override def mouseClicked(x: Int, y: Int, bt: Int) {
super.mouseClicked(x, y, bt)
val p = new Point(x, y) - rect.origin
for (w <- widgets if w.rect.contains(p))
w.mouseClicked(p - w.rect.origin, bt)
widgets.mouseClicked(Point(x, y) - rect.origin, bt)
}
protected override def drawGuiContainerForegroundLayer(x: Int, y: Int) {
for (w <- widgets)
w.draw()
}
protected override def keyTyped(c: Char, i: Int) =
if (!widgets.keyTyped(c, i))
super.keyTyped(c, i)
protected override def drawGuiContainerForegroundLayer(x: Int, y: Int) =
widgets.draw(Point(x, y) - rect.origin)
protected override def drawScreen(x: Int, y: Int, f: Float) {
super.drawScreen(x, y, f)
val tip = mutable.MutableList.empty[String]
val p = new Point(x, y) - rect.origin
for (w <- widgets if w.rect.contains(p))
w.handleTooltip(p - w.rect.origin, tip)
widgets.handleTooltip(Point(x, y) - rect.origin, tip)
import collection.JavaConversions._
@@ -79,11 +58,13 @@ abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContai
drawHoveringText(tip, x, y, fontRenderer)
}
protected def drawGuiContainerBackgroundLayer(f: Float, i: Int, j: Int) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F)
mc.renderEngine.bindTexture(texture)
val x = (width - xSize) / 2
val y = (height - ySize) / 2
this.drawTexturedModalRect(x, y, 0, 0, xSize, ySize)
protected def drawGuiContainerBackgroundLayer(f: Float, x: Int, y: Int) {
if (background != null)
widgets.drawTexture(rect, background)
GL11.glPushMatrix()
GL11.glTranslatef(rect.x, rect.y, 0)
widgets.drawBackground(Point(x, y) - rect.origin)
GL11.glPopMatrix()
}
}
+21
View File
@@ -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
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
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) {
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)
super.getBackgroundIconIndex
}
}
+49
View File
@@ -0,0 +1,49 @@
/*
* 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
import org.lwjgl.opengl.GL11
import net.bdew.lib.Misc
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)
def this(c: (Float, Float, Float, Float)) = this(c._1, c._2, c._3, c._4)
def activate() = GL11.glColor4f(r, g, b, a)
def asARGB =
Misc.clamp((a * 255).round, 0, 255) << 24 |
Misc.clamp((r * 255).round, 0, 255) << 16 |
Misc.clamp((g * 255).round, 0, 255) << 8 |
Misc.clamp((b * 255).round, 0, 255)
def asRGB =
Misc.clamp((r * 255).round, 0, 255) << 16 |
Misc.clamp((g * 255).round, 0, 255) << 8 |
Misc.clamp((b * 255).round, 0, 255)
}
object Color {
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
)
final val white = Color(1, 1, 1)
final val black = Color(0, 0, 0)
final val red = Color(1, 0, 0)
final val green = Color(0, 1, 0)
final val blue = Color(0, 0, 1)
final val yellow = Color(1, 1, 0)
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)
}
+4 -4
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -12,7 +12,7 @@ package net.bdew.lib.gui
object Direction extends Enumeration {
type Direction = Value
val UP = Value("UP")
val DOWN = Value("UP")
val LEFT = Value("UP")
val RIGHT = Value("UP")
val DOWN = Value("DOWN")
val LEFT = Value("LEFT")
val RIGHT = Value("RIGHT")
}
+46
View File
@@ -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.gui
import net.minecraft.client.renderer.Tessellator
import net.minecraft.client.gui.FontRenderer
trait DrawTarget {
def getZLevel: Float
def getFontRenderer: FontRenderer
def drawTexture(r: Rect, t: Texture, color: Color = Color.white)
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))
}
trait SimpleDrawTarget extends DrawTarget {
private final val T = Tessellator.instance
def drawTexture(r: Rect, t: Texture, color: Color = Color.white) {
val z = getZLevel
t.bind()
color.activate()
T.startDrawingQuads()
T.addVertexWithUV(r.x1, r.y2, z, t.u1, t.v2)
T.addVertexWithUV(r.x2, r.y2, z, t.u2, t.v2)
T.addVertexWithUV(r.x2, r.y1, z, t.u2, t.v1)
T.addVertexWithUV(r.x1, r.y1, z, t.u1, t.v1)
T.draw()
}
def drawText(text: String, p: Point, color: Color, shadow: Boolean) =
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)
}
+31
View File
@@ -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.gui
import cpw.mods.fml.common.network.IGuiHandler
import scala.collection.mutable
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.world.World
class GuiHandler extends IGuiHandler {
val guis = mutable.Map.empty[Int, GuiProvider]
def register(p: GuiProvider) = {
if (guis.isDefinedAt(p.guiId))
sys.error("GUI ID Collision - %d was registered for %s and attemted 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 =
guis(ID).getContainer(world.getBlockTileEntity(x, y, z), player)
def getClientGuiElement(ID: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): AnyRef =
guis(ID).getGui(world.getBlockTileEntity(x, y, z), player)
}
+28
View File
@@ -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.gui
import net.minecraft.tileentity.TileEntity
import net.minecraft.entity.player.EntityPlayer
import cpw.mods.fml.relauncher.{Side, SideOnly}
trait GuiProvider {
def guiId: Int
type TEClass
@SideOnly(Side.CLIENT)
def getGui(te: TEClass, player: EntityPlayer): AnyRef
def getContainer(te: TEClass, player: EntityPlayer): AnyRef
@SideOnly(Side.CLIENT)
def getGui(te: TileEntity, player: EntityPlayer): AnyRef = getGui(te.asInstanceOf[TEClass], player)
def getContainer(te: TileEntity, player: EntityPlayer): AnyRef = getContainer(te.asInstanceOf[TEClass], player)
}
+41
View File
@@ -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.gui
import net.minecraft.inventory.{Slot, Container}
import net.bdew.lib.Misc
import net.minecraft.entity.player.{EntityPlayer, InventoryPlayer, EntityPlayerMP}
import net.minecraft.item.ItemStack
abstract class NoInvContainer extends Container {
import scala.collection.JavaConversions._
def players = Misc.filterType(crafters, classOf[EntityPlayerMP])
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))
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 = {
if (inventorySlots.isDefinedAt(slotnum)) {
val slot = getSlot(slotnum)
if (slot != null && slot.isInstanceOf[SlotClickable])
return slot.asInstanceOf[SlotClickable].onClick(button, modifiers, player)
}
return super.slotClick(slotnum, button, modifiers, player)
}
override def transferStackInSlot(player: EntityPlayer, slot: Int): ItemStack = null
}
-25
View File
@@ -1,25 +0,0 @@
/*
* Copyright (c) bdew, 2013
* 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
class Point(val x: Int, val y: Int) {
def this(p: Point) = this(p.x, p.y)
def +(that: Point) = new Point(this.x + that.x, this.y + that.y)
def -(that: Point) = new Point(this.x - that.x, this.y - that.y)
}
object Point {
import language.implicitConversions
implicit def awt2point(p: java.awt.Point): Point = new Point(p.x, p.y)
implicit def point2awt(p: Point): java.awt.Point = new java.awt.Point(p.x, p.y)
implicit def tuple2point(p: (Int, Int)): Point = new Point(p._1, p._2)
}
-18
View File
@@ -1,18 +0,0 @@
/*
* Copyright (c) bdew, 2013
* 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
class Rect(val x: Int, val y: Int, val w: Int, val h: Int) {
def this(p: Point, w: Int, h: Int) = this(p.x, p.y, w, h)
def contains(p: Point) = p.x >= x && p.y >= y && p.x <= x + w && p.y <= y + h
def origin = new Point(x, y)
def +(p: Point) = new Rect(origin + p, w, h)
def -(p: Point) = new Rect(origin - p, w, h)
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -9,8 +9,10 @@
package net.bdew.lib.gui
import net.minecraft.util.ResourceLocation
import net.minecraft.item.ItemStack
import net.minecraft.inventory.Slot
import net.minecraft.entity.player.EntityPlayer
class TextureLocation(val resource: ResourceLocation, val p: Point) extends Point(p.x, p.y) {
def this(resource: ResourceLocation, x: Int, y: Int) = this(resource, new Point(x, y))
trait SlotClickable extends Slot {
def onClick(button: Int, mods: Int, player: EntityPlayer): ItemStack
}
+2 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -10,9 +10,8 @@
package net.bdew.lib.gui
import net.minecraft.inventory.IInventory
import net.minecraft.inventory.Slot
import net.minecraft.item.ItemStack
class SlotValidating(inv: IInventory, slot: Int, x: Int, y: Int) extends Slot(inv, slot, x, y) {
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)
}
+85
View File
@@ -0,0 +1,85 @@
/*
* 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
import net.minecraft.util.{Icon, ResourceLocation}
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.texture.TextureMap
trait Texture {
def u1: Float
def u2: Float
def v1: Float
def v2: Float
def bind(): Unit
}
class InterpolatedTexture(val texture: Texture, rect: Rect) extends Texture {
def bind() = texture.bind()
def u1 = rect.x1 * (texture.u2 - texture.u1) + texture.u1
def u2 = rect.x2 * (texture.u2 - texture.u1) + texture.u1
def v1 = rect.y1 * (texture.v2 - texture.v1) + texture.v1
def v2 = rect.y2 * (texture.v2 - texture.v1) + texture.v1
}
class IconWrapper(val resource: ResourceLocation, val icon: Icon) extends Texture {
def u1 = icon.getMinU
def u2 = icon.getMaxU
def v1 = icon.getMinV
def v2 = icon.getMaxV
def bind() = Minecraft.getMinecraft.renderEngine.bindTexture(resource)
}
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
def v1 = rect.y1
def v2 = rect.y2
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 = 256) = this(domain + ":" + path, scale)
}
object Texture {
val ITEMS = TextureMap.locationItemsTexture
val BLOCKS = TextureMap.locationBlocksTexture
// From minecraft Icon
def apply(res: ResourceLocation, i: Icon) = new IconWrapper(res, i)
// 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)
// 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))
// 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)
// 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)
// 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))
}
@@ -0,0 +1,85 @@
/*
* 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
import scala.collection.mutable
import net.bdew.lib.gui.widgets.BaseWidget
import net.minecraft.client.gui.FontRenderer
import org.lwjgl.opengl.GL11
trait WidgetContainer extends DrawTarget {
val rect: Rect
val widgets = mutable.MutableList.empty[BaseWidget]
def activeWidgets: Iterable[BaseWidget] = widgets
def getFontRenderer: FontRenderer
def clear() = widgets.clear()
def add[T <: BaseWidget](w: T): T = {
widgets += w
w.init(this)
return w
}
def mouseClicked(p: Point, bt: Int) {
for (w <- activeWidgets)
if (w.rect.contains(p))
w.mouseClicked(p - w.rect.origin, bt)
else
w.looseFocus()
}
def keyTyped(c: Char, i: Int): Boolean = {
for (w <- activeWidgets)
if (w.keyTyped(c, i))
return true
return false
}
def drawBackground(mouse: Point) {
val p = mouse - rect.origin
GL11.glPushMatrix()
GL11.glTranslatef(rect.origin.x, rect.origin.y, 0)
for (w <- activeWidgets) {
w.drawBackground(p)
}
GL11.glPopMatrix()
}
def draw(mouse: Point) {
val p = mouse - rect.origin
GL11.glPushMatrix()
GL11.glTranslatef(rect.origin.x, rect.origin.y, 0)
for (w <- activeWidgets) {
w.draw(p)
}
GL11.glPopMatrix()
}
def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
for (w <- activeWidgets if w.rect.contains(p))
w.handleTooltip(p - w.rect.origin, tip)
}
def looseFocus() =
for (w <- activeWidgets)
w.looseFocus()
def getOffsetFromWindow: Point
}
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)
val rect = Rect(0, 0, xSz, ySz)
}
+29
View File
@@ -0,0 +1,29 @@
/*
* 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
package object gui {
type Rect = BaseRect[Float]
type Point = BasePoint[Float]
import 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)
implicit def tuple2point[T: Numeric](p: (T, 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](f(a.x), f(a.y))
implicit def rectconvert[T, R](a: BaseRect[R])(implicit f: R => T, n: Numeric[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)
}
+18 -9
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -10,17 +10,26 @@
package net.bdew.lib.gui.widgets
import scala.collection.mutable
import net.bdew.lib.gui.{Point, BaseScreen, Rect}
import net.minecraft.util.ResourceLocation
import net.minecraft.client.Minecraft
import net.bdew.lib.gui.{WidgetContainer, Point, Rect}
trait Widget {
trait BaseWidget {
val rect: Rect
var parent: WidgetContainer = null
def init(p: WidgetContainer) = parent = p
def handleTooltip(p: Point, tip: mutable.MutableList[String])
def mouseClicked(p: Point, button: Int)
def keyTyped(c: Char, i: Int): Boolean
def draw(mouse: Point)
def drawBackground(mouse: Point)
def looseFocus()
}
trait Widget extends BaseWidget {
val rect: Rect
var parent: BaseScreen = null
def handleTooltip(p: Point, tip: mutable.MutableList[String]) {}
def mouseClicked(p: Point, button: Int) {}
def keyTyped(c: Char, i: Int): Boolean = false
def draw() {}
def bindTexture(res: ResourceLocation) = Minecraft.getMinecraft.renderEngine.bindTexture(res)
def draw(mouse: Point) {}
def drawBackground(mouse: Point) {}
def looseFocus() {}
}
@@ -0,0 +1,25 @@
/*
* 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.minecraft.client.gui.GuiButton
import net.bdew.lib.gui.{Point, Rect}
import net.minecraft.client.Minecraft
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 {
override def mouseClicked(p: Point, button: Int) {
Minecraft.getMinecraft.sndManager.playSoundFX("random.click", 1.0F, 1.0F)
clicked(this)
}
override def draw(mouse: Point) = drawButton(Minecraft.getMinecraft, mouse.x.round, mouse.y.round)
}
@@ -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.gui.widgets
import net.bdew.lib.gui.{Color, Point, Rect}
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)
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -9,29 +9,24 @@
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{TextureLocation, Rect}
import net.bdew.lib.gui.Direction
import net.bdew.lib.gui._
import net.bdew.lib.data.base.DataSlotNumeric
class WidgetFillDataslot[T](val rect: Rect, val texture: TextureLocation, 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 {
def getFillArea(max: Int): Int = (num.toFloat(dslot) / num.toFloat(maxval) * max).round
import num.mkNumericOps
override def draw() {
bindTexture(texture.resource)
override def draw(mouse: Point) {
val fill = dslot.cval.toFloat() / maxval.toFloat()
dir match {
case Direction.UP =>
val fill = getFillArea(rect.h)
parent.drawTexturedModalRect(rect.x, rect.y + rect.h - fill, texture.x, texture.y + rect.h - fill, rect.w, fill)
parent.drawTextureInterpolate(rect, texture, 0, 1 - fill, 1, 1)
case Direction.DOWN =>
val fill = getFillArea(rect.h)
parent.drawTexturedModalRect(rect.x, rect.y, texture.x, texture.y, rect.w, fill)
parent.drawTextureInterpolate(rect, texture, 0, 0, 1, fill)
case Direction.LEFT =>
val fill = getFillArea(rect.w)
parent.drawTexturedModalRect(rect.x + rect.w - fill, rect.y, texture.x + rect.w - fill, texture.y, fill, rect.h)
parent.drawTextureInterpolate(rect, texture, 1 - fill, 0, 1, 1)
case Direction.RIGHT =>
val fill = getFillArea(rect.w)
parent.drawTexturedModalRect(rect.x, rect.y, texture.x, texture.y, fill, rect.h)
parent.drawTextureInterpolate(rect, texture, 0, 0, fill, 1)
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -9,15 +9,14 @@
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{Point, TextureLocation, Rect}
import net.bdew.lib.gui.{Texture, Point, Rect}
import net.bdew.lib.data.DataSlotTankBase
import scala.collection.mutable
import net.minecraft.client.renderer.texture.TextureMap
import java.text.DecimalFormat
import net.bdew.lib.Misc
import org.lwjgl.opengl.GL11
class WidgetFluidGauge(val rect: Rect, overlay: TextureLocation, dslot: DataSlotTankBase) extends Widget {
class WidgetFluidGauge(val rect: Rect, overlay: Texture, dslot: DataSlotTankBase) extends Widget {
val formater = new DecimalFormat("#,###")
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) {
@@ -25,27 +24,26 @@ class WidgetFluidGauge(val rect: Rect, overlay: TextureLocation, dslot: DataSlot
tip += dslot.getFluid.getFluid.getLocalizedName
tip += "%s/%s mB".format(formater.format(dslot.getFluidAmount), formater.format(dslot.getCapacity))
} else {
tip += Misc.toLocal("gendustry.label.empty")
tip += Misc.toLocal("bdlib.label.empty")
}
}
override def draw() {
override def draw(mouse: Point) {
GL11.glEnable(GL11.GL_BLEND)
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA)
val fstack = dslot.getFluid
if (fstack != null && fstack.getFluid.getStillIcon != null) {
val icon = fstack.getFluid.getStillIcon
bindTexture(TextureMap.locationBlocksTexture)
var fillHeight: Int = (rect.h * fstack.amount / dslot.getCapacity).round
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
while (fillHeight > 0) {
if (fillHeight > 16) {
parent.drawTexturedModelRectFromIcon(rect.x, rect.y + rect.h - 16 - yStart, icon, 16, 16)
parent.drawTexture(new Rect(rect.x, rect.y2 - 16 - yStart, rect.w, 16), icon)
fillHeight -= 16
} else {
parent.drawTexturedModelRectFromIcon(rect.x, rect.y + rect.h - fillHeight - yStart, icon, 16, fillHeight)
parent.drawTextureInterpolate(new Rect(rect.x, rect.y2 - 16 - yStart, rect.w, 16), icon, 0, 1 - fillHeight / 16, 1, 1)
fillHeight = 0
}
yStart = yStart + 16
@@ -54,7 +52,6 @@ class WidgetFluidGauge(val rect: Rect, overlay: TextureLocation, dslot: DataSlot
GL11.glDisable(GL11.GL_BLEND)
bindTexture(overlay.resource)
parent.drawTexturedModalRect(rect.x, rect.y, overlay.x, overlay.y, rect.w, rect.h)
parent.drawTexture(rect, overlay)
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -9,11 +9,11 @@
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.Rect
import net.bdew.lib.gui.{Color, Point, Rect}
class WidgetLabel(text: String, x: Int, y: Int, color: Int) extends Widget {
val rect: Rect = new Rect(x, y, 0, 0)
override def draw() {
parent.getFontRenderer.drawString(text, x, y, color)
class WidgetLabel(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)
}
}
@@ -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.gui.widgets
import net.bdew.lib.gui.Rect
abstract class WidgetMultipane(rect: Rect) extends WidgetSubcontainer(rect) {
def getActivePane: BaseWidget
def addPane[T <: BaseWidget](w: T): T = {
w.init(this)
return w
}
override def activeWidgets = super.activeWidgets ++: List(getActivePane)
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -9,10 +9,10 @@
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{Point, Direction, TextureLocation, Rect}
import net.bdew.lib.data.DataSlotFloat
import net.bdew.lib.gui._
import scala.collection.mutable
import net.bdew.lib.data.DataSlotFloat
class WidgetProgressBar(rect: Rect, texture: TextureLocation, dslot: DataSlotFloat) extends WidgetFillDataslot[Float](rect, texture, Direction.RIGHT, dslot, 1) {
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) + "%"
}
@@ -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.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
def getFontRenderer = parent.getFontRenderer
def getOffsetFromWindow = parent.getOffsetFromWindow + rect.origin
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -12,8 +12,14 @@ package net.bdew.lib.gui.widgets
import net.minecraft.client.gui.{FontRenderer, GuiTextField}
import net.bdew.lib.gui.{Point, Rect}
class WidgetTextEdit(val rect: Rect, fr: FontRenderer) extends GuiTextField(fr, rect.x, rect.y, rect.w, rect.h) with Widget {
override def mouseClicked(p: Point, button: Int) = super.mouseClicked(p.x + rect.x, p.y + rect.y, button)
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
super.mouseClicked(pp.x.round, pp.y.round, button)
}
override def looseFocus() = setFocused(false)
override def keyTyped(c: Char, i: Int): Boolean = super.textboxKeyTyped(c, i)
override def draw() = super.drawTextBox()
override def draw(mouse: Point) = super.drawTextBox()
}
+23
View File
@@ -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.items
import net.minecraft.item.{Item, ItemStack}
/**
* Allows matching Items in ItemStacks in scala pattern matches
*/
object IStack {
def unapply(x: ItemStack): Option[Item] =
if (x == null || x.getItem == null)
None
else
Some(x.getItem)
}
+28 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -10,11 +10,13 @@
package net.bdew.lib.items
import net.minecraft.entity.item.EntityItem
import net.minecraft.item.ItemStack
import net.minecraft.item.{Item, ItemStack}
import net.minecraft.world.World
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.inventory.IInventory
import net.minecraft.inventory.{ISidedInventory, IInventory}
import net.bdew.lib.Misc
import java.util.Random
import net.minecraftforge.common.ForgeDirection
object ItemUtils {
def throwItemAt(world: World, x: Int, y: Int, z: Int, stack: ItemStack) {
@@ -76,4 +78,27 @@ object ItemUtils {
return stack
}
def getAccessibleSlotsFromSide(inv: IInventory, side: ForgeDirection) =
(Misc.asInstanceOpt(inv, classOf[ISidedInventory])
map (_.getAccessibleSlotsFromSide(side.ordinal()).toList)
getOrElse (0 until inv.getSizeInventory))
def findItemInInventory(inv: IInventory, item: Item) =
Range(0, inv.getSizeInventory).map(x => x -> inv.getStackInSlot(x))
.find({ case (slot, stack) => stack != null && stack.getItem == item })
.map({ case (slot, stack) => slot })
def copyWithRandomSize(template: ItemStack, max: Int, rand: Random) = {
val newSize = rand.nextInt(max)
val newStack = template.copy()
newStack.stackSize =
if (newSize > newStack.getMaxStackSize)
newStack.getMaxStackSize
else if (newSize <= 0)
1
else
newSize
newStack
}
}
+25
View File
@@ -0,0 +1,25 @@
/*
* 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.items
import net.minecraft.item.Item
import net.minecraft.client.renderer.texture.IconRegister
import cpw.mods.fml.relauncher.{Side, SideOnly}
import net.bdew.lib.Misc
class SimpleItem(id: Int, val name: String) extends Item(id) {
val modId = Misc.getActiveModId
setUnlocalizedName(modId + "." + name)
@SideOnly(Side.CLIENT)
override def registerIcons(reg: IconRegister) {
itemIcon = reg.registerIcon(modId + ":" + name.toLowerCase)
}
}
@@ -0,0 +1,29 @@
/*
* 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.items.inventory
import net.minecraft.entity.player.EntityPlayer
import net.bdew.lib.gui.BaseContainer
import net.minecraft.item.ItemStack
import net.minecraft.inventory.Slot
class ContainerItemInventory(inv: InventoryItemAdapter, player: EntityPlayer) extends BaseContainer(inv) {
def canInteractWith(entityplayer: EntityPlayer) = entityplayer == player
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))
return null
}
if (modifiers == 2 && button == inv.slot) return null
return super.slotClick(slotnum, button, modifiers, player)
}
}
@@ -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.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.minecraft.entity.player.EntityPlayer
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)
if (getStack.hasTagCompound)
load()
def load() {
val tag = getStack.getTagCompound
for (nbtItem <- Misc.iterNbtList[NBTTagCompound](tag.getTagList(tagName))) {
val slot = nbtItem.getByte("Slot")
if (slot >= 0 && slot < inv.size) {
inv(slot) = ItemStack.loadItemStackFromNBT(nbtItem)
}
}
}
def onInventoryChanged() {
if (!getStack.hasTagCompound) getStack.setTagCompound(new NBTTagCompound)
val tag = getStack.getTagCompound
val itemList = new NBTTagList
for ((item, i) <- inv.view.zipWithIndex if item != null) {
val itemNbt: NBTTagCompound = new NBTTagCompound
itemNbt.setByte("Slot", i.asInstanceOf[Byte])
item.writeToNBT(itemNbt)
itemList.appendTag(itemNbt)
}
tag.setTag(tagName, itemList)
}
}
@@ -0,0 +1,61 @@
/*
* 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.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.minecraft.world.World
/**
* Mixin for items that have an internal inventory
* Subclasses are responsible for registering themself with the GuiHandler of their mod
*/
trait ItemInventory extends Item with GuiProvider {
type TEClass = Any
def guiId: Int
val invSize: Int
val invTagName: String
val modObj = Loader.instance().activeModContainer().getMod
@SideOnly(Side.CLIENT)
def makeGui(inv: InventoryItemAdapter, player: EntityPlayer): AnyRef
def makeContainer(inv: InventoryItemAdapter, player: EntityPlayer): ContainerItemInventory
def makeAdaptor(player: EntityPlayer) = new InventoryItemAdapter(player, player.inventory.currentItem, invSize, invTagName)
@SideOnly(Side.CLIENT)
def getGui(te: TEClass, player: EntityPlayer) = {
val stack = player.inventory.getCurrentItem
if (stack.getItem == this) {
makeGui(makeAdaptor(player), player)
} else {
BdLib.logWarn("Attempt to open item container GUI without active item (%s)", this)
null
}
}
def getContainer(te: TEClass, player: EntityPlayer) = {
val stack = player.inventory.getCurrentItem
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)
null
}
}
def doOpenGui(player: EntityPlayer, world: World) {
player.openGui(modObj, guiId, world, player.posX.toInt, player.posY.toInt, player.posZ.toInt)
}
}
+35
View File
@@ -0,0 +1,35 @@
/*
* 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.machine
import net.bdew.lib.recipes.gencfg.ConfigSection
import net.minecraft.block.Block
import cpw.mods.fml.common.registry.GameRegistry
import net.minecraft.item.ItemStack
import net.bdew.lib.block.HasTE
import net.bdew.lib.config.IdManager
import net.bdew.lib.Misc
abstract class Machine[T <: Block](val name: String, val blockConstruct: (Int) => T) {
var block: T = null.asInstanceOf[T]
var tuning: ConfigSection = null
var enabled = false
val modId = Misc.getActiveModId
def regBlock(ids: IdManager) {
block = blockConstruct(ids.getBlockId(name))
GameRegistry.registerBlock(block, name)
GameRegistry.registerCustomItemStack(name, new ItemStack(block))
if (block.isInstanceOf[HasTE[_]]) {
GameRegistry.registerTileEntity(block.asInstanceOf[HasTE[_]].TEClass, "%s.%s".format(modId, name))
}
}
}
@@ -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.machine
import net.bdew.lib.recipes.gencfg.ConfigSection
trait PoweredMachine {
def tuning: ConfigSection
lazy val maxReceivedEnergy = tuning.getFloat("MaxReceivedEnergy")
lazy val activationEnergy = tuning.getFloat("ActivationEnergy")
lazy val maxStoredEnergy = tuning.getFloat("MaxStoredEnergy")
}
@@ -0,0 +1,15 @@
/*
* 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.machine
trait ProcessorMachine extends PoweredMachine {
lazy val mjPerItem = tuning.getFloat("MjPerItem")
lazy val powerUseRate = tuning.getFloat("PowerUseRate")
}
@@ -0,0 +1,65 @@
/*
* 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.power
import net.minecraft.nbt.NBTTagCompound
import net.bdew.lib.data.base.{TileDataSlots, UpdateKind, DataSlot}
import net.bdew.lib.Misc
import net.bdew.lib.machine.PoweredMachine
case class DataSlotPower(name: String, parent: TileDataSlots) extends DataSlot {
updateKind = Set(UpdateKind.GUI, UpdateKind.SAVE)
var stored = 0F
var capacity = 0F
var maxReceive = 0F
def inject(v: Float, simulate: Boolean): Float = {
val canAdd = Misc.clamp(v, 0F, Misc.min(capacity - stored, maxReceive))
if ((canAdd > 0) && !simulate) {
stored += canAdd
parent.dataSlotChanged(this)
}
return canAdd
}
def extract(v: Float, simulate: Boolean): Float = {
val canExtract = Misc.clamp(v, 0F, stored)
if ((canExtract > 0) && !simulate) {
stored -= canExtract
parent.dataSlotChanged(this)
}
return canExtract
}
def configure(cfg: PoweredMachine) {
capacity = cfg.maxStoredEnergy
maxReceive = cfg.maxReceivedEnergy
}
def save(t: NBTTagCompound, kind: UpdateKind.Value) {
val tag = new NBTTagCompound()
tag.setFloat("stored", stored)
if (kind == UpdateKind.GUI)
tag.setFloat("capacity", capacity)
t.setCompoundTag(name, tag)
}
def load(t: NBTTagCompound, kind: UpdateKind.Value) {
if (t.hasKey(name)) {
val tag = t.getCompoundTag(name)
stored = tag.getFloat("stored")
if (kind == UpdateKind.GUI)
capacity = tag.getFloat("capacity")
}
}
}
@@ -0,0 +1,49 @@
/*
* 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.power
import net.minecraft.item.{ItemStack, Item}
import net.bdew.lib.Misc
import net.minecraft.entity.EntityLivingBase
import net.minecraft.nbt.NBTTagCompound
trait ItemPoweredBase extends Item {
def maxCharge: Int
def mjPerCharge: Int
def getCharge(stack: ItemStack): Int = {
if (!stack.hasTagCompound) setCharge(stack, 0)
return Misc.clamp(stack.getTagCompound.getInteger("charge"), 0, maxCharge)
}
def useCharge(stack: ItemStack, uses: Int = 1, player: EntityLivingBase) {
setCharge(stack, Misc.clamp(getCharge(stack) - uses * mjPerCharge, 0, maxCharge))
}
def hasCharges(stack: ItemStack) = getCharge(stack) >= mjPerCharge
def setCharge(stack: ItemStack, charge: Int) {
if (!stack.hasTagCompound) stack.setTagCompound(new NBTTagCompound())
stack.getTagCompound.setInteger("charge", charge)
updateDamage(stack)
}
def updateDamage(stack: ItemStack) {
setDamage(stack, Misc.clamp((100 * (1 - getCharge(stack).toFloat / maxCharge)).round, 1, 100))
}
def stackWithCharge(charge: Int): ItemStack = {
val n = new ItemStack(this)
setCharge(n, charge)
return n
}
override def setDamage(stack: ItemStack, damage: Int) = super.setDamage(stack, Misc.clamp(damage, 1, 100))
}
@@ -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.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.machine.ProcessorMachine
abstract class TileBaseProcessor extends TileExtended
with TileDataSlots
with PersistentInventoryTile
with BreakableInventoryTile
with SidedInventory
with TilePoweredBase {
def cfg: ProcessorMachine
val power = DataSlotPower("power", this)
val progress = DataSlotFloat("progress", this).setUpdate(UpdateKind.SAVE, UpdateKind.GUI)
configurePower(cfg)
override def tickServer() {
if (power.stored > cfg.activationEnergy) {
if (!isWorking)
if (tryStart())
progress := 0
if (isWorking) {
if ((progress < 1) && (power.stored > cfg.activationEnergy)) {
val maxConsume = Math.min(Math.max(cfg.powerUseRate * power.stored, cfg.activationEnergy), cfg.mjPerItem * (1 - progress))
val consumed = power.extract(maxConsume, false)
progress += consumed / cfg.mjPerItem
}
if (progress >= 1) {
if (tryFinish())
progress := 0
}
}
}
}
/**
* Return true when an operation is in progress
*/
def isWorking: Boolean
/**
* Try starting a new operation, return true if succesful
*/
def tryStart(): Boolean
/**
* Perform output when operation is done, return true if succesful
*/
def tryFinish(): Boolean
}
@@ -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.power
import net.bdew.lib.data.DataSlotItemStack
import net.bdew.lib.data.base.UpdateKind
import net.bdew.lib.items.ItemUtils
abstract class TileItemProcessor extends TileBaseProcessor {
val output = DataSlotItemStack("output", this).setUpdate(UpdateKind.SAVE)
val outputSlots: Seq[Int]
def isWorking = output :!= null
def tryFinish(): Boolean = {
output := ItemUtils.addStackToSlots(output, this, outputSlots, false)
return output :== null
}
}
@@ -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
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.power
import net.bdew.lib.tile.TileExtended
import net.bdew.lib.machine.PoweredMachine
trait TilePoweredBase extends TileExtended {
def power: DataSlotPower
def configurePower(cfg: PoweredMachine) = power.configure(cfg)
}
@@ -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.power
import net.bdew.lib.gui.{Texture, Point, Rect}
import scala.collection.mutable
import java.text.DecimalFormat
import net.bdew.lib.gui.widgets.Widget
class WidgetPowerGauge(val rect: Rect, texture: Texture, dslot: DataSlotPower) extends Widget {
val formater = new DecimalFormat("#,###")
val a = rect.map(_.round)
override def draw(mouse: Point) {
val fill = dslot.stored / dslot.capacity
parent.drawTextureInterpolate(rect, texture, 0, 1 - fill, 1, 1)
}
override def handleTooltip(p: Point, tip: mutable.MutableList[String]) = tip += formater.format(dslot.stored) + "/" + formater.format(dslot.capacity) + " MJ"
}
+30 -10
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -89,6 +89,12 @@ case class StackMacro(id: Char) extends StackRef
*/
abstract class Statement
/**
* Base class for delayed statements (executed after everything is parsed)
* Actual processing is in [[net.bdew.lib.recipes.RecipeLoader.processDelayedStatements]]
*/
abstract class DelayedStatement extends Statement
/**
* Character assignment
* Syntax: {char} = {ref}
@@ -96,7 +102,7 @@ abstract class Statement
* @param char Character to assign
* @param spec ItemStack Reference
*/
case class StCharAssign(char: Char, spec: StackRef) extends Statement
case class StCharAssign(char: Char, spec: StackRef) extends DelayedStatement
/**
* Define class macro
@@ -105,7 +111,7 @@ case class StCharAssign(char: Char, spec: StackRef) extends Statement
* @param id Macro identifier
* @param cls Class name
*/
case class StClassMacro(id: String, cls: String) extends Statement
case class StClassMacro(id: String, cls: String) extends DelayedStatement
/**
* Conditional block - checks if mod is loaded
@@ -119,13 +125,27 @@ case class StIfHaveMod(mod: String, thn: List[Statement], els: List[Statement])
/**
* Conditional block - checks if mod is loaded
* Can contain only delayed statements
* Syntax: ifOreDict {string} { {statements} } [else { {statements} }]
* Parser: [[net.bdew.lib.recipes.RecipeParser.ifOreDict]]
* @param id Ore Dictionary Entry
* @param thn Statements to run if present
* @param els Statements to run otherwise
*/
case class StIfHaveOD(id: String, thn: List[Statement], els: List[Statement]) extends Statement
case class StIfHaveOD(id: String, thn: List[DelayedStatement], els: List[DelayedStatement]) extends DelayedStatement
/**
* Removes previously defined recieps for a specific result
* @param res Recipes that produce this result will be cleared
*/
case class StClearRecipes(res: StackRef) extends Statement
/**
* Base class for staments that represent a crafting recipe
*/
abstract class CraftingStatement extends DelayedStatement {
def result: StackRef
}
/**
* Shaped recipe definition
@@ -147,10 +167,10 @@ case class StIfHaveOD(id: String, thn: List[Statement], els: List[Statement]) ex
* Parser: [[net.bdew.lib.recipes.RecipeParser.recipeShaped9]]
*
* @param rec Recipe pattern
* @param res Result reference
* @param result Result reference
* @param cnt Number of output items
*/
case class StRecipeShaped(rec: Seq[String], res: StackRef, cnt: Int) extends Statement
case class StRecipeShaped(rec: Seq[String], result: StackRef, cnt: Int) extends CraftingStatement
/**
* Shapeless recipe definition
@@ -158,10 +178,10 @@ case class StRecipeShaped(rec: Seq[String], res: StackRef, cnt: Int) extends Sta
* Parser: [[net.bdew.lib.recipes.RecipeParser.recipeShapeless]]
*
* @param rec Recipe pattehrn
* @param res Result reference
* @param result Result reference
* @param cnt Number of output items
*/
case class StRecipeShapeless(rec: String, res: StackRef, cnt: Int) extends Statement
case class StRecipeShapeless(rec: String, result: StackRef, cnt: Int) extends CraftingStatement
/**
* Smelting recipe definition
@@ -169,11 +189,11 @@ case class StRecipeShapeless(rec: String, res: StackRef, cnt: Int) extends State
* Parser [[net.bdew.lib.recipes.RecipeParser.recipeSmelting]]
*
* @param in Input Stack
* @param out Output Stack
* @param result Output Stack
* @param cnt Output Count
* @param xp XP for smelting
*/
case class StSmeltRecipe(in: StackRef, out: StackRef, cnt: Int, xp: Float) extends Statement
case class StSmeltRecipe(in: StackRef, result: StackRef, cnt: Int, xp: Float) extends CraftingStatement
/**
* Used in statement processing to abort the current statement and show an error without a stack trace
+77 -22
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -11,12 +11,11 @@ package net.bdew.lib.recipes
import java.io.Reader
import net.minecraft.item.{Item, ItemStack}
import net.bdew.lib.Misc
import net.bdew.lib.{BdLib, Misc}
import net.minecraft.block.Block
import cpw.mods.fml.common.registry.GameRegistry
import net.minecraftforge.oredict.{ShapelessOreRecipe, OreDictionary}
import java.util.logging.Logger
import cpw.mods.fml.common.FMLLog
import net.minecraft.item.crafting.FurnaceRecipes
/**
@@ -35,23 +34,28 @@ class RecipeLoader {
def newParser() = new RecipeParser()
val log: Logger = Logger.getLogger("RecipeLoader")
log.setParent(FMLLog.getLogger)
log.setParent(BdLib.log)
/**
* Current map of recipe characters to parser item references
*/
val currCharMap = collection.mutable.Map.empty[Char, StackRef].withDefault(x => error("Undefined recipe character '%s'", x))
var currCharMap = Map.empty[Char, StackRef].withDefault(x => error("Undefined recipe character '%s'", x))
/**
* Current map of class macros
*/
val currClassMacros = collection.mutable.Map.empty[String, String].withDefault(x => error("Undefined class macro '%s'", x))
var currClassMacros = Map.empty[String, String].withDefault(x => error("Undefined class macro '%s'", x))
/**
* Triggers an error with formatted string
*/
def error(msg: String, params: Any*) = throw new StatementError(msg.format(params: _*))
/**
* List of unprocessed delayed statements
*/
var delayedStatements = List.empty[DelayedStatement]
/**
* Looks up a recipe component
* @param s Parser ItemStack reference
@@ -209,14 +213,6 @@ class RecipeLoader {
* @param s The statement
*/
def processStatement(s: Statement): Unit = s match {
case StCharAssign(c, r) =>
currCharMap(c) = r
log.info("Added %s = %s".format(c, r))
case StClassMacro(id, cls) =>
currClassMacros(id) = cls
log.info("Added def %s = %s".format(id, cls))
case StIfHaveMod(mod, thn, els) =>
if (Misc.haveModVersion(mod)) {
log.info("ifMod: %s found".format(mod))
@@ -226,14 +222,37 @@ class RecipeLoader {
processStatementsSafe(els)
}
case StIfHaveOD(od, thn, els) =>
if (OreDictionary.getOres(od).size() > 0) {
log.info("ifOreDict: %s found".format(od))
processStatementsSafe(thn)
} else {
log.info("ifOreDict: %s not found".format(od))
processStatementsSafe(els)
}
case StClearRecipes(res) =>
log.info("Clearing recipes that produce %s".format(res))
delayedStatements = delayedStatements.filter({
x =>
if (x.isInstanceOf[CraftingStatement])
if (x.asInstanceOf[CraftingStatement].result == res) {
log.info("Removing recipe %s".format(x))
false
} else true
else true
})
case x: DelayedStatement =>
delayedStatements :+= x
case x =>
log.severe("Can't process %s - this is a programing bug!".format(x))
}
/**
* Process a single delayed statement
* @param st The statement
*/
def processDelayedStatement(st: DelayedStatement) = st match {
case StCharAssign(c, r) =>
currCharMap += (c -> r)
log.info("Added %s = %s".format(c, r))
case StClassMacro(id, cls) =>
currClassMacros += (id -> cls)
log.info("Added def %s = %s".format(id, cls))
case StRecipeShaped(rec, res, cnt) =>
log.info("Adding shaped recipe %s => %s * %d".format(rec, res, cnt))
@@ -287,10 +306,46 @@ class RecipeLoader {
}
}
case StIfHaveOD(od, thn, els) =>
if (OreDictionary.getOres(od).size() > 0) {
log.info("ifOreDict: %s found".format(od))
processDelayedStatementsSafe(thn)
} else {
log.info("ifOreDict: %s not found".format(od))
processDelayedStatementsSafe(els)
}
case x =>
log.severe("Can't process %s - this is a programing bug!".format(x))
}
/**
* Process main delayed statements list, clear the list afterwards
*/
def processDelayedStatements() {
log.info("Processing %d delayed statements".format(delayedStatements.size))
processDelayedStatementsSafe(delayedStatements)
delayedStatements = List.empty
}
/**
* Process a list of delayed statements and catch all exceptions
* @param list The list to process
*/
def processDelayedStatementsSafe(list: List[DelayedStatement]) {
for (s <- list) {
try {
processDelayedStatement(s)
} catch {
case e: StatementError =>
log.severe("Error while processing %s: %s".format(s, e.getMessage))
case e: Throwable =>
log.severe("Error while processing %s: %s".format(s, e))
e.printStackTrace()
}
}
}
/**
* Process a list of statements and catch all exceptions
* @param r The list to process
+10 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -78,8 +78,8 @@ class RecipeParser extends JavaTokenParsers {
case mod ~ thn ~ els => new StIfHaveMod(mod, thn, els.getOrElse(List.empty[Statement]))
}
def ifOreDict = ("ifOreDict" ~> str) ~ ("{" ~> statements <~ "}") ~ ("else" ~> "{" ~> statements <~ "}").? ^^ {
case id ~ thn ~ els => new StIfHaveOD(id, thn, els.getOrElse(List.empty[Statement]))
def ifOreDict = ("ifOreDict" ~> str) ~ ("{" ~> delayedStatements <~ "}") ~ ("else" ~> "{" ~> delayedStatements <~ "}").? ^^ {
case id ~ thn ~ els => new StIfHaveOD(id, thn, els.getOrElse(List.empty[DelayedStatement]))
}
def recipeShaped3x3 = recipeTriplet ~ recipeTriplet ~ ("=>" ~> specWithCount) ~ recipeTriplet ^^ {
@@ -102,10 +102,12 @@ class RecipeParser extends JavaTokenParsers {
case in ~ (out ~ n) ~ xp => StSmeltRecipe(in, out, n.getOrElse(1), xp.getOrElse("0").toFloat)
}
def statement: Parser[Statement] = (
def clearRecipes = "clearRecipes" ~> ":" ~> spec ^^ { case sp => StClearRecipes(sp) }
def delayedStatement: Parser[DelayedStatement] = (
charSpec
| classMacro
| ifMod
| ifOreDict
| recipeShaped3x3
| recipeShaped2x2
| recipeShaped9
@@ -113,7 +115,10 @@ class RecipeParser extends JavaTokenParsers {
| recipeSmelting
)
def statement: Parser[Statement] = delayedStatement | ifMod | clearRecipes
def statements = statement.*
def delayedStatements = delayedStatement.*
def doParse(r: Reader): List[Statement] = {
parseAll(statements, r) match {
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -9,17 +9,21 @@
package net.bdew.lib.recipes.gencfg
import net.bdew.lib.gui.Color
abstract class CfgEntry
case class EntryDouble(v: Double) extends CfgEntry
case class EntryStr(v: String) extends CfgEntry
case class EntryNumList(v: List[Double]) extends CfgEntry
case class ConfigSection(pfx: String = "") extends CfgEntry with Iterable[(String, CfgEntry)] {
var raw = Map.empty[String, CfgEntry].withDefault(x => sys.error("Config value '%s%s' is missing".format(pfx,x)))
var raw = Map.empty[String, CfgEntry].withDefault(x => sys.error("Config value '%s%s' is missing".format(pfx, x)))
def iterator: Iterator[(String, CfgEntry)] = raw.iterator
def filterType[T<:CfgEntry](cls: Class[T]): Iterable[(String,T)] = raw.filter(x=>cls.isInstance(x._2)).map(x=>x.asInstanceOf[(String,T)])
def filterType[T <: CfgEntry](cls: Class[T]): Iterable[(String, T)] = raw.filter(x => cls.isInstance(x._2)).map(x => x.asInstanceOf[(String, T)])
def rawget[T](id: String, t: Class[T]): T = {
val v = raw(id)
@@ -33,12 +37,14 @@ case class ConfigSection(pfx: String = "") extends CfgEntry with Iterable[(Strin
def getDouble(id: String) = rawget(id, classOf[EntryDouble]).v
def getString(id: String) = rawget(id, classOf[EntryStr]).v
def getDoubleList(id: String) = rawget(id, classOf[EntryNumList]).v
def getSection(id: String) = rawget(id, classOf[ConfigSection])
final val trueVals = Set("y", "true", "yes", "on")
def getBoolean(id: String) = trueVals.contains(getString(id).toLowerCase)
def hasValue(id: String) = raw.isDefinedAt(id)
def getOrAddSection(id: String) = {
if (raw.isDefinedAt(id)) {
rawget(id, classOf[ConfigSection])
@@ -51,6 +57,15 @@ case class ConfigSection(pfx: String = "") extends CfgEntry with Iterable[(Strin
def getInt(id: String) = getDouble(id).round.toInt
def getFloat(id: String) = getDouble(id).toFloat
def getIntList(id: String) = getDoubleList(id).map(_.round.toInt).toList
def getFloatList(id: String) = getDoubleList(id).map(_.toFloat).toList
def getColor(id: String) =
raw(id) match {
case EntryDouble(c) => Color.fromInt(c.toInt)
case EntryNumList(r :: g :: b :: Nil) => Color(r.toFloat, g.toFloat, b.toFloat)
case x => sys.error("Invalid color definition: %s".format(x))
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -13,14 +13,25 @@ import net.bdew.lib.recipes.RecipeParser
trait GenericConfigParser extends RecipeParser {
override def statement = statementCfg | super.statement
def cfgStatementNum = ident ~ "=" ~ decimalNumber ^^ { case id ~ eq ~ n => CfgVal(id, EntryDouble(n.toDouble)) }
// Hex variant must come before decimalNumber, otherwise the parser breaks
def signedNumber = (
("0x" ~> "[0-9A-Fa-f]+".r) ^^ { case x => Integer.parseInt(x, 16).toDouble }
| decimalNumber ^^ { case x => x.toDouble }
| ("-" ~> decimalNumber) ^^ { case x => -x.toDouble }
)
def cfgStatementNum = ident ~ "=" ~ signedNumber ^^ { case id ~ eq ~ n => CfgVal(id, EntryDouble(n.toDouble)) }
def cfgStatementStr = ident ~ "=" ~ str ^^ { case id ~ eq ~ s => CfgVal(id, EntryStr(s)) }
def cfgStatementNumList = ident ~ ("=" ~> "{" ~> signedNumber.* <~ "}") ^^ { case id ~ l => CfgVal(id, EntryNumList(l)) }
def cfgStatementSub = cfgBlock ^^ { case (id, st) => CfgSub(id, st) }
def cfgStatement = cfgStatementNum | cfgStatementStr | cfgStatementSub
def cfgStatement = cfgStatementNum | cfgStatementStr | cfgStatementSub | cfgStatementNumList
// A bit of type acrobatics because this is recursive (via cfgStatementSub), the tuple is translated into the proper class in either cfgStatementSub or cfg
def cfgBlock: Parser[(String, List[CfgStatement])] = "cfg" ~> ident ~ ("{" ~> cfgStatement.* <~ "}") ^^ { case id ~ st => (id, st) }
// A bit of type acrobatics because this is recursive (via cfgStatementSub)
// the tuple is translated into the proper class in either cfgStatementSub or cfg
def cfgBlock: Parser[(String, List[CfgStatement])] =
"cfg" ~> ident ~ ("{" ~> cfgStatement.* <~ "}") ^^ { case id ~ st => (id, st) }
def statementCfg = cfgBlock ^^ { case (id, st) => StCfg(id, st) }
}
@@ -0,0 +1,24 @@
/*
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/gendustry
*
* 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/gendustry/master/MMPL-1.0.txt
*/
package net.bdew.lib.recipes.lootlist
import net.bdew.lib.recipes.StackRef
import net.bdew.lib.recipes.gencfg.CfgEntry
/**
* Allos definition of random-weighted loot/drop lists in config sections
* @param list List on (chance percent, stack reference) pairs, resolve to
* real ItemStacks with LootListLoader.resolveLootList
*/
case class EntryLootList(list: List[(Int, StackRef)]) extends CfgEntry
@@ -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.recipes.lootlist
import net.bdew.lib.recipes.gencfg.GenericConfigLoader
import net.minecraftforge.oredict.OreDictionary
import net.bdew.lib.recipes.StackRef
import net.minecraft.item.ItemStack
/**
* Loader mixin for loot lists
*/
trait LootListLoader extends GenericConfigLoader {
def resolveLootList(entry: EntryLootList): List[(Int, ItemStack)] = resolveLootList(entry.list)
def resolveLootList(list: List[(Int, StackRef)]) =
(for ((chance, ref) <- list) yield {
try {
val itemStack = getConcreteStack(ref)
if (itemStack == null) {
log.warning("Unable to resolve %s: null returned".format(ref))
None
} else {
if (itemStack.getItemDamage == OreDictionary.WILDCARD_VALUE) {
log.info("meta/damage is unset in %s, defaulting to 0".format(ref))
itemStack.setItemDamage(0)
}
Some((chance, itemStack))
}
} catch {
case e: Throwable =>
log.warning("Unable to resolve %s: %s".format(ref, e.getMessage))
None
}
}).flatten
}
@@ -0,0 +1,25 @@
/*
* 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.recipes.lootlist
import net.bdew.lib.recipes.gencfg.{CfgVal, GenericConfigParser}
/**
* Parser mixin for loot lists
* ident: DropsList(
* {chance}% {stackRef}
* ...
* )
*/
trait LootListParser extends GenericConfigParser {
def dropsEntry = (wholeNumber <~ "%") ~ spec ^^ { case n ~ s => (n.toInt, s) }
def cfgDrops = ident ~ (":" ~> "DropsList" ~> "(" ~> dropsEntry.* <~ ")") ^^ { case id ~ a => CfgVal(id, EntryLootList(a)) }
override def cfgStatement = cfgDrops | super.cfgStatement
}
@@ -0,0 +1,54 @@
/*
* 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.render
import net.minecraft.client.renderer.texture.IconRegister
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.event.ForgeSubscribe
import net.minecraftforge.client.event.TextureStitchEvent
import net.bdew.lib.gui.{Texture, IconWrapper}
/**
* Allows loading of texture that don't belong to specific block or item into vanilla block/item atlas
* @param kind 0=Blocks / 1=Items
*/
class IconPreloader(kind: Int) {
var icons = Set.empty[TextureLoc]
val sheet = kind match {
case 0 => Texture.BLOCKS
case 1 => Texture.ITEMS
case x => sys.error("Invalid spritesheet number: %d".format(x))
}
case class TextureLoc(loc: String) {
var texture: IconWrapper = null
icons += this
}
import language.implicitConversions
implicit def entry2icon(v: TextureLoc) = v.texture.icon
implicit def entry2texture(v: TextureLoc) = v.texture
def registerIcons(reg: IconRegister) {}
def init() {
MinecraftForge.EVENT_BUS.register(this)
}
@ForgeSubscribe
def preTextureStitch(ev: TextureStitchEvent.Pre) {
if (ev.map.getTextureType == kind) {
for (x <- icons) x.texture = Texture(sheet, ev.map.registerIcon(x.loc))
registerIcons(ev.map)
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
+1 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public
@@ -1,5 +1,5 @@
/*
* Copyright (c) bdew, 2013
* Copyright (c) bdew, 2013 - 2014
* https://github.com/bdew/bdlib
*
* This mod is distributed under the terms of the Minecraft Mod Public