mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-14 01:39:36 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8
Conflicts: build.gradle build.properties src/main/java/li/cil/oc/api/API.java src/main/scala/li/cil/oc/client/Sound.scala src/main/scala/li/cil/oc/client/gui/DynamicGuiContainer.scala src/main/scala/li/cil/oc/common/EventHandler.scala src/main/scala/li/cil/oc/common/asm/ClassTransformer.scala src/main/scala/li/cil/oc/common/block/Adapter.scala src/main/scala/li/cil/oc/common/block/Assembler.scala src/main/scala/li/cil/oc/common/block/Capacitor.scala src/main/scala/li/cil/oc/common/block/Case.scala src/main/scala/li/cil/oc/common/block/Charger.scala src/main/scala/li/cil/oc/common/block/Disassembler.scala src/main/scala/li/cil/oc/common/block/DiskDrive.scala src/main/scala/li/cil/oc/common/block/Item.scala src/main/scala/li/cil/oc/common/block/Keyboard.scala src/main/scala/li/cil/oc/common/block/Microcontroller.scala src/main/scala/li/cil/oc/common/block/Raid.scala src/main/scala/li/cil/oc/common/block/RedstoneAware.scala src/main/scala/li/cil/oc/common/block/RobotAfterimage.scala src/main/scala/li/cil/oc/common/block/RobotProxy.scala src/main/scala/li/cil/oc/common/block/Screen.scala src/main/scala/li/cil/oc/common/block/ServerRack.scala src/main/scala/li/cil/oc/common/block/SimpleBlock.scala src/main/scala/li/cil/oc/common/block/Switch.scala src/main/scala/li/cil/oc/common/block/traits/SpecialBlock.scala src/main/scala/li/cil/oc/common/component/TextBuffer.scala src/main/scala/li/cil/oc/common/entity/Drone.scala src/main/scala/li/cil/oc/common/init/Items.scala src/main/scala/li/cil/oc/common/item/Tablet.scala src/main/scala/li/cil/oc/common/tileentity/Capacitor.scala src/main/scala/li/cil/oc/common/tileentity/Microcontroller.scala src/main/scala/li/cil/oc/common/tileentity/Redstone.scala src/main/scala/li/cil/oc/common/tileentity/Screen.scala src/main/scala/li/cil/oc/common/tileentity/ServerRack.scala src/main/scala/li/cil/oc/common/tileentity/traits/BundledRedstoneAware.scala src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala src/main/scala/li/cil/oc/common/tileentity/traits/RedstoneAware.scala src/main/scala/li/cil/oc/common/tileentity/traits/power/Mekanism.scala src/main/scala/li/cil/oc/integration/Mods.scala src/main/scala/li/cil/oc/integration/opencomputers/DriverBlockEnvironments.scala src/main/scala/li/cil/oc/server/component/Redstone.scala src/main/scala/li/cil/oc/server/component/RedstoneWireless.scala src/main/scala/li/cil/oc/server/component/UpgradeInventoryController.scala src/main/scala/li/cil/oc/server/component/robot/Player.scala src/main/scala/li/cil/oc/server/network/Network.scala src/main/scala/li/cil/oc/util/ItemCosts.scala src/main/scala/li/cil/oc/util/ItemUtils.scala
This commit is contained in:
commit
19f614a3eb
2
LICENSE
2
LICENSE
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013-2014 Florian "Sangar" Nücke
|
||||
Copyright (c) 2013-2015 Florian "Sangar" Nücke
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -13,7 +13,7 @@ A few useful links:
|
||||
You can find experimental builds [on the build server][jenkins]. Expect these to be generally more unstable than builds marked as releases. Use these **at your own risk**, but - when using the latest one - please *do* report bugs you encounter using them. Thanks!
|
||||
|
||||
## License / Use in Modpacks
|
||||
This mod is [licensed under the **MIT license**](https://github.com/MightyPirates/OpenComputers/blob/master/LICENSE). All **assets are public domain**, unless otherwise stated; all are free to be distributed as long as the license / source credits are kept. This means you can use this mod in any mod pack **as you please**. I'd be happy to hear about you using it, though, just out of curiosity.
|
||||
This mod is [licensed under the **MIT license**](https://github.com/MightyPirates/OpenComputers/blob/master-MC1.7.10/LICENSE). All **assets are public domain**, unless otherwise stated; all are free to be distributed as long as the license / source credits are kept. This means you can use this mod in any mod pack **as you please**. I'd be happy to hear about you using it, though, just out of curiosity.
|
||||
|
||||
## Contributing
|
||||
###Assets and Localizations
|
||||
|
13
build.gradle
13
build.gradle
@ -17,6 +17,7 @@ buildscript {
|
||||
|
||||
apply plugin: 'scala'
|
||||
apply plugin: 'forge'
|
||||
apply plugin: 'idea'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
file "build.properties" withReader {
|
||||
@ -136,6 +137,10 @@ repositories {
|
||||
name 'Railcraft'
|
||||
artifactPattern "http://addons.cursecdn.com/files/${config.rc.cf}/[module]_[revision].[ext]"
|
||||
}
|
||||
ivy {
|
||||
name 'BloodMagic'
|
||||
artifactPattern "http://addons.cursecdn.com/files/${config.bloodmagic.cf}/[module]-${config.minecraft.version}-[revision].[ext]"
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@ -173,6 +178,8 @@ dependencies {
|
||||
provided name: 'ComputerCraft', version: config.cc.version, ext: 'jar'
|
||||
provided name: 'EnderIO', version: config.eio.version, ext: 'jar'
|
||||
provided name: 'Railcraft', version: config.rc.version, ext: 'jar'
|
||||
provided name: 'BloodMagic', version: config.bloodmagic.version, ext: 'jar'
|
||||
|
||||
*/
|
||||
compile 'com.google.code.findbugs:jsr305:1.3.9' // Annotations used by google libs.
|
||||
|
||||
@ -317,8 +324,8 @@ publishing {
|
||||
}
|
||||
|
||||
// this is needed for IntelliJ so we don't have to copy over the assets manually every time
|
||||
sourceSets {
|
||||
main {
|
||||
output.resourcesDir = output.classesDir
|
||||
idea {
|
||||
module {
|
||||
outputDir = file('build/classes/main')
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,19 @@
|
||||
minecraft.version=1.8
|
||||
forge.version=11.14.0.1280-1.8
|
||||
|
||||
oc.version=2.0.0
|
||||
oc.version=1.4.6
|
||||
oc.subversion=dev
|
||||
|
||||
ae2.version=rv1-stable-1
|
||||
bc.version=6.2.6
|
||||
bloodmagic.cf=2223/203
|
||||
bloodmagic.version=1.3.0a-1
|
||||
cc.cf=2216/236
|
||||
cc.version=1.65
|
||||
ccc.version=1.0.5.34
|
||||
ccl.version=1.1.2.115
|
||||
cofhlib.cf=2212/893
|
||||
cofhlib.version=[1.7.10]1.0.0B6-dev-26
|
||||
cofhlib.cf=2218/257
|
||||
cofhlib.version=[1.7.10]1.0.0B7-dev-29
|
||||
eio.cf=2219/296
|
||||
eio.version=1.7.10-2.2.1.276
|
||||
es.version=1.4.5.24
|
||||
|
@ -341,6 +341,71 @@ public interface TextBuffer extends ManagedEnvironment, Persistable {
|
||||
*/
|
||||
boolean isBackgroundFromPalette(int column, int row);
|
||||
|
||||
/**
|
||||
* Overwrites a portion of the text in raw mode.
|
||||
* <p/>
|
||||
* This will copy the given char array into the buffer, starting at the
|
||||
* specified column and row. The array is expected to be indexed row-
|
||||
* first, i.e. the first dimension is the vertical axis, the second
|
||||
* the horizontal.
|
||||
* <p/>
|
||||
* <em>Important</em>: this performs no checks as to whether something
|
||||
* actually changed. It will always send the changed patch to clients.
|
||||
* It will also not crop the specified array to the actually used range.
|
||||
* In other words, this is not intended to be exposed as-is to user code,
|
||||
* it should always be called with validated, and, as necessary, cropped
|
||||
* values.
|
||||
*
|
||||
* @param column the horizontal index.
|
||||
* @param row the vertical index.
|
||||
* @param text the text to write.
|
||||
*/
|
||||
void rawSetText(int column, int row, char[][] text);
|
||||
|
||||
/**
|
||||
* Overwrites a portion of the foreground color information in raw mode.
|
||||
* <p/>
|
||||
* This will convert the specified RGB data (in <tt>0xRRGGBB</tt> format)
|
||||
* to the internal, packed representation and copy it into the buffer,
|
||||
* starting at the specified column and row. The array is expected to be
|
||||
* indexed row-first, i.e. the first dimension is the vertical axis, the
|
||||
* second the horizontal.
|
||||
* <p/>
|
||||
* <em>Important</em>: this performs no checks as to whether something
|
||||
* actually changed. It will always send the changed patch to clients.
|
||||
* It will also not crop the specified array to the actually used range.
|
||||
* In other words, this is not intended to be exposed as-is to user code,
|
||||
* it should always be called with validated, and, as necessary, cropped
|
||||
* values.
|
||||
*
|
||||
* @param column the horizontal index.
|
||||
* @param row the vertical index.
|
||||
* @param color the foreground color data to write.
|
||||
*/
|
||||
void rawSetForeground(int column, int row, int[][] color);
|
||||
|
||||
/**
|
||||
* Overwrites a portion of the background color information in raw mode.
|
||||
* <p/>
|
||||
* This will convert the specified RGB data (in <tt>0xRRGGBB</tt> format)
|
||||
* to the internal, packed representation and copy it into the buffer,
|
||||
* starting at the specified column and row. The array is expected to be
|
||||
* indexed row-first, i.e. the first dimension is the vertical axis, the
|
||||
* second the horizontal.
|
||||
* <p/>
|
||||
* <em>Important</em>: this performs no checks as to whether something
|
||||
* actually changed. It will always send the changed patch to clients.
|
||||
* It will also not crop the specified array to the actually used range.
|
||||
* In other words, this is not intended to be exposed as-is to user code,
|
||||
* it should always be called with validated, and, as necessary, cropped
|
||||
* values.
|
||||
*
|
||||
* @param column the horizontal index.
|
||||
* @param row the vertical index.
|
||||
* @param color the background color data to write.
|
||||
*/
|
||||
void rawSetBackground(int column, int row, int[][] color);
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
/**
|
||||
@ -452,7 +517,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable {
|
||||
* @param button the button of the mouse that was pressed.
|
||||
* @param player the player that pressed the mouse button. Pass <tt>null</tt> on the client side.
|
||||
*/
|
||||
void mouseDown(int x, int y, int button, EntityPlayer player);
|
||||
void mouseDown(double x, double y, int button, EntityPlayer player);
|
||||
|
||||
/**
|
||||
* Signals a mouse drag event for the buffer.
|
||||
@ -465,7 +530,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable {
|
||||
* @param button the button of the mouse that is pressed.
|
||||
* @param player the player that moved the mouse. Pass <tt>null</tt> on the client side.
|
||||
*/
|
||||
void mouseDrag(int x, int y, int button, EntityPlayer player);
|
||||
void mouseDrag(double x, double y, int button, EntityPlayer player);
|
||||
|
||||
/**
|
||||
* Signals a mouse button release event for the buffer.
|
||||
@ -478,7 +543,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable {
|
||||
* @param button the button of the mouse that was released.
|
||||
* @param player the player that released the mouse button. Pass <tt>null</tt> on the client side.
|
||||
*/
|
||||
void mouseUp(int x, int y, int button, EntityPlayer player);
|
||||
void mouseUp(double x, double y, int button, EntityPlayer player);
|
||||
|
||||
/**
|
||||
* Signals a mouse wheel scroll event for the buffer.
|
||||
@ -491,7 +556,7 @@ public interface TextBuffer extends ManagedEnvironment, Persistable {
|
||||
* @param delta indicates the direction of the mouse scroll.
|
||||
* @param player the player that scrolled the mouse wheel. Pass <tt>null</tt> on the client side.
|
||||
*/
|
||||
void mouseScroll(int x, int y, int delta, EntityPlayer player);
|
||||
void mouseScroll(double x, double y, int delta, EntityPlayer player);
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
|
@ -6,7 +6,7 @@ import li.cil.oc.api.machine.Context;
|
||||
/**
|
||||
* This interface can be used with an {@link li.cil.oc.api.network.Environment}
|
||||
* and is intended to be used for environments wrapping a ComputerCraft
|
||||
* peripheral. Tt could be used for other purposes as well, though. It allows
|
||||
* peripheral. It could be used for other purposes as well, though. It allows
|
||||
* providing method names in addition to those defined via the
|
||||
* {@link li.cil.oc.api.machine.Callback} annotation, and invoking said methods.
|
||||
*/
|
||||
|
26
src/main/java/li/cil/oc/api/network/SidedComponent.java
Normal file
26
src/main/java/li/cil/oc/api/network/SidedComponent.java
Normal file
@ -0,0 +1,26 @@
|
||||
package li.cil.oc.api.network;
|
||||
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
/**
|
||||
* This is an extended version of {@link li.cil.oc.api.network.SimpleComponent}
|
||||
* which allows controlling connectivity on a side-by-side basis.
|
||||
* <p/>
|
||||
* Like the <tt>SimpleComponent</tt> interface, this is intended to be used
|
||||
* with tile entities that should act as OC components. Please see the
|
||||
* <tt>SimpleComponent</tt> interface for more information.
|
||||
*/
|
||||
public interface SidedComponent {
|
||||
/**
|
||||
* Whether this component can connect to a node on the specified side.
|
||||
* <p/>
|
||||
* The provided side is relative to the component, i.e. when the tile
|
||||
* entity sits at (0, 0, 0) and is asked for its southern node (positive
|
||||
* Z axis) it has to return the connectivity for the face between it and
|
||||
* the block at (0, 0, 1).
|
||||
*
|
||||
* @param side the side to check for.
|
||||
* @return whether the component may be connected to from the specified side.
|
||||
*/
|
||||
boolean canConnectNode(EnumFacing side);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
Copyright (c) 2013-2014 Florian "Sangar" Nücke
|
||||
Copyright (c) 2013-2015 Florian "Sangar" Nücke
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -105,6 +105,18 @@ opencomputers {
|
||||
# importantly, can only render code page 437 (as opposed to...
|
||||
# a *lot* of unicode).
|
||||
fontRenderer: "unifont"
|
||||
|
||||
# The sample rate used for generating beeps of computers' internal
|
||||
# speakers. Use custom values at your own responsibility here; if it
|
||||
# breaks OC you'll get no support. Some potentially reasonable
|
||||
# lower values are 16000 or even 8000 (which was the old default, but
|
||||
# leads to artifacting on certain frequencies).
|
||||
beepSampleRate: 44100
|
||||
|
||||
# The base volume of beeps generated by computers. This may be in a
|
||||
# range of [0, 127], where 0 means mute (the sound will not even be
|
||||
# generated), and 127 means maximum amplitude / volume.
|
||||
beepVolume: 32
|
||||
}
|
||||
|
||||
# Computer related settings, concerns server performance and security.
|
||||
@ -675,11 +687,11 @@ opencomputers {
|
||||
# each point of complexity.
|
||||
tabletAssemblyComplexity: 5000
|
||||
|
||||
# The base energy cost for assembling a microcontroller.
|
||||
# The base energy cost for assembling a drone.
|
||||
droneAssemblyBase: 25000
|
||||
|
||||
# The additional amount of energy required to assemble a
|
||||
# microcontroller for each point of complexity.
|
||||
# drone for each point of complexity.
|
||||
droneAssemblyComplexity: 15000
|
||||
|
||||
# The amount of energy it takes to extract one ingredient from an
|
||||
|
@ -298,7 +298,7 @@ oc:tooltip.UpgradePiston=This upgrade is very pushy. It allows moving blocks, si
|
||||
oc:tooltip.UpgradeSign=Allows reading text on and writing text to signs.
|
||||
oc:tooltip.UpgradeSolarGenerator=Can be used to generate energy from sunlight on the go. Requires a clear line of sight to the sky above the device. Generates energy at %s%% of the speed of a Stirling Engine.
|
||||
oc:tooltip.UpgradeTank=This upgrade provides a tank for fluid storage for robots and drones. Without one of these, they will not be able to store fluids internally.
|
||||
oc:tooltip.UpgradeTankController=This upgrade allows the robots and drones more control in how they interacts with external tanks, and allows them to transfer fluids into and out of fluid tank items in their inventory.
|
||||
oc:tooltip.UpgradeTankController=This upgrade allows robots and drones more control in how they interacts with external tanks, and allows them to transfer fluids into and out of fluid tank items in their inventory.
|
||||
oc:tooltip.UpgradeTractorBeam=Equips a device with extremely advanced technology, nicknamed the "Item Magnet". Allows the device to pick up items anywhere within 3 blocks of its location.
|
||||
oc:tooltip.WirelessNetworkCard=Allows wireless sending of network messages in addition to normal ones. You can adjust the §fsignal strength§7 to control how far messages are sent. Higher signal strength results in higher energy consumption.
|
||||
oc:tooltip.WorldSensorCard=Allows reading out information about the world, such as its gravity and whether it has a breathable atmosphere. Use results at own risk. The manufacturer takes no responsibility for bodily or material harm caused by decisions made upon the cards' outputs. We have lawyers. And money. Don't even try.
|
||||
@ -308,7 +308,7 @@ item.oc.AbstractBusCard.usage=This card allows computers, servers and robots to
|
||||
item.oc.Analyzer.usage=The §oAnalyzer§r is a handy tool for getting some information about OpenComputers-related blocks in the world. Simply (sneak-)activate a block to get some information printed to the chat. This ranges from basic things like the address of components, to power levels in the subnetwork the block is in, and information on the error lead to a computer to crash, for example.[nl][nl]Another useful functionality is that when using the using the analyzer on a block while holding down [Ctrl] the address of the block component will be copied to the clipboard.
|
||||
item.oc.ComponentBus.usage=A §oComponent Bus§r is a server-specific upgrade that allows the server to communicate with more components at the same time, without shutting down. Like with CPUs, higher tier buses provide higher component limits.
|
||||
item.oc.CPU.usage=The §oCentral Processing Unit§r is a core part for each computer. It defines the architecture of the computer, and the number of components that can be connected to the computer before it stops working. Higher tier CPUs also provide a higher per-tick direct call limit to the computer - in simpler terms: better CPUs run faster.
|
||||
item.oc.DebugCard.usage=The §oDebug Card§r is a non-craftable item that was originally only intended to make debugging things easier, by automating some processes. It has since gotten a bunch more functionality, making it quite useful for custom map-making.
|
||||
item.oc.DebugCard.usage=The §oDebug Card§r is a non-craftable item that was originally only intended to make debugging things easier, by automating some processes. It has since gotten a bunch more functionality, making it quite useful for custom map-making.[nl][nl]Note that you can use shift-rightclick while holding the card to bind it to you / unbind it, meaning §orunCommand§r will be performed using your permission levels instead of the default OpenComputers ones.
|
||||
item.oc.DroneCase.usage=The §oDrone Case§r is used to build Drones in the Assembler. Drones are light-weight, fast and very mobile machines with limited functionality. Unlike Robots they cannot use tools, and can interact with the world only in a relatively limited manner.[nl][nl]They make up for their limitations with speed and lower running energy costs. They are well suited for transport of small amounts of items, and ideal for reconnaissance. Pairing a Drone with a Robot can be quite powerful, with the Robot doing the "hard work", and the Drone providing information about the environment and transporting items to and from a central hub, for example.[nl][nl]Like microcontrollers, Drones can only be programmed using their EEPROM. Accordingly, the EEPROM can be changed by recrafting the Drone with another EEPROM.
|
||||
item.oc.eeprom.usage=The §oEEPROM§r is what contains the code used to initialize a computer when it is being booted. This data is stored as a plain byte array, and may mean different things to different CPU architectures. For example, for Lua it is usually a small script that searches for file systems with an init script, for other architectures it may be actual machine code.
|
||||
item.oc.FloppyDisk.usage=The §oFloppy Disk§r is the cheapest and smallest type of storage medium in OpenComputers. It is a handy early game way of storing data and transferring it between computers and robots. You may also find floppy disks with useful programs on them in dungeon chests.[nl][nl]Beware: shift-rightclicking while holding a floppy disk in your hand will wipe the floppy disk!
|
||||
|
@ -17,13 +17,17 @@ local text = require("text")
|
||||
|
||||
local args, options = shell.parse(...)
|
||||
if #args < 1 then
|
||||
print("Usage: irc <nickname> [server:port]")
|
||||
print("Usage: irc <nickname> [server[:port]]")
|
||||
return
|
||||
end
|
||||
|
||||
local nick = args[1]
|
||||
local host = args[2] or "irc.esper.net:6667"
|
||||
|
||||
if not host:find(":") then
|
||||
host = host .. ":6667"
|
||||
end
|
||||
|
||||
-- try to connect to server.
|
||||
local sock, reason = internet.open(host)
|
||||
if not sock then
|
||||
|
@ -27,7 +27,7 @@ end
|
||||
|
||||
function component.isAvailable(componentType)
|
||||
checkArg(1, componentType, "string")
|
||||
if not primaries[componentType] then
|
||||
if not primaries[componentType] and not adding[componentType] then
|
||||
-- This is mostly to avoid out of memory errors preventing proxy
|
||||
-- creation cause confusion by trying to create the proxy again,
|
||||
-- causing the oom error to be thrown again.
|
||||
|
@ -351,8 +351,8 @@ function filesystem.list(path)
|
||||
table.remove(result, i)
|
||||
else
|
||||
f = result[i]
|
||||
i = i + 1
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
local i = 0
|
||||
return function()
|
||||
@ -376,22 +376,31 @@ function filesystem.makeDirectory(path)
|
||||
end
|
||||
|
||||
function filesystem.remove(path)
|
||||
local node, rest, vnode, vrest = findNode(filesystem.path(path))
|
||||
local name = filesystem.name(path)
|
||||
if vnode.children[name] then
|
||||
vnode.children[name] = nil
|
||||
removeEmptyNodes(vnode)
|
||||
return true
|
||||
elseif vnode.links[name] then
|
||||
vnode.links[name] = nil
|
||||
removeEmptyNodes(vnode)
|
||||
return true
|
||||
else
|
||||
local function removeVirtual()
|
||||
local node, rest, vnode, vrest = findNode(filesystem.path(path))
|
||||
local name = filesystem.name(path)
|
||||
if vnode.children[name] then
|
||||
vnode.children[name] = nil
|
||||
removeEmptyNodes(vnode)
|
||||
return true
|
||||
elseif vnode.links[name] then
|
||||
vnode.links[name] = nil
|
||||
removeEmptyNodes(vnode)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
local function removePhysical()
|
||||
node, rest = findNode(path)
|
||||
if node.fs and rest then
|
||||
return component.proxy(node.fs).remove(rest)
|
||||
end
|
||||
return nil, "no such file or directory"
|
||||
return false
|
||||
end
|
||||
local success = removeVirtual()
|
||||
success = removePhysical() or success -- Always run.
|
||||
if success then return true
|
||||
else return nil, "no such file or directory"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -108,10 +108,11 @@ function term.isAvailable()
|
||||
return component.isAvailable("gpu") and component.isAvailable("screen")
|
||||
end
|
||||
|
||||
function term.read(history, dobreak, hint, pwchar)
|
||||
function term.read(history, dobreak, hint, pwchar, filter)
|
||||
checkArg(1, history, "table", "nil")
|
||||
checkArg(3, hint, "function", "table", "nil")
|
||||
checkArg(4, pwchar, "string", "nil")
|
||||
checkArg(5, filter, "string", "function", "nil")
|
||||
history = history or {}
|
||||
table.insert(history, "")
|
||||
local offset = term.getCursor() - 1
|
||||
@ -130,6 +131,13 @@ function term.read(history, dobreak, hint, pwchar)
|
||||
pwchar = unicode.sub(pwchar, 1, 1)
|
||||
end
|
||||
|
||||
if type(filter) == "string" then
|
||||
local pattern = filter
|
||||
filter = function(line)
|
||||
return line:match(pattern)
|
||||
end
|
||||
end
|
||||
|
||||
local function masktext(str)
|
||||
return pwchar and pwchar:rep(unicode.len(str)) or str
|
||||
end
|
||||
@ -327,12 +335,16 @@ function term.read(history, dobreak, hint, pwchar)
|
||||
elseif code == keyboard.keys.tab and hint then
|
||||
tab(keyboard.isShiftDown() and -1 or 1)
|
||||
elseif code == keyboard.keys.enter then
|
||||
local cbx, cby = getCursor()
|
||||
if cby ~= #history then -- bring entry to front
|
||||
history[#history] = line()
|
||||
table.remove(history, cby)
|
||||
if not filter or filter(line() or "") then
|
||||
local cbx, cby = getCursor()
|
||||
if cby ~= #history then -- bring entry to front
|
||||
history[#history] = line()
|
||||
table.remove(history, cby)
|
||||
end
|
||||
return true, history[#history] .. "\n"
|
||||
else
|
||||
computer.beep(2000, 0.1)
|
||||
end
|
||||
return true, history[#history] .. "\n"
|
||||
elseif keyboard.isControlDown() and code == keyboard.keys.d then
|
||||
if line() == "" then
|
||||
history[#history] = ""
|
||||
|
@ -9,7 +9,7 @@ DESCRIPTION
|
||||
|
||||
EXAMPLES
|
||||
echo test
|
||||
Print `test` to the terminal.
|
||||
Print `test` to the standard output (which is usually the terminal).
|
||||
|
||||
echo "a b" > test
|
||||
Writes the string `a b` to the standard output, which is redirected into file `test`.
|
||||
echo "a b"
|
||||
Writes the string `a b`.
|
16
src/main/resources/assets/opencomputers/sounds/preload.cfg
Normal file
16
src/main/resources/assets/opencomputers/sounds/preload.cfg
Normal file
@ -0,0 +1,16 @@
|
||||
assets/opencomputers/sounds/computer_running.ogg
|
||||
assets/opencomputers/sounds/floppy_access1.ogg
|
||||
assets/opencomputers/sounds/floppy_access2.ogg
|
||||
assets/opencomputers/sounds/floppy_access3.ogg
|
||||
assets/opencomputers/sounds/floppy_access4.ogg
|
||||
assets/opencomputers/sounds/floppy_access5.ogg
|
||||
assets/opencomputers/sounds/floppy_access6.ogg
|
||||
assets/opencomputers/sounds/floppy_eject.ogg
|
||||
assets/opencomputers/sounds/floppy_insert.ogg
|
||||
assets/opencomputers/sounds/hdd_access1.ogg
|
||||
assets/opencomputers/sounds/hdd_access2.ogg
|
||||
assets/opencomputers/sounds/hdd_access3.ogg
|
||||
assets/opencomputers/sounds/hdd_access4.ogg
|
||||
assets/opencomputers/sounds/hdd_access5.ogg
|
||||
assets/opencomputers/sounds/hdd_access6.ogg
|
||||
assets/opencomputers/sounds/hdd_access7.ogg
|
@ -49,6 +49,8 @@ class Settings(val config: Config) {
|
||||
}
|
||||
val monochromeColor = Integer.decode(config.getString("client.monochromeColor"))
|
||||
val fontRenderer = config.getString("client.fontRenderer")
|
||||
val beepSampleRate = config.getInt("client.beepSampleRate")
|
||||
val beepAmplitude = config.getInt("client.beepVolume") max 0 min Byte.MaxValue
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
// computer
|
||||
|
@ -5,9 +5,13 @@ import net.minecraftforge.fml.client.FMLClientHandler
|
||||
import org.lwjgl.input.Keyboard
|
||||
|
||||
object KeyBindings {
|
||||
def showExtendedTooltips = Keyboard.isCreated && Keyboard.isKeyDown(extendedTooltip.getKeyCode)
|
||||
def showExtendedTooltips = Keyboard.isCreated && (try Keyboard.isKeyDown(extendedTooltip.getKeyCode) catch {
|
||||
case _: Throwable => false // Don't ask me, sometimes things can apparently screw up LWJGL's keyboard handling.
|
||||
})
|
||||
|
||||
def showMaterialCosts = Keyboard.isCreated && Keyboard.isKeyDown(materialCosts.getKeyCode)
|
||||
def showMaterialCosts = Keyboard.isCreated && (try Keyboard.isKeyDown(materialCosts.getKeyCode) catch {
|
||||
case _: Throwable => false // Don't ask me, sometimes things can apparently screw up LWJGL's keyboard handling.
|
||||
})
|
||||
|
||||
def extendedTooltip = FMLClientHandler.instance.getClient.gameSettings.keyBindSneak
|
||||
|
||||
|
@ -355,6 +355,9 @@ object PacketHandler extends CommonPacketHandler {
|
||||
case PacketType.TextBufferMultiResolutionChange => onTextBufferMultiResolutionChange(p, buffer)
|
||||
case PacketType.TextBufferMultiMaxResolutionChange => onTextBufferMultiMaxResolutionChange(p, buffer)
|
||||
case PacketType.TextBufferMultiSet => onTextBufferMultiSet(p, buffer)
|
||||
case PacketType.TextBufferMultiRawSetText => onTextBufferMultiRawSetText(p, buffer)
|
||||
case PacketType.TextBufferMultiRawSetBackground => onTextBufferMultiRawSetBackground(p, buffer)
|
||||
case PacketType.TextBufferMultiRawSetForeground => onTextBufferMultiRawSetForeground(p, buffer)
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
}
|
||||
@ -426,6 +429,60 @@ object PacketHandler extends CommonPacketHandler {
|
||||
buffer.set(col, row, s, vertical)
|
||||
}
|
||||
|
||||
def onTextBufferMultiRawSetText(p: PacketParser, buffer: component.TextBuffer) {
|
||||
val col = p.readInt()
|
||||
val row = p.readInt()
|
||||
|
||||
val rows = p.readShort()
|
||||
val text = new Array[Array[Char]](rows)
|
||||
for (y <- 0 until rows) {
|
||||
val cols = p.readShort()
|
||||
val line = new Array[Char](cols)
|
||||
for (x <- 0 until cols) {
|
||||
line(x) = p.readChar()
|
||||
}
|
||||
text(y) = line
|
||||
}
|
||||
|
||||
buffer.rawSetText(col, row, text)
|
||||
}
|
||||
|
||||
def onTextBufferMultiRawSetBackground(p: PacketParser, buffer: component.TextBuffer) {
|
||||
val col = p.readInt()
|
||||
val row = p.readInt()
|
||||
|
||||
val rows = p.readShort()
|
||||
val color = new Array[Array[Int]](rows)
|
||||
for (y <- 0 until rows) {
|
||||
val cols = p.readShort()
|
||||
val line = new Array[Int](cols)
|
||||
for (x <- 0 until cols) {
|
||||
line(x) = p.readInt()
|
||||
}
|
||||
color(y) = line
|
||||
}
|
||||
|
||||
buffer.rawSetBackground(col, row, color)
|
||||
}
|
||||
|
||||
def onTextBufferMultiRawSetForeground(p: PacketParser, buffer: component.TextBuffer) {
|
||||
val col = p.readInt()
|
||||
val row = p.readInt()
|
||||
|
||||
val rows = p.readShort()
|
||||
val color = new Array[Array[Int]](rows)
|
||||
for (y <- 0 until rows) {
|
||||
val cols = p.readShort()
|
||||
val line = new Array[Int](cols)
|
||||
for (x <- 0 until cols) {
|
||||
line(x) = p.readInt()
|
||||
}
|
||||
color(y) = line
|
||||
}
|
||||
|
||||
buffer.rawSetForeground(col, row, color)
|
||||
}
|
||||
|
||||
def onScreenTouchMode(p: PacketParser) =
|
||||
p.readTileEntity[Screen]() match {
|
||||
case Some(t) => t.invertTouchMode = p.readBoolean()
|
||||
|
@ -76,35 +76,35 @@ object PacketSender {
|
||||
}
|
||||
}
|
||||
|
||||
def sendMouseClick(address: String, x: Int, y: Int, drag: Boolean, button: Int) {
|
||||
def sendMouseClick(address: String, x: Double, y: Double, drag: Boolean, button: Int) {
|
||||
val pb = new SimplePacketBuilder(PacketType.MouseClickOrDrag)
|
||||
|
||||
pb.writeUTF(address)
|
||||
pb.writeShort(x)
|
||||
pb.writeShort(y)
|
||||
pb.writeFloat(x.toFloat)
|
||||
pb.writeFloat(y.toFloat)
|
||||
pb.writeBoolean(drag)
|
||||
pb.writeByte(button.toByte)
|
||||
|
||||
pb.sendToServer()
|
||||
}
|
||||
|
||||
def sendMouseScroll(address: String, x: Int, y: Int, scroll: Int) {
|
||||
def sendMouseScroll(address: String, x: Double, y: Double, scroll: Int) {
|
||||
val pb = new SimplePacketBuilder(PacketType.MouseScroll)
|
||||
|
||||
pb.writeUTF(address)
|
||||
pb.writeShort(x)
|
||||
pb.writeShort(y)
|
||||
pb.writeFloat(x.toFloat)
|
||||
pb.writeFloat(y.toFloat)
|
||||
pb.writeByte(scroll)
|
||||
|
||||
pb.sendToServer()
|
||||
}
|
||||
|
||||
def sendMouseUp(address: String, x: Int, y: Int, button: Int) {
|
||||
def sendMouseUp(address: String, x: Double, y: Double, button: Int) {
|
||||
val pb = new SimplePacketBuilder(PacketType.MouseUp)
|
||||
|
||||
pb.writeUTF(address)
|
||||
pb.writeShort(x)
|
||||
pb.writeShort(y)
|
||||
pb.writeFloat(x.toFloat)
|
||||
pb.writeFloat(y.toFloat)
|
||||
pb.writeByte(button.toByte)
|
||||
|
||||
pb.sendToServer()
|
||||
|
@ -8,6 +8,7 @@ import java.util.Timer
|
||||
import java.util.TimerTask
|
||||
import java.util.UUID
|
||||
|
||||
import com.google.common.base.Charsets
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import net.minecraft.client.Minecraft
|
||||
@ -19,11 +20,13 @@ import net.minecraftforge.client.event.sound.SoundLoadEvent
|
||||
import net.minecraftforge.event.world.WorldEvent
|
||||
import net.minecraftforge.fml.client.FMLClientHandler
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent
|
||||
import net.minecraftforge.fml.relauncher.ReflectionHelper
|
||||
import paulscode.sound.SoundSystem
|
||||
import paulscode.sound.SoundSystemConfig
|
||||
|
||||
import scala.collection.mutable
|
||||
import scala.io.Source
|
||||
|
||||
object Sound {
|
||||
private val sources = mutable.Map.empty[TileEntity, PseudoLoopingStream]
|
||||
@ -100,6 +103,33 @@ object Sound {
|
||||
manager = event.manager
|
||||
}
|
||||
|
||||
private var hasPreloaded = Settings.get.soundVolume <= 0
|
||||
|
||||
@SubscribeEvent
|
||||
def onTick(e: ClientTickEvent) {
|
||||
if (!hasPreloaded && soundSystem != null) {
|
||||
hasPreloaded = true
|
||||
new Thread(new Runnable() {
|
||||
override def run(): Unit = {
|
||||
val preloadConfigLocation = new ResourceLocation(Settings.resourceDomain, "sounds/preload.cfg")
|
||||
val preloadConfigResource = Minecraft.getMinecraft.getResourceManager.getResource(preloadConfigLocation)
|
||||
for (location <- Source.fromInputStream(preloadConfigResource.getInputStream)(Charsets.UTF_8).getLines()) {
|
||||
val url = getClass.getClassLoader.getResource(location)
|
||||
if (url != null) try {
|
||||
val sourceName = "preload_" + location
|
||||
soundSystem.newSource(false, sourceName, url, location, true, 0, 0, 0, SoundSystemConfig.ATTENUATION_NONE, 16)
|
||||
soundSystem.activate(sourceName)
|
||||
soundSystem.removeSource(sourceName)
|
||||
} catch {
|
||||
case _: Throwable => // Meh.
|
||||
}
|
||||
else OpenComputers.log.warn(s"Couldn't preload sound $location!")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
def onWorldUnload(event: WorldEvent.Unload) {
|
||||
commandQueue.synchronized(commandQueue.clear())
|
||||
|
@ -6,8 +6,8 @@ import li.cil.oc.common.tileentity
|
||||
import net.minecraft.entity.player.InventoryPlayer
|
||||
|
||||
class Adapter(playerInventory: InventoryPlayer, val adapter: tileentity.Adapter) extends DynamicGuiContainer(new container.Adapter(playerInventory, adapter)) {
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawGuiContainerForegroundLayer(mouseX, mouseY)
|
||||
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawSecondaryForegroundLayer(mouseX, mouseY)
|
||||
fontRendererObj.drawString(
|
||||
Localization.localizeImmediately(adapter.getName),
|
||||
8, 6, 0x404040)
|
||||
|
@ -60,7 +60,7 @@ class Assembler(playerInventory: InventoryPlayer, val assembler: tileentity.Asse
|
||||
add(buttonList, runButton)
|
||||
}
|
||||
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) // Me lazy... prevents NEI render glitch.
|
||||
if (!assemblerContainer.isAssembling) {
|
||||
val message =
|
||||
|
@ -33,9 +33,8 @@ class Case(playerInventory: InventoryPlayer, val computer: tileentity.Case) exte
|
||||
add(buttonList, powerButton)
|
||||
}
|
||||
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawGuiContainerForegroundLayer(mouseX, mouseY)
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) // Me lazy... prevents NEI render glitch.
|
||||
override protected def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawSecondaryForegroundLayer(mouseX, mouseY)
|
||||
fontRendererObj.drawString(
|
||||
Localization.localizeImmediately(computer.getName),
|
||||
8, 6, 0x404040)
|
||||
@ -44,7 +43,6 @@ class Case(playerInventory: InventoryPlayer, val computer: tileentity.Case) exte
|
||||
tooltip.add(if (computer.isRunning) Localization.Computer.TurnOff else Localization.Computer.TurnOn)
|
||||
copiedDrawHoveringText(tooltip, mouseX - guiLeft, mouseY - guiTop, fontRendererObj)
|
||||
}
|
||||
GL11.glPopAttrib()
|
||||
}
|
||||
|
||||
override def drawSecondaryBackgroundLayer() {
|
||||
|
@ -6,8 +6,8 @@ import li.cil.oc.common.tileentity
|
||||
import net.minecraft.entity.player.InventoryPlayer
|
||||
|
||||
class Charger(playerInventory: InventoryPlayer, val charger: tileentity.Charger) extends DynamicGuiContainer(new container.Charger(playerInventory, charger)) {
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawGuiContainerForegroundLayer(mouseX, mouseY)
|
||||
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawSecondaryForegroundLayer(mouseX, mouseY)
|
||||
fontRendererObj.drawString(
|
||||
Localization.localizeImmediately(charger.getName),
|
||||
8, 6, 0x404040)
|
||||
|
@ -11,7 +11,7 @@ import org.lwjgl.opengl.GL11
|
||||
class Database(playerInventory: InventoryPlayer, val databaseInventory: DatabaseInventory) extends DynamicGuiContainer(new container.Database(playerInventory, databaseInventory)) {
|
||||
ySize = 256
|
||||
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) {}
|
||||
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) {}
|
||||
|
||||
override protected def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) {
|
||||
GL11.glColor4f(1, 1, 1, 1)
|
||||
|
@ -13,7 +13,7 @@ class Disassembler(playerInventory: InventoryPlayer, val disassembler: tileentit
|
||||
|
||||
val progress = addWidget(new ProgressBar(18, 65))
|
||||
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
fontRendererObj.drawString(
|
||||
Localization.localizeImmediately(disassembler.getName),
|
||||
8, 6, 0x404040)
|
||||
|
@ -6,8 +6,8 @@ import li.cil.oc.common.tileentity
|
||||
import net.minecraft.entity.player.InventoryPlayer
|
||||
|
||||
class DiskDrive(playerInventory: InventoryPlayer, val drive: tileentity.DiskDrive) extends DynamicGuiContainer(new container.DiskDrive(playerInventory, drive)) {
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawGuiContainerForegroundLayer(mouseX, mouseY)
|
||||
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawSecondaryForegroundLayer(mouseX, mouseY)
|
||||
fontRendererObj.drawString(
|
||||
Localization.localizeImmediately(drive.getName),
|
||||
8, 6, 0x404040)
|
||||
|
@ -87,7 +87,7 @@ class Drone(playerInventory: InventoryPlayer, val drone: entity.Drone) extends D
|
||||
|
||||
override protected def changeSize(w: Double, h: Double, recompile: Boolean) = 2.0
|
||||
|
||||
override protected def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) {
|
||||
override protected def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) {
|
||||
drawBufferLayer()
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) // Me lazy... prevents NEI render glitch.
|
||||
if (isPointInRegion(power.x, power.y, power.width, power.height, mouseX, mouseY)) {
|
||||
|
@ -1,18 +1,21 @@
|
||||
package li.cil.oc.client.gui
|
||||
|
||||
import codechicken.nei.ItemPanel
|
||||
import codechicken.nei.LayoutManager
|
||||
import li.cil.oc.Localization
|
||||
import li.cil.oc.client.Textures
|
||||
import li.cil.oc.common
|
||||
import li.cil.oc.common.container.ComponentSlot
|
||||
import li.cil.oc.common.container.Player
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util.NEI
|
||||
import li.cil.oc.util.RenderState
|
||||
import net.minecraft.client.gui.Gui
|
||||
import net.minecraft.client.renderer.GlStateManager
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.inventory.Container
|
||||
import net.minecraft.inventory.Slot
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraftforge.fml.common.Optional
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
@ -22,12 +25,24 @@ abstract class DynamicGuiContainer(container: Container) extends CustomGuiContai
|
||||
|
||||
protected var hoveredStackNEI: Option[ItemStack] = None
|
||||
|
||||
override protected def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) {
|
||||
protected def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) {
|
||||
fontRendererObj.drawString(
|
||||
Localization.localizeImmediately("container.inventory"),
|
||||
8, ySize - 96 + 2, 0x404040)
|
||||
}
|
||||
|
||||
override protected def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) {
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS)
|
||||
|
||||
drawSecondaryForegroundLayer(mouseX, mouseY)
|
||||
|
||||
for (slot <- 0 until inventorySlots.inventorySlots.size()) {
|
||||
drawSlotHighlight(inventorySlots.inventorySlots.get(slot).asInstanceOf[Slot])
|
||||
}
|
||||
|
||||
GL11.glPopAttrib()
|
||||
}
|
||||
|
||||
protected def drawSecondaryBackgroundLayer() {}
|
||||
|
||||
override protected def drawGuiContainerBackgroundLayer(dt: Float, mouseX: Int, mouseY: Int) {
|
||||
@ -41,9 +56,11 @@ abstract class DynamicGuiContainer(container: Container) extends CustomGuiContai
|
||||
|
||||
GL11.glPushMatrix()
|
||||
GL11.glTranslatef(guiLeft, guiTop, 0)
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST)
|
||||
for (slot <- 0 until inventorySlots.inventorySlots.size()) {
|
||||
drawSlotInventory(inventorySlots.inventorySlots.get(slot).asInstanceOf[Slot])
|
||||
}
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST)
|
||||
GL11.glPopMatrix()
|
||||
}
|
||||
|
||||
@ -55,12 +72,11 @@ abstract class DynamicGuiContainer(container: Container) extends CustomGuiContai
|
||||
|
||||
super.drawScreen(mouseX, mouseY, dt)
|
||||
|
||||
GL11.glPushMatrix()
|
||||
GL11.glTranslatef(guiLeft, guiTop, 0)
|
||||
for (slot <- 0 until inventorySlots.inventorySlots.size()) {
|
||||
drawSlotHighlight(inventorySlots.inventorySlots.get(slot).asInstanceOf[Slot])
|
||||
if (Mods.NotEnoughItems.isAvailable) {
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS)
|
||||
drawNEIHighlights()
|
||||
GL11.glPopAttrib()
|
||||
}
|
||||
GL11.glPopMatrix()
|
||||
}
|
||||
|
||||
protected def drawSlotInventory(slot: Slot) {
|
||||
@ -70,13 +86,13 @@ abstract class DynamicGuiContainer(container: Container) extends CustomGuiContai
|
||||
drawDisabledSlot(component)
|
||||
}
|
||||
case _ =>
|
||||
zLevel += 1
|
||||
if (!isInPlayerInventory(slot)) {
|
||||
drawSlotBackground(slot.xDisplayPosition - 1, slot.yDisplayPosition - 1)
|
||||
}
|
||||
if (!slot.getHasStack) {
|
||||
slot match {
|
||||
case component: ComponentSlot =>
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST)
|
||||
if (component.tierIcon != null) {
|
||||
mc.getTextureManager.bindTexture(component.tierIcon)
|
||||
Gui.drawModalRectWithCustomSizedTexture(slot.xDisplayPosition, slot.yDisplayPosition, 0, 0, 16, 16, 16, 16)
|
||||
@ -85,38 +101,37 @@ abstract class DynamicGuiContainer(container: Container) extends CustomGuiContai
|
||||
mc.getTextureManager.bindTexture(slot.getBackgroundLocation)
|
||||
Gui.drawModalRectWithCustomSizedTexture(slot.xDisplayPosition, slot.yDisplayPosition, 0, 0, 16, 16, 16, 16)
|
||||
}
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST)
|
||||
case _ =>
|
||||
}
|
||||
zLevel -= 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected def drawSlotHighlight(slot: Slot) {
|
||||
slot match {
|
||||
if (mc.thePlayer.inventory.getItemStack == null) slot match {
|
||||
case component: ComponentSlot if component.slot == common.Slot.None || component.tier == common.Tier.None => // Ignore.
|
||||
case _ =>
|
||||
if (mc.thePlayer.inventory.getItemStack == null) {
|
||||
val currentIsInPlayerInventory = isInPlayerInventory(slot)
|
||||
val drawHighlight = hoveredSlot match {
|
||||
case Some(hovered) =>
|
||||
val hoveredIsInPlayerInventory = isInPlayerInventory(hovered)
|
||||
(currentIsInPlayerInventory != hoveredIsInPlayerInventory) &&
|
||||
((currentIsInPlayerInventory && slot.getHasStack && isSelectiveSlot(hovered) && hovered.isItemValid(slot.getStack)) ||
|
||||
(hoveredIsInPlayerInventory && hovered.getHasStack && isSelectiveSlot(slot) && slot.isItemValid(hovered.getStack)))
|
||||
case _ => hoveredStackNEI match {
|
||||
case Some(stack) => !currentIsInPlayerInventory && isSelectiveSlot(slot) && slot.isItemValid(stack)
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
if (drawHighlight) {
|
||||
GlStateManager.disableLighting()
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST)
|
||||
drawGradientRect(slot.xDisplayPosition, slot.yDisplayPosition, slot.xDisplayPosition + 16, slot.yDisplayPosition + 16, 0x80FFFFFF, 0x80FFFFFF)
|
||||
GlStateManager.enableLighting()
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST)
|
||||
val currentIsInPlayerInventory = isInPlayerInventory(slot)
|
||||
val drawHighlight = hoveredSlot match {
|
||||
case Some(hovered) =>
|
||||
val hoveredIsInPlayerInventory = isInPlayerInventory(hovered)
|
||||
(currentIsInPlayerInventory != hoveredIsInPlayerInventory) &&
|
||||
((currentIsInPlayerInventory && slot.getHasStack && isSelectiveSlot(hovered) && hovered.isItemValid(slot.getStack)) ||
|
||||
(hoveredIsInPlayerInventory && hovered.getHasStack && isSelectiveSlot(slot) && slot.isItemValid(hovered.getStack)))
|
||||
case _ => hoveredStackNEI match {
|
||||
case Some(stack) => !currentIsInPlayerInventory && isSelectiveSlot(slot) && slot.isItemValid(stack)
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
if (drawHighlight) {
|
||||
zLevel += 100
|
||||
drawGradientRect(
|
||||
slot.xDisplayPosition, slot.yDisplayPosition,
|
||||
slot.xDisplayPosition + 16, slot.yDisplayPosition + 16,
|
||||
0x80FFFFFF, 0x80FFFFFF)
|
||||
zLevel -= 100
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,11 +143,7 @@ abstract class DynamicGuiContainer(container: Container) extends CustomGuiContai
|
||||
protected def drawDisabledSlot(slot: ComponentSlot) {
|
||||
GL11.glColor4f(1, 1, 1, 1)
|
||||
mc.getTextureManager.bindTexture(slot.tierIcon)
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST)
|
||||
GL11.glDisable(GL11.GL_LIGHTING)
|
||||
Gui.drawModalRectWithCustomSizedTexture(slot.xDisplayPosition, slot.yDisplayPosition, 0, 0, 16, 16, 16, 16)
|
||||
GL11.glEnable(GL11.GL_LIGHTING)
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST)
|
||||
}
|
||||
|
||||
protected def drawSlotBackground(x: Int, y: Int) {
|
||||
@ -152,4 +163,26 @@ abstract class DynamicGuiContainer(container: Container) extends CustomGuiContai
|
||||
case player: Player => slot.inventory == player.playerInventory
|
||||
case _ => false
|
||||
}
|
||||
|
||||
@Optional.Method(modid = Mods.IDs.NotEnoughItems)
|
||||
private def drawNEIHighlights(): Unit = {
|
||||
val panel = LayoutManager.itemPanel
|
||||
if (panel == null) return
|
||||
zLevel += 350
|
||||
for (index <- 0 until ItemPanel.items.size()) {
|
||||
val rect = panel.getSlotRect(index)
|
||||
val slot = panel.getSlotMouseOver(rect.x, rect.y)
|
||||
if (slot != null) hoveredSlot match {
|
||||
case Some(hovered) =>
|
||||
if (!isInPlayerInventory(hovered) && isSelectiveSlot(hovered) && hovered.isItemValid(slot.item)) {
|
||||
drawGradientRect(
|
||||
rect.x1 + 1, rect.y1 + 1,
|
||||
rect.x2, rect.y2,
|
||||
0x40FFFFFF, 0x40FFFFFF)
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
zLevel -= 350
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ import net.minecraft.entity.player.InventoryPlayer
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
class Raid(playerInventory: InventoryPlayer, val raid: tileentity.Raid) extends DynamicGuiContainer(new container.Raid(playerInventory, raid)) {
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawGuiContainerForegroundLayer(mouseX, mouseY)
|
||||
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawSecondaryForegroundLayer(mouseX, mouseY)
|
||||
fontRendererObj.drawString(
|
||||
Localization.localizeImmediately(raid.getName),
|
||||
8, 6, 0x404040)
|
||||
|
@ -128,7 +128,7 @@ class Robot(playerInventory: InventoryPlayer, val robot: tileentity.Robot) exten
|
||||
}
|
||||
}
|
||||
|
||||
override protected def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) {
|
||||
override protected def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) {
|
||||
drawBufferLayer()
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) // Me lazy... prevents NEI render glitch.
|
||||
if (isPointInRegion(power.x, power.y, power.width, power.height, mouseX, mouseY)) {
|
||||
|
@ -20,18 +20,18 @@ class Screen(val buffer: api.component.TextBuffer, val hasMouse: Boolean, val ha
|
||||
|
||||
private var x, y = 0
|
||||
|
||||
private var mx, my = 0
|
||||
private var mx, my = -1
|
||||
|
||||
override def handleMouseInput() {
|
||||
super.handleMouseInput()
|
||||
if (hasMouse && Mouse.hasWheel && Mouse.getEventDWheel != 0) {
|
||||
val mouseX = Mouse.getEventX * width / mc.displayWidth
|
||||
val mouseY = height - Mouse.getEventY * height / mc.displayHeight - 1
|
||||
val bx = (mouseX - x - bufferMargin) / TextBufferRenderCache.renderer.charRenderWidth + 1
|
||||
val by = (mouseY - y - bufferMargin) / TextBufferRenderCache.renderer.charRenderHeight + 1
|
||||
val bx = (mouseX - x - bufferMargin) / TextBufferRenderCache.renderer.charRenderWidth.toDouble
|
||||
val by = (mouseY - y - bufferMargin) / TextBufferRenderCache.renderer.charRenderHeight.toDouble
|
||||
val bw = buffer.getWidth
|
||||
val bh = buffer.getHeight
|
||||
if (bx > 0 && by > 0 && bx <= bw && by <= bh) {
|
||||
if (bx >= 0 && by >= 0 && bx < bw && by < bh) {
|
||||
val scroll = math.signum(Mouse.getEventDWheel)
|
||||
buffer.mouseScroll(bx, by, scroll, null)
|
||||
}
|
||||
@ -60,35 +60,35 @@ class Screen(val buffer: api.component.TextBuffer, val hasMouse: Boolean, val ha
|
||||
super.mouseReleased(mouseX, mouseY, button)
|
||||
if (hasMouse && button >= 0) {
|
||||
if (didDrag) {
|
||||
val bx = ((mouseX - x - bufferMargin) / scale / TextBufferRenderCache.renderer.charRenderWidth).toInt + 1
|
||||
val by = ((mouseY - y - bufferMargin) / scale / TextBufferRenderCache.renderer.charRenderHeight).toInt + 1
|
||||
val bx = (mouseX - x - bufferMargin) / scale / TextBufferRenderCache.renderer.charRenderWidth
|
||||
val by = (mouseY - y - bufferMargin) / scale / TextBufferRenderCache.renderer.charRenderHeight
|
||||
val bw = buffer.getWidth
|
||||
val bh = buffer.getHeight
|
||||
if (bx > 0 && by > 0 && bx <= bw && by <= bh) {
|
||||
if (bx >= 0 && by >= 0 && bx < bw && by < bh) {
|
||||
buffer.mouseUp(bx, by, button, null)
|
||||
}
|
||||
else {
|
||||
buffer.mouseUp(-1, -1, button, null)
|
||||
buffer.mouseUp(-1.0, -1.0, button, null)
|
||||
}
|
||||
}
|
||||
didDrag = false
|
||||
mx = 0
|
||||
my = 0
|
||||
mx = -1
|
||||
my = -1
|
||||
}
|
||||
}
|
||||
|
||||
private def clickOrDrag(mouseX: Int, mouseY: Int, button: Int) {
|
||||
val bx = ((mouseX - x - bufferMargin) / scale / TextBufferRenderCache.renderer.charRenderWidth).toInt + 1
|
||||
val by = ((mouseY - y - bufferMargin) / scale / TextBufferRenderCache.renderer.charRenderHeight).toInt + 1
|
||||
val bx = (mouseX - x - bufferMargin) / scale / TextBufferRenderCache.renderer.charRenderWidth
|
||||
val by = (mouseY - y - bufferMargin) / scale / TextBufferRenderCache.renderer.charRenderHeight
|
||||
val bw = buffer.getWidth
|
||||
val bh = buffer.getHeight
|
||||
if (bx > 0 && by > 0 && bx <= bw && by <= bh) {
|
||||
if (bx != mx || by != my) {
|
||||
if (mx > 0 && my > 0) buffer.mouseDrag(bx, by, button, null)
|
||||
if (bx >= 0 && by >= 0 && bx < bw && by < bh) {
|
||||
if (bx.toInt != mx || by.toInt != my) {
|
||||
if (mx >= 0 && my >= 0) buffer.mouseDrag(bx, by, button, null)
|
||||
else buffer.mouseDown(bx, by, button, null)
|
||||
didDrag = mx > 0 && my > 0
|
||||
mx = bx
|
||||
my = by
|
||||
didDrag = mx >= 0 && my >= 0
|
||||
mx = bx.toInt
|
||||
my = by.toInt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,8 @@ import net.minecraft.inventory.Slot
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
class Server(playerInventory: InventoryPlayer, serverInventory: ServerInventory) extends DynamicGuiContainer(new container.Server(playerInventory, serverInventory)) {
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) {
|
||||
super.drawGuiContainerForegroundLayer(mouseX, mouseY)
|
||||
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) {
|
||||
super.drawSecondaryForegroundLayer(mouseX, mouseY)
|
||||
fontRendererObj.drawString(
|
||||
Localization.localizeImmediately(serverInventory.getName),
|
||||
8, 6, 0x404040)
|
||||
|
@ -73,8 +73,8 @@ class ServerRack(playerInventory: InventoryPlayer, val rack: tileentity.ServerRa
|
||||
add(buttonList, switchButton)
|
||||
}
|
||||
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawGuiContainerForegroundLayer(mouseX, mouseY)
|
||||
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawSecondaryForegroundLayer(mouseX, mouseY)
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS) // Prevents NEI render glitch.
|
||||
|
||||
fontRendererObj.drawString(
|
||||
|
@ -11,8 +11,8 @@ class Switch(playerInventory: InventoryPlayer, val switch: tileentity.Switch) ex
|
||||
private val switchContainer = inventorySlots.asInstanceOf[container.Switch]
|
||||
private val format = new DecimalFormat("#.##hz")
|
||||
|
||||
override def drawGuiContainerForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawGuiContainerForegroundLayer(mouseX, mouseY)
|
||||
override def drawSecondaryForegroundLayer(mouseX: Int, mouseY: Int) = {
|
||||
super.drawSecondaryForegroundLayer(mouseX, mouseY)
|
||||
fontRendererObj.drawString(
|
||||
Localization.localizeImmediately(switch.getName),
|
||||
8, 6, 0x404040)
|
||||
|
@ -7,6 +7,7 @@ import li.cil.oc.api.Network
|
||||
import li.cil.oc.api.detail.ItemInfo
|
||||
import li.cil.oc.client.renderer.PetRenderer
|
||||
import li.cil.oc.client.{PacketSender => ClientPacketSender}
|
||||
import li.cil.oc.common.item.data.MicrocontrollerData
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
@ -45,7 +46,7 @@ object EventHandler {
|
||||
|
||||
def scheduleWirelessRedstone(rs: server.component.RedstoneWireless) {
|
||||
if (SideTracker.isServer) pending.synchronized {
|
||||
pending += (() => if (!rs.owner.isInvalid) {
|
||||
pending += (() => if (rs.node.network != null) {
|
||||
util.WirelessRedstone.addReceiver(rs)
|
||||
util.WirelessRedstone.updateOutput(rs)
|
||||
})
|
||||
@ -90,11 +91,18 @@ object EventHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
def clientLoggedIn(e: ClientConnectedToServerEvent) {
|
||||
PetRenderer.hidden.clear()
|
||||
if (Settings.get.hideOwnPet) {
|
||||
PetRenderer.hidden += Minecraft.getMinecraft.thePlayer.getName
|
||||
try {
|
||||
PetRenderer.hidden.clear()
|
||||
if (Settings.get.hideOwnPet) {
|
||||
PetRenderer.hidden += Minecraft.getMinecraft.thePlayer.getName
|
||||
}
|
||||
ClientPacketSender.sendPetVisibility()
|
||||
}
|
||||
catch {
|
||||
case _: Throwable =>
|
||||
// Reportedly, things can derp if this is called at inopportune moments,
|
||||
// such as the server shutting down.
|
||||
}
|
||||
ClientPacketSender.sendPetVisibility()
|
||||
}
|
||||
|
||||
lazy val drone = api.Items.get("drone")
|
||||
@ -116,12 +124,12 @@ object EventHandler {
|
||||
|
||||
didRecraft = recraft(e, mcu, stack => {
|
||||
// Restore EEPROM currently used in microcontroller.
|
||||
new ItemUtils.MicrocontrollerData(stack).components.find(api.Items.get(_) == eeprom)
|
||||
new MicrocontrollerData(stack).components.find(api.Items.get(_) == eeprom)
|
||||
}) || didRecraft
|
||||
|
||||
didRecraft = recraft(e, drone, stack => {
|
||||
// Restore EEPROM currently used in drone.
|
||||
new ItemUtils.MicrocontrollerData(stack).components.find(api.Items.get(_) == eeprom)
|
||||
new MicrocontrollerData(stack).components.find(api.Items.get(_) == eeprom)
|
||||
}) || didRecraft
|
||||
|
||||
// Presents?
|
||||
|
@ -40,6 +40,9 @@ object PacketType extends Enumeration {
|
||||
TextBufferMultiResolutionChange,
|
||||
TextBufferMultiMaxResolutionChange,
|
||||
TextBufferMultiSet,
|
||||
TextBufferMultiRawSetText,
|
||||
TextBufferMultiRawSetBackground,
|
||||
TextBufferMultiRawSetForeground,
|
||||
TextBufferPowerChange,
|
||||
ScreenTouchMode,
|
||||
ServerPresence,
|
||||
|
@ -1,33 +1,23 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Adapter extends SimpleBlock {
|
||||
class Adapter extends SimpleBlock with traits.GUI {
|
||||
override def guiType = GuiType.Adapter
|
||||
|
||||
override def hasTileEntity(state: IBlockState) = true
|
||||
|
||||
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Adapter()
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
if (!player.isSneaking) {
|
||||
if (!world.isRemote) {
|
||||
player.openGui(OpenComputers, GuiType.Adapter.id, world, pos.getX, pos.getY, pos.getZ)
|
||||
}
|
||||
true
|
||||
}
|
||||
else false
|
||||
}
|
||||
|
||||
override def onNeighborBlockChange(world: World, pos: BlockPos, state: IBlockState, neighborBlock: Block) =
|
||||
world.getTileEntity(pos) match {
|
||||
case adapter: tileentity.Adapter => adapter.neighborChanged()
|
||||
|
@ -1,17 +1,15 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Assembler extends SimpleBlock with traits.PowerAcceptor with traits.StateAware {
|
||||
class Assembler extends SimpleBlock with traits.PowerAcceptor with traits.StateAware with traits.GUI {
|
||||
setLightLevel(0.34f)
|
||||
|
||||
override def isOpaqueCube = false
|
||||
@ -20,23 +18,15 @@ class Assembler extends SimpleBlock with traits.PowerAcceptor with traits.StateA
|
||||
|
||||
override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.DOWN || side == EnumFacing.UP
|
||||
|
||||
override def isSideSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.DOWN || side == EnumFacing.UP
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def energyThroughput = Settings.get.assemblerRate
|
||||
|
||||
override def guiType = GuiType.Assembler
|
||||
|
||||
override def hasTileEntity(state: IBlockState) = true
|
||||
|
||||
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Assembler()
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
if (!player.isSneaking) {
|
||||
if (!world.isRemote) {
|
||||
player.openGui(OpenComputers, GuiType.Assembler.id, world, pos.getX, pos.getY, pos.getZ)
|
||||
}
|
||||
true
|
||||
}
|
||||
else false
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,9 @@ import codechicken.multipart.TFacePart
|
||||
import codechicken.multipart.TileMultipart
|
||||
import li.cil.oc.integration.fmp.CablePart
|
||||
*/
|
||||
|
||||
import li.cil.oc.api.network.Environment
|
||||
import li.cil.oc.api.network.SidedComponent
|
||||
import li.cil.oc.api.network.SidedEnvironment
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.Mods
|
||||
@ -65,6 +67,8 @@ class Cable extends SimpleBlock with traits.Extended {
|
||||
|
||||
override def shouldSideBeRendered(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = true
|
||||
|
||||
override def isSideSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def hasTileEntity(state: IBlockState) = true
|
||||
@ -142,12 +146,15 @@ object Cable {
|
||||
case host: SidedEnvironment =>
|
||||
if (host.getWorld.isRemote) host.canConnect(side)
|
||||
else host.sidedNode(side) != null
|
||||
case host: Environment with SidedComponent =>
|
||||
host.canConnectNode(side)
|
||||
case host: Environment => true
|
||||
case host if Mods.ForgeMultipart.isAvailable => hasMultiPartNode(tileEntity)
|
||||
case _ => false
|
||||
}
|
||||
|
||||
private def hasMultiPartNode(tileEntity: TileEntity) = false
|
||||
|
||||
/* TODO FMP
|
||||
tileEntity match {
|
||||
case host: TileMultipart => host.partList.exists(_.isInstanceOf[CablePart])
|
||||
@ -164,6 +171,7 @@ object Cable {
|
||||
}
|
||||
|
||||
private def cableColorFMP(tileEntity: TileEntity) = EnumDyeColor.SILVER
|
||||
|
||||
/* TODO FMP
|
||||
tileEntity match {
|
||||
case host: TileMultipart => (host.partList collect {
|
||||
@ -179,6 +187,7 @@ object Cable {
|
||||
}
|
||||
|
||||
private def canConnectFromSideFMP(tileEntity: TileEntity, side: EnumFacing) = true
|
||||
|
||||
/* TODO FMP
|
||||
tileEntity match {
|
||||
case host: TileMultipart =>
|
||||
|
@ -1,5 +1,7 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import java.util.Random
|
||||
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.state.IBlockState
|
||||
@ -8,6 +10,7 @@ import net.minecraft.world.World
|
||||
|
||||
class Capacitor extends SimpleBlock {
|
||||
setLightLevel(0.34f)
|
||||
setTickRandomly(true)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@ -17,6 +20,21 @@ class Capacitor extends SimpleBlock {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def hasComparatorInputOverride = true
|
||||
|
||||
override def getComparatorInputOverride(world: World, pos: BlockPos): Int =
|
||||
world.getTileEntity(pos) match {
|
||||
case capacitor: tileentity.Capacitor if !world.isRemote =>
|
||||
math.round(15 * capacitor.node.localBuffer / capacitor.node.localBufferSize).toInt
|
||||
case _ => 0
|
||||
}
|
||||
|
||||
override def updateTick(world: World, pos: BlockPos, state: IBlockState, rand: Random): Unit = {
|
||||
world.notifyNeighborsOfStateChange(pos, this)
|
||||
}
|
||||
|
||||
override def tickRate(world: World) = 1
|
||||
|
||||
override def onNeighborBlockChange(world: World, pos: BlockPos, state: IBlockState, neighborBlock: Block) =
|
||||
world.getTileEntity(pos) match {
|
||||
case capacitor: tileentity.Capacitor => capacitor.recomputeCapacity()
|
||||
|
@ -2,11 +2,9 @@ package li.cil.oc.common.block
|
||||
|
||||
import java.util
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.util.Wrench
|
||||
import li.cil.oc.util.Color
|
||||
import li.cil.oc.util.Rarity
|
||||
import li.cil.oc.util.Tooltip
|
||||
@ -28,7 +26,7 @@ object Case {
|
||||
final val Running = PropertyBool.create("running")
|
||||
}
|
||||
|
||||
class Case(val tier: Int) extends RedstoneAware with traits.PowerAcceptor with traits.Rotatable with traits.StateAware {
|
||||
class Case(val tier: Int) extends RedstoneAware with traits.PowerAcceptor with traits.Rotatable with traits.StateAware with traits.GUI {
|
||||
def getRunning(state: IBlockState) =
|
||||
if (state.getBlock == this)
|
||||
state.getValue(Case.Running).asInstanceOf[Boolean]
|
||||
@ -69,27 +67,21 @@ class Case(val tier: Int) extends RedstoneAware with traits.PowerAcceptor with t
|
||||
|
||||
override def energyThroughput = Settings.get.caseRate(tier)
|
||||
|
||||
override def guiType = GuiType.Case
|
||||
|
||||
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Case(tier)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
if (!player.isSneaking && !Wrench.holdsApplicableWrench(player, pos)) {
|
||||
if (!world.isRemote) {
|
||||
player.openGui(OpenComputers, GuiType.Case.id, world, pos.getX, pos.getY, pos.getZ)
|
||||
if (player.isSneaking) {
|
||||
if (!world.isRemote) world.getTileEntity(pos) match {
|
||||
case computer: tileentity.Case if !computer.machine.isRunning => computer.machine.start()
|
||||
case _ =>
|
||||
}
|
||||
true
|
||||
}
|
||||
else if (player.getCurrentEquippedItem == null) {
|
||||
if (!world.isRemote) {
|
||||
world.getTileEntity(pos) match {
|
||||
case computer: tileentity.Case if !computer.machine.isRunning => computer.machine.start()
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
else false
|
||||
else super.localOnBlockActivated(world, pos, player, side, hitX, hitY, hitZ)
|
||||
}
|
||||
|
||||
override def removedByPlayer(world: World, pos: BlockPos, player: EntityPlayer, willHarvest: Boolean) =
|
||||
|
@ -1,6 +1,5 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.tileentity
|
||||
@ -14,11 +13,13 @@ import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Charger extends RedstoneAware with traits.PowerAcceptor with traits.Rotatable with traits.StateAware {
|
||||
class Charger extends RedstoneAware with traits.PowerAcceptor with traits.Rotatable with traits.StateAware with traits.GUI {
|
||||
override protected def setDefaultExtendedState(state: IBlockState) = setDefaultState(state)
|
||||
|
||||
override def energyThroughput = Settings.get.chargerRate
|
||||
|
||||
override def guiType = GuiType.Charger
|
||||
|
||||
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Charger()
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
@ -28,26 +29,18 @@ class Charger extends RedstoneAware with traits.PowerAcceptor with traits.Rotata
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) =
|
||||
world.getTileEntity(pos) match {
|
||||
if (Wrench.holdsApplicableWrench(player, pos)) world.getTileEntity(pos) match {
|
||||
case charger: tileentity.Charger =>
|
||||
if (Wrench.holdsApplicableWrench(player, pos)) {
|
||||
if (!world.isRemote) {
|
||||
charger.invertSignal = !charger.invertSignal
|
||||
charger.chargeSpeed = 1.0 - charger.chargeSpeed
|
||||
PacketSender.sendChargerState(charger)
|
||||
Wrench.wrenchUsed(player, pos)
|
||||
}
|
||||
true
|
||||
if (!world.isRemote) {
|
||||
charger.invertSignal = !charger.invertSignal
|
||||
charger.chargeSpeed = 1.0 - charger.chargeSpeed
|
||||
PacketSender.sendChargerState(charger)
|
||||
Wrench.wrenchUsed(player, pos)
|
||||
}
|
||||
else if (!player.isSneaking) {
|
||||
if (!world.isRemote) {
|
||||
player.openGui(OpenComputers, GuiType.Charger.id, world, pos.getX, pos.getY, pos.getZ)
|
||||
}
|
||||
true
|
||||
}
|
||||
else false
|
||||
case _ => super.localOnBlockActivated(world, pos, player, side, hitX, hitY, hitZ)
|
||||
true
|
||||
case _ => false
|
||||
}
|
||||
else super.localOnBlockActivated(world, pos, player, side, hitX, hitY, hitZ)
|
||||
|
||||
override def onNeighborBlockChange(world: World, pos: BlockPos, state: IBlockState, neighborBlock: Block) {
|
||||
world.getTileEntity(pos) match {
|
||||
|
@ -1,6 +1,5 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.tileentity
|
||||
@ -8,11 +7,9 @@ import li.cil.oc.util.Tooltip
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Disassembler extends SimpleBlock with traits.PowerAcceptor with traits.StateAware {
|
||||
class Disassembler extends SimpleBlock with traits.PowerAcceptor with traits.StateAware with traits.GUI {
|
||||
override protected def tooltipBody(metadata: Int, stack: ItemStack, player: EntityPlayer, tooltip: java.util.List[String], advanced: Boolean) {
|
||||
tooltip.addAll(Tooltip.get(getClass.getSimpleName, (Settings.get.disassemblerBreakChance * 100).toInt.toString))
|
||||
}
|
||||
@ -21,19 +18,9 @@ class Disassembler extends SimpleBlock with traits.PowerAcceptor with traits.Sta
|
||||
|
||||
override def energyThroughput = Settings.get.disassemblerRate
|
||||
|
||||
override def guiType = GuiType.Disassembler
|
||||
|
||||
override def hasTileEntity(state: IBlockState) = true
|
||||
|
||||
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Disassembler()
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
if (!player.isSneaking) {
|
||||
if (!world.isRemote) {
|
||||
player.openGui(OpenComputers, GuiType.Disassembler.id, world, pos.getX, pos.getY, pos.getZ)
|
||||
}
|
||||
true
|
||||
}
|
||||
else false
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.Mods
|
||||
@ -12,7 +11,7 @@ import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.world.World
|
||||
|
||||
class DiskDrive extends SimpleBlock with traits.Rotatable {
|
||||
class DiskDrive extends SimpleBlock with traits.Rotatable with traits.GUI {
|
||||
override protected def setDefaultExtendedState(state: IBlockState) = setDefaultState(state)
|
||||
|
||||
override protected def tooltipTail(metadata: Int, stack: ItemStack, player: EntityPlayer, tooltip: java.util.List[String], advanced: Boolean) {
|
||||
@ -24,6 +23,8 @@ class DiskDrive extends SimpleBlock with traits.Rotatable {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def guiType = GuiType.DiskDrive
|
||||
|
||||
override def hasTileEntity(state: IBlockState) = true
|
||||
|
||||
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.DiskDrive()
|
||||
@ -41,30 +42,23 @@ class DiskDrive extends SimpleBlock with traits.Rotatable {
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
world.getTileEntity(pos) match {
|
||||
// Behavior: sneaking -> Insert[+Eject], not sneaking -> GUI.
|
||||
if (player.isSneaking) world.getTileEntity(pos) match {
|
||||
case drive: tileentity.DiskDrive =>
|
||||
// Behavior: sneaking -> Insert[+Eject], not sneaking -> GUI.
|
||||
if (!player.isSneaking) {
|
||||
val isDiskInDrive = drive.getStackInSlot(0) != null
|
||||
val isHoldingDisk = drive.isItemValidForSlot(0, player.getCurrentEquippedItem)
|
||||
if (isDiskInDrive) {
|
||||
if (!world.isRemote) {
|
||||
player.openGui(OpenComputers, GuiType.DiskDrive.id, world, pos.getX, pos.getY, pos.getZ)
|
||||
drive.dropSlot(0, 1, Option(drive.facing))
|
||||
}
|
||||
true
|
||||
}
|
||||
else {
|
||||
val isDiskInDrive = drive.getStackInSlot(0) != null
|
||||
val isHoldingDisk = drive.isItemValidForSlot(0, player.getCurrentEquippedItem)
|
||||
if (isDiskInDrive) {
|
||||
if (!world.isRemote) {
|
||||
drive.dropSlot(0, 1, Option(drive.facing))
|
||||
}
|
||||
}
|
||||
if (isHoldingDisk) {
|
||||
// Insert the disk.
|
||||
drive.setInventorySlotContents(0, player.inventory.decrStackSize(player.inventory.currentItem, 1))
|
||||
}
|
||||
isDiskInDrive || isHoldingDisk
|
||||
if (isHoldingDisk) {
|
||||
// Insert the disk.
|
||||
drive.setInventorySlotContents(0, player.inventory.decrStackSize(player.inventory.currentItem, 1))
|
||||
}
|
||||
isDiskInDrive || isHoldingDisk
|
||||
case _ => false
|
||||
}
|
||||
else super.localOnBlockActivated(world, pos, player, side, hitX, hitY, hitZ)
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,8 @@ class Hologram(val tier: Int) extends SimpleBlock {
|
||||
super.shouldSideBeRendered(world, pos, side) || side == EnumFacing.UP
|
||||
}
|
||||
|
||||
override def isSideSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.DOWN
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def rarity(stack: ItemStack) = Rarity.byTier(tier)
|
||||
|
@ -5,6 +5,7 @@ import java.util
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.client.KeyBindings
|
||||
import li.cil.oc.common.item.data.RobotData
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.util.Color
|
||||
import li.cil.oc.util.ItemCosts
|
||||
@ -83,7 +84,7 @@ class Item(value: Block) extends ItemBlock(value) {
|
||||
// manually before it's placed to ensure different component addresses
|
||||
// in the different robots, to avoid interference of screens e.g.
|
||||
val needsCopying = player.capabilities.isCreativeMode && api.Items.get(stack) == api.Items.get("robot")
|
||||
val stackToUse = if (needsCopying) new ItemUtils.RobotData(stack).copyItemStack() else stack
|
||||
val stackToUse = if (needsCopying) new RobotData(stack).copyItemStack() else stack
|
||||
if (super.placeBlockAt(stackToUse, player, world, pos, side, hitX, hitY, hitZ, newState)) {
|
||||
// If it's a rotatable block try to make it face the player.
|
||||
world.getTileEntity(pos) match {
|
||||
|
@ -5,13 +5,12 @@ import java.util
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.client.KeyBindings
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.item.data.MicrocontrollerData
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.util.NEI
|
||||
import li.cil.oc.integration.util.Wrench
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import li.cil.oc.util.Rarity
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.entity.EntityLivingBase
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
@ -19,10 +18,11 @@ import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.util.MovingObjectPosition
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Microcontroller extends RedstoneAware with traits.PowerAcceptor with traits.Rotatable with traits.StateAware {
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
class Microcontroller(protected implicit val tileTag: ClassTag[tileentity.Microcontroller]) extends RedstoneAware with traits.PowerAcceptor with traits.Rotatable with traits.StateAware with traits.CustomDrops[tileentity.Microcontroller] {
|
||||
setCreativeTab(null)
|
||||
NEI.hide(this)
|
||||
|
||||
@ -36,17 +36,12 @@ class Microcontroller extends RedstoneAware with traits.PowerAcceptor with trait
|
||||
case _ => null
|
||||
}
|
||||
|
||||
// Custom drop logic for NBT tagged item stack.
|
||||
override def getDrops(world: IBlockAccess, pos: BlockPos, state: IBlockState, fortune: Int) = new java.util.ArrayList[ItemStack]()
|
||||
|
||||
override def onBlockHarvested(worldIn: World, pos: BlockPos, state: IBlockState, player: EntityPlayer) {}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override protected def tooltipTail(metadata: Int, stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) {
|
||||
super.tooltipTail(metadata, stack, player, tooltip, advanced)
|
||||
if (KeyBindings.showExtendedTooltips) {
|
||||
val info = new ItemUtils.MicrocontrollerData(stack)
|
||||
val info = new MicrocontrollerData(stack)
|
||||
for (component <- info.components) {
|
||||
tooltip.add("- " + component.getDisplayName)
|
||||
}
|
||||
@ -54,7 +49,7 @@ class Microcontroller extends RedstoneAware with traits.PowerAcceptor with trait
|
||||
}
|
||||
|
||||
override def rarity(stack: ItemStack) = {
|
||||
val data = new ItemUtils.MicrocontrollerData(stack)
|
||||
val data = new MicrocontrollerData(stack)
|
||||
Rarity.byTier(data.tier)
|
||||
}
|
||||
|
||||
@ -81,26 +76,16 @@ class Microcontroller extends RedstoneAware with traits.PowerAcceptor with trait
|
||||
else false
|
||||
}
|
||||
|
||||
override def onBlockPlacedBy(world: World, pos: BlockPos, state: IBlockState, placer: EntityLivingBase, stack: ItemStack) {
|
||||
super.onBlockPlacedBy(world, pos, state, placer, stack)
|
||||
if (!world.isRemote) world.getTileEntity(pos) match {
|
||||
case mcu: tileentity.Microcontroller =>
|
||||
mcu.info.load(stack)
|
||||
mcu.snooperNode.changeBuffer(mcu.info.storedEnergy - mcu.snooperNode.localBuffer)
|
||||
case _ =>
|
||||
}
|
||||
override protected def doCustomInit(tileEntity: tileentity.Microcontroller, player: EntityLivingBase, stack: ItemStack): Unit = {
|
||||
super.doCustomInit(tileEntity, player, stack)
|
||||
tileEntity.info.load(stack)
|
||||
tileEntity.snooperNode.changeBuffer(tileEntity.info.storedEnergy - tileEntity.snooperNode.localBuffer)
|
||||
}
|
||||
|
||||
override def removedByPlayer(world: World, pos: BlockPos, player: EntityPlayer, willHarvest: Boolean) = {
|
||||
if (!world.isRemote) {
|
||||
world.getTileEntity(pos) match {
|
||||
case mcu: tileentity.Microcontroller =>
|
||||
mcu.saveComponents()
|
||||
mcu.info.storedEnergy = mcu.snooperNode.localBuffer.toInt
|
||||
InventoryUtils.spawnStackInWorld(BlockPosition(pos, world), mcu.info.createItemStack())
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
super.removedByPlayer(world, pos, player, willHarvest)
|
||||
override protected def doCustomDrops(tileEntity: tileentity.Microcontroller, player: EntityPlayer, willHarvest: Boolean): Unit = {
|
||||
super.doCustomDrops(tileEntity, player, willHarvest)
|
||||
tileEntity.saveComponents()
|
||||
tileEntity.info.storedEnergy = tileEntity.snooperNode.localBuffer.toInt
|
||||
Block.spawnAsEntity(tileEntity.world, tileEntity.getPos, tileEntity.info.createItemStack())
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,40 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import java.util
|
||||
|
||||
import li.cil.oc.client.KeyBindings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.item.data.RaidData
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.entity.EntityLivingBase
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Raid extends SimpleBlock with traits.Rotatable {
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
class Raid(protected implicit val tileTag: ClassTag[tileentity.Raid]) extends SimpleBlock with traits.Rotatable with traits.GUI with traits.CustomDrops[tileentity.Raid] {
|
||||
override protected def setDefaultExtendedState(state: IBlockState) = setDefaultState(state)
|
||||
|
||||
override def hasTileEntity(state: IBlockState) = true
|
||||
|
||||
override protected def tooltipTail(metadata: Int, stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) {
|
||||
super.tooltipTail(metadata, stack, player, tooltip, advanced)
|
||||
if (KeyBindings.showExtendedTooltips) {
|
||||
val data = new RaidData(stack)
|
||||
for (disk <- data.disks) {
|
||||
tooltip.add("- " + disk.getDisplayName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def guiType = GuiType.Raid
|
||||
|
||||
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Raid()
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
@ -26,16 +47,27 @@ class Raid extends SimpleBlock with traits.Rotatable {
|
||||
case _ => 0
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
world.getTileEntity(pos) match {
|
||||
case drive: tileentity.Raid if !player.isSneaking =>
|
||||
if (!world.isRemote) {
|
||||
player.openGui(OpenComputers, GuiType.Raid.id, world, pos.getX, pos.getY, pos.getZ)
|
||||
}
|
||||
true
|
||||
case _ => false
|
||||
override protected def doCustomInit(tileEntity: tileentity.Raid, player: EntityLivingBase, stack: ItemStack): Unit = {
|
||||
super.doCustomInit(tileEntity, player, stack)
|
||||
val data = new RaidData(stack)
|
||||
for (i <- 0 until math.min(data.disks.length, tileEntity.getSizeInventory)) {
|
||||
tileEntity.setInventorySlotContents(i, data.disks(i))
|
||||
}
|
||||
data.label.foreach(tileEntity.label.setLabel)
|
||||
if (!data.filesystem.hasNoTags) {
|
||||
tileEntity.tryCreateRaid(data.filesystem.getCompoundTag("node").getString("address"))
|
||||
tileEntity.filesystem.foreach(_.load(data.filesystem))
|
||||
}
|
||||
}
|
||||
|
||||
override protected def doCustomDrops(tileEntity: tileentity.Raid, player: EntityPlayer, willHarvest: Boolean): Unit = {
|
||||
super.doCustomDrops(tileEntity, player, willHarvest)
|
||||
val stack = createItemStack()
|
||||
val data = new RaidData()
|
||||
data.disks = tileEntity.items.map(_.orNull)
|
||||
tileEntity.filesystem.foreach(_.save(data.filesystem))
|
||||
data.label = Option(tileEntity.label.getLabel)
|
||||
data.save(stack)
|
||||
Block.spawnAsEntity(tileEntity.world, tileEntity.getPos, stack)
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ import java.util.Random
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.common.item.data.RobotData
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.util.NEI
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import li.cil.oc.util.Rarity
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
@ -30,6 +30,8 @@ class RobotAfterimage extends SimpleBlock {
|
||||
|
||||
override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false
|
||||
|
||||
override def isSideSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false
|
||||
|
||||
override def getPickBlock(target: MovingObjectPosition, world: World, pos: BlockPos) =
|
||||
findMovingRobot(world, pos) match {
|
||||
case Some(robot) => robot.info.createItemStack()
|
||||
@ -43,7 +45,7 @@ class RobotAfterimage extends SimpleBlock {
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def rarity(stack: ItemStack) = {
|
||||
val data = new ItemUtils.RobotData(stack)
|
||||
val data = new RobotData(stack)
|
||||
Rarity.byTier(data.tier)
|
||||
}
|
||||
|
||||
|
@ -7,13 +7,13 @@ import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.client.KeyBindings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.item.data.RobotData
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.util.NEI
|
||||
import li.cil.oc.server.PacketSender
|
||||
import li.cil.oc.server.component.robot
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import li.cil.oc.util.Rarity
|
||||
import li.cil.oc.util.Tooltip
|
||||
import net.minecraft.block.state.IBlockState
|
||||
@ -46,6 +46,8 @@ class RobotProxy extends RedstoneAware with traits.StateAware {
|
||||
|
||||
override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false
|
||||
|
||||
override def isSideSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = false
|
||||
|
||||
override def getPickBlock(target: MovingObjectPosition, world: World, pos: BlockPos) =
|
||||
world.getTileEntity(pos) match {
|
||||
case proxy: tileentity.RobotProxy => proxy.robot.info.copyItemStack()
|
||||
@ -55,7 +57,7 @@ class RobotProxy extends RedstoneAware with traits.StateAware {
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def rarity(stack: ItemStack) = {
|
||||
val data = new ItemUtils.RobotData(stack)
|
||||
val data = new RobotData(stack)
|
||||
Rarity.byTier(data.tier)
|
||||
}
|
||||
|
||||
@ -71,7 +73,7 @@ class RobotProxy extends RedstoneAware with traits.StateAware {
|
||||
override protected def tooltipTail(metadata: Int, stack: ItemStack, player: EntityPlayer, tooltip: util.List[String], advanced: Boolean) {
|
||||
super.tooltipTail(metadata, stack, player, tooltip, advanced)
|
||||
if (KeyBindings.showExtendedTooltips) {
|
||||
val info = new ItemUtils.RobotData(stack)
|
||||
val info = new RobotData(stack)
|
||||
val components = info.containers ++ info.components
|
||||
if (components.length > 0) {
|
||||
tooltip.addAll(Tooltip.get("Server.Components"))
|
||||
|
@ -36,6 +36,8 @@ object Screen {
|
||||
class Screen(val tier: Int) extends RedstoneAware with traits.OmniRotatable {
|
||||
setLightLevel(0.34f)
|
||||
|
||||
override def isSideSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = toLocal(world, pos, side) != EnumFacing.SOUTH
|
||||
|
||||
override protected def setDefaultExtendedState(state: IBlockState) = setDefaultState(state)
|
||||
|
||||
override protected def addExtendedState(state: IBlockState, world: IBlockAccess, pos: BlockPos) =
|
||||
@ -83,8 +85,9 @@ class Screen(val tier: Int) extends RedstoneAware with traits.OmniRotatable {
|
||||
|
||||
override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = rightClick(world, pos, player, side, hitX, hitY, hitZ, force = false)
|
||||
|
||||
def rightClick(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float, force: Boolean) =
|
||||
if (Wrench.holdsApplicableWrench(player, pos)) false
|
||||
def rightClick(world: World, pos: BlockPos, player: EntityPlayer,
|
||||
side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float, force: Boolean) = {
|
||||
if (Wrench.holdsApplicableWrench(player, pos) && getValidRotations(world, pos).contains(side) && !force) false
|
||||
else world.getTileEntity(pos) match {
|
||||
case screen: tileentity.Screen if screen.hasKeyboard && (force || player.isSneaking == screen.invertTouchMode) =>
|
||||
// Yep, this GUI is actually purely client side. We could skip this
|
||||
@ -98,6 +101,7 @@ class Screen(val tier: Int) extends RedstoneAware with traits.OmniRotatable {
|
||||
screen.click(player, hitX, hitY, hitZ)
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
override def onEntityCollidedWithBlock(world: World, pos: BlockPos, entity: Entity) =
|
||||
if (world.isRemote) (entity, world.getTileEntity(pos)) match {
|
||||
|
@ -1,11 +1,9 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.world.IBlockAccess
|
||||
@ -13,7 +11,7 @@ import net.minecraft.world.World
|
||||
import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
|
||||
class ServerRack extends RedstoneAware with traits.PowerAcceptor with traits.Rotatable with traits.StateAware {
|
||||
class ServerRack extends RedstoneAware with traits.PowerAcceptor with traits.Rotatable with traits.StateAware with traits.GUI {
|
||||
override protected def setDefaultExtendedState(state: IBlockState) = setDefaultState(state)
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@ -31,23 +29,15 @@ class ServerRack extends RedstoneAware with traits.PowerAcceptor with traits.Rot
|
||||
|
||||
override def isBlockSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = side == EnumFacing.SOUTH
|
||||
|
||||
override def isSideSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = toLocal(world, pos, side) != EnumFacing.SOUTH
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def energyThroughput = Settings.get.serverRackRate
|
||||
|
||||
override def guiType = GuiType.Rack
|
||||
|
||||
override def hasTileEntity(state: IBlockState) = true
|
||||
|
||||
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.ServerRack()
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
if (!player.isSneaking) {
|
||||
if (!world.isRemote) {
|
||||
player.openGui(OpenComputers, GuiType.Rack.id, world, pos.getX, pos.getY, pos.getZ)
|
||||
}
|
||||
true
|
||||
}
|
||||
else false
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ abstract class SimpleBlock(material: Material = Material.iron) extends BlockCont
|
||||
// Block
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def isNormalCube(world: IBlockAccess, pos: BlockPos) = true
|
||||
override def isSideSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = true
|
||||
|
||||
override def canHarvestBlock(world: IBlockAccess, pos: BlockPos, player: EntityPlayer) = true
|
||||
|
||||
|
@ -1,31 +1,14 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Switch extends SimpleBlock {
|
||||
class Switch extends SimpleBlock with traits.GUI {
|
||||
override def guiType = GuiType.Switch
|
||||
|
||||
override def hasTileEntity(state: IBlockState) = true
|
||||
|
||||
override def createNewTileEntity(world: World, metadata: Int) = new tileentity.Switch()
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = {
|
||||
world.getTileEntity(pos) match {
|
||||
case switch: tileentity.Switch =>
|
||||
if (!player.isSneaking) {
|
||||
if (!world.isRemote) {
|
||||
player.openGui(OpenComputers, GuiType.Switch.id, world, pos.getX, pos.getY, pos.getZ)
|
||||
}
|
||||
true
|
||||
}
|
||||
else false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
package li.cil.oc.common.block.traits
|
||||
|
||||
import java.util
|
||||
|
||||
import li.cil.oc.common.block.SimpleBlock
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.entity.EntityLivingBase
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.world.IBlockAccess
|
||||
import net.minecraft.world.World
|
||||
|
||||
import scala.reflect.ClassTag
|
||||
|
||||
trait CustomDrops[Tile <: TileEntity] extends SimpleBlock {
|
||||
protected def tileTag: ClassTag[Tile]
|
||||
|
||||
override def getDrops(world: IBlockAccess, pos: BlockPos, state: IBlockState, fortune: Int): util.List[ItemStack] = new java.util.ArrayList[ItemStack]()
|
||||
|
||||
override def breakBlock(world: World, pos: BlockPos, state: IBlockState): Unit = {}
|
||||
|
||||
|
||||
override def removedByPlayer(world: World, pos: BlockPos, player: EntityPlayer, willHarvest: Boolean): Boolean = {
|
||||
if (!world.isRemote) {
|
||||
val matcher = tileTag
|
||||
world.getTileEntity(pos) match {
|
||||
case matcher(tileEntity) => doCustomDrops(tileEntity, player, willHarvest)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
super.removedByPlayer(world, pos, player, willHarvest)
|
||||
}
|
||||
|
||||
override def onBlockPlacedBy(world: World, pos: BlockPos, state: IBlockState, placer: EntityLivingBase, stack: ItemStack): Unit = {
|
||||
super.onBlockPlacedBy(world, pos, state, placer, stack)
|
||||
if (!world.isRemote) {
|
||||
val matcher = tileTag
|
||||
world.getTileEntity(pos) match {
|
||||
case matcher(tileEntity) => doCustomInit(tileEntity, placer, stack)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected def doCustomInit(tileEntity: Tile, player: EntityLivingBase, stack: ItemStack): Unit = {}
|
||||
|
||||
protected def doCustomDrops(tileEntity: Tile, player: EntityPlayer, willHarvest: Boolean): Unit = {}
|
||||
}
|
24
src/main/scala/li/cil/oc/common/block/traits/GUI.scala
Normal file
24
src/main/scala/li/cil/oc/common/block/traits/GUI.scala
Normal file
@ -0,0 +1,24 @@
|
||||
package li.cil.oc.common.block.traits
|
||||
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.block.SimpleBlock
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.world.World
|
||||
|
||||
trait GUI extends SimpleBlock {
|
||||
def guiType: GuiType.EnumVal
|
||||
|
||||
override def localOnBlockActivated(world: World, pos: BlockPos, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
|
||||
if (!player.isSneaking) {
|
||||
if (!world.isRemote) {
|
||||
player.openGui(OpenComputers, guiType.id, world, pos.getX, pos.getY, pos.getZ)
|
||||
}
|
||||
true
|
||||
}
|
||||
else super.localOnBlockActivated(world, pos, player, side, hitX, hitY, hitZ)
|
||||
}
|
||||
}
|
@ -41,14 +41,16 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
withConnector().
|
||||
create()
|
||||
|
||||
private var maxResolution = Settings.screenResolutionsByTier(0)
|
||||
private var maxResolution = Settings.screenResolutionsByTier(Tier.One)
|
||||
|
||||
private var maxDepth = Settings.screenDepthsByTier(0)
|
||||
private var maxDepth = Settings.screenDepthsByTier(Tier.One)
|
||||
|
||||
private var aspectRatio = (1.0, 1.0)
|
||||
|
||||
private var powerConsumptionPerTick = Settings.get.screenCost
|
||||
|
||||
private var precisionMode = false
|
||||
|
||||
// For client side only.
|
||||
private var isRendering = true
|
||||
|
||||
@ -162,6 +164,21 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
}
|
||||
}
|
||||
|
||||
@Callback(direct = true, doc = """function():boolean -- Returns whether the screen is in high precision mode (sub-pixel mouse event positions).""")
|
||||
def isPrecise(computer: Context, args: Arguments): Array[AnyRef] = result(precisionMode)
|
||||
|
||||
@Callback(doc = """function(enabled:boolean):boolean -- Set whether to use high precision mode (sub-pixel mouse event positions).""")
|
||||
def setPrecise(computer: Context, args: Arguments): Array[AnyRef] = {
|
||||
// Available for T3 screens only... easiest way to check for us is to
|
||||
// base it off of the maximum color depth.
|
||||
if (maxDepth == Settings.screenDepthsByTier(Tier.Three)) {
|
||||
val oldValue = precisionMode
|
||||
precisionMode = args.checkBoolean(0)
|
||||
result(oldValue)
|
||||
}
|
||||
else result(Unit, "unsupported operation")
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def setEnergyCostPerTick(value: Double) {
|
||||
@ -189,7 +206,7 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
if (height < 1) throw new IllegalArgumentException("height must be larger or equal to one")
|
||||
maxResolution = (width, height)
|
||||
fullyLitCost = computeFullyLitCost()
|
||||
proxy.onScreenMaxResolutionChange(width, width)
|
||||
proxy.onBufferMaxResolutionChange(width, width)
|
||||
}
|
||||
|
||||
override def getMaximumWidth = maxResolution._1
|
||||
@ -205,7 +222,7 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
if (w < 1 || h < 1 || w > mw || h > mw || h * w > mw * mh)
|
||||
throw new IllegalArgumentException("unsupported resolution")
|
||||
// Always send to clients, their state might be dirty.
|
||||
proxy.onScreenResolutionChange(w, h)
|
||||
proxy.onBufferResolutionChange(w, h)
|
||||
if (data.size = (w, h)) {
|
||||
if (node != null) {
|
||||
node.sendToReachable("computer.signal", "screen_resized", Int.box(w), Int.box(h))
|
||||
@ -227,7 +244,7 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
if (depth.ordinal > maxDepth.ordinal)
|
||||
throw new IllegalArgumentException("unsupported depth")
|
||||
// Always send to clients, their state might be dirty.
|
||||
proxy.onScreenDepthChange(depth)
|
||||
proxy.onBufferDepthChange(depth)
|
||||
data.format = PackedColor.Depth.format(depth)
|
||||
}
|
||||
|
||||
@ -236,7 +253,7 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
override def setPaletteColor(index: Int, color: Int) = data.format match {
|
||||
case palette: PackedColor.MutablePaletteFormat =>
|
||||
palette(index) = color
|
||||
proxy.onScreenPaletteChange(index)
|
||||
proxy.onBufferPaletteChange(index)
|
||||
case _ => throw new Exception("palette not available")
|
||||
}
|
||||
|
||||
@ -251,7 +268,7 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
val value = PackedColor.Color(color, isFromPalette)
|
||||
if (data.foreground != value) {
|
||||
data.foreground = value
|
||||
proxy.onScreenColorChange()
|
||||
proxy.onBufferColorChange()
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,7 +282,7 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
val value = PackedColor.Color(color, isFromPalette)
|
||||
if (data.background != value) {
|
||||
data.background = value
|
||||
proxy.onScreenColorChange()
|
||||
proxy.onBufferColorChange()
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,27 +292,28 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
|
||||
def copy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) =
|
||||
if (data.copy(col, row, w, h, tx, ty))
|
||||
proxy.onScreenCopy(col, row, w, h, tx, ty)
|
||||
proxy.onBufferCopy(col, row, w, h, tx, ty)
|
||||
|
||||
def fill(col: Int, row: Int, w: Int, h: Int, c: Char) =
|
||||
if (data.fill(col, row, w, h, c))
|
||||
proxy.onScreenFill(col, row, w, h, c)
|
||||
proxy.onBufferFill(col, row, w, h, c)
|
||||
|
||||
def set(col: Int, row: Int, s: String, vertical: Boolean) = if (col < data.width && (col >= 0 || -col < s.length)) {
|
||||
// Make sure the string isn't longer than it needs to be, in particular to
|
||||
// avoid sending too much data to our clients.
|
||||
val (x, y, truncated) =
|
||||
if (vertical) {
|
||||
if (row < 0) (col, 0, s.substring(-row))
|
||||
else (col, row, s.substring(0, math.min(s.length, data.height - row)))
|
||||
}
|
||||
else {
|
||||
if (col < 0) (0, row, s.substring(-col))
|
||||
else (col, row, s.substring(0, math.min(s.length, data.width - col)))
|
||||
}
|
||||
if (data.set(x, y, truncated, vertical))
|
||||
proxy.onScreenSet(x, row, truncated, vertical)
|
||||
}
|
||||
def set(col: Int, row: Int, s: String, vertical: Boolean): Unit =
|
||||
if (col < data.width && (col >= 0 || -col < s.length)) {
|
||||
// Make sure the string isn't longer than it needs to be, in particular to
|
||||
// avoid sending too much data to our clients.
|
||||
val (x, y, truncated) =
|
||||
if (vertical) {
|
||||
if (row < 0) (col, 0, s.substring(-row))
|
||||
else (col, row, s.substring(0, math.min(s.length, data.height - row)))
|
||||
}
|
||||
else {
|
||||
if (col < 0) (0, row, s.substring(-col))
|
||||
else (col, row, s.substring(0, math.min(s.length, data.width - col)))
|
||||
}
|
||||
if (data.set(x, y, truncated, vertical))
|
||||
proxy.onBufferSet(x, row, truncated, vertical)
|
||||
}
|
||||
|
||||
def get(col: Int, row: Int) = data.get(col, row)
|
||||
|
||||
@ -321,6 +339,40 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
override def isBackgroundFromPalette(column: Int, row: Int) =
|
||||
data.format.isFromPalette(PackedColor.extractBackground(color(column, row)))
|
||||
|
||||
override def rawSetText(col: Int, row: Int, text: Array[Array[Char]]): Unit = {
|
||||
for (y <- row until ((row + text.length) min data.height)) {
|
||||
val line = text(y - row)
|
||||
Array.copy(line, 0, data.buffer(y), col, line.length min data.width)
|
||||
}
|
||||
proxy.onBufferRawSetText(col, row, text)
|
||||
}
|
||||
|
||||
override def rawSetBackground(col: Int, row: Int, color: Array[Array[Int]]): Unit = {
|
||||
for (y <- row until ((row + color.length) min data.height)) {
|
||||
val line = color(y - row)
|
||||
for (x <- col until ((col + line.length) min data.width)) {
|
||||
val packedBackground = data.color(row)(col) & 0x00FF
|
||||
val packedForeground = (data.format.deflate(PackedColor.Color(line(x - col))) << PackedColor.ForegroundShift) & 0xFF00
|
||||
data.color(row)(col) = (packedForeground | packedBackground).toShort
|
||||
}
|
||||
}
|
||||
// TODO Better for bandwidth to send packed shorts here. Would need a special case for handling on client, though...
|
||||
proxy.onBufferRawSetBackground(col, row, color)
|
||||
}
|
||||
|
||||
override def rawSetForeground(col: Int, row: Int, color: Array[Array[Int]]): Unit = {
|
||||
for (y <- row until ((row + color.length) min data.height)) {
|
||||
val line = color(y - row)
|
||||
for (x <- col until ((col + line.length) min data.width)) {
|
||||
val packedBackground = data.format.deflate(PackedColor.Color(line(x - col))) & 0x00FF
|
||||
val packedForeground = data.color(row)(col) & 0xFF00
|
||||
data.color(row)(col) = (packedForeground | packedBackground).toShort
|
||||
}
|
||||
}
|
||||
// TODO Better for bandwidth to send packed shorts here. Would need a special case for handling on client, though...
|
||||
proxy.onBufferRawSetForeground(col, row, color)
|
||||
}
|
||||
|
||||
private def color(column: Int, row: Int) = {
|
||||
if (column < 0 || column >= getWidth || row < 0 || row >= getHeight)
|
||||
throw new IndexOutOfBoundsException()
|
||||
@ -351,16 +403,16 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
override def clipboard(value: String, player: EntityPlayer) =
|
||||
proxy.clipboard(value, player)
|
||||
|
||||
override def mouseDown(x: Int, y: Int, button: Int, player: EntityPlayer) =
|
||||
override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer) =
|
||||
proxy.mouseDown(x, y, button, player)
|
||||
|
||||
override def mouseDrag(x: Int, y: Int, button: Int, player: EntityPlayer) =
|
||||
override def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer) =
|
||||
proxy.mouseDrag(x, y, button, player)
|
||||
|
||||
override def mouseUp(x: Int, y: Int, button: Int, player: EntityPlayer) =
|
||||
override def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer) =
|
||||
proxy.mouseUp(x, y, button, player)
|
||||
|
||||
override def mouseScroll(x: Int, y: Int, delta: Int, player: EntityPlayer) =
|
||||
override def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer) =
|
||||
proxy.mouseScroll(x, y, delta, player)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
@ -403,6 +455,12 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
if (nbt.hasKey(Settings.namespace + "hasPower")) {
|
||||
hasPower = nbt.getBoolean(Settings.namespace + "hasPower")
|
||||
}
|
||||
if (nbt.hasKey(Settings.namespace + "maxWidth") && nbt.hasKey(Settings.namespace + "maxHeight")) {
|
||||
val maxWidth = nbt.getInteger(Settings.namespace + "maxWidth")
|
||||
val maxHeight = nbt.getInteger(Settings.namespace + "maxHeight")
|
||||
maxResolution = (maxWidth, maxHeight)
|
||||
}
|
||||
precisionMode = nbt.getBoolean(Settings.namespace + "precise")
|
||||
}
|
||||
|
||||
// Null check for Waila (and other mods that may call this client side).
|
||||
@ -428,6 +486,9 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
SaveHandler.scheduleSave(host, nbt, node.address + "_buffer", data.save _)
|
||||
nbt.setBoolean(Settings.namespace + "isOn", isDisplaying)
|
||||
nbt.setBoolean(Settings.namespace + "hasPower", hasPower)
|
||||
nbt.setInteger(Settings.namespace + "maxWidth", maxResolution._1)
|
||||
nbt.setInteger(Settings.namespace + "maxHeight", maxResolution._2)
|
||||
nbt.setBoolean(Settings.namespace + "precise", precisionMode)
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,28 +538,40 @@ object TextBuffer {
|
||||
|
||||
def render() = false
|
||||
|
||||
def onScreenColorChange(): Unit
|
||||
def onBufferColorChange(): Unit
|
||||
|
||||
def onScreenCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
|
||||
def onBufferCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
|
||||
owner.relativeLitArea = -1
|
||||
}
|
||||
|
||||
def onScreenDepthChange(depth: ColorDepth): Unit
|
||||
def onBufferDepthChange(depth: ColorDepth): Unit
|
||||
|
||||
def onScreenFill(col: Int, row: Int, w: Int, h: Int, c: Char) {
|
||||
def onBufferFill(col: Int, row: Int, w: Int, h: Int, c: Char) {
|
||||
owner.relativeLitArea = -1
|
||||
}
|
||||
|
||||
def onScreenPaletteChange(index: Int): Unit
|
||||
def onBufferPaletteChange(index: Int): Unit
|
||||
|
||||
def onScreenResolutionChange(w: Int, h: Int) {
|
||||
def onBufferResolutionChange(w: Int, h: Int) {
|
||||
owner.relativeLitArea = -1
|
||||
}
|
||||
|
||||
def onScreenMaxResolutionChange(w: Int, h: Int) {
|
||||
def onBufferMaxResolutionChange(w: Int, h: Int) {
|
||||
}
|
||||
|
||||
def onScreenSet(col: Int, row: Int, s: String, vertical: Boolean) {
|
||||
def onBufferSet(col: Int, row: Int, s: String, vertical: Boolean) {
|
||||
owner.relativeLitArea = -1
|
||||
}
|
||||
|
||||
def onBufferRawSetText(col: Int, row: Int, text: Array[Array[Char]]) {
|
||||
owner.relativeLitArea = -1
|
||||
}
|
||||
|
||||
def onBufferRawSetBackground(col: Int, row: Int, color: Array[Array[Int]]) {
|
||||
owner.relativeLitArea = -1
|
||||
}
|
||||
|
||||
def onBufferRawSetForeground(col: Int, row: Int, color: Array[Array[Int]]) {
|
||||
owner.relativeLitArea = -1
|
||||
}
|
||||
|
||||
@ -508,13 +581,13 @@ object TextBuffer {
|
||||
|
||||
def clipboard(value: String, player: EntityPlayer): Unit
|
||||
|
||||
def mouseDown(x: Int, y: Int, button: Int, player: EntityPlayer): Unit
|
||||
def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer): Unit
|
||||
|
||||
def mouseDrag(x: Int, y: Int, button: Int, player: EntityPlayer): Unit
|
||||
def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer): Unit
|
||||
|
||||
def mouseUp(x: Int, y: Int, button: Int, player: EntityPlayer): Unit
|
||||
def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer): Unit
|
||||
|
||||
def mouseScroll(x: Int, y: Int, delta: Int, player: EntityPlayer): Unit
|
||||
def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer): Unit
|
||||
}
|
||||
|
||||
class ClientProxy(val owner: TextBuffer) extends Proxy {
|
||||
@ -532,35 +605,35 @@ object TextBuffer {
|
||||
wasDirty
|
||||
}
|
||||
|
||||
override def onScreenColorChange() {
|
||||
override def onBufferColorChange() {
|
||||
markDirty()
|
||||
}
|
||||
|
||||
override def onScreenCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
|
||||
super.onScreenCopy(col, row, w, h, tx, ty)
|
||||
override def onBufferCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
|
||||
super.onBufferCopy(col, row, w, h, tx, ty)
|
||||
markDirty()
|
||||
}
|
||||
|
||||
override def onScreenDepthChange(depth: ColorDepth) {
|
||||
override def onBufferDepthChange(depth: ColorDepth) {
|
||||
markDirty()
|
||||
}
|
||||
|
||||
override def onScreenFill(col: Int, row: Int, w: Int, h: Int, c: Char) {
|
||||
super.onScreenFill(col, row, w, h, c)
|
||||
override def onBufferFill(col: Int, row: Int, w: Int, h: Int, c: Char) {
|
||||
super.onBufferFill(col, row, w, h, c)
|
||||
markDirty()
|
||||
}
|
||||
|
||||
override def onScreenPaletteChange(index: Int) {
|
||||
override def onBufferPaletteChange(index: Int) {
|
||||
markDirty()
|
||||
}
|
||||
|
||||
override def onScreenResolutionChange(w: Int, h: Int) {
|
||||
super.onScreenResolutionChange(w, h)
|
||||
override def onBufferResolutionChange(w: Int, h: Int) {
|
||||
super.onBufferResolutionChange(w, h)
|
||||
markDirty()
|
||||
}
|
||||
|
||||
override def onScreenSet(col: Int, row: Int, s: String, vertical: Boolean) {
|
||||
super.onScreenSet(col, row, s, vertical)
|
||||
override def onBufferSet(col: Int, row: Int, s: String, vertical: Boolean) {
|
||||
super.onBufferSet(col, row, s, vertical)
|
||||
dirty = true
|
||||
}
|
||||
|
||||
@ -579,22 +652,22 @@ object TextBuffer {
|
||||
ClientPacketSender.sendClipboard(nodeAddress, value)
|
||||
}
|
||||
|
||||
override def mouseDown(x: Int, y: Int, button: Int, player: EntityPlayer) {
|
||||
override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer) {
|
||||
debug(s"{type = mouseDown, x = $x, y = $y, button = $button}")
|
||||
ClientPacketSender.sendMouseClick(nodeAddress, x, y, drag = false, button)
|
||||
}
|
||||
|
||||
override def mouseDrag(x: Int, y: Int, button: Int, player: EntityPlayer) {
|
||||
override def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer) {
|
||||
debug(s"{type = mouseDrag, x = $x, y = $y, button = $button}")
|
||||
ClientPacketSender.sendMouseClick(nodeAddress, x, y, drag = true, button)
|
||||
}
|
||||
|
||||
override def mouseUp(x: Int, y: Int, button: Int, player: EntityPlayer) {
|
||||
override def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer) {
|
||||
debug(s"{type = mouseUp, x = $x, y = $y, button = $button}")
|
||||
ClientPacketSender.sendMouseUp(nodeAddress, x, y, button)
|
||||
}
|
||||
|
||||
override def mouseScroll(x: Int, y: Int, delta: Int, player: EntityPlayer) {
|
||||
override def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer) {
|
||||
debug(s"{type = mouseScroll, x = $x, y = $y, delta = $delta}")
|
||||
ClientPacketSender.sendMouseScroll(nodeAddress, x, y, delta)
|
||||
}
|
||||
@ -609,53 +682,71 @@ object TextBuffer {
|
||||
}
|
||||
|
||||
class ServerProxy(val owner: TextBuffer) extends Proxy {
|
||||
override def onScreenColorChange() {
|
||||
override def onBufferColorChange() {
|
||||
owner.host.markChanged()
|
||||
owner.synchronized(ServerPacketSender.appendTextBufferColorChange(owner.pendingCommands, owner.data.foreground, owner.data.background))
|
||||
}
|
||||
|
||||
override def onScreenCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
|
||||
super.onScreenCopy(col, row, w, h, tx, ty)
|
||||
override def onBufferCopy(col: Int, row: Int, w: Int, h: Int, tx: Int, ty: Int) {
|
||||
super.onBufferCopy(col, row, w, h, tx, ty)
|
||||
owner.host.markChanged()
|
||||
owner.synchronized(ServerPacketSender.appendTextBufferCopy(owner.pendingCommands, col, row, w, h, tx, ty))
|
||||
}
|
||||
|
||||
override def onScreenDepthChange(depth: ColorDepth) {
|
||||
override def onBufferDepthChange(depth: ColorDepth) {
|
||||
owner.host.markChanged()
|
||||
owner.synchronized(ServerPacketSender.appendTextBufferDepthChange(owner.pendingCommands, depth))
|
||||
}
|
||||
|
||||
override def onScreenFill(col: Int, row: Int, w: Int, h: Int, c: Char) {
|
||||
super.onScreenFill(col, row, w, h, c)
|
||||
override def onBufferFill(col: Int, row: Int, w: Int, h: Int, c: Char) {
|
||||
super.onBufferFill(col, row, w, h, c)
|
||||
owner.host.markChanged()
|
||||
owner.synchronized(ServerPacketSender.appendTextBufferFill(owner.pendingCommands, col, row, w, h, c))
|
||||
}
|
||||
|
||||
override def onScreenPaletteChange(index: Int) {
|
||||
override def onBufferPaletteChange(index: Int) {
|
||||
owner.host.markChanged()
|
||||
owner.synchronized(ServerPacketSender.appendTextBufferPaletteChange(owner.pendingCommands, index, owner.getPaletteColor(index)))
|
||||
}
|
||||
|
||||
override def onScreenResolutionChange(w: Int, h: Int) {
|
||||
super.onScreenResolutionChange(w, h)
|
||||
override def onBufferResolutionChange(w: Int, h: Int) {
|
||||
super.onBufferResolutionChange(w, h)
|
||||
owner.host.markChanged()
|
||||
owner.synchronized(ServerPacketSender.appendTextBufferResolutionChange(owner.pendingCommands, w, h))
|
||||
}
|
||||
|
||||
override def onScreenMaxResolutionChange(w: Int, h: Int) {
|
||||
override def onBufferMaxResolutionChange(w: Int, h: Int) {
|
||||
if (owner.node.network != null) {
|
||||
super.onScreenMaxResolutionChange(w, h)
|
||||
super.onBufferMaxResolutionChange(w, h)
|
||||
owner.host.markChanged()
|
||||
owner.synchronized(ServerPacketSender.appendTextBufferMaxResolutionChange(owner.pendingCommands, w, h))
|
||||
}
|
||||
}
|
||||
|
||||
override def onScreenSet(col: Int, row: Int, s: String, vertical: Boolean) {
|
||||
super.onScreenSet(col, row, s, vertical)
|
||||
override def onBufferSet(col: Int, row: Int, s: String, vertical: Boolean) {
|
||||
super.onBufferSet(col, row, s, vertical)
|
||||
owner.host.markChanged()
|
||||
owner.synchronized(ServerPacketSender.appendTextBufferSet(owner.pendingCommands, col, row, s, vertical))
|
||||
}
|
||||
|
||||
override def onBufferRawSetText(col: Int, row: Int, text: Array[Array[Char]]) {
|
||||
super.onBufferRawSetText(col, row, text)
|
||||
owner.host.markChanged()
|
||||
owner.synchronized(ServerPacketSender.appendTextBufferRawSetText(owner.pendingCommands, col, row, text))
|
||||
}
|
||||
|
||||
override def onBufferRawSetBackground(col: Int, row: Int, color: Array[Array[Int]]) {
|
||||
super.onBufferRawSetBackground(col, row, color)
|
||||
owner.host.markChanged()
|
||||
owner.synchronized(ServerPacketSender.appendTextBufferRawSetBackground(owner.pendingCommands, col, row, color))
|
||||
}
|
||||
|
||||
override def onBufferRawSetForeground(col: Int, row: Int, color: Array[Array[Int]]) {
|
||||
super.onBufferRawSetForeground(col, row, color)
|
||||
owner.host.markChanged()
|
||||
owner.synchronized(ServerPacketSender.appendTextBufferRawSetForeground(owner.pendingCommands, col, row, color))
|
||||
}
|
||||
|
||||
override def keyDown(character: Char, code: Int, player: EntityPlayer) {
|
||||
sendToKeyboards("keyboard.keyDown", player, Char.box(character), Int.box(code))
|
||||
}
|
||||
@ -668,24 +759,41 @@ object TextBuffer {
|
||||
sendToKeyboards("keyboard.clipboard", player, value)
|
||||
}
|
||||
|
||||
override def mouseDown(x: Int, y: Int, button: Int, player: EntityPlayer) {
|
||||
if (Settings.get.inputUsername) owner.node.sendToReachable("computer.checked_signal", player, "touch", Int.box(x), Int.box(y), Int.box(button), player.getName)
|
||||
else owner.node.sendToReachable("computer.checked_signal", player, "touch", Int.box(x), Int.box(y), Int.box(button))
|
||||
override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer) {
|
||||
sendMouseEvent(player, "touch", x, y, button)
|
||||
}
|
||||
|
||||
override def mouseDrag(x: Int, y: Int, button: Int, player: EntityPlayer) {
|
||||
if (Settings.get.inputUsername) owner.node.sendToReachable("computer.checked_signal", player, "drag", Int.box(x), Int.box(y), Int.box(button), player.getName)
|
||||
else owner.node.sendToReachable("computer.checked_signal", player, "drag", Int.box(x), Int.box(y), Int.box(button))
|
||||
override def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer) {
|
||||
sendMouseEvent(player, "drag", x, y, button)
|
||||
}
|
||||
|
||||
override def mouseUp(x: Int, y: Int, button: Int, player: EntityPlayer) {
|
||||
if (Settings.get.inputUsername) owner.node.sendToReachable("computer.checked_signal", player, "drop", Int.box(x), Int.box(y), Int.box(button), player.getName)
|
||||
else owner.node.sendToReachable("computer.checked_signal", player, "drop", Int.box(x), Int.box(y), Int.box(button))
|
||||
override def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer) {
|
||||
sendMouseEvent(player, "drop", x, y, button)
|
||||
}
|
||||
|
||||
override def mouseScroll(x: Int, y: Int, delta: Int, player: EntityPlayer) {
|
||||
if (Settings.get.inputUsername) owner.node.sendToReachable("computer.checked_signal", player, "scroll", Int.box(x), Int.box(y), Int.box(delta), player.getName)
|
||||
else owner.node.sendToReachable("computer.checked_signal", player, "scroll", Int.box(x), Int.box(y), Int.box(delta))
|
||||
override def mouseScroll(x: Double, y: Double, delta: Int, player: EntityPlayer) {
|
||||
sendMouseEvent(player, "scroll", x, y, delta)
|
||||
}
|
||||
|
||||
private def sendMouseEvent(player: EntityPlayer, name: String, x: Double, y: Double, data: Int) = {
|
||||
val args = mutable.ArrayBuffer.empty[AnyRef]
|
||||
|
||||
args += player
|
||||
args += name
|
||||
if (owner.precisionMode) {
|
||||
args += double2Double(x)
|
||||
args += double2Double(y)
|
||||
}
|
||||
else {
|
||||
args += int2Integer(x.toInt + 1)
|
||||
args += int2Integer(y.toInt + 1)
|
||||
}
|
||||
args += int2Integer(data)
|
||||
if (Settings.get.inputUsername) {
|
||||
args += player.getName
|
||||
}
|
||||
|
||||
owner.node.sendToReachable("computer.checked_signal", args: _*)
|
||||
}
|
||||
|
||||
private def sendToKeyboards(name: String, values: AnyRef*) {
|
||||
|
@ -39,6 +39,15 @@ abstract class ComponentSlot(inventory: IInventory, index: Int, x: Int, y: Int)
|
||||
}
|
||||
}
|
||||
|
||||
override def putStack(stack: ItemStack): Unit = {
|
||||
super.putStack(stack)
|
||||
inventory match {
|
||||
case playerAware: common.tileentity.traits.PlayerInputAware =>
|
||||
playerAware.onSetInventorySlotContents(container.playerInventory.player, getSlotIndex, stack)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
override def onSlotChanged() {
|
||||
super.onSlotChanged()
|
||||
for (slot <- container.inventorySlots) slot match {
|
||||
|
@ -18,12 +18,12 @@ import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.inventory.ComponentInventory
|
||||
import li.cil.oc.common.inventory.Inventory
|
||||
import li.cil.oc.common.inventory.MultiTank
|
||||
import li.cil.oc.common.item.data.MicrocontrollerData
|
||||
import li.cil.oc.server.component
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.block.material.Material
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.entity.item.EntityItem
|
||||
@ -61,7 +61,7 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
|
||||
var lastEnergyUpdate = 0
|
||||
|
||||
// Logic stuff, components, machine and such.
|
||||
val info = new ItemUtils.MicrocontrollerData()
|
||||
val info = new MicrocontrollerData()
|
||||
val machine = if (!world.isRemote) {
|
||||
val m = Machine.create(this)
|
||||
m.node.asInstanceOf[Connector].setLocalBufferSize(0)
|
||||
@ -296,6 +296,7 @@ class Drone(val world: World) extends Entity(world) with MachineHost with intern
|
||||
|
||||
def setRunning(value: Boolean) = dataWatcher.updateObject(5, byte2Byte(if (value) 1: Byte else 0: Byte))
|
||||
|
||||
|
||||
// Round target values to low accuracy to avoid floating point errors accumulating.
|
||||
def targetX_=(value: Float): Unit = dataWatcher.updateObject(6, float2Float(math.round(value * 4) / 4f))
|
||||
|
||||
|
@ -13,10 +13,12 @@ import li.cil.oc.common.block.SimpleBlock
|
||||
import li.cil.oc.common.item
|
||||
import li.cil.oc.common.item.Delegator
|
||||
import li.cil.oc.common.item.SimpleItem
|
||||
import li.cil.oc.common.item.data.MicrocontrollerData
|
||||
import li.cil.oc.common.item.data.RobotData
|
||||
import li.cil.oc.common.item.data.TabletData
|
||||
import li.cil.oc.common.recipe.Recipes
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.util.Color
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.creativetab.CreativeTabs
|
||||
import net.minecraft.item.Item
|
||||
@ -149,7 +151,7 @@ object Items extends ItemAPI {
|
||||
}
|
||||
|
||||
def createConfiguredDrone() = {
|
||||
val data = new ItemUtils.MicrocontrollerData()
|
||||
val data = new MicrocontrollerData()
|
||||
|
||||
data.tier = Tier.Four
|
||||
data.storedEnergy = Settings.get.bufferDrone.toInt
|
||||
@ -175,7 +177,7 @@ object Items extends ItemAPI {
|
||||
}
|
||||
|
||||
def createConfiguredMicrocontroller() = {
|
||||
val data = new ItemUtils.MicrocontrollerData()
|
||||
val data = new MicrocontrollerData()
|
||||
|
||||
data.tier = Tier.Four
|
||||
data.storedEnergy = Settings.get.bufferMicrocontroller.toInt
|
||||
@ -198,7 +200,7 @@ object Items extends ItemAPI {
|
||||
}
|
||||
|
||||
def createConfiguredRobot() = {
|
||||
val data = new ItemUtils.RobotData()
|
||||
val data = new RobotData()
|
||||
|
||||
data.name = "Creatix"
|
||||
data.tier = Tier.Four
|
||||
@ -241,6 +243,37 @@ object Items extends ItemAPI {
|
||||
stack
|
||||
}
|
||||
|
||||
def createConfiguredTablet() = {
|
||||
val data = new TabletData()
|
||||
|
||||
data.energy = Settings.get.bufferTablet
|
||||
data.maxEnergy = data.energy
|
||||
data.items = Array(
|
||||
Option(get("screen1").createItemStack(1)),
|
||||
Option(get("keyboard").createItemStack(1)),
|
||||
|
||||
Option(get("signUpgrade").createItemStack(1)),
|
||||
Option(get("pistonUpgrade").createItemStack(1)),
|
||||
|
||||
Option(get("graphicsCard2").createItemStack(1)),
|
||||
Option(get("redstoneCard2").createItemStack(1)),
|
||||
Option(get("wlanCard").createItemStack(1)),
|
||||
|
||||
Option(get("cpu3").createItemStack(1)),
|
||||
Option(get("ram6").createItemStack(1)),
|
||||
Option(get("ram6").createItemStack(1)),
|
||||
|
||||
Option(createLuaBios()),
|
||||
Option(createOpenOS()),
|
||||
Option(get("hdd3").createItemStack(1))
|
||||
)
|
||||
|
||||
val stack = get("tablet").createItemStack(1)
|
||||
data.save(stack)
|
||||
|
||||
stack
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
def init() {
|
||||
@ -397,7 +430,8 @@ object Items extends ItemAPI {
|
||||
Items.createLuaBios(),
|
||||
Items.createConfiguredDrone(),
|
||||
Items.createConfiguredMicrocontroller(),
|
||||
Items.createConfiguredRobot()
|
||||
Items.createConfiguredRobot(),
|
||||
Items.createConfiguredTablet()
|
||||
)
|
||||
|
||||
override def getSubItems(item: Item, tab: CreativeTabs, list: util.List[_]): Unit = {
|
||||
|
@ -1,3 +1,27 @@
|
||||
package li.cil.oc.common.item
|
||||
|
||||
class DebugCard(val parent: Delegator) extends Delegate
|
||||
import java.util
|
||||
|
||||
import li.cil.oc.common.item.data.DebugCardData
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.world.World
|
||||
|
||||
class DebugCard(val parent: Delegator) extends Delegate {
|
||||
override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]): Unit = {
|
||||
super.tooltipExtended(stack, tooltip)
|
||||
val data = new DebugCardData(stack)
|
||||
data.player.foreach(name => tooltip.add(s"§8$name§r"))
|
||||
}
|
||||
|
||||
override def onItemRightClick(stack: ItemStack, world: World, player: EntityPlayer): ItemStack = {
|
||||
if (player.isSneaking) {
|
||||
val data = new DebugCardData(stack)
|
||||
if (data.player.contains(player.getName)) data.player = None
|
||||
else data.player = Option(player.getName)
|
||||
data.save(stack)
|
||||
player.swingItem()
|
||||
}
|
||||
stack
|
||||
}
|
||||
}
|
||||
|
@ -25,10 +25,11 @@ import scala.collection.mutable
|
||||
|
||||
object Delegator {
|
||||
def subItem(stack: ItemStack) =
|
||||
stack.getItem match {
|
||||
if (stack != null) stack.getItem match {
|
||||
case delegator: Delegator => delegator.subItem(stack.getItemDamage)
|
||||
case _ => None
|
||||
}
|
||||
else None
|
||||
}
|
||||
|
||||
class Delegator extends Item {
|
||||
|
@ -4,9 +4,9 @@ import java.util
|
||||
|
||||
import li.cil.oc.client.KeyBindings
|
||||
import li.cil.oc.common.entity
|
||||
import li.cil.oc.common.item.data.MicrocontrollerData
|
||||
import li.cil.oc.integration.util.NEI
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import li.cil.oc.util.Rarity
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
@ -19,15 +19,15 @@ class Drone(val parent: Delegator) extends Delegate {
|
||||
|
||||
override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]): Unit = {
|
||||
if (KeyBindings.showExtendedTooltips) {
|
||||
val info = new ItemUtils.MicrocontrollerData(stack)
|
||||
for (component <- info.components) {
|
||||
val info = new MicrocontrollerData(stack)
|
||||
for (component <- info.components if component != null) {
|
||||
tooltip.add("- " + component.getDisplayName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def rarity(stack: ItemStack) = {
|
||||
val data = new ItemUtils.MicrocontrollerData(stack)
|
||||
val data = new MicrocontrollerData(stack)
|
||||
Rarity.byTier(data.tier)
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,9 @@ import li.cil.oc.client.KeyBindings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.inventory.ComponentInventory
|
||||
import li.cil.oc.common.item.data.TabletData
|
||||
import li.cil.oc.server.component
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import li.cil.oc.util.ItemUtils.TabletData
|
||||
import li.cil.oc.util.RotationHelper
|
||||
import li.cil.oc.util.Tooltip
|
||||
import net.minecraft.entity.Entity
|
||||
@ -54,7 +53,7 @@ class Tablet(val parent: Delegator) extends Delegate {
|
||||
|
||||
override protected def tooltipExtended(stack: ItemStack, tooltip: util.List[String]): Unit = {
|
||||
if (KeyBindings.showExtendedTooltips) {
|
||||
val info = new ItemUtils.TabletData(stack)
|
||||
val info = new TabletData(stack)
|
||||
// Ignore/hide the screen.
|
||||
val components = info.items.drop(1)
|
||||
if (components.length > 1) {
|
||||
@ -70,7 +69,7 @@ class Tablet(val parent: Delegator) extends Delegate {
|
||||
|
||||
override def durability(stack: ItemStack) = {
|
||||
if (stack.hasTagCompound) {
|
||||
val data = new ItemUtils.TabletData()
|
||||
val data = new TabletData()
|
||||
data.load(stack.getTagCompound)
|
||||
data.energy / data.maxEnergy
|
||||
}
|
||||
|
@ -0,0 +1,34 @@
|
||||
package li.cil.oc.common.item.data
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
class DebugCardData extends ItemData {
|
||||
def this(stack: ItemStack) {
|
||||
this()
|
||||
load(stack)
|
||||
}
|
||||
|
||||
var player: Option[String] = None
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
val tag = dataTag(nbt)
|
||||
if (tag.hasKey(Settings.namespace + "player")) {
|
||||
player = Option(tag.getString(Settings.namespace + "player"))
|
||||
}
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
val tag = dataTag(nbt)
|
||||
tag.removeTag(Settings.namespace + "player")
|
||||
player.foreach(tag.setString(Settings.namespace + "player", _))
|
||||
}
|
||||
|
||||
private def dataTag(nbt: NBTTagCompound) = {
|
||||
if (!nbt.hasKey(Settings.namespace + "data")) {
|
||||
nbt.setTag(Settings.namespace + "data", new NBTTagCompound())
|
||||
}
|
||||
nbt.getCompoundTag(Settings.namespace + "data")
|
||||
}
|
||||
}
|
26
src/main/scala/li/cil/oc/common/item/data/ItemData.scala
Normal file
26
src/main/scala/li/cil/oc/common/item/data/ItemData.scala
Normal file
@ -0,0 +1,26 @@
|
||||
package li.cil.oc.common.item.data
|
||||
|
||||
import li.cil.oc.api.Persistable
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
object ItemData {
|
||||
|
||||
}
|
||||
|
||||
abstract class ItemData extends Persistable {
|
||||
def load(stack: ItemStack) {
|
||||
if (stack.hasTagCompound) {
|
||||
// Because ItemStack's load function doesn't copy the compound tag,
|
||||
// but keeps it as is, leading to oh so fun bugs!
|
||||
load(stack.getTagCompound.copy().asInstanceOf[NBTTagCompound])
|
||||
}
|
||||
}
|
||||
|
||||
def save(stack: ItemStack) {
|
||||
if (!stack.hasTagCompound) {
|
||||
stack.setTagCompound(new NBTTagCompound())
|
||||
}
|
||||
save(stack.getTagCompound)
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package li.cil.oc.common.item.data
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
|
||||
class MicrocontrollerData extends ItemData {
|
||||
def this(stack: ItemStack) {
|
||||
this()
|
||||
load(stack)
|
||||
}
|
||||
|
||||
var tier = Tier.One
|
||||
|
||||
var components = Array.empty[ItemStack]
|
||||
|
||||
var storedEnergy = 0
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
tier = nbt.getByte(Settings.namespace + "tier")
|
||||
components = nbt.getTagList(Settings.namespace + "components", NBT.TAG_COMPOUND).
|
||||
toArray[NBTTagCompound].map(ItemUtils.loadStack)
|
||||
storedEnergy = nbt.getInteger(Settings.namespace + "storedEnergy")
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
nbt.setByte(Settings.namespace + "tier", tier.toByte)
|
||||
nbt.setNewTagList(Settings.namespace + "components", components.toIterable)
|
||||
nbt.setInteger(Settings.namespace + "storedEnergy", storedEnergy)
|
||||
}
|
||||
|
||||
def createItemStack() = {
|
||||
val stack = api.Items.get("microcontroller").createItemStack(1)
|
||||
save(stack)
|
||||
stack
|
||||
}
|
||||
|
||||
def copyItemStack() = {
|
||||
val stack = createItemStack()
|
||||
val newInfo = new MicrocontrollerData(stack)
|
||||
newInfo.save(stack)
|
||||
stack
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package li.cil.oc.common.item.data
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.item.ItemMap
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.world.World
|
||||
|
||||
class NavigationUpgradeData extends ItemData {
|
||||
def this(stack: ItemStack) {
|
||||
this()
|
||||
load(stack)
|
||||
}
|
||||
|
||||
var map = new ItemStack(net.minecraft.init.Items.filled_map)
|
||||
|
||||
def mapData(world: World) = try map.getItem.asInstanceOf[ItemMap].getMapData(map, world) catch {
|
||||
case _: Throwable => throw new Exception("invalid map")
|
||||
}
|
||||
|
||||
override def load(stack: ItemStack) {
|
||||
if (stack.hasTagCompound) {
|
||||
load(stack.getTagCompound.getCompoundTag(Settings.namespace + "data"))
|
||||
}
|
||||
}
|
||||
|
||||
override def save(stack: ItemStack) {
|
||||
if (!stack.hasTagCompound) {
|
||||
stack.setTagCompound(new NBTTagCompound())
|
||||
}
|
||||
save(stack.getCompoundTag(Settings.namespace + "data"))
|
||||
}
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
if (nbt.hasKey(Settings.namespace + "map")) {
|
||||
map = ItemUtils.loadStack(nbt.getCompoundTag(Settings.namespace + "map"))
|
||||
}
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
if (map != null) {
|
||||
nbt.setNewCompoundTag(Settings.namespace + "map", map.writeToNBT)
|
||||
}
|
||||
}
|
||||
}
|
43
src/main/scala/li/cil/oc/common/item/data/RaidData.scala
Normal file
43
src/main/scala/li/cil/oc/common/item/data/RaidData.scala
Normal file
@ -0,0 +1,43 @@
|
||||
package li.cil.oc.common.item.data
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
|
||||
class RaidData extends ItemData {
|
||||
def this(stack: ItemStack) {
|
||||
this()
|
||||
load(stack)
|
||||
}
|
||||
|
||||
var disks = Array.empty[ItemStack]
|
||||
|
||||
var filesystem = new NBTTagCompound()
|
||||
|
||||
var label: Option[String] = None
|
||||
|
||||
override def load(nbt: NBTTagCompound): Unit = {
|
||||
disks = nbt.getTagList(Settings.namespace + "disks", NBT.TAG_COMPOUND).
|
||||
toArray[NBTTagCompound].map(ItemUtils.loadStack)
|
||||
filesystem = nbt.getCompoundTag(Settings.namespace + "filesystem")
|
||||
if (nbt.hasKey(Settings.namespace + "label")) {
|
||||
label = Option(nbt.getString(Settings.namespace + "label"))
|
||||
}
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound): Unit = {
|
||||
nbt.setNewTagList(Settings.namespace + "disks", disks.toIterable)
|
||||
nbt.setTag(Settings.namespace + "filesystem", filesystem)
|
||||
label.foreach(nbt.setString(Settings.namespace + "label", _))
|
||||
}
|
||||
|
||||
def createItemStack() = {
|
||||
val stack = api.Items.get("raid").createItemStack(1)
|
||||
save(stack)
|
||||
stack
|
||||
}
|
||||
}
|
114
src/main/scala/li/cil/oc/common/item/data/RobotData.scala
Normal file
114
src/main/scala/li/cil/oc/common/item/data/RobotData.scala
Normal file
@ -0,0 +1,114 @@
|
||||
package li.cil.oc.common.item.data
|
||||
|
||||
import com.google.common.base.Charsets
|
||||
import com.google.common.base.Strings
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.integration.opencomputers.DriverScreen
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
|
||||
import scala.io.Source
|
||||
|
||||
object RobotData {
|
||||
val names = try {
|
||||
Source.fromInputStream(getClass.getResourceAsStream(
|
||||
"/assets/" + Settings.resourceDomain + "/robot.names"))(Charsets.UTF_8).
|
||||
getLines().map(_.takeWhile(_ != '#').trim()).filter(_ != "").toArray
|
||||
}
|
||||
catch {
|
||||
case t: Throwable =>
|
||||
OpenComputers.log.warn("Failed loading robot name list.", t)
|
||||
Array.empty[String]
|
||||
}
|
||||
|
||||
def randomName = if (names.length > 0) names((math.random * names.length).toInt) else "Robot"
|
||||
}
|
||||
|
||||
class RobotData extends ItemData {
|
||||
def this(stack: ItemStack) {
|
||||
this()
|
||||
load(stack)
|
||||
}
|
||||
|
||||
var name = ""
|
||||
|
||||
// Overall energy including components.
|
||||
var totalEnergy = 0
|
||||
|
||||
// Energy purely stored in robot component - this is what we have to restore manually.
|
||||
var robotEnergy = 0
|
||||
|
||||
var tier = 0
|
||||
|
||||
var components = Array.empty[ItemStack]
|
||||
|
||||
var containers = Array.empty[ItemStack]
|
||||
|
||||
var lightColor = 0xF23030
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
if (nbt.hasKey("display") && nbt.getCompoundTag("display").hasKey("Name")) {
|
||||
name = nbt.getCompoundTag("display").getString("Name")
|
||||
}
|
||||
if (Strings.isNullOrEmpty(name)) {
|
||||
name = RobotData.randomName
|
||||
}
|
||||
totalEnergy = nbt.getInteger(Settings.namespace + "storedEnergy")
|
||||
robotEnergy = nbt.getInteger(Settings.namespace + "robotEnergy")
|
||||
tier = nbt.getInteger(Settings.namespace + "tier")
|
||||
components = nbt.getTagList(Settings.namespace + "components", NBT.TAG_COMPOUND).
|
||||
toArray[NBTTagCompound].map(ItemUtils.loadStack)
|
||||
containers = nbt.getTagList(Settings.namespace + "containers", NBT.TAG_COMPOUND).
|
||||
toArray[NBTTagCompound].map(ItemUtils.loadStack)
|
||||
if (nbt.hasKey(Settings.namespace + "lightColor")) {
|
||||
lightColor = nbt.getInteger(Settings.namespace + "lightColor")
|
||||
}
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
if (!Strings.isNullOrEmpty(name)) {
|
||||
if (!nbt.hasKey("display")) {
|
||||
nbt.setTag("display", new NBTTagCompound())
|
||||
}
|
||||
nbt.getCompoundTag("display").setString("Name", name)
|
||||
}
|
||||
nbt.setInteger(Settings.namespace + "storedEnergy", totalEnergy)
|
||||
nbt.setInteger(Settings.namespace + "robotEnergy", robotEnergy)
|
||||
nbt.setInteger(Settings.namespace + "tier", tier)
|
||||
nbt.setNewTagList(Settings.namespace + "components", components.toIterable)
|
||||
nbt.setNewTagList(Settings.namespace + "containers", containers.toIterable)
|
||||
nbt.setInteger(Settings.namespace + "lightColor", lightColor)
|
||||
}
|
||||
|
||||
def createItemStack() = {
|
||||
val stack = api.Items.get("robot").createItemStack(1)
|
||||
save(stack)
|
||||
stack
|
||||
}
|
||||
|
||||
def copyItemStack() = {
|
||||
val stack = createItemStack()
|
||||
// Forget all node addresses and so on. This is used when 'picking' a
|
||||
// robot in creative mode.
|
||||
val newInfo = new RobotData(stack)
|
||||
newInfo.components.foreach(cs => Option(api.Driver.driverFor(cs)) match {
|
||||
case Some(driver) if driver == DriverScreen =>
|
||||
val nbt = driver.dataTag(cs)
|
||||
for (tagName <- nbt.getKeySet.toArray) {
|
||||
nbt.removeTag(tagName.asInstanceOf[String])
|
||||
}
|
||||
case _ =>
|
||||
})
|
||||
// Don't show energy info (because it's unreliable) but fill up the
|
||||
// internal buffer. This is for creative use only, anyway.
|
||||
newInfo.totalEnergy = 0
|
||||
newInfo.robotEnergy = 50000
|
||||
newInfo.save(stack)
|
||||
stack
|
||||
}
|
||||
}
|
47
src/main/scala/li/cil/oc/common/item/data/TabletData.scala
Normal file
47
src/main/scala/li/cil/oc/common/item/data/TabletData.scala
Normal file
@ -0,0 +1,47 @@
|
||||
package li.cil.oc.common.item.data
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
|
||||
class TabletData extends ItemData {
|
||||
def this(stack: ItemStack) {
|
||||
this()
|
||||
load(stack)
|
||||
}
|
||||
|
||||
var items = Array.fill[Option[ItemStack]](32)(None)
|
||||
var isRunning = false
|
||||
var energy = 0.0
|
||||
var maxEnergy = 0.0
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
nbt.getTagList(Settings.namespace + "items", NBT.TAG_COMPOUND).foreach((slotNbt: NBTTagCompound) => {
|
||||
val slot = slotNbt.getByte("slot")
|
||||
if (slot >= 0 && slot < items.length) {
|
||||
items(slot) = Option(ItemUtils.loadStack(slotNbt.getCompoundTag("item")))
|
||||
}
|
||||
})
|
||||
isRunning = nbt.getBoolean(Settings.namespace + "isRunning")
|
||||
energy = nbt.getDouble(Settings.namespace + "energy")
|
||||
maxEnergy = nbt.getDouble(Settings.namespace + "maxEnergy")
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
nbt.setNewTagList(Settings.namespace + "items",
|
||||
items.zipWithIndex collect {
|
||||
case (Some(stack), slot) => (stack, slot)
|
||||
} map {
|
||||
case (stack, slot) =>
|
||||
val slotNbt = new NBTTagCompound()
|
||||
slotNbt.setByte("slot", slot.toByte)
|
||||
slotNbt.setNewCompoundTag("item", stack.writeToNBT)
|
||||
})
|
||||
nbt.setBoolean(Settings.namespace + "isRunning", isRunning)
|
||||
nbt.setDouble(Settings.namespace + "energy", energy)
|
||||
nbt.setDouble(Settings.namespace + "maxEnergy", maxEnergy)
|
||||
}
|
||||
}
|
@ -5,9 +5,10 @@ import java.util.UUID
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.detail.ItemInfo
|
||||
import li.cil.oc.common.init.Items
|
||||
import li.cil.oc.common.item.data.MicrocontrollerData
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import li.cil.oc.util.SideTracker
|
||||
import net.minecraft.init.Blocks
|
||||
import net.minecraft.inventory.InventoryCrafting
|
||||
@ -20,6 +21,7 @@ import scala.util.control.Breaks._
|
||||
object ExtendedRecipe {
|
||||
private lazy val drone = api.Items.get("drone")
|
||||
private lazy val eeprom = api.Items.get("eeprom")
|
||||
private lazy val luaBios = Items.createLuaBios()
|
||||
private lazy val mcu = api.Items.get("microcontroller")
|
||||
private lazy val navigationUpgrade = api.Items.get("navigationUpgrade")
|
||||
private lazy val linkedCard = api.Items.get("linkedCard")
|
||||
@ -71,7 +73,7 @@ object ExtendedRecipe {
|
||||
}
|
||||
}
|
||||
|
||||
if (api.Items.get(craftedStack) == eeprom) breakable {
|
||||
if (api.Items.get(craftedStack) == eeprom && !ItemStack.areItemStackTagsEqual(craftedStack, luaBios)) breakable {
|
||||
for (slot <- 0 until inventory.getSizeInventory) {
|
||||
val stack = inventory.getStackInSlot(slot)
|
||||
if (stack != null && api.Items.get(stack) == eeprom && stack.hasTagCompound) {
|
||||
@ -95,7 +97,7 @@ object ExtendedRecipe {
|
||||
// Find old Microcontroller.
|
||||
(0 until inventory.getSizeInventory).map(inventory.getStackInSlot).find(api.Items.get(_) == descriptor) match {
|
||||
case Some(oldMcu) =>
|
||||
val data = new ItemUtils.MicrocontrollerData(oldMcu)
|
||||
val data = new MicrocontrollerData(oldMcu)
|
||||
|
||||
// Remove old EEPROM.
|
||||
val oldRom = data.components.filter(api.Items.get(_) == eeprom)
|
||||
|
@ -5,6 +5,7 @@ import li.cil.oc.api
|
||||
import li.cil.oc.api.internal
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.item.data.MicrocontrollerData
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.inventory.IInventory
|
||||
@ -29,7 +30,7 @@ object DroneTemplate extends Template {
|
||||
|
||||
def assemble(inventory: IInventory) = {
|
||||
val items = (0 until inventory.getSizeInventory).map(inventory.getStackInSlot)
|
||||
val data = new ItemUtils.MicrocontrollerData()
|
||||
val data = new MicrocontrollerData()
|
||||
data.tier = caseTier(inventory)
|
||||
data.components = items.drop(1).filter(_ != null).toArray
|
||||
data.storedEnergy = Settings.get.bufferDrone.toInt
|
||||
@ -43,7 +44,7 @@ object DroneTemplate extends Template {
|
||||
def selectDisassembler(stack: ItemStack) = api.Items.get(stack) == api.Items.get("drone")
|
||||
|
||||
def disassemble(stack: ItemStack, ingredients: Array[ItemStack]) = {
|
||||
val info = new ItemUtils.MicrocontrollerData(stack)
|
||||
val info = new MicrocontrollerData(stack)
|
||||
val itemName = ItemUtils.caseNameWithTierSuffix("droneCase", info.tier)
|
||||
|
||||
Array(api.Items.get(itemName).createItemStack(1)) ++ info.components
|
||||
|
@ -5,6 +5,7 @@ import li.cil.oc.api
|
||||
import li.cil.oc.api.internal
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.item.data.MicrocontrollerData
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.inventory.IInventory
|
||||
@ -29,7 +30,7 @@ object MicrocontrollerTemplate extends Template {
|
||||
|
||||
def assemble(inventory: IInventory) = {
|
||||
val items = (0 until inventory.getSizeInventory).map(inventory.getStackInSlot)
|
||||
val data = new ItemUtils.MicrocontrollerData()
|
||||
val data = new MicrocontrollerData()
|
||||
data.tier = caseTier(inventory)
|
||||
data.components = items.drop(1).filter(_ != null).toArray
|
||||
data.storedEnergy = Settings.get.bufferMicrocontroller.toInt
|
||||
@ -43,7 +44,7 @@ object MicrocontrollerTemplate extends Template {
|
||||
def selectDisassembler(stack: ItemStack) = api.Items.get(stack) == api.Items.get("microcontroller")
|
||||
|
||||
def disassemble(stack: ItemStack, ingredients: Array[ItemStack]) = {
|
||||
val info = new ItemUtils.MicrocontrollerData(stack)
|
||||
val info = new MicrocontrollerData(stack)
|
||||
val itemName = ItemUtils.caseNameWithTierSuffix("microcontrollerCase", info.tier)
|
||||
|
||||
Array(api.Items.get(itemName).createItemStack(1)) ++ info.components
|
||||
|
@ -1,7 +1,7 @@
|
||||
package li.cil.oc.common.template
|
||||
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import li.cil.oc.common.item.data.NavigationUpgradeData
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraftforge.fml.common.event.FMLInterModComms
|
||||
@ -12,7 +12,7 @@ object NavigationUpgradeTemplate {
|
||||
def selectDisassembler(stack: ItemStack) = api.Items.get(stack) == api.Items.get("navigationUpgrade")
|
||||
|
||||
def disassemble(stack: ItemStack, ingredients: Array[ItemStack]) = {
|
||||
val info = new ItemUtils.NavigationUpgradeData(stack)
|
||||
val info = new NavigationUpgradeData(stack)
|
||||
ingredients.map {
|
||||
case part if part.getItem == net.minecraft.init.Items.filled_map => info.map
|
||||
case part => part
|
||||
|
@ -5,6 +5,7 @@ import li.cil.oc.api
|
||||
import li.cil.oc.api.internal
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.item.data.RobotData
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.inventory.IInventory
|
||||
@ -16,21 +17,21 @@ import net.minecraftforge.fml.common.event.FMLInterModComms
|
||||
object RobotTemplate extends Template {
|
||||
override protected def hostClass = classOf[internal.Robot]
|
||||
|
||||
def selectTier1(stack: ItemStack) = ItemUtils.caseTier(stack) == Tier.One
|
||||
def selectTier1(stack: ItemStack) = api.Items.get(stack) == api.Items.get("case1")
|
||||
|
||||
def selectTier2(stack: ItemStack) = ItemUtils.caseTier(stack) == Tier.Two
|
||||
def selectTier2(stack: ItemStack) = api.Items.get(stack) == api.Items.get("case2")
|
||||
|
||||
def selectTier3(stack: ItemStack) = ItemUtils.caseTier(stack) == Tier.Three
|
||||
def selectTier3(stack: ItemStack) = api.Items.get(stack) == api.Items.get("case3")
|
||||
|
||||
def selectCreative(stack: ItemStack) = ItemUtils.caseTier(stack) == Tier.Four
|
||||
def selectCreative(stack: ItemStack) = api.Items.get(stack) == api.Items.get("caseCreative")
|
||||
|
||||
def validate(inventory: IInventory): Array[AnyRef] = validateComputer(inventory)
|
||||
|
||||
def assemble(inventory: IInventory) = {
|
||||
val items = (0 until inventory.getSizeInventory).map(inventory.getStackInSlot)
|
||||
val data = new ItemUtils.RobotData()
|
||||
val data = new RobotData()
|
||||
data.tier = ItemUtils.caseTier(inventory.getStackInSlot(0))
|
||||
data.name = ItemUtils.RobotData.randomName
|
||||
data.name = RobotData.randomName
|
||||
data.robotEnergy = Settings.get.bufferRobot.toInt
|
||||
data.totalEnergy = data.robotEnergy
|
||||
data.containers = items.slice(1, 4).filter(_ != null).toArray
|
||||
@ -45,7 +46,7 @@ object RobotTemplate extends Template {
|
||||
def selectDisassembler(stack: ItemStack) = api.Items.get(stack) == api.Items.get("robot")
|
||||
|
||||
def disassemble(stack: ItemStack, ingredients: Array[ItemStack]) = {
|
||||
val info = new ItemUtils.RobotData(stack)
|
||||
val info = new RobotData(stack)
|
||||
val itemName = ItemUtils.caseNameWithTierSuffix("case", info.tier)
|
||||
|
||||
Array(api.Items.get(itemName).createItemStack(1)) ++ info.containers ++ info.components
|
||||
|
@ -5,8 +5,8 @@ import li.cil.oc.api
|
||||
import li.cil.oc.api.internal
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.item.data.TabletData
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
@ -32,7 +32,7 @@ object TabletTemplate extends Template {
|
||||
val items = mutable.ArrayBuffer(
|
||||
Option(api.Items.get("screen1").createItemStack(1))
|
||||
) ++ (1 until inventory.getSizeInventory).map(slot => Option(inventory.getStackInSlot(slot)))
|
||||
val data = new ItemUtils.TabletData()
|
||||
val data = new TabletData()
|
||||
data.items = items.filter(_.isDefined).toArray
|
||||
data.energy = Settings.get.bufferTablet
|
||||
data.maxEnergy = data.energy
|
||||
@ -46,7 +46,7 @@ object TabletTemplate extends Template {
|
||||
def selectDisassembler(stack: ItemStack) = api.Items.get(stack) == api.Items.get("tablet")
|
||||
|
||||
def disassemble(stack: ItemStack, ingredients: Array[ItemStack]) = {
|
||||
val info = new ItemUtils.TabletData(stack)
|
||||
val info = new TabletData(stack)
|
||||
Array(api.Items.get("tabletCase").createItemStack(1)) ++ info.items.collect {
|
||||
case Some(item) => item
|
||||
}.drop(1) // Screen.
|
||||
|
@ -10,10 +10,10 @@ import li.cil.oc.api.network._
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.entity.Drone
|
||||
import li.cil.oc.common.item.Tablet
|
||||
import li.cil.oc.common.item.data.TabletData
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
@ -101,7 +101,7 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
|
||||
handler(itemCharge)
|
||||
}
|
||||
}
|
||||
val data = new ItemUtils.TabletData(stack)
|
||||
val data = new TabletData(stack)
|
||||
tryCharge(data.energy, data.maxEnergy, (amount) => {
|
||||
data.energy = math.min(data.maxEnergy, data.energy + amount)
|
||||
data.save(stack)
|
||||
|
@ -11,6 +11,7 @@ import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.EnumFacing
|
||||
@ -20,7 +21,7 @@ import net.minecraftforge.fml.relauncher.SideOnly
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
class Disassembler extends traits.Environment with traits.PowerAcceptor with traits.Inventory with traits.StateAware {
|
||||
class Disassembler extends traits.Environment with traits.PowerAcceptor with traits.Inventory with traits.StateAware with traits.PlayerInputAware {
|
||||
val node = api.Network.newNode(this, Visibility.None).
|
||||
withConnector(Settings.get.bufferConverter).
|
||||
create()
|
||||
@ -33,6 +34,8 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
|
||||
var buffer = 0.0
|
||||
|
||||
var disassembleNextInstantly = false
|
||||
|
||||
def progress = if (queue.isEmpty) 0 else (1 - (queue.size * Settings.get.disassemblerItemCost - buffer) / totalRequiredEnergy) * 100
|
||||
|
||||
private def setActive(value: Boolean) = if (value != isActive) {
|
||||
@ -64,7 +67,8 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
super.updateEntity()
|
||||
if (world.getTotalWorldTime % Settings.get.tickFrequency == 0) {
|
||||
if (queue.isEmpty) {
|
||||
disassemble(decrStackSize(0, 1))
|
||||
val instant = disassembleNextInstantly // Is reset via decrStackSize
|
||||
disassemble(decrStackSize(0, 1), instant)
|
||||
setActive(queue.nonEmpty)
|
||||
}
|
||||
else {
|
||||
@ -76,10 +80,10 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
buffer += want
|
||||
}
|
||||
}
|
||||
if (buffer >= Settings.get.disassemblerItemCost) {
|
||||
while (buffer >= Settings.get.disassemblerItemCost && queue.nonEmpty) {
|
||||
buffer -= Settings.get.disassemblerItemCost
|
||||
val stack = queue.remove(0)
|
||||
if (world.rand.nextDouble > Settings.get.disassemblerBreakChance) {
|
||||
if (world.rand.nextDouble >= Settings.get.disassemblerBreakChance) {
|
||||
drop(stack)
|
||||
}
|
||||
}
|
||||
@ -87,7 +91,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
}
|
||||
}
|
||||
|
||||
def disassemble(stack: ItemStack) {
|
||||
def disassemble(stack: ItemStack, instant: Boolean = false) {
|
||||
// Validate the item, never trust Minecraft / other Mods on anything!
|
||||
if (stack != null && isItemValidForSlot(0, stack)) {
|
||||
val ingredients = ItemUtils.getIngredients(stack)
|
||||
@ -99,6 +103,10 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
case _ => queue ++= ingredients
|
||||
}
|
||||
totalRequiredEnergy = queue.size * Settings.get.disassemblerItemCost
|
||||
if (instant) {
|
||||
buffer = totalRequiredEnergy
|
||||
disassembleNextInstantly = false // Just to be sure...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,4 +160,17 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
override def isItemValidForSlot(i: Int, stack: ItemStack) =
|
||||
((Settings.get.disassembleAllTheThings || api.Items.get(stack) != null) && ItemUtils.getIngredients(stack).nonEmpty) ||
|
||||
DisassemblerTemplates.select(stack) != None
|
||||
|
||||
override def setInventorySlotContents(slot: Int, stack: ItemStack): Unit = {
|
||||
super.setInventorySlotContents(slot, stack)
|
||||
if (!world.isRemote) {
|
||||
disassembleNextInstantly = false
|
||||
}
|
||||
}
|
||||
|
||||
override def onSetInventorySlotContents(player: EntityPlayer, slot: Int, stack: ItemStack): Unit = {
|
||||
if (!world.isRemote) {
|
||||
disassembleNextInstantly = stack != null && slot == 0 && player.capabilities.isCreativeMode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ import li.cil.oc.api.machine.Context
|
||||
import li.cil.oc.api.network._
|
||||
import li.cil.oc.common.Slot
|
||||
import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.item.data.MicrocontrollerData
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.EnumFacing
|
||||
@ -21,7 +21,7 @@ import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
|
||||
class Microcontroller extends traits.PowerAcceptor with traits.Computer with SidedEnvironment with internal.Microcontroller {
|
||||
val info = new ItemUtils.MicrocontrollerData()
|
||||
val info = new MicrocontrollerData()
|
||||
|
||||
override val node = api.Network.newNode(this, Visibility.Network).
|
||||
withComponent("microcontroller").
|
||||
|
@ -77,7 +77,7 @@ class Raid extends traits.Environment with traits.Inventory with traits.Rotatabl
|
||||
}
|
||||
}
|
||||
|
||||
private def tryCreateRaid(id: String) {
|
||||
def tryCreateRaid(id: String) {
|
||||
if (items.count(_.isDefined) == items.length) {
|
||||
val fs = api.FileSystem.asManagedEnvironment(
|
||||
api.FileSystem.fromSaveDirectory(id, wipeDisksAndComputeSpace, Settings.get.bufferChanges),
|
||||
|
@ -1,6 +1,7 @@
|
||||
package li.cil.oc.common.tileentity
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.network.Visibility
|
||||
import li.cil.oc.common.tileentity.traits.BundledRedstoneAware
|
||||
import li.cil.oc.common.tileentity.traits.Environment
|
||||
@ -11,12 +12,18 @@ import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.EnumFacing
|
||||
|
||||
class Redstone extends Environment with BundledRedstoneAware {
|
||||
val instance = if (BundledRedstone.isAvailable) new component.Redstone[BundledRedstoneAware](this) with component.RedstoneBundled else new component.Redstone(this)
|
||||
val instance =
|
||||
if (BundledRedstone.isAvailable)
|
||||
new component.Redstone.Bundled(this)
|
||||
else
|
||||
new component.Redstone.Vanilla(this)
|
||||
val node = instance.node
|
||||
if (node != null) {
|
||||
val dummyNode = if (node != null) {
|
||||
node.setVisibility(Visibility.Network)
|
||||
_isOutputEnabled = true
|
||||
api.Network.newNode(this, Visibility.None).create()
|
||||
}
|
||||
else null
|
||||
|
||||
override def canUpdate = isServer
|
||||
|
||||
@ -34,8 +41,11 @@ class Redstone extends Environment with BundledRedstoneAware {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override protected def onRedstoneInputChanged(side: EnumFacing) {
|
||||
super.onRedstoneInputChanged(side)
|
||||
node.sendToReachable("computer.signal", "redstone_changed", Int.box(side.ordinal()))
|
||||
override protected def onRedstoneInputChanged(side: EnumFacing, oldMaxValue: Int, newMaxValue: Int) {
|
||||
super.onRedstoneInputChanged(side, oldMaxValue, newMaxValue)
|
||||
if (node != null && node.network != null) {
|
||||
node.connect(dummyNode)
|
||||
dummyNode.sendToNeighbors("redstone.changed", side, int2Integer(oldMaxValue), int2Integer(newMaxValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import li.cil.oc.common.Tier
|
||||
import li.cil.oc.common.inventory.InventorySelection
|
||||
import li.cil.oc.common.inventory.MultiTank
|
||||
import li.cil.oc.common.inventory.TankSelection
|
||||
import li.cil.oc.common.item.data.RobotData
|
||||
import li.cil.oc.integration.opencomputers.DriverKeyboard
|
||||
import li.cil.oc.integration.opencomputers.DriverRedstoneCard
|
||||
import li.cil.oc.integration.opencomputers.DriverScreen
|
||||
@ -28,7 +29,6 @@ import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import li.cil.oc.util.ItemUtils
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.BlockLiquid
|
||||
import net.minecraft.client.Minecraft
|
||||
@ -37,7 +37,6 @@ import net.minecraft.init.Blocks
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
@ -56,7 +55,7 @@ import scala.collection.mutable
|
||||
class Robot extends traits.Computer with traits.PowerInformation with IFluidHandler with internal.Robot with MultiTank with InventorySelection with TankSelection {
|
||||
var proxy: RobotProxy = _
|
||||
|
||||
val info = new ItemUtils.RobotData()
|
||||
val info = new RobotData()
|
||||
|
||||
val bot = if (isServer) new robot.Robot(this) else null
|
||||
|
||||
@ -244,7 +243,7 @@ class Robot extends traits.Computer with traits.PowerInformation with IFluidHand
|
||||
// worked before the client is notified so that we can use the same trick on
|
||||
// the client by sending a corresponding packet. This also saves us from
|
||||
// having to send the complete state again (e.g. screen buffer) each move.
|
||||
// world.setBlockToAir(newPosition)
|
||||
// world.setBlockToAir(newPosition)
|
||||
// In some cases (though I couldn't quite figure out which one) setBlock
|
||||
// will return true, even though the block was not created / adjusted.
|
||||
val created = world.setBlockState(newPosition, blockRobotProxy.getDefaultState, 1)
|
||||
@ -751,8 +750,13 @@ class Robot extends traits.Computer with traits.PowerInformation with IFluidHand
|
||||
override def dropSlot(slot: Int, count: Int, direction: Option[EnumFacing]) =
|
||||
InventoryUtils.dropSlot(BlockPosition(x, y, z, world), dynamicInventory, slot, count, direction)
|
||||
|
||||
override def dropAllSlots() =
|
||||
override def dropAllSlots() = {
|
||||
InventoryUtils.dropSlot(BlockPosition(x, y, z, world), this, 0, Int.MaxValue)
|
||||
for (slot <- containerSlots) {
|
||||
InventoryUtils.dropSlot(BlockPosition(x, y, z, world), this, slot, Int.MaxValue)
|
||||
}
|
||||
InventoryUtils.dropAllSlots(BlockPosition(x, y, z, world), dynamicInventory)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
|
@ -139,7 +139,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
|
||||
}
|
||||
|
||||
// Convert to absolute coordinates and send the packet to the server.
|
||||
origin.buffer.mouseDown((brx * bw).toInt + 1, (bry * bh).toInt + 1, 0, null)
|
||||
origin.buffer.mouseDown(brx * bw, bry * bh, 0, null)
|
||||
|
||||
true
|
||||
}
|
||||
@ -319,8 +319,8 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
|
||||
|
||||
override def onAnalyze(player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float) = Array(origin.node)
|
||||
|
||||
override protected def onRedstoneInputChanged(side: EnumFacing) {
|
||||
super.onRedstoneInputChanged(side)
|
||||
override protected def onRedstoneInputChanged(side: EnumFacing, oldMaxValue: Int, newMaxValue: Int) {
|
||||
super.onRedstoneInputChanged(side, oldMaxValue, newMaxValue)
|
||||
val hasRedstoneInput = screens.map(_.maxInput).max > 0
|
||||
if (hasRedstoneInput != hadRedstoneInput) {
|
||||
hadRedstoneInput = hasRedstoneInput
|
||||
|
@ -207,7 +207,7 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB
|
||||
val l = 2 / 16.0
|
||||
val h = 14 / 16.0
|
||||
val slot = (((1 - hitY) - l) / (h - l) * 4).toInt
|
||||
Some(math.max(0, math.min(servers.length, slot)))
|
||||
Some(math.max(0, math.min(servers.length - 1, slot)))
|
||||
}
|
||||
else None
|
||||
}
|
||||
@ -409,10 +409,10 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB
|
||||
checkRedstoneInputChanged()
|
||||
}
|
||||
|
||||
override protected def onRedstoneInputChanged(side: EnumFacing) {
|
||||
super.onRedstoneInputChanged(side)
|
||||
override protected def onRedstoneInputChanged(side: EnumFacing, oldMaxValue: Int, newMaxValue: Int) {
|
||||
super.onRedstoneInputChanged(side, oldMaxValue, newMaxValue)
|
||||
servers collect {
|
||||
case Some(server) => server.machine.signal("redstone_changed", server.machine.node.address, Int.box(toLocal(side).ordinal()))
|
||||
case Some(server) => server.machine.node.sendToNeighbors("redstone.changed", toLocal(side), int2Integer(oldMaxValue), int2Integer(newMaxValue))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,13 +55,15 @@ trait BundledRedstoneAware extends RedstoneAware /* with IBundledEmitter with IB
|
||||
def bundledInput(side: EnumFacing, color: Int) =
|
||||
math.max(_bundledInput(side.ordinal())(color), _rednetInput(side.ordinal())(color))
|
||||
|
||||
def rednetInput(side: EnumFacing, color: Int, value: Int) =
|
||||
if (_rednetInput(side.ordinal())(color) != value) {
|
||||
if (_rednetInput(side.ordinal())(color) != -1) {
|
||||
onRedstoneInputChanged(side)
|
||||
def rednetInput(side: EnumFacing, color: Int, value: Int): Unit = {
|
||||
val oldValue = _rednetInput(side.ordinal())(color)
|
||||
if (oldValue != value) {
|
||||
if (oldValue != -1) {
|
||||
onRedstoneInputChanged(side, oldValue, value)
|
||||
}
|
||||
_rednetInput(side.ordinal())(color) = value
|
||||
}
|
||||
}
|
||||
|
||||
def bundledOutput(side: EnumFacing) = _bundledOutput(toLocal(side).ordinal())
|
||||
|
||||
@ -87,19 +89,20 @@ trait BundledRedstoneAware extends RedstoneAware /* with IBundledEmitter with IB
|
||||
|
||||
override protected def updateRedstoneInput(side: EnumFacing) {
|
||||
super.updateRedstoneInput(side)
|
||||
val oldBundledInput = _bundledInput(side.ordinal())
|
||||
val ownBundledInput = _bundledInput(side.ordinal())
|
||||
val newBundledInput = computeBundledInput(side)
|
||||
val oldMaxValue = ownBundledInput.max
|
||||
var changed = false
|
||||
if (newBundledInput != null) for (color <- 0 until 16) {
|
||||
changed = changed || (oldBundledInput(color) >= 0 && oldBundledInput(color) != newBundledInput(color))
|
||||
oldBundledInput(color) = newBundledInput(color)
|
||||
changed = changed || (ownBundledInput(color) >= 0 && ownBundledInput(color) != newBundledInput(color))
|
||||
ownBundledInput(color) = newBundledInput(color)
|
||||
}
|
||||
else for (color <- 0 until 16) {
|
||||
changed = changed || oldBundledInput(color) > 0
|
||||
oldBundledInput(color) = 0
|
||||
changed = changed || ownBundledInput(color) > 0
|
||||
ownBundledInput(color) = 0
|
||||
}
|
||||
if (changed) {
|
||||
onRedstoneInputChanged(side)
|
||||
onRedstoneInputChanged(side, oldMaxValue, ownBundledInput.max)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,9 +180,9 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
|
||||
checkRedstoneInputChanged()
|
||||
}
|
||||
|
||||
override protected def onRedstoneInputChanged(side: EnumFacing) {
|
||||
super.onRedstoneInputChanged(side)
|
||||
machine.signal("redstone_changed", machine.node.address, Int.box(toLocal(side).ordinal()))
|
||||
override protected def onRedstoneInputChanged(side: EnumFacing, oldMaxValue: Int, newMaxValue: Int) {
|
||||
super.onRedstoneInputChanged(side, oldMaxValue, newMaxValue)
|
||||
machine.node.sendToNeighbors("redstone.changed", toLocal(side), int2Integer(oldMaxValue), int2Integer(newMaxValue))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -0,0 +1,14 @@
|
||||
package li.cil.oc.common.tileentity.traits
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.inventory.IInventory
|
||||
import net.minecraft.item.ItemStack
|
||||
|
||||
// Used to get notifications from containers when a player changes a slot in
|
||||
// this inventory. Normally the player causing a setInventorySlotContents is
|
||||
// unavailable. Using this we gain access to the causing player, allowing for
|
||||
// some player-specific logic, such as the disassembler working instantaneously
|
||||
// when used by a player in creative mode.
|
||||
trait PlayerInputAware extends IInventory {
|
||||
def onSetInventorySlotContents(player: EntityPlayer, slot: Int, stack: ItemStack): Unit
|
||||
}
|
@ -84,8 +84,8 @@ trait RedstoneAware extends RotationAware /* with IConnectable with IRedstoneEmi
|
||||
val oldInput = _input(side.ordinal())
|
||||
val newInput = computeInput(side)
|
||||
_input(side.ordinal()) = newInput
|
||||
if (oldInput >= 0 && input(side) != oldInput) {
|
||||
onRedstoneInputChanged(side)
|
||||
if (oldInput >= 0 && newInput != oldInput) {
|
||||
onRedstoneInputChanged(side, oldInput, newInput)
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ trait RedstoneAware extends RotationAware /* with IConnectable with IRedstoneEmi
|
||||
}
|
||||
}
|
||||
|
||||
protected def onRedstoneInputChanged(side: EnumFacing) {}
|
||||
protected def onRedstoneInputChanged(side: EnumFacing, oldMaxValue: Int, newMaxValue: Int) {}
|
||||
|
||||
protected def onRedstoneOutputEnabledChanged() {
|
||||
world.notifyNeighborsOfStateChange(getPos, getBlockType)
|
||||
|
@ -14,7 +14,7 @@
|
||||
// @Optional.Method(modid = Mods.IDs.Mekanism)
|
||||
// def transferEnergyToAcceptor(side: EnumFacing, amount: Double) =
|
||||
// if (!Mods.Mekanism.isAvailable) 0
|
||||
// else amount - tryChangeBuffer(side, amount * Settings.get.ratioMekanism) / Settings.get.ratioMekanism
|
||||
// else tryChangeBuffer(side, amount * Settings.get.ratioMekanism) / Settings.get.ratioMekanism
|
||||
//
|
||||
// @Optional.Method(modid = Mods.IDs.Mekanism)
|
||||
// def getMaxEnergy = EnumFacing.values.map(globalBufferSize).max / Settings.get.ratioMekanism
|
||||
|
@ -21,6 +21,7 @@ object Mods {
|
||||
|
||||
val AppliedEnergistics2 = new SimpleMod(IDs.AppliedEnergistics2, version = "@[rv1,)", providesPower = true)
|
||||
val BattleGear2 = new SimpleMod(IDs.BattleGear2)
|
||||
val BloodMagic = new SimpleMod(IDs.BloodMagic)
|
||||
val BuildCraft = new SimpleMod(IDs.BuildCraft)
|
||||
val BuildCraftTiles = new SimpleMod(IDs.BuildCraftTiles)
|
||||
val BuildCraftTools = new SimpleMod(IDs.BuildCraftTools)
|
||||
@ -71,37 +72,38 @@ object Mods {
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
val Proxies = Array(
|
||||
// integration.appeng.ModAppEng,
|
||||
// integration.buildcraft.tools.ModBuildCraftAPITools,
|
||||
// integration.buildcraft.tiles.ModBuildCraftAPITiles,
|
||||
// integration.buildcraft.transport.ModBuildCraftAPITransport,
|
||||
// integration.cofh.energy.ModCoFHEnergy,
|
||||
// integration.cofh.item.ModCoFHItem,
|
||||
// integration.cofh.tileentity.ModCoFHTileEntity,
|
||||
// integration.cofh.transport.ModCoFHTransport,
|
||||
// integration.enderstorage.ModEnderStorage,
|
||||
// integration.forestry.ModForestry,
|
||||
// integration.fmp.ModForgeMultipart,
|
||||
// integration.gc.ModGalacticraft,
|
||||
// integration.gregtech.ModGregtech,
|
||||
// integration.ic2.ModIndustrialCraft2,
|
||||
// integration.mfr.ModMineFactoryReloaded,
|
||||
// integration.mystcraft.ModMystcraft,
|
||||
// integration.railcraft.ModRailcraft,
|
||||
// integration.stargatetech2.ModStargateTech2,
|
||||
// integration.thaumcraft.ModThaumcraft,
|
||||
// integration.thermalexpansion.ModThermalExpansion,
|
||||
// integration.tcon.ModTinkersConstruct,
|
||||
// integration.tmechworks.ModTMechworks,
|
||||
// integration.appeng.ModAppEng,
|
||||
// integration.bloodmagic.ModBloodMagic,
|
||||
// integration.buildcraft.tools.ModBuildCraftAPITools,
|
||||
// integration.buildcraft.tiles.ModBuildCraftAPITiles,
|
||||
// integration.buildcraft.transport.ModBuildCraftAPITransport,
|
||||
// integration.cofh.energy.ModCoFHEnergy,
|
||||
// integration.cofh.item.ModCoFHItem,
|
||||
// integration.cofh.tileentity.ModCoFHTileEntity,
|
||||
// integration.cofh.transport.ModCoFHTransport,
|
||||
// integration.enderstorage.ModEnderStorage,
|
||||
// integration.forestry.ModForestry,
|
||||
// integration.fmp.ModForgeMultipart,
|
||||
// integration.gc.ModGalacticraft,
|
||||
// integration.gregtech.ModGregtech,
|
||||
// integration.ic2.ModIndustrialCraft2,
|
||||
// integration.mfr.ModMineFactoryReloaded,
|
||||
// integration.mystcraft.ModMystcraft,
|
||||
// integration.railcraft.ModRailcraft,
|
||||
// integration.stargatetech2.ModStargateTech2,
|
||||
// integration.thaumcraft.ModThaumcraft,
|
||||
// integration.thermalexpansion.ModThermalExpansion,
|
||||
// integration.tcon.ModTinkersConstruct,
|
||||
// integration.tmechworks.ModTMechworks,
|
||||
integration.vanilla.ModVanilla,
|
||||
// integration.versionchecker.ModVersionChecker,
|
||||
// integration.waila.ModWaila,
|
||||
// integration.wrcbe.ModWRCBE,
|
||||
// integration.wrsve.ModWRSVE,
|
||||
// integration.versionchecker.ModVersionChecker,
|
||||
// integration.waila.ModWaila,
|
||||
// integration.wrcbe.ModWRCBE,
|
||||
// integration.wrsve.ModWRSVE,
|
||||
|
||||
// // Register the general IPeripheral driver last, if at all, to avoid it
|
||||
// // being used rather than other more concrete implementations.
|
||||
// integration.computercraft.ModComputerCraft,
|
||||
// // Register the general IPeripheral driver last, if at all, to avoid it
|
||||
// // being used rather than other more concrete implementations.
|
||||
// integration.computercraft.ModComputerCraft,
|
||||
|
||||
// We go last to ensure all other mod integration is done, e.g. to
|
||||
// allow properly checking if wireless redstone is present.
|
||||
@ -111,7 +113,7 @@ object Mods {
|
||||
def init(): Unit = {
|
||||
for (proxy <- Proxies) {
|
||||
tryInit(proxy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def tryInit(mod: ModProxy) {
|
||||
@ -131,6 +133,7 @@ object Mods {
|
||||
object IDs {
|
||||
final val AppliedEnergistics2 = "appliedenergistics2"
|
||||
final val BattleGear2 = "battlegear2"
|
||||
final val BloodMagic = "AWWayofTime"
|
||||
final val BuildCraft = "BuildCraft|Core"
|
||||
final val BuildCraftPower = "BuildCraftAPI|power"
|
||||
final val BuildCraftTiles = "BuildCraftAPI|tiles"
|
||||
|
@ -1,11 +1,15 @@
|
||||
package li.cil.oc.integration.appeng
|
||||
|
||||
import appeng.api.AEApi
|
||||
import appeng.api.config.Actionable
|
||||
import appeng.api.networking.crafting.ICraftingLink
|
||||
import appeng.api.networking.crafting.ICraftingRequester
|
||||
import appeng.api.networking.security.IActionHost
|
||||
import appeng.api.networking.security.MachineSource
|
||||
import appeng.api.storage.data.IAEItemStack
|
||||
import appeng.core.Api
|
||||
import appeng.me.helpers.IGridProxyable
|
||||
import appeng.tile.misc.TileInterface
|
||||
import appeng.tile.networking.TileController
|
||||
import appeng.util.item.AEItemStack
|
||||
import com.google.common.collect.ImmutableSet
|
||||
@ -25,6 +29,7 @@ import li.cil.oc.util.ResultWrapper._
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.DimensionManager
|
||||
import net.minecraftforge.common.util.Constants.NBT
|
||||
@ -37,19 +42,30 @@ import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Future
|
||||
|
||||
object DriverController extends DriverTileEntity with EnvironmentAware {
|
||||
def getTileEntityClass = classOf[TileController]
|
||||
private type AETile = TileEntity with IGridProxyable with IActionHost
|
||||
|
||||
def getTileEntityClass = {
|
||||
if (AEApi.instance != null && AEApi.instance.blocks != null) {
|
||||
if (AEApi.instance.blocks.blockController != null && AEApi.instance.blocks.blockController.item != null)
|
||||
classOf[TileController]
|
||||
else
|
||||
classOf[TileInterface]
|
||||
}
|
||||
else null
|
||||
}
|
||||
|
||||
def createEnvironment(world: World, x: Int, y: Int, z: Int): ManagedEnvironment =
|
||||
new Environment(world.getTileEntity(x, y, z).asInstanceOf[TileController])
|
||||
new Environment(world.getTileEntity(x, y, z).asInstanceOf[AETile])
|
||||
|
||||
override def providedEnvironment(stack: ItemStack) =
|
||||
if (stack != null &&
|
||||
Api.instance != null &&
|
||||
Api.instance.blocks != null &&
|
||||
Api.instance.blocks.blockController != null &&
|
||||
Block.getBlockFromItem(stack.getItem) == Api.instance.blocks.blockController.block) classOf[Environment] else null
|
||||
AEApi.instance != null &&
|
||||
AEApi.instance.blocks != null &&
|
||||
AEApi.instance.blocks.blockController != null &&
|
||||
Block.getBlockFromItem(stack.getItem) == AEApi.instance.blocks.blockController.block) classOf[Environment]
|
||||
else null
|
||||
|
||||
class Environment(tileEntity: TileController) extends ManagedTileEntityEnvironment[TileController](tileEntity, "me_controller") with NamedBlock {
|
||||
class Environment(tileEntity: AETile) extends ManagedTileEntityEnvironment[AETile](tileEntity, "me_controller") with NamedBlock {
|
||||
override def preferredName = "me_controller"
|
||||
|
||||
override def priority = 0
|
||||
@ -63,9 +79,17 @@ object DriverController extends DriverTileEntity with EnvironmentAware {
|
||||
"busy" -> cpu.isBusy)))
|
||||
|
||||
@Callback(doc = "function():table -- Get a list of known item recipes. These can be used to issue crafting requests.")
|
||||
def getCraftables(context: Context, args: Arguments): Array[AnyRef] =
|
||||
def getCraftables(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
result(tileEntity.getProxy.getStorage.getItemInventory.getStorageList.
|
||||
filter(_.isCraftable).map(new Craftable(tileEntity, _)).toArray)
|
||||
filter(_.isCraftable).map(stack => {
|
||||
val patterns = tileEntity.getProxy.getCrafting.getCraftingFor(stack, null, 0, tileEntity.getWorldObj)
|
||||
val result = patterns.find(pattern => pattern.getOutputs.exists(_.isSameType(stack))) match {
|
||||
case Some(pattern) => pattern.getOutputs.find(_.isSameType(stack)).get
|
||||
case _ => stack.copy.setStackSize(0) // Should not be possible, but hey...
|
||||
}
|
||||
new Craftable(tileEntity, result)
|
||||
}).toArray)
|
||||
}
|
||||
|
||||
@Callback(doc = "function():table -- Get a list of the stored items in the network.")
|
||||
def getItemsInNetwork(context: Context, args: Arguments): Array[AnyRef] =
|
||||
@ -96,7 +120,7 @@ object DriverController extends DriverTileEntity with EnvironmentAware {
|
||||
result(tileEntity.getProxy.getEnergy.getStoredPower)
|
||||
}
|
||||
|
||||
class Craftable(var controller: TileController, var stack: IAEItemStack) extends AbstractValue with ICraftingRequester {
|
||||
class Craftable(var controller: AETile, var stack: IAEItemStack) extends AbstractValue with ICraftingRequester {
|
||||
def this() = this(null, null)
|
||||
|
||||
private val links = mutable.Set.empty[ICraftingLink]
|
||||
@ -180,8 +204,8 @@ object DriverController extends DriverTileEntity with EnvironmentAware {
|
||||
EventHandler.schedule(() => {
|
||||
val world = DimensionManager.getWorld(dimension)
|
||||
val tileEntity = world.getTileEntity(x, y, z)
|
||||
if (tileEntity != null && tileEntity.isInstanceOf[TileController]) {
|
||||
controller = tileEntity.asInstanceOf[TileController]
|
||||
if (tileEntity != null && tileEntity.isInstanceOf[AETile]) {
|
||||
controller = tileEntity.asInstanceOf[AETile]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
package li.cil.oc.integration.bloodmagic;
|
||||
|
||||
import WayofTime.alchemicalWizardry.api.items.interfaces.IBloodOrb;
|
||||
import WayofTime.alchemicalWizardry.api.soulNetwork.SoulNetworkHandler;
|
||||
import li.cil.oc.api.driver.Converter;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ConverterBloodOrb implements Converter {
|
||||
@Override
|
||||
public void convert(Object value, Map<Object, Object> output) {
|
||||
if (value instanceof ItemStack) {
|
||||
final ItemStack stack = (ItemStack) value;
|
||||
final Item item = stack.getItem();
|
||||
if (item instanceof IBloodOrb) {
|
||||
final IBloodOrb bloodOrb = (IBloodOrb) item;
|
||||
final String ownerName = stack.stackTagCompound.getString("ownerName");
|
||||
final int maxOrbTier = SoulNetworkHandler.getCurrentMaxOrb(ownerName);
|
||||
output.put("ownerName", ownerName);
|
||||
output.put("networkOrbTier", maxOrbTier);
|
||||
output.put("networkEssence", SoulNetworkHandler.getCurrentEssence(ownerName));
|
||||
output.put("maxNetworkEssence", SoulNetworkHandler.getMaximumForOrbTier(maxOrbTier));
|
||||
output.put("maxEssence", bloodOrb.getMaxEssence());
|
||||
output.put("orbTier", bloodOrb.getOrbLevel());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package li.cil.oc.integration.bloodmagic;
|
||||
|
||||
import li.cil.oc.api.driver.NamedBlock;
|
||||
import li.cil.oc.api.machine.Arguments;
|
||||
import li.cil.oc.api.machine.Callback;
|
||||
import li.cil.oc.api.machine.Context;
|
||||
import li.cil.oc.api.network.ManagedEnvironment;
|
||||
import li.cil.oc.api.prefab.DriverTileEntity;
|
||||
import li.cil.oc.integration.ManagedTileEntityEnvironment;
|
||||
import net.minecraft.world.World;
|
||||
import WayofTime.alchemicalWizardry.api.tile.IBloodAltar;
|
||||
|
||||
public class DriverBloodAltar extends DriverTileEntity {
|
||||
@Override
|
||||
public Class<?> getTileEntityClass() {
|
||||
return IBloodAltar.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedEnvironment createEnvironment(World world, int x, int y, int z) {
|
||||
return new Environment((IBloodAltar) world.getTileEntity(x, y, z));
|
||||
}
|
||||
|
||||
public static final class Environment extends ManagedTileEntityEnvironment<IBloodAltar> implements NamedBlock {
|
||||
public Environment(final IBloodAltar tileEntity) {
|
||||
super(tileEntity, "blood_altar");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String preferredName() {
|
||||
return "blood_altar";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Get the capacity.")
|
||||
public Object[] getCapacity(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.getCapacity()};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Get the amount of blood currently contained by this altar.")
|
||||
public Object[] getCurrentBlood(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.getCurrentBlood()};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Get the current tier.")
|
||||
public Object[] getTier(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.getTier()};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Get the progress.")
|
||||
public Object[] getProgress(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.getProgress()};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Get the sacrifice multiplier.")
|
||||
public Object[] getSacrificeMultiplier(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.getCapacity()};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Get the self sacrifice multiplier.")
|
||||
public Object[] getSelfSacrificeMultiplier(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.getSelfSacrificeMultiplier()};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Get the orb multiplier.")
|
||||
public Object[] getOrbMultiplier(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.getOrbMultiplier()};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Get the dislocation multiplier.")
|
||||
public Object[] getDislocationMultiplier(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.getDislocationMultiplier()};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package li.cil.oc.integration.bloodmagic;
|
||||
|
||||
import WayofTime.alchemicalWizardry.api.rituals.IMasterRitualStone;
|
||||
import WayofTime.alchemicalWizardry.common.tileEntity.TEMasterStone;
|
||||
import li.cil.oc.api.driver.NamedBlock;
|
||||
import li.cil.oc.api.machine.Arguments;
|
||||
import li.cil.oc.api.machine.Callback;
|
||||
import li.cil.oc.api.machine.Context;
|
||||
import li.cil.oc.api.network.ManagedEnvironment;
|
||||
import li.cil.oc.api.prefab.DriverTileEntity;
|
||||
import li.cil.oc.integration.ManagedTileEntityEnvironment;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class DriverMasterRitualStone extends DriverTileEntity {
|
||||
@Override
|
||||
public Class<?> getTileEntityClass() {
|
||||
return IMasterRitualStone.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedEnvironment createEnvironment(World world, int x, int y, int z) {
|
||||
return new Environment((IMasterRitualStone) world.getTileEntity(x, y, z));
|
||||
}
|
||||
|
||||
public static class Environment extends ManagedTileEntityEnvironment<IMasterRitualStone> implements NamedBlock {
|
||||
public Environment(IMasterRitualStone tileEntity) {
|
||||
super(tileEntity, "master_ritual_stone");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String preferredName() {
|
||||
return "master_ritual_stone";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int priority() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Callback(doc = "function():string -- Get the name of the player owning this master ritual stone.")
|
||||
public Object[] getOwner(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.getOwner()};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():string -- Get the current ritual.")
|
||||
public Object[] getCurrentRitual(final Context context, final Arguments arguments) {
|
||||
if (tileEntity instanceof TEMasterStone) {
|
||||
TEMasterStone masterStone = (TEMasterStone) tileEntity;
|
||||
return new Object[]{masterStone.getCurrentRitual()};
|
||||
}
|
||||
return new Object[]{"internal error"};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Get the remaining cooldown.")
|
||||
public Object[] getCooldown(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.getCooldown()};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():number -- Get the running time.")
|
||||
public Object[] getRunningTime(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.getRunningTime()};
|
||||
}
|
||||
|
||||
@Callback(doc = "function():boolean -- Get whether the tanks are empty.")
|
||||
public Object[] areTanksEmpty(final Context context, final Arguments arguments) {
|
||||
return new Object[]{tileEntity.areTanksEmpty()};
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package li.cil.oc.integration.bloodmagic
|
||||
|
||||
import li.cil.oc.api.Driver
|
||||
import li.cil.oc.integration.{Mods, ModProxy}
|
||||
|
||||
object ModBloodMagic extends ModProxy {
|
||||
override def getMod = Mods.BloodMagic
|
||||
|
||||
override def initialize() {
|
||||
Driver.add(new DriverBloodAltar)
|
||||
Driver.add(new DriverMasterRitualStone)
|
||||
|
||||
Driver.add(new ConverterBloodOrb)
|
||||
}
|
||||
}
|
@ -5,13 +5,90 @@ import dan200.computercraft.api.peripheral.IComputerAccess
|
||||
import dan200.computercraft.api.peripheral.IPeripheral
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.machine.Context
|
||||
import li.cil.oc.api.network.Component
|
||||
import li.cil.oc.common.tileentity.AccessPoint
|
||||
import li.cil.oc.common.tileentity.Switch
|
||||
import li.cil.oc.util.ResultWrapper._
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
import scala.collection.convert.WrapAsJava._
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
import scala.collection.mutable
|
||||
|
||||
class SwitchPeripheral(val switch: Switch) extends IPeripheral {
|
||||
private val methods = Map[String, (IComputerAccess, ILuaContext, Array[AnyRef]) => Array[AnyRef]](
|
||||
// Generic modem methods.
|
||||
"open" -> ((computer, context, arguments) => {
|
||||
val port = checkPort(arguments, 0)
|
||||
if (switch.openPorts(computer).size >= 128)
|
||||
throw new IllegalArgumentException("too many open channels")
|
||||
result(switch.openPorts(computer).add(port))
|
||||
}),
|
||||
"isOpen" -> ((computer, context, arguments) => {
|
||||
val port = checkPort(arguments, 0)
|
||||
result(switch.openPorts(computer).contains(port))
|
||||
}),
|
||||
"close" -> ((computer, context, arguments) => {
|
||||
val port = checkPort(arguments, 0)
|
||||
result(switch.openPorts(computer).remove(port))
|
||||
}),
|
||||
"closeAll" -> ((computer, context, arguments) => {
|
||||
switch.openPorts(computer).clear()
|
||||
null
|
||||
}),
|
||||
"transmit" -> ((computer, context, arguments) => {
|
||||
val sendPort = checkPort(arguments, 0)
|
||||
val answerPort = checkPort(arguments, 1)
|
||||
val data = Seq(Int.box(answerPort)) ++ arguments.drop(2)
|
||||
val packet = api.Network.newPacket(s"cc${computer.getID}_${computer.getAttachmentName}", null, sendPort, data.toArray)
|
||||
result(switch.tryEnqueuePacket(None, packet))
|
||||
}),
|
||||
"isWireless" -> ((computer, context, arguments) => {
|
||||
result(switch.isInstanceOf[AccessPoint])
|
||||
}),
|
||||
|
||||
// Undocumented modem messages.
|
||||
"callRemote" -> ((computer, context, arguments) => {
|
||||
val address = checkString(arguments, 0)
|
||||
visibleComponents.find(_.address == address) match {
|
||||
case Some(component) =>
|
||||
val method = checkString(arguments, 1)
|
||||
val fakeContext = new CCContext(computer, context)
|
||||
component.invoke(method, fakeContext, arguments.drop(2): _*)
|
||||
case _ => null
|
||||
}
|
||||
}),
|
||||
"getMethodsRemote" -> ((computer, context, arguments) => {
|
||||
val address = checkString(arguments, 0)
|
||||
visibleComponents.find(_.address == address) match {
|
||||
case Some(component) => result(mapAsJavaMap(component.methods.zipWithIndex.map(t => (t._2 + 1, t._1)).toMap))
|
||||
case _ => null
|
||||
}
|
||||
}),
|
||||
"getNamesRemote" -> ((computer, context, arguments) => {
|
||||
result(mapAsJavaMap(visibleComponents.map(_.address).zipWithIndex.map(t => (t._2 + 1, t._1)).toMap))
|
||||
}),
|
||||
"getTypeRemote" -> ((computer, context, arguments) => {
|
||||
val address = checkString(arguments, 0)
|
||||
visibleComponents.find(_.address == address) match {
|
||||
case Some(component) => result(component.name)
|
||||
case _ => null
|
||||
}
|
||||
}),
|
||||
"isPresentRemote" -> ((computer, context, arguments) => {
|
||||
val address = checkString(arguments, 0)
|
||||
result(visibleComponents.exists(_.address == address))
|
||||
}),
|
||||
|
||||
// OC specific.
|
||||
"maxPacketSize" -> ((computer, context, arguments) => {
|
||||
result(Settings.get.maxNetworkPacketSize)
|
||||
})
|
||||
)
|
||||
|
||||
private val methodNames = methods.keys.toArray.sorted
|
||||
|
||||
override def getType = "modem"
|
||||
|
||||
override def attach(computer: IComputerAccess) {
|
||||
@ -24,34 +101,9 @@ class SwitchPeripheral(val switch: Switch) extends IPeripheral {
|
||||
switch.openPorts -= computer
|
||||
}
|
||||
|
||||
override def getMethodNames = Array("open", "isOpen", "close", "closeAll", "maxPacketSize", "transmit", "isWireless")
|
||||
override def getMethodNames = methodNames
|
||||
|
||||
override def callMethod(computer: IComputerAccess, context: ILuaContext, method: Int, arguments: Array[AnyRef]) = getMethodNames()(method) match {
|
||||
case "open" =>
|
||||
val port = checkPort(arguments, 0)
|
||||
if (switch.openPorts(computer).size >= 128)
|
||||
throw new IllegalArgumentException("too many open channels")
|
||||
result(switch.openPorts(computer).add(port))
|
||||
case "isOpen" =>
|
||||
val port = checkPort(arguments, 0)
|
||||
result(switch.openPorts(computer).contains(port))
|
||||
case "close" =>
|
||||
val port = checkPort(arguments, 0)
|
||||
result(switch.openPorts(computer).remove(port))
|
||||
case "closeAll" =>
|
||||
switch.openPorts(computer).clear()
|
||||
null
|
||||
case "maxPacketSize" =>
|
||||
result(Settings.get.maxNetworkPacketSize)
|
||||
case "transmit" =>
|
||||
val sendPort = checkPort(arguments, 0)
|
||||
val answerPort = checkPort(arguments, 1)
|
||||
val data = Seq(Int.box(answerPort)) ++ arguments.drop(2)
|
||||
val packet = api.Network.newPacket(s"cc${computer.getID}_${computer.getAttachmentName}", null, sendPort, data.toArray)
|
||||
result(switch.tryEnqueuePacket(None, packet))
|
||||
case "isWireless" => result(switch.isInstanceOf[AccessPoint])
|
||||
case _ => null
|
||||
}
|
||||
override def callMethod(computer: IComputerAccess, context: ILuaContext, method: Int, arguments: Array[AnyRef]) = methods(methodNames(method))(computer, context, arguments)
|
||||
|
||||
override def equals(other: IPeripheral) = other match {
|
||||
case peripheral: SwitchPeripheral => peripheral.switch == switch
|
||||
@ -66,4 +118,41 @@ class SwitchPeripheral(val switch: Switch) extends IPeripheral {
|
||||
throw new IllegalArgumentException(s"bad argument #${index + 1} (number in [1, 65535] expected)")
|
||||
port
|
||||
}
|
||||
|
||||
private def checkString(args: Array[AnyRef], index: Int) = {
|
||||
if (args.length < index - 1 || !args(index).isInstanceOf[String])
|
||||
throw new IllegalArgumentException(s"bad argument #${index + 1} (string expected)")
|
||||
args(index).asInstanceOf[String]
|
||||
}
|
||||
|
||||
private def visibleComponents = {
|
||||
ForgeDirection.VALID_DIRECTIONS.flatMap(side => {
|
||||
val node = switch.sidedNode(side)
|
||||
node.reachableNodes.collect {
|
||||
case component: Component if component.canBeSeenFrom(node) => component
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
class CCContext(val computer: IComputerAccess, val context: ILuaContext) extends Context {
|
||||
override def node() = switch.node
|
||||
|
||||
override def isPaused = false
|
||||
|
||||
override def stop() = false
|
||||
|
||||
override def canInteract(player: String) = true
|
||||
|
||||
override def signal(name: String, args: AnyRef*) = {
|
||||
computer.queueEvent(name, args.toArray)
|
||||
true
|
||||
}
|
||||
|
||||
override def pause(seconds: Double) = false
|
||||
|
||||
override def isRunning = true
|
||||
|
||||
override def start() = false
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ object DriverBlockEnvironments extends driver.Block with EnvironmentAware {
|
||||
else if (isOneOf(block.getBlock, "case1", "case2", "case3", "caseCreative", "microcontroller")) classOf[Machine]
|
||||
else if (isOneOf(block.getBlock, "hologram1", "hologram2")) classOf[tileentity.Hologram]
|
||||
else if (isOneOf(block.getBlock, "motionSensor")) classOf[tileentity.MotionSensor]
|
||||
else if (isOneOf(block.getBlock, "redstone")) if (BundledRedstone.isAvailable) classOf[component.Redstone.Bundled] else classOf[component.Redstone.Simple]
|
||||
else if (isOneOf(block.getBlock, "redstone")) if (BundledRedstone.isAvailable) classOf[component.Redstone.Bundled] else classOf[component.Redstone.Vanilla]
|
||||
else if (isOneOf(block.getBlock, "screen1")) classOf[common.component.TextBuffer].asInstanceOf[Class[_ <: Environment]]
|
||||
else if (isOneOf(block.getBlock, "screen2", "screen3")) classOf[common.component.Screen]
|
||||
else if (isOneOf(block.getBlock, "robot")) classOf[component.robot.Robot].asInstanceOf[Class[_ <: Environment]]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user