Observing Fluids

- Stockpile Switches can now be used with Fluid Tanks
- Content Observers can now be used with Fluid Containers and Fluid Pipes
- Fixed Pumps not updating pressure when reversed
This commit is contained in:
simibubi 2021-10-11 22:45:53 +02:00
parent 5ee4e61c27
commit 3792e06b8a
24 changed files with 447 additions and 230 deletions

View File

@ -442,19 +442,19 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
5ae77ed97ee05a7ed98999178677e576c1140007 assets/create/lang/en_ud.json
5bcf39c319a77fa7a54a800a583a192b039066c4 assets/create/lang/en_us.json
15c307409c845cb122b9cd02e4bffe6c0b97bd41 assets/create/lang/unfinished/de_de.json
c99557107111254de385fb648d65180b1277d6d7 assets/create/lang/unfinished/es_es.json
df34bf60407e348c45c2ace17f284b71b2eb4504 assets/create/lang/unfinished/fr_fr.json
f55dd7f42fce5cb0cb8d90ee80c22de0954c76d1 assets/create/lang/unfinished/it_it.json
6c9f3979084b8a31db9a7fa9f412e1b4a5d8b4aa assets/create/lang/unfinished/ja_jp.json
1c74f1c5bc1b814d1d76d0eaca94d8b95f643abe assets/create/lang/unfinished/ko_kr.json
7a9a8b8b13effa89b1e4e5b1f9090f19e9b655d7 assets/create/lang/unfinished/nl_nl.json
f0565d7474fb89645ea98132edb7e7c48323d114 assets/create/lang/unfinished/pl_pl.json
0e4c967d1c14425fbedf9beba3ad926a034a1271 assets/create/lang/unfinished/pt_br.json
475a1171ca71e4f19b8b5eab0ce06a236c69af83 assets/create/lang/unfinished/ru_ru.json
749b4131dc16479bba7a19e1544bf71b8b61f7bc assets/create/lang/unfinished/zh_cn.json
bc1b3ab4b3d2a8bab387b32138ef2335e7907e96 assets/create/lang/unfinished/zh_tw.json
e2f40cd628f5110980e374b3738ce13f06991ff2 assets/create/lang/en_us.json
c01aace13b9b0c37b6ac1716515c156e68d6cdbc assets/create/lang/unfinished/de_de.json
bbb2ea577b398f046089d9bf40a489bd36e8279b assets/create/lang/unfinished/es_es.json
2590488af060c1f2f0147f2648b71b9fddfde0bd assets/create/lang/unfinished/fr_fr.json
fe167a21b16b8e799309563a6331dc479baf46f0 assets/create/lang/unfinished/it_it.json
cbdff6e54345fc929ba8fc63e4f6dd0664625a14 assets/create/lang/unfinished/ja_jp.json
e6c95e4735fef34c295de1b5fd80ffc1e7ebe26d assets/create/lang/unfinished/ko_kr.json
fb8b7465e9fa53ae83477fc854e7cf0d1c1998be assets/create/lang/unfinished/nl_nl.json
5ac4e9a807d30788375c94a4315b81de31408b56 assets/create/lang/unfinished/pl_pl.json
3fdc9f5b58e057c70860678035bebeb67eb78af9 assets/create/lang/unfinished/pt_br.json
24d20982201334cf008ba34ee3fdbbfd1f71a463 assets/create/lang/unfinished/ru_ru.json
0396d11c494d3b1bbd6ea36466eff091cd07a4f0 assets/create/lang/unfinished/zh_cn.json
cd24e59e352d75bb7b911d03ae7f8a7aab7e71ca assets/create/lang/unfinished/zh_tw.json
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json

View File

@ -1422,12 +1422,16 @@
"block.create.turntable.tooltip.summary": "Turns _Rotational Force_ into refined Motion Sickness.",
"block.create.stockpile_switch.tooltip": "STOCKPILE SWITCH",
"block.create.stockpile_switch.tooltip.summary": "Toggles a Redstone signal based on the amount of _Stored Items_ in the attached Container. Comes with a handy filter. As opposed to a _Comparator,_ the _Stockpile Switch_ allows configuration of _thresholds,_ at which signals are inverted.",
"block.create.stockpile_switch.tooltip.summary": "Toggles a Redstone signal based on the amount of _Stored Items_ or _Fluids_ in the attached Container. Comes with a handy filter. As opposed to a _Comparator,_ the _Stockpile Switch_ allows configuration of _thresholds,_ at which signals are inverted.",
"block.create.stockpile_switch.tooltip.condition1": "When R-Clicked",
"block.create.stockpile_switch.tooltip.behaviour1": "Opens the _Configuration Interface_.",
"block.create.content_observer.tooltip": "CONTENT OBSERVER",
"block.create.content_observer.tooltip.summary": "_Detects Items_ inside _containers_ and _conveyors_ matching a configured _filter_. While the observed _inventory_, _belt_ or _chute contains_ a matching item, this component will emit a _Redstone Signal_. When an observed _funnel transfers_ a matching item, this component will emit a _Redstone Pulse_.",
"block.create.content_observer.tooltip.summary": "_Detects Items_ or _Fluids_ inside _containers_, _pipes_ or _conveyors_ matching a configured _filter_.",
"block.create.content_observer.tooltip.condition1": "When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "ADJUSTABLE CRATE",
"block.create.adjustable_crate.tooltip.summary": "This _Item Container_ allows Manual control over its capacity. It can hold up to _16 Stacks_ of any Item. Supports _Redstone Comparators_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1160",
"_": "Missing Localizations: 1164",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1428,7 +1428,11 @@
"block.create.stockpile_switch.tooltip.behaviour1": "Wird das Redstone-Signal ausgeschaltet.",
"block.create.content_observer.tooltip": "UNLOCALIZED: CONTENT OBSERVER",
"block.create.content_observer.tooltip.summary": "UNLOCALIZED: _Detects Items_ inside _containers_ and _conveyors_ matching a configured _filter_. While the observed _inventory_, _belt_ or _chute contains_ a matching item, this component will emit a _Redstone Signal_. When an observed _funnel transfers_ a matching item, this component will emit a _Redstone Pulse_.",
"block.create.content_observer.tooltip.summary": "UNLOCALIZED: _Detects Items_ or _Fluids_ inside _containers_, _pipes_ or _conveyors_ matching a configured _filter_.",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "LAGERRAUM",
"block.create.adjustable_crate.tooltip.summary": "Dieser _Speicherbehälter_ erlaubt manuelle Kontrolle über seine Kapazität. Er kann bis zu _16_ _Stacks_ von jeglichem Gegenstand beinhalten.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 26",
"_": "Missing Localizations: 30",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1429,6 +1429,10 @@
"block.create.content_observer.tooltip": "OBSERVADOR DE CONTENIDO",
"block.create.content_observer.tooltip.summary": "_Detecta objetos_ dentro de _contenedores_ y _transportadores_ que coincidan con un _filtro_ configurado. Mientras el _inventario_, la _cinta_ o la _canaleta_ observados _contengan_ un objeto que coincida, este componente emitirá una _señal de redstone_. Cuando un embudo observado _transfiere_ un objeto coincidente, este componente emitirá un _pulso de redstone_.",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "CAJA AJUSTABLE",
"block.create.adjustable_crate.tooltip.summary": "Este _contenedor de objetos_ permite el control manual de su capacidad. Puede contener hasta _16 pilas_ de cualquier objeto. Soporta _comparadores de redstone_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1412",
"_": "Missing Localizations: 1416",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1429,6 +1429,10 @@
"block.create.content_observer.tooltip": "OBSERVATEUR DE CONTENU",
"block.create.content_observer.tooltip.summary": "_Détecte les objets_ à l'intérieur des _conteneurs_ et des _transporteurs_ correspondant à un _filtre_ configuré. Tant que l'_inventaire_, le _tapis roulant_ ou la _glissière_ observé _contient_ un objet correspondant, ce composant émet un _signal de redstone_. Quand un _entonnoir_ observé _transfère_ un objet correspondant, ce composant émet une _impulsion de redstone_.",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "CAISSE AJUSTABLE",
"block.create.adjustable_crate.tooltip.summary": "Ce _conteneur_ _de_ _stockage_ permet un contrôle manuel de sa capacité. Il peut contenir jusqu'à _16_ _piles_ de n'importe quel objet. Prend en charge les _comparateurs_ _de_ _redstone_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 940",
"_": "Missing Localizations: 944",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1429,6 +1429,10 @@
"block.create.content_observer.tooltip": "OSSERVATORE DEI CONTENUTI",
"block.create.content_observer.tooltip.summary": "_Rileva oggetti_ dentro i _contenitori_ ed i _nastri_ corrispondenti ad un _filtro_. Quando l'_inventario_ del blocco, _nastro_ or _scivolo_ contiene un oggetto corrispondente, questo componente emetterà un _segnale redstone_. Quando un _imbuto_ osservato _trasferisce_ un oggetto corrispondente, questo componente emetterà un _segnale redstone_ temporaneo.",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "BAULE REGOLABILE",
"block.create.adjustable_crate.tooltip.summary": "Questo _contenitore_ _di_ _stoccaggio_ consente il controllo manuale sulla sua capacità. Può contenere fino a _16_ _pile_ di qualsiasi oggetto. Supporta _comparatori_ _redstone_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 35",
"_": "Missing Localizations: 39",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1429,6 +1429,10 @@
"block.create.content_observer.tooltip": "コンテンツオブザーバー",
"block.create.content_observer.tooltip.summary": "設定された_フィルター_に一致する_コンテナ_や_メカニカルベルト_内の_アイテム_を_検出_します。観察している_収納ブロック_、_ベルト_、または_シュート_に一致するアイテムが含まれている場合、このは_レッドストーン信号_を発します。観察している_ファンネル_が一致するアイテムを_運搬_すると、このコンポーネントは_レッドストーンパルス_を発します。",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "可変クレート",
"block.create.adjustable_crate.tooltip.summary": "この_収納ブロック_は、容量を手動で調整できます。任意のアイテムを_16スタック_まで収納できます。_レッドストーンコンパレーター_に対応しています。",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 50",
"_": "Missing Localizations: 54",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1429,6 +1429,10 @@
"block.create.content_observer.tooltip": "CONTENT OBSERVER",
"block.create.content_observer.tooltip.summary": "보관함이나 벨트의 아이템을 등록된 _필터_를 이용해 _탐지_합니다. _보관함, 벨트, 슈트_ 안에 해당 아이템을 탐지하는 동안, 레드스톤 신호를 보냅니다. _퍼널_가 해당 아이템을 수송하면, _1틱_의 레드스톤 신호를 보냅니다.",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "ADJUSTABLE CRATE",
"block.create.adjustable_crate.tooltip.summary": "이 보관함는 용량을 _직접_ _정할_ 수 있습니다. 아무아이템이나 최대 16스택씩 담을 수 있습니다. 레드스톤 비교기와 호환됩니다.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1792",
"_": "Missing Localizations: 1796",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1428,7 +1428,11 @@
"block.create.stockpile_switch.tooltip.behaviour1": "Stopt met het aanbieden van _Redstone_ _Kracht_",
"block.create.content_observer.tooltip": "UNLOCALIZED: CONTENT OBSERVER",
"block.create.content_observer.tooltip.summary": "UNLOCALIZED: _Detects Items_ inside _containers_ and _conveyors_ matching a configured _filter_. While the observed _inventory_, _belt_ or _chute contains_ a matching item, this component will emit a _Redstone Signal_. When an observed _funnel transfers_ a matching item, this component will emit a _Redstone Pulse_.",
"block.create.content_observer.tooltip.summary": "UNLOCALIZED: _Detects Items_ or _Fluids_ inside _containers_, _pipes_ or _conveyors_ matching a configured _filter_.",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "FLEXKRAT",
"block.create.adjustable_crate.tooltip.summary": "Met deze _Opslag_ _Container_ kan de capaciteit handmatig worden geregeld. Het kan tot _16_ _Stapels_ van elk item bevatten",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 282",
"_": "Missing Localizations: 286",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1429,6 +1429,10 @@
"block.create.content_observer.tooltip": "DETEKTOR ZAWARTOŚCI",
"block.create.content_observer.tooltip.summary": "_Wykrywa przedmioty_ zawarte w sąsiadującym _bloku_ lub _taśmociągu_, które pasują do ustalonego filtra. Kiedy obserwowany blok _zawiera_ ten przedmiot, detektor wyśle _sygnał Redstone_.",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "REGULOWANA SKRZYNKA",
"block.create.adjustable_crate.tooltip.summary": "Ta skrzynia pozwala na _ręczną kontrolę_ jej pojemności. Może pomieścić do _16 stosów_ dowolnego przedmiotu. Działa z _komparatorami_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1833",
"_": "Missing Localizations: 1837",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1428,7 +1428,11 @@
"block.create.stockpile_switch.tooltip.behaviour1": "Para de enviar _Sinal_ de _Redstone_",
"block.create.content_observer.tooltip": "UNLOCALIZED: CONTENT OBSERVER",
"block.create.content_observer.tooltip.summary": "UNLOCALIZED: _Detects Items_ inside _containers_ and _conveyors_ matching a configured _filter_. While the observed _inventory_, _belt_ or _chute contains_ a matching item, this component will emit a _Redstone Signal_. When an observed _funnel transfers_ a matching item, this component will emit a _Redstone Pulse_.",
"block.create.content_observer.tooltip.summary": "UNLOCALIZED: _Detects Items_ or _Fluids_ inside _containers_, _pipes_ or _conveyors_ matching a configured _filter_.",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "adjustable_crate",
"block.create.adjustable_crate.tooltip.summary": "Este _Recipiente_ de _Armazenamento_ permite controle Manual da sua capacidade. Pode conter até _16_ _Pilhas_ de qualquer Item",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 31",
"_": "Missing Localizations: 35",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1429,6 +1429,10 @@
"block.create.content_observer.tooltip": "НАБЛЮДАТЕЛЬ ЗА СОДЕРЖИМЫМ",
"block.create.content_observer.tooltip.summary": "_Обнаруживает элементы_ внутри _контейнеров_ и _конвейеров_, соответствующие настроенному _фильтру_. Если наблюдаемый инвентарь, ремень или шланг содержит совпадающий элемент, этот компонент излучает сигнал красного камня. Когда наблюдаемая _ воронка передает_ соответствующий предмет, этот компонент испускает _импульс_.",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "РЕГУЛИРУЕМЫЙ ЯЩИК",
"block.create.adjustable_crate.tooltip.summary": "Этот контейнер для хранения позволяет вручную контролировать его емкость. Он может вместить до 16 стаков любого предмета. Поддерживает компараторы.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 30",
"_": "Missing Localizations: 34",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1429,6 +1429,10 @@
"block.create.content_observer.tooltip": "物品侦测器",
"block.create.content_observer.tooltip.summary": "检测_容器_和_传送带_中过滤器匹配的物品。当在_物品栏__传送带_或者_溜槽所容物_中侦测到匹配的物品时此组件将发出_红石信号_。当观察到的漏斗_转移匹配的物品_时此组件将发出_红石脉冲_。",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "可调节板条箱",
"block.create.adjustable_crate.tooltip.summary": "该箱子支持玩家对其容量进行调整最大可以容纳_16组_物品。支持_红石比较器_。",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 45",
"_": "Missing Localizations: 49",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1429,6 +1429,10 @@
"block.create.content_observer.tooltip": "物品偵測器",
"block.create.content_observer.tooltip.summary": "偵測_容器_和_輸送帶_中過濾器匹配的物品。當觀察到包含匹配的物品時此組件將發出_紅石訊號_。當觀察到的漏斗_轉移匹配的物品_時此組件將發出_紅石脈沖_。",
"block.create.content_observer.tooltip.condition1": "UNLOCALIZED: When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "UNLOCALIZED: Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "UNLOCALIZED: When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "UNLOCALIZED: Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "可調節板條箱",
"block.create.adjustable_crate.tooltip.summary": "這個箱子可以調整容量最大可以收納_16組_物品。",

View File

@ -2,8 +2,6 @@ package com.simibubi.create.content.contraptions.fluids;
import java.util.Random;
import org.apache.commons.lang3.mutable.MutableBoolean;
import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock;
@ -57,18 +55,7 @@ public class PumpBlock extends DirectionalKineticBlock implements IWaterLoggable
@Override
public BlockState updateAfterWrenched(BlockState newState, ItemUseContext context) {
BlockState state = super.updateAfterWrenched(newState, context);
World world = context.getLevel();
BlockPos pos = context.getClickedPos();
if (world.isClientSide)
return state;
TileEntity tileEntity = world.getBlockEntity(pos);
if (!(tileEntity instanceof PumpTileEntity))
return state;
PumpTileEntity pump = (PumpTileEntity) tileEntity;
pump.sidesToUpdate.forEach(MutableBoolean::setTrue);
pump.reversed = !pump.reversed;
return state;
return super.updateAfterWrenched(newState, context);
}
@Override
@ -94,22 +81,6 @@ public class PumpBlock extends DirectionalKineticBlock implements IWaterLoggable
return;
world.getBlockTicks()
.scheduleTick(pos, this, 1, TickPriority.HIGH);
// if (world.isRemote)
// return;
// if (otherBlock instanceof FluidPipeBlock)
// return;
// TileEntity tileEntity = world.getTileEntity(pos);
// if (!(tileEntity instanceof PumpTileEntity))
// return;
// PumpTileEntity pump = (PumpTileEntity) tileEntity;
// Direction facing = state.get(FACING);
// for (boolean front : Iterate.trueAndFalse) {
// Direction side = front ? facing : facing.getOpposite();
// if (!pos.offset(side)
// .equals(neighborPos))
// continue;
// pump.updatePipesOnSide(side);
// }
}
@Override
@ -125,8 +96,8 @@ public class PumpBlock extends DirectionalKineticBlock implements IWaterLoggable
}
@Override
public BlockState updateShape(BlockState state, Direction direction, BlockState neighbourState,
IWorld world, BlockPos pos, BlockPos neighbourPos) {
public BlockState updateShape(BlockState state, Direction direction, BlockState neighbourState, IWorld world,
BlockPos pos, BlockPos neighbourPos) {
if (state.getValue(BlockStateProperties.WATERLOGGED)) {
world.getLiquidTicks()
.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world));
@ -154,6 +125,15 @@ public class PumpBlock extends DirectionalKineticBlock implements IWaterLoggable
if (state != oldState)
world.getBlockTicks()
.scheduleTick(pos, this, 1, TickPriority.HIGH);
if (isPump(state) && isPump(oldState) && state.getValue(FACING) == oldState.getValue(FACING)
.getOpposite()) {
TileEntity tileEntity = world.getBlockEntity(pos);
if (!(tileEntity instanceof PumpTileEntity))
return;
PumpTileEntity pump = (PumpTileEntity) tileEntity;
pump.pressureUpdate = true;
}
}
public static boolean isOpenAt(BlockState state, Direction d) {
@ -174,10 +154,10 @@ public class PumpBlock extends DirectionalKineticBlock implements IWaterLoggable
if (state.hasTileEntity() && (blockTypeChanged || !newState.hasTileEntity()))
world.removeBlockEntity(pos);
}
@Override
public boolean isPathfindable(BlockState state, IBlockReader reader, BlockPos pos, PathType type) {
return false;
}
}

View File

@ -39,6 +39,7 @@ public class PumpTileEntity extends KineticTileEntity {
LerpedFloat arrowDirection;
Couple<MutableBoolean> sidesToUpdate;
boolean pressureUpdate;
boolean reversed;
public PumpTileEntity(TileEntityType<?> typeIn) {
@ -73,6 +74,9 @@ public class PumpTileEntity extends KineticTileEntity {
if (!isVirtual())
return;
}
// if (pressureUpdate)
// updatePressureChange();
sidesToUpdate.forEachWithContext((update, isFront) -> {
if (update.isFalse())
@ -85,6 +89,7 @@ public class PumpTileEntity extends KineticTileEntity {
return;
if (speed < 0 != reversed) {
reversed = speed < 0;
updatePressureChange();
return;
}
}
@ -100,6 +105,11 @@ public class PumpTileEntity extends KineticTileEntity {
if (level.isClientSide && !isVirtual())
return;
updatePressureChange();
}
public void updatePressureChange() {
pressureUpdate = false;
BlockPos frontPos = worldPosition.relative(getFront());
BlockPos backPos = worldPosition.relative(getFront().getOpposite());
FluidPropagator.propagateChangedPipe(level, frontPos, level.getBlockState(frontPos));

View File

@ -5,6 +5,7 @@ import java.util.Random;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour;
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity;
import com.simibubi.create.foundation.block.ITE;
@ -30,7 +31,11 @@ import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
public class ContentObserverBlock extends HorizontalBlock implements ITE<ContentObserverTileEntity>, IWrenchable {
@ -66,6 +71,8 @@ public class ContentObserverBlock extends HorizontalBlock implements ITE<Content
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
BlockState state = defaultBlockState();
Capability<IItemHandler> itemCap = CapabilityItemHandler.ITEM_HANDLER_CAPABILITY;
Capability<IFluidHandler> fluidCap = CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY;
Direction preferredFacing = null;
for (Direction face : Iterate.horizontalDirections) {
@ -77,8 +84,12 @@ public class ContentObserverBlock extends HorizontalBlock implements ITE<Content
if (TileEntityBehaviour.get(tileEntity, TransportedItemStackHandlerBehaviour.TYPE) != null)
canDetect = true;
else if (tileEntity != null && tileEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
.isPresent())
else if (TileEntityBehaviour.get(tileEntity, FluidTransportBehaviour.TYPE) != null)
canDetect = true;
else if (tileEntity != null && (tileEntity.getCapability(itemCap)
.isPresent()
|| tileEntity.getCapability(fluidCap)
.isPresent()))
canDetect = true;
else if (tileEntity instanceof FunnelTileEntity)
canDetect = true;
@ -132,7 +143,7 @@ public class ContentObserverBlock extends HorizontalBlock implements ITE<Content
@Override
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
boolean isMoving) {
boolean isMoving) {
InvManipulationBehaviour behaviour = TileEntityBehaviour.get(worldIn, pos, InvManipulationBehaviour.TYPE);
if (behaviour != null)
behaviour.onNeighborChanged(fromPos);

View File

@ -2,13 +2,17 @@ package com.simibubi.create.content.logistics.block.redstone;
import java.util.List;
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour;
import com.simibubi.create.content.contraptions.fluids.PipeConnection.Flow;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.CapManipulationBehaviourBase.InterfaceProvider;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour.InterfaceProvider;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.TankManipulationBehaviour;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
@ -22,6 +26,7 @@ public class ContentObserverTileEntity extends SmartTileEntity {
private static final int DEFAULT_DELAY = 6;
private FilteringBehaviour filtering;
private InvManipulationBehaviour observedInventory;
private TankManipulationBehaviour observedTank;
public int turnOffTicks = 0;
public ContentObserverTileEntity(TileEntityType<? extends ContentObserverTileEntity> type) {
@ -34,8 +39,9 @@ public class ContentObserverTileEntity extends SmartTileEntity {
filtering = new FilteringBehaviour(this, new FilteredDetectorFilterSlot()).moveText(new Vector3d(0, 5, 0));
behaviours.add(filtering);
observedInventory = new InvManipulationBehaviour(this, InterfaceProvider.towardBlockFacing()).bypassSidedness();
behaviours.add(observedInventory);
InterfaceProvider towardBlockFacing = InterfaceProvider.towardBlockFacing();
behaviours.add(observedInventory = new InvManipulationBehaviour(this, towardBlockFacing).bypassSidedness());
behaviours.add(observedTank = new TankManipulationBehaviour(this, towardBlockFacing).bypassSidedness());
}
@Override
@ -55,31 +61,54 @@ public class ContentObserverTileEntity extends SmartTileEntity {
Direction facing = state.getValue(ContentObserverBlock.FACING);
BlockPos targetPos = worldPosition.relative(facing);
// Detect items on belt
TransportedItemStackHandlerBehaviour behaviour =
TileEntityBehaviour.get(level, targetPos, TransportedItemStackHandlerBehaviour.TYPE);
if (behaviour != null) {
behaviour.handleCenteredProcessingOnAllItems(.45f, stack -> {
if (!filtering.test(stack.stack) || turnOffTicks == 6)
return TransportedResult.doNothing();
activate();
return TransportedResult.doNothing();
});
return;
}
// Detect fluids in pipe
FluidTransportBehaviour fluidBehaviour =
TileEntityBehaviour.get(level, targetPos, FluidTransportBehaviour.TYPE);
if (fluidBehaviour != null) {
for (Direction side : Iterate.directions) {
Flow flow = fluidBehaviour.getFlow(side);
if (flow == null || !flow.inbound || !flow.complete)
continue;
if (!filtering.test(flow.fluid))
continue;
activate();
return;
}
return;
}
if (!observedInventory.simulate()
.extract()
.isEmpty()) {
activate();
return;
}
if (!observedTank.simulate()
.extractAny()
.isEmpty()) {
activate();
return;
}
}
public void activate() {
activate(DEFAULT_DELAY);
}
public void activate(int ticks) {
BlockState state = getBlockState();
turnOffTicks = ticks;

View File

@ -32,8 +32,12 @@ import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
public class StockpileSwitchBlock extends HorizontalBlock implements ITE<StockpileSwitchTileEntity>, IWrenchable {
@ -83,11 +87,12 @@ public class StockpileSwitchBlock extends HorizontalBlock implements ITE<Stockpi
@Override
public int getSignal(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side) {
if (side == blockState.getValue(FACING).getOpposite())
if (side == blockState.getValue(FACING)
.getOpposite())
return 0;
return getTileEntityOptional(blockAccess, pos).filter(StockpileSwitchTileEntity::isPowered)
.map($ -> 15)
.orElse(0);
.map($ -> 15)
.orElse(0);
}
@Override
@ -120,14 +125,18 @@ public class StockpileSwitchBlock extends HorizontalBlock implements ITE<Stockpi
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
BlockState state = defaultBlockState();
Capability<IItemHandler> itemCap = CapabilityItemHandler.ITEM_HANDLER_CAPABILITY;
Capability<IFluidHandler> fluidCap = CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY;
Direction preferredFacing = null;
for (Direction face : Iterate.horizontalDirections) {
TileEntity te = context.getLevel()
.getBlockEntity(context.getClickedPos()
.relative(face));
if (te != null && te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
.isPresent())
if (te != null && (te.getCapability(itemCap)
.isPresent()
|| te.getCapability(fluidCap)
.isPresent()))
if (preferredFacing == null)
preferredFacing = face;
else {

View File

@ -5,8 +5,9 @@ import java.util.List;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.CapManipulationBehaviourBase.InterfaceProvider;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour.InterfaceProvider;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.TankManipulationBehaviour;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@ -17,6 +18,8 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.ITickList;
import net.minecraft.world.TickPriority;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
public class StockpileSwitchTileEntity extends SmartTileEntity {
@ -30,6 +33,7 @@ public class StockpileSwitchTileEntity extends SmartTileEntity {
private FilteringBehaviour filtering;
private InvManipulationBehaviour observedInventory;
private TankManipulationBehaviour observedTank;
public StockpileSwitchTileEntity(TileEntityType<?> typeIn) {
super(typeIn);
@ -70,34 +74,53 @@ public class StockpileSwitchTileEntity extends SmartTileEntity {
public void updateCurrentLevel() {
boolean changed = false;
observedInventory.findNewCapability();
if (!observedInventory.hasInventory()) {
if (currentLevel == -1)
return;
level.setBlock(worldPosition, getBlockState().setValue(StockpileSwitchBlock.INDICATOR, 0), 3);
currentLevel = -1;
state = false;
sendData();
scheduleBlockTick();
return;
}
float occupied = 0;
float totalSpace = 0;
IItemHandler inv = observedInventory.getInventory();
for (int slot = 0; slot < inv.getSlots(); slot++) {
ItemStack stackInSlot = inv.getStackInSlot(slot);
int space = Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slot));
int count = stackInSlot.getCount();
observedInventory.findNewCapability();
if (observedInventory.hasInventory()) {
// Item inventory
IItemHandler inv = observedInventory.getInventory();
for (int slot = 0; slot < inv.getSlots(); slot++) {
ItemStack stackInSlot = inv.getStackInSlot(slot);
int space = Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slot));
int count = stackInSlot.getCount();
if (space == 0)
continue;
if (space == 0)
continue;
totalSpace += 1;
if (filtering.test(stackInSlot))
occupied += count * (1f / space);
}
totalSpace += 1;
} else {
observedTank.findNewCapability();
if (observedTank.hasInventory()) {
// Fluid inventory
IFluidHandler tank = observedTank.getInventory();
for (int slot = 0; slot < tank.getTanks(); slot++) {
FluidStack stackInSlot = tank.getFluidInTank(slot);
int space = tank.getTankCapacity(slot);
int count = stackInSlot.getAmount();
if (space == 0)
continue;
if (filtering.test(stackInSlot))
occupied += count * (1f / space);
totalSpace += 1;
if (filtering.test(stackInSlot))
occupied += count * (1f / space);
}
} else {
// No compatible inventories found
if (currentLevel == -1)
return;
level.setBlock(worldPosition, getBlockState().setValue(StockpileSwitchBlock.INDICATOR, 0), 3);
currentLevel = -1;
state = false;
sendData();
scheduleBlockTick();
return;
}
}
float stockLevel = occupied / totalSpace;
@ -116,7 +139,8 @@ public class StockpileSwitchTileEntity extends SmartTileEntity {
int displayLevel = 0;
if (currentLevel > 0)
displayLevel = (int) (currentLevel * 6);
level.setBlock(worldPosition, getBlockState().setValue(StockpileSwitchBlock.INDICATOR, displayLevel), update ? 3 : 2);
level.setBlock(worldPosition, getBlockState().setValue(StockpileSwitchBlock.INDICATOR, displayLevel),
update ? 3 : 2);
if (update)
scheduleBlockTick();
@ -146,8 +170,9 @@ public class StockpileSwitchTileEntity extends SmartTileEntity {
.withCallback($ -> updateCurrentLevel());
behaviours.add(filtering);
observedInventory = new InvManipulationBehaviour(this, InterfaceProvider.towardBlockFacing()).bypassSidedness();
behaviours.add(observedInventory);
InterfaceProvider towardBlockFacing = InterfaceProvider.towardBlockFacing();
behaviours.add(observedInventory = new InvManipulationBehaviour(this, towardBlockFacing).bypassSidedness());
behaviours.add(observedTank = new TankManipulationBehaviour(this, towardBlockFacing).bypassSidedness());
}
public float getLevelForDisplay() {

View File

@ -0,0 +1,143 @@
package com.simibubi.create.foundation.tileEntity.behaviour.inventory;
import javax.annotation.Nullable;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.utility.BlockFace;
import net.minecraft.block.BlockState;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
public abstract class CapManipulationBehaviourBase<T, S extends CapManipulationBehaviourBase<?, ?>>
extends TileEntityBehaviour {
protected InterfaceProvider target;
protected LazyOptional<T> targetCapability;
protected boolean simulateNext;
protected boolean bypassSided;
private boolean findNewNextTick;
public CapManipulationBehaviourBase(SmartTileEntity te, InterfaceProvider target) {
super(te);
setLazyTickRate(5);
this.target = target;
targetCapability = LazyOptional.empty();
simulateNext = false;
bypassSided = false;
}
protected abstract Capability<T> capability();
@Override
public void initialize() {
super.initialize();
findNewNextTick = true;
}
@Override
public void onNeighborChanged(BlockPos neighborPos) {
BlockFace targetBlockFace = target.getTarget(getWorld(), tileEntity.getBlockPos(), tileEntity.getBlockState());
if (targetBlockFace.getConnectedPos()
.equals(neighborPos))
onHandlerInvalidated(targetCapability);
}
@SuppressWarnings("unchecked")
public S bypassSidedness() {
bypassSided = true;
return (S) this;
}
/**
* Only simulate the upcoming operation
*/
@SuppressWarnings("unchecked")
public S simulate() {
simulateNext = true;
return (S) this;
}
public boolean hasInventory() {
return targetCapability.isPresent();
}
@Nullable
public T getInventory() {
return targetCapability.orElse(null);
}
protected void onHandlerInvalidated(LazyOptional<T> handler) {
findNewNextTick = true;
targetCapability = LazyOptional.empty();
}
@Override
public void lazyTick() {
super.lazyTick();
if (!targetCapability.isPresent())
findNewCapability();
}
@Override
public void tick() {
super.tick();
if (findNewNextTick || getWorld().getGameTime() % 64 == 0) {
findNewNextTick = false;
findNewCapability();
}
}
public int getAmountFromFilter() {
int amount = -1;
FilteringBehaviour filter = tileEntity.getBehaviour(FilteringBehaviour.TYPE);
if (filter != null && !filter.anyAmount())
amount = filter.getAmount();
return amount;
}
public void findNewCapability() {
World world = getWorld();
BlockFace targetBlockFace = target.getTarget(world, tileEntity.getBlockPos(), tileEntity.getBlockState())
.getOpposite();
BlockPos pos = targetBlockFace.getPos();
targetCapability = LazyOptional.empty();
if (!world.isLoaded(pos))
return;
TileEntity invTE = world.getBlockEntity(pos);
if (invTE == null)
return;
Capability<T> capability = capability();
targetCapability =
bypassSided ? invTE.getCapability(capability) : invTE.getCapability(capability, targetBlockFace.getFace());
if (targetCapability.isPresent())
targetCapability.addListener(this::onHandlerInvalidated);
}
@FunctionalInterface
public interface InterfaceProvider {
public static InterfaceProvider towardBlockFacing() {
return (w, p, s) -> new BlockFace(p,
s.hasProperty(BlockStateProperties.FACING) ? s.getValue(BlockStateProperties.FACING)
: s.getValue(BlockStateProperties.HORIZONTAL_FACING));
}
public static InterfaceProvider oppositeOfBlockFacing() {
return (w, p, s) -> new BlockFace(p,
(s.hasProperty(BlockStateProperties.FACING) ? s.getValue(BlockStateProperties.FACING)
: s.getValue(BlockStateProperties.HORIZONTAL_FACING)).getOpposite());
}
public BlockFace getTarget(World world, BlockPos pos, BlockState blockState);
}
}

View File

@ -3,40 +3,25 @@ package com.simibubi.create.foundation.tileEntity.behaviour.inventory;
import java.util.function.Function;
import java.util.function.Predicate;
import javax.annotation.Nullable;
import com.google.common.base.Predicates;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.utility.BlockFace;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
public class InvManipulationBehaviour extends TileEntityBehaviour {
public class InvManipulationBehaviour extends CapManipulationBehaviourBase<IItemHandler, InvManipulationBehaviour> {
// Extra types available for multibehaviour
public static BehaviourType<InvManipulationBehaviour>
TYPE = new BehaviourType<>(), EXTRACT = new BehaviourType<>(), INSERT = new BehaviourType<>();
protected InterfaceProvider target;
protected LazyOptional<IItemHandler> targetCapability;
protected boolean simulateNext;
protected boolean bypassSided;
private boolean findNewNextTick;
private BehaviourType<InvManipulationBehaviour> behaviourType;
public static InvManipulationBehaviour forExtraction(SmartTileEntity te, InterfaceProvider target) {
@ -53,35 +38,13 @@ public class InvManipulationBehaviour extends TileEntityBehaviour {
private InvManipulationBehaviour(BehaviourType<InvManipulationBehaviour> type, SmartTileEntity te,
InterfaceProvider target) {
super(te);
super(te, target);
behaviourType = type;
setLazyTickRate(5);
this.target = target;
this.targetCapability = LazyOptional.empty();
simulateNext = false;
bypassSided = false;
}
public InvManipulationBehaviour bypassSidedness() {
bypassSided = true;
return this;
}
/**
* Only simulate the upcoming operation
*/
public InvManipulationBehaviour simulate() {
simulateNext = true;
return this;
}
public boolean hasInventory() {
return targetCapability.isPresent();
}
@Nullable
public IItemHandler getInventory() {
return targetCapability.orElse(null);
@Override
protected Capability<IItemHandler> capability() {
return CapabilityItemHandler.ITEM_HANDLER_CAPABILITY;
}
public ItemStack extract() {
@ -116,7 +79,7 @@ public class InvManipulationBehaviour extends TileEntityBehaviour {
}
private static ItemStack extractAmountOrThresh(IItemHandler inventory, Predicate<ItemStack> test, int amount,
Function<ItemStack, Integer> amountThreshold, boolean shouldSimulate) {
Function<ItemStack, Integer> amountThreshold, boolean shouldSimulate) {
if (amount == -1)
return ItemHelper.extract(inventory, test, amountThreshold, shouldSimulate);
return ItemHelper.extract(inventory, test, amount, shouldSimulate);
@ -139,87 +102,9 @@ public class InvManipulationBehaviour extends TileEntityBehaviour {
return test;
}
@Override
public void initialize() {
super.initialize();
findNewNextTick = true;
}
@Override
public void onNeighborChanged(BlockPos neighborPos) {
BlockFace targetBlockFace = target.getTarget(getWorld(), tileEntity.getBlockPos(), tileEntity.getBlockState());
if (targetBlockFace.getConnectedPos().equals(neighborPos))
onHandlerInvalidated(targetCapability);
}
protected void onHandlerInvalidated(LazyOptional<IItemHandler> handler) {
findNewNextTick = true;
targetCapability = LazyOptional.empty();
}
@Override
public void lazyTick() {
super.lazyTick();
if (!targetCapability.isPresent())
findNewCapability();
}
@Override
public void tick() {
super.tick();
if (findNewNextTick || getWorld().getGameTime() % 64 == 0) {
findNewNextTick = false;
findNewCapability();
}
}
public int getAmountFromFilter() {
int amount = -1;
FilteringBehaviour filter = tileEntity.getBehaviour(FilteringBehaviour.TYPE);
if (filter != null && !filter.anyAmount())
amount = filter.getAmount();
return amount;
}
public void findNewCapability() {
BlockFace targetBlockFace = target.getTarget(getWorld(), tileEntity.getBlockPos(), tileEntity.getBlockState())
.getOpposite();
BlockPos pos = targetBlockFace.getPos();
World world = getWorld();
targetCapability = LazyOptional.empty();
if (!world.isLoaded(pos))
return;
TileEntity invTE = world.getBlockEntity(pos);
if (invTE == null)
return;
targetCapability = bypassSided ? invTE.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
: invTE.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, targetBlockFace.getFace());
if (targetCapability.isPresent())
targetCapability.addListener(this::onHandlerInvalidated);
}
@Override
public BehaviourType<?> getType() {
return behaviourType;
}
@FunctionalInterface
public interface InterfaceProvider {
public static InterfaceProvider towardBlockFacing() {
return (w, p, s) -> new BlockFace(p, s.hasProperty(BlockStateProperties.FACING) ? s.getValue(BlockStateProperties.FACING)
: s.getValue(BlockStateProperties.HORIZONTAL_FACING));
}
public static InterfaceProvider oppositeOfBlockFacing() {
return (w, p, s) -> new BlockFace(p,
(s.hasProperty(BlockStateProperties.FACING) ? s.getValue(BlockStateProperties.FACING)
: s.getValue(BlockStateProperties.HORIZONTAL_FACING)).getOpposite());
}
public BlockFace getTarget(World world, BlockPos pos, BlockState blockState);
}
}

View File

@ -0,0 +1,69 @@
package com.simibubi.create.foundation.tileEntity.behaviour.inventory;
import java.util.function.Predicate;
import com.google.common.base.Predicates;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
public class TankManipulationBehaviour extends CapManipulationBehaviourBase<IFluidHandler, TankManipulationBehaviour> {
public static BehaviourType<TankManipulationBehaviour> OBSERVE = new BehaviourType<>();
private BehaviourType<TankManipulationBehaviour> behaviourType;
public TankManipulationBehaviour(SmartTileEntity te, InterfaceProvider target) {
this(OBSERVE, te, target);
}
private TankManipulationBehaviour(BehaviourType<TankManipulationBehaviour> type, SmartTileEntity te,
InterfaceProvider target) {
super(te, target);
behaviourType = type;
}
public FluidStack extractAny() {
if (!hasInventory())
return FluidStack.EMPTY;
IFluidHandler inventory = getInventory();
Predicate<FluidStack> filterTest = getFilterTest(Predicates.alwaysTrue());
for (int i = 0; i < inventory.getTanks(); i++) {
FluidStack fluidInTank = inventory.getFluidInTank(i);
if (fluidInTank.isEmpty())
continue;
if (!filterTest.test(fluidInTank))
continue;
FluidStack drained =
inventory.drain(fluidInTank, simulateNext ? FluidAction.SIMULATE : FluidAction.EXECUTE);
if (!drained.isEmpty())
return drained;
}
return FluidStack.EMPTY;
}
protected Predicate<FluidStack> getFilterTest(Predicate<FluidStack> customFilter) {
Predicate<FluidStack> test = customFilter;
FilteringBehaviour filter = tileEntity.getBehaviour(FilteringBehaviour.TYPE);
if (filter != null)
test = customFilter.and(filter::test);
return test;
}
@Override
protected Capability<IFluidHandler> capability() {
return CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY;
}
@Override
public BehaviourType<?> getType() {
return behaviourType;
}
}

View File

@ -137,12 +137,16 @@
"block.create.turntable.tooltip.summary": "Turns _Rotational Force_ into refined Motion Sickness.",
"block.create.stockpile_switch.tooltip": "STOCKPILE SWITCH",
"block.create.stockpile_switch.tooltip.summary": "Toggles a Redstone signal based on the amount of _Stored Items_ in the attached Container. Comes with a handy filter. As opposed to a _Comparator,_ the _Stockpile Switch_ allows configuration of _thresholds,_ at which signals are inverted.",
"block.create.stockpile_switch.tooltip.summary": "Toggles a Redstone signal based on the amount of _Stored Items_ or _Fluids_ in the attached Container. Comes with a handy filter. As opposed to a _Comparator,_ the _Stockpile Switch_ allows configuration of _thresholds,_ at which signals are inverted.",
"block.create.stockpile_switch.tooltip.condition1": "When R-Clicked",
"block.create.stockpile_switch.tooltip.behaviour1": "Opens the _Configuration Interface_.",
"block.create.content_observer.tooltip": "CONTENT OBSERVER",
"block.create.content_observer.tooltip.summary": "_Detects Items_ inside _containers_ and _conveyors_ matching a configured _filter_. While the observed _inventory_, _belt_ or _chute contains_ a matching item, this component will emit a _Redstone Signal_. When an observed _funnel transfers_ a matching item, this component will emit a _Redstone Pulse_.",
"block.create.content_observer.tooltip.summary": "_Detects Items_ or _Fluids_ inside _containers_, _pipes_ or _conveyors_ matching a configured _filter_.",
"block.create.content_observer.tooltip.condition1": "When observing a Container",
"block.create.content_observer.tooltip.behaviour1": "Emits a _Redstone Signal_ while the observed container has _matching_ _content_.",
"block.create.content_observer.tooltip.condition2": "When observing a Funnel",
"block.create.content_observer.tooltip.behaviour2": "Emits a _Redstone Pulse_ when a _matching_ Item is _transferred_.",
"block.create.adjustable_crate.tooltip": "ADJUSTABLE CRATE",
"block.create.adjustable_crate.tooltip.summary": "This _Item Container_ allows Manual control over its capacity. It can hold up to _16 Stacks_ of any Item. Supports _Redstone Comparators_.",