Compare commits

...
38 Commits
Author SHA1 Message Date
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
41 changed files with 845 additions and 164 deletions

No files matched your search

+1 -1
View File
@@ -14,7 +14,7 @@ buildscript {
apply plugin: 'forge'
apply plugin: 'scala'
version = "1.1.0"
version = "1.2.2"
if (project.hasProperty('buildnum')) {
project.version = project.version + '.' + project.buildnum
+11 -1
View File
@@ -11,10 +11,20 @@ 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", 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 BDLIB_VER 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)
}
}
+4
View File
@@ -16,6 +16,7 @@ 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
object Misc {
def iterNbtList[X](list: NBTTagList) =
@@ -25,6 +26,7 @@ object Misc {
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 {
@@ -53,6 +55,8 @@ object Misc {
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
+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
}
+10 -8
View File
@@ -12,7 +12,6 @@ package net.bdew.lib.gui
import net.minecraft.client.gui.inventory.GuiContainer
import net.minecraft.inventory.Container
import scala.collection.mutable
import net.minecraft.util.ResourceLocation
import org.lwjgl.opengl.GL11
abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContainer(cont) {
@@ -21,11 +20,12 @@ abstract class BaseScreen(cont: Container, xSz: Int, ySz: Int) extends GuiContai
val widgets = new WidgetContainerWindow(this, xSz, ySz)
val texture: ResourceLocation
val background: Texture
def rect = new Rect(guiLeft, guiTop, xSize, ySize)
def getFontRenderer = fontRenderer
def getZLevel = zLevel
override def initGui() {
super.initGui()
@@ -58,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)
}
+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)
}
-25
View File
@@ -1,25 +0,0 @@
/*
* 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 Point(x: Int, 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 - 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 Rect(x: Int, y: Int, w: Int, 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 -2
View File
@@ -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))
}
+26 -35
View File
@@ -11,15 +11,15 @@ package net.bdew.lib.gui
import scala.collection.mutable
import net.bdew.lib.gui.widgets.BaseWidget
import net.minecraft.util.Icon
import net.minecraft.client.gui.FontRenderer
import net.minecraft.client.Minecraft
import org.lwjgl.opengl.GL11
trait WidgetContainer {
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()
@@ -31,7 +31,7 @@ trait WidgetContainer {
}
def mouseClicked(p: Point, bt: Int) {
for (w <- widgets)
for (w <- activeWidgets)
if (w.rect.contains(p))
w.mouseClicked(p - w.rect.origin, bt)
else
@@ -39,56 +39,47 @@ trait WidgetContainer {
}
def keyTyped(c: Char, i: Int): Boolean = {
for (w <- widgets)
for (w <- activeWidgets)
if (w.keyTyped(c, i))
return true
return false
}
def draw(mouse: Point) {
def drawBackground(mouse: Point) {
val p = mouse - rect.origin
for (w <- widgets) {
GL11.glPushMatrix()
GL11.glTranslatef(rect.origin.x, rect.origin.y, 0)
w.draw(p)
GL11.glPopMatrix()
GL11.glPushMatrix()
GL11.glTranslatef(rect.origin.x, rect.origin.y, 0)
for (w <- activeWidgets) {
w.drawBackground(p)
}
GL11.glPopMatrix()
}
def handleTooltip(op: Point, tip: mutable.MutableList[String]) {
val p = op
for (w <- widgets if w.rect.contains(p))
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 drawTexture(r: Rect, t: TextureLocation) {
Minecraft.getMinecraft.renderEngine.bindTexture(t.resource)
drawTexture(r, t.p)
}
def looseFocus() =
for (w <- widgets)
for (w <- activeWidgets)
w.looseFocus()
def getOffsetFromWindow: Point
def drawTexture(r: Rect, uv: Point): Unit
def drawIcon(r: Rect, i: Icon)
}
class WidgetContainerWindow(val parent: BaseScreen, xSz: Int, ySz: Int) extends WidgetContainer {
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)
def drawTexture(r: Rect, uv: Point) =
parent.drawTexturedModalRect(r.x, r.y, uv.x, uv.y, r.w, r.h)
def drawIcon(r: Rect, i: Icon) =
parent.drawTexturedModelRectFromIcon(r.x, r.y, i, r.w, r.h)
}
class WidgetSubcontainer(val rect: Rect) extends BaseWidget with WidgetContainer {
def getFontRenderer = parent.getFontRenderer
def getOffsetFromWindow = parent.getOffsetFromWindow + rect.origin
def drawTexture(r: Rect, uv: Point) = parent.drawTexture(r, uv)
def drawIcon(r: Rect, i: Icon) = parent.drawIcon(r, i)
}
+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)
}
+2 -4
View File
@@ -11,8 +11,6 @@ package net.bdew.lib.gui.widgets
import scala.collection.mutable
import net.bdew.lib.gui.{WidgetContainer, Point, Rect}
import net.minecraft.util.ResourceLocation
import net.minecraft.client.Minecraft
trait BaseWidget {
val rect: Rect
@@ -22,6 +20,7 @@ trait BaseWidget {
def mouseClicked(p: Point, button: Int)
def keyTyped(c: Char, i: Int): Boolean
def draw(mouse: Point)
def drawBackground(mouse: Point)
def looseFocus()
}
@@ -31,7 +30,6 @@ trait Widget extends BaseWidget {
def mouseClicked(p: Point, button: Int) {}
def keyTyped(c: Char, i: Int): Boolean = false
def draw(mouse: Point) {}
def drawBackground(mouse: Point) {}
def looseFocus() {}
def bindTexture(res: ResourceLocation) = Minecraft.getMinecraft.renderEngine.bindTexture(res)
}
@@ -1,10 +1,10 @@
/*
* Copyright (c) bdew, 2014
* https://github.com/bdew/teleporter
* 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/teleporter/master/MMPL-1.0.txt
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.gui.widgets
@@ -14,12 +14,12 @@ 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, rect.y, rect.w, rect.h, text) with Widget {
extends GuiButton(0, rect.x.round, rect.y.round, rect.w.round, rect.h.round, text) with Widget {
override def mouseClicked(p: Point, button: Int) {
Minecraft.getMinecraft.sndManager.playSoundFX("random.click", 1.0F, 1.0F)
clicked(this)
}
override def draw(mouse: Point) = drawButton(Minecraft.getMinecraft, mouse.x, mouse.y)
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)
}
}
@@ -9,28 +9,24 @@
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{Point, TextureLocation, Rect, 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(mouse: Point) {
bindTexture(texture.resource)
val fill = dslot.cval.toFloat() / maxval.toFloat()
dir match {
case Direction.UP =>
val fill = getFillArea(rect.h)
parent.drawTexture(Rect(rect.x, rect.y + rect.h - fill, rect.w, fill), Point(texture.x, texture.y + rect.h - fill))
parent.drawTextureInterpolate(rect, texture, 0, 1 - fill, 1, 1)
case Direction.DOWN =>
val fill = getFillArea(rect.h)
parent.drawTexture(Rect(rect.x, rect.y, rect.w, fill), Point(texture.x, texture.y))
parent.drawTextureInterpolate(rect, texture, 0, 0, 1, fill)
case Direction.LEFT =>
val fill = getFillArea(rect.w)
parent.drawTexture(Rect(rect.x + rect.w - fill, rect.y, fill, rect.h), Point(texture.x + rect.w - fill, texture.y))
parent.drawTextureInterpolate(rect, texture, 1 - fill, 0, 1, 1)
case Direction.RIGHT =>
val fill = getFillArea(rect.w)
parent.drawTexture(Rect(rect.x, rect.y, fill, rect.h), Point(texture.x, texture.y))
parent.drawTextureInterpolate(rect, texture, 0, 0, fill, 1)
}
}
}
@@ -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]) {
@@ -35,17 +34,16 @@ class WidgetFluidGauge(val rect: Rect, overlay: TextureLocation, dslot: DataSlot
val fstack = dslot.getFluid
if (fstack != null && fstack.getFluid.getStillIcon != null) {
val icon = fstack.getFluid.getStillIcon
bindTexture(TextureMap.locationBlocksTexture)
var fillHeight: Int = if (dslot.getCapacity > 0) (rect.h * fstack.amount / dslot.getCapacity).round else 0
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.drawIcon(Rect(rect.x, rect.y + rect.h - 16 - yStart, rect.w, 16), icon)
parent.drawTexture(new Rect(rect.x, rect.y2 - 16 - yStart, rect.w, 16), icon)
fillHeight -= 16
} else {
parent.drawIcon(Rect(rect.x, rect.y + rect.h - fillHeight - yStart, rect.w, fillHeight), icon)
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
@@ -9,11 +9,11 @@
package net.bdew.lib.gui.widgets
import net.bdew.lib.gui.{Point, 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)
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.getFontRenderer.drawString(text, x, y, color)
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)
}
@@ -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
}
@@ -12,11 +12,11 @@ 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 {
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, pp.y, button)
super.mouseClicked(pp.x.round, pp.y.round, button)
}
override def looseFocus() = setFocused(false)
@@ -7,10 +7,17 @@
* https://raw.github.com/bdew/bdlib/master/MMPL-1.0.txt
*/
package net.bdew.lib.gui
package net.bdew.lib.items
import net.minecraft.util.ResourceLocation
import net.minecraft.item.{Item, ItemStack}
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))
/**
* 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)
}
+20 -1
View File
@@ -10,11 +10,12 @@
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.bdew.lib.Misc
import java.util.Random
object ItemUtils {
def throwItemAt(world: World, x: Int, y: Int, z: Int, stack: ItemStack) {
@@ -76,4 +77,22 @@ object ItemUtils {
return stack
}
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
}
}
@@ -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)
}
}
@@ -9,19 +9,19 @@
package net.bdew.lib.power
import net.bdew.lib.gui.{Point, TextureLocation, Rect}
import net.bdew.lib.gui.{Texture, Point, Rect}
import scala.collection.mutable
import java.text.DecimalFormat
import net.minecraft.client.Minecraft
import net.bdew.lib.gui.widgets.Widget
class WidgetPowerGauge(val rect: Rect, texture: TextureLocation, dslot: DataSlotPower) extends 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) {
Minecraft.getMinecraft.renderEngine.bindTexture(texture.resource)
val fill = (dslot.stored / dslot.capacity * rect.h).round
parent.drawTexture(Rect(rect.x, rect.y + rect.h - fill, rect.w, fill), Point(texture.x, texture.y + rect.h - fill))
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"
+2 -1
View File
@@ -125,13 +125,14 @@ 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
+22 -15
View File
@@ -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,7 +34,7 @@ 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
@@ -223,15 +222,6 @@ 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({
@@ -316,16 +306,34 @@ 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 delayed statements, clear the list afterwards
* Process main delayed statements list, clear the list afterwards
*/
def processDelayedStatements() {
log.info("Processing %d delayed statements".format(delayedStatements.size))
for (s <- delayedStatements) {
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 {
@@ -336,7 +344,6 @@ class RecipeLoader {
e.printStackTrace()
}
}
delayedStatements = List.empty
}
/**
+6 -5
View File
@@ -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 ^^ {
@@ -104,20 +104,21 @@ class RecipeParser extends JavaTokenParsers {
def clearRecipes = "clearRecipes" ~> ":" ~> spec ^^ { case sp => StClearRecipes(sp) }
def statement: Parser[Statement] = (
def delayedStatement: Parser[DelayedStatement] = (
charSpec
| classMacro
| ifMod
| ifOreDict
| recipeShaped3x3
| recipeShaped2x2
| recipeShaped9
| recipeShapeless
| recipeSmelting
| clearRecipes
)
def statement: Parser[Statement] = delayedStatement | ifMod | clearRecipes
def statements = statement.*
def delayedStatements = delayedStatement.*
def doParse(r: Reader): List[Statement] = {
parseAll(statements, r) match {
@@ -9,12 +9,16 @@
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)))
@@ -33,6 +37,7 @@ 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")
@@ -52,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))
}
}
@@ -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)
}
}
}