mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-30 16:45:14 -04:00
Merge branch 'master-MC1.8' of github.com:MightyPirates/OpenComputers into OC1.5-MC1.8
Conflicts: build.properties
This commit is contained in:
commit
394962e308
Binary file not shown.
41
build.gradle
41
build.gradle
@ -78,6 +78,10 @@ repositories {
|
||||
name = "mobius"
|
||||
url = "http://mobiusstrip.eu/maven"
|
||||
}
|
||||
maven {
|
||||
name = "fallback"
|
||||
url = "http://maven.cil.li/"
|
||||
}
|
||||
/*
|
||||
maven {
|
||||
name = "BluePower"
|
||||
@ -115,7 +119,14 @@ repositories {
|
||||
name 'DVS1 Maven FS'
|
||||
url 'http://dvs1.progwml6.com/files/maven'
|
||||
}
|
||||
|
||||
maven {
|
||||
name 'ProjectRed'
|
||||
url 'http://files.projectredwiki.com/maven/'
|
||||
}
|
||||
maven {
|
||||
name 'ColoredLightCore'
|
||||
url "http://coloredlightscore.us.to/maven/clc/"
|
||||
}
|
||||
ivy {
|
||||
name "BuildCraft"
|
||||
artifactPattern "http://www.mod-buildcraft.com/releases/BuildCraft/[revision]/[module]-[revision]-[classifier].[ext]"
|
||||
@ -128,19 +139,18 @@ repositories {
|
||||
name 'Mekanism'
|
||||
artifactPattern "http://ci.cil.li/job/Mekanism/${config.mekanism.build}/artifact/output/[module]-${config.minecraft.version}-[revision].${config.mekanism.build}.[ext]"
|
||||
}
|
||||
ivy {
|
||||
name 'ProjectRed'
|
||||
artifactPattern "http://projectredwiki.com/maven/mrtjp/[module]/${config.minecraft.version}-[revision]/[module]-${config.minecraft.version}-[revision]-dev.[ext]"
|
||||
}
|
||||
ivy {
|
||||
name 'immibis'
|
||||
artifactPattern "https://dl.dropboxusercontent.com/u/2944265/mods/autobuilt/files/[module]-[revision].[ext]"
|
||||
}
|
||||
|
||||
ivy {
|
||||
name 'CoFHLib'
|
||||
artifactPattern "http://addons-origin.cursecdn.com/files/${config.cofhlib.cf}/[module]-[revision].[ext]"
|
||||
}
|
||||
ivy {
|
||||
name 'CoFHCore'
|
||||
artifactPattern "http://addons-origin.cursecdn.com/files/${config.cofhcore.cf}/[module]-[revision].[ext]"
|
||||
}
|
||||
ivy {
|
||||
name 'MineFactoryReloaded'
|
||||
artifactPattern "http://addons-origin.cursecdn.com/files/${config.mfr.cf}/[module]-[revision].[ext]"
|
||||
@ -181,7 +191,9 @@ dependencies {
|
||||
provided "mcp.mobius.waila:Waila:${config.waila.version}:dev"
|
||||
/*
|
||||
provided "appeng:RotaryCraft:${config.rotc.version}:api"
|
||||
provided "appeng:appliedenergistics2:${config.ae2.version}:dev"
|
||||
provided ("appeng:appliedenergistics2:${config.ae2.version}:dev") {
|
||||
exclude module: 'buildcraft'
|
||||
}
|
||||
provided "codechicken:EnderStorage:${config.minecraft.version}-${config.es.version}:dev"
|
||||
provided "codechicken:ForgeMultipart:${config.minecraft.version}-${config.fmp.version}:dev"
|
||||
provided "codechicken:WR-CBE:${config.minecraft.version}-${config.wrcbe.version}:dev"
|
||||
@ -195,22 +207,27 @@ dependencies {
|
||||
provided "notenoughkeys:NeK:${config.minecraft.version}-${config.nek.version}:deobf-dev"
|
||||
provided "qmunity:QmunityLib:${config.qmunitylib.version}:deobf"
|
||||
provided "tmech:TMechworks:${config.minecraft.version}-${config.tmech.version}:deobf"
|
||||
provided ("mrtjp:ProjectRed:${config.projred.version}:dev") {
|
||||
exclude module: 'CoFHCore'
|
||||
}
|
||||
provided "coloredlightscore:ColoredLightsCore:${config.coloredlights.version}:api"
|
||||
|
||||
provided name: "buildcraft", version: "${config.bc.version}", classifier: "dev", ext: 'jar'
|
||||
provided name: 'buildcraft', version: config.bc.version, classifier: "dev", ext: 'jar'
|
||||
provided name: 'GalacticraftCoreAll', version: config.gc.version, ext: 'jar'
|
||||
provided name: 'MekanismAll', version: config.mekanism.version, ext: 'jar'
|
||||
provided name: 'ProjectRed', version: config.projred.version, ext: 'jar'
|
||||
provided name: 'redlogic', version: config.redlogic.version, ext: 'jar'
|
||||
|
||||
provided name: 'CoFHLib', version: URLEncoder.encode(config.cofhlib.version, "UTF-8"), ext: 'jar'
|
||||
provided name: 'MineFactoryReloaded', version: URLEncoder.encode(config.mfr.version, "UTF-8"), ext: 'jar'
|
||||
provided name: 'CoFHLib', version: config.cofhlib.version, ext: 'jar'
|
||||
provided name: 'CoFHCore', version: config.cofhcore.version, ext: 'jar'
|
||||
provided name: 'MineFactoryReloaded', version: config.mfr.version, ext: 'jar'
|
||||
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'
|
||||
provided name: 'ExtraCells', version: config.ec.version, ext: 'jar'
|
||||
|
||||
*/
|
||||
provided "cyano.poweradvantage:PowerAdvantage-API:${config.poweradvantage.version}"
|
||||
|
||||
compile 'com.google.code.findbugs:jsr305:1.3.9' // Annotations used by google libs.
|
||||
|
||||
embedded files('libs/OpenComputers-JNLua.jar', 'libs/OpenComputers-LuaJ.jar')
|
||||
|
@ -1,7 +1,7 @@
|
||||
minecraft.version=1.8
|
||||
forge.version=11.14.3.1450
|
||||
|
||||
oc.version=1.5.13
|
||||
oc.version=1.5.14
|
||||
oc.subversion=
|
||||
|
||||
ae2.version=rv2-beta-26
|
||||
@ -15,6 +15,7 @@ ccc.version=1.0.5.34
|
||||
ccl.version=1.1.2.115
|
||||
cofhlib.cf=2230/207
|
||||
cofhlib.version=[1.7.10]1.0.0RC7-127
|
||||
coloredlights.version=1.3.7.35
|
||||
ec.cf=2242/839
|
||||
ec.version=deobf-1.7.10-2.2.73b129
|
||||
eio.cf=2219/296
|
||||
@ -33,7 +34,8 @@ mfr.cf=2229/626
|
||||
mfr.version=[1.7.10]2.8.0RC8-86
|
||||
nei.version=1.0.5.82
|
||||
nek.version=1.0.0b35dev
|
||||
projred.version=4.7.0pre2.87
|
||||
poweradvantage.version=1.2.0
|
||||
projred.version=1.7.10-4.6.2.82
|
||||
qmunitylib.version=0.1.105
|
||||
rc.cf=2219/321
|
||||
rc.version=1.7.10-9.4.0.0
|
||||
@ -43,5 +45,7 @@ tmech.version=75.0afb56c
|
||||
re.version=3.0.0.342
|
||||
waila.version=1.6.0_B1_1.8.1
|
||||
wrcbe.version=1.4.1.2
|
||||
cofhcore.cf=2246/697
|
||||
cofhcore.version=[1.7.10]3.0.3B4-302-dev
|
||||
|
||||
maven.url=file:///home/www/maven.cil.li/web
|
@ -12,7 +12,7 @@ import li.cil.oc.api.detail.*;
|
||||
*/
|
||||
public class API {
|
||||
public static final String ID_OWNER = "OpenComputers|Core";
|
||||
public static final String VERSION = "5.5.2";
|
||||
public static final String VERSION = "5.5.3";
|
||||
|
||||
public static DriverAPI driver = null;
|
||||
public static FileSystemAPI fileSystem = null;
|
||||
|
@ -107,6 +107,19 @@ public final class FileSystem {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a file system retrieved via one of the <tt>from???</tt> methods to
|
||||
* make it read-only.
|
||||
*
|
||||
* @param fileSystem the file system to wrap.
|
||||
* @return the specified file system wrapped to be read-only.
|
||||
*/
|
||||
public static li.cil.oc.api.fs.FileSystem asReadOnly(final li.cil.oc.api.fs.FileSystem fileSystem) {
|
||||
if (API.fileSystem != null)
|
||||
return API.fileSystem.asReadOnly(fileSystem);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a network node that makes the specified file system available via
|
||||
* the common file system driver.
|
||||
|
@ -67,6 +67,15 @@ public interface FileSystemAPI {
|
||||
*/
|
||||
FileSystem fromMemory(long capacity);
|
||||
|
||||
/**
|
||||
* Wrap a file system retrieved via one of the <tt>from???</tt> methods to
|
||||
* make it read-only.
|
||||
*
|
||||
* @param fileSystem the file system to wrap.
|
||||
* @return the specified file system wrapped to be read-only.
|
||||
*/
|
||||
FileSystem asReadOnly(final FileSystem fileSystem);
|
||||
|
||||
/**
|
||||
* Creates a network node that makes the specified file system available via
|
||||
* the common file system driver.
|
||||
|
@ -780,6 +780,7 @@ opencomputers {
|
||||
Galacticraft: 48.0
|
||||
IndustrialCraft2: 400.0
|
||||
Mekanism: 1333.33
|
||||
PowerAdvantage: 31.25
|
||||
RedstoneFlux: 100.0
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ Keep in mind that some of these may not be available, depending on the recipe se
|
||||
|
||||
### Extensions
|
||||
* [Adapter](adapter.md)
|
||||
* [Cable](cable.md)
|
||||
* [Geolyzer](geolyzer.md)
|
||||
* [Motion Sensor](motionSensor.md)
|
||||
* [Redstone I/O](redstone.md)
|
||||
@ -38,6 +37,8 @@ Keep in mind that some of these may not be available, depending on the recipe se
|
||||
|
||||
## Networking
|
||||
* [Access Point](accessPoint.md)
|
||||
* [Cable](cable.md)
|
||||
* [Net Splitter](netSplitter.md)
|
||||
* [Switch](switch.md)
|
||||
|
||||
## Power management
|
||||
|
@ -0,0 +1,7 @@
|
||||
# Net Splitter
|
||||
|
||||

|
||||
|
||||
The net splitter is a device that allows controlling connectivity between subnetworks. Unlike the [switch](switch.md) or [power converter](powerConverter.md) it directly connects adjacent subnetworks, i.e. components can be accessed. Each side's connectivity can be toggled using a wrench (e.g. the [scrench](../item/wrench.md)). When a redstone signal is applied to the net splitter, all sides' connectivity is inverted.
|
||||
|
||||
This block can therefore be used to toggle connectivity to certain parts of a component network. Use a [redstone I/O block](redstone.md) or [redstone cards](../item/redstoneCard1.md) to automate the net splitter.
|
@ -4,13 +4,13 @@ Also know as "how to build your first computer". To get your first [computer](co
|
||||
|
||||
**Disclaimer**: this will be step-by-step, and also provide some information on how to look for issues yourself later on, so this is quite long. If you have never built a computer in real life, and/or are completely new to the mod, it is highly recommended you read through it all.
|
||||
|
||||
First off, you will need a [computer case](../block/case1.md). This is the block which will contain of the components, defining the behavior of the computer you are building.
|
||||
First off, you will need a [computer case](../block/case1.md). This is the block which will contain all of the components, defining the behavior of the computer you are building.
|
||||
|
||||

|
||||
|
||||
For example, you will need to choose what tier of [graphics card](../item/graphicsCard1.md) you wish to use, if you need a [network card](../item/lanCard.md), a [redstone card](../item/redstoneCard1.md) or, if you're just playing around in creative mode, maybe even a [debug card](../item/debugCard.md).
|
||||
|
||||
When you open the [computer case](../block/case1.md)'s GUI you will see a few slots to the right. The number of slots, and what tier of component can be placed into them (indicated by the small roman numeral in the slot) depends on the tier of the case itself.
|
||||
When you open the [computer case](../block/case1.md)'s GUI, you will see a few slots to the right. The number of slots, and what tier of component can be placed into them (indicated by the small roman numeral in the slot) depends on the tier of the case itself.
|
||||

|
||||
In their empty state, [computer cases](../block/case1.md) are pretty useless. You can try to power up your [computer](computer.md) now, but it'll immediately print an error message to your chat log, and make its dissatisfaction heard by beeping at you. Good thing the error message is telling you what you can do to fix this situation: it requires energy. Connect your [computer](computer.md) to some power, either directly or via a [power converter](../block/powerConverter.md).
|
||||
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
### Расширения
|
||||
* [Адаптер](adapter.md)
|
||||
* [Кабель](cable.md)
|
||||
* [Геоанализатор](geolyzer.md)
|
||||
* [Датчик движения](motionSensor.md)
|
||||
* [Редстоун I/O](redstone.md)
|
||||
@ -38,6 +37,8 @@
|
||||
|
||||
## Сеть
|
||||
* [Точка доступа](accessPoint.md)
|
||||
* [Кабель](cable.md)
|
||||
* [Сетевой переключатель](netSplitter.md)
|
||||
* [Коммутатор](switch.md)
|
||||
|
||||
## Управление питанием
|
||||
|
@ -0,0 +1,7 @@
|
||||
# Сетевой переключатель
|
||||
|
||||

|
||||
|
||||
Сетевой переключатель позволяет контролировать соединение между подсетями. В отличие от [коммутатора](switch.md) или [конвертера энергии](powerConverter.md) позволяет непосредственно соединить подсети, делая при этом доступными все компоненты. Соединение каждой стороны переключается [ключем](../item/wrench.md). При подаче сигнала красного камня все соединения инвертируются.
|
||||
|
||||
Таким образом, этот блок может быть использован для переключения соединения определенных компонентов сети. Используйте [редстоун I/O](redstone.md) или [редстоун карты](../item/redstoneCard1.md) для автоматизации сетевого переключателя.
|
@ -36,6 +36,7 @@ tile.oc.screen2.name=Screen (Tier 2)
|
||||
tile.oc.screen3.name=Screen (Tier 3)
|
||||
tile.oc.serverRack.name=Server Rack
|
||||
tile.oc.switch.name=Switch
|
||||
tile.oc.netSplitter.name=Net Splitter
|
||||
tile.oc.waypoint.name=Waypoint
|
||||
|
||||
# Items
|
||||
@ -155,6 +156,7 @@ oc:gui.Analyzer.AddressCopied=Address copied to clipboard.
|
||||
oc:gui.Analyzer.ChargerSpeed=§6Charge speed§f: %s
|
||||
oc:gui.Analyzer.ComponentName=§6Component name§f: %s
|
||||
oc:gui.Analyzer.Components=§6Number of connected components§f: %s
|
||||
oc:gui.Analyzer.CopyToClipboard=Click to copy to clipboard.
|
||||
oc:gui.Analyzer.LastError=§6Last error§f: %s
|
||||
oc:gui.Analyzer.RobotName=§6Name§f: %s
|
||||
oc:gui.Analyzer.RobotOwner=§6Owner§f: %s
|
||||
@ -330,6 +332,7 @@ oc:tooltip.TabletCase=Basic case for tablets. Place it into the assembler to add
|
||||
oc:tooltip.Terminal=Allows controlling a server remotely, as long as you are in range of it. Acts like a portable screen and keyboard. Shift-right-click a server in a server rack to bind the terminal to it.
|
||||
oc:tooltip.TexturePicker=This tool allows showing a string describing a block's surface, for use in 3D printer shape definitions. Totally not texture names, nope. No sir.
|
||||
oc:tooltip.Tier=§8Tier %s
|
||||
oc:tooltip.NetSplitter=Acts as a dynamic connector. Connectivity of each side can be toggled by hitting it with a wrench. Connectivity of all sides can be inverted by applying a redstone signal.
|
||||
oc:tooltip.TooLong=Hold [§f%s§7] for a detailed tooltip.
|
||||
oc:tooltip.Transistor=A basic element in most other computer parts. It's a bit twisted, but it does the job.
|
||||
oc:tooltip.UpgradeAngel=Allows robots to place blocks in thin air, even if there is no point of reference.
|
||||
|
@ -36,6 +36,7 @@ tile.oc.screen2.name=Монитор (2-ой уровень)
|
||||
tile.oc.screen3.name=Монитор (3-ий уровень)
|
||||
tile.oc.serverRack.name=Серверная стойка
|
||||
tile.oc.switch.name=Коммутатор
|
||||
tile.oc.netSplitter.name=Сетевой переключатель
|
||||
tile.oc.waypoint.name=Путевая точка
|
||||
|
||||
# Items
|
||||
@ -154,6 +155,7 @@ oc:gui.Analyzer.AddressCopied=Адрес скопирован в буфер об
|
||||
oc:gui.Analyzer.ChargerSpeed=§6Скорость зарядки§f: %s
|
||||
oc:gui.Analyzer.ComponentName=§6Имя компонента§f: %s
|
||||
oc:gui.Analyzer.Components=§6Количество подключенных компонентов§f: %s
|
||||
oc:gui.Analyzer.CopyToClipboard=Кликните для копирования в буфер обмена.
|
||||
oc:gui.Analyzer.LastError=§6Последняя ошибка§f: %s
|
||||
oc:gui.Analyzer.RobotName=§6Имя§f: %s
|
||||
oc:gui.Analyzer.RobotOwner=§6Владелец§f: %s
|
||||
@ -329,6 +331,7 @@ oc:tooltip.TabletCase=Простой корпус для планшета. По
|
||||
oc:tooltip.Terminal=Позволяет дистанционно управлять сервером, пока вы находитесь в радиусе его действия. Действует как портативный дисплей с клавиатурой.[nl] Shift+ПКМ по серверу в стойке для привязки к нему терминала.
|
||||
oc:tooltip.TexturePicker=Простой инструмент, позволяющий узнать название текстуры блока, которое можно использовать в 3D печати.
|
||||
oc:tooltip.Tier=§8Уровень %s
|
||||
oc:tooltip.NetSplitter=Работает как переключатель. Соединение каждой стороны переключается ключем. При подаче сигнала красного камня все соединения инвертируются.
|
||||
oc:tooltip.TooLong=Удерживайте [§f%s§7], чтобы отобразить описание.
|
||||
oc:tooltip.Transistor=Базовый элемент для других частей компьютера. Он немного деформирован, но отлично выполняет свою работу.
|
||||
oc:tooltip.UpgradeAngel=Позволяет роботам размещать блоки в воздухе, даже если отсутствует точка опоры.
|
||||
|
@ -9,7 +9,7 @@ local args, options = shell.parse(...)
|
||||
|
||||
local fromAddress = options.from and component.get(options.from) or filesystem.get(os.getenv("_")).address
|
||||
local candidates = {}
|
||||
for address in component.list("filesystem") do
|
||||
for address in component.list("filesystem", true) do
|
||||
local dev = component.proxy(address)
|
||||
if not dev.isReadOnly() and dev.address ~= computer.tmpAddress() and dev.address ~= fromAddress then
|
||||
table.insert(candidates, dev)
|
||||
|
@ -38,7 +38,11 @@ end
|
||||
|
||||
function memoryStream:write(value)
|
||||
if not self.redirect.write and self.closed then
|
||||
error("attempt to use a closed stream")
|
||||
-- if next is dead, ignore all writes
|
||||
if coroutine.status(self.next) ~= "dead" then
|
||||
error("attempt to use a closed stream")
|
||||
end
|
||||
return true
|
||||
end
|
||||
if self.redirect.write then
|
||||
self.redirect.write:write(value)
|
||||
@ -306,6 +310,7 @@ local function execute(env, command, ...)
|
||||
elseif pipes[i] then
|
||||
io.output(pipes[i])
|
||||
end
|
||||
io.write('')
|
||||
end, command)
|
||||
if not threads[i] then
|
||||
return false, reason
|
||||
|
@ -116,7 +116,7 @@ end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
for address in component.list('screen') do
|
||||
for address in component.list('screen', true) do
|
||||
if #component.invoke(address,'getKeyboards') > 0 then
|
||||
component.setPrimary('screen',address)
|
||||
end
|
||||
|
@ -28,8 +28,8 @@ do
|
||||
function rom.inits() return ipairs(rom.invoke("list", "boot")) end
|
||||
function rom.isDirectory(path) return rom.invoke("isDirectory", path) end
|
||||
|
||||
local screen = component.list('screen')()
|
||||
for address in component.list('screen') do
|
||||
local screen = component.list('screen', true)()
|
||||
for address in component.list('screen', true) do
|
||||
if #component.invoke(address, 'getKeyboards') > 0 then
|
||||
screen = address
|
||||
end
|
||||
|
@ -242,7 +242,7 @@ end
|
||||
function filesystem.proxy(filter)
|
||||
checkArg(1, filter, "string")
|
||||
local address
|
||||
for c in component.list("filesystem") do
|
||||
for c in component.list("filesystem", true) do
|
||||
if component.invoke(c, "getLabel") == filter then
|
||||
address = c
|
||||
break
|
||||
|
@ -22,6 +22,6 @@ else
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
file:close()
|
||||
io.write(data.toHex(data.md5(read)) .. "\t".. args[i])
|
||||
io.write(data.toHex(data.md5(read)) .. "\t".. args[i] .. "\n")
|
||||
end
|
||||
end
|
||||
|
@ -22,6 +22,6 @@ else
|
||||
read = read .. current
|
||||
until current ~= ""
|
||||
file:close()
|
||||
io.write(data.toHex(data.sha256(read)) .. "\t".. args[i])
|
||||
io.write(data.toHex(data.sha256(read)) .. "\t".. args[i] .. "\n")
|
||||
end
|
||||
end
|
||||
|
@ -732,7 +732,7 @@ sandbox = {
|
||||
tonumber = tonumber,
|
||||
tostring = tostring,
|
||||
type = type,
|
||||
_VERSION = _VERSION:match("5.3") and "Lua 5.3.0" or "Lua 5.2.4",
|
||||
_VERSION = _VERSION:match("5.3") and "Lua 5.3" or "Lua 5.2",
|
||||
xpcall = function(f, msgh, ...)
|
||||
local handled = false
|
||||
local result = table.pack(xpcall(f, function(...)
|
||||
|
@ -576,6 +576,11 @@ motionSensor {
|
||||
[daylightDetector, "oc:cpu2", daylightDetector]
|
||||
[ingotGold, "oc:materialCircuitBoardPrinted", ingotGold]]
|
||||
}
|
||||
netSplitter {
|
||||
input: [[ingotIron, "oc:cable", ingotIron]
|
||||
["oc:cable", craftingPiston, "oc:cable"]
|
||||
[ingotIron, "oc:materialCircuitBoardPrinted", ingotIron]]
|
||||
}
|
||||
printer {
|
||||
input: [[ingotIron, hopper, ingotIron]
|
||||
[craftingPiston, "oc:circuitChip3", craftingPiston]
|
||||
|
@ -30,6 +30,7 @@ Crypto # Kodos
|
||||
Curiosity # Mars Rover
|
||||
Daedalus # Deus Ex
|
||||
Dalek Sec # Doctor Who
|
||||
David # A.I. (the movie)
|
||||
Death Trap # Borderlands 2's Mechromancer
|
||||
Deputy ANDY # Eureka
|
||||
Dog # Half-Life
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 535 B |
Binary file not shown.
After Width: | Height: | Size: 423 B |
Binary file not shown.
After Width: | Height: | Size: 157 B |
@ -38,6 +38,7 @@ object Constants {
|
||||
final val ScreenTier3 = "screen3"
|
||||
final val ServerRack = "serverRack"
|
||||
final val Switch = "switch"
|
||||
final val NetSplitter = "netSplitter"
|
||||
final val Waypoint = "waypoint"
|
||||
|
||||
def Case(tier: Int) = ItemUtils.caseNameWithTierSuffix("case", tier)
|
||||
|
@ -1,5 +1,8 @@
|
||||
package li.cil.oc
|
||||
|
||||
import li.cil.oc.client.CommandHandler.SetClipboardCommand
|
||||
import net.minecraft.event.ClickEvent
|
||||
import net.minecraft.event.HoverEvent
|
||||
import net.minecraft.util.ChatComponentText
|
||||
import net.minecraft.util.ChatComponentTranslation
|
||||
import net.minecraft.util.StatCollector
|
||||
@ -23,7 +26,12 @@ object Localization {
|
||||
def localizeImmediately(key: String) = StatCollector.translateToLocal(resolveKey(key)).split(nl).map(_.trim).mkString("\n")
|
||||
|
||||
object Analyzer {
|
||||
def Address(value: String) = localizeLater("gui.Analyzer.Address", value)
|
||||
def Address(value: String) = {
|
||||
val result = localizeLater("gui.Analyzer.Address", value)
|
||||
result.getChatStyle.setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, s"/${SetClipboardCommand.name} $value"))
|
||||
result.getChatStyle.setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, localizeLater("gui.Analyzer.CopyToClipboard")))
|
||||
result
|
||||
}
|
||||
|
||||
def AddressCopied = localizeLater("gui.Analyzer.AddressCopied")
|
||||
|
||||
|
@ -2,7 +2,7 @@ package li.cil.oc
|
||||
|
||||
import li.cil.oc.common.IMC
|
||||
import li.cil.oc.common.Proxy
|
||||
import li.cil.oc.server.CommandHandler
|
||||
import li.cil.oc.server.command.CommandHandler
|
||||
import net.minecraftforge.fml.common.Mod
|
||||
import net.minecraftforge.fml.common.Mod.EventHandler
|
||||
import net.minecraftforge.fml.common.SidedProxy
|
||||
|
@ -218,6 +218,7 @@ class Settings(val config: Config) {
|
||||
private val valueGalacticraft = config.getDouble("power.value.Galacticraft")
|
||||
private val valueIndustrialCraft2 = config.getDouble("power.value.IndustrialCraft2")
|
||||
private val valueMekanism = config.getDouble("power.value.Mekanism")
|
||||
private val valuePowerAdvantage = config.getDouble("power.value.PowerAdvantage")
|
||||
private val valueRedstoneFlux = config.getDouble("power.value.RedstoneFlux")
|
||||
|
||||
private val valueInternal = 1000
|
||||
@ -227,6 +228,7 @@ class Settings(val config: Config) {
|
||||
val ratioGalacticraft = valueGalacticraft / valueInternal
|
||||
val ratioIndustrialCraft2 = valueIndustrialCraft2 / valueInternal
|
||||
val ratioMekanism = valueMekanism / valueInternal
|
||||
val ratioPowerAdvantage = valuePowerAdvantage / valueInternal
|
||||
val ratioRedstoneFlux = valueRedstoneFlux / valueInternal
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
31
src/main/scala/li/cil/oc/client/CommandHandler.scala
Normal file
31
src/main/scala/li/cil/oc/client/CommandHandler.scala
Normal file
@ -0,0 +1,31 @@
|
||||
package li.cil.oc.client
|
||||
|
||||
import li.cil.oc.common.command.SimpleCommand
|
||||
import net.minecraft.client.gui.GuiScreen
|
||||
import net.minecraft.command.ICommandSender
|
||||
import net.minecraftforge.client.ClientCommandHandler
|
||||
|
||||
object CommandHandler {
|
||||
def register(): Unit = {
|
||||
ClientCommandHandler.instance.registerCommand(SetClipboardCommand)
|
||||
}
|
||||
|
||||
object SetClipboardCommand extends SimpleCommand("oc_setclipboard") {
|
||||
override def getCommandUsage(source: ICommandSender): String = name + " <value>"
|
||||
|
||||
override def execute(source: ICommandSender, command: Array[String]): Unit = {
|
||||
if (source.getEntityWorld.isRemote && command != null && command.length > 0) {
|
||||
GuiScreen.setClipboardString(command(0))
|
||||
}
|
||||
}
|
||||
|
||||
// OP levels for reference:
|
||||
// 1 - Ops can bypass spawn protection.
|
||||
// 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks.
|
||||
// 3 - Ops can use /ban, /deop, /kick, and /op.
|
||||
// 4 - Ops can use /stop.
|
||||
|
||||
override def getRequiredPermissionLevel = 0
|
||||
}
|
||||
|
||||
}
|
@ -58,6 +58,7 @@ object PacketHandler extends CommonPacketHandler {
|
||||
case PacketType.HologramTranslation => onHologramPositionOffsetY(p)
|
||||
case PacketType.HologramValues => onHologramValues(p)
|
||||
case PacketType.LootDisk => onLootDisk(p)
|
||||
case PacketType.NetSplitterState => onNetSplitterState(p)
|
||||
case PacketType.ParticleEffect => onParticleEffect(p)
|
||||
case PacketType.PetVisibility => onPetVisibility(p)
|
||||
case PacketType.PowerState => onPowerState(p)
|
||||
@ -442,6 +443,7 @@ object PacketHandler extends CommonPacketHandler {
|
||||
}
|
||||
buffer.data.load(nbt)
|
||||
buffer.proxy.markDirty()
|
||||
buffer.markInitialized()
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
}
|
||||
@ -587,6 +589,15 @@ object PacketHandler extends CommonPacketHandler {
|
||||
buffer.rawSetForeground(col, row, color)
|
||||
}
|
||||
|
||||
def onNetSplitterState(p: PacketParser) =
|
||||
p.readTileEntity[NetSplitter]() match {
|
||||
case Some(t) =>
|
||||
t.isInverted = p.readBoolean()
|
||||
t.openSides = t.uncompressSides(p.readByte())
|
||||
t.world.markBlockForUpdate(t.getPos)
|
||||
case _ => // Invalid packet.
|
||||
}
|
||||
|
||||
def onScreenTouchMode(p: PacketParser) =
|
||||
p.readTileEntity[Screen]() match {
|
||||
case Some(t) => t.invertTouchMode = p.readBoolean()
|
||||
|
@ -34,6 +34,8 @@ private[oc] class Proxy extends CommonProxy {
|
||||
|
||||
api.API.manual = client.Manual
|
||||
|
||||
CommandHandler.register()
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(Textures)
|
||||
|
||||
ModelInitialization.preInit()
|
||||
@ -67,6 +69,7 @@ private[oc] class Proxy extends CommonProxy {
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.AccessPoint], SwitchRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.RobotProxy], RobotRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.Screen], ScreenRenderer)
|
||||
ClientRegistry.bindTileEntitySpecialRenderer(classOf[tileentity.NetSplitter], NetSplitterRenderer)
|
||||
|
||||
ClientRegistry.registerKeyBinding(KeyBindings.materialCosts)
|
||||
ClientRegistry.registerKeyBinding(KeyBindings.clipboardPaste)
|
||||
|
@ -131,6 +131,7 @@ object Textures {
|
||||
val GeolyzerTopOn = L("overlay/geolyzer_top_on")
|
||||
val MicrocontrollerFrontLight = L("overlay/microcontroller_front_light")
|
||||
val MicrocontrollerFrontOn = L("overlay/microcontroller_front_on")
|
||||
val NetSplitterOn = L("overlay/netSplitter_on")
|
||||
val PowerDistributorSideOn = L("overlay/powerDistributor_side_on")
|
||||
val PowerDistributorTopOn = L("overlay/powerDistributor_top_on")
|
||||
val RackFrontActivity = L("overlay/serverRack_front_activity")
|
||||
@ -143,6 +144,8 @@ object Textures {
|
||||
val Cable = L("cable")
|
||||
val CableCap = L("cableCap")
|
||||
val GenericTop = L("generic_top", load = false)
|
||||
val NetSplitterSide = L("netSplitter_side")
|
||||
val NetSplitterTop = L("netSplitter_top")
|
||||
val RackFront = L("serverRack_front", load = false)
|
||||
val RackSide = L("serverRack_side", load = false)
|
||||
|
||||
|
@ -31,7 +31,10 @@ object PetRenderer {
|
||||
"DaKaTotal" ->(0.5, 0.7, 1.0),
|
||||
"MichiyoRavencroft" ->(1.0, 0.0, 0.0),
|
||||
"Vexatos" ->(0.18, 0.95, 0.922),
|
||||
"StoneNomad" ->(0.8, 0.77, 0.75)
|
||||
"StoneNomad" ->(0.8, 0.77, 0.75),
|
||||
"LizzyTheSiren" ->(0.3, 0.3, 1.0),
|
||||
"vifino" ->(0.2, 1.0, 0.1),
|
||||
"Izaya" ->(0.0, 0.2, 0.6)
|
||||
)
|
||||
|
||||
private val petLocations = com.google.common.cache.CacheBuilder.newBuilder().
|
||||
|
@ -83,17 +83,17 @@ object CableModel extends SmartBlockModelBase with ISmartItemModel {
|
||||
class BlockModel(val state: IExtendedBlockState) extends SmartBlockModelBase {
|
||||
override def getGeneralQuads =
|
||||
state.getValue(block.property.PropertyTile.Tile) match {
|
||||
case cable: tileentity.Cable =>
|
||||
case t: tileentity.Cable =>
|
||||
val faces = mutable.ArrayBuffer.empty[BakedQuad]
|
||||
|
||||
val color = Some(cable.color)
|
||||
val mask = Cable.neighbors(cable.world, cable.getPos)
|
||||
val color = Some(t.color)
|
||||
val mask = Cable.neighbors(t.world, t.getPos)
|
||||
faces ++= bakeQuads(Middle, cableTexture, color)
|
||||
for (side <- EnumFacing.values) {
|
||||
val connected = (mask & (1 << side.getIndex)) != 0
|
||||
val (plug, shortBody, longBody) = Connected(side.getIndex)
|
||||
if (connected) {
|
||||
if (isCable(cable.position.offset(side))) {
|
||||
if (isCable(t.position.offset(side))) {
|
||||
faces ++= bakeQuads(longBody, cableTexture, color)
|
||||
}
|
||||
else {
|
||||
|
@ -29,6 +29,8 @@ import scala.collection.mutable
|
||||
object ModelInitialization {
|
||||
final val CableBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "normal")
|
||||
final val CableItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Cable, "inventory")
|
||||
final val NetSplitterBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.NetSplitter, "normal")
|
||||
final val NetSplitterItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.NetSplitter, "inventory")
|
||||
final val PrintBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Print, "normal")
|
||||
final val PrintItemLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Print, "inventory")
|
||||
final val RobotBlockLocation = new ModelResourceLocation(Settings.resourceDomain + ":" + Constants.BlockName.Robot, "normal")
|
||||
@ -45,6 +47,7 @@ object ModelInitialization {
|
||||
MinecraftForge.EVENT_BUS.register(this)
|
||||
|
||||
registerModel(Constants.BlockName.Cable, CableBlockLocation, CableItemLocation)
|
||||
registerModel(Constants.BlockName.NetSplitter, NetSplitterBlockLocation, NetSplitterItemLocation)
|
||||
registerModel(Constants.BlockName.Print, PrintBlockLocation, PrintItemLocation)
|
||||
registerModel(Constants.BlockName.Robot, RobotBlockLocation, RobotItemLocation)
|
||||
registerModel(Constants.BlockName.RobotAfterimage, RobotAfterimageBlockLocation, RobotAfterimageItemLocation)
|
||||
@ -137,6 +140,8 @@ object ModelInitialization {
|
||||
|
||||
registry.putObject(CableBlockLocation, CableModel)
|
||||
registry.putObject(CableItemLocation, CableModel)
|
||||
registry.putObject(NetSplitterBlockLocation, NetSplitterModel)
|
||||
registry.putObject(NetSplitterItemLocation, NetSplitterModel)
|
||||
registry.putObject(PrintBlockLocation, PrintModel)
|
||||
registry.putObject(PrintItemLocation, PrintModel)
|
||||
registry.putObject(RobotBlockLocation, RobotModel)
|
||||
|
@ -0,0 +1,106 @@
|
||||
package li.cil.oc.client.renderer.block
|
||||
|
||||
import li.cil.oc.client.Textures
|
||||
import li.cil.oc.common.block
|
||||
import li.cil.oc.common.item.data.PrintData
|
||||
import li.cil.oc.common.tileentity
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.util.Vec3
|
||||
import net.minecraftforge.client.model.ISmartItemModel
|
||||
import net.minecraftforge.common.property.IExtendedBlockState
|
||||
|
||||
import scala.collection.convert.WrapAsJava.bufferAsJavaList
|
||||
import scala.collection.mutable
|
||||
|
||||
object NetSplitterModel extends SmartBlockModelBase with ISmartItemModel {
|
||||
override def handleBlockState(state: IBlockState) = state match {
|
||||
case extended: IExtendedBlockState => new BlockModel(extended)
|
||||
case _ => missingModel
|
||||
}
|
||||
|
||||
override def handleItemState(stack: ItemStack) = new ItemModel(stack)
|
||||
|
||||
protected def splitterTexture = Array(
|
||||
Textures.getSprite(Textures.Block.NetSplitterTop),
|
||||
Textures.getSprite(Textures.Block.NetSplitterTop),
|
||||
Textures.getSprite(Textures.Block.NetSplitterSide),
|
||||
Textures.getSprite(Textures.Block.NetSplitterSide),
|
||||
Textures.getSprite(Textures.Block.NetSplitterSide),
|
||||
Textures.getSprite(Textures.Block.NetSplitterSide)
|
||||
)
|
||||
|
||||
protected final val BaseModel = {
|
||||
val faces = mutable.ArrayBuffer.empty[BakedQuad]
|
||||
|
||||
// Bottom.
|
||||
faces ++= bakeQuads(makeBox(new Vec3(0 / 16f, 0 / 16f, 5 / 16f), new Vec3(5 / 16f, 5 / 16f, 11 / 16f)), splitterTexture, None)
|
||||
faces ++= bakeQuads(makeBox(new Vec3(11 / 16f, 0 / 16f, 5 / 16f), new Vec3(16 / 16f, 5 / 16f, 11 / 16f)), splitterTexture, None)
|
||||
faces ++= bakeQuads(makeBox(new Vec3(5 / 16f, 0 / 16f, 0 / 16f), new Vec3(11 / 16f, 5 / 16f, 5 / 16f)), splitterTexture, None)
|
||||
faces ++= bakeQuads(makeBox(new Vec3(5 / 16f, 0 / 16f, 11 / 16f), new Vec3(11 / 16f, 5 / 16f, 16 / 16f)), splitterTexture, None)
|
||||
// Corners.
|
||||
faces ++= bakeQuads(makeBox(new Vec3(0 / 16f, 0 / 16f, 0 / 16f), new Vec3(5 / 16f, 16 / 16f, 5 / 16f)), splitterTexture, None)
|
||||
faces ++= bakeQuads(makeBox(new Vec3(11 / 16f, 0 / 16f, 0 / 16f), new Vec3(16 / 16f, 16 / 16f, 5 / 16f)), splitterTexture, None)
|
||||
faces ++= bakeQuads(makeBox(new Vec3(0 / 16f, 0 / 16f, 11 / 16f), new Vec3(5 / 16f, 16 / 16f, 16 / 16f)), splitterTexture, None)
|
||||
faces ++= bakeQuads(makeBox(new Vec3(11 / 16f, 0 / 16f, 11 / 16f), new Vec3(16 / 16f, 16 / 16f, 16 / 16f)), splitterTexture, None)
|
||||
// Top.
|
||||
faces ++= bakeQuads(makeBox(new Vec3(0 / 16f, 11 / 16f, 5 / 16f), new Vec3(5 / 16f, 16 / 16f, 11 / 16f)), splitterTexture, None)
|
||||
faces ++= bakeQuads(makeBox(new Vec3(11 / 16f, 11 / 16f, 5 / 16f), new Vec3(16 / 16f, 16 / 16f, 11 / 16f)), splitterTexture, None)
|
||||
faces ++= bakeQuads(makeBox(new Vec3(5 / 16f, 11 / 16f, 0 / 16f), new Vec3(11 / 16f, 16 / 16f, 5 / 16f)), splitterTexture, None)
|
||||
faces ++= bakeQuads(makeBox(new Vec3(5 / 16f, 11 / 16f, 11 / 16f), new Vec3(11 / 16f, 16 / 16f, 16 / 16f)), splitterTexture, None)
|
||||
|
||||
faces.toArray
|
||||
}
|
||||
|
||||
protected def addSideQuads(faces: mutable.ArrayBuffer[BakedQuad], openSides: Array[Boolean]): Unit = {
|
||||
val down = openSides(EnumFacing.DOWN.ordinal())
|
||||
faces ++= bakeQuads(makeBox(new Vec3(5 / 16f, if (down) 0 / 16f else 2 / 16f, 5 / 16f), new Vec3(11 / 16f, 5 / 16f, 11 / 16f)), splitterTexture, None)
|
||||
|
||||
val up = openSides(EnumFacing.UP.ordinal())
|
||||
faces ++= bakeQuads(makeBox(new Vec3(5 / 16f, 11 / 16f, 5 / 16f), new Vec3(11 / 16f, if (up) 16 / 16f else 14f / 16f, 11 / 16f)), splitterTexture, None)
|
||||
|
||||
val north = openSides(EnumFacing.NORTH.ordinal())
|
||||
faces ++= bakeQuads(makeBox(new Vec3(5 / 16f, 5 / 16f, if (north) 0 / 16f else 2 / 16f), new Vec3(11 / 16f, 11 / 16f, 5 / 16f)), splitterTexture, None)
|
||||
|
||||
val south = openSides(EnumFacing.SOUTH.ordinal())
|
||||
faces ++= bakeQuads(makeBox(new Vec3(5 / 16f, 5 / 16f, 11 / 16f), new Vec3(11 / 16f, 11 / 16f, if (south) 16 / 16f else 14 / 16f)), splitterTexture, None)
|
||||
|
||||
val west = openSides(EnumFacing.WEST.ordinal())
|
||||
faces ++= bakeQuads(makeBox(new Vec3(if (west) 0 / 16f else 2 / 16f, 5 / 16f, 5 / 16f), new Vec3(5 / 16f, 11 / 16f, 11 / 16f)), splitterTexture, None)
|
||||
|
||||
val east = openSides(EnumFacing.EAST.ordinal())
|
||||
faces ++= bakeQuads(makeBox(new Vec3(11 / 16f, 5 / 16f, 5 / 16f), new Vec3(if (east) 16 / 16f else 14 / 16f, 11 / 16f, 11 / 16f)), splitterTexture, None)
|
||||
}
|
||||
|
||||
class BlockModel(val state: IExtendedBlockState) extends SmartBlockModelBase {
|
||||
override def getGeneralQuads =
|
||||
state.getValue(block.property.PropertyTile.Tile) match {
|
||||
case t: tileentity.NetSplitter =>
|
||||
val faces = mutable.ArrayBuffer.empty[BakedQuad]
|
||||
|
||||
faces ++= BaseModel
|
||||
addSideQuads(faces, EnumFacing.values().map(t.isSideOpen))
|
||||
|
||||
bufferAsJavaList(faces)
|
||||
case _ => super.getGeneralQuads
|
||||
}
|
||||
}
|
||||
|
||||
class ItemModel(val stack: ItemStack) extends SmartBlockModelBase {
|
||||
val data = new PrintData(stack)
|
||||
|
||||
override def getGeneralQuads = {
|
||||
val faces = mutable.ArrayBuffer.empty[BakedQuad]
|
||||
|
||||
Textures.Block.bind()
|
||||
|
||||
faces ++= BaseModel
|
||||
addSideQuads(faces, EnumFacing.values().map(_ => false))
|
||||
|
||||
bufferAsJavaList(faces)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -32,11 +32,11 @@ object PrintModel extends SmartBlockModelBase with ISmartItemModel {
|
||||
class BlockModel(val state: IExtendedBlockState) extends SmartBlockModelBase {
|
||||
override def getGeneralQuads =
|
||||
state.getValue(block.property.PropertyTile.Tile) match {
|
||||
case print: tileentity.Print =>
|
||||
case t: tileentity.Print =>
|
||||
val faces = mutable.ArrayBuffer.empty[BakedQuad]
|
||||
|
||||
for (shape <- if (print.state) print.data.stateOn else print.data.stateOff if !Strings.isNullOrEmpty(shape.texture)) {
|
||||
val bounds = shape.bounds.rotateTowards(print.facing)
|
||||
for (shape <- if (t.state) t.data.stateOn else t.data.stateOff if !Strings.isNullOrEmpty(shape.texture)) {
|
||||
val bounds = shape.bounds.rotateTowards(t.facing)
|
||||
val texture = resolveTexture(shape.texture)
|
||||
faces ++= bakeQuads(makeBox(bounds.min, bounds.max), Array.fill(6)(texture), shape.tint.getOrElse(NoTint))
|
||||
}
|
||||
|
@ -0,0 +1,91 @@
|
||||
package li.cil.oc.client.renderer.tileentity
|
||||
|
||||
import li.cil.oc.client.Textures
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.util.RenderState
|
||||
import net.minecraft.client.renderer.Tessellator
|
||||
import net.minecraft.client.renderer.texture.TextureMap
|
||||
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.util.EnumFacing
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
object NetSplitterRenderer extends TileEntitySpecialRenderer {
|
||||
override def renderTileEntityAt(tileEntity: TileEntity, x: Double, y: Double, z: Double, f: Float, damage: Int) {
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||
|
||||
val splitter = tileEntity.asInstanceOf[tileentity.NetSplitter]
|
||||
if (splitter.openSides.contains(!splitter.isInverted)) {
|
||||
RenderState.pushAttrib()
|
||||
RenderState.disableEntityLighting()
|
||||
RenderState.makeItBlend()
|
||||
|
||||
RenderState.pushMatrix()
|
||||
|
||||
GL11.glTranslated(x + 0.5, y + 0.5, z + 0.5)
|
||||
GL11.glScaled(1.0025, -1.0025, 1.0025)
|
||||
GL11.glTranslatef(-0.5f, -0.5f, -0.5f)
|
||||
|
||||
bindTexture(TextureMap.locationBlocksTexture)
|
||||
|
||||
val t = Tessellator.getInstance
|
||||
val r = t.getWorldRenderer
|
||||
|
||||
Textures.Block.bind()
|
||||
r.startDrawingQuads()
|
||||
|
||||
val sideActivity = Textures.getSprite(Textures.Block.NetSplitterOn)
|
||||
|
||||
if (splitter.isSideOpen(EnumFacing.DOWN)) {
|
||||
r.addVertexWithUV(0, 1, 0, sideActivity.getMaxU, sideActivity.getMinV)
|
||||
r.addVertexWithUV(1, 1, 0, sideActivity.getMinU, sideActivity.getMinV)
|
||||
r.addVertexWithUV(1, 1, 1, sideActivity.getMinU, sideActivity.getMaxV)
|
||||
r.addVertexWithUV(0, 1, 1, sideActivity.getMaxU, sideActivity.getMaxV)
|
||||
}
|
||||
|
||||
if (splitter.isSideOpen(EnumFacing.UP)) {
|
||||
r.addVertexWithUV(0, 0, 0, sideActivity.getMaxU, sideActivity.getMaxV)
|
||||
r.addVertexWithUV(0, 0, 1, sideActivity.getMaxU, sideActivity.getMinV)
|
||||
r.addVertexWithUV(1, 0, 1, sideActivity.getMinU, sideActivity.getMinV)
|
||||
r.addVertexWithUV(1, 0, 0, sideActivity.getMinU, sideActivity.getMaxV)
|
||||
}
|
||||
|
||||
if (splitter.isSideOpen(EnumFacing.NORTH)) {
|
||||
r.addVertexWithUV(1, 1, 0, sideActivity.getMinU, sideActivity.getMaxV)
|
||||
r.addVertexWithUV(0, 1, 0, sideActivity.getMaxU, sideActivity.getMaxV)
|
||||
r.addVertexWithUV(0, 0, 0, sideActivity.getMaxU, sideActivity.getMinV)
|
||||
r.addVertexWithUV(1, 0, 0, sideActivity.getMinU, sideActivity.getMinV)
|
||||
}
|
||||
|
||||
if (splitter.isSideOpen(EnumFacing.SOUTH)) {
|
||||
r.addVertexWithUV(0, 1, 1, sideActivity.getMinU, sideActivity.getMaxV)
|
||||
r.addVertexWithUV(1, 1, 1, sideActivity.getMaxU, sideActivity.getMaxV)
|
||||
r.addVertexWithUV(1, 0, 1, sideActivity.getMaxU, sideActivity.getMinV)
|
||||
r.addVertexWithUV(0, 0, 1, sideActivity.getMinU, sideActivity.getMinV)
|
||||
}
|
||||
|
||||
if (splitter.isSideOpen(EnumFacing.WEST)) {
|
||||
r.addVertexWithUV(0, 1, 0, sideActivity.getMinU, sideActivity.getMaxV)
|
||||
r.addVertexWithUV(0, 1, 1, sideActivity.getMaxU, sideActivity.getMaxV)
|
||||
r.addVertexWithUV(0, 0, 1, sideActivity.getMaxU, sideActivity.getMinV)
|
||||
r.addVertexWithUV(0, 0, 0, sideActivity.getMinU, sideActivity.getMinV)
|
||||
}
|
||||
|
||||
if (splitter.isSideOpen(EnumFacing.EAST)) {
|
||||
r.addVertexWithUV(1, 1, 1, sideActivity.getMinU, sideActivity.getMaxV)
|
||||
r.addVertexWithUV(1, 1, 0, sideActivity.getMaxU, sideActivity.getMaxV)
|
||||
r.addVertexWithUV(1, 0, 0, sideActivity.getMaxU, sideActivity.getMinV)
|
||||
r.addVertexWithUV(1, 0, 1, sideActivity.getMinU, sideActivity.getMinV)
|
||||
}
|
||||
|
||||
t.draw()
|
||||
|
||||
RenderState.enableEntityLighting()
|
||||
|
||||
RenderState.popMatrix()
|
||||
RenderState.popAttrib()
|
||||
}
|
||||
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: leaving")
|
||||
}
|
||||
}
|
@ -135,7 +135,7 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
|
||||
|
||||
def createLootDisk(name: String, path: String, external: Boolean, color: Option[EnumDyeColor] = None) = {
|
||||
val callable = if (external) new Callable[FileSystem] {
|
||||
override def call(): FileSystem = api.FileSystem.fromSaveDirectory("loot/" + path, 0, false)
|
||||
override def call(): FileSystem = api.FileSystem.asReadOnly(api.FileSystem.fromSaveDirectory("loot/" + path, 0, false))
|
||||
} else new Callable[FileSystem] {
|
||||
override def call(): FileSystem = api.FileSystem.fromClass(OpenComputers.getClass, Settings.resourceDomain, "loot/" + path)
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ object PacketType extends Enumeration {
|
||||
TextBufferMultiRawSetBackground,
|
||||
TextBufferMultiRawSetForeground,
|
||||
TextBufferPowerChange,
|
||||
NetSplitterState,
|
||||
ScreenTouchMode,
|
||||
ServerPresence,
|
||||
Sound,
|
||||
|
@ -3,6 +3,7 @@ package li.cil.oc.common.block
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.coloredlights.ModColoredLights
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.util.EnumFacing
|
||||
@ -10,7 +11,7 @@ import net.minecraft.world.IBlockAccess
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Assembler extends SimpleBlock with traits.PowerAcceptor with traits.StateAware with traits.GUI {
|
||||
setLightLevel(0.34f)
|
||||
ModColoredLights.setLightLevel(this, 0, 3, 5)
|
||||
|
||||
override def isOpaqueCube = false
|
||||
|
||||
|
@ -3,13 +3,15 @@ package li.cil.oc.common.block
|
||||
import java.util.Random
|
||||
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.coloredlights.ModColoredLights
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Capacitor extends SimpleBlock {
|
||||
setLightLevel(0.34f)
|
||||
ModColoredLights.setLightLevel(this, 5, 5, 5)
|
||||
|
||||
setTickRandomly(true)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -1,11 +1,12 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.coloredlights.ModColoredLights
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.world.World
|
||||
|
||||
class Geolyzer extends SimpleBlock {
|
||||
setLightLevel(0.14f)
|
||||
ModColoredLights.setLightLevel(this, 3, 1, 1)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
|
@ -3,6 +3,7 @@ package li.cil.oc.common.block
|
||||
import java.util
|
||||
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.coloredlights.ModColoredLights
|
||||
import li.cil.oc.util.Rarity
|
||||
import li.cil.oc.util.Tooltip
|
||||
import net.minecraft.block.state.IBlockState
|
||||
@ -16,7 +17,7 @@ import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
|
||||
class Hologram(val tier: Int) extends SimpleBlock {
|
||||
setLightLevel(1)
|
||||
ModColoredLights.setLightLevel(this, 15, 15, 15)
|
||||
setBlockBounds(0, 0, 0, 1, 0.5f, 1)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
58
src/main/scala/li/cil/oc/common/block/NetSplitter.scala
Normal file
58
src/main/scala/li/cil/oc/common/block/NetSplitter.scala
Normal file
@ -0,0 +1,58 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.util.Wrench
|
||||
import net.minecraft.block.properties.IProperty
|
||||
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
|
||||
import net.minecraftforge.common.property.IExtendedBlockState
|
||||
import net.minecraftforge.common.property.IUnlistedProperty
|
||||
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
class NetSplitter extends RedstoneAware with traits.Extended {
|
||||
override protected def setDefaultExtendedState(state: IBlockState) = setDefaultState(state)
|
||||
|
||||
override protected def addExtendedState(state: IBlockState, world: IBlockAccess, pos: BlockPos) =
|
||||
(state, world.getTileEntity(pos)) match {
|
||||
case (extendedState: IExtendedBlockState, t: tileentity.NetSplitter) =>
|
||||
super.addExtendedState(extendedState.withProperty(property.PropertyTile.Tile, t), world, pos)
|
||||
case _ => None
|
||||
}
|
||||
|
||||
override protected def createProperties(listed: ArrayBuffer[IProperty], unlisted: ArrayBuffer[IUnlistedProperty[_]]) {
|
||||
super.createProperties(listed, unlisted)
|
||||
unlisted += property.PropertyTile.Tile
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def isSideSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing): Boolean = false
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def createNewTileEntity(world: World, meta: Int) = new tileentity.NetSplitter()
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// NOTE: must not be final for immibis microblocks to work.
|
||||
override def onBlockActivated(world: World, pos: BlockPos, state: IBlockState, player: EntityPlayer, side: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean = {
|
||||
if (Wrench.holdsApplicableWrench(player, pos)) {
|
||||
val sideToToggle = if (player.isSneaking) side.getOpposite else side
|
||||
world.getTileEntity(pos) match {
|
||||
case splitter: tileentity.NetSplitter =>
|
||||
if (!world.isRemote) {
|
||||
val oldValue = splitter.openSides(sideToToggle.ordinal())
|
||||
splitter.setSideOpen(sideToToggle, !oldValue)
|
||||
}
|
||||
true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
else super.onBlockActivated(world, pos, state, player, side, hitX, hitY, hitZ)
|
||||
}
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
package li.cil.oc.common.block
|
||||
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.coloredlights.ModColoredLights
|
||||
import net.minecraft.block.state.IBlockState
|
||||
import net.minecraft.world.World
|
||||
|
||||
class PowerDistributor extends SimpleBlock {
|
||||
setLightLevel(0.34f)
|
||||
ModColoredLights.setLightLevel(this, 5, 5, 3)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
|
@ -48,8 +48,8 @@ class Print(protected implicit val tileTag: ClassTag[tileentity.Print]) extends
|
||||
|
||||
override protected def addExtendedState(state: IBlockState, world: IBlockAccess, pos: BlockPos) =
|
||||
(state, world.getTileEntity(pos)) match {
|
||||
case (extendedState: IExtendedBlockState, print: tileentity.Print) =>
|
||||
super.addExtendedState(extendedState.withProperty(property.PropertyTile.Tile, print), world, pos)
|
||||
case (extendedState: IExtendedBlockState, t: tileentity.Print) =>
|
||||
super.addExtendedState(extendedState.withProperty(property.PropertyTile.Tile, t), world, pos)
|
||||
case _ => None
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.common.GuiType
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.integration.coloredlights.ModColoredLights
|
||||
import li.cil.oc.integration.util.Wrench
|
||||
import li.cil.oc.util.Color
|
||||
import li.cil.oc.util.PackedColor
|
||||
@ -33,7 +34,7 @@ import net.minecraftforge.fml.relauncher.SideOnly
|
||||
import scala.collection.mutable.ArrayBuffer
|
||||
|
||||
class Screen(val tier: Int) extends RedstoneAware with traits.OmniRotatable {
|
||||
setLightLevel(0.34f)
|
||||
ModColoredLights.setLightLevel(this, 5, 5, 5)
|
||||
|
||||
override def isSideSolid(world: IBlockAccess, pos: BlockPos, side: EnumFacing) = toLocal(world, pos, side) != EnumFacing.SOUTH
|
||||
|
||||
@ -89,7 +90,7 @@ class Screen(val tier: Int) extends RedstoneAware with traits.OmniRotatable {
|
||||
if (Wrench.holdsApplicableWrench(player, pos) && getValidRotations(world, pos).contains(side) && !force) false
|
||||
else if (api.Items.get(player.getHeldItem) == api.Items.get(Constants.ItemName.Analyzer)) false
|
||||
else world.getTileEntity(pos) match {
|
||||
case screen: tileentity.Screen if screen.hasKeyboard && (force || player.isSneaking == screen.invertTouchMode) =>
|
||||
case screen: tileentity.Screen if screen.hasKeyboard && (force || player.isSneaking == screen.origin.invertTouchMode) =>
|
||||
// Yep, this GUI is actually purely client side. We could skip this
|
||||
// if, but it is clearer this way (to trigger it from the server we
|
||||
// would have to give screens a "container", which we do not want).
|
||||
|
@ -190,10 +190,10 @@ abstract class SimpleBlock(material: Material = Material.iron) extends BlockCont
|
||||
|
||||
override def recolorBlock(world: World, pos: BlockPos, side: EnumFacing, color: EnumDyeColor) =
|
||||
world.getTileEntity(pos) match {
|
||||
case colored: Colored if colored.color != color =>
|
||||
colored.color = color
|
||||
case colored: Colored if colored.color != Color.byMeta(color) =>
|
||||
colored.color = Color.byMeta(color)
|
||||
world.markBlockForUpdate(pos)
|
||||
false // Don't consume items.
|
||||
true // Blame Vexatos.
|
||||
case _ => super.recolorBlock(world, pos, side, color)
|
||||
}
|
||||
|
||||
|
22
src/main/scala/li/cil/oc/common/command/SimpleCommand.scala
Normal file
22
src/main/scala/li/cil/oc/common/command/SimpleCommand.scala
Normal file
@ -0,0 +1,22 @@
|
||||
package li.cil.oc.common.command
|
||||
|
||||
import net.minecraft.command.CommandBase
|
||||
import net.minecraft.command.ICommandSender
|
||||
import net.minecraft.util.BlockPos
|
||||
|
||||
import scala.collection.convert.WrapAsJava._
|
||||
import scala.collection.mutable
|
||||
|
||||
abstract class SimpleCommand(val name: String) extends CommandBase {
|
||||
protected var aliases = mutable.ListBuffer.empty[String]
|
||||
|
||||
override def getName = name
|
||||
|
||||
override def getAliases = aliases
|
||||
|
||||
override def canCommandSenderUse(source: ICommandSender) = true
|
||||
|
||||
override def isUsernameIndex(command: Array[String], i: Int) = false
|
||||
|
||||
override def addTabCompletionOptions(source: ICommandSender, command: Array[String], pos: BlockPos) = List.empty[AnyRef]
|
||||
}
|
@ -63,6 +63,10 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
|
||||
private var _pendingCommands: Option[PacketBuilder] = None
|
||||
|
||||
private val syncInterval = 100
|
||||
|
||||
private var syncCooldown = syncInterval
|
||||
|
||||
private def pendingCommands = _pendingCommands.getOrElse {
|
||||
val pb = new CompressedPacketBuilder(PacketType.TextBufferMulti)
|
||||
pb.writeUTF(node.address)
|
||||
@ -89,6 +93,8 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
|
||||
val data = new util.TextBuffer(maxResolution, PackedColor.Depth.format(maxDepth))
|
||||
|
||||
def markInitialized(): Unit = syncCooldown = -1 // Stop polling for init state.
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override val canUpdate = true
|
||||
@ -128,6 +134,14 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi
|
||||
_pendingCommands.foreach(_.sendToPlayersNearHost(host, Option(Settings.get.maxWirelessRange * Settings.get.maxWirelessRange)))
|
||||
_pendingCommands = None
|
||||
}
|
||||
|
||||
if (SideTracker.isClient && syncCooldown > 0) {
|
||||
syncCooldown -= 1
|
||||
if (syncCooldown == 0) {
|
||||
syncCooldown = syncInterval
|
||||
ClientPacketSender.sendTextBufferInit(proxy.nodeAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
@ -34,6 +34,7 @@ object Blocks {
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Switch], Settings.namespace + "switch")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Screen], Settings.namespace + "screen")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.ServerRack], Settings.namespace + "serverRack")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.NetSplitter], Settings.namespace + "netSplitter")
|
||||
GameRegistry.registerTileEntity(classOf[tileentity.Waypoint], Settings.namespace + "waypoint")
|
||||
|
||||
Recipes.addBlock(new AccessPoint(), Constants.BlockName.AccessPoint, "oc:accessPoint")
|
||||
@ -73,5 +74,8 @@ object Blocks {
|
||||
|
||||
// v1.5.10
|
||||
Recipes.addBlock(new FakeEndstone(), Constants.BlockName.Endstone, "oc:stoneEndstone")
|
||||
|
||||
// v1.5.14
|
||||
Recipes.addBlock(new NetSplitter(), Constants.BlockName.NetSplitter, "oc:netSplitter")
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package li.cil.oc.common.template
|
||||
import java.lang.reflect.Method
|
||||
|
||||
import com.google.common.base.Strings
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.driver.EnvironmentHost
|
||||
import li.cil.oc.common.IMC
|
||||
@ -74,7 +75,11 @@ object AssemblerTemplates {
|
||||
def validate(inventory: IInventory, slot: Int, stack: ItemStack) = validator match {
|
||||
case Some(method) => IMC.tryInvokeStatic(method, inventory, slot.underlying(), tier.underlying(), stack)(false)
|
||||
case _ => Option(hostClass.fold(api.Driver.driverFor(stack))(api.Driver.driverFor(stack, _))) match {
|
||||
case Some(driver) => driver.slot(stack) == kind && driver.tier(stack) <= tier
|
||||
case Some(driver) => try driver.slot(stack) == kind && driver.tier(stack) <= tier catch {
|
||||
case t: AbstractMethodError =>
|
||||
OpenComputers.log.warn(s"Error trying to query driver '${driver.getClass.getName}' for slot and/or tier information. Probably their fault. Yell at them before coming to OpenComputers for support. :P")
|
||||
false
|
||||
}
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@ class AccessPoint extends Switch with WirelessEndpoint with traits.PowerAcceptor
|
||||
case _ => None
|
||||
}
|
||||
|
||||
override protected def energyThroughput = Settings.get.accessPointRate
|
||||
override def energyThroughput = Settings.get.accessPointRate
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
|
@ -41,7 +41,7 @@ class Assembler extends traits.Environment with traits.PowerAcceptor with traits
|
||||
|
||||
override protected def connector(side: EnumFacing) = Option(if (side != EnumFacing.UP) node else null)
|
||||
|
||||
override protected def energyThroughput = Settings.get.assemblerRate
|
||||
override def energyThroughput = Settings.get.assemblerRate
|
||||
|
||||
override def currentState = {
|
||||
if (isAssembling) util.EnumSet.of(traits.State.IsWorking)
|
||||
|
@ -29,7 +29,7 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with
|
||||
|
||||
override protected def connector(side: EnumFacing) = Option(if (side != facing && machine != null) machine.node.asInstanceOf[Connector] else null)
|
||||
|
||||
override protected def energyThroughput = Settings.get.caseRate(tier)
|
||||
override def energyThroughput = Settings.get.caseRate(tier)
|
||||
|
||||
|
||||
def isCreative = tier == Tier.Four
|
||||
|
@ -45,7 +45,7 @@ class Charger extends traits.Environment with traits.PowerAcceptor with traits.R
|
||||
|
||||
override protected def connector(side: EnumFacing) = Option(if (side != facing) node else null)
|
||||
|
||||
override protected def energyThroughput = Settings.get.chargerRate
|
||||
override def energyThroughput = Settings.get.chargerRate
|
||||
|
||||
override def currentState = {
|
||||
// TODO Refine to only report working if present robots/drones actually *need* power.
|
||||
|
@ -36,7 +36,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
|
||||
var disassembleNextInstantly = false
|
||||
|
||||
def progress = if (queue.isEmpty) 0 else (1 - (queue.size * Settings.get.disassemblerItemCost - buffer) / totalRequiredEnergy) * 100
|
||||
def progress = if (queue.isEmpty) 0.0 else (1 - (queue.size * Settings.get.disassemblerItemCost - buffer) / totalRequiredEnergy) * 100
|
||||
|
||||
private def setActive(value: Boolean) = if (value != isActive) {
|
||||
isActive = value
|
||||
@ -51,7 +51,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
|
||||
override protected def connector(side: EnumFacing) = Option(if (side != EnumFacing.UP) node else null)
|
||||
|
||||
override protected def energyThroughput = Settings.get.disassemblerRate
|
||||
override def energyThroughput = Settings.get.disassemblerRate
|
||||
|
||||
override def currentState = {
|
||||
if (isActive) util.EnumSet.of(traits.State.IsWorking)
|
||||
@ -113,7 +113,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
private def drop(stack: ItemStack) {
|
||||
if (stack != null) {
|
||||
for (side <- EnumFacing.values if stack.stackSize > 0) {
|
||||
InventoryUtils.insertIntoInventoryAt(stack, BlockPosition(this).offset(side), side.getOpposite)
|
||||
InventoryUtils.insertIntoInventoryAt(stack, BlockPosition(this).offset(side), Some(side.getOpposite))
|
||||
}
|
||||
if (stack.stackSize > 0) {
|
||||
spawnStackInWorld(stack, Option(EnumFacing.UP))
|
||||
@ -160,7 +160,7 @@ class Disassembler extends traits.Environment with traits.PowerAcceptor with tra
|
||||
override def isItemValidForSlot(i: Int, stack: ItemStack) =
|
||||
allowDisassembling(stack) &&
|
||||
(((Settings.get.disassembleAllTheThings || api.Items.get(stack) != null) && ItemUtils.getIngredients(stack).nonEmpty) ||
|
||||
DisassemblerTemplates.select(stack) != None)
|
||||
DisassemblerTemplates.select(stack).isDefined)
|
||||
|
||||
private def allowDisassembling(stack: ItemStack) = stack != null && (!stack.hasTagCompound || !stack.getTagCompound.getBoolean(Settings.namespace + "undisassemblable"))
|
||||
|
||||
|
@ -57,7 +57,7 @@ class Microcontroller extends traits.PowerAcceptor with traits.Hub with traits.C
|
||||
|
||||
override protected def connector(side: EnumFacing) = Option(if (side != facing) snooperNode else null)
|
||||
|
||||
override protected def energyThroughput = Settings.get.caseRate(Tier.One)
|
||||
override def energyThroughput = Settings.get.caseRate(Tier.One)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
|
106
src/main/scala/li/cil/oc/common/tileentity/NetSplitter.scala
Normal file
106
src/main/scala/li/cil/oc/common/tileentity/NetSplitter.scala
Normal file
@ -0,0 +1,106 @@
|
||||
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.EventHandler
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
|
||||
class NetSplitter extends traits.Environment with traits.RedstoneAware with api.network.SidedEnvironment {
|
||||
private final val SideCount = EnumFacing.values().length
|
||||
|
||||
_isOutputEnabled = true
|
||||
|
||||
val node = api.Network.newNode(this, Visibility.None).
|
||||
create()
|
||||
|
||||
var isInverted = false
|
||||
|
||||
var openSides = Array.fill(SideCount)(false)
|
||||
|
||||
def compressSides = (EnumFacing.values(), openSides).zipped.foldLeft(0)((acc, entry) => acc | (if (entry._2) 1 << entry._1.ordinal() else 0)).toByte
|
||||
|
||||
def uncompressSides(byte: Byte) = EnumFacing.values().map(d => ((1 << d.ordinal()) & byte) != 0)
|
||||
|
||||
def isSideOpen(side: EnumFacing) = side != null && {
|
||||
val isOpen = openSides(side.ordinal())
|
||||
if (isInverted) !isOpen else isOpen
|
||||
}
|
||||
|
||||
def setSideOpen(side: EnumFacing, value: Boolean): Unit = if (side != null && openSides(side.ordinal()) != value) {
|
||||
openSides(side.ordinal()) = value
|
||||
if (isServer) {
|
||||
node.remove()
|
||||
api.Network.joinOrCreateNetwork(this)
|
||||
ServerPacketSender.sendNetSplitterState(this)
|
||||
world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, "tile.piston.out", 0.5f, world.rand.nextFloat() * 0.25f + 0.7f)
|
||||
}
|
||||
else {
|
||||
world.markBlockForUpdate(getPos)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def sidedNode(side: EnumFacing) = if (isSideOpen(side)) node else null
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
override def canConnect(side: EnumFacing) = isSideOpen(side)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def canUpdate = false
|
||||
|
||||
override protected def initialize(): Unit = {
|
||||
super.initialize()
|
||||
EventHandler.schedule(this)
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override protected def onRedstoneInputChanged(side: EnumFacing, oldMaxValue: Int, newMaxValue: Int): Unit = {
|
||||
super.onRedstoneInputChanged(side, oldMaxValue, newMaxValue)
|
||||
val oldIsInverted = isInverted
|
||||
isInverted = newMaxValue > 0
|
||||
if (isInverted != oldIsInverted) {
|
||||
if (isServer) {
|
||||
node.remove()
|
||||
api.Network.joinOrCreateNetwork(this)
|
||||
ServerPacketSender.sendNetSplitterState(this)
|
||||
world.playSoundEffect(x + 0.5, y + 0.5, z + 0.5, "tile.piston.in", 0.5f, world.rand.nextFloat() * 0.25f + 0.7f)
|
||||
}
|
||||
else {
|
||||
world.markBlockForUpdate(getPos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def readFromNBTForServer(nbt: NBTTagCompound): Unit = {
|
||||
super.readFromNBTForServer(nbt)
|
||||
isInverted = nbt.getBoolean(Settings.namespace + "isInverted")
|
||||
openSides = uncompressSides(nbt.getByte(Settings.namespace + "openSides"))
|
||||
}
|
||||
|
||||
override def writeToNBTForServer(nbt: NBTTagCompound): Unit = {
|
||||
super.writeToNBTForServer(nbt)
|
||||
nbt.setBoolean(Settings.namespace + "isInverted", isInverted)
|
||||
nbt.setByte(Settings.namespace + "openSides", compressSides)
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT) override
|
||||
def readFromNBTForClient(nbt: NBTTagCompound): Unit = {
|
||||
super.readFromNBTForClient(nbt)
|
||||
isInverted = nbt.getBoolean(Settings.namespace + "isInverted")
|
||||
openSides = uncompressSides(nbt.getByte(Settings.namespace + "openSides"))
|
||||
}
|
||||
|
||||
override def writeToNBTForClient(nbt: NBTTagCompound): Unit = {
|
||||
super.writeToNBTForClient(nbt)
|
||||
nbt.setBoolean(Settings.namespace + "isInverted", isInverted)
|
||||
nbt.setByte(Settings.namespace + "openSides", compressSides)
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ class PowerConverter extends traits.PowerAcceptor with traits.Environment with t
|
||||
|
||||
override protected def connector(side: EnumFacing) = Option(node)
|
||||
|
||||
override protected def energyThroughput = Settings.get.powerConverterRate
|
||||
override def energyThroughput = Settings.get.powerConverterRate
|
||||
|
||||
override def canUpdate = isServer
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ class Screen(var tier: Int) extends traits.TextBuffer with SidedEnvironment with
|
||||
}
|
||||
})
|
||||
}
|
||||
if (arrows.size > 0) {
|
||||
if (arrows.nonEmpty) {
|
||||
for (arrow <- arrows) {
|
||||
val hitX = arrow.posX - x
|
||||
val hitY = arrow.posY - y
|
||||
|
@ -58,7 +58,7 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB
|
||||
|
||||
override protected def connector(side: EnumFacing) = Option(if (side != facing) sidedNode(side).asInstanceOf[Connector] else null)
|
||||
|
||||
override protected def energyThroughput = Settings.get.serverRackRate
|
||||
override def energyThroughput = Settings.get.serverRackRate
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package li.cil.oc.common.tileentity.traits
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.EventHandler
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util.BundledRedstone
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
@ -78,13 +79,18 @@ trait RedstoneAware extends RotationAware /* with IConnectable with IRedstoneEmi
|
||||
if (isServer) {
|
||||
if (shouldUpdateInput) {
|
||||
shouldUpdateInput = false
|
||||
for (side <- EnumFacing.values) {
|
||||
updateRedstoneInput(side)
|
||||
}
|
||||
EnumFacing.values().foreach(updateRedstoneInput)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override def validate(): Unit = {
|
||||
super.validate()
|
||||
if (!canUpdate) {
|
||||
EventHandler.schedule(() => EnumFacing.values().foreach(updateRedstoneInput))
|
||||
}
|
||||
}
|
||||
|
||||
def updateRedstoneInput(side: EnumFacing) {
|
||||
input(side, BundledRedstone.computeInput(position, side))
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
package li.cil.oc.common.tileentity.traits.power
|
||||
|
||||
import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api.network.Connector
|
||||
import li.cil.oc.common.tileentity.traits.TileEntity
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
|
||||
trait Common extends TileEntity {
|
||||
@SideOnly(Side.CLIENT)
|
||||
@ -15,7 +15,7 @@ trait Common extends TileEntity {
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
protected def energyThroughput: Double
|
||||
def energyThroughput: Double
|
||||
|
||||
protected def tryAllSides(provider: (Double, EnumFacing) => Double, ratio: Double) {
|
||||
// We make sure to only call this every `Settings.get.tickFrequency` ticks,
|
||||
@ -37,7 +37,15 @@ trait Common extends TileEntity {
|
||||
def canConnectPower(side: EnumFacing) =
|
||||
!Settings.get.ignorePower && (if (isClient) hasConnector(side) else connector(side).isDefined)
|
||||
|
||||
def tryChangeBuffer(side: EnumFacing, amount: Double, doReceive: Boolean = true) =
|
||||
/**
|
||||
* Tries to inject the specified amount of energy into the buffer via the specified side.
|
||||
*
|
||||
* @param side the side to change the buffer through.
|
||||
* @param amount the amount to change the buffer by.
|
||||
* @param doReceive whether to actually inject energy or only simulate it.
|
||||
* @return the amount of energy that was actually injected.
|
||||
*/
|
||||
def tryChangeBuffer(side: EnumFacing, amount: Double, doReceive: Boolean = true): Double =
|
||||
if (isClient || Settings.get.ignorePower) 0
|
||||
else connector(side) match {
|
||||
case Some(node) =>
|
||||
@ -47,14 +55,14 @@ trait Common extends TileEntity {
|
||||
case _ => 0
|
||||
}
|
||||
|
||||
def globalBuffer(side: EnumFacing) =
|
||||
def globalBuffer(side: EnumFacing): Double =
|
||||
if (isClient) 0
|
||||
else connector(side) match {
|
||||
case Some(node) => node.globalBuffer
|
||||
case _ => 0
|
||||
}
|
||||
|
||||
def globalBufferSize(side: EnumFacing) =
|
||||
def globalBufferSize(side: EnumFacing): Double =
|
||||
if (isClient) 0
|
||||
else connector(side) match {
|
||||
case Some(node) => node.globalBufferSize
|
||||
|
@ -32,6 +32,7 @@ object Mods {
|
||||
val CoFHItem = new SimpleMod(IDs.CoFHItem)
|
||||
val CoFHTileEntity = new SimpleMod(IDs.CoFHTileEntity)
|
||||
val CoFHTransport = new SimpleMod(IDs.CoFHTransport)
|
||||
val ColoredLights = new SimpleMod(IDs.ColoredLights)
|
||||
val ComputerCraft = new SimpleMod(IDs.ComputerCraft, version = "@[1.73,)")
|
||||
val CraftingCosts = new SimpleMod(IDs.CraftingCosts)
|
||||
val DeepStorageUnit = new ClassBasedMod(IDs.DeepStorageUnit, "powercrystals.minefactoryreloaded.api.IDeepStorageUnit")()
|
||||
@ -56,6 +57,7 @@ object Mods {
|
||||
val NotEnoughKeys = new SimpleMod(IDs.NotEnoughKeys)
|
||||
val OpenComputers = new SimpleMod(IDs.OpenComputers)
|
||||
val PortalGun = new SimpleMod(IDs.PortalGun)
|
||||
val PowerAdvantage = new SimpleMod(IDs.PowerAdvantage, version = "@[1.2.0,)", providesPower = true)
|
||||
val ProjectRedCore = new SimpleMod(IDs.ProjectRedCore)
|
||||
val ProjectRedTransmission = new SimpleMod(IDs.ProjectRedTransmission)
|
||||
val Railcraft = new SimpleMod(IDs.Railcraft)
|
||||
@ -105,6 +107,7 @@ object Mods {
|
||||
// integration.mystcraft.ModMystcraft,
|
||||
// integration.nek.ModNotEnoughKeys,
|
||||
// integration.projectred.ModProjectRed,
|
||||
integration.poweradvantage.ModPowerAdvantage,
|
||||
// integration.railcraft.ModRailcraft,
|
||||
// integration.redlogic.ModRedLogic,
|
||||
// integration.stargatetech2.ModStargateTech2,
|
||||
@ -165,6 +168,7 @@ object Mods {
|
||||
final val CoFHItem = "CoFHAPI|item"
|
||||
final val CoFHTileEntity = "CoFHAPI|tileentity"
|
||||
final val CoFHTransport = "CoFHAPI|transport"
|
||||
final val ColoredLights = "easycoloredlights"
|
||||
final val ComputerCraft = "ComputerCraft"
|
||||
final val CraftingCosts = "CraftingCosts"
|
||||
final val ElectricalAge = "Eln"
|
||||
@ -174,8 +178,7 @@ object Mods {
|
||||
final val Factorization = "factorization"
|
||||
final val Forestry = "Forestry"
|
||||
final val ForgeMultipart = "ForgeMultipart"
|
||||
final val DeepStorageUnit = "MineFactoryReloaded|DeepStorageUnit"
|
||||
// Doesn't really exist.
|
||||
final val DeepStorageUnit = "MineFactoryReloaded|DeepStorageUnit" // Doesn't really exist.
|
||||
final val Galacticraft = "Galacticraft API"
|
||||
final val GregTech = "gregtech"
|
||||
final val IndustrialCraft2 = "IC2"
|
||||
@ -190,6 +193,7 @@ object Mods {
|
||||
final val NotEnoughKeys = "notenoughkeys"
|
||||
final val OpenComputers = "OpenComputers"
|
||||
final val PortalGun = "PortalGun"
|
||||
final val PowerAdvantage = "poweradvantage"
|
||||
final val ProjectRedCore = "ProjRed|Core"
|
||||
final val ProjectRedTransmission = "ProjRed|Transmission"
|
||||
final val Railcraft = "Railcraft"
|
||||
|
@ -0,0 +1,29 @@
|
||||
package li.cil.oc.integration.coloredlights
|
||||
|
||||
/* TODO Colored Lights
|
||||
import coloredlightscore.src.api.CLApi
|
||||
*/
|
||||
import li.cil.oc.integration.Mods
|
||||
import net.minecraft.block.Block
|
||||
|
||||
// Doesn't need initialization, just a thin wrapper for block light value initialization.
|
||||
object ModColoredLights {
|
||||
def setLightLevel(block: Block, r: Int, g: Int, b: Int): Unit = {
|
||||
// Extra layer of indirection because I've learned to be paranoid when it comes to class loading...
|
||||
if (Mods.ColoredLights.isAvailable)
|
||||
setColoredLightLevel(block, r, g, b)
|
||||
else
|
||||
setPlainLightLevel(block, r, g, b)
|
||||
}
|
||||
|
||||
private def setColoredLightLevel(block: Block, r: Int, g: Int, b: Int): Unit = {
|
||||
/* TODO Colored Lights
|
||||
CLApi.setBlockColorRGB(block, r, g, b)
|
||||
*/
|
||||
}
|
||||
|
||||
private def setPlainLightLevel(block: Block, r: Int, g: Int, b: Int): Unit = {
|
||||
val brightness = Array(r, g, b).max
|
||||
block.setLightLevel((brightness + 0.1f) / 15f)
|
||||
}
|
||||
}
|
@ -121,7 +121,7 @@ class SwitchPeripheral(val switch: Switch) extends IPeripheral {
|
||||
}
|
||||
|
||||
private def checkPort(args: Array[AnyRef], index: Int) = {
|
||||
if (args.length < index - 1 || !args(index).isInstanceOf[Double])
|
||||
if (args.length < index - 1 || !args(index).isInstanceOf[Number])
|
||||
throw new IllegalArgumentException(s"bad argument #${index + 1} (number expected)")
|
||||
val port = args(index).asInstanceOf[Double].toInt
|
||||
if (port < 0 || port > 0xFFFF)
|
||||
|
@ -4,6 +4,10 @@ import codechicken.lib.data.MCDataInput
|
||||
import codechicken.lib.data.MCDataOutput
|
||||
import codechicken.lib.vec.Cuboid6
|
||||
import codechicken.lib.vec.Vector3
|
||||
import codechicken.microblock.ISidedHollowConnect
|
||||
import codechicken.multipart._
|
||||
import cpw.mods.fml.relauncher.Side
|
||||
import cpw.mods.fml.relauncher.SideOnly
|
||||
import li.cil.oc.Constants
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.api
|
||||
@ -27,7 +31,7 @@ import net.minecraft.util.MovingObjectPosition
|
||||
import scala.collection.convert.WrapAsJava
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
class CablePart(val original: Option[tileentity.Cable] = None) extends SimpleBlockPart with TCuboidPart with TNormalOcclusion with network.Environment {
|
||||
class CablePart(val original: Option[tileentity.Cable] = None) extends SimpleBlockPart with TCuboidPart with TSlottedPart with ISidedHollowConnect with TNormalOcclusion with network.Environment {
|
||||
val node = api.Network.newNode(this, Visibility.None).create()
|
||||
|
||||
private var _color = Color.LightGray
|
||||
@ -64,6 +68,11 @@ class CablePart(val original: Option[tileentity.Cable] = None) extends SimpleBlo
|
||||
|
||||
override def getRenderBounds = new Cuboid6(Cable.bounds(world, x, y, z).offset(x, y, z))
|
||||
|
||||
override def getHollowSize(side: Int) = 4 // 4 pixels as this is width of cable.
|
||||
|
||||
override def getSlotMask = 1 << 6 // 6 is center part.
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def activate(player: EntityPlayer, hit: MovingObjectPosition, item: ItemStack) = {
|
||||
|
@ -245,7 +245,6 @@ public class ConverterIIndividual implements Converter {
|
||||
output.put("generation", bee.getGeneration());
|
||||
output.put("hasEffect", bee.hasEffect());
|
||||
output.put("isAlive", bee.isAlive());
|
||||
output.put("isIrregularMating", bee.isIrregularMating());
|
||||
output.put("isNatural", bee.isNatural());
|
||||
|
||||
if (isAnalyzed) genomeReader = new BeeGenomeReader(bee.getGenome());
|
||||
|
@ -27,7 +27,7 @@ object DriverAPU extends DriverCPU with HostAware with EnvironmentAware {
|
||||
|
||||
override def cpuTier(stack: ItemStack) =
|
||||
Delegator.subItem(stack) match {
|
||||
case Some(apu: common.item.APU) => apu.tier
|
||||
case Some(apu: common.item.APU) => apu.cpuTier
|
||||
case _ => Tier.One
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ abstract class DriverCPU extends Item with Processor {
|
||||
|
||||
def cpuTier(stack: ItemStack): Int =
|
||||
Delegator.subItem(stack) match {
|
||||
case Some(cpu: item.CPU) => cpu.tier
|
||||
case Some(cpu: item.CPU) => cpu.cpuTier
|
||||
case _ => Tier.One
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ object DriverGraphicsCard extends Item with HostAware with EnvironmentAware {
|
||||
|
||||
override def tier(stack: ItemStack) =
|
||||
Delegator.subItem(stack) match {
|
||||
case Some(gpu: common.item.GraphicsCard) => gpu.tier
|
||||
case Some(gpu: common.item.GraphicsCard) => gpu.gpuTier
|
||||
case _ => Tier.One
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,46 @@
|
||||
package li.cil.oc.integration.poweradvantage
|
||||
|
||||
import cyano.poweradvantage.api.ConduitType
|
||||
import cyano.poweradvantage.api.modsupport.ILightWeightPowerAcceptor
|
||||
import cyano.poweradvantage.api.modsupport.LightWeightPowerRegistry
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.block
|
||||
import li.cil.oc.common.tileentity.traits.PowerAcceptor
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.tileentity.TileEntity
|
||||
import net.minecraft.util.EnumFacing
|
||||
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
object LightWeightPowerAcceptor extends ILightWeightPowerAcceptor {
|
||||
def init(): Unit = {
|
||||
Block.blockRegistry.collect {
|
||||
case b: Block with block.traits.PowerAcceptor =>
|
||||
LightWeightPowerRegistry.registerLightWeightPowerAcceptor(b, this)
|
||||
}
|
||||
}
|
||||
|
||||
def canAcceptEnergyType(powerType: ConduitType) = ConduitType.areSameType(powerType, "electricity")
|
||||
|
||||
def getEnergyDemand(tileEntity: TileEntity, powerType: ConduitType) = tileEntity match {
|
||||
case acceptor: PowerAcceptor if canAcceptEnergyType(powerType) =>
|
||||
(EnumFacing.values().map(side => {
|
||||
val capacity = acceptor.globalBufferSize(side)
|
||||
val stored = acceptor.globalBuffer(side)
|
||||
capacity - stored
|
||||
}).max / Settings.get.ratioPowerAdvantage).toInt
|
||||
case _ => 0
|
||||
}
|
||||
|
||||
def addEnergy(tileEntity: TileEntity, amountAdded: Float, powerType: ConduitType) = tileEntity match {
|
||||
case acceptor: PowerAcceptor if canAcceptEnergyType(powerType) =>
|
||||
var remainingEnergy = math.min(amountAdded, acceptor.energyThroughput) * Settings.get.ratioPowerAdvantage
|
||||
// .exists() for early exit.
|
||||
EnumFacing.values().exists(side => {
|
||||
remainingEnergy -= acceptor.tryChangeBuffer(side, remainingEnergy)
|
||||
remainingEnergy <= 0
|
||||
})
|
||||
amountAdded - (remainingEnergy / Settings.get.ratioPowerAdvantage).toFloat
|
||||
case _ => 0
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package li.cil.oc.integration.poweradvantage
|
||||
|
||||
import li.cil.oc.integration.ModProxy
|
||||
import li.cil.oc.integration.Mods
|
||||
|
||||
object ModPowerAdvantage extends ModProxy {
|
||||
override def getMod = Mods.PowerAdvantage
|
||||
|
||||
override def initialize(): Unit = {
|
||||
LightWeightPowerAcceptor.init()
|
||||
}
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
package li.cil.oc.server
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import net.minecraft.command.CommandBase
|
||||
import net.minecraft.command.ICommandSender
|
||||
import net.minecraft.command.WrongUsageException
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.BlockPos
|
||||
import net.minecraftforge.fml.common.event.FMLServerStartingEvent
|
||||
|
||||
import scala.collection.convert.wrapAsJava._
|
||||
import scala.collection.mutable
|
||||
|
||||
object CommandHandler {
|
||||
def register(e: FMLServerStartingEvent) {
|
||||
e.registerServerCommand(WirelessRenderingCommand)
|
||||
e.registerServerCommand(NonDisassemblyAgreementCommand)
|
||||
}
|
||||
|
||||
// OP levels for reference:
|
||||
// 1 - Ops can bypass spawn protection.
|
||||
// 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks.
|
||||
// 3 - Ops can use /ban, /deop, /kick, and /op.
|
||||
// 4 - Ops can use /stop.
|
||||
|
||||
object WirelessRenderingCommand extends SimpleCommand("oc_renderWirelessNetwork") {
|
||||
aliases += "oc_wlan"
|
||||
|
||||
override def getCommandUsage(source: ICommandSender) = name + " <boolean>"
|
||||
|
||||
override def execute(sender: ICommandSender, command: Array[String]) {
|
||||
Settings.rTreeDebugRenderer =
|
||||
if (command != null && command.length > 0)
|
||||
CommandBase.parseBoolean(command(0))
|
||||
else
|
||||
!Settings.rTreeDebugRenderer
|
||||
}
|
||||
|
||||
override def getRequiredPermissionLevel = 2
|
||||
}
|
||||
|
||||
object NonDisassemblyAgreementCommand extends SimpleCommand("oc_preventDisassembling") {
|
||||
aliases += "oc_nodis"
|
||||
aliases += "oc_prevdis"
|
||||
|
||||
override def getCommandUsage(source: ICommandSender) = name + " <boolean>"
|
||||
|
||||
override def execute(sender: ICommandSender, command: Array[String]) {
|
||||
sender match {
|
||||
case player: EntityPlayer =>
|
||||
val stack = player.getHeldItem
|
||||
if (stack != null) {
|
||||
if (!stack.hasTagCompound) {
|
||||
stack.setTagCompound(new NBTTagCompound())
|
||||
}
|
||||
val nbt = stack.getTagCompound
|
||||
val preventDisassembly =
|
||||
if (command != null && command.length > 0)
|
||||
CommandBase.parseBoolean(command(0))
|
||||
else
|
||||
!nbt.getBoolean(Settings.namespace + "undisassemblable")
|
||||
if (preventDisassembly)
|
||||
nbt.setBoolean(Settings.namespace + "undisassemblable", true)
|
||||
else
|
||||
nbt.removeTag(Settings.namespace + "undisassemblable")
|
||||
if (nbt.hasNoTags) stack.setTagCompound(null)
|
||||
}
|
||||
case _ => throw new WrongUsageException("Can only be used by players.")
|
||||
}
|
||||
}
|
||||
|
||||
override def getRequiredPermissionLevel = 2
|
||||
}
|
||||
|
||||
abstract class SimpleCommand(val name: String) extends CommandBase {
|
||||
protected var aliases = mutable.ListBuffer.empty[String]
|
||||
|
||||
override def getName = name
|
||||
|
||||
override def getAliases = aliases
|
||||
|
||||
override def canCommandSenderUse(sender: ICommandSender) = true
|
||||
|
||||
override def addTabCompletionOptions(sender: ICommandSender, args: Array[String], pos: BlockPos) = List.empty[AnyRef]
|
||||
|
||||
override def isUsernameIndex(command: Array[String], i: Int) = false
|
||||
}
|
||||
|
||||
}
|
@ -522,6 +522,16 @@ object PacketSender {
|
||||
pb.sendToPlayersNearHost(host)
|
||||
}
|
||||
|
||||
def sendNetSplitterState(t: tileentity.NetSplitter): Unit = {
|
||||
val pb = new SimplePacketBuilder(PacketType.NetSplitterState)
|
||||
|
||||
pb.writeTileEntity(t)
|
||||
pb.writeBoolean(t.isInverted)
|
||||
pb.writeByte(t.compressSides)
|
||||
|
||||
pb.sendToPlayersNearTileEntity(t)
|
||||
}
|
||||
|
||||
def sendScreenTouchMode(t: tileentity.Screen, value: Boolean) {
|
||||
val pb = new SimplePacketBuilder(PacketType.ScreenTouchMode)
|
||||
|
||||
|
11
src/main/scala/li/cil/oc/server/command/CommandHandler.scala
Normal file
11
src/main/scala/li/cil/oc/server/command/CommandHandler.scala
Normal file
@ -0,0 +1,11 @@
|
||||
package li.cil.oc.server.command
|
||||
|
||||
import net.minecraftforge.fml.common.event.FMLServerStartingEvent
|
||||
|
||||
object CommandHandler {
|
||||
def register(e: FMLServerStartingEvent) {
|
||||
e.registerServerCommand(NonDisassemblyAgreementCommand)
|
||||
e.registerServerCommand(WirelessRenderingCommand)
|
||||
e.registerServerCommand(SpawnComputerCommand)
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package li.cil.oc.server.command
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.command.SimpleCommand
|
||||
import net.minecraft.command.CommandBase
|
||||
import net.minecraft.command.ICommandSender
|
||||
import net.minecraft.command.WrongUsageException
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
object NonDisassemblyAgreementCommand extends SimpleCommand("oc_preventDisassembling") {
|
||||
aliases += "oc_nodis"
|
||||
aliases += "oc_prevdis"
|
||||
|
||||
override def getCommandUsage(source: ICommandSender) = name + " <boolean>"
|
||||
|
||||
override def execute(source: ICommandSender, command: Array[String]) {
|
||||
source match {
|
||||
case player: EntityPlayer =>
|
||||
val stack = player.getHeldItem
|
||||
if (stack != null) {
|
||||
if (!stack.hasTagCompound) {
|
||||
stack.setTagCompound(new NBTTagCompound())
|
||||
}
|
||||
val nbt = stack.getTagCompound
|
||||
val preventDisassembly =
|
||||
if (command != null && command.length > 0)
|
||||
CommandBase.parseBoolean(command(0))
|
||||
else
|
||||
!nbt.getBoolean(Settings.namespace + "undisassemblable")
|
||||
if (preventDisassembly)
|
||||
nbt.setBoolean(Settings.namespace + "undisassemblable", true)
|
||||
else
|
||||
nbt.removeTag(Settings.namespace + "undisassemblable")
|
||||
if (nbt.hasNoTags) stack.setTagCompound(null)
|
||||
}
|
||||
case _ => throw new WrongUsageException("Can only be used by players.")
|
||||
}
|
||||
}
|
||||
|
||||
// OP levels for reference:
|
||||
// 1 - Ops can bypass spawn protection.
|
||||
// 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks.
|
||||
// 3 - Ops can use /ban, /deop, /kick, and /op.
|
||||
// 4 - Ops can use /stop.
|
||||
|
||||
override def getRequiredPermissionLevel = 2
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package li.cil.oc.server.command
|
||||
|
||||
import li.cil.oc.Constants
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.common.command.SimpleCommand
|
||||
import li.cil.oc.common.tileentity
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import li.cil.oc.util.InventoryUtils
|
||||
import net.minecraft.command.ICommandSender
|
||||
import net.minecraft.command.WrongUsageException
|
||||
import net.minecraft.entity.player.EntityPlayer
|
||||
import net.minecraft.util.ChatComponentText
|
||||
import net.minecraft.util.EnumFacing
|
||||
import net.minecraft.util.MovingObjectPosition
|
||||
import net.minecraft.util.Vec3
|
||||
|
||||
object SpawnComputerCommand extends SimpleCommand("oc_spawnComputer") {
|
||||
aliases += "oc_sc"
|
||||
|
||||
final val MaxDistance = 16
|
||||
|
||||
override def getCommandUsage(source: ICommandSender): String = name
|
||||
|
||||
override def execute(source: ICommandSender, command: Array[String]) {
|
||||
source match {
|
||||
case player: EntityPlayer =>
|
||||
val world = player.getEntityWorld
|
||||
val origin = new Vec3(player.posX, player.posY + player.getEyeHeight, player.posZ)
|
||||
val direction = player.getLookVec
|
||||
val lookAt = origin.addVector(direction.xCoord * MaxDistance, direction.yCoord * MaxDistance, direction.zCoord * MaxDistance)
|
||||
world.rayTraceBlocks(origin, lookAt) match {
|
||||
case hit: MovingObjectPosition if hit.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK =>
|
||||
val hitPos = BlockPosition(hit.getBlockPos, world)
|
||||
val casePos = hitPos.offset(hit.sideHit)
|
||||
val screenPos = casePos.offset(EnumFacing.UP)
|
||||
val keyboardPos = screenPos.offset(EnumFacing.UP)
|
||||
|
||||
if (!world.isAirBlock(casePos) || !world.isAirBlock(screenPos) || !world.isAirBlock(keyboardPos)) {
|
||||
player.addChatMessage(new ChatComponentText("Target position obstructed."))
|
||||
return
|
||||
}
|
||||
|
||||
world.setBlock(casePos, api.Items.get(Constants.BlockName.CaseCreative).block())
|
||||
world.setBlock(screenPos, api.Items.get(Constants.BlockName.ScreenTier2).block())
|
||||
world.setBlock(keyboardPos, api.Items.get(Constants.BlockName.Keyboard).block())
|
||||
world.getTileEntity(keyboardPos) match {
|
||||
case t: tileentity.traits.Rotatable => t.setFromFacing(EnumFacing.UP)
|
||||
case _ => // ???
|
||||
}
|
||||
world.getTileEntity(screenPos) match {
|
||||
case t: tileentity.traits.Rotatable => t.setFromFacing(EnumFacing.NORTH)
|
||||
case _ => // ???
|
||||
}
|
||||
|
||||
api.Network.joinOrCreateNetwork(world.getTileEntity(casePos))
|
||||
|
||||
InventoryUtils.insertIntoInventoryAt(api.Items.get(Constants.ItemName.APUCreative).createItemStack(1), casePos)
|
||||
InventoryUtils.insertIntoInventoryAt(api.Items.get(Constants.ItemName.RAMTier6).createItemStack(2), casePos)
|
||||
InventoryUtils.insertIntoInventoryAt(api.Items.get(Constants.ItemName.HDDTier3).createItemStack(1), casePos)
|
||||
InventoryUtils.insertIntoInventoryAt(api.Items.get(Constants.ItemName.LuaBios).createItemStack(1), casePos)
|
||||
InventoryUtils.insertIntoInventoryAt(api.Items.get(Constants.ItemName.OpenOS).createItemStack(1), casePos)
|
||||
case _ => player.addChatMessage(new ChatComponentText("You need to be looking at a nearby block."))
|
||||
}
|
||||
case _ => throw new WrongUsageException("Can only be used by players.")
|
||||
}
|
||||
}
|
||||
|
||||
// OP levels for reference:
|
||||
// 1 - Ops can bypass spawn protection.
|
||||
// 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks.
|
||||
// 3 - Ops can use /ban, /deop, /kick, and /op.
|
||||
// 4 - Ops can use /stop.
|
||||
|
||||
override def getRequiredPermissionLevel = 2
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package li.cil.oc.server.command
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.common.command.SimpleCommand
|
||||
import net.minecraft.command.CommandBase
|
||||
import net.minecraft.command.ICommandSender
|
||||
|
||||
object WirelessRenderingCommand extends SimpleCommand("oc_renderWirelessNetwork") {
|
||||
aliases += "oc_wlan"
|
||||
|
||||
override def getCommandUsage(source: ICommandSender) = name + " <boolean>"
|
||||
|
||||
override def execute(source: ICommandSender, command: Array[String]) {
|
||||
Settings.rTreeDebugRenderer =
|
||||
if (command != null && command.length > 0)
|
||||
CommandBase.parseBoolean(command(0))
|
||||
else
|
||||
!Settings.rTreeDebugRenderer
|
||||
}
|
||||
|
||||
// OP levels for reference:
|
||||
// 1 - Ops can bypass spawn protection.
|
||||
// 2 - Ops can use /clear, /difficulty, /effect, /gamemode, /gamerule, /give, /summon, /setblock and /tp, and can edit command blocks.
|
||||
// 3 - Ops can use /ban, /deop, /kick, and /op.
|
||||
// 4 - Ops can use /stop.
|
||||
|
||||
override def getRequiredPermissionLevel = 2
|
||||
}
|
@ -99,6 +99,10 @@ object FileSystem extends api.detail.FileSystemAPI {
|
||||
|
||||
def fromMemory(capacity: Long): api.fs.FileSystem = new RamFileSystem(capacity)
|
||||
|
||||
override def asReadOnly(fileSystem: api.fs.FileSystem) =
|
||||
if (fileSystem.isReadOnly) fileSystem
|
||||
else new ReadOnlyWrapper(fileSystem)
|
||||
|
||||
def asManagedEnvironment(fileSystem: api.fs.FileSystem, label: Label, host: EnvironmentHost, accessSound: String, speed: Int) =
|
||||
Option(fileSystem).flatMap(fs => Some(component.FileSystem(fs, label, Option(host), Option(accessSound), speed))).orNull
|
||||
|
||||
|
47
src/main/scala/li/cil/oc/server/fs/ReadOnlyWrapper.scala
Normal file
47
src/main/scala/li/cil/oc/server/fs/ReadOnlyWrapper.scala
Normal file
@ -0,0 +1,47 @@
|
||||
package li.cil.oc.server.fs
|
||||
|
||||
import java.io.FileNotFoundException
|
||||
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.api.fs.Mode
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
|
||||
private class ReadOnlyWrapper(val fileSystem: api.fs.FileSystem) extends api.fs.FileSystem {
|
||||
override def isReadOnly = true
|
||||
|
||||
override def spaceTotal = fileSystem.spaceUsed()
|
||||
|
||||
override def spaceUsed = fileSystem.spaceUsed()
|
||||
|
||||
override def exists(path: String) = fileSystem.exists(path)
|
||||
|
||||
override def size(path: String) = fileSystem.size(path)
|
||||
|
||||
override def isDirectory(path: String) = fileSystem.isDirectory(path)
|
||||
|
||||
override def lastModified(path: String) = fileSystem.lastModified(path)
|
||||
|
||||
override def list(path: String) = fileSystem.list(path)
|
||||
|
||||
override def delete(path: String) = false
|
||||
|
||||
override def makeDirectory(path: String) = false
|
||||
|
||||
override def rename(from: String, to: String) = false
|
||||
|
||||
override def setLastModified(path: String, time: Long) = false
|
||||
|
||||
override def open(path: String, mode: Mode) = mode match {
|
||||
case Mode.Read => fileSystem.open(path, mode)
|
||||
case Mode.Write => throw new FileNotFoundException()
|
||||
case Mode.Append => throw new FileNotFoundException()
|
||||
}
|
||||
|
||||
override def getHandle(handle: Int) = fileSystem.getHandle(handle)
|
||||
|
||||
override def close() = fileSystem.close()
|
||||
|
||||
override def load(nbt: NBTTagCompound) = fileSystem.load(nbt)
|
||||
|
||||
override def save(nbt: NBTTagCompound) = fileSystem.save(nbt)
|
||||
}
|
@ -25,7 +25,7 @@ class OSAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
|
||||
else "%d/%m/%y %H:%M:%S"
|
||||
val time =
|
||||
if (lua.getTop > 1 && lua.isNumber(2)) lua.toNumber(2) * 1000 / 60 / 60
|
||||
else machine.worldTime + 5000
|
||||
else machine.worldTime + 6000
|
||||
|
||||
val dt = GameTimeFormatter.parse(time)
|
||||
def fmt(format: String) {
|
||||
|
@ -18,7 +18,7 @@ class OSAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) {
|
||||
else "%d/%m/%y %H:%M:%S"
|
||||
val time =
|
||||
if (args.narg > 1 && args.isnumber(2)) args.todouble(2) * 1000 / 60 / 60
|
||||
else machine.worldTime + 5000
|
||||
else machine.worldTime + 6000
|
||||
|
||||
val dt = GameTimeFormatter.parse(time)
|
||||
def fmt(format: String) = {
|
||||
|
@ -64,6 +64,8 @@ object Color {
|
||||
|
||||
val byTier = Array(EnumDyeColor.SILVER, EnumDyeColor.YELLOW, EnumDyeColor.CYAN, EnumDyeColor.MAGENTA)
|
||||
|
||||
def byMeta(meta: EnumDyeColor) = byOreName(dyes(meta.getDyeDamage))
|
||||
|
||||
def findDye(stack: ItemStack) = byOreName.keys.find(OreDictionary.getOres(_).exists(oreStack => OreDictionary.itemMatches(stack, oreStack, false)))
|
||||
|
||||
def isDye(stack: ItemStack) = findDye(stack).isDefined
|
||||
|
@ -67,8 +67,8 @@ object GameTimeFormatter {
|
||||
def parse(time: Double) = {
|
||||
var day = (time / 24000).toLong
|
||||
val weekDay = ((4 + day) % 7).toInt
|
||||
val year = 1970 + (day / 365.2425).toInt
|
||||
val yearDay = (day % 365.2425).toInt
|
||||
val year = 1970 + (day / 364.2425).toInt
|
||||
val yearDay = (day % 364.2425).toInt
|
||||
day = yearDay
|
||||
val monthLengths = monthLengthsForYear(year)
|
||||
var month = 0
|
||||
@ -80,7 +80,7 @@ object GameTimeFormatter {
|
||||
var seconds = ((time % 24000) * 60 * 60 / 1000).toInt
|
||||
var minutes = seconds / 60
|
||||
seconds = seconds % 60
|
||||
val hours = (1 + minutes / 60) % 24
|
||||
val hours = (minutes / 60) % 24
|
||||
minutes = minutes % 60
|
||||
|
||||
new DateTime(year, month + 1, day.toInt + 1, weekDay + 1, yearDay + 1, hours, minutes, seconds)
|
||||
@ -107,7 +107,6 @@ object GameTimeFormatter {
|
||||
val monthLengths = monthLengthsForYear(year)
|
||||
val days = ((year - 1970) * 365.2425).ceil.toInt + (0 until mon - 1).foldLeft(0)((d, m) => d + monthLengths(m)) + mday - 1
|
||||
val secs = sec + (min + (hour - 1 + days * 24) * 60) * 60
|
||||
if (secs < 0) None
|
||||
else Option(secs)
|
||||
Option(secs)
|
||||
}
|
||||
}
|
||||
|
@ -211,8 +211,8 @@ object InventoryUtils {
|
||||
* Utility method for calling <tt>insertIntoInventory</tt> on an inventory
|
||||
* in the world.
|
||||
*/
|
||||
def insertIntoInventoryAt(stack: ItemStack, position: BlockPosition, side: EnumFacing, limit: Int = 64, simulate: Boolean = false): Boolean =
|
||||
inventoryAt(position).exists(insertIntoInventory(stack, _, Option(side), limit, simulate))
|
||||
def insertIntoInventoryAt(stack: ItemStack, position: BlockPosition, side: Option[EnumFacing] = None, limit: Int = 64, simulate: Boolean = false): Boolean =
|
||||
inventoryAt(position).exists(insertIntoInventory(stack, _, side, limit, simulate))
|
||||
|
||||
/**
|
||||
* Utility method for calling <tt>extractFromInventory</tt> on an inventory
|
||||
|
@ -12,13 +12,14 @@ class RTree[Data](private val M: Int)(implicit val coordinate: Data => (Double,
|
||||
|
||||
private var root = new NonLeaf()
|
||||
|
||||
def apply(value: Data): Option[(Double, Double, Double)] =
|
||||
def apply(value: Data): Option[(Double, Double, Double)] = this.synchronized {
|
||||
entries.get(value).fold(None: Option[(Double, Double, Double)])(position => Some(position.bounds.min.asTuple))
|
||||
}
|
||||
|
||||
// Allows debug rendering of the tree.
|
||||
def allBounds = root.allBounds(0)
|
||||
def allBounds = this.synchronized(root.allBounds(0))
|
||||
|
||||
def add(value: Data): Boolean = {
|
||||
def add(value: Data): Boolean = this.synchronized {
|
||||
val replaced = remove(value)
|
||||
val entry = new Leaf(value, new Point(value))
|
||||
entries += value -> entry
|
||||
@ -29,7 +30,7 @@ class RTree[Data](private val M: Int)(implicit val coordinate: Data => (Double,
|
||||
!replaced
|
||||
}
|
||||
|
||||
def remove(value: Data): Boolean =
|
||||
def remove(value: Data): Boolean = this.synchronized {
|
||||
entries.remove(value) match {
|
||||
case Some(node) =>
|
||||
val change = root.remove(node)
|
||||
@ -43,9 +44,11 @@ class RTree[Data](private val M: Int)(implicit val coordinate: Data => (Double,
|
||||
true
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
def query(from: (Double, Double, Double), to: (Double, Double, Double)) =
|
||||
def query(from: (Double, Double, Double), to: (Double, Double, Double)) = this.synchronized {
|
||||
root.query(new Rectangle(new Point(from), new Point(to)))
|
||||
}
|
||||
|
||||
private abstract class Node {
|
||||
def bounds: Rectangle
|
||||
|
Loading…
x
Reference in New Issue
Block a user