mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-13 17:28:52 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8
Conflicts: build.gradle src/main/scala/li/cil/oc/client/renderer/tileentity/HologramRenderer.scala src/main/scala/li/cil/oc/common/Loot.scala src/main/scala/li/cil/oc/common/tileentity/traits/BundledRedstoneAware.scala src/main/scala/li/cil/oc/common/tileentity/traits/RedstoneAware.scala src/main/scala/li/cil/oc/common/tileentity/traits/TileEntity.scala src/main/scala/li/cil/oc/integration/Mods.scala src/main/scala/li/cil/oc/util/Audio.scala
This commit is contained in:
commit
852c5b18db
21
build.gradle
21
build.gradle
@ -83,10 +83,26 @@ repositories {
|
||||
name = "bc"
|
||||
url = "http://mod-buildcraft.com/"
|
||||
}
|
||||
maven {
|
||||
name = "BluePower"
|
||||
url = "http://maven.bluepowermod.com/"
|
||||
}
|
||||
maven {
|
||||
name = "chickenbones"
|
||||
url = "http://chickenbones.net/maven/"
|
||||
}
|
||||
maven {
|
||||
name = "ic2, forestry"
|
||||
url = "http://maven.ic2.player.to/"
|
||||
}
|
||||
maven {
|
||||
name = "IGW"
|
||||
url = "http://maven.k-4u.nl/"
|
||||
}
|
||||
maven {
|
||||
name = "mobius"
|
||||
url = "http://mobiusstrip.eu/maven"
|
||||
}
|
||||
maven {
|
||||
name = "ue"
|
||||
url = "http://calclavia.com/maven/"
|
||||
@ -161,11 +177,15 @@ dependencies {
|
||||
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"
|
||||
provided "com.bluepowermod:BluePower:${config.bluepower.version}:deobf"
|
||||
provided "com.gregoriust.gregtech:gregtech_${config.minecraft.version}:${config.gt.version}:dev"
|
||||
provided "com.mod-buildcraft:buildcraft:${config.bc.version}:dev"
|
||||
provided "dev.calclavia.resonantengine:resonant-engine:${config.re.version}:dev"
|
||||
provided "igwmod:IGW-Mod-1.7.10:${config.igwmod.version}:userdev"
|
||||
provided "mcp.mobius.waila:Waila:${config.waila.version}_${config.minecraft.version}:dev"
|
||||
provided "net.industrial-craft:industrialcraft-2:${config.ic2.version}:dev"
|
||||
provided "net.sengir.forestry:forestry_${config.minecraft.version}:${config.forestry.version}:dev"
|
||||
provided "qmunity:QmunityLib:${config.qmunitylib.version}:deobf"
|
||||
provided "tmech:TMechworks:${config.minecraft.version}-${config.tmech.version}:deobf"
|
||||
|
||||
provided name: 'GalacticraftCoreAll', version: config.gc.version, ext: 'jar'
|
||||
@ -226,7 +246,6 @@ minecraft {
|
||||
// stable_# stables are built at the discretion of the MCP team.
|
||||
mappings = "snapshot_20141130"
|
||||
|
||||
replaceIn "li/cil/oc/OpenComputers.scala"
|
||||
replace "@VERSION@", project.simpleVersion
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ ae2.version=rv2-beta-26
|
||||
bc.version=6.4.9
|
||||
bloodmagic.cf=2223/203
|
||||
bloodmagic.version=1.3.0a-1
|
||||
bluepower.version=0.2.928
|
||||
cc.cf=2216/236
|
||||
cc.version=1.65
|
||||
ccc.version=1.0.5.34
|
||||
@ -23,12 +24,14 @@ gc.build=3
|
||||
gc.version=3.0.7
|
||||
gt.version=5.04.06
|
||||
ic2.version=2.2.654-experimental
|
||||
igwmod.version=1.1.3-18
|
||||
mekanism.build=5
|
||||
mekanism.version=7.1.2
|
||||
mfr.cf=2229/626
|
||||
mfr.version=[1.7.10]2.8.0RC8-86
|
||||
nei.version=1.0.5.82
|
||||
projred.version=4.5.8.59
|
||||
qmunitylib.version=0.1.105
|
||||
rc.cf=2219/321
|
||||
rc.version=1.7.10-9.4.0.0
|
||||
redlogic.version=59.0.3
|
||||
|
@ -1,11 +1,6 @@
|
||||
package li.cil.oc.api;
|
||||
|
||||
import li.cil.oc.api.detail.DriverAPI;
|
||||
import li.cil.oc.api.detail.FileSystemAPI;
|
||||
import li.cil.oc.api.detail.ItemAPI;
|
||||
import li.cil.oc.api.detail.MachineAPI;
|
||||
import li.cil.oc.api.detail.ManualAPI;
|
||||
import li.cil.oc.api.detail.NetworkAPI;
|
||||
import li.cil.oc.api.detail.*;
|
||||
|
||||
/**
|
||||
* Central reference for the API.
|
||||
@ -16,7 +11,7 @@ import li.cil.oc.api.detail.NetworkAPI;
|
||||
*/
|
||||
public class API {
|
||||
public static final String ID_OWNER = "OpenComputers|Core";
|
||||
public static final String VERSION = "5.2.2";
|
||||
public static final String VERSION = "5.2.3";
|
||||
|
||||
public static DriverAPI driver = null;
|
||||
public static FileSystemAPI fileSystem = null;
|
||||
|
@ -141,6 +141,51 @@ public interface Machine extends ManagedEnvironment, Context {
|
||||
*/
|
||||
double cpuTime();
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
/**
|
||||
* Play a sound using the machine's built-in speaker.
|
||||
* <p/>
|
||||
* This is what's used to emit beep codes when an error occurs while trying
|
||||
* to start the computer, for example, and what's used for playing sounds
|
||||
* when <tt>computer.beep</tt> is called.
|
||||
* <p/>
|
||||
* Be responsible in how you limit calls to this, as each call will cause
|
||||
* a packet to be sent to all nearby clients, and will cause the receiving
|
||||
* clients to generate the required sound sample on-the-fly. It is
|
||||
* therefore recommended to not call this too frequently, and to limit the
|
||||
* length of the sound to something relatively short (not longer than a few
|
||||
* seconds at most).
|
||||
* <p/>
|
||||
* The audio will be played at the machine's host's location.
|
||||
*
|
||||
* @param frequency the frequency of the tone to generate.
|
||||
* @param duration the duration of the tone to generate, in milliseconds.
|
||||
*/
|
||||
void beep(short frequency, short duration);
|
||||
|
||||
/**
|
||||
* Utility method for playing beep codes.
|
||||
* <p/>
|
||||
* The underlying functionality is similar to that of {@link #beep(short, short)},
|
||||
* except that this will play tones at a fixed frequency, and two different
|
||||
* durations - in a pattern as defined in the passed string.
|
||||
* <p/>
|
||||
* This is useful for generating beep codes, such as for boot errors. It
|
||||
* has the advantage of only generating a single network packet, and
|
||||
* generating a single, longer sound sample for the full pattern. As such
|
||||
* the same considerations should be made as for {@link #beep(short, short)},
|
||||
* i.e. prefer not to use overly long patterns.
|
||||
* <p/>
|
||||
* The passed pattern must consist of dots (<tt>.</tt>) and dashes (<tt>-</tt>),
|
||||
* where a dot is short tone, and a dash is a long tone.
|
||||
* <p/>
|
||||
* The audio will be played at the machine's host's location.
|
||||
*
|
||||
* @param pattern the beep pattern to play.
|
||||
*/
|
||||
void beep(String pattern);
|
||||
|
||||
/**
|
||||
* Crashes the computer.
|
||||
* <p/>
|
||||
@ -221,6 +266,8 @@ public interface Machine extends ManagedEnvironment, Context {
|
||||
*/
|
||||
Object[] invoke(Value value, String method, Object[] args) throws Exception;
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
/**
|
||||
* The list of users registered on this machine.
|
||||
* <p/>
|
||||
|
@ -6,6 +6,6 @@
|
||||
|
||||
3D prints can be recycled by putting them as input into a [3D printer](printer.md). This will re-use some of the [chamelium](../item/chamelium.md) that was used to print them. Color that was used to print the model will not be recycled.
|
||||
|
||||
Holding the key for OpenComputers' extended tooltips (default is [Shift]), a print's active state will be shown, if any.
|
||||
Holding the key for OpenComputers' extended tooltips (default is `Shift`), a print's active state will be shown, if any.
|
||||
|
||||
Printed blocks are also Forge MultiPart compatible. If present, multiple prints can be placed into a single block-space, unless they do not collide, and the total number of shapes in the block-space does not exceed the limit for a single model. Due to the nature of Forge MultiPart, prints can therefore also be placed into the same block-space as any other Forge MultiPart compatible block, such as torches, levers, cables or red alloy wires from Project Red, for example.
|
||||
|
@ -6,6 +6,6 @@
|
||||
|
||||
В дополнение к этому, точки доступа могут использоваться как повторители: они могут перенаправлять сообщения из проводной линии другим устройствам; или беспроводные сообщения как проводные, так и беспроводные.
|
||||
|
||||
Коммутаторы и [коммутаторы](switch.md) *не* отслеживают, какие пакеты и куда они передали, поэтому в сети могут образовываться петли или вы можете получать одно сообщение несколько раз. Из-за ограниченного буфера сообщений коммутатора, частое отправление сообщений приводит к их потере. Вы можете улучшить [коммутатор](switch.md) или точку доступа для увеличения скорости обработки сообщений, а также увеличения размера сообщений.
|
||||
Точки доступа и [коммутаторы](switch.md) *не* отслеживают, какие пакеты и куда они передали, поэтому в сети могут образовываться петли или вы можете получать одно сообщение несколько раз. Из-за ограниченного буфера сообщений коммутатора, частое отправление сообщений приводит к их потере. Вы можете улучшить [коммутатор](switch.md) или точку доступа для увеличения скорости обработки сообщений, а также увеличения размера сообщений.
|
||||
|
||||
Сообщения, могут перенаправлены всего несколько раз, поэтому цепочки с произвольным количеством коммутаторов или точек доступа невозможны. По умолчанию, сообщение может быть перенаправлено пять раз.
|
||||
|
@ -0,0 +1,9 @@
|
||||
# Путевая точка
|
||||
|
||||

|
||||
|
||||
Главное не что это такое, а как это использовать. [Навигационное улучшение](../item/navigationUpgrade.md) может обнаруживать путевые точки, что позволяет устройствам с этим улучшением ориентироваться в игровом мире. Это можно использовать для написания программ для [роботов](robot.md) и [дронов](../item/drone.md).
|
||||
|
||||
Обратите внимание, что актуальным местоположением считается *блок перед путевой точкой* (выделен с помощью частиц), именно это местоположение будет передано, при запросе его навигационным улучшением. Это позволяет поместить путевую точку рядом или над сундуком и позволит обратиться к путевой точке "над сундуком", без необходимости вращения самой точки.
|
||||
|
||||
Путевая точка имеет два параметра, которые могут быть использованы при ее опросе навигационным улучшением: уровень редстоун сигнала, который получает точка и изменяемое имя. Имя это строка, состоящая из 32 символов, оно может быть изменено через интерфейс или через API. Эти два параметра могут быть использованы устройством, для определения, что можно сделать с путевой точкой. Например, сортировочная программа может использовать блоки с высоким уровнем редстоун сигнала как входные, а с низким как выходные.
|
@ -4,4 +4,6 @@
|
||||
|
||||
Данное улучшение добавляет навигацию и ориентацию для устройств. Получаемые координаты начинаются от центра карты, где было собрано улучшение, радиус функционирования зависит от размера карты.
|
||||
|
||||
Карта внутри улучшения может быть обновлена, повторным крафтом улучшения с новой картой. Старая карта при этом будет возвращена игроку.
|
||||
Карта внутри улучшения может быть обновлена, повторным крафтом улучшения с новой картой. Старая карта при этом будет возвращена игроку.
|
||||
|
||||
Наиболее эффективно это улучшение работает в паре с одной или несколькими [точками доступа](../block/waypoint.md).
|
@ -35,6 +35,7 @@ tile.oc.screen2.name=Монитор (2-ой уровень)
|
||||
tile.oc.screen3.name=Монитор (3-ий уровень)
|
||||
tile.oc.serverRack.name=Серверная стойка
|
||||
tile.oc.switch.name=Коммутатор
|
||||
tile.oc.waypoint.name=Путевая точка
|
||||
|
||||
# Items
|
||||
item.oc.AbstractBusCard.name=Карта абстрактной шины
|
||||
@ -133,6 +134,7 @@ item.oc.UpgradeSolarGenerator.name=Улучшение "Солнечный ген
|
||||
item.oc.UpgradeTank.name=Улучшение "Бак для жидкостей"
|
||||
item.oc.UpgradeTankController.name=Улучшение "Контроллер бака"
|
||||
item.oc.UpgradeTractorBeam.name=Улучшение "Притягивающий луч"
|
||||
oc:tooltip.Waypoint=Добавляет путевую точку для устройств с навигационным улучшением.
|
||||
item.oc.WirelessNetworkCard.name=Плата беспроводной сети
|
||||
item.oc.WorldSensorCard.name=Карта-мировой сенсор
|
||||
item.oc.wrench.name=Ключ
|
||||
|
@ -2,15 +2,21 @@ local event = require "event"
|
||||
local component = require "component"
|
||||
local keyboard = require "keyboard"
|
||||
|
||||
local args = {...}
|
||||
|
||||
local interactive = io.output() == io.stdout
|
||||
local color, isPal, evt
|
||||
if interactive then
|
||||
color, isPal = component.gpu.getForeground()
|
||||
end
|
||||
io.write("Press 'q' to exit\n")
|
||||
io.write("Press 'Ctrl-C' to exit\n")
|
||||
pcall(function()
|
||||
repeat
|
||||
evt = table.pack(event.pull())
|
||||
if #args > 0 then
|
||||
evt = table.pack(event.pullMultiple("interrupted", table.unpack(args)))
|
||||
else
|
||||
evt = table.pack(event.pull())
|
||||
end
|
||||
if interactive then component.gpu.setForeground(0xCC2200) end
|
||||
io.write("[" .. os.date("%T") .. "] ")
|
||||
if interactive then component.gpu.setForeground(0x44CC00) end
|
||||
@ -25,7 +31,7 @@ pcall(function()
|
||||
end
|
||||
|
||||
io.write("\n")
|
||||
until evt[1] == "key_down" and evt[4] == keyboard.keys.q
|
||||
until evt[1] == "interrupted"
|
||||
end)
|
||||
if interactive then
|
||||
component.gpu.setForeground(color, isPal)
|
||||
|
@ -4,19 +4,6 @@ local keyboard = require("keyboard")
|
||||
local event, listeners, timers = {}, {}, {}
|
||||
local lastInterrupt = -math.huge
|
||||
|
||||
local function matches(signal, name, filter)
|
||||
if name and not (type(signal[1]) == "string" and signal[1]:match(name))
|
||||
then
|
||||
return false
|
||||
end
|
||||
for i = 1, filter.n do
|
||||
if filter[i] ~= nil and filter[i] ~= signal[i + 1] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function call(callback, ...)
|
||||
local result, message = pcall(callback, ...)
|
||||
if not result and type(event.onError) == "function" then
|
||||
@ -64,6 +51,45 @@ local function tick()
|
||||
end
|
||||
end
|
||||
|
||||
local function createPlainFilter(name, ...)
|
||||
local filter = table.pack(...)
|
||||
if name == nil and filter.n == 0 then
|
||||
return nil
|
||||
end
|
||||
|
||||
return function(...)
|
||||
local signal = table.pack(...)
|
||||
if name and not (type(signal[1]) == "string" and signal[1]:match(name)) then
|
||||
return false
|
||||
end
|
||||
for i = 1, filter.n do
|
||||
if filter[i] ~= nil and filter[i] ~= signal[i + 1] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function createMultipleFilter(...)
|
||||
local filter = table.pack(...)
|
||||
if filter.n == 0 then
|
||||
return nil
|
||||
end
|
||||
|
||||
return function(...)
|
||||
local signal = table.pack(...)
|
||||
if type(signal[1]) ~= "string" then
|
||||
return false
|
||||
end
|
||||
for i = 1, filter.n do
|
||||
if filter[i] ~= nil and signal[1]:match(filter[i]) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function event.cancel(timerId)
|
||||
@ -118,28 +144,50 @@ end
|
||||
|
||||
function event.pull(...)
|
||||
local args = table.pack(...)
|
||||
local seconds, name, filter
|
||||
if type(args[1]) == "string" then
|
||||
name = args[1]
|
||||
filter = table.pack(table.unpack(args, 2, args.n))
|
||||
return event.pullFiltered(createPlainFilter(...))
|
||||
else
|
||||
checkArg(1, args[1], "number", "nil")
|
||||
checkArg(2, args[2], "string", "nil")
|
||||
seconds = args[1]
|
||||
name = args[2]
|
||||
filter = table.pack(table.unpack(args, 3, args.n))
|
||||
return event.pullFiltered(args[1], createPlainFilter(select(2, ...)))
|
||||
end
|
||||
end
|
||||
|
||||
local hasFilter = name ~= nil
|
||||
if not hasFilter then
|
||||
for i = 1, filter.n do
|
||||
hasFilter = hasFilter or filter[i] ~= nil
|
||||
function event.pullMultiple(...)
|
||||
local seconds
|
||||
local args
|
||||
if type(...) == "number" then
|
||||
seconds = ...
|
||||
args = table.pack(select(2,...))
|
||||
for i=1,args.n do
|
||||
checkArg(i+1, args[i], "string", "nil")
|
||||
end
|
||||
else
|
||||
args = table.pack(...)
|
||||
for i=1,args.n do
|
||||
checkArg(i, args[i], "string", "nil")
|
||||
end
|
||||
end
|
||||
return event.pullFiltered(seconds, createMultipleFilter(table.unpack(args, 1, args.n)))
|
||||
|
||||
end
|
||||
|
||||
function event.pullFiltered(...)
|
||||
local args = table.pack(...)
|
||||
local seconds, filter
|
||||
|
||||
if type(args[1]) == "function" then
|
||||
filter = args[1]
|
||||
else
|
||||
checkArg(1, args[1], "number", "nil")
|
||||
checkArg(2, args[2], "function", "nil")
|
||||
seconds = args[1]
|
||||
filter = args[2]
|
||||
end
|
||||
|
||||
local deadline = seconds and
|
||||
(computer.uptime() + seconds) or
|
||||
(hasFilter and math.huge or 0)
|
||||
(filter and math.huge or 0)
|
||||
repeat
|
||||
local closest = seconds and deadline or math.huge
|
||||
for _, timer in pairs(timers) do
|
||||
@ -154,9 +202,15 @@ function event.pull(...)
|
||||
lastInterrupt = computer.uptime()
|
||||
error("interrupted", 0)
|
||||
end
|
||||
if not (seconds or hasFilter) or matches(signal, name, filter) then
|
||||
if event.shouldSoftInterrupt() and (filter == nil or filter("interrupted", computer.uptime() - lastInterrupt)) then
|
||||
local awaited = computer.uptime() - lastInterrupt
|
||||
lastInterrupt = computer.uptime()
|
||||
return "interrupted", awaited
|
||||
end
|
||||
if not (seconds or filter) or filter == nil or filter(table.unpack(signal, 1, signal.n)) then
|
||||
return table.unpack(signal, 1, signal.n)
|
||||
end
|
||||
|
||||
until computer.uptime() >= deadline
|
||||
end
|
||||
|
||||
@ -167,6 +221,12 @@ function event.shouldInterrupt()
|
||||
keyboard.isKeyDown(keyboard.keys.c)
|
||||
end
|
||||
|
||||
function event.shouldSoftInterrupt()
|
||||
return computer.uptime() - lastInterrupt > 1 and
|
||||
keyboard.isControlDown() and
|
||||
keyboard.isKeyDown(keyboard.keys.c)
|
||||
end
|
||||
|
||||
function event.timer(interval, callback, times)
|
||||
checkArg(1, interval, "number")
|
||||
checkArg(2, callback, "function")
|
||||
|
@ -2,5 +2,12 @@ NAME
|
||||
dmesg - display messages(events)
|
||||
|
||||
SYNOPIS
|
||||
dmesg
|
||||
dmesg [EVENT]...
|
||||
|
||||
EXAMPLES
|
||||
dmesg
|
||||
Shows all events.
|
||||
|
||||
dmesg touch
|
||||
Shows only "touch" events.
|
||||
|
||||
|
@ -888,6 +888,26 @@ sandbox = {
|
||||
},
|
||||
|
||||
debug = {
|
||||
getinfo = function(...)
|
||||
local result = debug.getinfo(...)
|
||||
if result then
|
||||
-- Only make primitive information available in the sandbox.
|
||||
return {
|
||||
source = result.source,
|
||||
short_src = result.short_src,
|
||||
linedefined = result.linedefined,
|
||||
lastlinedefined = result.lastlinedefined,
|
||||
what = result.what,
|
||||
currentline = result.currentline,
|
||||
nups = result.nups,
|
||||
nparams = result.nparams,
|
||||
isvararg = result.isvararg,
|
||||
name = result.name,
|
||||
namewhat = result.namewhat,
|
||||
istailcall = result.istailcall
|
||||
}
|
||||
end
|
||||
end,
|
||||
traceback = debug.traceback
|
||||
},
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
package li.cil.oc.client.renderer.markdown
|
||||
|
||||
object MarkupFormat extends Enumeration {
|
||||
val Markdown, IGWMod = Value
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package li.cil.oc.client.renderer.markdown.segment
|
||||
|
||||
import li.cil.oc.client.renderer.markdown.Document
|
||||
import li.cil.oc.client.renderer.markdown.MarkupFormat
|
||||
import net.minecraft.client.gui.FontRenderer
|
||||
|
||||
trait BasicTextSegment extends Segment {
|
||||
@ -38,6 +39,8 @@ trait BasicTextSegment extends Segment {
|
||||
lines * lineHeight(renderer)
|
||||
}
|
||||
|
||||
override def toString(format: MarkupFormat.Value): String = text
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
protected def text: String
|
||||
|
@ -1,9 +1,13 @@
|
||||
package li.cil.oc.client.renderer.markdown.segment
|
||||
|
||||
import li.cil.oc.client.renderer.markdown.MarkupFormat
|
||||
import net.minecraft.util.EnumChatFormatting
|
||||
|
||||
private[markdown] class BoldSegment(parent: Segment, text: String) extends TextSegment(parent, text) {
|
||||
override protected def format = EnumChatFormatting.BOLD.toString
|
||||
|
||||
override def toString: String = s"{BoldSegment: text = $text}"
|
||||
override def toString(format: MarkupFormat.Value): String = format match {
|
||||
case MarkupFormat.Markdown => s"**$text**"
|
||||
case MarkupFormat.IGWMod => s"[prefix{l}]$text [prefix{}]"
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package li.cil.oc.client.renderer.markdown.segment
|
||||
|
||||
import li.cil.oc.client.renderer.TextBufferRenderCache
|
||||
import li.cil.oc.client.renderer.markdown.MarkupFormat
|
||||
import net.minecraft.client.gui.FontRenderer
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
@ -30,5 +31,8 @@ private[markdown] class CodeSegment(val parent: Segment, val text: String) exten
|
||||
|
||||
override protected def stringWidth(s: String, renderer: FontRenderer): Int = s.length * TextBufferRenderCache.renderer.charRenderWidth
|
||||
|
||||
override def toString: String = s"{CodeSegment: text = $text}"
|
||||
override def toString(format: MarkupFormat.Value): String = format match {
|
||||
case MarkupFormat.Markdown => s"`$text`"
|
||||
case MarkupFormat.IGWMod => s"[prefix{1}]$text [prefix{}]"
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package li.cil.oc.client.renderer.markdown.segment
|
||||
|
||||
import li.cil.oc.client.renderer.markdown.MarkupFormat
|
||||
import net.minecraft.util.EnumChatFormatting
|
||||
|
||||
private[markdown] class HeaderSegment(parent: Segment, text: String, val level: Int) extends TextSegment(parent, text) {
|
||||
@ -9,5 +10,8 @@ private[markdown] class HeaderSegment(parent: Segment, text: String, val level:
|
||||
|
||||
override protected def format = EnumChatFormatting.UNDERLINE.toString
|
||||
|
||||
override def toString: String = s"{HeaderSegment: text = $text, level = $level}"
|
||||
override def toString(format: MarkupFormat.Value): String = format match {
|
||||
case MarkupFormat.Markdown => s"${"#" * level} $text"
|
||||
case MarkupFormat.IGWMod => s"[prefix{l}]$text [prefix{}]"
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
package li.cil.oc.client.renderer.markdown.segment
|
||||
|
||||
import li.cil.oc.client.renderer.markdown.MarkupFormat
|
||||
import net.minecraft.util.EnumChatFormatting
|
||||
|
||||
private[markdown] class ItalicSegment(parent: Segment, text: String) extends TextSegment(parent, text) {
|
||||
override protected def format = EnumChatFormatting.ITALIC.toString
|
||||
|
||||
override def toString: String = s"{ItalicSegment: text = $text}"
|
||||
override def toString(format: MarkupFormat.Value): String = format match {
|
||||
case MarkupFormat.Markdown => s"*$text*"
|
||||
case MarkupFormat.IGWMod => s"[prefix{o}]$text [prefix{}]"
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,10 @@ package li.cil.oc.client.renderer.markdown.segment
|
||||
import java.net.URI
|
||||
|
||||
import li.cil.oc.Localization
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.client.Manual
|
||||
import li.cil.oc.client.renderer.markdown.MarkupFormat
|
||||
import net.minecraft.client.Minecraft
|
||||
|
||||
private[markdown] class LinkSegment(parent: Segment, text: String, val url: String) extends TextSegment(parent, text) with InteractiveSegment {
|
||||
@ -54,5 +56,10 @@ private[markdown] class LinkSegment(parent: Segment, text: String, val url: Stri
|
||||
}
|
||||
}
|
||||
|
||||
override def toString: String = s"{LinkSegment: text = $text, url = $url}"
|
||||
override def toString(format: MarkupFormat.Value): String = format match {
|
||||
case MarkupFormat.Markdown => s"[$text]($url)"
|
||||
case MarkupFormat.IGWMod =>
|
||||
if (url.startsWith("http://") || url.startsWith("https://")) text
|
||||
else s"[link{${OpenComputers.ID}:$url}]$text [link{}]"
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package li.cil.oc.client.renderer.markdown.segment
|
||||
import li.cil.oc.api.manual.ImageRenderer
|
||||
import li.cil.oc.api.manual.InteractiveImageRenderer
|
||||
import li.cil.oc.client.renderer.markdown.Document
|
||||
import li.cil.oc.client.renderer.markdown.MarkupFormat
|
||||
import net.minecraft.client.gui.FontRenderer
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
@ -74,5 +75,8 @@ private[markdown] class RenderSegment(val parent: Segment, val title: String, va
|
||||
hovered
|
||||
}
|
||||
|
||||
override def toString: String = s"{RendererSegment: title = $title, imageRenderer = $imageRenderer}"
|
||||
override def toString(format: MarkupFormat.Value): String = format match {
|
||||
case MarkupFormat.Markdown => s""
|
||||
case MarkupFormat.IGWMod => "(Sorry, images only work in the OpenComputers manual for now.)" // TODO
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package li.cil.oc.client.renderer.markdown.segment
|
||||
|
||||
import li.cil.oc.client.renderer.markdown.MarkupFormat
|
||||
import net.minecraft.client.gui.FontRenderer
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.collection.mutable
|
||||
import scala.util.matching.Regex
|
||||
|
||||
trait Segment {
|
||||
@ -46,6 +48,25 @@ trait Segment {
|
||||
*/
|
||||
def render(x: Int, y: Int, indent: Int, maxWidth: Int, renderer: FontRenderer, mouseX: Int, mouseY: Int): Option[InteractiveSegment] = None
|
||||
|
||||
def renderAsText(format: MarkupFormat.Value): Iterable[String] = {
|
||||
var segment = this
|
||||
val result = mutable.Buffer.empty[String]
|
||||
val builder = mutable.StringBuilder.newBuilder
|
||||
while (segment != null) {
|
||||
builder.append(segment.toString(format))
|
||||
if (segment.isLast) {
|
||||
result += builder.toString()
|
||||
builder.clear()
|
||||
}
|
||||
segment = segment.next
|
||||
}
|
||||
result.toIterable
|
||||
}
|
||||
|
||||
def toString(format: MarkupFormat.Value): String
|
||||
|
||||
override def toString: String = toString(MarkupFormat.Markdown)
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
// Used during construction, checks a segment for inner segments.
|
||||
|
@ -1,9 +1,13 @@
|
||||
package li.cil.oc.client.renderer.markdown.segment
|
||||
|
||||
import li.cil.oc.client.renderer.markdown.MarkupFormat
|
||||
import net.minecraft.util.EnumChatFormatting
|
||||
|
||||
private[markdown] class StrikethroughSegment(parent: Segment, text: String) extends TextSegment(parent, text) {
|
||||
override protected def format = EnumChatFormatting.STRIKETHROUGH.toString
|
||||
|
||||
override def toString: String = s"{StrikethroughSegment: text = $text}"
|
||||
override def toString(format: MarkupFormat.Value): String = format match {
|
||||
case MarkupFormat.Markdown => s"~~$text~~"
|
||||
case MarkupFormat.IGWMod => s"[prefix{m}]$text [prefix{}]"
|
||||
}
|
||||
}
|
||||
|
@ -96,6 +96,4 @@ private[markdown] class TextSegment(val parent: Segment, val text: String) exten
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
override def toString: String = s"{TextSegment: text = $text}"
|
||||
}
|
||||
|
@ -57,7 +57,18 @@ object HologramRenderer extends TileEntitySpecialRenderer with Callable[Int] wit
|
||||
/** Used to pass the current screen along to call(). */
|
||||
private var hologram: Hologram = null
|
||||
|
||||
/**
|
||||
* Whether initialization failed (e.g. due to an out of memory error) and we
|
||||
* should render using the fallback renderer instead.
|
||||
*/
|
||||
private var failed = false
|
||||
|
||||
override def renderTileEntityAt(tileEntity: TileEntity, x: Double, y: Double, z: Double, f: Float, damage: Int) {
|
||||
if (failed) {
|
||||
HologramRendererFallback.renderTileEntityAt(tileEntity, x, y, z, f, damage)
|
||||
return
|
||||
}
|
||||
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||
|
||||
hologram = tileEntity.asInstanceOf[Hologram]
|
||||
@ -143,12 +154,13 @@ object HologramRenderer extends TileEntitySpecialRenderer with Callable[Int] wit
|
||||
}
|
||||
|
||||
def draw(glBuffer: Int) {
|
||||
initialize()
|
||||
validate(glBuffer)
|
||||
publish(glBuffer)
|
||||
if (initialize()) {
|
||||
validate(glBuffer)
|
||||
publish(glBuffer)
|
||||
}
|
||||
}
|
||||
|
||||
private def initialize() {
|
||||
private def initialize(): Boolean = !failed && (try {
|
||||
// First run only, create structure information.
|
||||
if (commonBuffer == 0) {
|
||||
dataBuffer = BufferUtils.createIntBuffer(hologram.width * hologram.width * hologram.height * 6 * 4 * 2)
|
||||
@ -223,7 +235,14 @@ object HologramRenderer extends TileEntitySpecialRenderer with Callable[Int] wit
|
||||
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, commonBuffer)
|
||||
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STATIC_DRAW)
|
||||
}
|
||||
true
|
||||
}
|
||||
catch {
|
||||
case oom: OutOfMemoryError =>
|
||||
HologramRendererFallback.text = "Not enough memory"
|
||||
failed = true
|
||||
false
|
||||
})
|
||||
|
||||
private def validate(glBuffer: Int) {
|
||||
// Refresh indexes when the hologram's data changed.
|
||||
|
@ -7,7 +7,7 @@ import net.minecraft.tileentity.TileEntity
|
||||
import org.lwjgl.opengl.GL11
|
||||
|
||||
object HologramRendererFallback extends TileEntitySpecialRenderer {
|
||||
val text = "Requires OpenGL 1.5"
|
||||
var text = "Requires OpenGL 1.5"
|
||||
|
||||
override def renderTileEntityAt(tileEntity: TileEntity, x: Double, y: Double, z: Double, f: Float, damage: Int) {
|
||||
RenderState.checkError(getClass.getName + ".renderTileEntityAt: entering (aka: wasntme)")
|
||||
|
@ -124,6 +124,6 @@ object Loot extends WeightedRandomChestContent(new ItemStack(null: Item), 1, 1,
|
||||
case Some(disk) =>
|
||||
ChestGenHooks.generateStacks(random, disk,
|
||||
theMinimumChanceToGenerateItem, theMaximumChanceToGenerateItem)
|
||||
case _ => Array.empty
|
||||
case _ => Array.empty[ItemStack]
|
||||
}
|
||||
}
|
||||
|
@ -31,9 +31,9 @@ import net.minecraftforge.fml.common.registry.GameRegistry
|
||||
import scala.collection.mutable
|
||||
|
||||
object Items extends ItemAPI {
|
||||
private val descriptors = mutable.Map.empty[String, ItemInfo]
|
||||
val descriptors = mutable.Map.empty[String, ItemInfo]
|
||||
|
||||
private val names = mutable.Map.empty[Any, String]
|
||||
val names = mutable.Map.empty[Any, String]
|
||||
|
||||
override def get(name: String): ItemInfo = descriptors.get(name).orNull
|
||||
|
||||
|
@ -16,6 +16,7 @@ import net.minecraft.world.World
|
||||
@Injectable.InterfaceList(Array(
|
||||
new Injectable.Interface(value = "appeng.api.implementations.items.IAEWrench", modid = Mods.IDs.AppliedEnergistics2),
|
||||
new Injectable.Interface(value = "buildcraft.api.tools.IToolWrench", modid = Mods.IDs.BuildCraftTools),
|
||||
new Injectable.Interface(value = "com.bluepowermod.api.misc.IScrewdriver", modid = Mods.IDs.BluePower),
|
||||
new Injectable.Interface(value = "cofh.api.item.IToolHammer", modid = Mods.IDs.CoFHItem),
|
||||
new Injectable.Interface(value = "crazypants.enderio.tool.ITool", modid = Mods.IDs.EnderIO),
|
||||
new Injectable.Interface(value = "mekanism.api.IMekWrench", modid = Mods.IDs.Mekanism),
|
||||
@ -49,6 +50,9 @@ class Wrench extends SimpleItem with api.internal.Wrench {
|
||||
|
||||
def canWrench(stack: ItemStack, player: EntityPlayer, pos: BlockPos): Boolean = true
|
||||
|
||||
// BluePower
|
||||
def damage(stack: ItemStack, damage: Int, player: EntityPlayer, simulated: Boolean): Boolean = damage == 0
|
||||
|
||||
// BuildCraft
|
||||
|
||||
def canWrench(player: EntityPlayer, pos: BlockPos): Boolean = true
|
||||
|
@ -2,17 +2,16 @@ package li.cil.oc.common.tileentity.traits
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util.BundledRedstone
|
||||
import li.cil.oc.util.ExtendedNBT._
|
||||
import net.minecraftforge.fml.common.Optional
|
||||
|
||||
/* TODO RedLogic
|
||||
import mods.immibis.redlogic.api.wiring.IBundledEmitter
|
||||
import mods.immibis.redlogic.api.wiring.IBundledUpdatable
|
||||
import mods.immibis.redlogic.api.wiring.IInsulatedRedstoneWire
|
||||
*/
|
||||
/* TODO Project Red
|
||||
import mrtjp.projectred.api.IBundledTile
|
||||
import mrtjp.projectred.api.ProjectRedAPI
|
||||
*/
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
@ -55,6 +54,23 @@ trait BundledRedstoneAware extends RedstoneAware /* with IBundledEmitter with IB
|
||||
def bundledInput(side: EnumFacing) =
|
||||
(_bundledInput(side.ordinal()), _rednetInput(side.ordinal())).zipped.map(math.max)
|
||||
|
||||
def bundledInput(side: EnumFacing, newBundledInput: Array[Int]): Unit = {
|
||||
val ownBundledInput = _bundledInput(side.ordinal())
|
||||
val oldMaxValue = ownBundledInput.max
|
||||
var changed = false
|
||||
if (newBundledInput != null) for (color <- 0 until 16) {
|
||||
changed = changed || (ownBundledInput(color) >= 0 && ownBundledInput(color) != newBundledInput(color))
|
||||
ownBundledInput(color) = newBundledInput(color)
|
||||
}
|
||||
else for (color <- 0 until 16) {
|
||||
changed = changed || ownBundledInput(color) > 0
|
||||
ownBundledInput(color) = 0
|
||||
}
|
||||
if (changed) {
|
||||
onRedstoneInputChanged(side, oldMaxValue, ownBundledInput.max)
|
||||
}
|
||||
}
|
||||
|
||||
def bundledInput(side: EnumFacing, color: Int) =
|
||||
math.max(_bundledInput(side.ordinal())(color), _rednetInput(side.ordinal())(color))
|
||||
|
||||
@ -92,21 +108,7 @@ trait BundledRedstoneAware extends RedstoneAware /* with IBundledEmitter with IB
|
||||
|
||||
override def updateRedstoneInput(side: EnumFacing) {
|
||||
super.updateRedstoneInput(side)
|
||||
val ownBundledInput = _bundledInput(side.ordinal())
|
||||
val newBundledInput = computeBundledInput(side)
|
||||
val oldMaxValue = ownBundledInput.max
|
||||
var changed = false
|
||||
if (newBundledInput != null) for (color <- 0 until 16) {
|
||||
changed = changed || (ownBundledInput(color) >= 0 && ownBundledInput(color) != newBundledInput(color))
|
||||
ownBundledInput(color) = newBundledInput(color)
|
||||
}
|
||||
else for (color <- 0 until 16) {
|
||||
changed = changed || ownBundledInput(color) > 0
|
||||
ownBundledInput(color) = 0
|
||||
}
|
||||
if (changed) {
|
||||
onRedstoneInputChanged(side, oldMaxValue, ownBundledInput.max)
|
||||
}
|
||||
bundledInput(side, BundledRedstone.computeBundledInput(position, side))
|
||||
}
|
||||
|
||||
override def readFromNBTForServer(nbt: NBTTagCompound) {
|
||||
@ -147,49 +149,6 @@ trait BundledRedstoneAware extends RedstoneAware /* with IBundledEmitter with IB
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
protected def computeBundledInput(side: EnumFacing): Array[Int] = {
|
||||
/* TODO RedLogic
|
||||
val redLogic =
|
||||
if (Mods.RedLogic.isAvailable) {
|
||||
val (nx, ny, nz) = (x + side.offsetX, y + side.offsetY, z + side.offsetZ)
|
||||
if (world.blockExists(nx, ny, nz)) world.getTileEntity(nx, ny, nz) match {
|
||||
case wire: IInsulatedRedstoneWire =>
|
||||
var strength: Array[Int] = null
|
||||
for (face <- -1 to 5 if wire.wireConnectsInDirection(face, side.ordinal()) && strength == null) {
|
||||
strength = Array.fill(16)(0)
|
||||
strength(wire.getInsulatedWireColour) = wire.getEmittedSignalStrength(face, side.ordinal())
|
||||
}
|
||||
strength
|
||||
case emitter: IBundledEmitter =>
|
||||
var strength: Array[Int] = null
|
||||
for (i <- -1 to 5 if strength == null) {
|
||||
strength = Option(emitter.getBundledCableStrength(i, side.getOpposite.ordinal())).fold(null: Array[Int])(_.map(_ & 0xFF))
|
||||
}
|
||||
strength
|
||||
case _ => null
|
||||
}
|
||||
else null
|
||||
}
|
||||
else null
|
||||
*/
|
||||
/* TODO Project Red
|
||||
val projectRed =
|
||||
if (Mods.ProjectRedTransmission.isAvailable) {
|
||||
Option(ProjectRedAPI.transmissionAPI.getBundledInput(world, x, y, z, side.ordinal)).fold(null: Array[Int])(_.map(_ & 0xFF))
|
||||
}
|
||||
else null
|
||||
*/
|
||||
/* TODO RedLogic or Project Red
|
||||
(redLogic, projectRed) match {
|
||||
case (a: Array[Int], b: Array[Int]) => (a, b).zipped.map((r1, r2) => math.max(r1, r2))
|
||||
case (a: Array[Int], _) => a
|
||||
case (_, b: Array[Int]) => b
|
||||
case _ => null
|
||||
}
|
||||
*/
|
||||
null
|
||||
}
|
||||
|
||||
override protected def onRedstoneOutputEnabledChanged() {
|
||||
/* TODO MFR
|
||||
if (Mods.MineFactoryReloaded.isAvailable) {
|
||||
|
@ -2,10 +2,8 @@ package li.cil.oc.common.tileentity.traits
|
||||
|
||||
import li.cil.oc.Settings
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util.BundledRedstone
|
||||
import li.cil.oc.server.{PacketSender => ServerPacketSender}
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import net.minecraft.block.BlockRedstoneWire
|
||||
import net.minecraftforge.fml.common.Optional
|
||||
import net.minecraftforge.fml.relauncher.Side
|
||||
import net.minecraftforge.fml.relauncher.SideOnly
|
||||
@ -17,7 +15,6 @@ import mods.immibis.redlogic.api.wiring.IRedstoneUpdatable
|
||||
import mods.immibis.redlogic.api.wiring.IWire
|
||||
*/
|
||||
|
||||
import net.minecraft.init.Blocks
|
||||
import net.minecraft.nbt.NBTTagCompound
|
||||
import net.minecraft.util.EnumFacing
|
||||
|
||||
@ -52,6 +49,14 @@ trait RedstoneAware extends RotationAware /* with IConnectable with IRedstoneEmi
|
||||
|
||||
def input(side: EnumFacing) = _input(side.ordinal()) max 0
|
||||
|
||||
def input(side: EnumFacing, newInput: Int): Unit = {
|
||||
val oldInput = _input(side.ordinal())
|
||||
_input(side.ordinal()) = newInput
|
||||
if (oldInput >= 0 && newInput != oldInput) {
|
||||
onRedstoneInputChanged(side, oldInput, newInput)
|
||||
}
|
||||
}
|
||||
|
||||
def maxInput = EnumFacing.values.map(input).max
|
||||
|
||||
def output(side: EnumFacing) = _output(toLocal(side).ordinal())
|
||||
@ -81,12 +86,7 @@ trait RedstoneAware extends RotationAware /* with IConnectable with IRedstoneEmi
|
||||
}
|
||||
|
||||
def updateRedstoneInput(side: EnumFacing) {
|
||||
val oldInput = _input(side.ordinal())
|
||||
val newInput = computeInput(side)
|
||||
_input(side.ordinal()) = newInput
|
||||
if (oldInput >= 0 && newInput != oldInput) {
|
||||
onRedstoneInputChanged(side, oldInput, newInput)
|
||||
}
|
||||
input(side, BundledRedstone.computeInput(position, side))
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
@ -122,32 +122,6 @@ trait RedstoneAware extends RotationAware /* with IConnectable with IRedstoneEmi
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
protected def computeInput(side: EnumFacing) = {
|
||||
val blockPos = BlockPosition(x, y, z).offset(side)
|
||||
if (!world.blockExists(blockPos)) 0
|
||||
else {
|
||||
// See BlockRedstoneLogic.getInputStrength() for reference.
|
||||
val vanilla = math.max(world.getIndirectPowerLevelTo(blockPos, side),
|
||||
if (world.getBlock(blockPos) == Blocks.redstone_wire) world.getBlockMetadata(blockPos).getValue(BlockRedstoneWire.POWER).asInstanceOf[Integer].intValue() else 0)
|
||||
val redLogic = 0
|
||||
/* TODO RedLogic
|
||||
val redLogic = if (Mods.RedLogic.isAvailable) {
|
||||
world.getTileEntity(blockPos) match {
|
||||
case emitter: IRedstoneEmitter =>
|
||||
var strength = 0
|
||||
for (i <- -1 to 5) {
|
||||
strength = math.max(strength, emitter.getEmittedSignalStrength(i, side.getOpposite.ordinal()))
|
||||
}
|
||||
strength
|
||||
case _ => 0
|
||||
}
|
||||
}
|
||||
else 0
|
||||
*/
|
||||
math.max(vanilla, redLogic)
|
||||
}
|
||||
}
|
||||
|
||||
protected def onRedstoneInputChanged(side: EnumFacing, oldMaxValue: Int, newMaxValue: Int) {}
|
||||
|
||||
protected def onRedstoneOutputEnabledChanged() {
|
||||
|
@ -22,6 +22,7 @@ object Mods {
|
||||
val AppliedEnergistics2 = new SimpleMod(IDs.AppliedEnergistics2, version = "@[rv1,)", providesPower = true)
|
||||
val BattleGear2 = new SimpleMod(IDs.BattleGear2)
|
||||
val BloodMagic = new SimpleMod(IDs.BloodMagic)
|
||||
val BluePower = new SimpleMod(IDs.BluePower)
|
||||
val BuildCraft = new SimpleMod(IDs.BuildCraft)
|
||||
val BuildCraftTiles = new SimpleMod(IDs.BuildCraftTiles)
|
||||
val BuildCraftTools = new SimpleMod(IDs.BuildCraftTools)
|
||||
@ -43,6 +44,7 @@ object Mods {
|
||||
val GregTech = new ClassBasedMod(IDs.GregTech, "gregtech.api.GregTech_API")()
|
||||
val IndustrialCraft2 = new SimpleMod(IDs.IndustrialCraft2, providesPower = true)
|
||||
val IndustrialCraft2Classic = new SimpleMod(IDs.IndustrialCraft2Classic, providesPower = true)
|
||||
val IngameWiki = new SimpleMod(IDs.IngameWiki, version = "@[1.1.3,)")
|
||||
val Mekanism = new SimpleMod(IDs.Mekanism, providesPower = true)
|
||||
val Minecraft = new SimpleMod(IDs.Minecraft)
|
||||
val MineFactoryReloaded = new SimpleMod(IDs.MineFactoryReloaded)
|
||||
@ -76,43 +78,50 @@ object Mods {
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
val Proxies = Array(
|
||||
// integration.appeng.ModAppEng,
|
||||
// integration.bloodmagic.ModBloodMagic,
|
||||
// integration.buildcraft.tools.ModBuildCraftAPITools,
|
||||
// integration.buildcraft.tiles.ModBuildCraftAPITiles,
|
||||
// integration.buildcraft.transport.ModBuildCraftAPITransport,
|
||||
// integration.cofh.energy.ModCoFHEnergy,
|
||||
// integration.cofh.item.ModCoFHItem,
|
||||
// integration.cofh.tileentity.ModCoFHTileEntity,
|
||||
// integration.cofh.transport.ModCoFHTransport,
|
||||
// integration.enderstorage.ModEnderStorage,
|
||||
// integration.dsu.ModDeepStorageUnit,
|
||||
// integration.forestry.ModForestry,
|
||||
// integration.fmp.ModForgeMultipart,
|
||||
// integration.gc.ModGalacticraft,
|
||||
// integration.gregtech.ModGregtech,
|
||||
// integration.ic2.ModIndustrialCraft2,
|
||||
// integration.mfr.ModMineFactoryReloaded,
|
||||
// integration.mystcraft.ModMystcraft,
|
||||
// integration.railcraft.ModRailcraft,
|
||||
// integration.stargatetech2.ModStargateTech2,
|
||||
// integration.thaumcraft.ModThaumcraft,
|
||||
// integration.thermalexpansion.ModThermalExpansion,
|
||||
// integration.tcon.ModTinkersConstruct,
|
||||
// integration.tmechworks.ModTMechworks,
|
||||
// integration.appeng.ModAppEng,
|
||||
// integration.bloodmagic.ModBloodMagic,
|
||||
// integration.bluepower.ModBluePower,
|
||||
// integration.buildcraft.tools.ModBuildCraftAPITools,
|
||||
// integration.buildcraft.tiles.ModBuildCraftAPITiles,
|
||||
// integration.buildcraft.transport.ModBuildCraftAPITransport,
|
||||
// integration.cofh.energy.ModCoFHEnergy,
|
||||
// integration.cofh.item.ModCoFHItem,
|
||||
// integration.cofh.tileentity.ModCoFHTileEntity,
|
||||
// integration.cofh.transport.ModCoFHTransport,
|
||||
// integration.enderstorage.ModEnderStorage,
|
||||
// integration.dsu.ModDeepStorageUnit,
|
||||
// integration.forestry.ModForestry,
|
||||
// integration.fmp.ModForgeMultipart,
|
||||
// integration.gc.ModGalacticraft,
|
||||
// integration.gregtech.ModGregtech,
|
||||
// integration.ic2.ModIndustrialCraft2,
|
||||
// integration.mfr.ModMineFactoryReloaded,
|
||||
// integration.mystcraft.ModMystcraft,
|
||||
// integration.projectred.ModProjectRed,
|
||||
// integration.railcraft.ModRailcraft,
|
||||
// integration.redlogic.ModRedLogic,
|
||||
// integration.stargatetech2.ModStargateTech2,
|
||||
// integration.thaumcraft.ModThaumcraft,
|
||||
// integration.thermalexpansion.ModThermalExpansion,
|
||||
// integration.tcon.ModTinkersConstruct,
|
||||
// integration.tmechworks.ModTMechworks,
|
||||
integration.vanilla.ModVanilla,
|
||||
// integration.versionchecker.ModVersionChecker,
|
||||
// integration.waila.ModWaila,
|
||||
// integration.wrcbe.ModWRCBE,
|
||||
// integration.wrsve.ModWRSVE,
|
||||
integration.versionchecker.ModVersionChecker,
|
||||
integration.waila.ModWaila,
|
||||
// integration.wrcbe.ModWRCBE,
|
||||
// integration.wrsve.ModWRSVE,
|
||||
|
||||
// // Register the general IPeripheral driver last, if at all, to avoid it
|
||||
// // being used rather than other more concrete implementations.
|
||||
// integration.computercraft.ModComputerCraft,
|
||||
// // Register the general IPeripheral driver last, if at all, to avoid it
|
||||
// // being used rather than other more concrete implementations.
|
||||
// integration.computercraft.ModComputerCraft,
|
||||
|
||||
// We go last to ensure all other mod integration is done, e.g. to
|
||||
// We go late to ensure all other mod integration is done, e.g. to
|
||||
// allow properly checking if wireless redstone is present.
|
||||
integration.opencomputers.ModOpenComputers
|
||||
|
||||
// Run IGW registration after OC registration because we use the manual
|
||||
// in there to know which pages to register.
|
||||
// integration.igw.ModIngameWiki
|
||||
)
|
||||
|
||||
def init(): Unit = {
|
||||
@ -139,6 +148,7 @@ object Mods {
|
||||
final val AppliedEnergistics2 = "appliedenergistics2"
|
||||
final val BattleGear2 = "battlegear2"
|
||||
final val BloodMagic = "AWWayofTime"
|
||||
final val BluePower = "bluepowerAPI"
|
||||
final val BuildCraft = "BuildCraft|Core"
|
||||
final val BuildCraftPower = "BuildCraftAPI|power"
|
||||
final val BuildCraftTiles = "BuildCraftAPI|tiles"
|
||||
@ -161,6 +171,7 @@ object Mods {
|
||||
final val GregTech = "gregtech"
|
||||
final val IndustrialCraft2 = "IC2"
|
||||
final val IndustrialCraft2Classic = "IC2-Classic"
|
||||
final val IngameWiki = "IGWMod"
|
||||
final val Mekanism = "Mekanism"
|
||||
final val Minecraft = "Minecraft"
|
||||
final val MineFactoryReloaded = "MineFactoryReloaded"
|
||||
|
@ -0,0 +1,38 @@
|
||||
package li.cil.oc.integration.bluepower
|
||||
|
||||
import com.bluepowermod.api.BPApi
|
||||
import com.bluepowermod.api.connect.ConnectionType
|
||||
import com.bluepowermod.api.connect.IConnectionCache
|
||||
import com.bluepowermod.api.misc.MinecraftColor
|
||||
import com.bluepowermod.api.wire.redstone.IBundledDevice
|
||||
import li.cil.oc.common.tileentity.traits.BundledRedstoneAware
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
class BundledRedstoneDevice(val tileEntity: BundledRedstoneAware) extends IBundledDevice {
|
||||
lazy val cache = BPApi.getInstance.getRedstoneApi.createBundledConnectionCache(this)
|
||||
|
||||
override def getX: Int = tileEntity.x
|
||||
|
||||
override def getY: Int = tileEntity.y
|
||||
|
||||
override def getZ: Int = tileEntity.z
|
||||
|
||||
override def getWorld: World = tileEntity.world
|
||||
|
||||
override def canConnect(side: ForgeDirection, dev: IBundledDevice, connectionType: ConnectionType): Boolean = tileEntity.isOutputEnabled
|
||||
|
||||
override def isNormalFace(side: ForgeDirection): Boolean = true
|
||||
|
||||
override def getBundledConnectionCache: IConnectionCache[_ <: IBundledDevice] = cache
|
||||
|
||||
override def getBundledColor(side: ForgeDirection): MinecraftColor = MinecraftColor.ANY
|
||||
|
||||
override def getBundledOutput(side: ForgeDirection): Array[Byte] = tileEntity.bundledOutput(side).map(_.toByte)
|
||||
|
||||
override def getBundledPower(side: ForgeDirection): Array[Byte] = tileEntity.bundledInput(side).map(_.toByte)
|
||||
|
||||
override def setBundledPower(side: ForgeDirection, power: Array[Byte]): Unit = tileEntity.bundledInput(side, power.map(_ & 0xFF))
|
||||
|
||||
override def onBundledUpdate(): Unit = tileEntity.checkRedstoneInputChanged()
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package li.cil.oc.integration.bluepower
|
||||
|
||||
import com.bluepowermod.api.BPApi
|
||||
import com.bluepowermod.api.wire.redstone.IBundledDevice
|
||||
import com.bluepowermod.api.wire.redstone.IRedstoneDevice
|
||||
import li.cil.oc.integration.ModProxy
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util.BundledRedstone
|
||||
import li.cil.oc.integration.util.BundledRedstone.RedstoneProvider
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
object ModBluePower extends ModProxy with RedstoneProvider {
|
||||
override def getMod = Mods.BluePower
|
||||
|
||||
override def initialize(): Unit = {
|
||||
RedstoneProvider.init()
|
||||
|
||||
BundledRedstone.addProvider(this)
|
||||
}
|
||||
|
||||
override def computeInput(pos: BlockPosition, side: ForgeDirection): Int = {
|
||||
val world = pos.world.get
|
||||
val (nx, ny, nz) = (pos.x + side.offsetX, pos.y + side.offsetY, pos.z + side.offsetZ)
|
||||
ForgeDirection.values.map(BPApi.getInstance.getRedstoneApi.getRedstoneDevice(world, nx, ny, nz, _, ForgeDirection.UNKNOWN)).collect {
|
||||
case device: IRedstoneDevice => device.getRedstonePower(side.getOpposite) & 0xFF
|
||||
}.padTo(1, 0).max
|
||||
}
|
||||
|
||||
def computeBundledInput(pos: BlockPosition, side: ForgeDirection): Array[Int] = {
|
||||
val world = pos.world.get
|
||||
val (nx, ny, nz) = (pos.x + side.offsetX, pos.y + side.offsetY, pos.z + side.offsetZ)
|
||||
val inputs = ForgeDirection.values.map(BPApi.getInstance.getRedstoneApi.getBundledDevice(world, nx, ny, nz, _, ForgeDirection.UNKNOWN)).collect {
|
||||
case device: IBundledDevice => Option(device.getBundledOutput(side.getOpposite)).fold(null: Array[Int])(_.map(_ & 0xFF))
|
||||
}.filter(_ != null)
|
||||
if (inputs.isEmpty) null
|
||||
else inputs.reduce((a, b) => (a, b).zipped.map((l, r) => math.max(l, r)))
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package li.cil.oc.integration.bluepower
|
||||
|
||||
import com.bluepowermod.api.BPApi
|
||||
import com.bluepowermod.api.connect.ConnectionType
|
||||
import com.bluepowermod.api.connect.IConnectionCache
|
||||
import com.bluepowermod.api.wire.redstone.IRedstoneDevice
|
||||
import li.cil.oc.common.tileentity.traits.RedstoneAware
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
class RedstoneDevice(val tileEntity: RedstoneAware) extends IRedstoneDevice {
|
||||
lazy val cache = BPApi.getInstance.getRedstoneApi.createRedstoneConnectionCache(this)
|
||||
|
||||
override def getX: Int = tileEntity.x
|
||||
|
||||
override def getY: Int = tileEntity.y
|
||||
|
||||
override def getZ: Int = tileEntity.z
|
||||
|
||||
override def getWorld: World = tileEntity.world
|
||||
|
||||
override def canConnect(side: ForgeDirection, dev: IRedstoneDevice, connectionType: ConnectionType): Boolean = tileEntity.isOutputEnabled
|
||||
|
||||
override def isNormalFace(side: ForgeDirection): Boolean = true
|
||||
|
||||
override def getRedstoneConnectionCache: IConnectionCache[_ <: IRedstoneDevice] = cache
|
||||
|
||||
override def getRedstonePower(side: ForgeDirection): Byte = tileEntity.output(side).toByte
|
||||
|
||||
override def setRedstonePower(side: ForgeDirection, power: Byte): Unit = tileEntity.input(side, power & 0xFF)
|
||||
|
||||
override def onRedstoneUpdate(): Unit = tileEntity.checkRedstoneInputChanged()
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package li.cil.oc.integration.bluepower
|
||||
|
||||
import com.bluepowermod.api.BPApi
|
||||
import com.bluepowermod.api.wire.redstone.IBundledDevice
|
||||
import com.bluepowermod.api.wire.redstone.IRedstoneDevice
|
||||
import com.bluepowermod.api.wire.redstone.IRedstoneProvider
|
||||
import li.cil.oc.common.tileentity.traits.BundledRedstoneAware
|
||||
import li.cil.oc.common.tileentity.traits.RedstoneAware
|
||||
import net.minecraft.world.World
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
object RedstoneProvider extends IRedstoneProvider {
|
||||
val redstoneDevices = mutable.WeakHashMap.empty[RedstoneAware, RedstoneDevice]
|
||||
|
||||
val bundledRedstoneDevices = mutable.WeakHashMap.empty[BundledRedstoneAware, BundledRedstoneDevice]
|
||||
|
||||
def init(): Unit = {
|
||||
BPApi.getInstance.getRedstoneApi.registerRedstoneProvider(this)
|
||||
}
|
||||
|
||||
override def getRedstoneDeviceAt(world: World, x: Int, y: Int, z: Int, side: ForgeDirection, face: ForgeDirection): IRedstoneDevice = {
|
||||
world.getTileEntity(x, y, z) match {
|
||||
case tileEntity: RedstoneAware => redstoneDevices.getOrElseUpdate(tileEntity, new RedstoneDevice(tileEntity))
|
||||
case _ => null
|
||||
}
|
||||
}
|
||||
|
||||
override def getBundledDeviceAt(world: World, x: Int, y: Int, z: Int, side: ForgeDirection, face: ForgeDirection): IBundledDevice = {
|
||||
world.getTileEntity(x, y, z) match {
|
||||
case tileEntity: BundledRedstoneAware => bundledRedstoneDevices.getOrElseUpdate(tileEntity, new BundledRedstoneDevice(tileEntity))
|
||||
case _ => null
|
||||
}
|
||||
}
|
||||
}
|
14
src/main/scala/li/cil/oc/integration/igw/ModIngameWiki.scala
Normal file
14
src/main/scala/li/cil/oc/integration/igw/ModIngameWiki.scala
Normal file
@ -0,0 +1,14 @@
|
||||
package li.cil.oc.integration.igw
|
||||
|
||||
import li.cil.oc.api.Driver
|
||||
import li.cil.oc.integration.ModProxy
|
||||
import li.cil.oc.integration.Mods
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
|
||||
object ModIngameWiki extends ModProxy {
|
||||
override def getMod = Mods.IngameWiki
|
||||
|
||||
override def initialize(): Unit = {
|
||||
WikiEventHandler.init()
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package li.cil.oc.integration.igw
|
||||
|
||||
import java.util
|
||||
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent
|
||||
import igwmod.api.PageChangeEvent
|
||||
import igwmod.api.WikiRegistry
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.api
|
||||
import li.cil.oc.client.Manual
|
||||
import li.cil.oc.client.renderer.markdown
|
||||
import li.cil.oc.client.renderer.markdown.MarkupFormat
|
||||
import li.cil.oc.common.init.Items
|
||||
import net.minecraftforge.common.MinecraftForge
|
||||
|
||||
import scala.collection.convert.WrapAsJava._
|
||||
import scala.collection.convert.WrapAsScala._
|
||||
|
||||
object WikiEventHandler {
|
||||
var lastPath = ""
|
||||
|
||||
def init(): Unit = {
|
||||
MinecraftForge.EVENT_BUS.register(this)
|
||||
|
||||
for ((name, info) <- Items.descriptors) {
|
||||
val stack = info.createItemStack(1)
|
||||
val path = api.Manual.pathFor(stack)
|
||||
if (path != null && api.Manual.contentFor(path) != null) {
|
||||
WikiRegistry.registerBlockAndItemPageEntry(stack)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
def onPageChangeEvent(e: PageChangeEvent): Unit = {
|
||||
val path =
|
||||
if (e.associatedStack != null)
|
||||
"/" + api.Manual.pathFor(e.associatedStack)
|
||||
else if (e.currentFile.startsWith(OpenComputers.ID + ":"))
|
||||
e.currentFile.stripPrefix(OpenComputers.ID + ":")
|
||||
else null
|
||||
|
||||
val base = lastPath
|
||||
lastPath = ""
|
||||
if (path != null) {
|
||||
val resolvedPath = Manual.makeRelative(path, base)
|
||||
val content = api.Manual.contentFor(resolvedPath)
|
||||
if (content != null) {
|
||||
val document = markdown.Document.parse(content)
|
||||
val processed = document.renderAsText(MarkupFormat.IGWMod)
|
||||
e.pageText = new util.ArrayList[String](asJavaCollection(processed))
|
||||
e.currentFile = resolvedPath
|
||||
lastPath = resolvedPath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package li.cil.oc.integration.projectred
|
||||
|
||||
import li.cil.oc.integration.ModProxy
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util.BundledRedstone
|
||||
import li.cil.oc.integration.util.BundledRedstone.RedstoneProvider
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import mrtjp.projectred.api.ProjectRedAPI
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
object ModProjectRed extends ModProxy with RedstoneProvider {
|
||||
override def getMod = Mods.ProjectRedTransmission
|
||||
|
||||
override def initialize(): Unit = {
|
||||
BundledRedstone.addProvider(this)
|
||||
}
|
||||
|
||||
override def computeInput(pos: BlockPosition, side: ForgeDirection): Int = 0
|
||||
|
||||
def computeBundledInput(pos: BlockPosition, side: ForgeDirection): Array[Int] = {
|
||||
Option(ProjectRedAPI.transmissionAPI.getBundledInput(pos.world.get, pos.x, pos.y, pos.z, side.ordinal)).
|
||||
fold(null: Array[Int])(_.map(_ & 0xFF))
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package li.cil.oc.integration.redlogic
|
||||
|
||||
import li.cil.oc.integration.ModProxy
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util.BundledRedstone
|
||||
import li.cil.oc.integration.util.BundledRedstone.RedstoneProvider
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import mods.immibis.redlogic.api.wiring.IBundledEmitter
|
||||
import mods.immibis.redlogic.api.wiring.IInsulatedRedstoneWire
|
||||
import mods.immibis.redlogic.api.wiring.IRedstoneEmitter
|
||||
import net.minecraftforge.common.util.ForgeDirection
|
||||
|
||||
object ModRedLogic extends ModProxy with RedstoneProvider {
|
||||
override def getMod = Mods.RedLogic
|
||||
|
||||
override def initialize(): Unit = {
|
||||
BundledRedstone.addProvider(this)
|
||||
}
|
||||
|
||||
override def computeInput(pos: BlockPosition, side: ForgeDirection): Int = {
|
||||
pos.world.get.getTileEntity(pos) match {
|
||||
case emitter: IRedstoneEmitter =>
|
||||
var strength = 0
|
||||
for (i <- -1 to 5) {
|
||||
strength = math.max(strength, emitter.getEmittedSignalStrength(i, side.getOpposite.ordinal()))
|
||||
}
|
||||
strength
|
||||
case _ => 0
|
||||
}
|
||||
}
|
||||
|
||||
def computeBundledInput(pos: BlockPosition, side: ForgeDirection): Array[Int] = {
|
||||
val world = pos.world.get
|
||||
val npos = pos.offset(side)
|
||||
world.getTileEntity(npos) match {
|
||||
case wire: IInsulatedRedstoneWire =>
|
||||
var strength: Array[Int] = null
|
||||
for (face <- -1 to 5 if wire.wireConnectsInDirection(face, side.ordinal())) {
|
||||
if (strength == null) strength = Array.fill(16)(0)
|
||||
strength(wire.getInsulatedWireColour) = math.max(strength(wire.getInsulatedWireColour), wire.getEmittedSignalStrength(face, side.ordinal()))
|
||||
}
|
||||
strength
|
||||
case emitter: IBundledEmitter =>
|
||||
var strength: Array[Int] = null
|
||||
for (i <- -1 to 5 if strength == null) {
|
||||
strength = Option(emitter.getBundledCableStrength(i, side.getOpposite.ordinal())).fold(null: Array[Int])(_.map(_ & 0xFF))
|
||||
}
|
||||
strength
|
||||
case _ => null
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,38 @@
|
||||
package li.cil.oc.integration.util
|
||||
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import net.minecraft.util.EnumFacing
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
object BundledRedstone {
|
||||
def isAvailable = Mods.RedLogic.isAvailable ||
|
||||
Mods.MineFactoryReloaded.isAvailable ||
|
||||
Mods.ProjectRedTransmission.isAvailable
|
||||
val providers = mutable.Buffer.empty[RedstoneProvider]
|
||||
|
||||
def addProvider(provider: RedstoneProvider): Unit = providers += provider
|
||||
|
||||
def isAvailable = Mods.MineFactoryReloaded.isAvailable || providers.length > 0
|
||||
|
||||
def computeInput(pos: BlockPosition, side: EnumFacing): Int = {
|
||||
if (pos.world.get.blockExists(pos.offset(side)))
|
||||
providers.map(_.computeInput(pos, side)).padTo(1, 0).max
|
||||
else 0
|
||||
}
|
||||
|
||||
def computeBundledInput(pos: BlockPosition, side: EnumFacing): Array[Int] = {
|
||||
if (pos.world.get.blockExists(pos.offset(side))) {
|
||||
val inputs = providers.map(_.computeBundledInput(pos, side)).filter(_ != null)
|
||||
if (inputs.isEmpty) null
|
||||
else inputs.reduce((a, b) => (a, b).zipped.map((l, r) => math.max(l, r)))
|
||||
}
|
||||
else null
|
||||
}
|
||||
|
||||
trait RedstoneProvider {
|
||||
def computeInput(pos: BlockPosition, side: EnumFacing): Int
|
||||
|
||||
def computeBundledInput(pos: BlockPosition, side: EnumFacing): Array[Int]
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,8 +4,15 @@ import li.cil.oc.Settings
|
||||
import li.cil.oc.api.Driver
|
||||
import li.cil.oc.integration.ModProxy
|
||||
import li.cil.oc.integration.Mods
|
||||
import li.cil.oc.integration.util.BundledRedstone
|
||||
import li.cil.oc.integration.util.BundledRedstone.RedstoneProvider
|
||||
import li.cil.oc.util.BlockPosition
|
||||
import li.cil.oc.util.ExtendedWorld._
|
||||
import net.minecraft.block.BlockRedstoneWire
|
||||
import net.minecraft.init.Blocks
|
||||
import net.minecraft.util.EnumFacing
|
||||
|
||||
object ModVanilla extends ModProxy {
|
||||
object ModVanilla extends ModProxy with RedstoneProvider {
|
||||
def getMod = Mods.Minecraft
|
||||
|
||||
def initialize() {
|
||||
@ -36,5 +43,16 @@ object ModVanilla extends ModProxy {
|
||||
Driver.add(ConverterWorldProvider)
|
||||
|
||||
RecipeHandler.init()
|
||||
|
||||
BundledRedstone.addProvider(this)
|
||||
}
|
||||
|
||||
override def computeInput(pos: BlockPosition, side: EnumFacing): Int = {
|
||||
val world = pos.world.get
|
||||
// See BlockRedstoneLogic.getInputStrength() for reference.
|
||||
math.max(world.getIndirectPowerLevelTo(pos, side),
|
||||
if (world.getBlock(pos) == Blocks.redstone_wire) world.getBlockMetadata(pos).getValue(BlockRedstoneWire.POWER).asInstanceOf[Integer].intValue() else 0)
|
||||
}
|
||||
|
||||
override def computeBundledInput(pos: BlockPosition, side: EnumFacing): Array[Int] = null
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ class EEPROM extends prefab.ManagedEnvironment {
|
||||
if (!node.tryChangeBuffer(-Settings.get.eepromWriteCost)) {
|
||||
return result(Unit, "not enough energy")
|
||||
}
|
||||
val newData = args.optByteArray(0, Array.empty)
|
||||
val newData = args.optByteArray(0, Array.empty[Byte])
|
||||
if (newData.length > Settings.get.eepromSize) throw new IllegalArgumentException("not enough space")
|
||||
codeData = newData
|
||||
context.pause(2) // deliberately slow to discourage use as normal storage medium
|
||||
@ -85,7 +85,7 @@ class EEPROM extends prefab.ManagedEnvironment {
|
||||
if (!node.tryChangeBuffer(-Settings.get.eepromWriteCost)) {
|
||||
return result(Unit, "not enough energy")
|
||||
}
|
||||
val newData = args.optByteArray(0, Array.empty)
|
||||
val newData = args.optByteArray(0, Array.empty[Byte])
|
||||
if (newData.length > Settings.get.eepromDataSize) throw new IllegalArgumentException("not enough space")
|
||||
volatileData = newData
|
||||
context.pause(1) // deliberately slow to discourage use as normal storage medium
|
||||
|
@ -235,10 +235,6 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
false
|
||||
})
|
||||
|
||||
private def beep(pattern: String) {
|
||||
PacketSender.sendSound(host.world, host.xPosition, host.yPosition, host.zPosition, pattern)
|
||||
}
|
||||
|
||||
override def pause(seconds: Double): Boolean = {
|
||||
val ticksToPause = math.max((seconds * 20).toInt, 0)
|
||||
def shouldPause(state: Machine.State.Value) = state match {
|
||||
@ -270,6 +266,14 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
true
|
||||
})
|
||||
|
||||
override def beep(frequency: Short, duration: Short): Unit = {
|
||||
PacketSender.sendSound(host.world, host.xPosition, host.yPosition, host.zPosition, frequency, duration)
|
||||
}
|
||||
|
||||
override def beep(pattern: String) {
|
||||
PacketSender.sendSound(host.world, host.xPosition, host.yPosition, host.zPosition, pattern)
|
||||
}
|
||||
|
||||
override def crash(message: String) = {
|
||||
this.message = Option(message)
|
||||
state.synchronized {
|
||||
|
@ -5,7 +5,9 @@ import java.nio.ByteBuffer
|
||||
import li.cil.oc.OpenComputers
|
||||
import li.cil.oc.Settings
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.audio.PositionedSoundRecord
|
||||
import net.minecraft.client.audio.SoundCategory
|
||||
import net.minecraft.util.ResourceLocation
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent
|
||||
@ -39,10 +41,29 @@ object Audio {
|
||||
}
|
||||
|
||||
def play(x: Float, y: Float, z: Float, pattern: String, frequencyInHz: Int = 1000, durationInMilliseconds: Int = 200): Unit = {
|
||||
if (!disableAudio) {
|
||||
val distanceBasedGain = math.max(0, 1 - Minecraft.getMinecraft.thePlayer.getDistance(x, y, z) / 12).toFloat
|
||||
val gain = distanceBasedGain * volume
|
||||
if (gain > 0 && amplitude > 0 && AL.isCreated) {
|
||||
val mc = Minecraft.getMinecraft
|
||||
val distanceBasedGain = math.max(0, 1 - mc.thePlayer.getDistance(x, y, z) / 12).toFloat
|
||||
val gain = distanceBasedGain * volume
|
||||
if (gain <= 0 || amplitude <= 0) return
|
||||
|
||||
if (disableAudio) {
|
||||
// Fallback audio generation, using built-in Minecraft sound. This can be
|
||||
// necessary on certain systems with audio cards that do not have enough
|
||||
// memory. May still fail, but at least we can say we tried!
|
||||
// Valid range is 20-2000Hz, clamp it to that and get a relative value.
|
||||
// MC's pitch system supports a minimum pitch of 0.5, however, so up it
|
||||
// by that.
|
||||
val clampedFrequency = ((frequencyInHz - 20) max 0 min 1980) / 1980f + 0.5f
|
||||
var delay = 0
|
||||
for (ch <- pattern) {
|
||||
val record = new PositionedSoundRecord(new ResourceLocation("note.harp"), gain, clampedFrequency, x, y, z)
|
||||
if (delay == 0) mc.getSoundHandler.playSound(record)
|
||||
else mc.getSoundHandler.playDelayedSound(record, delay)
|
||||
delay += ((if (ch == '.') durationInMilliseconds else 2 * durationInMilliseconds) * 20 / 1000) max 1
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (AL.isCreated) {
|
||||
val sampleCounts = pattern.toCharArray.
|
||||
map(ch => if (ch == '.') durationInMilliseconds else 2 * durationInMilliseconds).
|
||||
map(_ * sampleRate / 1000)
|
||||
|
@ -73,13 +73,13 @@ object ItemUtils {
|
||||
def getIngredients(stack: ItemStack): Array[ItemStack] = try {
|
||||
def getFilteredInputs(inputs: Iterable[ItemStack], outputSize: Double) = inputs.filter(input =>
|
||||
input != null &&
|
||||
input.getItem != null &&
|
||||
math.floor(input.stackSize / outputSize) > 0 &&
|
||||
// Strip out buckets, because those are returned when crafting, and
|
||||
// we have no way of returning the fluid only (and I can't be arsed
|
||||
// to make it output fluids into fluiducts or such, sorry).
|
||||
!input.getItem.isInstanceOf[ItemBucket]).toArray
|
||||
def getOutputSize(recipe: IRecipe) =
|
||||
input.getItem != null &&
|
||||
math.floor(input.stackSize / outputSize) > 0 &&
|
||||
// Strip out buckets, because those are returned when crafting, and
|
||||
// we have no way of returning the fluid only (and I can't be arsed
|
||||
// to make it output fluids into fluiducts or such, sorry).
|
||||
!input.getItem.isInstanceOf[ItemBucket]).toArray
|
||||
def getOutputSize(recipe: IRecipe): Double =
|
||||
if (recipe != null && recipe.getRecipeOutput != null)
|
||||
recipe.getRecipeOutput.stackSize
|
||||
else
|
||||
@ -93,11 +93,11 @@ object ItemUtils {
|
||||
case Some(recipe: ShapelessRecipes) => getFilteredInputs(recipe.recipeItems.map(_.asInstanceOf[ItemStack]), getOutputSize(recipe))
|
||||
case Some(recipe: ShapedOreRecipe) => getFilteredInputs(resolveOreDictEntries(recipe.getInput), getOutputSize(recipe))
|
||||
case Some(recipe: ShapelessOreRecipe) => getFilteredInputs(resolveOreDictEntries(recipe.getInput), getOutputSize(recipe))
|
||||
case _ => Array.empty
|
||||
case _ => Array.empty[ItemStack]
|
||||
}
|
||||
// Avoid positive feedback loops.
|
||||
if (ingredients.exists(ingredient => ingredient.isItemEqual(stack))) {
|
||||
return Array.empty
|
||||
return Array.empty[ItemStack]
|
||||
}
|
||||
// Merge equal items for size division by output size.
|
||||
val merged = mutable.ArrayBuffer.empty[ItemStack]
|
||||
@ -122,7 +122,7 @@ object ItemUtils {
|
||||
catch {
|
||||
case t: Throwable =>
|
||||
OpenComputers.log.warn("Whoops, something went wrong when trying to figure out an item's parts.", t)
|
||||
Array.empty
|
||||
Array.empty[ItemStack]
|
||||
}
|
||||
|
||||
private lazy val rng = new Random()
|
||||
|
Loading…
x
Reference in New Issue
Block a user