diff --git a/src/main/scala/li/cil/oc/client/PacketHandler.scala b/src/main/scala/li/cil/oc/client/PacketHandler.scala index b3f961625..7bb86376d 100644 --- a/src/main/scala/li/cil/oc/client/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/client/PacketHandler.scala @@ -36,7 +36,7 @@ object PacketHandler extends CommonPacketHandler { } override def dispatch(p: PacketParser) { - p.packetType match { + if (p.player != null && p.player.getEntityWorld != null) p.packetType match { case PacketType.Analyze => onAnalyze(p) case PacketType.ChargerState => onChargerState(p) case PacketType.ColorChange => onColorChange(p) @@ -332,14 +332,14 @@ object PacketHandler extends CommonPacketHandler { } def onTextBufferPowerChange(p: PacketParser) = - ComponentTracker.get(p.player.worldObj, p.readUTF()) match { + ComponentTracker.get(p.player.getEntityWorld, p.readUTF()) match { case Some(buffer: component.TextBuffer) => buffer.setRenderingEnabled(p.readBoolean()) case _ => // Invalid packet. } def onTextBufferInit(p: PacketParser) { - ComponentTracker.get(p.player.worldObj, p.readUTF()) match { + ComponentTracker.get(p.player.getEntityWorld, p.readUTF()) match { case Some(buffer: li.cil.oc.common.component.TextBuffer) => val nbt = p.readNBT() if (nbt.hasKey("maxWidth")) { @@ -354,7 +354,7 @@ object PacketHandler extends CommonPacketHandler { } def onTextBufferMulti(p: PacketParser) = - ComponentTracker.get(p.player.worldObj, p.readUTF()) match { + ComponentTracker.get(p.player.getEntityWorld, p.readUTF()) match { case Some(buffer: component.TextBuffer) => try while (true) { p.readPacketType() match { diff --git a/src/main/scala/li/cil/oc/client/Proxy.scala b/src/main/scala/li/cil/oc/client/Proxy.scala index 06eff5a40..6941079f1 100644 --- a/src/main/scala/li/cil/oc/client/Proxy.scala +++ b/src/main/scala/li/cil/oc/client/Proxy.scala @@ -5,7 +5,7 @@ import li.cil.oc.client.renderer.HighlightRenderer import li.cil.oc.client.renderer.PetRenderer import li.cil.oc.client.renderer.TextBufferRenderCache import li.cil.oc.client.renderer.WirelessNetworkDebugRenderer -import li.cil.oc.client.renderer.block.ExtendedBlockModel +import li.cil.oc.client.renderer.block.ModelInitialization import li.cil.oc.client.renderer.entity.DroneRenderer import li.cil.oc.client.renderer.tileentity._ import li.cil.oc.common.component.TextBuffer @@ -16,13 +16,7 @@ import li.cil.oc.common.tileentity.ServerRack import li.cil.oc.common.{Proxy => CommonProxy} import li.cil.oc.util.Audio import net.minecraft.block.Block -import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.ItemMeshDefinition -import net.minecraft.client.resources.model.ModelBakery -import net.minecraft.client.resources.model.ModelResourceLocation import net.minecraft.item.Item -import net.minecraft.item.ItemStack -import net.minecraftforge.client.model.ModelLoader import net.minecraftforge.common.MinecraftForge import net.minecraftforge.fml.client.registry.ClientRegistry import net.minecraftforge.fml.client.registry.RenderingRegistry @@ -33,12 +27,7 @@ import net.minecraftforge.fml.common.event.FMLPreInitializationEvent import net.minecraftforge.fml.common.network.NetworkRegistry import org.lwjgl.opengl.GLContext -import scala.collection.mutable - private[oc] class Proxy extends CommonProxy { - private val meshableItems = mutable.ArrayBuffer.empty[Item] - private val itemDelegates = mutable.ArrayBuffer.empty[(String, Delegate)] - override def preInit(e: FMLPreInitializationEvent) { if (Loader.isModLoaded("OpenComponents")) { throw new OpenComponentsPresentException() @@ -50,20 +39,7 @@ private[oc] class Proxy extends CommonProxy { MinecraftForge.EVENT_BUS.register(Textures) MinecraftForge.EVENT_BUS.register(HighlightRenderer) - ExtendedBlockModel.preInit() - } - - override def registerModel(instance: Delegate, id: String): Unit = { - itemDelegates += id -> instance - } - - override def registerModel(instance: Item, id: String): Unit = { - meshableItems += instance - } - - override def registerModel(instance: Block, id: String): Unit = { - val item = Item.getItemFromBlock(instance) - registerModel(item, id) + ModelInitialization.preInit() } override def init(e: FMLInitializationEvent) { @@ -71,25 +47,7 @@ private[oc] class Proxy extends CommonProxy { OpenComputers.channel.register(client.PacketHandler) - val mesher = Minecraft.getMinecraft.getRenderItem.getItemModelMesher - val meshDefinition = new ItemMeshDefinition { - override def getModelLocation(stack: ItemStack) = { - Option(api.Items.get(stack)) match { - case Some(descriptor) => new ModelResourceLocation(Settings.resourceDomain + ":" + descriptor.name(), "inventory") - case _ => null - } - } - } - for (item <- meshableItems) { - mesher.register(item, meshDefinition) - } - meshableItems.clear() - for ((id, item) <- itemDelegates) { - val location = Settings.resourceDomain + ":" + id - mesher.register(item.parent, item.itemId, new ModelResourceLocation(location, "inventory")) - ModelBakery.addVariantName(item.parent, location) - } - itemDelegates.clear() + ModelInitialization.init() RenderingRegistry.registerEntityRenderingHandler(classOf[Drone], DroneRenderer) @@ -130,4 +88,10 @@ private[oc] class Proxy extends CommonProxy { FMLCommonHandler.instance.bus.register(PetRenderer) FMLCommonHandler.instance.bus.register(TextBufferRenderCache) } + + override def registerModel(instance: Delegate, id: String) = ModelInitialization.registerModel(instance, id) + + override def registerModel(instance: Item, id: String) = ModelInitialization.registerModel(instance, id) + + override def registerModel(instance: Block, id: String) = ModelInitialization.registerModel(instance, id) } diff --git a/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala index 89648abfd..c027fb76f 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/CableModel.scala @@ -112,7 +112,7 @@ object CableModel extends SmartBlockModelBase with ISmartItemModel { } class ItemModel(val stack: ItemStack) extends SmartBlockModelBase { - override def getFaceQuads(side: EnumFacing) = { + override def getGeneralQuads = { val faces = mutable.ArrayBuffer.empty[BakedQuad] faces ++= bakeQuads(Middle, cableTexture, Some(EnumDyeColor.SILVER)) diff --git a/src/main/scala/li/cil/oc/client/renderer/block/ExtendedBlockModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/ExtendedBlockModel.scala deleted file mode 100644 index 63c9624e2..000000000 --- a/src/main/scala/li/cil/oc/client/renderer/block/ExtendedBlockModel.scala +++ /dev/null @@ -1,57 +0,0 @@ -package li.cil.oc.client.renderer.block - -import li.cil.oc.Constants -import li.cil.oc.Settings -import li.cil.oc.api -import net.minecraft.block.state.IBlockState -import net.minecraft.client.renderer.block.statemap.StateMapperBase -import net.minecraft.client.resources.model.ModelResourceLocation -import net.minecraft.util.RegistrySimple -import net.minecraftforge.client.event.ModelBakeEvent -import net.minecraftforge.client.model.ModelLoader -import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -import scala.collection.convert.WrapAsScala._ - -object ExtendedBlockModel { - final val CableBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "normal") - final val CableItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "inventory") - final val RobotBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "normal") - final val RobotItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "inventory") - - def preInit(): Unit = { - MinecraftForge.EVENT_BUS.register(this) - - registerModel(Constants.BlockName.Cable, CableBlockLocation, CableItemLocation) - registerModel(Constants.BlockName.Robot, RobotBlockLocation, RobotItemLocation) - } - - private def registerModel(blockName: String, blockLocation: ModelResourceLocation, itemLocation: ModelResourceLocation): Unit = { - val descriptor = api.Items.get(blockName) - val block = descriptor.block() - val stack = descriptor.createItemStack(1) - - ModelLoader.setCustomModelResourceLocation(stack.getItem, stack.getMetadata, itemLocation) - ModelLoader.setCustomStateMapper(block, new StateMapperBase { - override def getModelResourceLocation(state: IBlockState) = blockLocation - }) - } - - @SubscribeEvent - def onModelBake(e: ModelBakeEvent): Unit = { - val registry = e.modelRegistry.asInstanceOf[RegistrySimple] - - registry.putObject(CableBlockLocation, CableModel) - registry.putObject(CableItemLocation, CableModel) - registry.putObject(RobotBlockLocation, RobotModel) - registry.putObject(RobotItemLocation, RobotModel) - - registry.getKeys.collect { - case location: ModelResourceLocation => - if (location.toString.matches("^" + Settings.resourceDomain + ":screen\\d#.*")) { - registry.putObject(location, ScreenModel) - } - } - } -} diff --git a/src/main/scala/li/cil/oc/client/renderer/block/ModelInitialization.scala b/src/main/scala/li/cil/oc/client/renderer/block/ModelInitialization.scala new file mode 100644 index 000000000..607fe877a --- /dev/null +++ b/src/main/scala/li/cil/oc/client/renderer/block/ModelInitialization.scala @@ -0,0 +1,127 @@ +package li.cil.oc.client.renderer.block + +import li.cil.oc.Constants +import li.cil.oc.Settings +import li.cil.oc.api +import li.cil.oc.common.item.Delegate +import net.minecraft.block.Block +import net.minecraft.block.state.IBlockState +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.ItemMeshDefinition +import net.minecraft.client.renderer.block.statemap.StateMapperBase +import net.minecraft.client.resources.model.ModelBakery +import net.minecraft.client.resources.model.ModelResourceLocation +import net.minecraft.item.Item +import net.minecraft.item.ItemStack +import net.minecraft.util.RegistrySimple +import net.minecraftforge.client.event.ModelBakeEvent +import net.minecraftforge.client.model.ModelLoader +import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +import scala.collection.convert.WrapAsScala._ +import scala.collection.mutable + +object ModelInitialization { + final val CableBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "normal") + final val CableItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "inventory") + final val RobotBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "normal") + final val RobotItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "inventory") + final val RobotAfterimageBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.RobotAfterimage, "normal") + final val RobotAfterimageItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.RobotAfterimage, "inventory") + + private val meshableItems = mutable.ArrayBuffer.empty[Item] + private val itemDelegates = mutable.ArrayBuffer.empty[(String, Delegate)] + + def preInit(): Unit = { + MinecraftForge.EVENT_BUS.register(this) + + registerModel(Constants.BlockName.Cable, CableBlockLocation, CableItemLocation) + registerModel(Constants.BlockName.Robot, RobotBlockLocation, RobotItemLocation) + registerModel(Constants.BlockName.RobotAfterimage, RobotAfterimageBlockLocation, RobotAfterimageItemLocation) + } + + def init(): Unit = { + registerItems(meshableItems) + registerSubItems(itemDelegates) + } + + // ----------------------------------------------------------------------- // + + def registerModel(instance: Delegate, id: String): Unit = { + itemDelegates += id -> instance + } + + def registerModel(instance: Item, id: String): Unit = { + meshableItems += instance + } + + def registerModel(instance: Block, id: String): Unit = { + val item = Item.getItemFromBlock(instance) + registerModel(item, id) + } + + // ----------------------------------------------------------------------- // + + private def registerModel(blockName: String, blockLocation: ModelResourceLocation, itemLocation: ModelResourceLocation): Unit = { + val descriptor = api.Items.get(blockName) + val block = descriptor.block() + val stack = descriptor.createItemStack(1) + + ModelLoader.setCustomModelResourceLocation(stack.getItem, stack.getMetadata, itemLocation) + ModelLoader.setCustomStateMapper(block, new StateMapperBase { + override def getModelResourceLocation(state: IBlockState) = blockLocation + }) + } + + private def registerItems(items: mutable.Buffer[Item]): Unit = { + val meshDefinition = new ItemMeshDefinition { + override def getModelLocation(stack: ItemStack) = { + Option(api.Items.get(stack)) match { + case Some(descriptor) => + val location = Settings.resourceDomain + ":" + descriptor.name() + new ModelResourceLocation(location, "inventory") + case _ => null + } + } + } + + val modelMeshes = Minecraft.getMinecraft.getRenderItem.getItemModelMesher + for (item <- items) { + modelMeshes.register(item, meshDefinition) + } + items.clear() + } + + private def registerSubItems(items: mutable.Buffer[(String, Delegate)]): Unit = { + val modelMeshes = Minecraft.getMinecraft.getRenderItem.getItemModelMesher + for ((id, item) <- items) { + val location = Settings.resourceDomain + ":" + id + modelMeshes.register(item.parent, item.itemId, new ModelResourceLocation(location, "inventory")) + ModelBakery.addVariantName(item.parent, location) + } + items.clear() + } + + // ----------------------------------------------------------------------- // + + @SubscribeEvent + def onModelBake(e: ModelBakeEvent): Unit = { + val registry = e.modelRegistry.asInstanceOf[RegistrySimple] + + registry.putObject(CableBlockLocation, CableModel) + registry.putObject(CableItemLocation, CableModel) + registry.putObject(RobotBlockLocation, RobotModel) + registry.putObject(RobotItemLocation, RobotModel) + registry.putObject(RobotAfterimageBlockLocation, NullModel) + registry.putObject(RobotAfterimageItemLocation, NullModel) + + val screenPattern = "^" + Settings.resourceDomain + ":screen\\d#.*" + registry.getKeys.collect { + case location: ModelResourceLocation => + if (location.toString.matches(screenPattern)) { + registry.putObject(location, ScreenModel) + } + } + } +} diff --git a/src/main/scala/li/cil/oc/client/renderer/block/NullModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/NullModel.scala new file mode 100644 index 000000000..80a2a9813 --- /dev/null +++ b/src/main/scala/li/cil/oc/client/renderer/block/NullModel.scala @@ -0,0 +1,14 @@ +package li.cil.oc.client.renderer.block + +import net.minecraft.block.state.IBlockState +import net.minecraft.item.ItemStack +import net.minecraftforge.client.model.ISmartItemModel + +object NullModel extends SmartBlockModelBase with ISmartItemModel { + override def handleBlockState(state: IBlockState) = new Model() + + override def handleItemState(stack: ItemStack) = new Model() + + class Model extends SmartBlockModelBase + +} diff --git a/src/main/scala/li/cil/oc/client/renderer/block/RobotModel.scala b/src/main/scala/li/cil/oc/client/renderer/block/RobotModel.scala index 6378a8a28..847171030 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/RobotModel.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/RobotModel.scala @@ -9,14 +9,10 @@ import scala.collection.convert.WrapAsJava.bufferAsJavaList import scala.collection.mutable object RobotModel extends SmartBlockModelBase with ISmartItemModel { - override def handleBlockState(state: IBlockState) = new BlockModel() + override def handleBlockState(state: IBlockState) = new NullModel.Model() override def handleItemState(stack: ItemStack) = new ItemModel(stack) - class BlockModel extends SmartBlockModelBase { - // No faces, robots are exclusively rendered via their TESR. - } - class ItemModel(val stack: ItemStack) extends SmartBlockModelBase { override def getGeneralQuads = { val faces = mutable.ArrayBuffer.empty[BakedQuad] diff --git a/src/main/scala/li/cil/oc/client/renderer/block/SmartBlockModelBase.scala b/src/main/scala/li/cil/oc/client/renderer/block/SmartBlockModelBase.scala index 7d55b35e7..71d080e5d 100644 --- a/src/main/scala/li/cil/oc/client/renderer/block/SmartBlockModelBase.scala +++ b/src/main/scala/li/cil/oc/client/renderer/block/SmartBlockModelBase.scala @@ -56,12 +56,12 @@ trait SmartBlockModelBase extends ISmartBlockModel with ISmartItemModel { // Standard faces for a unit cube. protected final val UnitCube = Array( - Array(new Vec3(0, 0, 0), new Vec3(1, 0, 0), new Vec3(1, 0, 1), new Vec3(0, 0, 1)), - Array(new Vec3(0, 1, 1), new Vec3(1, 1, 1), new Vec3(1, 1, 0), new Vec3(0, 1, 0)), - Array(new Vec3(0, 1, 0), new Vec3(1, 1, 0), new Vec3(1, 0, 0), new Vec3(0, 0, 0)), - Array(new Vec3(1, 1, 1), new Vec3(0, 1, 1), new Vec3(0, 0, 1), new Vec3(1, 0, 1)), - Array(new Vec3(0, 1, 1), new Vec3(0, 1, 0), new Vec3(0, 0, 0), new Vec3(0, 0, 1)), - Array(new Vec3(1, 1, 0), new Vec3(1, 1, 1), new Vec3(1, 0, 1), new Vec3(1, 0, 0)) + Array(new Vec3(0, 0, 1), new Vec3(0, 0, 0), new Vec3(1, 0, 0), new Vec3(1, 0, 1)), + Array(new Vec3(0, 1, 0), new Vec3(0, 1, 1), new Vec3(1, 1, 1), new Vec3(1, 1, 0)), + Array(new Vec3(1, 1, 0), new Vec3(1, 0, 0), new Vec3(0, 0, 0), new Vec3(0, 1, 0)), + Array(new Vec3(0, 1, 1), new Vec3(0, 0, 1), new Vec3(1, 0, 1), new Vec3(1, 1, 1)), + Array(new Vec3(0, 1, 0), new Vec3(0, 0, 0), new Vec3(0, 0, 1), new Vec3(0, 1, 1)), + Array(new Vec3(1, 1, 1), new Vec3(1, 0, 1), new Vec3(1, 0, 0), new Vec3(1, 1, 0)) ) // Planes perpendicular to facings. Negative values mean we mirror along that, @@ -136,20 +136,36 @@ trait SmartBlockModelBase extends ISmartBlockModel with ISmartItemModel { u = v v = (-(tmp - 0.5)) + 0.5 } - rawData(vertex.xCoord, vertex.yCoord, vertex.zCoord, texture, u, v) + rawData(vertex.xCoord, vertex.yCoord, vertex.zCoord, facing, texture, u, v) }).flatten } // See FaceBakery#storeVertexData. - private def rawData(x: Double, y: Double, z: Double, texture: TextureAtlasSprite, u: Double, v: Double) = { + private def rawData(x: Double, y: Double, z: Double, face: EnumFacing, texture: TextureAtlasSprite, u: Double, v: Double) = { Array( java.lang.Float.floatToRawIntBits(x.toFloat), java.lang.Float.floatToRawIntBits(y.toFloat), java.lang.Float.floatToRawIntBits(z.toFloat), - 0xFFFFFFFF, + getFaceShadeColor(face), java.lang.Float.floatToRawIntBits(texture.getInterpolatedU(u * 16)), java.lang.Float.floatToRawIntBits(texture.getInterpolatedV(v * 16)), 0 ) } + + // See FaceBakery. + private def getFaceShadeColor(face: EnumFacing): Int = { + val brightness = getFaceBrightness(face) + val color = (brightness * 255).toInt max 0 min 255 + 0xFF000000 | color << 16 | color << 8 | color + } + + private def getFaceBrightness(face: EnumFacing): Float = { + face match { + case EnumFacing.DOWN => 0.5f + case EnumFacing.UP => 1.0f + case EnumFacing.NORTH | EnumFacing.SOUTH => 0.8f + case EnumFacing.WEST | EnumFacing.EAST => 0.6f + } + } } diff --git a/src/main/scala/li/cil/oc/common/Proxy.scala b/src/main/scala/li/cil/oc/common/Proxy.scala index 47966634e..8daa5beb3 100644 --- a/src/main/scala/li/cil/oc/common/Proxy.scala +++ b/src/main/scala/li/cil/oc/common/Proxy.scala @@ -75,12 +75,6 @@ class Proxy { api.Machine.add(classOf[LuaJLuaArchitecture]) } - def registerModel(instance: Delegate, id: String): Unit = {} - - def registerModel(instance: Item, id: String): Unit = {} - - def registerModel(instance: Block, id: String): Unit = {} - def init(e: FMLInitializationEvent) { OpenComputers.channel = NetworkRegistry.INSTANCE.newEventDrivenChannel("OpenComputers") OpenComputers.channel.register(server.PacketHandler) @@ -99,6 +93,12 @@ class Proxy { driver.Registry.locked = true } + def registerModel(instance: Delegate, id: String): Unit = {} + + def registerModel(instance: Item, id: String): Unit = {} + + def registerModel(instance: Block, id: String): Unit = {} + private def registerExclusive(name: String, items: ItemStack*) { if (OreDictionary.getOres(name).isEmpty) { for (item <- items) { diff --git a/src/main/scala/li/cil/oc/common/block/Cable.scala b/src/main/scala/li/cil/oc/common/block/Cable.scala index bf67d839c..f92b83885 100644 --- a/src/main/scala/li/cil/oc/common/block/Cable.scala +++ b/src/main/scala/li/cil/oc/common/block/Cable.scala @@ -32,8 +32,6 @@ import net.minecraftforge.fml.relauncher.SideOnly import scala.collection.mutable.ArrayBuffer class Cable extends SimpleBlock with traits.Extended { - setLightOpacity(2) - // For Immibis Microblock support. val ImmibisMicroblocks_TransformableBlockMarker = null