mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-17 11:15:12 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8.9
# Conflicts: # build.gradle # build.properties # src/main/java/li/cil/oc/api/Driver.java # src/main/java/li/cil/oc/api/detail/DriverAPI.java # src/main/scala/li/cil/oc/client/Textures.scala # src/main/scala/li/cil/oc/client/renderer/PetRenderer.scala # src/main/scala/li/cil/oc/client/renderer/item/HoverBootRenderer.scala # src/main/scala/li/cil/oc/common/item/HoverBoots.scala # src/main/scala/li/cil/oc/integration/Mods.scala # src/main/scala/li/cil/oc/server/driver/CompoundBlockDriver.scala # src/main/scala/li/cil/oc/server/driver/Registry.scala
This commit is contained in:
commit
338666235b
@ -164,6 +164,10 @@ repositories {
|
|||||||
name 'ExtraCells'
|
name 'ExtraCells'
|
||||||
artifactPattern "http://addons-origin.cursecdn.com/files/${config.ec.cf}/[module]-[revision].[ext]"
|
artifactPattern "http://addons-origin.cursecdn.com/files/${config.ec.cf}/[module]-[revision].[ext]"
|
||||||
}
|
}
|
||||||
|
ivy {
|
||||||
|
name 'ThaumicEnergistics'
|
||||||
|
artifactPattern "http://addons-origin.cursecdn.com/files/${config.thaumicenergistics.cf}/[module]-[revision].[ext]"
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,6 +218,7 @@ dependencies {
|
|||||||
provided name: 'Railcraft', version: config.rc.version, ext: 'jar'
|
provided name: 'Railcraft', version: config.rc.version, ext: 'jar'
|
||||||
provided name: 'BloodMagic', version: config.bloodmagic.version, ext: 'jar'
|
provided name: 'BloodMagic', version: config.bloodmagic.version, ext: 'jar'
|
||||||
provided name: 'ExtraCells', version: config.ec.version, ext: 'jar'
|
provided name: 'ExtraCells', version: config.ec.version, ext: 'jar'
|
||||||
|
provided name: 'ThaumicEnergistics', version: config.thaumicenergistics.version, ext: 'jar'
|
||||||
provided "cyano.poweradvantage:PowerAdvantage-API:${config.poweradvantage.version}"
|
provided "cyano.poweradvantage:PowerAdvantage-API:${config.poweradvantage.version}"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -43,6 +43,8 @@ rc.cf=2219/321
|
|||||||
rc.version=1.7.10-9.4.0.0
|
rc.version=1.7.10-9.4.0.0
|
||||||
redlogic.version=59.0.3
|
redlogic.version=59.0.3
|
||||||
rotc.version=V5c
|
rotc.version=V5c
|
||||||
|
thaumicenergistics.cf=2277/520
|
||||||
|
thaumicenergistics.version=1.0.0.1-RV2
|
||||||
tis3d.version=MC1.8.9-0.8.0.2
|
tis3d.version=MC1.8.9-0.8.0.2
|
||||||
tmech.version=75.0afb56c
|
tmech.version=75.0afb56c
|
||||||
re.version=3.0.0.342
|
re.version=3.0.0.342
|
||||||
|
@ -5,11 +5,13 @@ import li.cil.oc.api.driver.Converter;
|
|||||||
import li.cil.oc.api.driver.EnvironmentProvider;
|
import li.cil.oc.api.driver.EnvironmentProvider;
|
||||||
import li.cil.oc.api.driver.InventoryProvider;
|
import li.cil.oc.api.driver.InventoryProvider;
|
||||||
import li.cil.oc.api.driver.Item;
|
import li.cil.oc.api.driver.Item;
|
||||||
|
import li.cil.oc.api.driver.SidedBlock;
|
||||||
import li.cil.oc.api.network.EnvironmentHost;
|
import li.cil.oc.api.network.EnvironmentHost;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.inventory.IInventory;
|
import net.minecraft.inventory.IInventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.BlockPos;
|
import net.minecraft.util.BlockPos;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -28,7 +30,7 @@ import java.util.Collection;
|
|||||||
* at that time. Only start calling these methods in the init phase or later.
|
* at that time. Only start calling these methods in the init phase or later.
|
||||||
*
|
*
|
||||||
* @see Network
|
* @see Network
|
||||||
* @see Block
|
* @see SidedBlock
|
||||||
* @see Item
|
* @see Item
|
||||||
*/
|
*/
|
||||||
public final class Driver {
|
public final class Driver {
|
||||||
@ -43,12 +45,31 @@ public final class Driver {
|
|||||||
* phases.
|
* phases.
|
||||||
*
|
*
|
||||||
* @param driver the driver to register.
|
* @param driver the driver to register.
|
||||||
|
* @deprecated Use {@link SidedBlock} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated // TODO Remove in OC 1.7
|
||||||
public static void add(final Block driver) {
|
public static void add(final Block driver) {
|
||||||
if (API.driver != null)
|
if (API.driver != null)
|
||||||
API.driver.add(driver);
|
API.driver.add(driver);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new side-aware block driver.
|
||||||
|
* <p/>
|
||||||
|
* Whenever the neighboring blocks of an Adapter block change, it checks if
|
||||||
|
* there exists a driver for the changed block, and if it is configured to
|
||||||
|
* interface that block type connects it to the component network.
|
||||||
|
* <p/>
|
||||||
|
* This must be called in the init phase, <em>not</em> the pre- or post-init
|
||||||
|
* phases.
|
||||||
|
*
|
||||||
|
* @param driver the driver to register.
|
||||||
|
*/
|
||||||
|
public static void add(final SidedBlock driver) {
|
||||||
|
if (API.driver != null)
|
||||||
|
API.driver.add(driver);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a new item driver.
|
* Registers a new item driver.
|
||||||
* <p/>
|
* <p/>
|
||||||
@ -121,13 +142,35 @@ public final class Driver {
|
|||||||
* @param world the world containing the block.
|
* @param world the world containing the block.
|
||||||
* @param pos the position of the block.
|
* @param pos the position of the block.
|
||||||
* @return a driver for the block, or <tt>null</tt> if there is none.
|
* @return a driver for the block, or <tt>null</tt> if there is none.
|
||||||
|
* @deprecated Use {@link #driverFor(World, BlockPos, EnumFacing)},
|
||||||
|
* passing <tt>null</tt> if the side is to be ignored.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated // TODO Remove in OC 1.7
|
||||||
public static Block driverFor(World world, BlockPos pos) {
|
public static Block driverFor(World world, BlockPos pos) {
|
||||||
if (API.driver != null)
|
if (API.driver != null)
|
||||||
return API.driver.driverFor(world, pos);
|
return API.driver.driverFor(world, pos);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up a driver for the block at the specified position in the
|
||||||
|
* specified world.
|
||||||
|
* <p/>
|
||||||
|
* Note that several drivers for a single block can exist. Because of this
|
||||||
|
* block drivers are always encapsulated in a 'compound' driver, which is
|
||||||
|
* what will be returned here. In other words, you should will <em>not</em>
|
||||||
|
* get actual instances of drivers registered via {@link #add(li.cil.oc.api.driver.Block)}.
|
||||||
|
*
|
||||||
|
* @param world the world containing the block.
|
||||||
|
* @param pos the position of the block.
|
||||||
|
* @return a driver for the block, or <tt>null</tt> if there is none.
|
||||||
|
*/
|
||||||
|
public static SidedBlock driverFor(World world, BlockPos pos, EnumFacing side) {
|
||||||
|
if (API.driver != null)
|
||||||
|
return API.driver.driverFor(world, pos, side);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up a driver for the specified item stack.
|
* Looks up a driver for the specified item stack.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -5,11 +5,13 @@ import li.cil.oc.api.driver.Converter;
|
|||||||
import li.cil.oc.api.driver.EnvironmentProvider;
|
import li.cil.oc.api.driver.EnvironmentProvider;
|
||||||
import li.cil.oc.api.driver.InventoryProvider;
|
import li.cil.oc.api.driver.InventoryProvider;
|
||||||
import li.cil.oc.api.driver.Item;
|
import li.cil.oc.api.driver.Item;
|
||||||
|
import li.cil.oc.api.driver.SidedBlock;
|
||||||
import li.cil.oc.api.network.EnvironmentHost;
|
import li.cil.oc.api.network.EnvironmentHost;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.inventory.IInventory;
|
import net.minecraft.inventory.IInventory;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.BlockPos;
|
import net.minecraft.util.BlockPos;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -26,9 +28,25 @@ public interface DriverAPI {
|
|||||||
* phases.
|
* phases.
|
||||||
*
|
*
|
||||||
* @param driver the driver for a block component.
|
* @param driver the driver for a block component.
|
||||||
|
* @deprecated Use {@link SidedBlock} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated // TODO Remove in OC 1.7
|
||||||
void add(Block driver);
|
void add(Block driver);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new side-aware block driver.
|
||||||
|
* <p/>
|
||||||
|
* Whenever the neighboring blocks of an Adapter block change, it checks if
|
||||||
|
* there exists a driver for the changed block, and if it is configured to
|
||||||
|
* interface that block type connects it to the component network.
|
||||||
|
* <p/>
|
||||||
|
* This must be called in the init phase, <em>not</em> the pre- or post-init
|
||||||
|
* phases.
|
||||||
|
*
|
||||||
|
* @param driver the driver to register.
|
||||||
|
*/
|
||||||
|
void add(SidedBlock driver);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers a new driver for an item component.
|
* Registers a new driver for an item component.
|
||||||
* <p/>
|
* <p/>
|
||||||
@ -89,9 +107,28 @@ public interface DriverAPI {
|
|||||||
* @param world the world containing the block.
|
* @param world the world containing the block.
|
||||||
* @param pos the position of the block.
|
* @param pos the position of the block.
|
||||||
* @return a driver for the block, or <tt>null</tt> if there is none.
|
* @return a driver for the block, or <tt>null</tt> if there is none.
|
||||||
|
* @deprecated Use {@link #driverFor(World, BlockPos, EnumFacing)},
|
||||||
|
* passing <tt>null</tt> if the side is to be ignored.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated // TODO Remove in OC 1.7
|
||||||
Block driverFor(World world, BlockPos pos);
|
Block driverFor(World world, BlockPos pos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up a driver for the block at the specified position in the
|
||||||
|
* specified world.
|
||||||
|
* <p/>
|
||||||
|
* Note that several drivers for a single block can exist. Because of this
|
||||||
|
* block drivers are always encapsulated in a 'compound' driver, which is
|
||||||
|
* what will be returned here. In other words, you should will <em>not</em>
|
||||||
|
* get actual instances of drivers registered via {@link #add(li.cil.oc.api.driver.Block)}.
|
||||||
|
*
|
||||||
|
* @param world the world containing the block.
|
||||||
|
* @param pos the position of the block.
|
||||||
|
* @param side the side of the block.
|
||||||
|
* @return a driver for the block, or <tt>null</tt> if there is none.
|
||||||
|
*/
|
||||||
|
SidedBlock driverFor(World world, BlockPos pos, EnumFacing side);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Looks up a driver for the specified item stack.
|
* Looks up a driver for the specified item stack.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -21,7 +21,11 @@ import net.minecraft.world.World;
|
|||||||
* Note that it is possible to write one driver that supports as many different
|
* Note that it is possible to write one driver that supports as many different
|
||||||
* blocks as you wish. I'd recommend writing one per device (type), though, to
|
* blocks as you wish. I'd recommend writing one per device (type), though, to
|
||||||
* keep things modular.
|
* keep things modular.
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link SidedBlock} instead, ignoring the side argument if
|
||||||
|
* the side doesn't matter.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated // TODO Remove in OC 1.7
|
||||||
public interface Block {
|
public interface Block {
|
||||||
/**
|
/**
|
||||||
* Used to determine the block types this driver handles.
|
* Used to determine the block types this driver handles.
|
||||||
|
71
src/main/java/li/cil/oc/api/driver/SidedBlock.java
Normal file
71
src/main/java/li/cil/oc/api/driver/SidedBlock.java
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package li.cil.oc.api.driver;
|
||||||
|
|
||||||
|
import li.cil.oc.api.network.ManagedEnvironment;
|
||||||
|
import net.minecraft.util.BlockPos;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for side-aware block component drivers.
|
||||||
|
* <p/>
|
||||||
|
* This driver type is used for components that are blocks, i.e. that can be
|
||||||
|
* placed in the world, but cannot be modified to or don't want to have their
|
||||||
|
* {@link net.minecraft.tileentity.TileEntity} implement one of the interfaces
|
||||||
|
* for environments ({@link li.cil.oc.api.network.Environment} or
|
||||||
|
* {@link li.cil.oc.api.network.SidedEnvironment}).
|
||||||
|
* <p/>
|
||||||
|
* A block driver is used by <tt>Adapter</tt> blocks to check its neighbors and
|
||||||
|
* whether those neighbors should be treated as components or not. If a driver
|
||||||
|
* is present, it will be used to create a {@link ManagedEnvironment} that is
|
||||||
|
* managed by the adapter.
|
||||||
|
* <p/>
|
||||||
|
* Note that it is possible to write one driver that supports as many different
|
||||||
|
* blocks as you wish. I'd recommend writing one per device (type), though, to
|
||||||
|
* keep things modular.
|
||||||
|
* </p>
|
||||||
|
* Note that side-aware block drivers are queried before regular block drivers,
|
||||||
|
* because they are more specific.
|
||||||
|
*/
|
||||||
|
public interface SidedBlock {
|
||||||
|
/**
|
||||||
|
* Used to determine the block types this driver handles.
|
||||||
|
* <p/>
|
||||||
|
* This is used to determine which driver to use for a block placed next to
|
||||||
|
* an <tt>Adapter</tt> block. Note that the return value should not change
|
||||||
|
* over time; if it does, though, an already installed component will not
|
||||||
|
* be removed, since this value is only checked when scanning blocks. You
|
||||||
|
* can force this by sending a neighbor block change notification.
|
||||||
|
* <p/>
|
||||||
|
* The side is relative to the block, i.e. "south" is the side of the block
|
||||||
|
* facing south.
|
||||||
|
*
|
||||||
|
* @param world the world in which the block to check lives.
|
||||||
|
* @param pos the position coordinate of the block to check.
|
||||||
|
* @param side the side of the block to check.
|
||||||
|
* @return <tt>true</tt> if the block is supported; <tt>false</tt> otherwise.
|
||||||
|
*/
|
||||||
|
boolean worksWith(World world, BlockPos pos, EnumFacing side);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new managed environment interfacing the specified block.
|
||||||
|
* <p/>
|
||||||
|
* This is used to connect the component to the component network when it
|
||||||
|
* is detected next to an <tt>Adapter</tt>. Components that are not part of
|
||||||
|
* the component network probably don't make much sense (can't think of any
|
||||||
|
* uses at this time), but you may still opt to not implement this - i.e.
|
||||||
|
* it is safe to return <tt>null</tt> here.
|
||||||
|
* <p/>
|
||||||
|
* This is expected to return a <em>new instance</em> each time it is
|
||||||
|
* called. The created instance's life cycle is managed by the
|
||||||
|
* <tt>Adapter</tt> block that caused its creation.
|
||||||
|
* <p/>
|
||||||
|
* The side is relative to the block, i.e. "south" is the side of the block
|
||||||
|
* facing south.
|
||||||
|
*
|
||||||
|
* @param world the world containing the block to get the environment for.
|
||||||
|
* @param pos the position coordinate of the block to check.
|
||||||
|
* @param side the side of the block to check.
|
||||||
|
* @return the environment for the block at that location.
|
||||||
|
*/
|
||||||
|
ManagedEnvironment createEnvironment(World world, BlockPos pos, EnumFacing side);
|
||||||
|
}
|
@ -1337,7 +1337,8 @@ opencomputers {
|
|||||||
# computers (such as magic related mods, which is why Thaumcraft is on this
|
# computers (such as magic related mods, which is why Thaumcraft is on this
|
||||||
# list by default.)
|
# list by default.)
|
||||||
modBlacklist: [
|
modBlacklist: [
|
||||||
"Thaumcraft"
|
"Thaumcraft",
|
||||||
|
"thaumicenergistics"
|
||||||
]
|
]
|
||||||
|
|
||||||
# A list of tile entities by class name that should NOT be accessible via
|
# A list of tile entities by class name that should NOT be accessible via
|
||||||
|
@ -9,3 +9,5 @@ Either way, these boots have a few useful properties: as long as they have power
|
|||||||
Additionally, due to always being in kind of a hovering state anyway, they allow you to seamlessly walk up steps of up to one block height. This is particularly handy when sprinting up a mountain, for example, a very commonplace fitness routine amongst Minecrafters. Or so I hear.
|
Additionally, due to always being in kind of a hovering state anyway, they allow you to seamlessly walk up steps of up to one block height. This is particularly handy when sprinting up a mountain, for example, a very commonplace fitness routine amongst Minecrafters. Or so I hear.
|
||||||
|
|
||||||
The boots can be recharged in an OpenComputers [charger](../block/charger.md) or any other such device, like the Applied Energistics 2 charger, an IndustrialCraft 2 battery box, or the Energetic Infuser from Thermal Expansion.
|
The boots can be recharged in an OpenComputers [charger](../block/charger.md) or any other such device, like the Applied Energistics 2 charger, an IndustrialCraft 2 battery box, or the Energetic Infuser from Thermal Expansion.
|
||||||
|
|
||||||
|
You can change the boots' color by crafting them with any type of dye. Akin to leather armor, it is possible to apply multiple dyes at once or in succession to create a large variety of colors. The dye can be removed again either by crafting the boots with a bucket of water or by tossing them into a cauldron.
|
||||||
|
@ -59,6 +59,11 @@ local function areEqual(path1, path2)
|
|||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local mounts = {}
|
||||||
|
for dev,path in fs.mounts() do
|
||||||
|
mounts[fs.canonical(path)] = dev
|
||||||
|
end
|
||||||
|
|
||||||
local function recurse(fromPath, toPath, origin)
|
local function recurse(fromPath, toPath, origin)
|
||||||
status(fromPath, toPath)
|
status(fromPath, toPath)
|
||||||
if fs.isDirectory(fromPath) then
|
if fs.isDirectory(fromPath) then
|
||||||
@ -66,17 +71,17 @@ local function recurse(fromPath, toPath, origin)
|
|||||||
io.write("omitting directory `" .. fromPath .. "'\n")
|
io.write("omitting directory `" .. fromPath .. "'\n")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
if fs.canonical(fs.path(toPath)):find(fs.canonical(fromPath),1,true) then
|
|
||||||
return nil, "cannot copy a directory, `" .. fromPath .. "', into itself, `" .. toPath .. "'"
|
|
||||||
end
|
|
||||||
if fs.exists(toPath) and not fs.isDirectory(toPath) then
|
if fs.exists(toPath) and not fs.isDirectory(toPath) then
|
||||||
-- my real cp always does this, even with -f, -n or -i.
|
-- my real cp always does this, even with -f, -n or -i.
|
||||||
return nil, "cannot overwrite non-directory `" .. toPath .. "' with directory `" .. fromPath .. "'"
|
return nil, "cannot overwrite non-directory `" .. toPath .. "' with directory `" .. fromPath .. "'"
|
||||||
end
|
end
|
||||||
fs.makeDirectory(toPath)
|
if options.x and origin and mounts[fs.canonical(fromPath)] then
|
||||||
if options.x and origin and fs.get(fromPath) ~= origin then
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
if fs.get(fromPath) == fs.get(toPath) and fs.canonical(fs.path(toPath)):find(fs.canonical(fromPath),1,true) then
|
||||||
|
return nil, "cannot copy a directory, `" .. fromPath .. "', into itself, `" .. toPath .. "'"
|
||||||
|
end
|
||||||
|
fs.makeDirectory(toPath)
|
||||||
for file in fs.list(fromPath) do
|
for file in fs.list(fromPath) do
|
||||||
local result, reason = recurse(fs.concat(fromPath, file), fs.concat(toPath, file), origin or fs.get(fromPath))
|
local result, reason = recurse(fs.concat(fromPath, file), fs.concat(toPath, file), origin or fs.get(fromPath))
|
||||||
if not result then
|
if not result then
|
||||||
|
@ -60,7 +60,7 @@ io.write("Installing " .. name .." to device " .. (choice.getLabel() or choice.a
|
|||||||
os.sleep(0.25)
|
os.sleep(0.25)
|
||||||
local cpPath = filesystem.concat(findMount(filesystem.get(os.getenv("_")).address), "bin/cp")
|
local cpPath = filesystem.concat(findMount(filesystem.get(os.getenv("_")).address), "bin/cp")
|
||||||
local cpOptions = "-vrx" .. (options.u and "ui " or "")
|
local cpOptions = "-vrx" .. (options.u and "ui " or "")
|
||||||
local cpSource = filesystem.concat(findMount(fromAddress), options.fromDir or "/", "*")
|
local cpSource = filesystem.concat(findMount(fromAddress), options.fromDir or "/")
|
||||||
local cpDest = findMount(choice.address) .. "/"
|
local cpDest = findMount(choice.address) .. "/"
|
||||||
local result, reason = os.execute(cpPath .. " " .. cpOptions .. " " .. cpSource .. " " .. cpDest)
|
local result, reason = os.execute(cpPath .. " " .. cpOptions .. " " .. cpSource .. " " .. cpDest)
|
||||||
if not result then
|
if not result then
|
||||||
|
@ -118,31 +118,42 @@ function text.removeEscapes(txt)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
function --[[@delayloaded-start@]] text.split(input, delimiters, dropDelims, di)
|
||||||
function --[[@delayloaded-start@]] text.split(input, delimiters, dropDelims)
|
|
||||||
checkArg(1, input, "string")
|
checkArg(1, input, "string")
|
||||||
checkArg(2, delimiters, "table")
|
checkArg(2, delimiters, "table")
|
||||||
checkArg(3, dropDelims, "boolean", "nil")
|
checkArg(3, dropDelims, "boolean", "nil")
|
||||||
|
checkArg(4, di, "number", "nil")
|
||||||
|
|
||||||
local input_table = text.internal.table_view(input)
|
if #input == 0 then return {} end
|
||||||
local delim_table = tx.select(delimiters, function(e,i,t)
|
di = di or 1
|
||||||
return text.internal.table_view(e)
|
local result = {input}
|
||||||
end)
|
if di > #delimiters then return result end
|
||||||
local parts = tx.partition(input_table, function(e,i,t)
|
|
||||||
local ns, ne = tx.first(t,delim_table,i)
|
local function add(part, index, r, s, e)
|
||||||
if not ns or dropDelims or ns == i then
|
local sub = part:sub(s,e)
|
||||||
return ns, ne
|
if #sub == 0 then return index end
|
||||||
else -- not droping delims and ns>i
|
local subs = r and text.split(sub,delimiters,dropDelims,r) or {sub}
|
||||||
return i, ns-1
|
for i=1,#subs do
|
||||||
|
table.insert(result, index+i-1, subs[i])
|
||||||
end
|
end
|
||||||
end, dropDelims)
|
return index+#subs
|
||||||
return tx.select(parts, function(e,i,t)
|
end
|
||||||
local inner = ''
|
|
||||||
tx.foreach(e, function(ee,ii,tt)
|
local i,d=1,delimiters[di]
|
||||||
inner = inner..ee
|
while true do
|
||||||
end)
|
local next = table.remove(result,i)
|
||||||
return inner
|
if not next then break end
|
||||||
end)
|
local si,ei = next:find(d)
|
||||||
|
if si and ei and ei~=0 then -- delim found
|
||||||
|
i=add(next, i, di+1, 1, si-1)
|
||||||
|
i=dropDelims and i or add(next, i, false, si, ei)
|
||||||
|
i=add(next, i, di, ei+1)
|
||||||
|
else
|
||||||
|
i=add(next, i, di+1, 1, #next)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return result
|
||||||
end --[[@delayloaded-end@]]
|
end --[[@delayloaded-end@]]
|
||||||
|
|
||||||
-----------------------------------------------------------------------------
|
-----------------------------------------------------------------------------
|
||||||
|
Binary file not shown.
After Width: | Height: | Size: 198 B |
Binary file not shown.
Before Width: | Height: | Size: 461 B After Width: | Height: | Size: 420 B |
@ -8,7 +8,6 @@ import li.cil.oc.api.event.RobotRenderEvent
|
|||||||
import li.cil.oc.client.renderer.tileentity.RobotRenderer
|
import li.cil.oc.client.renderer.tileentity.RobotRenderer
|
||||||
import li.cil.oc.util.RenderState
|
import li.cil.oc.util.RenderState
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.gui.inventory.GuiContainer
|
|
||||||
import net.minecraft.client.renderer.GlStateManager
|
import net.minecraft.client.renderer.GlStateManager
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraftforge.client.event.RenderPlayerEvent
|
import net.minecraftforge.client.event.RenderPlayerEvent
|
||||||
@ -26,16 +25,16 @@ object PetRenderer {
|
|||||||
|
|
||||||
// http://goo.gl/frLWYR
|
// http://goo.gl/frLWYR
|
||||||
private val entitledPlayers = Map(
|
private val entitledPlayers = Map(
|
||||||
"Sangar" ->(0.3, 0.9, 0.6),
|
"9f1f262f-0d68-4e13-9161-9eeaf4a0a1a8" ->(0.3, 0.9, 0.6), // Sangar
|
||||||
"Jodarion" ->(1.0, 0.0, 0.0),
|
"18f8bed4-f027-44af-8947-6a3a2317645a" ->(1.0, 0.0, 0.0), // Jodarion
|
||||||
"DaKaTotal" ->(0.5, 0.7, 1.0),
|
"36123742-2cf6-4cfc-8b65-278581b3caeb" ->(0.5, 0.7, 1.0), // DaKaTotal
|
||||||
"MichiRavencroft" ->(1.0, 0.0, 0.0),
|
"2c0c214b-96f4-4565-b513-de90d5fbc977" ->(1.0, 0.0, 0.0), // MichiRavencroft
|
||||||
"Vexatos" ->(0.18, 0.95, 0.922),
|
"f3ba6ec8-c280-4950-bb08-1fcb2eab3a9c" ->(0.18, 0.95, 0.922), // Vexatos
|
||||||
"StoneNomad" ->(0.8, 0.77, 0.75),
|
"9d636bdd-b9f4-4b80-b9ce-586ca04bd4f3" ->(0.8, 0.77, 0.75), // StoneNomad
|
||||||
"LizzyTheSiren" ->(0.3, 0.3, 1.0),
|
"23c7ed71-fb13-4abe-abe7-f355e1de6e62" ->(0.3, 0.3, 1.0), // LizzyTheSiren
|
||||||
"vifino" ->(0.2, 1.0, 0.1),
|
"076541f1-f10a-46de-a127-dfab8adfbb75" ->(0.2, 1.0, 0.1), // vifino
|
||||||
"Izaya" ->(0.0, 0.2, 0.6),
|
"e7e90198-0ccf-4662-a827-192ec8f4419d" ->(0.0, 0.2, 0.6), // Izaya
|
||||||
"Wobbo" ->(0.098, 0.471, 0.784)
|
"f514ee69-7bbb-4e46-9e94-d8176324cec2" ->(0.098, 0.471, 0.784) // Wobbo
|
||||||
)
|
)
|
||||||
|
|
||||||
private val petLocations = com.google.common.cache.CacheBuilder.newBuilder().
|
private val petLocations = com.google.common.cache.CacheBuilder.newBuilder().
|
||||||
@ -47,9 +46,9 @@ object PetRenderer {
|
|||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
def onPlayerRender(e: RenderPlayerEvent.Pre) {
|
def onPlayerRender(e: RenderPlayerEvent.Pre) {
|
||||||
val name = e.entityPlayer.getName
|
val uuid = e.entityPlayer.getUniqueID.toString
|
||||||
if (hidden.contains(name) || !entitledPlayers.contains(name)) return
|
if (hidden.contains(uuid) || !entitledPlayers.contains(uuid)) return
|
||||||
rendering = Some(entitledPlayers(name))
|
rendering = Some(entitledPlayers(uuid))
|
||||||
|
|
||||||
val worldTime = e.entityPlayer.getEntityWorld.getTotalWorldTime
|
val worldTime = e.entityPlayer.getEntityWorld.getTotalWorldTime
|
||||||
val timeJitter = e.entityPlayer.hashCode ^ 0xFF
|
val timeJitter = e.entityPlayer.hashCode ^ 0xFF
|
||||||
@ -144,8 +143,7 @@ object PetRenderer {
|
|||||||
GlStateManager.translate(0.3, -0.1, -0.2)
|
GlStateManager.translate(0.3, -0.1, -0.2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Someone please tell me a cleaner solution than this...
|
private def isForInventory = Minecraft.getMinecraft.currentScreen != null && owner == Minecraft.getMinecraft.thePlayer
|
||||||
private def isForInventory = new Exception().getStackTrace.exists(_.getClassName == classOf[GuiContainer].getName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
@ -91,6 +91,8 @@ object HoverBootRenderer extends ModelBiped {
|
|||||||
bipedRightArm.isHidden = true
|
bipedRightArm.isHidden = true
|
||||||
bipedLeftArm.isHidden = true
|
bipedLeftArm.isHidden = true
|
||||||
|
|
||||||
|
var lightColor = 0x66DD55
|
||||||
|
|
||||||
override def render(entity: Entity, f0: Float, f1: Float, f2: Float, f3: Float, f4: Float, f5: Float): Unit = {
|
override def render(entity: Entity, f0: Float, f1: Float, f2: Float, f3: Float, f4: Float, f5: Float): Unit = {
|
||||||
// Because Forge is being a dummy...
|
// Because Forge is being a dummy...
|
||||||
isSneak = entity.isSneaking
|
isSneak = entity.isSneaking
|
||||||
@ -103,10 +105,12 @@ object HoverBootRenderer extends ModelBiped {
|
|||||||
override def render(dt: Float): Unit = {
|
override def render(dt: Float): Unit = {
|
||||||
GlStateManager.pushAttrib()
|
GlStateManager.pushAttrib()
|
||||||
GlStateManager.disableLighting()
|
GlStateManager.disableLighting()
|
||||||
RenderHelper.disableStandardItemLighting()
|
|
||||||
GlStateManager.depthFunc(GL11.GL_LEQUAL)
|
GlStateManager.depthFunc(GL11.GL_LEQUAL)
|
||||||
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE)
|
GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE)
|
||||||
GlStateManager.color(0x66 / 255f, 0xDD / 255f, 0x55 / 255f)
|
val r = ((lightColor >>> 16) & 0xFF) / 255f
|
||||||
|
val g = ((lightColor >>> 8) & 0xFF) / 255f
|
||||||
|
val b = ((lightColor >>> 0) & 0xFF) / 255f
|
||||||
|
GlStateManager.color(r, g, b)
|
||||||
|
|
||||||
super.render(dt)
|
super.render(dt)
|
||||||
|
|
||||||
|
@ -3,10 +3,14 @@ package li.cil.oc.common.item
|
|||||||
import li.cil.oc.Settings
|
import li.cil.oc.Settings
|
||||||
import li.cil.oc.client.renderer.item.HoverBootRenderer
|
import li.cil.oc.client.renderer.item.HoverBootRenderer
|
||||||
import li.cil.oc.common.item.data.HoverBootsData
|
import li.cil.oc.common.item.data.HoverBootsData
|
||||||
|
import li.cil.oc.util.ItemColorizer
|
||||||
|
import net.minecraft.block.BlockCauldron
|
||||||
import net.minecraft.client.model.ModelBiped
|
import net.minecraft.client.model.ModelBiped
|
||||||
import net.minecraft.entity.Entity
|
import net.minecraft.entity.Entity
|
||||||
import net.minecraft.entity.EntityLivingBase
|
import net.minecraft.entity.EntityLivingBase
|
||||||
|
import net.minecraft.entity.item.EntityItem
|
||||||
import net.minecraft.entity.player.EntityPlayer
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
|
import net.minecraft.init.Blocks
|
||||||
import net.minecraft.item.EnumRarity
|
import net.minecraft.item.EnumRarity
|
||||||
import net.minecraft.item.ItemArmor
|
import net.minecraft.item.ItemArmor
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
@ -56,7 +60,10 @@ class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, 3) with t
|
|||||||
|
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
override def getArmorModel(entityLiving: EntityLivingBase, itemStack: ItemStack, armorSlot: Int): ModelBiped = {
|
override def getArmorModel(entityLiving: EntityLivingBase, itemStack: ItemStack, armorSlot: Int): ModelBiped = {
|
||||||
if (armorSlot == 4 - armorType) HoverBootRenderer
|
if (armorSlot == 4 - armorType) {
|
||||||
|
HoverBootRenderer.lightColor = if (ItemColorizer.hasColor(itemStack)) ItemColorizer.getColor(itemStack) else 0x66DD55
|
||||||
|
HoverBootRenderer
|
||||||
|
}
|
||||||
else super.getArmorModel(entityLiving, itemStack, armorSlot)
|
else super.getArmorModel(entityLiving, itemStack, armorSlot)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +84,29 @@ class HoverBoots extends ItemArmor(ItemArmor.ArmorMaterial.DIAMOND, 0, 3) with t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def onEntityItemUpdate(entity: EntityItem): Boolean = {
|
||||||
|
if (entity != null && entity.worldObj != null && !entity.worldObj.isRemote && ItemColorizer.hasColor(entity.getEntityItem)) {
|
||||||
|
val pos = entity.getPosition
|
||||||
|
val state = entity.worldObj.getBlockState(pos)
|
||||||
|
if (state.getBlock == Blocks.cauldron) {
|
||||||
|
val level = state.getValue(BlockCauldron.LEVEL).toInt
|
||||||
|
if (level > 0) {
|
||||||
|
ItemColorizer.removeColor(entity.getEntityItem)
|
||||||
|
entity.worldObj.setBlockState(pos, state.withProperty(BlockCauldron.LEVEL, Int.box(level - 1)), 3)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.onEntityItemUpdate(entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getColorFromItemStack(itemStack: ItemStack, pass: Int): Int = {
|
||||||
|
if (pass == 1) {
|
||||||
|
return if (ItemColorizer.hasColor(itemStack)) ItemColorizer.getColor(itemStack) else 0x66DD55
|
||||||
|
}
|
||||||
|
super.getColorFromItemStack(itemStack, pass)
|
||||||
|
}
|
||||||
|
|
||||||
override def showDurabilityBar(stack: ItemStack): Boolean = true
|
override def showDurabilityBar(stack: ItemStack): Boolean = true
|
||||||
|
|
||||||
override def getDurabilityForDisplay(stack: ItemStack): Double = {
|
override def getDurabilityForDisplay(stack: ItemStack): Double = {
|
||||||
|
86
src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala
Normal file
86
src/main/scala/li/cil/oc/common/recipe/ColorizeRecipe.scala
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package li.cil.oc.common.recipe
|
||||||
|
|
||||||
|
import li.cil.oc.util.Color
|
||||||
|
import li.cil.oc.util.ItemColorizer
|
||||||
|
import net.minecraft.entity.passive.EntitySheep
|
||||||
|
import net.minecraft.inventory.InventoryCrafting
|
||||||
|
import net.minecraft.item.Item
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author asie, Vexatos
|
||||||
|
*/
|
||||||
|
class ColorizeRecipe(target: Item, source: Array[Item] = null) extends ContainerItemAwareRecipe {
|
||||||
|
val targetItem = target
|
||||||
|
val sourceItems = if (source != null) source else Array(targetItem)
|
||||||
|
|
||||||
|
override def matches(crafting: InventoryCrafting, world: World): Boolean = {
|
||||||
|
val stacks = (0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i)))
|
||||||
|
val targets = stacks.filter(stack => sourceItems.contains(stack.getItem) || stack.getItem == targetItem)
|
||||||
|
val other = stacks.filterNot(targets.contains)
|
||||||
|
targets.size == 1 && other.nonEmpty && other.forall(Color.isDye)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getCraftingResult(crafting: InventoryCrafting): ItemStack = {
|
||||||
|
var targetStack: ItemStack = null
|
||||||
|
val color = Array[Int](0, 0, 0)
|
||||||
|
var colorCount = 0
|
||||||
|
var maximum = 0
|
||||||
|
|
||||||
|
(0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i))).foreach { stack =>
|
||||||
|
if (sourceItems.contains(stack.getItem)
|
||||||
|
|| stack.getItem == targetItem) {
|
||||||
|
targetStack = stack.copy()
|
||||||
|
targetStack.stackSize = 1
|
||||||
|
} else {
|
||||||
|
val dye = Color.findDye(stack)
|
||||||
|
if (dye.isEmpty)
|
||||||
|
return null
|
||||||
|
|
||||||
|
val itemColor = EntitySheep.func_175513_a(Color.byOreName(dye.get))
|
||||||
|
val red = (itemColor(0) * 255.0F).toInt
|
||||||
|
val green = (itemColor(1) * 255.0F).toInt
|
||||||
|
val blue = (itemColor(2) * 255.0F).toInt
|
||||||
|
maximum += Math.max(red, Math.max(green, blue))
|
||||||
|
color(0) += red
|
||||||
|
color(1) += green
|
||||||
|
color(2) += blue
|
||||||
|
colorCount = colorCount + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetStack == null) return null
|
||||||
|
|
||||||
|
if (targetItem == targetStack.getItem) {
|
||||||
|
if (ItemColorizer.hasColor(targetStack)) {
|
||||||
|
val itemColor = ItemColorizer.getColor(targetStack)
|
||||||
|
val red = (itemColor >> 16 & 255).toFloat / 255.0F
|
||||||
|
val green = (itemColor >> 8 & 255).toFloat / 255.0F
|
||||||
|
val blue = (itemColor & 255).toFloat / 255.0F
|
||||||
|
maximum = (maximum.toFloat + Math.max(red, Math.max(green, blue)) * 255.0F).toInt
|
||||||
|
color(0) = (color(0).toFloat + red * 255.0F).toInt
|
||||||
|
color(1) = (color(1).toFloat + green * 255.0F).toInt
|
||||||
|
color(2) = (color(2).toFloat + blue * 255.0F).toInt
|
||||||
|
colorCount = colorCount + 1
|
||||||
|
}
|
||||||
|
} else if (sourceItems.contains(targetStack.getItem)) {
|
||||||
|
targetStack = new ItemStack(targetItem, targetStack.stackSize, targetStack.getItemDamage)
|
||||||
|
}
|
||||||
|
|
||||||
|
var red = color(0) / colorCount
|
||||||
|
var green = color(1) / colorCount
|
||||||
|
var blue = color(2) / colorCount
|
||||||
|
val max = maximum.toFloat / colorCount.toFloat
|
||||||
|
val div = Math.max(red, Math.max(green, blue)).toFloat
|
||||||
|
red = (red.toFloat * max / div).toInt
|
||||||
|
green = (green.toFloat * max / div).toInt
|
||||||
|
blue = (blue.toFloat * max / div).toInt
|
||||||
|
ItemColorizer.setColor(targetStack, (red << 16) | (green << 8) | blue)
|
||||||
|
targetStack
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getRecipeSize = 10
|
||||||
|
|
||||||
|
override def getRecipeOutput = null
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package li.cil.oc.common.recipe
|
||||||
|
|
||||||
|
import net.minecraft.inventory.InventoryCrafting
|
||||||
|
import net.minecraft.item.crafting.IRecipe
|
||||||
|
|
||||||
|
trait ContainerItemAwareRecipe extends IRecipe {
|
||||||
|
override def getRemainingItems(inv: InventoryCrafting) =
|
||||||
|
(0 until inv.getSizeInventory).
|
||||||
|
map(inv.getStackInSlot).
|
||||||
|
map(net.minecraftforge.common.ForgeHooks.getContainerItem).
|
||||||
|
filter(_ != null).
|
||||||
|
toArray
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package li.cil.oc.common.recipe
|
||||||
|
|
||||||
|
import li.cil.oc.util.ItemColorizer
|
||||||
|
import net.minecraft.init.Items
|
||||||
|
import net.minecraft.inventory.InventoryCrafting
|
||||||
|
import net.minecraft.item.Item
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vexatos
|
||||||
|
*/
|
||||||
|
class DecolorizeRecipe(target: Item) extends ContainerItemAwareRecipe {
|
||||||
|
val targetItem = target
|
||||||
|
|
||||||
|
override def matches(crafting: InventoryCrafting, world: World): Boolean = {
|
||||||
|
val stacks = (0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i)))
|
||||||
|
val targets = stacks.filter(stack => stack.getItem == targetItem)
|
||||||
|
val other = stacks.filterNot(targets.contains)
|
||||||
|
targets.size == 1 && other.size == 1 && other.forall(_.getItem == Items.water_bucket)
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getCraftingResult(crafting: InventoryCrafting): ItemStack = {
|
||||||
|
var targetStack: ItemStack = null
|
||||||
|
|
||||||
|
(0 until crafting.getSizeInventory).flatMap(i => Option(crafting.getStackInSlot(i))).foreach { stack =>
|
||||||
|
if (stack.getItem == targetItem) {
|
||||||
|
targetStack = stack.copy()
|
||||||
|
targetStack.stackSize = 1
|
||||||
|
} else if (stack.getItem != Items.water_bucket) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetStack == null) return null
|
||||||
|
|
||||||
|
ItemColorizer.removeColor(targetStack)
|
||||||
|
targetStack
|
||||||
|
}
|
||||||
|
|
||||||
|
override def getRecipeSize = 10
|
||||||
|
|
||||||
|
override def getRecipeOutput = null
|
||||||
|
}
|
@ -102,6 +102,8 @@ object Recipes {
|
|||||||
def init() {
|
def init() {
|
||||||
RecipeSorter.register(Settings.namespace + "extshaped", classOf[ExtendedShapedOreRecipe], Category.SHAPED, "after:forge:shapedore")
|
RecipeSorter.register(Settings.namespace + "extshaped", classOf[ExtendedShapedOreRecipe], Category.SHAPED, "after:forge:shapedore")
|
||||||
RecipeSorter.register(Settings.namespace + "extshapeless", classOf[ExtendedShapelessOreRecipe], Category.SHAPELESS, "after:forge:shapelessore")
|
RecipeSorter.register(Settings.namespace + "extshapeless", classOf[ExtendedShapelessOreRecipe], Category.SHAPELESS, "after:forge:shapelessore")
|
||||||
|
RecipeSorter.register(Settings.namespace + "colorizer", classOf[ColorizeRecipe], Category.SHAPELESS, "after:forge:shapelessore")
|
||||||
|
RecipeSorter.register(Settings.namespace + "decolorizer", classOf[DecolorizeRecipe], Category.SHAPELESS, "after:oc:colorizer")
|
||||||
|
|
||||||
for ((name, stack) <- oreDictEntries) {
|
for ((name, stack) <- oreDictEntries) {
|
||||||
if (!OreDictionary.getOres(name).contains(stack)) {
|
if (!OreDictionary.getOres(name).contains(stack)) {
|
||||||
@ -333,6 +335,10 @@ object Recipes {
|
|||||||
api.Items.get(Constants.BlockName.AccessPoint).createItemStack(1))
|
api.Items.get(Constants.BlockName.AccessPoint).createItemStack(1))
|
||||||
GameRegistry.addShapelessRecipe(api.Items.get(Constants.BlockName.Relay).createItemStack(1),
|
GameRegistry.addShapelessRecipe(api.Items.get(Constants.BlockName.Relay).createItemStack(1),
|
||||||
api.Items.get(Constants.BlockName.Switch).createItemStack(1))
|
api.Items.get(Constants.BlockName.Switch).createItemStack(1))
|
||||||
|
|
||||||
|
// Hover Boot dyeing
|
||||||
|
GameRegistry.addRecipe(new ColorizeRecipe(api.Items.get(Constants.ItemName.HoverBoots).item()))
|
||||||
|
GameRegistry.addRecipe(new DecolorizeRecipe(api.Items.get(Constants.ItemName.HoverBoots).item()))
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
case e: Throwable => OpenComputers.log.error("Error parsing recipes, you may not be able to craft any items from this mod!", e)
|
case e: Throwable => OpenComputers.log.error("Error parsing recipes, you may not be able to craft any items from this mod!", e)
|
||||||
|
@ -78,6 +78,7 @@ object Mods {
|
|||||||
override def isModAvailable: Boolean = isModAvailable_
|
override def isModAvailable: Boolean = isModAvailable_
|
||||||
}
|
}
|
||||||
val Thaumcraft = new SimpleMod(IDs.Thaumcraft)
|
val Thaumcraft = new SimpleMod(IDs.Thaumcraft)
|
||||||
|
val ThaumicEnergistics = new SimpleMod(IDs.ThaumicEnergistics)
|
||||||
val ThermalExpansion = new SimpleMod(IDs.ThermalExpansion, providesPower = true)
|
val ThermalExpansion = new SimpleMod(IDs.ThermalExpansion, providesPower = true)
|
||||||
val TinkersConstruct = new SimpleMod(IDs.TinkersConstruct)
|
val TinkersConstruct = new SimpleMod(IDs.TinkersConstruct)
|
||||||
val TIS3D = new SimpleMod(IDs.TIS3D, version = "@[0.7,)")
|
val TIS3D = new SimpleMod(IDs.TIS3D, version = "@[0.7,)")
|
||||||
@ -125,6 +126,7 @@ object Mods {
|
|||||||
// integration.rotarycraft.ModRotaryCraft,
|
// integration.rotarycraft.ModRotaryCraft,
|
||||||
// integration.stargatetech2.ModStargateTech2,
|
// integration.stargatetech2.ModStargateTech2,
|
||||||
// integration.thaumcraft.ModThaumcraft,
|
// integration.thaumcraft.ModThaumcraft,
|
||||||
|
// integration.thaumicenergistics.ModThaumicEnergistics,
|
||||||
// integration.thermalexpansion.ModThermalExpansion,
|
// integration.thermalexpansion.ModThermalExpansion,
|
||||||
integration.tis3d.ModTIS3D,
|
integration.tis3d.ModTIS3D,
|
||||||
// integration.tcon.ModTinkersConstruct,
|
// integration.tcon.ModTinkersConstruct,
|
||||||
@ -219,6 +221,7 @@ object Mods {
|
|||||||
final val RotaryCraft = "RotaryCraft"
|
final val RotaryCraft = "RotaryCraft"
|
||||||
final val StargateTech2 = "StargateTech2"
|
final val StargateTech2 = "StargateTech2"
|
||||||
final val Thaumcraft = "Thaumcraft"
|
final val Thaumcraft = "Thaumcraft"
|
||||||
|
final val ThaumicEnergistics = "thaumicenergistics"
|
||||||
final val ThermalExpansion = "ThermalExpansion"
|
final val ThermalExpansion = "ThermalExpansion"
|
||||||
final val TinkersConstruct = "TConstruct"
|
final val TinkersConstruct = "TConstruct"
|
||||||
final val TIS3D = "tis3d"
|
final val TIS3D = "tis3d"
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
package li.cil.oc.integration.thaumicenergistics
|
||||||
|
|
||||||
|
import appeng.tile.misc.TileInterface
|
||||||
|
import li.cil.oc.api.driver.EnvironmentProvider
|
||||||
|
import li.cil.oc.api.network.ManagedEnvironment
|
||||||
|
import li.cil.oc.api.prefab.DriverTileEntity
|
||||||
|
import li.cil.oc.integration.ManagedTileEntityEnvironment
|
||||||
|
import li.cil.oc.integration.appeng.AEUtil
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
object DriverBlockInterface extends DriverTileEntity {
|
||||||
|
def getTileEntityClass: Class[_] = classOf[TileInterface]
|
||||||
|
|
||||||
|
def createEnvironment(world: World, x: Int, y: Int, z: Int): ManagedEnvironment =
|
||||||
|
new Environment(world.getTileEntity(x, y, z).asInstanceOf[TileInterface])
|
||||||
|
|
||||||
|
final class Environment(val tile: TileInterface) extends ManagedTileEntityEnvironment[TileInterface](tile, "me_interface") with NetworkControl[TileInterface]
|
||||||
|
|
||||||
|
object Provider extends EnvironmentProvider {
|
||||||
|
override def getEnvironment(stack: ItemStack): Class[_] =
|
||||||
|
if (AEUtil.isBlockInterface(stack))
|
||||||
|
classOf[Environment]
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package li.cil.oc.integration.thaumicenergistics
|
||||||
|
|
||||||
|
import appeng.api.networking.security.IActionHost
|
||||||
|
import appeng.me.helpers.IGridProxyable
|
||||||
|
import li.cil.oc.api.driver.EnvironmentProvider
|
||||||
|
import li.cil.oc.api.network.ManagedEnvironment
|
||||||
|
import li.cil.oc.api.prefab.DriverTileEntity
|
||||||
|
import li.cil.oc.integration.ManagedTileEntityEnvironment
|
||||||
|
import li.cil.oc.integration.appeng.AEUtil
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import net.minecraft.world.World
|
||||||
|
|
||||||
|
import scala.language.existentials
|
||||||
|
|
||||||
|
object DriverController extends DriverTileEntity {
|
||||||
|
private type TileController = TileEntity with IGridProxyable with IActionHost
|
||||||
|
|
||||||
|
def getTileEntityClass = AEUtil.controllerClass
|
||||||
|
|
||||||
|
def createEnvironment(world: World, x: Int, y: Int, z: Int): ManagedEnvironment =
|
||||||
|
new Environment(world.getTileEntity(x, y, z).asInstanceOf[TileController])
|
||||||
|
|
||||||
|
final class Environment(val tile: TileController) extends ManagedTileEntityEnvironment[TileController](tile, "me_controller") with NetworkControl[TileController]
|
||||||
|
|
||||||
|
object Provider extends EnvironmentProvider {
|
||||||
|
override def getEnvironment(stack: ItemStack): Class[_] =
|
||||||
|
if (AEUtil.isController(stack))
|
||||||
|
classOf[Environment]
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package li.cil.oc.integration.thaumicenergistics
|
||||||
|
|
||||||
|
import li.cil.oc.api.Driver
|
||||||
|
import li.cil.oc.integration.Mod
|
||||||
|
import li.cil.oc.integration.ModProxy
|
||||||
|
import li.cil.oc.integration.Mods
|
||||||
|
|
||||||
|
object ModThaumicEnergistics extends ModProxy {
|
||||||
|
override def getMod: Mod = Mods.ThaumicEnergistics
|
||||||
|
|
||||||
|
override def initialize(): Unit = {
|
||||||
|
Driver.add(DriverController)
|
||||||
|
Driver.add(DriverBlockInterface)
|
||||||
|
|
||||||
|
Driver.add(DriverController.Provider)
|
||||||
|
Driver.add(DriverBlockInterface.Provider)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package li.cil.oc.integration.thaumicenergistics
|
||||||
|
|
||||||
|
import appeng.api.networking.security.IActionHost
|
||||||
|
import appeng.me.helpers.IGridProxyable
|
||||||
|
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.util.ResultWrapper._
|
||||||
|
import net.minecraft.tileentity.TileEntity
|
||||||
|
import thaumicenergistics.api.IThEEssentiaGas
|
||||||
|
|
||||||
|
import scala.collection.convert.WrapAsScala._
|
||||||
|
|
||||||
|
// Note to self: this class is used by ExtraCells (and potentially others), do not rename / drastically change it.
|
||||||
|
trait NetworkControl[AETile >: Null <: TileEntity with IGridProxyable with IActionHost] {
|
||||||
|
def tile: AETile
|
||||||
|
|
||||||
|
@Callback(doc = "function():table -- Get a list of the stored essentia in the network.")
|
||||||
|
def getEssentiaInNetwork(context: Context, args: Arguments): Array[AnyRef] =
|
||||||
|
result(tile.getProxy.getStorage.getFluidInventory.getStorageList.filter(stack =>
|
||||||
|
stack.getFluid != null && stack.getFluid.isInstanceOf[IThEEssentiaGas]).
|
||||||
|
map(ThaumicEnergisticsUtils.getAspect).toArray)
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package li.cil.oc.integration.thaumicenergistics
|
||||||
|
|
||||||
|
import appeng.api.storage.data.IAEFluidStack
|
||||||
|
|
||||||
|
object ThaumicEnergisticsUtils {
|
||||||
|
def getAspect(fluid: IAEFluidStack) = {
|
||||||
|
val aspect = fluid.getFluidStack.copy()
|
||||||
|
aspect.amount = (fluid.getStackSize / 128).toInt
|
||||||
|
aspect
|
||||||
|
}
|
||||||
|
}
|
@ -27,7 +27,7 @@ class UpgradeCrafting(val host: EnvironmentHost with internal.Robot) extends pre
|
|||||||
|
|
||||||
@Callback(doc = """function([count:number]):number -- Tries to craft the specified number of items in the top left area of the inventory.""")
|
@Callback(doc = """function([count:number]):number -- Tries to craft the specified number of items in the top left area of the inventory.""")
|
||||||
def craft(context: Context, args: Arguments): Array[AnyRef] = {
|
def craft(context: Context, args: Arguments): Array[AnyRef] = {
|
||||||
val count = args.optInteger(0, Int.MaxValue)
|
val count = args.optInteger(0, 64) max 0 min 64
|
||||||
result(CraftingInventory.craft(count): _*)
|
result(CraftingInventory.craft(count): _*)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,13 +9,20 @@ import net.minecraft.item.Item
|
|||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.tileentity.TileEntity
|
import net.minecraft.tileentity.TileEntity
|
||||||
import net.minecraft.util.BlockPos
|
import net.minecraft.util.BlockPos
|
||||||
|
import net.minecraft.util.EnumFacing
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
class CompoundBlockDriver(val blocks: driver.Block*) extends driver.Block {
|
// TODO Remove blocks in OC 1.7.
|
||||||
override def createEnvironment(world: World, pos: BlockPos) = {
|
class CompoundBlockDriver(val sidedBlocks: Array[driver.SidedBlock], val blocks: Array[driver.Block]) extends driver.SidedBlock {
|
||||||
val list = blocks.map {
|
override def createEnvironment(world: World, pos: BlockPos, side: EnumFacing) = {
|
||||||
|
val list = sidedBlocks.map {
|
||||||
|
driver => Option(driver.createEnvironment(world, pos, side)) match {
|
||||||
|
case Some(environment) => (driver.getClass.getName, environment)
|
||||||
|
case _ => null
|
||||||
|
}
|
||||||
|
} ++ blocks.map {
|
||||||
driver => Option(driver.createEnvironment(world, pos)) match {
|
driver => Option(driver.createEnvironment(world, pos)) match {
|
||||||
case Some(environment) => (driver, environment)
|
case Some(environment) => (driver.getClass.getName, environment)
|
||||||
case _ => null
|
case _ => null
|
||||||
}
|
}
|
||||||
} filter (_ != null)
|
} filter (_ != null)
|
||||||
@ -23,10 +30,10 @@ class CompoundBlockDriver(val blocks: driver.Block*) extends driver.Block {
|
|||||||
else new CompoundBlockEnvironment(cleanName(tryGetName(world, pos, list.map(_._2))), list: _*)
|
else new CompoundBlockEnvironment(cleanName(tryGetName(world, pos, list.map(_._2))), list: _*)
|
||||||
}
|
}
|
||||||
|
|
||||||
override def worksWith(world: World, pos: BlockPos) = blocks.forall(_.worksWith(world, pos))
|
override def worksWith(world: World, pos: BlockPos, side: EnumFacing) = sidedBlocks.forall(_.worksWith(world, pos, side)) && blocks.forall(_.worksWith(world, pos))
|
||||||
|
|
||||||
override def equals(obj: Any) = obj match {
|
override def equals(obj: Any) = obj match {
|
||||||
case multi: CompoundBlockDriver if multi.blocks.length == blocks.length => blocks.intersect(multi.blocks).length == blocks.length
|
case multi: CompoundBlockDriver if multi.sidedBlocks.length == sidedBlocks.length && multi.blocks.length == blocks.length => sidedBlocks.intersect(multi.sidedBlocks).length == sidedBlocks.length && blocks.intersect(multi.blocks).length == blocks.length
|
||||||
case _ => false
|
case _ => false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,12 @@ import java.nio.charset.Charset
|
|||||||
import com.google.common.hash.Hashing
|
import com.google.common.hash.Hashing
|
||||||
import li.cil.oc.OpenComputers
|
import li.cil.oc.OpenComputers
|
||||||
import li.cil.oc.api
|
import li.cil.oc.api
|
||||||
import li.cil.oc.api.driver
|
|
||||||
import li.cil.oc.api.network._
|
import li.cil.oc.api.network._
|
||||||
import li.cil.oc.util.ExtendedNBT._
|
import li.cil.oc.util.ExtendedNBT._
|
||||||
import net.minecraft.nbt.NBTTagCompound
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
|
||||||
class CompoundBlockEnvironment(val name: String, val environments: (driver.Block, ManagedEnvironment)*) extends ManagedEnvironment {
|
// TODO Remove block in OC 1.7.
|
||||||
|
class CompoundBlockEnvironment(val name: String, val environments: (String, ManagedEnvironment)*) extends ManagedEnvironment {
|
||||||
// Block drivers with visibility < network usually won't make much sense,
|
// Block drivers with visibility < network usually won't make much sense,
|
||||||
// but let's play it safe and use the least possible visibility based on
|
// but let's play it safe and use the least possible visibility based on
|
||||||
// the drivers we encapsulate.
|
// the drivers we encapsulate.
|
||||||
@ -58,12 +58,11 @@ class CompoundBlockEnvironment(val name: String, val environments: (driver.Block
|
|||||||
if (nbt.hasKey("typeHash") && nbt.getLong("typeHash") != typeHash) return
|
if (nbt.hasKey("typeHash") && nbt.getLong("typeHash") != typeHash) return
|
||||||
node.load(nbt)
|
node.load(nbt)
|
||||||
for ((driver, environment) <- environments) {
|
for ((driver, environment) <- environments) {
|
||||||
val name = driver.getClass.getName
|
if (nbt.hasKey(driver)) {
|
||||||
if (nbt.hasKey(name)) {
|
|
||||||
try {
|
try {
|
||||||
environment.load(nbt.getCompoundTag(name))
|
environment.load(nbt.getCompoundTag(driver))
|
||||||
} catch {
|
} catch {
|
||||||
case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$name') threw an error while loading.", e)
|
case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$driver') threw an error while loading.", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,11 +72,10 @@ class CompoundBlockEnvironment(val name: String, val environments: (driver.Block
|
|||||||
nbt.setLong("typeHash", typeHash)
|
nbt.setLong("typeHash", typeHash)
|
||||||
node.save(nbt)
|
node.save(nbt)
|
||||||
for ((driver, environment) <- environments) {
|
for ((driver, environment) <- environments) {
|
||||||
val name = driver.getClass.getName
|
|
||||||
try {
|
try {
|
||||||
nbt.setNewCompoundTag(name, environment.save)
|
nbt.setNewCompoundTag(driver, environment.save)
|
||||||
} catch {
|
} catch {
|
||||||
case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$name') threw an error while saving.", e)
|
case e: Throwable => OpenComputers.log.warn(s"A block component of type '${environment.getClass.getName}' (provided by driver '$driver') threw an error while saving.", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,12 @@ import li.cil.oc.api.driver.InventoryProvider
|
|||||||
import li.cil.oc.api.driver.item.HostAware
|
import li.cil.oc.api.driver.item.HostAware
|
||||||
import li.cil.oc.api.machine.Value
|
import li.cil.oc.api.machine.Value
|
||||||
import li.cil.oc.api.network.EnvironmentHost
|
import li.cil.oc.api.network.EnvironmentHost
|
||||||
|
import li.cil.oc.api.network.ManagedEnvironment
|
||||||
import net.minecraft.entity.player.EntityPlayer
|
import net.minecraft.entity.player.EntityPlayer
|
||||||
import net.minecraft.inventory.IInventory
|
import net.minecraft.inventory.IInventory
|
||||||
import net.minecraft.item.ItemStack
|
import net.minecraft.item.ItemStack
|
||||||
import net.minecraft.util.BlockPos
|
import net.minecraft.util.BlockPos
|
||||||
|
import net.minecraft.util.EnumFacing
|
||||||
import net.minecraft.world.World
|
import net.minecraft.world.World
|
||||||
|
|
||||||
import scala.collection.convert.WrapAsJava._
|
import scala.collection.convert.WrapAsJava._
|
||||||
@ -38,6 +40,8 @@ import scala.math.ScalaNumber
|
|||||||
private[oc] object Registry extends api.detail.DriverAPI {
|
private[oc] object Registry extends api.detail.DriverAPI {
|
||||||
val blocks = mutable.ArrayBuffer.empty[api.driver.Block]
|
val blocks = mutable.ArrayBuffer.empty[api.driver.Block]
|
||||||
|
|
||||||
|
val sidedBlocks = mutable.ArrayBuffer.empty[api.driver.SidedBlock]
|
||||||
|
|
||||||
val items = mutable.ArrayBuffer.empty[api.driver.Item]
|
val items = mutable.ArrayBuffer.empty[api.driver.Item]
|
||||||
|
|
||||||
val converters = mutable.ArrayBuffer.empty[api.driver.Converter]
|
val converters = mutable.ArrayBuffer.empty[api.driver.Converter]
|
||||||
@ -59,9 +63,17 @@ private[oc] object Registry extends api.detail.DriverAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def add(driver: api.driver.SidedBlock) {
|
||||||
|
if (locked) throw new IllegalStateException("Please register all drivers in the init phase.")
|
||||||
|
if (!sidedBlocks.contains(driver)) {
|
||||||
|
OpenComputers.log.debug(s"Registering block driver ${driver.getClass.getName}.")
|
||||||
|
sidedBlocks += driver
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override def add(driver: api.driver.Item) {
|
override def add(driver: api.driver.Item) {
|
||||||
if (locked) throw new IllegalStateException("Please register all drivers in the init phase.")
|
if (locked) throw new IllegalStateException("Please register all drivers in the init phase.")
|
||||||
if (!blocks.contains(driver)) {
|
if (!items.contains(driver)) {
|
||||||
OpenComputers.log.debug(s"Registering item driver ${driver.getClass.getName}.")
|
OpenComputers.log.debug(s"Registering item driver ${driver.getClass.getName}.")
|
||||||
items += driver
|
items += driver
|
||||||
}
|
}
|
||||||
@ -91,9 +103,21 @@ private[oc] object Registry extends api.detail.DriverAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override def driverFor(world: World, pos: BlockPos) =
|
// TODO Remove in OC 1.7
|
||||||
blocks.filter(_.worksWith(world, pos)) match {
|
override def driverFor(world: World, pos: BlockPos) = {
|
||||||
case drivers if drivers.nonEmpty => new CompoundBlockDriver(drivers: _*)
|
driverFor(world, pos, null) match {
|
||||||
|
case driver: api.driver.SidedBlock => new api.driver.Block {
|
||||||
|
override def worksWith(world: World, pos: BlockPos): Boolean = driver.worksWith(world, pos, null)
|
||||||
|
|
||||||
|
override def createEnvironment(world: World, pos: BlockPos): ManagedEnvironment = driver.createEnvironment(world, pos, null)
|
||||||
|
}
|
||||||
|
case _ => null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override def driverFor(world: World, pos: BlockPos, side: EnumFacing): api.driver.SidedBlock =
|
||||||
|
(sidedBlocks.filter(_.worksWith(world, pos, side)), blocks.filter(_.worksWith(world, pos))) match {
|
||||||
|
case (sidedDrivers, drivers) if sidedDrivers.nonEmpty || drivers.nonEmpty => new CompoundBlockDriver(sidedDrivers.toArray, drivers.toArray)
|
||||||
case _ => null
|
case _ => null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
47
src/main/scala/li/cil/oc/util/ItemColorizer.scala
Normal file
47
src/main/scala/li/cil/oc/util/ItemColorizer.scala
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package li.cil.oc.util
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.nbt.NBTTagCompound
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author asie, Vexatos
|
||||||
|
*/
|
||||||
|
object ItemColorizer {
|
||||||
|
/**
|
||||||
|
* Return whether the specified armor ItemStack has a color.
|
||||||
|
*/
|
||||||
|
def hasColor(stack: ItemStack): Boolean = stack.hasTagCompound && stack.getTagCompound.hasKey("display") && stack.getTagCompound.getCompoundTag("display").hasKey("color")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the color for the specified armor ItemStack.
|
||||||
|
*/
|
||||||
|
def getColor(stack: ItemStack): Int = {
|
||||||
|
val tag = stack.getTagCompound
|
||||||
|
if (tag != null) {
|
||||||
|
val displayTag = tag.getCompoundTag("display")
|
||||||
|
if (displayTag == null) -1 else if (displayTag.hasKey("color")) displayTag.getInteger("color") else -1
|
||||||
|
}
|
||||||
|
else -1
|
||||||
|
}
|
||||||
|
|
||||||
|
def removeColor(stack: ItemStack) {
|
||||||
|
val tag = stack.getTagCompound
|
||||||
|
if (tag != null) {
|
||||||
|
val displayTag = tag.getCompoundTag("display")
|
||||||
|
if (displayTag.hasKey("color")) displayTag.removeTag("color")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def setColor(stack: ItemStack, color: Int) {
|
||||||
|
var tag = stack.getTagCompound
|
||||||
|
if (tag == null) {
|
||||||
|
tag = new NBTTagCompound
|
||||||
|
stack.setTagCompound(tag)
|
||||||
|
}
|
||||||
|
val displayTag = tag.getCompoundTag("display")
|
||||||
|
if (!tag.hasKey("display")) {
|
||||||
|
tag.setTag("display", displayTag)
|
||||||
|
}
|
||||||
|
displayTag.setInteger("color", color)
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user