Files
ForgeMultipart/codechicken/microblock/MicroMaterialRegistry.scala
T
Chicken-Bones 306a47d1f4 Added damage/nbt sensitive cutting strength to saws
The highest tier saw is now able to cut blocks with strength requirements higher than itself
General code cleanup
2013-12-23 02:57:43 +10:00

232 lines
7.1 KiB
Scala

package codechicken.microblock
import codechicken.multipart.IDWriter
import codechicken.lib.lighting.LightMatrix
import codechicken.lib.packet.PacketCustom
import scala.collection.mutable.HashMap
import codechicken.lib.data.MCDataOutput
import codechicken.lib.data.MCDataInput
import codechicken.multipart.MultiPartRegistry
import cpw.mods.fml.relauncher.SideOnly
import cpw.mods.fml.relauncher.Side
import codechicken.lib.vec.Vector3
import net.minecraft.util.Icon
import net.minecraft.entity.player.EntityPlayer
import codechicken.lib.render.Vertex5
import net.minecraft.item.{Item, ItemStack}
import scala.collection.mutable.ListBuffer
import net.minecraft.block.StepSound
import net.minecraft.util.MovingObjectPosition
import net.minecraft.world.World
object MicroMaterialRegistry
{
/**
* Interface for defining a micro material
*/
trait IMicroMaterial
{
/**
* The icon to be used for breaking particles on side
*/
@SideOnly(Side.CLIENT)
def getBreakingIcon(side:Int):Icon
/**
* Callback to load icons from the underlying block/etc
*/
@SideOnly(Side.CLIENT)
def loadIcons(){}
/**
* This function must render the quad face specified by verts facing on side, at pos (x, y, z)
* @param lightMatrix A helper class provided for calculating minecraft smooth lighting on the face.
* @param part An IMicroMaterialRender callback for some information about the caller such as bounds and world for grass decals.
*/
@SideOnly(Side.CLIENT)
def renderMicroFace(verts:Array[Vertex5], side:Int, pos:Vector3, lightMatrix:LightMatrix, part:IMicroMaterialRender)
/**
* Get the render pass for which this material renders in.
*/
@SideOnly(Side.CLIENT)
def getRenderPass:Int
/**
* Return true if this material is not opaque (glass, ice).
*/
def isTransparent:Boolean
/**
* Return the light level emitted by this material (glowstone)
*/
def getLightValue:Int
/**
* Return the strength of this material
*/
def getStrength(player:EntityPlayer):Float
/**
* Return the localised name of this material (normally the block name)
*/
def getLocalizedName:String
/**
* Get the item that this material is cut from (full block -> slabs)
*/
def getItem:ItemStack
/**
* Get the strength of saw requried to cut this material
*/
def getCutterStrength:Int
/**
* Get the breaking/walking sound
*/
def getSound:StepSound
/**
* Return true if this material is solid and opaque (can run wires on etc)
*/
def isSolid = !isTransparent
}
/**
* Interface for overriding the default micro placement highlight handler to show the effect of placement on a certain block/part
*/
trait IMicroHighlightRenderer
{
/**
* Return true if a custom highlight was rendered and the default should be skipped
*/
def renderHighlight(world:World, player:EntityPlayer, hit:MovingObjectPosition, mcrClass:MicroblockClass, size:Int, material:Int):Boolean
}
private val typeMap = HashMap[String, IMicroMaterial]()
private val nameMap = HashMap[String, Int]()
private var idMap:Array[(String, IMicroMaterial)] = _
private val idWriter = new IDWriter
private val highlightRenderers = ListBuffer[IMicroHighlightRenderer]()
private var maxCuttingStrength:Int = _
/**
* Register a micro material with unique identifier name
*/
def registerMaterial(material:IMicroMaterial, name:String)
{
if(MultiPartRegistry.loaded)
throw new IllegalStateException("You must register your materials in the init methods.")
if(typeMap.contains(name))
throw new IllegalStateException("Material with id "+name+" is already registered.")
System.out.println("Registered micro material: "+name)
typeMap.put(name, material)
}
/**
* Replace a micro material with unique identifier name
*/
def replaceMaterial(material:IMicroMaterial, name:String) {
if(MultiPartRegistry.loaded)
throw new IllegalStateException("You must register your materials in the init methods.")
if(typeMap.remove(name).isEmpty)
System.err.println("Material with id "+name+" is was not registered.")
System.out.println("Replaced micro material: "+name)
typeMap.put(name, material)
}
/**
* Registers a highlight renderer
*/
def registerHighlightRenderer(handler:IMicroHighlightRenderer)
{
highlightRenderers+=handler
}
private [microblock] def setupIDMap()
{
idMap = typeMap.toList.sortBy(_._1).toArray
idWriter.setMax(idMap.length)
nameMap.clear()
for(i <- 0 until idMap.length)
nameMap.put(idMap(i)._1, i)
}
private [microblock] def calcMaxCuttingStrength()
{
maxCuttingStrength = Item.itemsList.flatMap {
case saw: Saw => Some(saw.getMaxCuttingStrength)
case _ => None
}.max
}
def getMaxCuttingStrength = maxCuttingStrength
def writeIDMap(packet:PacketCustom)
{
packet.writeInt(idMap.size)
idMap.foreach(e => packet.writeString(e._1))
}
def readIDMap(packet:PacketCustom):Seq[String] =
{
val k = packet.readInt()
idWriter.setMax(k)
idMap = new Array(k)
nameMap.clear()
val missing = ListBuffer[String]()
for(i <- 0 until k)
{
val s = packet.readString()
val v = typeMap.get(s)
if(v.isEmpty)
missing+=s
else {
idMap(i) = (s, v.get)
nameMap.put(s, i)
}
}
return missing
}
//TODO: change to material
def writePartID(data:MCDataOutput, id:Int)
{
idWriter.write(data, id)
}
//TODO: change to material
def readPartID(data:MCDataInput) = idWriter.read(data)
def materialName(id:Int) = idMap(id)._1
def materialID(name:String) = nameMap.get(name) match {
case Some(v) => v
case None =>
System.err.println("Missing mapping for part with ID: "+name)
0
}
def getMaterial(name:String) = typeMap.getOrElse(name, null)
def getMaterial(id:Int) = idMap(id)._2
def getIdMap = idMap
def renderHighlight(world:World, player:EntityPlayer, hit:MovingObjectPosition, mcrClass:MicroblockClass, size:Int, material:Int):Boolean =
{
val overridden = highlightRenderers.find(_.renderHighlight(world, player, hit, mcrClass, size, material))
if(overridden.isDefined)
return true
return mcrClass.renderHighlight(world, player, hit, size, material)
}
}