mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-12 00:35:56 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8
Conflicts: src/main/scala/li/cil/oc/common/inventory/Inventory.scala src/main/scala/li/cil/oc/common/tileentity/Hologram.scala src/main/scala/li/cil/oc/common/tileentity/Robot.scala
This commit is contained in:
commit
b0950d73b2
@ -1,7 +1,7 @@
|
|||||||
minecraft.version=1.8
|
minecraft.version=1.8
|
||||||
forge.version=11.14.3.1450
|
forge.version=11.14.3.1450
|
||||||
|
|
||||||
oc.version=1.5.17
|
oc.version=1.5.18
|
||||||
oc.subversion=dev
|
oc.subversion=dev
|
||||||
|
|
||||||
ae2.version=rv2-beta-26
|
ae2.version=rv2-beta-26
|
||||||
|
@ -54,6 +54,8 @@ object PacketHandler extends CommonPacketHandler {
|
|||||||
case PacketType.HologramClear => onHologramClear(p)
|
case PacketType.HologramClear => onHologramClear(p)
|
||||||
case PacketType.HologramColor => onHologramColor(p)
|
case PacketType.HologramColor => onHologramColor(p)
|
||||||
case PacketType.HologramPowerChange => onHologramPowerChange(p)
|
case PacketType.HologramPowerChange => onHologramPowerChange(p)
|
||||||
|
case PacketType.HologramRotation => onHologramRotation(p)
|
||||||
|
case PacketType.HologramRotationSpeed => onHologramRotationSpeed(p)
|
||||||
case PacketType.HologramScale => onHologramScale(p)
|
case PacketType.HologramScale => onHologramScale(p)
|
||||||
case PacketType.HologramTranslation => onHologramPositionOffsetY(p)
|
case PacketType.HologramTranslation => onHologramPositionOffsetY(p)
|
||||||
case PacketType.HologramValues => onHologramValues(p)
|
case PacketType.HologramValues => onHologramValues(p)
|
||||||
@ -254,6 +256,26 @@ object PacketHandler extends CommonPacketHandler {
|
|||||||
case _ => // Invalid packet.
|
case _ => // Invalid packet.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def onHologramRotation(p: PacketParser) =
|
||||||
|
p.readTileEntity[Hologram]() match {
|
||||||
|
case Some(t) =>
|
||||||
|
t.rotationAngle = p.readFloat()
|
||||||
|
t.rotationX = p.readFloat()
|
||||||
|
t.rotationY = p.readFloat()
|
||||||
|
t.rotationZ = p.readFloat()
|
||||||
|
case _ => // Invalid packet.
|
||||||
|
}
|
||||||
|
|
||||||
|
def onHologramRotationSpeed(p: PacketParser) =
|
||||||
|
p.readTileEntity[Hologram]() match {
|
||||||
|
case Some(t) =>
|
||||||
|
t.rotationSpeed = p.readFloat()
|
||||||
|
t.rotationSpeedX = p.readFloat()
|
||||||
|
t.rotationSpeedY = p.readFloat()
|
||||||
|
t.rotationSpeedZ = p.readFloat()
|
||||||
|
case _ => // Invalid packet.
|
||||||
|
}
|
||||||
|
|
||||||
def onLootDisk(p: PacketParser) = {
|
def onLootDisk(p: PacketParser) = {
|
||||||
val stack = p.readItemStack()
|
val stack = p.readItemStack()
|
||||||
if (stack != null) {
|
if (stack != null) {
|
||||||
|
@ -2,7 +2,7 @@ package li.cil.oc.client.renderer.font
|
|||||||
|
|
||||||
import li.cil.oc.Settings
|
import li.cil.oc.Settings
|
||||||
import li.cil.oc.client.renderer.font.DynamicFontRenderer.CharTexture
|
import li.cil.oc.client.renderer.font.DynamicFontRenderer.CharTexture
|
||||||
import li.cil.oc.util.FontUtil
|
import li.cil.oc.util.FontUtils
|
||||||
import li.cil.oc.util.RenderState
|
import li.cil.oc.util.RenderState
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.renderer.GlStateManager
|
import net.minecraft.client.renderer.GlStateManager
|
||||||
@ -76,7 +76,7 @@ class DynamicFontRenderer extends TextureFontRenderer with IResourceManagerReloa
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def createCharIcon(char: Char): DynamicFontRenderer.CharIcon = {
|
private def createCharIcon(char: Char): DynamicFontRenderer.CharIcon = {
|
||||||
if (FontUtil.wcwidth(char) < 1 || glyphProvider.getGlyph(char) == null) {
|
if (FontUtils.wcwidth(char) < 1 || glyphProvider.getGlyph(char) == null) {
|
||||||
if (char == '?') null
|
if (char == '?') null
|
||||||
else charMap.getOrElseUpdate('?', createCharIcon('?'))
|
else charMap.getOrElseUpdate('?', createCharIcon('?'))
|
||||||
}
|
}
|
||||||
@ -123,10 +123,10 @@ object DynamicFontRenderer {
|
|||||||
RenderState.bindTexture(id)
|
RenderState.bindTexture(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
def isFull(char: Char) = chars + FontUtil.wcwidth(char) > capacity
|
def isFull(char: Char) = chars + FontUtils.wcwidth(char) > capacity
|
||||||
|
|
||||||
def add(char: Char) = {
|
def add(char: Char) = {
|
||||||
val glyphWidth = FontUtil.wcwidth(char)
|
val glyphWidth = FontUtils.wcwidth(char)
|
||||||
val w = owner.charWidth * glyphWidth
|
val w = owner.charWidth * glyphWidth
|
||||||
val h = owner.charHeight
|
val h = owner.charHeight
|
||||||
// Force line break if we have a char that's wider than what space remains in this row.
|
// Force line break if we have a char that's wider than what space remains in this row.
|
||||||
|
@ -2,7 +2,7 @@ package li.cil.oc.client.renderer.font;
|
|||||||
|
|
||||||
import li.cil.oc.OpenComputers;
|
import li.cil.oc.OpenComputers;
|
||||||
import li.cil.oc.Settings;
|
import li.cil.oc.Settings;
|
||||||
import li.cil.oc.util.FontUtil;
|
import li.cil.oc.util.FontUtils;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
@ -35,7 +35,7 @@ public class FontParserUnifont implements IGlyphProvider {
|
|||||||
while ((line = input.readLine()) != null) {
|
while ((line = input.readLine()) != null) {
|
||||||
final String[] info = line.split(":");
|
final String[] info = line.split(":");
|
||||||
final int charCode = Integer.parseInt(info[0], 16);
|
final int charCode = Integer.parseInt(info[0], 16);
|
||||||
final int expectedWidth = FontUtil.wcwidth(charCode);
|
final int expectedWidth = FontUtils.wcwidth(charCode);
|
||||||
if (expectedWidth < 1) continue; // Skip control characters.
|
if (expectedWidth < 1) continue; // Skip control characters.
|
||||||
final byte[] glyph = new byte[info[1].length() >> 1];
|
final byte[] glyph = new byte[info[1].length() >> 1];
|
||||||
final int glyphWidth = glyph.length / getGlyphHeight();
|
final int glyphWidth = glyph.length / getGlyphHeight();
|
||||||
|
@ -39,7 +39,7 @@ public interface IGlyphProvider {
|
|||||||
* <p/>
|
* <p/>
|
||||||
* Each glyph provided is expected to have the same width multiplier; i.e.
|
* Each glyph provided is expected to have the same width multiplier; i.e.
|
||||||
* a glyphs actual width (in pixels) is expected to be this value times
|
* a glyphs actual width (in pixels) is expected to be this value times
|
||||||
* {@link li.cil.oc.util.FontUtil#wcwidth(int)} (for a specific char).
|
* {@link li.cil.oc.util.FontUtils#wcwidth(int)} (for a specific char).
|
||||||
*/
|
*/
|
||||||
public int getGlyphWidth();
|
public int getGlyphWidth();
|
||||||
|
|
||||||
|
@ -99,6 +99,9 @@ object HologramRenderer extends TileEntitySpecialRenderer with Callable[Int] wit
|
|||||||
case _ => // No pitch.
|
case _ => // No pitch.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GL11.glRotatef(hologram.rotationAngle, hologram.rotationX, hologram.rotationY, hologram.rotationZ)
|
||||||
|
GL11.glRotatef(hologram.rotationSpeed * (hologram.getWorld.getTotalWorldTime % (360 * 20 - 1) + f) / 20f, hologram.rotationSpeedX, hologram.rotationSpeedY, hologram.rotationSpeedZ)
|
||||||
|
|
||||||
GL11.glScaled(1.001, 1.001, 1.001) // Avoid z-fighting with other blocks.
|
GL11.glScaled(1.001, 1.001, 1.001) // Avoid z-fighting with other blocks.
|
||||||
GL11.glTranslated(
|
GL11.glTranslated(
|
||||||
(hologram.translation.xCoord * hologram.width / 16 - 1.5) * hologram.scale,
|
(hologram.translation.xCoord * hologram.width / 16 - 1.5) * hologram.scale,
|
||||||
|
@ -26,7 +26,6 @@ import li.cil.oc.util._
|
|||||||
import net.minecraft.entity.player.EntityPlayer
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
import net.minecraft.entity.player.EntityPlayerMP
|
import net.minecraft.entity.player.EntityPlayerMP
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
|
||||||
import net.minecraft.server.MinecraftServer
|
import net.minecraft.server.MinecraftServer
|
||||||
import net.minecraft.tileentity.TileEntity
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraftforge.common.util.FakePlayer
|
import net.minecraftforge.common.util.FakePlayer
|
||||||
@ -199,13 +198,9 @@ object EventHandler {
|
|||||||
def onEntityJoinWorld(e: EntityJoinWorldEvent): Unit = {
|
def onEntityJoinWorld(e: EntityJoinWorldEvent): Unit = {
|
||||||
if (Settings.get.giveManualToNewPlayers && !e.world.isRemote) e.entity match {
|
if (Settings.get.giveManualToNewPlayers && !e.world.isRemote) e.entity match {
|
||||||
case player: EntityPlayer if !player.isInstanceOf[FakePlayer] =>
|
case player: EntityPlayer if !player.isInstanceOf[FakePlayer] =>
|
||||||
val nbt = player.getEntityData
|
val persistedData = PlayerUtils.persistedData(player)
|
||||||
if (!nbt.hasKey(EntityPlayer.PERSISTED_NBT_TAG)) {
|
if (!persistedData.getBoolean(Settings.namespace + "receivedManual")) {
|
||||||
nbt.setTag(EntityPlayer.PERSISTED_NBT_TAG, new NBTTagCompound())
|
persistedData.setBoolean(Settings.namespace + "receivedManual", true)
|
||||||
}
|
|
||||||
val ocData = nbt.getCompoundTag(EntityPlayer.PERSISTED_NBT_TAG)
|
|
||||||
if (!ocData.getBoolean(Settings.namespace + "receivedManual")) {
|
|
||||||
ocData.setBoolean(Settings.namespace + "receivedManual", true)
|
|
||||||
player.inventory.addItemStackToInventory(api.Items.get(Constants.ItemName.Manual).createItemStack(1))
|
player.inventory.addItemStackToInventory(api.Items.get(Constants.ItemName.Manual).createItemStack(1))
|
||||||
}
|
}
|
||||||
case _ =>
|
case _ =>
|
||||||
|
@ -16,6 +16,8 @@ object PacketType extends Enumeration {
|
|||||||
HologramClear,
|
HologramClear,
|
||||||
HologramColor,
|
HologramColor,
|
||||||
HologramPowerChange,
|
HologramPowerChange,
|
||||||
|
HologramRotation,
|
||||||
|
HologramRotationSpeed,
|
||||||
HologramScale,
|
HologramScale,
|
||||||
HologramTranslation,
|
HologramTranslation,
|
||||||
HologramValues,
|
HologramValues,
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
package li.cil.oc.common.inventory
|
package li.cil.oc.common.inventory
|
||||||
|
|
||||||
import li.cil.oc.Localization
|
|
||||||
import li.cil.oc.Settings
|
import li.cil.oc.Settings
|
||||||
import li.cil.oc.util.ExtendedNBT._
|
import li.cil.oc.util.ExtendedNBT._
|
||||||
import net.minecraft.entity.player.EntityPlayer
|
|
||||||
import net.minecraft.inventory.IInventory
|
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
import net.minecraftforge.common.util.Constants.NBT
|
import net.minecraftforge.common.util.Constants.NBT
|
||||||
|
|
||||||
trait Inventory extends IInventory {
|
trait Inventory extends SimpleInventory {
|
||||||
def items: Array[Option[ItemStack]]
|
def items: Array[Option[ItemStack]]
|
||||||
|
|
||||||
def updateItems(slot: Int, stack: ItemStack) = items(slot) = Option(stack)
|
def updateItems(slot: Int, stack: ItemStack) = items(slot) = Option(stack)
|
||||||
@ -20,24 +17,6 @@ trait Inventory extends IInventory {
|
|||||||
if (slot >= 0 && slot < getSizeInventory) items(slot).orNull
|
if (slot >= 0 && slot < getSizeInventory) items(slot).orNull
|
||||||
else null
|
else null
|
||||||
|
|
||||||
override def decrStackSize(slot: Int, amount: Int) =
|
|
||||||
if (slot >= 0 && slot < getSizeInventory) {
|
|
||||||
(items(slot) match {
|
|
||||||
case Some(stack) if stack.stackSize - amount < getInventoryStackRequired =>
|
|
||||||
setInventorySlotContents(slot, null)
|
|
||||||
stack
|
|
||||||
case Some(stack) =>
|
|
||||||
val result = stack.splitStack(amount)
|
|
||||||
markDirty()
|
|
||||||
result
|
|
||||||
case _ => null
|
|
||||||
}) match {
|
|
||||||
case stack: ItemStack if stack.stackSize > 0 => stack
|
|
||||||
case _ => null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else null
|
|
||||||
|
|
||||||
override def setInventorySlotContents(slot: Int, stack: ItemStack): Unit = {
|
override def setInventorySlotContents(slot: Int, stack: ItemStack): Unit = {
|
||||||
if (slot >= 0 && slot < getSizeInventory) {
|
if (slot >= 0 && slot < getSizeInventory) {
|
||||||
if (stack == null && items(slot).isEmpty) {
|
if (stack == null && items(slot).isEmpty) {
|
||||||
@ -67,30 +46,10 @@ trait Inventory extends IInventory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def getInventoryStackRequired = 1
|
|
||||||
|
|
||||||
override def getStackInSlotOnClosing(slot: Int) = null
|
|
||||||
|
|
||||||
override def openInventory(player: EntityPlayer) {}
|
|
||||||
|
|
||||||
override def closeInventory(player: EntityPlayer) {}
|
|
||||||
|
|
||||||
override def clear() {} // TODO implement?
|
|
||||||
|
|
||||||
override def getName = Settings.namespace + "container." + inventoryName
|
override def getName = Settings.namespace + "container." + inventoryName
|
||||||
|
|
||||||
override def hasCustomName = false
|
|
||||||
|
|
||||||
override def getDisplayName = Localization.localizeLater(getName)
|
|
||||||
|
|
||||||
protected def inventoryName = getClass.getSimpleName
|
protected def inventoryName = getClass.getSimpleName
|
||||||
|
|
||||||
override def getField(id: Int) = 0
|
|
||||||
|
|
||||||
override def setField(id: Int, value: Int) {}
|
|
||||||
|
|
||||||
override def getFieldCount = 0
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------- //
|
// ----------------------------------------------------------------------- //
|
||||||
|
|
||||||
def load(nbt: NBTTagCompound) {
|
def load(nbt: NBTTagCompound) {
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
package li.cil.oc.common.inventory
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraft.inventory.IInventory
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
|
||||||
|
trait InventoryProxy extends IInventory {
|
||||||
|
def inventory: IInventory
|
||||||
|
|
||||||
|
def offset = 0
|
||||||
|
|
||||||
|
override def getSizeInventory = inventory.getSizeInventory
|
||||||
|
|
||||||
|
override def getInventoryStackLimit = inventory.getInventoryStackLimit
|
||||||
|
|
||||||
|
override def getName = inventory.getName
|
||||||
|
|
||||||
|
override def getDisplayName = inventory.getDisplayName
|
||||||
|
|
||||||
|
override def hasCustomName = inventory.hasCustomName
|
||||||
|
|
||||||
|
override def isUseableByPlayer(player: EntityPlayer) = inventory.isUseableByPlayer(player)
|
||||||
|
|
||||||
|
override def isItemValidForSlot(slot: Int, stack: ItemStack) = {
|
||||||
|
val offsetSlot = slot + offset
|
||||||
|
isValidSlot(offsetSlot) && inventory.isItemValidForSlot(offsetSlot, stack)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getStackInSlot(slot: Int) = {
|
||||||
|
val offsetSlot = slot + offset
|
||||||
|
if (isValidSlot(offsetSlot)) inventory.getStackInSlot(offsetSlot)
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
|
override def decrStackSize(slot: Int, amount: Int) = {
|
||||||
|
val offsetSlot = slot + offset
|
||||||
|
if (isValidSlot(offsetSlot)) inventory.decrStackSize(offsetSlot, amount)
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getStackInSlotOnClosing(slot: Int) = {
|
||||||
|
val offsetSlot = slot + offset
|
||||||
|
if (isValidSlot(offsetSlot)) inventory.getStackInSlotOnClosing(offsetSlot)
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
|
override def setInventorySlotContents(slot: Int, stack: ItemStack) = {
|
||||||
|
val offsetSlot = slot + offset
|
||||||
|
if (isValidSlot(offsetSlot)) inventory.setInventorySlotContents(offsetSlot, stack)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def markDirty() = inventory.markDirty()
|
||||||
|
|
||||||
|
override def openInventory(player: EntityPlayer) = inventory.openInventory(player)
|
||||||
|
|
||||||
|
override def closeInventory(player: EntityPlayer) = inventory.closeInventory(player)
|
||||||
|
|
||||||
|
override def setField(id: Int, value: Int) = inventory.setField(id, value)
|
||||||
|
|
||||||
|
override def clear() = inventory.clear()
|
||||||
|
|
||||||
|
override def getFieldCount = inventory.getFieldCount
|
||||||
|
|
||||||
|
override def getField(id: Int) = inventory.getField(id)
|
||||||
|
|
||||||
|
private def isValidSlot(slot: Int) = slot >= 0 && slot < getSizeInventory
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package li.cil.oc.common.inventory
|
||||||
|
|
||||||
|
import li.cil.oc.Localization
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraft.inventory.IInventory
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
|
||||||
|
trait SimpleInventory extends IInventory {
|
||||||
|
override def hasCustomName = false
|
||||||
|
|
||||||
|
override def getDisplayName = Localization.localizeLater(getName)
|
||||||
|
|
||||||
|
override def getInventoryStackLimit = 64
|
||||||
|
|
||||||
|
// Items required in a slot before it's set to null (for ghost stacks).
|
||||||
|
def getInventoryStackRequired = 1
|
||||||
|
|
||||||
|
override def openInventory(player: EntityPlayer): Unit = {}
|
||||||
|
|
||||||
|
override def closeInventory(player: EntityPlayer): Unit = {}
|
||||||
|
|
||||||
|
override def decrStackSize(slot: Int, amount: Int): ItemStack = {
|
||||||
|
if (slot >= 0 && slot < getSizeInventory) {
|
||||||
|
(getStackInSlot(slot) match {
|
||||||
|
case stack: ItemStack if stack.stackSize - amount < getInventoryStackRequired =>
|
||||||
|
setInventorySlotContents(slot, null)
|
||||||
|
stack
|
||||||
|
case stack: ItemStack =>
|
||||||
|
val result = stack.splitStack(amount)
|
||||||
|
markDirty()
|
||||||
|
result
|
||||||
|
case _ => null
|
||||||
|
}) match {
|
||||||
|
case stack: ItemStack if stack.stackSize > 0 => stack
|
||||||
|
case _ => null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getStackInSlotOnClosing(slot: Int) = {
|
||||||
|
if (slot >= 0 && slot < getSizeInventory) {
|
||||||
|
val stack = getStackInSlot(slot)
|
||||||
|
setInventorySlotContents(slot, null)
|
||||||
|
stack
|
||||||
|
}
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
|
override def clear(): Unit = {
|
||||||
|
for (slot <- 0 until getSizeInventory) {
|
||||||
|
setInventorySlotContents(slot, null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getField(id: Int) = 0
|
||||||
|
|
||||||
|
override def setField(id: Int, value: Int) {}
|
||||||
|
|
||||||
|
override def getFieldCount = 0
|
||||||
|
}
|
@ -155,8 +155,6 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
|||||||
|
|
||||||
override def getSizeInventory = 1
|
override def getSizeInventory = 1
|
||||||
|
|
||||||
override def getInventoryStackLimit = 64
|
|
||||||
|
|
||||||
override def isItemValidForSlot(i: Int, stack: ItemStack) =
|
override def isItemValidForSlot(i: Int, stack: ItemStack) =
|
||||||
allowDisassembling(stack) &&
|
allowDisassembling(stack) &&
|
||||||
(((Settings.get.disassembleAllTheThings || api.Items.get(stack) != null) && ItemUtils.getIngredients(stack).nonEmpty) ||
|
(((Settings.get.disassembleAllTheThings || api.Items.get(stack) != null) && ItemUtils.getIngredients(stack).nonEmpty) ||
|
||||||
|
@ -63,6 +63,16 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
|
|||||||
|
|
||||||
var hasPower = true
|
var hasPower = true
|
||||||
|
|
||||||
|
// Rotation base state. Current rotation is based on world time. See HologramRenderer.
|
||||||
|
var rotationAngle = 0f
|
||||||
|
var rotationX = 0f
|
||||||
|
var rotationY = 0f
|
||||||
|
var rotationZ = 0f
|
||||||
|
var rotationSpeed = 0f
|
||||||
|
var rotationSpeedX = 0f
|
||||||
|
var rotationSpeedY = 0f
|
||||||
|
var rotationSpeedZ = 0f
|
||||||
|
|
||||||
final val colorsByTier = Array(Array(0x00FF00), Array(0x0000FF, 0x00FF00, 0xFF0000)) // 0xBBGGRR for rendering convenience
|
final val colorsByTier = Array(Array(0x00FF00), Array(0x0000FF, 0x00FF00, 0xFF0000)) // 0xBBGGRR for rendering convenience
|
||||||
|
|
||||||
// This is a def and not a val for loading (where the tier comes from the nbt and is always 0 here).
|
// This is a def and not a val for loading (where the tier comes from the nbt and is always 0 here).
|
||||||
@ -293,6 +303,44 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
|
|||||||
result(oldValue)
|
result(oldValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Callback(doc = """function(angle:number, x:number, y:number, z:number):boolean -- Set the base rotation of the displayed hologram.""")
|
||||||
|
def setRotation(context: Context, args: Arguments): Array[AnyRef] = {
|
||||||
|
if (tier > 0) {
|
||||||
|
val r = args.checkDouble(0) % 360
|
||||||
|
val x = args.checkDouble(1)
|
||||||
|
val y = args.checkDouble(2)
|
||||||
|
val z = args.checkDouble(3)
|
||||||
|
|
||||||
|
rotationAngle = r.toFloat
|
||||||
|
rotationX = x.toFloat
|
||||||
|
rotationY = y.toFloat
|
||||||
|
rotationZ = z.toFloat
|
||||||
|
ServerPacketSender.sendHologramRotation(this)
|
||||||
|
|
||||||
|
result(true)
|
||||||
|
}
|
||||||
|
else result(null, "not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Callback(doc = """function(speed:number, x:number, y:number, z:number):boolean -- Set the rotation speed of the displayed hologram.""")
|
||||||
|
def setRotationSpeed(context: Context, args: Arguments): Array[AnyRef] = {
|
||||||
|
if (tier > 0) {
|
||||||
|
val v = args.checkDouble(0) max -360 * 4 min 360 * 4
|
||||||
|
val x = args.checkDouble(1)
|
||||||
|
val y = args.checkDouble(2)
|
||||||
|
val z = args.checkDouble(3)
|
||||||
|
|
||||||
|
rotationSpeed = v.toFloat
|
||||||
|
rotationSpeedX = x.toFloat
|
||||||
|
rotationSpeedY = y.toFloat
|
||||||
|
rotationSpeedZ = z.toFloat
|
||||||
|
ServerPacketSender.sendHologramRotationSpeed(this)
|
||||||
|
|
||||||
|
result(true)
|
||||||
|
}
|
||||||
|
else result(null, "not supported")
|
||||||
|
}
|
||||||
|
|
||||||
private def checkCoordinates(args: Arguments, idxX: Int = 0, idxY: Int = 1, idxZ: Int = 2) = {
|
private def checkCoordinates(args: Arguments, idxX: Int = 0, idxY: Int = 1, idxZ: Int = 2) = {
|
||||||
val x = if (idxX >= 0) args.checkInteger(idxX) - 1 else 0
|
val x = if (idxX >= 0) args.checkInteger(idxX) - 1 else 0
|
||||||
if (x < 0 || x >= width) throw new ArrayIndexOutOfBoundsException("x")
|
if (x < 0 || x >= width) throw new ArrayIndexOutOfBoundsException("x")
|
||||||
@ -370,12 +418,14 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
|
|||||||
|
|
||||||
def getFadeStartDistanceSquared = scale / Settings.get.hologramMaxScaleByTier.max * Settings.get.hologramFadeStartDistance * Settings.get.hologramFadeStartDistance
|
def getFadeStartDistanceSquared = scale / Settings.get.hologramMaxScaleByTier.max * Settings.get.hologramFadeStartDistance * Settings.get.hologramFadeStartDistance
|
||||||
|
|
||||||
|
private final val Sqrt2 = Math.sqrt(2)
|
||||||
|
|
||||||
override def getRenderBoundingBox = {
|
override def getRenderBoundingBox = {
|
||||||
val cx = x + 0.5
|
val cx = x + 0.5
|
||||||
val cy = y + 0.5
|
val cy = y + 0.5
|
||||||
val cz = z + 0.5
|
val cz = z + 0.5
|
||||||
val sh = width / 16 * scale
|
val sh = width / 16 * scale * Sqrt2 // overscale to take into account 45 degree rotation
|
||||||
val sv = height / 16 * scale
|
val sv = height / 16 * scale * Sqrt2
|
||||||
AxisAlignedBB.fromBounds(
|
AxisAlignedBB.fromBounds(
|
||||||
cx + (-0.5 + translation.xCoord) * sh,
|
cx + (-0.5 + translation.xCoord) * sh,
|
||||||
cy + translation.yCoord * sv,
|
cy + translation.yCoord * sv,
|
||||||
@ -398,6 +448,14 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
|
|||||||
val ty = nbt.getDouble(Settings.namespace + "offsetY")
|
val ty = nbt.getDouble(Settings.namespace + "offsetY")
|
||||||
val tz = nbt.getDouble(Settings.namespace + "offsetZ")
|
val tz = nbt.getDouble(Settings.namespace + "offsetZ")
|
||||||
translation = new Vec3(tx, ty, tz)
|
translation = new Vec3(tx, ty, tz)
|
||||||
|
rotationAngle = nbt.getFloat(Settings.namespace + "rotationAngle")
|
||||||
|
rotationX = nbt.getFloat(Settings.namespace + "rotationX")
|
||||||
|
rotationY = nbt.getFloat(Settings.namespace + "rotationY")
|
||||||
|
rotationZ = nbt.getFloat(Settings.namespace + "rotationZ")
|
||||||
|
rotationSpeed = nbt.getFloat(Settings.namespace + "rotationSpeed")
|
||||||
|
rotationSpeedX = nbt.getFloat(Settings.namespace + "rotationSpeedX")
|
||||||
|
rotationSpeedY = nbt.getFloat(Settings.namespace + "rotationSpeedY")
|
||||||
|
rotationSpeedZ = nbt.getFloat(Settings.namespace + "rotationSpeedZ")
|
||||||
}
|
}
|
||||||
|
|
||||||
override def writeToNBTForServer(nbt: NBTTagCompound) = this.synchronized {
|
override def writeToNBTForServer(nbt: NBTTagCompound) = this.synchronized {
|
||||||
@ -413,6 +471,14 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
|
|||||||
nbt.setDouble(Settings.namespace + "offsetX", translation.xCoord)
|
nbt.setDouble(Settings.namespace + "offsetX", translation.xCoord)
|
||||||
nbt.setDouble(Settings.namespace + "offsetY", translation.yCoord)
|
nbt.setDouble(Settings.namespace + "offsetY", translation.yCoord)
|
||||||
nbt.setDouble(Settings.namespace + "offsetZ", translation.zCoord)
|
nbt.setDouble(Settings.namespace + "offsetZ", translation.zCoord)
|
||||||
|
nbt.setFloat(Settings.namespace + "rotationAngle", rotationAngle)
|
||||||
|
nbt.setFloat(Settings.namespace + "rotationX", rotationX)
|
||||||
|
nbt.setFloat(Settings.namespace + "rotationY", rotationY)
|
||||||
|
nbt.setFloat(Settings.namespace + "rotationZ", rotationZ)
|
||||||
|
nbt.setFloat(Settings.namespace + "rotationSpeed", rotationSpeed)
|
||||||
|
nbt.setFloat(Settings.namespace + "rotationSpeedX", rotationSpeedX)
|
||||||
|
nbt.setFloat(Settings.namespace + "rotationSpeedY", rotationSpeedY)
|
||||||
|
nbt.setFloat(Settings.namespace + "rotationSpeedZ", rotationSpeedZ)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
@ -426,6 +492,14 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
|
|||||||
val ty = nbt.getDouble("offsetY")
|
val ty = nbt.getDouble("offsetY")
|
||||||
val tz = nbt.getDouble("offsetZ")
|
val tz = nbt.getDouble("offsetZ")
|
||||||
translation = new Vec3(tx, ty, tz)
|
translation = new Vec3(tx, ty, tz)
|
||||||
|
rotationAngle = nbt.getFloat("rotationAngle")
|
||||||
|
rotationX = nbt.getFloat("rotationX")
|
||||||
|
rotationY = nbt.getFloat("rotationY")
|
||||||
|
rotationZ = nbt.getFloat("rotationZ")
|
||||||
|
rotationSpeed = nbt.getFloat("rotationSpeed")
|
||||||
|
rotationSpeedX = nbt.getFloat("rotationSpeedX")
|
||||||
|
rotationSpeedY = nbt.getFloat("rotationSpeedY")
|
||||||
|
rotationSpeedZ = nbt.getFloat("rotationSpeedZ")
|
||||||
}
|
}
|
||||||
|
|
||||||
override def writeToNBTForClient(nbt: NBTTagCompound) {
|
override def writeToNBTForClient(nbt: NBTTagCompound) {
|
||||||
@ -437,5 +511,13 @@ class Hologram(var tier: Int) extends traits.Environment with SidedEnvironment w
|
|||||||
nbt.setDouble("offsetX", translation.xCoord)
|
nbt.setDouble("offsetX", translation.xCoord)
|
||||||
nbt.setDouble("offsetY", translation.yCoord)
|
nbt.setDouble("offsetY", translation.yCoord)
|
||||||
nbt.setDouble("offsetZ", translation.zCoord)
|
nbt.setDouble("offsetZ", translation.zCoord)
|
||||||
|
nbt.setFloat("rotationAngle", rotationAngle)
|
||||||
|
nbt.setFloat("rotationX", rotationX)
|
||||||
|
nbt.setFloat("rotationY", rotationY)
|
||||||
|
nbt.setFloat("rotationZ", rotationZ)
|
||||||
|
nbt.setFloat("rotationSpeed", rotationSpeed)
|
||||||
|
nbt.setFloat("rotationSpeedX", rotationSpeedX)
|
||||||
|
nbt.setFloat("rotationSpeedY", rotationSpeedY)
|
||||||
|
nbt.setFloat("rotationSpeedZ", rotationSpeedZ)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,6 +235,9 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C
|
|||||||
// Nope.
|
// Nope.
|
||||||
override def decrStackSize(slot: Int, amount: Int) = null
|
override def decrStackSize(slot: Int, amount: Int) = null
|
||||||
|
|
||||||
|
// Nope.
|
||||||
|
override def getStackInSlotOnClosing(slot: Int) = null
|
||||||
|
|
||||||
// For hotswapping EEPROMs.
|
// For hotswapping EEPROMs.
|
||||||
def changeEEPROM(newEeprom: ItemStack) = {
|
def changeEEPROM(newEeprom: ItemStack) = {
|
||||||
val oldEepromIndex = info.components.indexWhere(api.Items.get(_) == api.Items.get(Constants.ItemName.EEPROM))
|
val oldEepromIndex = info.components.indexWhere(api.Items.get(_) == api.Items.get(Constants.ItemName.EEPROM))
|
||||||
|
@ -325,8 +325,6 @@ class Printer extends traits.Environment with traits.Inventory with traits.Rotat
|
|||||||
|
|
||||||
override def getSizeInventory = 3
|
override def getSizeInventory = 3
|
||||||
|
|
||||||
override def getInventoryStackLimit = 64
|
|
||||||
|
|
||||||
override def isItemValidForSlot(slot: Int, stack: ItemStack) =
|
override def isItemValidForSlot(slot: Int, stack: ItemStack) =
|
||||||
if (slot == slotMaterial)
|
if (slot == slotMaterial)
|
||||||
PrintData.materialValue(stack) > 0
|
PrintData.materialValue(stack) > 0
|
||||||
|
@ -14,6 +14,7 @@ import li.cil.oc.client.gui
|
|||||||
import li.cil.oc.common.EventHandler
|
import li.cil.oc.common.EventHandler
|
||||||
import li.cil.oc.common.Slot
|
import li.cil.oc.common.Slot
|
||||||
import li.cil.oc.common.Tier
|
import li.cil.oc.common.Tier
|
||||||
|
import li.cil.oc.common.inventory.InventoryProxy
|
||||||
import li.cil.oc.common.inventory.InventorySelection
|
import li.cil.oc.common.inventory.InventorySelection
|
||||||
import li.cil.oc.common.inventory.TankSelection
|
import li.cil.oc.common.inventory.TankSelection
|
||||||
import li.cil.oc.common.item.data.RobotData
|
import li.cil.oc.common.item.data.RobotData
|
||||||
@ -32,7 +33,6 @@ import net.minecraft.block.BlockLiquid
|
|||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.entity.player.EntityPlayer
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
import net.minecraft.init.Blocks
|
import net.minecraft.init.Blocks
|
||||||
import net.minecraft.inventory.IInventory
|
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
import net.minecraft.util.AxisAlignedBB
|
import net.minecraft.util.AxisAlignedBB
|
||||||
@ -68,87 +68,19 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
|
|||||||
|
|
||||||
def isCreative = tier == Tier.Four
|
def isCreative = tier == Tier.Four
|
||||||
|
|
||||||
val equipmentInventory = new IInventory {
|
val equipmentInventory = new InventoryProxy {
|
||||||
|
override def inventory = Robot.this
|
||||||
|
|
||||||
override def getSizeInventory = 4
|
override def getSizeInventory = 4
|
||||||
|
|
||||||
override def getInventoryStackLimit = Robot.this.getInventoryStackLimit
|
|
||||||
|
|
||||||
override def markDirty() = Robot.this.markDirty()
|
|
||||||
|
|
||||||
override def isItemValidForSlot(slot: Int, stack: ItemStack) =
|
|
||||||
slot >= 0 && slot < getSizeInventory && Robot.this.isItemValidForSlot(slot, stack)
|
|
||||||
|
|
||||||
override def getStackInSlot(slot: Int) =
|
|
||||||
if (slot >= 0 && slot < getSizeInventory) Robot.this.getStackInSlot(slot)
|
|
||||||
else null
|
|
||||||
|
|
||||||
override def setInventorySlotContents(slot: Int, stack: ItemStack) =
|
|
||||||
if (slot >= 0 && slot < getSizeInventory) Robot.this.setInventorySlotContents(slot, stack)
|
|
||||||
|
|
||||||
override def decrStackSize(slot: Int, amount: Int) =
|
|
||||||
if (slot >= 0 && slot < getSizeInventory) Robot.this.decrStackSize(slot, amount)
|
|
||||||
else null
|
|
||||||
|
|
||||||
override def getName = Robot.this.getName
|
|
||||||
|
|
||||||
override def hasCustomName = Robot.this.hasCustomName
|
|
||||||
|
|
||||||
override def openInventory(player: EntityPlayer): Unit = {}
|
|
||||||
|
|
||||||
override def closeInventory(player: EntityPlayer): Unit = {}
|
|
||||||
|
|
||||||
override def getStackInSlotOnClosing(slot: Int): ItemStack = null
|
|
||||||
|
|
||||||
override def isUseableByPlayer(player: EntityPlayer) = Robot.this.isUseableByPlayer(player)
|
|
||||||
|
|
||||||
override def getField(id: Int) = Robot.this.getField(id)
|
|
||||||
|
|
||||||
override def setField(id: Int, value: Int) = Robot.this.setField(id, value)
|
|
||||||
|
|
||||||
override def getFieldCount = Robot.this.getFieldCount
|
|
||||||
|
|
||||||
override def clear() = Robot.this.clear()
|
|
||||||
|
|
||||||
override def getDisplayName = Robot.this.getDisplayName
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapper for the part of the inventory that is mutable.
|
// Wrapper for the part of the inventory that is mutable.
|
||||||
val mainInventory = new IInventory {
|
val mainInventory = new InventoryProxy {
|
||||||
|
override def inventory = Robot.this
|
||||||
|
|
||||||
override def getSizeInventory = Robot.this.inventorySize
|
override def getSizeInventory = Robot.this.inventorySize
|
||||||
|
|
||||||
override def getInventoryStackLimit = Robot.this.getInventoryStackLimit
|
override def offset = equipmentInventory.getSizeInventory
|
||||||
|
|
||||||
override def markDirty() = Robot.this.markDirty()
|
|
||||||
|
|
||||||
override def isItemValidForSlot(slot: Int, stack: ItemStack) = Robot.this.isItemValidForSlot(equipmentInventory.getSizeInventory + slot, stack)
|
|
||||||
|
|
||||||
override def getStackInSlot(slot: Int) = Robot.this.getStackInSlot(equipmentInventory.getSizeInventory + slot)
|
|
||||||
|
|
||||||
override def setInventorySlotContents(slot: Int, stack: ItemStack) = Robot.this.setInventorySlotContents(equipmentInventory.getSizeInventory + slot, stack)
|
|
||||||
|
|
||||||
override def decrStackSize(slot: Int, amount: Int) = Robot.this.decrStackSize(equipmentInventory.getSizeInventory + slot, amount)
|
|
||||||
|
|
||||||
override def getName = Robot.this.getName
|
|
||||||
|
|
||||||
override def hasCustomName = Robot.this.hasCustomName
|
|
||||||
|
|
||||||
override def openInventory(player: EntityPlayer): Unit = {}
|
|
||||||
|
|
||||||
override def closeInventory(player: EntityPlayer): Unit = {}
|
|
||||||
|
|
||||||
override def getStackInSlotOnClosing(slot: Int): ItemStack = null
|
|
||||||
|
|
||||||
override def isUseableByPlayer(player: EntityPlayer) = Robot.this.isUseableByPlayer(player)
|
|
||||||
|
|
||||||
override def getField(id: Int) = Robot.this.getField(id)
|
|
||||||
|
|
||||||
override def setField(id: Int, value: Int) = Robot.this.setField(id, value)
|
|
||||||
|
|
||||||
override def getFieldCount = Robot.this.getFieldCount
|
|
||||||
|
|
||||||
override def clear() = Robot.this.clear()
|
|
||||||
|
|
||||||
override def getDisplayName = Robot.this.getDisplayName
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val actualInventorySize = 100
|
val actualInventorySize = 100
|
||||||
@ -760,8 +692,6 @@ class Robot extends traits.Computer with traits.PowerInformation with traits.Rot
|
|||||||
|
|
||||||
var getSizeInventory = actualInventorySize
|
var getSizeInventory = actualInventorySize
|
||||||
|
|
||||||
override def getInventoryStackLimit = 64
|
|
||||||
|
|
||||||
override def getStackInSlot(slot: Int) = {
|
override def getStackInSlot(slot: Int) = {
|
||||||
if (slot >= getSizeInventory) null // Required to always show 16 inventory slots in GUI.
|
if (slot >= getSizeInventory) null // Required to always show 16 inventory slots in GUI.
|
||||||
else if (slot >= getSizeInventory - componentCount) {
|
else if (slot >= getSizeInventory - componentCount) {
|
||||||
|
@ -215,6 +215,30 @@ object PacketSender {
|
|||||||
pb.sendToPlayersNearTileEntity(t)
|
pb.sendToPlayersNearTileEntity(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def sendHologramRotation(t: tileentity.Hologram) {
|
||||||
|
val pb = new SimplePacketBuilder(PacketType.HologramRotation)
|
||||||
|
|
||||||
|
pb.writeTileEntity(t)
|
||||||
|
pb.writeFloat(t.rotationAngle)
|
||||||
|
pb.writeFloat(t.rotationX)
|
||||||
|
pb.writeFloat(t.rotationY)
|
||||||
|
pb.writeFloat(t.rotationZ)
|
||||||
|
|
||||||
|
pb.sendToPlayersNearTileEntity(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
def sendHologramRotationSpeed(t: tileentity.Hologram) {
|
||||||
|
val pb = new SimplePacketBuilder(PacketType.HologramRotationSpeed)
|
||||||
|
|
||||||
|
pb.writeTileEntity(t)
|
||||||
|
pb.writeFloat(t.rotationSpeed)
|
||||||
|
pb.writeFloat(t.rotationSpeedX)
|
||||||
|
pb.writeFloat(t.rotationSpeedY)
|
||||||
|
pb.writeFloat(t.rotationSpeedZ)
|
||||||
|
|
||||||
|
pb.sendToPlayersNearTileEntity(t)
|
||||||
|
}
|
||||||
|
|
||||||
def sendLootDisks(p: EntityPlayerMP): Unit = {
|
def sendLootDisks(p: EntityPlayerMP): Unit = {
|
||||||
// Sending as separate packets, because CompressedStreamTools hiccups otherwise...
|
// Sending as separate packets, because CompressedStreamTools hiccups otherwise...
|
||||||
val stacks = Loot.worldDisks.values.map(_._1)
|
val stacks = Loot.worldDisks.values.map(_._1)
|
||||||
|
@ -527,7 +527,12 @@ class Player(val agent: internal.Agent) extends FakePlayer(agent.world.asInstanc
|
|||||||
|
|
||||||
override def onItemPickup(entity: Entity, count: Int) {}
|
override def onItemPickup(entity: Entity, count: Int) {}
|
||||||
|
|
||||||
override def setCurrentItemOrArmor(slot: Int, stack: ItemStack) {}
|
override def setCurrentItemOrArmor(slot: Int, stack: ItemStack): Unit = {
|
||||||
|
if (slot == 0 && agent.equipmentInventory.getSizeInventory > 0) {
|
||||||
|
agent.equipmentInventory.setInventorySlotContents(slot, stack)
|
||||||
|
}
|
||||||
|
// else: armor slots, which are unsupported in agents.
|
||||||
|
}
|
||||||
|
|
||||||
override def setRevengeTarget(entity: EntityLivingBase) {}
|
override def setRevengeTarget(entity: EntityLivingBase) {}
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ class OSAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
|
|||||||
if (lua.getTop > 0 && lua.isString(1)) lua.toString(1)
|
if (lua.getTop > 0 && lua.isString(1)) lua.toString(1)
|
||||||
else "%d/%m/%y %H:%M:%S"
|
else "%d/%m/%y %H:%M:%S"
|
||||||
val time =
|
val time =
|
||||||
if (lua.getTop > 1 && lua.isNumber(2)) lua.toNumber(2) * 1000 / 60 / 60
|
if (lua.getTop > 1 && lua.isNumber(2)) lua.toNumber(2)
|
||||||
else machine.worldTime + 6000
|
else (machine.worldTime + 6000) * 60 * 60 / 1000
|
||||||
|
|
||||||
val dt = GameTimeFormatter.parse(time)
|
val dt = GameTimeFormatter.parse(time)
|
||||||
def fmt(format: String) {
|
def fmt(format: String) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package li.cil.oc.server.machine.luac
|
package li.cil.oc.server.machine.luac
|
||||||
|
|
||||||
import li.cil.oc.util.ExtendedLuaState.extendLuaState
|
import li.cil.oc.util.ExtendedLuaState.extendLuaState
|
||||||
import li.cil.oc.util.FontUtil
|
import li.cil.oc.util.FontUtils
|
||||||
|
|
||||||
class UnicodeAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
|
class UnicodeAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
|
||||||
override def initialize() {
|
override def initialize() {
|
||||||
@ -57,20 +57,20 @@ class UnicodeAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
|
|||||||
lua.setField(-2, "upper")
|
lua.setField(-2, "upper")
|
||||||
|
|
||||||
lua.pushScalaFunction(lua => {
|
lua.pushScalaFunction(lua => {
|
||||||
lua.pushBoolean(FontUtil.wcwidth(lua.checkString(1).codePointAt(0)) > 1)
|
lua.pushBoolean(FontUtils.wcwidth(lua.checkString(1).codePointAt(0)) > 1)
|
||||||
1
|
1
|
||||||
})
|
})
|
||||||
lua.setField(-2, "isWide")
|
lua.setField(-2, "isWide")
|
||||||
|
|
||||||
lua.pushScalaFunction(lua => {
|
lua.pushScalaFunction(lua => {
|
||||||
lua.pushInteger(FontUtil.wcwidth(lua.checkString(1).codePointAt(0)))
|
lua.pushInteger(FontUtils.wcwidth(lua.checkString(1).codePointAt(0)))
|
||||||
1
|
1
|
||||||
})
|
})
|
||||||
lua.setField(-2, "charWidth")
|
lua.setField(-2, "charWidth")
|
||||||
|
|
||||||
lua.pushScalaFunction(lua => {
|
lua.pushScalaFunction(lua => {
|
||||||
val value = lua.checkString(1)
|
val value = lua.checkString(1)
|
||||||
lua.pushInteger(value.toCharArray.map(ch => math.max(1, FontUtil.wcwidth(ch))).sum)
|
lua.pushInteger(value.toCharArray.map(ch => math.max(1, FontUtils.wcwidth(ch))).sum)
|
||||||
1
|
1
|
||||||
})
|
})
|
||||||
lua.setField(-2, "wlen")
|
lua.setField(-2, "wlen")
|
||||||
@ -81,7 +81,7 @@ class UnicodeAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
|
|||||||
var width = 0
|
var width = 0
|
||||||
var end = 0
|
var end = 0
|
||||||
while (width < count) {
|
while (width < count) {
|
||||||
width += FontUtil.wcwidth(value(end))
|
width += FontUtils.wcwidth(value(end))
|
||||||
end += 1
|
end += 1
|
||||||
}
|
}
|
||||||
if (end > 1) lua.pushString(value.substring(0, end - 1))
|
if (end > 1) lua.pushString(value.substring(0, end - 1))
|
||||||
|
@ -17,8 +17,8 @@ class OSAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) {
|
|||||||
if (args.narg > 0 && args.isstring(1)) args.tojstring(1)
|
if (args.narg > 0 && args.isstring(1)) args.tojstring(1)
|
||||||
else "%d/%m/%y %H:%M:%S"
|
else "%d/%m/%y %H:%M:%S"
|
||||||
val time =
|
val time =
|
||||||
if (args.narg > 1 && args.isnumber(2)) args.todouble(2) * 1000 / 60 / 60
|
if (args.narg > 1 && args.isnumber(2)) args.todouble(2)
|
||||||
else machine.worldTime + 6000
|
else (machine.worldTime + 6000) * 60 * 60 / 1000
|
||||||
|
|
||||||
val dt = GameTimeFormatter.parse(time)
|
val dt = GameTimeFormatter.parse(time)
|
||||||
def fmt(format: String) = {
|
def fmt(format: String) = {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package li.cil.oc.server.machine.luaj
|
package li.cil.oc.server.machine.luaj
|
||||||
|
|
||||||
import li.cil.oc.util.FontUtil
|
import li.cil.oc.util.FontUtils
|
||||||
import li.cil.oc.util.ScalaClosure._
|
import li.cil.oc.util.ScalaClosure._
|
||||||
import li.cil.repack.org.luaj.vm2.LuaValue
|
import li.cil.repack.org.luaj.vm2.LuaValue
|
||||||
import li.cil.repack.org.luaj.vm2.Varargs
|
import li.cil.repack.org.luaj.vm2.Varargs
|
||||||
@ -37,14 +37,14 @@ class UnicodeAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
unicode.set("isWide", (args: Varargs) =>
|
unicode.set("isWide", (args: Varargs) =>
|
||||||
LuaValue.valueOf(FontUtil.wcwidth(args.checkjstring(1).codePointAt(0)) > 1))
|
LuaValue.valueOf(FontUtils.wcwidth(args.checkjstring(1).codePointAt(0)) > 1))
|
||||||
|
|
||||||
unicode.set("charWidth", (args: Varargs) =>
|
unicode.set("charWidth", (args: Varargs) =>
|
||||||
LuaValue.valueOf(FontUtil.wcwidth(args.checkjstring(1).codePointAt(0))))
|
LuaValue.valueOf(FontUtils.wcwidth(args.checkjstring(1).codePointAt(0))))
|
||||||
|
|
||||||
unicode.set("wlen", (args: Varargs) => {
|
unicode.set("wlen", (args: Varargs) => {
|
||||||
val value = args.checkjstring(1)
|
val value = args.checkjstring(1)
|
||||||
LuaValue.valueOf(value.toCharArray.map(ch => math.max(1, FontUtil.wcwidth(ch))).sum)
|
LuaValue.valueOf(value.toCharArray.map(ch => math.max(1, FontUtils.wcwidth(ch))).sum)
|
||||||
})
|
})
|
||||||
|
|
||||||
unicode.set("wtrunc", (args: Varargs) => {
|
unicode.set("wtrunc", (args: Varargs) => {
|
||||||
@ -53,7 +53,7 @@ class UnicodeAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) {
|
|||||||
var width = 0
|
var width = 0
|
||||||
var end = 0
|
var end = 0
|
||||||
while (width < count) {
|
while (width < count) {
|
||||||
width += FontUtil.wcwidth(value(end))
|
width += FontUtils.wcwidth(value(end))
|
||||||
end += 1
|
end += 1
|
||||||
}
|
}
|
||||||
if (end > 1) LuaValue.valueOf(value.substring(0, end - 1))
|
if (end > 1) LuaValue.valueOf(value.substring(0, end - 1))
|
||||||
|
@ -4,14 +4,14 @@ import java.io.IOException
|
|||||||
|
|
||||||
import li.cil.oc.OpenComputers
|
import li.cil.oc.OpenComputers
|
||||||
|
|
||||||
object FontUtil {
|
object FontUtils {
|
||||||
// Note: we load the widths from a file (one byte per width) because the Scala
|
// Note: we load the widths from a file (one byte per width) because the Scala
|
||||||
// compiler craps its pants when we try to have it as an array in the source
|
// compiler craps its pants when we try to have it as an array in the source
|
||||||
// file... seems having an array with 0x10000 entries leads to stack overflows,
|
// file... seems having an array with 0x10000 entries leads to stack overflows,
|
||||||
// who would have known!
|
// who would have known!
|
||||||
private val widths = {
|
private val widths = {
|
||||||
val ba = Array.fill[Byte](0x10000)(-1)
|
val ba = Array.fill[Byte](0x10000)(-1)
|
||||||
val is = FontUtil.getClass.getResourceAsStream("/assets/opencomputers/wcwidth.bin")
|
val is = FontUtils.getClass.getResourceAsStream("/assets/opencomputers/wcwidth.bin")
|
||||||
if (is != null) {
|
if (is != null) {
|
||||||
try {
|
try {
|
||||||
is.read(ba)
|
is.read(ba)
|
@ -1,5 +1,8 @@
|
|||||||
package li.cil.oc.util
|
package li.cil.oc.util
|
||||||
|
|
||||||
|
import java.util.Calendar
|
||||||
|
import java.util.GregorianCalendar
|
||||||
|
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
|
||||||
object GameTimeFormatter {
|
object GameTimeFormatter {
|
||||||
@ -56,34 +59,19 @@ object GameTimeFormatter {
|
|||||||
'%' -> (t => "%")
|
'%' -> (t => "%")
|
||||||
)
|
)
|
||||||
|
|
||||||
private val monthLengths = Array(
|
|
||||||
Array(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
|
|
||||||
Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31))
|
|
||||||
|
|
||||||
private def monthLengthsForYear(year: Int) = {
|
|
||||||
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) monthLengths(0) else monthLengths(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
def parse(time: Double) = {
|
def parse(time: Double) = {
|
||||||
var day = (time / 24000).toLong
|
val calendar = new GregorianCalendar()
|
||||||
val weekDay = ((4 + day) % 7).toInt
|
calendar.setTimeInMillis((time * 1000).toLong)
|
||||||
val year = 1970 + (day / 364.2425).toInt
|
|
||||||
val yearDay = (day % 364.2425).toInt
|
|
||||||
day = yearDay
|
|
||||||
val monthLengths = monthLengthsForYear(year)
|
|
||||||
var month = 0
|
|
||||||
while (day >= monthLengths(month)) {
|
|
||||||
day = day - monthLengths(month)
|
|
||||||
month = month + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
var seconds = ((time % 24000) * 60 * 60 / 1000).toInt
|
new DateTime(
|
||||||
var minutes = seconds / 60
|
calendar.get(Calendar.YEAR),
|
||||||
seconds = seconds % 60
|
calendar.get(Calendar.MONTH) + 1,
|
||||||
val hours = (minutes / 60) % 24
|
calendar.get(Calendar.DAY_OF_MONTH),
|
||||||
minutes = minutes % 60
|
calendar.get(Calendar.DAY_OF_WEEK),
|
||||||
|
calendar.get(Calendar.DAY_OF_YEAR),
|
||||||
new DateTime(year, month + 1, day.toInt + 1, weekDay + 1, yearDay + 1, hours, minutes, seconds)
|
calendar.get(Calendar.HOUR_OF_DAY),
|
||||||
|
calendar.get(Calendar.MINUTE),
|
||||||
|
calendar.get(Calendar.SECOND))
|
||||||
}
|
}
|
||||||
|
|
||||||
def format(format: String, time: DateTime) = {
|
def format(format: String, time: DateTime) = {
|
||||||
@ -103,10 +91,14 @@ object GameTimeFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
def mktime(year: Int, mon: Int, mday: Int, hour: Int, min: Int, sec: Int): Option[Int] = {
|
def mktime(year: Int, mon: Int, mday: Int, hour: Int, min: Int, sec: Int): Option[Int] = {
|
||||||
if (year < 1970 || mon < 1 || mon > 12) return None
|
val calendar = new GregorianCalendar()
|
||||||
val monthLengths = monthLengthsForYear(year)
|
calendar.set(Calendar.YEAR, year)
|
||||||
val days = ((year - 1970) * 365.2425).ceil.toInt + (0 until mon - 1).foldLeft(0)((d, m) => d + monthLengths(m)) + mday - 1
|
calendar.set(Calendar.MONTH, mon - 1)
|
||||||
val secs = sec + (min + (hour - 1 + days * 24) * 60) * 60
|
calendar.set(Calendar.DAY_OF_MONTH, mday)
|
||||||
Option(secs)
|
calendar.set(Calendar.HOUR_OF_DAY, hour)
|
||||||
|
calendar.set(Calendar.MINUTE, min)
|
||||||
|
calendar.set(Calendar.SECOND, sec)
|
||||||
|
|
||||||
|
Option((calendar.getTimeInMillis / 1000).toInt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
src/main/scala/li/cil/oc/util/PlayerUtils.scala
Normal file
14
src/main/scala/li/cil/oc/util/PlayerUtils.scala
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package li.cil.oc.util
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
|
||||||
|
object PlayerUtils {
|
||||||
|
def persistedData(player: EntityPlayer): NBTTagCompound = {
|
||||||
|
val nbt = player.getEntityData
|
||||||
|
if (!nbt.hasKey(EntityPlayer.PERSISTED_NBT_TAG)) {
|
||||||
|
nbt.setTag(EntityPlayer.PERSISTED_NBT_TAG, new NBTTagCompound())
|
||||||
|
}
|
||||||
|
nbt.getCompoundTag(EntityPlayer.PERSISTED_NBT_TAG)
|
||||||
|
}
|
||||||
|
}
|
@ -129,7 +129,7 @@ class TextBuffer(var width: Int, var height: Int, initialFormat: PackedColor.Col
|
|||||||
val c = s(x - col)
|
val c = s(x - col)
|
||||||
changed = changed || (line(bx) != c) || (lineColor(bx) != packed)
|
changed = changed || (line(bx) != c) || (lineColor(bx) != packed)
|
||||||
setChar(line, lineColor, bx, c)
|
setChar(line, lineColor, bx, c)
|
||||||
bx += math.max(1, FontUtil.wcwidth(c))
|
bx += math.max(1, FontUtils.wcwidth(c))
|
||||||
}
|
}
|
||||||
changed
|
changed
|
||||||
}
|
}
|
||||||
@ -148,7 +148,7 @@ class TextBuffer(var width: Int, var height: Int, initialFormat: PackedColor.Col
|
|||||||
for (x <- bx until math.min(col + w, width) if bx < line.length) {
|
for (x <- bx until math.min(col + w, width) if bx < line.length) {
|
||||||
changed = changed || (line(bx) != c) || (lineColor(bx) != packed)
|
changed = changed || (line(bx) != c) || (lineColor(bx) != packed)
|
||||||
setChar(line, lineColor, bx, c)
|
setChar(line, lineColor, bx, c)
|
||||||
bx += math.max(1, FontUtil.wcwidth(c))
|
bx += math.max(1, FontUtils.wcwidth(c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
changed
|
changed
|
||||||
@ -185,7 +185,7 @@ class TextBuffer(var width: Int, var height: Int, initialFormat: PackedColor.Col
|
|||||||
changed = changed || (nl(nx) != ol(ox)) || (nc(nx) != oc(ox))
|
changed = changed || (nl(nx) != ol(ox)) || (nc(nx) != oc(ox))
|
||||||
nl(nx) = ol(ox)
|
nl(nx) = ol(ox)
|
||||||
nc(nx) = oc(ox)
|
nc(nx) = oc(ox)
|
||||||
for (offset <- 1 until FontUtil.wcwidth(nl(nx))) {
|
for (offset <- 1 until FontUtils.wcwidth(nl(nx))) {
|
||||||
nl(nx + offset) = ol(' ')
|
nl(nx + offset) = ol(' ')
|
||||||
nc(nx + offset) = oc(nx)
|
nc(nx + offset) = oc(nx)
|
||||||
}
|
}
|
||||||
@ -198,17 +198,17 @@ class TextBuffer(var width: Int, var height: Int, initialFormat: PackedColor.Col
|
|||||||
}
|
}
|
||||||
|
|
||||||
private def setChar(line: Array[Char], lineColor: Array[Short], x: Int, c: Char) {
|
private def setChar(line: Array[Char], lineColor: Array[Short], x: Int, c: Char) {
|
||||||
if (FontUtil.wcwidth(c) > 1 && x >= line.length - 1) {
|
if (FontUtils.wcwidth(c) > 1 && x >= line.length - 1) {
|
||||||
// Don't allow setting wide chars in right-most col.
|
// Don't allow setting wide chars in right-most col.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (x > 0 && line(x) == ' ' && FontUtil.wcwidth(line(x - 1)) > 1) {
|
if (x > 0 && line(x) == ' ' && FontUtils.wcwidth(line(x - 1)) > 1) {
|
||||||
// Don't allow setting the cell following a wide char.
|
// Don't allow setting the cell following a wide char.
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
line(x) = c
|
line(x) = c
|
||||||
lineColor(x) = packed
|
lineColor(x) = packed
|
||||||
for (x1 <- x + 1 until x + FontUtil.wcwidth(c)) {
|
for (x1 <- x + 1 until x + FontUtils.wcwidth(c)) {
|
||||||
line(x1) = ' '
|
line(x1) = ' '
|
||||||
lineColor(x1) = packed
|
lineColor(x1) = packed
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user