diff --git a/.github/workflows/test-on-push.yml b/.github/workflows/test-on-push.yml new file mode 100644 index 00000000000..043be9c7127 --- /dev/null +++ b/.github/workflows/test-on-push.yml @@ -0,0 +1,60 @@ +name: Test pull request on push + +on: + pull_request: + paths: ['**'] + +# Cancel previous jobs if PR gets another push +concurrency: + group: PR-test-${{ github.ref }} + cancel-in-progress: true + +jobs: + test: + runs-on: ubuntu-latest + env: + VERSION_SUFFIX: "PR-${{ github.event.number }}" + steps: + - uses: actions/checkout@v4 + - name: Check Path Filter + uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + code: + - 'src/**' + - '*.gradle' + - 'gradle.properties' + - 'gradlew*' + - 'gradle/**' + - name: Setup Build + if: steps.filter.outputs.code == 'true' + uses: ./.github/actions/build_setup + - name: Run GameTests + if: steps.filter.outputs.code == 'true' + id: gametest + continue-on-error: true + run: ./gradlew runGameTestServer + - name: Update “Tests Passed” / “Tests Failed” labels + if: steps.filter.outputs.code == 'true' && github.event.pull_request.head.repo.full_name == github.repository + uses: actions/github-script@v7 + with: + script: | + const [add, remove] = { + success: ['Tests: Passed','Tests: Failed'], + failure: ['Tests: Failed','Tests: Passed'] + }['${{ steps.gametest.outcome }}']; + + const { owner, repo } = context.repo; + const issue_number = context.payload.pull_request.number; + + await github.rest.issues + .addLabels({ owner, repo, issue_number, labels: [add] }) + .catch(() => {}); + + await github.rest.issues + .removeLabel({ owner, repo, issue_number, name: remove }) + .catch(() => {}); + - name: Fail on GameTest failures + if: steps.filter.outputs.code == 'true' && steps.gametest.outcome == 'failure' + run: exit 1 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index af7afc23b62..61e448905f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,231 @@ # ChangeLog -## Version [v7.0.1](https://github.com/GregTechCEu/GregTech-Modern/compare/v7.0.0-1.21.1...v7.0.1) +## Version [v7.4.0](https://github.com/GregTechCEu/GregTech-Modern/compare/v7.3.0-1.20.1...v7.4.0-1.20.1) +### Added + +- Add Bucket/Tank items interaction with coke oven by @Spicierspace153 in [#4190](https://github.com/GregTechCEu/GregTech-Modern/pull/4190) +- NBT Predicate Ingredient by @jurrejelle in [#4175](https://github.com/GregTechCEu/GregTech-Modern/pull/4175) +- Add a SpeedBoost When Walking on Concrete by @YoungOnionMC in [#3985](https://github.com/GregTechCEu/GregTech-Modern/pull/3985) + +### Fixed + +- Change paused steel boiler texture to be consistent with other boilers by @GirixK in [#4196](https://github.com/GregTechCEu/GregTech-Modern/pull/4196) +- Fix server disconnections and other network errors from causing a crash by @gustovafing in [#4169](https://github.com/GregTechCEu/GregTech-Modern/pull/4169) +- Implement creating Chanced and Ranged NBTPredicateIngredients by @DilithiumThoride in [#4202](https://github.com/GregTechCEu/GregTech-Modern/pull/4202) +- Fix machines set to disable after current cycle not disabling on powerstall by @DilithiumThoride in [#4215](https://github.com/GregTechCEu/GregTech-Modern/pull/4215) +- Balance chemical titanium recipe by @jurrejelle in [#4228](https://github.com/GregTechCEu/GregTech-Modern/pull/4228) +- Fix Jade showing all singleblock generators as producing at LV by @DilithiumThoride in [#4193](https://github.com/GregTechCEu/GregTech-Modern/pull/4193) +- Use manual tag checking instead of IsSameItemSameTags by @YoungOnionMC in [#4210](https://github.com/GregTechCEu/GregTech-Modern/pull/4210) + +### Changed + +- Update zh_cn.json 1.20 by @iouter in [#4226](https://github.com/GregTechCEu/GregTech-Modern/pull/4226) +- Refactor OR and XOR chance logic rolls to multiply outputs for Guaranteed Rolls rather than adding by @DilithiumThoride in [#4211](https://github.com/GregTechCEu/GregTech-Modern/pull/4211) + + +## Version [v7.3.0](https://github.com/GregTechCEu/GregTech-Modern/compare/v7.2.1-1.20.1...v7.3.0-1.20.1) +### Added + +- Re-enable using Screwdriver to toggle Drum auto output, if Allow Input From Output Side is disabled by @DilithiumThoride in [#4163](https://github.com/GregTechCEu/GregTech-Modern/pull/4163) +- Implement voiding mode by @nutant233 in [#3924](https://github.com/GregTechCEu/GregTech-Modern/pull/3924) +- Turbine Energy Voiding by @YoungOnionMC in [#4177](https://github.com/GregTechCEu/GregTech-Modern/pull/4177) +- Max Parallel Setting on place by @YoungOnionMC in [#4186](https://github.com/GregTechCEu/GregTech-Modern/pull/4186) +- Miner block replacement by @YoungOnionMC in [#4021](https://github.com/GregTechCEu/GregTech-Modern/pull/4021) +- Change some formulas to make them more accurate by @TarLaboratories in [#4017](https://github.com/GregTechCEu/GregTech-Modern/pull/4017) + +### Fixed + +- Fix CC integration with the monitor cover by @TarLaboratories in [#4143](https://github.com/GregTechCEu/GregTech-Modern/pull/4143) +- Add material existing checks before making pipe recipes by @jurrejelle in [#4146](https://github.com/GregTechCEu/GregTech-Modern/pull/4146) +- Fix toggling Advanced Energy Detector Cover between EU and % modes causing values to decrement by @DilithiumThoride in [#4159](https://github.com/GregTechCEu/GregTech-Modern/pull/4159) +- Fix Stone Pressure Plate / Button recipe conflict by @DilithiumThoride in [#4131](https://github.com/GregTechCEu/GregTech-Modern/pull/4131) +- Re-enable using Screwdriver to toggle Drum auto output, if Allow Input From Output Side is disabled by @DilithiumThoride in [#4163](https://github.com/GregTechCEu/GregTech-Modern/pull/4163) +- Validate KubeJS recipes to ensure no invalid/missing ingredients by @mikerooni in [#4170](https://github.com/GregTechCEu/GregTech-Modern/pull/4170) +- fix (steam) multiblocks not resetting progress on powerfail by @DilithiumThoride in [#4181](https://github.com/GregTechCEu/GregTech-Modern/pull/4181) +- Add missing tooltips for auto-output buttons in machine UIs by @mikerooni in [#4180](https://github.com/GregTechCEu/GregTech-Modern/pull/4180) +- Fix XEI display for recipes with IO and TickIO of the same ingredient type by @DilithiumThoride in [#4137](https://github.com/GregTechCEu/GregTech-Modern/pull/4137) +- Fix Jade provider displaying no energy for addon steam machines consuming 1mB/t by @DilithiumThoride in [#4127](https://github.com/GregTechCEu/GregTech-Modern/pull/4127) +- Fix ore veins with only one layer causing crashes by @screret in [#4183](https://github.com/GregTechCEu/GregTech-Modern/pull/4183) +- Fix Ranged Fluid Ingredients deserializing incorrectly in SMP by @DilithiumThoride in [#4150](https://github.com/GregTechCEu/GregTech-Modern/pull/4150) +- Swap Diluted HCl to return HCl on Circuit 1 by @DilithiumThoride in [#4125](https://github.com/GregTechCEu/GregTech-Modern/pull/4125) +- Fix Tool Matching using every Item tag by @YoungOnionMC in [#3945](https://github.com/GregTechCEu/GregTech-Modern/pull/3945) +- Ore Maceration Changes by @YoungOnionMC in [#4020](https://github.com/GregTechCEu/GregTech-Modern/pull/4020) + +### Changed + +- update ja_jp by @code-onigiri in [#4099](https://github.com/GregTechCEu/GregTech-Modern/pull/4099) +- Deprecate ChanceLogic.FIRST by @DilithiumThoride in [#4109](https://github.com/GregTechCEu/GregTech-Modern/pull/4109) +- Holistic Rebalance to the Large and Small Boiler by @Ghostipedia in [#4075](https://github.com/GregTechCEu/GregTech-Modern/pull/4075) +- Ore Maceration Changes by @YoungOnionMC in [#4020](https://github.com/GregTechCEu/GregTech-Modern/pull/4020) + + +## Version [v7.2.1](https://github.com/GregTechCEu/GregTech-Modern/compare/v.7.2.0-1.20.1...v7.2.1-1.20.1) +### Added + +- Add flag to disable create compat by @jurrejelle in [#3956](https://github.com/GregTechCEu/GregTech-Modern/pull/3956) +- Make new flag DISABLE_MATERIAL_RECIPES to replace NO_UNIFICATION. by @Phoenixvine32908 in [#3999](https://github.com/GregTechCEu/GregTech-Modern/pull/3999) +- Alter Jade/TOP provider to display machine voltage tier by machine tier rather than by recipe/overclock tier by @DilithiumThoride in [#4002](https://github.com/GregTechCEu/GregTech-Modern/pull/4002) +- Buff facade recipe by @htmlcsjs in [#4007](https://github.com/GregTechCEu/GregTech-Modern/pull/4007) +- Format Numbers by @remakefactory in [#4111](https://github.com/GregTechCEu/GregTech-Modern/pull/4111) + +### Fixed + +- Make energy placeholder work with substations by @TarLaboratories in [#3964](https://github.com/GregTechCEu/GregTech-Modern/pull/3964) +- Fix Advanced Energy Detector Cover not working in % mode by @DilithiumThoride in [#3950](https://github.com/GregTechCEu/GregTech-Modern/pull/3950) +- Fix recipe search for Ranged Fluid Ingredients on 0 roll by @DilithiumThoride in [#3968](https://github.com/GregTechCEu/GregTech-Modern/pull/3968) +- Rename AdjacentFluid overload by @jurrejelle in [#3960](https://github.com/GregTechCEu/GregTech-Modern/pull/3960) +- Slightly increase Large Turbine energy output and fuel burn by @DilithiumThoride in [#3988](https://github.com/GregTechCEu/GregTech-Modern/pull/3988) +- Fix crates voiding the inventories of their stack after being placed down by @purebluez in [#4012](https://github.com/GregTechCEu/GregTech-Modern/pull/4012) +- Read and Display Subtick Overclock Parallels separately from Hatch-based Parallels by @DilithiumThoride in [#3961](https://github.com/GregTechCEu/GregTech-Modern/pull/3961) +- Fix central monitor crash by @TarLaboratories in [#4010](https://github.com/GregTechCEu/GregTech-Modern/pull/4010) +- Fix Machine explosions by @YoungOnionMC in [#3983](https://github.com/GregTechCEu/GregTech-Modern/pull/3983) +- Fix color spray not working with blockstate by @bnjmn21 in [#3982](https://github.com/GregTechCEu/GregTech-Modern/pull/3982) +- Fix and align textures of (passthrough) hatch/buses, pipeline endpoints and pump hatch by @arsdragonfly in [#3944](https://github.com/GregTechCEu/GregTech-Modern/pull/3944) +- Add slice-by-slice recipe consumption by @jurrejelle in [#4006](https://github.com/GregTechCEu/GregTech-Modern/pull/4006) +- Fix representative recipes not generating by @YoungOnionMC in [#4019](https://github.com/GregTechCEu/GregTech-Modern/pull/4019) +- Downscale manual IO disabled button by @JuiceyBeans in [#4051](https://github.com/GregTechCEu/GregTech-Modern/pull/4051) +- fix registry removal by @NegaNote in [#4108](https://github.com/GregTechCEu/GregTech-Modern/pull/4108) +- Fix material decomp not working with KJS recipes by @YoungOnionMC in [#4116](https://github.com/GregTechCEu/GregTech-Modern/pull/4116) +- Fix Polished Stone Crafting Recipe by @YoungOnionMC in [#4071](https://github.com/GregTechCEu/GregTech-Modern/pull/4071) +- Fix laser and Optical pipe ignoring connections by @nutant233 in [#3939](https://github.com/GregTechCEu/GregTech-Modern/pull/3939) +- Fix turbines crashing when interacting with active rotor holders by @Taskeren in [#4047](https://github.com/GregTechCEu/GregTech-Modern/pull/4047) + +### Changed + +- Force modifier re-apply when recipe starts after being suspended by @jurrejelle in [#3971](https://github.com/GregTechCEu/GregTech-Modern/pull/3971) +- recipe manager handling refactor by @TechLord22 in [#3975](https://github.com/GregTechCEu/GregTech-Modern/pull/3975) +- Rename AdjacentFluid overload by @jurrejelle in [#3960](https://github.com/GregTechCEu/GregTech-Modern/pull/3960) +- Read and Display Subtick Overclock Parallels separately from Hatch-based Parallels by @DilithiumThoride in [#3961](https://github.com/GregTechCEu/GregTech-Modern/pull/3961) +- Translated using Weblate (Russian) for 1.20.1 by @marisathewitch in [#4078](https://github.com/GregTechCEu/GregTech-Modern/pull/4078) + + +## Version [v.7.2.0](https://github.com/GregTechCEu/GregTech-Modern/compare/v7.1.4-1.20.1...v.7.2.0-1.20.1) +### Added + +- Add pipe casting molds by @FourIsTheNumber in [#3671](https://github.com/GregTechCEu/GregTech-Modern/pull/3671) +- Suspend machines immediately if they're already idle by @DilithiumThoride in [#3719](https://github.com/GregTechCEu/GregTech-Modern/pull/3719) +- Generic Research Lang Keys by @YoungOnionMC in [#3738](https://github.com/GregTechCEu/GregTech-Modern/pull/3738) +- Add CraftingComponent for emitter/sensor gems by @dz894 in [#3720](https://github.com/GregTechCEu/GregTech-Modern/pull/3720) +- Custom Material Lang name by @YoungOnionMC in [#3578](https://github.com/GregTechCEu/GregTech-Modern/pull/3578) +- Recycling Yield and Working Configs by @YoungOnionMC in [#3754](https://github.com/GregTechCEu/GregTech-Modern/pull/3754) +- Powerfailing bypass by @YoungOnionMC in [#3767](https://github.com/GregTechCEu/GregTech-Modern/pull/3767) +- Ranged Inputs by @DilithiumThoride in [#3694](https://github.com/GregTechCEu/GregTech-Modern/pull/3694) +- More ender link covers by @TarLaboratories in [#3598](https://github.com/GregTechCEu/GregTech-Modern/pull/3598) +- programmed circuit icon Unified 9 Display by @remakefactory in [#3791](https://github.com/GregTechCEu/GregTech-Modern/pull/3791) +- Tank Fluid Preview by @Taskeren in [#3716](https://github.com/GregTechCEu/GregTech-Modern/pull/3716) +- Large Bronze Tank by @TarLaboratories in [#3796](https://github.com/GregTechCEu/GregTech-Modern/pull/3796) +- Minor improvements to jetpacks by @TarLaboratories in [#3798](https://github.com/GregTechCEu/GregTech-Modern/pull/3798) +- Play metal pipe sound when a long rod item falls by @TarLaboratories in [#3829](https://github.com/GregTechCEu/GregTech-Modern/pull/3829) +- Fixes and minor additions to the placeholder system by @TarLaboratories in [#3790](https://github.com/GregTechCEu/GregTech-Modern/pull/3790) +- Wrench improvements by @TarLaboratories in [#3690](https://github.com/GregTechCEu/GregTech-Modern/pull/3690) +- Make redstone-related blocks mineable with wrenches by @TarLaboratories in [#3800](https://github.com/GregTechCEu/GregTech-Modern/pull/3800) +- Add API for setting batch mode by @YoungOnionMC in [#3872](https://github.com/GregTechCEu/GregTech-Modern/pull/3872) +- Added allow input from output side for drums and the config by @Taskeren in [#3789](https://github.com/GregTechCEu/GregTech-Modern/pull/3789) +- Allow ULV Input Hatches in Primitive Pump Multiblock by @Nanabell in [#3892](https://github.com/GregTechCEu/GregTech-Modern/pull/3892) +- Allow filling steam boiler water/fuel tank with buckets by @serenibyss in [#3519](https://github.com/GregTechCEu/GregTech-Modern/pull/3519) +- Hammer Prospecting by @TarLaboratories in [#3802](https://github.com/GregTechCEu/GregTech-Modern/pull/3802) +- Growing plants rendering system by @RubenVerg in [#3363](https://github.com/GregTechCEu/GregTech-Modern/pull/3363) +- Placeable Fluids by @YoungOnionMC in [#3558](https://github.com/GregTechCEu/GregTech-Modern/pull/3558) +- Added Jade provider for Data Bank by @Taskeren in [#3930](https://github.com/GregTechCEu/GregTech-Modern/pull/3930) + +### Fixed + +- Fix Storage Cover missing its cover icon texture in machine UI by @purebluez in [#3684](https://github.com/GregTechCEu/GregTech-Modern/pull/3684) +- Fix Large Maceration Tower not receiving dropped items as input by @dz894 in [#3687](https://github.com/GregTechCEu/GregTech-Modern/pull/3687) +- Fix Hammer AOE and sounds missing by @YoungOnionMC in [#3688](https://github.com/GregTechCEu/GregTech-Modern/pull/3688) +- Fix Icons not being centered in tool grid by @dz894 in [#3709](https://github.com/GregTechCEu/GregTech-Modern/pull/3709) +- Reduce polymer extrusion cost by @FourIsTheNumber in [#3670](https://github.com/GregTechCEu/GregTech-Modern/pull/3670) +- Fix Ignore NBT in Not Working Properly in Robot Arms/Fluid Regulators by @Bumperdo09 in [#3699](https://github.com/GregTechCEu/GregTech-Modern/pull/3699) +- Fix passthrough hatches by @DilithiumThoride in [#3721](https://github.com/GregTechCEu/GregTech-Modern/pull/3721) +- Fix quantum tanks' fluid handlers not checking if the contained fluid is valid by @Taskeren in [#3715](https://github.com/GregTechCEu/GregTech-Modern/pull/3715) +- Queue an update for pattern buffers when they are placed by @jurrejelle in [#3724](https://github.com/GregTechCEu/GregTech-Modern/pull/3724) +- Update docs for creating custom coils. Fix tooltip on coil energy usage. by @DilithiumThoride in [#3739](https://github.com/GregTechCEu/GregTech-Modern/pull/3739) +- Give idle HPCA parts emissive textures by @YoungOnionMC in [#3746](https://github.com/GregTechCEu/GregTech-Modern/pull/3746) +- Improve name for research recipe failure case by @jurrejelle in [#3737](https://github.com/GregTechCEu/GregTech-Modern/pull/3737) +- Fix amount checking for fluid containers by @jurrejelle in [#3731](https://github.com/GregTechCEu/GregTech-Modern/pull/3731) +- Add check for recipe voltage in notifiableEnergyContainer by @jurrejelle in [#3735](https://github.com/GregTechCEu/GregTech-Modern/pull/3735) +- Fix world accelerator not working when reloaded by @WinExp in [#3743](https://github.com/GregTechCEu/GregTech-Modern/pull/3743) +- Offset facades by smaller number by @jurrejelle in [#3728](https://github.com/GregTechCEu/GregTech-Modern/pull/3728) +- Fix Multi-Smelter Energy Usage by @DilithiumThoride in [#3748](https://github.com/GregTechCEu/GregTech-Modern/pull/3748) +- Make Jade Provider not show %s Fluid Cell by @DilithiumThoride in [#3752](https://github.com/GregTechCEu/GregTech-Modern/pull/3752) +- Don't do chance rolls for ingredients with a chance of 0. by @DilithiumThoride in [#3751](https://github.com/GregTechCEu/GregTech-Modern/pull/3751) +- Fix broken models of multi parts by @YoungOnionMC in [#3745](https://github.com/GregTechCEu/GregTech-Modern/pull/3745) +- Fix Partial NBT not matching by @jurrejelle in [#3761](https://github.com/GregTechCEu/GregTech-Modern/pull/3761) +- Increase priority on inventory mixin to prevent clashing with IU by @jurrejelle in [#3765](https://github.com/GregTechCEu/GregTech-Modern/pull/3765) +- Three fixes with Chanced and Ranged Outputs by @DilithiumThoride in [#3691](https://github.com/GregTechCEu/GregTech-Modern/pull/3691) +- Missing Formed AE Model Property by @YoungOnionMC in [#3773](https://github.com/GregTechCEu/GregTech-Modern/pull/3773) +- Fix AOE not working on tools other than Mining Hammer by @YoungOnionMC in [#3774](https://github.com/GregTechCEu/GregTech-Modern/pull/3774) +- Fix fluid cell dupe using AE2 by @TarLaboratories in [#3693](https://github.com/GregTechCEu/GregTech-Modern/pull/3693) +- Fix NPE in GUI preview when machine model is replaced by a resource pack by @FakeDomi in [#3786](https://github.com/GregTechCEu/GregTech-Modern/pull/3786) +- Fix rock breaker recipe condition by @TarLaboratories in [#3804](https://github.com/GregTechCEu/GregTech-Modern/pull/3804) +- Set default fluids to the rock breaker recipes by @YoungOnionMC in [#3805](https://github.com/GregTechCEu/GregTech-Modern/pull/3805) +- Added translate key to tooltips changing machine mode by @Taskeren in [#3795](https://github.com/GregTechCEu/GregTech-Modern/pull/3795) +- Fix #3792 Multi-mode machines won't check recipe after mode changes by @Taskeren in [#3794](https://github.com/GregTechCEu/GregTech-Modern/pull/3794) +- Fix Robot Arms ignoring Keep Exact behavior when taking input from a Pipe by @DilithiumThoride in [#3812](https://github.com/GregTechCEu/GregTech-Modern/pull/3812) +- More vanilla recipe helpers by @jurrejelle in [#3814](https://github.com/GregTechCEu/GregTech-Modern/pull/3814) +- Render Docs and Update Docs by @jurrejelle in [#3782](https://github.com/GregTechCEu/GregTech-Modern/pull/3782) +- Make deserialisation registry-aware by @jurrejelle in [#3815](https://github.com/GregTechCEu/GregTech-Modern/pull/3815) +- Fix Tree Felling happening for Logged off Players by @alegian in [#3806](https://github.com/GregTechCEu/GregTech-Modern/pull/3806) +- Fix ender link cover textures and translations by @TarLaboratories in [#3819](https://github.com/GregTechCEu/GregTech-Modern/pull/3819) +- Fixed potassium feldspar formula by @TarLaboratories in [#3823](https://github.com/GregTechCEu/GregTech-Modern/pull/3823) +- Research Data Holder no longer voids recipes by @jurrejelle in [#3826](https://github.com/GregTechCEu/GregTech-Modern/pull/3826) +- Update HPCA Render system by @jurrejelle in [#3803](https://github.com/GregTechCEu/GregTech-Modern/pull/3803) +- Fix bug in combine placeholder by @TarLaboratories in [#3840](https://github.com/GregTechCEu/GregTech-Modern/pull/3840) +- fix offsets bugging out when there are multiple faces passed to a FluidAreaRender by @NegaNote in [#3858](https://github.com/GregTechCEu/GregTech-Modern/pull/3858) +- Fixed Shaped Recipes for Warning Signs by @Atmudia in [#3864](https://github.com/GregTechCEu/GregTech-Modern/pull/3864) +- parity between centrifuging oilsands dust and oilsands ore by @Zoryn4163 in [#3878](https://github.com/GregTechCEu/GregTech-Modern/pull/3878) +- Fix Jade not reporting disabled after current cycle by @DilithiumThoride in [#3879](https://github.com/GregTechCEu/GregTech-Modern/pull/3879) +- Fix tooltip claiming item/fluid pipes were modified with wire cutters by @DilithiumThoride in [#3844](https://github.com/GregTechCEu/GregTech-Modern/pull/3844) +- Fix Conveyor cover Round Robin with Restriction mode by @DilithiumThoride in [#3855](https://github.com/GregTechCEu/GregTech-Modern/pull/3855) +- Add missing particles to item/fluid passthrough and laser hatches by @jtuc in [#3890](https://github.com/GregTechCEu/GregTech-Modern/pull/3890) +- Chainsaw/crowbar model fixes by @jtuc in [#3894](https://github.com/GregTechCEu/GregTech-Modern/pull/3894) +- Fix maintenance not happening as often as intended by @serenibyss in [#3740](https://github.com/GregTechCEu/GregTech-Modern/pull/3740) +- Redo of 3744 by @YoungOnionMC in [#3873](https://github.com/GregTechCEu/GregTech-Modern/pull/3873) +- Order EMI Machine List manually by @jurrejelle in [#3902](https://github.com/GregTechCEu/GregTech-Modern/pull/3902) +- Probably fixed npe in raytrace #3891 by @Taskeren in [#3904](https://github.com/GregTechCEu/GregTech-Modern/pull/3904) +- Set fluid block map colors from material color by @jtuc in [#3911](https://github.com/GregTechCEu/GregTech-Modern/pull/3911) +- Fix Ender Redstone Link Covers on non-default channels by @jtuc in [#3918](https://github.com/GregTechCEu/GregTech-Modern/pull/3918) +- Fixed missing animation using duct tape by @Taskeren in [#3920](https://github.com/GregTechCEu/GregTech-Modern/pull/3920) +- Allow only 1 item in a turbo charger slot by @TarLaboratories in [#3922](https://github.com/GregTechCEu/GregTech-Modern/pull/3922) +- fix calcium carbonate formula by @arsdragonfly in [#3931](https://github.com/GregTechCEu/GregTech-Modern/pull/3931) +- broadcast item break event to client side for sound effect by @arsdragonfly in [#3933](https://github.com/GregTechCEu/GregTech-Modern/pull/3933) +- Fix GTValues.VHA[LV] value by @jurrejelle in [#3914](https://github.com/GregTechCEu/GregTech-Modern/pull/3914) +- Remove tier-based chance boosting from Bauxite Slag by @DilithiumThoride in [#3948](https://github.com/GregTechCEu/GregTech-Modern/pull/3948) + +### Changed + +- Implement tool action support & Fix default enchantments being removable by @screret in [#3582](https://github.com/GregTechCEu/GregTech-Modern/pull/3582) +- Refactor the rock breaker recipe condition by @screret in [#3591](https://github.com/GregTechCEu/GregTech-Modern/pull/3591) +- Make HPCA coolant a tag instead of a fluid by @jurrejelle in [#3779](https://github.com/GregTechCEu/GregTech-Modern/pull/3779) +- Update zh_cn.json 1.20 by @iouter in [#3821](https://github.com/GregTechCEu/GregTech-Modern/pull/3821) + + +## Version [v7.1.4](https://github.com/GregTechCEu/GregTech-Modern/compare/v7.1.3-1.20.1...v7.1.4-1.20.1) +### Fixed + +- Fix Machine power failing by @YoungOnionMC in [#3680](https://github.com/GregTechCEu/GregTech-Modern/pull/3680) + + +## Version [v7.1.3](https://github.com/GregTechCEu/GregTech-Modern/compare/v7.1.2-1.20.1...v7.1.3-1.20.1) +### Added + +- Make Parallel calculations use longs for stack amounts by @jurrejelle in [#3650](https://github.com/GregTechCEu/GregTech-Modern/pull/3650) +- make multiblock maintenance time configurable by @DilithiumThoride in [#3652](https://github.com/GregTechCEu/GregTech-Modern/pull/3652) +- make the fe-to-eu and eu-to-fe ratios max at maxint by @NegaNote in [#3656](https://github.com/GregTechCEu/GregTech-Modern/pull/3656) + +### Fixed + +- 335,544.32% recipe logic improvement by @YoungOnionMC in [#3645](https://github.com/GregTechCEu/GregTech-Modern/pull/3645) +- Fix diodes not updating their model on sync by @DilithiumThoride in [#3651](https://github.com/GregTechCEu/GregTech-Modern/pull/3651) +- Fix recipe viewer integration not working with research recipes that contain fluids by @Ghostipedia in [#3655](https://github.com/GregTechCEu/GregTech-Modern/pull/3655) +- Fix Parallel logic calculating the required amount wrong when there are split ingredients by @YoungOnionMC in [#3658](https://github.com/GregTechCEu/GregTech-Modern/pull/3658) + +### Changed + +- Optimize Network Switch for repeat CWU/t requests by @serenibyss in [#3654](https://github.com/GregTechCEu/GregTech-Modern/pull/3654) + -## Version [v7.0.0](https://github.com/GregTechCEu/GregTech-Modern/compare/v1.4.6-1.21...v7.0.0-1.21.1) +## Version [v7.0.0](https://github.com/GregTechCEu/GregTech-Modern/compare/v1.6.4-1.20.1...v7.0.0-1.20.1) ### Added - Add more plasmas and plasma turbine fuels by @omergunr100 in [#2974](https://github.com/GregTechCEu/GregTech-Modern/pull/2974) diff --git a/CODEOWNERS b/CODEOWNERS index 2510df1f345..e4ca2c13de6 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -4,4 +4,4 @@ # Specific files requiring admin approval CODEOWNERS @GregTechCEu/admin LICENSE @GregTechCEu/admin -README.md @GregTechCEu/admin +/README.md @GregTechCEu/admin diff --git a/build.gradle b/build.gradle index ecf0981e9b9..35793313dde 100644 --- a/build.gradle +++ b/build.gradle @@ -32,10 +32,7 @@ sourceSets { } test { - kotlin { - srcDirs += 'src/test/java' - } - compileClasspath += main.output + compileClasspath += main.output + main.compileClasspath runtimeClasspath += main.output + main.runtimeClasspath } @@ -55,11 +52,17 @@ configurations { clientRuntimeOnly.canBeResolved = false extraRuntimeOnly.canBeResolved = false clientExtraRuntimeOnly.canBeResolved = false + testImplementation.canBeResolved = false + testRuntimeOnly.canBeResolved = false runtimeClasspath.extendsFrom localRuntime extraRuntimeClasspath.extendsFrom extraLocalRuntime clientRuntimeClasspath.extendsFrom clientLocalRuntime extraClientRuntimeClasspath.extendsFrom clientExtraLocalRuntime + + renderNurseCfg { + canBeConsumed = false + } } apply from: "$rootDir/gradle/scripts/jars.gradle" @@ -69,6 +72,7 @@ apply from: "$rootDir/dependencies.gradle" apply from: "$rootDir/gradle/scripts/resources.gradle" apply from: "$rootDir/gradle/scripts/publishing.gradle" apply from: "$rootDir/gradle/scripts/spotless.gradle" +apply from: "$rootDir/gradle/scripts/docs.gradle" tasks.withType(JavaCompile).configureEach { @@ -78,5 +82,5 @@ tasks.withType(JavaCompile).configureEach { } lombok { - version = "1.18.36" + version = "1.18.38" } diff --git a/dependencies.gradle b/dependencies.gradle index ebf3baa5293..a29ad1ad506 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,7 +1,8 @@ dependencies { compileOnly(libs.jetbrains.annotations) - // LDLib + testJarJar(testApi(libs.testframework.get())) + jarJar(api(forge.ldlib.get())) // Registrate @@ -26,11 +27,16 @@ dependencies { compileOnly(forge.ae2) compileOnly(forge.ae2wtlib) + // Create + compileOnly(forge.ponder) + compileOnly(variantOf(forge.create) { classifier("slim") }) + compileOnly(forge.flywheel.forge.api) + // KJS compileOnly(forge.bundles.kjs) // Shimmer - compileOnly(forge.shimmer) + // compileOnly(forge.shimmer) compileOnly(forge.sodium) compileOnly(forge.iris) compileOnly(forge.modernfix) @@ -40,8 +46,8 @@ dependencies { compileOnly(forge.ftbteams) compileOnly(forge.ftbquests) compileOnly(forge.resourcefullib) - compileOnly(forge.argonauts) - compileOnly(forge.heracles) + // compileOnly(forge.argonauts) + // compileOnly(forge.heracles) // Maps compileOnly(forge.ftbchunks) @@ -51,26 +57,34 @@ dependencies { compileOnly(forge.journeymap.forge) // GameStages - compileOnly(forge.gamestages) + // compileOnly(forge.gamestages) // CC: Tweaked compileOnly(forge.cc.tweaked.core.api) compileOnly(forge.cc.tweaked.forge.api) // Standard runtime mods // + localRuntime(libs.testframework) + localRuntime(forge.jade) localRuntime(forge.ae2) localRuntime(forge.spark) localRuntime(forge.modernfix) + localRuntime(forge.create) { + // Needed to prevent game-test crashes + exclude group: "maven.modrinth", module: "journeymap" + exclude group: "info.journeymap", module: "journeymap-api-neoforge" + } // Runtime Recipe Viewers - uncomment whichever one you want to use // localRuntime(forge.emi) -// localRuntime(forge.jei.forge.impl) + localRuntime(forge.jei.neoforge.impl) // localRuntime(forge.bundles.rei.runtime) // Client-only runtime mods // clientLocalRuntime(forge.sodium) clientLocalRuntime(forge.iris) + renderNurseCfg(libs.renderNurse) ////////////////////////////////////////////////////// // Runtime mods for dev testing with unclean client // @@ -79,9 +93,9 @@ dependencies { extraLocalRuntime(forge.trenzalore) extraLocalRuntime(forge.curios) // extraLocalRuntime(forge.worldstripper) - extraLocalRuntime(forge.cc.tweaked.forge.impl) + localRuntime(forge.cc.tweaked.forge.impl) - extraLocalRuntime(forge.bundles.kjs) + localRuntime(forge.bundles.kjs) extraLocalRuntime(forge.ftblibrary) extraLocalRuntime(forge.ftbteams) @@ -106,5 +120,4 @@ dependencies { extraLocalRuntime(forge.observable) ////////////////////////// - testImplementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") } diff --git a/docs/README.md b/docs/README.md index 55fc578c723..66b84b35b54 100644 --- a/docs/README.md +++ b/docs/README.md @@ -26,9 +26,53 @@ Once you're happy, commit these changes and make a pull request for us to review If you come back to work on the docs, you can use a codespace again. You might need to `pull` to bring your codespace up to date, which you can do by pressing this button in the `Source Control` tab. ![image](https://github.com/user-attachments/assets/7d1246d2-f091-4452-bdb3-edf221902503) -## Installing Required Dependencies -To install the required dependencies, please run `pip install -r requirements.txt` +## Running in Gradle + +To run mkdocs locally, run the mkdocsServe task in gradle. + +Either in the gradle sidebar, click documentation/mkdocsServe, or run .`/gradlew mkdocsServe`. + +Click on the link it gives you at the bottom to open the local copy, and pages will automatically update with content as you save your files. + +You can also run documentation/mkdocsBuild. This will build the documentation in `docs/site`, which you can either host yourself or just open in a browser. + +## Installing Required Dependencies & Run Locally + +If you want to manually install and go through the steps to run locally, you can follow the steps below. + +Please run all commands from this section inside the `docs` folder! + +**First, setup a venv for python:** + +```bash +python -m venv .venv +``` +or: +```bash +python3 -m venv .venv +``` + +**Now activate the venv:** + +Windows: +```cmd +.venv\Scripts\activate +``` +Linux / MacOS: +```bash +source .venv/bin/activate +``` + +**Install the required dependencies:** +```bash +pip install -r requirements.txt +``` + +**Run locally**: +```bash +mkdocs serve +``` ## MkDocs Plugins diff --git a/docs/content/Development/External-Resources.md b/docs/content/Development/External-Resources.md index 434eaf4d351..46907c07632 100644 --- a/docs/content/Development/External-Resources.md +++ b/docs/content/Development/External-Resources.md @@ -16,9 +16,6 @@ as other resources you might find helpful. - [Forge-Wiki](https://docs.minecraftforge.net/en/1.20.x/) - [NeoForge-Wiki](https://docs.neoforged.net/) -!!! link "Official Fabric Docs" - [Fabric-Wiki :material-arrow-right: Mod Developer Docs](https://fabricmc.net/wiki/tutorial:start) - !!! link "Other Modding Docs" - [Forge Community-Wiki](https://forge.gemwire.uk/wiki/Main_Page) - [MCJty's Modding Wiki](https://www.mcjty.eu/docs/intro) diff --git a/docs/content/Development/General-Topics/Capabilities.md b/docs/content/Development/General-Topics/Capabilities.md deleted file mode 100644 index 07de9ae5653..00000000000 --- a/docs/content/Development/General-Topics/Capabilities.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Capabilities ---- - - -# How to access Capabilities of blocks and items - -Fabric doesn't have a capability system like Forge does, but you can use several utility methods instead: - -```java -FluidTransferHelper.getFluidTransfer(...); -ItemTransferHelper.getItemTransfer(...); -GTCapabilityHelper.getRecipeLogic(...) -GTCapabilityHelper.getControllable(...) -GTCapabilityHelper.getCoverable(...) -GTCapabilityHelper.getToolable(...) -GTCapabilityHelper.getWorkable(...) -GTCapabilityHelper.getElectricItem(...) -GTCapabilityHelper.getEnergyContainer(...) -``` diff --git a/docs/content/Development/General-Topics/Handling-Fluid-Bucket-Size.md b/docs/content/Development/General-Topics/Handling-Fluid-Bucket-Size.md deleted file mode 100644 index 07cad3fd9ad..00000000000 --- a/docs/content/Development/General-Topics/Handling-Fluid-Bucket-Size.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Handling Fluid Bucket Size ---- - - -# Dealing with Fluid Bucket Sizes - -The fluid systems of Forge and Fabric use different units. -Make sure you use the correct units whenever you're handling fluid amounts. - -To get the size of one bucket, use the following method: - -```java -FluidHelper.getBucket(); // returns 1000 on Forge and 81000 on Fabric. -``` \ No newline at end of file diff --git a/docs/content/Development/Recipe-Logic/.pages b/docs/content/Development/Recipe-Logic/.pages new file mode 100644 index 00000000000..df050fceea5 --- /dev/null +++ b/docs/content/Development/Recipe-Logic/.pages @@ -0,0 +1,6 @@ +nav: + - Recipe-Logic.md + - Recipe-Searching.md + - Recipe-Execution.md + - Custom-Ingredient.md + - ... \ No newline at end of file diff --git a/docs/content/Development/Recipe-Logic/Custom-Ingredient.md b/docs/content/Development/Recipe-Logic/Custom-Ingredient.md new file mode 100644 index 00000000000..cfa00b798d7 --- /dev/null +++ b/docs/content/Development/Recipe-Logic/Custom-Ingredient.md @@ -0,0 +1,417 @@ +--- +title: "Custom Ingredient" +--- + +!!! Note + Before reading / following this document, it is heavily recommended to have read [Recipe Logic](./Recipe-Logic.md), [Recipe Searching](./Recipe-Searching.md) and [Recipe Execution](./Recipe-Execution.md) first. + +If you want to make a custom ingredient, you need to do the following things + +1. Create the Ingredient itself +2. Create a MapIngredient to hold/check the Ingredient +3. Create a RecipeCapability to process the Ingredient +4. Create the NotifiableHatch to keep track of the Ingredient in the machine +5. Create a MultiPart that lets you interact with the ingredient in-game +6. Create the PartAbility for the MultiPart +7. Create a RecipeType so we can test with it +8. Register all these things + +## Creating the Ingredient +For our example, we will be using a simple ingredient called Bonk that simply holds how often you right clicked the hatch with a hard hammer. + +For our first step, we will be creating the ingredient: + +```java title="BonkIngredient.java" +public class BonkIngredient { + + public static final BonkIngredient EMPTY = new BonkIngredient(0); + + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.INT.fieldOf("bonk").forGetter(BonkIngredient::getBonk) + ).apply(instance, BonkIngredient::new)); + + @Getter + private int bonk; + + public BonkIngredient(int bonk){ + this.bonk = bonk; + } + + public BonkIngredient copy(){ + return new BonkIngredient(bonk); + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof BonkIngredient other)) return false; + return this.bonk == other.bonk; + } + + @Override + public int hashCode() { + return Integer.hashCode(bonk); + } + + @Override + public String toString() { + return "BonkIngredient{bonk=" + bonk + "}"; + } + + public static final class Serializer implements IContentSerializer { + public static final BonkIngredient.Serializer INSTANCE = new BonkIngredient.Serializer(); + + @Override + public BonkIngredient of(Object o) { + if (o instanceof Integer integer) { + return new BonkIngredient(integer); + } else if (o instanceof BonkIngredient bonkIngredient) { + return bonkIngredient; + } + return null; + } + + @Override + public BonkIngredient defaultValue() { + return EMPTY; + } + + @Override + public Class contentClass() { + return BonkIngredient.class; + } + + @Override + public Codec codec() { + return CODEC; + } + } +} +``` + +This is mostly just a wrapper around an integer, but the methods are there in case your ingredient would need to hold more data or have more complicated (de)serialization. For more information on Codecs, read [the forge docs](https://docs.minecraftforge.net/en/latest/datastorage/codecs/). + + +## Creating the MapIngredient + +```java title="MapBonkIngredient" +public class MapBonkIngredient extends AbstractMapIngredient { + + public final BonkIngredient ingredient; + + public MapBonkIngredient(BonkIngredient ingredient) { + this.ingredient = ingredient; + } + + @Override + protected int hash() { + return ingredient.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof MapBonkIngredient other)) return false; + return other.ingredient.equals(this.ingredient); + } + + @Override + public String toString() { + return "MapBonkIngredient{" + "bonk=" + ingredient + '}'; + } + + public static List convertToMapIngredient(BonkIngredient ingredient) { + return Collections.singletonList(new MapBonkIngredient(ingredient)); + } +} +``` + + +## Creating the RecipeCapability +```java title="BonkRecipeCapability" +public class BonkRecipeCapability extends RecipeCapability { + + public final static BonkRecipeCapability CAP = new BonkRecipeCapability(); + + protected BonkRecipeCapability() { + super("bonk", 0x777777, false, 5, BonkIngredient.Serializer.INSTANCE); + } + + @Override + public BonkIngredient copyInner(BonkIngredient content) { + return content.copy(); + } + + @Override + public @Nullable List getDefaultMapIngredient(Object ingredient) { + List ingredients = new ObjectArrayList<>(1); + if (ingredient instanceof BonkIngredient bonkIngredient) ingredients.add(new MapBonkIngredient(bonkIngredient)); + return ingredients; + } + + @Override + public List compressIngredients(Collection ingredients) { + int bonkTotal = 0; + for(Object ingredient : ingredients){ + if (ingredient instanceof BonkIngredient bonkIngredient){ + bonkTotal += bonkIngredient.getBonk(); + } + } + if(bonkTotal > 0){ + return new ObjectArrayList<>(Collections.singleton(new BonkIngredient(bonkTotal))); + } + return Collections.emptyList(); + } + + @Override + public void addXEIInfo(WidgetGroup group, int xOffset, GTRecipe recipe, List contents, boolean perTick, + boolean isInput, MutableInt yOffset) { + for (var content : contents) { + var bonkIngredient = BonkRecipeCapability.CAP.of(content); + if(isInput){ + group.addWidget(new LabelWidget(3-xOffset, yOffset.addAndGet(10), "Bonk needed: " + bonkIngredient.getBonk())); + } + // Bonk output not supported for now + } + } +} +``` + +## Creating the NotifiableHatch +```java title="NotifiableBonkHandler" +public class NotifiableBonkHandler extends NotifiableRecipeHandlerTrait + implements ICapabilityTrait { + + @Getter + public final IO handlerIO; + @Getter + public final IO capabilityIO; + + @Getter + private int bonk; + + public NotifiableBonkHandler(MetaMachine machine, IO io) { + this(machine, io, io); + } + + public NotifiableBonkHandler(MetaMachine machine, IO handlerIO, IO capabilityIO) { + super(machine); + this.handlerIO = handlerIO; + this.capabilityIO = capabilityIO; + } + + public boolean addBonk(int bonkToAdd, boolean simulate){ + if(bonkToAdd < 0) return false; + if((long) bonkToAdd + (long) this.bonk > Integer.MAX_VALUE) return false; + if(simulate) return true; + bonk += bonkToAdd; + this.notifyListeners(); + return true; + } + + + public boolean drainBonk(int bonkToDrain, boolean simulate){ + if(bonkToDrain < 0) return false; + if(bonkToDrain > this.bonk) return false; + if(simulate) return true; + bonk -= bonkToDrain; + this.notifyListeners(); + return true; + } + + @Override + public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { + for (int i = 0; i < left.size(); i++) { + BonkIngredient bonkIngredient = left.get(i); + if (bonk >= bonkIngredient.getBonk()) { + if (!simulate) { + bonk -= bonkIngredient.getBonk(); + } + left.remove(i); + break; + } + } + return left.isEmpty() ? null : left; + } + + @Override + public @NotNull List getContents() { + return List.of(new BonkIngredient(bonk)); + } + + @Override + public double getTotalContentAmount() { + return 1; + } + + @Override + public RecipeCapability getCapability() { + return BonkRecipeCapability.CAP; + } +} +``` + +## Creating the MultiPart +```java title="BonkHatchPartMachine" +public class BonkHatchPartMachine extends TieredIOPartMachine { + + @Persisted + public NotifiableBonkHandler bonkHandler; + + + public BonkHatchPartMachine(IMachineBlockEntity holder, int tier, IO io) { + super(holder, tier, io); + // On creation the NotifiableBonkHandler attaches itself to the machine + this.bonkHandler = new NotifiableBonkHandler(this, io); + } + + @Override + protected InteractionResult onHardHammerClick(Player playerIn, InteractionHand hand, Direction gridSide, BlockHitResult hitResult) { + if(isRemote()) return InteractionResult.SUCCESS; + if(bonkHandler.addBonk(1, false)){ + playerIn.sendSystemMessage(Component.literal("Bonk! Total bonk stored: " + bonkHandler.getBonk())); + return InteractionResult.CONSUME; + } + return super.onHardHammerClick(playerIn, hand, gridSide, hitResult); + } +} +``` + +We will register the actual part, as well as a "Large Bonk Reactor" which is an LCR that can use our part ability: + +```java title="BonkMachines.java" +public class BonkMachines { + + public static final MachineDefinition BONK_HATCH = Bonk.REGISTRATE + .machine("bonk_hatch", (holder) -> new BonkHatchPartMachine(holder, ZPM, IO.IN)) + .langValue("Bonk Hatch") + .rotationState(RotationState.ALL) + .tier(ZPM) + .modelProperty(GTMachineModelProperties.IS_FORMED, false) + .colorOverlayTieredHullModel(GTCEu.id("block/overlay/machine/overlay_pipe_in_emissive"), null, + GTCEu.id("block/overlay/machine/" + OVERLAY_ITEM_HATCH)) + .abilities(BonkPartAbilities.BONK_HATCH) + .register(); + + public static final MultiblockMachineDefinition LARGE_BONK_REACTOR = Bonk.REGISTRATE + .multiblock("large_bonk_reactor", WorkableElectricMultiblockMachine::new) + .langValue("Large Bonk Reactor") + .rotationState(RotationState.ALL) + .recipeType(BonkRecipeTypes.LARGE_BONK_RECIPES) + .recipeModifiers(OC_PERFECT_SUBTICK, BATCH_MODE) + .appearanceBlock(CASING_PTFE_INERT) + .pattern(definition -> { + var casing = blocks(CASING_PTFE_INERT.get()).setMinGlobalLimited(10); + var abilities = Predicates.autoAbilities(definition.getRecipeTypes()) + .or(Predicates.autoAbilities(true, false, false)) + .or(Predicates.abilities(BonkPartAbilities.BONK_HATCH)); + return FactoryBlockPattern.start() + .aisle("XXX", "XCX", "XXX") + .aisle("XCX", "CPC", "XCX") + .aisle("XXX", "XSX", "XXX") + .where('S', Predicates.controller(blocks(definition.getBlock()))) + .where('X', casing.or(abilities)) + .where('P', blocks(CASING_POLYTETRAFLUOROETHYLENE_PIPE.get())) + .where('C', Predicates.heatingCoils().setExactLimit(1) + .or(abilities) + .or(casing)) + .build(); + }) + .workableCasingModel(GTCEu.id("block/casings/solid/machine_casing_inert_ptfe"), + GTCEu.id("block/multiblock/large_chemical_reactor")) + .register(); + + public static void init() { + } +} +``` + +## Creating the PartAbility +```java title="BonkPartAbilities.java" +public class BonkPartAbilities { + public static final PartAbility BONK_HATCH = new PartAbility("bonk_hatch"); +} +``` + +## Creating the RecipeType +```java title="BonkRecipeTypes.java" +public class BonkRecipeTypes { + public static final GTRecipeType LARGE_BONK_RECIPES = register("large_bonk_reactor", MULTIBLOCK) + .setMaxIOSize(3, 3, 5, 4) + .setMaxSize(IO.IN, BonkRecipeCapability.CAP, 1) + .setEUIO(IO.IN); + + public static void init() {} + + public static GTRecipeType register(String name, String group, RecipeType... proxyRecipes) { + var recipeType = new GTRecipeType(GTCEu.id(name), group, proxyRecipes); + GTRegistries.register(BuiltInRegistries.RECIPE_TYPE, recipeType.registryName, recipeType); + GTRegistries.register(BuiltInRegistries.RECIPE_SERIALIZER, recipeType.registryName, new GTRecipeSerializer()); + GTRegistries.RECIPE_TYPES.register(recipeType.registryName, recipeType); + return recipeType; + } +} +``` + +## Making a Recipe +```java title="BonkRecipes.java" +public class BonkRecipes { + + public static void init(Consumer provider) { + LARGE_BONK_RECIPES.recipeBuilder( + GTCEu.id("test")) + .inputItems(Items.STONE) + .input(BonkRecipeCapability.CAP, new BonkIngredient(2)) + .outputItems(Items.COBBLESTONE) + .duration(100) + .EUt(GTValues.VA[GTValues.LV]) + .save(provider); + } +} +``` + +## Registering Everything + +```java title="BonkRecipeCapabilities.java" +public class BonkRecipeCapabilities { + + public static final BonkRecipeCapability BONK = BonkRecipeCapability.CAP; + + public static void init() { + GTRegistries.RECIPE_CAPABILITIES.register(BONK.name, BONK); + } +} +``` +The following parts, you would do in your main java class and your main GTAddon class, assuming you are working off of the [Addon Template](https://github.com/JuiceyBeans/GregTech-Addon-Template): +```java title="Bonk.java" +@Mod(Bonk.MOD_ID) +public class Bonk { + // ... + private void registerRecipeTypes(GTCEuAPI.RegisterEvent event) { + BonkRecipeTypes.init(); + } + + private void registerMachines(GTCEuAPI.RegisterEvent event) { + BonkMachines.init(); + } +} +``` + +```java title="BonkGTAddon.java" +@GTAddon +public class BonkGTAddon implements IGTAddon { + // ... + @Override + public void initializeAddon() { + MapIngredientTypeManager.registerMapIngredient(BonkIngredient.class, MapBonkIngredient::convertToMapIngredient); + } + @Override + public void addRecipes(Consumer provider) { + BonkRecipes.init(provider); + } + + @Override + public void registerRecipeCapabilities() { + BonkRecipeCapabilities.init(); + } +} + +``` diff --git a/docs/content/Development/Recipe-Logic/Recipe-Execution.md b/docs/content/Development/Recipe-Logic/Recipe-Execution.md new file mode 100644 index 00000000000..35c1035385b --- /dev/null +++ b/docs/content/Development/Recipe-Logic/Recipe-Execution.md @@ -0,0 +1,218 @@ +--- +title: "Recipe Execution" +--- + +## Recipe Execution +After the recipe is found, we run `RecipeLogic.setupRecipe(recipe)`. +This method runs `machine.beforeWorking(recipe)`. If that fails, it resets and goes back to recipe searching. +If it doesn't, it continues and actually consumes the contents of the recipe using `handleRecipeIO(recipe, IO.IN)`. + +- This calls `RecipeHelper.handleRecipeIO(machine, recipe, io, this.chanceCaches)`, +- Which calls `handleRecipe(holder, recipe, io, io == IO.IN ? recipe.inputs : recipe.outputs, chanceCaches, false, false)`. +- Which calls `RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, simulated); var result = runner.handle(contents)` + +This `runner.handle(contents)` call is where the actual recipe consumption happens. +First, it calls `runner.fillContentMatchList(contents)`, which populates two values: + +- `this.searchRecipeContents`, which contains all the recipe contents including every ingredient that has a chance to be consumed +- `this.recipeContents`, which contains the recipe contents with chances actually evaluated. So if your chance ingredient didn't pass the chance roll, it will not be in here. + +then, it calls `return this.handleContents()`, which will use these two lists to actually check and/or consume the recipe contents. + + +## Needed Concepts +Before we dive in, we need to understand some concepts. +A `RecipeHandler` is the lowest level abstraction of I/O. It's for example the circuit slot in an input bus, it's the energy buffer of an energy hatch, etc. +A `RecipeHandlerList` is an abstraction around multiple RecipeHandlers, for example a dual input bus holds 3 `RecipeHandler`s: + + - One for the circuit slot + - One for the item slots + - One for the fluid slots + +These are packaged in one `RecipeHandlerList`, which is what our `handleContents` method interacts with. When you call `RHL.handleRecipe`, that calls `.handleRecipe` on all their internal `RecipeHandler`s. + +A `RecipeHandlerList` can also have two other properties of interest to us: + + - `boolean isDistinct`, says if the bus is set to distinct or not + - `long color`, says which color the bus is colored in-game + +This dictates what `RecipeHandlerGroup` a `RecipeHandlerList` is put in: + + - If the `RecipeHandlerList` has a `RecipeHandler` whose `RecipeCapability` has `.shouldBypassDistinct()` return true, it gets put in the `BYPASS_DISTINCT` group. These busses (for example Energy Hatches) are global and should interact with every combination, regardless of distinctness, color, etc. + - If the `RecipeHandlerList` is set to distinct, it will get put in the `BUS_DISTINCT` group. + - If the `RecipeHandlerList` is undyed, it gets put in the `UNDYED` group + - Otherwise, the `RecipeHandlerList` gets put in a group specific to its color. + +It's important to note that, during grouping, UNDYED groups get added to every other color group as well. This is because our recipe handling logic works the following way: +1. If it's `BYPASS_DISTINCT`, it should be included in every recipe check +2. If it's `BUS_DISTINCT`, it should only check with itself (and any `BYPASS_DISTINCT`) +3. If it's a color, it will only check with its own color + the `UNDYED` busses + the `BYPASS_DISTINCT` busses. +4. If it's `UNDYED`, it will check with other `UNDYED` busses. + +So UNDYED acts as a wildcard for other dyed groups. + +During recipe handling, the `RecipeHandlerList`s get split up in groups during `RecipeHelper.addToRecipeHandlerMap`. This is also where the `UNDYED` wildcard gets take care of, as that will get added to the other color groups. + +## RecipeRunner.handleContents +This is a very big function, so we will go through it in steps: +```java title="RecipeRunner.java" +private ActionResult handleContents() { + if (recipeContents.isEmpty()) return ActionResult.SUCCESS; + if (!capabilityProxies.containsKey(io)) { + return ActionResult.FAIL_NO_CAPABILITIES; + } + + List handlers = capabilityProxies.getOrDefault(io, Collections.emptyList()); + // Only sort for non-tick outputs + if (!isTick && io.support(IO.OUT)) { + handlers.sort(RecipeHandlerList.COMPARATOR.reversed()); + } + + Map> handlerGroups = new HashMap<>(); + for (var handler : handlers) { + addToRecipeHandlerMap(handler.getGroup(), handler, handlerGroups); + } +``` + +This takes care of fetching the `RecipeHandlerList`s of a machine, and dividing them up into groups +we take care of the grouping `RecipeHandlerList`s by their respective group, and dividing them up. + +```java title="RecipeRunner.java" + // Specifically check distinct handlers first + for (RecipeHandlerList handler : handlerGroups.getOrDefault(BUS_DISTINCT, Collections.emptyList())) { + // Handle the contents of this handler and also all the bypassed handlers + var res = handler.handleRecipe(io, recipe, searchRecipeContents, true); + if (!res.isEmpty()) { + for (RecipeHandlerList bypassHandler : handlerGroups.getOrDefault(BYPASS_DISTINCT, + Collections.emptyList())) { + res = bypassHandler.handleRecipe(io, recipe, res, true); + if (res.isEmpty()) break; + } + } + if (res.isEmpty()) { + if (!simulated) { + // Actually consume the contents of this handler and also all the bypassed handlers + recipeContents = handler.handleRecipe(io, recipe, recipeContents, false); + if (!recipeContents.isEmpty()) { + for (RecipeHandlerList bypassHandler : handlerGroups.getOrDefault(BYPASS_DISTINCT, + Collections.emptyList())) { + recipeContents = bypassHandler.handleRecipe(io, recipe, recipeContents, false); + if (recipeContents.isEmpty()) break; + } + } + } + recipeContents.clear(); + return ActionResult.SUCCESS; + } + } +``` +This is the first block of logic that actually checks and consumes. +Do note the last argument of `handleRecipe` is the `simulate` argument. `true` doesn't actually consume the items, `false` does consume the items. +So we start off by looping through each `BUS_DISTINCT` `RecipeHandlerList`, and making it check the recipe. +Then, if the list of remaining items is not empty yet, we check the `RecipeHandlerList`s that are in the `BYPASS_DISTINCT` group. +If it is empty, then the simulation is a success. If `simulated` is false, we can run the code again, this time actually consuming the recipe contents. +If it's not empty, we continue to the next distinct bus. + +```java title="RecipeRunner.java" + // Check the other groups. + for (Map.Entry> handlerListEntry : handlerGroups.entrySet()) { + if (handlerListEntry.getKey().equals(BUS_DISTINCT)) continue; + + // List to keep track of the remaining items for this RecipeHandlerGroup + Map, List> copiedRecipeContents = searchRecipeContent; + boolean found = false; + + for (RecipeHandlerList handler : handlerListEntry.getValue()) { + copiedRecipeContents = handler.handleRecipe(io, recipe, copiedRecipeContents, true); + if (copiedRecipeContents.isEmpty()) { + found = true; + break; + } + } + // If we're already in the bypass_distinct group, don't check it twice. + if (!handlerListEntry.getKey().equals(BYPASS_DISTINCT)) { + for (RecipeHandlerList bypassHandler : handlerGroups.getOrDefault(BYPASS_DISTINCT, + Collections.emptyList())) { + copiedRecipeContents = bypassHandler.handleRecipe(io, recipe, copiedRecipeContents, true); + if (copiedRecipeContents.isEmpty()) { + found = true; + break; + } + } + } + + if (!found) continue; + if (simulated) return ActionResult.SUCCESS; + // Start actually removing items. + // Keep track of the remaining items for this RecipeHandlerGroup + // First go through the handlers of the group + for (RecipeHandlerList handler : handlerListEntry.getValue()) { + recipeContents = handler.handleRecipe(io, recipe, recipeContents, false); + if (recipeContents.isEmpty()) { + return ActionResult.SUCCESS; + } + } + // Then go through the handlers that bypass the distinctness system and empty those + // If we're already in the bypass_distinct group, don't check it twice. + if (!handlerListEntry.getKey().equals(BYPASS_DISTINCT)) { + for (RecipeHandlerList bypassHandler : handlerGroups.getOrDefault(BYPASS_DISTINCT, + Collections.emptyList())) { + recipeContents = bypassHandler.handleRecipe(io, recipe, recipeContents, false); + if (recipeContents.isEmpty()) { + return ActionResult.SUCCESS; + } + } + } + } + + for (var entry : recipeContents.entrySet()) { + if (entry.getValue() != null && !entry.getValue().isEmpty()) { + return ActionResult.fail(null, entry.getKey(), io); + } + } + + return ActionResult.FAIL_NO_REASON; +} +``` + +This is the same loop of logic as we had before, but a little more complicated. +Instead of checking each `RecipeHandlerList` individually like we did for `BUS_DISTINCT`, we check all the busses in each group at once. +There's also the caveat of `BYPASS_DISTINCT` having to be checked with every group, but not with itself, so there's additional logic in place for that. +The rest is relatively the same. + +This is how the logic for RecipeHelper.handleRecipeIO works. The same can be said for tick ingredients, except the tick inputs are passed in, as well as the sorting step in the start. The rest remains the same. + +## The rest of RecipeLogic +To recap, this is what happens during `RecipeLogic.setupRecipe(recipe)` after the recipe is found. +Then, if that returns a success, a bunch of RecipeLogic related variables are set, like: +```java title="RecipeLogic.java" + var handledIO = handleRecipeIO(recipe, IO.IN); + if (handledIO.isSuccess()) { + recipeDirty = false; + lastRecipe = recipe; + setStatus(Status.WORKING); + progress = 0; + duration = recipe.duration; + isActive = true; + } +``` +This is all that happens in this tick (see [RecipeLogic.serverTick](./Recipe-Logic.md)). +Then, on the next tick, we call `recipeLogic.handleRecipeWorking()`, which calls the following: +```java title="RecipeLogic.java" +public ActionResult handleTickRecipe(GTRecipe recipe) { + if (!recipe.hasTick()) return ActionResult.SUCCESS; + + var result = RecipeHelper.matchTickRecipe(machine, recipe); + if (!result.isSuccess()) return result; + + result = handleTickRecipeIO(recipe, IO.IN); + if (!result.isSuccess()) return result; + + result = handleTickRecipeIO(recipe, IO.OUT); + return result; +} +``` +Where `handleTickRecipeIO` calls `handleRecipe` with the `recipe.tickInputs` / `recipe.tickOutputs` and `tick=true`. + +Then, if the `recipeLogic.progress >= recipeLogic.duration`, it calls `onRecipeFinish()` +This calls `machine.afterWorking()` and `handleRecipeIO(lastRecipe, IO.OUT)`, which outputs the recipe's output into the output busses. diff --git a/docs/content/Development/Recipe-Logic/Recipe-Logic.md b/docs/content/Development/Recipe-Logic/Recipe-Logic.md new file mode 100644 index 00000000000..43dc6973745 --- /dev/null +++ b/docs/content/Development/Recipe-Logic/Recipe-Logic.md @@ -0,0 +1,25 @@ +--- +title: "Recipe Logic" +--- + +Any `WorkableMachine` has a `RecipeLogic` as a trait. These machines have a `TickableSubscription` that calls `recipeLogic.serverTick`. +A (slightly simplified) version of `recipeLogic.serverTick` can be seen below: +```java title="RecipeLogic.java" +public void serverTick() { + if (!isSuspend()) { + if (!isIdle() && lastRecipe != null) { + if (progress < duration) { + handleRecipeWorking(); + } + if (progress >= duration) { + onRecipeFinish(); + } + } else { + findAndHandleRecipe(); + } // Code for re-doing previous recipe + } + // Logic for unsubscribing if needed +} +``` + +We will dissect this method in [Recipe Searching](./Recipe-Searching.md) and [Recipe Execution](./Recipe-Execution.md). \ No newline at end of file diff --git a/docs/content/Development/Recipe-Logic/Recipe-Searching.md b/docs/content/Development/Recipe-Logic/Recipe-Searching.md new file mode 100644 index 00000000000..fcb1d1eba3c --- /dev/null +++ b/docs/content/Development/Recipe-Logic/Recipe-Searching.md @@ -0,0 +1,195 @@ +--- +title: "Recipe Searching" +--- + +# Recipe Searching +!!! Note + This is not an in-depth exploration of Recipe Searching, but rather a general overview. + A lot of code will be referenced, redacted and simplified. + +For recipe searching happens in 3 phases. + +1. Creation of the recipe +2. Recipe Lookup +3. Recipe Matching + +This document will go through them step by step + +## Recipe creation +To create a recipe, one must first create a `RecipeType`. A `RecipeType` contains metadata about the recipe, but more importantly for this, a `RecipeLookup`. This is where the recipes are stored. + +This lookup is effectively a Trie. It holds a Branch, and every branch has a `Map>`. +When you add the recipe to the lookup, you effectively add the ingredients one by one until you arrive at the recipe. + +So a simplified assembler(8) trie could be +``` + Map { "8 cobblestone" -> Left(FurnaceRecipe), + "4 iron rods" -> Right(Map { + "4 iron plates" -> Left(Iron Machine Hull) + }) + } +``` +## Recipe Lookup +During the `RecipeLogic.serverTick` method (see [Recipe Logic](./Recipe-Logic.md)), a method called `findAndHandleRecipe` is called. +This checks if the `lastRecipe` is set, and if it can be matched, runs it again. +If it can't be matched, it calls `handleSearchingRecipes(searchRecipe())` + +`searchRecipe()` is the actual recipe searching logic. In big lines, it finds what ingredients are currently available in the machine, groups those, and traverses the `RecipeLookup` to create an iterator of recipes that are available. +`handleSearchingRecipes()` then goes through that iterator, and for every recipe it runs the recipe modifier, checks if this machine can run it, if the inputs are there, if it has enough output space etc. + +The actual code for searchRecipe is: +```java + return machine.getRecipeType().searchRecipe(machine, r -> matchRecipe(r).isSuccess()) +``` +`RecipeType.searchRecipe(...)` effectively calls `getLookup().getRecipeIterator(holder, canHandle)`. +This canHandle function will be further explored in the Recipe Matching stage. + +This function first generates a list of ingredients from the machine via `.fromHolder`, which calls `holder.getCapabilitiesFlat(IO.IN)`. It then takes the list of `IRecipeHandlers`, calls `.getContents` on each, and converts all those contents to Ingredients. +After that, it passes the list of ingredients to a new RecipeIterator, which is a wrapper around `recurseIngredientTreeFindRecipe(ingredients, recipeMap.getLookup().getLookup(), canHandle, +/***/)`. + +With this, we have arrived at the function that actually does the searching of the recipe. +Before we can dive into the actual function, we need to understand how Ingredients work. + +## From Machine to Ingredient +A trait is a type of object that gets stored on the machine on creation, e.g. +```java + public MachineTrait(MetaMachine machine) { + // ... + machine.attachTraits(this); + } +``` +A machine can have many different traits. One of these is `IRecipeHandler`. This trait is used when collecting the inputs/outputs for `RecipeLogic`. +`IRecipeHandler`s are abstractions around for example the item slots and circuit slot of an input bus, or the energy buffer of a singleblock. + +An example of one of these would be an `new NotifiableItemStackHandler(machine, slots, IO)`. On creation, it attaches itself to the machine, so you don't have to link it to the `RecipeLogic` in any way. The WorkableMachine takes care of that. + +This NotifiableHandler has a few important methods: + + - a `List getContents()` method, which is where the ingredient list is retrieved for recipe search + - a `List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate)` method, which is where the I/O magic of the handler happens + - `IO io`: whether the recipe is trying to input or output into the world (e.g. IO.IN takes stuff from the handler, IO.OUT puts stuff in the handler) + - `GTRecipe recipe`: the recipe that's being run + - `List left`: the remaining items to put into / take out of the handler + - `boolean simulate`: whether this is a simulate run (for e.g. recipe checking) or to actually modify the contents of the handler + - returns `List` a list of remaining ingredients, aka what could not be inserted / extracted. Note that if no contents are left, `null` should be returned. + +In this case it's an `NotifiableRecipeHandlerTrait` (where `Ingredient` is a wrapper around `ItemStack` to help account for ranged inputs/outputs), but a recipe handler can take anything. + +To actually store this `Ingredient`, we need something that can be handled properly by our RecipeLookup. To do this, we wrap the `Ingredient` in another object, called an `ItemStackMapIngredient`. +This class extends AbstractMapIngredient, which most importantly has a correct `.hash()` and `.equals()` function. +These are used by our GTRecipeLookup to find the correct ingredients inside our Trie. + +!!! Note + while two objects that should match should also have return true on .equals check and have the same hash code, `.equals` does NOT have to be a correct `.equals` implementation, for example for matching of partial NBT: + (the following code is psuedocode) + ``` + PartialNBTItemStackMapIngredient(Iron, {foo: bar, bar: baz}).equals(PartialNBTItemStackMapIngredient(Iron, {foo: bar}) = True" + ``` + +!!! Note + It's important to note that even if two functions match with `.equals`, if they don't also have the same hash they won't be matched in our recipe search. + +## GTRecipeLookup.recurseIngredientTreeFindRecipe +```java + /** + * Recursively finds a recipe + * + * @param ingredients the ingredients part + * @param branchMap the current branch of the tree + * @param canHandle predicate to test found recipe. + * @param index the index of the wrapper to get + * @param count how deep we are in recursion, < ingredients.length + * @param skip bitmap of ingredients to skip, i.e. which ingredients are already used in the recursion. + * @return a recipe + */ + @Nullable + public GTRecipe recurseIngredientTreeFindRecipe(@NotNull List> ingredients, + @NotNull Branch branchMap, @NotNull Predicate canHandle, + int index, int count, BitSet skip) { + // exhausted all the ingredients, and didn't find anything + if (count == ingredients.size()) return null; + + // Iterate over current level of nodes. + for (AbstractMapIngredient obj : ingredients.get(index)) { + // determine the root nodes + Map> targetMap = determineRootNodes(obj, branchMap); + + Either result = targetMap.get(obj); + if (result != null) { + // if there is a recipe (left mapping), return it immediately as found, if it can be handled + // Otherwise, recurse and go to the next branch. + GTRecipe r = result.map(potentialRecipe -> canHandle.test(potentialRecipe) ? potentialRecipe : null, + potentialBranch -> diveIngredientTreeFindRecipe(ingredients, potentialBranch, canHandle, index, + count, skip)); + if (r != null) { + return r; + } + } + } + return null; + } +``` + +When our GTRecipeLookup scans the machine for inputs (via the handlers' `.getContents()` methods), it then converts these to MapIngredients. +This is the `List>` input. The reason it's a double list is that one `Content` can be turned into multiple `Ingredient`s. e.g. one written book can become: a `ItemStackMapIngredient`, an `ItemTagMapIngredient`, a `PartialNBTItemStackMapIngredient`, a `StrictNBTItemStackMapIngredient`, and potentially others based on addons / registration. +So for every content from `.getContents()`, a `List` gets made. See this excerpt from the `.fromHolder` method: +```java +var compressed = cap.compressIngredients(handler.getContents()); +for (var ingredient : compressed) { + list.add(MapIngredientTypeManager.getFrom(ingredient, cap)); +} +``` + +This list is then iterated, in our for loop in the method above. For every `AbstractMapIngredient`, `branchMap.getNodes()` is called in `determineRootNodes`. + +Then, in this map, we call `map.get(obj)`. Since this is implemented as a `HashMap`, this is where our `AbstractMapIngredient`'s methods come in. According to the `.hash` and `.equals` methods, this matches the ingredients for that layer of the Trie. +When this get call is made, it can return `null` (if that ingredient isn't in the map), or it can return an `Either`. +In the case it is a recipe, we check if it works with our current machine (see canHandle later), and if so we return this recipe. +In the case it is a branch, we recurse down into the next layer of our recipe search. + +## Recipe Matching +In this entire call stack, a canHandle predicate is passed down. This predicate, being `r -> matchRecipe(r).isSuccess()` as you might recall from earlier, is a way to check if the machine can handle the current recipe. +After a few layers of indirection, we arrive at `RecipeHelper.matchRecipe` +```java + private static ActionResult matchRecipe(IRecipeCapabilityHolder holder, GTRecipe recipe, boolean tick) { + if (!holder.hasCapabilityProxies()) return ActionResult.FAIL_NO_CAPABILITIES; + + var result = handleRecipe(holder, recipe, IO.IN, tick ? recipe.tickInputs : recipe.inputs, + Collections.emptyMap(), tick, true); + if (!result.isSuccess()) return result; + + result = handleRecipe(holder, recipe, IO.OUT, tick ? recipe.tickOutputs : recipe.outputs, + Collections.emptyMap(), tick, true); + return result; + } +``` +As you can see, this calls handleRecipe for both the normal and tick inputs, with `simulate = true`. Do note that at this stage, RecipeModifiers have not been applied yet. + +With the info on how the `Iterator` is created by `searchRecipes()` above, we can now dive into `handleSearchingRecipes(Iterator)`. +This method loops through the iterator, and calls `checkMatchedRecipeAvailable` on it. + +```java + public boolean checkMatchedRecipeAvailable(GTRecipe match) { + var modified = machine.fullModifyRecipe(match); + if (modified != null) { + var recipeMatch = checkRecipe(modified); + if (recipeMatch.isSuccess()) { + setupRecipe(modified); + } + if (lastRecipe != null && getStatus() == Status.WORKING) { + lastOriginRecipe = match; + lastFailedMatches = null; + return true; + } + } + return false; +} +``` + +This is where Recipe Modifiers are applied. If any of the RecipeModifiers return null, this recipe is ignored and we will continue on the next recipe in the iterator. +If it isn't null, we validate that the inputs are again available (via an indirection to `RecipeHelper.matchRecipe` as seen above). +If it is, we call `.setupRecipe(...)`. This setupRecipe call will call `machine.beforeWorking()` and (try to) consume the input items. +If after this, the recipe is running, we return true and have found a recipe. Our recipe search is over. + + diff --git a/docs/content/Gameplay/Electricity/Cables-and-Transformers.md b/docs/content/Gameplay/Electricity/Cables-and-Transformers.md new file mode 100644 index 00000000000..a7111278c6f --- /dev/null +++ b/docs/content/Gameplay/Electricity/Cables-and-Transformers.md @@ -0,0 +1,112 @@ +# Cables and Transformers +EU needs to move from generators to storage to machines. EU travels through Wires and Cables. + +Every wire or cable has several properties: + +* Toggled connections. A cable is placed in world as a block and can be connected separately in all six directions. Cables +are not directional in how they allow power to flow. Cable connections can be added or removed using Wire Cutters, and +Wire Cutters are also the tool used to break and retrieve cable blocks. +* Maximum Voltage. Every cable has a maximum voltage of energy it can carry. Sending EU of too high a voltage down a +cable will cause the cable to catch fire and be destroyed. + * If a cable attempts to carry an amp of too high a voltage, the cable will *reduce the carried voltage to its own + safe limit* before being destroyed. This means that, if a high-voltage generator is inadvertently connected to a low- + voltage cable, the cable will act as a sacrificial fuse and be destroyed, but the lower-voltage machines further down + the line will be protected and not explode. As such, it is generally much less safe to directly power machines using + cables that carry a higher voltage tier than the machine. +* Maximum Amperage. Similar to Voltage, every cable has a maximum Amperage it can safely carry. However, sending too many +Amps down a cable will not cause an instant failure. Instead, over-amping a cable will cause it to very briefly heat up. +If the cable heats up too much, its Insulation layer will burn off, and if it continues heating, it will eventually +catch fire and be destroyed. + * Wires can be combined into 2x, 4x, 8x, or 16x Wires. Combined wires combine their maximum amperage, allowing more + Amps to be carried through a single block space. + * To ensure amperage safety, it is generally recommended to never run cables that can carry fewer Amps than the + [Generators](./Generators.md) or [Battery Buffers](./Energy-Storage.md#battery-buffers) connected to them them can supply. + (1A per singleblock generator, [Dynamo Hatch] Amps per Multiblock generator, [Battery slots] amps per Battery Buffer.) + This is important to note as machines will often *accept* more than 1 Amp of power, and thus it's generally simpler to + control for energy supply than energy demand. +* Voltage Loss per Block. Power transfer is not free. For every cable block that an Amp of electricity travels down, one +or more Volts are lost from it. This effect is much more pronounced at low voltages or when using inferior cable materials, +and especially when using uninsulated wires. For an example of this, see [below](./Cables-and-Transformers.md#an-example-of-voltage-loss-and-transformer-usage). + * Voltage Loss can be compensated for by using [Battery Buffers](./Energy-Storage.md), Diodes, or Transformers. + While these do not eliminate voltage loss, they can mitigate its effects on machines. +* Insulation. Wires should never be used without first being covered in insulation and converted to Cables. Cables have +significantly reduced Voltage Drop than uninsulated wires. Furthermore, touching an uninsulated wire that has carried +energy during the last tick will inflict a significant amount of damage, easily lethal at high voltages. + * Higher-thickness cables are made by applying insulation to higher-thickness wires. + * Cable insulation is made out of Rubber. LV cables can be insulated by crafting them together with Rubber Sheets, + however higher tier cables require an Assembler and Liquid Rubber. + * Liquid Rubber can eventually be replaced with Silicone Rubber or Styrene-Butadiene Rubber (and high tier + components require this). + * EV cables and above also require Thin Polyvinyl Chloride Sheets, and higher tier cables require further sheets. + * Certain wires are marked as Superconductors. These wires do not require insulation, are safe to touch, and have + 0 voltage drop per block. However, they are all made out of alloys that are much more complex than the simple wires + and cables that are generally used for power transmission. + * Insulation can be removed from wires using the Packer. This can be used to retire older cables and reclaim the + wires used. + +## Diodes +Diodes are blocks used to help manage power transmission. + +* Energy can enter a Diode from any of five sides, but can only exit the Diode from its output side. +* Diodes limit the energy flowing through them. By default, a Diode will emit 1 Amp of its voltage, but right-clicking +with a Soft Mallet will cycle its output through 2, 4, 8, and 16 Amps. Diodes will accept Amps equal to their output. +* Diodes do not store large amounts of power. They have the same 64-tick buffer as any other machines of their tier. +* Diodes can be placed in the walls of **Cleanrooms**. This is the means by which EU can be sent into a Cleanroom to power +the machines inside. + +Diodes are much cheaper than Battery Buffers, and while they do not act as bulk energy storage, they can be used to merge +several small cables into one large cable, or to tap small cables off of a large cable, and ensure that the resulting +cables are never sent more Amps than they can carry. Also, because they are blocks which absorb and emit power rather than +simply transmitting it, every Amp that is emitted by a Diode *will* be on-Voltage, thus allowing Diodes to compensate for +voltage loss, by (as necessary) merging together multiple reduced-voltage amps into a few full-voltage amps. + +## Transformers +Transformers allow for shifting voltages up and down. A Transformer can convert 1 Amp of a voltage one tier above its own +into 4 Amps of its own voltage tier, or vice-versa. (For example, an LV Transformer will accept 1A MV and emit 4A LV, or +accept 4A LV to emit 1A MV.) A Soft Mallet will switch the Transformer's mode from Down to Up. + +Transformers come in three further variants: 2x High-Amp (converting 2A into 8A), 4x High-Amp (converting 4A into 16A), +and Power Transformer (converting 16A into 64A). + +Transformers are useful for powering a large array of low-voltage machines using a small number of high-voltage generators. +As generators are quite expensive to build, powering many parallel machines with only a few generators can save significantly +on resources and space. + +Transformers are also useful to help mitigate Voltage Loss from cables. Higher voltage cables do not always have lower +voltage loss per block, however voltage loss per block per Amp is *subtractive*, not *multiplicative*. As such, transmitting +a small number of high-voltage Amps a long distance results in far less energy loss than transporting a large number of +low voltage Amps that distance. (And furthermore, carrying more Amps requires thicker and more expensive Cables.) + +### An Example of Voltage Loss and Transformer Usage +For an example of this last point, take following simple case: 16A LV, traveling 20 blocks down a 16x Tin Cable. +A 16x Tin Cable can carry 16 Amps at LV, and suffers 1V loss per block per amp. By the end of the 20 block travel, the +32V x 16A that entered the cable has been reduced to 12V x 16A, losing 68.75% of its power and greatly reducing its +ability to reliably power machines (as at that point any machine that requires more than 12EU/t to run will *need* to +consume an entire second Amp), likely limiting the cable to powering only 8 machines. + +For contrast, take if that 16A LV was first Transformed up to MV and sent down the same 20 blocks of 4x Annealed Copper Cable. +A 4x Annealed Copper Cable can carry 4A at MV, and suffers 1V loss per block per amp. By the end of the 20 block travel, +the 128V x 4A that entered the cable has been reduced to 108V x 4A, losing only 15.6% of its power, and the resulting +4x Hi-Amp LV Transformer on the destination end is able to emit that as 13.5A LV (Amps must be whole numbers so it will +alternate between 13A and 14A), and thus easily power at least 13 machines running at full speed. + +## Active Transformers +The Active Transformer is an LuV-tier multiblock machine. An Active Transformer can accept up to **13** Energy, Dynamo, +or Laser Hatches, of any voltage tiers, and it will transform all of its input feeds to power all of its output feeds. + +Active Transformers are commonly paired with [Power Substations](./Energy-Storage.md#power-substation) to take the +Substation's very high output amperages, and appropriately deliver them to machine arrays. + +### Laser Hatches and Laser Pipes +Power Substations and Active Transformers can use Laser Source Hatches and Laser Target Hatches as an extremely high-Amp +alternative to traditional power delivery. Laser Hatches become available starting at IV, and can emit or receive from +256A to 4096A power. + +Laser Pipes carry energy from Source Hatches to Target Hatches. They are quite cheap for their power but have several +important characteristics: + +* Laser Pipes have no Max Voltage, Max Amperage, Voltage Loss, or Insulation. They carry energy at whatever Voltage and +Amperage they are fed from their Source hatch. +* Laser Pipes must be connected in a **straight line**. Laser Pipes are not allowed to have any bends in them, or they +will not transfer power. + * As a consequence of this, Laser Pipes can only act as 1-to-1 connections between a single Source and Target Hatch. \ No newline at end of file diff --git a/docs/content/Gameplay/Electricity/Energy-Storage.md b/docs/content/Gameplay/Electricity/Energy-Storage.md new file mode 100644 index 00000000000..7e6db922d25 --- /dev/null +++ b/docs/content/Gameplay/Electricity/Energy-Storage.md @@ -0,0 +1,64 @@ +# Electric Energy Storage +[Generators](./Generators.md) are expensive machines. While it is possible to build a generator to power every machine, +it's much less expensive to build a small number of generators, and a means to store the generated EU, allowing a small +number of generators to power a large array of machines. This becomes especially applicable in EV and beyond, where +singleblock generators are no longer available. + +GregTech Modern contains three primary forms of energy storage: Batteries, Battery Buffers, and the Power Substation. + +## Batteries +Available at the beginnings of LV and present at all energy tiers, a Battery is an item which stores EU. Batteries are +generally made in the Canner, out of a Battery Hull and some amount of acceptable Dust (initially Lithium, Cadmium, or +Sodium). Higher-tier batteries (HV and beyond) also include the Energy Crystal, Lapotron Crystal, and the various +Lapotron Orb derivatives. These Crystal batteries are made using Autoclaves and Assemblers, and are more expensive than +traditional batteries, but have much higher power capacities. + +Batteries can be used in four ways: + +* Batteries can be placed in singleblock [Electric Machines](./Machines.md#singleblock-machines). All singleblock machines +have a dedicated Battery slot, marked with a lightning bolt. A Battery placed in this slot will: + * Charge from the machine's energy buffer, if the machine's buffer is above 2/3s full + * Discharge to feed the machine's buffer, if the buffer is below 1/3 full +* Batteries carried in a player's inventory will use their held charge to recharge electric tools or Armor that the player +is holding or wearing, at a rate of 1 Amp per tick. This behavior can be (de)activated by shift-right-clicking while +holding the battery. +* Batteries can be placed in Turbochargers to rapidly recharge them. A Turbocharger will accept up to 4 Amps of power +per electric item contained (Batteries, Tools, Armor), and distribute that power among their contained batteries. +* Batteries can be placed in Battery Buffers, which will be discussed next. + +## Battery Buffers +A Battery Buffer is a block that contains 1, 4, 8, or 16 inventory slots. Each of those inventory slots can hold one +battery. Battery Buffers will accept 2 Amps of power per contained electric item, and will **output** 1 Amp of power per +contained battery. Battery Buffers will charge and discharge all contained batteries evenly, and are the primary means of +bulk energy storage and power supply stabilization from LV through mid EV. + +In early EV, Battery Buffers also have an important further usage. A Battery Buffer can have an Energy Detector or +Advanced Energy Detector Cover attached, to read the total energy contained within their held batteries. This readout +is emitted as a Redstone Signal, which can be fed to a Machine Controller cover placed on a [Large Steam, Gas, or Plasma +Turbine](./Generators.md#large-turbines). This setup can then be used to automatically turn the Turbine On when the +batteries run low, and Off when the batteries fill, greatly saving fuel and ensuring that full power is available at all +times, regardless of if the Turbines are spun up or not. + +## Power Substation +The Power Substation is GregTech Modern's strongest answer to energy storage, centralization, and distribution. The PSS +is a Multiblock structure, available midway through EV, and constructed out of Palladium, Laminated Glass, and Capacitor +Blocks. The total energy storage of a Power Substation is based on the set of Capacitor Blocks used to build it. + +Power Substations have several significant features to them: + +* Extremely high energy storage capacity. The initial EV PSS holds up to 2.7 billion EU, roughly 18 Amp-Hours of energy. +* High input and output capacity at arbitrary Voltages. The PSS does not have a Voltage Tier, and can have multiple +Energy Hatches and Dynamo Hatches placed in it, of any tier. + * 64 Amp Hatches. The PSS has a unique set of Energy and Dynamo Hatches capable of accepting or emitting 64 Amps of + power, from EV through MAX Voltage. +* Laser Hatches. Power Substations can utilize Laser Source Hatches and Laser Target Hatches, to transfer colossal Amperages +between Substations or Active Transformers +* Very slight power decay. Power Substations lose approximately 1% of their stored energy per 24 hours. At the power scale +that the PSS exists at, this is a relatively insignificant drain, but it does mean that you can't fully ignore power +generation. + +The extremely high amperages allowed by the Power Substation pair well with the high outputs and large size of [Multiblock +Generators](./Generators.md#multiblock-generators), and encourage fully centralized power production and distribution. +Designing a base to take advantage of this also acts as a strong encouragement to utilize [Transformers](./Cables-and-Transformers.md#transformers) +to transmit very high voltage energy over long distances using thin cables, before downtransforming it at machinery lines +for use. diff --git a/docs/content/Gameplay/Electricity/Generators.md b/docs/content/Gameplay/Electricity/Generators.md new file mode 100644 index 00000000000..b0402adee5c --- /dev/null +++ b/docs/content/Gameplay/Electricity/Generators.md @@ -0,0 +1,114 @@ +# Generators +Generators are machines which consume Fuel to produce EU every tick. There are several different types of Generators, +which each consume different fuels. + +## Singleblock Generators +From LV to HV, EU is produced using singleblock generators, machines like the Basic Steam Turbine or Advanced Combustion +Generator. All singleblock generators: + +* Consume Fuel. In base GregTech Modern, all electric generators consume either liquids or gasses as fuels, but no items. +EMI can display a list of all valid fuels a generator can consume. This fuel display lists: + * An amount consumed per burn cycle. For most fuels, this is 1mb, however for certain low-efficiency fuels like Steam + it can be much higher. + * A burn time. + * The generation rate. Any generator which consumes this fuel must be of a power tier at or above this rate. + * The total EU produced by one cycle. This is equal to the burn time x the generation rate. +* Produce EU every tick. All singleblock generators produce and output EU equal to 1A @ their tier voltage. +* Output EU every tick. All generators have one output side, marked with a colored dot, which provides 1A @ tier voltage +to either a Cable or an adjacent Machine. + * Generators do not output "partial" amps or partial voltage. Generators will always output power in exact packets + of 1A @ tier voltage. +* Cannot be placed inside **Cleanrooms**. Placing a Generator inside a Cleanroom will block the Cleanroom controller from +activating. + * To transfer power into a Cleanroom, use a [Diode](./Cables-and-Transformers.md#diodes). + +Singleblock generators come in several variants, each accepting different fuels. + +* Steam Turbines produce EU from large volumes of Steam. The EMI display for Steam Turbines shows that they also +output Distilled Water; this is a feature of the multiblock Large Steam Turbine (discussed below) but not the basic +singleblock turbines +* Gas Turbines produce EU from combustible gasses such as Methane and Benzene. +* Combustion Engines produce EU from liquid Oils, Diesels, Gasolines, and Biofuels. Combustion Engines benefit very +heavily from refining fuel before burning it. + +Singleblock generators are simple to operate, but are relatively expensive, often more expensive than the machines they +give power to. While it is possible to directly feed machines with generators, it is often preferable to build a small +number of generators along with some form of [Energy Storage](./Energy-Storage.md) to power a large number of machines, +given that most of those machines will not consume a full amp of power, or will not be running simultaneously. + +MV and HV generators consume additional fuel to produce power at higher voltages. They do not do this by altering fuel +burn time; they do this by consuming multiple cycles of fuel simultaneously (which is sometimes displayed as "running [X] +recipes in parallel"), multiplying both their EU/t and fuel consumption rate. + +## Multiblock Generators +At EV and beyond, energy generation shifts to multiblock machines. The size of these machines strongly encourages +centralizing power production, storage, and distribution; however because these generators are largely made of Casings, +they are substantially cheaper than the large number of singleblock generators needed to match their output. + +All Multiblock Generators: + +* Consume fuel. Lots of fuel. This fuel is provided to them using Input Hatches, as with other multiblock machines. +* Generate and output EU. Unlike with singleblock generators, this EU is outputted from a **Dynamo Hatch** placed on +one side of the generator. The Dynamo Hatch used determines the maximum output of the generator. Dynamo Hatches come in +several variants, with different Voltage *and Amperage* output values, allowing a single multiblock generator to produce +multiple Amps of power at their voltage. This helps compensate for their large size. + * A Dynamo Hatch determines the Voltage and the Maximum Amperage output by the generator. This is **not** the same as + the amount of EU the generator produces per tick. While using an undersized Dynamo Hatch will limit the maximum + output of the generator, using an oversized Dynamo Hatch will result in a generator which awakens from idle and + emits a much higher amperage than its on-paper sustained power generation for a few seconds, until the Dynamo's internal + energy buffer drains. +* Have efficiency boosts. Depending on their configuration, multiblock generators can produce significantly more EU per +mB of fuel than singleblock generators. This further compensates for their size, allowing larger and more powerful +machinery to be operated using a smaller fuel source. +* Require open air in front of them (either in front of their Air Intakes or their Rotor Holder) +* Allow Wallsharing to save on casings between multiple turbines. + +There are two primary types of Multiblock Generators: the Large Combustion Engine, and Large Turbines. + +### Large Combustion Engines +The Large Combustion Engine (EV) and Extreme Combustion Engine (IV) are the simpler of the large generator types. They +consume Combustion Engine fuels to produce EU. They also passively consume Lubricant to operate. + +The output and energy efficiency of an LCE/ECE can be significantly increased by feeding the generator with Oxygen (LCE) +or Liquid Oxygen (ECE). This boost doubles the fuel consumption of the generator, but triples (LCE) or quadruples (ECE) +the energy production. + +If the Dynamo Hatch of an LCE/ECE fills with EU, the engine will pause and stop consuming fuel. + +Large Combustion Engines are expensive structures to build but are fairly low-maintenance once operational; and higher +tier combustion fuels such as Gasoline are quite energy dense. + +### Large Turbines +The Large Steam, Gas, and Plasma turbine are more complex generators which accept a wider range of fuels. + +* Large Steam Turbines consume extremely large volumes of Steam to produce EU. LSTs also output Distilled Water, allowing +for setups that loop back their own feed water or providing free distilled water to use elsewhere. +* Large Gas Turbines consume large volumes of Gas Turbine fuels such as Benzene to produce EU. +* Large Plasma Turbines consume small volumes of Plasma, produced by Fusion Reactors, to produce large amounts of EU. +LPTs also output the liquid or gas form of the plasma that was consumed as fuel. + +Large Turbines are significantly cheaper to construct than Large Combustion Engines. However, they require an additional +component: A **Rotor**. The Rotor is an expensive item with a finite durability (measured in seconds), that determines +the fuel consumption, energy production, and efficiency of the Turbine. Rotors are placed in Rotor Holders, and Rotor +Holders cannot be opened while the Turbine is active. (Trying will hurt.) Higher tier Rotor Holders increase the power +output of the Turbine (doubling the power output and fuel consumption per Rotor Holder tier) but also increase the +fuel efficiency of the turbine (reducing fuel consumption by 10% per tier above the Turbine's minimum requirement). +Unlike with smaller generators, this reduced fuel consumption is applied as *increased fuel burn duration*. + +Additionally, Large Turbines require several minutes to spin up to their full output, and then spin down when inactive. +Energy production scales exponentially with turbine RPM, meaning that for much of the spinup time the turbine's output +will be quite low. When active, RPM increases by 1 per tick, and when inactive RPM decreases by 3 per tick. To manage +this behavior, Large Turbines are best run either continuously, or in limited bursts to fill an energy storage, +activated via Machine Controller Cover when the storage is low and deactivated when the storage is nearly full. + +Large Turbine behavior was changed slightly in 7.3.0. Prior to this version, if a Large Turbine's Dynamo Hatch filled with +EU, the Turbine would stop consuming fuel and spin down. As of 7.3.0, Large Turbines ignore the contents of their Dynamo +and Output Hatches, and continue running at full speed, even if the produced EU or Fluids have nowhere to go. While this +does result in the excess outputs being voided, it means the Turbines retain their full speed and output. + +The total EU/t output and fuel consumption of a Large Turbine is determined by: + +* EU/t Output = [Turbine base EU/t] x [2 ^ Rotor Holder Tier - minimum tier] x [Turbine Power Mutiplier] x [Current RPM / Max RPM]^2 +* Fuel Consumption = [EU/t output] / [Fuel base generation rate] (rounded up) +* Fuel Duration = [1 + 0.1 x [Rotor Holder Tier - minimum tier]] x [Rotor Efficiency Multiplier] + diff --git a/docs/content/Gameplay/Electricity/Machines.md b/docs/content/Gameplay/Electricity/Machines.md new file mode 100644 index 00000000000..644e1a0ed14 --- /dev/null +++ b/docs/content/Gameplay/Electricity/Machines.md @@ -0,0 +1,132 @@ +# Electric Machines +The vast majority of functional machines in GregTech Modern are powered by EU. And as with Generators, there are a +number of shared rules and patterns between them. + +## Singleblock Machines +Available at all electrical tiers from LV to UV, singleblock machines consume EU to run recipes. All singleblock electric +machines: + +* Perform recipes to produce or convert items or fluids +* Consume EU every tick to operate + * A machine that runs out of power mid-recipe will "Powerstall", stopping processing and resetting its recipe progress + to 0. It will then sit idle for several seconds, attempting to refill its internal energy buffer before starting again. + * A powerstalling machine does not delete its input items, it simply cannot complete its work until it is given enough + energy to run. + * A powerstalling machine can also be fully set to standby by right-clicking it with a Soft Mallet. This will cause + it to stop attempting to run the recipe until turned on again, but will not delete the input items. + * In previous versions of GregTech, machines could be paused and unpaused mid-recipe, and a powerstalling recipe would + have its progress tick backwards rather than fully resetting. These behaviors were changed in 7.0.0, as they allowed + exploits in running machines without feeding them sufficient power. +* Have a Voltage Tier. This voltage tier determines: + * The voltage which can be safely input to the machine. A machine which receives an amp of power from a voltage above + its tier will **explode**. + * The tier of recipes the machine can run. Many recipes have a minimum required voltage tier. + * The tier of **Overclock** the machine runs at. Higher-voltage machines running lower-voltage recipes will Overclock + the recipes. And Overclocked recipe consumes power as if it were a tier up (4x EU/t), and be completed in 1/2 the time. + This does mean that overclocked machines are less energy efficient (4x voltage, 1/2 time, 2x total energy usage), + however such is the cost of technology, speed, and industrialization. +* Accept EU emitted by a connected Generator or Cable. Cables and generators can connect to any side of a machine. + * Every singleblock machine contains a small buffer of energy, equal to (Voltage x 64) EU + * Every singleblock machine accepts 1 Amp of power at its voltage tier to fill its buffer. + * When running a recipe, the machine accepts amps equal to the amperage of the recipe. + * When below 50% energy buffer and running a recipe, the machine accepts 1 additional Amp. + +This last aspect means that singleblock machines will, in general, accept either 1 or 2 Amps of power from any +connected generators. While it is possible to create recipes consuming multiple amps of power, there are currently +no recipes in GregTech Modern that do this. + +* Contain a Battery Slot, marked with a lightning bolt. Batteries will be discussed more in [Energy Storage](./Energy-Storage.md#batteries), +however Batteries placed inside Machines will: + * Charge themselves when the machine's buffer is more than 2/3s full + * Discharge themselves to power the machine when the machine's buffer is less than 1/3 full + +These behaviors mean that a Battery can be used to stabilize the power feed to a machine that may otherwise not +have sufficient power to run continuously, counteract Powerstalling, and allow the machine to buffer enough power to +run for short bursts and finish important recipes. + +In the ancient days of IndustrialCraft 2, Redstone Dust could be placed in a machine's battery slot to provide 1000 EU +to the machine. This is *not* a feature in GregTech Modern. + +## Multiblock Machines +Starting from the Electric Blast Furnace as the gateway to MV, and expanding greatly in HV and IV, Multiblock Machines +are the answer to needing more processing speed and volume, or doing processes which are too large or power intensive to +run in singleblock machines. All multiblock electric machines: + +* Perform recipes to produce or convert items or fluids. + * Most Multiblock machines have an additional operating mode called Batch Mode. Batch Mode is enabled via a toggle button + in the multiblock's Controller. Batch Mode has no effect on recipes that take longer than 2.5 seconds (after overclocks). + However, for any recipes shorter than 2.5 seconds, the machine will attempt to combine together multiple recipe runs + into a single large batch, completing as many recipes as possible within 5 second periods, combining their inputs and + duration. This reduces how frequently the machine needs to search for new recipes, and improves server performance for + large, late-game bases with extremely fast machines. +* Are a Structure built around a Controller. + * The Controller defines the multiblock, is used to examine the machine's current activity and status, and is used + to toggle the machine's recipe processing on or off. However, the Controller does **not** handle any item, fluid, or + energy input or output. + * Much of a multiblock's structure will be comprised of Casings of some variant. Casings are fully inert blocks + which make up much of the cost of a multiblock structure, but are very simple and cheap to make next to functional + machine blocks. + * Certain multiblock machines, notably the Electric Blast Furnace and Alloy Blast Smelter, also contain Heating Coil + blocks. These Heating Coils come in multiple tiers and determine some of the machine's recipe capabilities and parameters, + either unlocking new recipes or making existing recipes more efficient. For machines which contain Heating Coils, all + Coils in the structure must match. +* Contain Hatches and Busses. Hatches and Busses are blocks which replace Casings in a structure, and are the places where +Items, Fluids, Energy, and other interactions are done with the multiblock structure. + * Input hatches and busses will automatically pull items or fluids into them through their input face; Output hatches + and busses will automatically push items or fluids into inventories or tanks connected to their output face. This + automation behavior can be disabled by toggling the hatch Off using its power button or a soft mallet. + * All multiblock structures have a "Minimum Required Casings", which acts as an upper limit on how many Casings + can be replaced by busses and hatches. + * Add-on mods may also define other types of Hatches to input or output other special types of recipe ingredients. +* Consume EU from Energy Hatches. Unlike with singleblock machines, multiblock machines do not have an inherent voltage +tier. Instead, multiblock machines operate at a voltage tier equal to the combined input of all of their energy hatches. + * Standard Energy Hatches accept 2 Amps of power on-tier, and provide this power to their associated Controller. + An Energy Hatch which receives an amp of power of a voltage above its tier will **explode**. + * Most multiblock machines can accept multiple energy hatches, allowing them to run recipes at higher tiers + using lower-tier components. This is immediately used on the Electric Blast Furnace, which requires MV power to run + most recipes but can only be initially built using LV Energy Hatches. As such, a player's first EBF must be constructed + using two LV Energy Hatches, and fed by four LV Generators (or a [4x Battery Buffer](./Energy-Storage.md#battery-buffers)). + * The power tier of a multiblock machine is also used to determine Overclocks. Almost all multiblock machines use + the same Overclocking rules as normal machines (4x EU/t, 1/2 recipe time), with three notable exceptions: + * The **Large Chemical Reactor** uses "Perfect Overclocks": recipes run at 4x EU/t but **1/4th** recipe time, + meaning that the LCR does not lose energy efficiency when overclocked. This also makes the LCR extremely fast at + completing recipes. + * The **Fusion Reactor** uses "Perfect Half Overclocks": recipes run at 2x EU/t and 1/2 recipe time. + * If a multiblock machine is overclocked to the point that its recipes would take less than 1 tick to complete, + it begins performing Subtick Overclocks. Subtick Overclocks work similar to Batch Mode, in that the machine will + attempt to perform multiple copies of the recipe (as many instances as it could finish in 1 tick) to try to keep + pace with the machine's newfound extreme speed. +* Most (but not all) require Maintenance. Maintenance Issues occur every few hours while a multiblock machine is running +and must be repaired by using a Tool on a Maintenance Hatch. The maintenance issue that occurs dictates the tool needed. +Most machines require a Maintenance Hatch; and when a Maintenance Hatch is first placed it appears with all maintenance +issues present and thus needs maintenance before the machine can come online. + * A machine with maintenance issues will safely shut itself down after finishing its current recipe, and once the + maintenance issues are resolved it will turn on again. +* Can **Wallshare** components. The inert casings, frames, coils, and *most Hatches and Busses* in the structure of a multiblock +machine can be shared between multiple controllers. Unlike in most other mods that contain multiblock machines, GregTech +Multiblock Machines do **not** form a single connected entity out of the full machine; the only interactable Block Entities +are the Controller and the Hatches. The result of this is that, while the first multiblock machine of a given type must +be built at full cost, additional machines of the same type can be built sharing walls with the first, significantly +reducing their full build cost. + * Most Hatches and Busses can also be shared between machines, allowing wallshared machines to take from the same + feed of input materials to run the same recipe side by side, or run different recipes that share a common ingredient. + * Energy Hatches can be shared between machines, however this is generally discouraged as it can lead to the machines + running out of power. + +### GCYM Multiblock Machines +Constructing the Alloy Blast Smelter unlocks production of a number of complex metal alloys. These alloys are used to build +a line of IV-tier machines sometimes called the Gregicality Multiblocks. GCYM was an independent GregTech add-on mod that +was fully integrated into GregTech Modern, and adds a collection of multiblock replacements for singleblock machines. +The GCYM Multiblocks have all the above properties of normal Multiblock machines, with a few additional features: + +* Are constructed from alloys made in an Alloy Blast Smelter. +* Perform recipes otherwise available in singleblock machines. + * Certain GCYM Multis can also perform multiple different recipe sets. For example, the Large Centrifuge can perform + either Centrifuge or Thermal Centrifuge recipes. The operating mode of a machine can be set in its Controller. +* Accept a **Parallel Hatch**. Parallel Hatches cause a machine to attempt to run multiple copies of a recipe simultaneously, +combining their inputs, outputs, and EU/t cost. If a machine does not have enough energy input to run its Hatch-allowed +parallels at full overclocked speed, it will reduce its overclock tier to compensate, improving energy efficiency but +(because of the parallel runs) not sacrificing recipe throughput volume. +* Can use High-Amp Energy Hatches. + * Normal energy hatches accept 2 Amps of power. GCYM machines can accept 4A or 16A Energy Hatches, allowing for + running higher parallel counts at higher overclock tiers. \ No newline at end of file diff --git a/docs/content/Gameplay/Electricity/index.md b/docs/content/Gameplay/Electricity/index.md new file mode 100644 index 00000000000..bb304a95edf --- /dev/null +++ b/docs/content/Gameplay/Electricity/index.md @@ -0,0 +1,26 @@ +# Electricity +The vast majority of GregTech Modern machines run on Electricity, also known as EU ("Energy Units"). Electricity and +Electric machines share several common safety and behavior rules. + +## General concepts of EU +* EU is produced by [**Generators**](./Generators.md) every tick. +* [**Electric Machines**](./Machines.md) consume EU every tick while operating. +* Batteries and Battery Buffers act as EU [**Storage**](./Energy-Storage.md). +* [**Cables and Transformers**](./Cables-and-Transformers.md) transport EU between generators, storage, and machines. + +Batteries and Machines store EU in an internal buffer, but all EU transportation is done using **Voltage** and **Amperage**. + +* Voltage (V) is the power tier of a device, and the size of an energy "packet" which is emitted by Generators and received +by Machines. +* Cables and Machines have a voltage tier, which is the maximum voltage they can safely carry or receive. +Carrying or receiving unsafe Voltages can be highly destructive. + * Tiers are referred to using a two or three letter abbreviation. In order, the full list of tiers is: + * ULV, LV, MV, HV, EV, IV, LuV, ZPM, UV, UHV, UEV, UIV, UXV, OpV, MAX + * Each successive voltage tier is 4x the voltage of the previous. (LV = 32V, MV = 128V, HV = 512V . . .) + * Transformers can be used to convert power at a voltage tier into the voltage above, or vice-versa. +* Amperage (A) is how many Voltage packets are being carried at the same time in parallel. +* Voltage x Amperage results in **EU/t**. EU/t x Time results in **Total EU**. +* Blocks that emit EU will only emit EU from a single designated output side, usually marked with a large colored dot. +Blocks that accept EU can accept it from any side that is not an EU Output side. Blocks that can emit multiple Amps will +have a larger and more complex dot on their output side. + diff --git a/docs/content/Gameplay/Logistics/Covers.md b/docs/content/Gameplay/Logistics/Covers.md new file mode 100644 index 00000000000..000f4ddf8f0 --- /dev/null +++ b/docs/content/Gameplay/Logistics/Covers.md @@ -0,0 +1,100 @@ +# Covers +**All** GregTech Modern blocks which contain a BlockEntity can have Covers attached to them to add additional functionality +or alter their normal functions. Some of these covers affect item and fluid transfer. + +Covers can be attached, configured, or removed, through the machine side configuration UI found in all GregTech Modern +machines and hatches. They can also be: + +* Attached by right-clicking the machine while holding the cover +* Configured by right-clicking their side with a Screwdriver or shift- right-clicking with an empty hand +* Removed by right-clicking with a Crowbar. + +Logistics are available at all voltage tiers starting at LV, and the maximum rate at which they transfer items and fluids +is based on their voltage tier. (There is an add-on mod which also adds ULV covers however those are not included in base +GregTech Modern.) + +## Conveyor Modules and Electric Pumps +Conveyor Modules and Electric Pumps are the standard set of logistics covers. They can be placed on blocks with inventories +or tanks, or on item or fluid pipes (respectively). On placement, they default to Export mode, extracting items or fluids +from their attached block and pushing them into the block they face. By using a Screwdriver, they can be toggled to +Import mode, and their transfer rate per-second or per-tick can also be configured. + +When connected to a Fluid Pipe, Electric Pumps will override the normal fluid transfer rate of the pipe on that side, +and fluid will transfer according to the Pump's settings. + +When transporting items into an Item Pipe (either by being placed adjacent to a pipe and set to export, or placed on a +pipe and set to import), Conveyor Modules have an additional feature: Distribution Mode. There are three options for this: + +* Priority: Items are sent to the closest available inventory first +* Round Robin: Items are distributed approximately equally across all available inventories +* Round Robin with Restriction: Items are distributed across all available inventories, but the distribution will ignore +any destinations that have Restrictive Item Pipes along the route to them, unless there are no other destinations it can +send to. + +## Robot Arms and Fluid Regulators +Robot Arms and Fluid Regulators are more advanced versions of the Conveyor and Pump. They have the same features, but +with an additional Transfer Mode toggle: + +* Transfer Any: always transfer as many items/fluid as are available +* Transfer Exact: Only transfer items/fluid if an **exact** amount is available for transport (e.g. only transport +exactly 13 items at once, or exactly 144mB of a fluid). The cover will not transfer any if it has less than the target, +and will only transfer the exact amount even if more is available. This is useful for preventing machines being jammed +from a full inventory but each stack has only half the items needed to run a recipe. +* Keep Exact: Check the contents of the target inventory. Only transfer items/fluids if the amount of each available +item/fluid in the target is less than the set amount, and only transfer enough to raise the target's inventory to the +set amount. This is useful to prevent a machine from getting completely filled with one item and having no space for a +second required item. + +When attached to a Pipe, Robot Arms can export into the pipe using Transfer Exact mode, but they are unable to export using +Keep Exact mode. However, Robot Arms *can* be attached to pipe output ends, and they will enforce the Keep Exact quantity +for the inventory they are exporting to. + +## Filters +Logistics covers can have Filters installed in them, to specifically allow (whitelist) or disallow (blacklist) chosen +items or fluids to pass through those covers. Filters can be configured by right-clicking them against the air, and +items and fluids can be added to the filter either by placing them in from inventory (not consumed), or by dragging them +in from NEI/JEI/EMI. + +There are five types of filters: + +* Item Filter, Fluid Filter - filters by specific items/fluids. Can be set to filter by, or ignore, item NBT data. +* Item Tag Filter, Fluid Tag Filter - Filters using a Regular Expression string, searching by one or more Item Tags. +Multiple tags can be included or excluded from a single filter using logical operators. +* Smart Item Filter - Filters items by searching recipe logic for valid ingredients. Supports the Centrifuge, Electrolyzer, +and Sifter recipe lists. + +Filters can also be attached as covers to Machine faces set to auto-export or receiving inputs, to apply their filter +to the items or fluids traveling through that face. + +Fluid Filter Covers can also be attached to Fluid Pipes to isolate individual pipe directions and ensure only a single +fluid can travel down that pipe (if, for example, there was a Quadruple Fluid Pipe carrying four fluids, and one fluid +needed to be separated out). + +## Ender Links +Independent from all these other devices, there are also another set of covers: the Ender Link Covers. These come in +three types: Item, Fluid, and Redstone. These covers must be configured with a screwdriver on placement, but once configured +they become part of a Network of interdimensionally wirelessly connected Ender Links. + +Ender Links are assigned a network using a Channel, using an 8-digit hexadecimal color code (RBGA format) and optionally +a Description (as a text string). Every Channel has two forms: a Public form (accessible to everyone on the server), and +a Private form (accessible only to the player who placed the Link cover). All Links of the same type on the same channel +then become linked, allowing items, fluids, or redstone signals to be imported or exported between them. + +After being assigned a channel, Ender Links have the same input/output and filter controls as a Conveyor or Pump. A single +Ender Link cover is only one-directional though, only allowing its attached machine to export to the ender network, or +import from it. + +Each Ender Link channel contains a single storage slot: either a single redstone value, a 160,000mB fluid tank, or a 1- +slot inventory. Each Ender Fluid Link cover can transfer up to 160,000mB of fluid per second in or out, and each Ender +Item Link can transfer up to 160 items per second in or out, attempting transfer every tick. Because Link Covers contain +only a single slot, they are most efficient at teleporting only a single type of item or fluid. + +## Void Covers +Sometimes items or fluids are unneeded or unwanted. Void Covers answer that. Any items or fluids which are exported into +a Voiding Cover are simply deleted. + +Void Covers have two versions: + +* Simple: Voids all items/fluids that enter it. No further configuration. +* Advanced: Allows for Filter configuration to only void specific items/fluids. Also has a Keep Exact mode, causing the +cover to only void contents if the attached inventory contains more than the configured amount. \ No newline at end of file diff --git a/docs/content/Gameplay/Logistics/Machines.md b/docs/content/Gameplay/Logistics/Machines.md new file mode 100644 index 00000000000..8cfe69a4bdd --- /dev/null +++ b/docs/content/Gameplay/Logistics/Machines.md @@ -0,0 +1,59 @@ +# Machine Logistics +## Steam Machines +Steam Machines do not have any form of built-in logistics capability, with three exceptions: + +* The Primitive Water Pump is a Multiblock Machine and contains an Output Hatch. This hatch will automatically push water + out into any connected pipe or tank. +* The Coke Oven is also a Multiblock machine, but unlike other multiblocks its controller does contain its inventory. + To aid in Coke Oven automation, a unique block called the Coke Oven Hatch can be placed in its structure, which will + accept item input and automatically push items and fluids out. +* All Boilers which contain Steam will attempt to push Steam out into any fluid pipes or machines adjacent to them, on + all sides _except below_. This means that water can be safely input from below with no risk of steam entering your water + pipes. + +Additionally, Steam machines have a unique design challenge feature: all Steam machines have an Exhaust face, which must +be facing open air, and will emit a blast of Steam every time the machine finishes a recipe. If the Exhaust face is +blocked, the machine cannot complete its recipes; and the blast of Steam released will heavily injure any player +standing in it. + +## Electric Machines +All Electric machines have the ability to automatically output their produced items, fluids, or both, into any adjacent +machine, inventory, tank, or pipe. This can be done with a Wrench, or via the Side Configuration tab in the machine's UI. + +* To change auto output from outside a machine, shift-right-click on air with the wrench to choose whether to configure + for Items, Fluids, or Both, then right click with a Wrench on the side of the machine to rotate its output face. + * To then enable automated output, right-click the machine face with a Screwdriver. +* To change auto output from inside a machine, open the Side Configuration tab, and click the side you want to set as + output. + * One click will select the side, a second left click will set the side to item output, and a third left click will + toggle auto output. Right clicks will set and toggle fluid output. + * The main machine UI also contains two toggle buttons to enable or disable auto output for items or fluids, without + needing to open the configuration panel. + +Additionally, all electric machines will also **block** automated item or fluid input from their output sides. To +override this and allow input from output side, there is an additional toggle button in the Side Configuration tab, or +shift-right-click on the machine with a Screwdriver. + +## Multiblock Machines +Multiblock machines do not contain items within their controller blocks, and instead all I/O is handled by Buses and +Hatches. Buses and Hatches will, by default, **auto-import** from any inventories, tanks, or pipes they face, and +**auto-export** to any inventories, tanks, or pipes. This behavior can be toggled by Disabling the hatch, either through +the power button in its UI or by right-clicking it with a Soft Mallet. + +Buses and Hatches can accept automated import or export from other sides, so long as something else is causing it. + +## Passthrough Hatches and the Cleanroom +The Cleanroom is a unique multiblock with unique restrictions. Because the Cleanroom must have solid walls, pipes, cables, +and inventories outside cannot directly connect to machines inside. For this purpose, Passthrough Hatches exist. +Passthrough Hatches (by default, only the HV Passthrough Hatches can be crafted) are solid blocks which can be placed in +the walls or floor of a cleanroom. These hatches act as Input and Output at the same time, and will auto-Import from +their green face, and auto-Export to their red face, in the same tick. This allows items and fluids to be pulled through +the cleanroom walls, in or out. + +Furthermore, as Generators cannot be placed inside the Cleanroom, to transfer power in, Diodes can be used. Diodes can +also be placed in the Walls or Floor, and if right-clicked with a Soft Mallet will limit how many Amps will travel through, +cycling through 1/2/4/8/16A. + +Finally, Machine Hulls have a unique feature. On one hand, they can be used as a 1A Diode and transfer a single amp +of power. On the other hand, they are also considered valid cables for an Applied Energistics ME Network, and thus +ME Cables will connect to Hulls and allow an ME Network to extend into a Cleanroom. \ No newline at end of file diff --git a/docs/content/Gameplay/Logistics/Pipes.md b/docs/content/Gameplay/Logistics/Pipes.md new file mode 100644 index 00000000000..afc9b25dba1 --- /dev/null +++ b/docs/content/Gameplay/Logistics/Pipes.md @@ -0,0 +1,96 @@ +# Pipes +GregTech Modern offers both Item and Fluid pipes, made out of a wide range of materials in a wide range of capacities. + +## Pipe Placement +Pipes and Cables use a shared, unique system for placement in world. + +A pipe or cable which is placed in world will, by default, not connect to any other adjacent blocks. However, if the +pipe was shift-right-click placed against a machine or another pipe, the pipe will be placed connected to that machine. + +Once one pipe has been placed, looking at that pipe with another pipe will display the same sided overlay as when +looking at a machine with a wrench or other tool. Right-clicking with a pipe within one of the sided regions will place +a new pipe *on that side of the existing pipe*, connected to the pipe. This allows for placing lines of pipe without +needing to stand in the path being placed along. + +### Frame Boxes +Pipes can be placed inside of Frame Boxes, and Frame Boxes can be placed over Pipes. This is primarily an aesthetic +choice, however it also forces the pipe's collision box to take up a full block of space, and thus also provides some +protection from the hazards of touching a fluid pipe carrying very hot or cold fluids (see below). + +## Pipe Connections +Pipes can be right-clicked with a wrench to Connect or Disconnect the pipe from that side. This can be used to +preemptively set pipe connections in preparation for a machine to be placed there, or to connect or disconnect pipe +segments that need to branch off of others. + +Additionally, pipes can be shift-right-clicked in order to "Shutter" a given side of them. Shuttered pipe sides become +**output-only**, allowing pipes to be made one-way. Shuttered pipe sides are visible via a small black arrow drawn in the +allowed direction of transfer. + +Pipes have default logic for how they distribute their contents across their connections, however these behaviors can be +modified by using [Covers](./Covers.md) + +## Pipe Materials and Sizes +Pipes come in four sizes: Small, Normal, Large, and Huge. Fluid pipes also come in a Tiny size. Each larger size is more +expensive but has greater throughput. The throughput of a pipe is determined by its Material (and in general, materials +that require higher voltage tiers to produce have higher throughput) and multiplied by its size. + +## Item Pipes +Item Pipes effectively act as teleportation tunnels between their sources and destinations: any items which are pushed +into a pipe, are instantly pushed out the other end(s). Item pipes can be 1-to-1, 1-to-many, many-to-1, or many-to-many. +Item pipes have a limit on how many items can be pushed through them every second. The limit of a full pipe is the limit +of the smallest segment through (as even though the items are teleported rather than moving from pipe block to pipe block, +they do still follow a path through the pipes and check every pipe along the path). There is no limit to the amount of +different items that can move through a pipe at once, only the total count per second. + +When items are pushed into a pipe, by default they are pushed to the "closest" inventory to the source. However, the +"closest" inventory is not directly determined by the distance in blocks between source and destination. Instead, it is +determined by the "Priority" value of the pipe. Larger pipes have lower priorities, smaller pipes have higher priorities, +and items will take the path which has the smallest total priority value. + +### Restrictive Item Pipes +Item Pipes have a special variant called Restrictive Item Pipes. Restrictive pipes have 100x the priority value of +equivalent non-restrictive pipes, allowing a pipe path to be forcibly made into the "longest" path and thus the final +path items can choose to go down. + +## Fluid Pipes +Fluid Pipes function completely differently from item pipes. Each fluid pipe block is a small fluid tank, with a size +equal to 20x the pipe's listed Transfer Rate. + +Every 5 ticks (4 times per second), fluid pipes will check for their adjacent connections, and try to export up to +Half of their maximum storage capacity, distributed among all adjacent connections that the pipe did *not* receive input +from since it last exported, based on the fullness percentage of those connections. + +As a result, while fluid pipes list their throughput as mB/t, they do not transfer on every tick; they transfer a large +amount of fluid several times per second. + +As a further result however, a line or network of fluid pipes which are not completely filled can experience the fluid +in the pipes sloshing around, becoming more full in some places and more empty in others. This can be mitigated by +Shuttering pipes to prevent backflow. + +## Multi Pipes +While Item Pipes can transfer an unlimited number of item types at once, Fluid Pipes cannot and trying to move multiple +fluids through one pipe is liable to get a fluid stuck somewhere. To combat this, 4 Small Pipes or 9 Tiny Pipes can be +crafted together into a Quadruple or Nonuple Fluid Pipe. These pipes act as 4 or 9 separate piped all in a single block. +Each of these pipes calculates its I/O independently, but **cannot contain duplicate fluids**, allowing 4 or 9 fluids +to be transferred through a single block with no risk of jams. + +## Hazards +Fluid Pipes have an additional set of properties on them: Max Temperature, and Fluid Containment. + +All fluids in GregTech Modern have a Temperature, and some of them also have further properties: +* Acids +* Gases +* Cryogenics +* Plasmas + +If a Pipe's max temperature is less than the temperature of the fluid traveling through it, the pipe will intermittently +void some of its contents, severely injuring nearby players and spreading fires, and quickly be destroyed. +The exception to this is that if the fluid a pipe is carrying is a Plasma, and the pipe is marked as being able to contain +Plasmas, the temperature limit is ignored. + +For other properties, if improperly contained, the effects are similarly hazardous. Acids and Cryogenics will harm their +surroundings, then explode. Gases within pipes that cannot carry them will not destroy the pipe, but the gasses will +quickly escape and cause small explosions. + +Finally, pipes carrying very hot or cold fluids (above 320K or below 260K) will injure entities that touch them, twice +per second, damage scaling with how extreme the heat or cold is. \ No newline at end of file diff --git a/docs/content/Gameplay/Logistics/index.md b/docs/content/Gameplay/Logistics/index.md new file mode 100644 index 00000000000..e57afaccfd7 --- /dev/null +++ b/docs/content/Gameplay/Logistics/index.md @@ -0,0 +1,11 @@ +# Logistics: Automated Item and Fluid Transport +GregTech Modern contains several options for how items and fluids can be transferred between machines, at varying speeds +and technology levels. + +Automated item and fluid transport is managed by three separate systems: + +* [**Machines**](./Machines.md) +* [**Pipes**](./Pipes.md) +* [**Covers**](./Covers.md) + +These systems are commonly manipulated using Tools such as a Wrench, Screwdriver, or Soft Mallet. diff --git a/docs/content/Gameplay/Ore-Generation.md b/docs/content/Gameplay/Ore-Generation.md index 0b872dd46f6..de3824819a1 100644 --- a/docs/content/Gameplay/Ore-Generation.md +++ b/docs/content/Gameplay/Ore-Generation.md @@ -68,7 +68,7 @@ Please note that these are the default settings and may be different in certain ### Iron Vein - Goethite -- Yellow Limonite +- Limonite - Hematite - Malachite @@ -216,7 +216,7 @@ Please note that these are the default settings and may be different in certain ### Banded Iron Vein - Goethite -- Yellow Limonite +- Limonite - Hematite - Gold diff --git a/docs/content/Modpacks/Changes/v7.0.0.md b/docs/content/Modpacks/Changes/v7.0.0.md new file mode 100644 index 00000000000..96c90c28fcc --- /dev/null +++ b/docs/content/Modpacks/Changes/v7.0.0.md @@ -0,0 +1,55 @@ +--- +title: "Version 7.0.0" +--- + + +# Updating from `1.6.4` to `7.0.0` + +## Custom UIs + +In your custom `.rtui` files, you need to rename the following references: + + - `phantom_fluid_slot` -> `gtm_phantom_fluid_slot` + - `phantom_item_slot` -> `gtm_phantom_item_slot` + - `item_slot` -> `gtm_item_slot` + - `fluid_slot` -> `gtm_fluid_slot` + - `container` -> `gtm_container` + +This can be done in any NBT editor of choice, e.g. [webNBT](https://irath96.github.io/webNBT/). + +## Models + +We have completely reworked our rendering system to be model-based instead of renderer-based. + +Previously, you would do +```javascript + .workableCasingRenderer( + "gtceu:block/casings/solid/machine_casing_robust_tungstensteel", + "gtceu:block/multiblock/primitive_blast_furnace", false + ); +``` + +Now, you should instead use: + +```javascript + .workableCasingModel( + "gtceu:block/casings/solid/machine_casing_robust_tungstensteel", + "gtceu:block/multiblock/primitive_blast_furnace" + ); +``` +Note: The third argument has been removed and should no longer be used. + + +Previously, you would do +```javascript + .workableTieredHullRenderer("gtceu:block/machines/reconstructor") +``` + +Now, you would do +```javascript + .workableTieredHullModel("gtceu:block/machines/reconstructor") +``` + +To find an updated list of all the methods for models, look at [MachineBuilder.java](https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MachineBuilder.java) for singleblocks, and [MultiblockMachineBuilder.java](https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MultiblockMachineBuilder.java) for multiblocks. Most methods have kept a similar name, replacing `renderer` with `model`. + + diff --git a/docs/content/Modpacks/Changes/v7.2.0.md b/docs/content/Modpacks/Changes/v7.2.0.md new file mode 100644 index 00000000000..517bf29ffe8 --- /dev/null +++ b/docs/content/Modpacks/Changes/v7.2.0.md @@ -0,0 +1,52 @@ +--- +title: "Version 7.2.0" +--- + + +# Updating from `7.1.4` to `7.2.0` + + +## Models +If you have any block model that + - has overridden base textures when part of a formed structure (fluid hatch coloring for say an EBF), + - doesn't use any of the builtin model methods that set it, + +in the MachineDefinition, you need to add `.modelProperty(GTMachineModelProperties.IS_FORMED, false)` + +## Ranged inputs/outputs +In recipes, you can now use: + +- `.itemInputsRanged(..., min, max)` + +- `.itemOutputsRanged(..., min, max)` + +- `.fluidInputsRanged(..., min, max)` + +- `.fluidOutputsRanged(..., min, max)` + +Where the inputs or outputs will be rolled inclusively from min to max. + +## Rock breaker conditions +Previously, rock breaker recipes used the `addData("fluidA", ...)` methods. + +Now, they work by AdjacentFluidConditions, added with the `adjacentFluids(Fluid...)` methods. See [our other condition builder methods](https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java#L894). + +In a similar vein, recipes that used to have adjacent block requirements, you now need to use `adjacentBlocks(Block...)` rather than `addData("blockA")`. + +There also exist methods for tagged fluids, by using `.adjacentFluidTag(ResourceLocation)` and `.adjacentBlockTag(ResourceLocation)`. + +## Recipe Conditions +We have moved away from the .serialize, .deserialize, .toNetwork and .fromNetwork calls on the RecipeCondition, and we now exclusively use the recipeCondition's codec. +See the [Recipe Conditions Page](../Recipes/Recipe-Conditions.md) + +## Primitive Pump +MV output hatches are no longer valid hatches for the Primitive Pump and need to be replaced with either a ULV`(new)` or LV hatch. + +## Conveyor and Robot Arm Covers +Conveyor Covers, when placed feeding into pipes, allow selecting their distribution mode, between Priority (default), Round Robin, and Round Robin with Restriction. + +Round Robin with Priority mode has been changed to Round Robin with Restriction mode. The previous Round Robin with Priority mode was unclear, and nonfunctional. +The new Round Robin wih Restriction mode attempts to evenly distribute items, as in Round Robin mode; however it attempts to *not* send any items down Restrictive Pipes unless there are no other valid destinations. + +Robot Arm covers, when placed on Pipe *exits*, can now appropriately limit item outputs using Keep Exact mode. +However, a Robot Arm being used to transfer items *into* a pipe, still cannot use Keep Exact mode for transfer; it will not move items. diff --git a/docs/content/Modpacks/Changes/v7.2.1.md b/docs/content/Modpacks/Changes/v7.2.1.md new file mode 100644 index 00000000000..812fbbb47ae --- /dev/null +++ b/docs/content/Modpacks/Changes/v7.2.1.md @@ -0,0 +1,20 @@ +--- +title: "Version 7.2.1" +--- + + +# Updating from `7.2.0` to `7.2.1` + +## AdjacentFluid() and AdjacentBlock() + +For ease of use for KJS, we have added overrides for + +- `adjacentFluid(ResourceLocation... tagNames)` -> `adjacentFluidTag(ResourceLocation... tagNames)` + +and + +- `adjacentFluid(Fluid... fluids)` -> `adjacentFluids(Fluid... fluids)` + +This way, the old `AdjacentFluid(...)` methods still exist, but there also is a clear way to use the kubejs without ambiguous casts / methods. + +These changes hold for the `.adjacentBlock()` too. \ No newline at end of file diff --git a/docs/content/Modpacks/Changes/v7.3.0.md b/docs/content/Modpacks/Changes/v7.3.0.md new file mode 100644 index 00000000000..902cfd7f3bf --- /dev/null +++ b/docs/content/Modpacks/Changes/v7.3.0.md @@ -0,0 +1,18 @@ +--- +title: "Version 7.3.0" +--- + +# Updating from `7.2.1` to `7.3.0` + +## Diluted Sulfuric and Hydrochloric Acid +Previously, Distilling Diluted H2SO4 and HCl back into usable acid was done on Circuit 1 for H2SO4 but on Circuit 2 for +HCl. These have been unified to both use Circuit 1. This will (very mildly) break existing bases. + +## Chance Logics + +- `first` ChanceLogic has been Deprecated as its behavior is highly unreliable, and it will be fully removed in 8.0.0. + We recommend using `xor` instead. + +## KJS Errors +Previously, empty inputs to KJS recipes (like `.inputItems('minecraft:gravl')`) would silently fail and would not add items. +We have made inputItems respect recycling logic and as a side effect require valid, non-null inputItems. If an input is null or invalid, it will now throw an error. \ No newline at end of file diff --git a/docs/content/Modpacks/Changes/v7.4.0.md b/docs/content/Modpacks/Changes/v7.4.0.md new file mode 100644 index 00000000000..766793617d0 --- /dev/null +++ b/docs/content/Modpacks/Changes/v7.4.0.md @@ -0,0 +1,27 @@ +--- +title: "Version 7.4.0" +--- + + +# Updating from `7.3.0` to `7.4.0` + +## Added NBTPredicateIngredients +Added a type of ingredient to do more careful pattern matching on ItemStack NBT data, see [NBT Predicate Ingredient](../Recipes/Ingredients/NBT-Predicate-Ingredients.md). + +## Balance sodium_bicarbonate_from_salt recipe +Removed a salt sink in the recipe to produce sodium bicarbonate from salt, see [GTM PR 4228: Balance chemical titanium recipe](https://github.com/GregTechCEu/GregTech-Modern/pull/4228). + +## ChanceLogic rolls in Custom Recipe Logic +_This is only relevant to add-on mods with custom machine and recipe logic which overrides +`RecipeRunner.fillContentMatchList()`, or otherwise directly call `ChanceLogic.roll()`._ + +The method signature of `ChanceLogic.roll()` was changed from + +`roll(List chancedEntries, ChanceBoostFunction boostFunction, int recipeTier, int chanceTier, Object2IntMap cache, int times)` + +to + +`roll(RecipeCapability cap, List chancedEntries, ChanceBoostFunction boostFunction, int recipeTier, int chanceTier, Object2IntMap cache, int times)` + +(The chance roll function now also requires the RecipeCapability that is currently being processed to be passed in.) + diff --git a/docs/content/Modpacks/Examples/Alternator.md b/docs/content/Modpacks/Examples/Alternator.md deleted file mode 100644 index 2b2ce01e098..00000000000 --- a/docs/content/Modpacks/Examples/Alternator.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: "Alternator" ---- - - -## Alternator Multiblock (by Drack.ion) - -### Recipe Type - -```js title="alternator_recipe_type.js" -GTCEuStartupEvents.registry('gtceu:recipe_type', event => { - event.create('basic_alternator') - .category('multiblock') - .setEUIO('out') - .setMaxIOSize(1, 0, 0, 0) - .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT) - .setSound(GTSoundEntries.ARC) - .setMaxTooltips(6) -}) -``` - -### Multiblock - -```js title="alternator_multiblock.js" -GTCEuStartupEvents.registry('gtceu:machine', event => { - event.create('basic_alternator', 'multiblock') - .rotationState(RotationState.NON_Y_AXIS) - .recipeType('basic_alternator') - .appearanceBlock(GTBlocks.CASING_STEEL_SOLID) - .generator(true) - .pattern(definition => FactoryBlockPattern.start() - .aisle("CWC", "CWC", "#W#") - .aisle("CWC", "K#E", "CWC") - .aisle("CWC", "CWA", "#W#") - .where('A', Predicates.controller(Predicates.blocks(definition.get()))) - .where('W', Predicates.blocks(GTBlocks.COIL_CUPRONICKEL.get())) - .where("C", Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get())) - .where('#', Predicates.any()) - .where('K', Predicates.abilities(PartAbility.INPUT_KINETIC).setExactLimit(1)) - .where('E', Predicates.abilities(PartAbility.OUTPUT_ENERGY).setExactLimit(1)) - .build() - ) - .workableCasingRenderer( - "gtceu:block/casings/solid/machine_casing_solid_steel", - "gtceu:block/multiblock/implosion_compressor", false - ) -}) -``` - -### Lang - -```json title="en_us.json" -{ - "block.gtceu.basic_alternator": "Basic Alternator", - "gtceu.basic_alternator": "Basic Alternator" -} -``` - -### Recipes - -```js title="alternator_recipes.js" -ServerEvents.recipes(event => { - function basic_alt(id, rpm, eu){ - event.recipes.gtceu.basic_alternator(id) - .circuit(1) - .rpm(rpm) - .duration(2) - .EUt(eu) - } - basic_alt('lv_1_amp', 32, -32) -}) -``` diff --git a/docs/content/Modpacks/Examples/Custom-Recipe-Condition.md b/docs/content/Modpacks/Examples/Custom-Recipe-Condition.md new file mode 100644 index 00000000000..a457621f8f8 --- /dev/null +++ b/docs/content/Modpacks/Examples/Custom-Recipe-Condition.md @@ -0,0 +1,154 @@ +--- +title: Custom Recipe Condition +--- + +!!! Warning + Custom recipe conditions are only supported in Java. Therefore, this page will only contain Java examples. + +Recipe conditions are custom conditions for your recipe, like biome, machine tier, or anything else you can think of. + +!!! Note + The condition is run after recipe matching and before recipe execution. If the recipe condition doesn't match, the machine will be suspended and won't be updated again until something in the inputs/outputs changes. + +They are registered using +```java +@Mod(ExampleMod.MOD_ID) +public class ExampleMod { + + public ExampleMod(FMLJavaModLoadingContext context) { + var bus = context.getModEventBus(); + bus.addGenericListener(RecipeConditionType.class, this::registerConditions); + } + + public static RecipeConditionType EXAMPLE_CONDITION; + + public void registerConditions(GTCEuAPI.RegisterEvent> event) { + EXAMPLE_CONDITION = GTRegistries.RECIPE_CONDITIONS.register("example_condition", + new RecipeConditionType<>( + ExampleCondition::new, + ExampleCondition.CODEC + ) + ); + } +} +``` + +We will set up a condition that requires that the power buffer of the machine is above a certain Y level. +```java +public class ExampleCondition extends RecipeCondition { + + public int height; + + public static final Codec CODEC = RecordCodecBuilder + .create(instance -> RecipeCondition.isReverse(instance) + .and(Codec.INT.fieldOf("height").forGetter(val -> val.height)) + .apply(instance, ExampleCondition::new)); + + + public ExampleCondition(boolean isReverse, int height) { + this.isReverse = isReverse; + this.height = height; + } + + public ExampleCondition(int height) { + this(false, height); + } + + public ExampleCondition() { + this(false, 0); + } + + @Override + public RecipeConditionType getType() { + return ExampleMod.EXAMPLE_CONDITION; + } + + @Override + public Component getTooltips() { + return Component.literal(String.format("Should be ran at least at height %d", height)); + } + + @Override + protected boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + return recipeLogic.getMachine().getHolder().getCurrentPos().getY() >= height; + } + + @Override + public RecipeCondition createTemplate() { + return new ExampleCondition(0); + } +} +``` + +Lets step through this example. This will not be in order as it is in the file, but rather in the order that makes most sense. + +Starting with: +```java + @Override + public RecipeConditionType getType() { + return ExampleMod.EXAMPLE_CONDITION; + } + + @Override + public Component getTooltips() { + return Component.literal(String.format("Should be ran at least at height %d", height)); + } +``` +This part is quite simple, and just returns the type and tooltip for the condition. The tooltip is what gets added in the recipe viewer's screen if this condition is present. + +```java + public ExampleCondition(boolean isReverse, int height) { + this.isReverse = isReverse; + this.height = height; + } + + public ExampleCondition(int height) { + this(false, height); + } + + public ExampleCondition() { + this(false, 0); + } +``` +These are the constructors. We need the `isReverse`, as it is part of the overarching `RecipeCondition` type. `isReverse` means that if the condition is met, your recipe won't be run. Furthermore, a no-arg constructor is required for (de)serialization. + +```java + @Override + public RecipeCondition createTemplate() { + return new ExampleCondition(0); + } +``` + +This creates the basic "template" that might be used for serialization. This should return a default version of your condition. + +```java + @Override + protected boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + return recipeLogic.getMachine().getHolder().getCurrentPos().getY() >= height; + } +``` + +This is the actual condition. + +```java + public int height; + + public static final Codec CODEC = RecordCodecBuilder + .create(instance -> RecipeCondition.isReverse(instance) + .and(Codec.INT.fieldOf("height").forGetter(val -> val.height)) + .apply(instance, ExampleCondition::new)); +``` + +The CODEC is how java knows how to serialize/deserialize your condition. This is needed for syncing between client/server, and storing it to json to load when the world loads. +It consists of a few parts: + +- `RecordCodecBuilder.create(instance -> ` means we will start a RecordCodecBuilder, or a builder that only consists of simple types. +- `RecipeCondition.isReverse(instance)` is a helper codec that serializes the isReverse boolean of your codec. +- `.and(` means this is the next field in the record. +- `Codec.INT.fieldOf("height").forGetter(val -> val.height)` means we want to serialize an INT, we want to call it "height" in the json, and to get the value you call `.height`. +- `.apply(instance, ExampleCondition::new)` means when deserializing back to an object, you apply these steps to get the values (in this case `bool isReverse, int height`) and call the constructor with those arguments. + In this case, this would call our `new ExampleCondition(isReverse, height)` constructor we have defined earlier. + +With this, you should have everything you need to make a custom RecipeCondition. + +To apply it to a recipeCondition, you would add to the Recipe Builder: `.condition(new ExampleCondition(70))` for a required height of 70 \ No newline at end of file diff --git a/docs/content/Modpacks/Examples/Greenhouse.md b/docs/content/Modpacks/Examples/Greenhouse.md deleted file mode 100644 index 7c910abcb1b..00000000000 --- a/docs/content/Modpacks/Examples/Greenhouse.md +++ /dev/null @@ -1,218 +0,0 @@ ---- -title: "Greenhouse" ---- - - -# Greenhouse Multiblock (by Drack.ion) - - -## Recipe Type - -```js title="greenhouse_recipe_type.js" -GTCEuStartupEvents.registry('gtceu:recipe_type', event => { - event.create('greenhouse') - .category('drack') - .setEUIO('in') - .setMaxIOSize(3, 4, 1, 0) - .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT) - .setSound(GTSoundEntries.BATH) -}) -``` - - -## Multiblock - -```js title="greenhouse_multiblock.js" -GTCEuStartupEvents.registry('gtceu:machine', event => { - event.create('greenhouse', 'multiblock') - .rotationState(RotationState.NON_Y_AXIS) - .recipeType('greenhouse') - .appearanceBlock(GTBlocks.CASING_STEEL_SOLID) - .pattern(definition => FactoryBlockPattern.start() - .aisle('CCC', 'CGC', 'CGC', 'CLC', 'CCC') - .aisle('CMC', 'GSG', 'G#G', 'LIL', 'COC') - .aisle('CKC', 'CGC', 'CGC', 'CLC', 'CNC') - .where('K', Predicates.controller(Predicates.blocks(definition.get()))) - .where('M', Predicates.blocks('moss_block') - .or(Predicates.blocks('dirt')) - .or(Predicates.blocks('grass_block')) - ) - .where('G', Predicates.blocks('ae2:quartz_glass')) - .where('S', Predicates.blocks('oak_sapling') - .or(Predicates.blocks('dark_oak_sapling')) - .or(Predicates.blocks('spruce_sapling')) - .or(Predicates.blocks('birch_sapling')) - .or(Predicates.blocks('jungle_sapling')) - .or(Predicates.blocks('acacia_sapling')) - .or(Predicates.blocks('azalea')) - .or(Predicates.blocks('flowering_azalea')) - .or(Predicates.blocks('mangrove_propagule')) - .or(Predicates.blocks('gtceu:rubber_sapling')) - ) - .where('I', Predicates.blocks('glowstone')) - .where('L', Predicates.blocks(GTBlocks.CASING_GRATE.get())) - .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get()) - .or(Predicates.autoAbilities(definition.getRecipeTypes())) - ) - .where('O', Predicates.abilities(PartAbility.MUFFLER) - .setExactLimit(1) - ) - .where('N', Predicates.abilities(PartAbility.MAINTENANCE)) - .where('#', Predicates.air()) - .build() - ) - .workableCasingRenderer('gtceu:block/casings/solid/machine_casing_solid_steel', 'gtceu:block/multiblock/implosion_compressor', false) -}) -``` - - -## Lang - -```json title="en_us.json" -{ - "block.gtceu.greenhouse": "Greenhouse", - "gtceu.greenhouse": "Greenhouse" -} -``` - - -## Recipes - -```js title="greenhouse_recipes.js" -ServerEvents.recipes(event => { - - ////// Machine Recipe ////// - - event.shaped( - 'gtceu:greenhouse', - ['AWA', 'CSC', 'WCW'], - { - A: '#forge:circuits/mv', - W: 'gtceu:copper_single_cable', - C: '#forge:circuits/mv', - S: 'gtceu:solid_machine_casing' - } - ).id('gtceu:shaped/greenhouse') - - - ////// Greenhouse Recipes ////// - - function Greenhouse(id, input, fluid, output, boosted) { - if (boosted) { - event.recipes.gtceu.greenhouse(id) - .circuit(2) - .notConsumable(InputItem.of(input)) - .itemInputs('4x gtceu:fertilizer') - .inputFluids(Fluid.of('minecraft:water', fluid)) - .itemOutputs(output) - .duration(320) - .EUt(MV) - } else { - event.recipes.gtceu.greenhouse(id) - .circuit(1) - .notConsumable(InputItem.of(input)) - .inputFluids(Fluid.of('minecraft:water', fluid)) - .itemOutputs(output) - .duration(640) - .EUt(MV) - } - } - - - ////// Trees ////// - - // Rubber - Greenhouse('rubber_sapling', 'gtceu:rubber_sapling', 1000, ['32x gtceu:rubber_log', '8x gtceu:sticky_resin', '4x gtceu:rubber_sapling'], false) - Greenhouse('rubber_sapling_boosted', 'gtceu:rubber_sapling', 1000, ['64x gtceu:rubber_log', '16x gtceu:sticky_resin', '4x gtceu:rubber_sapling'], true) - - // Oak - Greenhouse('oak_sapling', 'minecraft:oak_sapling', 1000, ['64x minecraft:oak_log', '4x minecraft:oak_sapling'], false) - Greenhouse('oak_sapling_boosted', 'minecraft:oak_sapling', 1000, ['64x minecraft:oak_log', '64x minecraft:oak_log', '4x minecraft:oak_sapling'], true) - - // Dark Oak - Greenhouse('dark_oak_sapling', 'minecraft:dark_oak_sapling', 1000, ['64x minecraft:dark_oak_log', '4x minecraft:dark_oak_sapling'], false) - Greenhouse('dark_oak_sapling_boosted', 'minecraft:dark_oak_sapling', 1000, ['64x minecraft:dark_oak_log', '64x minecraft:dark_oak_log', '4x minecraft:dark_oak_sapling'], true) - - // Spruce - Greenhouse('spruce_sapling', 'minecraft:spruce_sapling', 1000, ['64x minecraft:spruce_log', '4x minecraft:spruce_sapling'], false) - Greenhouse('spruce_sapling_boosted', 'minecraft:spruce_sapling', 1000, ['64x minecraft:spruce_log', '64x minecraft:spruce_log', '4x minecraft:spruce_sapling'], true) - - // Birch - Greenhouse('birch_sapling', 'minecraft:birch_sapling', 1000, ['64x minecraft:birch_log', '4x minecraft:birch_sapling'], false) - Greenhouse('birch_sapling_boosted', 'minecraft:birch_sapling', 1000, ['64x minecraft:birch_log', '64x minecraft:birch_log', '4x minecraft:birch_sapling'], true) - - // Acacia - Greenhouse('acacia_sapling', 'minecraft:acacia_sapling', 1000, ['64x minecraft:acacia_log', '4x minecraft:acacia_sapling'], false) - Greenhouse('acacia_sapling_boosted', 'minecraft:acacia_sapling', 1000, ['64x minecraft:acacia_log', '64x minecraft:acacia_log', '4x minecraft:acacia_sapling'], true) - - // Jungle - Greenhouse('jungle_sapling', 'minecraft:jungle_sapling', 1000, ['64x minecraft:jungle_log', '4x minecraft:jungle_sapling'], false) - Greenhouse('jungle_sapling_boosted', 'minecraft:jungle_sapling', 1000, ['64x minecraft:jungle_log', '64x minecraft:jungle_log', '4x minecraft:jungle_sapling'], true) - - // Azalea - Greenhouse('azalea_sapling', 'minecraft:azalea', 1000, ['64x minecraft:oak_log', '4x minecraft:azalea'], false) - Greenhouse('azalea_boosted', 'minecraft:azalea', 1000, ['64x minecraft:oak_log', '64x minecraft:oak_log', '4x minecraft:azalea'], true) - - // Flowering Azalea - Greenhouse('flowering_azalea', 'minecraft:flowering_azalea', 1000, ['64x minecraft:oak_log', '4x minecraft:flowering_azalea'], false) - Greenhouse('flowering_azalea_boosted', 'minecraft:flowering_azalea', 1000, ['64x minecraft:oak_log', '64x minecraft:oak_log', '4x minecraft:flowering_azalea'], true) - - // Mangrove - Greenhouse('mangrove_propagule', 'minecraft:mangrove_propagule', 1000, ['64x minecraft:mangrove_log', '4x minecraft:mangrove_propagule'], false) - Greenhouse('mangrove_propagule_boosted', 'minecraft:mangrove_propagule', 1000, ['64x minecraft:mangrove_log', '64x minecraft:mangrove_log', '4x minecraft:mangrove_propagule'], true) - - ////// Crops ////// - - // Sugarcane - Greenhouse('sugar_cane', 'minecraft:sugar_cane', 1000, '24x minecraft:sugar_cane', false) - Greenhouse('sugar_cane_boosted', 'minecraft:sugar_cane', 1000, '48x minecraft:sugar_cane', true) - - // Kelp - Greenhouse('kelp', 'minecraft:kelp', 2000, '24x minecraft:kelp', false) - Greenhouse('kelp_boosted', 'minecraft:kelp', 2000, '48x minecraft:kelp', true) - - // Bamboo - Greenhouse('bamboo', 'minecraft:bamboo', 1000, '24x minecraft:bamboo', false) - Greenhouse('bamboo_boosted', 'minecraft:bamboo', 1000, '48x minecraft:bamboo', true) - - // Cactus - Greenhouse('cactus', 'minecraft:cactus', 1000, '24x minecraft:cactus', false) - Greenhouse('cactus_boosted', 'minecraft:cactus', 1000, '48x minecraft:cactus', true) - - // Wheat - Greenhouse('wheat', 'minecraft:wheat_seeds', 1000, '24x minecraft:wheat', false) - Greenhouse('wheat_boosted', 'minecraft:wheat_seeds', 1000, '48x minecraft:wheat', true) - - // Carrot - Greenhouse('carrot', 'minecraft:carrot', 1000, '24x minecraft:carrot', false) - Greenhouse('carrot_boosted', 'minecraft:carrot', 1000, '48x minecraft:carrot', true) - - // Potato - Greenhouse('potato', 'minecraft:potato', 1000, '24x minecraft:potato', false) - Greenhouse('potato_boosted', 'minecraft:potato', 1000, '48x minecraft:potato', true) - - // Beetroot - Greenhouse('beetroot', 'minecraft:beetroot_seeds', 1000, '24x minecraft:beetroot', false) - Greenhouse('beetroot_boosted', 'minecraft:beetroot_seeds', 1000, '48x minecraft:beetroot', true) - - // Mellon - Greenhouse('melon', 'minecraft:melon_seeds', 1000, '12x minecraft:melon', false) - Greenhouse('melon_boosted', 'minecraft:melon_seeds', 1000, '24x minecraft:melon', true) - - // Pumpkin - Greenhouse('pumpkin', 'minecraft:pumpkin_seeds', 1000, '12x minecraft:pumpkin', false) - Greenhouse('pumpkin_boosted', 'minecraft:pumpkin_seeds', 1000, '24x minecraft:pumpkin', true) - - // Nether Wart - Greenhouse('nether_wart', 'minecraft:nether_wart', 1000, '12x minecraft:nether_wart', false) - Greenhouse('nether_wart_boosted', 'minecraft:nether_wart', 1000, '24x minecraft:nether_wart', true) - - // Red Mushroom - Greenhouse('red_mushroom', 'minecraft:red_mushroom', 1000, '12x minecraft:red_mushroom', false) - Greenhouse('red_mushroom_boosted', 'minecraft:red_mushroom', 1000, '24x minecraft:red_mushroom', true) - - // Brown Mushroom - Greenhouse('brown_mushroom', 'minecraft:brown_mushroom', 1000, '12x minecraft:brown_mushroom', false) - Greenhouse('brown_mushroom_boosted', 'minecraft:brown_mushroom', 1000, '24x minecraft:brown_mushroom', true) -}) -``` \ No newline at end of file diff --git a/docs/content/Modpacks/Examples/Multiblocks/Example_Coil_Multiblock.md b/docs/content/Modpacks/Examples/Multiblocks/Example_Coil_Multiblock.md new file mode 100644 index 00000000000..09fa577b996 --- /dev/null +++ b/docs/content/Modpacks/Examples/Multiblocks/Example_Coil_Multiblock.md @@ -0,0 +1,102 @@ +--- +title: "Example Coil Multiblock" +--- + +### Superheated Pyrolyzing Oven Multiblock (by Phoenixvine) + + +Below is an example of a multiblock using the CoilWorkableElectricMultiblockMachine class and the pyrolyseOvenOverclock machine logic. + +### Multiblock +=== "JavaScript" + ```js title="superheated_pyrolyzing_oven_multiblock.js" + // In order to use multiblock logic extending beyond the normal WorkableElectricMultiblockMachine, (This is the multiblock type used by default for kubejs) you need to load a class. Coil multiblocks such as the Electric Blast Furnace, Pyrolyse Oven, and the Cracker use this class. + const CoilWorkableElectricMultiblockMachine = Java.loadClass("com.gregtechceu.gtceu.api.machine.multiblock.CoilWorkableElectricMultiblockMachine") + + GTCEuStartupEvents.registry('gtceu:machine', event => { + event.create("superheated_pyrolyzing_oven", "multiblock") + .machine((holder) => new CoilWorkableElectricMultiblockMachine(holder)) + .rotationState(RotationState.NON_Y_AXIS) + .recipeTypes('pyrolyse_oven') + .recipeModifiers( + [ + GTRecipeModifiers.PARALLEL_HATCH, + (machine, recipe) => GTRecipeModifiers.pyrolyseOvenOverclock(machine, recipe) + ] + ) + .appearanceBlock(GTBlocks.CASING_STEEL_SOLID) + .pattern(definition => FactoryBlockPattern.start() + .aisle("BBCCCBB", "BBCDCBB", "BBCCCBB", "BBCCCBB", "BBEEEBB", "BBEEEBB") + .aisle("BCCCCCB", "BCAFACB", "BCAFACB", "BCGGGCB", "BEAAAEB", "BEHHHEB") + .aisle("CCCCCCC", "CAAFAAC", "CAAFAAC", "CGGGGGC", "EAAAAAE", "EHHHHHE") + .aisle("CCCCCCC", "DFFFFFD", "CFFFFFC", "CGGGGGC", "EAAAAAE", "EHHMHHE") + .aisle("CCCCCCC", "CAAFAAC", "CAAFAAC", "CGGGGGC", "EAAAAAE", "EHHHHHE") + .aisle("BCCCCCB", "BCAFACB", "BCAFACB", "BCGGGCB", "BEAAAEB", "BEHHHEB") + .aisle("BBCCCBB", "BBCICBB", "BBCCCBB", "BBCCCBB", "BBEEEBB", "BBEEEBB") + .where('A', Predicates.blocks("minecraft:air")) + .where('B', Predicates.any()) + .where('C', Predicates.blocks('gtceu:solid_machine_casing').setMinGlobalLimited(10) + .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1)) + .or(Predicates.abilities(PartAbility.PARALLEL_HATCH).setMaxGlobalLimited(1)) + .or(Predicates.autoAbilities(definition.getRecipeTypes()))) + .where('D', Predicates.blocks("gtceu:steel_firebox_casing")) + .where('E', Predicates.blocks("gtceu:laminated_glass")) + .where('F', Predicates.blocks("gtceu:ptfe_pipe_casing")) + .where('G', Predicates.heatingCoils()) + .where('H', Predicates.blocks("gtceu:high_temperature_smelting_casing")) + .where('M', Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1)) + .where('I', Predicates.controller(Predicates.blocks(definition.get()))) + .build()) + .workableCasingModel("gtceu:block/casings/solid/machine_casing_solid_steel", + "gtceu:block/multiblock/pyrolyse_oven"); + + }) + ``` + + +=== "Java" + ```java title="MultiMachines.java" + + public static final MultiblockMachineDefinition SUPERHEATED_PYROLYZING_OVEN = REGISTRATE + .multiblock("superheated_pyrolyzing_oven", (holder) -> new CoilWorkableElectricMultiblockMachine(holder)) + .rotationState(RotationState.NON_Y_AXIS) + .recipeType(GTRecipeTypes.PYROLYSE_RECIPES) + .recipeModifiers(GTRecipeModifiers.PARALLEL_HATCH, + (machine, recipe) -> GTRecipeModifiers.pyrolyseOvenOverclock(machine, recipe)) + .appearanceBlock(GTBlocks.CASING_STEEL_SOLID) + .pattern(definition -> FactoryBlockPattern.start() + .aisle("BBCCCBB", "BBCDCBB", "BBCCCBB", "BBCCCBB", "BBEEEBB", "BBEEEBB") + .aisle("BCCCCCB", "BCAFACB", "BCAFACB", "BCGGGCB", "BEAAAEB", "BEHHHEB") + .aisle("CCCCCCC", "CAAFAAC", "CAAFAAC", "CGGGGGC", "EAAAAAE", "EHHHHHE") + .aisle("CCCCCCC", "DFFFFFD", "CFFFFFC", "CGGGGGC", "EAAAAAE", "EHHMHHE") + .aisle("CCCCCCC", "CAAFAAC", "CAAFAAC", "CGGGGGC", "EAAAAAE", "EHHHHHE") + .aisle("BCCCCCB", "BCAFACB", "BCAFACB", "BCGGGCB", "BEAAAEB", "BEHHHEB") + .aisle("BBCCCBB", "BBCICBB", "BBCCCBB", "BBCCCBB", "BBEEEBB", "BBEEEBB") + .where('A', Predicates.air()) + .where('B', Predicates.any()) + .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get()).setMinGlobalLimited(10) + .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1)) + .or(Predicates.abilities(PartAbility.PARALLEL_HATCH).setMaxGlobalLimited(1)) + .or(Predicates.autoAbilities(definition.getRecipeTypes()))) + .where('D', Predicates.blocks(GTBlocks.FIREBOX_STEEL.get())) + .where('E', Predicates.blocks(CASING_LAMINATED_GLASS.get())) + .where('F', Predicates.blocks(GTBlocks.CASING_POLYTETRAFLUOROETHYLENE_PIPE.get())) + .where('G', Predicates.heatingCoils()) + .where('H', Predicates.blocks(GCYMBlocks.CASING_HIGH_TEMPERATURE_SMELTING.get())) + .where('M', Predicates.abilities(PartAbility.MUFFLER).setExactLimit(1)) + .where('I', Predicates.controller(Predicates.blocks(definition.get()))) + .build()) + .workableCasingModel(GTCEu.id("block/casings/solid/machine_casing_solid_steel"), + GTCEu.id("block/multiblock/pyrolyse_oven")) + .register(); + ``` + +### Lang + +```json title="en_us.json" +{ + "block.gtceu.superheated_pyrolyzing_oven": "Superheated Pyrolyzing Oven", +} +``` + + diff --git a/docs/content/Modpacks/Examples/Multiblocks/Example_Steam_Multiblock.md b/docs/content/Modpacks/Examples/Multiblocks/Example_Steam_Multiblock.md new file mode 100644 index 00000000000..41adf435a64 --- /dev/null +++ b/docs/content/Modpacks/Examples/Multiblocks/Example_Steam_Multiblock.md @@ -0,0 +1,89 @@ +--- +title: "Example Steam Multiblock" +--- + +### Large Steam Compressor Multiblock + +Below is an example of a multiblock using the SteamParallelMultiblockMachine class. +Steam multiblocks such as the Steam Grinder and Steam Oven use this class. + +### Multiblock + +=== "JavaScript" + ```js title="example_steam_multiblock_multiblock.js" + + // In order to use multiblock logic extending beyond the default multiblock type for KJS (WorkableElectricMultiblockMachine), you need to load a class. + const $SteamMulti = Java.loadClass('com.gregtechceu.gtceu.common.machine.multiblock.steam.SteamParallelMultiblockMachine'); + + GTCEuStartupEvents.registry('gtceu:machine', event => { + event.create('large_steam_compressor', 'multiblock') + .machine((holder) => new $SteamMulti(holder, 4)) + // The number in holder is the max amount of parallel it can use. + .rotationState(RotationState.NON_Y_AXIS) + .recipeType('compressor') + .recipeModifier((machine, recipe) => $SteamMulti.recipeModifier(machine, recipe), true) + .appearanceBlock(GTBlocks.BRONZE_HULL) + .pattern(definition => FactoryBlockPattern.start() + .aisle("BCCCB", "BBCBB", "BBCBB", "BBBBB", "BBBBB") + .aisle("CDDDC", "BDBDB", "BDEDB", "BBDBB", "BBBBB") + .aisle("CDDDC", "CBBBC", "CEFEC", "BDDDB", "BBGBB") + .aisle("CDDDC", "BDBDB", "BDEDB", "BBDBB", "BBBBB") + .aisle("BCCCB", "BBHBB", "BBCBB", "BBBBB", "BBBBB") + .where('B', Predicates.any()) + .where('C', Predicates.blocks('gtceu:steam_machine_casing').setMinGlobalLimited(10) + .or(Predicates.abilities(PartAbility.STEAM_IMPORT_ITEMS).setMaxGlobalLimited(1)) + .or(Predicates.abilities(PartAbility.STEAM).setMaxGlobalLimited(1)) + .or(Predicates.abilities(PartAbility.STEAM_EXPORT_ITEMS).setMaxGlobalLimited(1))) + .where('D', Predicates.blocks("gtceu:industrial_steam_casing")) + .where('E', Predicates.blocks("gtceu:bronze_brick_casing")) + .where('F', Predicates.blocks("gtceu:bronze_firebox_casing")) + .where('G', Predicates.blocks("gtceu:bronze_machine_casing")) + .where('H', Predicates.controller(Predicates.blocks(definition.get()))) + .build()) + .workableCasingModel("gtceu:block/casings/steam/bronze/bottom", + "gtceu:block/machines/compressor") + }) + ``` + +=== "Java" + ```java title="MultiMachines.java" + public static final MultiblockMachineDefinition LARGE_STEAM_COMPRESSOR = REGISTRATE + .multiblock("large_steam_compressor", (holder) -> new SteamParallelMultiblockMachine(holder, 4)) + .rotationState(RotationState.NON_Y_AXIS) + .recipeType(COMPRESSOR_RECIPES) + .recipeModifier((machine, recipe) -> SteamParallelMultiblockMachine.recipeModifier(machine, recipe), true) + .appearanceBlock(GTBlocks.BRONZE_HULL) + .pattern(definition -> FactoryBlockPattern.start() + .aisle("BCCCB", "BBCBB", "BBCBB", "BBBBB", "BBBBB") + .aisle("CDDDC", "BDBDB", "BDEDB", "BBDBB", "BBBBB") + .aisle("CDDDC", "CBBBC", "CEFEC", "BDDDB", "BBGBB") + .aisle("CDDDC", "BDBDB", "BDEDB", "BBDBB", "BBBBB") + .aisle("BCCCB", "BBHBB", "BBCBB", "BBBBB", "BBBBB") + .where('B', Predicates.any()) + .where('C', Predicates.blocks(GTBlocks.CASING_BRONZE_BRICKS.get()).setMinGlobalLimited(10) + .or(Predicates.abilities(PartAbility.STEAM_IMPORT_ITEMS).setMaxGlobalLimited(1)) + .or(Predicates.abilities(PartAbility.STEAM).setMaxGlobalLimited(1)) + .or(Predicates.abilities(PartAbility.STEAM_EXPORT_ITEMS).setMaxGlobalLimited(1))) + .where('D', Predicates.blocks(GCYMBlocks.CASING_INDUSTRIAL_STEAM.get())) + .where('E', Predicates.blocks(GTBlocks.BRONZE_BRICKS_HULL.get())) + .where('F', Predicates.blocks(GTBlocks.FIREBOX_BRONZE.get())) + .where('G', Predicates.blocks(GTBlocks.BRONZE_HULL.get())) + .where('H', Predicates.controller(Predicates.blocks(definition.get()))) + .build()) + .workableCasingModel(GTCEu.id("block/casings/steam/bronze/bottom"), + GTCEu.id("block/machines/compressor")) + .register(); + ``` + +### Lang + +```json title="en_us.json" +{ + "block.gtceu.large_steam_compressor": "Large Steam Compressor", +} +``` + + + + + diff --git a/docs/content/Modpacks/Examples/Multiblocks/Example_Turbine.md b/docs/content/Modpacks/Examples/Multiblocks/Example_Turbine.md new file mode 100644 index 00000000000..bd7ae77a838 --- /dev/null +++ b/docs/content/Modpacks/Examples/Multiblocks/Example_Turbine.md @@ -0,0 +1,95 @@ +--- +title: "Example Turbine" +--- + +### Example Turbine + +Below is an example of a multiblock using the LargeTurbineMachine class for making custom large turbines. + +### Multiblock + +=== "JavaScript" + ```js title="hyper_gas_turbine.js" + // In order to use multiblock logic extending beyond the normal WorkableElectricMultiblockMachine, (This is the multiblock type used by default for kubejs) you need to load a class. LargeTurbineMachines such as the gas, steam, and plasma turbines use this class. + const $LargeTurbineMachine = Java.loadClass("com.gregtechceu.gtceu.common.machine.multiblock.generator.LargeTurbineMachine") + + GTCEuStartupEvents.registry('gtceu:machine', event => { + event.create('hyper_gas_turbine', 'multiblock') + .machine((holder) => new $LargeTurbineMachine(holder, GTValues.LuV)) // The value shows one rotor holder tier above the recommended minimum rotor holder. The tier of rotor holder provides a boost based on the efficiency stat. + .rotationState(RotationState.NON_Y_AXIS) + .recipeTypes("gas_turbine") + .recipeModifiers([GTRecipeModifiers.OC_NON_PERFECT_SUBTICK, GTRecipeModifiers.BATCH_MODE, (machine, recipe) => GTRecipeModifiers.LargeTurbineMachine(machine, recipe)]) + .appearanceBlock(GTBlocks.CASING_STAINLESS_TURBINE) + .pattern(definition => FactoryBlockPattern.start() + .aisle("BBBBBBB", "BBBCBBB", "BBBDBBB", "BBBCBBB", "BBBBBBB") + .aisle("BBBCBBB", "BBCACBB", "BBCFCBB", "BBCACBB", "BBBCBBB") + .aisle("BBCCCBB", "BCAAACB", "BCAFACB", "BCAFACB", "BBCCCBB") + .aisle("BCCCCCB", "CAAFAAC", "CFFFFFC", "CAFFFAC", "BCCECCB") + .aisle("BBCCCBB", "BCAAACB", "BCAFACB", "BCAFACB", "BBCCCBB") + .aisle("BBBCBBB", "BBCACBB", "BBCFCBB", "BBCACBB", "BBBCBBB") + .aisle("BBBBBBB", "BBBCBBB", "BBBGBBB", "BBBCBBB", "BBBBBBB") + .where("A", Predicates.blocks("minecraft:air")) + .where("B", Predicates.any()) + .where("C", Predicates.blocks("gtceu:stainless_steel_turbine_casing") + .or(Predicates.autoAbilities(definition.getRecipeTypes())) + .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))) + .where("D", Predicates.ability(PartAbility.MUFFLER).setExactLimit(1)) + .where("E", Predicates.ability(PartAbility.ROTOR_HOLDER).setExactLimit(1)) + .where("F", Predicates.blocks("gtceu:stainless_steel_frame")) + .where("G", Predicates.controller(Predicates.blocks(definition.get()))) + .build()) + .workableCasingModel("gtceu:block/casings/mechanic/machine_casing_turbine_stainless_steel", + "gtceu:block/multiblock/generator/large_gas_turbine") + }); + ``` + +=== "Java" + ```java title="MultiMachines.java" + public static final MultiblockMachineDefinition HYPER_GAS_TURBINE = REGISTRATE + .multiblock("hyper_gas_turbine", (holder) -> new LargeTurbineMachine(holder, GTValues.LuV)) // The value shows one rotor holder tier above the recommended minimum rotor holder. The tier of rotor holder provides a boost based on the efficiency stat. + .rotationState(RotationState.NON_Y_AXIS) + .recipeType(GTRecipeTypes.GAS_TURBINE_FUELS) + .recipeModifiers(GTRecipeModifiers.OC_NON_PERFECT_SUBTICK, GTRecipeModifiers.BATCH_MODE, LargeTurbineMachine::recipeModifier) + .appearanceBlock(GTBlocks.CASING_STAINLESS_TURBINE) + .pattern(definition -> FactoryBlockPattern.start() + .aisle("BBBBBBB", "BBBCBBB", "BBBDBBB", "BBBCBBB", "BBBBBBB") + .aisle("BBBCBBB", "BBCACBB", "BBCECBB", "BBCACBB", "BBBCBBB") + .aisle("BBCCCBB", "BCAAACB", "BCAEACB", "BCAEACB", "BBCCCBB") + .aisle("BCCCCCB", "CAAEAAC", "CEEEEEC", "CAEEEAC", "BCCFCCB") + .aisle("BBCCCBB", "BCAAACB", "BCAEACB", "BCAEACB", "BBCCCBB") + .aisle("BBBCBBB", "BBCACBB", "BBCECBB", "BBCACBB", "BBBCBBB") + .aisle("BBBBBBB", "BBBCBBB", "BBBGBBB", "BBBCBBB", "BBBBBBB") + .where("A", Predicates.blocks("minecraft:air")) + .where("B", Predicates.any()) + .where("C", Predicates.blocks("gtceu:stainless_steel_turbine_casing") + .or(Predicates.autoAbilities(definition.getRecipeTypes())) + .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1))) + .where("D", Predicates.ability(PartAbility.MUFFLER).setExactLimit(1)) + .where("F", Predicates.ability(PartAbility.ROTOR_HOLDER).setExactLimit(1)) + .where("E", Predicates.blocks("gtceu:stainless_steel_frame")) + .where("G", Predicates.controller(Predicates.blocks(definition.get()))) + .build()) + .workableCasingModel(GTCEu.id("block/casings/steam/bronze/bottom"), + GTCEu.id("block/machines/compressor")) + .register(); + ``` + + +### Lang + +```json title="en_us.json" +{ + "block.gtceu.hyper_gas_turbine": "Hyper Gas Turbine", +} +``` + + + + + + + + + + + diff --git a/docs/content/Modpacks/Examples/Multiblocks/Greenhouse.md b/docs/content/Modpacks/Examples/Multiblocks/Greenhouse.md new file mode 100644 index 00000000000..76bbe0754b2 --- /dev/null +++ b/docs/content/Modpacks/Examples/Multiblocks/Greenhouse.md @@ -0,0 +1,386 @@ +--- +title: "Greenhouse" +--- + + +# Greenhouse Multiblock (by Drack.ion) + + +## Recipe Type + +=== "JavaScript" + ```js title="greenhouse_recipe_type.js" + GTCEuStartupEvents.registry('gtceu:recipe_type', event => { + event.create('greenhouse') + .category('drack') + .setEUIO('in') + .setMaxIOSize(3, 4, 1, 0) + .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT) + .setSound(GTSoundEntries.BATH) + }) + ``` + +=== "Java" + ```java title="RecipeTypes.java" + public final static GTRecipeType GREENHOUSE_RECIPES = register("greenhouse", MULTIBLOCK) + .setMaxIOSize(2, 1, 1, 1) + .setEUIO(IO.IN) + .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, ProgressTexture.FillDirection.LEFT_TO_RIGHT) + .setSound(GTSoundEntries.BATH); + ``` + +## Multiblock +=== "JavaScript" + ```js title="greenhouse_multiblock.js" + const $RecipeLogic = Java.loadClass('com.gregtechceu.gtceu.api.machine.trait.RecipeLogic') + const $List = Java.loadClass('java.util.List') + + GTCEuStartupEvents.registry('gtceu:machine', event => { + event.create('greenhouse', 'multiblock') + .rotationState(RotationState.NON_Y_AXIS) + .recipeType('greenhouse') + .appearanceBlock(GTBlocks.CASING_STEEL_SOLID) + .pattern(definition => FactoryBlockPattern.start() + .aisle('CCC', 'CGC', 'CGC', 'CLC', 'CCC') + .aisle('CMC', 'G#G', 'G#G', 'LIL', 'COC') + .aisle('CKC', 'CGC', 'CGC', 'CLC', 'CNC') + .where('K', Predicates.controller(Predicates.blocks(definition.get()))) + .where('M', Predicates.blocks('moss_block') + .or(Predicates.blocks('dirt')) + .or(Predicates.blocks('grass_block')) + ) + .where('G', Predicates.blocks('ae2:quartz_glass')) + .where('I', Predicates.blocks('glowstone')) + .where('L', Predicates.blocks(GTBlocks.CASING_GRATE.get())) + .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get()) + .or(Predicates.autoAbilities(definition.getRecipeTypes())) + ) + .where('O', Predicates.abilities(PartAbility.MUFFLER) + .setExactLimit(1) + ) + .where('N', Predicates.abilities(PartAbility.MAINTENANCE)) + .where('#', Predicates.air()) + .build() + ) + .modelProperty(GTModelProperties.RECIPE_LOGIC_STATUS, $RecipeLogic.Status.IDLE) + .model(GTMachineModels.createWorkableCasingMachineModel(GTCEu.id("block/casings/solid/machine_casing_solid_steel"), GTCEu.id("block/multiblock/implosion_compressor")) + ["andThen(java.util.function.Consumer)"](b => b.addDynamicRenderer(() => GTDynamicRenders.makeGrowingPlantRender($List.of(new Vector3f(0, 1, -1))))) + ) + }) + ``` +=== "Java" + ```java title="MultiMachines.java" + public static final MultiblockMachineDefinition GREENHOUSE = REGISTRATE + .multiblock("greenhouse", WorkableElectricMultiblockMachine::new) + .rotationState(RotationState.NON_Y_AXIS) + .recipeType(RecipeTypes.GREENHOUSE_RECIPES) + .appearanceBlock(GTBlocks.CASING_STEEL_SOLID) + .pattern(definition -> FactoryBlockPattern.start() + .aisle("CCC", "CGC", "CGC", "CLC", "CCC") + .aisle("CMC", "G#G", "G#G", "LIL", "COC") + .aisle("CKC", "CGC", "CGC", "CLC", "CNC") + .where('K', Predicates.controller(Predicates.blocks(definition.get()))) + .where('M', Predicates.blocks(Blocks.MOSS_BLOCK) + .or(Predicates.blocks(Blocks.DIRT)) + .or(Predicates.blocks(Blocks.GRASS_BLOCK))) + .where('G', Predicates.blocks(AEBlocks.QUARTZ_GLASS.block())) + .where('I', Predicates.blocks(Blocks.GLOWSTONE)) + .where('L', Predicates.blocks(GTBlocks.CASING_GRATE.get())) + .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get()) + .or(Predicates.autoAbilities(definition.getRecipeTypes()))) + .where('O', Predicates.abilities(PartAbility.MUFFLER) + .setExactLimit(1)) + .where('N', Predicates.abilities(PartAbility.MAINTENANCE)) + .where('#', Predicates.air()) + .build()) + .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE) + .model(GTMachineModels.createWorkableCasingMachineModel(GTCEu.id("block/casings/solid/machine_casing_solid_steel"), GTCEu.id("block/multiblock/implosion_compressor")) + .andThen(b -> b.addDynamicRenderer(() -> GTDynamicRenders.makeGrowingPlantRender(List.of(new Vector3f(0, 1, -1)))))) + .register(); + ``` + + + +## Lang + +```json title="en_us.json" +{ + "block.gtceu.greenhouse": "Greenhouse", + "gtceu.greenhouse": "Greenhouse" +} +``` + + +## Recipes + +=== "JavaScript" + ```js title="greenhouse_recipes.js" + ServerEvents.recipes(event => { + + ////// Machine Recipe ////// + + event.shaped( + 'gtceu:greenhouse', + ['AWA', 'ASA', 'WAW'], + { + A: '#forge:circuits/mv', + W: 'gtceu:copper_single_cable', + S: 'gtceu:solid_machine_casing' + } + ).id('gtceu:shaped/greenhouse') + + + ////// Greenhouse Recipes ////// + + function Greenhouse(id, input, fluid, output, boosted) { + if (boosted) { + event.recipes.gtceu.greenhouse(id) + .circuit(2) + .notConsumable(InputItem.of(input)) + .itemInputs('4x gtceu:fertilizer') + .inputFluids(Fluid.of('minecraft:water', fluid)) + .itemOutputs(output) + .duration(320) + .EUt(MV) + } else { + event.recipes.gtceu.greenhouse(id) + .circuit(1) + .notConsumable(InputItem.of(input)) + .inputFluids(Fluid.of('minecraft:water', fluid)) + .itemOutputs(output) + .duration(640) + .EUt(MV) + } + } + + + ////// Trees ////// + + // Rubber + Greenhouse('rubber_sapling', 'gtceu:rubber_sapling', 1000, ['32x gtceu:rubber_log', '8x gtceu:sticky_resin', '4x gtceu:rubber_sapling'], false) + Greenhouse('rubber_sapling_boosted', 'gtceu:rubber_sapling', 1000, ['64x gtceu:rubber_log', '16x gtceu:sticky_resin', '4x gtceu:rubber_sapling'], true) + + // Oak + Greenhouse('oak_sapling', 'minecraft:oak_sapling', 1000, ['64x minecraft:oak_log', '4x minecraft:oak_sapling'], false) + Greenhouse('oak_sapling_boosted', 'minecraft:oak_sapling', 1000, ['64x minecraft:oak_log', '64x minecraft:oak_log', '4x minecraft:oak_sapling'], true) + + // Dark Oak + Greenhouse('dark_oak_sapling', 'minecraft:dark_oak_sapling', 1000, ['64x minecraft:dark_oak_log', '4x minecraft:dark_oak_sapling'], false) + Greenhouse('dark_oak_sapling_boosted', 'minecraft:dark_oak_sapling', 1000, ['64x minecraft:dark_oak_log', '64x minecraft:dark_oak_log', '4x minecraft:dark_oak_sapling'], true) + + // Spruce + Greenhouse('spruce_sapling', 'minecraft:spruce_sapling', 1000, ['64x minecraft:spruce_log', '4x minecraft:spruce_sapling'], false) + Greenhouse('spruce_sapling_boosted', 'minecraft:spruce_sapling', 1000, ['64x minecraft:spruce_log', '64x minecraft:spruce_log', '4x minecraft:spruce_sapling'], true) + + // Birch + Greenhouse('birch_sapling', 'minecraft:birch_sapling', 1000, ['64x minecraft:birch_log', '4x minecraft:birch_sapling'], false) + Greenhouse('birch_sapling_boosted', 'minecraft:birch_sapling', 1000, ['64x minecraft:birch_log', '64x minecraft:birch_log', '4x minecraft:birch_sapling'], true) + + // Acacia + Greenhouse('acacia_sapling', 'minecraft:acacia_sapling', 1000, ['64x minecraft:acacia_log', '4x minecraft:acacia_sapling'], false) + Greenhouse('acacia_sapling_boosted', 'minecraft:acacia_sapling', 1000, ['64x minecraft:acacia_log', '64x minecraft:acacia_log', '4x minecraft:acacia_sapling'], true) + + // Jungle + Greenhouse('jungle_sapling', 'minecraft:jungle_sapling', 1000, ['64x minecraft:jungle_log', '4x minecraft:jungle_sapling'], false) + Greenhouse('jungle_sapling_boosted', 'minecraft:jungle_sapling', 1000, ['64x minecraft:jungle_log', '64x minecraft:jungle_log', '4x minecraft:jungle_sapling'], true) + + // Azalea + Greenhouse('azalea_sapling', 'minecraft:azalea', 1000, ['64x minecraft:oak_log', '4x minecraft:azalea'], false) + Greenhouse('azalea_boosted', 'minecraft:azalea', 1000, ['64x minecraft:oak_log', '64x minecraft:oak_log', '4x minecraft:azalea'], true) + + // Flowering Azalea + Greenhouse('flowering_azalea', 'minecraft:flowering_azalea', 1000, ['64x minecraft:oak_log', '4x minecraft:flowering_azalea'], false) + Greenhouse('flowering_azalea_boosted', 'minecraft:flowering_azalea', 1000, ['64x minecraft:oak_log', '64x minecraft:oak_log', '4x minecraft:flowering_azalea'], true) + + // Mangrove + Greenhouse('mangrove_propagule', 'minecraft:mangrove_propagule', 1000, ['64x minecraft:mangrove_log', '4x minecraft:mangrove_propagule'], false) + Greenhouse('mangrove_propagule_boosted', 'minecraft:mangrove_propagule', 1000, ['64x minecraft:mangrove_log', '64x minecraft:mangrove_log', '4x minecraft:mangrove_propagule'], true) + + ////// Crops ////// + + // Sugarcane + Greenhouse('sugar_cane', 'minecraft:sugar_cane', 1000, '24x minecraft:sugar_cane', false) + Greenhouse('sugar_cane_boosted', 'minecraft:sugar_cane', 1000, '48x minecraft:sugar_cane', true) + + // Kelp + Greenhouse('kelp', 'minecraft:kelp', 2000, '24x minecraft:kelp', false) + Greenhouse('kelp_boosted', 'minecraft:kelp', 2000, '48x minecraft:kelp', true) + + // Bamboo + Greenhouse('bamboo', 'minecraft:bamboo', 1000, '24x minecraft:bamboo', false) + Greenhouse('bamboo_boosted', 'minecraft:bamboo', 1000, '48x minecraft:bamboo', true) + + // Cactus + Greenhouse('cactus', 'minecraft:cactus', 1000, '24x minecraft:cactus', false) + Greenhouse('cactus_boosted', 'minecraft:cactus', 1000, '48x minecraft:cactus', true) + + // Wheat + Greenhouse('wheat', 'minecraft:wheat_seeds', 1000, '24x minecraft:wheat', false) + Greenhouse('wheat_boosted', 'minecraft:wheat_seeds', 1000, '48x minecraft:wheat', true) + + // Carrot + Greenhouse('carrot', 'minecraft:carrot', 1000, '24x minecraft:carrot', false) + Greenhouse('carrot_boosted', 'minecraft:carrot', 1000, '48x minecraft:carrot', true) + + // Potato + Greenhouse('potato', 'minecraft:potato', 1000, '24x minecraft:potato', false) + Greenhouse('potato_boosted', 'minecraft:potato', 1000, '48x minecraft:potato', true) + + // Beetroot + Greenhouse('beetroot', 'minecraft:beetroot_seeds', 1000, '24x minecraft:beetroot', false) + Greenhouse('beetroot_boosted', 'minecraft:beetroot_seeds', 1000, '48x minecraft:beetroot', true) + + // Mellon + Greenhouse('melon', 'minecraft:melon_seeds', 1000, '12x minecraft:melon', false) + Greenhouse('melon_boosted', 'minecraft:melon_seeds', 1000, '24x minecraft:melon', true) + + // Pumpkin + Greenhouse('pumpkin', 'minecraft:pumpkin_seeds', 1000, '12x minecraft:pumpkin', false) + Greenhouse('pumpkin_boosted', 'minecraft:pumpkin_seeds', 1000, '24x minecraft:pumpkin', true) + + // Nether Wart + Greenhouse('nether_wart', 'minecraft:nether_wart', 1000, '12x minecraft:nether_wart', false) + Greenhouse('nether_wart_boosted', 'minecraft:nether_wart', 1000, '24x minecraft:nether_wart', true) + + // Red Mushroom + Greenhouse('red_mushroom', 'minecraft:red_mushroom', 1000, '12x minecraft:red_mushroom', false) + Greenhouse('red_mushroom_boosted', 'minecraft:red_mushroom', 1000, '24x minecraft:red_mushroom', true) + + // Brown Mushroom + Greenhouse('brown_mushroom', 'minecraft:brown_mushroom', 1000, '12x minecraft:brown_mushroom', false) + Greenhouse('brown_mushroom_boosted', 'minecraft:brown_mushroom', 1000, '24x minecraft:brown_mushroom', true) + }) + ``` + +=== "Java" + ```java title="Recipes.java" + private static void greenhouseHelper(Consumer provider, String id, Item input, ItemStack output_normal, ItemStack output_boosted) { + greenhouseHelper(provider, id, input, List.of(output_normal), List.of(output_boosted)); + + } + private static void greenhouseHelper(Consumer provider, String id, Item input, List output_normal, List output_boosted) { + + GREENHOUSE_RECIPES.recipeBuilder(id) + .circuitMeta(2) + .notConsumable(input) + .inputItems(FERTILIZER.get(), 4) + .inputFluids(Water, 1000) + .outputItems(output_normal) + .duration(320) + .EUt(MV) + .save(provider); + GREENHOUSE_RECIPES.recipeBuilder(id + "_boosted") + .circuitMeta(1) + .notConsumable(input) + .inputFluids(Water, 1000) + .outputItems(output_boosted) + .duration(320) + .EUt(MV) + .save(provider); + } + + private static void loadGreenhouseRecipes(Consumer provider){ + VanillaRecipeHelper.addShapedRecipe(provider, true, GTCEu.id("greenhouse"), + GTMultiMachines.GREENHOUSE.asStack(), + "AWA", + "ASA", + "WAW", + "A", CustomTags.MV_CIRCUITS, + "W", ChemicalHelper.get(TagPrefix.wireGtSingle, GTMaterials.Copper), + "S", GTBlocks.CASING_STEEL_SOLID.asItem()); + + // Rubber + greenhouseHelper(provider, "rubber_sapling", GTBlocks.RUBBER_SAPLING.asItem(), + List.of(new ItemStack(GTBlocks.RUBBER_LOG.get(), 64), new ItemStack(GTItems.STICKY_RESIN.get(), 8), new ItemStack(GTBlocks.RUBBER_SAPLING.asItem(), 4)), + List.of(new ItemStack(GTBlocks.RUBBER_LOG.get(), 64), new ItemStack(GTItems.STICKY_RESIN.get(), 16), new ItemStack(GTBlocks.RUBBER_SAPLING.asItem(), 4))); + + // Oak + greenhouseHelper(provider, "oak_sapling", Blocks.OAK_SAPLING.asItem(), + List.of(new ItemStack(Blocks.OAK_LOG, 64), new ItemStack(Blocks.OAK_SAPLING.asItem(), 4)), + List.of(new ItemStack(Blocks.OAK_LOG, 64), new ItemStack(Blocks.OAK_LOG, 64), new ItemStack(Blocks.OAK_SAPLING.asItem(), 4))); + + // Dark Oak + greenhouseHelper(provider, "dark_oak_sapling", Blocks.DARK_OAK_SAPLING.asItem(), + List.of(new ItemStack(Blocks.DARK_OAK_LOG, 64), new ItemStack(Blocks.DARK_OAK_SAPLING.asItem(), 4)), + List.of(new ItemStack(Blocks.DARK_OAK_LOG, 64), new ItemStack(Blocks.DARK_OAK_LOG, 64), new ItemStack(Blocks.DARK_OAK_SAPLING.asItem(), 4))); + + // Spruce + greenhouseHelper(provider, "spruce_sapling", Blocks.SPRUCE_SAPLING.asItem(), + List.of(new ItemStack(Blocks.SPRUCE_LOG, 64), new ItemStack(Blocks.SPRUCE_SAPLING.asItem(), 4)), + List.of(new ItemStack(Blocks.SPRUCE_LOG, 64), new ItemStack(Blocks.SPRUCE_LOG, 64), new ItemStack(Blocks.SPRUCE_SAPLING.asItem(), 4))); + + // Birch + greenhouseHelper(provider, "birch_sapling", Blocks.BIRCH_SAPLING.asItem(), + List.of(new ItemStack(Blocks.BIRCH_LOG, 64), new ItemStack(Blocks.BIRCH_SAPLING.asItem(), 4)), + List.of(new ItemStack(Blocks.BIRCH_LOG, 64), new ItemStack(Blocks.BIRCH_LOG, 64), new ItemStack(Blocks.BIRCH_SAPLING.asItem(), 4))); + + // Acacia + greenhouseHelper(provider, "acacia_sapling", Blocks.ACACIA_SAPLING.asItem(), + List.of(new ItemStack(Blocks.ACACIA_LOG, 64), new ItemStack(Blocks.ACACIA_SAPLING.asItem(), 4)), + List.of(new ItemStack(Blocks.ACACIA_LOG, 64), new ItemStack(Blocks.ACACIA_LOG, 64), new ItemStack(Blocks.ACACIA_SAPLING.asItem(), 4))); + + // Jungle + greenhouseHelper(provider, "jungle_sapling", Blocks.JUNGLE_SAPLING.asItem(), + List.of(new ItemStack(Blocks.JUNGLE_LOG, 64), new ItemStack(Blocks.JUNGLE_SAPLING.asItem(), 4)), + List.of(new ItemStack(Blocks.JUNGLE_LOG, 64), new ItemStack(Blocks.JUNGLE_LOG, 64), new ItemStack(Blocks.JUNGLE_SAPLING.asItem(), 4))); + + + // Azalea + greenhouseHelper(provider, "azalea_sapling", Blocks.AZALEA.asItem(), + List.of(new ItemStack(Blocks.OAK_LOG, 64), new ItemStack(Blocks.AZALEA.asItem(), 4)), + List.of(new ItemStack(Blocks.OAK_LOG, 64), new ItemStack(Blocks.OAK_LOG, 64), new ItemStack(Blocks.AZALEA.asItem(), 4))); + + + // Flowering Azalea + greenhouseHelper(provider, "flowering_azalea", Blocks.FLOWERING_AZALEA.asItem(), + List.of(new ItemStack(Blocks.OAK_LOG, 64), new ItemStack(Blocks.FLOWERING_AZALEA.asItem(), 4)), + List.of(new ItemStack(Blocks.OAK_LOG, 64), new ItemStack(Blocks.OAK_LOG, 64), new ItemStack(Blocks.AZALEA.asItem(), 4))); + + // Mangrove + greenhouseHelper(provider, "mangrove_propagule", Blocks.MANGROVE_PROPAGULE.asItem(), + List.of(new ItemStack(Blocks.MANGROVE_LOG, 64), new ItemStack(Blocks.MANGROVE_PROPAGULE.asItem(), 4)), + List.of(new ItemStack(Blocks.MANGROVE_LOG, 64), new ItemStack(Blocks.MANGROVE_LOG, 64), new ItemStack(Blocks.MANGROVE_PROPAGULE.asItem(), 4))); + + + ////// Crops ////// + + // Sugarcane + greenhouseHelper(provider, "sugar_cane", Items.SUGAR_CANE, new ItemStack(Items.SUGAR_CANE, 24), new ItemStack(Items.SUGAR_CANE, 48)); + + // Kelp + greenhouseHelper(provider, "kelp", Items.KELP, new ItemStack(Items.KELP, 24), new ItemStack(Items.KELP, 48)); + + // Bamboo + greenhouseHelper(provider, "bamboo", Items.BAMBOO, new ItemStack(Items.BAMBOO, 24), new ItemStack(Items.BAMBOO, 48)); + + // Cactus + greenhouseHelper(provider, "cactus", Items.CACTUS, new ItemStack(Items.CACTUS, 24), new ItemStack(Items.CACTUS, 48)); + + // Wheat + greenhouseHelper(provider, "wheat", Items.WHEAT_SEEDS, new ItemStack(Items.WHEAT, 24), new ItemStack(Items.WHEAT, 48)); + + // Carrot + greenhouseHelper(provider, "carrot", Items.CARROT, new ItemStack(Items.CARROT, 24), new ItemStack(Items.CARROT, 48)); + + // Potato + greenhouseHelper(provider, "potato", Items.POTATO, new ItemStack(Items.POTATO, 24), new ItemStack(Items.POTATO, 48)); + + // Beetroot + greenhouseHelper(provider, "beetroot", Items.BEETROOT_SEEDS, new ItemStack(Items.BEETROOT, 24), new ItemStack(Items.BEETROOT, 48)); + + // Mellon + greenhouseHelper(provider, "melon", Items.MELON_SEEDS, new ItemStack(Items.MELON, 12), new ItemStack(Items.MELON, 24)); + + // Pumpkin + greenhouseHelper(provider, "pumpkin", Items.PUMPKIN_SEEDS, new ItemStack(Items.PUMPKIN, 12), new ItemStack(Items.PUMPKIN, 24)); + + // Nether Wart + greenhouseHelper(provider, "nether_wart", Items.NETHER_WART, new ItemStack(Items.NETHER_WART, 12), new ItemStack(Items.NETHER_WART, 24)); + + // Red Mushroom + greenhouseHelper(provider, "red_mushroom", Items.RED_MUSHROOM, new ItemStack(Items.RED_MUSHROOM, 12), new ItemStack(Items.RED_MUSHROOM, 24)); + + // Brown Mushroom + greenhouseHelper(provider, "brown_mushroom", Items.BROWN_MUSHROOM, new ItemStack(Items.BROWN_MUSHROOM, 12), new ItemStack(Items.BROWN_MUSHROOM, 24)) + } + ``` \ No newline at end of file diff --git a/docs/content/Modpacks/Examples/Multiblocks/Ore-Processing-Plant.md b/docs/content/Modpacks/Examples/Multiblocks/Ore-Processing-Plant.md new file mode 100644 index 00000000000..7db24432958 --- /dev/null +++ b/docs/content/Modpacks/Examples/Multiblocks/Ore-Processing-Plant.md @@ -0,0 +1,105 @@ +--- +title: "Ore Processing Plant" +--- + + +# Ore Processing Plant Multiblock (by trulyno) + +## Recipe Type + +=== "JavaScript" + ```js title="ore_processing_plant.js" + GTCEuStartupEvents.registry('gtceu:recipe_type', event => { + event.create('ore_processing_plant') + .category('ore_processing_plant') + .setEUIO('in') + .setMaxIOSize(1, 8, 2, 1) + .setSound(GTSoundEntries.BATH); + }); + ``` + +=== "Java" + ```java title="RecipeTypes.java" + public final static GTRecipeType ORE_PROCESSING_RECIPES = register("ore_processing_plant", MULTIBLOCK) + .setMaxIOSize(1, 8, 2, 1) + .setEUIO(IO.IN) + .setSound(GTSoundEntries.BATH); + ``` + + +## Multiblock +=== "JavaScript" + ```js title="ore_processing_plant.js" + GTCEuStartupEvents.registry('gtceu:machine', event => { + event.create('ore_processing_plant', 'multiblock') + .rotationState(RotationState.NON_Y_AXIS) + .recipeType('ore_processing_plant') + .recipeModifiers(GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.ELECTRIC_OVERCLOCK.apply(OverclockingLogic.PERFECT_OVERCLOCK)) + .appearanceBlock(GTBlocks.CASING_TUNGSTENSTEEL_ROBUST) + .pattern(definition => FactoryBlockPattern.start() + .aisle(' AAA ', ' FFF ', ' FFF ', ' F ', ' ', ' ', ' ') + .aisle('AFFFA', 'FG GF', 'F F', ' F F ', ' FFF ', ' F ', ' B ') + .aisle('AFFFA', 'F P F', 'F P F', 'F P F', ' FPF ', ' FMF ', ' B B ') + .aisle('AFFFA', 'FG GF', 'F F', ' F F ', ' FFF ', ' F ', ' B ') + .aisle(' AAA ', ' FCF ', ' FFF ', ' F ', ' ', ' ', ' ') + .where('C', Predicates.controller(Predicates.blocks(definition.get()))) + .where('F', Predicates.blocks(GTBlocks.CASING_TUNGSTENSTEEL_ROBUST.get()) + .or(Predicates.autoAbilities(definition.getRecipeTypes())) + .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1)) + .or(Predicates.abilities(PartAbility.PARALLEL_HATCH).setMaxGlobalLimited(1))) + .where('M', Predicates.abilities(PartAbility.MUFFLER)) + .where('P', Predicates.blocks(GTBlocks.CASING_TUNGSTENSTEEL_PIPE.get())) + .where('G', Predicates.blocks(GTBlocks.CASING_TUNGSTENSTEEL_GEARBOX.get())) + .where('A', Predicates.blocks(GTBlocks.FIREBOX_TUNGSTENSTEEL.get())) + .where('B', Predicates.blocks('gtceu:bronze_machine_casing')) + .where(' ', Predicates.any()) + .build()) + .workableCasingModel( + "gtceu:block/casings/solid/machine_casing_robust_tungstensteel", + "gtceu:block/multiblock/primitive_blast_furnace" + ); + }) + ``` + +=== "Java" + ```java title="MultiMachines.java" + public static final MultiblockMachineDefinition ORE_PROCESSING_PLANT = REGISTRATE + .multiblock("ore_processing_plant", WorkableElectricMultiblockMachine::new) + .rotationState(RotationState.NON_Y_AXIS) + .recipeType(RecipeTypes.ORE_PROCESSING_PLANT) + .recipeModifiers(GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.ELECTRIC_OVERCLOCK.apply(OverclockingLogic.PERFECT_OVERCLOCK)) + .appearanceBlock(GTBlocks.CASING_TUNGSTENSTEEL_ROBUST) + .pattern(definition => FactoryBlockPattern.start() + .aisle(' AAA ', ' FFF ', ' FFF ', ' F ', ' ', ' ', ' ') + .aisle('AFFFA', 'FG GF', 'F F', ' F F ', ' FFF ', ' F ', ' B ') + .aisle('AFFFA', 'F P F', 'F P F', 'F P F', ' FPF ', ' FMF ', ' B B ') + .aisle('AFFFA', 'FG GF', 'F F', ' F F ', ' FFF ', ' F ', ' B ') + .aisle(' AAA ', ' FCF ', ' FFF ', ' F ', ' ', ' ', ' ') + .where('C', Predicates.controller(Predicates.blocks(definition.get()))) + .where('F', Predicates.blocks(GTBlocks.CASING_TUNGSTENSTEEL_ROBUST.get()) + .or(Predicates.autoAbilities(definition.getRecipeTypes())) + .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1)) + .or(Predicates.abilities(PartAbility.PARALLEL_HATCH).setMaxGlobalLimited(1))) + .where('M', Predicates.abilities(PartAbility.MUFFLER)) + .where('P', Predicates.blocks(GTBlocks.CASING_TUNGSTENSTEEL_PIPE.get())) + .where('G', Predicates.blocks(GTBlocks.CASING_TUNGSTENSTEEL_GEARBOX.get())) + .where('A', Predicates.blocks(GTBlocks.FIREBOX_TUNGSTENSTEEL.get())) + .where('B', Predicates.blocks('gtceu:bronze_machine_casing')) + .where(' ', Predicates.any()) + .build()) + .workableCasingModel( + GTCEu.id("block/casings/solid/machine_casing_robust_tungstensteel"), + GTCEu.id("block/multiblock/primitive_blast_furnace") + ) + .register(); + ``` + + +## Lang + +```json title="en_us.json" +{ + "block.gtceu.ore_processing_plant": "Ore Processing Plant", + "gtceu.ore_processing_plant": "Ore Processing" +} +``` \ No newline at end of file diff --git a/docs/content/Modpacks/Examples/Ore-Processing-Plant.md b/docs/content/Modpacks/Examples/Ore-Processing-Plant.md deleted file mode 100644 index 2e83c043852..00000000000 --- a/docs/content/Modpacks/Examples/Ore-Processing-Plant.md +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: "Ore Processing Plant" ---- - - -# Ore Processing Plant Multiblock (by trulyno) - - -## Recipe Type - -```js title="ore_processing_plant.js" -GTCEuStartupEvents.registry('gtceu:recipe_type', event => { - event.create('ore_processing_plant') - .category('ore_processing_plant') - .setEUIO('in') - .setMaxIOSize(1, 8, 2, 1) - .setSound(GTSoundEntries.BATH); -}); -``` - - -## Multiblock - -```js title="ore_processing_plant.js" -GTCEuStartupEvents.registry('gtceu:machine', event => { - event.create('ore_processing_plant', 'multiblock') - .rotationState(RotationState.NON_Y_AXIS) - .recipeType('ore_processing_plant') - .recipeModifiers(GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.ELECTRIC_OVERCLOCK.apply(OverclockingLogic.PERFECT_OVERCLOCK)) - .appearanceBlock(GTBlocks.CASING_TUNGSTENSTEEL_ROBUST) - .pattern(definition => FactoryBlockPattern.start() - .aisle(' AAA ', ' FFF ', ' FFF ', ' F ', ' ', ' ', ' ') - .aisle('AFFFA', 'FG GF', 'F F', ' F F ', ' FFF ', ' F ', ' B ') - .aisle('AFFFA', 'F P F', 'F P F', 'F P F', ' FPF ', ' FMF ', ' B B ') - .aisle('AFFFA', 'FG GF', 'F F', ' F F ', ' FFF ', ' F ', ' B ') - .aisle(' AAA ', ' FCF ', ' FFF ', ' F ', ' ', ' ', ' ') - .where('C', Predicates.controller(Predicates.blocks(definition.get()))) - .where('F', Predicates.blocks(GTBlocks.CASING_TUNGSTENSTEEL_ROBUST.get()) - .or(Predicates.autoAbilities(definition.getRecipeTypes())) - .or(Predicates.abilities(PartAbility.MAINTENANCE).setExactLimit(1)) - .or(Predicates.abilities(PartAbility.PARALLEL_HATCH).setMaxGlobalLimited(1))) - .where('M', Predicates.abilities(PartAbility.MUFFLER)) - .where('P', Predicates.blocks(GTBlocks.CASING_TUNGSTENSTEEL_PIPE.get())) - .where('G', Predicates.blocks(GTBlocks.CASING_TUNGSTENSTEEL_GEARBOX.get())) - .where('A', Predicates.blocks(GTBlocks.FIREBOX_TUNGSTENSTEEL.get())) - .where('B', Predicates.blocks('gtceu:bronze_machine_casing')) - .where(' ', Predicates.any()) - .build()) - .workableCasingRenderer("gtceu:block/casings/solid/machine_casing_robust_tungstensteel", - "gtceu:block/multiblock/primitive_blast_furnace", false); - }) -``` - - -## Lang - -```json title="en_us.json" -{ - "block.gtceu.ore_processing_plant": "Ore Processing Plant", - "gtceu.ore_processing_plant": "Ore Processing" -} -``` \ No newline at end of file diff --git a/docs/content/Modpacks/Examples/Removing-Oil-Sprouts.md b/docs/content/Modpacks/Examples/Removing-Oil-Sprouts.md new file mode 100644 index 00000000000..1d4bed8332a --- /dev/null +++ b/docs/content/Modpacks/Examples/Removing-Oil-Sprouts.md @@ -0,0 +1,29 @@ +--- +title: "Configuring Oil Sprouts" +--- + +# Configuring Oil Sprouts + +!!! warning "This feature is named raw_oil_**sprout**, not raw_oil_spout." + +Oil Sprouts are generated via Minecraft's "Configured Feature" system, and can be customized via standard datapacks. +If you are using kubejs, placing files in the `kubejs/data` folder is equivalent to adding files to a datapack. + +## Removing Oil Sprouts + +To disable oil sprouts entirely, place the following file in `kubejs/data/gtceu/worldgen/configured_feature/raw_oil_sprout.json`, +or create a datapack containing the equivalent. This will replace the sprouts with a `no_op` - i.e. a feature that does nothing. + +```json title="data/gtceu/worldgen/configured_feature/raw_oil_sprout.json" +{ +"type": "minecraft:no_op", +"config": {} +} +``` + +## Adjusting Oil Sprout Placement Conditions + +If you just want to adjust the rarity of oil sprouts, that is configured via the "Placed Feature" system. Copy the +[current version](https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/generated/resources/data/gtceu/worldgen/placed_feature/raw_oil_sprout.json) +of the placed feature file to `kubejs/data/gtceu/worldgen/placed_feature/raw_oil_sprout.json`, and modify the settings +as desired. (The default file uses a `"minecraft:rarity_filter"` to give a 1/64 chance of each chunk containing a sprout.) \ No newline at end of file diff --git a/docs/content/Modpacks/Materials-and-Elements/01-Material-Creation.md b/docs/content/Modpacks/Materials-and-Elements/01-Material-Creation.md index 68fac55d986..4d33d67bb4b 100644 --- a/docs/content/Modpacks/Materials-and-Elements/01-Material-Creation.md +++ b/docs/content/Modpacks/Materials-and-Elements/01-Material-Creation.md @@ -4,57 +4,33 @@ title: Material Creation Materials are in-game items or fluids. They can be dusts, ingots, gems, fluids and all their derivatives. -To make a new material, write an `event.create()` call in the registering function, like in the examples. -Write inside the parentheses the name of the material inside `''` or `""`. -(**NOTE**: to add a material that is present on the periodic table, but doesn't have any in-game items/fluids, look below for how to do it) +!!! note + To add a material that is present on the periodic table, but doesn't have any in-game items/fluids, look at the [material modification page](./Modifying-Existing-Materials.md). You can change the properties of the material by adding any combination of the following calls: - `.ingot()` will make the material have both an ingot and dust form. - `.dust()` will make the material have a dust form. Don't use this together with `.ingot()`. -- `.gem()` will make the material have both a gem form and a dust form. Don't use those together with `.dust()` or `.ingot()` +- `.gem()` will make the material have both a gem form and a dust form. Don't use those together with `.dust()` or `.ingot()`. - `.liquid()` will make the material have a liquid (fluid) form with liquid properties. +- `.block()` will make the material have a placeable (block) fluid form. Requires `.liquid()`. - `.gas()` will make the material have a gas (fluid) form with gas properties. - `.plasma()` will make the material have a plasma (fluid) form with plasma properties. - `.polymer()` will make the material have a dust form with polymer properties. +- `.ore()` will create an ore from the material. + - Optionally you can add any of these sets of parameters: + 1. `boolean isEmissive` -> `true` for emissive textures + 2. `int oreMultiplier, int byproductMultiplier` -> how many crushed ores will be given from one raw ore and how many byproducts dusts will be given throughout the ore processing + 3. `int oreMultiplier, int byproductMultiplier, boolean isEmissive` -> see previous points - `.burnTime(int burnTime)` will turn the material into a furnace fuel. - `.fluidBurnTime(int burnTime)` defines how long the fluid of the material will burn. - `.components(component1, component2, ...)` describes the composition. The components are a list of elements of the following form: `'Kx material_name'`, where `K` is a positive integer. +- `.element(element)` is similar to `.components()`, but is used when the material represents an element. - `.iconSet(set)` gives the material an icon set. -- `.color(int colorCode)` gives the material a color. The color must be provided as a hex value in the following form: `0xNNNNNN`, where `N` are digits. +- `.color(int colorCode)` gives the material a color. The color must be provided as a hex value in the following form: `0xRRGGBB`. - `.secondaryColor(int colorCode)` gives the material a secondary color. If this is not being called, the secondary value will default to white(0xffffff). -- `.flags(flag1, flag2, ...)` can be used to select certain properties of the material, like generating gears, or disabling decomposition. -- `.element(element)` -> similar to `.components()`, but is used when the material represents an element. -- `.rotorStats(speed, damage, durability)` -> this will create a turbine rotor from this material. -- `.blastTemp()` is meant to be paired together with `.ingot()`. Will generate a EBF recipe (and an ABS recipe) based on the parameters you give it: - 1. temperature -> dictates what coil tier it will require (check the coil tooltips for their max temperature). - If the temperature is below 1000, it will also generate a PBF recipe. - If temperature is above 1750, a hot ingot will be generated, this requiring a Vacuum Freezer. - 2. (optional) gas tier -> can be `null` for none, `'low'` for nitrogen, `'mid'` for helium, `'high'` for argon, `'higher'` for neon or `'highest'` for krypton. - 3. (optional) EU per tick -> the recipe voltage - 4. (optional) duration in ticks -> how long the recipe should take -- `.ore()` will create an ore from the material. - - Optionally you can add any of these sets of parameters: - 1. is emissive -> `true` for emissive textures - 2. ore multiplier and byproduct multiplier -> how many crushed ores will be given from one raw ore and how many byproducts dusts will be given throughout the ore processing - 3. ore multiplier, byproduct multiplier, is emissive -- `.washedIn()` -- `.separatedIn()` -- `.separatedInto()` -- `.oreSmeltInto()` -- `.polarizesInto()` -- `.arcSmeltInto()` -- `.maceratesInto()` -- `.ingotSmeltInto()` -- `.addOreByproducts()` -- `.cableProperties()` generates wires and cables(if material is not a superconductor). The following parameter sets can be given: - 1. Voltage, amperage, loss per block - 2. Voltage, amperage, loss per block, is superconductor -> for a super conductor, set loss as 0 and is super conductor as true - 3. Voltage, amperage, loss per block, is super conductor, critical temperature -- `.toolProperties()` -- `.fluidPipeProperties()` -- `.itemPipeProperties()` -- `.addDefaultEnchant()` + - The secondary color is the overlay over the primary color on the material. This can be seen in the dust of a material, as the secondary color outline is visible. Rotors are another solid example. +- `.addDefaultEnchant(string EnchantName, int level)` gives the material a default enchant. !!! tip "Harvest Level & Burn Time" For `.ingot()`, `.dust()` and `.gem()`, optionally you can put inside the parentheses any of these sets of parameters: @@ -62,14 +38,15 @@ You can change the properties of the material by adding any combination of the f 1. harvest level (e.g. `.ingot(2)` will make the material have the harvest level of iron tools) 2. harvest level, burn time (e.g. `ingot(2, 2000)` will make the material have the harvest level of iron tools and will burn in furnaces as fuel for 2000 ticks or 100 seconds). -!!! tip "Disabling Decomposition" - Depending on the composition, GT will autogenerate an electrolyzer or centrifuge recipe to decompose the material. You can block that by adding the disable decomposition flag. `DISABLE_DECOMPOSITION` - !!! tip "Choosing EU/t" GT has some builtin constants to ease choosing the required EU/t: + - `GTValues.V` for a full amp of power at the selected tier + - `GTValues.VA` for a full amp, adjusted for cable loss + - `GTValues.VH` for half an amp + - `GTValues.VHA` for half an amp, adjusted for cable loss These values are arrays containing the respective EU/t values for each tier. @@ -80,51 +57,122 @@ You can change the properties of the material by adding any combination of the f ``` ??? tip "Color Pickers" - To chose a color for your material, you can checkout https://www.w3schools.com/colors/colors_picker.asp + To chose a color for your material, you can checkout the [color picker](https://www.w3schools.com/colors/colors_picker.asp). After you select a color with the above tool, copy the 6 digits that follow the # under the color preview. + ## Creating an Ingot -```js title="ingot.js" -GTCEuStartupEvents.registry('gtceu:material', event => { - event.create('andesite_alloy') - .ingot() - .components('1x andesite', '1x iron') - .color(0x839689).iconSet(GTMaterialIconSet.DULL) - .flags(GTMaterialFlags.GENERATE_PLATE, GTMaterialFlags.GENERATE_GEAR, GTMaterialFlags.GENERATE_SMALL_GEAR) -}) -``` +=== "JavaScript" + ```js title="ingot.js" + GTCEuStartupEvents.registry('gtceu:material', event => { + event.create('andesite_alloy') + .ingot() + .components('1x andesite', '1x iron') + .color(0x839689).iconSet(GTMaterialIconSet.DULL) + .flags(GTMaterialFlags.GENERATE_PLATE, GTMaterialFlags.GENERATE_GEAR, GTMaterialFlags.GENERATE_SMALL_GEAR) + }) + ``` +=== "Java" + ```java title="Ingot.java" + public static Material ANDESITE_ALLOY; + public static void register() { + ANDESITE_ALLOY = new Material.Builder( + your_mod_id.id("andesite_alloy")) + .ingot() + .components("1x andesite", "1x iron") + .color(0xFF0000).secondaryColor(0x840707).iconSet(GTMaterialIconSet.DULL) + .flags(MaterialFlags.GENERATE_PLATE, MaterialFlags.GENERATE_GEAR, MaterialFlags.GENERATE_SMALL_GEAR) + .buildAndRegister(); + } + ``` -## Creating a Gem +## Creating a Dust -```js title="gem.js" -GTCEuStartupEvents.registry('gtceu:material', event => { - event.create('purple_coal') - .gem(2, 4000) - .element(GTElements.C) - .ore(2, 3) - .color(0x7D2DDB).iconSet(GTMaterialIconSet.LIGNITE) -}) -``` +=== "JavaScript" + ```js title="dust.js" + GTCEuStartupEvents.registry('gtceu:material', event => { + event.create('mysterious_dust') + .dust() // The harvest level and burn time can be specified in the brackets. Example: `.dust(2, 4000)` + .color(0x7D2DDB) + }) + ``` -## Creating a Dust +=== "Java" + ```java title="Dust.java" + public static Material MYSTERIOUS_DUST; + public static void register() { + MYSTERIOUS_DUST = new Material.Builder( + your_mod_id.id("mysterious_dust")) + .dust() // The harvest level and burn time can be specified in the brackets. Example: `.dust(2, 4000)` + .color(0x7D2DDB) + .buildAndRegister(); + } + ``` -```js title="dust.js" -GTCEuStartupEvents.registry('gtceu:material', event => { - event.create('mysterious_dust') - .dust() - .cableProperties(GTValues.V[GTValues.LV], 69, 0, true) // (1) -}) -``` +## Creating a Gem + +=== "JavaScript" + ```js title="gem.js" + GTCEuStartupEvents.registry('gtceu:material', event => { + event.create('purple_coal') + .gem(2, 4000) + .element(GTElements.C) + .ore(2, 3) + .color(0x7D2DDB).iconSet(GTMaterialIconSet.LIGNITE) + + }) + ``` -1. Voltage, Amperage, EU loss, Is Superconductor. +=== "Java" + ```java title="Gem.java" + public static Material PURPLE_COAL; + public static void register() { + PURPLE_COAL = new Material.Builder( + your_mod_id.id("purple_coal")) + .gem(2, 4000) + .element(GTElements.C) + .ore(2, 3) + .color(0x7D2DDB).iconSet(GTMaterialIconSet.LIGNITE) + .buildAndRegister(); + } + ``` ## Creating a Fluid -```js title="fluid.js" -GTCEuStartupEvents.registry('gtceu:material', event => { - event.create('mysterious_ooze') - .fluid() - .color(0x500bbf) - .fluidTemp(69420) -}) -``` +=== "JavaScript" + ```js title="fluid.js" + // const $FluidBuilder = Java.loadClass('com.gregtechceu.gtceu.api.fluids.FluidBuilder'); Uncomment if you want to use the Fluid Builder. + GTCEuStartupEvents.registry('gtceu:material', event => { + event.create('mysterious_ooze') + .fluid() // Or .liquid(Int Temperature) + .color(0x500bbf) + }) + ``` + +=== "Java" + ```java title="Fluid.java" + public static Material MYSTERIOUS_OOZE; + public static void register() { + MYSTERIOUS_OOZE = new Material.Builder( + your_mod_id.id("mysterious_ooze")) + .fluid() // Or .liquid(Int Temperature) + .color(0x500bbf) + .buildAndRegister(); + } + ``` + +!!! note + - To create a placeable fluid, you need to call a new instance of the FluidBuilder class and call .block() inside of it. The syntax for this will be the same in java and kubejs but you will need to load the FluidBuilder class for kubejs. + - For example: `.liquid(new $FluidBuilder().block().temperature(3100))`. + + +!!! tip "Further Material Information" + For more information on more fine grained material control, check out the pages below! + +For a full list of the flags, check out the [Material Flags page](./Material-Flags.md). + +For a full list of material properties, check out the [Material Properties page](./Material-Properties.md). + +For an explanation of tools, check out the [Tool Creation page](./Tool-Creation.md). + +For an explanation of custom icon sets and a list of existing ones, check out the [Icon Set page](./Material-Icon-Sets.md). diff --git a/docs/content/Modpacks/Materials-and-Elements/Material-Flags.md b/docs/content/Modpacks/Materials-and-Elements/Material-Flags.md index b64387b405e..86b161a54c5 100644 --- a/docs/content/Modpacks/Materials-and-Elements/Material-Flags.md +++ b/docs/content/Modpacks/Materials-and-Elements/Material-Flags.md @@ -8,7 +8,7 @@ title: Material Flags Using material flags, you can specify several properties of each material, which can influence how the material behaves, as well as which items are generated for it. -!!! example "Using material Flags" +=== "Javascript" ```js GTCEuStartupEvents.registry('gtceu:material', event => { event.create('my_material') @@ -16,52 +16,213 @@ can influence how the material behaves, as well as which items are generated for .flags(GTMaterialFlags.FLAMMABLE) }) ``` +=== "Java" + ```java + public static Material MY_MATERIAL; + public static void register() { + MY_MATERIAL = new Material.Builder( + your_mod_id.id('my_material')) + // ... + .flags(GTMaterialFlags.FLAMMABLE) + .buildAndRegister(); + } + ``` -## Generate Items +# Generic Flags + +- `NO_UNIFICATION` + - Description: Add to material to disable automatic recipe generation for it fully. This flag is deprecated, please use DISABLE_MATERIAL_RECIPES instead. + +- `DISABLE_MATERIAL_RECIPES` + - Description: Add to material to disable automatic recipe generation for it fully. This replaces NO_UNIFICATION. + +- `DECOMPOSITION_BY_ELECTROLYZING` + - Description: Enables electrolyzer decomposition recipe generation Requires `.components(...)` to be set. + +- `DECOMPOSITION_BY_CENTRIFUGING` + - Description: Enables centrifuge decomposition recipe generation. Requires `.components(...)` to be set. + +- `DISABLE_DECOMPOSITION` + - Description: Disables decomposition recipe generation for this material. + +- `EXPLOSIVE` + - Description: Any material with this flag wont have implosion compression recipes, and it will give ash when you arc furnace recycle it instead of that material. + +- `FLAMMABLE` + - Description: Adding this flag means you cant smelt that material and thus wont generate an ebf recipe/furnace recipe. Also disables implosion compressor recipes like `EXPLOSIVE` does. + +- `STICKY` + - Description: Add to material if it is sticky. This changes the viscosity of the placed fluid. Only the oils and creosote have a placeable state by default. + +- `PHOSPHORESCENT` + - Description: Adding this flag onto a material gives liquids a luminosity of 15, no matter the fluid state(liquid, gas, plasma). Otherwise they default to 10 for specifically liquid state. + +# Dust Flags + +- `GENERATE_PLATE` + - Description: Generates a plate and double plate for this material. + - Required Flags: `GENERATE_PLATE`. + - Required Properties: `PropertyKey.DUST`. + +- `GENERATE_DENSE` + - Description: Generates a dense plate for this material. + - Required Flags: `GENERATE_PLATE`. + - Required Properties: `PropertyKey.DUST`. + +- `GENERATE_ROD` + - Description: Generates a rod for this material. + - Required Properties: `PropertyKey.DUST`. -- `FORCE_GENERATE_BLOCK` - `GENERATE_BOLT_SCREW` -- `GENERATE_DENSE` -- `GENERATE_FINE_WIRE` -- `GENERATE_FOIL` + - Description: Generates a bolt and screw for this material. + - Required Flags: `GENERATE_ROD`. + - Required Properties: `PropertyKey.DUST`. + - `GENERATE_FRAME` + - Description: Generates a frame for this material. + - Required Flags: `GENERATE_ROD`. + - Required Properties: `PropertyKey.DUST`. + - `GENERATE_GEAR` -- `GENERATE_LENS` + - Description: Generates a gear for this material. + - Required Flags: `GENERATE_PLATE`, `GENERATE_ROD`. + - Required Properties: `PropertyKey.DUST`. + - `GENERATE_LONG_ROD` -- `GENERATE_PLATE` -- `GENERATE_RING` -- `GENERATE_ROD` -- `GENERATE_ROTOR` -- `GENERATE_ROUND` -- `GENERATE_SMALL_GEAR` -- `GENERATE_SPRING` -- `GENERATE_SPRING_SMALL` + - Description: Generates a long rod for this material. + - Required Flags: `GENERATE_ROD`. + - Required Properties: `PropertyKey.DUST`. + +- `FORCE_GENERATE_BLOCK` + - Description: Add this to a material to force generate a block. + - Required Properties: `PropertyKey.DUST`. +- `EXCLUDE_BLOCK_CRAFTING_RECIPES` + - Description: This will prevent material from creating Shapeless recipes for dust to block and vice versa. Also preventing extruding and alloy smelting recipes via `SHAPE_EXTRUDING`/`MOLD_BLOCK`. + - Required Properties: `PropertyKey.DUST`. -## Other Flags +- `EXCLUDE_PLATE_COMPRESSOR_RECIPE` + - Description: Add this to material if you want to disable the forge hammer plate recipe. + - Required Flags: `GENERATE_PLATE`. + - Required Properties: `PropertyKey.DUST`. -- `BLAST_FURNACE_CALCITE_DOUBLE` -- `BLAST_FURNACE_CALCITE_TRIPLE` -- `DISABLE_ALLOY_BLAST` -- `DISABLE_ALLOY_PROPERTY` -- `CRYSTALLIZABLE` -- `DECOMPOSITION_BY_CENTRIFUGING` -- `DECOMPOSITION_BY_ELECTROLYZING` -- `DISABLE_DECOMPOSITION` - `EXCLUDE_BLOCK_CRAFTING_BY_HAND_RECIPES` -- `EXCLUDE_BLOCK_CRAFTING_RECIPES` -- `EXCLUDE_PLATE_COMPRESSOR_RECIPES` -- `EXPLOSIVE` -- `FLAMMABLE` -- `HIGH_SIFTER_OUTPUT` -- `IS_MAGNETIC` + - Description: This will prevent material from creating Shapeless recipes for dust to block and vice versa. + - Required Properties: `PropertyKey.DUST`. + - `MORTAR_GRINDABLE` + - Description: Adds a mortar grinding recipe to this material. + - Required Properties: `PropertyKey.DUST`. + +- `NO_WORKING` + - Description: Add to material if it cannot be worked by any other means, than smashing or smelting. This is used for coated materials. + - Required Properties: `PropertyKey.DUST`. + - `NO_SMASHING` + - Description: Add to material if it cannot be used for regular metal working techniques since it is not possible to bend it. + - Required Properties: `PropertyKey.DUST`. + - `NO_SMELTING` -- `NO_UNIFICATION` -- `NO_WORKING` + - Description: Add to material if it's impossible to smelt it. + - Required Properties: `PropertyKey.DUST`. + +- `NO_ORE_SMELTING` + - Description: Add to material if it's impossible to smelt it from an ore. + - Required Properties: `PropertyKey.DUST`. + +- `NO_ORE_PROCESSING_TAB` + - Description: Add to a material to disable creating an ore processing tab. + - Required Properties: `PropertyKey.ORE`. + +- `BLAST_FURNACE_CALCITE_DOUBLE` + - Description: Add this to your material if you want to have its ore calcite heated in a Blast Furnace for double output. Already listed are: Iron, Pyrite, PigIron, WroughtIron. + - Required Properties: `PropertyKey.DUST`. + +- `BLAST_FURNACE_CALCITE_TRIPLE` + - Description: Add this to your material if you want to have its ore calcite heated in a Blast Furnace for triple output. + - Required Properties: `PropertyKey.DUST`. + +- `DISABLE_ALLOY_BLAST` + - Description: Use to disable alloy blast recipes from generating. + - Required Properties: `PropertyKey.BLAST`, `PropertyKey.FLUID`. + +- `DISABLE_ALLOY_PROPERTY` + - Description: Use to disable everything related to alloy blasting. + - Required Flags: `DISABLE_ALLOY_BLAST`. + - Required Properties: `PropertyKey.BLAST`, `PropertyKey.FLUID`. + +# Fluid Flags + - `SOLDER_MATERIAL` + - Description: Allows this material to be used in place of soldering alloy. + - Required Properties: `PropertyKey.FLUID`. + - `SOLDER_MATERIAL_BAD` + - Description: Not yet implemented. Supposed to set this material as a bad soldering material. + - Required Properties: `PropertyKey.FLUID`. + - `SOLDER_MATERIAL_GOOD` -- `STICKY` \ No newline at end of file + - Description: Not yet implemented. Supposed to set this material as a good soldering material. + - Required Properties: `PropertyKey.FLUID`. + +# Ingot Flags + +- `GENERATE_FOIL` + - Description: Generates a foil for this material. + - Required Flags: `GENERATE_PLATE`. + - Required Properties: `PropertyKey.INGOT`. + +- `GENERATE_RING` + - Description: Generates a ring for this material. + - Required Flags: `GENERATE_ROD`. + - Required Properties: `PropertyKey.INGOT`. + +- `GENERATE_SPRING` + - Description: Generates a spring for this material. + - Required Flags: `GENERATE_LONG_ROD`. + - Required Properties: `PropertyKey.INGOT`. + +- `GENERATE_SPRING_SMALL` + - Description: Generates a small spring for this material. + - Required Flags: `GENERATE_ROD`. + - Required Properties: `PropertyKey.INGOT`. + +- `GENERATE_SMALL_GEAR` + - Description: Generates a small gear for this material. + - Required Flags: `GENERATE_PLATE`, `GENERATE_ROD`. + - Required Properties: `PropertyKey.INGOT`. + +- `GENERATE_FINE_WIRE` + - Description: Generates all wires for this material. + - Required Flags: `GENERATE_FOIL`. + - Required Properties: `PropertyKey.INGOT`. + +- `GENERATE_ROTOR` + - Description: Generates a rotor for this material. + - Required Flags: `GENERATE_BOLT_SCREW`, `GENERATE_RING, GENERATE_PLATE`. + - Required Properties: `PropertyKey.INGOT`. + +- `GENERATE_ROUND` + - Description: Generates a round for this material. + - Required Properties: `PropertyKey.INGOT`. + +- `IS_MAGNETIC` + - Description: Add this to your Material if it is a magnetized form of another Material. When this flag is on a Material, it macerates into the non-magnetic version of said Material, which is then used for certain crafting recipes. + - Required Properties: `PropertyKey.INGOT`. + +# Gem Flags + +- `CRYSTALLIZABLE` + - Description: If this material can be crystallized (turned back into gem by autoclave). + - Required Properties: `PropertyKey.GEM`. + +- `GENERATE_LENS` + - Description: Generates a lens for this material. + - Required Flags: `GENERATE_PLATE`. + - Required Properties: `PropertyKey.GEM`. + +# Ore Flags +- `HIGH_SIFTER_OUTPUT` + - Description: Boosts sifter output of the gem ore for the material. + - Required Properties: `PropertyKey.GEM`, `PropertyKey.ORE`. diff --git a/docs/content/Modpacks/Materials-and-Elements/Material-Properties.md b/docs/content/Modpacks/Materials-and-Elements/Material-Properties.md index addaf3ee04f..f7a351edab3 100644 --- a/docs/content/Modpacks/Materials-and-Elements/Material-Properties.md +++ b/docs/content/Modpacks/Materials-and-Elements/Material-Properties.md @@ -3,56 +3,107 @@ title: Material Properties --- -# Material Properties (WIP) - -## Blast Furnace Properties - -### `BlastProperty.blastTemp()` -Sets the Blast Furnace Temperature of the material. If the temperature is below 1000K recipes will be generated in the Primitive Blast Furnace. If above 1750K recipes for the Hot Ingot will be created along with the Vacuum Freezer Recipe to cool the ingot. Example: `.blastTemp(2750)` - -### `BlastProperty.gasTier()` -Sets the Gas Tier which determins what GAS EBF recipes will be generated. Example: `.gasTier(LOW)` - -### `BlastProperty.durationOverride()` -Overrides the EBF's default behaviour for recipe durations. - -### `BlastProperty.eutOverride()` -Overrides the EBF's default behaviour for EU/t. - - -## `DustProperty.dust()` -Used for creating a dust material. The haverst level and burn time can be specified in the brackets. Example: `.dust(2, 4000)` - - -## `FluidPipeProperty.fluidPipeProperties()` -Creates a fluid pipe out of the material it is added to. The possible values are: Max Fluid Temperature, Throughput, Gas Proof, Acid Proof, Cyro Proof, Plasma Proof, -Channels. Example: `.fluidPipeProperties(9620, 850, false, false, false, false, 1)` - +# Material Properties + +Properties can be applied to a material to decide how they behave. An example of this can be seen below: + +=== "Javascript" + ```js + GTCEuStartupEvents.registry('gtceu:material', event => { + event.create('my_material') + // ... + .blastTemp(3700, "mid", GTValues.VA[GTValues.EV], 1600) + }) + ``` +=== "Java" + ```java + public static Material MY_MATERIAL; + public static void register() { + MY_MATERIAL = new Material.Builder( + your_mod_id.id('my_material')) + // ... + .blastTemp(3700, "mid", GTValues.VA[GTValues.EV], 1600) + .buildAndRegister(); + } + ``` + +## `Blast Furnace Properties` +- `.blastTemp()` is meant to be paired together with `.ingot()`. Will generate a EBF recipe (and an ABS recipe) based on the parameters you give it: + 1. `int temperature` -> dictates what coil tier it will require (check the coil tooltips for their max temperature). + If the temperature is below 1000, it will also generate a PBF recipe. + If temperature is above 1750, a hot ingot will be generated, this requiring a Vacuum Freezer. + 2. (optional) `string gasTier` -> can be `null` for none, `'low'` for nitrogen, `'mid'` for helium, `'high'` for argon, `'higher'` for neon or `'highest'` for krypton. + 3. (optional) `long EUPerTick` -> the recipe voltage + 4. (optional) `int durationInTicks` -> how long the recipe should take +!!! tip "ABS Recipe Generation" + For an ABS recipe to actually generate from your material, you must set `.components()`. To disable the alloy blast smelter recipes from generating while `.components` and `.blastTemp` are set, check out [DISABLE_ALLOY_BLAST](./Material-Flags.md#dust-flags) + +- `.durationOverride(int duration)` + - `int duration` -> Overrides the EBF's default behaviour for recipe durations. + +- `.eutOverride(int EU/t)` + - `int EU/t` -> Overrides the EBF's default behaviour for EU/t. + +## `Fluid Pipe Property` +- `.fluidPipeProperties(int maxTemp, int throughput, boolean gasProof, boolean acidProof, boolean cryoProof, boolean plasmaProof)` -> this will create an fluid pipe from this material + 1. `int maxtemp` -> The maximum temperature of fluid that this pipe can handle before breaking the pipe and voiding fluids. + 2. `int throughput` -> The rate at which fluid can flow through this pipe. + 3. `boolean gasProof` -> Whether this pipe can hold gases. If not, some gas will be lost as it travels through the pipe. + 4. `boolean acidProof` -> Whether this pipe can hold Acids. If not, the pipe will break and void all fluids. + 5. `boolean cryoProof` -> Whether this pipe can hold cryogenic Fluids (below 120K). If not, the pipe will break and void all fluids. + 6. `boolean plasmaProof` -> Whether this pipe can hold plasmas. If not, the pipe will break and void all fluids. Plasma capable pipes do not care about temperature. + +## `Item Pipe Property` +- `.itemPipeProperties(int priority, int stacksPerSecond)` -> this will create an item pipe from this material + 1. `int priority` -> Priority of this Item Pipe, used for the standard routing mode. + 2. `int stacksPerSecond` -> How many stacks of items can be moved per second (20 ticks). + +## `Rotor Property` +- `.rotorStats(int power, int efficiency, float damage, int durability)` -> this will create a turbine rotor from this material + 1. `int power` -> Power is the EU/t and fuel consumption multiplier the turbine gets when equipped with this rotor. + This output varies depending on speed of turbine and rotor holder. + 2. `int efficiency` -> Efficiency is how well it handles fuel. + A smaller number will make it consume more fuel while a bigger number means it uses less fuel. + Actual efficiency: rotorEfficiency * holder Efficiency / 100 + 3. `float damage` -> Damage is the amount of damage that happens to the player when opening the ui of a running turbine's rotor holder. + 4. `int durability` -> Durability is how much base durability it has. +- Here are some examples of base gt rotors: + 1. Titanium Rotor: .rotorStats(130, 115, 3.0, 1600) + 2. HSS-S Rotor .rotorStats(250, 180, 7.0, 3000) + +## `Cable Property` +- .cableProperties(long voltage, int amperage, int lossPerBlock, boolean isSuperconductor) + 1. `long voltage` -> The voltage tier of this Cable. Should conform to standard GregTech voltage tiers. + 2. `int amperage` -> The amperage of this Cable. Should be greater than zero. + 3. `int lossPerBlock` -> The loss-per-block of this Cable. A value of zero here will still have loss as wires. + 4. `boolean isSuperconductor` -> Whether this Material is a Superconductor. If so, Cables will NOT be generated and the Wires will have zero cable loss, ignoring the loss parameter. ## Fluid Properties -### `FluidProperty.fluid()` -!!! failure "Not yet documented" - -### `FluidProperty.isGas()` -!!! failure "Not yet documented" - -### `FluidProperty.hasBlock()` -!!! failure "Not yet documented" - - -## `GemProperty.gem()` -!!! failure "Not yet documented" - - -## `IngotProperty.ingot()` -!!! failure "Not yet documented" - -- `.smeltInto()` -- `.arcSmeltInto()` -- `.magneticMaterial()` -- `.macerateInto()` - +### `Fluid Block Property` +- Add .block() into the builder of a liquid material to allow this material to be placeable. + +## `Ingot Property` +- `.polarizesInto(string newMaterial)` + - `string newMaterial` -> Is what is obtained through polarizing the material. +- `.arcSmeltInto(string newMaterial)` + - `string newMaterial` -> Is what is obtained through arc smelting the material. +- `.macerateInto(string newMaterial)` + - `string newMaterial` -> Is what is obtained through macerating the material. +- `.ingotSmeltInto(string newMaterial)` + - `string newMaterial` -> Is what is obtained when smelting a material's ingot. + +## `Ore Property` +- `.addOreByproducts()` is an "open" list of extra byproduct materials. + 1. Is the material when going crushed -> impure in macerator, or impure dust to dust in centrifuge + 2. Is the material when going crushed->refined in thermal centrifuge, or crushed to dust in macerator, or pure dust to dust in centrifuge + 3. Is the material when going from refined to dust in macerator, + 4. Is the material when going from crushed ore to purified or in chem bath(works only if you have a getWashedIn material) +- `.washedIn(string fluid)` + - `string fluid` Is what fluid it uses for if it has the ore prop and is making crushed->refined. For example, the sodium persulfate and mercury ore washing recipes. +- `.separatedInto(list material)` + - `list material` Is the list of materials that are obtained when processing purified dusts in the centrifuge. +- `.oreSmeltInto(string material)` + - `string material` Is what is obtained through directly smelting the ore. + -## `OreProperty.ore()` -!!! failure "Not yet documented" \ No newline at end of file diff --git a/docs/content/Modpacks/Materials-and-Elements/Tool-Creation.md b/docs/content/Modpacks/Materials-and-Elements/Tool-Creation.md new file mode 100644 index 00000000000..cd5a6dac2ab --- /dev/null +++ b/docs/content/Modpacks/Materials-and-Elements/Tool-Creation.md @@ -0,0 +1,172 @@ +--- +title: Tool Creation +--- + +Tools can be made out of materials you create by calling toolStats inside the material's code. + +toolStats has the following arguments: + +`.toolStats(float harvestSpeed, float attackDamage, int durability, int harvestLevel, GTToolType[] types)` + +- `harvestSpeed: float` is how fast the tool actually breaks blocks in world. +- `attackDamage: float` is the amount of damage per hit you deal to mobs/players. +- `durability: int` is the number of times the tool can be used before it breaks. + - This applies to both crafting use and in-world use. + Crafting generally consumes 2 points of durability per use. +- `harvestLevel: int` is the tier of block it can break. + - Can take an integer between 0-6 with 0 being wood, 6 being neutronium. +- `types: GTToolType[]` is an array of tools in an object. + - Must pass these as an array, using the [] notation. + This argument can be left out if you want your material to apply to all tool types. + +An example of this being used is included below. +=== "JavaScript" + ```js title="example_tool_material.js" + // When working with tools in kubejs you will need to load these classes at the top of your file. + Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.PropertyKey'); + Java.loadClass('com.gregtechceu.gtceu.api.data.chemical.material.properties.ToolProperty'); + GTCEuStartupEvents.registry('gtceu:material', event => { + event.create('aluminfrost') + .ingot() + .color(0xadd8e6).secondaryColor(0xc0c0c0).iconSet(GTMaterialIconSet.DULL) + .toolStats(new ToolProperty(12.0, 7.0, 3072, 6, + [ + GTToolType.DRILL_LV, + GTToolType.MINING_HAMMER + ] + )) + }); + ``` +=== "Java" + ```java title="ExampleToolMaterial.java" + public static Material ALUMINFROST; + ALUMINFROST = new Material.Builder( + your_mod_id.id("aluminfrost")) + .color(0xadd8e6).secondaryColor(0xc0c0c0).iconSet(MaterialIconSet.DULL) + .toolStats(new ToolProperty(12.0F, 7.0F, 3072, 6, + new GTToolType[] { GTToolType.DRILL_LV, GTToolType.MINING_HAMMER })) + .buildAndRegister(); + ``` +Using the ToolProperties.Builder, you can also add further arguments onto your tools. +The builder has the same arguments as the constructor, and can have chained methods such as: + +- `.unbreakable()` + - Makes electric tools bypass durability effectively making them never break. +- `.magnetic()` + - Makes mined blocks and mob drops teleport to player inventory. +- `attackSpeed(float attackSpeed)` + - Set the attack speed of a tool made from this Material (animation time). +- `ignoreCraftingTools()` + - Disable crafting tools being made from this Material. + +- `addEnchantmentForTools(Enchantment enchantment, int level)` + - Enchantment is the default enchantment applied on tool creation. + Level is the level of said enchantment. +- `enchantability(int enchantability)` + - Set the base enchantability of a tool made from this Material. + Iron is 14, Diamond is 10, Stone is 5. + +Here is an example of using the builder in a material: +=== "JavaScript" + ```js title="example_tool_material.js" + GTCEuStartupEvents.registry('gtceu:material', event => { + event.create('aluminfrost') + .ingot() + .color(0xadd8e6).secondaryColor(0xc0c0c0).iconSet(GTMaterialIconSet.DULL) + .toolStats( + ToolProperty.Builder.of(1.8, 1.7, 700, 3, + [ + GTToolType.SWORD, + GTToolType.PICKAXE, + GTToolType.SHOVEL, + ] + ) + .unbreakable() + .addEnchantmentForTools(silk_touch, 1) + .build() + ) + }); + ``` +=== "Java" + ```java title="ExampleToolMaterial.java" + public static Material ALUMINFROST; + ALUMINFROST = new Material.Builder( + your_mod_id.id("aluminfrost")) + .ingot() + .color(0xadd8e6).secondaryColor(0xc0c0c0).iconSet(MaterialIconSet.DULL) + .toolStats(ToolProperty.Builder.of(1.8F, 1.7F, 700, 3) + .types( + GTToolType.SWORD, + GTToolType.PICKAXE, + GTToolType.SHOVEL) + .unbreakable() + .enchantment(SILK_TOUCH, 1) + .build()) + .buildAndRegister(); + ``` + +You can also change the tool property of a GT material that already has a tool property. You do, however, have to remove the current tool property as it is immutable. +=== "JavaScript" + ```js title="tool_replacement.js" + GTCEuStartupEvents.materialModification(event => { + if (GTMaterials.TungstenCarbide.hasProperty(PropertyKey.TOOL)) { + GTMaterials.TungstenCarbide.removeProperty(PropertyKey.TOOL); + } + GTMaterials.TungstenCarbide.setProperty(PropertyKey.TOOL, + ToolProperty.Builder.of(180, 5.9, 2147483647, 6, + [ + GTToolType.SOFT_MALLET, + GTToolType.DRILL_LV + ] + ).build()); + }); + ``` +=== "Java" + ```java title="ToolReplacement.java" + public static void modifyMaterials() { + if (GTMaterials.TungstenCarbide.hasProperty(PropertyKey.TOOL)) { + GTMaterials.TungstenCarbide.removeProperty(PropertyKey.TOOL); + } + TungstenCarbide.setProperty(PropertyKey.TOOL, + (ToolProperty.Builder.of(180, 5.9, 2147483647, 6, GTToolType.SOFT_MALLET, GTToolType.DRILL_LV) + .build())); + } + + ``` + +Here is a list of all the GtToolTypes. + +- SWORD +- PICKAXE +- SHOVEL +- AXE +- HOE +- MINING_HAMMER +- SPADE +- SAW +- HARD_HAMMER +- SOFT_MALLET +- WRENCH +- FILE +- CROWBAR +- SCREWDRIVER +- MORTAR +- WIRE_CUTTER +- SCYTHE +- KNIFE +- BUTCHERY_KNIFE +- PLUNGER +- DRILL_LV +- DRILL_MV +- DRILL_HV +- DRILL_EV +- DRILL_IV +- CHAINSAW_LV +- WRENCH_LV +- WRENCH_HV +- WRENCH_IV +- BUZZSAW +- SCREWDRIVER_LV +- WIRE_CUTTER_LV +- WIRE_CUTTER_HV +- WIRE_CUTTER_IV diff --git a/docs/content/Modpacks/Ore-Generation/Bedrock-Fluid-Veins.md b/docs/content/Modpacks/Ore-Generation/Bedrock-Fluid-Veins.md index 4cc7cdd7f50..e3766b1a553 100644 --- a/docs/content/Modpacks/Ore-Generation/Bedrock-Fluid-Veins.md +++ b/docs/content/Modpacks/Ore-Generation/Bedrock-Fluid-Veins.md @@ -14,8 +14,8 @@ Bedrock Fluid Veins are invisable veins that exist under the bedrock, to find Fl GTCEuServerEvents.fluidVeins(event => { event.add('gtceu:custom_bedrock_fluid_vein', vein => { - vein.addSpawnDimension('minecraft:overworld') - vein.fluid(() => Fluid.of('gtceu:custom_fluid').fluid) + vein.dimensions('minecraft:overworld') // (1) + vein.fluid(() => Fluid.of('gtceu:custom_fluid').fluid) vein.weight(600) vein.minimumYield(120) vein.maximumYield(720) @@ -23,5 +23,8 @@ GTCEuServerEvents.fluidVeins(event => { vein.depletionChance(1) vein.depletedYield(50) }); +}); -``` \ No newline at end of file +``` + +1. Dimension where fluid vein will spawn. \ No newline at end of file diff --git a/docs/content/Modpacks/Ore-Generation/Bedrock-Ore-Veins.md b/docs/content/Modpacks/Ore-Generation/Bedrock-Ore-Veins.md index b35cb5184cc..494f27d36f1 100644 --- a/docs/content/Modpacks/Ore-Generation/Bedrock-Ore-Veins.md +++ b/docs/content/Modpacks/Ore-Generation/Bedrock-Ore-Veins.md @@ -27,7 +27,7 @@ GTCEuServerEvents.bedrockOreVeins(event => { .size(3) // (1) .yield(10, 20) .material(GTMaterials.Goethite, 5) // (2) - .material(GTMaterials.YellowLimonite, 2) + .material(GTMaterials.Limonite, 2) .material(GTMaterials.Hematite, 2) .material(GTMaterials.Malachite, 1) .dimensions('minecraft:overworld') diff --git a/docs/content/Modpacks/Other-Topics/Ambiguous-Methods.md b/docs/content/Modpacks/Other-Topics/Ambiguous-Methods.md new file mode 100644 index 00000000000..53dceeb592b --- /dev/null +++ b/docs/content/Modpacks/Other-Topics/Ambiguous-Methods.md @@ -0,0 +1,100 @@ +--- +title: Ambiguous Methods +--- + +## Ambiguous Methods +Sometimes in KJS, you run into ambiguous methods when calling functions. +This happens when there's multiple overloads (e.g. methods with the same name but different types) and KubeJS isn't sure which function to call with your arguments. + +For example, when you do: +```js + +GTCEuStartupEvents.registry('gtceu:machine', event => { + event.create('unboxinator', 'multiblock') + .tooltips(Component.literal("I am a multiblock")) + // Rest of the multiblock +}) +``` + +you'd get the error: +``` +Error in 'GTCEuStartupEvents.registry': The choice of Java method com.gregtechceu.gtceu.api.registry.registrate.MultiblockMachineBuilder.tooltips matching JavaScript argument types (net.minecraft.network.chat.MutableComponent) is ambiguous; candidate methods are: + class com.gregtechceu.gtceu.api.registry.registrate.MachineBuilder tooltips(java.util.List) + class com.gregtechceu.gtceu.api.registry.registrate.MachineBuilder tooltips(net.minecraft.network.chat.Component[]) +``` + +In this case, there's ambiguity between the following 2 java functions: +```java + public MachineBuilder tooltips(@Nullable Component... components) { + return tooltips(Arrays.asList(components)); + } + + public MachineBuilder tooltips(List components) { + tooltips.addAll(components.stream().filter(Objects::nonNull).toList()); + return this; + } +``` + +You would want to select one of the two, and this can be done in the following way: +```js +GTCEuStartupEvents.registry('gtceu:machine', event => { + event.create('unboxinator', 'multiblock') + ["tooltips(java.util.List)"]([Component.literal("I am a multiblock")]) + // Rest of the multiblock +}) +``` +or +```js +GTCEuStartupEvents.registry('gtceu:machine', event => { + event.create('unboxinator', 'multiblock') + ["tooltips(net.minecraft.network.chat.Component[])"]([Component.literal("I am a multiblock")]) + // Rest of the multiblock +}) +``` + +Because of the way javascript indexing works, `.foo` and `["foo"]` are the same thing, so you can just keep chaning your functions afterward, since it's just a "normal" builder method, just called in a more specific way. + +## Ambiguous Constructors +This same problem can occur when trying to call a constructor. +For example, when you do +```js +GTCEuStartupEvents.registry("gtceu:recipe_type", event => { + event.create("unboxinator") + .setProgressBar( + new ResourceTexture("kubejs:textures/gui/progress_bar/progress_bar_stone_oreifier.png"), + FillDirection.LEFT_TO_RIGHT + ) + // Rest of the recipe type +}) +``` +You'd get the following error: +``` +dev.latvian.mods.rhino.EvaluatorException: The choice of Java constructor com.lowdragmc.lowdraglib.gui.texture.ResourceTexture matching JavaScript argument types (string) is ambiguous; candidate constructors are: + ResourceTexture(net.minecraft.resources.ResourceLocation) + ResourceTexture(java.lang.String) (startup_scripts:example.js#17) +``` + +You would want to select one of the two, and this can be done in the following way: +```js +GTCEuStartupEvents.registry("gtceu:recipe_type", event => { + event.create("unboxinator") + .setProgressBar( + ResourceTexture["(java.lang.String)"]("kubejs:textures/gui/progress_bar/progress_bar_stone_oreifier.png"), + FillDirection.LEFT_TO_RIGHT + ) + // Rest of the recipe type +}) +``` +or +```js +GTCEuStartupEvents.registry("gtceu:recipe_type", event => { + event.create("unboxinator") + .setProgressBar( + ResourceTexture["(net.minecraft.resources.ResourceLocation)"](new ResourceLocation("kubejs:textures/gui/progress_bar/progress_bar_stone_oreifier.png")), + FillDirection.LEFT_TO_RIGHT + ) + // Rest of the recipe type +}) +``` +!!! Note + Generics don't exist in compiled code, so e.g. a call to `memoize(Supplier delegate)` would turn into `["memoize(Supplier)"](...)` \ No newline at end of file diff --git a/docs/content/Modpacks/Other-Topics/Custom-Machine-Behavior.md b/docs/content/Modpacks/Other-Topics/Custom-Machine-Behavior.md new file mode 100644 index 00000000000..36647e0db7f --- /dev/null +++ b/docs/content/Modpacks/Other-Topics/Custom-Machine-Behavior.md @@ -0,0 +1,71 @@ +--- +title: Custom Machine Behavior +--- + +!!! Warning + Custom Machine Behavior is currently only supported in Java. + +Sometimes, you want to do something in a machine that's not possible via Recipe Conditions or Recipe Modifiers. For this, Custom Machine Behavior might be the correct tool. + +It works by registering a custom TickableSubscription, which gets called every tick. +Here, we want to make a greenhouse that, while running, also turns all the dirt above it into grass. +```java + +public class Greenhouse extends WorkableElectricMultiblockMachine { + + private TickableSubscription tickSubscription; + + @Override + public void onStructureFormed() { + super.onStructureFormed(); + if (!isRemote()) { + tickSubscription = this.subscribeServerTick(this::turnGreenery); + } + } + + @Override + public void onStructureInvalid() { + super.onStructureInvalid(); + if (!isRemote()) { + tickSubscription.unsubscribe(); + tickSubscription = null; + } + } + + private void turnGreenery(){ + if(!getRecipeLogic().isActive()) return; + BlockPos currentPosition = getRecipeLogic().getMachine().getHolder().getCurrentPos(); + BlockPos abovePosition = currentPosition.above(); + if(this.getLevel().getBlockState(abovePosition).equals(Blocks.DIRT.defaultBlockState())){ + this.getLevel().setBlock(abovePosition, Blocks.GRASS.defaultBlockState(), 3); + } + } +} +``` +The `tickSubscription` field is a reference to the current subscription that should be called every tick. When this subscription is created, we tell the server to run `this.turnGreenery()` every tick. + +In there, we simply check if the recipe logic is active, and if so, we turn the block above the machine into grass if it was already dirt. + +To use it, you would do: +```java + public static final MultiblockMachineDefinition GREENHOUSE = REGISTRATE + .multiblock("green_house", Greenhouse::new) + .rotationState(RotationState.ALL) + .recipeType(MyRecipeTypes.GREENHOUSE) + .recipeModifiers(OC_PERFECT_SUBTICK, BATCH_MODE) + .appearanceBlock(CASING_PTFE_INERT) + .pattern(definition -> { + var casing = blocks(CASING_PTFE_INERT.get()).setMinGlobalLimited(10); + var abilities = Predicates.autoAbilities(definition.getRecipeTypes()) + .or(Predicates.autoAbilities(true, false, false)); + return FactoryBlockPattern.start() + .aisle("XSX", "XXX", "XXX") + .aisle("XXX", "XXX", "XXX") + .where('S', Predicates.controller(blocks(definition.getBlock()))) + .where('X', casing.or(abilities)) + .build(); + }) + .workableCasingModel(GTCEu.id("block/casings/solid/machine_casing_inert_ptfe"), + GTCEu.id("block/multiblock/large_chemical_reactor")) + .register(); +``` diff --git a/docs/content/Modpacks/Other-Topics/Custom-Machines.md b/docs/content/Modpacks/Other-Topics/Custom-Machines.md index 7ba98823950..5ec698eda4c 100644 --- a/docs/content/Modpacks/Other-Topics/Custom-Machines.md +++ b/docs/content/Modpacks/Other-Topics/Custom-Machines.md @@ -65,6 +65,7 @@ GTCEuStartupEvents.registry('gtceu:machine', event => { .rotationState(RotationState.NON_Y_AXIS) .appearanceBlock(GTBlocks.CASING_STEEL_SOLID) .recipeTypes(['test_recipe_type_1', 'test_recipe_type_2']) + .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, ELECTRIC_OVERCLOCK.apply(PERFECT_OVERCLOCK)]) // (2) .pattern(definition => FactoryBlockPattern.start() .aisle('CCC', 'GGG', 'CCC') .aisle('CCC', 'GDG', 'CSC') @@ -77,17 +78,16 @@ GTCEuStartupEvents.registry('gtceu:machine', event => { .where('C', Predicates.blocks(GTBlocks.CASING_STEEL_SOLID.get()) .or(Predicates.autoAbilities(definition.getRecipeTypes()))) .build()) - .workableCasingRenderer( + .workableCasingModel( "gtceu:block/casings/solid/machine_casing_inert_ptfe", - "gtceu:block/multiblock/large_chemical_reactor", - false + "gtceu:block/multiblock/large_chemical_reactor" ) }) ``` 1. You can add tooltips to your multiblock controllers that show up when you mouseover them. Each separate call of ```.tooltips()``` will add a separate line to the controller's tooltip. ```Component.translatable()``` reads entries from .json lang files placed in ```kubejs/assets/gtceu/lang``` or supplied via a standalone resource pack. The ```Component``` class is autoloaded by KubeJS at compile time; it doesn't need to be manually loaded. - +2. If electric and/or multiblock machines can process your custom recipe type, ```.recipeModifiers()``` will allow you to fine-tune the behaviour of these machine when running recipes of your custom recipe type. ```GTRecipeModifiers.PARALLEL_HATCH``` will enable Multiblock Machines to parallelize recipes of your custom type via an optional Parallel Hatch, while ```ELECTRIC_OVERCLOCK.apply(PERFECT_OVERCLOCK)```will define how your recipes overclock in electric machines and multiblocks. ### Shape Info @@ -125,10 +125,9 @@ GTCEuStartupEvents.registry('gtceu:machine', event => { .where('i', GTMachines.ITEM_IMPORT_BUS[1], Direction.SOUTH) .where('0', GTMachines.ITEM_EXPORT_BUS[1], Direction.SOUTH) .build()) - .workableCasingRenderer( + .workableCasingModel( "gtceu:block/casings/solid/machine_casing_inert_ptfe", - "gtceu:block/multiblock/large_chemical_reactor", - false + "gtceu:block/multiblock/large_chemical_reactor" ) }) ``` diff --git a/docs/content/Modpacks/Other-Topics/Custom-Recipe-Types.md b/docs/content/Modpacks/Other-Topics/Custom-Recipe-Types.md index 26ec1c6c191..4b3694f33e5 100644 --- a/docs/content/Modpacks/Other-Topics/Custom-Recipe-Types.md +++ b/docs/content/Modpacks/Other-Topics/Custom-Recipe-Types.md @@ -11,31 +11,14 @@ title: Custom Recipe Type GTCEuStartupEvents.registry('gtceu:recipe_type', event => { event.create('test_recipe_type') .category('test') - .recipeModifiers([GTRecipeModifiers.PARALLEL_HATCH, GTRecipeModifiers.ELECTRIC_OVERCLOCK.apply(OverclockingLogic.PERFECT_OVERCLOCK)]) // (1) .setEUIO('in') - .setMaxIOSize(3, 3, 3, 3) // (2) + .setMaxIOSize(3, 3, 3, 3) // (1) .setSlotOverlay(false, false, GuiTextures.SOLIDIFIER_OVERLAY) - .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT) // (3) + .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT) // (2) .setSound(GTSoundEntries.COOLING) }) ``` -1. If electric and/or multiblock machines can process your custom recipe type, ```.recipeModifiers()``` will allow you to fine-tune the behaviour of these machine when running recipes of your custom recipe type. ```GTRecipeModifiers.PARALLEL_HATCH``` will enable Multiblock Machines to parallelize recipes of your custom type via an optional Parallel Hatch, while ```GTRecipeModifiers.ELECTRIC_OVERCLOCK```will define how your recipes overclock in electric machines and multiblocks. -2. Max Item Inputs, Max Item Outputs, Max Fluid Inputs, Max Fluid Outputs -3. A list of available ```GuiTextures``` and ```FillDirection```s can be found in the GTCEu Modern Github, or in the .jar file. - - -```js title="test_kinetic_recipe_type.js" -GTCEuStartupEvents.registry('gtceu:recipe_type', event => { - event.create('test_recipe_type') - .category('test_kinetic') - .setEUIO('in') - .setMaxIOSize(3, 3, 3, 3) - .setSlotOverlay(false, false, GuiTextures.SOLIDIFIER_OVERLAY) - .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, FillDirection.LEFT_TO_RIGHT) - .setSound(GTSoundEntries.COOLING) - .setMaxTooltip(6) // (1) -}) -``` - -1. Helps to adjust the JEI/REI/EMI layout when adding addition conditions to the recipe like RPM and SU. +1. Max Item Inputs, Max Item Outputs, Max Fluid Inputs, Max Fluid Outputs +2. A list of available ```GuiTextures``` and ```FillDirection```s can be found in the GTCEu Modern Github, or in the .jar file. + diff --git a/docs/content/Modpacks/Other-Topics/Custom-Sounds.md b/docs/content/Modpacks/Other-Topics/Custom-Sounds.md new file mode 100644 index 00000000000..e7a243f9ea9 --- /dev/null +++ b/docs/content/Modpacks/Other-Topics/Custom-Sounds.md @@ -0,0 +1,50 @@ +--- +title: Custom Sounds +--- + + +## Creating a Custom Sound + +!!! Warning + Registering custom sounds is currently only supported in Java, though you can use your sound in kubejs scripts once it's defined. + +To add a new sound, a sounds class is required. +This class prepares for registrate to register the sounds. +An example of a custom sound can be found below. + +```java +import static com.examplemod.common.registry.ExampleRegistration.REGISTRATE; + +public class ExampleSound { + + public static final SoundEntry MICROVERSE = REGISTRATE.sound(ExampleMod.id("microverse")).build(); + + public static void init() {} +} +``` + +Before you run datagen, the sound needs to be prepared for use. For a sound to be registered it must be in .ogg format and be inside `assets/examplemod/sounds`. +!!! note "mono vs. stereo audio" + + Your audio file should be mono, as Minecraft's attentuation logic only works with single-channel audio. Stereo sounds won't fade out (they'll be played at the same volume at any distance from the source) and should only be used for background tracks such as the main menu music. + +After you make this class, prepare your sound, and initialize it in your main mod class, you want to setup datagen for the sounds. +It's a bit more complicated than normal datagen, so an example can be found below. + +```java +@Mod.EventBusSubscriber(modid = ExampleMod.MOD_ID) +public class ExampleDataGenerators { + + @SubscribeEvent + public static void gatherData(GatherDataEvent event) { + PackOutput packOutput = event.getGenerator().getPackOutput(); + + if (event.includeClient()) { + event.getGenerator().addProvider( + true, + new SoundEntryBuilder.SoundEntryProvider(packOutput, examplemod.MOD_ID)); + } + } +} + +``` diff --git a/docs/content/Modpacks/Other-Topics/Modifying-Crafting-Components.md b/docs/content/Modpacks/Other-Topics/Modifying-Crafting-Components.md deleted file mode 100644 index 8dc2e2e7f32..00000000000 --- a/docs/content/Modpacks/Other-Topics/Modifying-Crafting-Components.md +++ /dev/null @@ -1,150 +0,0 @@ ---- -title: "Modifying Crafting Components" ---- - -# Modifying Crafting Components - -## Changing a single entry - -With KubeJS it is possible to modify the predefined components of existing GTCEu Modern machine crafting recipes. -You can replace singular entries, or do bulk modification of components. --1 is defined as a fallback value if no other entries exist. if you modify in bulk, you **MUST** insert one if the component expects it to exist. otherwise the game may crash when loading recipes. Other numbers correspond to tier indices. for example: `3 == GTValues.HV` - -```js title="modification.js" -const Map = Java.loadClass("java.util.Map") - -GTCEuServerEvents.craftingComponents(event => { - event.modifyItem(CraftingComponent.CIRCUIT, GTValues.MV, Item.of('minecraft:dirt')) // (1) - event.modifyItem(CraftingComponent.PUMP, Map.of( - GTValues.FALLBACK, Item.of('gtceu:lv_robot_arm'), - GTValues.LV, Item.of('gtceu:lv_robot_arm'), - GTValues.MV, Item.of('gtceu:mv_robot_arm'), - GTValues.HV, Item.of('gtceu:hv_robot_arm'), - GTValues.EV, Item.of('gtceu:ev_robot_arm'), - GTValues.IV, Item.of('gtceu:iv_robot_arm'), - GTValues.LuV, Item.of('gtceu:luv_robot_arm'), - GTValues.ZPM, Item.of('gtceu:zpm_robot_arm'), - GTValues.UV, Item.of('gtceu:uv_robot_arm'), - )) // (2) - event.modifyTag(CraftingComponent.CASING, GTValues.EV, 'minecraft:logs') // (3) - event.modifyUnificationEntry(CraftingComponent.PLATE, GTValues.UEV, new UnificationEntry('plate', 'gtceu:infinity')) // (4) -}) -``` - -1. Replaces the MV circuit tag in all GT machine crafting recipes with a single block of `minecraft:dirt`. -2. Modifies all pumps in GT machine crafting recipes by replacing the pump with a robot arm, and reinserts the FALLBACK entry. -3. Replaces the EV casing with the `#minecraft:logs` tag. note the lack of `#` at the beginning of the tag! -4. Adds a new entry to the plate component for UEV with prefix `plate` and material `gtceu:infinity`. - -!!! tip "Bulk Callbacks" - - All the bulk callbacks (`modify*` functions that take two parameters instead of three, see example 2) work the same as the single modification functions, except they take a map of `int: value` instead of a single entry. - - -## Creating new components - -It's also possible to create new crafting components with KubeJS. -You must add entries for all tiers you're planning to use, and a FALLBACK if the map *may* be indexed out of bounds at all. -It's recommended to always add a FALLBACK entry. - -```js title="creation.js" -const Map = Java.loadClass("java.util.Map") - -let ITEM_CRAFTING_COMPONENT = null -let TAG_CRAFTING_COMPONENT = null -let UNIFICATION_CRAFTING_COMPONENT = null - -GTCEuServerEvents.craftingComponents(event => { - ITEM_CRAFTING_COMPONENT = event.createItem(Map.of( - GTValues.FALLBACK: Item.of('minecraft:cyan_stained_glass'), - GTValues.LV: Item.of('minecraft:cyan_stained_glass'), - GTValues.MV: Item.of('minecraft:cyan_stained_glass'), - GTValues.HV: Item.of('minecraft:cyan_stained_glass'), - GTValues.EV: Item.of('minecraft:lime_stained_glass'), - GTValues.IV: Item.of('minecraft:lime_stained_glass'), - GTValues.LuV: Item.of('minecraft:lime_stained_glass'), - GTValues.ZPM: Item.of('minecraft:magenta_stained_glass'), - GTValues.UV: Item.of('minecraft:magenta_stained_glass'), - )) // (1) - TAG_CRAFTING_COMPONENT = event.createTag(Map.of( - GTValues.FALLBACK: 'forge:barrels/wooden' - GTValues.LV: 'forge:chests/wooden' - GTValues.MV: 'forge:chests/trapped' - GTValues.HV: 'forge:chests/ender' - GTValues.EV: 'forge:cobblestone' - GTValues.IV: 'forge:cobblestone/normal' - GTValues.LuV: 'forge:cobblestone/infested' - GTValues.ZPM: 'forge:cobblestone/mossy' - GTValues.UV: 'forge:cobblestone/deepslate' - )) // (2) - UNIFICATION_CRAFTING_COMPONENT = event.createUnificationEntry(Map.of( - GTValues.FALLBACK: new UnificationEntry('plate', 'gtceu:infinity') - GTValues.LV: new UnificationEntry('block', 'gtceu:infinity') - GTValues.MV: new UnificationEntry('ingot', 'gtceu:infinity') - GTValues.HV: new UnificationEntry('dust', 'gtceu:infinity') - GTValues.EV: new UnificationEntry('round', 'gtceu:infinity') - GTValues.IV: new UnificationEntry('foil', 'gtceu:infinity') - GTValues.LuV: new UnificationEntry('longRod', 'gtceu:infinity') - GTValues.ZPM: new UnificationEntry('rod', 'gtceu:infinity') - GTValues.UV: new UnificationEntry('bolt', 'gtceu:infinity') - )) // (3) -}) -``` - -1. Creates a new crafting component with item stack entries. -2. Creates a new crafting component with item tag entries. note the lack of `#` at the beginning of the tag! -3. Creates a new crafting component with UnificationEntry entries. - - -### Builtin Crafting Components - -- `CIRCUIT` -- `BETTER_CIRCUIT` -- `PUMP` -- `WIRE_ELECTRIC` -- `WIRE_QUAD` -- `WIRE_OCT` -- `WIRE_HEX` -- `CABLE` -- `CABLE_DOUBLE` -- `CABLE_QUAD` -- `CABLE_OCT` -- `CABLE_HEX` -- `CABLE_TIER_UP` -- `CABLE_TIER_UP_DOUBLE` -- `CABLE_TIER_UP_QUAD` -- `CABLE_TIER_UP_OCT` -- `CABLE_TIER_UP_HEX` -- `CASING` -- `HULL` -- `PIPE_NORMAL` -- `PIPE_LARGE` -- `PIPE_NONUPLE` -- `GLASS` -- `PLATE` -- `HULL_PLATE` -- `MOTOR` -- `ROTOR` -- `SENSOR` -- `GRINDER` -- `SAWBLADE` -- `DIAMOND` -- `PISTON` -- `EMITTER` -- `CONVEYOR` -- `ROBOT_ARM` -- `COIL_HEATING` -- `COIL_HEATING_DOUBLE` -- `COIL_ELECTRIC` -- `STICK_MAGNETIC` -- `STICK_DISTILLATION` -- `FIELD_GENERATOR` -- `STICK_ELECTROMAGNETIC` -- `STICK_RADIOACTIVE` -- `PIPE_REACTOR` -- `POWER_COMPONENT` -- `VOLTAGE_COIL` -- `SPRING` -- `CRATE` -- `DRUM` -- `FRAME` diff --git a/docs/content/Modpacks/Other-Topics/Modifying-Multiblock-Controller-UI.md b/docs/content/Modpacks/Other-Topics/Modifying-Multiblock-Controller-UI.md new file mode 100644 index 00000000000..62bf4e06fa4 --- /dev/null +++ b/docs/content/Modpacks/Other-Topics/Modifying-Multiblock-Controller-UI.md @@ -0,0 +1,42 @@ +--- +title: Modifying Multiblock Controller UI +--- +# Modifying Multiblock Controller UI + +## Adding text component +To add text component to the UI, you need to use `.additionalDisplay` in the multiblock registration builder. +`.additionalDisplay` takes a lambda that takes 2 arguments: the `IMultiController` machine that the components are being added to, and the `List` of existing components. +An example of using it would be: + +```js title="ui_modified_multiblock.js" +GTCEuStartupEvents.registry('gtceu:machine', event => { + event.create('ui_modified_multiblock', 'multiblock') + .rotationState(RotationState.NON_Y_AXIS) + .recipeType('electrolyzer') + .recipeModifiers([GTRecipeModifiers.OC_NON_PERFECT_SUBTICK]) + .appearanceBlock(() => Block.getBlock("gtceu:solid_machine_casing")) + .pattern(definition => FactoryBlockPattern.start() + .aisle('###',' ','###') + .aisle('###',' S ','###') + .aisle('#C#',' ','###') + .where('C', Predicates.controller(Predicates.blocks(definition.get()))) + .where('#', Predicates.blocks("gtceu:solid_machine_casing") + .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setPreviewCount(1)) + .or(Predicates.abilities(PartAbility.EXPORT_ITEMS).setPreviewCount(1)) + .or(Predicates.abilities(PartAbility.INPUT_ENERGY).setMaxGlobalLimited(1).setPreviewCount(1))) + .where('S', Predicates.blocks("gtceu:steel_machine_casing")) + .where(' ', Predicates.any()) + .build()) + .workableCasingModel("gtceu:block/casings/solid/machine_casing_solid_steel", "gtceu:block/multiblock/blast_furnace") + .additionalDisplay((machine, components) => { // (3) + if (machine.isFormed()) { // (1) + components.add(Component.literal("I am text component #1")) // (2) + components.add(Component.literal("I am text component #2")) + } + }) +}); +``` + +1. Check if multiblock is formed +2. To add new line - Use `components.add(Component)`. +3. Using `.additionalDisplay()` to add text component. \ No newline at end of file diff --git a/docs/content/Modpacks/Other-Topics/Adding-and-Removing-Recipes.md b/docs/content/Modpacks/Recipes/Adding-and-Removing-Recipes.md similarity index 71% rename from docs/content/Modpacks/Other-Topics/Adding-and-Removing-Recipes.md rename to docs/content/Modpacks/Recipes/Adding-and-Removing-Recipes.md index fda0b6e784e..c8d1e5a807f 100644 --- a/docs/content/Modpacks/Other-Topics/Adding-and-Removing-Recipes.md +++ b/docs/content/Modpacks/Recipes/Adding-and-Removing-Recipes.md @@ -86,10 +86,12 @@ ServerEvents.recipes(event => { - `.itemInput()` - `.itemInputs()` - `.chancedInput()` + - `.itemInputsRanged()` - `.notConsumable()` - Fluids: - `.inputFluids()` - `.chancedFluidInput()` + - `.inputFluidsRanged()` - `.notConsumableFluid()` - Misc: - `.circuit()` @@ -98,9 +100,11 @@ ServerEvents.recipes(event => { - `.itemOutput()` - `.itemOutputs()` - `.chancedOutput()` + - `.itemOutputsRanged()` - Fluids: - `.outputFluids()` - `.chancedFluidOutput()` + - `.outputFluidsRanged()` - Energy: - `.inputEU()`: Makes the recipe consume a lump sum of EU to start the recipe. Most often seen in fusion reactor recipes. @@ -109,6 +113,28 @@ ServerEvents.recipes(event => { - `.EUt()`: Takes a numerical value representing an EU amount. Positive values will make the recipe consume energy per tick, negative ones will make it generate energy per tick. +- Chanced Ingredients: + - Ingredients that are not consumed/produced on every run of a recipe. Can be expressed as either a fraction, or as an + integer chance out of 10,000. + - Assigning an Input ingredient with a Chance of `0` causes that ingredient to be flagged as `Non-Consumed` in EMI. + This can also be done more easily using `.notConsumable()`. + - Recipes with chanced ingredients can also have a Chance Logic designated for each of their input/output sets, using + one or more of the functions `.chancedItemInputLogic()`, `.chancedFluidInputLogic()`, `.chancedTickInputLogic()`, + `.chancedItemOutputLogic()`, `.chancedFluidOutputLogic()`, `.chancedTickOutputLogic()` + - Valid options for chanced logic are: + - `or` - (default) Any item/fluid which succeeds on its chance roll is produced/consumed. + - `and` - If _all_ items/fluids succeed on their chance roll, all are produced/consumed together. Otherwise, none are. + - `xor` - Normalizes ingredient chances, and guarantees that exactly one of the chanced items/fluids will be + produced/consumed on every run. XOR's behavior was changed in 7.0.0. + - `first` - Makes a chance roll for each item/fluid, in order of registration. Only the first item which succeeds + on its roll is returned. Prior to 7.0.0, this was the behavior of `xor` logic. + - Because of its unpredictable behavior, FIRST has been Deprecated as of 7.3.0, and is scheduled for removal + in 8.0.0. +- Ranged Ingredients: + - Item or Fluid ingredients that will be consumed or produced in a random amount within a `min, max` range (inclusive). +- Circuits + - Many GT recipes use a `Programmed Circuit` item with a Configuration value of `1-32` as a `Non-Consumed` input, +to distinguish them from other recipes in the same machine with similar ingredients. `.circuit()` adds one to a recipe. - More granular functionality: - `.perTick()`: Using this will enable you to control whether a recipe input/output is consumed/produced per tick the recipe is @@ -154,18 +180,21 @@ ServerEvents.recipes(event => { ### Rock breaker fluids -!!! warning -When adding rock breaker recipes you will need to manually define the fluids the rock breaker will use. -(might change in the future) +Rock breaker recipes use AdjacentFluidConditions. + +To add a condition, you can use the `adjacentFluids(Fluid...)` methods, see [our other condition builder methods](https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java#L894). ```js title="rock_breaker.js" ServerEvents.recipes(event => { event.recipes.gtceu.rock_breaker('rhino_jank') .notConsumable('minecraft:dirt') .itemOutputs('minecraft:dirt') - .addDataString("fluidA", "minecraft:lava") - .addDataString("fluidB", "minecraft:water") + .adjacentFluids('minecraft:water') + .adjacentFluids('minecraft:lava') .duration(16) .EUt(30) }) ``` + +### More custom ingredients +For more custom ingredients, see the [Ingredients list in the sidebar](Ingredients/index.md) \ No newline at end of file diff --git a/docs/content/Modpacks/Recipes/Crafting-Components.md b/docs/content/Modpacks/Recipes/Crafting-Components.md new file mode 100644 index 00000000000..4c56bf47351 --- /dev/null +++ b/docs/content/Modpacks/Recipes/Crafting-Components.md @@ -0,0 +1,163 @@ +--- +title: "Crafting Components" +--- + +# Crafting Components + +Crafting Components are a way to organize and simplify the various similar recipes that GregTech generates. For example: writing out the recipes for all tiers of an alloy smelter can be done iteratively rather than one by one. + +Crafting Components are a map pairing a Voltage tier (the tier number) to a value. The value can be a `MaterialEntry`, `ItemStack`, or `TagPrefix`. + +## Changing a single entry + +With KubeJS it is possible to modify the predefined components of existing GTCEu Modern machine crafting recipes. +You can replace singular entries, or do bulk modification of components. +-1 is defined as a fallback value if no other entries exist. + +```js title="startup/modification.js" +const Map = Java.loadClass("java.util.Map") + +GTCEuStartupEvents.craftingComponents(event => { + event.setItem(GTCraftingComponents.CIRCUIT, GTValues.MV, Item.of('minecraft:dirt')) // (1) + event.setItems(GTCraftingComponents.PUMP, Map.of( + GTValues.LV, Item.of('gtceu:lv_robot_arm'), + GTValues.MV, Item.of('gtceu:mv_robot_arm'), + GTValues.HV, Item.of('gtceu:hv_robot_arm'), + GTValues.EV, Item.of('gtceu:ev_robot_arm'), + GTValues.IV, Item.of('gtceu:iv_robot_arm'), + GTValues.LuV, Item.of('gtceu:luv_robot_arm'), + GTValues.ZPM, Item.of('gtceu:zpm_robot_arm'), + GTValues.UV, Item.of('gtceu:uv_robot_arm'), + )) // (2) + event.setTag(GTCraftingComponents.CASING, GTValues.EV, 'minecraft:logs') // (3) + event.setMaterialEntry(GTCraftingComponents.PLATE, GTValues.UEV, new MaterialEntry('plate', 'gtceu:infinity')) // (4) + event.removeTier("sensor", 3) // (5) +}) +``` +1. Replaces the MV circuit tag in all GT machine crafting recipes with a single block of `minecraft:dirt`. +2. Modifies all pumps in GT machine crafting recipes by replacing the pump with a robot arm. +3. Replaces the EV casing with the `#minecraft:logs` tag. note the lack of `#` at the beginning of the tag! +4. Adds a new entry to the plate component for UEV with prefix `plate` and material `gtceu:infinity`. +5. Removes the 3rd offset entry `(HV Tier)` of the sensor crafting component, will default to the fallback `(LV Sensor)` + + +## Creating new components + +It's also possible to create new crafting components with KubeJS. +The crafting component is constructed with a id and a fallback value. You can add entries by chaining `.add(tier, value)` methods after your construction. + +```js title="creation.js" +const Map = Java.loadClass("java.util.Map") + +let ITEM_CRAFTING_COMPONENT = null +let TAG_CRAFTING_COMPONENT = null +let UNIFICATION_CRAFTING_COMPONENT = null + +GTCEuServerEvents.craftingComponents(event => { + ITEM_CRAFTING_COMPONENT = event.createItem("item_component", 'minecraft:cyan_stained_glass') + .addItem(GTValues.LV, Item.of('minecraft:cyan_stained_glass')) + .addItem(GTValues.MV, Item.of('minecraft:cyan_stained_glass')) + .addItem(GTValues.HV, Item.of('minecraft:cyan_stained_glass')) + .addItem(GTValues.EV, Item.of('minecraft:lime_stained_glass')) + .addItem(GTValues.IV, Item.of('minecraft:lime_stained_glass')) + .addItem(GTValues.LuV, Item.of('minecraft:lime_stained_glass')) + .addItem(GTValues.ZPM, Item.of('minecraft:magenta_stained_glass')) + .addItem(GTValues.UV, Item.of('minecraft:magenta_stained_glass')) + // (1) + TAG_CRAFTING_COMPONENT = event.createTag("tag_component", 'forge:barrels/wooden') + .addTag(GTValues.LV, 'forge:chests/wooden') + .addTag(GTValues.MV, 'forge:chests/trapped') + .addTag(GTValues.HV, 'forge:chests/ender') + .addTag(GTValues.EV, 'forge:cobblestone') + .addTag(GTValues.IV, 'forge:cobblestone/normal') + .addTag(GTValues.LuV, 'forge:cobblestone/infested') + .addTag(GTValues.ZPM, 'forge:cobblestone/mossy') + .addTag(GTValues.UV, 'forge:cobblestone/deepslate') + // (2) + UNIFICATION_CRAFTING_COMPONENT = event.createMaterialEntry("material_entry_component", new MaterialEntry('plate', 'gtceu:infinity')) + .addMaterialEntry(GTValues.LV, new MaterialEntry('block', 'gtceu:infinity')) + .addMaterialEntry(GTValues.MV, 'ingot', 'gtceu:infinity') + .addMaterialEntry(GTValues.HV, new MaterialEntry('dust', 'gtceu:infinity')) + .addMaterialEntry(GTValues.EV, new MaterialEntry('round', 'gtceu:infinity')) + .addMaterialEntry(GTValues.IV, new MaterialEntry('foil', 'gtceu:infinity')) + .addMaterialEntry(GTValues.LuV, 'longRod', 'gtceu:infinity') + .addMaterialEntry(GTValues.ZPM, new MaterialEntry('rod', 'gtceu:infinity')) + .addMaterialEntry(GTValues.UV, new MaterialEntry('bolt', 'gtceu:infinity')) + // (3) +}) +``` + +1. Creates a new crafting component with item stack entries. +2. Creates a new crafting component with item tag entries. note the lack of `#` at the beginning of the tag! +3. Creates a new crafting component with UnificationEntry entries. + +## Retrieving existing crafting components + +All `remove`, `modify*`, and `setFallback*` methods use a Crafting Component as its first argument, you can supply that argument with just a string matching the id of the crafting component + +```js title="modify.js" + +GTCEuServerEvents.craftingComponents(event => { + event.removeTier('robot_arm', GTValues.EV) // (1) + + event.removeTiers('pump', GTValues.EV, GTValues.IV, GTValues.LuV) // (2) +}) +``` + +1. Finds the crafting component with id `robot_arm` and removes the entry for `EV` tier +2. Finds the crafting component with id `pump` and removes the entry for `EV, IV & LuV` tiers + +### Builtin Crafting Components + +- `CIRCUIT 'circuit'` +- `BETTER_CIRCUIT 'better_circuit'` +- `WIRE_ELECTRIC 'wire_single'` +- `WIRE_QUAD 'wire_quad'` +- `WIRE_OCT 'wire_oct'` +- `WIRE_HEX 'wire_hex'` +- `CABLE 'cable_single'` +- `CABLE_DOUBLE 'cable_double'` +- `CABLE_QUAD 'cable_quad'` +- `CABLE_OCT 'cable_oct'` +- `CABLE_HEX 'cable_hex'` +- `CABLE_TIER_UP 'cable_tier_up_single'` +- `CABLE_TIER_UP_DOUBLE 'cable_tier_up_double'` +- `CABLE_TIER_UP_QUAD 'cable_tier_up_quad'` +- `CABLE_TIER_UP_OCT 'cable_tier_up_oct'` +- `CABLE_TIER_UP_HEX 'cable_tier_up_hex'` +- `CASING 'casing'` +- `HULL 'hull'` +- `PIPE_NORMAL 'normal_pipe'` +- `PIPE_LARGE 'large_pipe'` +- `PIPE_NONUPLE 'nonuple_pipe'` +- `GLASS 'glass'` +- `PLATE 'plate'` +- `HULL_PLATE 'hull_plate'` +- `ROTOR 'rotor'` +- `GRINDER 'grinder'` +- `SAWBLADE 'sawblade'` +- `DIAMOND 'diamond'` +- `MOTOR 'motor'` +- `PUMP 'pump'` +- `PISTON 'piston'` +- `EMITTER 'emitter'` +- `SENSOR 'sensor'` +- `CONVEYOR 'conveyor'` +- `ROBOT_ARM 'robot_arm'` +- `FIELD_GENERATOR 'field_generator'` +- `COIL_HEATING 'coil_heating'` +- `COIL_HEATING_DOUBLE 'coil_heating_double'` +- `COIL_ELECTRIC 'coil_electric'` +- `STICK_MAGNETIC 'rod_magnetic'` +- `STICK_DISTILLATION 'rod_distillation'` +- `STICK_ELECTROMAGNETIC 'rod_electromagnetic'` +- `STICK_RADIOACTIVE 'rod_radioactive'` +- `PIPE_REACTOR 'pipe_reactor'` +- `POWER_COMPONENT 'power_component'` +- `VOLTAGE_COIL 'voltage_coil'` +- `SPRING 'spring'` +- `CRATE 'crate'` +- `DRUM 'drum'` +- `FRAME 'frame'` +- `SMALL_SPRING_TRANSFORMER 'small_spring_transformer'` +- `SPRING_TRANSFORMER 'spring_transformer'` \ No newline at end of file diff --git a/docs/content/Modpacks/Recipes/Custom-Recipe-Modifiers.md b/docs/content/Modpacks/Recipes/Custom-Recipe-Modifiers.md new file mode 100644 index 00000000000..27d77db8610 --- /dev/null +++ b/docs/content/Modpacks/Recipes/Custom-Recipe-Modifiers.md @@ -0,0 +1,95 @@ +--- +title: Custom Recipe Modifiers +--- + +# Custom Recipe Modifiers / Data Logic + +## Adding a Modifier +Custom recipe modifiers in KubeJS are done through a function. For this example, we will make multiblock that requires temperature for recipes, like the EBF does. +```js title="temperature_recipe_modifier.js" +const $GTRecipe = Java.loadClass("com.gregtechceu.gtceu.api.recipe.GTRecipe"); +const $MetaMachine = Java.loadClass("com.gregtechceu.gtceu.api.machine.MetaMachine"); + +function TemperatureModifier(machine, recipe) { + if (!(machine instanceof $MetaMachine)) return ModifierFunction.NULL // (1) + if (!(recipe instanceof $GTRecipe)) return ModifierFunction.NULL + + if (!machine instanceof $CoilWorkableElectricMultiblockMachine) { + return $RecipeModifier.nullWrongType($CoilWorkableElectricMultiblockMachine, machine); + } else { + + let temp = machine.getCoilType().getCoilTemperature() // (3) + + let recipeTemp = recipe.data.getInt("RequiredTemp") // (4) + if (recipeTemp > temp) { + return ModifierFunction.NULL + } + return ModifierFunction.IDENTITY // (2) + } +} +``` + +1. `ModifierFunction.NULL` Stops recipe. +2. `ModifierFunction.IDENTITY` Starts recipe. +3. Getting the coil temperature, multiblock **must** contain ``.heatingCoils()`` in any of its keys. +4. Checking if coil temperature is high enough. + +## Using Modifier +```js title="example_temperature_multiblock.js" +const $CoilWorkableElectricMultiblockMachine = Java.loadClass("com.gregtechceu.gtceu.api.machine.multiblock.CoilWorkableElectricMultiblockMachine"); + +GTCEuStartupEvents.registry('gtceu:recipe_type', event => { + event.create('example_smelting') + .category('multiblock') + .setMaxIOSize(1, 1, 0, 0) + .setProgressBar(GuiTextures.PROGRESS_BAR_FUSION, FillDirection.LEFT_TO_RIGHT) + .setSound(GTSoundEntries.BATH); +}); + +GTCEuStartupEvents.registry('gtceu:machine', event => { + + GTRecipeTypes.get("example_smelting").addDataInfo((data) => ( + `Temperature: ${data.getInt("RequiredTemp")}K` // (4) + )) // (3) + + event.create('example_smelter', 'multiblock') + .rotationState(RotationState.NON_Y_AXIS) + .machine((holder) => new $CoilWorkableElectricMultiblockMachine(holder)) // (1) + .recipeType('alchemy') + .recipeModifiers([(machine, recipe) => TemperatureModifier(machine, recipe)]) // (2) + .appearanceBlock(() => Block.getBlock("gtceu:solid_machine_casing")) + .pattern(definition => FactoryBlockPattern.start() + .aisle('###','HHH','###') + .aisle('###','H H','###') + .aisle('#C#','HHH','###') + .where('C', Predicates.controller(Predicates.blocks(definition.get()))) + .where('#', Predicates.blocks("gtceu:solid_machine_casing") + .or(Predicates.abilities(PartAbility.IMPORT_ITEMS).setPreviewCount(1)) + .or(Predicates.abilities(PartAbility.EXPORT_ITEMS).setPreviewCount(1)) + .or(Predicates.abilities(PartAbility.INPUT_ENERGY).setMaxGlobalLimited(1).setPreviewCount(1))) + .where('H', Predicates.heatingCoils()) + .where(' ', Predicates.any()) + .build()) + .workableCasingModel("gtceu:block/casings/solid/machine_casing_solid_steel", "gtceu:block/multiblock/blast_furnace") +}) +``` + +1. Making multiblock **coilMachine**, without it our modifier won't work. +2. Using our modifier. +3. Display our data in EMI. +4. Getting `RequiredTemp` data from our recipe. + +## Using our Modifier in a Recipe +To use our modifier in recipe, you need to add data to it. +```js title="example_smelting.js" +ServerEvents.recipes(event => { + event.recipes.gtceu.example_smelting('example:diamondirt') + .itemInputs('minecraft:dirt') + .itemOutputs('gtceu:raw_diamond') + .addData("RequiredTemp", 1000) // (1) + .duration(320) + .EUt(GTValues.VA[GTValues.LV]); +}) +``` + +1. Adding data to our recipe, in this situation - Temperature \ No newline at end of file diff --git a/docs/content/Modpacks/Recipes/Ingredients/NBT-Predicate-Ingredients.md b/docs/content/Modpacks/Recipes/Ingredients/NBT-Predicate-Ingredients.md new file mode 100644 index 00000000000..3233996f1af --- /dev/null +++ b/docs/content/Modpacks/Recipes/Ingredients/NBT-Predicate-Ingredients.md @@ -0,0 +1,191 @@ +--- +title: "NBT Predicate Ingredients" +--- + +For some use-cases, using Partial or Strict NBT Ingredients does not give enough control. For this, we have NBT Predicate Ingredients. +This system allows you to query NBT contents during recipe matching to validate more advanced queries on ItemStacks. + +!!! note + To test your items in-game, you can use the give and ftblibrary commands, e.g. `/give @p dirt{"attributes": {"strength":16, "sound":"crunch.wav" } }` to give yourself an item with custom NBT or `/ftblibrary nbtedit hand` for a graphical editor +## Usage +### Equals +For JavaScript, custom overloads were made: + +- `.eqString(key, value)` +- `.eqInt(key, value)` +- `.eqFloat(key, value)` +- `.eqByte(key, value)` +- `.eqDouble(key, value)` +- `.eqTag(key, value)` + +All of these also have an `.neq[...](key, value)` function. +In Java, these are also available, as well as simpler `.[n]eq(key, [type] value)` overloads. + + +=== "JavaScript" + ```js title="gt_recipes.js" + + ServerEvents.recipes(event => { + event.recipes.gtceu.assembler('test_nbt') + .inputItemNbtPredicate('minecraft:dirt', NBTPredicates.eqString("charge", "23")) + .itemOutputs('minecraft:stick') + .duration(100) + .EUt(30) + }) + + ``` + +=== "Java" + ```java title="GTRecipes.java" + + public static void init(Consumer provider) { + ASSEMBLER_RECIPES.recipeBuilder("test_nbt") + .inputItemNbtPredicate(new ItemStack(Items.dirt, 1), NBTPredicates.eq("charge", "23")) + .outputItems(new ItemStack(Items.STICK)) + .duration(100) + .EUt(30) + .save(provider); + } + + ``` + +### Number Comparison +The following number comparison operators exist: + +- `.lte(key, number)`: Less Than or Equal to +- `.lt(key, number)`: Less Than +- `.gte(key, number)`: Greater Than or Equal to +- `.gt(key, number)`: Greater Than + +=== "JavaScript" + ```js title="gt_recipes.js" + + ServerEvents.recipes(event => { + event.recipes.gtceu.assembler('test_nbt') + .inputItemNbtPredicate('minecraft:dirt', NBTPredicates.lt("charge", 23)) + .itemOutputs('minecraft:stick') + .duration(100) + .EUt(30) + }) + + ``` + +=== "Java" + ```java title="GTRecipes.java" + + public static void init(Consumer provider) { + ASSEMBLER_RECIPES.recipeBuilder("test_nbt") + .inputItemNbtPredicate(new ItemStack(Items.dirt, 1), NBTPredicates.lt("charge", 23)) + .outputItems(new ItemStack(Items.STICK)) + .duration(100) + .EUt(30) + .save(provider); + } + + ``` + + +### Any/All +The following list operators exist: + +- `.all(NBTPredicate...)` +- `.any(NBTPredicate...)` + +=== "JavaScript" + ```js title="gt_recipes.js" + + ServerEvents.recipes(event => { + event.recipes.gtceu.assembler('test_nbt') + .inputItemNbtPredicate('minecraft:dirt', + NBTPredicates.all([ + NBTPredicates.lt("charge", 23), + NBTPredicates.eqString("color", "blue") + ])) + .itemOutputs('minecraft:stick') + .duration(100) + .EUt(30) + }) + + ``` + +=== "Java" + ```java title="GTRecipes.java" + + public static void init(Consumer provider) { + ASSEMBLER_RECIPES.recipeBuilder("test_nbt") + .inputItemNbtPredicate(new ItemStack(Items.dirt, 1), + NBTPredicates.all([ + NBTPredicates.lt("charge", 23), + NBTPredicates.eqString("color", "blue") + ])) + .outputItems(new ItemStack(Items.STICK)) + .duration(100) + .EUt(30) + .save(provider); + } + + ``` + + +### Not +The negation operators exists: + +- `.not(NBTPredicate)` + + +=== "JavaScript" + ```js title="gt_recipes.js" + + ServerEvents.recipes(event => { + event.recipes.gtceu.assembler('test_nbt') + .inputItemNbtPredicate(new ItemStack(Items.dirt, 1), + NBTPredicates.not( + NBTPredicates.all([ + NBTPredicates.lt("charge", 23), + NBTPredicates.eqString("color", "blue") + ]) + ) + ) + .itemOutputs('minecraft:stick') + .duration(100) + .EUt(30) + }) + + ``` + +=== "Java" + ```java title="GTRecipes.java" + + public static void init(Consumer provider) { + ASSEMBLER_RECIPES.recipeBuilder("test_nbt") + .inputItemNbtPredicate(new ItemStack(Items.dirt, 1), + NBTPredicates.not( + NBTPredicates.all([ + NBTPredicates.lt("charge", 23), + NBTPredicates.eqString("color", "blue") + ]) + ) + ) + .outputItems(new ItemStack(Items.STICK)) + .duration(100) + .EUt(30) + .save(provider); + } + + ``` + + +### Key Navigation +You can use `.` to navigate nested tags, and `[i]` to index into lists. so +``` +{ "machine": + { "states" : + [ + {"color": "green"}, + {"color": "red"}, + ] + } +} +``` +would match +`.eq("machine.states[0].color", "green")` diff --git a/docs/content/Modpacks/Recipes/Ingredients/index.md b/docs/content/Modpacks/Recipes/Ingredients/index.md new file mode 100644 index 00000000000..4dbc5931ba8 --- /dev/null +++ b/docs/content/Modpacks/Recipes/Ingredients/index.md @@ -0,0 +1,5 @@ +--- +title: "Ingredients" +--- + +These pages contain information about custom ingredients to be used in your recipes. \ No newline at end of file diff --git a/docs/content/Modpacks/Recipes/Material-Entries.md b/docs/content/Modpacks/Recipes/Material-Entries.md new file mode 100644 index 00000000000..d4849514a95 --- /dev/null +++ b/docs/content/Modpacks/Recipes/Material-Entries.md @@ -0,0 +1,99 @@ +--- +title: "Material Entry" +--- + +# Material Entries + +With the abundance of items in GregTech, there comes an abundance of recipes to craft those items into. However, sometimes you make too many of a certain item and want to recover your lost materials. Luckily you can do that with GT's built in recycling system. + +Any recipe that crafts an item, whether it be through a crafting table or a GT machine, can be specified to generate an additional recipe for decomposing that output item in the Macerator, Arc Furnace, and Extractor. + +## ItemMaterialInfo + +Before 7.0, the way to specify the decomposition information (called the `ItemMaterialInfo`) of an item was to strictly append it like the following: + +```java title="ItemMaterialInfo.java" +ChemicalHelper.registerMaterialInfo(GTBlocks.COIL_KANTHAL.get(), + new ItemMaterialInfo(new MaterialStack(GTMaterials.Kanthal, M * 8), // double wire + new MaterialStack(GTMaterials.Aluminium, M * 2), // foil + new MaterialStack(GTMaterials.Copper, M)) // ingot + ); // (1) + + VanillaRecipeHelper.addShapedRecipe(provider, true, // (2) + "casing_bronze_bricks", GTBlocks.CASING_BRONZE_BRICKS.asStack(ConfigHolder.INSTANCE.recipes.casingsPerCraft), + "PhP", "PBP", "PwP", + 'P', new MaterialEntry(TagPrefix.plate, GTMaterials.Bronze), + 'B', new ItemStack(Blocks.BRICKS)); + +``` + +1. `GTValues.M` denotes a single (1) mol amount of the material (usually 1 full dust's worth) +2. The boolean denotes whether to generate a decomposition recipe for this recipe + +In 7.0, a system was introduced to automatically detect the inputs of a recipe and use that information when generating a decomposition recipe for the resulting items. + +You can tell recipes to generate recycling information using either `.addMaterialInfo()` for item inputs ONLY or `addMaterialInfo(true, true)` for item and fluid inputs. You can also remove existing ItemMaterialInfo from an output item using `.removePreviousMaterialInfo()`, which will tell GT to not generate recycling recipes for the item output in that recipe. + +In KubeJS, adding decomposition info to a recipe would look as follows: + +```js title="itemDecomp.js" + +ServerEvents.recipes(event => { + event.recipes.gtceu.assembler('mv_hatch') + .itemInputs('17x gtceu:iron_plate') + .itemOutputs('1x gtceu:mv_energy_output_hatch') + .duration(20) + .addMaterialInfo(true) // (1) + .EUt(10) + + event.recipes.gtceu.assembler('bucket') + .itemInputs('4x minecraft:gold_ingot') + .itemOutputs('minecraft:bucket') + .removePreviousMaterialInfo() // (2) + .duration(20) + .EUt(23) +}) + +``` + +1. Generates a recycling recipe turning an MV energy hatch into 17 iron dust. +!!! note inline end + This will overwrite the original recycling recipe if it exists. + +2. Buckets will no longer have recycling recipes + +The ItemMaterialInfo system only takes into account the first item output a recipe has when appending material information to that item. However, it will automatically scale the decomposition rate based on the amount of the output stack. + +```js title="Seven Dirt" +ServerEvents.recipes(event => { + event.recipes.gtceu.assembler('mv_hatch') + .itemInputs('21x gtceu:iron_plate') + .itemOutputs('7x minecraft:dirt') + .duration(20) + .addMaterialInfo(true) // (1) + .EUt(10) +}) +``` + +1. Each dirt will turn into 3 iron dust when macerated + +## Crafting Table Recipes with Decomposition information + +```js title="Crafting Table" +ServerEvents.recipes(event => { + event.recipes.gtceu.shaped('4x kubejs:examplium', [ + " A ", + "ABA", + " A " + ], { + A: "gtceu:steel_ingot", + B: "minecraft:nether_star" + }) + .addMaterialInfo(true) // (1) +}) +``` + +1. Each examplium will turn into 1 steel dust and 1 small nether star dust when macerated + +??? tip "Decomposition recipes with Java" + You can still generate decomposition information for shapeless or shaped recipes with `VanillaRecipeHelper`, the argument was just renamed from `withUnificationData` to `setMaterialInfoData` diff --git a/docs/content/Modpacks/Recipes/Recipe-Conditions.md b/docs/content/Modpacks/Recipes/Recipe-Conditions.md new file mode 100644 index 00000000000..47fdaaa0ef8 --- /dev/null +++ b/docs/content/Modpacks/Recipes/Recipe-Conditions.md @@ -0,0 +1,49 @@ +--- +title: Recipe Conditions +--- + +Recipe Conditions are recipe properties that can prevent a recipe from starting based on certain criteria, like for example Biome, Weather, Quest Completions, or self-made custom Conditions. + +These conditions can be used in both java and kubejs recipes. However, custom conditons can only be done in java. If you want to see how to make these, check out the [Custom Recipe Condition](../Examples/Custom-Recipe-Condition.md) example page. + +!!! Note + The condition is run after recipe matching and before recipe execution. If the recipe condition doesn't match, the machine will be suspended and won't be updated again until something in the inputs/outputs changes. + +### Base Conditons + +- Biome: `.biome("namespace:biome_id")` + - Locks a recipe behind being inside a certain biome, works with any biome a pack has loaded. For example, you could use `minecraft:plains`. +- Dimension: `.dimension("namespace:dimension_id")` + - Locks a recipe being behind a certain dimension, the gas collector is a good example of this. For example, you could use `minecraft:the_end` +- Position_Y: `.posY(int min, int max)` + - Locks a recipe behind a certain y level in-world. For example, you could use `.posY(120, 130)` to have a recipe require a machine to be in between y 120 and y 130. +- Rain: `.rain(float level)` + - Locks a recipe behind a certain level of rain. For example, you could use `.rain(1.0)` to make a recipe need full rain. +- Adjacent_Fluids: `adjacentFluids("minecraft:water","minecraft:lava")` + - You can pass through any amount of fluids into the array. Moreover, any fluid passed into the array will make the recipe require a full source block touching the machine. We also have `adjacentFluidTag("forge:water", "forge:lava")`. +- Adjacent_Blocks: `adjacentBlocks("minecraft:stone", "minecraft:iron_block")` + - Much like the fluid condition, you can pass blocks into the array that lock the recipe behind needing the machine to touch these blocks. We also have `adjacentBlockTag("forge:stone", "forge:storage_blocks/iron")`. +- Thunder: `.thunder(float level)` + - Locks a recipe behind a certain level of rain. For example, you could use `.thunder(1.0)` to make a recipe need a strong thunderstorm. +- Vent: This condition is auto added to any steam single block, it blocks recipes from running if the vent is obstructed. +- Cleanroom: `.cleanroom(CleanroomType.CLEANROOM)` + - Locks a recipe to being inside a cleanroom. You can also use STERILE_CLEANROOM as well as your own custom cleanroom type. +- Fusion_Start_EU: `.fusionStartEU(long eu)` + - Locks a recipe behind the amount of stored power in a fusion machine. To use this, the machine must use the FusionReactorMachine class. For example, you could use `.fusionStartEU(600000)` +- Station_Research: `.stationResearch(b => b.researchStack("namespace:item_id").EUt(long eu).CWUt(int minCWUPerTick, int TotalCWU))` + - Locks a recipe behind having a certain research stack. For this condition to be properly seen, you will either need a base machine recipe type with the research ui component, or make your own. For example, you could do `.stationResearch(b => b.researchStack("gtceu:lv_motor").EUt(131000).CWUt(24, 12000))` which would lock a recipe behind needing a data orb with the lv motor research. It will also generate you a research station recipe. +- Scanner_Research: `.scannerResearch(b => b.researchStack("namespace:item_id").EUt(long eu))` + - Much like station research, this condition locks a recipe behind needing a research stack. However, in this case it will default to a data stick. For example, you could do `.scannerResearch(b => b.researchStack("gtceu:lv_motor").EUt(8192))`, which would make the recipe need a data stick with the lv motor research, and generates a scanner recipe. +- Enviromental_Hazard: `.environmentalHazard(GTMedicalConditions.CARBON_MONOXIDE_POISONING)` + - Locks a recipe into needing a certain environmental hazard to run. For now, carbon monoxide is the only one. An example of a machine using this condition is the air scrubber. +- Daytime: `.daytime(boolean notNight)` + - Locks recipe behind whether it is day or night. For example, you could do `.daytime(true)`, to make the recipe need it to be daytime. + +### Mod Dependent Conditions +- Ftb_Quests: `.ftbQuest(quest_id)` + - Locks a recipe behind the owner of a machine completing a ftb quest. An example can't be easily given since every quest book is different. +- Gamestage: `.gameStage(gameStage_id)` + - Locks a recipe behind a certain game stage. +- Heracles_Quests: `.heraclesQuest(quest_id)` + - Locks a recipe behind the owner of a machine completing a heracles quest. An example can't be easily given since every quest book is different. + diff --git a/docs/content/Modpacks/Recipes/TagPrefixRecipeGeneration.md b/docs/content/Modpacks/Recipes/TagPrefixRecipeGeneration.md new file mode 100644 index 00000000000..47ecefcae8c --- /dev/null +++ b/docs/content/Modpacks/Recipes/TagPrefixRecipeGeneration.md @@ -0,0 +1,54 @@ +--- +title: "Tag Prefix Recipe Generation" +--- + +# Generating recipes based on TagPrefixes + +Most recipes that turn some form of a material into another form, like iron ingots to iron plates, or tin bolts into tin screws, are done through tag prefix based recipe generation. + +Gregtech will iterate through all materials and all tag prefixes possible for that material to generate recipes. You can do the same in your addon by mirroring the following: + +```java title="TagPrefixRecipes.java" + +public static void recipeAddition(Consumer consumer) { + + for (Material material : GTCEuAPI.materialManager.getRegisteredMaterials()) { + if (material.hasFlag(MaterialFlags.NO_UNIFICATION)) { + continue; + } + MaterialRecipeHandler.run(provider, material) + } + +} + +``` + +```java title="MaterialRecipeHandler.java" + +public static void run(@NotNull Consumer provider, @NotNull Material material) { + processFrame(provider, material); +} + +private static void processFrame(@NotNull Consumer provider, @NotNull Material material) { + if (!material.shouldGenerateRecipesFor(frameGt) || !material.hasProperty(PropertyKey.DUST)) { + return; + } // (1) + + if (material.hasFlag(GENERATE_FRAME)) { + boolean isWoodenFrame = material.hasProperty(PropertyKey.WOOD); + VanillaRecipeHelper.addShapedRecipe(provider, String.format("frame_%s", material.getName()), + ChemicalHelper.get(frameGt, material, 2), + "SSS", isWoodenFrame ? "SsS" : "SwS", "SSS", + 'S', new UnificationEntry(rod, material)); + + ASSEMBLER_RECIPES.recipeBuilder("assemble_" + material.getName() + "_frame") + .inputItems(rod, material, 4) + .circuitMeta(4) + .outputItems(frameGt, material) + .EUt(VA[ULV]).duration(64) + .save(provider); + } + } + +``` +1. Checks that the material has a valid item with that specific tag prefix and can generate the recipe. \ No newline at end of file diff --git a/docs/content/index.md b/docs/content/index.md index 24d9f36b73f..430437cbf85 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -23,4 +23,3 @@ You can download an offline version of this wiki here: ## Want to Contribute? If you want to contribute to this documentation site, feel free to read [the instructions](https://github.com/GregTechCEu/GregTech-Modern/blob/1.20.1/docs/CONTRIBUTING.md) and open a pull request on the [GitHub repository](https://github.com/GregTechCEu/GregTech-Modern). -``` diff --git a/gradle.properties b/gradle.properties index a3f3bfe6a73..b9a1286baf9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ org.gradle.caching = true # Mod Info mod_id = gtceu mod_name = GregTech -mod_version = 7.1.0 +mod_version = 7.4.1 mod_description = GregTech CE Unofficial, ported from 1.12.2 mod_license = LGPL-3.0 license mod_url = https://github.com/GregTechCEu/GregTech-Modern/ diff --git a/gradle/forge.versions.toml b/gradle/forge.versions.toml index 935d6d8922f..bf422273fac 100644 --- a/gradle/forge.versions.toml +++ b/gradle/forge.versions.toml @@ -1,20 +1,20 @@ [versions] +configuration = "3.1.1-neoforge" ldlib = "1.0.35.a" registrate = "MC1.21-1.3.0+67" -configuration = "3.1.0-neoforge" -jei = "19.21.0.247" +jei = "19.25.1.328" rei = "16.0.799" -emi = "1.1.21+1.21.1" +emi = "1.1.22+1.21.1" ae2 = "19.2.8" -kubejs = "2101.7.1-build.181" -rhino = "2101.2.7-build.74" +kubejs = "2101.7.2-build.336" +rhino = "2101.2.7-build.81" architectury = "13.0.8" clothconfig = "15.0.140" theoneprobe = "1.21_neo-12.0.4-6" curios = "9.4.2+1.21.1" kotlinforforge = "5.7.0" -shimmer = "1.20.1-0.2.4" +# shimmer = "1.20.1-0.2.4" journeyMapApi = "2.0.0-1.21.1-SNAPSHOT" ftblibrary = "2101.1.12" ftbteams = "2101.1.2" @@ -27,7 +27,15 @@ bookshelf = "21.1.56" ae2wtlib = "19.2.2" argonauts = "1.2.4" # FIXME for some reason their maven only has versions up to 1.1.10? -heracles = "1.1.10" +# heracles = "1.1.13" +# journeyMapApi = "1.20-1.9-SNAPSHOT" +# ftblibrary = "2001.2.4" +# ftbteams = "2001.3.0" +# ftbquests = "2001.4.11" +# ftbchunks = "2001.3.4" +create = "6.0.8-168" +ponder = "1.0.64" +flywheel = "1.0.5" ## modrinth maven ## jade = "15.10.0+neoforge" @@ -54,6 +62,8 @@ ftbchunks-cm = "6295696" ldlib = { module = "com.lowdragmc.ldlib:ldlib-neoforge-1.21.1", version.ref = "ldlib" } registrate = { module = "com.tterrag.registrate:Registrate", version.ref = "registrate" } configuration = { module = "dev.toma.configuration:configuration-1.21.1", version.ref = "configuration" } +# mixinExtras-common = { module = "io.github.llamalad7:mixinextras-common", version.ref = "mixinExtras" } +# mixinExtras-forge = { module = "io.github.llamalad7:mixinextras-forge", version.ref = "mixinExtras" } jei-common-api = { module = "mezz.jei:jei-1.21.1-common-api", version.ref = "jei" } jei-neoforge-api = { module = "mezz.jei:jei-1.21.1-neoforge-api", version.ref = "jei" } @@ -68,22 +78,26 @@ kubejs = { module = "dev.latvian.mods:kubejs-neoforge", version.ref rhino = { module = "dev.latvian.mods:rhino", version.ref = "rhino" } architectury = { module = "dev.architectury:architectury-neoforge", version.ref = "architectury" } clothconfig = { module = "me.shedaniel.cloth:cloth-config-neoforge", version.ref = "clothconfig" } +create = { module = "com.simibubi.create:create-1.21.1", version.ref = "create" } +ponder = { module = "net.createmod.ponder:Ponder-NeoForge-1.21.1", version.ref = "ponder"} +flywheel-forge-api = { module = "dev.engine-room.flywheel:flywheel-neoforge-api-1.21.1", version.ref = "flywheel"} +flywheel-forge = { module = "dev.engine-room.flywheel:flywheel-neoforge-1.21.1", version.ref = "flywheel"} theoneprobe = { module = "mcjty.theoneprobe:theoneprobe", version.ref = "theoneprobe" } curios = { module = "top.theillusivec4.curios:curios-neoforge", version.ref = "curios" } kotlinforforge = { module = "thedarkcolour:kotlinforforge-neoforge", version.ref = "kotlinforforge" } journeymap-api = { module = "info.journeymap:journeymap-api-neoforge", version.ref = "journeyMapApi" } -shimmer = { module = "com.lowdragmc.shimmer:Shimmer-forge", version.ref = "shimmer" } +# shimmer = { module = "com.lowdragmc.shimmer:Shimmer-forge", version.ref = "shimmer" } ftblibrary = { module = "dev.ftb.mods:ftb-library-neoforge", version.ref = "ftblibrary" } ftbteams = { module = "dev.ftb.mods:ftb-teams-neoforge", version.ref = "ftbteams" } ftbquests = { module = "dev.ftb.mods:ftb-quests-neoforge", version.ref = "ftbquests" } ftbchunks = { module = "dev.ftb.mods:ftb-chunks-neoforge", version.ref = "ftbchunks" } resourcefullib = { module = "com.teamresourceful.resourcefullib:resourcefullib-neoforge-1.21", version.ref = "resourcefullib" } -gamestages = { module = "net.darkhax.gamestages:GameStages-Forge-1.20.3", version.ref = "gamestages" } +# gamestages = { module = "net.darkhax.gamestages:GameStages-Forge-1.20.3", version.ref = "gamestages" } bookshelf = { module = "net.darkhax.bookshelf:bookshelf-neoforge-1.21.1", version.ref = "bookshelf" } ae2wtlib = { module = "de.mari_023:ae2wtlib", version.ref = "ae2wtlib" } # TODO update these once there's 1.21 versions -argonauts = { module = "earth.terrarium.argonauts:argonauts-neoforge-1.20.4", version.ref = "argonauts" } -heracles = { module = "earth.terrarium.heracles:heracles-forge-1.20.1", version.ref = "heracles" } +# argonauts = { module = "earth.terrarium.argonauts:argonauts-neoforge-1.21.1`", version.ref = "argonauts" } +# heracles = { module = "earth.terrarium.heracles:heracles-neoforge-1.21.1", version.ref = "heracles" } jade = { module = "maven.modrinth:jade", version.ref = "jade" } sodium = { module = "maven.modrinth:sodium", version.ref = "sodium" } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 22ea9944e9c..351f52eae50 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,19 +1,23 @@ [versions] minecraft = "1.21.1" -neoForge = "21.1.147" +neoForge = "21.1.215" loader = "4" parchment = "2024.11.17" # https://parchmentmc.org/docs/getting-started shadow = "8.3.5" spotless = "7.0.4" -modDevGradle = "2.0.86" -lombok = "8.13.1" +modDevGradle = "2.0.119" +lombok = "8.14" jetbrains-annotations = "26.0.1" +renderNurse = "0.0.12" mixin = "0.8.7" [libraries] minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" } neoForge = { module = "net.neoforged:neoforge", version.ref = "neoForge" } +testframework = { module = "net.neoforged:testframework", version.ref = "neoForge" } jetbrains-annotations = { module = "org.jetbrains:annotations", version.ref = "jetbrains-annotations" } +renderNurse = { module = "net.neoforged:render-nurse", version.ref = "renderNurse" } +mixin = { module = "org.spongepowered:mixin", version.ref = "mixin" } [plugins] modDevGradle = { id = "net.neoforged.moddev", version.ref = "modDevGradle" } diff --git a/gradle/scripts/docs.gradle b/gradle/scripts/docs.gradle new file mode 100644 index 00000000000..ebcd4bbe41e --- /dev/null +++ b/gradle/scripts/docs.gradle @@ -0,0 +1,41 @@ +import org.apache.tools.ant.taskdefs.condition.Os + +tasks.register('mkdocsSetup', Exec) { + description = "Installs requirements for the MkDocs server." + group = "documentation" + + workingDir 'docs' + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + commandLine 'cmd.exe', '/c', + 'python -m venv .venv && .venv\\Scripts\\pip.exe install -r requirements.txt' + } else { + commandLine '/usr/bin/env', 'bash', '-c', + 'python3 -m venv .venv && ./.venv/bin/pip3 install -r requirements.txt' + } +} + +tasks.register('mkdocsServe', Exec) { + description = "Runs the MkDocs server." + group = "documentation" + dependsOn tasks.named('mkdocsSetup') + + workingDir 'docs' + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + commandLine '.\\docs\\.venv\\Scripts\\mkdocs.exe', 'serve' + } else { + commandLine './docs/.venv/bin/mkdocs', 'serve' + } +} + +tasks.register('mkdocsBuild', Exec) { + description = "Builds the MkDocs documentation in docs/site." + group = "documentation" + dependsOn tasks.named('mkdocsSetup') + + workingDir 'docs' + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + commandLine '.\\docs\\.venv\\Scripts\\mkdocs.exe', 'build' + } else { + commandLine './docs/.venv/bin/mkdocs', 'build' + } +} \ No newline at end of file diff --git a/gradle/scripts/jars.gradle b/gradle/scripts/jars.gradle index 2779f50e134..eefd0324763 100644 --- a/gradle/scripts/jars.gradle +++ b/gradle/scripts/jars.gradle @@ -16,6 +16,7 @@ sourcesJar { } from delombok } +jar.archiveClassifier = "dev" base { archivesName = "${project.name}-${libs.versions.minecraft.get()}" diff --git a/gradle/scripts/moddevgradle.gradle b/gradle/scripts/moddevgradle.gradle index 06b241d988c..39382ba9210 100644 --- a/gradle/scripts/moddevgradle.gradle +++ b/gradle/scripts/moddevgradle.gradle @@ -18,7 +18,7 @@ neoForge { publish(file) } // I'd have it on but it just doesn't work :( (fails on some neoforge classes) - // validateAccessTransformers = true + validateAccessTransformers = true interfaceInjectionData { var file = project.file('injected_interfaces/interfaces.json') @@ -29,7 +29,7 @@ neoForge { interfaceInjectionData = project.files('injected_interfaces/interfaces.json') addModdingDependenciesTo(sourceSets.test) -// addModdingDependenciesTo(sourceSets.extra) + addModdingDependenciesTo(sourceSets.extra) mods { // define mod <-> source bindings @@ -101,6 +101,17 @@ neoForge { gameDirectory.set(file('run/gametest')) systemProperty('neoforge.enabledGameTestNamespaces', project.mod_id) + environment('TEST', 'true') + } + + gameTestClient { + client() + sourceSet = sourceSets.test + ideName = "Game Tests (Client)" + + gameDirectory.set(file('run/gametest')) + systemProperty('neoforge.enabledGameTestNamespaces', project.mod_id) + environment('TEST', 'true') } data { @@ -116,6 +127,26 @@ neoForge { programArguments.addAll('--existing', file('src/main/resources/').getAbsolutePath()) } + String renderDocPath = System.getenv("RENDERDOC_LIB") + // RenderDoc cannot run on macos so we don't add the config for mac users + if(renderDocPath != null && !OperatingSystem.current().isMacOsX()) { + create("renderDocClient") { + client() + sourceSet = sourceSets.client + ideName = "Clean Client + RenderDoc (Requires Java 21)" + + programArguments.addAll('--username', 'screret', '--uuid', '1184eb79-5831-4f7d-b8f4-3a46fccf7a1d') + + systemProperty("neoforge.rendernurse.renderdoc.library", renderDocPath) + if(OperatingSystem.current().isLinux()) { + environment("LD_PRELOAD", renderDocPath) + } + // parses out the render nurse jar path and adds as `-javaagent:${path}` + jvmArguments.addAll(project.configurations.renderNurseCfg.incoming.files.elements.map { it.collect { "-javaagent:${it.asFile.absolutePath}" }}) + jvmArguments.addAll("--enable-preview", "--enable-native-access=ALL-UNNAMED") + } + } + // applies to all the run configs above configureEach { // Recommended logging data for a userdev environment diff --git a/gradle/scripts/repositories.gradle b/gradle/scripts/repositories.gradle index 3ecbe3a8b6b..ee14869ea80 100644 --- a/gradle/scripts/repositories.gradle +++ b/gradle/scripts/repositories.gradle @@ -14,9 +14,26 @@ repositories { maven { // LDLib, Shimmer name = "FirstDarkDev Maven" - url = "https://maven.firstdarkdev.xyz/snapshots/" + url = "https://maven.firstdark.dev/snapshots" } + maven { url = "https://maven.createmod.net" } + + + exclusiveContent { // Create, Ponder, Flywheel + forRepository { + maven { url = "https://maven.createmod.net" } + } + filter { + includeGroup("net.createmod.ponder") + includeGroup("com.simibubi.create") + includeGroup("dev.engine-room.flywheel") + } + } + exclusiveContent { // Configuration + forRepository { maven { url = "https://repo.repsy.io/mvn/toma/public" } } + filter { includeGroup("dev.toma.configuration")} + } exclusiveContent { // KubeJS and Rhino forRepository { maven { url = "https://maven.latvian.dev/releases" } } filter { @@ -24,10 +41,6 @@ repositories { includeGroup("dev.latvian.apps") } } - exclusiveContent { // Configuration - forRepository { maven { url = "https://repo.repsy.io/mvn/toma/public/" } } - filter { includeGroup('dev.toma.configuration') } - } exclusiveContent { // FTB mods forRepository { maven { url = "https://maven.ftb.dev/releases/" } } filter { includeGroup("dev.ftb.mods") } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa75..1b33c55baab 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e1adfb4938e..ca025c83a7c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index b740cf13397..23d15a93670 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -112,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -203,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. @@ -211,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 25da30dbdee..db3a6ac207e 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @@ -68,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/generated/resources/assets/gtceu/blockstates/active_transformer.json b/src/generated/resources/assets/gtceu/blockstates/active_transformer.json index a1fb5bbb1f8..1f6525e5d7d 100644 --- a/src/generated/resources/assets/gtceu/blockstates/active_transformer.json +++ b/src/generated/resources/assets/gtceu/blockstates/active_transformer.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/active_transformer", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/active_transformer", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/active_transformer" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/active_transformer" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/active_transformer" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/active_transformer", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/active_transformer", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/active_transformer", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/active_transformer", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/active_transformer", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/active_transformer", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/advanced_monitor.json b/src/generated/resources/assets/gtceu/blockstates/advanced_monitor.json new file mode 100644 index 00000000000..a290a4c4878 --- /dev/null +++ b/src/generated/resources/assets/gtceu/blockstates/advanced_monitor.json @@ -0,0 +1,114 @@ +{ + "variants": { + "facing=down,upwards_facing=east": { + "gtceu:z": 90, + "model": "gtceu:block/machine/advanced_monitor", + "x": 90 + }, + "facing=down,upwards_facing=north": { + "model": "gtceu:block/machine/advanced_monitor", + "x": 90 + }, + "facing=down,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/advanced_monitor", + "x": 90 + }, + "facing=down,upwards_facing=west": { + "gtceu:z": 270, + "model": "gtceu:block/machine/advanced_monitor", + "x": 90 + }, + "facing=east,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/advanced_monitor", + "y": 90 + }, + "facing=east,upwards_facing=north": { + "model": "gtceu:block/machine/advanced_monitor", + "y": 90 + }, + "facing=east,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/advanced_monitor", + "y": 90 + }, + "facing=east,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/advanced_monitor", + "y": 90 + }, + "facing=north,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/advanced_monitor" + }, + "facing=north,upwards_facing=north": { + "model": "gtceu:block/machine/advanced_monitor" + }, + "facing=north,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/advanced_monitor" + }, + "facing=north,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/advanced_monitor" + }, + "facing=south,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/advanced_monitor", + "y": 180 + }, + "facing=south,upwards_facing=north": { + "model": "gtceu:block/machine/advanced_monitor", + "y": 180 + }, + "facing=south,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/advanced_monitor", + "y": 180 + }, + "facing=south,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/advanced_monitor", + "y": 180 + }, + "facing=up,upwards_facing=east": { + "gtceu:z": 90, + "model": "gtceu:block/machine/advanced_monitor", + "x": 270 + }, + "facing=up,upwards_facing=north": { + "gtceu:z": 180, + "model": "gtceu:block/machine/advanced_monitor", + "x": 270 + }, + "facing=up,upwards_facing=south": { + "model": "gtceu:block/machine/advanced_monitor", + "x": 270 + }, + "facing=up,upwards_facing=west": { + "gtceu:z": 270, + "model": "gtceu:block/machine/advanced_monitor", + "x": 270 + }, + "facing=west,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/advanced_monitor", + "y": 270 + }, + "facing=west,upwards_facing=north": { + "model": "gtceu:block/machine/advanced_monitor", + "y": 270 + }, + "facing=west,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/advanced_monitor", + "y": 270 + }, + "facing=west,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/advanced_monitor", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/blockstates/alloy_blast_smelter.json b/src/generated/resources/assets/gtceu/blockstates/alloy_blast_smelter.json index f815dd04f37..b1c3a4e008c 100644 --- a/src/generated/resources/assets/gtceu/blockstates/alloy_blast_smelter.json +++ b/src/generated/resources/assets/gtceu/blockstates/alloy_blast_smelter.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/alloy_blast_smelter", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/alloy_blast_smelter", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/alloy_blast_smelter" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/alloy_blast_smelter" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/alloy_blast_smelter" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/alloy_blast_smelter", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/alloy_blast_smelter", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/alloy_blast_smelter", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/alloy_blast_smelter", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/alloy_blast_smelter", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/alloy_blast_smelter", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/assembly_line.json b/src/generated/resources/assets/gtceu/blockstates/assembly_line.json index e60c2f78f22..323d7956b30 100644 --- a/src/generated/resources/assets/gtceu/blockstates/assembly_line.json +++ b/src/generated/resources/assets/gtceu/blockstates/assembly_line.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/assembly_line", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/assembly_line", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/assembly_line" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/assembly_line" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/assembly_line" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/assembly_line", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/assembly_line", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/assembly_line", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/assembly_line", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/assembly_line", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/assembly_line", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/basic_data_access_hatch.json b/src/generated/resources/assets/gtceu/blockstates/basic_data_access_hatch.json new file mode 100644 index 00000000000..2c33bcc837c --- /dev/null +++ b/src/generated/resources/assets/gtceu/blockstates/basic_data_access_hatch.json @@ -0,0 +1,28 @@ +{ + "variants": { + "facing=down": { + "model": "gtceu:block/machine/basic_data_access_hatch", + "x": 90 + }, + "facing=east": { + "model": "gtceu:block/machine/basic_data_access_hatch", + "y": 90 + }, + "facing=north": { + "model": "gtceu:block/machine/basic_data_access_hatch" + }, + "facing=south": { + "model": "gtceu:block/machine/basic_data_access_hatch", + "y": 180 + }, + "facing=up": { + "gtceu:z": 180, + "model": "gtceu:block/machine/basic_data_access_hatch", + "x": 270 + }, + "facing=west": { + "model": "gtceu:block/machine/basic_data_access_hatch", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/blockstates/bronze_multiblock_tank.json b/src/generated/resources/assets/gtceu/blockstates/bronze_multiblock_tank.json new file mode 100644 index 00000000000..211dbef6ab7 --- /dev/null +++ b/src/generated/resources/assets/gtceu/blockstates/bronze_multiblock_tank.json @@ -0,0 +1,114 @@ +{ + "variants": { + "facing=down,upwards_facing=east": { + "gtceu:z": 90, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "x": 90 + }, + "facing=down,upwards_facing=north": { + "model": "gtceu:block/machine/bronze_multiblock_tank", + "x": 90 + }, + "facing=down,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "x": 90 + }, + "facing=down,upwards_facing=west": { + "gtceu:z": 270, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "x": 90 + }, + "facing=east,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 90 + }, + "facing=east,upwards_facing=north": { + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 90 + }, + "facing=east,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 90 + }, + "facing=east,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 90 + }, + "facing=north,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/bronze_multiblock_tank" + }, + "facing=north,upwards_facing=north": { + "model": "gtceu:block/machine/bronze_multiblock_tank" + }, + "facing=north,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/bronze_multiblock_tank" + }, + "facing=north,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/bronze_multiblock_tank" + }, + "facing=south,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 180 + }, + "facing=south,upwards_facing=north": { + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 180 + }, + "facing=south,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 180 + }, + "facing=south,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 180 + }, + "facing=up,upwards_facing=east": { + "gtceu:z": 90, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "x": 270 + }, + "facing=up,upwards_facing=north": { + "gtceu:z": 180, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "x": 270 + }, + "facing=up,upwards_facing=south": { + "model": "gtceu:block/machine/bronze_multiblock_tank", + "x": 270 + }, + "facing=up,upwards_facing=west": { + "gtceu:z": 270, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "x": 270 + }, + "facing=west,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 270 + }, + "facing=west,upwards_facing=north": { + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 270 + }, + "facing=west,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 270 + }, + "facing=west,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/bronze_multiblock_tank", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/blockstates/bronze_tank_valve.json b/src/generated/resources/assets/gtceu/blockstates/bronze_tank_valve.json new file mode 100644 index 00000000000..3f3265053c9 --- /dev/null +++ b/src/generated/resources/assets/gtceu/blockstates/bronze_tank_valve.json @@ -0,0 +1,28 @@ +{ + "variants": { + "facing=down": { + "model": "gtceu:block/machine/bronze_tank_valve", + "x": 90 + }, + "facing=east": { + "model": "gtceu:block/machine/bronze_tank_valve", + "y": 90 + }, + "facing=north": { + "model": "gtceu:block/machine/bronze_tank_valve" + }, + "facing=south": { + "model": "gtceu:block/machine/bronze_tank_valve", + "y": 180 + }, + "facing=up": { + "gtceu:z": 180, + "model": "gtceu:block/machine/bronze_tank_valve", + "x": 270 + }, + "facing=west": { + "model": "gtceu:block/machine/bronze_tank_valve", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/blockstates/central_monitor.json b/src/generated/resources/assets/gtceu/blockstates/central_monitor.json new file mode 100644 index 00000000000..c6f4ac24060 --- /dev/null +++ b/src/generated/resources/assets/gtceu/blockstates/central_monitor.json @@ -0,0 +1,114 @@ +{ + "variants": { + "facing=down,upwards_facing=east": { + "gtceu:z": 90, + "model": "gtceu:block/machine/central_monitor", + "x": 90 + }, + "facing=down,upwards_facing=north": { + "model": "gtceu:block/machine/central_monitor", + "x": 90 + }, + "facing=down,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/central_monitor", + "x": 90 + }, + "facing=down,upwards_facing=west": { + "gtceu:z": 270, + "model": "gtceu:block/machine/central_monitor", + "x": 90 + }, + "facing=east,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/central_monitor", + "y": 90 + }, + "facing=east,upwards_facing=north": { + "model": "gtceu:block/machine/central_monitor", + "y": 90 + }, + "facing=east,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/central_monitor", + "y": 90 + }, + "facing=east,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/central_monitor", + "y": 90 + }, + "facing=north,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/central_monitor" + }, + "facing=north,upwards_facing=north": { + "model": "gtceu:block/machine/central_monitor" + }, + "facing=north,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/central_monitor" + }, + "facing=north,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/central_monitor" + }, + "facing=south,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/central_monitor", + "y": 180 + }, + "facing=south,upwards_facing=north": { + "model": "gtceu:block/machine/central_monitor", + "y": 180 + }, + "facing=south,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/central_monitor", + "y": 180 + }, + "facing=south,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/central_monitor", + "y": 180 + }, + "facing=up,upwards_facing=east": { + "gtceu:z": 90, + "model": "gtceu:block/machine/central_monitor", + "x": 270 + }, + "facing=up,upwards_facing=north": { + "gtceu:z": 180, + "model": "gtceu:block/machine/central_monitor", + "x": 270 + }, + "facing=up,upwards_facing=south": { + "model": "gtceu:block/machine/central_monitor", + "x": 270 + }, + "facing=up,upwards_facing=west": { + "gtceu:z": 270, + "model": "gtceu:block/machine/central_monitor", + "x": 270 + }, + "facing=west,upwards_facing=east": { + "gtceu:z": 270, + "model": "gtceu:block/machine/central_monitor", + "y": 270 + }, + "facing=west,upwards_facing=north": { + "model": "gtceu:block/machine/central_monitor", + "y": 270 + }, + "facing=west,upwards_facing=south": { + "gtceu:z": 180, + "model": "gtceu:block/machine/central_monitor", + "y": 270 + }, + "facing=west,upwards_facing=west": { + "gtceu:z": 90, + "model": "gtceu:block/machine/central_monitor", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/blockstates/coke_oven.json b/src/generated/resources/assets/gtceu/blockstates/coke_oven.json index ff06e1ca741..8eb5c1f5382 100644 --- a/src/generated/resources/assets/gtceu/blockstates/coke_oven.json +++ b/src/generated/resources/assets/gtceu/blockstates/coke_oven.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/coke_oven", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/coke_oven", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/coke_oven" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/coke_oven" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/coke_oven" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/coke_oven", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/coke_oven", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/coke_oven", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/coke_oven", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/coke_oven", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/coke_oven", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/cracker.json b/src/generated/resources/assets/gtceu/blockstates/cracker.json index cdc05b8cb07..87747664942 100644 --- a/src/generated/resources/assets/gtceu/blockstates/cracker.json +++ b/src/generated/resources/assets/gtceu/blockstates/cracker.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/cracker", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/cracker", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/cracker" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/cracker" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/cracker" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/cracker", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/cracker", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/cracker", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/cracker", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/cracker", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/cracker", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/creative_chest.json b/src/generated/resources/assets/gtceu/blockstates/creative_chest.json index 86a3407de48..4c72ae29c0a 100644 --- a/src/generated/resources/assets/gtceu/blockstates/creative_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/creative_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/creative_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/creative_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/creative_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/creative_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/creative_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/creative_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/creative_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/creative_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/creative_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/creative_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/creative_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/creative_tank.json b/src/generated/resources/assets/gtceu/blockstates/creative_tank.json index c1ef1aa2f6c..5e3e5acd44d 100644 --- a/src/generated/resources/assets/gtceu/blockstates/creative_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/creative_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/creative_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/creative_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/creative_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/creative_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/creative_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/creative_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/creative_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/creative_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/creative_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/creative_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/creative_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/creosote.json b/src/generated/resources/assets/gtceu/blockstates/creosote.json new file mode 100644 index 00000000000..6007668dbc2 --- /dev/null +++ b/src/generated/resources/assets/gtceu/blockstates/creosote.json @@ -0,0 +1,7 @@ +{ + "variants": { + "": { + "model": "gtceu:block/creosote" + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/blockstates/data_bank.json b/src/generated/resources/assets/gtceu/blockstates/data_bank.json index f03f1292c1c..a75100bf32c 100644 --- a/src/generated/resources/assets/gtceu/blockstates/data_bank.json +++ b/src/generated/resources/assets/gtceu/blockstates/data_bank.json @@ -1,7 +1,7 @@ { "variants": { "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/data_bank", "y": 90 }, @@ -15,12 +15,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/data_bank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/data_bank" }, "facing=north,upwards_facing=north": { @@ -31,11 +31,11 @@ "model": "gtceu:block/machine/data_bank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/data_bank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/data_bank", "y": 180 }, @@ -49,12 +49,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/data_bank", "y": 180 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/data_bank", "y": 270 }, @@ -68,7 +68,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/data_bank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/electric_blast_furnace.json b/src/generated/resources/assets/gtceu/blockstates/electric_blast_furnace.json index 04a39461e11..da6e1806204 100644 --- a/src/generated/resources/assets/gtceu/blockstates/electric_blast_furnace.json +++ b/src/generated/resources/assets/gtceu/blockstates/electric_blast_furnace.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/electric_blast_furnace", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/electric_blast_furnace", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/electric_blast_furnace" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/electric_blast_furnace" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/electric_blast_furnace" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/electric_blast_furnace", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/electric_blast_furnace", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/electric_blast_furnace", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/electric_blast_furnace", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/electric_blast_furnace", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/electric_blast_furnace", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/ev_bedrock_ore_miner.json b/src/generated/resources/assets/gtceu/blockstates/ev_bedrock_ore_miner.json index 621813a2910..fed35a0f730 100644 --- a/src/generated/resources/assets/gtceu/blockstates/ev_bedrock_ore_miner.json +++ b/src/generated/resources/assets/gtceu/blockstates/ev_bedrock_ore_miner.json @@ -1,7 +1,7 @@ { "variants": { "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_bedrock_ore_miner", "y": 90 }, @@ -15,12 +15,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_bedrock_ore_miner", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_bedrock_ore_miner" }, "facing=north,upwards_facing=north": { @@ -31,11 +31,11 @@ "model": "gtceu:block/machine/ev_bedrock_ore_miner" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_bedrock_ore_miner" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_bedrock_ore_miner", "y": 180 }, @@ -49,12 +49,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_bedrock_ore_miner", "y": 180 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_bedrock_ore_miner", "y": 270 }, @@ -68,7 +68,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_bedrock_ore_miner", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/ev_fluid_drilling_rig.json b/src/generated/resources/assets/gtceu/blockstates/ev_fluid_drilling_rig.json index 6151c8129f3..341d2ae5da1 100644 --- a/src/generated/resources/assets/gtceu/blockstates/ev_fluid_drilling_rig.json +++ b/src/generated/resources/assets/gtceu/blockstates/ev_fluid_drilling_rig.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_fluid_drilling_rig", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_fluid_drilling_rig", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_fluid_drilling_rig" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/ev_fluid_drilling_rig" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_fluid_drilling_rig" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_fluid_drilling_rig", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_fluid_drilling_rig", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_fluid_drilling_rig", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_fluid_drilling_rig", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_fluid_drilling_rig", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_fluid_drilling_rig", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/ev_large_miner.json b/src/generated/resources/assets/gtceu/blockstates/ev_large_miner.json index 84248bd16a0..328371a40c1 100644 --- a/src/generated/resources/assets/gtceu/blockstates/ev_large_miner.json +++ b/src/generated/resources/assets/gtceu/blockstates/ev_large_miner.json @@ -1,7 +1,7 @@ { "variants": { "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_large_miner", "y": 90 }, @@ -15,12 +15,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_large_miner", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_large_miner" }, "facing=north,upwards_facing=north": { @@ -31,11 +31,11 @@ "model": "gtceu:block/machine/ev_large_miner" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_large_miner" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_large_miner", "y": 180 }, @@ -49,12 +49,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_large_miner", "y": 180 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_large_miner", "y": 270 }, @@ -68,7 +68,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_large_miner", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/ev_super_chest.json b/src/generated/resources/assets/gtceu/blockstates/ev_super_chest.json index 18c4d4eb76e..9f568209bf1 100644 --- a/src/generated/resources/assets/gtceu/blockstates/ev_super_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/ev_super_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_super_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_super_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_super_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/ev_super_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_super_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_super_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_super_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_super_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_super_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_super_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_super_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/ev_super_tank.json b/src/generated/resources/assets/gtceu/blockstates/ev_super_tank.json index f8b83a2d7fa..77ba0c0454f 100644 --- a/src/generated/resources/assets/gtceu/blockstates/ev_super_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/ev_super_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_super_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_super_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_super_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/ev_super_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_super_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_super_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_super_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_super_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_super_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/ev_super_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/ev_super_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/extreme_combustion_engine.json b/src/generated/resources/assets/gtceu/blockstates/extreme_combustion_engine.json index 8ec753d07b0..59001194cda 100644 --- a/src/generated/resources/assets/gtceu/blockstates/extreme_combustion_engine.json +++ b/src/generated/resources/assets/gtceu/blockstates/extreme_combustion_engine.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/extreme_combustion_engine", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/extreme_combustion_engine", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/extreme_combustion_engine" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/extreme_combustion_engine" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/extreme_combustion_engine" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/extreme_combustion_engine", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/extreme_combustion_engine", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/extreme_combustion_engine", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/extreme_combustion_engine", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/extreme_combustion_engine", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/extreme_combustion_engine", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/gas_large_turbine.json b/src/generated/resources/assets/gtceu/blockstates/gas_large_turbine.json index 95c3e324a19..12e53bf85c0 100644 --- a/src/generated/resources/assets/gtceu/blockstates/gas_large_turbine.json +++ b/src/generated/resources/assets/gtceu/blockstates/gas_large_turbine.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/gas_large_turbine", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/gas_large_turbine", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/gas_large_turbine" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/gas_large_turbine" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/gas_large_turbine" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/gas_large_turbine", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/gas_large_turbine", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/gas_large_turbine", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/gas_large_turbine", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/gas_large_turbine", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/gas_large_turbine", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/high_performance_computation_array.json b/src/generated/resources/assets/gtceu/blockstates/high_performance_computation_array.json index 5e5b9bb7904..708fce1d49a 100644 --- a/src/generated/resources/assets/gtceu/blockstates/high_performance_computation_array.json +++ b/src/generated/resources/assets/gtceu/blockstates/high_performance_computation_array.json @@ -1,7 +1,7 @@ { "variants": { "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/high_performance_computation_array", "y": 90 }, @@ -15,12 +15,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/high_performance_computation_array", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/high_performance_computation_array" }, "facing=north,upwards_facing=north": { @@ -31,11 +31,11 @@ "model": "gtceu:block/machine/high_performance_computation_array" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/high_performance_computation_array" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/high_performance_computation_array", "y": 180 }, @@ -49,12 +49,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/high_performance_computation_array", "y": 180 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/high_performance_computation_array", "y": 270 }, @@ -68,7 +68,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/high_performance_computation_array", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/hv_bedrock_ore_miner.json b/src/generated/resources/assets/gtceu/blockstates/hv_bedrock_ore_miner.json index 94701535fd7..b8994ad85ef 100644 --- a/src/generated/resources/assets/gtceu/blockstates/hv_bedrock_ore_miner.json +++ b/src/generated/resources/assets/gtceu/blockstates/hv_bedrock_ore_miner.json @@ -1,7 +1,7 @@ { "variants": { "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_bedrock_ore_miner", "y": 90 }, @@ -15,12 +15,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_bedrock_ore_miner", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_bedrock_ore_miner" }, "facing=north,upwards_facing=north": { @@ -31,11 +31,11 @@ "model": "gtceu:block/machine/hv_bedrock_ore_miner" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_bedrock_ore_miner" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_bedrock_ore_miner", "y": 180 }, @@ -49,12 +49,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_bedrock_ore_miner", "y": 180 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_bedrock_ore_miner", "y": 270 }, @@ -68,7 +68,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_bedrock_ore_miner", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/hv_fluid_drilling_rig.json b/src/generated/resources/assets/gtceu/blockstates/hv_fluid_drilling_rig.json index 0c7f575c87d..21ebd4f3fc6 100644 --- a/src/generated/resources/assets/gtceu/blockstates/hv_fluid_drilling_rig.json +++ b/src/generated/resources/assets/gtceu/blockstates/hv_fluid_drilling_rig.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_fluid_drilling_rig", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_fluid_drilling_rig", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_fluid_drilling_rig" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/hv_fluid_drilling_rig" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_fluid_drilling_rig" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_fluid_drilling_rig", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_fluid_drilling_rig", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_fluid_drilling_rig", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_fluid_drilling_rig", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_fluid_drilling_rig", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_fluid_drilling_rig", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/hv_super_chest.json b/src/generated/resources/assets/gtceu/blockstates/hv_super_chest.json index efcf694afc9..1f96a467615 100644 --- a/src/generated/resources/assets/gtceu/blockstates/hv_super_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/hv_super_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_super_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_super_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_super_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/hv_super_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_super_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_super_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_super_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_super_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_super_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_super_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_super_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/hv_super_tank.json b/src/generated/resources/assets/gtceu/blockstates/hv_super_tank.json index 49d56d8d8b9..323dba7651d 100644 --- a/src/generated/resources/assets/gtceu/blockstates/hv_super_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/hv_super_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_super_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_super_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_super_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/hv_super_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_super_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_super_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_super_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_super_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_super_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/hv_super_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/hv_super_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/implosion_compressor.json b/src/generated/resources/assets/gtceu/blockstates/implosion_compressor.json index 313573b6d8a..d2582de5ac1 100644 --- a/src/generated/resources/assets/gtceu/blockstates/implosion_compressor.json +++ b/src/generated/resources/assets/gtceu/blockstates/implosion_compressor.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/implosion_compressor", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/implosion_compressor", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/implosion_compressor" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/implosion_compressor" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/implosion_compressor" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/implosion_compressor", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/implosion_compressor", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/implosion_compressor", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/implosion_compressor", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/implosion_compressor", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/implosion_compressor", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/iv_large_miner.json b/src/generated/resources/assets/gtceu/blockstates/iv_large_miner.json index e6093eb4e03..e0e8917e2f6 100644 --- a/src/generated/resources/assets/gtceu/blockstates/iv_large_miner.json +++ b/src/generated/resources/assets/gtceu/blockstates/iv_large_miner.json @@ -1,7 +1,7 @@ { "variants": { "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_large_miner", "y": 90 }, @@ -15,12 +15,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_large_miner", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_large_miner" }, "facing=north,upwards_facing=north": { @@ -31,11 +31,11 @@ "model": "gtceu:block/machine/iv_large_miner" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_large_miner" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_large_miner", "y": 180 }, @@ -49,12 +49,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_large_miner", "y": 180 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_large_miner", "y": 270 }, @@ -68,7 +68,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_large_miner", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/iv_quantum_chest.json b/src/generated/resources/assets/gtceu/blockstates/iv_quantum_chest.json index 3be94ee9c0a..d3c6ebd788c 100644 --- a/src/generated/resources/assets/gtceu/blockstates/iv_quantum_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/iv_quantum_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_quantum_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_quantum_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_quantum_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/iv_quantum_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_quantum_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_quantum_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_quantum_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_quantum_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_quantum_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_quantum_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_quantum_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/iv_quantum_tank.json b/src/generated/resources/assets/gtceu/blockstates/iv_quantum_tank.json index 751fe993fe3..68f5b2fd183 100644 --- a/src/generated/resources/assets/gtceu/blockstates/iv_quantum_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/iv_quantum_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_quantum_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_quantum_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_quantum_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/iv_quantum_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_quantum_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_quantum_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_quantum_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_quantum_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_quantum_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/iv_quantum_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/iv_quantum_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_arc_smelter.json b/src/generated/resources/assets/gtceu/blockstates/large_arc_smelter.json index 9f0a6fafdf1..c9c6c4656ea 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_arc_smelter.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_arc_smelter.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_arc_smelter", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_arc_smelter", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_arc_smelter" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_arc_smelter" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_arc_smelter" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_arc_smelter", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_arc_smelter", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_arc_smelter", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_arc_smelter", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_arc_smelter", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_arc_smelter", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_assembler.json b/src/generated/resources/assets/gtceu/blockstates/large_assembler.json index 0a81071287e..7f555190463 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_assembler.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_assembler.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_assembler", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_assembler", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_assembler" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_assembler" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_assembler" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_assembler", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_assembler", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_assembler", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_assembler", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_assembler", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_assembler", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_autoclave.json b/src/generated/resources/assets/gtceu/blockstates/large_autoclave.json index 902c54db2a5..ebfeff5a303 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_autoclave.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_autoclave.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_autoclave", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_autoclave", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_autoclave" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_autoclave" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_autoclave" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_autoclave", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_autoclave", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_autoclave", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_autoclave", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_autoclave", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_autoclave", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_brewer.json b/src/generated/resources/assets/gtceu/blockstates/large_brewer.json index 59fa9963254..730bc9c175a 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_brewer.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_brewer.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_brewer", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_brewer", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_brewer" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_brewer" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_brewer" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_brewer", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_brewer", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_brewer", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_brewer", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_brewer", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_brewer", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_centrifuge.json b/src/generated/resources/assets/gtceu/blockstates/large_centrifuge.json index b4bacfc81fc..1a54f4a3898 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_centrifuge.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_centrifuge.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_centrifuge", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_centrifuge", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_centrifuge" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_centrifuge" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_centrifuge" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_centrifuge", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_centrifuge", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_centrifuge", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_centrifuge", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_centrifuge", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_centrifuge", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_chemical_bath.json b/src/generated/resources/assets/gtceu/blockstates/large_chemical_bath.json index 344c7fd69c9..cd5579a46d0 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_chemical_bath.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_chemical_bath.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_chemical_bath", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_chemical_bath", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_chemical_bath" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_chemical_bath" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_chemical_bath" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_chemical_bath", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_chemical_bath", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_chemical_bath", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_chemical_bath", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_chemical_bath", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_chemical_bath", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_chemical_reactor.json b/src/generated/resources/assets/gtceu/blockstates/large_chemical_reactor.json index a420b9a01dc..cdaf5b689d6 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_chemical_reactor.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_chemical_reactor.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_chemical_reactor", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_chemical_reactor", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_chemical_reactor" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_chemical_reactor" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_chemical_reactor" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_chemical_reactor", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_chemical_reactor", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_chemical_reactor", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_chemical_reactor", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_chemical_reactor", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_chemical_reactor", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_circuit_assembler.json b/src/generated/resources/assets/gtceu/blockstates/large_circuit_assembler.json index 7bcd27f3bdb..22838f7f138 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_circuit_assembler.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_circuit_assembler.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_circuit_assembler", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_circuit_assembler", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_circuit_assembler" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_circuit_assembler" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_circuit_assembler" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_circuit_assembler", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_circuit_assembler", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_circuit_assembler", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_circuit_assembler", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_circuit_assembler", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_circuit_assembler", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_combustion_engine.json b/src/generated/resources/assets/gtceu/blockstates/large_combustion_engine.json index dd958af8fda..612597cf9d1 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_combustion_engine.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_combustion_engine.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_combustion_engine", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_combustion_engine", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_combustion_engine" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_combustion_engine" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_combustion_engine" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_combustion_engine", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_combustion_engine", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_combustion_engine", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_combustion_engine", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_combustion_engine", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_combustion_engine", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_cutter.json b/src/generated/resources/assets/gtceu/blockstates/large_cutter.json index 67e1ed0a018..27dd9dc799a 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_cutter.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_cutter.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_cutter", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_cutter", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_cutter" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_cutter" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_cutter" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_cutter", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_cutter", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_cutter", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_cutter", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_cutter", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_cutter", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_electrolyzer.json b/src/generated/resources/assets/gtceu/blockstates/large_electrolyzer.json index 4d5a122a352..ae69eb2b889 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_electrolyzer.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_electrolyzer.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_electrolyzer", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_electrolyzer", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_electrolyzer" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_electrolyzer" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_electrolyzer" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_electrolyzer", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_electrolyzer", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_electrolyzer", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_electrolyzer", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_electrolyzer", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_electrolyzer", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_electromagnet.json b/src/generated/resources/assets/gtceu/blockstates/large_electromagnet.json index 400e7585059..caa0da5220c 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_electromagnet.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_electromagnet.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_electromagnet", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_electromagnet", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_electromagnet" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_electromagnet" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_electromagnet" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_electromagnet", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_electromagnet", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_electromagnet", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_electromagnet", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_electromagnet", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_electromagnet", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_engraving_laser.json b/src/generated/resources/assets/gtceu/blockstates/large_engraving_laser.json index c1f8fe1f3fa..cdc9e162ad6 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_engraving_laser.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_engraving_laser.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_engraving_laser", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_engraving_laser", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_engraving_laser" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_engraving_laser" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_engraving_laser" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_engraving_laser", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_engraving_laser", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_engraving_laser", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_engraving_laser", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_engraving_laser", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_engraving_laser", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_extractor.json b/src/generated/resources/assets/gtceu/blockstates/large_extractor.json index 6203174284c..f9a0c98f904 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_extractor.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_extractor.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_extractor", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_extractor", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_extractor" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_extractor" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_extractor" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_extractor", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_extractor", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_extractor", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_extractor", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_extractor", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_extractor", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_extruder.json b/src/generated/resources/assets/gtceu/blockstates/large_extruder.json index e795bbabc58..77e54f4b037 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_extruder.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_extruder.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_extruder", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_extruder", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_extruder" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_extruder" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_extruder" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_extruder", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_extruder", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_extruder", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_extruder", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_extruder", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_extruder", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_maceration_tower.json b/src/generated/resources/assets/gtceu/blockstates/large_maceration_tower.json index 3bcf8a8bd56..b6ffc4ce2fa 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_maceration_tower.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_maceration_tower.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_maceration_tower", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_maceration_tower", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_maceration_tower" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_maceration_tower" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_maceration_tower" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_maceration_tower", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_maceration_tower", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_maceration_tower", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_maceration_tower", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_maceration_tower", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_maceration_tower", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_material_press.json b/src/generated/resources/assets/gtceu/blockstates/large_material_press.json index a27a9d9d049..a1619231414 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_material_press.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_material_press.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_material_press", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_material_press", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_material_press" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_material_press" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_material_press" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_material_press", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_material_press", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_material_press", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_material_press", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_material_press", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_material_press", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_mixer.json b/src/generated/resources/assets/gtceu/blockstates/large_mixer.json index 69c8c9eb08d..74a19469bf7 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_mixer.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_mixer.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_mixer", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_mixer", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_mixer" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_mixer" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_mixer" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_mixer", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_mixer", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_mixer", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_mixer", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_mixer", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_mixer", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_packer.json b/src/generated/resources/assets/gtceu/blockstates/large_packer.json index d8c5fca87d1..c3c35b1d733 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_packer.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_packer.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_packer", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_packer", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_packer" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_packer" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_packer" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_packer", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_packer", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_packer", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_packer", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_packer", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_packer", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_sifting_funnel.json b/src/generated/resources/assets/gtceu/blockstates/large_sifting_funnel.json index cb72bd437f9..3ecc2ee9034 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_sifting_funnel.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_sifting_funnel.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_sifting_funnel", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_sifting_funnel", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_sifting_funnel" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_sifting_funnel" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_sifting_funnel" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_sifting_funnel", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_sifting_funnel", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_sifting_funnel", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_sifting_funnel", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_sifting_funnel", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_sifting_funnel", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_solidifier.json b/src/generated/resources/assets/gtceu/blockstates/large_solidifier.json index 141415ea1a7..0a0490e47e0 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_solidifier.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_solidifier.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_solidifier", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_solidifier", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_solidifier" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_solidifier" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_solidifier" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_solidifier", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_solidifier", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_solidifier", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_solidifier", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_solidifier", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_solidifier", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/large_wiremill.json b/src/generated/resources/assets/gtceu/blockstates/large_wiremill.json index 1b4aab34626..c68595ad018 100644 --- a/src/generated/resources/assets/gtceu/blockstates/large_wiremill.json +++ b/src/generated/resources/assets/gtceu/blockstates/large_wiremill.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_wiremill", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_wiremill", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_wiremill" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/large_wiremill" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_wiremill" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_wiremill", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_wiremill", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_wiremill", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_wiremill", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/large_wiremill", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/large_wiremill", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/long_distance_fluid_pipeline_endpoint.json b/src/generated/resources/assets/gtceu/blockstates/long_distance_fluid_pipeline_endpoint.json index ba9425c1710..c5e66fa3007 100644 --- a/src/generated/resources/assets/gtceu/blockstates/long_distance_fluid_pipeline_endpoint.json +++ b/src/generated/resources/assets/gtceu/blockstates/long_distance_fluid_pipeline_endpoint.json @@ -1,7 +1,28 @@ { "variants": { - "": { + "facing=down": { + "model": "gtceu:block/machine/long_distance_fluid_pipeline_endpoint", + "x": 90 + }, + "facing=east": { + "model": "gtceu:block/machine/long_distance_fluid_pipeline_endpoint", + "y": 90 + }, + "facing=north": { "model": "gtceu:block/machine/long_distance_fluid_pipeline_endpoint" + }, + "facing=south": { + "model": "gtceu:block/machine/long_distance_fluid_pipeline_endpoint", + "y": 180 + }, + "facing=up": { + "gtceu:z": 180, + "model": "gtceu:block/machine/long_distance_fluid_pipeline_endpoint", + "x": 270 + }, + "facing=west": { + "model": "gtceu:block/machine/long_distance_fluid_pipeline_endpoint", + "y": 270 } } } \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/blockstates/long_distance_item_pipeline_endpoint.json b/src/generated/resources/assets/gtceu/blockstates/long_distance_item_pipeline_endpoint.json index 405eeea8f3e..b794156833b 100644 --- a/src/generated/resources/assets/gtceu/blockstates/long_distance_item_pipeline_endpoint.json +++ b/src/generated/resources/assets/gtceu/blockstates/long_distance_item_pipeline_endpoint.json @@ -1,7 +1,28 @@ { "variants": { - "": { + "facing=down": { + "model": "gtceu:block/machine/long_distance_item_pipeline_endpoint", + "x": 90 + }, + "facing=east": { + "model": "gtceu:block/machine/long_distance_item_pipeline_endpoint", + "y": 90 + }, + "facing=north": { "model": "gtceu:block/machine/long_distance_item_pipeline_endpoint" + }, + "facing=south": { + "model": "gtceu:block/machine/long_distance_item_pipeline_endpoint", + "y": 180 + }, + "facing=up": { + "gtceu:z": 180, + "model": "gtceu:block/machine/long_distance_item_pipeline_endpoint", + "x": 270 + }, + "facing=west": { + "model": "gtceu:block/machine/long_distance_item_pipeline_endpoint", + "y": 270 } } } \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/blockstates/luv_fusion_reactor.json b/src/generated/resources/assets/gtceu/blockstates/luv_fusion_reactor.json index 76699e80fb6..a4ba2cbd283 100644 --- a/src/generated/resources/assets/gtceu/blockstates/luv_fusion_reactor.json +++ b/src/generated/resources/assets/gtceu/blockstates/luv_fusion_reactor.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_fusion_reactor", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_fusion_reactor", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_fusion_reactor" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/luv_fusion_reactor" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_fusion_reactor" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_fusion_reactor", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_fusion_reactor", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_fusion_reactor", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_fusion_reactor", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_fusion_reactor", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_fusion_reactor", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/luv_large_miner.json b/src/generated/resources/assets/gtceu/blockstates/luv_large_miner.json index 436a920d1a6..6e73b86e890 100644 --- a/src/generated/resources/assets/gtceu/blockstates/luv_large_miner.json +++ b/src/generated/resources/assets/gtceu/blockstates/luv_large_miner.json @@ -1,7 +1,7 @@ { "variants": { "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_large_miner", "y": 90 }, @@ -15,12 +15,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_large_miner", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_large_miner" }, "facing=north,upwards_facing=north": { @@ -31,11 +31,11 @@ "model": "gtceu:block/machine/luv_large_miner" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_large_miner" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_large_miner", "y": 180 }, @@ -49,12 +49,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_large_miner", "y": 180 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_large_miner", "y": 270 }, @@ -68,7 +68,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_large_miner", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/luv_quantum_chest.json b/src/generated/resources/assets/gtceu/blockstates/luv_quantum_chest.json index 368ad57705e..f838ed8fe7b 100644 --- a/src/generated/resources/assets/gtceu/blockstates/luv_quantum_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/luv_quantum_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_quantum_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_quantum_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_quantum_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/luv_quantum_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_quantum_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_quantum_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_quantum_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_quantum_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_quantum_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_quantum_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_quantum_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/luv_quantum_tank.json b/src/generated/resources/assets/gtceu/blockstates/luv_quantum_tank.json index 4720f5349a1..bd9d53ff8e7 100644 --- a/src/generated/resources/assets/gtceu/blockstates/luv_quantum_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/luv_quantum_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_quantum_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_quantum_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_quantum_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/luv_quantum_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_quantum_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_quantum_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_quantum_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_quantum_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_quantum_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/luv_quantum_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/luv_quantum_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/lv_super_chest.json b/src/generated/resources/assets/gtceu/blockstates/lv_super_chest.json index 56fa48d0fe5..acb3f6f72fc 100644 --- a/src/generated/resources/assets/gtceu/blockstates/lv_super_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/lv_super_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/lv_super_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/lv_super_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/lv_super_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/lv_super_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/lv_super_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/lv_super_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/lv_super_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/lv_super_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/lv_super_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/lv_super_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/lv_super_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/lv_super_tank.json b/src/generated/resources/assets/gtceu/blockstates/lv_super_tank.json index dba17885bfb..82833258870 100644 --- a/src/generated/resources/assets/gtceu/blockstates/lv_super_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/lv_super_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/lv_super_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/lv_super_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/lv_super_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/lv_super_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/lv_super_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/lv_super_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/lv_super_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/lv_super_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/lv_super_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/lv_super_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/lv_super_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/mega_vacuum_freezer.json b/src/generated/resources/assets/gtceu/blockstates/mega_vacuum_freezer.json index d64dbc6a5a2..e90581f6d84 100644 --- a/src/generated/resources/assets/gtceu/blockstates/mega_vacuum_freezer.json +++ b/src/generated/resources/assets/gtceu/blockstates/mega_vacuum_freezer.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mega_vacuum_freezer", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mega_vacuum_freezer", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mega_vacuum_freezer" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/mega_vacuum_freezer" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mega_vacuum_freezer" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mega_vacuum_freezer", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mega_vacuum_freezer", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mega_vacuum_freezer", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mega_vacuum_freezer", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mega_vacuum_freezer", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mega_vacuum_freezer", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/monitor.json b/src/generated/resources/assets/gtceu/blockstates/monitor.json new file mode 100644 index 00000000000..18a7df23f55 --- /dev/null +++ b/src/generated/resources/assets/gtceu/blockstates/monitor.json @@ -0,0 +1,28 @@ +{ + "variants": { + "facing=down": { + "model": "gtceu:block/machine/monitor", + "x": 90 + }, + "facing=east": { + "model": "gtceu:block/machine/monitor", + "y": 90 + }, + "facing=north": { + "model": "gtceu:block/machine/monitor" + }, + "facing=south": { + "model": "gtceu:block/machine/monitor", + "y": 180 + }, + "facing=up": { + "gtceu:z": 180, + "model": "gtceu:block/machine/monitor", + "x": 270 + }, + "facing=west": { + "model": "gtceu:block/machine/monitor", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/blockstates/multi_smelter.json b/src/generated/resources/assets/gtceu/blockstates/multi_smelter.json index 9a0a331b4b0..3294606afd6 100644 --- a/src/generated/resources/assets/gtceu/blockstates/multi_smelter.json +++ b/src/generated/resources/assets/gtceu/blockstates/multi_smelter.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/multi_smelter", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/multi_smelter", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/multi_smelter" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/multi_smelter" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/multi_smelter" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/multi_smelter", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/multi_smelter", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/multi_smelter", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/multi_smelter", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/multi_smelter", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/multi_smelter", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/mv_bedrock_ore_miner.json b/src/generated/resources/assets/gtceu/blockstates/mv_bedrock_ore_miner.json index 1edfed8e9da..3c1a08d7b31 100644 --- a/src/generated/resources/assets/gtceu/blockstates/mv_bedrock_ore_miner.json +++ b/src/generated/resources/assets/gtceu/blockstates/mv_bedrock_ore_miner.json @@ -1,7 +1,7 @@ { "variants": { "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_bedrock_ore_miner", "y": 90 }, @@ -15,12 +15,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_bedrock_ore_miner", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_bedrock_ore_miner" }, "facing=north,upwards_facing=north": { @@ -31,11 +31,11 @@ "model": "gtceu:block/machine/mv_bedrock_ore_miner" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_bedrock_ore_miner" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_bedrock_ore_miner", "y": 180 }, @@ -49,12 +49,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_bedrock_ore_miner", "y": 180 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_bedrock_ore_miner", "y": 270 }, @@ -68,7 +68,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_bedrock_ore_miner", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/mv_fluid_drilling_rig.json b/src/generated/resources/assets/gtceu/blockstates/mv_fluid_drilling_rig.json index 34d2dcbf65d..538a734eaba 100644 --- a/src/generated/resources/assets/gtceu/blockstates/mv_fluid_drilling_rig.json +++ b/src/generated/resources/assets/gtceu/blockstates/mv_fluid_drilling_rig.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_fluid_drilling_rig", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_fluid_drilling_rig", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_fluid_drilling_rig" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/mv_fluid_drilling_rig" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_fluid_drilling_rig" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_fluid_drilling_rig", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_fluid_drilling_rig", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_fluid_drilling_rig", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_fluid_drilling_rig", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_fluid_drilling_rig", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_fluid_drilling_rig", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/mv_super_chest.json b/src/generated/resources/assets/gtceu/blockstates/mv_super_chest.json index 469afe89fe3..4379ff05646 100644 --- a/src/generated/resources/assets/gtceu/blockstates/mv_super_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/mv_super_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_super_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_super_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_super_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/mv_super_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_super_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_super_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_super_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_super_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_super_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_super_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_super_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/mv_super_tank.json b/src/generated/resources/assets/gtceu/blockstates/mv_super_tank.json index ec2454578ce..6a2e7ee5e3a 100644 --- a/src/generated/resources/assets/gtceu/blockstates/mv_super_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/mv_super_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_super_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_super_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_super_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/mv_super_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_super_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_super_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_super_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_super_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_super_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/mv_super_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/mv_super_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/network_switch.json b/src/generated/resources/assets/gtceu/blockstates/network_switch.json index fa837f766db..6b019ad218c 100644 --- a/src/generated/resources/assets/gtceu/blockstates/network_switch.json +++ b/src/generated/resources/assets/gtceu/blockstates/network_switch.json @@ -1,7 +1,7 @@ { "variants": { "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/network_switch", "y": 90 }, @@ -15,12 +15,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/network_switch", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/network_switch" }, "facing=north,upwards_facing=north": { @@ -31,11 +31,11 @@ "model": "gtceu:block/machine/network_switch" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/network_switch" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/network_switch", "y": 180 }, @@ -49,12 +49,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/network_switch", "y": 180 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/network_switch", "y": 270 }, @@ -68,7 +68,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/network_switch", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/opv_quantum_chest.json b/src/generated/resources/assets/gtceu/blockstates/opv_quantum_chest.json index 572ca705273..65afd41f3a1 100644 --- a/src/generated/resources/assets/gtceu/blockstates/opv_quantum_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/opv_quantum_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/opv_quantum_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/opv_quantum_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/opv_quantum_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/opv_quantum_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/opv_quantum_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/opv_quantum_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/opv_quantum_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/opv_quantum_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/opv_quantum_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/opv_quantum_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/opv_quantum_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/opv_quantum_tank.json b/src/generated/resources/assets/gtceu/blockstates/opv_quantum_tank.json index a1ef2c0ac90..f1f65c0b6f1 100644 --- a/src/generated/resources/assets/gtceu/blockstates/opv_quantum_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/opv_quantum_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/opv_quantum_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/opv_quantum_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/opv_quantum_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/opv_quantum_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/opv_quantum_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/opv_quantum_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/opv_quantum_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/opv_quantum_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/opv_quantum_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/opv_quantum_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/opv_quantum_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/plasma_large_turbine.json b/src/generated/resources/assets/gtceu/blockstates/plasma_large_turbine.json index 84e7efa3ffe..088e890c3e6 100644 --- a/src/generated/resources/assets/gtceu/blockstates/plasma_large_turbine.json +++ b/src/generated/resources/assets/gtceu/blockstates/plasma_large_turbine.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/plasma_large_turbine", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/plasma_large_turbine", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/plasma_large_turbine" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/plasma_large_turbine" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/plasma_large_turbine" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/plasma_large_turbine", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/plasma_large_turbine", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/plasma_large_turbine", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/plasma_large_turbine", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/plasma_large_turbine", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/plasma_large_turbine", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/power_substation.json b/src/generated/resources/assets/gtceu/blockstates/power_substation.json index a810c3380bb..3b233444a64 100644 --- a/src/generated/resources/assets/gtceu/blockstates/power_substation.json +++ b/src/generated/resources/assets/gtceu/blockstates/power_substation.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/power_substation", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/power_substation", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/power_substation" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/power_substation" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/power_substation" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/power_substation", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/power_substation", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/power_substation", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/power_substation", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/power_substation", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/power_substation", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/primitive_blast_furnace.json b/src/generated/resources/assets/gtceu/blockstates/primitive_blast_furnace.json index 7267ad5466a..75625b46de4 100644 --- a/src/generated/resources/assets/gtceu/blockstates/primitive_blast_furnace.json +++ b/src/generated/resources/assets/gtceu/blockstates/primitive_blast_furnace.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/primitive_blast_furnace", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/primitive_blast_furnace", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/primitive_blast_furnace" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/primitive_blast_furnace" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/primitive_blast_furnace" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/primitive_blast_furnace", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/primitive_blast_furnace", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/primitive_blast_furnace", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/primitive_blast_furnace", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/primitive_blast_furnace", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/primitive_blast_furnace", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/pyrolyse_oven.json b/src/generated/resources/assets/gtceu/blockstates/pyrolyse_oven.json index 93a51d9f282..3be4cd0a1f2 100644 --- a/src/generated/resources/assets/gtceu/blockstates/pyrolyse_oven.json +++ b/src/generated/resources/assets/gtceu/blockstates/pyrolyse_oven.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/pyrolyse_oven", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/pyrolyse_oven", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/pyrolyse_oven" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/pyrolyse_oven" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/pyrolyse_oven" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/pyrolyse_oven", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/pyrolyse_oven", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/pyrolyse_oven", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/pyrolyse_oven", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/pyrolyse_oven", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/pyrolyse_oven", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/research_station.json b/src/generated/resources/assets/gtceu/blockstates/research_station.json index 601a2c8cc80..76d8108b673 100644 --- a/src/generated/resources/assets/gtceu/blockstates/research_station.json +++ b/src/generated/resources/assets/gtceu/blockstates/research_station.json @@ -1,7 +1,7 @@ { "variants": { "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/research_station", "y": 90 }, @@ -15,12 +15,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/research_station", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/research_station" }, "facing=north,upwards_facing=north": { @@ -31,11 +31,11 @@ "model": "gtceu:block/machine/research_station" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/research_station" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/research_station", "y": 180 }, @@ -49,12 +49,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/research_station", "y": 180 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/research_station", "y": 270 }, @@ -68,7 +68,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/research_station", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/rotary_hearth_furnace.json b/src/generated/resources/assets/gtceu/blockstates/rotary_hearth_furnace.json index 3b45b26bff7..a1e48d1e743 100644 --- a/src/generated/resources/assets/gtceu/blockstates/rotary_hearth_furnace.json +++ b/src/generated/resources/assets/gtceu/blockstates/rotary_hearth_furnace.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/rotary_hearth_furnace", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/rotary_hearth_furnace", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/rotary_hearth_furnace" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/rotary_hearth_furnace" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/rotary_hearth_furnace" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/rotary_hearth_furnace", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/rotary_hearth_furnace", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/rotary_hearth_furnace", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/rotary_hearth_furnace", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/rotary_hearth_furnace", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/rotary_hearth_furnace", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/steam_grinder.json b/src/generated/resources/assets/gtceu/blockstates/steam_grinder.json index df23bacf36c..af9bdb854ab 100644 --- a/src/generated/resources/assets/gtceu/blockstates/steam_grinder.json +++ b/src/generated/resources/assets/gtceu/blockstates/steam_grinder.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_grinder", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_grinder", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_grinder" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/steam_grinder" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_grinder" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_grinder", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_grinder", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_grinder", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_grinder", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_grinder", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_grinder", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/steam_large_turbine.json b/src/generated/resources/assets/gtceu/blockstates/steam_large_turbine.json index bbbe532cb8b..917acc23b40 100644 --- a/src/generated/resources/assets/gtceu/blockstates/steam_large_turbine.json +++ b/src/generated/resources/assets/gtceu/blockstates/steam_large_turbine.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_large_turbine", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_large_turbine", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_large_turbine" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/steam_large_turbine" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_large_turbine" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_large_turbine", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_large_turbine", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_large_turbine", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_large_turbine", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_large_turbine", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_large_turbine", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/steam_oven.json b/src/generated/resources/assets/gtceu/blockstates/steam_oven.json index 5aef881eb37..dc3fbe675e4 100644 --- a/src/generated/resources/assets/gtceu/blockstates/steam_oven.json +++ b/src/generated/resources/assets/gtceu/blockstates/steam_oven.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_oven", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_oven", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_oven" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/steam_oven" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_oven" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_oven", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_oven", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_oven", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_oven", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steam_oven", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steam_oven", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/steel_multiblock_tank.json b/src/generated/resources/assets/gtceu/blockstates/steel_multiblock_tank.json index 749734df7a2..24be5f8e420 100644 --- a/src/generated/resources/assets/gtceu/blockstates/steel_multiblock_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/steel_multiblock_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steel_multiblock_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steel_multiblock_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steel_multiblock_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/steel_multiblock_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steel_multiblock_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steel_multiblock_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steel_multiblock_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steel_multiblock_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steel_multiblock_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/steel_multiblock_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/steel_multiblock_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/uev_quantum_chest.json b/src/generated/resources/assets/gtceu/blockstates/uev_quantum_chest.json index 643301976e1..39096f91c24 100644 --- a/src/generated/resources/assets/gtceu/blockstates/uev_quantum_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/uev_quantum_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uev_quantum_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uev_quantum_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uev_quantum_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/uev_quantum_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uev_quantum_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uev_quantum_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uev_quantum_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uev_quantum_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uev_quantum_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uev_quantum_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uev_quantum_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/uev_quantum_tank.json b/src/generated/resources/assets/gtceu/blockstates/uev_quantum_tank.json index 8b0630a658c..1c0f7e0d9a7 100644 --- a/src/generated/resources/assets/gtceu/blockstates/uev_quantum_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/uev_quantum_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uev_quantum_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uev_quantum_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uev_quantum_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/uev_quantum_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uev_quantum_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uev_quantum_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uev_quantum_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uev_quantum_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uev_quantum_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uev_quantum_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uev_quantum_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/uhv_quantum_chest.json b/src/generated/resources/assets/gtceu/blockstates/uhv_quantum_chest.json index 44cbb6fb416..ac2a69597d9 100644 --- a/src/generated/resources/assets/gtceu/blockstates/uhv_quantum_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/uhv_quantum_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uhv_quantum_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uhv_quantum_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uhv_quantum_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/uhv_quantum_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uhv_quantum_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uhv_quantum_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uhv_quantum_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uhv_quantum_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uhv_quantum_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uhv_quantum_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uhv_quantum_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/uhv_quantum_tank.json b/src/generated/resources/assets/gtceu/blockstates/uhv_quantum_tank.json index 4e1316b3fd3..fe32a5b393d 100644 --- a/src/generated/resources/assets/gtceu/blockstates/uhv_quantum_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/uhv_quantum_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uhv_quantum_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uhv_quantum_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uhv_quantum_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/uhv_quantum_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uhv_quantum_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uhv_quantum_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uhv_quantum_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uhv_quantum_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uhv_quantum_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uhv_quantum_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uhv_quantum_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/uiv_quantum_chest.json b/src/generated/resources/assets/gtceu/blockstates/uiv_quantum_chest.json index d2349231c56..71962b60e99 100644 --- a/src/generated/resources/assets/gtceu/blockstates/uiv_quantum_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/uiv_quantum_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uiv_quantum_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uiv_quantum_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uiv_quantum_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/uiv_quantum_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uiv_quantum_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uiv_quantum_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uiv_quantum_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uiv_quantum_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uiv_quantum_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uiv_quantum_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uiv_quantum_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/uiv_quantum_tank.json b/src/generated/resources/assets/gtceu/blockstates/uiv_quantum_tank.json index 48d65630492..0985f1b9357 100644 --- a/src/generated/resources/assets/gtceu/blockstates/uiv_quantum_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/uiv_quantum_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uiv_quantum_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uiv_quantum_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uiv_quantum_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/uiv_quantum_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uiv_quantum_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uiv_quantum_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uiv_quantum_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uiv_quantum_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uiv_quantum_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uiv_quantum_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uiv_quantum_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/uv_fusion_reactor.json b/src/generated/resources/assets/gtceu/blockstates/uv_fusion_reactor.json index a50e053e059..f3a31c96de5 100644 --- a/src/generated/resources/assets/gtceu/blockstates/uv_fusion_reactor.json +++ b/src/generated/resources/assets/gtceu/blockstates/uv_fusion_reactor.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_fusion_reactor", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_fusion_reactor", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_fusion_reactor" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/uv_fusion_reactor" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_fusion_reactor" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_fusion_reactor", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_fusion_reactor", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_fusion_reactor", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_fusion_reactor", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_fusion_reactor", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_fusion_reactor", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/uv_quantum_chest.json b/src/generated/resources/assets/gtceu/blockstates/uv_quantum_chest.json index 98a48241710..a827f407137 100644 --- a/src/generated/resources/assets/gtceu/blockstates/uv_quantum_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/uv_quantum_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_quantum_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_quantum_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_quantum_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/uv_quantum_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_quantum_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_quantum_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_quantum_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_quantum_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_quantum_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_quantum_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_quantum_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/uv_quantum_tank.json b/src/generated/resources/assets/gtceu/blockstates/uv_quantum_tank.json index 9e70f4c2aba..e9e39d963f6 100644 --- a/src/generated/resources/assets/gtceu/blockstates/uv_quantum_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/uv_quantum_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_quantum_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_quantum_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_quantum_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/uv_quantum_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_quantum_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_quantum_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_quantum_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_quantum_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_quantum_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uv_quantum_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uv_quantum_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/uxv_quantum_chest.json b/src/generated/resources/assets/gtceu/blockstates/uxv_quantum_chest.json index 1d7ef52c85c..f7633277864 100644 --- a/src/generated/resources/assets/gtceu/blockstates/uxv_quantum_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/uxv_quantum_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uxv_quantum_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uxv_quantum_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uxv_quantum_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/uxv_quantum_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uxv_quantum_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uxv_quantum_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uxv_quantum_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uxv_quantum_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uxv_quantum_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uxv_quantum_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uxv_quantum_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/uxv_quantum_tank.json b/src/generated/resources/assets/gtceu/blockstates/uxv_quantum_tank.json index 5ed4d39c648..109f15251ea 100644 --- a/src/generated/resources/assets/gtceu/blockstates/uxv_quantum_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/uxv_quantum_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uxv_quantum_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uxv_quantum_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uxv_quantum_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/uxv_quantum_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uxv_quantum_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uxv_quantum_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uxv_quantum_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uxv_quantum_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uxv_quantum_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/uxv_quantum_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/uxv_quantum_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/vacuum_freezer.json b/src/generated/resources/assets/gtceu/blockstates/vacuum_freezer.json index c1e1c92b262..9ae2565d933 100644 --- a/src/generated/resources/assets/gtceu/blockstates/vacuum_freezer.json +++ b/src/generated/resources/assets/gtceu/blockstates/vacuum_freezer.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/vacuum_freezer", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/vacuum_freezer", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/vacuum_freezer" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/vacuum_freezer" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/vacuum_freezer" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/vacuum_freezer", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/vacuum_freezer", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/vacuum_freezer", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/vacuum_freezer", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/vacuum_freezer", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/vacuum_freezer", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/wooden_multiblock_tank.json b/src/generated/resources/assets/gtceu/blockstates/wooden_multiblock_tank.json index ba0da244adf..447a3bb025e 100644 --- a/src/generated/resources/assets/gtceu/blockstates/wooden_multiblock_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/wooden_multiblock_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/wooden_multiblock_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/wooden_multiblock_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/wooden_multiblock_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/wooden_multiblock_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/wooden_multiblock_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/wooden_multiblock_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/wooden_multiblock_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/wooden_multiblock_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/wooden_multiblock_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/wooden_multiblock_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/wooden_multiblock_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/zpm_fusion_reactor.json b/src/generated/resources/assets/gtceu/blockstates/zpm_fusion_reactor.json index ca0c9050dc1..f294bdab420 100644 --- a/src/generated/resources/assets/gtceu/blockstates/zpm_fusion_reactor.json +++ b/src/generated/resources/assets/gtceu/blockstates/zpm_fusion_reactor.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_fusion_reactor", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_fusion_reactor", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_fusion_reactor" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/zpm_fusion_reactor" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_fusion_reactor" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_fusion_reactor", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_fusion_reactor", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_fusion_reactor", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_fusion_reactor", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_fusion_reactor", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_fusion_reactor", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/zpm_quantum_chest.json b/src/generated/resources/assets/gtceu/blockstates/zpm_quantum_chest.json index aa1005ea13a..0c696c7112c 100644 --- a/src/generated/resources/assets/gtceu/blockstates/zpm_quantum_chest.json +++ b/src/generated/resources/assets/gtceu/blockstates/zpm_quantum_chest.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_quantum_chest", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_quantum_chest", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_quantum_chest" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/zpm_quantum_chest" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_quantum_chest" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_quantum_chest", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_quantum_chest", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_quantum_chest", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_quantum_chest", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_quantum_chest", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_quantum_chest", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/blockstates/zpm_quantum_tank.json b/src/generated/resources/assets/gtceu/blockstates/zpm_quantum_tank.json index aa4fc653723..6752c497582 100644 --- a/src/generated/resources/assets/gtceu/blockstates/zpm_quantum_tank.json +++ b/src/generated/resources/assets/gtceu/blockstates/zpm_quantum_tank.json @@ -20,7 +20,7 @@ "x": 90 }, "facing=east,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_quantum_tank", "y": 90 }, @@ -34,12 +34,12 @@ "y": 90 }, "facing=east,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_quantum_tank", "y": 90 }, "facing=north,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_quantum_tank" }, "facing=north,upwards_facing=north": { @@ -50,11 +50,11 @@ "model": "gtceu:block/machine/zpm_quantum_tank" }, "facing=north,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_quantum_tank" }, "facing=south,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_quantum_tank", "y": 180 }, @@ -68,12 +68,12 @@ "y": 180 }, "facing=south,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_quantum_tank", "y": 180 }, "facing=up,upwards_facing=east": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_quantum_tank", "x": 270 }, @@ -87,12 +87,12 @@ "x": 270 }, "facing=up,upwards_facing=west": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_quantum_tank", "x": 270 }, "facing=west,upwards_facing=east": { - "gtceu:z": 90, + "gtceu:z": 270, "model": "gtceu:block/machine/zpm_quantum_tank", "y": 270 }, @@ -106,7 +106,7 @@ "y": 270 }, "facing=west,upwards_facing=west": { - "gtceu:z": 270, + "gtceu:z": 90, "model": "gtceu:block/machine/zpm_quantum_tank", "y": 270 } diff --git a/src/generated/resources/assets/gtceu/lang/en_ud.json b/src/generated/resources/assets/gtceu/lang/en_ud.json index 991240bfba3..87908addafe 100644 --- a/src/generated/resources/assets/gtceu/lang/en_ud.json +++ b/src/generated/resources/assets/gtceu/lang/en_ud.json @@ -101,13 +101,14 @@ "behaviour.setting.output.direction.tooltip": "%s :uoıʇɔǝɹıp ʇndʇno %s", "behaviour.soft_hammer": "sǝuıɥɔɐW sǝʇɐʌıʇɔɐǝᗡ puɐ sǝʇɐʌıʇɔⱯ", "behaviour.soft_hammer.disabled": "pǝןqɐsıᗡ buıʞɹoM", + "behaviour.soft_hammer.disabled_cycle": "ǝןɔʎɔ ʇuǝɹɹnɔ ɹǝʇɟɐ pǝןqɐsıᗡ buıʞɹoM", "behaviour.soft_hammer.enabled": "pǝןqɐuƎ buıʞɹoM", - "behaviour.soft_hammer.idle_after_cycle": "ǝןɔʎɔ ʇuǝɹɹnɔ ɹǝʇɟɐ ǝuıɥɔɐɯ ǝsnɐԀ", "behaviour.wrench": "ʞɔıןɔʇɥbıᴚ uo sʞɔoןᗺ sǝʇɐʇoᴚ", "block.gtceu.acid_hazard_sign_block": "ʞɔoןᗺ ubıS pɹɐzɐH pıɔⱯ", "block.gtceu.active_transformer": "ɹǝɯɹoɟsuɐɹ⟘ ǝʌıʇɔⱯ", "block.gtceu.advanced_computer_casing": "buısɐƆ ɹǝʇndɯoƆ pǝɔuɐʌpⱯ", "block.gtceu.advanced_data_access_hatch": "ɥɔʇɐH ssǝɔɔⱯ ɐʇɐᗡ pǝɔuɐʌpⱯ", + "block.gtceu.advanced_monitor": "ɹoʇıuoW pǝɔuɐʌpⱯ", "block.gtceu.alloy_blast_smelter": "ɹǝʇןǝɯS ʇsɐןᗺ ʎoןןⱯ", "block.gtceu.aluminium_crate": "ǝʇɐɹƆ ɯnıuıɯnןⱯ", "block.gtceu.aluminium_drum": "ɯnɹᗡ ɯnıuıɯnןⱯ", @@ -118,6 +119,7 @@ "block.gtceu.assembly_line_unit": "buısɐƆ ןoɹʇuoƆ ʎןqɯǝssⱯ", "block.gtceu.atomic_casing": "buısɐƆ ɔıɯoʇⱯ", "block.gtceu.auto_maintenance_hatch": "ɥɔʇɐH ǝɔuɐuǝʇuıɐW oʇnⱯ", + "block.gtceu.basic_data_access_hatch": "ɥɔʇɐH ssǝɔɔⱯ ɐʇɐᗡ ɔısɐᗺ", "block.gtceu.bio_hazard_sign_block": "ʞɔoןᗺ ubıS pɹɐzɐH oıᗺ", "block.gtceu.black_borderless_lamp": "dɯɐꞀ ssǝןɹǝpɹoᗺ ʞɔɐןᗺ", "block.gtceu.black_lamp": "dɯɐꞀ ʞɔɐןᗺ", @@ -138,7 +140,9 @@ "block.gtceu.bronze_gearbox": "buısɐƆ xoqɹɐǝ⅁ ǝzuoɹᗺ", "block.gtceu.bronze_large_boiler": "ɹǝןıoᗺ ǝzuoɹᗺ ǝbɹɐꞀ", "block.gtceu.bronze_machine_casing": "buısɐƆ ǝuıɥɔɐW ǝzuoɹᗺ", + "block.gtceu.bronze_multiblock_tank": "ʞuɐ⟘ ʞɔoןqıʇןnW ǝzuoɹᗺ", "block.gtceu.bronze_pipe_casing": "buısɐƆ ǝdıԀ ǝzuoɹᗺ", + "block.gtceu.bronze_tank_valve": "ǝʌןɐΛ ʞuɐ⟘ ǝzuoɹᗺ", "block.gtceu.brown_borderless_lamp": "dɯɐꞀ ssǝןɹǝpɹoᗺ uʍoɹᗺ", "block.gtceu.brown_lamp": "dɯɐꞀ uʍoɹᗺ", "block.gtceu.brown_large_metal_sheet": "ʇǝǝɥS ןɐʇǝW ǝbɹɐꞀ uʍoɹᗺ", @@ -147,6 +151,7 @@ "block.gtceu.casing_coke_bricks": "sʞɔıɹᗺ uǝʌO ǝʞoƆ", "block.gtceu.casing_grate": "buısɐƆ ǝuıɥɔɐW ǝʇɐɹ⅁", "block.gtceu.causality_hazard_sign_block": "ʞɔoןᗺ ubıS pɹɐzɐH ʎʇıןɐsnɐƆ", + "block.gtceu.central_monitor": "ɹoʇıuoW ןɐɹʇuǝƆ", "block.gtceu.charcoal_pile_igniter": "ɹǝʇıubI ǝןıԀ ןɐoɔɹɐɥƆ", "block.gtceu.chiseled_dark_concrete": "ǝʇǝɹɔuoƆ ʞɹɐᗡ pǝןǝsıɥƆ", "block.gtceu.chiseled_light_concrete": "ǝʇǝɹɔuoƆ ʇɥbıꞀ pǝןǝsıɥƆ", @@ -175,6 +180,7 @@ "block.gtceu.creative_data_access_hatch": "ɥɔʇɐH ssǝɔɔⱯ ɐʇɐᗡ ǝʌıʇɐǝɹƆ", "block.gtceu.creative_energy": "ʎbɹǝuƎ ǝʌıʇɐǝɹƆ", "block.gtceu.creative_tank": "ʞuɐ⟘ ǝʌıʇɐǝɹƆ", + "block.gtceu.creosote": "ǝʇosoǝɹƆ", "block.gtceu.crushing_wheels": "sןǝǝɥM buıɥsnɹƆ", "block.gtceu.cupronickel_coil_block": "ʞɔoןᗺ ןıoƆ ןǝʞɔıuoɹdnƆ", "block.gtceu.cyan_borderless_lamp": "dɯɐꞀ ssǝןɹǝpɹoᗺ uɐʎƆ", @@ -810,6 +816,7 @@ "block.gtceu.mob_infestation_hazard_sign_block": "ʞɔoןᗺ ubıS pɹɐzɐH uoıʇɐʇsǝɟuI qoW", "block.gtceu.mob_spawner_hazard_sign_block": "ʞɔoןᗺ ubıS pɹɐzɐH ɹǝuʍɐdS qoW", "block.gtceu.molybdenum_disilicide_coil_block": "ʞɔoןᗺ ןıoƆ ǝpıɔıןısıᗡ ɯnuǝpqʎןoW", + "block.gtceu.monitor": "ɹoʇıuoW", "block.gtceu.mossy_dark_concrete_bricks": "sʞɔıɹᗺ ǝʇǝɹɔuoƆ ʞɹɐᗡ ʎssoW", "block.gtceu.mossy_dark_concrete_cobblestone": "ǝuoʇsǝןqqoƆ ǝʇǝɹɔuoƆ ʞɹɐᗡ ʎssoW", "block.gtceu.mossy_light_concrete_bricks": "sʞɔıɹᗺ ǝʇǝɹɔuoƆ ʇɥbıꞀ ʎssoW", @@ -1735,8 +1742,9 @@ "command.gtceu.share_prospection_data.notification": "¡noʎ ɥʇıʍ ɐʇɐp buıʇɔǝdsoɹd buıɹɐɥs sı %s", "config.gtceu.option.addLoot": "ʇooꞀppɐ", "config.gtceu.option.ae2": "ᄅǝɐ", - "config.gtceu.option.allUniqueStoneTypes": "sǝdʎ⟘ǝuoʇSǝnbıu∩ןןɐ", + "config.gtceu.option.allowDrumsInputFluidsFromOutputSide": "ǝpıSʇndʇnOɯoɹℲspınןℲʇnduIsɯnɹᗡʍoןןɐ", "config.gtceu.option.animationTime": "ǝɯı⟘uoıʇɐɯıuɐ", + "config.gtceu.option.arcRecyclingYield": "pןǝıʎbuıןɔʎɔǝᴚɔɹɐ", "config.gtceu.option.armorHud": "pnHɹoɯɹɐ", "config.gtceu.option.batchDuration": "uoıʇɐɹnᗡɥɔʇɐq", "config.gtceu.option.bedrockOreDistance": "ǝɔuɐʇsıᗡǝɹOʞɔoɹpǝq", @@ -1751,6 +1759,7 @@ "config.gtceu.option.coloredTieredMachineOutline": "ǝuıןʇnOǝuıɥɔɐWpǝɹǝı⟘pǝɹoןoɔ", "config.gtceu.option.coloredWireOutline": "ǝuıןʇnOǝɹıMpǝɹoןoɔ", "config.gtceu.option.compat": "ʇɐdɯoɔ", + "config.gtceu.option.createCompat": "ʇɐdɯoƆǝʇɐǝɹɔ", "config.gtceu.option.debug": "bnqǝp", "config.gtceu.option.debugWorldgen": "uǝbpןɹoMbnqǝp", "config.gtceu.option.defaultPaintingColor": "ɹoןoƆbuıʇuıɐԀʇןnɐɟǝp", @@ -1762,10 +1771,14 @@ "config.gtceu.option.doDatafixers": "sɹǝxıɟɐʇɐᗡop", "config.gtceu.option.doSuperflatOres": "sǝɹOʇɐןɟɹǝdnSop", "config.gtceu.option.doesExplosionDamagesTerrain": "uıɐɹɹǝ⟘sǝbɐɯɐᗡuoısoןdxƎsǝop", + "config.gtceu.option.drum": "ɯnɹp", "config.gtceu.option.dumpAssets": "sʇǝssⱯdɯnp", "config.gtceu.option.dumpRecipes": "sǝdıɔǝᴚdɯnp", + "config.gtceu.option.enableArcRecycling": "buıןɔʎɔǝᴚɔɹⱯǝןqɐuǝ", "config.gtceu.option.enableCleanroom": "ɯooɹuɐǝןƆǝןqɐuǝ", + "config.gtceu.option.enableExtractorRecycling": "buıןɔʎɔǝᴚɹoʇɔɐɹʇxƎǝןqɐuǝ", "config.gtceu.option.enableFEConverters": "sɹǝʇɹǝʌuoƆƎℲǝןqɐuǝ", + "config.gtceu.option.enableMaceratorRecycling": "buıןɔʎɔǝᴚɹoʇɐɹǝɔɐWǝןqɐuǝ", "config.gtceu.option.enableMaintenance": "ǝɔuɐuǝʇuıɐWǝןqɐuǝ", "config.gtceu.option.enableResearch": "ɥɔɹɐǝsǝᴚǝןqɐuǝ", "config.gtceu.option.enableTieredCasings": "sbuısɐƆpǝɹǝı⟘ǝןqɐuǝ", @@ -1777,6 +1790,7 @@ "config.gtceu.option.environmentalHazardDecayRate": "ǝʇɐᴚʎɐɔǝᗡpɹɐzɐHןɐʇuǝɯuoɹıʌuǝ", "config.gtceu.option.environmentalHazards": "spɹɐzɐHןɐʇuǝɯuoɹıʌuǝ", "config.gtceu.option.euToFeRatio": "oıʇɐᴚǝℲo⟘nǝ", + "config.gtceu.option.extractorRecyclingYield": "pןǝıʎbuıןɔʎɔǝᴚɹoʇɔɐɹʇxǝ", "config.gtceu.option.feToEuRatio": "oıʇɐᴚnƎo⟘ǝɟ", "config.gtceu.option.flintAndSteelRequireSteel": "ןǝǝʇSǝɹınbǝᴚןǝǝʇSpuⱯʇuıןɟ", "config.gtceu.option.ftbChunksIntegration": "uoıʇɐɹbǝʇuIsʞunɥƆqʇɟ", @@ -1817,9 +1831,12 @@ "config.gtceu.option.ldFluidPipeMinDistance": "ǝɔuɐʇsıᗡuıWǝdıԀpınןℲpן", "config.gtceu.option.ldItemPipeMinDistance": "ǝɔuɐʇsıᗡuıWǝdıԀɯǝʇIpן", "config.gtceu.option.liquidBoilerBaseOutput": "ʇndʇnOǝsɐᗺɹǝןıoᗺpınbıן", + "config.gtceu.option.maceratorRecyclingYield": "pןǝıʎbuıןɔʎɔǝᴚɹoʇɐɹǝɔɐɯ", "config.gtceu.option.machineSounds": "spunoSǝuıɥɔɐɯ", "config.gtceu.option.machines": "sǝuıɥɔɐɯ", "config.gtceu.option.machinesEmissiveTextures": "sǝɹnʇxǝ⟘ǝʌıssıɯƎsǝuıɥɔɐɯ", + "config.gtceu.option.machinesHaveBERsByDefault": "ʇןnɐɟǝᗡʎᗺsᴚƎᗺǝʌɐHsǝuıɥɔɐɯ", + "config.gtceu.option.maintenanceCheckRate": "ǝʇɐᴚʞɔǝɥƆǝɔuɐuǝʇuıɐɯ", "config.gtceu.option.meHatchEnergyUsage": "ǝbɐs∩ʎbɹǝuƎɥɔʇɐHǝɯ", "config.gtceu.option.minerSpeed": "pǝǝdSɹǝuıɯ", "config.gtceu.option.minimap": "dɐɯıuıɯ", @@ -1845,7 +1862,7 @@ "config.gtceu.option.oreVeins": "suıǝΛǝɹo", "config.gtceu.option.ownerOPBypass": "ssɐdʎᗺԀOɹǝuʍo", "config.gtceu.option.prospectorEnergyUseMultiplier": "ɹǝıןdıʇןnWǝs∩ʎbɹǝuƎɹoʇɔǝdsoɹd", - "config.gtceu.option.recipeProgressLowEnergy": "ʎbɹǝuƎʍoꞀssǝɹboɹԀǝdıɔǝɹ", + "config.gtceu.option.quantumTank": "ʞuɐ⟘ɯnʇuɐnb", "config.gtceu.option.recipes": "sǝdıɔǝɹ", "config.gtceu.option.removeSmeltingForEBFMetals": "sןɐʇǝWℲᗺƎɹoℲbuıʇןǝɯSǝʌoɯǝɹ", "config.gtceu.option.removeVanillaBlockRecipes": "sǝdıɔǝᴚʞɔoןᗺɐןןıuɐΛǝʌoɯǝɹ", @@ -1853,8 +1870,10 @@ "config.gtceu.option.removeVanillaOreGen": "uǝ⅁ǝɹOɐןןıuɐΛǝʌoɯǝɹ", "config.gtceu.option.removeVanillaTNTRecipe": "ǝdıɔǝᴚ⟘N⟘ɐןןıuɐΛǝʌoɯǝɹ", "config.gtceu.option.renderFluids": "spınןℲɹǝpuǝɹ", + "config.gtceu.option.renderGrowingPlants": "sʇuɐןԀbuıʍoɹ⅁ɹǝpuǝɹ", "config.gtceu.option.renderer": "ɹǝɹǝpuǝɹ", "config.gtceu.option.replaceMinedBlocksWith": "ɥʇıMsʞɔoןᗺpǝuıWǝɔɐןdǝɹ", + "config.gtceu.option.replaceWithCobbleVersion": "uoısɹǝΛǝןqqoƆɥʇıMǝɔɐןdǝɹ", "config.gtceu.option.requireGTToolsForBlocks": "sʞɔoןᗺɹoℲsןoo⟘⟘⅁ǝɹınbǝɹ", "config.gtceu.option.rngDamageElectricTools": "sןoo⟘ɔıɹʇɔǝןƎǝbɐɯɐᗡbuɹ", "config.gtceu.option.rubberTreeSpawnChance": "ǝɔuɐɥƆuʍɐdSǝǝɹ⟘ɹǝqqnɹ", @@ -1871,6 +1890,7 @@ "config.gtceu.option.steelBoilerMaxTemperature": "ǝɹnʇɐɹǝdɯǝ⟘xɐWɹǝןıoᗺןǝǝʇs", "config.gtceu.option.steelSteamMultiblocks": "sʞɔoןqıʇןnWɯɐǝʇSןǝǝʇs", "config.gtceu.option.surfaceRockProspectRange": "ǝbuɐᴚʇɔǝdsoɹԀʞɔoᴚǝɔɐɟɹns", + "config.gtceu.option.tankItemFluidPreview": "ʍǝıʌǝɹԀpınןℲɯǝʇIʞuɐʇ", "config.gtceu.option.titaniumBoilerHeatSpeed": "pǝǝdSʇɐǝHɹǝןıoᗺɯnıuɐʇıʇ", "config.gtceu.option.titaniumBoilerMaxTemperature": "ǝɹnʇɐɹǝdɯǝ⟘xɐWɹǝןıoᗺɯnıuɐʇıʇ", "config.gtceu.option.toggle": "ǝןbboʇ", @@ -1899,6 +1919,7 @@ "config.jade.plugin_gtceu.auto_output_info": "oɟuI ʇndʇnO oʇnⱯ ]nƎƆ⟘⅁[", "config.jade.plugin_gtceu.cable_info": "oɟuI ǝןqɐƆ ]nƎƆ⟘⅁[", "config.jade.plugin_gtceu.controllable_provider": "ǝןqɐןןoɹʇuoƆ ]nƎƆ⟘⅁[", + "config.jade.plugin_gtceu.data_bank": "oɟuI ʞuɐᗺ ɐʇɐᗡ ]nƎƆ⟘⅁[", "config.jade.plugin_gtceu.electric_container_provider": "ɹǝuıɐʇuoƆ ɔıɹʇɔǝןƎ ]nƎƆ⟘⅁[", "config.jade.plugin_gtceu.energy_converter_provider": "ǝpoW ɹǝʇɹǝʌuoƆ ʎbɹǝuƎ ]nƎƆ⟘⅁[", "config.jade.plugin_gtceu.exhaust_vent_info": "oɟuI ʇuǝΛ ʇsnɐɥxƎ ]nƎƆ⟘⅁[", @@ -1976,9 +1997,9 @@ "cover.conveyor.distribution.insert_first.2": "˙ɥʇɐd ɐ ɟo ʎʇıɹoıɹd ǝɥʇ ɹǝʍoן sǝdıd ɯǝʇı ǝʌıʇɔıɹʇsǝᴚㄥ§", "cover.conveyor.distribution.round_robin_global.0": "uıqoᴚ punoᴚq§ :ǝpoW uoıʇnqıɹʇsıᗡ", "cover.conveyor.distribution.round_robin_global.1": "sǝıɹoʇuǝʌuı pǝʇɔǝuuoɔ ssoɹɔɐ ʎןןɐnbǝ sɯǝʇı sʇıןdSㄥ§", - "cover.conveyor.distribution.round_robin_prio.0": "ʎʇıɹoıɹԀ ɥʇıʍ uıqoᴚ punoᴚq§ :ǝpoW uoıʇnqıɹʇsıᗡ", - "cover.conveyor.distribution.round_robin_prio.1": "˙ʇsɹıɟ sǝıʇıɹoıɹd ɹǝɥbıɥ sɹǝpısuoɔ puɐ sǝıɹoʇuǝʌuı pǝʇɔǝuuoɔ ssoɹɔɐ sɯǝʇı ʇıןds oʇ sǝıɹ⟘ㄥ§", - "cover.conveyor.distribution.round_robin_prio.2": "˙ɥʇɐd ɐ ɟo ʎʇıɹoıɹd ǝɥʇ ɹǝʍoן sǝdıd ɯǝʇı ǝʌıʇɔıɹʇsǝᴚㄥ§", + "cover.conveyor.distribution.round_robin_prio.0": "uoıʇɔıɹʇsǝᴚ ɥʇıʍ uıqoᴚ punoᴚq§ :ǝpoW uoıʇnqıɹʇsıᗡ", + "cover.conveyor.distribution.round_robin_prio.1": "˙sǝıɹoʇuǝʌuı pǝʇɔǝuuoɔ ssoɹɔɐ ʎןןɐnbǝ sɯǝʇı ʇıןds oʇ sǝıɹ⟘ㄥ§", + "cover.conveyor.distribution.round_robin_prio.2": "˙ǝןqɐןıɐʌɐ ǝɹɐ sɥʇɐd ɹǝɥʇo ou ssǝןun sǝdıd ɯǝʇı ǝʌıʇɔıɹʇsǝᴚ uʍop sɯǝʇı puǝs ʇou ןןıMㄥ§", "cover.conveyor.item_filter.title": "ɹǝʇןıℲ ɯǝʇI", "cover.conveyor.mode": "%s :ǝpoW", "cover.conveyor.mode.export": "ʇɹodxƎ :ǝpoW", @@ -2002,6 +2023,8 @@ "cover.ender_fluid_link.tooltip.channel_name": "ʇxǝʇ ʇnduı ɥʇıʍ ǝɯɐu ןǝuuɐɥɔ ʇǝS", "cover.ender_fluid_link.tooltip.clear_button": "uoıʇdıɹɔsǝp ןǝuuɐɥɔ ɹɐǝןƆ", "cover.ender_fluid_link.tooltip.list_button": "ʇsıן ןǝuuɐɥɔ ʍoɥS", + "cover.ender_item_link.title": "ʞuıꞀ ɯǝʇI ɹǝpuƎ", + "cover.ender_redstone_link.title": "ʞuıꞀ ǝuoʇspǝᴚ ɹǝpuƎ", "cover.filter.blacklist.disabled": "ʇsıןǝʇıɥM", "cover.filter.blacklist.enabled": "ʇsıןʞɔɐןᗺ", "cover.filter.mode.filter_both": "ʇɔɐɹʇxƎ/ʇɹǝsuI ɹǝʇןıℲ", @@ -2045,6 +2068,7 @@ "cover.machine_controller.mode.null": "buıɥʇoN ןoɹʇuoƆ", "cover.machine_controller.normal": "ןɐɯɹoN", "cover.machine_controller.redstone": "%d :ɥʇbuǝɹʇS ǝuoʇspǝᴚ uıW", + "cover.machine_controller.suspend_powerfail": ":buıןıɐℲ ɹǝʍoԀ ʇuǝʌǝɹԀ", "cover.machine_controller.title": "sbuıʇʇǝS ɹǝןןoɹʇuoƆ ǝuıɥɔɐW", "cover.pump.fluid_filter.title": "ɹǝʇןıℲ pınןℲ", "cover.pump.mode.export": "ʇɹodxƎ :ǝpoW", @@ -2180,12 +2204,41 @@ "gtceu.cable.loss_per_block": "ʇןoΛ-∩Ǝ ㄥ§%dɔ§ ɹ§:ǝɹǝdɯⱯ/ɹǝʇǝW/ssoꞀɔ§", "gtceu.cable.superconductor": "ɹoʇɔnpuoɔɹǝdnSp§ %s", "gtceu.cable.voltage": ")ɐ§%s(ɐ§ %dɐ§ ɹ§:ǝbɐʇןoΛ xɐWɐ§", + "gtceu.central_monitor.gui.create_group": "dnoɹb ǝʇɐǝɹƆ", + "gtceu.central_monitor.gui.currently_editing": "%s :buıʇıpǝ ʎןʇuǝɹɹnƆ", + "gtceu.central_monitor.gui.remove_from_group": "dnoɹb ɯoɹɟ ǝʌoɯǝᴚ", + "gtceu.central_monitor.gui.set_target": "ʇǝbɹɐʇ ʇǝS", + "gtceu.central_monitor.info_tooltip.0": "˙ʇı uı ǝןnpoɯ Ɩ ǝʌɐɥ ʎןuo ʎɐɯ dnoɹb Ɐ ˙ʇsɹıɟ sdnoɹb oʇuı ɯǝɥʇ ʇıןds oʇ ǝʌɐɥ noʎ 'sɹoʇıuoɯ ǝsn oʇ ɹǝpɹo uI", + "gtceu.central_monitor.info_tooltip.1": "˙,dnoɹb ǝʇɐǝɹƆ, ʞɔıןɔ uǝɥʇ 'buıʞɔıןɔ-ʇɟǝן ʎq ɯǝɥʇ ʇɔǝןǝS", + "gtceu.central_monitor.info_tooltip.2": "˙ǝbɐd ǝɯɐs ǝɥʇ uı ʇı ǝɹnbıɟuoɔ uɐɔ noʎ 'ǝןnpoɯ ɐ ʇɹǝsuı uɐɔ noʎ dnoɹb ǝɥʇ ɹoɟ ǝbɐd sbuıʇʇǝs ǝɥʇ uı uǝɥ⟘", + "gtceu.central_monitor.info_tooltip.3": "˙,dnoɹb ɯoɹɟ ǝʌoɯǝᴚ, ʞɔıןɔ puɐ sʇuǝuodɯoɔ s,ʇı ɟo ןןɐ ʇɔǝןǝs 'dnoɹb ɐ ǝʇǝןǝp o⟘", + "gtceu.central_monitor.info_tooltip.4": "˙ʇɔǝןǝsun oʇ uıɐbɐ ʞɔıןƆ ˙ǝɯɐu s,ʇı uo buıʞɔıןɔ ʎq dnoɹb ɐ ɟo sʇuǝuodɯoɔ ןןɐ ʇɔǝןǝs ʎןʞɔınb uɐɔ noʎ", + "gtceu.central_monitor.info_tooltip.5": "˙ʇuǝuodɯoɔ ʇǝbɹɐʇ ǝɥʇ uo ʞɔıןɔ-ʇɥbıɹ puɐ dnoɹb ʇɐɥʇ ɟo ʇuǝuodɯoɔ ʎuɐ ʇɔǝןǝs dnoɹb ɐ ɹoɟ ʇǝbɹɐʇ ɐ ʇǝs oʇ 'ʇǝbɹɐʇ ʎǝɥʇ ʞɔoןq ǝɥʇ uo buıpuǝdǝp sbuıɥʇ ʎɐןdsıp ʎɐɯ sǝןnpoɯ ǝɯoS", + "gtceu.central_monitor.info_tooltip.6": "˙ʇɐɥʇ ɹoɟ ɹǝʌoɔ ɹǝʇʇıɯsuɐɹʇ ssǝןǝɹıʍ ǝɥʇ ǝsn oʇ ǝʌɐɥ noʎ 'ʞɔoןqıʇןnɯ ǝɥʇ uı ʇou sı ʇɐɥʇ ʇǝbɹɐʇ ɐ ʇɔǝןǝs oʇ ɥsıʍ ʎɐɯ noʎ", + "gtceu.central_monitor.info_tooltip.7": "˙ʞɔoןqıʇןnɯ ǝɥʇ uı ɥɔʇɐɥ ssǝɔɔɐ ɐʇɐp ɐ oʇuı ʞɔıʇs ɐʇɐp ʇɐɥʇ ʇnd puɐ ʞɔıʇs ɐʇɐp ɐ ɥʇıʍ ʇı ʞɔıןɔ-ʇɥbıɹ 'ʞɔoןq ʇǝbɹɐʇ ǝɥʇ uo ɹǝʌoɔ ǝɥʇ ǝɔɐןԀ", + "gtceu.central_monitor.info_tooltip.8": "˙pǝɹɐǝddɐ ʇɐɥʇ pןǝıɟ ɹǝqɯnu ǝɥʇ uı ʞɔıʇs ɐʇɐp ɹnoʎ ɟo xǝpuı ʇoןs ǝɥʇ ʇǝs puɐ 'ʇǝbɹɐʇ ǝɥʇ sɐ ɥɔʇɐɥ ssǝɔɔɐ ɐʇɐp ǝɥʇ ʇɔǝןǝs uǝɥ⟘", + "gtceu.central_monitor.size": ")%d+Ɩ+%d(x)%d+Ɩ+%d( :ǝzıS", "gtceu.chance_logic.and": "ᗡNⱯ", "gtceu.chance_logic.first": "⟘SᴚIℲ", "gtceu.chance_logic.none": "ƎNON", "gtceu.chance_logic.or": "ᴚO", "gtceu.chance_logic.xor": "ᴚOX", "gtceu.chat.cape": "ɹ§˙ʇı ǝsn oʇ ddɐ ןɐuıɯɹǝʇ ɹoʇɔǝןǝS ǝdɐƆ ǝɥʇ ǝǝS ¡ǝdɐɔ ʍǝu ɐ pǝʞɔoןun ʇsnظ noʎ :sʇɐɹbuoƆϛ§", + "gtceu.computer_monitor_cover.error.bf_invalid": "%d ʇɐ ɹǝʇɔɐɹɐɥɔ pıןɐʌuI", + "gtceu.computer_monitor_cover.error.bf_invalid_num": "%d ɹǝqɯnu ןoqɯʎs buıssǝɔoɹd uǝɥʍ %d xǝpuı ʇɐ ɹǝqɯnu pıןɐʌuI", + "gtceu.computer_monitor_cover.error.exception": "%s :pǝɹɹnɔɔo uoıʇdǝɔxǝ pǝʇɔǝdxǝu∩", + "gtceu.computer_monitor_cover.error.invalid_args": "¡sʇuǝɯnbɹɐ pıןɐʌuI", + "gtceu.computer_monitor_cover.error.invalid_number": "¡,%s, ɹǝqɯnu pıןɐʌuI", + "gtceu.computer_monitor_cover.error.missing_item": "¡%d ʇoןs uı %s buıssıW", + "gtceu.computer_monitor_cover.error.no_ae": "¡ʞɹoʍʇǝu ᄅƎⱯ uɐ ǝʌɐɥ ʇou sǝop ɹǝpןoɥ ɹǝʌoƆ", + "gtceu.computer_monitor_cover.error.no_cover": "¡ɹǝʌoɔ oN", + "gtceu.computer_monitor_cover.error.no_placeholder": "¡,%s, :ɹǝpןoɥǝɔɐןd ɥɔns oN", + "gtceu.computer_monitor_cover.error.not_enough_args": "¡%d ʇob 'sbɹɐ %d ʇsɐǝן ʇɐ pǝʇɔǝdxƎ", + "gtceu.computer_monitor_cover.error.not_in_range": "%d ʇob ')ǝʌısnןɔuı( %d puɐ %d uǝǝʍʇǝq ǝq oʇ %s pǝʇɔǝdxƎ", + "gtceu.computer_monitor_cover.error.not_supported": "¡ɹǝʌoɔ/ʞɔoןq sıɥʇ ʎq pǝʇɹoddns ʇou sı ǝɹnʇɐǝɟ sıɥ⟘", + "gtceu.computer_monitor_cover.error.unclosed_bracket": "¡ʇǝʞɔɐɹq pǝsoןɔu∩", + "gtceu.computer_monitor_cover.error.unexpected_bracket": "¡ʇǝʞɔɐɹq buısoןɔ pǝʇɔǝdxǝu∩", + "gtceu.computer_monitor_cover.error.wrong_number_of_args": "¡%d ʇob 'sbɹɐ %d pǝʇɔǝdxƎ", "gtceu.cover.activity_detector.message_activity_inverted": "snʇɐʇS ʎʇıʌıʇɔⱯ pǝʇɹǝʌuI buıɹoʇıuoW", "gtceu.cover.activity_detector.message_activity_normal": "snʇɐʇS ʎʇıʌıʇɔⱯ ןɐɯɹoN buıɹoʇıuoW", "gtceu.cover.activity_detector_advanced.message_activity_inverted": "snʇɐʇS ssǝɹboɹԀ pǝʇɹǝʌuI buıɹoʇıuoW", @@ -2219,7 +2272,14 @@ "gtceu.direction.tooltip.left": "ʇɟǝꞀ", "gtceu.direction.tooltip.right": "ʇɥbıᴚ", "gtceu.direction.tooltip.up": "d∩", + "gtceu.display_source.computer_monitor_cover": "ɹǝʌoƆ ɹoʇıuoW ɹǝʇndɯoƆ", + "gtceu.display_target.computer_monitor_cover": "ɹǝʌoƆ ɹoʇıuoW ɹǝʇndɯoƆ", "gtceu.duct_pipe.transfer_rate": "%s :ǝʇɐɹ ɹǝɟsuɐɹʇ ɹıⱯq§", + "gtceu.ender_item_link_cover.title": "ʞuıꞀ ɯǝʇI ɹǝpuƎ", + "gtceu.ender_item_link_cover.tooltip": "˙ㄥ§ɹǝʌoƆɟ§ sɐ ㄥ§uoıʇɔǝuuoƆ ɟ§ɹǝpuƎp§ ssǝןǝɹıMɟ§ ɐ ɥʇıʍ ㄥ§sɯǝʇIɟ§ sʇɹodsuɐɹ⟘ㄥ§", + "gtceu.ender_redstone_link_cover.label": "%d :ɹǝʍod ǝuoʇspǝᴚ", + "gtceu.ender_redstone_link_cover.title": "ʞuıꞀ ǝuoʇspǝᴚ ɹǝpuƎ", + "gtceu.ender_redstone_link_cover.tooltip": "˙ㄥ§ɹǝʌoƆɟ§ sɐ ㄥ§uoıʇɔǝuuoƆ ɟ§ɹǝpuƎp§ ssǝןǝɹıMɟ§ ɐ ɥʇıʍ ㄥ§sןɐubıs ǝuoʇspǝᴚɟ§ sʇıɯsuɐɹ⟘ㄥ§", "gtceu.fluid.amount": "ᗺɯ %d/%d :ʇunoɯⱯ6§", "gtceu.fluid.click_combined": "˙)ʞɔɐʇs ןןnɟ ɐ ɹoɟ ʞɔıןɔ-ʇɟıɥS( ʞuɐʇ ǝɥʇㄥ§ ןןıɟq§ ɹoㄥ§ ʎʇdɯǝɔ§ oʇ ɹǝuıɐʇuoƆ pınןℲ ɐ ɥʇıʍ ʞɔıןƆㄥ§", "gtceu.fluid.click_to_empty": "˙)ʞɔɐʇs ןןnɟ ɐ ɹoɟ ʞɔıןɔ-ʇɟıɥS( ʞuɐʇ ǝɥʇㄥ§ ʎʇdɯǝɔ§ oʇ ɹǝuıɐʇuoƆ pınןℲ ɐ ɥʇıʍ ʞɔıןƆㄥ§", @@ -2248,7 +2308,16 @@ "gtceu.forming_press.naming.named": "ɯǝʇI pǝɯɐNo§", "gtceu.forming_press.naming.press": "ssǝɹԀ pǝɯɐNo§", "gtceu.forming_press.naming.to_name": "ǝɯɐN oʇ ɯǝʇIo§", + "gtceu.gui.adv_stocking_config.min_fluid_count": "buıןןnԀ pǝʇɐɯoʇnⱯ ɹoɟ ǝzıS ʞɔɐʇS pınןℲ ɯnɯıuıW", + "gtceu.gui.adv_stocking_config.min_item_count": "buıןןnԀ pǝʇɐɯoʇnⱯ ɹoɟ ǝzıS ʞɔɐʇS ɯǝʇI ɯnɯıuıW", + "gtceu.gui.adv_stocking_config.ticks_per_cycle": "sǝʇɐpdn ʇsıן ɯǝʇı uǝǝʍʇǝq ʎɐןǝᗡ", + "gtceu.gui.adv_stocking_config.title": "buıʞɔoʇS ɔıʇɐɯoʇnⱯ ǝɹnbıɟuoƆ", + "gtceu.gui.all_voiding": "ןןⱯɔ§ buıpıoΛㄥ§", "gtceu.gui.auto_output.name": "oʇnɐ", + "gtceu.gui.central_monitor.group": "%s :dnoɹ⅁", + "gtceu.gui.central_monitor.group_default_name": "%d# dnoɹ⅁", + "gtceu.gui.central_monitor.none": "ǝuou", + "gtceu.gui.central_monitor.text_scale": "ǝןɐɔs ʇxǝ⟘", "gtceu.gui.charger_slot.tooltip.0": "ɹ§ʇoןS ɹǝbɹɐɥƆɟ§", "gtceu.gui.charger_slot.tooltip.1": "ɹ§sǝıɹǝʇʇɐq %s ɯoɹɟ ɹǝʍod sʍɐɹᗡㄥ§", "gtceu.gui.charger_slot.tooltip.2": "sǝıɹǝʇʇɐq puɐ sןooʇ %s sǝbɹɐɥƆㄥ§", @@ -2257,6 +2326,18 @@ "gtceu.gui.chunkmode.enabled.0": "˙ǝןqɐsıᗡ oʇ ʞɔıןƆ :pǝןqɐuƎ ǝpoW ʞunɥƆ", "gtceu.gui.chunkmode.enabled.1": "˙ǝuıɥɔɐɯ ǝןpı uɐ sǝɹınbǝɹ buıɥɔʇıʍSㄥ§", "gtceu.gui.circuit.title": "sbuıʇʇǝS ʇınɔɹıƆ", + "gtceu.gui.computer_monitor_cover.edit_blank_placeholders": "sɹǝpןoɥǝɔɐןd ʞuɐןq ʇıpƎ", + "gtceu.gui.computer_monitor_cover.edit_displayed_text": "ʇxǝʇ pǝʎɐןdsıp ʇıpƎ", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.0": "˙ǝɹǝɥ %d ǝuıן uo ʎɐןdsıp oʇ buıɹʇs ʇnduI", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.1": ",∩Ǝ }ʎʇıɔɐdɐƆʎbɹǝuǝ{/}ʎbɹǝuǝ{ :ʎbɹǝuƎ, :ǝןdɯɐxǝ ɹoɟ 'sɹǝpןoɥǝɔɐןd ǝʌɐɥ uɐɔ ʇI", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.2": "˙sɹǝpןoɥǝɔɐןd ɹǝɥʇo ǝpısuı ǝq osןɐ uɐɔ sɹǝpןoɥǝɔɐןԀ", + "gtceu.gui.computer_monitor_cover.placeholder_reference.0": ":sɹǝpןoɥǝɔɐןd ןןⱯ", + "gtceu.gui.computer_monitor_cover.placeholder_reference.1": ")oɟuı ǝɹoɯ ɹoɟ ɹǝʌoɥ(", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.0": "˙ǝɹǝɥ ,}{, %s ɟo ǝɔɐןd uı pǝsn ǝq oʇ ɹǝpןoɥǝɔɐןd ʇnduI", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.1": "˙sǝxoq ʇxǝʇ ǝsǝɥʇ uı ,ʎʇıɔɐdɐƆʎbɹǝuǝ, puɐ ,ʎbɹǝuǝ, puɐ ,∩Ǝ }{/}{ :ʎbɹǝuƎ, buıɹʇs ɐ ǝʌɐɥ uɐɔ noʎ 'ǝןdɯɐxǝ ɹoℲ", + "gtceu.gui.computer_monitor_cover.slot_tooltip.0": "ǝɔuǝɹǝɟǝɹ uɐɔ sɹǝpןoɥǝɔɐןd ǝɯos ʇɐɥʇ sɯǝʇı ɹoɟ ʇoןs Ɐ", + "gtceu.gui.computer_monitor_cover.slot_tooltip.1": "%d :ɹǝqɯnu ʇoןS", + "gtceu.gui.computer_monitor_cover.update_interval": ")sʞɔıʇ uı( ןɐʌɹǝʇuı ǝʇɐpd∩", "gtceu.gui.config_slot": "ɹ§ʇoןS bıɟuoƆɟ§", "gtceu.gui.config_slot.auto_pull_managed": "ןןnԀ-oʇnⱯ ʎq pǝbɐuɐW ㄥ§:pǝןqɐsıᗡㄣ§", "gtceu.gui.config_slot.remove": "ɹ§˙ʇoןs bıɟuoɔ ㄥ§ɹɐǝןɔㄣ§ oʇ ʞɔıןɔ ʇɥbıᴚㄥ§", @@ -2281,11 +2362,15 @@ "gtceu.gui.content.count_range": "x%s-%s", "gtceu.gui.content.fluid_range": "ᗺɯ%s-%s", "gtceu.gui.content.per_tick": "ɹ§ʞɔı⟘ ɹǝԀ pǝɔnpoɹԀ/pǝɯnsuoƆɐ§", + "gtceu.gui.content.range": "%s-%s", + "gtceu.gui.content.times_item": "%s x", "gtceu.gui.content.tips.per_second_short": "ɹ§puoɔǝs/ɐ§", "gtceu.gui.content.tips.per_tick_short": "ɹ§ʞɔıʇ/ɐ§", "gtceu.gui.content.units.per_second": "s/", "gtceu.gui.content.units.per_tick": "ʇ/", "gtceu.gui.cover_setting.title": "sbuıʇʇǝS ɹǝʌoƆ", + "gtceu.gui.directional_setting.tab_tooltip": "buıʇʇǝS ןɐuoıʇɔǝɹıᗡ ǝbuɐɥƆ", + "gtceu.gui.directional_setting.title": "buıʇʇǝS ןɐuoıʇɔǝɹıᗡ", "gtceu.gui.editor.group.recipe_type": "dɐɔ", "gtceu.gui.editor.tips.citation": "suoıʇɐʇıɔ ɟo ɹǝqɯnN", "gtceu.gui.fisher_mode.tooltip.0": "sɯǝʇı ʞunظ ǝןbbo⟘", @@ -2295,10 +2380,18 @@ "gtceu.gui.fluid_auto_input.tooltip.enabled": "pǝןqɐuƎ ʇnduI-oʇnⱯ pınןℲ", "gtceu.gui.fluid_auto_output.allow_input.disabled": "ǝpıs ʇndʇno ǝɥʇ ɯoɹɟ ʇnduı spınןɟ ǝןqɐsıp", "gtceu.gui.fluid_auto_output.allow_input.enabled": "ǝpıs ʇndʇno ǝɥʇ ɯoɹɟ ʇnduı spınןɟ ʍoןןɐ", + "gtceu.gui.fluid_auto_output.disabled": "pǝןqɐsıᗡɔ§ :ʇndʇnO oʇnⱯ pınןℲ", + "gtceu.gui.fluid_auto_output.enabled": "pǝןqɐuƎɐ§ :ʇndʇnO oʇnⱯ pınןℲ", + "gtceu.gui.fluid_auto_output.other_direction.0": "uoıʇɔǝɹıᗡ ɹǝɥʇO9§ :ʇndʇnO oʇnⱯ pınןℲ", + "gtceu.gui.fluid_auto_output.other_direction.1": "˙uoıʇɔǝɹıp ɹǝɥʇouɐ oʇ ʇǝs sı ʇndʇno pınןɟ s,ǝuıɥɔɐɯ ǝɥ⟘ㄥ§", + "gtceu.gui.fluid_auto_output.other_direction.2": "˙ǝpıs pǝʇɔǝןǝs ʎןʇuǝɹɹnɔ ǝɥʇ oʇ ʇndʇno ǝɥʇ ǝʌoɯ oʇ ʞɔıןƆㄥ§", "gtceu.gui.fluid_auto_output.tooltip.disabled": "pǝןqɐsıᗡ ʇndʇnO-oʇnⱯ pınןℲ", "gtceu.gui.fluid_auto_output.tooltip.enabled": "pǝןqɐuƎ ʇndʇnO-oʇnⱯ pınןℲ", + "gtceu.gui.fluid_auto_output.unselected.0": "ʇndʇnO oʇnⱯ pınןℲ", + "gtceu.gui.fluid_auto_output.unselected.1": "˙ʇndʇno sʇı ǝɹnbıɟuoɔ oʇ ǝuıɥɔɐɯ ǝɥʇ ɟo ǝpıs ɐ ʇɔǝןǝSㄥ§", "gtceu.gui.fluid_lock.tooltip.disabled": "pǝןqɐsıᗡ buıʞɔoꞀ pınןℲ", "gtceu.gui.fluid_lock.tooltip.enabled": "pǝןqɐuƎ buıʞɔoꞀ pınןℲ", + "gtceu.gui.fluid_voiding": "spınןℲ6§ buıpıoΛㄥ§", "gtceu.gui.fluid_voiding_partial.tooltip.disabled": "pǝןqɐsıᗡ buıpıoΛ pınןℲ", "gtceu.gui.fluid_voiding_partial.tooltip.enabled": "pǝןqɐuƎ buıpıoΛ pınןℲ", "gtceu.gui.fuel_amount": ":ʇunoɯⱯ ןǝnℲ", @@ -2306,25 +2399,28 @@ "gtceu.gui.item_auto_input.tooltip.enabled": "pǝןqɐuƎ ʇnduI-oʇnⱯ ɯǝʇI", "gtceu.gui.item_auto_output.allow_input.disabled": "ǝpıs ʇndʇno ǝɥʇ ɯoɹɟ ʇnduı sɯǝʇı ǝןqɐsıp", "gtceu.gui.item_auto_output.allow_input.enabled": "ǝpıs ʇndʇno ǝɥʇ ɯoɹɟ ʇnduı sɯǝʇı ʍoןןɐ", + "gtceu.gui.item_auto_output.disabled": "pǝןqɐsıᗡɔ§ :ʇndʇnO oʇnⱯ ɯǝʇI", + "gtceu.gui.item_auto_output.enabled": "pǝןqɐuƎɐ§ :ʇndʇnO oʇnⱯ ɯǝʇI", + "gtceu.gui.item_auto_output.other_direction.0": "uoıʇɔǝɹıᗡ ɹǝɥʇO9§ :ʇndʇnO oʇnⱯ ɯǝʇI", + "gtceu.gui.item_auto_output.other_direction.1": "˙uoıʇɔǝɹıp ɹǝɥʇouɐ oʇ ʇǝs sı ʇndʇno ɯǝʇı s,ǝuıɥɔɐɯ ǝɥ⟘ㄥ§", + "gtceu.gui.item_auto_output.other_direction.2": "˙ǝpıs pǝʇɔǝןǝs ʎןʇuǝɹɹnɔ ǝɥʇ oʇ ʇndʇno ǝɥʇ ǝʌoɯ oʇ ʞɔıןƆㄥ§", "gtceu.gui.item_auto_output.tooltip.disabled": "pǝןqɐsıᗡ ʇndʇnO-oʇnⱯ ɯǝʇI", "gtceu.gui.item_auto_output.tooltip.enabled": "pǝןqɐuƎ ʇndʇnO-oʇnⱯ ɯǝʇI", + "gtceu.gui.item_auto_output.unselected.0": "ʇndʇnO oʇnⱯ ɯǝʇI", + "gtceu.gui.item_auto_output.unselected.1": "˙ʇndʇno sʇı ǝɹnbıɟuoɔ oʇ ǝuıɥɔɐɯ ǝɥʇ ɟo ǝpıs ɐ ʇɔǝןǝSㄥ§", "gtceu.gui.item_lock.tooltip.disabled": "pǝןqɐsıᗡ buıʞɔoꞀ ɯǝʇI", "gtceu.gui.item_lock.tooltip.enabled": "pǝןqɐuƎ buıʞɔoꞀ ɯǝʇI", + "gtceu.gui.item_voiding": "sɯǝʇI9§ buıpıoΛㄥ§", "gtceu.gui.item_voiding_partial.tooltip.disabled": "pǝןqɐsıᗡ buıpıoΛ ɯǝʇI", "gtceu.gui.item_voiding_partial.tooltip.enabled": "pǝןqɐuƎ buıpıoΛ ɯǝʇI", "gtceu.gui.machinemode": "%s :ǝpoW ǝuıɥɔɐW ǝʌıʇɔⱯ", + "gtceu.gui.machinemode.tab_tooltip": "ǝpoW ǝuıɥɔɐW ǝʌıʇɔɐ ǝbuɐɥƆ", "gtceu.gui.machinemode.title": "ǝpoW ǝuıɥɔɐW ǝʌıʇɔⱯ", "gtceu.gui.me_bus.auto_pull_button": "ƎW ɯoɹɟ buıןןnd ɯǝʇı ɔıʇɐɯoʇnɐ ǝןbboʇ oʇ ʞɔıןƆ", "gtceu.gui.me_network.offline": "ɹ§ǝuıןɟɟOㄣ§ :snʇɐʇS ʞɹoʍʇǝN", "gtceu.gui.me_network.online": "ɹ§ǝuıןuOᄅ§ :snʇɐʇS ʞɹoʍʇǝN", - "gtceu.gui.multiblock_fluid_voiding.0": "ǝpoW buıpıoΛ", - "gtceu.gui.multiblock_fluid_voiding.1": "spınןℲ6§ buıpıoΛㄥ§", - "gtceu.gui.multiblock_item_fluid_voiding.0": "ǝpoW buıpıoΛ", - "gtceu.gui.multiblock_item_fluid_voiding.1": "spınןℲ6§ puɐㄥ§ sɯǝʇI9§ buıpıoΛㄥ§", - "gtceu.gui.multiblock_item_voiding.0": "ǝpoW buıpıoΛ", - "gtceu.gui.multiblock_item_voiding.1": "sɯǝʇI9§ buıpıoΛㄥ§", - "gtceu.gui.multiblock_no_voiding.0": "ǝpoW buıpıoΛ", - "gtceu.gui.multiblock_no_voiding.1": "buıɥʇoN buıpıoΛㄥ§", + "gtceu.gui.multiblock.voiding_mode": ":ǝpoW buıpıoΛ", + "gtceu.gui.no_voiding": "buıɥʇoN buıpıoΛㄥ§", "gtceu.gui.output_setting.title": "sbuıʇʇǝS ʇndʇnO", "gtceu.gui.output_setting.tooltips.0": "ʇndʇno oʇnɐ ɯǝʇı ǝɥʇ ǝunʇ oʇ ʞɔıןɔ-ʇɟǝן", "gtceu.gui.output_setting.tooltips.1": "˙ʇndʇno oʇnɐ pınןɟ ǝɥʇ ǝunʇ oʇ ʞɔıןɔ-ʇɥbıɹ", @@ -2342,6 +2438,9 @@ "gtceu.gui.silktouch.enabled.0": "˙ǝןqɐsıᗡ oʇ ʞɔıןƆ :pǝןqɐuƎ ɥɔno⟘ ʞןıS", "gtceu.gui.silktouch.enabled.1": "˙ǝuıɥɔɐɯ ǝןpı uɐ sǝɹınbǝɹ buıɥɔʇıʍSㄥ§", "gtceu.gui.sort": "ʇɹoS", + "gtceu.gui.title.adv_stocking_config.min_fluid_count": "ʇunoƆ pınןℲ ˙uıW", + "gtceu.gui.title.adv_stocking_config.min_item_count": "ʇunoƆ ɯǝʇI ˙uıW", + "gtceu.gui.title.adv_stocking_config.ticks_per_cycle": "ǝןɔʎƆ ɹǝԀ sʞɔı⟘", "gtceu.gui.title_bar.back": "ʞɔɐᗺ", "gtceu.gui.title_bar.page_switcher": "sǝbɐԀ", "gtceu.gui.toggle_view.disabled": ")spınןℲ( ʍǝıΛ ǝןbbo⟘", @@ -2361,8 +2460,11 @@ "gtceu.item_filter.footer": "ǝpıɹɹǝʌo oʇ ɯǝʇı ɥʇıʍ ʞɔıןƆǝ§", "gtceu.item_list.item_stored": "%d :pǝɹoʇSㄥ§", "gtceu.item_pipe.priority": "%dɟ§ :ʎʇıɹoıɹԀ6§", + "gtceu.jade.amperage_use": "Ɐ %s", + "gtceu.jade.at": " @ ", "gtceu.jade.cleaned_this_second": "s/%s :pɹɐzɐɥ pǝuɐǝןƆ", "gtceu.jade.energy_stored": "∩Ǝ %d / %d", + "gtceu.jade.fluid_use": "ʇ/ᗺɯ %s", "gtceu.jade.progress_computation": "∩MƆ %s / %s", "gtceu.jade.progress_sec": "s %s / %s", "gtceu.jade.progress_tick": "ʇ %s / %s", @@ -2435,9 +2537,9 @@ "gtceu.machine.bedrock_ore_miner.production": "pǝʞɔoןɔɹǝʌo xɟ% 'x%dɟ§ :ɹǝıןdıʇןnW uoıʇɔnpoɹԀǝ§", "gtceu.machine.block_breaker.speed_bonus": "%d%%ɟ§ :snuoᗺ pǝǝdSǝ§", "gtceu.machine.block_breaker.tooltip": "sdoɹp sʇı sʇɔǝןןoɔ puɐ ǝɔɐɟ ʇuoɹɟ uo ʞɔoןq sǝuıWㄥ§", - "gtceu.machine.boiler.info.cooling.down": "%sɹ§uʍop buıןooƆ6§", - "gtceu.machine.boiler.info.heating.up": "%sɹ§dn buıʇɐǝHɔ§", - "gtceu.machine.boiler.info.producing.steam": ")ɹǝʇɐʍ buıןıoq(ɐ§ ", + "gtceu.machine.boiler.info.cooling.down": "ɹ§buıןooƆ6§", + "gtceu.machine.boiler.info.heating.up": "ɹ§buıʇɐǝHɔ§", + "gtceu.machine.boiler.info.production.data": "ʇ/ᗺɯ ɐ§%s buıɔnpoɹԀɐ§", "gtceu.machine.buffer.tooltip": "spınןℲ puɐ sɯǝʇI ǝɹoʇs oʇ ɹǝɟɟnᗺ ןןɐɯS Ɐ", "gtceu.machine.canner.jei_description": ")sןןǝƆ pınןℲ ɹo sʇǝʞɔnᗺ ˙b˙ǝ( ɹǝuuɐƆ pınןℲ ǝɥʇ ɥʇıʍ sɹǝuıɐʇuoɔ pınןɟ ʎuɐ ʎʇdɯǝ puɐ ןןıɟ uɐɔ noʎ", "gtceu.machine.central_monitor.tooltip": "¿ɯooᗡ unɹ ʇı uɐɔ ʇnᗺ", @@ -2567,7 +2669,7 @@ "gtceu.machine.hp_steam_forge_hammer.tooltip": "ɹǝɯɯɐH ǝbɹoℲㄥ§", "gtceu.machine.hp_steam_furnace.tooltip": "ɯɐǝʇS pǝssǝɹdɯoɔ ɥʇıʍ sbuıɥʇ buıʇןǝɯSㄥ§", "gtceu.machine.hp_steam_liquid_boiler.tooltip": "ɹǝןıoᗺ pınbıꞀ ɯɐǝʇS ןןɐɯS uɐɥʇ ɹǝʇsɐℲㄥ§", - "gtceu.machine.hp_steam_macerator.tooltip": "sǝɹO ɹnoʎ buıʇɐɹǝɔɐWㄥ§", + "gtceu.machine.hp_steam_macerator.tooltip": "sʇɔnpoɹdʎᗺ ʇnoɥʇıʍ sǝɹO ɹnoʎ buıʇɐɹǝɔɐWㄥ§", "gtceu.machine.hp_steam_rock_crusher.tooltip": "ʇuǝɔɐظpɐ ʎןןɐʇuozıɹoɥ ɐʌɐꞀ puɐ ɹǝʇɐM ǝɔɐןԀㄥ§", "gtceu.machine.hp_steam_solar_boiler.tooltip": "unS ʎq ɹǝʍoԀ ɯɐǝʇSㄥ§", "gtceu.machine.hp_steam_solid_boiler.tooltip": "ɹǝןıoᗺ ןǝnℲ pıןoS ɯɐǝʇS ןןɐɯS ǝɥʇ uɐɥʇ ɹǝʇsɐℲㄥ§", @@ -2705,7 +2807,7 @@ "gtceu.machine.lp_steam_forge_hammer.tooltip": "ɹǝɯɯɐH ǝbɹoℲㄥ§", "gtceu.machine.lp_steam_furnace.tooltip": "ɯɐǝʇS pǝssǝɹdɯoɔ ɥʇıʍ sbuıɥʇ buıʇןǝɯSㄥ§", "gtceu.machine.lp_steam_liquid_boiler.tooltip": "spınbıꞀ ɟɟo buıuunɹ ɹǝןıoᗺ Ɐㄥ§", - "gtceu.machine.lp_steam_macerator.tooltip": "sǝɹO ɹnoʎ buıʇɐɹǝɔɐWㄥ§", + "gtceu.machine.lp_steam_macerator.tooltip": "sʇɔnpoɹdʎᗺ ʇnoɥʇıʍ sǝɹO ɹnoʎ buıʇɐɹǝɔɐWㄥ§", "gtceu.machine.lp_steam_rock_crusher.tooltip": "ʇuǝɔɐظpɐ ʎןןɐʇuozıɹoɥ ɐʌɐꞀ puɐ ɹǝʇɐM ǝɔɐןԀㄥ§", "gtceu.machine.lp_steam_solar_boiler.tooltip": "unS ʎq ɹǝʍoԀ ɯɐǝʇSㄥ§", "gtceu.machine.lp_steam_solid_boiler.tooltip": "ɹǝʍoԀ ɯɐǝʇS ʇǝb oʇ ʎɐʍ ʎןɹɐǝ uⱯㄥ§", @@ -2825,6 +2927,7 @@ "gtceu.machine.miner.multi.modes": "˙sǝpoW pǝubıןⱯ ʞunɥƆ puɐ ɥɔno⟘ ʞןıS sɐH", "gtceu.machine.miner.multi.production": "˙ㄥ§ɹoʇɐɹǝɔɐWɟ§ ɐ uɐɥʇ ǝɹo pǝɥsnɹɔ ǝɹoɯ ㄥ§xƐɟ§ sǝɔnpoɹԀ", "gtceu.machine.miner.per_block": "ʞɔoןᗺ ɹǝdㄥ§ %dsɟ§ sǝʞɐʇㄥ§", + "gtceu.machine.miner.progress": "%d/%d :ssǝɹboɹԀ", "gtceu.machine.miner.radius": "%d :snıpɐᴚ", "gtceu.machine.miner.startx": "%d :Xs", "gtceu.machine.miner.starty": "%d :ʎs", @@ -3071,7 +3174,7 @@ "gtceu.multiblock.active_transformer.max_input": "ʇ/∩Ǝ %sɟ§ :ʇnduI xɐWɐ§", "gtceu.multiblock.active_transformer.max_output": "ʇ/∩Ǝ %sɟ§ :ʇndʇnO xɐWɔ§", "gtceu.multiblock.assembly_line.description": "˙sʇuǝuodɯoɔ buıʇɟɐɹɔ pǝɔuɐʌpɐ buıʇɐǝɹɔ ɹoɟ pǝsn 'ǝuıɥɔɐW buıןqɯǝssⱯ ǝbɹɐן s,ʇı 'ʎɹoǝɥʇ uI ˙\"sǝɔıןs\" 9Ɩ oʇ ϛ ɟo buıʇsısuoɔ ǝɹnʇɔnɹʇs ʞɔoןqıʇןnɯ ǝbɹɐן ɐ sı ǝuıꞀ ʎןqɯǝssⱯ ǝɥ⟘", - "gtceu.multiblock.batch_enabled": ")x%s( pǝןqɐuƎ :ǝpoW buıɥɔʇɐᗺ", + "gtceu.multiblock.batch_enabled": "buıɥɔʇɐᗺ ɯoɹɟ x%d -", "gtceu.multiblock.blast_furnace.max_temperature": "%s :ʎʇıɔɐdɐƆ ʇɐǝH", "gtceu.multiblock.central_monitor.height": ":ʇɥbıǝH uǝǝɹɔS", "gtceu.multiblock.central_monitor.height_modify": "%d :ʇɥbıǝH ʎɟıpoW", @@ -3202,7 +3305,7 @@ "gtceu.multiblock.page_switcher.io.export": "sʇndʇnOㄣ§", "gtceu.multiblock.page_switcher.io.import": "sʇnduIᄅ§", "gtceu.multiblock.parallel": "ןǝןןɐɹɐԀ uı sǝdıɔǝᴚ %d oʇ dn buıɯɹoɟɹǝԀ", - "gtceu.multiblock.parallel.exact": "ןǝןןɐɹɐԀ uı sǝdıɔǝᴚ %d buıɯɹoɟɹǝԀ", + "gtceu.multiblock.parallel.exact": "sןǝןןɐɹɐԀ ɯoɹɟ x%d -", "gtceu.multiblock.parallelizable.tooltip": "˙sǝɥɔʇɐH ןoɹʇuoƆ ןǝןןɐɹɐԀ ɥʇıʍ ǝzıןǝןןɐɹɐd uɐƆ", "gtceu.multiblock.pattern.clear_amount_1": "ɹ§ʇuoɹɟ uı ǝɔɐds ƖxƖxƖ ɹɐǝןɔ ɐ ǝʌɐɥ ʇsnW9§", "gtceu.multiblock.pattern.clear_amount_3": "ɹ§ʇuoɹɟ uı ǝɔɐds ƖxƐxƐ ɹɐǝןɔ ɐ ǝʌɐɥ ʇsnW9§", @@ -3268,7 +3371,9 @@ "gtceu.multiblock.steam.steam_stored": "qɯ %s / %s :ɯɐǝʇS", "gtceu.multiblock.steam_grinder.description": "˙ɥɔʇɐH ɯɐǝʇS ǝɥʇ uɐɥʇ ɹǝɥʇo sǝɥɔʇɐH pınןℲ ɹou 'sǝssnq ʇndʇnO/ʇnduI ןɐɯɹou ǝsn ʇouuɐƆ ˙ɯɹoɟ oʇ sbuısɐƆ ǝzuoɹᗺ ㄣƖ ʇsɐǝן ʇɐ sǝɹınbǝᴚ ˙ǝbⱯ ɯɐǝʇS ǝɥʇ ʇɐ ɹoʇɐɹǝɔɐW ʞɔoןqıʇןnW Ɐ", "gtceu.multiblock.steam_oven.description": "˙ǝuo uɐɥʇ ǝɹoɯ ou 'ɹǝʎɐן ɯoʇʇoq ǝɥʇ uo ǝq ʇsnɯ ɥɔʇɐH ɯɐǝʇS ˙ɥɔʇɐH ɯɐǝʇS ǝɥʇ uɐɥʇ ɹǝɥʇo sǝɥɔʇɐH pınןℲ ɹou 'sǝssnq ʇndʇnO/ʇnduI ןɐɯɹou ǝsn ʇouuɐƆ ˙ɯɹoɟ oʇ sbuısɐƆ ǝzuoɹᗺ 9 ʇsɐǝן ʇɐ sǝɹınbǝᴚ ˙ǝbⱯ ɯɐǝʇS ǝɥʇ ʇɐ ɹǝʇןǝɯS ıʇןnW Ɐ", + "gtceu.multiblock.subtick_parallels": "buıʞɔoןɔɹǝʌO ɯoɹɟ x%d -", "gtceu.multiblock.title": "uɹǝʇʇɐԀ ʞɔoןqıʇןnW", + "gtceu.multiblock.total_runs": "ǝɔuo ʇɐ sǝdıɔǝᴚ %d buıɯɹoɟɹǝԀ", "gtceu.multiblock.turbine.efficiency": "%s%% :ʎɔuǝıɔıɟɟƎ ǝuıqɹn⟘", "gtceu.multiblock.turbine.efficiency_tooltip": "˙ㄥ§ᄅ ʎq ʇ/∩Ǝ sǝıןdıʇןnɯ puɐ ʎɔuǝıɔıɟɟǝ %%0Ɩɟ§ sppɐ ㄥ§%s ǝʌoqɐ ɹǝpןoH ɹoʇoᴚ ɥɔɐƎ", "gtceu.multiblock.turbine.energy_per_tick": "ʇ/∩Ǝ %s/%s :ʇndʇnO ʎbɹǝuƎ", @@ -3310,6 +3415,209 @@ "gtceu.ownership.name.player": "ɹǝʎɐןԀ", "gtceu.part_sharing.disabled": "pǝןqɐsıᗡㄣ§ buıɹɐɥS ʞɔoןqıʇןnW", "gtceu.part_sharing.enabled": "pǝןqɐuƎɐ§ buıɹɐɥS ʞɔoןqıʇןnW", + "gtceu.placeholder_info.active.0": "˙ǝsıʍɹǝɥʇo 0 'ǝdıɔǝɹ ɐ buıuunɹ ʎןʇuǝɹɹnɔ sı oʇ pǝɥɔɐʇʇɐ sı ɹǝʌoɔ ǝɥʇ ʞɔoןq ǝɥʇ ɟı Ɩ ɐ suɹnʇǝᴚ", + "gtceu.placeholder_info.active.1": ":ǝbɐs∩", + "gtceu.placeholder_info.active.2": "ǝdıɔǝɹ buıuunɹ ʎןʇuǝɹɹnɔ ɐ s,ǝɹǝɥʇ ɹǝɥʇǝɥʍ >- }ǝʌıʇɔɐ{ ", + "gtceu.placeholder_info.ae2crafting.0": "˙uo sı ɹǝʌoɔ sıɥʇ ʞɔoןq ǝɥʇ ɟo ʞɹoʍʇǝu ƎW ǝɥʇ uı buıʇɟɐɹɔ-oʇnɐ ʇnoqɐ uoıʇɐɯɹoɟuı suɹnʇǝᴚ", + "gtceu.placeholder_info.ae2crafting.1": ":ǝbɐs∩", + "gtceu.placeholder_info.ae2crafting.10": "ǝןpı sı ∩ԀƆ ǝɥʇ ɟı 0 ɹo ')spuoɔǝsouɐu uı( ʇɟɐɹɔ ǝɥʇ ɟo ʇɹɐʇs ǝɥʇ ɯoɹɟ pǝsdɐןǝ ǝɯıʇ ɟo ʇunoɯɐ ǝɥʇ >- }ǝɯıʇ >xǝpuı< ʇǝb buıʇɟɐɹɔᄅǝɐ{ ", + "gtceu.placeholder_info.ae2crafting.2": "ʞɹoʍʇǝu ƎW ǝɥʇ uı s∩ԀƆ buıʇɟɐɹɔ ɟo ʇunoɯɐ ǝɥʇ >- }ʇunoɯɐ ʇǝb buıʇɟɐɹɔᄅǝɐ{ ", + "gtceu.placeholder_info.ae2crafting.3": "sɐɥ ∩ԀƆ pǝıɟıɔǝds ǝɥʇ ǝbɐɹoʇs buıʇɟɐɹɔ ɟo ʇunoɯɐ ǝɥʇ >- }ǝbɐɹoʇs >xǝpuı< ʇǝb buıʇɟɐɹɔᄅǝɐ{ ", + "gtceu.placeholder_info.ae2crafting.4": "sɐɥ ∩ԀƆ pǝıɟıɔǝds ǝɥʇ sɹossǝɔoɹd-oɔ ɟo ʇunoɯɐ ǝɥʇ >- }spɐǝɹɥʇ >xǝpuı< ʇǝb buıʇɟɐɹɔᄅǝɐ{ ", + "gtceu.placeholder_info.ae2crafting.5": "∩ԀƆ buıʇɟɐɹɔ pǝıɟıɔǝds ǝɥʇ ɟo ǝɯɐu ǝɥʇ >- }ǝɯɐu >xǝpuı< ʇǝb buıʇɟɐɹɔᄅǝɐ{ ", + "gtceu.placeholder_info.ae2crafting.6": ")sʇsǝnbǝɹ ɥʇoq ɹo ɔıʇɐɯoʇnɐ 'ןɐnuɐɯ ɹoɟ pǝsn( ∩ԀƆ buıʇɟɐɹɔ pǝıɟıɔǝds ǝɥʇ ɟo ǝpoɯ uoıʇɔǝןǝs ǝɥʇ >- }ǝpoWuoıʇɔǝןǝs >xǝpuı< ʇǝb buıʇɟɐɹɔᄅǝɐ{ ", + "gtceu.placeholder_info.ae2crafting.7": "ǝןpı sı ∩ԀƆ ǝɥʇ ɟı 0 ɹo 'pǝʇsǝnbǝɹ sɐʍ ʇɐɥʇ ɯǝʇı ǝɥʇ ɟo ʇunoɯɐ ǝɥʇ >- }ʇunoɯɐ >xǝpuı< ʇǝb buıʇɟɐɹɔᄅǝɐ{ ", + "gtceu.placeholder_info.ae2crafting.8": "ǝןpı sı ∩ԀƆ ǝɥʇ ɟı 0 ɹo 'pǝʇsǝnbǝɹ sɐʍ ʇɐɥʇ ɯǝʇı ǝɥʇ ɟo ǝɯɐu ʎɐןdsıp ǝɥʇ >- }ɯǝʇı >xǝpuı< ʇǝb buıʇɟɐɹɔᄅǝɐ{ ", + "gtceu.placeholder_info.ae2crafting.9": "ǝןpı sı ∩ԀƆ ǝɥʇ ɟı 0 ɹo 'ssǝɹboɹd qoظ buıʇɟɐɹɔ ǝɥʇ >- }ssǝɹboɹd >xǝpuı< ʇǝb buıʇɟɐɹɔᄅǝɐ{ ", + "gtceu.placeholder_info.ae2energy.0": "˙uo sı ɹǝʌoɔ sıɥʇ ʞɔoןq ǝɥʇ ɟo ʞɹoʍʇǝu ƎW ǝɥʇ uı pǝɹoʇs ʎןʇuǝɹɹnɔ ʎbɹǝuǝ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.ae2energy.1": ":ǝbɐs∩", + "gtceu.placeholder_info.ae2energy.2": ")sʇıun ƎⱯ uı( ʞɹoʍʇǝu ƎW ǝɥʇ uı ʎbɹǝuǝ ǝɥʇ >- }ʎbɹǝuǝᄅǝɐ{ ", + "gtceu.placeholder_info.ae2fluidCount.0": "˙oʇ pǝɥɔɐʇʇɐ sı ɹǝʌoɔ sıɥʇ ʞɔoןq ǝɥʇ ɟo ʞɹoʍʇǝu ƎW ǝɥʇ uı sɯǝʇı sʇunoɔ ʇnq 'ʇunoƆpınןɟ sɐ ǝɯɐS", + "gtceu.placeholder_info.ae2fluidCount.1": "¡bɐן ǝsnɐɔ ʎɐɯ spınןɟ ןןɐ buıʇunoɔ ʇɐɥʇ ǝʇoN", + "gtceu.placeholder_info.ae2fluidCount.2": ":ǝbɐs∩", + "gtceu.placeholder_info.ae2fluidCount.3": "pǝıɟıɔǝds ɟı pIpınןɟ ɥʇıʍ pınןɟ ǝɥʇ ɹo 'spınןɟ ןןɐ ɟo ʇunoɯɐ ǝɥʇ >- }]pIpınןɟ[ ʇunoƆpınןɟ{ ", + "gtceu.placeholder_info.ae2itemCount.0": "˙oʇ pǝɥɔɐʇʇɐ sı ɹǝʌoɔ sıɥʇ ʞɔoןq ǝɥʇ ɟo ʞɹoʍʇǝu ƎW ǝɥʇ uı sɯǝʇı sʇunoɔ ʇnq 'ʇunoƆɯǝʇı sɐ ǝɯɐS", + "gtceu.placeholder_info.ae2itemCount.1": "¡bɐן ǝsnɐɔ ʎɐɯ sɯǝʇı ןןɐ ɹo ɹǝʇןıɟ ʎq buıʇunoɔ ʇɐɥʇ ǝʇoN", + "gtceu.placeholder_info.ae2itemCount.2": ":ǝbɐs∩", + "gtceu.placeholder_info.ae2itemCount.3": "ʇunoɯɐ ɯǝʇı ןɐʇoʇ >- }ʇunoƆɯǝʇı{ ", + "gtceu.placeholder_info.ae2itemCount.4": "pı‾ɯǝʇı oʇ ןɐnbǝ spı ɥʇıʍ sɯǝʇı ɟo ʇunoɯɐ >- }>pı‾ɯǝʇı< ʇunoƆɯǝʇı{ ", + "gtceu.placeholder_info.ae2itemCount.5": "ɹǝʌoɔ sıɥʇ ɟo ʇoןs pǝıɟıɔǝds uı ɹǝʇןıɟ buıɥɔʇɐɯ sɯǝʇı ɟo ʇunoɯɐ >- }>pı‾ʇoןs< ɹǝʇןıɟ ʇunoƆɯǝʇı{ ", + "gtceu.placeholder_info.ae2maxPower.0": "˙uo sı ɹǝʌoɔ sıɥʇ ʞɔoןq ǝɥʇ ɟo ʞɹoʍʇǝu ƎW ǝɥʇ ɟo ʎʇıɔɐdɐɔ ʎbɹǝuǝ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.ae2maxPower.1": ":ǝbɐs∩", + "gtceu.placeholder_info.ae2maxPower.2": "ʞɹoʍʇǝu ƎW ǝɥʇ ɟo ʎʇıɔɐdɐɔ ʎbɹǝuǝ ǝɥʇ >- }ɹǝʍoԀxɐɯᄅǝɐ{ ", + "gtceu.placeholder_info.ae2powerUsage.0": "˙uo sı ɹǝʌoɔ sıɥʇ ʞɔoןq ǝɥʇ ɟo ʞɹoʍʇǝu ƎW ǝɥʇ ɟo uoıʇdɯnsuoɔ ʎbɹǝuǝ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.ae2powerUsage.1": ":ǝbɐs∩", + "gtceu.placeholder_info.ae2powerUsage.2": "ʞɹoʍʇǝu ƎW ǝɥʇ ɟo uoıʇdɯnsuoɔ ʎbɹǝuǝ ǝɥʇ >- }ǝbɐs∩ɹǝʍodᄅǝɐ{ ", + "gtceu.placeholder_info.ae2spatial.0": "˙uo sı ɹǝʌoɔ sıɥʇ ʞɔoןq ǝɥʇ ɟo ʞɹoʍʇǝu ƎW ǝɥʇ uı O/I ןɐıʇɐds ʇnoqɐ uoıʇɐɯɹoɟuı suɹnʇǝᴚ", + "gtceu.placeholder_info.ae2spatial.1": ":ǝbɐs∩", + "gtceu.placeholder_info.ae2spatial.2": "O/I ןɐıʇɐds ǝʇɐıʇıuı oʇ pǝɹınbǝɹ ɹǝʍod ɟo ʇunoɯɐ ǝɥʇ >- }ɹǝʍod ןɐıʇɐdsᄅǝɐ{ ", + "gtceu.placeholder_info.ae2spatial.3": ")SԀS( ǝɹnʇɔnɹʇS ʇuǝɯuıɐʇuoƆ ןɐıʇɐdS ǝɥʇ ɟo ʎɔuǝıɔıɟɟǝ ǝɥʇ >- }ʎɔuǝıɔıɟɟǝ ןɐıʇɐdsᄅǝɐ{ ", + "gtceu.placeholder_info.ae2spatial.4": "),}Zǝzıs{x}ʎǝzıs{x}Xǝzıs{ :ǝzıS, :ǝןdɯɐxǝ( sıxɐ pǝıɟıɔǝds ǝɥʇ buoןɐ SԀS ǝɥʇ ɟo ǝzıs ǝɥʇ >- }>Z|ʎ|X<ǝzıs ןɐıʇɐdsᄅǝɐ{ ", + "gtceu.placeholder_info.amperage.0": "˙uo sı ɹǝʌoɔ ǝɥʇ ǝןqɐɔ/ǝɹıʍ ǝɥʇ uı ǝbɐɹǝdɯɐ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.amperage.1": ":ǝbɐs∩", + "gtceu.placeholder_info.amperage.2": "ǝןqɐɔ/ǝɹıʍ ǝɥʇ uı ǝʇɐɹǝdɯɐ ǝɥʇ >- }ǝbɐɹǝdɯɐ{ ", + "gtceu.placeholder_info.bf.0": ":ǝbɐs∩", + "gtceu.placeholder_info.bf.1": "buıɹʇs ʎʇdɯǝ >- }>ǝpoɔ< >xǝpuı‾ʇoןs‾ɯǝʇı‾ɐʇɐp< ɟq{ ", + "gtceu.placeholder_info.block.0": "˙)█( ןoqɯʎs ʞɔoןq ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.block.1": ":ǝbɐs∩", + "gtceu.placeholder_info.block.2": ",█, >- }ʞɔoןq{ ", + "gtceu.placeholder_info.blockNbt.0": "ʎʇıʇuǝ ʞɔoןq ǝɥʇ ɟo ⟘ᗺN ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.blockNbt.1": ":ǝbɐs∩", + "gtceu.placeholder_info.blockNbt.2": "ʇqu ʎʇıʇuǝ ʞɔoןq ןןnɟ >- }ʇqNʞɔoןq{ ", + "gtceu.placeholder_info.blockNbt.3": "ʇqu ǝɥʇ ɟo ʇɹɐd >- }˙˙˙ ]ᄅʎǝʞ[ ]Ɩʎǝʞ[ ʇqNʞɔoןq{ ", + "gtceu.placeholder_info.bufferText.0": "ʇɟɐɹƆɹǝʇndɯoƆ ʎq ǝןqıssǝɔɔɐ ɹǝɟɟnq ɐ ɯoɹɟ ʇxǝʇ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.bufferText.1": ":ǝbɐs∩", + "gtceu.placeholder_info.bufferText.2": ")00Ɩ-Ɩ sı ǝuıן( ǝuıן pǝıɟıɔǝds ǝɥʇ uo ɹǝɟɟnq ǝɥʇ ɯoɹɟ ʇxǝʇ >- }>ǝuıן< ʇxǝ⟘ɹǝɟɟnq{ ", + "gtceu.placeholder_info.calc.0": "˙uoıʇɐɹǝdo ɹo uoıʇɔunɟ ɥʇɐɯ ɐ ɟo ʇןnsǝɹ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.calc.1": ":ǝbɐs∩", + "gtceu.placeholder_info.calc.2": "buıɹʇs‾ʎuɐ >- }>buıɹʇs‾ʎuɐ< ɔןɐɔ{ ", + "gtceu.placeholder_info.calc.3": "uoıʇɐɹǝdo pǝıɟıɔǝds ǝɥʇ ɟo ʇןnsǝɹ ǝɥʇ >- }>bɹɐ< >~|ʇɹbs|ןıǝɔ|ɹooןɟ|punoɹ< ɔןɐɔ{ ", + "gtceu.placeholder_info.calc.4": "uoıʇɐɹǝdo pǝıɟıɔǝds ǝɥʇ ɟo ʇןnsǝɹ ǝɥʇ >- }>bɹɐ‾puoɔǝs< >%|<<|>>|//|/|*|-|+< >bɹɐ‾ʇsɹıɟ< ɔןɐɔ{ ", + "gtceu.placeholder_info.click.0": "ʞɔıʇ ʇuǝɹɹnɔ ǝɥʇ ǝɹoɟǝq pǝʞɔıןɔ sɐʍ ɹoʇıuoɯ pǝɔuɐʌpɐ pǝʇǝbɹɐʇ ǝɥʇ ɹǝɥʇǝɥʍ suɹnʇǝᴚ", + "gtceu.placeholder_info.click.1": ":ǝbɐs∩", + "gtceu.placeholder_info.click.2": "ǝsıʍɹǝɥʇo \"0\" 'pǝʞɔıןɔ sɐʍ ɹoʇıuoɯ pǝɔuɐʌpɐ pǝʇǝbɹɐʇ ǝɥʇ ɟı \"Ɩ\" >- }ʞɔıןɔ{ ", + "gtceu.placeholder_info.click.3": ")Ɩ puɐ 0 uǝǝʍʇǝq( ʞɔıןɔ ʇsɐן ǝɥʇ ɟo uoıʇısod x ǝɥʇ >- }x ʞɔıןɔ{ ", + "gtceu.placeholder_info.click.4": ")Ɩ puɐ 0 uǝǝʍʇǝq( ʞɔıןɔ ʇsɐן ǝɥʇ ɟo uoıʇısod ʎ ǝɥʇ >- }ʎ ʞɔıןɔ{ ", + "gtceu.placeholder_info.cmd.0": "˙ʇndʇno ɹıǝɥʇ suɹnʇǝɹ puɐ spuɐɯɯoɔ ʇɟɐɹɔǝuıW sǝʇnɔǝxƎ", + "gtceu.placeholder_info.cmd.1": "˙ʇı ɥʇıʍ buıʞɔıןɔ-ʇɥbıɹ ʎq ɟןǝsɹnoʎ oʇ ɯǝʇı ɐʇɐp ʎuɐ puıq 'ɹǝʎɐןd ɐ oʇ punoq ɯǝʇı ɐʇɐp ɐ sǝɹınbǝᴚ", + "gtceu.placeholder_info.cmd.2": ":ǝbɐs∩", + "gtceu.placeholder_info.cmd.3": "ʇndʇno puɐɯɯoɔ >- }>puɐɯɯoɔ< >xǝpuı‾ʇoןs< pɯɔ{ ", + "gtceu.placeholder_info.cmp.0": "sʇuǝɯnbɹɐ s,ʇı uı uoıssǝɹdxǝ ǝɥʇ uo pǝsɐq 0 ɹo Ɩ ɐ suɹnʇǝᴚ", + "gtceu.placeholder_info.cmp.1": ":ǝbɐs∩", + "gtceu.placeholder_info.cmp.2": "=¡ '== '=< '=> '< '> ɟo ǝuo sı ɹoʇɐɹǝdo '0 ɹo Ɩ >- }>q< >ɹoʇɐɹǝdo< >ɐ< dɯɔ{ ", + "gtceu.placeholder_info.color.0": "˙pǝsn ǝq uɐɔ sɹoןoɔ ʇɐɥɔ ʇɟɐɹɔǝuıɯ ʇןnɐɟǝp ןןⱯ ˙ʇuǝɯnbɹɐ ʇsɹıɟ ǝɥʇ ɯoɹɟ ɹoןoɔ ǝɥʇ ɥʇıʍ pǝɹoןoɔ 'ʇuǝɯnbɹɐ puoɔǝs ǝɥʇ ɯoɹɟ ʇxǝʇ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.color.1": ":ǝbɐs∩", + "gtceu.placeholder_info.color.2": "ʇxǝʇ pǝɹoןoɔ >- }>ʇxǝʇ< >ɹoןoɔ< ɹoןoɔ{ ", + "gtceu.placeholder_info.combine.0": ")sʇuǝɯnbɹɐ ǝɥʇ uǝǝʍʇǝq sǝɔɐds ןןɐ buıdɐɔsǝ ʎq( buıɹʇs ǝןbuıs ɐ oʇuı sʇuǝɯnbɹɐ s,ʇı ɟo ןןɐ sǝuıqɯoƆ", + "gtceu.placeholder_info.combine.1": "\"ouɯ \\ןʞظ \\ıɥb \\ɟǝp \\ɔqɐ\" >- }ouɯ ןʞظ ıɥb ɟǝp ɔqɐ ǝuıqɯoɔ{ :ǝןdɯɐxƎ", + "gtceu.placeholder_info.combine.2": ":ǝbɐs∩", + "gtceu.placeholder_info.combine.3": "sɹǝpןoɥǝɔɐןd ɹǝɥʇɹnɟ uı ʇuǝɯnbɹɐ ǝןbuıs ɐ sɐ pǝʇɐǝɹʇ ǝq ןןıʍ ʇɐɥʇ buıɹʇs ɐ >- }˙˙˙ ]Ɛbɹɐ[ ]ᄅbɹɐ[ ]Ɩbɹɐ[ ǝuıqɯoɔ{ ", + "gtceu.placeholder_info.count.0": ")\"0˙0\" =¡ \"0\" os 'sbuıɹʇs sɐ pǝɹɐdɯoɔ( ʇsɹıɟ ǝɥʇ oʇ ןɐnbǝ ǝɹɐ sʇuǝɯnbɹɐ pǝpıʌoɹd ǝɥʇ ɟo ʎuɐɯ ʍoɥ suɹnʇǝᴚ", + "gtceu.placeholder_info.count.1": ":ǝbɐs∩", + "gtceu.placeholder_info.count.2": "ʇsɹıɟ ǝɥʇ oʇ ןɐnbǝ ǝɹɐ ʇɐɥʇ sʇuǝɯnbɹɐ ɟo ʇunoɯɐ ǝɥʇ >- }˙˙˙ ]ㄣbɹɐ[ ]Ɛbɹɐ[ ]ᄅbɹɐ[ >Ɩbɹɐ< ʇunoɔ{ ", + "gtceu.placeholder_info.data.0": "˙sʇoןs ǝɥʇ ɟo ǝuo uı )ǝןnpoɯ/qɹo/ʞɔıʇs ɐʇɐp( ɯǝʇı ɐʇɐp ɐ ɯoɹɟ ɐʇɐp ǝɯos sǝʌǝıɹʇǝɹ ɹo sǝɹoʇS", + "gtceu.placeholder_info.data.1": "˙)ʇqu ɯǝʇı ɐʇɐp ǝɥʇ uı pǝɹoʇs sı ʇɐɥʇ )Ɩ - ʎʇıɔɐdɐɔ( oʇ 0 ɯoɹɟ ɹǝbǝʇuı uɐ sı d( d ǝnןɐʌ ǝɥʇ ɥʇıʍ pǝɔɐןdǝɹ ǝq ןןıʍ ʇı 'ʎʇdɯǝ ʇuǝɯnbɹɐ >xǝpuı< ǝɥʇ ǝʌɐǝן noʎ ɟI", + "gtceu.placeholder_info.data.2": ":ǝbɐs∩", + "gtceu.placeholder_info.data.3": "ʇoןs pǝıɟıɔǝds ǝɥʇ uı ɯǝʇı ǝɥʇ uı pǝɹoʇs ɐʇɐp ǝɥʇ >- }>xǝpuı< >ʇoןs< ʇǝb ɐʇɐp{ ", + "gtceu.placeholder_info.data.4": "buıɹʇs ʎʇdɯǝ uɐ suɹnʇǝɹ 'ʇoןs pǝıɟıɔǝds ǝɥʇ uı ɯǝʇı ǝɥʇ uı pǝɹoʇs ɐʇɐp ǝɥʇ sʇǝs >- }>ǝnןɐʌ< >xǝpuı< >ʇoןs< ʇǝs ɐʇɐp{ ", + "gtceu.placeholder_info.data.5": "d >- }>ʇoןs< dʇǝb ɐʇɐp{ ", + "gtceu.placeholder_info.data.6": "buıɹʇs ʎʇdɯǝ uɐ suɹnʇǝɹ 'd sʇǝs >- }>ǝnןɐʌ< >ʇoןs< dʇǝs ɐʇɐp{ ", + "gtceu.placeholder_info.data.7": "0 oʇ d sʇǝs 'ʎʇıɔɐdɐɔ oʇ ןɐnbǝ ɹo uɐɥʇ ǝɹoɯ sǝɯoɔǝq d ɟı 'Ɩ ʎq d sʇuǝɯǝɹɔuı >- }>ʇoןs< ɔuı ɐʇɐp{ ", + "gtceu.placeholder_info.data.8": ")Ɩ - ʎʇıɔɐdɐɔ( oʇ d sʇǝs '0 uɐɥʇ ssǝן sǝɯoɔǝq d ɟı 'Ɩ ʎq d sʇuǝɯǝɹɔǝp >- }>ʇoןs< ɔǝp ɐʇɐp{ ", + "gtceu.placeholder_info.displayTarget.0": "˙ʞuıן ʎɐןdsıp ɐ buısn ɹǝʌoɔ sıɥʇ oʇ pǝʇʇıɯsuɐɹʇ sɐʍ ʇɐɥʇ ǝuıן pǝıɟıɔǝds ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.displayTarget.1": ":ǝbɐs∩", + "gtceu.placeholder_info.displayTarget.2": ")00Ɩ-Ɩ sı ɹǝqɯnu ǝuıן( ǝuıן pǝıɟıɔǝds ǝɥʇ uo ʇxǝʇ ǝɥʇ >- }>ɹǝqɯnu‾ǝuıן< ʇǝbɹɐ⟘ʎɐןdsıp{ ", + "gtceu.placeholder_info.ender.0": "sɹǝʌoɔ ʞuıן ɹǝpuǝ ɥʇıʍ sʇɔɐɹǝʇuI", + "gtceu.placeholder_info.ender.1": "ɹǝʎɐןd ɐ oʇ punoq ɯǝʇı ɐʇɐp ɐ ɥʇıʍ pǝpıʌoɹd ɟı sןǝuuɐɥɔ ǝʇɐʌıɹd ɥʇıʍ ʇɔɐɹǝʇuı uɐƆ", + "gtceu.placeholder_info.ender.10": ")buıɹʇs ʎʇdɯǝ '0 ʇou( ʎʇdɯǝ ʇɟǝן ǝq ʎɐɯ ʇuǝɯnbɹɐ ʇoןs‾ɯǝʇı‾ɐʇɐp‾ɹǝʎɐןd ǝɥ⟘", + "gtceu.placeholder_info.ender.2": ":ǝbɐs∩", + "gtceu.placeholder_info.ender.3": "ʇunoɔ ɯǝʇı >- }]ʇoןs‾ɯǝʇı‾ɐʇɐp‾ɹǝʎɐןd[ >ןǝuuɐɥɔ< ɯǝʇı ɹǝpuǝ{ ", + "gtceu.placeholder_info.ender.4": "ɹǝɟɟnq s,ʞuıן ɹǝpuǝ ǝɥʇ ɯoɹɟ ɯǝʇı Ɩ ןןnd >- }]ʇoןs‾ɯǝʇı‾ɐʇɐp‾ɹǝʎɐןd[ >ןǝuuɐɥɔ< ןןnԀɯǝʇı ɹǝpuǝ{ ", + "gtceu.placeholder_info.ender.5": "ɹǝɟɟnq s,ʞuıן ɹǝpuǝ ǝɥʇ oʇ ɯǝʇı Ɩ ɥsnd >- }]ʇoןs‾ɯǝʇı‾ɐʇɐp‾ɹǝʎɐןd[ >ןǝuuɐɥɔ< ɥsnԀɯǝʇı ɹǝpuǝ{ ", + "gtceu.placeholder_info.ender.6": ")\"ʇɹıp:ʇɟɐɹɔǝuıɯ 9ᄅ\" ˙xǝ( ɹǝɟɟnq s,ʞuıן ɹǝpuǝ ǝɥʇ uı ɯǝʇı ǝɥʇ ɟo pı ǝɥʇ >- }]ʇoןs‾ɯǝʇı‾ɐʇɐp‾ɹǝʎɐןd[ >ןǝuuɐɥɔ< pIɯǝʇı ɹǝpuǝ{ ", + "gtceu.placeholder_info.ender.7": "ʇunoɔ pınןɟ >- }]ʇoןs‾ɯǝʇı‾ɐʇɐp‾ɹǝʎɐןd[ >ןǝuuɐɥɔ< pınןɟ ɹǝpuǝ{ ", + "gtceu.placeholder_info.ender.8": "ןǝʌǝן ןɐubıs ǝuoʇspǝɹ >- ]ʇoןs‾ɯǝʇı‾ɐʇɐp‾ɹǝʎɐןd[ >ןǝuuɐɥɔ< ǝuoʇspǝɹ ɹǝpuǝ{ ", + "gtceu.placeholder_info.ender.9": "buıɹʇs ʎʇdɯǝ suɹnʇǝɹ 'ʞuıן ǝuoʇspǝɹ ɹǝpuǝ ǝɥʇ oʇ pǝʇndʇno ןɐubıs ǝuoʇspǝɹ ǝɥʇ sʇǝs >- >ןɐubıs< >ʇoןs‾ɯǝʇı‾ɐʇɐp‾ɹǝʎɐןd< >ןǝuuɐɥɔ< ǝuoʇspǝɹ ɹǝpuǝ{ ", + "gtceu.placeholder_info.energy.0": "˙pǝɹoʇs ʎbɹǝuǝ ɟo ʇunoɯɐ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.energy.1": ":ǝbɐs∩", + "gtceu.placeholder_info.energy.2": "pǝɹoʇs ʎbɹǝuǝ ɟo ʇunoɯɐ ǝɥʇ >- }ʎbɹǝuǝ{ ", + "gtceu.placeholder_info.energyCapacity.0": "pǝɹoʇs ǝq uɐɔ ʇɐɥʇ ʎbɹǝuǝ ɟo ʇunoɯɐ xɐɯ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.energyCapacity.1": ":ǝbɐs∩", + "gtceu.placeholder_info.energyCapacity.2": "ʎʇıɔɐdɐɔ ʎbɹǝuǝ ǝɥʇ >- }ʎʇıɔɐdɐƆʎbɹǝuǝ{", + "gtceu.placeholder_info.eval.0": "sɹǝpןoɥǝɔɐןd ʎɐɯ ɥɔıɥʍ buıɹʇs pǝpıʌoɹd ǝɥʇ buıʇɐnןɐʌǝ ɟo ʇןnsǝɹ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.eval.1": ":ǝbɐs∩", + "gtceu.placeholder_info.eval.2": "bɟǝpɔqɐ >- }bɟǝpɔqɐ ןɐʌǝ{ ", + "gtceu.placeholder_info.eval.3": " ɐ ɐ ɐ ɐ ɐ :ɐ buıʇɐǝdǝɹ >- \"}\"\\ ɐ\"\\ ϛ ʇɐǝdǝɹ{ :ɐ buıʇɐǝdǝɹ\" ןɐʌǝ{ ", + "gtceu.placeholder_info.eval.4": "}ʇxǝʇ ɯopuɐɹ ǝɯos{ >- \"\\\"}ʇxǝʇ ɯopuɐɹ ǝɯos{\"\"\\ ןɐʌǝ{ ", + "gtceu.placeholder_info.eval.5": "ʇxǝʇ ǝɹoɯ }sǝɔɐds ɥʇıʍ buıɥʇǝɯos{ ʇxǝʇ >- \"ʇxǝʇ ǝɹoɯ \"\"\\\"}sǝɔɐds ɥʇıʍ buıɥʇǝɯos{\"\"\\\" ʇxǝʇ\" ןɐʌǝ{ ", + "gtceu.placeholder_info.fluidCount.0": "˙)pǝɹǝʇןıɟ ǝq uɐɔ( spınןɟ ɟo ʇunoɯɐ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.fluidCount.1": ":ǝbɐs∩", + "gtceu.placeholder_info.fluidCount.2": "pǝıɟıɔǝds ɟı pIpınןɟ ɥʇıʍ pınןɟ ǝɥʇ ɹo 'spınןɟ ןןɐ ɟo ʇunoɯɐ ǝɥʇ >- }]pIpınןɟ[ ʇunoƆpınןɟ{ ", + "gtceu.placeholder_info.formatInt.0": "ɹǝbǝʇuı pǝpıʌoɹd ǝɥʇ ɟo uoıʇɐʇuǝsǝɹdǝɹ buıɹʇs ɐ suɹnʇǝᴚ", + "gtceu.placeholder_info.formatInt.1": "Wㄣᄅ˙Ɩ >- }ㄥϛㄣ9ƐᄅƖ ʇuIʇɐɯɹoɟ{ :ǝןdɯɐxƎ", + "gtceu.placeholder_info.formatInt.2": ":ǝbɐs∩", + "gtceu.placeholder_info.formatInt.3": "ʇuı ǝɥʇ ɟo uoıʇɐʇuǝsǝɹdǝɹ buıɹʇs >- }>bɹɐ< ʇuIʇɐɯɹoɟ{ ", + "gtceu.placeholder_info.fromAscii.0": "ǝpoɔ IIƆSⱯ pǝpıʌoɹd ǝɥʇ ʎq pǝʇuǝsǝɹdǝɹ ɹǝʇɔɐɹɐɥɔ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.fromAscii.1": ":ǝbɐs∩", + "gtceu.placeholder_info.fromAscii.2": "ɹǝʇɔɐɹɐɥɔ ɐ >- }>ǝpoɔ‾ɹɐɥɔ< ııɔsⱯɯoɹɟ{ ", + "gtceu.placeholder_info.if.0": "˙0 oʇ ןɐnbǝ ʇou sı puɐ buıɹʇs ʎʇdɯǝ uɐ ʇou sı ʇı ɟı ǝnɹʇ pǝɹǝpısuoɔ sı uoıʇıpuoɔ ǝɥ⟘ ˙uoıʇıpuoɔ ǝɥʇ uo buıpuǝdǝp sʇuǝɯnbɹɐ ǝɥʇ ɟo ǝuo suɹnʇǝᴚ", + "gtceu.placeholder_info.if.1": ":ǝbɐs∩", + "gtceu.placeholder_info.if.2": "}]ǝsןɐɟ‾ɟı‾pǝuɹnʇǝɹ[ >ǝnɹʇ‾ɟı‾pǝuɹnʇǝɹ< >uoıʇıpuoɔ< ɟı{ ", + "gtceu.placeholder_info.itemCount.0": "˙)pǝɹǝʇןıɟ ǝq uɐɔ( sɯǝʇı ɟo ʇunoɯɐ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.itemCount.1": ":ǝbɐs∩", + "gtceu.placeholder_info.itemCount.2": "ʇunoɯɐ ɯǝʇı ןɐʇoʇ >- }ʇunoƆɯǝʇı{ ", + "gtceu.placeholder_info.itemCount.3": "pı‾ɯǝʇı oʇ ןɐnbǝ spı ɥʇıʍ sɯǝʇı ɟo ʇunoɯɐ >- }>pı‾ɯǝʇı< ʇunoƆɯǝʇı{ ", + "gtceu.placeholder_info.itemCount.4": "ɹǝʌoɔ sıɥʇ ɟo ʇoןs pǝıɟıɔǝds uı ɹǝʇןıɟ buıɥɔʇɐɯ sɯǝʇı ɟo ʇunoɯɐ >- }>pı‾ʇoןs< ɹǝʇןıɟ ʇunoƆɯǝʇı{ ", + "gtceu.placeholder_info.maintenance.0": "˙ǝsıʍɹǝɥʇo 0 'oʇ pǝɥɔɐʇʇɐ sı ɹǝʌoɔ ǝɥʇ ʞɔoןq ǝɥʇ uı sɯǝןqoɹd ǝɔuɐuǝʇuıɐɯ ǝɹɐ ǝɹǝɥʇ ɟı Ɩ ɐ suɹnʇǝᴚ", + "gtceu.placeholder_info.maintenance.1": ",}ʞO ᗡƎᴚI∩ὉƎᴚ \\⅁NIXIℲ }ǝɔuɐuǝʇuıɐɯ{ ɟı{ :snʇɐʇs ǝɔuɐuǝʇuıɐW, :ǝןdɯɐxƎ", + "gtceu.placeholder_info.maintenance.2": ":ǝbɐs∩", + "gtceu.placeholder_info.maintenance.3": "sɯǝןqoɹd ǝɔuɐuǝʇuıɐɯ ǝɹɐ ǝɹǝɥʇ ɹǝɥʇǝɥʍ >- }ǝɔuɐuǝʇuıɐɯ{ ", + "gtceu.placeholder_info.maxProgress.0": "˙oʇ pǝɥɔɐʇʇɐ sı ɹǝʌoɔ sıɥʇ ʞɔoןq ǝɥʇ ɟo ǝdıɔǝɹ buıuunɹ ʎןʇuǝɹɹnɔ ǝɥʇ ɟo ssǝɹboɹd ɯnɯıxɐɯ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.maxProgress.1": ",%}00Ɩ * }}ssǝɹboɹԀxɐɯ{ / }ssǝɹboɹd{ ɔןɐɔ{ ɔןɐɔ{ :ssǝɹboɹԀ, :ǝןdɯɐxƎ", + "gtceu.placeholder_info.maxProgress.2": ":ǝbɐs∩", + "gtceu.placeholder_info.maxProgress.3": "ǝdıɔǝɹ buıuunɹ ʎןʇuǝɹɹnɔ ǝɥʇ ɟo ssǝɹboɹd xɐɯ ǝɥʇ >- }ssǝɹboɹԀxɐɯ{ ", + "gtceu.placeholder_info.nbt.0": "ʇoןs pǝıɟıɔǝds ǝɥʇ uı ɯǝʇı ǝɥʇ ɟo ɐʇɐp ʇqu ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.nbt.1": ":ǝbɐs∩", + "gtceu.placeholder_info.nbt.2": "]˙˙˙[]Ɛʎǝʞ[]ᄅʎǝʞ[]Ɩʎǝʞ[ʇqu‾ɯǝʇı >- }˙˙˙ ]Ɛʎǝʞ[ ]ᄅʎǝʞ[ ]Ɩʎǝʞ[ >ʇoןs< ʇqu{ ", + "gtceu.placeholder_info.obf.0": "˙pǝʇɐɔsnɟqo 'ʇuǝɯnbɹɐ ʇsɹıɟ ǝɥʇ ɯoɹɟ ʇxǝʇ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.obf.1": ":ǝbɐs∩", + "gtceu.placeholder_info.obf.2": "ʇxǝʇ pǝʇɐɔsnɟqo >- }>ʇxǝʇ< ɟqo{ ", + "gtceu.placeholder_info.previousText.0": "˙)buıddɐɹʍ-ǝuıן ǝɹoɟǝq( ǝuıן pǝıɟıɔǝds ǝɥʇ ʇɐ ɹǝʌoɔ sıɥʇ ʎq pǝʎɐןdsıp ʎןsnoıʌǝɹd sɐʍ ʇɐɥʇ ʇxǝʇ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.previousText.1": ":ǝbɐs∩", + "gtceu.placeholder_info.previousText.2": ")Ɩ ʇɐ sʇɹɐʇs xǝpuı( ǝuıן pǝıɟıɔǝds ǝɥʇ uo pǝʎɐןdsıp ʎןsnoıʌǝɹd ʇxǝʇ ǝɥʇ >- }>ǝuıן< ʇxǝ⟘snoıʌǝɹd{ ", + "gtceu.placeholder_info.progress.0": "˙oʇ pǝɥɔɐʇʇɐ sı ɹǝʌoɔ sıɥʇ ʞɔoןq ǝɥʇ ɟo ǝdıɔǝɹ buıuunɹ ʎןʇuǝɹɹnɔ ǝɥʇ ɟo ssǝɹboɹd ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.progress.1": "}ssǝɹboɹԀxɐɯ{ puɐ 0 uǝǝʍʇǝq ɹǝbǝʇuı uɐ sı ssǝɹboɹd ʇɐɥʇ ǝʇoN", + "gtceu.placeholder_info.progress.2": ":ǝbɐs∩", + "gtceu.placeholder_info.progress.3": "ǝdıɔǝɹ buıuunɹ ʎןʇuǝɹɹnɔ ǝɥʇ ɟo ssǝɹboɹd ǝɥʇ >- }ssǝɹboɹd{ ", + "gtceu.placeholder_info.random.0": "˙)ǝʌısnןɔuı( ןɐʌɹǝʇuı pǝıɟıɔǝds ǝɥʇ uı ɹǝqɯnu ɯopuɐɹ ɐ suɹnʇǝᴚ", + "gtceu.placeholder_info.random.1": ":ǝbɐs∩", + "gtceu.placeholder_info.random.2": ")ǝʌısnןɔuı( xɐɯ puɐ uıɯ uǝǝʍʇǝq ɹǝqɯnu ɯopuɐɹ ɐ >- }>xɐɯ< >uıɯ< ɯopuɐɹ{ ", + "gtceu.placeholder_info.redstone.0": "ɥʇbuǝɹʇs ʇndʇno ǝuoʇspǝɹ ǝɥʇ sʇǝs ɹo ɥʇbuǝɹʇs ןɐubıs ǝuoʇspǝɹ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.redstone.1": ":ǝbɐs∩", + "gtceu.placeholder_info.redstone.2": "ǝpıs pǝıɟıɔǝds ǝɥʇ ʇɐ )ϛƖ-0( ɥʇbuǝɹʇs ןɐubıs ǝuoʇspǝɹ >- }>ʇsǝʍ|ʇsɐǝ|ɥʇnos|ɥʇɹou|uʍop|dn< ʇǝb ǝuoʇspǝɹ{ ", + "gtceu.placeholder_info.redstone.3": ")9-0 'ʇɥbıɹ oʇ ʇɟǝן ɯoɹɟ( ɹǝןןoɹʇuoɔ ǝɥʇ ǝpısuı ʎɔuǝnbǝɹɟ ǝɥʇ ɟo xǝpuı ǝɥʇ sı xǝpuı‾ʇoןs‾bǝɹɟ ˙xǝpuı‾ʇoןs# ʇoןs uı ɹǝןןoɹʇuoɔ pǝʞuıן ɐ ʎq pǝıɟıɔǝds ʎɔuǝnbǝɹɟ ʞuıן ǝuoʇspǝɹ ǝʇɐǝɹƆ ɐ ɟo ɥʇbuǝɹʇs ןɐubıs ǝuoʇspǝɹ >- }>xǝpuı‾ʇoןs‾bǝɹɟ< >xǝpuı‾ʇoןs< ʞuıן ʇǝb ǝuoʇspǝɹ{ ", + "gtceu.placeholder_info.redstone.4": "ǝpıs s,ɹǝʌoɔ sıɥʇ ɯoɹɟ ɥʇbuǝɹʇs ʇndʇno ǝuoʇspǝɹ ǝɥʇ sʇǝs 'buıɹʇs ʎʇdɯǝ >- }>ɹǝʍod< ʇǝs ǝuoʇspǝɹ{ ", + "gtceu.placeholder_info.redstone.5": "ʎɔuǝnbǝɹɟ ʞuıן ǝuoʇspǝɹ ǝʇɐǝɹƆ pǝıɟıɔǝds ǝɥʇ uo ɹǝʍod ǝuoʇspǝɹ pǝıɟıɔǝds ǝɥʇ sʇsɐɔpɐoɹq 'buıɹʇs ʎʇdɯǝ >- }>ɹǝʍod< >xǝpuı‾ʇoןs‾bǝɹɟ< >xǝpuı‾ʇoןs< ʞuıן ʇǝs ǝuoʇspǝɹ{ ", + "gtceu.placeholder_info.repeat.0": "˙ʇuǝɯnbɹɐ ʇsɹıɟ ǝɥʇ uı pǝıɟıɔǝds sǝɯıʇ ɟo ʇunoɯɐ ǝɥʇ pǝʇɐǝdǝɹ 'sʇuǝɯnbɹɐ puoɔǝs ǝɥʇ ɯoɹɟ ʇxǝʇ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.repeat.1": ":ǝbɐs∩", + "gtceu.placeholder_info.repeat.2": "sǝɯıʇ ɟo ʇunoɯɐ pǝıɟıɔǝds ǝɥʇ pǝʇɐǝdǝɹ ʇxǝʇ >- }>ʇxǝʇ< >ʇunoɯɐ< ʇɐǝdǝɹ{ ", + "gtceu.placeholder_info.select.0": ")0 ɯoɹɟ buıʇɹɐʇs( xǝpuı pǝıɟıɔǝds ǝɥʇ ʇɐ ʇuǝɯnbɹɐ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.select.1": ":ǝbɐs∩", + "gtceu.placeholder_info.select.2": "xǝpuı pǝıɟıɔǝds ǝɥʇ ʇɐ ʇuǝɯnbɹɐ >- ˙˙˙ ]Ɛbɹɐ[ ]ᄅbɹɐ[ ]Ɩbɹɐ[ >xǝpuı< ʇɔǝןǝs{ ", + "gtceu.placeholder_info.strike.0": "ʇno pǝssoɹɔ sɐʍ ʇı ɟı sɐ ʇı buıʎɐןdsıp 'ʇxǝʇ ʇsɹıɟ ǝɥʇ ɯoɹɟ ʇxǝʇ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.strike.1": ":ǝbɐs∩", + "gtceu.placeholder_info.strike.2": "ʇxǝʇ ʇno-pǝssoɹɔ >- }>ʇxǝʇ< ǝʞıɹʇs{ ", + "gtceu.placeholder_info.subList.0": ")0 ɯoɹɟ buıʇɹɐʇs( )ǝʌısnןɔxǝ( ɹ oʇ )ǝʌısnןɔuı( ן ɯoɹɟ sǝxǝpuı ɥʇıʍ ɯoɹɟ sʇuǝɯnbɹɐ suɹnʇǝᴚ", + "gtceu.placeholder_info.subList.1": ":ǝbɐs∩", + "gtceu.placeholder_info.subList.2": "sǝɔɐds ʎq pǝʇɐɹɐdǝs ɹ oʇ ן ɯoɹɟ sǝxǝpuı ɥʇıʍ sʇuǝɯnbɹɐ ןןɐ >- }˙˙˙ ]Ɩbɹɐ[ ]0bɹɐ[ >ʇɥbıɹ< >ʇɟǝן< ʇsıꞀqns{ ", + "gtceu.placeholder_info.tick.0": "˙pǝɔɐןd sɐʍ ɹǝʌoɔ sıɥʇ uǝɥʍ ɯoɹɟ pǝssɐd sʞɔıʇ ɟo ʇunoɯɐ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.tick.1": ":ǝbɐs∩", + "gtceu.placeholder_info.tick.2": "sʞɔıʇ ɟo ʇunoɯɐ ǝɥʇ >- }ʞɔıʇ{ ", + "gtceu.placeholder_info.tm.0": "ןoqɯʎs ™ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.tm.1": ":ǝbɐs∩", + "gtceu.placeholder_info.tm.2": "ןoqɯʎs ™ ǝɥʇ >- }ɯʇ{ ", + "gtceu.placeholder_info.toAscii.0": "ɹǝʇɔɐɹɐɥɔ pǝpıʌoɹd ǝɥʇ ɟo ǝpoɔ IIƆSⱯ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.toAscii.1": ":ǝbɐs∩", + "gtceu.placeholder_info.toAscii.2": "ɹǝʇɔɐɹɐɥɔ ǝɥʇ ɟo ǝpoɔ IIƆSⱯ >- }>ɹǝʇɔɐɹɐɥɔ< ııɔsⱯoʇ{ ", + "gtceu.placeholder_info.toChars.0": "ɯǝɥʇ uǝǝʍʇǝq sǝɔɐds ɥʇıʍ buıɹʇs pǝpıʌoɹd ǝɥʇ ɟo sɹǝʇɔɐɹɐɥɔ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.toChars.1": ",ǝ ן d ɯ ɐ x ǝ, >- }ǝןdɯɐxǝ sɹɐɥƆoʇ{ :ǝןdɯɐxƎ", + "gtceu.placeholder_info.toChars.2": ":ǝbɐs∩", + "gtceu.placeholder_info.toChars.3": "sɹǝʇɔɐɹɐɥɔ >- }>bɹɐ< sɹɐɥƆoʇ{ ", + "gtceu.placeholder_info.underline.0": "pǝuıןɹǝpun 'ʇuǝɯnbɹɐ ʇsɹıɟ ǝɥʇ ɯoɹɟ ʇxǝʇ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.underline.1": ":ǝbɐs∩", + "gtceu.placeholder_info.underline.2": "ʇxǝʇ pǝuıןɹǝpun >- }>ʇxǝʇ< ǝuıןɹǝpun{ ", + "gtceu.placeholder_info.voltage.0": "˙uo sı ɹǝʌoɔ ǝɥʇ ǝןqɐɔ/ǝɹıʍ ǝɥʇ uı ǝbɐʇןoʌ ǝɥʇ suɹnʇǝᴚ", + "gtceu.placeholder_info.voltage.1": ":ǝbɐs∩", + "gtceu.placeholder_info.voltage.2": "ǝןqɐɔ/ǝɹıʍ ǝɥʇ uı ǝbɐʇןoʌ ǝɥʇ >- }ǝbɐʇןoʌ{ ", + "gtceu.recipe.byproduct_tier": "+ɹ§%s ɯoɹɟ sʇɔnpoɹdʎᗺ", + "gtceu.recipe.category.arc_furnace_recycling": "buıddɐɹɔS ɔɹⱯ", + "gtceu.recipe.category.chem_dyes": "buıǝʎᗡ ןɐɔıɯǝɥƆ", + "gtceu.recipe.category.extractor_recycling": "buıʇןǝɯǝᴚ dɐɹɔS", + "gtceu.recipe.category.ingot_molding": "buıpןoW ןɐʇǝW", + "gtceu.recipe.category.macerator_recycling": "buıpuıɹ⅁ ʇɹɐԀ", + "gtceu.recipe.category.ore_bathing": "buıʇɐǝɹ⟘ ǝɹO", + "gtceu.recipe.category.ore_crushing": "buıpuıɹ⅁ ǝɹO", + "gtceu.recipe.category.ore_forging": "buıɥsnɹƆ ǝɹO", "gtceu.recipe.chance": "ɹǝıʇ/%s+ %s :ǝɔuɐɥƆ", "gtceu.recipe.cleanroom": "%s sǝɹınbǝᴚ", "gtceu.recipe.cleanroom.display_name": "ɯooɹuɐǝןƆ", @@ -3424,9 +3732,14 @@ "gtceu.tool_action.wire_cutter.connect": "suoıʇɔǝuuoƆ ʇǝs oʇ sɹǝʇʇnƆ ǝɹıM ǝs∩8§", "gtceu.tool_action.wrench.connect": "suoıʇɔǝuuoƆ ʞɔoןq oʇ ʞɐǝus 'suoıʇɔǝuuoƆ ʇǝs oʇ ɥɔuǝɹM ǝs∩8§", "gtceu.tool_action.wrench.set_facing": "buıɔɐℲ ʇǝs oʇ ɥɔuǝɹM ǝs∩8§", + "gtceu.tooltip.computer_monitor_config": "ɐʇɐp uoıʇɐɹnbıɟuoɔ ɹǝʌoɔ ɹoʇıuoɯ ɹǝʇndɯoɔ buıɹoʇS", + "gtceu.tooltip.computer_monitor_data": "%s :ɐʇɐp buıɹoʇS", "gtceu.tooltip.fluid_pipe_hold_shift": "oɟuI ʇuǝɯuıɐʇuoƆ pınןℲ ʍoɥs oʇ ⟘ℲIHS pןoHㄥ§", "gtceu.tooltip.hold_ctrl": "oɟuı ǝɹoɯ ɹoɟ Ꞁᴚ⟘Ɔ pןoHㄥ§", "gtceu.tooltip.hold_shift": "oɟuı ǝɹoɯ ɹoɟ ⟘ℲIHS pןoHㄥ§", + "gtceu.tooltip.player_bind": "%s :ɹǝʎɐןd oʇ punoᗺ", + "gtceu.tooltip.player_name.placeholder_processor": "ɹossǝɔoɹd ɹǝpןoɥǝɔɐןԀ", + "gtceu.tooltip.player_name.unknown": "ɹǝʎɐןd uʍouʞu∩", "gtceu.tooltip.potion.each": "ɹ§buıuǝddɐɥ ɟo ǝɔuɐɥɔㄥ§ %s%% ɹ§ɐ ɥʇıʍ sʞɔıʇㄥ§ %s ɹ§ɹoɟㄥ§ %s %s", "gtceu.tooltip.potion.header": ":sʇɔǝɟɟǝ suıɐʇuoƆ9§", "gtceu.tooltip.proxy_bind": "%s %s %s ʇɐ ɹǝɟɟnᗺ uɹǝʇʇɐԀ ɐ oʇ buıpuıᗺɟ§", @@ -3434,6 +3747,7 @@ "gtceu.tooltip.status.trinary.true": "ǝnɹ⟘", "gtceu.tooltip.status.trinary.unknown": "uʍouʞu∩", "gtceu.tooltip.tool_fluid_hold_shift": "oɟuI ןoo⟘ puɐ ʇuǝɯuıɐʇuoƆ pınןℲ ʍoɥs oʇ ⟘ℲIHS pןoHㄥ§", + "gtceu.tooltip.wireless_transmitter_bind": "%s uı %s buıɔɐɟ %s %s %s ʇɐ ɹǝʌoɔ ɹǝʇʇıɯsuɐɹʇ ɐ oʇ buıpuıᗺ", "gtceu.top.allow_output_input": "ʇnduI ʍoןןⱯ", "gtceu.top.auto_output": "ʇndʇnO oʇnⱯ", "gtceu.top.buffer_bound_pos": "%s :Z '%s :ʎ '%s :X - o⟘ punoᗺ", @@ -3485,6 +3799,10 @@ "gtceu.universal.clear_nbt_recipe.tooltip": "¡sʇuǝʇuoɔ ןןɐ ʎoɹʇsǝp ןןıʍ sıɥ⟘ɔ§", "gtceu.universal.kiloliters": "ᗺ %s", "gtceu.universal.liters": "ᗺɯ %s", + "gtceu.universal.padded_parentheses": " )%s( ", + "gtceu.universal.padded_spaced_parentheses": " ) %s ( ", + "gtceu.universal.parentheses": ")%s(", + "gtceu.universal.spaced_parentheses": ") %s (", "gtceu.universal.tooltip.amperage_in": "Ɐ%dɟ§ :NI ǝbɐɹǝdɯⱯǝ§", "gtceu.universal.tooltip.amperage_in_out": "Ɐ%dɟ§ :⟘∩O/NI ǝbɐɹǝdɯⱯǝ§", "gtceu.universal.tooltip.amperage_in_out_till": "Ɐ%dɟ§ :oʇ dn ⟘∩O/NI ǝbɐɹǝdɯⱯǝ§", @@ -3709,6 +4027,8 @@ "item.gtceu.empty_wooden_form": "ɯɹoℲ uǝpooM ʎʇdɯƎ", "item.gtceu.ender_fluid_link_cover": "ʞuıꞀ pınןℲ ɹǝpuƎ", "item.gtceu.ender_fluid_link_cover.tooltip": "˙ㄥ§ɹǝʌoƆɟ§ sɐ ㄥ§uoıʇɔǝuuoƆ ɟ§ɹǝpuƎp§ ssǝןǝɹıMɟ§ ɐ ɥʇıʍ ㄥ§spınןℲɟ§ sʇɹodsuɐɹ⟘ㄥ§", + "item.gtceu.ender_item_link_cover": "ʞuıꞀ ɯǝʇI ɹǝpuƎ", + "item.gtceu.ender_redstone_link_cover": "ʞuıꞀ ǝuoʇspǝᴚ ɹǝpuƎ", "item.gtceu.energium_dust": "ʇsnᗡ ɯnıbɹǝuƎ", "item.gtceu.energy_cluster": "ɹǝʇsnןƆ ʎbɹǝuƎ", "item.gtceu.energy_cluster.tooltip": "ʎɹǝʇʇɐᗺ ǝןqɐsnǝᴚㄥ§", @@ -3745,7 +4065,7 @@ "item.gtceu.exquisite_glass_gem": "ןɐʇsʎɹƆ ssɐן⅁ ǝʇısınbxƎ", "item.gtceu.facade_cover": "ǝpɐɔɐℲ ɹǝʌoƆ %s", "item.gtceu.facade_cover.tooltip.0": "˙ㄥ§ɹǝʌoƆɟ§ ʇıɟʇnO ǝʌıʇɐɹoɔǝᗡㄥ§", - "item.gtceu.facade_cover.tooltip.1": "ʞɔoןq ʎuɐ puɐ sǝʇɐןԀ uoɹI Ɛ buısn pǝʇɟɐɹƆㄥ§", + "item.gtceu.facade_cover.tooltip.1": "ʞɔoןq ʎuɐ puɐ ǝʇɐןԀ uoɹI uɐ buısn pǝʇɟɐɹƆㄥ§", "item.gtceu.face_mask": "ʞsɐW ǝɔɐℲ", "item.gtceu.fertilizer": "ɹǝzıןıʇɹǝℲ", "item.gtceu.fiber_reinforced_circuit_board": "pɹɐoᗺ ʇınɔɹıƆ pǝɔɹoɟuıǝᴚ-ɹǝqıℲ", @@ -3820,6 +4140,7 @@ "item.gtceu.hpic_chip.tooltip": "ƆI ɹǝʍoԀ ɥbıHㄥ§", "item.gtceu.hpic_wafer": "ɹǝɟɐM ƆIԀH", "item.gtceu.hpic_wafer.tooltip": "ʇınɔɹıƆ ɹǝʍoԀ ɥbıH ʍɐᴚㄥ§", + "item.gtceu.huge_pipe_casting_mold": ")ǝdıԀ ǝbnH( pןoW buıʇsɐƆ", "item.gtceu.huge_pipe_extruder_mold": ")ǝdıԀ ǝbnH( pןoW ɹǝpnɹʇxƎ", "item.gtceu.hv_battery_hull": "ןןnH ʎɹǝʇʇɐᗺ ǝbɹɐꞀ", "item.gtceu.hv_battery_hull.tooltip": "ןןnH ʎɹǝʇʇɐᗺㄥ§ ΛH9§ ʎʇdɯǝ uⱯㄥ§", @@ -3848,6 +4169,7 @@ "item.gtceu.ilc_chip.tooltip": "ʇınɔɹıƆ ɔıboꞀ pǝʇɐɹbǝʇuIㄥ§", "item.gtceu.ilc_wafer": "ɹǝɟɐM ƆꞀI", "item.gtceu.ilc_wafer.tooltip": "ʇınɔɹıƆ pǝʇɐɹbǝʇuI ʍɐᴚㄥ§", + "item.gtceu.image_module": "ǝןnpoW ǝbɐɯI", "item.gtceu.impure_bentonite_dust": "ǝʇıuoʇuǝᗺ ɟo ǝןıԀ ǝɹndɯI", "item.gtceu.impure_cassiterite_sand_dust": "puɐS ǝʇıɹǝʇıssɐƆ ɟo ǝןıԀ ǝɹndɯI", "item.gtceu.impure_pitchblende_dust": "ǝpuǝןqɥɔʇıԀ ɟo ǝןıԀ ǝɹndɯI", @@ -3900,6 +4222,7 @@ "item.gtceu.lapotronic_energy_orb.tooltip": "ʎɹǝʇʇɐᗺ ǝןqɐsnǝᴚㄥ§", "item.gtceu.lapotronic_energy_orb_cluster": "ɹǝʇsnןƆ qɹO ʎbɹǝuƎ ɔıuoɹʇodɐꞀ", "item.gtceu.lapotronic_energy_orb_cluster.tooltip": "ʎɹǝʇʇɐᗺ ǝןqɐsnǝᴚㄥ§", + "item.gtceu.large_pipe_casting_mold": ")ǝdıԀ ǝbɹɐꞀ( pןoW buıʇsɐƆ", "item.gtceu.large_pipe_extruder_mold": ")ǝdıԀ ǝbɹɐꞀ( pןoW ɹǝpnɹʇxƎ", "item.gtceu.light_blue_dye_spray_can": ")ǝnןᗺ ʇɥbıꞀ( uɐƆ ʎɐɹdS", "item.gtceu.light_blue_glass_lens": ")ǝnןᗺ ʇɥbıꞀ( suǝꞀ ssɐן⅁", @@ -4059,6 +4382,7 @@ "item.gtceu.nor_memory_chip.tooltip": "ǝʇɐ⅁ ɔıboꞀ ᴚONㄥ§", "item.gtceu.nor_memory_wafer": "ɹǝɟɐM ʎɹoɯǝW ᴚON", "item.gtceu.nor_memory_wafer.tooltip": "ǝʇɐ⅁ ɔıboꞀ ʍɐᴚㄥ§", + "item.gtceu.normal_pipe_casting_mold": ")ǝdıԀ ןɐɯɹoN( pןoW buıʇsɐƆ", "item.gtceu.normal_pipe_extruder_mold": ")ǝdıԀ ןɐɯɹoN( pןoW ɹǝpnɹʇxƎ", "item.gtceu.nugget_casting_mold": ")ʇǝbbnN( pןoW buıʇsɐƆ", "item.gtceu.nugget_casting_mold.tooltip": "sʇǝbbnN buıʞɐɯ ɹoɟ pןoWㄥ§", @@ -4229,6 +4553,7 @@ "item.gtceu.small_meat_dust": "ʇɐǝW ǝɔuıW ɟo ǝןıԀ ןןɐɯS", "item.gtceu.small_palladium_raw_dust": "ɹǝpʍoԀ ɯnıpɐןןɐԀ ʍɐᴚ ɟo ǝןıԀ ןןɐɯS", "item.gtceu.small_paper_dust": "pɐɥƆ ɟo ǝןıԀ ןןɐɯS", + "item.gtceu.small_pipe_casting_mold": ")ǝdıԀ ןןɐɯS( pןoW buıʇsɐƆ", "item.gtceu.small_pipe_extruder_mold": ")ǝdıԀ ןןɐɯS( pןoW ɹǝpnɹʇxƎ", "item.gtceu.small_pitchblende_dust": "ǝpuǝןqɥɔʇıԀ ɟo ǝןıԀ ןןɐɯS", "item.gtceu.small_platinum_group_sludge_dust": "ǝbpnןS dnoɹ⅁ ɯnuıʇɐןԀ ɟo dɯnןƆ ןןɐɯS", @@ -4282,6 +4607,7 @@ "item.gtceu.tantalum_capacitor": "ɹoʇıɔɐdɐƆ ɯnןɐʇuɐ⟘", "item.gtceu.terminal": "ןɐuıɯɹǝ⟘", "item.gtceu.terminal.tooltip": "ʞɔoןqıʇןnɯ ǝɥʇ pןınq ʎןןɐɔıʇɐɯoʇnɐ oʇ ɹǝןןoɹʇuoɔ ɐ uo ʞɔıןƆ-ᴚ + ʇɟıɥS", + "item.gtceu.text_module": "ǝןnpoW ʇxǝ⟘", "item.gtceu.tiny_ash_dust": "sǝɥsⱯ ɟo ǝןıԀ ʎuı⟘", "item.gtceu.tiny_basaltic_mineral_sand_dust": "puɐS ןɐɹǝuıW ɔıʇןɐsɐᗺ ɟo ǝןıԀ ʎuı⟘", "item.gtceu.tiny_bentonite_dust": "ǝʇıuoʇuǝᗺ ɟo ǝןıԀ ʎuı⟘", @@ -4300,6 +4626,7 @@ "item.gtceu.tiny_meat_dust": "ʇɐǝW ǝɔuıW ɟo ǝןıԀ ʎuı⟘", "item.gtceu.tiny_palladium_raw_dust": "ɹǝpʍoԀ ɯnıpɐןןɐԀ ʍɐᴚ ɟo ǝןıԀ ʎuı⟘", "item.gtceu.tiny_paper_dust": "pɐɥƆ ɟo ǝןıԀ ʎuı⟘", + "item.gtceu.tiny_pipe_casting_mold": ")ǝdıԀ ʎuı⟘( pןoW buıʇsɐƆ", "item.gtceu.tiny_pipe_extruder_mold": ")ǝdıԀ ʎuı⟘( pןoW ɹǝpnɹʇxƎ", "item.gtceu.tiny_pitchblende_dust": "ǝpuǝןqɥɔʇıԀ ɟo ǝןıԀ ʎuı⟘", "item.gtceu.tiny_platinum_group_sludge_dust": "ǝbpnןS dnoɹ⅁ ɯnuıʇɐןԀ ɟo dɯnןƆ ʎuı⟘", @@ -4324,9 +4651,15 @@ "item.gtceu.tool.behavior.block_rotation": "sʞɔoןᗺ sǝʇɐʇoᴚɟ§ :ɔıuɐɥɔǝWᄅ§", "item.gtceu.tool.behavior.crop_harvesting": "sdoɹƆ sʇsǝʌɹɐHɟ§ :ɹǝʇsǝʌɹɐHɐ§", "item.gtceu.tool.behavior.damage_boost": "%s ʇsuıɐbɐ ǝbɐɯɐp ɐɹʇxƎɟ§ :ʇsooᗺ ǝbɐɯɐᗡㄣ§", + "item.gtceu.tool.behavior.dowse_campfire": "sǝɹıɟdɯɐƆ sǝsʍoᗡɟ§ :ɹǝʇɥbıɟǝɹıℲƖ§", "item.gtceu.tool.behavior.grass_path": "sɥʇɐԀ ssɐɹ⅁ sǝʇɐǝɹƆɟ§ :ɹǝdɐɔspuɐꞀǝ§", "item.gtceu.tool.behavior.ground_tilling": "punoɹ⅁ sןןı⟘ɟ§ :ɹǝɯɹɐℲǝ§", "item.gtceu.tool.behavior.plunger": "spınןℲ suıɐɹᗡɟ§ :ɹǝqɯnןԀ6§", + "item.gtceu.tool.behavior.prospecting.air": "ʇǝʞɔod ɹıɐ uɐ punoℲ", + "item.gtceu.tool.behavior.prospecting.changing": "ǝbuɐɥɔ ןɐıɹǝʇɐɯ pǝʇɔǝʇǝᗡ", + "item.gtceu.tool.behavior.prospecting.lava": "ɐʌɐן punoℲ", + "item.gtceu.tool.behavior.prospecting.ore": "%s :ǝɹo punoℲ", + "item.gtceu.tool.behavior.prospecting.water": "ɹǝʇɐʍ punoℲ", "item.gtceu.tool.behavior.rail_rotation": "sןıɐᴚ sǝʇɐʇoᴚɟ§ :ɹǝǝuıbuƎ pɐoɹןıɐᴚǝ§", "item.gtceu.tool.behavior.relocate_mining": "sdoɹᗡ qoW puɐ sʞɔoןᗺ pǝuıW sǝʇɐɔoןǝᴚɟ§ :ɔıʇǝubɐWᄅ§", "item.gtceu.tool.behavior.remove_wax": "xɐM sǝʌoɯǝᴚɟ§ :ɹǝuɐǝןƆ9§", @@ -4514,6 +4847,7 @@ "item.gtceu.white_dye_spray_can": ")ǝʇıɥM( uɐƆ ʎɐɹdS", "item.gtceu.wire_extruder_mold": ")ǝɹıM( pןoW ɹǝpnɹʇxƎ", "item.gtceu.wire_extruder_mold.tooltip": "sǝɹıM buıʞɐɯ ɹoɟ ǝdɐɥS ɹǝpnɹʇxƎㄥ§", + "item.gtceu.wireless_transmitter_cover": "ɹǝʇʇıɯsuɐɹ⟘ ssǝןǝɹıM", "item.gtceu.wood_bolt": "ʞɔıʇS pooM ʇɹoɥS", "item.gtceu.wood_dust": "dןnԀ pooM", "item.gtceu.wood_plate": "ʞuɐןԀ pooM", @@ -5352,6 +5686,7 @@ "recipe.capability.fluid.name": "pınןℲ", "recipe.capability.item.name": "ɯǝʇI", "recipe.condition.adjacent_block.tooltip": "punoɹɐ sʞɔoןᗺ", + "recipe.condition.adjacent_fluid.tooltip": "punoɹɐ sʞɔoןq pınןℲ", "recipe.condition.biome.tooltip": "%s :ǝɯoıᗺ", "recipe.condition.daytime.day.tooltip": "ʞɹoʍ oʇ ǝɯıʇ ʎɐp sǝɹınbǝᴚ", "recipe.condition.daytime.night.tooltip": "ʞɹoʍ oʇ ǝɯıʇ ʇɥbıu sǝɹınbǝᴚ", @@ -5364,17 +5699,8 @@ "recipe.condition.quest.completed.tooltip": "pǝʇǝןdɯoɔ %s sǝɹınbǝᴚ", "recipe.condition.quest.not_completed.tooltip": "pǝʇǝןdɯoɔ ʇou %s sǝɹınbǝᴚ", "recipe.condition.rain.tooltip": "%d :ןǝʌǝꞀ uıɐᴚ", - "recipe.condition.rock_breaker.tooltip": "punoɹɐ sʞɔoןq pınןℲ", "recipe.condition.steam_vent.tooltip": "ʇuǝʌ ɯɐǝʇs uɐǝןƆ", "recipe.condition.thunder.tooltip": "%d :ןǝʌǝꞀ ɹǝpunɥ⟘", - "recipe_category.gtceu.arc_furnace_recycling": "buıddɐɹɔS ɐɯsɐןԀ", - "recipe_category.gtceu.chem_dyes": "buıǝʎᗡ ןɐɔıɯǝɥƆ", - "recipe_category.gtceu.extractor_recycling": "buıʇןǝɯǝᴚ dɐɹɔS", - "recipe_category.gtceu.ingot_molding": "buıpןoW ןɐʇǝW", - "recipe_category.gtceu.macerator_recycling": "buıpuıɹ⅁ ʇɹɐԀ", - "recipe_category.gtceu.ore_bathing": "buıʇɐǝɹ⟘ ǝɹO", - "recipe_category.gtceu.ore_crushing": "buıpuıɹ⅁ ǝɹO", - "recipe_category.gtceu.ore_forging": "buıɥsnɹƆ ǝɹO", "recipe_type.gtceu.air_scrubber": "ɹǝqqnɹɔS ɹıⱯ", "recipe_type.gtceu.alloy_blast_smelter": "ɹǝʇןǝɯS ʇsɐןᗺ ʎoןןⱯ", "recipe_type.gtceu.alloy_smelter": "ɹǝʇןǝɯS ʎoןןⱯ", diff --git a/src/generated/resources/assets/gtceu/lang/en_us.json b/src/generated/resources/assets/gtceu/lang/en_us.json index 81224833c88..9f783c57464 100644 --- a/src/generated/resources/assets/gtceu/lang/en_us.json +++ b/src/generated/resources/assets/gtceu/lang/en_us.json @@ -101,13 +101,14 @@ "behaviour.setting.output.direction.tooltip": "%s output direction: %s", "behaviour.soft_hammer": "Activates and Deactivates Machines", "behaviour.soft_hammer.disabled": "Working Disabled", + "behaviour.soft_hammer.disabled_cycle": "Working Disabled after current cycle", "behaviour.soft_hammer.enabled": "Working Enabled", - "behaviour.soft_hammer.idle_after_cycle": "Pause machine after current cycle", "behaviour.wrench": "Rotates Blocks on Rightclick", "block.gtceu.acid_hazard_sign_block": "Acid Hazard Sign Block", "block.gtceu.active_transformer": "Active Transformer", "block.gtceu.advanced_computer_casing": "Advanced Computer Casing", "block.gtceu.advanced_data_access_hatch": "Advanced Data Access Hatch", + "block.gtceu.advanced_monitor": "Advanced Monitor", "block.gtceu.alloy_blast_smelter": "Alloy Blast Smelter", "block.gtceu.aluminium_crate": "Aluminium Crate", "block.gtceu.aluminium_drum": "Aluminium Drum", @@ -118,6 +119,7 @@ "block.gtceu.assembly_line_unit": "Assembly Control Casing", "block.gtceu.atomic_casing": "Atomic Casing", "block.gtceu.auto_maintenance_hatch": "Auto Maintenance Hatch", + "block.gtceu.basic_data_access_hatch": "Basic Data Access Hatch", "block.gtceu.bio_hazard_sign_block": "Bio Hazard Sign Block", "block.gtceu.black_borderless_lamp": "Black Borderless Lamp", "block.gtceu.black_lamp": "Black Lamp", @@ -138,7 +140,9 @@ "block.gtceu.bronze_gearbox": "Bronze Gearbox Casing", "block.gtceu.bronze_large_boiler": "Large Bronze Boiler", "block.gtceu.bronze_machine_casing": "Bronze Machine Casing", + "block.gtceu.bronze_multiblock_tank": "Bronze Multiblock Tank", "block.gtceu.bronze_pipe_casing": "Bronze Pipe Casing", + "block.gtceu.bronze_tank_valve": "Bronze Tank Valve", "block.gtceu.brown_borderless_lamp": "Brown Borderless Lamp", "block.gtceu.brown_lamp": "Brown Lamp", "block.gtceu.brown_large_metal_sheet": "Brown Large Metal Sheet", @@ -147,6 +151,7 @@ "block.gtceu.casing_coke_bricks": "Coke Oven Bricks", "block.gtceu.casing_grate": "Grate Machine Casing", "block.gtceu.causality_hazard_sign_block": "Causality Hazard Sign Block", + "block.gtceu.central_monitor": "Central Monitor", "block.gtceu.charcoal_pile_igniter": "Charcoal Pile Igniter", "block.gtceu.chiseled_dark_concrete": "Chiseled Dark Concrete", "block.gtceu.chiseled_light_concrete": "Chiseled Light Concrete", @@ -175,6 +180,7 @@ "block.gtceu.creative_data_access_hatch": "Creative Data Access Hatch", "block.gtceu.creative_energy": "Creative Energy", "block.gtceu.creative_tank": "Creative Tank", + "block.gtceu.creosote": "Creosote", "block.gtceu.crushing_wheels": "Crushing Wheels", "block.gtceu.cupronickel_coil_block": "Cupronickel Coil Block", "block.gtceu.cyan_borderless_lamp": "Cyan Borderless Lamp", @@ -810,6 +816,7 @@ "block.gtceu.mob_infestation_hazard_sign_block": "Mob Infestation Hazard Sign Block", "block.gtceu.mob_spawner_hazard_sign_block": "Mob Spawner Hazard Sign Block", "block.gtceu.molybdenum_disilicide_coil_block": "Molybdenum Disilicide Coil Block", + "block.gtceu.monitor": "Monitor", "block.gtceu.mossy_dark_concrete_bricks": "Mossy Dark Concrete Bricks", "block.gtceu.mossy_dark_concrete_cobblestone": "Mossy Dark Concrete Cobblestone", "block.gtceu.mossy_light_concrete_bricks": "Mossy Light Concrete Bricks", @@ -1735,8 +1742,9 @@ "command.gtceu.share_prospection_data.notification": "%s is sharing prospecting data with you!", "config.gtceu.option.addLoot": "addLoot", "config.gtceu.option.ae2": "ae2", - "config.gtceu.option.allUniqueStoneTypes": "allUniqueStoneTypes", + "config.gtceu.option.allowDrumsInputFluidsFromOutputSide": "allowDrumsInputFluidsFromOutputSide", "config.gtceu.option.animationTime": "animationTime", + "config.gtceu.option.arcRecyclingYield": "arcRecyclingYield", "config.gtceu.option.armorHud": "armorHud", "config.gtceu.option.batchDuration": "batchDuration", "config.gtceu.option.bedrockOreDistance": "bedrockOreDistance", @@ -1751,6 +1759,7 @@ "config.gtceu.option.coloredTieredMachineOutline": "coloredTieredMachineOutline", "config.gtceu.option.coloredWireOutline": "coloredWireOutline", "config.gtceu.option.compat": "compat", + "config.gtceu.option.createCompat": "createCompat", "config.gtceu.option.debug": "debug", "config.gtceu.option.debugWorldgen": "debugWorldgen", "config.gtceu.option.defaultPaintingColor": "defaultPaintingColor", @@ -1762,10 +1771,14 @@ "config.gtceu.option.doDatafixers": "doDatafixers", "config.gtceu.option.doSuperflatOres": "doSuperflatOres", "config.gtceu.option.doesExplosionDamagesTerrain": "doesExplosionDamagesTerrain", + "config.gtceu.option.drum": "drum", "config.gtceu.option.dumpAssets": "dumpAssets", "config.gtceu.option.dumpRecipes": "dumpRecipes", + "config.gtceu.option.enableArcRecycling": "enableArcRecycling", "config.gtceu.option.enableCleanroom": "enableCleanroom", + "config.gtceu.option.enableExtractorRecycling": "enableExtractorRecycling", "config.gtceu.option.enableFEConverters": "enableFEConverters", + "config.gtceu.option.enableMaceratorRecycling": "enableMaceratorRecycling", "config.gtceu.option.enableMaintenance": "enableMaintenance", "config.gtceu.option.enableResearch": "enableResearch", "config.gtceu.option.enableTieredCasings": "enableTieredCasings", @@ -1777,6 +1790,7 @@ "config.gtceu.option.environmentalHazardDecayRate": "environmentalHazardDecayRate", "config.gtceu.option.environmentalHazards": "environmentalHazards", "config.gtceu.option.euToFeRatio": "euToFeRatio", + "config.gtceu.option.extractorRecyclingYield": "extractorRecyclingYield", "config.gtceu.option.feToEuRatio": "feToEuRatio", "config.gtceu.option.flintAndSteelRequireSteel": "flintAndSteelRequireSteel", "config.gtceu.option.ftbChunksIntegration": "ftbChunksIntegration", @@ -1817,9 +1831,12 @@ "config.gtceu.option.ldFluidPipeMinDistance": "ldFluidPipeMinDistance", "config.gtceu.option.ldItemPipeMinDistance": "ldItemPipeMinDistance", "config.gtceu.option.liquidBoilerBaseOutput": "liquidBoilerBaseOutput", + "config.gtceu.option.maceratorRecyclingYield": "maceratorRecyclingYield", "config.gtceu.option.machineSounds": "machineSounds", "config.gtceu.option.machines": "machines", "config.gtceu.option.machinesEmissiveTextures": "machinesEmissiveTextures", + "config.gtceu.option.machinesHaveBERsByDefault": "machinesHaveBERsByDefault", + "config.gtceu.option.maintenanceCheckRate": "maintenanceCheckRate", "config.gtceu.option.meHatchEnergyUsage": "meHatchEnergyUsage", "config.gtceu.option.minerSpeed": "minerSpeed", "config.gtceu.option.minimap": "minimap", @@ -1845,7 +1862,7 @@ "config.gtceu.option.oreVeins": "oreVeins", "config.gtceu.option.ownerOPBypass": "ownerOPBypass", "config.gtceu.option.prospectorEnergyUseMultiplier": "prospectorEnergyUseMultiplier", - "config.gtceu.option.recipeProgressLowEnergy": "recipeProgressLowEnergy", + "config.gtceu.option.quantumTank": "quantumTank", "config.gtceu.option.recipes": "recipes", "config.gtceu.option.removeSmeltingForEBFMetals": "removeSmeltingForEBFMetals", "config.gtceu.option.removeVanillaBlockRecipes": "removeVanillaBlockRecipes", @@ -1853,8 +1870,10 @@ "config.gtceu.option.removeVanillaOreGen": "removeVanillaOreGen", "config.gtceu.option.removeVanillaTNTRecipe": "removeVanillaTNTRecipe", "config.gtceu.option.renderFluids": "renderFluids", + "config.gtceu.option.renderGrowingPlants": "renderGrowingPlants", "config.gtceu.option.renderer": "renderer", "config.gtceu.option.replaceMinedBlocksWith": "replaceMinedBlocksWith", + "config.gtceu.option.replaceWithCobbleVersion": "replaceWithCobbleVersion", "config.gtceu.option.requireGTToolsForBlocks": "requireGTToolsForBlocks", "config.gtceu.option.rngDamageElectricTools": "rngDamageElectricTools", "config.gtceu.option.rubberTreeSpawnChance": "rubberTreeSpawnChance", @@ -1871,6 +1890,7 @@ "config.gtceu.option.steelBoilerMaxTemperature": "steelBoilerMaxTemperature", "config.gtceu.option.steelSteamMultiblocks": "steelSteamMultiblocks", "config.gtceu.option.surfaceRockProspectRange": "surfaceRockProspectRange", + "config.gtceu.option.tankItemFluidPreview": "tankItemFluidPreview", "config.gtceu.option.titaniumBoilerHeatSpeed": "titaniumBoilerHeatSpeed", "config.gtceu.option.titaniumBoilerMaxTemperature": "titaniumBoilerMaxTemperature", "config.gtceu.option.toggle": "toggle", @@ -1899,6 +1919,7 @@ "config.jade.plugin_gtceu.auto_output_info": "[GTCEu] Auto Output Info", "config.jade.plugin_gtceu.cable_info": "[GTCEu] Cable Info", "config.jade.plugin_gtceu.controllable_provider": "[GTCEu] Controllable", + "config.jade.plugin_gtceu.data_bank": "[GTCEu] Data Bank Info", "config.jade.plugin_gtceu.electric_container_provider": "[GTCEu] Electric Container", "config.jade.plugin_gtceu.energy_converter_provider": "[GTCEu] Energy Converter Mode", "config.jade.plugin_gtceu.exhaust_vent_info": "[GTCEu] Exhaust Vent Info", @@ -1976,9 +1997,9 @@ "cover.conveyor.distribution.insert_first.2": "§7Restrictive item pipes lower the priority of a path.", "cover.conveyor.distribution.round_robin_global.0": "Distribution Mode: §bRound Robin", "cover.conveyor.distribution.round_robin_global.1": "§7Splits items equally across connected inventories", - "cover.conveyor.distribution.round_robin_prio.0": "Distribution Mode: §bRound Robin with Priority", - "cover.conveyor.distribution.round_robin_prio.1": "§7Tries to split items across connected inventories and considers higher priorities first.", - "cover.conveyor.distribution.round_robin_prio.2": "§7Restrictive item pipes lower the priority of a path.", + "cover.conveyor.distribution.round_robin_prio.0": "Distribution Mode: §bRound Robin with Restriction", + "cover.conveyor.distribution.round_robin_prio.1": "§7Tries to split items equally across connected inventories.", + "cover.conveyor.distribution.round_robin_prio.2": "§7Will not send items down Restrictive item pipes unless no other paths are available.", "cover.conveyor.item_filter.title": "Item Filter", "cover.conveyor.mode": "Mode: %s", "cover.conveyor.mode.export": "Mode: Export", @@ -2002,6 +2023,8 @@ "cover.ender_fluid_link.tooltip.channel_name": "Set channel name with input text", "cover.ender_fluid_link.tooltip.clear_button": "Clear channel description", "cover.ender_fluid_link.tooltip.list_button": "Show channel list", + "cover.ender_item_link.title": "Ender Item Link", + "cover.ender_redstone_link.title": "Ender Redstone Link", "cover.filter.blacklist.disabled": "Whitelist", "cover.filter.blacklist.enabled": "Blacklist", "cover.filter.mode.filter_both": "Filter Insert/Extract", @@ -2045,6 +2068,7 @@ "cover.machine_controller.mode.null": "Control Nothing", "cover.machine_controller.normal": "Normal", "cover.machine_controller.redstone": "Min Redstone Strength: %d", + "cover.machine_controller.suspend_powerfail": "Prevent Power Failing:", "cover.machine_controller.title": "Machine Controller Settings", "cover.pump.fluid_filter.title": "Fluid Filter", "cover.pump.mode.export": "Mode: Export", @@ -2180,12 +2204,41 @@ "gtceu.cable.loss_per_block": "§cLoss/Meter/Ampere:§r §c%d§7 EU-Volt", "gtceu.cable.superconductor": "%s §dSuperconductor", "gtceu.cable.voltage": "§aMax Voltage:§r §a%d §a(%s§a)", + "gtceu.central_monitor.gui.create_group": "Create group", + "gtceu.central_monitor.gui.currently_editing": "Currently editing: %s", + "gtceu.central_monitor.gui.remove_from_group": "Remove from group", + "gtceu.central_monitor.gui.set_target": "Set target", + "gtceu.central_monitor.info_tooltip.0": "In order to use monitors, you have to split them into groups first. A group may only have 1 module in it.", + "gtceu.central_monitor.info_tooltip.1": "Select them by left-clicking, then click 'Create group'.", + "gtceu.central_monitor.info_tooltip.2": "Then in the settings page for the group you can insert a module, you can configure it in the same page.", + "gtceu.central_monitor.info_tooltip.3": "To delete a group, select all of it's components and click 'Remove from group'.", + "gtceu.central_monitor.info_tooltip.4": "You can quickly select all components of a group by clicking on it's name. Click again to unselect.", + "gtceu.central_monitor.info_tooltip.5": "Some modules may display things depending on the block they target, to set a target for a group select any component of that group and right-click on the target component.", + "gtceu.central_monitor.info_tooltip.6": "You may wish to select a target that is not in the multiblock, you have to use the wireless transmitter cover for that.", + "gtceu.central_monitor.info_tooltip.7": "Place the cover on the target block, right-click it with a data stick and put that data stick into a data access hatch in the multiblock.", + "gtceu.central_monitor.info_tooltip.8": "Then select the data access hatch as the target, and set the slot index of your data stick in the number field that appeared.", + "gtceu.central_monitor.size": "Size: (%d+1+%d)x(%d+1+%d)", "gtceu.chance_logic.and": "AND", "gtceu.chance_logic.first": "FIRST", "gtceu.chance_logic.none": "NONE", "gtceu.chance_logic.or": "OR", "gtceu.chance_logic.xor": "XOR", "gtceu.chat.cape": "§5Congrats: you just unlocked a new cape! See the Cape Selector terminal app to use it.§r", + "gtceu.computer_monitor_cover.error.bf_invalid": "Invalid character at %d", + "gtceu.computer_monitor_cover.error.bf_invalid_num": "Invalid number at index %d when processing symbol number %d", + "gtceu.computer_monitor_cover.error.exception": "Unexpected exception occurred: %s", + "gtceu.computer_monitor_cover.error.invalid_args": "Invalid arguments!", + "gtceu.computer_monitor_cover.error.invalid_number": "Invalid number '%s'!", + "gtceu.computer_monitor_cover.error.missing_item": "Missing %s in slot %d!", + "gtceu.computer_monitor_cover.error.no_ae": "Cover holder does not have an AE2 network!", + "gtceu.computer_monitor_cover.error.no_cover": "No cover!", + "gtceu.computer_monitor_cover.error.no_placeholder": "No such placeholder: '%s'!", + "gtceu.computer_monitor_cover.error.not_enough_args": "Expected at least %d args, got %d!", + "gtceu.computer_monitor_cover.error.not_in_range": "Expected %s to be between %d and %d (inclusive), got %d", + "gtceu.computer_monitor_cover.error.not_supported": "This feature is not supported by this block/cover!", + "gtceu.computer_monitor_cover.error.unclosed_bracket": "Unclosed bracket!", + "gtceu.computer_monitor_cover.error.unexpected_bracket": "Unexpected closing bracket!", + "gtceu.computer_monitor_cover.error.wrong_number_of_args": "Expected %d args, got %d!", "gtceu.cover.activity_detector.message_activity_inverted": "Monitoring Inverted Activity Status", "gtceu.cover.activity_detector.message_activity_normal": "Monitoring Normal Activity Status", "gtceu.cover.activity_detector_advanced.message_activity_inverted": "Monitoring Inverted Progress Status", @@ -2219,7 +2272,14 @@ "gtceu.direction.tooltip.left": "Left", "gtceu.direction.tooltip.right": "Right", "gtceu.direction.tooltip.up": "Up", + "gtceu.display_source.computer_monitor_cover": "Computer Monitor Cover", + "gtceu.display_target.computer_monitor_cover": "Computer Monitor Cover", "gtceu.duct_pipe.transfer_rate": "§bAir transfer rate: %s", + "gtceu.ender_item_link_cover.title": "Ender Item Link", + "gtceu.ender_item_link_cover.tooltip": "§7Transports §fItems§7 with a §fWireless §dEnder§f Connection§7 as §fCover§7.", + "gtceu.ender_redstone_link_cover.label": "Redstone power: %d", + "gtceu.ender_redstone_link_cover.title": "Ender Redstone Link", + "gtceu.ender_redstone_link_cover.tooltip": "§7Transmits §fRedstone signals§7 with a §fWireless §dEnder§f Connection§7 as §fCover§7.", "gtceu.fluid.amount": "§9Amount: %d/%d mB", "gtceu.fluid.click_combined": "§7Click with a Fluid Container to §cempty §7or §bfill §7the tank (Shift-click for a full stack).", "gtceu.fluid.click_to_empty": "§7Click with a Fluid Container to §cempty §7the tank (Shift-click for a full stack).", @@ -2248,7 +2308,16 @@ "gtceu.forming_press.naming.named": "§oNamed Item", "gtceu.forming_press.naming.press": "§oNamed Press", "gtceu.forming_press.naming.to_name": "§oItem to Name", + "gtceu.gui.adv_stocking_config.min_fluid_count": "Minimum Fluid Stack Size for Automated Pulling", + "gtceu.gui.adv_stocking_config.min_item_count": "Minimum Item Stack Size for Automated Pulling", + "gtceu.gui.adv_stocking_config.ticks_per_cycle": "Delay between item list updates", + "gtceu.gui.adv_stocking_config.title": "Configure Automatic Stocking", + "gtceu.gui.all_voiding": "§7Voiding §cAll", "gtceu.gui.auto_output.name": "auto", + "gtceu.gui.central_monitor.group": "Group: %s", + "gtceu.gui.central_monitor.group_default_name": "Group #%d", + "gtceu.gui.central_monitor.none": "none", + "gtceu.gui.central_monitor.text_scale": "Text scale", "gtceu.gui.charger_slot.tooltip.0": "§fCharger Slot§r", "gtceu.gui.charger_slot.tooltip.1": "§7Draws power from %s batteries§r", "gtceu.gui.charger_slot.tooltip.2": "§7Charges %s tools and batteries", @@ -2257,6 +2326,18 @@ "gtceu.gui.chunkmode.enabled.0": "Chunk Mode Enabled: Click to Disable.", "gtceu.gui.chunkmode.enabled.1": "§7Switching requires an idle machine.", "gtceu.gui.circuit.title": "Circuit Settings", + "gtceu.gui.computer_monitor_cover.edit_blank_placeholders": "Edit blank placeholders", + "gtceu.gui.computer_monitor_cover.edit_displayed_text": "Edit displayed text", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.0": "Input string to display on line %d here.", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.1": "It can have placeholders, for example: 'Energy: {energy}/{energyCapacity} EU'", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.2": "Placeholders can also be inside other placeholders.", + "gtceu.gui.computer_monitor_cover.placeholder_reference.0": "All placeholders:", + "gtceu.gui.computer_monitor_cover.placeholder_reference.1": "(hover for more info)", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.0": "Input placeholder to be used in place of %s '{}' here.", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.1": "For example, you can have a string 'Energy: {}/{} EU' and 'energy' and 'energyCapacity' in these text boxes.", + "gtceu.gui.computer_monitor_cover.slot_tooltip.0": "A slot for items that some placeholders can reference", + "gtceu.gui.computer_monitor_cover.slot_tooltip.1": "Slot number: %d", + "gtceu.gui.computer_monitor_cover.update_interval": "Update interval (in ticks)", "gtceu.gui.config_slot": "§fConfig Slot§r", "gtceu.gui.config_slot.auto_pull_managed": "§4Disabled:§7 Managed by Auto-Pull", "gtceu.gui.config_slot.remove": "§7Right click to §4clear§7 config slot.§r", @@ -2281,11 +2362,15 @@ "gtceu.gui.content.count_range": "%s-%sx", "gtceu.gui.content.fluid_range": "%s-%smB", "gtceu.gui.content.per_tick": "§aConsumed/Produced Per Tick§r", + "gtceu.gui.content.range": "%s-%s", + "gtceu.gui.content.times_item": "x %s", "gtceu.gui.content.tips.per_second_short": "§a/second§r", "gtceu.gui.content.tips.per_tick_short": "§a/tick§r", "gtceu.gui.content.units.per_second": "/s", "gtceu.gui.content.units.per_tick": "/t", "gtceu.gui.cover_setting.title": "Cover Settings", + "gtceu.gui.directional_setting.tab_tooltip": "Change Directional Setting", + "gtceu.gui.directional_setting.title": "Directional Setting", "gtceu.gui.editor.group.recipe_type": "cap", "gtceu.gui.editor.tips.citation": "Number of citations", "gtceu.gui.fisher_mode.tooltip.0": "Toggle junk items", @@ -2295,10 +2380,18 @@ "gtceu.gui.fluid_auto_input.tooltip.enabled": "Fluid Auto-Input Enabled", "gtceu.gui.fluid_auto_output.allow_input.disabled": "disable fluids input from the output side", "gtceu.gui.fluid_auto_output.allow_input.enabled": "allow fluids input from the output side", + "gtceu.gui.fluid_auto_output.disabled": "Fluid Auto Output: §cDisabled", + "gtceu.gui.fluid_auto_output.enabled": "Fluid Auto Output: §aEnabled", + "gtceu.gui.fluid_auto_output.other_direction.0": "Fluid Auto Output: §6Other Direction", + "gtceu.gui.fluid_auto_output.other_direction.1": "§7The machine's fluid output is set to another direction.", + "gtceu.gui.fluid_auto_output.other_direction.2": "§7Click to move the output to the currently selected side.", "gtceu.gui.fluid_auto_output.tooltip.disabled": "Fluid Auto-Output Disabled", "gtceu.gui.fluid_auto_output.tooltip.enabled": "Fluid Auto-Output Enabled", + "gtceu.gui.fluid_auto_output.unselected.0": "Fluid Auto Output", + "gtceu.gui.fluid_auto_output.unselected.1": "§7Select a side of the machine to configure its output.", "gtceu.gui.fluid_lock.tooltip.disabled": "Fluid Locking Disabled", "gtceu.gui.fluid_lock.tooltip.enabled": "Fluid Locking Enabled", + "gtceu.gui.fluid_voiding": "§7Voiding §9Fluids", "gtceu.gui.fluid_voiding_partial.tooltip.disabled": "Fluid Voiding Disabled", "gtceu.gui.fluid_voiding_partial.tooltip.enabled": "Fluid Voiding Enabled", "gtceu.gui.fuel_amount": "Fuel Amount:", @@ -2306,25 +2399,28 @@ "gtceu.gui.item_auto_input.tooltip.enabled": "Item Auto-Input Enabled", "gtceu.gui.item_auto_output.allow_input.disabled": "disable items input from the output side", "gtceu.gui.item_auto_output.allow_input.enabled": "allow items input from the output side", + "gtceu.gui.item_auto_output.disabled": "Item Auto Output: §cDisabled", + "gtceu.gui.item_auto_output.enabled": "Item Auto Output: §aEnabled", + "gtceu.gui.item_auto_output.other_direction.0": "Item Auto Output: §6Other Direction", + "gtceu.gui.item_auto_output.other_direction.1": "§7The machine's item output is set to another direction.", + "gtceu.gui.item_auto_output.other_direction.2": "§7Click to move the output to the currently selected side.", "gtceu.gui.item_auto_output.tooltip.disabled": "Item Auto-Output Disabled", "gtceu.gui.item_auto_output.tooltip.enabled": "Item Auto-Output Enabled", + "gtceu.gui.item_auto_output.unselected.0": "Item Auto Output", + "gtceu.gui.item_auto_output.unselected.1": "§7Select a side of the machine to configure its output.", "gtceu.gui.item_lock.tooltip.disabled": "Item Locking Disabled", "gtceu.gui.item_lock.tooltip.enabled": "Item Locking Enabled", + "gtceu.gui.item_voiding": "§7Voiding §6Items", "gtceu.gui.item_voiding_partial.tooltip.disabled": "Item Voiding Disabled", "gtceu.gui.item_voiding_partial.tooltip.enabled": "Item Voiding Enabled", "gtceu.gui.machinemode": "Active Machine Mode: %s", + "gtceu.gui.machinemode.tab_tooltip": "Change active Machine Mode", "gtceu.gui.machinemode.title": "Active Machine Mode", "gtceu.gui.me_bus.auto_pull_button": "Click to toggle automatic item pulling from ME", "gtceu.gui.me_network.offline": "Network Status: §4Offline§r", "gtceu.gui.me_network.online": "Network Status: §2Online§r", - "gtceu.gui.multiblock_fluid_voiding.0": "Voiding Mode", - "gtceu.gui.multiblock_fluid_voiding.1": "§7Voiding §9Fluids", - "gtceu.gui.multiblock_item_fluid_voiding.0": "Voiding Mode", - "gtceu.gui.multiblock_item_fluid_voiding.1": "§7Voiding §6Items §7and §9Fluids", - "gtceu.gui.multiblock_item_voiding.0": "Voiding Mode", - "gtceu.gui.multiblock_item_voiding.1": "§7Voiding §6Items", - "gtceu.gui.multiblock_no_voiding.0": "Voiding Mode", - "gtceu.gui.multiblock_no_voiding.1": "§7Voiding Nothing", + "gtceu.gui.multiblock.voiding_mode": "Voiding Mode:", + "gtceu.gui.no_voiding": "§7Voiding Nothing", "gtceu.gui.output_setting.title": "Output Settings", "gtceu.gui.output_setting.tooltips.0": "left-click to tune the item auto output", "gtceu.gui.output_setting.tooltips.1": "right-click to tune the fluid auto output.", @@ -2342,6 +2438,9 @@ "gtceu.gui.silktouch.enabled.0": "Silk Touch Enabled: Click to Disable.", "gtceu.gui.silktouch.enabled.1": "§7Switching requires an idle machine.", "gtceu.gui.sort": "Sort", + "gtceu.gui.title.adv_stocking_config.min_fluid_count": "Min. Fluid Count", + "gtceu.gui.title.adv_stocking_config.min_item_count": "Min. Item Count", + "gtceu.gui.title.adv_stocking_config.ticks_per_cycle": "Ticks Per Cycle", "gtceu.gui.title_bar.back": "Back", "gtceu.gui.title_bar.page_switcher": "Pages", "gtceu.gui.toggle_view.disabled": "Toggle View (Fluids)", @@ -2361,8 +2460,11 @@ "gtceu.item_filter.footer": "§eClick with item to override", "gtceu.item_list.item_stored": "§7Stored: %d", "gtceu.item_pipe.priority": "§9Priority: §f%d", + "gtceu.jade.amperage_use": "%s A", + "gtceu.jade.at": " @ ", "gtceu.jade.cleaned_this_second": "Cleaned hazard: %s/s", "gtceu.jade.energy_stored": "%d / %d EU", + "gtceu.jade.fluid_use": "%s mB/t", "gtceu.jade.progress_computation": "%s / %s CWU", "gtceu.jade.progress_sec": "%s / %s s", "gtceu.jade.progress_tick": "%s / %s t", @@ -2435,9 +2537,9 @@ "gtceu.machine.bedrock_ore_miner.production": "§eProduction Multiplier: §f%dx, %fx overclocked", "gtceu.machine.block_breaker.speed_bonus": "§eSpeed Bonus: §f%d%%", "gtceu.machine.block_breaker.tooltip": "§7Mines block on front face and collects its drops", - "gtceu.machine.boiler.info.cooling.down": "§9Cooling down§r%s", - "gtceu.machine.boiler.info.heating.up": "§cHeating up§r%s", - "gtceu.machine.boiler.info.producing.steam": " §a(boiling water)", + "gtceu.machine.boiler.info.cooling.down": "§9Cooling§r", + "gtceu.machine.boiler.info.heating.up": "§cHeating§r", + "gtceu.machine.boiler.info.production.data": "§aProducing %s§a mB/t", "gtceu.machine.buffer.tooltip": "A Small Buffer to store Items and Fluids", "gtceu.machine.canner.jei_description": "You can fill and empty any fluid containers with the Fluid Canner (e.g. Buckets or Fluid Cells)", "gtceu.machine.central_monitor.tooltip": "But can it run Doom?", @@ -2567,7 +2669,7 @@ "gtceu.machine.hp_steam_forge_hammer.tooltip": "§7Forge Hammer", "gtceu.machine.hp_steam_furnace.tooltip": "§7Smelting things with compressed Steam", "gtceu.machine.hp_steam_liquid_boiler.tooltip": "§7Faster than Small Steam Liquid Boiler", - "gtceu.machine.hp_steam_macerator.tooltip": "§7Macerating your Ores", + "gtceu.machine.hp_steam_macerator.tooltip": "§7Macerating your Ores without Byproducts", "gtceu.machine.hp_steam_rock_crusher.tooltip": "§7Place Water and Lava horizontally adjacent", "gtceu.machine.hp_steam_solar_boiler.tooltip": "§7Steam Power by Sun", "gtceu.machine.hp_steam_solid_boiler.tooltip": "§7Faster than the Small Steam Solid Fuel Boiler", @@ -2705,7 +2807,7 @@ "gtceu.machine.lp_steam_forge_hammer.tooltip": "§7Forge Hammer", "gtceu.machine.lp_steam_furnace.tooltip": "§7Smelting things with compressed Steam", "gtceu.machine.lp_steam_liquid_boiler.tooltip": "§7A Boiler running off Liquids", - "gtceu.machine.lp_steam_macerator.tooltip": "§7Macerating your Ores", + "gtceu.machine.lp_steam_macerator.tooltip": "§7Macerating your Ores without Byproducts", "gtceu.machine.lp_steam_rock_crusher.tooltip": "§7Place Water and Lava horizontally adjacent", "gtceu.machine.lp_steam_solar_boiler.tooltip": "§7Steam Power by Sun", "gtceu.machine.lp_steam_solid_boiler.tooltip": "§7An early way to get Steam Power", @@ -2825,6 +2927,7 @@ "gtceu.machine.miner.multi.modes": "Has Silk Touch and Chunk Aligned Modes.", "gtceu.machine.miner.multi.production": "Produces §f3x§7 more crushed ore than a §fMacerator§7.", "gtceu.machine.miner.per_block": "§7takes §f%ds §7per Block", + "gtceu.machine.miner.progress": "Progress: %d/%d", "gtceu.machine.miner.radius": "Radius: %d", "gtceu.machine.miner.startx": "sX: %d", "gtceu.machine.miner.starty": "sY: %d", @@ -3071,7 +3174,7 @@ "gtceu.multiblock.active_transformer.max_input": "§aMax Input: §f%s EU/t", "gtceu.multiblock.active_transformer.max_output": "§cMax Output: §f%s EU/t", "gtceu.multiblock.assembly_line.description": "The Assembly Line is a large multiblock structure consisting of 5 to 16 \"slices\". In theory, it's large Assembling Machine, used for creating advanced crafting components.", - "gtceu.multiblock.batch_enabled": "Batching Mode: Enabled (%sx)", + "gtceu.multiblock.batch_enabled": "- %dx from Batching", "gtceu.multiblock.blast_furnace.max_temperature": "Heat Capacity: %s", "gtceu.multiblock.central_monitor.height": "Screen Height:", "gtceu.multiblock.central_monitor.height_modify": "Modify Height: %d", @@ -3202,7 +3305,7 @@ "gtceu.multiblock.page_switcher.io.export": "§4Outputs", "gtceu.multiblock.page_switcher.io.import": "§2Inputs", "gtceu.multiblock.parallel": "Performing up to %d Recipes in Parallel", - "gtceu.multiblock.parallel.exact": "Performing %d Recipes in Parallel", + "gtceu.multiblock.parallel.exact": "- %dx from Parallels", "gtceu.multiblock.parallelizable.tooltip": "Can parallelize with Parallel Control Hatches.", "gtceu.multiblock.pattern.clear_amount_1": "§6Must have a clear 1x1x1 space in front§r", "gtceu.multiblock.pattern.clear_amount_3": "§6Must have a clear 3x3x1 space in front§r", @@ -3268,7 +3371,9 @@ "gtceu.multiblock.steam.steam_stored": "Steam: %s / %s mb", "gtceu.multiblock.steam_grinder.description": "A Multiblock Macerator at the Steam Age. Requires at least 14 Bronze Casings to form. Cannot use normal Input/Output busses, nor Fluid Hatches other than the Steam Hatch.", "gtceu.multiblock.steam_oven.description": "A Multi Smelter at the Steam Age. Requires at least 6 Bronze Casings to form. Cannot use normal Input/Output busses, nor Fluid Hatches other than the Steam Hatch. Steam Hatch must be on the bottom layer, no more than one.", + "gtceu.multiblock.subtick_parallels": "- %dx from Overclocking", "gtceu.multiblock.title": "Multiblock Pattern", + "gtceu.multiblock.total_runs": "Performing %d Recipes at once", "gtceu.multiblock.turbine.efficiency": "Turbine Efficiency: %s%%", "gtceu.multiblock.turbine.efficiency_tooltip": "Each Rotor Holder above %s§7 adds §f10%% efficiency and multiplies EU/t by 2§7.", "gtceu.multiblock.turbine.energy_per_tick": "Energy Output: %s/%s EU/t", @@ -3310,6 +3415,209 @@ "gtceu.ownership.name.player": "Player", "gtceu.part_sharing.disabled": "Multiblock Sharing §4Disabled", "gtceu.part_sharing.enabled": "Multiblock Sharing §aEnabled", + "gtceu.placeholder_info.active.0": "Returns a 1 if the block the cover is attached to is currently running a recipe, 0 otherwise.", + "gtceu.placeholder_info.active.1": "Usage:", + "gtceu.placeholder_info.active.2": " {active} -> whether there's a currently running recipe", + "gtceu.placeholder_info.ae2crafting.0": "Returns information about auto-crafting in the ME network of the block this cover is on.", + "gtceu.placeholder_info.ae2crafting.1": "Usage:", + "gtceu.placeholder_info.ae2crafting.10": " {ae2crafting get time} -> the amount of time elapsed from the start of the craft (in nanoseconds), or 0 if the CPU is idle", + "gtceu.placeholder_info.ae2crafting.2": " {ae2crafting get amount} -> the amount of crafting CPUs in the ME network", + "gtceu.placeholder_info.ae2crafting.3": " {ae2crafting get storage} -> the amount of crafting storage the specified CPU has", + "gtceu.placeholder_info.ae2crafting.4": " {ae2crafting get threads} -> the amount of co-processors the specified CPU has", + "gtceu.placeholder_info.ae2crafting.5": " {ae2crafting get name} -> the name of the specified crafting CPU", + "gtceu.placeholder_info.ae2crafting.6": " {ae2crafting get selectionMode} -> the selection mode of the specified crafting CPU (used for manual, automatic or both requests)", + "gtceu.placeholder_info.ae2crafting.7": " {ae2crafting get amount} -> the amount of the item that was requested, or 0 if the CPU is idle", + "gtceu.placeholder_info.ae2crafting.8": " {ae2crafting get item} -> the display name of the item that was requested, or 0 if the CPU is idle", + "gtceu.placeholder_info.ae2crafting.9": " {ae2crafting get progress} -> the crafting job progress, or 0 if the CPU is idle", + "gtceu.placeholder_info.ae2energy.0": "Returns the energy currently stored in the ME network of the block this cover is on.", + "gtceu.placeholder_info.ae2energy.1": "Usage:", + "gtceu.placeholder_info.ae2energy.2": " {ae2energy} -> the energy in the ME network (in AE units)", + "gtceu.placeholder_info.ae2fluidCount.0": "Same as fluidCount, but counts items in the ME network of the block this cover is attached to.", + "gtceu.placeholder_info.ae2fluidCount.1": "Note that counting all fluids may cause lag!", + "gtceu.placeholder_info.ae2fluidCount.2": "Usage:", + "gtceu.placeholder_info.ae2fluidCount.3": " {fluidCount [fluidId]} -> the amount of all fluids, or the fluid with fluidId if specified", + "gtceu.placeholder_info.ae2itemCount.0": "Same as itemCount, but counts items in the ME network of the block this cover is attached to.", + "gtceu.placeholder_info.ae2itemCount.1": "Note that counting by filter or all items may cause lag!", + "gtceu.placeholder_info.ae2itemCount.2": "Usage:", + "gtceu.placeholder_info.ae2itemCount.3": " {itemCount} -> total item amount", + "gtceu.placeholder_info.ae2itemCount.4": " {itemCount } -> amount of items with ids equal to item_id", + "gtceu.placeholder_info.ae2itemCount.5": " {itemCount filter } -> amount of items matching filter in specified slot of this cover", + "gtceu.placeholder_info.ae2maxPower.0": "Returns the energy capacity of the ME network of the block this cover is on.", + "gtceu.placeholder_info.ae2maxPower.1": "Usage:", + "gtceu.placeholder_info.ae2maxPower.2": " {ae2maxPower} -> the energy capacity of the ME network", + "gtceu.placeholder_info.ae2powerUsage.0": "Returns the energy consumption of the ME network of the block this cover is on.", + "gtceu.placeholder_info.ae2powerUsage.1": "Usage:", + "gtceu.placeholder_info.ae2powerUsage.2": " {ae2powerUsage} -> the energy consumption of the ME network", + "gtceu.placeholder_info.ae2spatial.0": "Returns information about spatial I/O in the ME network of the block this cover is on.", + "gtceu.placeholder_info.ae2spatial.1": "Usage:", + "gtceu.placeholder_info.ae2spatial.2": " {ae2spatial power} -> the amount of power required to initiate spatial I/O", + "gtceu.placeholder_info.ae2spatial.3": " {ae2spatial efficiency} -> the efficiency of the Spatial Containment Structure (SPS)", + "gtceu.placeholder_info.ae2spatial.4": " {ae2spatial size} -> the size of the SPS along the specified axis (example: 'Size: {sizeX}x{sizeY}x{sizeZ}')", + "gtceu.placeholder_info.amperage.0": "Returns the amperage in the wire/cable the cover is on.", + "gtceu.placeholder_info.amperage.1": "Usage:", + "gtceu.placeholder_info.amperage.2": " {amperage} -> the amperate in the wire/cable", + "gtceu.placeholder_info.bf.0": "Usage:", + "gtceu.placeholder_info.bf.1": " {bf } -> empty string", + "gtceu.placeholder_info.block.0": "Returns the block symbol (█).", + "gtceu.placeholder_info.block.1": "Usage:", + "gtceu.placeholder_info.block.2": " {block} -> '█'", + "gtceu.placeholder_info.blockNbt.0": "Returns the NBT of the block entity", + "gtceu.placeholder_info.blockNbt.1": "Usage:", + "gtceu.placeholder_info.blockNbt.2": " {blockNbt} -> full block entity nbt", + "gtceu.placeholder_info.blockNbt.3": " {blockNbt [key1] [key2] ...} -> part of the nbt", + "gtceu.placeholder_info.bufferText.0": "Returns the text from a buffer accessible by ComputerCraft", + "gtceu.placeholder_info.bufferText.1": "Usage:", + "gtceu.placeholder_info.bufferText.2": " {bufferText } -> text from the buffer on the specified line (line is 1-100)", + "gtceu.placeholder_info.calc.0": "Returns the result of a math function or operation.", + "gtceu.placeholder_info.calc.1": "Usage:", + "gtceu.placeholder_info.calc.2": " {calc } -> any_string", + "gtceu.placeholder_info.calc.3": " {calc } -> the result of the specified operation", + "gtceu.placeholder_info.calc.4": " {calc <+|-|*|/|//|>>|<<|%> } -> the result of the specified operation", + "gtceu.placeholder_info.click.0": "Returns whether the targeted advanced monitor was clicked before the current tick", + "gtceu.placeholder_info.click.1": "Usage:", + "gtceu.placeholder_info.click.2": " {click} -> \"1\" if the targeted advanced monitor was clicked, \"0\" otherwise", + "gtceu.placeholder_info.click.3": " {click x} -> the x position of the last click (between 0 and 1)", + "gtceu.placeholder_info.click.4": " {click y} -> the y position of the last click (between 0 and 1)", + "gtceu.placeholder_info.cmd.0": "Executes Minecraft commands and returns their output.", + "gtceu.placeholder_info.cmd.1": "Requires a data item bound to a player, bind any data item to yourself by right-clicking with it.", + "gtceu.placeholder_info.cmd.2": "Usage:", + "gtceu.placeholder_info.cmd.3": " {cmd } -> command output", + "gtceu.placeholder_info.cmp.0": "Returns a 1 or 0 based on the expression in it's arguments", + "gtceu.placeholder_info.cmp.1": "Usage:", + "gtceu.placeholder_info.cmp.2": " {cmp } -> 1 or 0, operator is one of >, <, >=, <=, ==, !=", + "gtceu.placeholder_info.color.0": "Returns the text from the second argument, colored with the color from the first argument. All default minecraft chat colors can be used.", + "gtceu.placeholder_info.color.1": "Usage:", + "gtceu.placeholder_info.color.2": " {color } -> colored text", + "gtceu.placeholder_info.combine.0": "Combines all of it's arguments into a single string (by escaping all spaces between the arguments)", + "gtceu.placeholder_info.combine.1": "Example: {combine abc def ghi jkl mno} -> \"abc\\ def\\ ghi\\ jkl\\ mno\"", + "gtceu.placeholder_info.combine.2": "Usage:", + "gtceu.placeholder_info.combine.3": " {combine [arg1] [arg2] [arg3] ...} -> a string that will be treated as a single argument in further placeholders", + "gtceu.placeholder_info.count.0": "Returns how many of the provided arguments are equal to the first (compared as strings, so \"0\" != \"0.0\")", + "gtceu.placeholder_info.count.1": "Usage:", + "gtceu.placeholder_info.count.2": " {count [arg2] [arg3] [arg4] ...} -> the amount of arguments that are equal to the first", + "gtceu.placeholder_info.data.0": "Stores or retrieves some data from a data item (data stick/orb/module) in one of the slots.", + "gtceu.placeholder_info.data.1": "If you leave the argument empty, it will be replaced with the value p (p is an integer from 0 to (capacity - 1) that is stored in the data item nbt).", + "gtceu.placeholder_info.data.2": "Usage:", + "gtceu.placeholder_info.data.3": " {data get } -> the data stored in the item in the specified slot", + "gtceu.placeholder_info.data.4": " {data set } -> sets the data stored in the item in the specified slot, returns an empty string", + "gtceu.placeholder_info.data.5": " {data getp } -> p", + "gtceu.placeholder_info.data.6": " {data setp } -> sets p, returns an empty string", + "gtceu.placeholder_info.data.7": " {data inc } -> increments p by 1, if p becomes more than or equal to capacity, sets p to 0", + "gtceu.placeholder_info.data.8": " {data dec } -> decrements p by 1, if p becomes less than 0, sets p to (capacity - 1)", + "gtceu.placeholder_info.displayTarget.0": "Returns the specified line that was transmitted to this cover using a display link.", + "gtceu.placeholder_info.displayTarget.1": "Usage:", + "gtceu.placeholder_info.displayTarget.2": " {displayTarget } -> the text on the specified line (line number is 1-100)", + "gtceu.placeholder_info.ender.0": "Interacts with ender link covers", + "gtceu.placeholder_info.ender.1": "Can interact with private channels if provided with a data item bound to a player", + "gtceu.placeholder_info.ender.10": "The player_data_item_slot argument may be left empty (not 0, empty string)", + "gtceu.placeholder_info.ender.2": "Usage:", + "gtceu.placeholder_info.ender.3": " {ender item [player_data_item_slot]} -> item count", + "gtceu.placeholder_info.ender.4": " {ender itemPull [player_data_item_slot]} -> pull 1 item from the ender link's buffer", + "gtceu.placeholder_info.ender.5": " {ender itemPush [player_data_item_slot]} -> push 1 item to the ender link's buffer", + "gtceu.placeholder_info.ender.6": " {ender itemId [player_data_item_slot]} -> the id of the item in the ender link's buffer (ex. \"26 minecraft:dirt\")", + "gtceu.placeholder_info.ender.7": " {ender fluid [player_data_item_slot]} -> fluid count", + "gtceu.placeholder_info.ender.8": " {ender redstone [player_data_item_slot] -> redstone signal level", + "gtceu.placeholder_info.ender.9": " {ender redstone -> sets the redstone signal outputed to the ender redstone link, returns empty string", + "gtceu.placeholder_info.energy.0": "Returns the amount of energy stored.", + "gtceu.placeholder_info.energy.1": "Usage:", + "gtceu.placeholder_info.energy.2": " {energy} -> the amount of energy stored", + "gtceu.placeholder_info.energyCapacity.0": "Returns the max amount of energy that can be stored", + "gtceu.placeholder_info.energyCapacity.1": "Usage:", + "gtceu.placeholder_info.energyCapacity.2": "{energyCapacity} -> the energy capacity", + "gtceu.placeholder_info.eval.0": "Returns the result of evaluating the provided string which may placeholders", + "gtceu.placeholder_info.eval.1": "Usage:", + "gtceu.placeholder_info.eval.2": " {eval abcdefg} -> abcdefg", + "gtceu.placeholder_info.eval.3": " {eval \"repeating a: {repeat 5 \\\"a \\\"}\" -> repeating a: a a a a a ", + "gtceu.placeholder_info.eval.4": " {eval \\\"\"{some random text}\"\\\" -> {some random text}", + "gtceu.placeholder_info.eval.5": " {eval \"text \"\\\"\"{something with spaces}\"\\\"\" more text\" -> text {something with spaces} more text", + "gtceu.placeholder_info.fluidCount.0": "Returns the amount of fluids (can be filtered).", + "gtceu.placeholder_info.fluidCount.1": "Usage:", + "gtceu.placeholder_info.fluidCount.2": " {fluidCount [fluidId]} -> the amount of all fluids, or the fluid with fluidId if specified", + "gtceu.placeholder_info.formatInt.0": "Returns a string representation of the provided integer", + "gtceu.placeholder_info.formatInt.1": "Example: {formatInt 1236457} -> 1.24M", + "gtceu.placeholder_info.formatInt.2": "Usage:", + "gtceu.placeholder_info.formatInt.3": " {formatInt } -> string representation of the int", + "gtceu.placeholder_info.fromAscii.0": "Returns the character represented by the provided ASCII code", + "gtceu.placeholder_info.fromAscii.1": "Usage:", + "gtceu.placeholder_info.fromAscii.2": " {fromAscii } -> a character", + "gtceu.placeholder_info.if.0": "Returns one of the arguments depending on the condition. The condition is considered true if it is not an empty string and is not equal to 0.", + "gtceu.placeholder_info.if.1": "Usage:", + "gtceu.placeholder_info.if.2": " {if [returned_if_false]}", + "gtceu.placeholder_info.itemCount.0": "Returns the amount of items (can be filtered).", + "gtceu.placeholder_info.itemCount.1": "Usage:", + "gtceu.placeholder_info.itemCount.2": " {itemCount} -> total item amount", + "gtceu.placeholder_info.itemCount.3": " {itemCount } -> amount of items with ids equal to item_id", + "gtceu.placeholder_info.itemCount.4": " {itemCount filter } -> amount of items matching filter in specified slot of this cover", + "gtceu.placeholder_info.maintenance.0": "Returns a 1 if there are maintenance problems in the block the cover is attached to, 0 otherwise.", + "gtceu.placeholder_info.maintenance.1": "Example: 'Maintenance status: {if {maintenance} FIXING\\ REQUIRED OK}'", + "gtceu.placeholder_info.maintenance.2": "Usage:", + "gtceu.placeholder_info.maintenance.3": " {maintenance} -> whether there are maintenance problems", + "gtceu.placeholder_info.maxProgress.0": "Returns the maximum progress of the currently running recipe of the block this cover is attached to.", + "gtceu.placeholder_info.maxProgress.1": "Example: 'Progress: {calc {calc {progress} / {maxProgress}} * 100}%'", + "gtceu.placeholder_info.maxProgress.2": "Usage:", + "gtceu.placeholder_info.maxProgress.3": " {maxProgress} -> the max progress of the currently running recipe", + "gtceu.placeholder_info.nbt.0": "Returns the nbt data of the item in the specified slot", + "gtceu.placeholder_info.nbt.1": "Usage:", + "gtceu.placeholder_info.nbt.2": " {nbt [key1] [key2] [key3] ...} -> item_nbt[key1][key2][key3][...]", + "gtceu.placeholder_info.obf.0": "Returns the text from the first argument, obfuscated.", + "gtceu.placeholder_info.obf.1": "Usage:", + "gtceu.placeholder_info.obf.2": " {obf } -> obfuscated text", + "gtceu.placeholder_info.previousText.0": "Returns the text that was previously displayed by this cover at the specified line (before line-wrapping).", + "gtceu.placeholder_info.previousText.1": "Usage:", + "gtceu.placeholder_info.previousText.2": " {previousText } -> the text previously displayed on the specified line (index starts at 1)", + "gtceu.placeholder_info.progress.0": "Returns the progress of the currently running recipe of the block this cover is attached to.", + "gtceu.placeholder_info.progress.1": "Note that progress is an integer between 0 and {maxProgress}", + "gtceu.placeholder_info.progress.2": "Usage:", + "gtceu.placeholder_info.progress.3": " {progress} -> the progress of the currently running recipe", + "gtceu.placeholder_info.random.0": "Returns a random number in the specified interval (inclusive).", + "gtceu.placeholder_info.random.1": "Usage:", + "gtceu.placeholder_info.random.2": " {random } -> a random number between min and max (inclusive)", + "gtceu.placeholder_info.redstone.0": "Returns the redstone signal strength or sets the redstone output strength", + "gtceu.placeholder_info.redstone.1": "Usage:", + "gtceu.placeholder_info.redstone.2": " {redstone get } -> redstone signal strength (0-15) at the specified side", + "gtceu.placeholder_info.redstone.3": " {redstone get link } -> redstone signal strength of a Create redstone link frequency specified by a linked controller in slot #slot_index. freq_slot_index is the index of the frequency inside the controller (from left to right, 0-6)", + "gtceu.placeholder_info.redstone.4": " {redstone set } -> empty string, sets the redstone output strength from this cover's side", + "gtceu.placeholder_info.redstone.5": " {redstone set link } -> empty string, broadcasts the specified redstone power on the specified Create redstone link frequency", + "gtceu.placeholder_info.repeat.0": "Returns the text from the second arguments, repeated the amount of times specified in the first argument.", + "gtceu.placeholder_info.repeat.1": "Usage:", + "gtceu.placeholder_info.repeat.2": " {repeat } -> text repeated the specified amount of times", + "gtceu.placeholder_info.select.0": "Returns the argument at the specified index (starting from 0)", + "gtceu.placeholder_info.select.1": "Usage:", + "gtceu.placeholder_info.select.2": " {select [arg1] [arg2] [arg3] ... -> argument at the specified index", + "gtceu.placeholder_info.strike.0": "Returns the text from the first text, displaying it as if it was crossed out", + "gtceu.placeholder_info.strike.1": "Usage:", + "gtceu.placeholder_info.strike.2": " {strike } -> crossed-out text", + "gtceu.placeholder_info.subList.0": "Returns arguments from with indexes from l (inclusive) to r (exclusive) (starting from 0)", + "gtceu.placeholder_info.subList.1": "Usage:", + "gtceu.placeholder_info.subList.2": " {subList [arg0] [arg1] ...} -> all arguments with indexes from l to r separated by spaces", + "gtceu.placeholder_info.tick.0": "Returns the amount of ticks passed from when this cover was placed.", + "gtceu.placeholder_info.tick.1": "Usage:", + "gtceu.placeholder_info.tick.2": " {tick} -> the amount of ticks", + "gtceu.placeholder_info.tm.0": "Returns the ™ symbol", + "gtceu.placeholder_info.tm.1": "Usage:", + "gtceu.placeholder_info.tm.2": " {tm} -> the ™ symbol", + "gtceu.placeholder_info.toAscii.0": "Returns the ASCII code of the provided character", + "gtceu.placeholder_info.toAscii.1": "Usage:", + "gtceu.placeholder_info.toAscii.2": " {toAscii } -> ASCII code of the character", + "gtceu.placeholder_info.toChars.0": "Returns the characters of the provided string with spaces between them", + "gtceu.placeholder_info.toChars.1": "Example: {toChars example} -> 'e x a m p l e'", + "gtceu.placeholder_info.toChars.2": "Usage:", + "gtceu.placeholder_info.toChars.3": " {toChars } -> characters", + "gtceu.placeholder_info.underline.0": "Returns the text from the first argument, underlined", + "gtceu.placeholder_info.underline.1": "Usage:", + "gtceu.placeholder_info.underline.2": " {underline } -> underlined text", + "gtceu.placeholder_info.voltage.0": "Returns the voltage in the wire/cable the cover is on.", + "gtceu.placeholder_info.voltage.1": "Usage:", + "gtceu.placeholder_info.voltage.2": " {voltage} -> the voltage in the wire/cable", + "gtceu.recipe.byproduct_tier": "Byproducts from %s§r+", + "gtceu.recipe.category.arc_furnace_recycling": "Arc Scrapping", + "gtceu.recipe.category.chem_dyes": "Chemical Dyeing", + "gtceu.recipe.category.extractor_recycling": "Scrap Remelting", + "gtceu.recipe.category.ingot_molding": "Metal Molding", + "gtceu.recipe.category.macerator_recycling": "Part Grinding", + "gtceu.recipe.category.ore_bathing": "Ore Treating", + "gtceu.recipe.category.ore_crushing": "Ore Grinding", + "gtceu.recipe.category.ore_forging": "Ore Crushing", "gtceu.recipe.chance": "Chance: %s +%s/tier", "gtceu.recipe.cleanroom": "Requires %s", "gtceu.recipe.cleanroom.display_name": "Cleanroom", @@ -3424,9 +3732,14 @@ "gtceu.tool_action.wire_cutter.connect": "§8Use Wire Cutters to set Connections", "gtceu.tool_action.wrench.connect": "§8Use Wrench to set Connections, sneak to block Connections", "gtceu.tool_action.wrench.set_facing": "§8Use Wrench to set Facing", + "gtceu.tooltip.computer_monitor_config": "Storing computer monitor cover configuration data", + "gtceu.tooltip.computer_monitor_data": "Storing data: %s", "gtceu.tooltip.fluid_pipe_hold_shift": "§7Hold SHIFT to show Fluid Containment Info", "gtceu.tooltip.hold_ctrl": "§7Hold CTRL for more info", "gtceu.tooltip.hold_shift": "§7Hold SHIFT for more info", + "gtceu.tooltip.player_bind": "Bound to player: %s", + "gtceu.tooltip.player_name.placeholder_processor": "Placeholder processor", + "gtceu.tooltip.player_name.unknown": "Unknown player", "gtceu.tooltip.potion.each": "%s %s §7for§r %s §7ticks with a§r %s%% §7chance of happening§r", "gtceu.tooltip.potion.header": "§6Contains effects:", "gtceu.tooltip.proxy_bind": "§fBinding to a Pattern Buffer at %s %s %s", @@ -3434,6 +3747,7 @@ "gtceu.tooltip.status.trinary.true": "True", "gtceu.tooltip.status.trinary.unknown": "Unknown", "gtceu.tooltip.tool_fluid_hold_shift": "§7Hold SHIFT to show Fluid Containment and Tool Info", + "gtceu.tooltip.wireless_transmitter_bind": "Binding to a transmitter cover at %s %s %s facing %s in %s", "gtceu.top.allow_output_input": "Allow Input", "gtceu.top.auto_output": "Auto Output", "gtceu.top.buffer_bound_pos": "Bound To - X: %s, Y: %s, Z: %s", @@ -3485,6 +3799,10 @@ "gtceu.universal.clear_nbt_recipe.tooltip": "§cThis will destroy all contents!", "gtceu.universal.kiloliters": "%s B", "gtceu.universal.liters": "%s mB", + "gtceu.universal.padded_parentheses": " (%s) ", + "gtceu.universal.padded_spaced_parentheses": " ( %s ) ", + "gtceu.universal.parentheses": "(%s)", + "gtceu.universal.spaced_parentheses": "( %s )", "gtceu.universal.tooltip.amperage_in": "§eAmperage IN: §f%dA", "gtceu.universal.tooltip.amperage_in_out": "§eAmperage IN/OUT: §f%dA", "gtceu.universal.tooltip.amperage_in_out_till": "§eAmperage IN/OUT up to: §f%dA", @@ -3709,6 +4027,8 @@ "item.gtceu.empty_wooden_form": "Empty Wooden Form", "item.gtceu.ender_fluid_link_cover": "Ender Fluid Link", "item.gtceu.ender_fluid_link_cover.tooltip": "§7Transports §fFluids§7 with a §fWireless §dEnder§f Connection§7 as §fCover§7.", + "item.gtceu.ender_item_link_cover": "Ender Item Link", + "item.gtceu.ender_redstone_link_cover": "Ender Redstone Link", "item.gtceu.energium_dust": "Energium Dust", "item.gtceu.energy_cluster": "Energy Cluster", "item.gtceu.energy_cluster.tooltip": "§7Reusable Battery", @@ -3745,7 +4065,7 @@ "item.gtceu.exquisite_glass_gem": "Exquisite Glass Crystal", "item.gtceu.facade_cover": "%s Cover Facade", "item.gtceu.facade_cover.tooltip.0": "§7Decorative Outfit §fCover§7.", - "item.gtceu.facade_cover.tooltip.1": "§7Crafted using 3 Iron Plates and any block", + "item.gtceu.facade_cover.tooltip.1": "§7Crafted using an Iron Plate and any block", "item.gtceu.face_mask": "Face Mask", "item.gtceu.fertilizer": "Fertilizer", "item.gtceu.fiber_reinforced_circuit_board": "Fiber-Reinforced Circuit Board", @@ -3820,6 +4140,7 @@ "item.gtceu.hpic_chip.tooltip": "§7High Power IC", "item.gtceu.hpic_wafer": "HPIC Wafer", "item.gtceu.hpic_wafer.tooltip": "§7Raw High Power Circuit", + "item.gtceu.huge_pipe_casting_mold": "Casting Mold (Huge Pipe)", "item.gtceu.huge_pipe_extruder_mold": "Extruder Mold (Huge Pipe)", "item.gtceu.hv_battery_hull": "Large Battery Hull", "item.gtceu.hv_battery_hull.tooltip": "§7An empty §6HV §7Battery Hull", @@ -3848,6 +4169,7 @@ "item.gtceu.ilc_chip.tooltip": "§7Integrated Logic Circuit", "item.gtceu.ilc_wafer": "ILC Wafer", "item.gtceu.ilc_wafer.tooltip": "§7Raw Integrated Circuit", + "item.gtceu.image_module": "Image Module", "item.gtceu.impure_bentonite_dust": "Impure Pile of Bentonite", "item.gtceu.impure_cassiterite_sand_dust": "Impure Pile of Cassiterite Sand", "item.gtceu.impure_pitchblende_dust": "Impure Pile of Pitchblende", @@ -3900,6 +4222,7 @@ "item.gtceu.lapotronic_energy_orb.tooltip": "§7Reusable Battery", "item.gtceu.lapotronic_energy_orb_cluster": "Lapotronic Energy Orb Cluster", "item.gtceu.lapotronic_energy_orb_cluster.tooltip": "§7Reusable Battery", + "item.gtceu.large_pipe_casting_mold": "Casting Mold (Large Pipe)", "item.gtceu.large_pipe_extruder_mold": "Extruder Mold (Large Pipe)", "item.gtceu.light_blue_dye_spray_can": "Spray Can (Light Blue)", "item.gtceu.light_blue_glass_lens": "Glass Lens (Light Blue)", @@ -4059,6 +4382,7 @@ "item.gtceu.nor_memory_chip.tooltip": "§7NOR Logic Gate", "item.gtceu.nor_memory_wafer": "NOR Memory Wafer", "item.gtceu.nor_memory_wafer.tooltip": "§7Raw Logic Gate", + "item.gtceu.normal_pipe_casting_mold": "Casting Mold (Normal Pipe)", "item.gtceu.normal_pipe_extruder_mold": "Extruder Mold (Normal Pipe)", "item.gtceu.nugget_casting_mold": "Casting Mold (Nugget)", "item.gtceu.nugget_casting_mold.tooltip": "§7Mold for making Nuggets", @@ -4229,6 +4553,7 @@ "item.gtceu.small_meat_dust": "Small Pile of Mince Meat", "item.gtceu.small_palladium_raw_dust": "Small Pile of Raw Palladium Powder", "item.gtceu.small_paper_dust": "Small Pile of Chad", + "item.gtceu.small_pipe_casting_mold": "Casting Mold (Small Pipe)", "item.gtceu.small_pipe_extruder_mold": "Extruder Mold (Small Pipe)", "item.gtceu.small_pitchblende_dust": "Small Pile of Pitchblende", "item.gtceu.small_platinum_group_sludge_dust": "Small Clump of Platinum Group Sludge", @@ -4282,6 +4607,7 @@ "item.gtceu.tantalum_capacitor": "Tantalum Capacitor", "item.gtceu.terminal": "Terminal", "item.gtceu.terminal.tooltip": "Shift + R-Click on a controller to automatically build the multiblock", + "item.gtceu.text_module": "Text Module", "item.gtceu.tiny_ash_dust": "Tiny Pile of Ashes", "item.gtceu.tiny_basaltic_mineral_sand_dust": "Tiny Pile of Basaltic Mineral Sand", "item.gtceu.tiny_bentonite_dust": "Tiny Pile of Bentonite", @@ -4300,6 +4626,7 @@ "item.gtceu.tiny_meat_dust": "Tiny Pile of Mince Meat", "item.gtceu.tiny_palladium_raw_dust": "Tiny Pile of Raw Palladium Powder", "item.gtceu.tiny_paper_dust": "Tiny Pile of Chad", + "item.gtceu.tiny_pipe_casting_mold": "Casting Mold (Tiny Pipe)", "item.gtceu.tiny_pipe_extruder_mold": "Extruder Mold (Tiny Pipe)", "item.gtceu.tiny_pitchblende_dust": "Tiny Pile of Pitchblende", "item.gtceu.tiny_platinum_group_sludge_dust": "Tiny Clump of Platinum Group Sludge", @@ -4324,9 +4651,15 @@ "item.gtceu.tool.behavior.block_rotation": "§2Mechanic: §fRotates Blocks", "item.gtceu.tool.behavior.crop_harvesting": "§aHarvester: §fHarvests Crops", "item.gtceu.tool.behavior.damage_boost": "§4Damage Boost: §fExtra damage against %s", + "item.gtceu.tool.behavior.dowse_campfire": "§1Firefighter: §fDowses Campfires", "item.gtceu.tool.behavior.grass_path": "§eLandscaper: §fCreates Grass Paths", "item.gtceu.tool.behavior.ground_tilling": "§eFarmer: §fTills Ground", "item.gtceu.tool.behavior.plunger": "§9Plumber: §fDrains Fluids", + "item.gtceu.tool.behavior.prospecting.air": "Found an air pocket", + "item.gtceu.tool.behavior.prospecting.changing": "Detected material change", + "item.gtceu.tool.behavior.prospecting.lava": "Found lava", + "item.gtceu.tool.behavior.prospecting.ore": "Found ore: %s", + "item.gtceu.tool.behavior.prospecting.water": "Found water", "item.gtceu.tool.behavior.rail_rotation": "§eRailroad Engineer: §fRotates Rails", "item.gtceu.tool.behavior.relocate_mining": "§2Magnetic: §fRelocates Mined Blocks and Mob Drops", "item.gtceu.tool.behavior.remove_wax": "§6Cleaner: §fRemoves Wax", @@ -4514,6 +4847,7 @@ "item.gtceu.white_dye_spray_can": "Spray Can (White)", "item.gtceu.wire_extruder_mold": "Extruder Mold (Wire)", "item.gtceu.wire_extruder_mold.tooltip": "§7Extruder Shape for making Wires", + "item.gtceu.wireless_transmitter_cover": "Wireless Transmitter", "item.gtceu.wood_bolt": "Short Wood Stick", "item.gtceu.wood_dust": "Wood Pulp", "item.gtceu.wood_plate": "Wood Plank", @@ -5352,6 +5686,7 @@ "recipe.capability.fluid.name": "Fluid", "recipe.capability.item.name": "Item", "recipe.condition.adjacent_block.tooltip": "Blocks around", + "recipe.condition.adjacent_fluid.tooltip": "Fluid blocks around", "recipe.condition.biome.tooltip": "Biome: %s", "recipe.condition.daytime.day.tooltip": "Requires day time to work", "recipe.condition.daytime.night.tooltip": "Requires night time to work", @@ -5364,17 +5699,8 @@ "recipe.condition.quest.completed.tooltip": "Requires %s completed", "recipe.condition.quest.not_completed.tooltip": "Requires %s not completed", "recipe.condition.rain.tooltip": "Rain Level: %d", - "recipe.condition.rock_breaker.tooltip": "Fluid blocks around", "recipe.condition.steam_vent.tooltip": "Clean steam vent", "recipe.condition.thunder.tooltip": "Thunder Level: %d", - "recipe_category.gtceu.arc_furnace_recycling": "Plasma Scrapping", - "recipe_category.gtceu.chem_dyes": "Chemical Dyeing", - "recipe_category.gtceu.extractor_recycling": "Scrap Remelting", - "recipe_category.gtceu.ingot_molding": "Metal Molding", - "recipe_category.gtceu.macerator_recycling": "Part Grinding", - "recipe_category.gtceu.ore_bathing": "Ore Treating", - "recipe_category.gtceu.ore_crushing": "Ore Grinding", - "recipe_category.gtceu.ore_forging": "Ore Crushing", "recipe_type.gtceu.air_scrubber": "Air Scrubber", "recipe_type.gtceu.alloy_blast_smelter": "Alloy Blast Smelter", "recipe_type.gtceu.alloy_smelter": "Alloy Smelter", diff --git a/src/generated/resources/assets/gtceu/models/block/creosote.json b/src/generated/resources/assets/gtceu/models/block/creosote.json new file mode 100644 index 00000000000..5a8d6c2dfd3 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/block/creosote.json @@ -0,0 +1,5 @@ +{ + "textures": { + "particle": "gtceu:block/fluids/fluid.creosote" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/machine/advanced_data_access_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/advanced_data_access_hatch.json index 10bbd89b8e4..ba019b0899b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/advanced_data_access_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/advanced_data_access_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/data_access_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/data_access_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/advanced_monitor.json b/src/generated/resources/assets/gtceu/models/block/machine/advanced_monitor.json new file mode 100644 index 00000000000..69296236c31 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/block/machine/advanced_monitor.json @@ -0,0 +1,18 @@ +{ + "parent": "minecraft:block/block", + "loader": "gtceu:machine", + "machine": "gtceu:advanced_monitor", + "replaceable_textures": [ + "all" + ], + "variants": { + "": { + "model": { + "parent": "gtceu:block/machine/part/computer_monitor", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_clean_stainless_steel" + } + } + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/machine/auto_maintenance_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/auto_maintenance_hatch.json index 60292c3c963..87e2b046507 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/auto_maintenance_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/auto_maintenance_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/auto_maintenance_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/auto_maintenance_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/basic_data_access_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/basic_data_access_hatch.json new file mode 100644 index 00000000000..88a88153e22 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/block/machine/basic_data_access_hatch.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:block/block", + "loader": "gtceu:machine", + "machine": "gtceu:basic_data_access_hatch", + "replaceable_textures": [ + "bottom", + "top", + "side" + ], + "variants": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/data_access_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true": { + "model": { + "parent": "gtceu:block/machine/part/data_access_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/machine/bronze_multiblock_tank.json b/src/generated/resources/assets/gtceu/models/block/machine/bronze_multiblock_tank.json new file mode 100644 index 00000000000..66d5de566cc --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/block/machine/bronze_multiblock_tank.json @@ -0,0 +1,82 @@ +{ + "parent": "minecraft:block/block", + "loader": "gtceu:machine", + "machine": "gtceu:bronze_multiblock_tank", + "texture_overrides": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks" + }, + "variants": { + "is_formed=false,recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/multiblock_tank/overlay_front" + } + } + }, + "is_formed=false,recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/multiblock_tank/overlay_front" + } + } + }, + "is_formed=false,recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/multiblock_tank/overlay_front_active" + } + } + }, + "is_formed=false,recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/multiblock_tank/overlay_front_active" + } + } + }, + "is_formed=true,recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/multiblock_tank/overlay_front" + } + } + }, + "is_formed=true,recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/multiblock_tank/overlay_front" + } + } + }, + "is_formed=true,recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/multiblock_tank/overlay_front_active" + } + } + }, + "is_formed=true,recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/multiblock_tank/overlay_front_active" + } + } + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/machine/bronze_tank_valve.json b/src/generated/resources/assets/gtceu/models/block/machine/bronze_tank_valve.json new file mode 100644 index 00000000000..d92b5d82639 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/block/machine/bronze_tank_valve.json @@ -0,0 +1,46 @@ +{ + "parent": "minecraft:block/block", + "loader": "gtceu:machine", + "machine": "gtceu:bronze_tank_valve", + "texture_overrides": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks" + }, + "variants": { + "recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/tank_valve/overlay_front" + } + } + }, + "recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/tank_valve/overlay_front" + } + } + }, + "recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/tank_valve/overlay_front_active" + } + } + }, + "recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_bronze_plated_bricks", + "overlay_front": "gtceu:block/multiblock/tank_valve/overlay_front_active" + } + } + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/machine/central_monitor.json b/src/generated/resources/assets/gtceu/models/block/machine/central_monitor.json new file mode 100644 index 00000000000..4338202c509 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/block/machine/central_monitor.json @@ -0,0 +1,91 @@ +{ + "parent": "minecraft:block/block", + "dynamic_renders": [ + { + "type": "gtceu:central_monitor" + } + ], + "loader": "gtceu:machine", + "machine": "gtceu:central_monitor", + "texture_overrides": { + "all": "gtceu:block/casings/solid/machine_casing_frost_proof" + }, + "variants": { + "is_formed=false,recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_frost_proof", + "overlay_front": "gtceu:block/multiblock/central_monitor/overlay_front" + } + } + }, + "is_formed=false,recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_frost_proof", + "overlay_front": "gtceu:block/multiblock/central_monitor/overlay_front" + } + } + }, + "is_formed=false,recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_frost_proof", + "overlay_front": "gtceu:block/multiblock/central_monitor/overlay_front_active", + "overlay_front_emissive": "gtceu:block/multiblock/central_monitor/overlay_front_active_emissive" + } + } + }, + "is_formed=false,recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_frost_proof", + "overlay_front": "gtceu:block/multiblock/central_monitor/overlay_front_active", + "overlay_front_emissive": "gtceu:block/multiblock/central_monitor/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_frost_proof", + "overlay_front": "gtceu:block/multiblock/central_monitor/overlay_front" + } + } + }, + "is_formed=true,recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_frost_proof", + "overlay_front": "gtceu:block/multiblock/central_monitor/overlay_front" + } + } + }, + "is_formed=true,recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_frost_proof", + "overlay_front": "gtceu:block/multiblock/central_monitor/overlay_front_active", + "overlay_front_emissive": "gtceu:block/multiblock/central_monitor/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/machine/template/cube_all/sided", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_frost_proof", + "overlay_front": "gtceu:block/multiblock/central_monitor/overlay_front_active", + "overlay_front_emissive": "gtceu:block/multiblock/central_monitor/overlay_front_active_emissive" + } + } + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/machine/cleaning_maintenance_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/cleaning_maintenance_hatch.json index ce3a7a0607d..a2649620060 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/cleaning_maintenance_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/cleaning_maintenance_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/cleaning_maintenance_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/cleaning_maintenance_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/coke_oven_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/coke_oven_hatch.json index 0235d154b2d..c480f1a9150 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/coke_oven_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/coke_oven_hatch.json @@ -3,7 +3,10 @@ "loader": "gtceu:machine", "machine": "gtceu:coke_oven_hatch", "variants": { - "": { + "is_formed=false": { + "model": "gtceu:block/machine/part/coke_oven_hatch" + }, + "is_formed=true": { "model": "gtceu:block/machine/part/coke_oven_hatch" } } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/computation_receiver_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/computation_receiver_hatch.json index 1dc40dfd92d..5adc0f5928e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/computation_receiver_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/computation_receiver_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/computation_data_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/computation_data_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/computation_transmitter_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/computation_transmitter_hatch.json index b0a1c7d676e..c4b1a93b2db 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/computation_transmitter_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/computation_transmitter_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/computation_data_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/computation_data_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/configurable_maintenance_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/configurable_maintenance_hatch.json index 8ee342abf3c..9d6f781cb12 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/configurable_maintenance_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/configurable_maintenance_hatch.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "maintenance_taped=false": { + "is_formed=false,taped=false": { "model": { "parent": "gtceu:block/machine/part/configurable_maintenance_hatch", "textures": { @@ -18,7 +18,28 @@ } } }, - "maintenance_taped=true": { + "is_formed=false,taped=true": { + "model": { + "parent": "gtceu:block/machine/part/configurable_maintenance_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay_2": "gtceu:block/overlay/machine/overlay_maintenance_taped", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true,taped=false": { + "model": { + "parent": "gtceu:block/machine/part/configurable_maintenance_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true,taped=true": { "model": { "parent": "gtceu:block/machine/part/configurable_maintenance_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/creative_data_access_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/creative_data_access_hatch.json index 267ccef500b..4034ec51e23 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/creative_data_access_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/creative_data_access_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/data_access_hatch_creative", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/data_access_hatch_creative", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/data_access_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/data_access_hatch.json index 0966d8eba3d..256066936bf 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/data_access_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/data_access_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/data_access_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/data_access_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/data_receiver_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/data_receiver_hatch.json index 6e0d9f6be76..71b2ca63a24 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/data_receiver_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/data_receiver_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/optical_data_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/optical_data_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/data_transmitter_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/data_transmitter_hatch.json index 7d1ddf88a1e..9b35f637b5f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/data_transmitter_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/data_transmitter_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/optical_data_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/optical_data_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_diode.json index 659edd8ef6f..6a49e78736c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch.json index 2e4f9313e7e..0b9a5ee4747 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch_16a.json index 4099879fb9f..d9330a9b185 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch_4a.json index f03abb044f5..c8debf45479 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_input_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch.json index 1c4f6c5f5d5..81b92ce2c7b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch_16a.json index 8bd01d6f67d..6d82d6250d0 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch_4a.json index eaf5c83cc63..bcd2feaed63 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_energy_output_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_fluid_passthrough_hatch.json index 4c3a7c1ca6f..8976104b991 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_input_bus.json index 7f9d2f70f7b..a72b8dace02 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch.json index efecd1b02d0..7b38140a631 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch_4x.json index 6f2fc8736cf..4eedf069577 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch_9x.json index d0de36ffe26..2aabf576bbb 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_input_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_item_passthrough_hatch.json index cfcf7a766fa..a8a52de7144 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_machine_hull.json index e356e1c3c21..aee1c97664d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_muffler_hatch.json index cb81618de42..cfd8c34395c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_output_bus.json index b58ff04e5b8..f06c85a1936 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch.json index 4fdcc38ed1e..111c19a94b6 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch_4x.json index ec75f0fbb09..eeef73ed939 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch_9x.json index 79e5298133f..e01f2916794 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_output_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/ev/side", "top": "gtceu:block/casings/voltage/ev/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_substation_input_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_substation_input_hatch_64a.json index 15e4aa5076e..2e0b2066144 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_substation_input_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_substation_input_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ev_substation_output_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/ev_substation_output_hatch_64a.json index e9c107084d6..a9d5cc99e07 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ev_substation_output_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ev_substation_output_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hpca_active_cooler_component.json b/src/generated/resources/assets/gtceu/models/block/machine/hpca_active_cooler_component.json index b0f5d280484..abc691fb953 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hpca_active_cooler_component.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hpca_active_cooler_component.json @@ -3,7 +3,7 @@ "loader": "gtceu:machine", "machine": "gtceu:hpca_active_cooler_component", "variants": { - "active=false,hpca_part_damaged=false": { + "active=false,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_active_cooler_component_base", "textures": { @@ -12,7 +12,25 @@ } } }, - "active=false,hpca_part_damaged=true": { + "active=false,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_active_cooler_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/active_cooler", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_active_cooler_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged_advanced", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_active_cooler_component_base", "textures": { @@ -21,7 +39,7 @@ } } }, - "active=true,hpca_part_damaged=false": { + "active=true,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_active_cooler_component_base", "textures": { @@ -30,7 +48,25 @@ } } }, - "active=true,hpca_part_damaged=true": { + "active=true,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_active_cooler_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/active_cooler_active", + "overlay_emissive": "gtceu:block/overlay/machine/hpca/active_cooler_active_emissive" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_active_cooler_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged_advanced_active", + "overlay_emissive": "gtceu:block/overlay/machine/hpca/damaged_advanced_active_emissive" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_active_cooler_component_base", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hpca_advanced_computation_component.json b/src/generated/resources/assets/gtceu/models/block/machine/hpca_advanced_computation_component.json index df8d1e8639a..41065d1330a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hpca_advanced_computation_component.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hpca_advanced_computation_component.json @@ -3,7 +3,7 @@ "loader": "gtceu:machine", "machine": "gtceu:hpca_advanced_computation_component", "variants": { - "active=false,hpca_part_damaged=false": { + "active=false,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_advanced_computation_component_base", "textures": { @@ -12,7 +12,25 @@ } } }, - "active=false,hpca_part_damaged=true": { + "active=false,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_advanced_computation_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/advanced_computation", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_advanced_computation_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged_advanced", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_advanced_computation_component_base", "textures": { @@ -21,7 +39,7 @@ } } }, - "active=true,hpca_part_damaged=false": { + "active=true,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_advanced_computation_component_base", "textures": { @@ -30,7 +48,25 @@ } } }, - "active=true,hpca_part_damaged=true": { + "active=true,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_advanced_computation_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/advanced_computation_active", + "overlay_emissive": "gtceu:block/overlay/machine/hpca/advanced_computation_active_emissive" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_advanced_computation_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged_advanced_active", + "overlay_emissive": "gtceu:block/overlay/machine/hpca/damaged_advanced_active_emissive" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_advanced_computation_component_base", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hpca_bridge_component.json b/src/generated/resources/assets/gtceu/models/block/machine/hpca_bridge_component.json index e4c8817151b..03943419e80 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hpca_bridge_component.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hpca_bridge_component.json @@ -3,7 +3,7 @@ "loader": "gtceu:machine", "machine": "gtceu:hpca_bridge_component", "variants": { - "active=false,hpca_part_damaged=false": { + "active=false,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_bridge_component_base", "textures": { @@ -12,7 +12,25 @@ } } }, - "active=false,hpca_part_damaged=true": { + "active=false,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_bridge_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/bridge", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_bridge_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_bridge_component_base", "textures": { @@ -21,7 +39,7 @@ } } }, - "active=true,hpca_part_damaged=false": { + "active=true,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_bridge_component_base", "textures": { @@ -30,7 +48,25 @@ } } }, - "active=true,hpca_part_damaged=true": { + "active=true,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_bridge_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/bridge_active", + "overlay_emissive": "gtceu:block/overlay/machine/hpca/bridge_active_emissive" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_bridge_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged_active", + "overlay_emissive": "gtceu:block/overlay/machine/hpca/damaged_active_emissive" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_bridge_component_base", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hpca_computation_component.json b/src/generated/resources/assets/gtceu/models/block/machine/hpca_computation_component.json index 1600d6b1786..7fda37b7b7d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hpca_computation_component.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hpca_computation_component.json @@ -3,7 +3,7 @@ "loader": "gtceu:machine", "machine": "gtceu:hpca_computation_component", "variants": { - "active=false,hpca_part_damaged=false": { + "active=false,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_computation_component_base", "textures": { @@ -12,7 +12,25 @@ } } }, - "active=false,hpca_part_damaged=true": { + "active=false,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_computation_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/computation", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_computation_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_computation_component_base", "textures": { @@ -21,7 +39,7 @@ } } }, - "active=true,hpca_part_damaged=false": { + "active=true,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_computation_component_base", "textures": { @@ -30,7 +48,25 @@ } } }, - "active=true,hpca_part_damaged=true": { + "active=true,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_computation_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/computation_active", + "overlay_emissive": "gtceu:block/overlay/machine/hpca/computation_active_emissive" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_computation_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged_active", + "overlay_emissive": "gtceu:block/overlay/machine/hpca/damaged_active_emissive" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_computation_component_base", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hpca_empty_component.json b/src/generated/resources/assets/gtceu/models/block/machine/hpca_empty_component.json index fe2e519ed92..c9904115bcd 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hpca_empty_component.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hpca_empty_component.json @@ -3,7 +3,7 @@ "loader": "gtceu:machine", "machine": "gtceu:hpca_empty_component", "variants": { - "active=false,hpca_part_damaged=false": { + "active=false,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_empty_component_base", "textures": { @@ -12,7 +12,25 @@ } } }, - "active=false,hpca_part_damaged=true": { + "active=false,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_empty_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/empty", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_empty_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_empty_component_base", "textures": { @@ -21,7 +39,7 @@ } } }, - "active=true,hpca_part_damaged=false": { + "active=true,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_empty_component_base", "textures": { @@ -30,7 +48,25 @@ } } }, - "active=true,hpca_part_damaged=true": { + "active=true,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_empty_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/empty", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_empty_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged_active", + "overlay_emissive": "gtceu:block/overlay/machine/hpca/damaged_active_emissive" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_empty_component_base", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hpca_heat_sink_component.json b/src/generated/resources/assets/gtceu/models/block/machine/hpca_heat_sink_component.json index 666bf85cf40..d4696438a37 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hpca_heat_sink_component.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hpca_heat_sink_component.json @@ -3,7 +3,7 @@ "loader": "gtceu:machine", "machine": "gtceu:hpca_heat_sink_component", "variants": { - "active=false,hpca_part_damaged=false": { + "active=false,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_heat_sink_component_base", "textures": { @@ -12,7 +12,25 @@ } } }, - "active=false,hpca_part_damaged=true": { + "active=false,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_heat_sink_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/heat_sink", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_heat_sink_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=false,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_heat_sink_component_base", "textures": { @@ -21,7 +39,7 @@ } } }, - "active=true,hpca_part_damaged=false": { + "active=true,hpca_part_damaged=false,is_formed=false": { "model": { "parent": "gtceu:block/hpca_heat_sink_component_base", "textures": { @@ -30,7 +48,25 @@ } } }, - "active=true,hpca_part_damaged=true": { + "active=true,hpca_part_damaged=false,is_formed=true": { + "model": { + "parent": "gtceu:block/hpca_heat_sink_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/heat_sink", + "overlay_emissive": "gtceu:block/void" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=false": { + "model": { + "parent": "gtceu:block/hpca_heat_sink_component_base", + "textures": { + "overlay": "gtceu:block/overlay/machine/hpca/damaged_active", + "overlay_emissive": "gtceu:block/overlay/machine/hpca/damaged_active_emissive" + } + } + }, + "active=true,hpca_part_damaged=true,is_formed=true": { "model": { "parent": "gtceu:block/hpca_heat_sink_component_base", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hv_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/hv_diode.json index fa66ac0661c..a0c4cd9842a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hv_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hv_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hv_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/hv_energy_input_hatch.json index 579d2214ce9..609d68c709a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hv_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hv_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hv_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/hv_energy_output_hatch.json index 26e409438ec..6e598bdc482 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hv_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hv_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hv_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/hv_fluid_passthrough_hatch.json index a993932404e..d06634caec3 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hv_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hv_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hv_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/hv_input_bus.json index 23e0525e931..d5a54b10d03 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hv_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hv_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/hv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/hv/side", "top": "gtceu:block/casings/voltage/hv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/hv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/hv/side", "top": "gtceu:block/casings/voltage/hv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hv_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/hv_input_hatch.json index f7b8f2a3f5b..56b5214520e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hv_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hv_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/hv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/hv/side", "top": "gtceu:block/casings/voltage/hv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/hv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/hv/side", "top": "gtceu:block/casings/voltage/hv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hv_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/hv_item_passthrough_hatch.json index a5ea4e721cb..fa9a87cb3ab 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hv_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hv_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hv_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/hv_machine_hull.json index ffe79962ec4..8ab6463529e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hv_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hv_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hv_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/hv_muffler_hatch.json index f9429517ca2..97461841db2 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hv_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hv_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hv_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/hv_output_bus.json index da7fb8f1b67..80b310824b3 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hv_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hv_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/hv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/hv/side", "top": "gtceu:block/casings/voltage/hv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/hv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/hv/side", "top": "gtceu:block/casings/voltage/hv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/hv_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/hv_output_hatch.json index 70c78f93437..02b696b3596 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/hv_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/hv_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/hv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/hv/side", "top": "gtceu:block/casings/voltage/hv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/hv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/hv/side", + "top": "gtceu:block/casings/voltage/hv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/hv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/hv/side", "top": "gtceu:block/casings/voltage/hv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_1024a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_1024a_laser_source_hatch.json index d4ba77f4c93..737c6e3f30a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_1024a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_1024a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_1024a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_1024a_laser_target_hatch.json index 8f7ccb2c1f2..ee526d18433 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_1024a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_1024a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_256a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_256a_laser_source_hatch.json index 9dc9fcfb4e4..69480fee1cb 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_256a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_256a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_256a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_256a_laser_target_hatch.json index 5c28623e9e7..11e7446c6de 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_256a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_256a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_4096a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_4096a_laser_source_hatch.json index 94384e08e5f..a6cc918a762 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_4096a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_4096a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_4096a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_4096a_laser_target_hatch.json index a66f3ea2c44..e69c4ed3364 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_4096a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_4096a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_diode.json index c8b7925b9f5..b2c78cf0194 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch.json index 0e67bae30d4..4e12141f061 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch_16a.json index 47076302c3a..ffb376c93ec 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch_4a.json index d7940c03a49..0e5f0d79080 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_input_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch.json index a60df0d3f94..f0b759319fc 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch_16a.json index 8e9c1b819dc..70f34d90710 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch_4a.json index 7d0fcc898b6..93989e705a6 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_energy_output_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_fluid_passthrough_hatch.json index 8c585259a52..9b0ff535dc7 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_input_bus.json index 148bb460215..02e43a30412 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch.json index d748e8c964d..b5e16d3faa8 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch_4x.json index 608127e2d66..ef6e2c81cd9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch_9x.json index 82d4f1a4f5c..52e705c76c4 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_input_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_item_passthrough_hatch.json index 215bf33b680..576b40ea808 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_machine_hull.json index 38955082c00..f434e8e4f5d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_muffler_hatch.json index a33b34d3b9a..6d897a1f7e6 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_output_bus.json index 17c137b97f6..6586099fe26 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch.json index 512b3e3d307..364fdc6ea19 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch_4x.json index 537928513f5..1db248685c0 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch_9x.json index 08613a16eb5..f8c6d95d194 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_output_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/iv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/iv/side", "top": "gtceu:block/casings/voltage/iv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_parallel_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_parallel_hatch.json index 4de920f1e5c..57c001fb4a2 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_parallel_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_parallel_hatch.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "recipe_logic_status=idle": { + "is_formed=false,recipe_logic_status=idle": { "model": { "parent": "gtceu:block/casings/voltage/iv", "textures": { @@ -17,7 +17,7 @@ } } }, - "recipe_logic_status=suspend": { + "is_formed=false,recipe_logic_status=suspend": { "model": { "parent": "gtceu:block/casings/voltage/iv", "textures": { @@ -26,7 +26,7 @@ } } }, - "recipe_logic_status=waiting": { + "is_formed=false,recipe_logic_status=waiting": { "model": { "parent": "gtceu:block/casings/voltage/iv", "textures": { @@ -35,7 +35,43 @@ } } }, - "recipe_logic_status=working": { + "is_formed=false,recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/casings/voltage/iv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk1/overlay_front_active", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk1/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/casings/voltage/iv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk1/overlay_front", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk1/overlay_front_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/casings/voltage/iv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk1/overlay_front", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk1/overlay_front_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/casings/voltage/iv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk1/overlay_front_active", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk1/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=working": { "model": { "parent": "gtceu:block/casings/voltage/iv", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_substation_input_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_substation_input_hatch_64a.json index 645a9496475..fe9183f4de9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_substation_input_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_substation_input_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/iv_substation_output_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/iv_substation_output_hatch_64a.json index 1600057a2e8..bd403f2ef80 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/iv_substation_output_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/iv_substation_output_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/iv/bottom", + "side": "gtceu:block/casings/voltage/iv/side", + "top": "gtceu:block/casings/voltage/iv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/long_distance_fluid_pipeline_endpoint.json b/src/generated/resources/assets/gtceu/models/block/machine/long_distance_fluid_pipeline_endpoint.json new file mode 100644 index 00000000000..23423a5c433 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/block/machine/long_distance_fluid_pipeline_endpoint.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:block/block", + "loader": "gtceu:machine", + "machine": "gtceu:long_distance_fluid_pipeline_endpoint", + "replaceable_textures": [ + "bottom", + "top", + "side" + ], + "variants": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/long_distance_fluid_pipeline_endpoint", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true": { + "model": { + "parent": "gtceu:block/machine/part/long_distance_fluid_pipeline_endpoint", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/machine/long_distance_item_pipeline_endpoint.json b/src/generated/resources/assets/gtceu/models/block/machine/long_distance_item_pipeline_endpoint.json new file mode 100644 index 00000000000..894f84c0a64 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/block/machine/long_distance_item_pipeline_endpoint.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:block/block", + "loader": "gtceu:machine", + "machine": "gtceu:long_distance_item_pipeline_endpoint", + "replaceable_textures": [ + "bottom", + "top", + "side" + ], + "variants": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/long_distance_item_pipeline_endpoint", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true": { + "model": { + "parent": "gtceu:block/machine/part/long_distance_item_pipeline_endpoint", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_1024a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_1024a_laser_source_hatch.json index 721b59367bf..00392dbe6c3 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_1024a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_1024a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_1024a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_1024a_laser_target_hatch.json index 0090c9e0c60..a3f7bfbfe5b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_1024a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_1024a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_256a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_256a_laser_source_hatch.json index f24ceea29fe..675b76ec3aa 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_256a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_256a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_256a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_256a_laser_target_hatch.json index f0f4ca7d914..e0d0d639ba2 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_256a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_256a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_4096a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_4096a_laser_source_hatch.json index d1a2e14d183..9c3c2df4fda 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_4096a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_4096a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_4096a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_4096a_laser_target_hatch.json index de039ba10b3..4cf7853a1a0 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_4096a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_4096a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_diode.json index c542cb05a8a..03f8de38d51 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_dual_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_dual_input_hatch.json index 27694fbdc76..5d0a6f97c7c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_dual_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_dual_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_dual_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_dual_output_hatch.json index 9c768fdec87..c58d1299843 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_dual_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_dual_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch.json index d1488f2ed36..6518570762c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch_16a.json index 1152f0e7055..63b42d32951 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch_4a.json index 0bb381bf8dd..820f55dbbcb 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_input_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch.json index 3c1a1f53ac2..17fa00a5d4c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch_16a.json index 95b4c4363dc..7077fc0349f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch_4a.json index 3d6b85e12c6..2ecba7aecab 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_energy_output_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_fluid_passthrough_hatch.json index ca14a893b8e..81f6780fb8e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_input_bus.json index 1aaaf9fd4d5..5790f115f40 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch.json index f7b9387bf0b..565dbda1fa2 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch_4x.json index bd215f6e45c..f7d97f42b79 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch_9x.json index 5988b934e6d..94d2c9a3493 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_input_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_item_passthrough_hatch.json index 0c56751c24c..1025757799b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_machine_hull.json index 774d7ebabbf..98f10d544cb 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_muffler_hatch.json index 6b9de45e7a5..a1fab17a813 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_output_bus.json index 15d94b91701..a10842413fc 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch.json index 4cf271e9953..630520f90f4 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch_4x.json index a84a29e1490..ebc70f2f484 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch_9x.json index 1daa812696b..3d793ee2d17 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_output_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/luv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/luv/side", "top": "gtceu:block/casings/voltage/luv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_parallel_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_parallel_hatch.json index 2ee9370463a..be5e91ba684 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_parallel_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_parallel_hatch.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "recipe_logic_status=idle": { + "is_formed=false,recipe_logic_status=idle": { "model": { "parent": "gtceu:block/casings/voltage/luv", "textures": { @@ -17,7 +17,7 @@ } } }, - "recipe_logic_status=suspend": { + "is_formed=false,recipe_logic_status=suspend": { "model": { "parent": "gtceu:block/casings/voltage/luv", "textures": { @@ -26,7 +26,7 @@ } } }, - "recipe_logic_status=waiting": { + "is_formed=false,recipe_logic_status=waiting": { "model": { "parent": "gtceu:block/casings/voltage/luv", "textures": { @@ -35,7 +35,43 @@ } } }, - "recipe_logic_status=working": { + "is_formed=false,recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/casings/voltage/luv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk2/overlay_front_active", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk2/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/casings/voltage/luv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk2/overlay_front", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk2/overlay_front_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/casings/voltage/luv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk2/overlay_front", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk2/overlay_front_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/casings/voltage/luv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk2/overlay_front_active", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk2/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=working": { "model": { "parent": "gtceu:block/casings/voltage/luv", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_substation_input_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_substation_input_hatch_64a.json index dbdfe76c591..3d8c084e2e4 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_substation_input_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_substation_input_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/luv_substation_output_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/luv_substation_output_hatch_64a.json index b8f2cdebd80..2db55d9f65a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/luv_substation_output_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/luv_substation_output_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/lv_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/lv_diode.json index 640a58949a3..b9c64760de9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/lv_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/lv_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/lv_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/lv_energy_input_hatch.json index 228dab47a7d..301a73080d9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/lv_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/lv_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/lv_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/lv_energy_output_hatch.json index 51879fb7fb9..0211234b691 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/lv_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/lv_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/lv_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/lv_fluid_passthrough_hatch.json index f6b6856b0b4..12e39e7f0f0 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/lv_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/lv_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/lv_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/lv_input_bus.json index 76f24f18d3f..c573a5f6f34 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/lv_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/lv_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/lv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/lv/side", "top": "gtceu:block/casings/voltage/lv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/lv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/lv/side", "top": "gtceu:block/casings/voltage/lv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/lv_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/lv_input_hatch.json index 5cad86ee7ab..a3ac0c75f65 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/lv_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/lv_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/lv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/lv/side", "top": "gtceu:block/casings/voltage/lv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/lv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/lv/side", "top": "gtceu:block/casings/voltage/lv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/lv_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/lv_item_passthrough_hatch.json index d2cb4a4fd75..0288f611a0b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/lv_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/lv_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/lv_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/lv_machine_hull.json index 65adf730e4b..bc90f170b4e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/lv_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/lv_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/lv_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/lv_muffler_hatch.json index 5d885fa9930..0f81c00baf4 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/lv_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/lv_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/lv_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/lv_output_bus.json index 34774b7871c..e888403f518 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/lv_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/lv_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/lv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/lv/side", "top": "gtceu:block/casings/voltage/lv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/lv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/lv/side", "top": "gtceu:block/casings/voltage/lv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/lv_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/lv_output_hatch.json index f4b3cbe36da..92cde287280 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/lv_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/lv_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/lv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/lv/side", "top": "gtceu:block/casings/voltage/lv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/lv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/lv/side", "top": "gtceu:block/casings/voltage/lv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/maintenance_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/maintenance_hatch.json index 36ca9c7c1d1..167dbb02f0f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/maintenance_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/maintenance_hatch.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "maintenance_taped=false": { + "is_formed=false,taped=false": { "model": { "parent": "gtceu:block/machine/part/maintenance_hatch", "textures": { @@ -18,7 +18,28 @@ } } }, - "maintenance_taped=true": { + "is_formed=false,taped=true": { + "model": { + "parent": "gtceu:block/machine/part/maintenance_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "overlay_2": "gtceu:block/overlay/machine/overlay_maintenance_taped", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true,taped=false": { + "model": { + "parent": "gtceu:block/machine/part/maintenance_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/lv/bottom", + "side": "gtceu:block/casings/voltage/lv/side", + "top": "gtceu:block/casings/voltage/lv/top" + } + } + }, + "is_formed=true,taped=true": { "model": { "parent": "gtceu:block/machine/part/maintenance_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_dual_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/max_dual_input_hatch.json index 6d1a5eede06..2b23cdb36e3 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_dual_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_dual_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_dual_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/max_dual_output_hatch.json index 087e0a2d9f5..d1dcf701049 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_dual_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_dual_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch.json index ff31950e401..31b2030234a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch_16a.json index 6d41a8b36df..5964712050d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch_4a.json index 6030052635a..0c8d724e6c9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_input_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch.json index 3917a9d48e7..e1eabbb5646 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch_16a.json index 954f9206d16..8d12ddd68a7 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch_4a.json index d2e81a881e7..303d38549bc 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_energy_output_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/max_input_bus.json index 4e47eb2bbac..dd846fd400a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch.json index fe30866d3b7..9378df1bd76 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch_4x.json index 46d98ede47d..901fb4309ba 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch_9x.json index af302cec321..95f67c28970 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_input_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/max_machine_hull.json index fdd1a8252af..61a6bb54e50 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/max_output_bus.json index ef66d278baa..55e0207049a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch.json index 6b3951ad66c..e00d6154cae 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch_4x.json index fd760a2e8aa..fb870e352e0 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch_9x.json index 74349549d25..b56691be16f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_output_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/max/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/max/side", "top": "gtceu:block/casings/voltage/max/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_substation_input_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/max_substation_input_hatch_64a.json index 69afb137230..f35fc0f8e7e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_substation_input_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_substation_input_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/max_substation_output_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/max_substation_output_hatch_64a.json index da746400f31..657d92e0c2c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/max_substation_output_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/max_substation_output_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/max/bottom", + "side": "gtceu:block/casings/voltage/max/side", + "top": "gtceu:block/casings/voltage/max/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/me_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/me_input_bus.json index 8e5263a5c98..245e740d689 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/me_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/me_input_bus.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine", "textures": { @@ -19,7 +19,29 @@ } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/appeng/me_input_bus", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/appeng/me_input_bus", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/me_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/me_input_hatch.json index ca092fd348f..68a8862787e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/me_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/me_input_hatch.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine", "textures": { @@ -19,7 +19,29 @@ } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/appeng/me_input_hatch", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/appeng/me_input_hatch", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/me_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/me_output_bus.json index 1e0360e971a..73682f105d8 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/me_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/me_output_bus.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine", "textures": { @@ -19,7 +19,29 @@ } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/appeng/me_output_bus", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/appeng/me_output_bus", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/me_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/me_output_hatch.json index 0e2ac7ddcef..87add0ba090 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/me_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/me_output_hatch.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine", "textures": { @@ -19,7 +19,29 @@ } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/appeng/me_output_hatch", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "overlay": "gtceu:block/overlay/appeng/me_output_hatch", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/me_pattern_buffer.json b/src/generated/resources/assets/gtceu/models/block/machine/me_pattern_buffer.json index 22933c75c19..88e2f6c6200 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/me_pattern_buffer.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/me_pattern_buffer.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine", "textures": { @@ -19,7 +19,29 @@ } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/appeng/me_buffer_hatch", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/appeng/me_buffer_hatch", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/me_pattern_buffer_proxy.json b/src/generated/resources/assets/gtceu/models/block/machine/me_pattern_buffer_proxy.json index 809c5dd1b2d..6e9d26ba128 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/me_pattern_buffer_proxy.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/me_pattern_buffer_proxy.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine", "textures": { @@ -19,7 +19,29 @@ } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/appeng/me_buffer_hatch_proxy", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/appeng/me_buffer_hatch_proxy", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/me_stocking_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/me_stocking_input_bus.json index f4458040898..f1353753047 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/me_stocking_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/me_stocking_input_bus.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine", "textures": { @@ -19,7 +19,29 @@ } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/appeng/me_input_bus", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/appeng/me_input_bus", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/me_stocking_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/me_stocking_input_hatch.json index 17a7a419084..3d86a15160f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/me_stocking_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/me_stocking_input_hatch.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine", "textures": { @@ -19,7 +19,29 @@ } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/appeng/me_input_hatch", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/luv/bottom", + "overlay": "gtceu:block/overlay/appeng/me_input_hatch", + "side": "gtceu:block/casings/voltage/luv/side", + "top": "gtceu:block/casings/voltage/luv/top" + } + } + }, + "is_formed=true,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_color_ring", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/monitor.json b/src/generated/resources/assets/gtceu/models/block/machine/monitor.json new file mode 100644 index 00000000000..880ef73c875 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/block/machine/monitor.json @@ -0,0 +1,18 @@ +{ + "parent": "minecraft:block/block", + "loader": "gtceu:machine", + "machine": "gtceu:monitor", + "replaceable_textures": [ + "all" + ], + "variants": { + "": { + "model": { + "parent": "gtceu:block/machine/part/computer_monitor", + "textures": { + "all": "gtceu:block/casings/solid/machine_casing_frost_proof" + } + } + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/block/machine/mv_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/mv_diode.json index 13ef45eb26b..2ba04aef163 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/mv_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/mv_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/mv_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/mv_energy_input_hatch.json index 4a58b1f852a..0379f0ef910 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/mv_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/mv_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/mv_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/mv_energy_output_hatch.json index 31855b6844e..3f0db726e69 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/mv_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/mv_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/mv_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/mv_fluid_passthrough_hatch.json index 04bf39d4454..a30fb71e9ce 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/mv_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/mv_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/mv_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/mv_input_bus.json index e818889e4fb..90b6ce4822d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/mv_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/mv_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/mv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/mv/side", "top": "gtceu:block/casings/voltage/mv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/mv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/mv/side", "top": "gtceu:block/casings/voltage/mv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/mv_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/mv_input_hatch.json index 2c640a00058..c56fbe0cd05 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/mv_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/mv_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/mv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/mv/side", "top": "gtceu:block/casings/voltage/mv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/mv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/mv/side", "top": "gtceu:block/casings/voltage/mv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/mv_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/mv_item_passthrough_hatch.json index 70b5a3cd60c..0f949d91554 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/mv_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/mv_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/mv_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/mv_machine_hull.json index 91a1ea92329..10aaa845609 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/mv_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/mv_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/mv_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/mv_muffler_hatch.json index de483edde9b..b39e4cfc172 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/mv_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/mv_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/mv_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/mv_output_bus.json index c4e8f4ffb80..d9bbb5b54e2 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/mv_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/mv_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/mv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/mv/side", "top": "gtceu:block/casings/voltage/mv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/mv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/mv/side", "top": "gtceu:block/casings/voltage/mv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/mv_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/mv_output_hatch.json index d44b1b0d8b1..6639010175a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/mv_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/mv_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/mv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/mv/side", "top": "gtceu:block/casings/voltage/mv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/mv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/mv/side", + "top": "gtceu:block/casings/voltage/mv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/mv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/mv/side", "top": "gtceu:block/casings/voltage/mv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/object_holder.json b/src/generated/resources/assets/gtceu/models/block/machine/object_holder.json index 91980594343..e0f85527751 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/object_holder.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/object_holder.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "recipe_logic_status=idle": { + "is_formed=false,recipe_logic_status=idle": { "model": { "parent": "gtceu:block/casings/voltage/zpm", "textures": { @@ -16,7 +16,7 @@ } } }, - "recipe_logic_status=suspend": { + "is_formed=false,recipe_logic_status=suspend": { "model": { "parent": "gtceu:block/casings/voltage/zpm", "textures": { @@ -24,7 +24,7 @@ } } }, - "recipe_logic_status=waiting": { + "is_formed=false,recipe_logic_status=waiting": { "model": { "parent": "gtceu:block/casings/voltage/zpm", "textures": { @@ -33,7 +33,41 @@ } } }, - "recipe_logic_status=working": { + "is_formed=false,recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/casings/voltage/zpm", + "textures": { + "overlay_front": "gtceu:block/machines/object_holder/overlay_front_active", + "overlay_front_emissive": "gtceu:block/machines/object_holder/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/casings/voltage/zpm", + "textures": { + "overlay_front": "gtceu:block/machines/object_holder/overlay_front" + } + } + }, + "is_formed=true,recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/casings/voltage/zpm", + "textures": { + "overlay_front": "gtceu:block/machines/object_holder/overlay_front" + } + } + }, + "is_formed=true,recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/casings/voltage/zpm", + "textures": { + "overlay_front": "gtceu:block/machines/object_holder/overlay_front_active", + "overlay_front_emissive": "gtceu:block/machines/object_holder/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=working": { "model": { "parent": "gtceu:block/casings/voltage/zpm", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_1024a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_1024a_laser_source_hatch.json index ca682f544c8..8e7b645ea6b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_1024a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_1024a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_1024a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_1024a_laser_target_hatch.json index 889257f40b4..221292bfccc 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_1024a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_1024a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_256a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_256a_laser_source_hatch.json index 62c24189bcd..ed3f0b66927 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_256a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_256a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_256a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_256a_laser_target_hatch.json index 3ff30ebec87..f1993cdf02c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_256a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_256a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_4096a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_4096a_laser_source_hatch.json index 3ec75f0cae6..b7c73a75648 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_4096a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_4096a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_4096a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_4096a_laser_target_hatch.json index 916e12b2b59..14170675a20 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_4096a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_4096a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_diode.json index 78cf53c4202..aa242e1a156 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_dual_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_dual_input_hatch.json index ded4259f05d..0f4b267aaea 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_dual_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_dual_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_dual_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_dual_output_hatch.json index 945c222a257..73fe79be6ff 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_dual_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_dual_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch.json index d7696ef5494..fbf76424be1 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch_16a.json index d2297d57b27..983a5a49cd0 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch_4a.json index 2245aaf3858..66cf4fa7a4f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_input_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch.json index 4f4038b19d5..9a6cfa1d730 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch_16a.json index b5261d7bf41..d770ab23d38 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch_4a.json index f34508d4c69..5c6597b8d0a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_energy_output_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_fluid_passthrough_hatch.json index 1c83bbf2347..c2ee814aa3b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_input_bus.json index cdb9d0e3619..c7ae80b5c3b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch.json index 968985989f3..9edac136b1d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch_4x.json index ce80702ba18..9dea498efc8 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch_9x.json index 1a840f8417e..1c2d25caa57 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_input_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_item_passthrough_hatch.json index 6f02a0a3cff..8acab3a9f2e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_machine_hull.json index d8b4aece4ef..4f964524a23 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_muffler_hatch.json index 6849f94f4f4..d2d5fb06f7a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_output_bus.json index baa8313c7df..9dca8c89a3b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch.json index 39d7c500394..88e54e09caa 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch_4x.json index c9b867a669a..86341220bfd 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch_9x.json index 4c3ed75dfaa..e6e03c09eea 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_output_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/opv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/opv/side", "top": "gtceu:block/casings/voltage/opv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_substation_input_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_substation_input_hatch_64a.json index 754dff22d3c..e8e2a4af0a9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_substation_input_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_substation_input_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/opv_substation_output_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/opv_substation_output_hatch_64a.json index 350f9d68acc..fbe7ea7aa4e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/opv_substation_output_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/opv_substation_output_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/opv/bottom", + "side": "gtceu:block/casings/voltage/opv/side", + "top": "gtceu:block/casings/voltage/opv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/pump_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/pump_hatch.json index 1d180e265fe..4ca3e7051cd 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/pump_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/pump_hatch.json @@ -8,7 +8,10 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": "gtceu:block/machine/part/pump_hatch" + }, + "is_formed=true": { "model": "gtceu:block/machine/part/pump_hatch" } } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/reservoir_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/reservoir_hatch.json index 82a52c7bb55..5d722efd8b1 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/reservoir_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/reservoir_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/reservoir_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/ev/bottom", + "side": "gtceu:block/casings/voltage/ev/side", + "top": "gtceu:block/casings/voltage/ev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/reservoir_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/steam_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/steam_input_bus.json index c036162390c..03000069b55 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/steam_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/steam_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/steam/bronze/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/steam/bronze/side", "top": "gtceu:block/casings/steam/bronze/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/steam/bronze/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/steam/bronze/side", + "top": "gtceu:block/casings/steam/bronze/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/steam/bronze/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/steam/bronze/side", + "top": "gtceu:block/casings/steam/bronze/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/steam/bronze/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/steam/bronze/side", "top": "gtceu:block/casings/steam/bronze/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/steam_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/steam_input_hatch.json index a4510aac7ef..f9a52ffbcdf 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/steam_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/steam_input_hatch.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "steel=false": { + "is_formed=false,steel=false": { "model": { "parent": "gtceu:block/machine/part/steam_hatch", "textures": { @@ -18,7 +18,27 @@ } } }, - "steel=true": { + "is_formed=false,steel=true": { + "model": { + "parent": "gtceu:block/machine/part/steam_hatch", + "textures": { + "bottom": "gtceu:block/casings/steam/steel/bottom", + "side": "gtceu:block/casings/steam/steel/side", + "top": "gtceu:block/casings/steam/steel/top" + } + } + }, + "is_formed=true,steel=false": { + "model": { + "parent": "gtceu:block/machine/part/steam_hatch", + "textures": { + "bottom": "gtceu:block/casings/steam/bronze/bottom", + "side": "gtceu:block/casings/steam/bronze/side", + "top": "gtceu:block/casings/steam/bronze/top" + } + } + }, + "is_formed=true,steel=true": { "model": { "parent": "gtceu:block/machine/part/steam_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/steam_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/steam_output_bus.json index e3d215b1991..1b863277b1a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/steam_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/steam_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/steam/bronze/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/steam/bronze/side", "top": "gtceu:block/casings/steam/bronze/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/steam/bronze/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/steam/bronze/side", + "top": "gtceu:block/casings/steam/bronze/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/steam/bronze/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/steam/bronze/side", + "top": "gtceu:block/casings/steam/bronze/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/steam/bronze/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/steam/bronze/side", "top": "gtceu:block/casings/steam/bronze/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_1024a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_1024a_laser_source_hatch.json index 28ec0c74db0..30a8efd481a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_1024a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_1024a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_1024a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_1024a_laser_target_hatch.json index b89a98f39b8..ad23815caef 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_1024a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_1024a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_256a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_256a_laser_source_hatch.json index 1e73db60bcb..f9702e52aa9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_256a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_256a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_256a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_256a_laser_target_hatch.json index e1dc54f87cb..6ced26ce439 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_256a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_256a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_4096a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_4096a_laser_source_hatch.json index cec4c2831b9..34c2018cc81 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_4096a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_4096a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_4096a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_4096a_laser_target_hatch.json index ced9d587623..33e1f20843a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_4096a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_4096a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_diode.json index 64659421c57..4679cb098c9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_dual_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_dual_input_hatch.json index eb9481f5a4f..99928591617 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_dual_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_dual_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_dual_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_dual_output_hatch.json index fe522e60232..7f46e625b1e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_dual_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_dual_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch.json index 58e01244d10..56956fbe24c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch_16a.json index 00962d3cf33..52c542bcb10 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch_4a.json index 381c86fe7de..8ca61dbfabe 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_input_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch.json index 43564dde7e7..00bdcbe1032 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch_16a.json index 325c8b26a8f..26a228a3149 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch_4a.json index 71787ac0a81..3254321ac12 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_energy_output_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_fluid_passthrough_hatch.json index a596d6becbb..725c10f0c7c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_input_bus.json index 41fd347b53c..40302423fe8 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch.json index a87ae7a6c65..666653f300b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch_4x.json index daec65d66b2..1db41ffad7a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch_9x.json index eb061686315..04386c7458b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_input_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_item_passthrough_hatch.json index fa95eb8caad..e12daf3ff0c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_machine_hull.json index 04fa7e0a752..bea91f8ea2a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_muffler_hatch.json index 77832d6cb76..a2a9a577dd1 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_output_bus.json index fcc10e58262..f4431be2e05 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch.json index 0a6b7282d31..9bc60467ddb 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch_4x.json index 20b7608cc03..6775f452f88 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch_9x.json index 8ce0e30df75..fe930f8a4b8 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_output_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uev/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uev/side", "top": "gtceu:block/casings/voltage/uev/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_substation_input_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_substation_input_hatch_64a.json index 81fc5651b80..5d08832af27 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_substation_input_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_substation_input_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uev_substation_output_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/uev_substation_output_hatch_64a.json index 4fcec181cd5..11f729aa77f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uev_substation_output_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uev_substation_output_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uev/bottom", + "side": "gtceu:block/casings/voltage/uev/side", + "top": "gtceu:block/casings/voltage/uev/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_1024a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_1024a_laser_source_hatch.json index 1649f30b6fb..13c822b8f45 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_1024a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_1024a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_1024a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_1024a_laser_target_hatch.json index 89628b8ac8c..55fe402cf38 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_1024a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_1024a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_256a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_256a_laser_source_hatch.json index 1848bf23a70..b70e577d201 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_256a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_256a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_256a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_256a_laser_target_hatch.json index 460e3ea474a..bfd2baa9601 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_256a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_256a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_4096a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_4096a_laser_source_hatch.json index 7db76b36ec0..ce744fb10bd 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_4096a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_4096a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_4096a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_4096a_laser_target_hatch.json index 2cd5309a2a5..442d7e77b2b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_4096a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_4096a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_diode.json index 5a391a2b6c6..eb3eaaaf4b4 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_dual_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_dual_input_hatch.json index 832800061d8..99183559d93 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_dual_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_dual_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_dual_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_dual_output_hatch.json index d2a585c7af6..ff42cc57af1 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_dual_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_dual_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch.json index 345b1bbb585..85cde895095 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch_16a.json index df0011afeb6..b9c123489f2 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch_4a.json index c44c6f3fbb1..21dc74da509 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_input_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch.json index 51c75812bf8..e2398685c1c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch_16a.json index 0a3d1b2718a..d3bad9eb780 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch_4a.json index fb09cbcd7bf..dc7032ab606 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_energy_output_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_fluid_passthrough_hatch.json index 56e3ffb3cb0..81617d7bc28 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_bus.json index a9eb15032b0..1effc1e27de 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch.json index 5da28853310..f7e9109863a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch_4x.json index 4feb842d067..bbed74342e2 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch_9x.json index a0b9f99c827..f55015b80a6 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_input_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_item_passthrough_hatch.json index f2aa74aa535..2932214494e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_machine_hull.json index eca83b32963..f38a52d8ea6 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_muffler_hatch.json index 9471a6eefbd..30486b3b454 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_bus.json index 935c024d0bb..fb4c82e7a48 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch.json index 6266445a7b0..1b41a8274bd 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch_4x.json index f84082f717f..997be62fe3a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch_9x.json index ffd16aa3f0d..2144d4a0632 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_output_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uhv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uhv/side", "top": "gtceu:block/casings/voltage/uhv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_substation_input_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_substation_input_hatch_64a.json index 55ea9307bff..a2e90c28e61 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_substation_input_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_substation_input_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uhv_substation_output_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/uhv_substation_output_hatch_64a.json index e9d9a3c48e8..c0b3bb7fdf6 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uhv_substation_output_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uhv_substation_output_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uhv/bottom", + "side": "gtceu:block/casings/voltage/uhv/side", + "top": "gtceu:block/casings/voltage/uhv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_1024a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_1024a_laser_source_hatch.json index fca4a0e2b58..9098cf314f5 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_1024a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_1024a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_1024a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_1024a_laser_target_hatch.json index 68456147cdc..8d5847bdf51 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_1024a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_1024a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_256a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_256a_laser_source_hatch.json index d61ebfbb2e4..e3a2f5ca0ca 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_256a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_256a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_256a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_256a_laser_target_hatch.json index 8a6814e134b..83173875b45 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_256a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_256a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_4096a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_4096a_laser_source_hatch.json index 5141a31ef85..97708f2e70e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_4096a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_4096a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_4096a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_4096a_laser_target_hatch.json index 56ae3c54dec..27118a0fe66 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_4096a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_4096a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_diode.json index 7d55161db31..5a34f07f3a6 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_dual_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_dual_input_hatch.json index f4cf425ded0..68e3a1f1580 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_dual_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_dual_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_dual_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_dual_output_hatch.json index a82bed87bf3..33972356c6c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_dual_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_dual_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch.json index da95ea226fe..5e7fffbe01d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch_16a.json index 49ef4b68f44..c30887d20d2 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch_4a.json index 1139d9c75c4..c7e03a0391f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_input_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch.json index f859d675731..b909bcea885 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch_16a.json index 1ca277bc2c4..8ccba52e5ec 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch_4a.json index bd590ec2c5b..d2bfa9ad969 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_energy_output_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_fluid_passthrough_hatch.json index afcf7084776..cbdbe8de508 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_bus.json index 108ecef9594..e096c120a0f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch.json index c572b755b32..8aac454ffa7 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch_4x.json index e9a2aeeff33..2cfe21c09b2 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch_9x.json index 58d954f8324..f4f7c32be32 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_input_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_item_passthrough_hatch.json index 54b2631e4b4..c545fc1ad1c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_machine_hull.json index e29033a5a4a..0c053f73f60 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_muffler_hatch.json index cc71795c34f..51d0173545b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_bus.json index 7cd1770271b..e56ee5116e6 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch.json index 0a41d85fb9f..7d95e8aa018 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch_4x.json index c5affe6259f..5abf12a04d5 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch_9x.json index 2dee7caa49a..a2719892480 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_output_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uiv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uiv/side", "top": "gtceu:block/casings/voltage/uiv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_substation_input_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_substation_input_hatch_64a.json index 83d50d1fad4..3e1a9f4d3d3 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_substation_input_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_substation_input_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uiv_substation_output_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/uiv_substation_output_hatch_64a.json index ca828e79995..8c588f5eede 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uiv_substation_output_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uiv_substation_output_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uiv/bottom", + "side": "gtceu:block/casings/voltage/uiv/side", + "top": "gtceu:block/casings/voltage/uiv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ulv_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/ulv_energy_input_hatch.json index 7491a85a904..04ceed22189 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ulv_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ulv_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/ulv/bottom", + "side": "gtceu:block/casings/voltage/ulv/side", + "top": "gtceu:block/casings/voltage/ulv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ulv_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/ulv_energy_output_hatch.json index 08a5aee5c57..8cc9376e6b1 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ulv_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ulv_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/ulv/bottom", + "side": "gtceu:block/casings/voltage/ulv/side", + "top": "gtceu:block/casings/voltage/ulv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ulv_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/ulv_input_bus.json index 33d53f5a6b9..81c9d114a93 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ulv_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ulv_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ulv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/ulv/side", "top": "gtceu:block/casings/voltage/ulv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ulv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/ulv/side", + "top": "gtceu:block/casings/voltage/ulv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ulv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/ulv/side", + "top": "gtceu:block/casings/voltage/ulv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ulv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/ulv/side", "top": "gtceu:block/casings/voltage/ulv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ulv_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/ulv_input_hatch.json index 256fef2a0e7..16d52180226 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ulv_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ulv_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ulv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/ulv/side", "top": "gtceu:block/casings/voltage/ulv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ulv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/ulv/side", + "top": "gtceu:block/casings/voltage/ulv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ulv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/ulv/side", + "top": "gtceu:block/casings/voltage/ulv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ulv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/ulv/side", "top": "gtceu:block/casings/voltage/ulv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ulv_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/ulv_machine_hull.json index 9f754326e52..c77a505b1c0 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ulv_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ulv_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/ulv/bottom", + "side": "gtceu:block/casings/voltage/ulv/side", + "top": "gtceu:block/casings/voltage/ulv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ulv_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/ulv_output_bus.json index 3fea2df7d5e..070a433d3c0 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ulv_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ulv_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ulv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/ulv/side", "top": "gtceu:block/casings/voltage/ulv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ulv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/ulv/side", + "top": "gtceu:block/casings/voltage/ulv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ulv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/ulv/side", + "top": "gtceu:block/casings/voltage/ulv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ulv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/ulv/side", "top": "gtceu:block/casings/voltage/ulv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/ulv_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/ulv_output_hatch.json index 8af4fe3d48b..84335adfbeb 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/ulv_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/ulv_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/ulv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/ulv/side", "top": "gtceu:block/casings/voltage/ulv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/ulv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/ulv/side", + "top": "gtceu:block/casings/voltage/ulv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/ulv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/ulv/side", + "top": "gtceu:block/casings/voltage/ulv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/ulv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/ulv/side", "top": "gtceu:block/casings/voltage/ulv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_1024a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_1024a_laser_source_hatch.json index 1cde7fbd5da..32c33e82d15 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_1024a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_1024a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_1024a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_1024a_laser_target_hatch.json index 3e1a3359117..8e1645484bf 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_1024a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_1024a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_256a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_256a_laser_source_hatch.json index d6d9a341078..96072f35299 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_256a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_256a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_256a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_256a_laser_target_hatch.json index 73abb542859..9e8c1769940 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_256a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_256a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_4096a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_4096a_laser_source_hatch.json index c974f35b64d..bb2d480b4b9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_4096a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_4096a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_4096a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_4096a_laser_target_hatch.json index 623abe17ade..623ba8512db 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_4096a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_4096a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_diode.json index 13a6bc753cc..937d58e36cc 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_dual_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_dual_input_hatch.json index db58c0e5a71..37aeb73cb2b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_dual_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_dual_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_dual_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_dual_output_hatch.json index aa73d74d81d..3095b07e8e9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_dual_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_dual_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch.json index 44592d942cf..3e3993deb5d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch_16a.json index 8bced205db7..e79a14f0c81 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch_4a.json index de176ac9bbb..448b2461d94 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_input_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch.json index fce91370195..76b89d0c0fb 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch_16a.json index 69ccc4faad4..90acb4db38a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch_4a.json index c8fc1007134..12a7a086845 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_energy_output_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_fluid_passthrough_hatch.json index 05efa7b142b..fba4e74de38 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_input_bus.json index c7d51723587..52ca95ae11d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch.json index 63f1f80914c..f64ccc5fae1 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch_4x.json index c2666a25260..1c2b3ea883c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch_9x.json index 527503d49b2..80e36309c92 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_input_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_item_passthrough_hatch.json index e22944a89c1..51154bf35ed 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_machine_hull.json index c05982e3bd5..1c9ea6a3253 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_muffler_hatch.json index 0d4e5c941b4..42b7f438469 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_output_bus.json index 033aad257ec..c5153995449 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch.json index 2749f3eb0a1..926059a6826 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch_4x.json index b59eaeb9dfc..1c2575f8e00 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch_9x.json index 8ff8e223b1e..b13ff7db7e1 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_output_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uv/side", "top": "gtceu:block/casings/voltage/uv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_parallel_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_parallel_hatch.json index 07d34543415..1d814407c02 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_parallel_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_parallel_hatch.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "recipe_logic_status=idle": { + "is_formed=false,recipe_logic_status=idle": { "model": { "parent": "gtceu:block/casings/voltage/uv", "textures": { @@ -17,7 +17,7 @@ } } }, - "recipe_logic_status=suspend": { + "is_formed=false,recipe_logic_status=suspend": { "model": { "parent": "gtceu:block/casings/voltage/uv", "textures": { @@ -26,7 +26,7 @@ } } }, - "recipe_logic_status=waiting": { + "is_formed=false,recipe_logic_status=waiting": { "model": { "parent": "gtceu:block/casings/voltage/uv", "textures": { @@ -35,7 +35,43 @@ } } }, - "recipe_logic_status=working": { + "is_formed=false,recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/casings/voltage/uv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk4/overlay_front_active", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk4/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/casings/voltage/uv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk4/overlay_front", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk4/overlay_front_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/casings/voltage/uv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk4/overlay_front", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk4/overlay_front_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/casings/voltage/uv", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk4/overlay_front_active", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk4/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=working": { "model": { "parent": "gtceu:block/casings/voltage/uv", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_substation_input_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_substation_input_hatch_64a.json index 3dc84068d5b..ed73cfc0ac3 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_substation_input_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_substation_input_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uv_substation_output_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/uv_substation_output_hatch_64a.json index eed1432974e..c99c2c1be6f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uv_substation_output_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uv_substation_output_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uv/bottom", + "side": "gtceu:block/casings/voltage/uv/side", + "top": "gtceu:block/casings/voltage/uv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_1024a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_1024a_laser_source_hatch.json index 798d3d7c110..f5ef4d4af5d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_1024a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_1024a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_1024a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_1024a_laser_target_hatch.json index eb9d1795710..9cab7faf4cb 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_1024a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_1024a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_256a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_256a_laser_source_hatch.json index 3db6e0d178a..e6a7074a68f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_256a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_256a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_256a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_256a_laser_target_hatch.json index 13e921ece49..39d3747a060 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_256a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_256a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_4096a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_4096a_laser_source_hatch.json index 4a3fc6809bc..90d98bf566f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_4096a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_4096a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_4096a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_4096a_laser_target_hatch.json index 54b8a49727a..63c11103da6 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_4096a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_4096a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_diode.json index 5151682d5d5..bab3e99fca8 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_dual_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_dual_input_hatch.json index e2eca28fdb2..a4d0b14c2da 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_dual_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_dual_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_dual_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_dual_output_hatch.json index b93f033f183..7bd0c847639 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_dual_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_dual_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch.json index 8e2e1258a47..6c2fe3b8d6c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch_16a.json index 673098d8fe7..77b34d244ac 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch_4a.json index bde2d514003..4e4c3494c4b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_input_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch.json index 3aca76de804..952b1c7e99b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch_16a.json index c4f2aac5e4c..6afbdbddbdd 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch_4a.json index 66017558273..26a05eb4bfa 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_energy_output_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_fluid_passthrough_hatch.json index d882c499627..5a92cafb552 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_bus.json index ad21dab8fe1..4eada256ee1 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch.json index 5352f169e54..dc6fad49a5c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch_4x.json index c30df2537d3..ae12772e832 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch_9x.json index 7365aaa5bd6..5431ac9a25b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_input_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_item_passthrough_hatch.json index b137d0c01ec..699bd6f9e20 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_machine_hull.json index 6c57826ae4f..83e5296056c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_muffler_hatch.json index 923feecd6ae..0be9913d427 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_bus.json index 593f201ec2a..fdaab38692f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch.json index 70b6272781f..2a17e7b5010 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch_4x.json index 341e38a13b5..914ab0a937b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch_9x.json index ef54a8f9f25..d5f9b014229 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_output_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/uxv/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/uxv/side", "top": "gtceu:block/casings/voltage/uxv/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_substation_input_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_substation_input_hatch_64a.json index 44ed5ca06da..62a00e91973 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_substation_input_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_substation_input_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/uxv_substation_output_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/uxv_substation_output_hatch_64a.json index f7e2034a036..ae1c843250b 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/uxv_substation_output_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/uxv_substation_output_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/uxv/bottom", + "side": "gtceu:block/casings/voltage/uxv/side", + "top": "gtceu:block/casings/voltage/uxv/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_1024a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_1024a_laser_source_hatch.json index a127ba5e413..9e003859ea1 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_1024a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_1024a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_1024a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_1024a_laser_target_hatch.json index 56c4663f2fc..a00391bb30c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_1024a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_1024a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_256a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_256a_laser_source_hatch.json index 86d88c3f0cd..bf064405d42 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_256a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_256a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_256a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_256a_laser_target_hatch.json index 1acbbba005d..b9f70fe637f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_256a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_256a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_4096a_laser_source_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_4096a_laser_source_hatch.json index 9d625e3e692..efd435332c5 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_4096a_laser_source_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_4096a_laser_source_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_source_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_source_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_4096a_laser_target_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_4096a_laser_target_hatch.json index 03cf4297b56..90c5cab9f1c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_4096a_laser_target_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_4096a_laser_target_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/laser_target_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/laser_target_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_diode.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_diode.json index 37e5439a762..499e098af9c 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_diode.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_diode.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "amp_mode=16a": { + "amp_mode=16a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -24,7 +24,39 @@ } } }, - "amp_mode=1a": { + "amp_mode=16a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_16a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_16a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_16a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_16a_tinted", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "amp_mode=1a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_1a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_1a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_1a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_1a_tinted", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "amp_mode=1a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -40,7 +72,7 @@ } } }, - "amp_mode=2a": { + "amp_mode=2a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -56,7 +88,23 @@ } } }, - "amp_mode=4a": { + "amp_mode=2a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_2a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_2a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_2a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_2a_tinted", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "amp_mode=4a,is_formed=false": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { @@ -72,7 +120,39 @@ } } }, - "amp_mode=8a": { + "amp_mode=4a,is_formed=true": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_4a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_4a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_4a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_4a_tinted", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "amp_mode=8a,is_formed=false": { + "model": { + "parent": "gtceu:block/machine/template/transformer_like_machine", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay_in_io": "gtceu:block/overlay/machine/overlay_energy_8a_in", + "overlay_in_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_in_emissive", + "overlay_in_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "overlay_out_io": "gtceu:block/overlay/machine/overlay_energy_8a_out", + "overlay_out_io_emissive": "gtceu:block/overlay/machine/overlay_energy_8a_out_emissive", + "overlay_out_tinted": "gtceu:block/overlay/machine/overlay_energy_8a_tinted", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "amp_mode=8a,is_formed=true": { "model": { "parent": "gtceu:block/machine/template/transformer_like_machine", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_dual_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_dual_input_hatch.json index eb0979b826e..a22ea6923cc 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_dual_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_dual_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_dual_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_dual_output_hatch.json index 1b282c3a636..7ba68487942 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_dual_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_dual_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/dual_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/dual_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch.json index 809a84b54f9..5d636750f3a 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch_16a.json index b46ce3c4bce..e31e76607a8 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch_4a.json index 5f9a73f39b7..5fb615be0f0 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_input_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch.json index b1f3e7d456d..e3a407c1269 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch_16a.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch_16a.json index 62653f301a7..692e6492a16 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch_16a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch_16a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_16a", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_16a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch_4a.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch_4a.json index c0ed6d8db9a..fefc4f7afc5 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch_4a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_energy_output_hatch_4a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_4a", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_4a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_fluid_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_fluid_passthrough_hatch.json index ed3b46ad970..cb319144f2d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_fluid_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_fluid_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/fluid_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_bus.json index de7f954c68b..6be8278ac44 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch.json index 57c7d674e15..e08c8188ade 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch_4x.json index 77ff2b415af..129c0c37573 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch_9x.json index 64d07cff0d0..5f7b161090d 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_input_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_item_passthrough_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_item_passthrough_hatch.json index 5ca8d0a6566..9944224230e 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_item_passthrough_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_item_passthrough_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/item_passthrough_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/item_passthrough_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_machine_hull.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_machine_hull.json index 3fe327dcfee..6a931fc7afe 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_machine_hull.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_machine_hull.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/hull", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/hull", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_muffler_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_muffler_hatch.json index 4524ac92d45..7a8c161b2c9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_muffler_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_muffler_hatch.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/muffler_hatch", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/muffler_hatch", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_bus.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_bus.json index c763a0447af..a7f93e66eb7 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_bus.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_bus.json @@ -8,25 +8,53 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_item_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_item_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch.json index 25c80567f2b..2698ab63e87 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch.json @@ -8,25 +8,49 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch_4x.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch_4x.json index d2d7018ec76..d179685d65f 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch_4x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch_4x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_4x", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch_9x.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch_9x.json index 51b7a9beadf..f23cfb05dfe 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch_9x.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_output_hatch_9x.json @@ -8,26 +8,52 @@ "side" ], "variants": { - "is_painted=false": { + "is_formed=false,is_painted=false": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" } } }, - "is_painted=true": { + "is_formed=false,is_painted=true": { "model": { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", "textures": { "bottom": "gtceu:block/casings/voltage/zpm/bottom", - "overlay": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch_half_px_out", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=false": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true,is_painted=true": { + "model": { + "parent": "gtceu:block/machine/template/part/hatch_machine_emissive_color_ring", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive", "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe_9x", "side": "gtceu:block/casings/voltage/zpm/side", "top": "gtceu:block/casings/voltage/zpm/top" diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_parallel_hatch.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_parallel_hatch.json index bc730ab10e8..0ebadd8e2e9 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_parallel_hatch.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_parallel_hatch.json @@ -8,7 +8,7 @@ "side" ], "variants": { - "recipe_logic_status=idle": { + "is_formed=false,recipe_logic_status=idle": { "model": { "parent": "gtceu:block/casings/voltage/zpm", "textures": { @@ -17,7 +17,7 @@ } } }, - "recipe_logic_status=suspend": { + "is_formed=false,recipe_logic_status=suspend": { "model": { "parent": "gtceu:block/casings/voltage/zpm", "textures": { @@ -26,7 +26,7 @@ } } }, - "recipe_logic_status=waiting": { + "is_formed=false,recipe_logic_status=waiting": { "model": { "parent": "gtceu:block/casings/voltage/zpm", "textures": { @@ -35,7 +35,43 @@ } } }, - "recipe_logic_status=working": { + "is_formed=false,recipe_logic_status=working": { + "model": { + "parent": "gtceu:block/casings/voltage/zpm", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk3/overlay_front_active", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk3/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=idle": { + "model": { + "parent": "gtceu:block/casings/voltage/zpm", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk3/overlay_front", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk3/overlay_front_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=suspend": { + "model": { + "parent": "gtceu:block/casings/voltage/zpm", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk3/overlay_front", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk3/overlay_front_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=waiting": { + "model": { + "parent": "gtceu:block/casings/voltage/zpm", + "textures": { + "overlay_front": "gtceu:block/machines/parallel_hatch_mk3/overlay_front_active", + "overlay_front_emissive": "gtceu:block/machines/parallel_hatch_mk3/overlay_front_active_emissive" + } + } + }, + "is_formed=true,recipe_logic_status=working": { "model": { "parent": "gtceu:block/casings/voltage/zpm", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_substation_input_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_substation_input_hatch_64a.json index 17f3e3fe3e3..42abd4ceeae 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_substation_input_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_substation_input_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_input_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_input_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/block/machine/zpm_substation_output_hatch_64a.json b/src/generated/resources/assets/gtceu/models/block/machine/zpm_substation_output_hatch_64a.json index 960328e89c8..b4fce033ab0 100644 --- a/src/generated/resources/assets/gtceu/models/block/machine/zpm_substation_output_hatch_64a.json +++ b/src/generated/resources/assets/gtceu/models/block/machine/zpm_substation_output_hatch_64a.json @@ -8,7 +8,17 @@ "side" ], "variants": { - "": { + "is_formed=false": { + "model": { + "parent": "gtceu:block/machine/part/energy_output_hatch_64a", + "textures": { + "bottom": "gtceu:block/casings/voltage/zpm/bottom", + "side": "gtceu:block/casings/voltage/zpm/side", + "top": "gtceu:block/casings/voltage/zpm/top" + } + } + }, + "is_formed=true": { "model": { "parent": "gtceu:block/machine/part/energy_output_hatch_64a", "textures": { diff --git a/src/generated/resources/assets/gtceu/models/item/advanced_monitor.json b/src/generated/resources/assets/gtceu/models/item/advanced_monitor.json new file mode 100644 index 00000000000..c55fc13416e --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/advanced_monitor.json @@ -0,0 +1,3 @@ +{ + "parent": "gtceu:block/machine/advanced_monitor" +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/basic_data_access_hatch.json b/src/generated/resources/assets/gtceu/models/item/basic_data_access_hatch.json new file mode 100644 index 00000000000..1606b7b5928 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/basic_data_access_hatch.json @@ -0,0 +1,3 @@ +{ + "parent": "gtceu:block/machine/basic_data_access_hatch" +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/bronze_multiblock_tank.json b/src/generated/resources/assets/gtceu/models/item/bronze_multiblock_tank.json new file mode 100644 index 00000000000..44cbbf6c0bb --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/bronze_multiblock_tank.json @@ -0,0 +1,3 @@ +{ + "parent": "gtceu:block/machine/bronze_multiblock_tank" +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/bronze_tank_valve.json b/src/generated/resources/assets/gtceu/models/item/bronze_tank_valve.json new file mode 100644 index 00000000000..8e4314a8c3e --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/bronze_tank_valve.json @@ -0,0 +1,3 @@ +{ + "parent": "gtceu:block/machine/bronze_tank_valve" +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/central_monitor.json b/src/generated/resources/assets/gtceu/models/item/central_monitor.json new file mode 100644 index 00000000000..06060c7263d --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/central_monitor.json @@ -0,0 +1,3 @@ +{ + "parent": "gtceu:block/machine/central_monitor" +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/ender_item_link_cover.json b/src/generated/resources/assets/gtceu/models/item/ender_item_link_cover.json new file mode 100644 index 00000000000..3166303c19e --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/ender_item_link_cover.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/ender_item_link_cover" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/ender_redstone_link_cover.json b/src/generated/resources/assets/gtceu/models/item/ender_redstone_link_cover.json new file mode 100644 index 00000000000..d96fcce6084 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/ender_redstone_link_cover.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/ender_redstone_link_cover" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/huge_pipe_casting_mold.json b/src/generated/resources/assets/gtceu/models/item/huge_pipe_casting_mold.json new file mode 100644 index 00000000000..c882f1b1b95 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/huge_pipe_casting_mold.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/huge_pipe_casting_mold" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/image_module.json b/src/generated/resources/assets/gtceu/models/item/image_module.json new file mode 100644 index 00000000000..cbbeb7225ca --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/image_module.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/image_module" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/large_pipe_casting_mold.json b/src/generated/resources/assets/gtceu/models/item/large_pipe_casting_mold.json new file mode 100644 index 00000000000..79d95045a6c --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/large_pipe_casting_mold.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/large_pipe_casting_mold" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/monitor.json b/src/generated/resources/assets/gtceu/models/item/monitor.json new file mode 100644 index 00000000000..501222af800 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/monitor.json @@ -0,0 +1,3 @@ +{ + "parent": "gtceu:block/machine/monitor" +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/normal_pipe_casting_mold.json b/src/generated/resources/assets/gtceu/models/item/normal_pipe_casting_mold.json new file mode 100644 index 00000000000..2b9f77849b3 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/normal_pipe_casting_mold.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/normal_pipe_casting_mold" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/small_pipe_casting_mold.json b/src/generated/resources/assets/gtceu/models/item/small_pipe_casting_mold.json new file mode 100644 index 00000000000..7759c860715 --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/small_pipe_casting_mold.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/small_pipe_casting_mold" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/text_module.json b/src/generated/resources/assets/gtceu/models/item/text_module.json new file mode 100644 index 00000000000..fe4ccea06aa --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/text_module.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/text_module" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/tiny_pipe_casting_mold.json b/src/generated/resources/assets/gtceu/models/item/tiny_pipe_casting_mold.json new file mode 100644 index 00000000000..0c834772f3d --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/tiny_pipe_casting_mold.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/tiny_pipe_casting_mold" + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/gtceu/models/item/wireless_transmitter_cover.json b/src/generated/resources/assets/gtceu/models/item/wireless_transmitter_cover.json new file mode 100644 index 00000000000..6b7360324ac --- /dev/null +++ b/src/generated/resources/assets/gtceu/models/item/wireless_transmitter_cover.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/generated", + "textures": { + "layer0": "gtceu:item/wireless_transmitter_cover" + } +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/concrete_powders.json b/src/generated/resources/data/c/tags/block/concrete_powders.json new file mode 100644 index 00000000000..3c2bae66750 --- /dev/null +++ b/src/generated/resources/data/c/tags/block/concrete_powders.json @@ -0,0 +1,20 @@ +{ + "values": [ + "minecraft:white_concrete_powder", + "minecraft:orange_concrete_powder", + "minecraft:magenta_concrete_powder", + "minecraft:light_blue_concrete_powder", + "minecraft:yellow_concrete_powder", + "minecraft:lime_concrete_powder", + "minecraft:pink_concrete_powder", + "minecraft:gray_concrete_powder", + "minecraft:light_gray_concrete_powder", + "minecraft:cyan_concrete_powder", + "minecraft:purple_concrete_powder", + "minecraft:blue_concrete_powder", + "minecraft:brown_concrete_powder", + "minecraft:green_concrete_powder", + "minecraft:red_concrete_powder", + "minecraft:black_concrete_powder" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/concretes.json b/src/generated/resources/data/c/tags/block/concretes.json new file mode 100644 index 00000000000..de733e1e36f --- /dev/null +++ b/src/generated/resources/data/c/tags/block/concretes.json @@ -0,0 +1,20 @@ +{ + "values": [ + "minecraft:white_concrete", + "minecraft:orange_concrete", + "minecraft:magenta_concrete", + "minecraft:light_blue_concrete", + "minecraft:yellow_concrete", + "minecraft:lime_concrete", + "minecraft:pink_concrete", + "minecraft:gray_concrete", + "minecraft:light_gray_concrete", + "minecraft:cyan_concrete", + "minecraft:purple_concrete", + "minecraft:blue_concrete", + "minecraft:brown_concrete", + "minecraft:green_concrete", + "minecraft:red_concrete", + "minecraft:black_concrete" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/fast_walkable_blocks.json b/src/generated/resources/data/c/tags/block/fast_walkable_blocks.json new file mode 100644 index 00000000000..42b113e3418 --- /dev/null +++ b/src/generated/resources/data/c/tags/block/fast_walkable_blocks.json @@ -0,0 +1,20 @@ +{ + "values": [ + "gtceu:white_studs", + "gtceu:orange_studs", + "gtceu:magenta_studs", + "gtceu:light_blue_studs", + "gtceu:yellow_studs", + "gtceu:lime_studs", + "gtceu:pink_studs", + "gtceu:gray_studs", + "gtceu:light_gray_studs", + "gtceu:cyan_studs", + "gtceu:purple_studs", + "gtceu:blue_studs", + "gtceu:brown_studs", + "gtceu:green_studs", + "gtceu:red_studs", + "gtceu:black_studs" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/block/very_fast_walkable_blocks.json b/src/generated/resources/data/c/tags/block/very_fast_walkable_blocks.json new file mode 100644 index 00000000000..fecb04ee14f --- /dev/null +++ b/src/generated/resources/data/c/tags/block/very_fast_walkable_blocks.json @@ -0,0 +1,34 @@ +{ + "values": [ + "gtceu:light_concrete", + "gtceu:dark_concrete", + "gtceu:light_concrete", + "gtceu:light_concrete_cobblestone", + "gtceu:mossy_light_concrete_cobblestone", + "gtceu:polished_light_concrete", + "gtceu:light_concrete_bricks", + "gtceu:cracked_light_concrete_bricks", + "gtceu:mossy_light_concrete_bricks", + "gtceu:chiseled_light_concrete", + "gtceu:light_concrete_tile", + "gtceu:light_concrete_small_tile", + "gtceu:light_concrete_windmill_a", + "gtceu:light_concrete_windmill_b", + "gtceu:small_light_concrete_bricks", + "gtceu:square_light_concrete_bricks", + "gtceu:dark_concrete", + "gtceu:dark_concrete_cobblestone", + "gtceu:mossy_dark_concrete_cobblestone", + "gtceu:polished_dark_concrete", + "gtceu:dark_concrete_bricks", + "gtceu:cracked_dark_concrete_bricks", + "gtceu:mossy_dark_concrete_bricks", + "gtceu:chiseled_dark_concrete", + "gtceu:dark_concrete_tile", + "gtceu:dark_concrete_small_tile", + "gtceu:dark_concrete_windmill_a", + "gtceu:dark_concrete_windmill_b", + "gtceu:small_dark_concrete_bricks", + "gtceu:square_dark_concrete_bricks" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/c/tags/item/tools/igniter.json b/src/generated/resources/data/c/tags/item/tools/igniter.json index 635a1d28172..9126dc5530f 100644 --- a/src/generated/resources/data/c/tags/item/tools/igniter.json +++ b/src/generated/resources/data/c/tags/item/tools/igniter.json @@ -3,6 +3,7 @@ "gtceu:matches", "gtceu:matchbox", "gtceu:invar_lighter", - "gtceu:platinum_lighter" + "gtceu:platinum_lighter", + "#minecraft:creeper_igniters" ] } \ No newline at end of file diff --git a/src/generated/resources/data/gtceu/gtceu/ore_vein/coal.json b/src/generated/resources/data/gtceu/gtceu/ore_vein/coal.json index f5b2c422062..79ab3693824 100644 --- a/src/generated/resources/data/gtceu/gtceu/ore_vein/coal.json +++ b/src/generated/resources/data/gtceu/gtceu/ore_vein/coal.json @@ -14,14 +14,6 @@ "type": "gtceu:layer", "layer_patterns": [ [ - { - "max_size": 4, - "min_size": 2, - "targets": [ - "gtceu:coal" - ], - "weight": 3 - }, { "max_size": 4, "min_size": 2, diff --git a/src/generated/resources/data/gtceu/tags/block/incorrect_for_neutronium_tool.json b/src/generated/resources/data/gtceu/tags/block/incorrect_for_neutronium_tool.json new file mode 100644 index 00000000000..ee98a1be3e1 --- /dev/null +++ b/src/generated/resources/data/gtceu/tags/block/incorrect_for_neutronium_tool.json @@ -0,0 +1,3 @@ +{ + "values": [] +} \ No newline at end of file diff --git a/src/generated/resources/data/gtceu/tags/fluid/hpca_coolants.json b/src/generated/resources/data/gtceu/tags/fluid/hpca_coolants.json new file mode 100644 index 00000000000..28b07cd30c2 --- /dev/null +++ b/src/generated/resources/data/gtceu/tags/fluid/hpca_coolants.json @@ -0,0 +1,5 @@ +{ + "values": [ + "gtceu:pcb_coolant" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/gtceu/tags/item/skip_item_detector.json b/src/generated/resources/data/gtceu/tags/item/skip_item_detector.json new file mode 100644 index 00000000000..dbe67132ddb --- /dev/null +++ b/src/generated/resources/data/gtceu/tags/item/skip_item_detector.json @@ -0,0 +1,5 @@ +{ + "values": [ + "gtceu:programmed_circuit" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/incorrect_for_diamond_tool.json b/src/generated/resources/data/minecraft/tags/block/incorrect_for_diamond_tool.json index 19fa65b7660..f798ba82dc5 100644 --- a/src/generated/resources/data/minecraft/tags/block/incorrect_for_diamond_tool.json +++ b/src/generated/resources/data/minecraft/tags/block/incorrect_for_diamond_tool.json @@ -1,7 +1,6 @@ { "values": [ - "#neoforge:needs_netherite_tool", - "#gtceu:needs_duranium_tool", - "#gtceu:needs_neutronium_tool" + "#gtceu:needs_neutronium_tool", + "#gtceu:needs_duranium_tool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/incorrect_for_gold_tool.json b/src/generated/resources/data/minecraft/tags/block/incorrect_for_gold_tool.json new file mode 100644 index 00000000000..f798ba82dc5 --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/block/incorrect_for_gold_tool.json @@ -0,0 +1,6 @@ +{ + "values": [ + "#gtceu:needs_neutronium_tool", + "#gtceu:needs_duranium_tool" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/incorrect_for_iron_tool.json b/src/generated/resources/data/minecraft/tags/block/incorrect_for_iron_tool.json new file mode 100644 index 00000000000..f798ba82dc5 --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/block/incorrect_for_iron_tool.json @@ -0,0 +1,6 @@ +{ + "values": [ + "#gtceu:needs_neutronium_tool", + "#gtceu:needs_duranium_tool" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/incorrect_for_netherite_tool.json b/src/generated/resources/data/minecraft/tags/block/incorrect_for_netherite_tool.json index e17b34401d3..f798ba82dc5 100644 --- a/src/generated/resources/data/minecraft/tags/block/incorrect_for_netherite_tool.json +++ b/src/generated/resources/data/minecraft/tags/block/incorrect_for_netherite_tool.json @@ -1,6 +1,6 @@ { "values": [ - "#gtceu:needs_duranium_tool", - "#gtceu:needs_neutronium_tool" + "#gtceu:needs_neutronium_tool", + "#gtceu:needs_duranium_tool" ] } \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/incorrect_for_stone_tool.json b/src/generated/resources/data/minecraft/tags/block/incorrect_for_stone_tool.json new file mode 100644 index 00000000000..f798ba82dc5 --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/block/incorrect_for_stone_tool.json @@ -0,0 +1,6 @@ +{ + "values": [ + "#gtceu:needs_neutronium_tool", + "#gtceu:needs_duranium_tool" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/block/incorrect_for_wooden_tool.json b/src/generated/resources/data/minecraft/tags/block/incorrect_for_wooden_tool.json new file mode 100644 index 00000000000..f798ba82dc5 --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/block/incorrect_for_wooden_tool.json @@ -0,0 +1,6 @@ +{ + "values": [ + "#gtceu:needs_neutronium_tool", + "#gtceu:needs_duranium_tool" + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/item/enchanting_fuels.json b/src/generated/resources/data/neoforge/tags/item/enchanting_fuels.json new file mode 100644 index 00000000000..26fc8f22274 --- /dev/null +++ b/src/generated/resources/data/neoforge/tags/item/enchanting_fuels.json @@ -0,0 +1,6 @@ +{ + "values": [ + "gtceu:lazurite_gem", + "gtceu:sodalite_gem" + ] +} \ No newline at end of file diff --git a/src/main/java/com/gregtechceu/gtceu/GTCEu.java b/src/main/java/com/gregtechceu/gtceu/GTCEu.java index 814cd812acc..a94e4542372 100644 --- a/src/main/java/com/gregtechceu/gtceu/GTCEu.java +++ b/src/main/java/com/gregtechceu/gtceu/GTCEu.java @@ -246,5 +246,9 @@ public static boolean isGameStagesLoaded() { public static boolean isCCTweakedLoaded() { return isModLoaded(GTValues.MODID_CCTWEAKED); } + + public static boolean isCreateLoaded() { + return isModLoaded(GTValues.MODID_CREATE); + } } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/GTCEuAPI.java b/src/main/java/com/gregtechceu/gtceu/api/GTCEuAPI.java index 1079446b14f..3f8b0cc704c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/GTCEuAPI.java +++ b/src/main/java/com/gregtechceu/gtceu/api/GTCEuAPI.java @@ -22,7 +22,7 @@ public class GTCEuAPI { - public static final int GT_DATA_VERSION = 3; + public static final int GT_DATA_VERSION = 4; public static final String NETWORK_VERSION = "3"; /** Will always be available */ diff --git a/src/main/java/com/gregtechceu/gtceu/api/GTValues.java b/src/main/java/com/gregtechceu/gtceu/api/GTValues.java index c4a5f83b380..df7aaf3e0a2 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/GTValues.java +++ b/src/main/java/com/gregtechceu/gtceu/api/GTValues.java @@ -36,13 +36,28 @@ public class GTValues { public static final int L = 144; public static final RandomSource RNG = RandomSource.createThreadSafe(); + // shortcut for various lengths of time in ticks + public static final long SECONDS = 20; + public static final long MINUTES = 60 * SECONDS; + public static final long HOURS = 60 * MINUTES; + public static final long DAYS = 24 * HOURS; + public static final long WEEKS = 7 * DAYS; + public static final long MONTHS = 30 * DAYS; + public static final long YEARS = 365 * DAYS; + + /** + * The Item WildCard Tag. Even shorter than the "-1" of the past + */ + + // public static final short W = OreDictionary.WILDCARD_VALUE; + /** Current time on the Client. Will always be zero on the server. */ public static long CLIENT_TIME = 0; /** * The Voltage Tiers. Use this Array instead of the old named Voltage Variables */ - public static final long[] V = new long[] { 8, 32, 128, 512, 2048, 8192, 32768, 131072, 524288, 2097152, 8388608, + public static final long[] V = { 8, 32, 128, 512, 2048, 8192, 32768, 131072, 524288, 2097152, 8388608, 33554432, 134217728, 536870912, 2147483648L }; /** @@ -54,19 +69,19 @@ public class GTValues { /** * The Voltage Tiers adjusted for cable loss. Use this for recipe EU/t to avoid full-amp recipes */ - public static final int[] VA = new int[] { 7, 30, 120, 480, 1920, 7680, 30720, 122880, 491520, 1966080, 7864320, + public static final int[] VA = { 7, 30, 120, 480, 1920, 7680, 30720, 122880, 491520, 1966080, 7864320, 31457280, 125829120, 503316480, 2013265920 }; /** * The Voltage Tiers adjusted for cable loss, divided by 2. */ - public static final int[] VHA = { 7, 16, 60, 240, 960, 3840, 15360, 61440, 245760, 983040, 3932160, 15728640, + public static final int[] VHA = { 3, 15, 60, 240, 960, 3840, 15360, 61440, 245760, 983040, 3932160, 15728640, 62914560, 251658240, 1006632960 }; /** * The Voltage Tiers. Use this Array instead of the old named Voltage Variables */ - public static final long[] VEX = new long[] { 8, 32, 128, 512, 2048, 8192, 32768, 131072, 524288, 2097152, 8388608, + public static final long[] VEX = { 8, 32, 128, 512, 2048, 8192, 32768, 131072, 524288, 2097152, 8388608, 33554432, 134217728, 536870912, 2147483648L, 8589934592L, 34359738368L, 137438953472L, 549755813888L, 2199023255552L, 8796093022208L, 35184372088832L, 140737488355328L, 562949953421312L, 2251799813685248L, 9007199254740992L, 36028797018963968L, 144115188075855872L, 576460752303423488L, 2305843009213693952L, @@ -120,7 +135,8 @@ public static int[] tiersBetween(int minInclusive, int maxInclusive) { MODID_HERACLES = "heracles", MODID_GAMESTAGES = "gamestages", MODID_FTB_QUEST = "ftbquests", - MODID_CCTWEAKED = "computercraft"; + MODID_CCTWEAKED = "computercraft", + MODID_CREATE = "create"; /** * Spray painting compat modids @@ -270,6 +286,10 @@ public static int[] tiersBetween(int minInclusive, int maxInclusive) { RED.getColor() }; + // Main color for steam machines + public static final int VC_LP_STEAM = 0xBB8E53; + public static final int VC_HP_STEAM = 0x79756F; + /** * The long names for the voltages */ diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/ActiveBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/ActiveBlock.java index bc4c182ba63..d031d9988f3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/block/ActiveBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/api/block/ActiveBlock.java @@ -1,5 +1,6 @@ package com.gregtechceu.gtceu.api.block; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.BlockAndTintGetter; @@ -11,9 +12,13 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + import static com.gregtechceu.gtceu.api.block.property.GTBlockStateProperties.ACTIVE; -public class ActiveBlock extends AppearanceBlock { +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class ActiveBlock extends Block { public ActiveBlock(Properties properties) { super(properties); @@ -46,8 +51,8 @@ public boolean isActive(BlockState state) { } @Override - public BlockState getBlockAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, - @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) { + public BlockState getAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, + @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) { return defaultBlockState(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/AppearanceBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/AppearanceBlock.java index 0e944446d26..95ee548a54d 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/block/AppearanceBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/api/block/AppearanceBlock.java @@ -8,6 +8,9 @@ import org.jetbrains.annotations.Nullable; +/// @deprecated Use normal Block class instead - replace `AppearanceBlock::getBlockAppearance` with +/// `Block::getAppearance` +@Deprecated(forRemoval = true) public class AppearanceBlock extends Block implements IAppearance { public AppearanceBlock(Properties properties) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/BlockAttributes.java b/src/main/java/com/gregtechceu/gtceu/api/block/BlockAttributes.java new file mode 100644 index 00000000000..fb539251ed9 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/block/BlockAttributes.java @@ -0,0 +1,10 @@ +package com.gregtechceu.gtceu.api.block; + +import com.gregtechceu.gtceu.GTCEu; + +import net.minecraft.resources.ResourceLocation; + +public class BlockAttributes { + + public static final ResourceLocation BLOCK_SPEED_BOOST = GTCEu.id("block_speed_boost"); +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/IAppearance.java b/src/main/java/com/gregtechceu/gtceu/api/block/IAppearance.java index f9853098fcc..1f018321ef3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/block/IAppearance.java +++ b/src/main/java/com/gregtechceu/gtceu/api/block/IAppearance.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.Nullable; +@Deprecated(forRemoval = true) public interface IAppearance { /** diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/MaterialBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/MaterialBlock.java index 98ad0d769cd..de48cad1ea6 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/block/MaterialBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/api/block/MaterialBlock.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.data.material.GTMaterials; import com.gregtechceu.gtceu.data.recipe.VanillaRecipeHelper; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.client.color.block.BlockColor; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -52,8 +53,11 @@ import java.util.Set; import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; -public class MaterialBlock extends AppearanceBlock { +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class MaterialBlock extends Block { public final TagPrefix tagPrefix; public final Material material; diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java index 5f81adbba30..1c2876a74ab 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/api/block/MetaMachineBlock.java @@ -15,6 +15,7 @@ import com.gregtechceu.gtceu.data.item.GTItems; import com.gregtechceu.gtceu.utils.GTUtil; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.locale.Language; @@ -55,7 +56,12 @@ import java.util.List; import java.util.Set; -public class MetaMachineBlock extends AppearanceBlock implements IMachineBlock { +import javax.annotation.ParametersAreNonnullByDefault; + +@SuppressWarnings("deprecation") +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class MetaMachineBlock extends Block implements IMachineBlock { @Getter public final MachineDefinition definition; @@ -353,13 +359,13 @@ public void neighborChanged(BlockState state, Level level, BlockPos pos, Block b @Nullable @Override - public BlockState getBlockAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, - @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) { + public BlockState getAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, + @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) { var machine = getMachine(level, pos); if (machine != null) { return machine.getBlockAppearance(state, level, pos, side, sourceState, sourcePos); } - return super.getBlockAppearance(state, level, pos, side, sourceState, sourcePos); + return super.getAppearance(state, level, pos, side, sourceState, sourcePos); } public static ItemInteractionResult getFromInteractionResult(InteractionResult result) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java b/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java index a296047d551..b47bd5a4214 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/api/block/PipeBlock.java @@ -68,7 +68,7 @@ @SuppressWarnings("deprecation") public abstract class PipeBlock & IPipeType, NodeDataType, - WorldPipeNetType extends LevelPipeNet>> extends AppearanceBlock + WorldPipeNetType extends LevelPipeNet>> extends Block implements EntityBlock, IBlockRendererProvider, SimpleWaterloggedBlock { public final PipeType pipeType; @@ -407,15 +407,13 @@ public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, pipeBlockEntity = pipeTile; } - // slightly cleaner this way, I hope? - boolean hasCover = CoverPlaceBehavior.isCoverBehaviorItem(held, coverable::hasAnyCover, - coverDef -> ICoverable.canPlaceCover(coverDef, coverable)); - boolean holdingSamePipe = held.getItem() instanceof BlockItem blockItem && - blockItem.getBlock() instanceof PipeBlock pipeBlock && - pipeBlock.pipeType.type().equals(pipeType.type()); - boolean hasTool = types.stream().anyMatch(type -> type.itemTags.stream().anyMatch(held::is)); - boolean hasAbility = pipeBlockEntity != null && pipeBlockEntity.hasCorrectAction(held); - if (hasCover || holdingSamePipe || hasTool || hasAbility) { + if ((player.isShiftKeyDown() && held.isEmpty() && coverable.hasAnyCover()) || + types.stream().anyMatch(type -> type.matchTags.stream().anyMatch(held::is)) || + CoverPlaceBehavior.isCoverBehaviorItem(held, coverable::hasAnyCover, + coverDef -> ICoverable.canPlaceCover(coverDef, coverable)) || + (held.getItem() instanceof BlockItem blockItem && + blockItem.getBlock() instanceof PipeBlock pipeBlock && + pipeBlock.pipeType.type().equals(pipeType.type()))) { return Shapes.block(); } } @@ -441,15 +439,15 @@ public BlockEntityTicker getTicker(Level level, Block } @Override - public BlockState getBlockAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, - @Nullable BlockState sourceState, BlockPos sourcePos) { + public BlockState getAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, + @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) { var pipe = getPipeTile(level, pos); if (pipe != null) { var appearance = pipe.getCoverContainer().getBlockAppearance(state, level, pos, side, sourceState, sourcePos); if (appearance != null) return appearance; } - return super.getBlockAppearance(state, level, pos, side, sourceState, sourcePos); + return super.getAppearance(state, level, pos, side, sourceState, sourcePos); } @Override @@ -468,4 +466,8 @@ public List getDrops(BlockState state, LootParams.Builder builder) { } return drops; } + + public GTToolType getPipeTuneTool() { + return GTToolType.WRENCH; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/blockentity/IPaintable.java b/src/main/java/com/gregtechceu/gtceu/api/blockentity/IPaintable.java index bb17dd79ffa..26105165b5b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/blockentity/IPaintable.java +++ b/src/main/java/com/gregtechceu/gtceu/api/blockentity/IPaintable.java @@ -1,10 +1,12 @@ package com.gregtechceu.gtceu.api.blockentity; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; + import net.minecraft.world.level.block.state.properties.BooleanProperty; public interface IPaintable { - BooleanProperty IS_PAINTED_PROPERTY = BooleanProperty.create("is_painted"); + BooleanProperty IS_PAINTED_PROPERTY = GTMachineModelProperties.IS_PAINTED; int UNPAINTED_COLOR = 0xffffffff; /** diff --git a/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java b/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java index 2fa89e185e3..94e4a39bddd 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java +++ b/src/main/java/com/gregtechceu/gtceu/api/blockentity/MetaMachineBlockEntity.java @@ -157,6 +157,155 @@ public void setChanged() { } } + // public static LazyOptional getCapability(MetaMachine machine, @NotNull Capability cap, + // @Nullable Direction side) { + // if (cap == GTCapability.CAPABILITY_COVERABLE) { + // return GTCapability.CAPABILITY_COVERABLE.orEmpty(cap, LazyOptional.of(machine::getCoverContainer)); + // } else if (cap == GTCapability.CAPABILITY_TOOLABLE) { + // return GTCapability.CAPABILITY_TOOLABLE.orEmpty(cap, LazyOptional.of(() -> machine)); + // } else if (cap == GTCapability.CAPABILITY_WORKABLE) { + // if (machine instanceof IWorkable workable) { + // return GTCapability.CAPABILITY_WORKABLE.orEmpty(cap, LazyOptional.of(() -> workable)); + // } + // for (MachineTrait trait : machine.getTraits()) { + // if (trait instanceof IWorkable workable) { + // return GTCapability.CAPABILITY_WORKABLE.orEmpty(cap, LazyOptional.of(() -> workable)); + // } + // } + // } else if (cap == GTCapability.CAPABILITY_CONTROLLABLE) { + // if (machine instanceof IControllable controllable) { + // return GTCapability.CAPABILITY_CONTROLLABLE.orEmpty(cap, LazyOptional.of(() -> controllable)); + // } + // for (MachineTrait trait : machine.getTraits()) { + // if (trait instanceof IControllable controllable) { + // return GTCapability.CAPABILITY_CONTROLLABLE.orEmpty(cap, LazyOptional.of(() -> controllable)); + // } + // } + // } else if (cap == GTCapability.CAPABILITY_RECIPE_LOGIC) { + // for (MachineTrait trait : machine.getTraits()) { + // if (trait instanceof RecipeLogic recipeLogic) { + // return GTCapability.CAPABILITY_RECIPE_LOGIC.orEmpty(cap, LazyOptional.of(() -> recipeLogic)); + // } + // } + // } else if (cap == GTCapability.CAPABILITY_ENERGY_CONTAINER) { + // if (machine instanceof IEnergyContainer energyContainer) { + // return GTCapability.CAPABILITY_ENERGY_CONTAINER.orEmpty(cap, LazyOptional.of(() -> energyContainer)); + // } + // var list = getCapabilitiesFromTraits(machine.getTraits(), side, IEnergyContainer.class); + // if (!list.isEmpty()) { + // return GTCapability.CAPABILITY_ENERGY_CONTAINER.orEmpty(cap, + // LazyOptional.of(() -> list.size() == 1 ? list.get(0) : new EnergyContainerList(list))); + // } + // } else if (cap == GTCapability.CAPABILITY_ENERGY_INFO_PROVIDER) { + // if (machine instanceof IEnergyInfoProvider energyInfoProvider) { + // return GTCapability.CAPABILITY_ENERGY_INFO_PROVIDER.orEmpty(cap, + // LazyOptional.of(() -> energyInfoProvider)); + // } + // var list = getCapabilitiesFromTraits(machine.getTraits(), side, IEnergyInfoProvider.class); + // if (!list.isEmpty()) { + // return GTCapability.CAPABILITY_ENERGY_INFO_PROVIDER.orEmpty(cap, + // LazyOptional.of(() -> list.size() == 1 ? list.get(0) : new EnergyInfoProviderList(list))); + // } + // } else if (cap == GTCapability.CAPABILITY_CLEANROOM_RECEIVER) { + // if (machine instanceof ICleanroomReceiver cleanroomReceiver) { + // return GTCapability.CAPABILITY_CLEANROOM_RECEIVER.orEmpty(cap, + // LazyOptional.of(() -> cleanroomReceiver)); + // } + // } else if (cap == GTCapability.CAPABILITY_MAINTENANCE_MACHINE) { + // if (machine instanceof IMaintenanceMachine maintenanceMachine) { + // return GTCapability.CAPABILITY_MAINTENANCE_MACHINE.orEmpty(cap, + // LazyOptional.of(() -> maintenanceMachine)); + // } + // } else if (cap == GTCapability.CAPABILITY_TURBINE_MACHINE) { + // if (machine instanceof ITurbineMachine turbineMachine) { + // return GTCapability.CAPABILITY_TURBINE_MACHINE.orEmpty(cap, + // LazyOptional.of(() -> turbineMachine)); + // } + // } else if (cap == ForgeCapabilities.ITEM_HANDLER) { + // var handler = machine.getItemHandlerCap(side, true); + // if (handler != null) { + // return ForgeCapabilities.ITEM_HANDLER.orEmpty(cap, LazyOptional.of(() -> handler)); + // } + // } else if (cap == ForgeCapabilities.FLUID_HANDLER) { + // var handler = machine.getFluidHandlerCap(side, true); + // if (handler != null) { + // return ForgeCapabilities.FLUID_HANDLER.orEmpty(cap, LazyOptional.of(() -> handler)); + // } + // } else if (cap == ForgeCapabilities.ENERGY) { + // if (machine instanceof IEnergyStorage energyStorage) { + // return ForgeCapabilities.ENERGY.orEmpty(cap, LazyOptional.of(() -> energyStorage)); + // } + // var list = getCapabilitiesFromTraits(machine.getTraits(), side, IEnergyStorage.class); + // if (!list.isEmpty()) { + // // TODO wrap list in the future + // return ForgeCapabilities.ENERGY.orEmpty(cap, LazyOptional.of(() -> list.get(0))); + // } + // } else if (cap == GTCapability.CAPABILITY_LASER) { + // if (machine instanceof ILaserContainer energyContainer) { + // return GTCapability.CAPABILITY_LASER.orEmpty(cap, LazyOptional.of(() -> energyContainer)); + // } + // var list = getCapabilitiesFromTraits(machine.getTraits(), side, ILaserContainer.class); + // if (!list.isEmpty()) { + // return GTCapability.CAPABILITY_LASER.orEmpty(cap, + // LazyOptional.of(() -> list.size() == 1 ? list.get(0) : new LaserContainerList(list))); + // } + // } else if (cap == GTCapability.CAPABILITY_COMPUTATION_PROVIDER) { + // if (machine instanceof IOpticalComputationProvider computationProvider) { + // return GTCapability.CAPABILITY_COMPUTATION_PROVIDER.orEmpty(cap, + // LazyOptional.of(() -> computationProvider)); + // } + // var list = getCapabilitiesFromTraits(machine.getTraits(), side, IOpticalComputationProvider.class); + // if (!list.isEmpty()) { + // return GTCapability.CAPABILITY_COMPUTATION_PROVIDER.orEmpty(cap, LazyOptional.of(() -> list.get(0))); + // } + // } else if (cap == GTCapability.CAPABILITY_DATA_ACCESS) { + // if (machine instanceof IDataAccessHatch computationProvider) { + // return GTCapability.CAPABILITY_DATA_ACCESS.orEmpty(cap, LazyOptional.of(() -> computationProvider)); + // } + // var list = getCapabilitiesFromTraits(machine.getTraits(), side, IDataAccessHatch.class); + // if (!list.isEmpty()) { + // return GTCapability.CAPABILITY_DATA_ACCESS.orEmpty(cap, LazyOptional.of(() -> list.get(0))); + // } + // } else if (cap == GTCapability.CAPABILITY_MONITOR_COMPONENT) { + // if (machine instanceof IMonitorComponent monitorComponent) { + // return GTCapability.CAPABILITY_MONITOR_COMPONENT.orEmpty(cap, LazyOptional.of(() -> monitorComponent)); + // } + // var list = getCapabilitiesFromTraits(machine.getTraits(), side, IMonitorComponent.class); + // if (!list.isEmpty()) { + // return GTCapability.CAPABILITY_MONITOR_COMPONENT.orEmpty(cap, LazyOptional.of(() -> list.get(0))); + // } + // } else if (cap == GTCapability.CAPABILITY_CENTRAL_MONITOR) { + // if (machine instanceof ICentralMonitor centralMonitor) { + // return GTCapability.CAPABILITY_CENTRAL_MONITOR.orEmpty(cap, LazyOptional.of(() -> centralMonitor)); + // } + // var list = getCapabilitiesFromTraits(machine.getTraits(), side, ICentralMonitor.class); + // if (!list.isEmpty()) { + // return GTCapability.CAPABILITY_CENTRAL_MONITOR.orEmpty(cap, LazyOptional.of(() -> list.get(0))); + // } + // } + // if (GTCEu.Mods.isAE2Loaded()) { + // LazyOptional opt = AE2CallWrapper.getGridNodeHostCapability(cap, machine, side); + // if (opt.isPresent()) { + // // noinspection unchecked + // return (LazyOptional) opt; + // } + // } + // return LazyOptional.empty(); + // } + + // public static List getCapabilitiesFromTraits(List traits, Direction accessSide, + // Class capability) { + // if (traits.isEmpty()) return Collections.emptyList(); + // List list = new ArrayList<>(); + // for (MachineTrait trait : traits) { + // if (trait.hasCapability(accessSide) && capability.isInstance(trait)) { + // list.add(capability.cast(trait)); + // } + // } + // return list; + // } + + // >>>>>>> v7.1.0-1.20.1 /** * Extending interface to make {@link BlockEntity.DataComponentInput} public as it's protected by default. */ diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/GTCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/GTCapability.java index cffe947e317..4dd2665cfb2 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/GTCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/GTCapability.java @@ -38,4 +38,10 @@ public class GTCapability { .createSided(GTCEu.id("data_access"), IDataAccessHatch.class); public static final BlockCapability CAPABILITY_HAZARD_CONTAINER = BlockCapability .createSided(GTCEu.id("hazard_particle_container"), IHazardParticleContainer.class); + public static final BlockCapability CAPABILITY_MONITOR_COMPONENT = BlockCapability + .createSided(GTCEu.id("monitor_component"), IMonitorComponent.class); + public static final BlockCapability CAPABILITY_TURBINE_MACHINE = BlockCapability + .createSided(GTCEu.id("turbine_machine"), ITurbineMachine.class); + public static final BlockCapability CAPABILITY_CENTRAL_MONITOR = BlockCapability + .createSided(GTCEu.id("central_monitor"), ICentralMonitor.class); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/GTCapabilityHelper.java b/src/main/java/com/gregtechceu/gtceu/api/capability/GTCapabilityHelper.java index 81c6f01b658..4e6732f0036 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/GTCapabilityHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/GTCapabilityHelper.java @@ -11,6 +11,8 @@ import net.minecraft.world.level.Level; import net.neoforged.neoforge.capabilities.Capabilities; import net.neoforged.neoforge.energy.IEnergyStorage; +import net.neoforged.neoforge.fluids.capability.IFluidHandler; +import net.neoforged.neoforge.items.IItemHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,6 +29,16 @@ public static IEnergyStorage getForgeEnergyItem(ItemStack itemStack) { return itemStack.getCapability(Capabilities.EnergyStorage.ITEM); } + @Nullable + public static IItemHandler getItemHandler(Level level, BlockPos pos, @Nullable Direction side) { + return level.getCapability(Capabilities.ItemHandler.BLOCK, pos, side); + } + + @Nullable + public static IFluidHandler getFluidHandler(Level level, BlockPos pos, @Nullable Direction side) { + return level.getCapability(Capabilities.FluidHandler.BLOCK, pos, side); + } + @Nullable public static IEnergyContainer getEnergyContainer(Level level, BlockPos pos, @Nullable Direction side) { return level.getCapability(GTCapability.CAPABILITY_ENERGY_CONTAINER, pos, side); @@ -101,4 +113,9 @@ public static IHazardParticleContainer getHazardContainer(Level level, BlockPos public static IMedicalConditionTracker getMedicalConditionTracker(@NotNull Player entity) { return entity.getData(GTAttachmentTypes.MEDICAL_CONDITION_TRACKER); } + + @Nullable + public static IMonitorComponent getMonitorComponent(Level level, BlockPos pos, @Nullable Direction side) { + return level.getCapability(GTCapability.CAPABILITY_MONITOR_COMPONENT, pos, side); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/ICentralMonitor.java b/src/main/java/com/gregtechceu/gtceu/api/capability/ICentralMonitor.java new file mode 100644 index 00000000000..42d7fc528bb --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/ICentralMonitor.java @@ -0,0 +1,10 @@ +package com.gregtechceu.gtceu.api.capability; + +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; + +import java.util.List; + +public interface ICentralMonitor { + + List getMonitorGroups(); +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/IControllable.java b/src/main/java/com/gregtechceu/gtceu/api/capability/IControllable.java index e72890e03e0..f46ae7ec81f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/IControllable.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/IControllable.java @@ -1,10 +1,12 @@ package com.gregtechceu.gtceu.api.capability; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; + import net.minecraft.world.level.block.state.properties.BooleanProperty; public interface IControllable { - BooleanProperty WORKING_ENABLED_PROPERTY = BooleanProperty.create("working_enabled"); + BooleanProperty WORKING_ENABLED_PROPERTY = GTMachineModelProperties.IS_WORKING_ENABLED; /** * @return true if the controllable is allowed to work @@ -19,4 +21,8 @@ public interface IControllable { void setWorkingEnabled(boolean isWorkingAllowed); default void setSuspendAfterFinish(boolean suspendAfterFinish) {} + + default boolean isSuspendAfterFinish() { + return false; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/ICoverable.java b/src/main/java/com/gregtechceu/gtceu/api/capability/ICoverable.java index 9e3f9f8f477..430f46228cc 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/ICoverable.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/ICoverable.java @@ -1,7 +1,6 @@ package com.gregtechceu.gtceu.api.capability; import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.block.IAppearance; import com.gregtechceu.gtceu.api.blockentity.ITickSubscription; import com.gregtechceu.gtceu.api.cover.CoverBehavior; import com.gregtechceu.gtceu.api.cover.CoverDefinition; @@ -26,7 +25,6 @@ import net.neoforged.neoforge.items.IItemHandlerModifiable; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -35,7 +33,7 @@ import java.util.Objects; import java.util.stream.Collectors; -public interface ICoverable extends ITickSubscription, IAppearance { +public interface ICoverable extends ITickSubscription { Level getLevel(); @@ -81,7 +79,7 @@ public interface ICoverable extends ITickSubscription, IAppearance { CoverBehavior getCoverAtSide(Direction side); default boolean placeCoverOnSide(Direction side, ItemStack itemStack, CoverDefinition coverDefinition, - ServerPlayer player) { + @Nullable ServerPlayer player) { CoverBehavior coverBehavior = coverDefinition.createCoverBehavior(this, side); if (!canPlaceCoverOnSide(coverDefinition, side) || !coverBehavior.canAttach()) { return false; @@ -216,13 +214,31 @@ static Direction rayTraceCoverableSide(ICoverable coverable, Player player) { return traceCoverSide((BlockHitResult) rayTrace); } + default boolean hasDynamicCovers() { + for (Direction face : GTUtil.DIRECTIONS) { + CoverBehavior cover = this.getCoverAtSide(face); + if (cover != null && cover.getDynamicRenderer().get() != null) return true; + } + return false; + } + + class PrimaryBoxData { + + public final boolean usePlacementGrid; + + public PrimaryBoxData(boolean usePlacementGrid) { + this.usePlacementGrid = usePlacementGrid; + } + } + @Nullable - static Direction traceCoverSide(BlockHitResult result) { + static Direction traceCoverSide(@Nullable BlockHitResult result) { return determineGridSideHit(result); } @Nullable - static Direction determineGridSideHit(BlockHitResult result) { + static Direction determineGridSideHit(@Nullable BlockHitResult result) { + if (result == null) return null; return GTUtil.determineWrenchingSide(result.getDirection(), (float) (result.getLocation().x - result.getBlockPos().getX()), (float) (result.getLocation().y - result.getBlockPos().getY()), @@ -253,13 +269,10 @@ static boolean canPlaceCover(CoverDefinition coverDef, ICoverable coverable) { } @Nullable - @Override - default BlockState getBlockAppearance(@NotNull BlockState state, @NotNull BlockAndTintGetter level, - @NotNull BlockPos pos, @NotNull Direction side, - @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) { - CoverBehavior cover = getCoverAtSide(side); - if (cover != null) { - return cover.getAppearance(sourceState, sourcePos); + default BlockState getBlockAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, + BlockState sourceState, BlockPos sourcePos) { + if (hasCover(side)) { + return getCoverAtSide(side).getAppearance(sourceState, sourcePos); } return null; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/IHPCAComponentHatch.java b/src/main/java/com/gregtechceu/gtceu/api/capability/IHPCAComponentHatch.java index 9a3c9e8ed1f..dd2cbadfd94 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/IHPCAComponentHatch.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/IHPCAComponentHatch.java @@ -1,12 +1,14 @@ package com.gregtechceu.gtceu.api.capability; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; + import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; import net.minecraft.world.level.block.state.properties.BooleanProperty; public interface IHPCAComponentHatch { - BooleanProperty HPCA_PART_DAMAGED_PROPERTY = BooleanProperty.create("hpca_part_damaged"); + BooleanProperty HPCA_PART_DAMAGED_PROPERTY = GTMachineModelProperties.IS_HPCA_PART_DAMAGED; /** * How much EU/t this component needs for the multi to just be idle. @@ -51,4 +53,9 @@ default void setDamaged(boolean damaged) {} * The icon for this component in the HPCA's UI. Should be a 13x13 px sprite. */ ResourceTexture getComponentIcon(); + + /** + * Sets the component to be active for the sake of model overlays. + */ + void setActive(boolean active); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/IMonitorComponent.java b/src/main/java/com/gregtechceu/gtceu/api/capability/IMonitorComponent.java new file mode 100644 index 00000000000..bbeea735b79 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/IMonitorComponent.java @@ -0,0 +1,23 @@ +package com.gregtechceu.gtceu.api.capability; + +import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; + +import net.minecraft.core.BlockPos; +import net.neoforged.neoforge.items.IItemHandler; + +import org.jetbrains.annotations.Nullable; + +public interface IMonitorComponent { + + default boolean isMonitor() { + return false; + } + + IGuiTexture getComponentIcon(); + + BlockPos getPos(); + + default @Nullable net.neoforged.neoforge.items.IItemHandler getDataItems() { + return null; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/ITurbineMachine.java b/src/main/java/com/gregtechceu/gtceu/api/capability/ITurbineMachine.java new file mode 100644 index 00000000000..c1fe3cfa157 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/ITurbineMachine.java @@ -0,0 +1,42 @@ +package com.gregtechceu.gtceu.api.capability; + +/** + * For the large gas turbine / large plasma turbine + */ +public interface ITurbineMachine extends IWorkable { + + /** + * @return true if the machine has a roter installed + */ + boolean hasRotor(); + + /** + * @return the current rotor speed or 0 when no rotor is installed + */ + int getRotorSpeed(); + + /** + * @return the maximum rotor speed or 0 when no rotor is installed + */ + int getMaxRotorHolderSpeed(); + + /** + * @return the total efficiency the rotor holder and rotor provide in % or -1 when no rotor is installed + */ + int getTotalEfficiency(); + + /** + * @return the current energy production + */ + long getCurrentProduction(); + + /** + * @return the maximum energy production + */ + long getOverclockVoltage(); + + /** + * @return the rotor durability in % or -1 when no rotor is installed + */ + int getRotorDurabilityPercent(); +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/IWorkable.java b/src/main/java/com/gregtechceu/gtceu/api/capability/IWorkable.java index 114ac7edb8d..3db349c2b12 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/IWorkable.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/IWorkable.java @@ -1,5 +1,7 @@ package com.gregtechceu.gtceu.api.capability; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; + import net.minecraft.world.level.block.state.properties.BooleanProperty; /** @@ -7,7 +9,7 @@ */ public interface IWorkable extends IControllable { - BooleanProperty ACTIVE_PROPERTY = BooleanProperty.create("active"); + BooleanProperty ACTIVE_PROPERTY = GTMachineModelProperties.IS_ACTIVE; /** * @return current progress of machine diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/CWURecipeCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/CWURecipeCapability.java index 4e988895144..788db01bcdb 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/CWURecipeCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/CWURecipeCapability.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; import com.gregtechceu.gtceu.api.recipe.content.SerializerInteger; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; +import com.gregtechceu.gtceu.utils.FormattingUtil; import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; @@ -38,11 +39,12 @@ public void addXEIInfo(WidgetGroup group, int xOffset, GTRecipe recipe, List compressIngredients(Collection ingredients) { List list = new ObjectArrayList<>(ingredients.size()); @@ -96,7 +94,7 @@ public List compressIngredients(Collection ingredients) { break; } } else if (obj instanceof FluidStack fluidStack) { - if (fluid.test(fluidStack)) { + if (fluid.ingredient().test(fluidStack)) { isEqual = true; break; } @@ -108,7 +106,7 @@ public List compressIngredients(Collection ingredients) { boolean isEqual = false; for (Object obj : list) { if (obj instanceof SizedFluidIngredient fluidIngredient) { - if (fluidIngredient.test(fluidStack)) { + if (fluidIngredient.ingredient().test(fluidStack)) { isEqual = true; break; } @@ -196,13 +194,14 @@ public int getMaxParallelByInput(IRecipeCapabilityHolder holder, GTRecipe recipe if (inputs == null || inputs.isEmpty()) return limit; // Find all the fluids in the combined Fluid Input inventories and create oversized FluidStacks - List> inventoryGroups = getInputContents(holder); + List> inventoryGroups = getInputContents(holder); if (inventoryGroups.isEmpty()) return 0; // map the recipe ingredients to account for duplicated and notConsumable ingredients. // notConsumable ingredients are not counted towards the max ratio - var nonConsumables = new Object2IntOpenHashMap(); - var consumables = new Object2IntOpenHashMap(); + + var nonConsumables = new Object2LongOpenHashMap(); + var consumables = new Object2LongOpenHashMap(); for (Content content : inputs) { SizedFluidIngredient ing = of(content.content); @@ -213,8 +212,22 @@ public int getMaxParallelByInput(IRecipeCapabilityHolder holder, GTRecipe recipe amount = ing.amount(); } - if (content.chance == 0) nonConsumables.addTo(ing, amount); - else consumables.addTo(ing, amount); + if (content.chance == 0) { + nonConsumables.addTo(ing, amount); + } else { + boolean has = false; + for (var recipeIng : consumables.object2LongEntrySet()) { + var stack = ing.getFluids()[0]; + if (recipeIng.getKey().ingredient().test(stack)) { + recipeIng.setValue(recipeIng.getLongValue() + stack.getAmount()); + has = true; + break; + } + } + if (!has) { + consumables.addTo(ing, amount); + } + } } // is this even possible @@ -225,13 +238,13 @@ public int getMaxParallelByInput(IRecipeCapabilityHolder holder, GTRecipe recipe for (var group : inventoryGroups) { // Check for enough NC in inventory group boolean satisfied = true; - for (var ncEntry : Object2IntMaps.fastIterable(nonConsumables)) { + for (var ncEntry : Object2LongMaps.fastIterable(nonConsumables)) { SizedFluidIngredient ingredient = ncEntry.getKey(); - int needed = ncEntry.getIntValue(); - for (var stackEntry : Object2IntMaps.fastIterable(group)) { + long needed = ncEntry.getLongValue(); + for (var stackEntry : Object2LongMaps.fastIterable(group)) { if (ingredient.test(stackEntry.getKey())) { - int count = stackEntry.getIntValue(); - int lesser = Math.min(needed, count); + long count = stackEntry.getLongValue(); + long lesser = Math.min(needed, count); count -= lesser; needed -= lesser; stackEntry.setValue(count); @@ -250,21 +263,22 @@ public int getMaxParallelByInput(IRecipeCapabilityHolder holder, GTRecipe recipe int invMultiplier = Integer.MAX_VALUE; // Loop over all consumables - for (var cEntry : Object2IntMaps.fastIterable(consumables)) { + + for (var cEntry : Object2LongMaps.fastIterable(consumables)) { SizedFluidIngredient ingredient = cEntry.getKey(); - final int needed = cEntry.getIntValue(); - final int maxNeeded = needed * limit; - int available = 0; + final long needed = cEntry.getLongValue(); + final long maxNeeded = needed * limit; + long available = 0; // Search stacks in our inventory group, summing them up - for (var stackEntry : Object2IntMaps.fastIterable(group)) { + for (var stackEntry : Object2LongMaps.fastIterable(group)) { if (ingredient.test(stackEntry.getKey())) { - available += stackEntry.getIntValue(); + available += stackEntry.getLongValue(); // We can stop if we already have enough for max parallel if (available >= maxNeeded) break; } } // ratio will equal 0 if available < needed - int ratio = Math.min(limit, available / needed); + int ratio = GTMath.saturatedCast(Math.min(limit, available / needed)); invMultiplier = Math.min(invMultiplier, ratio); // Not enough of this ingredient in this group -> skip inventory if (ratio == 0) break; @@ -277,7 +291,7 @@ public int getMaxParallelByInput(IRecipeCapabilityHolder holder, GTRecipe recipe return maxMultiplier; } - private static List> getInputContents(IRecipeCapabilityHolder holder) { + private static List> getInputContents(IRecipeCapabilityHolder holder) { var handlerLists = holder.getCapabilitiesForIO(IO.IN); if (handlerLists.isEmpty()) return Collections.emptyList(); @@ -290,11 +304,11 @@ private static List> getInputContents(IRecipeCapabilit List distinctHandlerLists = handlerGroups.getOrDefault( RecipeHandlerGroupDistinctness.BUS_DISTINCT, Collections.emptyList()); - List> invs = new ArrayList<>(distinctHandlerLists.size() + 1); + List> invs = new ArrayList<>(distinctHandlerLists.size() + 1); // Handle distinct groups first, adding an inventory based on their contents individually. for (RecipeHandlerList handlerList : distinctHandlerLists) { var handlers = handlerList.getCapability(FluidRecipeCapability.CAP); - Object2IntOpenHashMap distinctInv = new Object2IntOpenHashMap<>(); + Object2LongOpenHashMap distinctInv = new Object2LongOpenHashMap<>(); for (IRecipeHandler handler : handlers) { for (var content : handler.getContents()) { @@ -311,7 +325,7 @@ private static List> getInputContents(IRecipeCapabilit for (Map.Entry> handlerListEntry : handlerGroups.entrySet()) { if (handlerListEntry.getKey() == RecipeHandlerGroupDistinctness.BUS_DISTINCT) continue; - Object2IntOpenHashMap inventory = new Object2IntOpenHashMap<>(); + Object2LongOpenHashMap inventory = new Object2LongOpenHashMap<>(); for (RecipeHandlerList handlerList : handlerListEntry.getValue()) { var handlers = handlerList.getCapability(FluidRecipeCapability.CAP); for (var handler : handlers) { @@ -413,8 +427,8 @@ public void applyWidgetInfo(@NotNull Widget widget, // Maps ingredients to an FluidEntryList for XEI: either an FluidTagList or a FluidStackList private static FluidEntryList mapFluid(final SizedFluidIngredient ingredient) { int amount; - if (ingredient.ingredient() instanceof IntProviderFluidIngredient provider) { - amount = provider.getCountProvider().getMaxValue(); + if (ingredient.ingredient() instanceof IntProviderFluidIngredient) { + amount = 1; } else { amount = ingredient.amount(); } @@ -460,4 +474,10 @@ public interface ICustomParallel { */ int limitFluidParallel(GTRecipe recipe, int multiplier, boolean tick); } + + // Fluids should be respected for distinct checks + @Override + public boolean shouldBypassDistinct() { + return false; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java index 892e8c46612..9b63ef2c806 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/IRecipeCapabilityHolder.java @@ -34,11 +34,11 @@ default List> getCapabilitiesFlat(IO io, RecipeCapability c .getOrDefault(cap, Collections.emptyList()); } - default void addHandlerList(RecipeHandlerList handler) { - if (handler == RecipeHandlerList.NO_DATA) return; - IO io = handler.getHandlerIO(); - getCapabilitiesProxy().computeIfAbsent(io, i -> new ArrayList<>()).add(handler); - var entrySet = handler.getHandlerMap().entrySet(); + default void addHandlerList(RecipeHandlerList handlerList) { + if (handlerList == RecipeHandlerList.NO_DATA) return; + IO io = handlerList.getHandlerIO(); + getCapabilitiesProxy().computeIfAbsent(io, i -> new ArrayList<>()).add(handlerList); + var entrySet = handlerList.getHandlerMap().entrySet(); var inner = getCapabilitiesFlat().computeIfAbsent(io, i -> new Reference2ObjectOpenHashMap<>(entrySet.size())); for (var entry : entrySet) { var entryList = entry.getValue(); diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java index 1dba7029579..e9eedad3733 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/ItemRecipeCapability.java @@ -19,10 +19,7 @@ import com.gregtechceu.gtceu.api.recipe.modifier.ParallelLogic; import com.gregtechceu.gtceu.api.recipe.ui.GTRecipeTypeUI; import com.gregtechceu.gtceu.common.recipe.condition.ResearchCondition; -import com.gregtechceu.gtceu.common.valueprovider.AddedFloat; -import com.gregtechceu.gtceu.common.valueprovider.CastedFloat; -import com.gregtechceu.gtceu.common.valueprovider.FlooredInt; -import com.gregtechceu.gtceu.common.valueprovider.MultipliedFloat; +import com.gregtechceu.gtceu.common.valueprovider.*; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.item.GTDataComponents; import com.gregtechceu.gtceu.integration.xei.entry.item.ItemEntryList; @@ -39,7 +36,6 @@ import net.minecraft.core.component.DataComponentPatch; import net.minecraft.network.chat.Component; import net.minecraft.tags.TagKey; -import net.minecraft.util.valueproviders.ConstantFloat; import net.minecraft.util.valueproviders.IntProvider; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; @@ -75,19 +71,18 @@ public SizedIngredient copyInner(SizedIngredient content) { @Override public SizedIngredient copyWithModifier(SizedIngredient content, ContentModifier modifier) { - if (content.getContainedCustom() instanceof IntProviderIngredient intProviderIngredient) { - var newIntProvider = new FlooredInt( - new AddedFloat( - new MultipliedFloat( - new CastedFloat(intProviderIngredient.getCountProvider()), - ConstantFloat.of((float) modifier.multiplier())), - ConstantFloat.of((float) modifier.addition()))); - var newIngredient = IntProviderIngredient.of(intProviderIngredient.getInner(), newIntProvider); - return new SizedIngredient(newIngredient, 1); + if (content.getContainedCustom() instanceof IntProviderIngredient provider) { + return new SizedIngredient(IntProviderIngredient.of(provider.getInner(), + ModifiedIntProvider.of(provider.getCountProvider(), modifier)).toVanilla(), content.count()); } return content.copyWithCount(modifier.apply(content.count())); } + public IntProviderIngredient copyWithModifier(IntProviderIngredient content, ContentModifier modifier) { + return IntProviderIngredient.of(content.getInner(), + ModifiedIntProvider.of(content.getCountProvider(), modifier)); + } + @Override public List compressIngredients(Collection ingredients) { List list = new ObjectArrayList<>(ingredients.size()); @@ -101,7 +96,7 @@ public List compressIngredients(Collection ingredients) { break; } } else if (obj instanceof ItemStack stack) { - if (ingredient.test(stack)) { + if (ingredient.ingredient().test(stack)) { isEqual = true; break; } @@ -127,7 +122,7 @@ public List compressIngredients(Collection ingredients) { break; } } else if (obj instanceof ItemStack stack1) { - if (ItemStack.isSameItem(stack, stack1)) { + if (GTUtil.isSameItemSameTags(stack, stack1)) { isEqual = true; break; } @@ -218,13 +213,14 @@ public int getMaxParallelByInput(IRecipeCapabilityHolder holder, GTRecipe recipe if (inputs == null || inputs.isEmpty()) return limit; // Find all the items in the combined Item Input inventories and create oversized ItemStacks - List> inventoryGroups = getInputContents(holder); + List> inventoryGroups = getInputContents(holder); if (inventoryGroups.isEmpty()) return 0; // map the recipe ingredients to account for duplicated and notConsumable ingredients. // notConsumable ingredients are not counted towards the max ratio - var nonConsumables = new Object2IntOpenHashMap(); - var consumables = new Object2IntOpenHashMap(); + + var nonConsumables = new Object2LongOpenHashMap(); + var consumables = new Object2LongOpenHashMap(); for (Content content : inputs) { SizedIngredient ing = of(content.content); if (ing.getContainedCustom() instanceof IntCircuitIngredient) continue; @@ -234,8 +230,22 @@ public int getMaxParallelByInput(IRecipeCapabilityHolder holder, GTRecipe recipe count = provider.getCountProvider().getMaxValue(); else count = ing.count(); - if (content.chance == 0) nonConsumables.addTo(ing, count); - else consumables.addTo(ing, count); + if (content.chance == 0) { + nonConsumables.addTo(ing, count); + } else { + boolean has = false; + for (var recipeIng : consumables.object2LongEntrySet()) { + var stack = ing.getItems()[0]; + if (recipeIng.getKey().test(stack)) { + recipeIng.setValue(recipeIng.getLongValue() + stack.getCount()); + has = true; + break; + } + } + if (!has) { + consumables.addTo(ing, count); + } + } } // is this even possible @@ -246,13 +256,13 @@ public int getMaxParallelByInput(IRecipeCapabilityHolder holder, GTRecipe recipe for (var group : inventoryGroups) { // Check for enough NC in inventory group boolean satisfied = true; - for (var ncEntry : Object2IntMaps.fastIterable(nonConsumables)) { + for (var ncEntry : Object2LongMaps.fastIterable(nonConsumables)) { SizedIngredient ingredient = ncEntry.getKey(); - int needed = ncEntry.getIntValue(); - for (var stackEntry : Object2IntMaps.fastIterable(group)) { - if (ingredient.test(stackEntry.getKey())) { - int count = stackEntry.getIntValue(); - int lesser = Math.min(needed, count); + long needed = ncEntry.getLongValue(); + for (var stackEntry : Object2LongMaps.fastIterable(group)) { + if (ingredient.ingredient().test(stackEntry.getKey())) { + long count = stackEntry.getLongValue(); + long lesser = Math.min(needed, count); count -= lesser; needed -= lesser; stackEntry.setValue(count); @@ -271,21 +281,22 @@ public int getMaxParallelByInput(IRecipeCapabilityHolder holder, GTRecipe recipe int invMultiplier = Integer.MAX_VALUE; // Loop over all consumables - for (var cEntry : Object2IntMaps.fastIterable(consumables)) { + + for (var cEntry : Object2LongMaps.fastIterable(consumables)) { SizedIngredient ingredient = cEntry.getKey(); - final int needed = cEntry.getIntValue(); - final int maxNeeded = needed * limit; - int available = 0; + final long needed = cEntry.getLongValue(); + final long maxNeeded = needed * limit; + long available = 0; // Search stacks in our inventory group, summing them up - for (var stackEntry : Object2IntMaps.fastIterable(group)) { - if (ingredient.test(stackEntry.getKey())) { - available += stackEntry.getIntValue(); + for (var stackEntry : Object2LongMaps.fastIterable(group)) { + if (ingredient.ingredient().test(stackEntry.getKey())) { + available += stackEntry.getLongValue(); // We can stop if we already have enough for max parallel if (available >= maxNeeded) break; } } // ratio will equal 0 if available < needed - int ratio = Math.min(limit, available / needed); + int ratio = GTMath.saturatedCast(Math.min(limit, available / needed)); invMultiplier = Math.min(invMultiplier, ratio); // Not enough of this ingredient in this group -> skip inventory if (ratio == 0) break; @@ -298,7 +309,7 @@ public int getMaxParallelByInput(IRecipeCapabilityHolder holder, GTRecipe recipe return maxMultiplier; } - private static List> getInputContents(IRecipeCapabilityHolder holder) { + private static List> getInputContents(IRecipeCapabilityHolder holder) { var handlerLists = holder.getCapabilitiesForIO(IO.IN); if (handlerLists.isEmpty()) return Collections.emptyList(); @@ -313,11 +324,11 @@ private static List> getInputContents(IRecipeCapability List distinctHandlerLists = handlerGroups.getOrDefault( RecipeHandlerGroupDistinctness.BUS_DISTINCT, Collections.emptyList()); - List> invs = new ArrayList<>(distinctHandlerLists.size() + 1); + List> invs = new ArrayList<>(distinctHandlerLists.size() + 1); // Handle distinct groups first, adding an inventory based on their contents individually. for (RecipeHandlerList handlerList : distinctHandlerLists) { var handlers = handlerList.getCapability(ItemRecipeCapability.CAP); - Object2IntOpenCustomHashMap distinctInv = new Object2IntOpenCustomHashMap<>(strat); + Object2LongOpenCustomHashMap distinctInv = new Object2LongOpenCustomHashMap<>(strat); for (IRecipeHandler handler : handlers) { for (var content : handler.getContents()) { @@ -334,7 +345,7 @@ private static List> getInputContents(IRecipeCapability for (Map.Entry> handlerListEntry : handlerGroups.entrySet()) { if (handlerListEntry.getKey() == RecipeHandlerGroupDistinctness.BUS_DISTINCT) continue; - Object2IntOpenCustomHashMap inventory = new Object2IntOpenCustomHashMap<>(strat); + Object2LongOpenCustomHashMap inventory = new Object2LongOpenCustomHashMap<>(strat); for (RecipeHandlerList handlerList : handlerListEntry.getValue()) { var handlers = handlerList.getCapability(ItemRecipeCapability.CAP); for (var handler : handlers) { @@ -530,7 +541,7 @@ private static ItemEntryList mapItem(final SizedIngredient ingredient) { ItemStackList stackList = new ItemStackList(); boolean isIntProvider = inner.getCustomIngredient() instanceof IntProviderIngredient; - UnaryOperator setCount = stack -> isIntProvider ? stack.copyWithCount(1) : stack; + UnaryOperator setCount = (stack) -> isIntProvider ? stack.copyWithCount(1) : stack; Arrays.stream(inner.getItems()) .map(setCount) .forEach(stackList::add); @@ -578,4 +589,10 @@ public interface ICustomParallel { */ int limitItemParallel(GTRecipe recipe, int multiplier, boolean tick); } + + // Items should be respected for distinct checks + @Override + public boolean shouldBypassDistinct() { + return false; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/RecipeCapability.java b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/RecipeCapability.java index 31fef6fc33b..ce67aab8800 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/RecipeCapability.java +++ b/src/main/java/com/gregtechceu/gtceu/api/capability/recipe/RecipeCapability.java @@ -238,4 +238,13 @@ private static DataResult>> safeReference(H DataResult.success(reference) : DataResult.error( () -> "Unregistered holder in " + GTRegistries.RECIPE_CAPABILITY_REGISTRY + ": " + value); } + + /** + * Should this RecipeCapability bypass distinct checks? + * E.g. should this bus be added to all recipe checks on a multi, even distinct ones like ME Pattern buffers. + * for example: energy hatches, soul hatches, other "global per multi" hatches. + */ + public boolean shouldBypassDistinct() { + return true; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/cosmetics/CapeRegistry.java b/src/main/java/com/gregtechceu/gtceu/api/cosmetics/CapeRegistry.java index 8453a4a1026..5a78f7c2e2d 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cosmetics/CapeRegistry.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cosmetics/CapeRegistry.java @@ -11,7 +11,6 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.saveddata.SavedData; import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.network.PacketDistributor; @@ -277,30 +276,25 @@ public static boolean setActiveCape(UUID player, @Nullable ResourceLocation cape } // For loading capes when the player logs in, so that it's synced to the clients. - public static void loadCurrentCapesOnLogin(Player player) { - if (player instanceof ServerPlayer serverPlayer) { - UUID uuid = player.getUUID(); - // sync to others - PacketDistributor.sendToAllPlayers(new SPacketNotifyCapeChange(uuid, CURRENT_CAPES.get(uuid))); - // sync to the one who's logging in - for (ServerPlayer otherPlayer : serverPlayer.getServer().getPlayerList().getPlayers()) { - uuid = otherPlayer.getUUID(); - PacketDistributor.sendToPlayer(serverPlayer, - new SPacketNotifyCapeChange(uuid, CURRENT_CAPES.get(uuid))); - } + public static void loadCurrentCapesOnLogin(ServerPlayer serverPlayer) { + UUID uuid = serverPlayer.getUUID(); + // sync to others + PacketDistributor.sendToAllPlayers(new SPacketNotifyCapeChange(uuid, CURRENT_CAPES.get(uuid))); + // sync to the one who's logging in + for (ServerPlayer otherPlayer : serverPlayer.getServer().getPlayerList().getPlayers()) { + uuid = otherPlayer.getUUID(); + PacketDistributor.sendToPlayer(serverPlayer, new SPacketNotifyCapeChange(uuid, CURRENT_CAPES.get(uuid))); } } // Runs on login and gives the player all free capes & capes they've already unlocked. - public static void detectNewCapes(Player player) { - if (player instanceof ServerPlayer) { - var playerCapes = UNLOCKED_CAPES.get(player.getUUID()); - if (playerCapes == null || !new HashSet<>(playerCapes).containsAll(FREE_CAPES)) { - for (ResourceLocation cape : FREE_CAPES) { - unlockCape(player.getUUID(), cape); - } - save(); + public static void detectNewCapes(ServerPlayer serverPlayer) { + var playerCapes = UNLOCKED_CAPES.get(serverPlayer.getUUID()); + if (playerCapes == null || !new HashSet<>(playerCapes).containsAll(FREE_CAPES)) { + for (ResourceLocation cape : FREE_CAPES) { + unlockCape(serverPlayer.getUUID(), cape); } + save(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java b/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java index 55a5146c416..4deb2d75aa0 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/CoverBehavior.java @@ -9,6 +9,7 @@ import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; import com.gregtechceu.gtceu.client.renderer.cover.ICoverRenderer; +import com.gregtechceu.gtceu.client.renderer.cover.IDynamicCoverRenderer; import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; import com.lowdragmc.lowdraglib.syncdata.IEnhancedManaged; @@ -106,7 +107,7 @@ public boolean canAttach() { * * @param itemStack the item cover was attached from */ - public void onAttached(ItemStack itemStack, ServerPlayer player) { + public void onAttached(ItemStack itemStack, @Nullable ServerPlayer player) { attachItem = itemStack.copy(); attachItem.setCount(1); } @@ -217,6 +218,10 @@ public BlockState getAppearance(@Nullable BlockState sourceState, @Nullable Bloc return null; } + public Supplier getDynamicRenderer() { + return () -> null; + } + ////////////////////////////////////// // ******* Capabilities *******// ////////////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleItemFilter.java b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleItemFilter.java index c2c29ab5985..a6b495760dd 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleItemFilter.java +++ b/src/main/java/com/gregtechceu/gtceu/api/cover/filter/SimpleItemFilter.java @@ -5,6 +5,7 @@ import com.gregtechceu.gtceu.api.gui.widget.ToggleButtonWidget; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.gregtechceu.gtceu.data.item.GTDataComponents; +import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; @@ -139,7 +140,8 @@ public int getTotalConfiguredItemCount(ItemStack itemStack) { for (var candidate : matches) { if (ignoreNbt && ItemStack.isSameItemSameComponents(candidate, itemStack)) { totalCount += candidate.getCount(); - } else if (ItemStack.isSameItemSameComponents(candidate, itemStack)) { + } + if (!ignoreNbt && GTUtil.isSameItemSameTags(candidate, itemStack)) { totalCount += candidate.getCount(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/fluid/FluidBuilder.java b/src/main/java/com/gregtechceu/gtceu/api/fluid/FluidBuilder.java index 3c9898861b5..b78a016cb12 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/fluid/FluidBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/fluid/FluidBuilder.java @@ -86,6 +86,7 @@ public class FluidBuilder { @Getter private boolean hasCustomFlowing = false; + @Getter private boolean hasFluidBlock = false; private boolean hasBucket = true; diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/fancy/FancyMachineUIWidget.java b/src/main/java/com/gregtechceu/gtceu/api/gui/fancy/FancyMachineUIWidget.java index ed934ed888d..5e62d3bf958 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/gui/fancy/FancyMachineUIWidget.java +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/fancy/FancyMachineUIWidget.java @@ -184,7 +184,7 @@ protected void setupFancyUI(IFancyUIProvider fancyUI, boolean showInventory) { sideTabsWidget.selectTab(fancyUI); titleBar.updateState( - currentHomePage, + fancyUI, !this.previousPages.isEmpty(), this.allPages.size() > 1 && this.currentPage != this.pageSwitcher); diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/EnumSelectorWidget.java b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/EnumSelectorWidget.java index 3b77658449a..f4771dbdf74 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/EnumSelectorWidget.java +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/EnumSelectorWidget.java @@ -32,12 +32,12 @@ public interface SelectableEnum { IGuiTexture getIcon(); } - private final CycleButtonWidget buttonWidget; + public final CycleButtonWidget buttonWidget; - private final List values; - private final Consumer onChanged; + public final List values; + public final Consumer onChanged; - private int selected = 0; + public int selected = 0; private BiFunction textureSupplier = (value, texture) -> new GuiTextureGroup( GuiTextures.VANILLA_BUTTON, texture); @@ -80,7 +80,7 @@ public T getCurrentValue() { return values.get(selected); } - private IGuiTexture getTexture(int selected) { + public IGuiTexture getTexture(int selected) { var selectedValue = values.get(selected); return textureSupplier.apply(selectedValue, selectedValue.getIcon()); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/FloatInputWidget.java b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/FloatInputWidget.java new file mode 100644 index 00000000000..3a5d6dd178e --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/FloatInputWidget.java @@ -0,0 +1,88 @@ +package com.gregtechceu.gtceu.api.gui.widget; + +import com.lowdragmc.lowdraglib.gui.widget.TextFieldWidget; +import com.lowdragmc.lowdraglib.utils.Position; +import com.lowdragmc.lowdraglib.utils.Size; + +import net.minecraft.util.Mth; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + * A widget containing a floating point input field, as well as adjacent buttons for increasing or decreasing the value. + * + *

+ * The buttons' change amount can be altered with Ctrl, Shift, or both.
+ * The input is limited by a minimum and maximum value. + *

+ */ +public class FloatInputWidget extends NumberInputWidget { + + public FloatInputWidget(Supplier valueSupplier, Consumer onChanged) { + super(valueSupplier, onChanged); + } + + public FloatInputWidget(Position position, Supplier valueSupplier, Consumer onChanged) { + super(position, valueSupplier, onChanged); + } + + public FloatInputWidget(Position position, Size size, Supplier valueSupplier, Consumer onChanged) { + super(position, size, valueSupplier, onChanged); + } + + public FloatInputWidget(int x, int y, int width, int height, Supplier valueSupplier, + Consumer onChanged) { + super(x, y, width, height, valueSupplier, onChanged); + } + + @Override + protected Float defaultMin() { + return 0.0f; + } + + @Override + protected Float defaultMax() { + return Float.MAX_VALUE; + } + + @Override + protected String toText(Float value) { + return String.valueOf(value); + } + + @Override + protected Float fromText(String value) { + return Float.parseFloat(value); + } + + @Override + protected ChangeValues getChangeValues() { + return new ChangeValues<>(1.0f, 0.1f, 0.01f, 0.001f); + } + + @Override + protected Float add(Float a, Float b) { + return a + b; + } + + @Override + protected Float multiply(Float a, Float b) { + return a * b; + } + + @Override + protected Float clamp(Float value, Float min, Float max) { + return Mth.clamp(value, min, max); + } + + @Override + protected void setTextFieldRange(TextFieldWidget textField, Float min, Float max) { + textField.setNumbersOnly(min, max); + } + + @Override + protected Float getOne(boolean positive) { + return positive ? 1.0f : -1.0f; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/NumberInputWidget.java b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/NumberInputWidget.java index 87f1a31e2b0..c5e750ad36f 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/NumberInputWidget.java +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/NumberInputWidget.java @@ -10,6 +10,7 @@ import com.lowdragmc.lowdraglib.gui.util.ClickData; import com.lowdragmc.lowdraglib.gui.widget.ButtonWidget; import com.lowdragmc.lowdraglib.gui.widget.TextFieldWidget; +import com.lowdragmc.lowdraglib.gui.widget.Widget; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import com.lowdragmc.lowdraglib.utils.Position; import com.lowdragmc.lowdraglib.utils.Size; @@ -111,6 +112,12 @@ public void readInitialData(RegistryFriendlyByteBuf buffer) { textField.setCurrentString(buffer.readUtf()); } + @Override + public Widget setHoverTooltips(String... tooltipText) { + textField.setHoverTooltips(tooltipText); + return super.setHoverTooltips(tooltipText); + } + private void buildUI() { int buttonWidth = Mth.clamp(this.getSize().width / 5, 15, 40); int textFieldWidth = this.getSize().width - (2 * buttonWidth) - 4; diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/PatternPreviewSlotWidget.java b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/PatternPreviewSlotWidget.java new file mode 100644 index 00000000000..4d80bd54d07 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/PatternPreviewSlotWidget.java @@ -0,0 +1,112 @@ +package com.gregtechceu.gtceu.api.gui.widget; + +import com.lowdragmc.lowdraglib.gui.modular.ModularUIGuiContainer; +import com.lowdragmc.lowdraglib.gui.util.DrawerHelper; +import com.lowdragmc.lowdraglib.utils.ColorUtils; +import com.lowdragmc.lowdraglib.utils.Position; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.items.IItemHandlerModifiable; + +import com.mojang.blaze3d.systems.RenderSystem; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.lwjgl.opengl.GL11; + +import javax.annotation.Nonnull; + +public class PatternPreviewSlotWidget extends SlotWidget { + + public PatternPreviewSlotWidget(IItemHandlerModifiable itemHandler, int slotIndex, int xPosition, int yPosition, + boolean canTakeItems, boolean canPutItems) { + super(itemHandler, slotIndex, xPosition, yPosition, canTakeItems, canPutItems); + } + + /** + * Override the draw method for regular slot widget since we do custom offsets when drawing the stack + */ + @Override + public void drawInBackground(@NotNull GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { + super.drawBackgroundTexture(graphics, mouseX, mouseY); + Position pos = this.getPosition(); + if (this.slotReference != null) { + ItemStack itemStack = this.getRealStack(this.slotReference.getItem()); + ModularUIGuiContainer modularUIGui = this.gui == null ? null : this.gui.getModularUIGui(); + if (itemStack.isEmpty() && modularUIGui != null && modularUIGui.getQuickCrafting() && + modularUIGui.getQuickCraftSlots().contains(this.slotReference)) { + int splitSize = modularUIGui.getQuickCraftSlots().size(); + itemStack = this.gui.getModularUIContainer().getCarried(); + if (!itemStack.isEmpty() && splitSize > 1 && + AbstractContainerMenu.canItemQuickReplace(this.slotReference, itemStack, true)) { + itemStack = itemStack.copy(); + itemStack.grow(AbstractContainerMenu.getQuickCraftPlaceCount(modularUIGui.getQuickCraftSlots(), + modularUIGui.dragSplittingLimit, itemStack)); + int k = Math.min(itemStack.getMaxStackSize(), this.slotReference.getMaxStackSize(itemStack)); + if (itemStack.getCount() > k) { + itemStack.setCount(k); + } + } + } + + if (!itemStack.isEmpty()) { + drawItemStack(graphics, itemStack, pos.x + 1, pos.y + 1, -1, (String) null); + } + } + + this.drawOverlay(graphics, mouseX, mouseY, partialTicks); + if (this.drawHoverOverlay && this.isMouseOverElement((double) mouseX, (double) mouseY) && + this.getHoverElement((double) mouseX, (double) mouseY) == this) { + RenderSystem.colorMask(true, true, true, false); + DrawerHelper.drawSolidRect(graphics, this.getPosition().x + 1, this.getPosition().y + 1, 16, 16, + -2130706433); + RenderSystem.colorMask(true, true, true, true); + } + } + + public static void drawItemStack(@Nonnull GuiGraphics graphics, ItemStack itemStack, int x, int y, int color, + @Nullable String altTxt) { + var a = ColorUtils.alpha(color); + var r = ColorUtils.red(color); + var g = ColorUtils.green(color); + var b = ColorUtils.blue(color); + RenderSystem.setShaderColor(r, g, b, a); + + RenderSystem.enableDepthTest(); + RenderSystem.depthMask(true); + + Minecraft mc = Minecraft.getInstance(); + + graphics.pose().pushPose(); + graphics.pose().translate(0, 0, 100); + + graphics.renderItem(itemStack, x, y); + graphics.pose().translate(0, 0, 100); + + graphics.pose().pushPose(); + + // actual offset bit that's important :3 + int xOffset = 0; + if (itemStack.getCount() / 100_000 != 0) { + xOffset = 9; + } else if (itemStack.getCount() / 10_000 != 0) { + xOffset = 6; + } else if (itemStack.getCount() / 1000 != 0) { + xOffset = 3; + } + + graphics.renderItemDecorations(mc.font, itemStack, x + xOffset, y, altTxt); + graphics.pose().popPose(); + + graphics.pose().popPose(); + + // clear depth buffer,it may cause some rendering issues? + RenderSystem.clear(GL11.GL_DEPTH_BUFFER_BIT, Minecraft.ON_OSX); + RenderSystem.depthMask(false); + RenderSystem.setShaderColor(1F, 1F, 1F, 1F); + RenderSystem.enableBlend(); + RenderSystem.disableDepthTest(); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/PatternPreviewWidget.java b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/PatternPreviewWidget.java index 162b80cddec..9853155695b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/PatternPreviewWidget.java +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/PatternPreviewWidget.java @@ -249,10 +249,21 @@ public void setPage(int index) { } slotWidgets = new SlotWidget[Math.min(pattern.parts.size(), 18)]; var itemHandler = CycleItemEntryHandler.createFromStacks(pattern.parts); + int xOffset = 0; for (int i = 0; i < slotWidgets.length; i++) { - slotWidgets[i] = new SlotWidget(itemHandler, i, 4 + i * 18, 0, false, false) + int padding = 1; + if (itemHandler.getStackInSlot(i).getCount() / 100_000 >= 1) { + padding = 10; + } else if (itemHandler.getStackInSlot(i).getCount() / 10_000 >= 1) { + padding = 7; + } else if (itemHandler.getStackInSlot(i).getCount() / 1_000 >= 1) { + padding = 4; + } + + slotWidgets[i] = new PatternPreviewSlotWidget(itemHandler, i, (4 + xOffset + padding), 0, false, false) .setBackgroundTexture(ColorPattern.T_GRAY.rectTexture()) .setIngredientIO(IngredientIO.INPUT); + xOffset += 18 + (2 * padding); scrollableWidgetGroup.addWidget(slotWidgets[i]); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/TankWidget.java b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/TankWidget.java index d5b556a2f0a..46172bfe89e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/TankWidget.java +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/TankWidget.java @@ -9,6 +9,7 @@ import com.gregtechceu.gtceu.integration.xei.entry.fluid.FluidTagList; import com.gregtechceu.gtceu.integration.xei.handlers.fluid.CycleFluidEntryHandler; import com.gregtechceu.gtceu.utils.FormattingUtil; +import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.gui.editor.annotation.Configurable; import com.lowdragmc.lowdraglib.gui.editor.annotation.LDLRegister; @@ -488,7 +489,7 @@ private int tryClickContainer(boolean isShiftKeyDown) { if (filledResult.isEmpty()) { filledResult = remainingStack.copy(); - } else if (ItemStack.isSameItemSameComponents(filledResult, remainingStack)) { + } else if (GTUtil.isSameItemSameTags(filledResult, remainingStack)) { if (filledResult.getCount() < filledResult.getMaxStackSize()) filledResult.grow(1); else @@ -533,7 +534,7 @@ private int tryClickContainer(boolean isShiftKeyDown) { if (drainedResult.isEmpty()) { drainedResult = remainingStack.copy(); - } else if (ItemStack.isSameItemSameComponents(drainedResult, remainingStack)) { + } else if (GTUtil.isSameItemSameTags(drainedResult, remainingStack)) { if (drainedResult.getCount() < drainedResult.getMaxStackSize()) drainedResult.grow(1); else diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputFluidConfigHandler.java b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputFluidConfigHandler.java index 03d7c42792c..65ff3f14a59 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputFluidConfigHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputFluidConfigHandler.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.gui.widget.directional.IDirectionalConfigHandler; import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputFluid; import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; +import com.gregtechceu.gtceu.data.datagen.lang.LangHandler; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; @@ -16,6 +17,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; @@ -50,14 +52,22 @@ public Widget getSideSelectorWidget(SceneWidget scene, FancyMachineUIWidget mach @Override public void updateScreen() { super.updateScreen(); - if (machine.getOutputFacingFluids() == side) { + if (side == null) { + setButtonTexture(TEXTURE_OFF); + setHoverTooltips(LangHandler.getMultiLang("gtceu.gui.fluid_auto_output.unselected") + .toArray(Component[]::new)); + } else if (machine.getOutputFacingFluids() == side) { if (machine.isAutoOutputFluids()) { setButtonTexture(TEXTURE_AUTO); + setHoverTooltips("gtceu.gui.fluid_auto_output.enabled"); } else { setButtonTexture(TEXTURE_OUTPUT); + setHoverTooltips("gtceu.gui.fluid_auto_output.disabled"); } } else { setButtonTexture(TEXTURE_OFF); + setHoverTooltips(LangHandler.getMultiLang("gtceu.gui.fluid_auto_output.other_direction") + .toArray(Component[]::new)); } } }); diff --git a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputItemConfigHandler.java b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputItemConfigHandler.java index b36735bcf28..3eeee94da0d 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputItemConfigHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/gui/widget/directional/handlers/AutoOutputItemConfigHandler.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.gui.widget.directional.IDirectionalConfigHandler; import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputFluid; import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; +import com.gregtechceu.gtceu.data.datagen.lang.LangHandler; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; @@ -15,6 +16,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; @@ -50,14 +52,22 @@ public Widget getSideSelectorWidget(SceneWidget scene, FancyMachineUIWidget mach public void updateScreen() { super.updateScreen(); - if (machine.getOutputFacingItems() == side) { + if (side == null) { + setButtonTexture(TEXTURE_OFF); + setHoverTooltips(LangHandler.getMultiLang("gtceu.gui.item_auto_output.unselected") + .toArray(Component[]::new)); + } else if (machine.getOutputFacingItems() == side) { if (machine.isAutoOutputItems()) { setButtonTexture(TEXTURE_AUTO); + setHoverTooltips("gtceu.gui.item_auto_output.enabled"); } else { setButtonTexture(TEXTURE_OUTPUT); + setHoverTooltips("gtceu.gui.item_auto_output.disabled"); } } else { setButtonTexture(TEXTURE_OFF); + setHoverTooltips(LangHandler.getMultiLang("gtceu.gui.item_auto_output.other_direction") + .toArray(Component[]::new)); } } }); diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/GTBucketItem.java b/src/main/java/com/gregtechceu/gtceu/api/item/GTBucketItem.java index a248c3eecb6..37f0b7b7dee 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/GTBucketItem.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/GTBucketItem.java @@ -1,18 +1,37 @@ package com.gregtechceu.gtceu.api.item; +import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.fluid.GTFluid; +import com.gregtechceu.gtceu.api.fluid.store.FluidStorageKey; +import com.gregtechceu.gtceu.api.fluid.store.FluidStorageKeys; import com.gregtechceu.gtceu.api.material.material.Material; import com.gregtechceu.gtceu.api.material.material.properties.PropertyKey; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.network.chat.Component; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BucketItem; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.LiquidBlockContainer; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.FlowingFluid; import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.phys.BlockHitResult; import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.FluidUtil; import org.jetbrains.annotations.Nullable; +import java.util.Optional; + public class GTBucketItem extends BucketItem { final Material material; @@ -58,6 +77,102 @@ public int getBurnTime(ItemStack itemStack, @Nullable RecipeType recipeType) return gtFluid.getBurnTime(); } } - return 0; + return -1; + } + + @Override + public boolean emptyContents(@Nullable Player player, Level level, BlockPos pos, + @Nullable BlockHitResult result, + @Nullable ItemStack container) { + if (!(material.getFluid() instanceof FlowingFluid)) return false; + + BlockState blockstate = level.getBlockState(pos); + Block block = blockstate.getBlock(); + boolean canReplace = blockstate.canBeReplaced(material.getFluid()); + boolean canPlace = blockstate.isAir() || canReplace || + block instanceof LiquidBlockContainer lbc && + lbc.canPlaceLiquid(player, level, pos, blockstate, material.getFluid()); + + if (!canPlace) { + return result != null && this.emptyContents(player, level, + result.getBlockPos().relative(result.getDirection()), null, container); + } + + var fluidType = material.getFluid().getFluidType(); + Optional containedFluidStack = Optional.ofNullable(container).flatMap(FluidUtil::getFluidContained); + if (containedFluidStack.isPresent() && + fluidType.isVaporizedOnPlacement(level, pos, containedFluidStack.get())) { + fluidType.onVaporize(player, level, pos, containedFluidStack.get()); + return true; + } + + if (doesFluidVaporize(material, level)) { + int i = pos.getX(); + int j = pos.getY(); + int k = pos.getZ(); + level.playSound(player, pos, SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5F, + 2.6F + (level.random.nextFloat() - level.random.nextFloat()) * 0.8F); + + for (int l = 0; l < 8; ++l) { + double xi = i + GTValues.RNG.nextDouble(); + double xj = j + GTValues.RNG.nextDouble(); + double xk = k + GTValues.RNG.nextDouble(); + level.addParticle(ParticleTypes.LARGE_SMOKE, xi, xj, xk, 0.0D, 0.0D, 0.0D); + } + return true; + } + + if (block instanceof LiquidBlockContainer blockContainer && + blockContainer.canPlaceLiquid(player, level, pos, blockstate, material.getFluid())) { + var flowingFluid = ((FlowingFluid) material.getFluid()); + blockContainer.placeLiquid(level, pos, blockstate, flowingFluid.getSource(false)); + this.playEmptySound(player, level, pos); + return true; + } else { + if (!level.isClientSide && canReplace && !blockstate.liquid()) { + level.destroyBlock(pos, true); + } + + var fluidBlockState = material.getFluid().defaultFluidState().createLegacyBlock(); + if (hasFluidBlock(material) && level.setBlock(pos, fluidBlockState, Block.UPDATE_ALL_IMMEDIATE) && + fluidBlockState.getFluidState().isSource()) { + this.playEmptySound(player, level, pos); + return true; + } + } + return false; + } + + private static boolean hasFluidBlock(Material mat) { + var fluidStorage = mat.getProperty(PropertyKey.FLUID).getStorage(); + + for (var key : FluidStorageKey.allKeys()) { + var fluidEntry = fluidStorage.getEntry(key); + if (fluidEntry != null) { + var fluidBuilder = fluidEntry.getBuilder(); + if (fluidBuilder != null && fluidBuilder.hasFluidBlock()) { + return true; + } + } + } + return false; + } + + private boolean doesFluidVaporize(Material mat, Level level) { + // water in nether behavior + if (level.dimensionType().ultraWarm() && material.getFluid().defaultFluidState().is(FluidTags.WATER)) { + return true; + } + var fluidStorage = mat.getProperty(PropertyKey.FLUID).getStorage(); + var plasmaEntry = fluidStorage.getEntry(FluidStorageKeys.PLASMA); + var gasEntry = fluidStorage.getEntry(FluidStorageKeys.GAS); + if (plasmaEntry != null) { + var plasmaBuilder = plasmaEntry.getBuilder(); + return plasmaBuilder != null && plasmaBuilder.hasFluidBlock(); + } else if (gasEntry != null) { + var gasBuilder = gasEntry.getBuilder(); + return gasBuilder != null && gasBuilder.hasFluidBlock(); + } + return false; } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/IGTTool.java b/src/main/java/com/gregtechceu/gtceu/api/item/IGTTool.java index 6868d8a601f..c4789e87f7e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/IGTTool.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/IGTTool.java @@ -181,6 +181,11 @@ default int getMaterialHarvestLevel() { return toolProperty == null ? 0 : toolProperty.getHarvestLevel(); } + default int getProspectingDepth() { + ToolProperty toolProperty = getToolProperty(); + return toolProperty == null ? 1 : toolProperty.getProspectingDepth(); + } + @SuppressWarnings("DataFlowIssue") default long getMaxCharge(ItemStack stack) { if (isElectric()) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/PipeBlockItem.java b/src/main/java/com/gregtechceu/gtceu/api/item/PipeBlockItem.java index 939f7133305..69c14eeab92 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/PipeBlockItem.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/PipeBlockItem.java @@ -38,7 +38,8 @@ public void appendHoverText(ItemStack stack, Item.TooltipContext context, List getArmorModel(LivingEntity entityLiving, ItemStack item default float getHeatResistance() { return 1.0f; } + + default void onEquip(Player player) {} + + default void onUnequip(Player player) {} } diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/component/IMonitorModuleItem.java b/src/main/java/com/gregtechceu/gtceu/api/item/component/IMonitorModuleItem.java new file mode 100644 index 00000000000..6bfa55da341 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/item/component/IMonitorModuleItem.java @@ -0,0 +1,22 @@ +package com.gregtechceu.gtceu.api.item.component; + +import com.gregtechceu.gtceu.client.renderer.monitor.IMonitorRenderer; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; + +import com.lowdragmc.lowdraglib.gui.widget.Widget; + +import net.minecraft.world.item.ItemStack; + +public interface IMonitorModuleItem extends IItemComponent { + + default void tick(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) {} + + IMonitorRenderer getRenderer(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group); + + Widget createUIWidget(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group); + + default String getType() { + return "unknown"; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/tool/GTToolType.java b/src/main/java/com/gregtechceu/gtceu/api/item/tool/GTToolType.java index 0adc228e869..7784fa72937 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/tool/GTToolType.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/tool/GTToolType.java @@ -6,7 +6,6 @@ import com.gregtechceu.gtceu.api.material.material.Material; import com.gregtechceu.gtceu.api.sound.ExistingSoundEntry; import com.gregtechceu.gtceu.api.sound.SoundEntry; -import com.gregtechceu.gtceu.api.tag.TagUtil; import com.gregtechceu.gtceu.common.item.tool.behavior.*; import com.gregtechceu.gtceu.data.item.GTItemAbilities; import com.gregtechceu.gtceu.data.sound.GTSoundEntries; @@ -45,7 +44,7 @@ public class GTToolType { // FIXME the speed and breakability values are all broken. refer to (vanilla?) for correct-er values. public static final GTToolType SWORD = GTToolType.builder("sword") - .toolTag(ItemTags.SWORDS) + .toolTag(ToolItemTagType.MATCH, ItemTags.SWORDS) .definition(b -> b.tool(new Tool(List.of( Tool.Rule.overrideSpeed(BlockTags.SWORD_EFFICIENT, 1.5F), Tool.Rule.minesAndDrops(List.of(Blocks.COBWEB), 15.0F)), @@ -56,7 +55,7 @@ public class GTToolType { .materialAmount(2 * GTValues.M) .build(); public static final GTToolType PICKAXE = GTToolType.builder("pickaxe") - .toolTag(ItemTags.PICKAXES) + .toolTag(ToolItemTagType.MATCH, ItemTags.PICKAXES) .toolTag(ItemTags.CLUSTER_MAX_HARVESTABLES) .harvestTag(BlockTags.MINEABLE_WITH_PICKAXE) .definition(b -> b.blockBreaking().attackDamage(1.0F).attackSpeed(-2.8F) @@ -66,7 +65,7 @@ public class GTToolType { .materialAmount(3 * GTValues.M) .build(); public static final GTToolType SHOVEL = GTToolType.builder("shovel") - .toolTag(ItemTags.SHOVELS) + .toolTag(ToolItemTagType.MATCH, ItemTags.SHOVELS) .harvestTag(BlockTags.MINEABLE_WITH_SHOVEL) .definition(b -> b.blockBreaking().attackDamage(1.5F) .behaviors(GrassPathBehavior.INSTANCE)) @@ -75,7 +74,7 @@ public class GTToolType { .defaultAbilities(ItemAbilities.SHOVEL_DIG, ItemAbilities.SHOVEL_DOUSE) .build(); public static final GTToolType AXE = GTToolType.builder("axe") - .toolTag(ItemTags.AXES) + .toolTag(ToolItemTagType.MATCH, ItemTags.AXES) .harvestTag(BlockTags.MINEABLE_WITH_AXE) .definition(b -> b.blockBreaking() .attackDamage(5.0F).baseEfficiency(2.0F).attackSpeed(-3.2F) @@ -86,7 +85,7 @@ public class GTToolType { .defaultAbilities(ItemAbilities.AXE_DIG) .build(); public static final GTToolType HOE = GTToolType.builder("hoe") - .toolTag(TagUtil.createItemTag("hoes", true)) + .toolTag(ToolItemTagType.MATCH, ItemTags.HOES) .harvestTag(BlockTags.MINEABLE_WITH_HOE) .definition(b -> b.cannotAttack().behaviors(HoeGroundBehavior.INSTANCE)) .toolClassNames("hoe") @@ -95,7 +94,7 @@ public class GTToolType { .build(); public static final GTToolType MINING_HAMMER = GTToolType.builder("mining_hammer") - .toolTag(CustomTags.TOOLS_MINING_HAMMER) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_MINING_HAMMER) .harvestTag(BlockTags.MINEABLE_WITH_PICKAXE) .definition(b -> b.blockBreaking().aoe(1, 1, 0) .efficiencyMultiplier(0.4F).attackDamage(1.5F).durabilityMultiplier(3.0F).attackSpeed(-3.2F) @@ -105,17 +104,18 @@ public class GTToolType { .materialAmount(6 * GTValues.M) .build(); public static final GTToolType SPADE = GTToolType.builder("spade") - .toolTag(CustomTags.TOOLS_SPADE) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_SPADE) .harvestTag(BlockTags.MINEABLE_WITH_SHOVEL) .definition(b -> b.blockBreaking().aoe(1, 1, 0) - .efficiencyMultiplier(0.4F).attackDamage(1.5F).durabilityMultiplier(3.0F).attackSpeed(-3.2F) + .efficiencyMultiplier(0.4F).attackDamage(1.5F).attackSpeed(-3.2F) + .durabilityMultiplier(3.0F) .behaviors(AOEConfigUIBehavior.INSTANCE, GrassPathBehavior.INSTANCE)) .toolClasses(GTToolType.SHOVEL) .defaultAbilities(ItemAbilities.SHOVEL_DIG, ItemAbilities.SHOVEL_DOUSE) .materialAmount(3 * GTValues.M) .build(); public static final GTToolType SCYTHE = GTToolType.builder("scythe") - .toolTag(CustomTags.TOOLS_SCYTHE) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_SCYTHE) .harvestTag(BlockTags.MINEABLE_WITH_HOE) .definition(b -> b.blockBreaking().attacking() .attackDamage(5.0F).durabilityMultiplier(3.0F).attackSpeed(-3.0F) @@ -129,8 +129,8 @@ public class GTToolType { .build(); public static final GTToolType SAW = GTToolType.builder("saw") - .toolTag(CustomTags.CRAFTING_SAWS) - .toolTag(CustomTags.TOOLS_SAW) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_SAWS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_SAW) .harvestTag(CustomTags.MINEABLE_WITH_SAW) .definition(b -> b.crafting() .damagePerCraftingAction(2).attackDamage(-1.0F).attackSpeed(-2.6F) @@ -141,13 +141,13 @@ public class GTToolType { .materialAmount(2 * GTValues.M) .build(); public static final GTToolType HARD_HAMMER = GTToolType.builder("hammer") - .toolTag(CustomTags.CRAFTING_HAMMERS) - .toolTag(CustomTags.TOOLS_HAMMER) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_HAMMERS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_HAMMER) .harvestTag(CustomTags.MINEABLE_WITH_HAMMER) .harvestTag(BlockTags.MINEABLE_WITH_PICKAXE) - .definition(b -> b.blockBreaking().crafting() - .damagePerCraftingAction(2).attackDamage(1.0F).attackSpeed(-2.8F) - .behaviors(new EntityDamageBehavior(2.0F, CustomTags.IRON_GOLEMS))) + .definition(b -> b.blockBreaking().crafting().damagePerCraftingAction(2) + .attackDamage(1.0F).attackSpeed(-2.8F) + .behaviors(new EntityDamageBehavior(2.0F, CustomTags.IRON_GOLEMS), ProspectingBehavior.INSTANCE)) .sound(GTSoundEntries.FORGE_HAMMER) .symbol('h') .toolClasses(GTToolType.PICKAXE) @@ -156,8 +156,8 @@ public class GTToolType { .materialAmount(6 * GTValues.M) .build(); public static final GTToolType SOFT_MALLET = GTToolType.builder("mallet") - .toolTag(CustomTags.CRAFTING_MALLETS) - .toolTag(CustomTags.TOOLS_MALLET) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_MALLETS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_MALLET) .definition(b -> b.crafting().cannotAttack().attackSpeed(-2.4F).sneakBypassUse() .behaviors(ToolModeSwitchBehavior.INSTANCE)) .sound(GTSoundEntries.SOFT_MALLET_TOOL) @@ -166,8 +166,9 @@ public class GTToolType { .materialAmount(6 * GTValues.M) .build(); public static final GTToolType WRENCH = GTToolType.builder("wrench") - .toolTag(CustomTags.CRAFTING_WRENCHES) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_WRENCHES) .toolTag(Tags.Items.TOOLS_WRENCH) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_WRENCH) .harvestTag(CustomTags.MINEABLE_WITH_WRENCH) .definition(b -> b.blockBreaking().crafting().sneakBypassUse() .attackDamage(1.0F).attackSpeed(-2.8F) @@ -181,8 +182,8 @@ public class GTToolType { .materialAmount(4 * GTValues.M) .build(); public static final GTToolType FILE = GTToolType.builder("file") - .toolTag(CustomTags.CRAFTING_FILES) - .toolTag(CustomTags.TOOLS_FILE) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_FILES) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_FILE) .definition(b -> b.crafting().cannotAttack() .damagePerCraftingAction(4).attackSpeed(-2.4F)) .sound(GTSoundEntries.FILE_TOOL) @@ -190,8 +191,8 @@ public class GTToolType { .materialAmount(2 * GTValues.M) .build(); public static final GTToolType CROWBAR = GTToolType.builder("crowbar") - .toolTag(CustomTags.CRAFTING_CROWBARS) - .toolTag(CustomTags.TOOLS_CROWBAR) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_CROWBARS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_CROWBAR) .harvestTag(CustomTags.MINEABLE_WITH_CROWBAR) .definition(b -> b.blockBreaking().crafting() .attackDamage(2.0F).attackSpeed(-2.4F) @@ -202,8 +203,8 @@ public class GTToolType { .materialAmount(3 * GTValues.M / 2) .build(); public static final GTToolType SCREWDRIVER = GTToolType.builder("screwdriver") - .toolTag(CustomTags.CRAFTING_SCREWDRIVERS) - .toolTag(CustomTags.TOOLS_SCREWDRIVER) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_SCREWDRIVERS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_SCREWDRIVER) .definition(b -> b.crafting().damagePerCraftingAction(4).sneakBypassUse() .attackDamage(-1.0F).attackSpeed(3.0F).efficiencyMultiplier(3.0F) .behaviors(new EntityDamageBehavior(3.0F, CustomTags.SPIDERS))) @@ -213,8 +214,8 @@ public class GTToolType { .materialAmount(GTValues.M) .build(); public static final GTToolType MORTAR = GTToolType.builder("mortar") - .toolTag(CustomTags.CRAFTING_MORTARS) - .toolTag(CustomTags.TOOLS_MORTAR) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_MORTARS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_MORTAR) .definition(b -> b.crafting().damagePerCraftingAction(2) .cannotAttack().attackSpeed(-2.4F)) .sound(GTSoundEntries.MORTAR_TOOL) @@ -222,8 +223,8 @@ public class GTToolType { .materialAmount(2 * GTValues.M) .build(); public static final GTToolType WIRE_CUTTER = GTToolType.builder("wire_cutter") - .toolTag(CustomTags.CRAFTING_WIRE_CUTTERS) - .toolTag(CustomTags.TOOLS_WIRE_CUTTER) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_WIRE_CUTTERS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_WIRE_CUTTER) .harvestTag(CustomTags.MINEABLE_WITH_WIRE_CUTTER) .definition(b -> b.blockBreaking().crafting().sneakBypassUse() .damagePerCraftingAction(4).attackDamage(-1.0F).attackSpeed(-2.4F)) @@ -233,8 +234,8 @@ public class GTToolType { .materialAmount(4 * GTValues.M) // 3 plates + 2 rods .build(); public static final GTToolType KNIFE = GTToolType.builder("knife") - .toolTag(CustomTags.CRAFTING_KNIVES) - .toolTag(CustomTags.TOOLS_KNIFE) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_KNIVES) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_KNIFE) .harvestTag(CustomTags.MINEABLE_WITH_KNIFE) .definition(b -> b.crafting().attacking().attackSpeed(3.0F)) .symbol('k') @@ -243,27 +244,28 @@ public class GTToolType { .materialAmount(GTValues.M) .build(); public static final GTToolType BUTCHERY_KNIFE = GTToolType.builder("butchery_knife") - .toolTag(CustomTags.TOOLS_BUTCHERY_KNIFE) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_BUTCHERY_KNIFE) .definition(b -> b.attacking() .attackDamage(1.5F).attackSpeed(-1.3F) .defaultEnchantment(Enchantments.LOOTING, 3)) + .materialAmount(4 * GTValues.M) .build(); public static final GTToolType PLUNGER = GTToolType.builder("plunger") - .toolTag(CustomTags.TOOLS_PLUNGER) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_PLUNGER) .definition(b -> b.cannotAttack().sneakBypassUse() .attackSpeed(-2.4F).attackSpeed(-2.4F) .behaviors(PlungerBehavior.INSTANCE)) .sound(GTSoundEntries.PLUNGER_TOOL) .build(); public static final GTToolType SHEARS = GTToolType.builder("shears") - .toolTag(Tags.Items.TOOLS_SHEAR) + .toolTag(ToolItemTagType.MATCH, Tags.Items.TOOLS_SHEAR) .harvestTag(CustomTags.MINEABLE_WITH_SHEARS) .definition(b -> b) .defaultAbilities(ItemAbilities.DEFAULT_SHEARS_ACTIONS) .build(); public static final GTToolType DRILL_LV = GTToolType.builder("lv_drill") .idFormat("lv_%s_drill") - .toolTag(CustomTags.TOOLS_DRILL) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_DRILL) .toolTag(ItemTags.PICKAXES) .toolTag(ItemTags.SHOVELS) .toolTag(ItemTags.HOES) @@ -282,7 +284,7 @@ public class GTToolType { .build(); public static final GTToolType DRILL_MV = GTToolType.builder("mv_drill") .idFormat("mv_%s_drill") - .toolTag(CustomTags.TOOLS_DRILL) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_DRILL) .toolTag(ItemTags.PICKAXES) .toolTag(ItemTags.SHOVELS) .toolTag(ItemTags.HOES) @@ -301,7 +303,7 @@ public class GTToolType { .build(); public static final GTToolType DRILL_HV = GTToolType.builder("hv_drill") .idFormat("hv_%s_drill") - .toolTag(CustomTags.TOOLS_DRILL) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_DRILL) .toolTag(ItemTags.PICKAXES) .toolTag(ItemTags.SHOVELS) .toolTag(ItemTags.HOES) @@ -320,7 +322,7 @@ public class GTToolType { .build(); public static final GTToolType DRILL_EV = GTToolType.builder("ev_drill") .idFormat("ev_%s_drill") - .toolTag(CustomTags.TOOLS_DRILL) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_DRILL) .toolTag(ItemTags.PICKAXES) .toolTag(ItemTags.SHOVELS) .toolTag(ItemTags.HOES) @@ -339,7 +341,7 @@ public class GTToolType { .build(); public static final GTToolType DRILL_IV = GTToolType.builder("iv_drill") .idFormat("iv_%s_drill") - .toolTag(CustomTags.TOOLS_DRILL) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_DRILL) .toolTag(ItemTags.PICKAXES) .toolTag(ItemTags.SHOVELS) .toolTag(ItemTags.HOES) @@ -358,8 +360,8 @@ public class GTToolType { .build(); public static final GTToolType CHAINSAW_LV = GTToolType.builder("lv_chainsaw") .idFormat("lv_%s_chainsaw") - .toolTag(ItemTags.AXES) - .toolTag(CustomTags.TOOLS_CHAINSAW) + .toolTag(ToolItemTagType.MATCH, ItemTags.AXES) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_CHAINSAW) .harvestTag(BlockTags.MINEABLE_WITH_AXE) .harvestTag(BlockTags.SWORD_EFFICIENT) .harvestTag(BlockTags.MINEABLE_WITH_HOE) @@ -376,8 +378,8 @@ public class GTToolType { .build(); public static final GTToolType WRENCH_LV = GTToolType.builder("lv_wrench") .idFormat("lv_%s_wrench") - .toolTag(CustomTags.CRAFTING_WRENCHES) - .toolTag(Tags.Items.TOOLS_WRENCH) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_WRENCHES) + .toolTag(ToolItemTagType.MATCH, Tags.Items.TOOLS_WRENCH) .harvestTag(CustomTags.MINEABLE_WITH_WRENCH) .definition(b -> b.blockBreaking().crafting().sneakBypassUse() .efficiencyMultiplier(2.0F).attackDamage(1.0F).attackSpeed(-2.8F) @@ -393,8 +395,8 @@ public class GTToolType { .build(); public static final GTToolType WRENCH_HV = GTToolType.builder("hv_wrench") .idFormat("hv_%s_wrench") - .toolTag(CustomTags.CRAFTING_WRENCHES) - .toolTag(Tags.Items.TOOLS_WRENCH) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_WRENCHES) + .toolTag(ToolItemTagType.MATCH, Tags.Items.TOOLS_WRENCH) .harvestTag(CustomTags.MINEABLE_WITH_WRENCH) .definition(b -> b.blockBreaking().crafting().sneakBypassUse() .efficiencyMultiplier(3.0F).attackDamage(1.0F).attackSpeed(-2.8F) @@ -410,8 +412,8 @@ public class GTToolType { .build(); public static final GTToolType WRENCH_IV = GTToolType.builder("iv_wrench") .idFormat("iv_%s_wrench") - .toolTag(CustomTags.CRAFTING_WRENCHES) - .toolTag(Tags.Items.TOOLS_WRENCH) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_WRENCHES) + .toolTag(ToolItemTagType.MATCH, Tags.Items.TOOLS_WRENCH) .harvestTag(CustomTags.MINEABLE_WITH_WRENCH) .definition(b -> b.blockBreaking().crafting().sneakBypassUse() .efficiencyMultiplier(4.0F).attackDamage(1.0F).attackSpeed(-2.8F) @@ -428,8 +430,8 @@ public class GTToolType { public static final GTToolType WIRE_CUTTER_LV = GTToolType.builder("lv_wirecutter") .idFormat("lv_%s_wire_cutter") - .toolTag(CustomTags.CRAFTING_WIRE_CUTTERS) - .toolTag(CustomTags.TOOLS_WIRE_CUTTER) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_WIRE_CUTTERS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_WIRE_CUTTER) .harvestTag(CustomTags.MINEABLE_WITH_WIRE_CUTTER) .definition(b -> b.blockBreaking().crafting().sneakBypassUse() .damagePerCraftingAction(4).attackDamage(-1.0F).attackSpeed(-2.4F) @@ -442,8 +444,8 @@ public class GTToolType { public static final GTToolType WIRE_CUTTER_HV = GTToolType.builder("hv_wirecutter") .idFormat("hv_%s_wire_cutter") - .toolTag(CustomTags.CRAFTING_WIRE_CUTTERS) - .toolTag(CustomTags.TOOLS_WIRE_CUTTER) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_WIRE_CUTTERS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_WIRE_CUTTER) .harvestTag(CustomTags.MINEABLE_WITH_WIRE_CUTTER) .definition(b -> b.blockBreaking().crafting().sneakBypassUse() .damagePerCraftingAction(4).attackDamage(-1.0F).attackSpeed(-2.4F) @@ -456,8 +458,8 @@ public class GTToolType { public static final GTToolType WIRE_CUTTER_IV = GTToolType.builder("iv_wirecutter") .idFormat("iv_%s_wire_cutter") - .toolTag(CustomTags.CRAFTING_WIRE_CUTTERS) - .toolTag(CustomTags.TOOLS_WIRE_CUTTER) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_WIRE_CUTTERS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_WIRE_CUTTER) .harvestTag(CustomTags.MINEABLE_WITH_WIRE_CUTTER) .definition(b -> b.blockBreaking().crafting().sneakBypassUse() .damagePerCraftingAction(4).attackDamage(-1.0F).attackSpeed(-2.4F) @@ -469,9 +471,9 @@ public class GTToolType { .build(); public static final GTToolType BUZZSAW_LV = GTToolType.builder("lv_buzzsaw") .idFormat("lv_%s_buzzsaw") - .toolTag(CustomTags.CRAFTING_SAWS) - .toolTag(CustomTags.TOOLS_SAW) - .toolTag(CustomTags.TOOLS_BUZZSAW) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_SAWS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_SAW) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_BUZZSAW) .definition(b -> b.crafting().attackDamage(1.5F).attackSpeed(-3.2F) .brokenStack(ToolHelper.SUPPLY_POWER_UNIT_LV)) .sound(GTSoundEntries.CHAINSAW_TOOL, true) @@ -480,8 +482,8 @@ public class GTToolType { .build(); public static final GTToolType SCREWDRIVER_LV = GTToolType.builder("lv_screwdriver") .idFormat("lv_%s_screwdriver") - .toolTag(CustomTags.CRAFTING_SCREWDRIVERS) - .toolTag(CustomTags.TOOLS_SCREWDRIVER) + .toolTag(ToolItemTagType.CRAFTING, CustomTags.CRAFTING_SCREWDRIVERS) + .toolTag(ToolItemTagType.MATCH, CustomTags.TOOLS_SCREWDRIVER) .definition(b -> b.crafting().sneakBypassUse() .attackDamage(-1.0F).efficiencyMultiplier(3.0F) .behaviors(new EntityDamageBehavior(3.0F, CustomTags.SPIDERS)) @@ -496,6 +498,8 @@ public class GTToolType { public final String idFormat; // at least one has to be set. first one MUST be the main tag. public final List> itemTags; + public final List> matchTags; + public final List> craftingTags; public final List> harvestTags; public final Set defaultAbilities; public final ResourceLocation modelLocation; @@ -513,7 +517,8 @@ public class GTToolType { public GTToolType(String name, String idFormat, char symbol, Set toolClasses, ToolConstructor constructor, IGTToolDefinition toolDefinition, - Set defaultAbilities, List> itemTags, List> harvestTags, + List> itemTags, List> matchTags, List> craftingTags, + List> harvestTags, Set defaultAbilities, Set toolClassNames, ResourceLocation modelLocation, @Nullable SoundEntry soundEntry, boolean playSoundOnBlockDestroy, int electricTier, long materialAmount) { @@ -525,6 +530,8 @@ public GTToolType(String name, String idFormat, char symbol, this.toolDefinition = toolDefinition; this.constructor = constructor; this.itemTags = itemTags; + this.matchTags = matchTags; + this.craftingTags = craftingTags; this.harvestTags = harvestTags; this.defaultAbilities = defaultAbilities; this.modelLocation = modelLocation; @@ -545,6 +552,12 @@ public String getUnlocalizedName() { return "item.gtceu.tool." + name; } + public enum ToolItemTagType { + NONE, + MATCH, + CRAFTING; + } + @FunctionalInterface public interface ToolConstructor { @@ -564,6 +577,8 @@ public static class Builder { private String idFormat; private final List> itemTags = new ArrayList<>(); + private final List> matchTags = new ArrayList<>(); + private final List> craftingTags = new ArrayList<>(); private final List> harvestTags = new ArrayList<>(); private final Set defaultAbilities = Sets.newIdentityHashSet(); @Setter @@ -590,8 +605,20 @@ public Builder(String name) { this.modelLocation = GTCEu.id("item/tools/" + name); } - public Builder toolTag(TagKey tag) { - itemTags.add(tag); + @SafeVarargs + public final Builder toolTag(TagKey... tags) { + return toolTag(ToolItemTagType.NONE, tags); + } + + @SafeVarargs + public final Builder toolTag(ToolItemTagType tagType, TagKey... tags) { + itemTags.addAll(Arrays.asList(tags)); + if (tagType == ToolItemTagType.MATCH) { + matchTags.addAll(Arrays.asList(tags)); + } + if (tagType == ToolItemTagType.CRAFTING) { + craftingTags.addAll(Arrays.asList(tags)); + } return this; } @@ -651,8 +678,8 @@ public Builder electric(int tier) { private GTToolType get() { return new GTToolType(name, idFormat, symbol, - toolClasses, constructor, toolDefinition, - defaultAbilities, itemTags, harvestTags, + toolClasses, constructor, + toolDefinition, itemTags, matchTags, craftingTags, harvestTags, defaultAbilities, toolClassNames, modelLocation, sound, playSoundOnBlockDestroy, tier, materialAmount); diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java index dcf120b7f5d..b9e4134d315 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/tool/ToolHelper.java @@ -189,6 +189,9 @@ public static void damageItem(@NotNull ItemStack stack, @Nullable LivingEntity u } if (user != null) { user.breakItem(stack); + user.onEquippedItemBroken(stack.getItem(), + user.getSlotForHand( + user.isUsingItem() ? user.getUsedItemHand() : InteractionHand.MAIN_HAND)); } stack.shrink(1); } @@ -462,16 +465,26 @@ public static boolean removeBlock(Level level, ServerPlayer player, BlockPos pos return removed; } + /** + * Calculates the harvestable blocks, used for tool AoE harvesting + * + * @param player the player clicking the item + * @param stack the item that was used + * + * @return listOfBlockPositions or empty list if none + */ public static List getHarvestableBlocks(ItemStack stack, Player player) { - if (!hasBehaviorsComponent(stack)) return List.of(); + final List NO_BLOCKS = List.of(); + if (!hasBehaviorsComponent(stack)) return NO_BLOCKS; var aoeDefinition = getAoEDefinition(stack); if (aoeDefinition.isZero()) { - return List.of(); + return NO_BLOCKS; } + InteractionHand hand = InteractionHand.MAIN_HAND; BlockHitResult hitResult = getPlayerDefaultRaytrace(player); - UseOnContext context = new UseOnContext(player, player.getUsedItemHand(), hitResult); + UseOnContext context = new UseOnContext(player, hand, hitResult); return getHarvestableBlocks(aoeDefinition, context); } @@ -515,8 +528,19 @@ public static Set getToolTypes(final ItemStack tool) { return gtTool.getToolClasses(tool); } for (GTToolType toolType : GTToolType.getTypes().values()) { - if (toolType.itemTags.stream().anyMatch(tool::is)) types.add(toolType); - if (toolType.defaultAbilities.stream().anyMatch(tool::canPerformAction)) types.add(toolType); + if (toolType.matchTags.stream().anyMatch(tool::is)) types.add(toolType); + } + return types; + } + + @NotNull + public static Set getCraftingToolTypes(ItemStack tool) { + Set types = new HashSet<>(); + if (tool.getItem() instanceof IGTTool gtTool) { + return gtTool.getToolClasses(tool); + } + for (GTToolType toolType : GTToolType.getTypes().values()) { + if (toolType.craftingTags.stream().anyMatch(tool::is)) types.add(toolType); } GTItemAbilities.DEFAULT_TYPE_ASSOCIATIONS.forEach((action, type) -> { if (tool.canPerformAction(action)) { @@ -531,7 +555,7 @@ public static Set getToolTypes(final ItemStack tool) { */ public static boolean isTool(ItemStack tool, GTToolType... toolClasses) { for (GTToolType toolType : toolClasses) { - if (toolType.itemTags.stream().anyMatch(tool::is)) return true; + if (toolType.matchTags.stream().anyMatch(tool::is)) return true; } if (tool.getItem() instanceof IGTTool igtTool) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/item/tool/TreeFellingHelper.java b/src/main/java/com/gregtechceu/gtceu/api/item/tool/TreeFellingHelper.java index a41e56c5464..3149cdc6272 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/item/tool/TreeFellingHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/item/tool/TreeFellingHelper.java @@ -22,7 +22,7 @@ import static com.gregtechceu.gtceu.api.item.tool.ToolHelper.*; -@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, modid = GTCEu.MOD_ID) +@EventBusSubscriber(modid = GTCEu.MOD_ID) public class TreeFellingHelper { private final ServerPlayer player; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/MachineDefinition.java b/src/main/java/com/gregtechceu/gtceu/api/machine/MachineDefinition.java index 16c49f24d36..1a9d980b7ef 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/MachineDefinition.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/MachineDefinition.java @@ -25,8 +25,8 @@ import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Reference2IntMap; +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; @@ -127,7 +127,7 @@ public class MachineDefinition implements Supplier { private EditableMachineUI editableUI; @Getter @Setter - private Object2IntMap> recipeOutputLimits = new Object2IntOpenHashMap<>(); + private Reference2IntMap> recipeOutputLimits = new Reference2IntOpenHashMap<>(); @Getter @Setter(onMethod_ = @ApiStatus.Internal) diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java index 768d57eedf8..47044ecfae0 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/MetaMachine.java @@ -1,7 +1,6 @@ package com.gregtechceu.gtceu.api.machine; import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.block.IAppearance; import com.gregtechceu.gtceu.api.block.MetaMachineBlock; import com.gregtechceu.gtceu.api.block.property.GTBlockStateProperties; import com.gregtechceu.gtceu.api.blockentity.IPaintable; @@ -19,6 +18,7 @@ import com.gregtechceu.gtceu.api.item.tool.IToolGridHighLight; import com.gregtechceu.gtceu.api.machine.feature.*; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.MachineTrait; import com.gregtechceu.gtceu.api.misc.IOFilteredInvWrapper; import com.gregtechceu.gtceu.api.misc.IOFluidHandlerList; @@ -28,6 +28,7 @@ import com.gregtechceu.gtceu.client.util.ModelUtils; import com.gregtechceu.gtceu.common.cover.FluidFilterCover; import com.gregtechceu.gtceu.common.cover.ItemFilterCover; +import com.gregtechceu.gtceu.common.cover.data.ManualIOMode; import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; import com.gregtechceu.gtceu.common.machine.owner.PlayerOwner; import com.gregtechceu.gtceu.data.item.GTItemAbilities; @@ -43,6 +44,7 @@ import com.lowdragmc.lowdraglib.utils.DummyWorld; import net.minecraft.ChatFormatting; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.component.DataComponentMap; @@ -81,13 +83,17 @@ import java.util.function.Consumer; import java.util.function.Predicate; +import javax.annotation.ParametersAreNonnullByDefault; + /** * an abstract layer of a gregtech machine. * Because I have to implement BlockEntities for both fabric and forge platform. * All fundamental features will be implemented here. * To add additional features, you can see {@link IMachineFeature} */ -public class MetaMachine implements IEnhancedManaged, IToolable, ITickSubscription, IAppearance, IToolGridHighLight, +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class MetaMachine implements IEnhancedManaged, IToolable, ITickSubscription, IToolGridHighLight, IFancyTooltip, IPaintable, IRedstoneSignalMachine { protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(MetaMachine.class); @@ -184,8 +190,8 @@ public void setPaintingColor(int color) { this.onPaintingColorChanged(color); MachineRenderState renderState = getRenderState(); - if (renderState.hasProperty(IS_PAINTED_PROPERTY)) { - setRenderState(renderState.setValue(IS_PAINTED_PROPERTY, this.isPainted())); + if (renderState.hasProperty(GTMachineModelProperties.IS_PAINTED)) { + setRenderState(renderState.setValue(GTMachineModelProperties.IS_PAINTED, this.isPainted())); } } @@ -217,11 +223,16 @@ public void onLoad() { coverContainer.onLoad(); // update the painted model property if the machine is painted - if (this.isPainted()) { - MachineRenderState renderState = getRenderState(); - if (renderState.hasProperty(IS_PAINTED_PROPERTY) && !renderState.getValue(IS_PAINTED_PROPERTY)) { - setRenderState(renderState.setValue(IS_PAINTED_PROPERTY, true)); - } + MachineRenderState renderState = getRenderState(); + if (renderState.hasProperty(GTMachineModelProperties.IS_PAINTED) && + this.isPainted() != renderState.getValue(GTMachineModelProperties.IS_PAINTED)) { + setRenderState(renderState.setValue(GTMachineModelProperties.IS_PAINTED, this.isPainted())); + } + + // Force model data refresh on client when BlockEntity finishes loading, + // in case the chunk was rendered before this BlockEntity was available + if (isRemote()) { + scheduleRenderUpdate(); } } @@ -443,14 +454,9 @@ protected ItemInteractionResult onSoftMalletClick(Player playerIn, InteractionHa var controllable = GTCapabilityHelper.getControllable(getLevel(), getPos(), gridSide); if (controllable == null) return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; if (!isRemote()) { - if (!playerIn.isShiftKeyDown() || !controllable.isWorkingEnabled()) { - controllable.setWorkingEnabled(!controllable.isWorkingEnabled()); - playerIn.sendSystemMessage(Component.translatable(controllable.isWorkingEnabled() ? - "behaviour.soft_hammer.enabled" : "behaviour.soft_hammer.disabled")); - } else { - controllable.setSuspendAfterFinish(true); - playerIn.sendSystemMessage(Component.translatable("behaviour.soft_hammer.idle_after_cycle")); - } + controllable.setWorkingEnabled(!controllable.isWorkingEnabled()); + playerIn.sendSystemMessage(Component.translatable(controllable.isWorkingEnabled() ? + "behaviour.soft_hammer.enabled" : "behaviour.soft_hammer.disabled_cycle")); } return ItemInteractionResult.sidedSuccess(playerIn.level().isClientSide); } @@ -704,7 +710,6 @@ public void onNeighborChanged(Block block, BlockPos fromPos, boolean isMoving) { public void animateTick(RandomSource random) {} - @Override @NotNull public BlockState getBlockAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side, @Nullable BlockState sourceState, @Nullable BlockPos sourcePos) { @@ -773,7 +778,15 @@ public boolean canConnectRedstone(@Nullable Direction side) { public Predicate getItemCapFilter(@Nullable Direction side, IO io) { if (side != null) { var cover = getCoverContainer().getCoverAtSide(side); - if (cover instanceof ItemFilterCover filterCover && filterCover.getFilterMode().filters(io)) { + if (cover instanceof ItemFilterCover filterCover) { + if (!filterCover.getFilterMode().filters(io)) { + if (filterCover.getAllowFlow() == ManualIOMode.DISABLED) { + return item -> false; + } + if (filterCover.getAllowFlow() == ManualIOMode.UNFILTERED) { + return item -> true; + } + } return filterCover.getItemFilter(); } } @@ -783,7 +796,15 @@ public Predicate getItemCapFilter(@Nullable Direction side, IO io) { public Predicate getFluidCapFilter(@Nullable Direction side, IO io) { if (side != null) { var cover = getCoverContainer().getCoverAtSide(side); - if (cover instanceof FluidFilterCover filterCover && filterCover.getFilterMode().filters(io)) { + if (cover instanceof FluidFilterCover filterCover) { + if (!filterCover.getFilterMode().filters(io)) { + if (filterCover.getAllowFlow() == ManualIOMode.DISABLED) { + return fluid -> false; + } + if (filterCover.getAllowFlow() == ManualIOMode.UNFILTERED) { + return fluid -> true; + } + } return filterCover.getFluidFilter(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleTieredMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleTieredMachine.java index a6fb8a4f214..1c1f70f6b30 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleTieredMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/SimpleTieredMachine.java @@ -7,6 +7,8 @@ import com.gregtechceu.gtceu.api.gui.editor.EditableMachineUI; import com.gregtechceu.gtceu.api.gui.editor.EditableUI; import com.gregtechceu.gtceu.api.gui.fancy.ConfiguratorPanel; +import com.gregtechceu.gtceu.api.gui.fancy.IFancyConfigurator; +import com.gregtechceu.gtceu.api.gui.fancy.IFancyConfiguratorButton; import com.gregtechceu.gtceu.api.gui.widget.GhostCircuitSlotWidget; import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; import com.gregtechceu.gtceu.api.item.tool.GTToolType; @@ -23,8 +25,10 @@ import com.gregtechceu.gtceu.data.datagen.lang.LangHandler; import com.gregtechceu.gtceu.utils.GTTransferUtils; +import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; +import com.lowdragmc.lowdraglib.gui.util.ClickData; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import com.lowdragmc.lowdraglib.syncdata.ISubscription; import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; @@ -52,7 +56,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.function.BiFunction; +import java.util.function.*; /** * All simple single machines are implemented here. @@ -308,11 +312,57 @@ public void onMachineRemoved() { @Override public void attachConfigurators(ConfiguratorPanel configuratorPanel) { IFancyUIMachine.super.attachConfigurators(configuratorPanel); + + if (hasAutoOutputFluid()) { + configuratorPanel.attachConfigurators(createAutoOutputFluidConfigurator()); + } + if (hasAutoOutputItem()) { + configuratorPanel.attachConfigurators(createAutoOutputItemConfigurator()); + } + if (isCircuitSlotEnabled()) { configuratorPanel.attachConfigurators(new CircuitFancyConfigurator(circuitInventory.storage)); } } + private IFancyConfigurator createAutoOutputFluidConfigurator() { + return createAutoOutputConfigurator( + GuiTextures.IO_CONFIG_FLUID_MODES_BUTTON, + "gtceu.gui.fluid_auto_output", + this::isAutoOutputFluids, + (cd, nextState) -> this.setAutoOutputFluids(nextState)); + } + + private IFancyConfigurator createAutoOutputItemConfigurator() { + return createAutoOutputConfigurator( + GuiTextures.IO_CONFIG_ITEM_MODES_BUTTON, + "gtceu.gui.item_auto_output", + this::isAutoOutputItems, + (cd, nextState) -> this.setAutoOutputItems(nextState)); + } + + private IFancyConfigurator createAutoOutputConfigurator(ResourceTexture modesButtonTexture, + String tooltipBaseLangKey, + BooleanSupplier stateSupplier, + BiConsumer onToggle) { + var toggle = new IFancyConfiguratorButton.Toggle( + new GuiTextureGroup( + GuiTextures.TOGGLE_BUTTON_BACK.getSubTexture(0, 0, 1, 0.5), + modesButtonTexture.getSubTexture(0, 1 / 3f, 1, 1 / 3f)), + new GuiTextureGroup( + GuiTextures.TOGGLE_BUTTON_BACK.getSubTexture(0, 0.5, 1, 0.5), + modesButtonTexture.getSubTexture(0, 2 / 3f, 1, 1 / 3f)), + stateSupplier, + onToggle); + + toggle.setTooltipsSupplier(enabled -> { + var key = tooltipBaseLangKey + '.' + (enabled ? "enabled" : "disabled"); + return List.of(Component.translatable(key)); + }); + + return toggle; + } + @SuppressWarnings("UnstableApiUsage") public static BiFunction EDITABLE_UI_CREATOR = Util .memoize((path, recipeType) -> new EditableMachineUI("simple", path, () -> { @@ -356,7 +406,7 @@ public void attachConfigurators(ConfiguratorPanel configuratorPanel) { })); /** - * Create an energy bar widget. + * Create a battery slot widget. */ protected static EditableUI createBatterySlot() { return new EditableUI<>("battery_slot", SlotWidget.class, () -> { @@ -373,7 +423,7 @@ protected static EditableUI createBatterySlot() } /** - * Create an energy bar widget. + * Create a ghost circuit slot widget. */ protected static EditableUI createCircuitConfigurator() { return new EditableUI<>("circuit_configurator", GhostCircuitSlotWidget.class, () -> { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/TieredEnergyMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/TieredEnergyMachine.java index 358fa0c3a08..fa99a9b86d4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/TieredEnergyMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/TieredEnergyMachine.java @@ -11,7 +11,6 @@ import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; import com.lowdragmc.lowdraglib.gui.texture.ProgressTexture; import com.lowdragmc.lowdraglib.gui.widget.ProgressWidget; -import com.lowdragmc.lowdraglib.syncdata.ISubscription; import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; @@ -25,8 +24,7 @@ public class TieredEnergyMachine extends TieredMachine implements ITieredMachine @Persisted @DescSynced public final NotifiableEnergyContainer energyContainer; - protected TickableSubscription explosionSubs; - protected ISubscription energyListener; + protected TickableSubscription explosionSub; public TieredEnergyMachine(IMachineBlockEntity holder, int tier, Object... args) { super(holder, tier); @@ -53,40 +51,29 @@ protected NotifiableEnergyContainer createEnergyContainer(Object... args) { @Override public void onLoad() { super.onLoad(); - // if machine need do check explosion conditions if (!isRemote() && ConfigHolder.INSTANCE.machines.shouldWeatherOrTerrainExplosion && shouldWeatherOrTerrainExplosion()) { - energyListener = energyContainer.addChangedListener(this::updateExplosionSubscription); - updateExplosionSubscription(); + explosionSub = subscribeServerTick(this::checkExplosion); + checkExplosion(); } } @Override public void onUnload() { super.onUnload(); - if (energyListener != null) { - energyListener.unsubscribe(); - energyListener = null; + if (explosionSub != null) { + explosionSub.unsubscribe(); + explosionSub = null; } } ////////////////////////////////////// // ******** Explosion ********// ////////////////////////////////////// - - protected void updateExplosionSubscription() { - if (ConfigHolder.INSTANCE.machines.shouldWeatherOrTerrainExplosion && shouldWeatherOrTerrainExplosion() && - energyContainer.getEnergyStored() > 0) { - explosionSubs = subscribeServerTick(explosionSubs, this::checkExplosion); - } else if (explosionSubs != null) { - explosionSubs.unsubscribe(); - explosionSubs = null; - } - } - protected void checkExplosion() { - checkWeatherOrTerrainExplosion(tier, tier * 10); - updateExplosionSubscription(); + if (energyContainer.getEnergyStored() > 0) { + checkWeatherOrTerrainExplosion(tier, tier * 10); + } } ////////////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java index 16af4b4be74..3520a62574d 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/WorkableTieredMachine.java @@ -1,5 +1,6 @@ package com.gregtechceu.gtceu.api.machine; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.capability.recipe.*; import com.gregtechceu.gtceu.api.machine.feature.*; @@ -13,8 +14,10 @@ import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; import it.unimi.dsi.fastutil.ints.Int2IntFunction; +import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,8 +33,8 @@ public abstract class WorkableTieredMachine extends TieredEnergyMachine implemen @Persisted @DescSynced public final RecipeLogic recipeLogic; - @Getter - public final GTRecipeType[] recipeTypes; + @Getter(AccessLevel.PUBLIC) + private GTRecipeType[] recipeTypes; @Getter @Setter @Persisted @@ -231,6 +234,30 @@ public boolean keepSubscribing() { @NotNull public GTRecipeType getRecipeType() { + if (activeRecipeType >= recipeTypes.length) { + GTCEu.LOGGER.warn("Preventing crash from bad recipe type index!"); + activeRecipeType = recipeTypes.length - 1; + } return recipeTypes[activeRecipeType]; } + + // Recipe compat + @ApiStatus.Internal + public void setRecipeType(@NotNull GTRecipeType type) { + int recipeIndex = -1; + for (int i = 0; i < recipeTypes.length; i++) { + if (type.equals(recipeTypes[i])) { + recipeIndex = i; + break; + } + } + if (recipeIndex == -1) { + var newer = new GTRecipeType[recipeTypes.length + 1]; + System.arraycopy(recipeTypes, 0, newer, 0, recipeTypes.length); + newer[recipeTypes.length] = type; + recipeTypes = newer; + recipeIndex = recipeTypes.length - 1; + } + setActiveRecipeType(recipeIndex); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/AutoStockingFancyConfigurator.java b/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/AutoStockingFancyConfigurator.java new file mode 100644 index 00000000000..e76cb424815 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/AutoStockingFancyConfigurator.java @@ -0,0 +1,53 @@ +package com.gregtechceu.gtceu.api.machine.fancyconfigurator; + +import com.gregtechceu.gtceu.api.gui.fancy.IFancyConfigurator; +import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; +import com.gregtechceu.gtceu.config.ConfigHolder; +import com.gregtechceu.gtceu.data.item.GTItems; +import com.gregtechceu.gtceu.integration.ae2.machine.MEStockingBusPartMachine; +import com.gregtechceu.gtceu.integration.ae2.machine.feature.multiblock.IMEStockingPart; + +import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; +import com.lowdragmc.lowdraglib.gui.texture.ItemStackTexture; +import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; +import com.lowdragmc.lowdraglib.gui.widget.Widget; +import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; + +import net.minecraft.network.chat.Component; + +public class AutoStockingFancyConfigurator implements IFancyConfigurator { + + private IMEStockingPart machine; + + public AutoStockingFancyConfigurator(IMEStockingPart machine) { + this.machine = machine; + } + + @Override + public Component getTitle() { + return Component.translatable("gtceu.gui.adv_stocking_config.title"); + } + + @Override + public IGuiTexture getIcon() { + return new ItemStackTexture(GTItems.TOOL_DATA_STICK.asStack()); + } + + @Override + public Widget createConfigurator() { + var group = new WidgetGroup(0, 0, 90, 70); + + String suffix = machine instanceof MEStockingBusPartMachine ? "min_item_count" : "min_fluid_count"; + + group.addWidget(new LabelWidget(4, 2, "gtceu.gui.title.adv_stocking_config." + suffix)); + group.addWidget(new IntInputWidget(4, 12, 81, 14, machine::getMinStackSize, + machine::setMinStackSize).setMin(1) + .appendHoverTooltips(Component.translatable("gtceu.gui.adv_stocking_config." + suffix))); + group.addWidget(new LabelWidget(4, 36, "gtceu.gui.title.adv_stocking_config.ticks_per_cycle")); + group.addWidget(new IntInputWidget(4, 46, 81, 14, machine::getTicksPerCycle, + machine::setTicksPerCycle).setMin(ConfigHolder.INSTANCE.compat.ae2.updateIntervals) + .setHoverTooltips(Component.translatable("gtceu.gui.adv_stocking_config.ticks_per_cycle"))); + + return group; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/CombinedDirectionalFancyConfigurator.java b/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/CombinedDirectionalFancyConfigurator.java index 4a91692bf2a..94a269dc406 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/CombinedDirectionalFancyConfigurator.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/CombinedDirectionalFancyConfigurator.java @@ -54,7 +54,14 @@ public IGuiTexture getTabIcon() { @Override public Component getTitle() { - return Component.translatable("gtceu.gui.directional_setting.title"); // TODO add this + return Component.translatable("gtceu.gui.directional_setting.title"); + } + + @Override + public List getTabTooltips() { + List tooltip = new ArrayList<>(); + tooltip.add(Component.translatable("gtceu.gui.directional_setting.tab_tooltip")); + return tooltip; } // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/FancySelectorConfigurator.java b/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/FancySelectorConfigurator.java new file mode 100644 index 00000000000..5b89d526cdc --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/FancySelectorConfigurator.java @@ -0,0 +1,54 @@ +package com.gregtechceu.gtceu.api.machine.fancyconfigurator; + +import com.gregtechceu.gtceu.api.gui.fancy.IFancyConfiguratorButton; +import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; + +import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; +import com.lowdragmc.lowdraglib.gui.util.ClickData; + +import net.minecraft.network.chat.Component; + +import lombok.Setter; +import lombok.experimental.Accessors; + +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; + +public class FancySelectorConfigurator & EnumSelectorWidget.SelectableEnum> + implements IFancyConfiguratorButton { + + private final EnumSelectorWidget widget; + + @Setter + @Accessors(chain = true) + private Function> tooltip = t -> Collections.singletonList(Component.empty()); + + public FancySelectorConfigurator(T[] values, T initialValue, Consumer onChanged) { + this.widget = new EnumSelectorWidget<>(0, 0, 20, 20, values, initialValue, onChanged); + } + + @Override + public IGuiTexture getIcon() { + return widget.getTexture(widget.selected); + } + + @Override + public List getTooltips() { + return this.tooltip.apply(widget.getCurrentValue()); + } + + @Override + public void onClick(ClickData clickData) { + ++widget.selected; + if (widget.selected >= widget.values.size()) { + widget.selected = 0; + } + + widget.buttonWidget.setIndex(widget.selected); + if (widget.onChanged != null) { + widget.onChanged.accept(widget.getCurrentValue()); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/MachineModeFancyConfigurator.java b/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/MachineModeFancyConfigurator.java index d396fe64472..04cdb2cd1fb 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/MachineModeFancyConfigurator.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/fancyconfigurator/MachineModeFancyConfigurator.java @@ -44,7 +44,7 @@ public Widget createMainPage(FancyMachineUIWidget widget) { for (int i = 0; i < machine.getRecipeTypes().length; i++) { int finalI = i; group.addWidget(new ButtonWidget(2, 2 + i * 20, 136, 20, IGuiTexture.EMPTY, - cd -> machine.setActiveRecipeType(finalI))); + cd -> setActiveRecipeTypeAndUpdateTickSubs(finalI))); group.addWidget(new ImageWidget(2, 2 + i * 20, 136, 20, () -> new GuiTextureGroup( ResourceBorderTexture.BUTTON_COMMON.copy() @@ -59,10 +59,18 @@ public Widget createMainPage(FancyMachineUIWidget widget) { @Override public List getTabTooltips() { List tooltip = new ArrayList<>(); - tooltip.add(Component.literal("Change active Machine Mode")); + tooltip.add(Component.translatable("gtceu.gui.machinemode.tab_tooltip")); return tooltip; } + private void setActiveRecipeTypeAndUpdateTickSubs(int activeRecipeType) { + boolean needUpdateTickSubs = !machine.keepSubscribing() && activeRecipeType != machine.getActiveRecipeType(); + machine.setActiveRecipeType(activeRecipeType); + if (needUpdateTickSubs) { + machine.getRecipeLogic().updateTickSubscription(); + } + } + public class MachineModeConfigurator extends WidgetGroup { public MachineModeConfigurator(int x, int y, int width, int height) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IExhaustVentMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IExhaustVentMachine.java index 1047ffb28cd..8eece95b522 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IExhaustVentMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IExhaustVentMachine.java @@ -1,9 +1,11 @@ package com.gregtechceu.gtceu.api.machine.feature; import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.damagesource.GTDamageTypes; +import com.gregtechceu.gtceu.utils.GTUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -28,8 +30,7 @@ */ public interface IExhaustVentMachine extends IMachineFeature { - EnumProperty VENT_DIRECTION_PROPERTY = EnumProperty.create("steam_vent", - RelativeDirection.class); + EnumProperty VENT_DIRECTION_PROPERTY = GTMachineModelProperties.VENT_DIRECTION; /** * @return the direction the vent faces @@ -86,22 +87,35 @@ default boolean isVentingBlocked() { * @param pos the position of the machine */ default void tryDoVenting(@NotNull Level level, @NotNull BlockPos pos) { - if (isNeedsVenting() && !isVentingBlocked()) { - doVentingDamage(level, pos); + if (!isNeedsVenting()) return; - Direction ventingDirection = getVentingDirection(); - double posX = pos.getX() + 0.5 + ventingDirection.getStepX() * 0.6; - double posY = pos.getY() + 0.5 + ventingDirection.getStepY() * 0.6; - double posZ = pos.getZ() + 0.5 + ventingDirection.getStepZ() * 0.6; - createVentingParticles(level, posX, posY, posZ); + if (!isVentingBlocked()) { + performVenting(level, pos); + return; + } - if (ConfigHolder.INSTANCE.machines.machineSounds) { - playVentingSound(level, posX, posY, posZ); - } - markVentingComplete(); + BlockPos ventingPos = pos.relative(getVentingDirection()); + if (GTUtil.tryBreakSnow(level, ventingPos, level.getBlockState(ventingPos), false)) { + performVenting(level, pos); } } + private void performVenting(@NotNull Level level, @NotNull BlockPos pos) { + doVentingDamage(level, pos); + + Direction ventingDirection = getVentingDirection(); + double posX = pos.getX() + 0.5 + ventingDirection.getStepX() * 0.6; + double posY = pos.getY() + 0.5 + ventingDirection.getStepY() * 0.6; + double posZ = pos.getZ() + 0.5 + ventingDirection.getStepZ() * 0.6; + createVentingParticles(level, posX, posY, posZ); + + if (ConfigHolder.INSTANCE.machines.machineSounds) { + playVentingSound(level, posX, posY, posZ); + } + + markVentingComplete(); + } + /** * Damages entities upon venting * diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java index e63aa7ae802..3833e76fc1b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IRecipeLogicMachine.java @@ -144,6 +144,11 @@ default void setSuspendAfterFinish(boolean suspendAfterFinish) { getRecipeLogic().setSuspendAfterFinish(suspendAfterFinish); } + @Override + default boolean isSuspendAfterFinish() { + return getRecipeLogic().isSuspendAfterFinish(); + } + @Override default int getProgress() { return getRecipeLogic().getProgress(); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IVoidable.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IVoidable.java index 4c968d6c918..72e6f1941ef 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IVoidable.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/IVoidable.java @@ -1,35 +1,73 @@ package com.gregtechceu.gtceu.api.machine.feature; +import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; +import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; +import com.gregtechceu.gtceu.api.gui.GuiTextures; +import com.gregtechceu.gtceu.api.gui.fancy.ConfiguratorPanel; +import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; +import com.gregtechceu.gtceu.api.machine.fancyconfigurator.FancySelectorConfigurator; +import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; + +import net.minecraft.network.chat.Component; import net.minecraft.util.StringRepresentable; -import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Reference2IntMap; +import lombok.Getter; import org.jetbrains.annotations.NotNull; +import java.util.List; +import java.util.function.Predicate; + public interface IVoidable extends IMachineFeature { default boolean canVoidRecipeOutputs(RecipeCapability capability) { - return self().getDefinition().getRecipeOutputLimits().containsKey(capability); + return getVoidingMode().canVoid(capability) || + self().getDefinition().getRecipeOutputLimits().getOrDefault(capability, -1) == 0; } - default Object2IntMap> getOutputLimits() { + default Reference2IntMap> getOutputLimits() { return self().getDefinition().getRecipeOutputLimits(); } - enum VoidingMode implements StringRepresentable { + default void setVoidingMode(VoidingMode mode) {} + + default VoidingMode getVoidingMode() { + return VoidingMode.VOID_NONE; + } + + static void attachConfigurators(ConfiguratorPanel configuratorPanel, IVoidable controller) { + configuratorPanel + .attachConfigurators(new FancySelectorConfigurator<>(VoidingMode.VALUES, controller.getVoidingMode(), + controller::setVoidingMode) + .setTooltip(m -> List.of(Component.translatable("gtceu.gui.multiblock.voiding_mode"), + Component.translatable(m.localeName)))); + } + + enum VoidingMode implements StringRepresentable, EnumSelectorWidget.SelectableEnum { - VOID_NONE("gtceu.gui.multiblock_no_voiding"), - VOID_ITEMS("gtceu.gui.multiblock_item_voiding"), - VOID_FLUIDS("gtceu.gui.multiblock_fluid_voiding"), - VOID_BOTH("gtceu.gui.multiblock_item_fluid_voiding"); + VOID_NONE("gtceu.gui.no_voiding", cap -> false), + VOID_ITEMS("gtceu.gui.item_voiding", cap -> cap == ItemRecipeCapability.CAP), + VOID_FLUIDS("gtceu.gui.fluid_voiding", cap -> cap == FluidRecipeCapability.CAP), + VOID_ITEMS_FLUIDS("gtceu.gui.all_voiding", + cap -> cap == ItemRecipeCapability.CAP || cap == FluidRecipeCapability.CAP); public static final VoidingMode[] VALUES = values(); - public final String localeName; + private final String localeName; + @Getter + private final IGuiTexture icon; + private final Predicate> canVoid; - VoidingMode(String name) { + VoidingMode(String name, Predicate> canVoid) { this.localeName = name; + this.canVoid = canVoid; + this.icon = GuiTextures.BUTTON_VOID_MULTIBLOCK.getSubTexture(0, ordinal() * 0.25, 1, 0.25); + } + + public boolean canVoid(RecipeCapability capability) { + return canVoid.test(capability); } @NotNull @@ -37,5 +75,10 @@ enum VoidingMode implements StringRepresentable { public String getSerializedName() { return localeName; } + + @Override + public @NotNull String getTooltip() { + return localeName; + } } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IFluidRenderMulti.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IFluidRenderMulti.java index 473eb1ba5f4..b581208717e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IFluidRenderMulti.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IFluidRenderMulti.java @@ -1,7 +1,5 @@ package com.gregtechceu.gtceu.api.machine.feature.multiblock; -import com.gregtechceu.gtceu.api.machine.feature.IMachineFeature; - import net.minecraft.core.BlockPos; import org.jetbrains.annotations.ApiStatus; @@ -9,7 +7,7 @@ import java.util.Set; -public interface IFluidRenderMulti extends IWorkableMultiController, IMachineFeature { +public interface IFluidRenderMulti extends IWorkableMultiController { @ApiStatus.NonExtendable default Set getFluidOffsets() { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMaintenanceMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMaintenanceMachine.java index 40745e40009..fd5486bfa12 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMaintenanceMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMaintenanceMachine.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.gui.GuiTextures; import com.gregtechceu.gtceu.api.gui.fancy.IFancyTooltip; import com.gregtechceu.gtceu.api.gui.fancy.TooltipsPanel; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.config.ConfigHolder; @@ -16,8 +17,7 @@ public interface IMaintenanceMachine extends IMultiPart { - BooleanProperty MAINTENANCE_TAPED_PROPERTY = BooleanProperty.create("maintenance_taped"); - int MINIMUM_MAINTENANCE_TIME = 3456000; // 48 real-life hours = 3456000 ticks + BooleanProperty MAINTENANCE_TAPED_PROPERTY = GTMachineModelProperties.IS_TAPED; byte ALL_PROBLEMS = 0; byte NO_PROBLEMS = 0b111111; @@ -79,20 +79,6 @@ default boolean canShared() { return false; } - /** - * @param duration recipe progress time - * @return it's time for a new problem occurring; - */ - default boolean calculateTime(int duration) { - setTimeActive(duration + getTimeActive()); - var value = getTimeActive() - MINIMUM_MAINTENANCE_TIME; - if (value > 0) { - setTimeActive(value); - return true; - } - return false; - } - /** * Used to calculate whether a maintenance problem should happen based on machine time active * @@ -103,14 +89,24 @@ default void calculateMaintenance(IMaintenanceMachine maintenanceMachine, int du return; } - if (calculateTime((int) (duration * maintenanceMachine.getTimeMultiplier()))) { - if (GTValues.RNG.nextFloat() - 0.75f >= 0) { + setTimeActive(getTimeActive() + duration); + float rate = ConfigHolder.INSTANCE.machines.maintenanceCheckRate / maintenanceMachine.getTimeMultiplier(); + if (getTimeActive() >= rate) { + setTimeActive(0); + if (GTValues.RNG.nextInt(6000) == 0) { causeRandomMaintenanceProblems(); maintenanceMachine.setTaped(false); } } } + /** + * Used to calculate whether a maintenance problem should happen based on machine time active + */ + default void calculateMaintenance(IMaintenanceMachine maintenanceMachine) { + calculateMaintenance(maintenanceMachine, 1); + } + default int getNumMaintenanceProblems() { return ConfigHolder.INSTANCE.machines.enableMaintenance ? 6 - Integer.bitCount(getMaintenanceProblems()) : 0; } @@ -129,13 +125,10 @@ default void causeRandomMaintenanceProblems() { } @Override - default boolean afterWorking(IWorkableMultiController controller) { - if (ConfigHolder.INSTANCE.machines.enableMaintenance) { - calculateMaintenance(this, controller.getRecipeLogic().getProgress()); - if (hasMaintenanceProblems()) { - controller.getRecipeLogic().markLastRecipeDirty(); - return false; - } + default boolean onWorking(IWorkableMultiController controller) { + calculateMaintenance(this); + if (hasMaintenanceProblems()) { + controller.getRecipeLogic().markLastRecipeDirty(); } return true; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiController.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiController.java index 61c2b33c235..a4ef7d18e7d 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiController.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IMultiController.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.machine.feature.IInteractedMachine; import com.gregtechceu.gtceu.api.machine.feature.IMachineFeature; import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockControllerMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.multiblock.BlockPattern; import com.gregtechceu.gtceu.api.multiblock.MultiblockState; import com.gregtechceu.gtceu.client.renderer.MultiblockInWorldPreviewRenderer; @@ -30,7 +31,7 @@ public interface IMultiController extends IMachineFeature, IInteractedMachine { - BooleanProperty IS_FORMED_PROPERTY = BooleanProperty.create("is_formed"); + BooleanProperty IS_FORMED_PROPERTY = GTMachineModelProperties.IS_FORMED; @Override default MultiblockControllerMachine self() { @@ -162,6 +163,8 @@ default boolean isBatchEnabled() { return false; } + default void setBatchEnabled(boolean batch) {} + /** * Called from part, when part is invalid due to chunk unload or broken. */ diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IRotorHolderMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IRotorHolderMachine.java index 362bf3916fd..437523bfbde 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IRotorHolderMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/feature/multiblock/IRotorHolderMachine.java @@ -3,6 +3,7 @@ import com.gregtechceu.gtceu.api.gui.GuiTextures; import com.gregtechceu.gtceu.api.gui.fancy.IFancyTooltip; import com.gregtechceu.gtceu.api.gui.fancy.TooltipsPanel; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.material.material.Material; import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; @@ -24,9 +25,9 @@ public interface IRotorHolderMachine extends IMultiPart { int SPEED_INCREMENT = 1; int SPEED_DECREMENT = 3; - BooleanProperty HAS_ROTOR_PROPERTY = BooleanProperty.create("has_rotor"); - BooleanProperty ROTOR_SPINNING_PROPERTY = BooleanProperty.create("rotor_spinning"); - BooleanProperty EMISSIVE_ROTOR_PROPERTY = BooleanProperty.create("emissive_rotor"); + BooleanProperty HAS_ROTOR_PROPERTY = GTMachineModelProperties.HAS_ROTOR; + BooleanProperty ROTOR_SPINNING_PROPERTY = GTMachineModelProperties.IS_ROTOR_SPINNING; + BooleanProperty EMISSIVE_ROTOR_PROPERTY = GTMachineModelProperties.IS_EMISSIVE_ROTOR; /** * @return the base efficiency of the rotor holder in % diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java index 5eec9dd77e0..a9d61b3df6b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockControllerMachine.java @@ -9,6 +9,7 @@ import com.gregtechceu.gtceu.api.machine.MultiblockMachineDefinition; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.multiblock.MultiblockState; import com.gregtechceu.gtceu.api.multiblock.MultiblockWorldSavedData; import com.gregtechceu.gtceu.client.model.machine.MachineRenderState; @@ -165,8 +166,8 @@ public void asyncCheckPattern(long periodID) { public void onStructureFormed() { isFormed = true; MachineRenderState renderState = getRenderState(); - if (renderState.hasProperty(IMultiController.IS_FORMED_PROPERTY)) { - setRenderState(renderState.setValue(IMultiController.IS_FORMED_PROPERTY, true)); + if (renderState.hasProperty(GTMachineModelProperties.IS_FORMED)) { + setRenderState(renderState.setValue(GTMachineModelProperties.IS_FORMED, true)); } this.parts.clear(); @@ -190,8 +191,8 @@ public void onStructureFormed() { public void onStructureInvalid() { isFormed = false; MachineRenderState renderState = getRenderState(); - if (renderState.hasProperty(IMultiController.IS_FORMED_PROPERTY)) { - setRenderState(renderState.setValue(IMultiController.IS_FORMED_PROPERTY, false)); + if (renderState.hasProperty(GTMachineModelProperties.IS_FORMED)) { + setRenderState(renderState.setValue(GTMachineModelProperties.IS_FORMED, false)); } for (IMultiPart part : parts) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockDisplayText.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockDisplayText.java index d8c34953c43..90a043ab8a0 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockDisplayText.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/MultiblockDisplayText.java @@ -4,8 +4,11 @@ import com.gregtechceu.gtceu.api.capability.IEnergyContainer; import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; +import com.gregtechceu.gtceu.api.recipe.ingredient.IntProviderFluidIngredient; +import com.gregtechceu.gtceu.api.recipe.ingredient.IntProviderIngredient; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.utils.FormattingUtil; @@ -15,6 +18,8 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.chat.HoverEvent; import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.fluids.FluidStack; import java.util.List; import java.util.function.Consumer; @@ -312,6 +317,23 @@ public Builder addProgressLineOnlyPercent(double progressPercent) { return this; } + /** + * Adds a progress line based on the recipe logic. + * + * @param recipeLogic The recipe logic that provides the progress info + * + * @see #addProgressLine(double, double, double) + * @see #addCustomProgressLine(RecipeLogic) + */ + public Builder addProgressLine(RecipeLogic recipeLogic) { + if (recipeLogic.hasCustomProgressLine()) { + return this.addCustomProgressLine(recipeLogic); + } else { + return this.addProgressLine(recipeLogic.getProgress(), recipeLogic.getMaxProgress(), + recipeLogic.getProgressPercent()); + } + } + /** * Adds a simple progress line that displays the current time of a recipe and its progress as a percentage. *
@@ -333,9 +355,53 @@ public Builder addProgressLine(double currentDuration, double maxDuration, doubl return this; } + /** + * Adds a customized progress line that is often used to display the current time of a recipe and its progress + * as a percentage. + *

+ * Added if structure if formed and the machine is active. + * + * @param recipeLogic The recipe logic that provides the line + */ + public Builder addCustomProgressLine(RecipeLogic recipeLogic) { + if (!isStructureFormed || !isActive) + return this; + Component line = recipeLogic.getCustomProgressLine(); + if (line != null) { + textList.add(line); + } + return this; + } + public Builder addBatchModeLine(boolean batchEnabled, int batchAmount) { if (batchEnabled && batchAmount > 0) { - textList.add(Component.translatable("gtceu.multiblock.batch_enabled", batchAmount)); + Component runs = Component.literal(FormattingUtil.formatNumbers(batchAmount)) + .withStyle(ChatFormatting.DARK_PURPLE); + String key = "gtceu.multiblock.batch_enabled"; + textList.add(Component.translatable(key, runs) + .withStyle(ChatFormatting.GRAY)); + } + return this; + } + + public Builder addSubtickParallelsLine(int subtickParallels) { + if (subtickParallels > 1) { + Component runs = Component.literal(FormattingUtil.formatNumbers(subtickParallels)) + .withStyle(ChatFormatting.DARK_PURPLE); + String key = "gtceu.multiblock.subtick_parallels"; + textList.add(Component.translatable(key, runs) + .withStyle(ChatFormatting.GRAY)); + } + return this; + } + + public Builder addTotalRunsLine(int totalRuns) { + if (totalRuns > 1) { + Component runs = Component.literal(FormattingUtil.formatNumbers(totalRuns)) + .withStyle(ChatFormatting.DARK_PURPLE); + String key = "gtceu.multiblock.total_runs"; + textList.add(Component.translatable(key, runs) + .withStyle(ChatFormatting.GRAY)); } return this; } @@ -350,46 +416,93 @@ public Builder addOutputLines(GTRecipe recipe) { double maxDurationSec = (double) recipe.duration / 20.0; var itemOutputs = recipe.getOutputContents(ItemRecipeCapability.CAP); var fluidOutputs = recipe.getOutputContents(FluidRecipeCapability.CAP); + int runs = recipe.getTotalRuns(); for (var item : itemOutputs) { - var stacks = ItemRecipeCapability.CAP.of(item.content).getItems(); - if (stacks.length == 0) continue; - var stack = stacks[0]; - int count = stack.getCount(); - double countD = count; - if (item.chance < item.maxChance) { - countD = countD * recipe.parallels * recipe.batchParallels * - function.getBoostedChance(item, recipeTier, chanceTier) / item.maxChance; - count = countD < 1 ? 1 : (int) Math.round(countD); + boolean rounded = false; + ItemStack stack; + // number of items output by a non-ranged ingredient + int count = 0; + // number of items output, but stored as a double. Used for accurate items/second display. + double countD = 1; + // number of items output which is actually displayed. Can be either a number, or a range. + Component displaycount; + if (item.content instanceof IntProviderIngredient provider) { + rounded = true; + stack = provider.getMaxSizeStack(); + displaycount = Component.translatable("gtceu.gui.content.range", + provider.getCountProvider().getMinValue(), + provider.getCountProvider().getMaxValue()); + if (item.chance < item.maxChance) { + countD = countD * runs * function.getBoostedChance(item, recipeTier, chanceTier) / + item.maxChance; + } + countD = countD * provider.getMidRoll(); + } else { + var stacks = ItemRecipeCapability.CAP.of(item.content).getItems(); + if (stacks.length == 0) continue; + stack = stacks[0]; + count = stack.getCount(); + countD *= count; + if (item.chance < item.maxChance) { + rounded = true; + countD = countD * runs * function.getBoostedChance(item, recipeTier, chanceTier) / + item.maxChance; + } + count = Math.max(1, (int) Math.round(countD)); + displaycount = Component.literal(String.valueOf(count)); } - if (count < maxDurationSec) { - String key = "gtceu.multiblock.output_line." + (item.chance < item.maxChance ? "2" : "0"); - textList.add(Component.translatable(key, stack.getHoverName(), count, + if (countD < maxDurationSec) { + String key = "gtceu.multiblock.output_line." + (rounded ? "2" : "0"); + textList.add(Component.translatable(key, stack.getHoverName(), displaycount, FormattingUtil.formatNumber2Places(maxDurationSec / countD))); } else { - String key = "gtceu.multiblock.output_line." + (item.chance < item.maxChance ? "3" : "1"); - textList.add(Component.translatable(key, stack.getHoverName(), count, + String key = "gtceu.multiblock.output_line." + (rounded ? "3" : "1"); + textList.add(Component.translatable(key, stack.getHoverName(), displaycount, FormattingUtil.formatNumber2Places(countD / maxDurationSec))); } } for (var fluid : fluidOutputs) { - var stacks = FluidRecipeCapability.CAP.of(fluid.content).getFluids(); - if (stacks.length == 0) continue; - var stack = stacks[0]; - int amount = stack.getAmount(); - double amountD = amount; - if (fluid.chance < fluid.maxChance) { - amountD = amountD * recipe.parallels * recipe.batchParallels * - function.getBoostedChance(fluid, recipeTier, chanceTier) / fluid.maxChance; - amount = amountD < 1 ? 1 : (int) Math.round(amountD); + boolean rounded = false; + FluidStack stack; + // amount of fluid output by a non-ranged ingredient + int amount = 0; + // amount of fluid output, but stored as a double. Used for accurate fluid/second display. + double amountD = 1; + // amount of fluid output which is actually displayed. Can be either a number, or a range. + Component displaycount; + if (fluid.content instanceof IntProviderFluidIngredient provider) { + rounded = true; + stack = provider.getMaxSizeStack(); + displaycount = Component.translatable("gtceu.gui.content.range", + provider.getCountProvider().getMinValue(), + provider.getCountProvider().getMaxValue()); + if (fluid.chance < fluid.maxChance) { + amountD = amountD * runs * function.getBoostedChance(fluid, recipeTier, chanceTier) / + fluid.maxChance; + } + amountD = amountD * provider.getMidRoll(); + } else { + var stacks = FluidRecipeCapability.CAP.of(fluid.content).getFluids(); + if (stacks.length == 0) continue; + stack = stacks[0]; + amount = stack.getAmount(); + amountD *= amount; + if (fluid.chance < fluid.maxChance) { + rounded = true; + amountD = amountD * runs * function.getBoostedChance(fluid, recipeTier, chanceTier) / + fluid.maxChance; + } + amount = Math.max(1, (int) Math.round(amountD)); + displaycount = Component.literal(String.valueOf(amount)); } - if (amount < maxDurationSec) { - String key = "gtceu.multiblock.output_line." + (fluid.chance < fluid.maxChance ? "2" : "0"); - textList.add(Component.translatable(key, stack.getHoverName(), amount, + if (amountD < maxDurationSec) { + String key = "gtceu.multiblock.output_line." + (rounded ? "2" : "0"); + textList.add(Component.translatable(key, stack.getHoverName(), displaycount, FormattingUtil.formatNumber2Places(maxDurationSec / amountD))); } else { - String key = "gtceu.multiblock.output_line." + (fluid.chance < fluid.maxChance ? "3" : "1"); - textList.add(Component.translatable(key, stack.getHoverName(), amount, + String key = "gtceu.multiblock.output_line." + (rounded ? "3" : "1"); + textList.add(Component.translatable(key, stack.getHoverName(), displaycount, FormattingUtil.formatNumber2Places(amountD / maxDurationSec))); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java index 9d8e3c92408..69d75a5c9f4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableElectricMultiblockMachine.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IOverclockMachine; import com.gregtechceu.gtceu.api.machine.feature.ITieredMachine; +import com.gregtechceu.gtceu.api.machine.feature.IVoidable; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IDisplayUIMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; import com.gregtechceu.gtceu.api.misc.EnergyContainerList; @@ -81,6 +82,11 @@ public void onPartUnload() { this.tier = 0; } + @Override + public void setBatchEnabled(boolean batch) { + this.batchEnabled = batch; + } + ////////////////////////////////////// // ********** GUI ***********// ////////////////////////////////////// @@ -88,17 +94,23 @@ public void onPartUnload() { @Override public void addDisplayText(@NotNull List textList) { int numParallels; + int subtickParallels; int batchParallels; + int totalRuns; boolean exact = false; if (recipeLogic.isActive() && recipeLogic.getLastRecipe() != null) { numParallels = recipeLogic.getLastRecipe().parallels; + subtickParallels = recipeLogic.getLastRecipe().subtickParallels; batchParallels = recipeLogic.getLastRecipe().batchParallels; + totalRuns = recipeLogic.getLastRecipe().getTotalRuns(); exact = true; } else { numParallels = getParallelHatch() .map(IParallelHatch::getCurrentParallel) .orElse(0); + subtickParallels = 0; batchParallels = 0; + totalRuns = 0; } MultiblockDisplayText.builder(textList, isFormed()) @@ -106,11 +118,12 @@ public void addDisplayText(@NotNull List textList) { .addEnergyUsageLine(energyContainer) .addEnergyTierLine(tier) .addMachineModeLine(getRecipeType(), getRecipeTypes().length > 1) + .addTotalRunsLine(totalRuns) .addParallelsLine(numParallels, exact) + .addSubtickParallelsLine(subtickParallels) .addBatchModeLine(isBatchEnabled(), batchParallels) .addWorkingStatusLine() - .addProgressLine(recipeLogic.getProgress(), recipeLogic.getMaxProgress(), - recipeLogic.getProgressPercent()) + .addProgressLine(recipeLogic) .addOutputLines(recipeLogic.getLastRecipe()); getDefinition().getAdditionalDisplay().accept(this, textList); IDisplayUIMachine.super.addDisplayText(textList); @@ -141,13 +154,14 @@ public List getSubTabs() { @Override public void attachConfigurators(ConfiguratorPanel configuratorPanel) { + IVoidable.attachConfigurators(configuratorPanel, this); if (getDefinition().getRecipeModifier() instanceof RecipeModifierList list && Arrays.stream(list.getModifiers()) .anyMatch(modifier -> modifier == GTRecipeModifiers.BATCH_MODE)) { configuratorPanel.attachConfigurators(new IFancyConfiguratorButton.Toggle( GuiTextures.BUTTON_BATCH.getSubTexture(0, 0, 1, 0.5), GuiTextures.BUTTON_BATCH.getSubTexture(0, 0.5, 1, 0.5), this::isBatchEnabled, - (cd, p) -> batchEnabled = p) + (cd, p) -> setBatchEnabled(p)) .setTooltipsSupplier( p -> List.of( Component.translatable("gtceu.machine.batch_" + (p ? "enabled" : "disabled"))))); diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java index 2d44526cbde..11084de0f5d 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/WorkableMultiblockMachine.java @@ -1,5 +1,6 @@ package com.gregtechceu.gtceu.api.machine.multiblock; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.block.property.GTBlockStateProperties; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; @@ -9,6 +10,7 @@ import com.gregtechceu.gtceu.api.machine.feature.IMufflableMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IWorkableMultiController; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; import com.gregtechceu.gtceu.api.machine.trait.MachineTrait; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; @@ -50,7 +52,7 @@ public abstract class WorkableMultiblockMachine extends MultiblockControllerMach @DescSynced public final RecipeLogic recipeLogic; @Getter - private final GTRecipeType[] recipeTypes; + private GTRecipeType[] recipeTypes; @Getter @Setter @Persisted @@ -70,6 +72,11 @@ public abstract class WorkableMultiblockMachine extends MultiblockControllerMach @Getter protected LongSet activeBlocks; + @Getter + @Persisted + @DescSynced + protected VoidingMode voidingMode = VoidingMode.VOID_NONE; + public WorkableMultiblockMachine(IMachineBlockEntity holder, Object... args) { super(holder); this.recipeTypes = getDefinition().getRecipeTypes(); @@ -230,8 +237,8 @@ public void notifyStatusChanged(RecipeLogic.Status oldStatus, RecipeLogic.Status } for (IMultiPart part : getParts()) { MachineRenderState state = part.self().getRenderState(); - if (state.hasProperty(RecipeLogic.STATUS_PROPERTY)) { - part.self().setRenderState(state.setValue(RecipeLogic.STATUS_PROPERTY, newStatus)); + if (state.hasProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS)) { + part.self().setRenderState(state.setValue(GTMachineModelProperties.RECIPE_LOGIC_STATUS, newStatus)); } } } @@ -289,6 +296,35 @@ public void setWorkingEnabled(boolean isWorkingAllowed) { @NotNull public GTRecipeType getRecipeType() { + if (activeRecipeType >= recipeTypes.length) { + GTCEu.LOGGER.warn("Preventing crash from bad recipe type index!"); + activeRecipeType = recipeTypes.length - 1; + } return recipeTypes[activeRecipeType]; } + + // Recipe compat + public void setRecipeType(@NotNull GTRecipeType type) { + int recipeIndex = -1; + for (int i = 0; i < recipeTypes.length; i++) { + if (type.equals(recipeTypes[i])) { + recipeIndex = i; + break; + } + } + if (recipeIndex == -1) { + var newer = new GTRecipeType[recipeTypes.length + 1]; + System.arraycopy(recipeTypes, 0, newer, 0, recipeTypes.length); + newer[recipeTypes.length] = type; + recipeTypes = newer; + recipeIndex = recipeTypes.length - 1; + } + setActiveRecipeType(recipeIndex); + } + + @Override + public void setVoidingMode(VoidingMode mode) { + voidingMode = mode; + getRecipeLogic().updateTickSubscription(); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java index c94aa7a7771..54428759c09 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/multiblock/part/MultiblockPartMachine.java @@ -6,16 +6,20 @@ import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.IRecipeHandlerTrait; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.client.model.machine.MachineRenderState; import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; +import com.lowdragmc.lowdraglib.syncdata.annotation.RequireRerender; import com.lowdragmc.lowdraglib.syncdata.annotation.UpdateListener; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.state.BlockState; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; @@ -35,6 +39,7 @@ public class MultiblockPartMachine extends MetaMachine implements IMultiPart { MetaMachine.MANAGED_FIELD_HOLDER); @DescSynced + @RequireRerender @UpdateListener(methodName = "onControllersUpdated") protected final Set controllerPositions = new ObjectOpenHashSet<>(8); protected final SortedSet controllers = new ReferenceLinkedOpenHashSet<>(8); @@ -138,8 +143,8 @@ public void removedFromController(IMultiController controller) { if (controllers.isEmpty()) { MachineRenderState renderState = getRenderState(); - if (renderState.hasProperty(IMultiController.IS_FORMED_PROPERTY)) { - setRenderState(renderState.setValue(IMultiController.IS_FORMED_PROPERTY, false)); + if (renderState.hasProperty(GTMachineModelProperties.IS_FORMED)) { + setRenderState(renderState.setValue(GTMachineModelProperties.IS_FORMED, false)); } } } @@ -151,8 +156,22 @@ public void addedToController(IMultiController controller) { controllers.add(controller); MachineRenderState renderState = getRenderState(); - if (renderState.hasProperty(IMultiController.IS_FORMED_PROPERTY)) { - setRenderState(renderState.setValue(IMultiController.IS_FORMED_PROPERTY, true)); + if (renderState.hasProperty(GTMachineModelProperties.IS_FORMED)) { + setRenderState(renderState.setValue(GTMachineModelProperties.IS_FORMED, true)); } } + + @Override + public boolean replacePartModelWhenFormed() { + var renderState = getRenderState(); + return renderState.hasProperty(GTMachineModelProperties.IS_FORMED) && + renderState.getValue(GTMachineModelProperties.IS_FORMED); + } + + @Override + @Nullable + public BlockState getFormedAppearance(BlockState sourceState, BlockPos sourcePos, Direction side) { + if (!replacePartModelWhenFormed()) return null; + return IMultiPart.super.getFormedAppearance(sourceState, sourcePos, side); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/property/GTMachineModelProperties.java b/src/main/java/com/gregtechceu/gtceu/api/machine/property/GTMachineModelProperties.java new file mode 100644 index 00000000000..883e9b7b82b --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/property/GTMachineModelProperties.java @@ -0,0 +1,44 @@ +package com.gregtechceu.gtceu.api.machine.property; + +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; +import com.gregtechceu.gtceu.common.machine.electric.ChargerMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.part.DiodePartMachine; + +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; + +import lombok.experimental.UtilityClass; + +// spotless:off +@UtilityClass +public class GTMachineModelProperties { + + // Generic properties + public static final BooleanProperty IS_PAINTED = BooleanProperty.create("is_painted"); + public static final BooleanProperty IS_FORMED = BooleanProperty.create("is_formed"); + public static final BooleanProperty IS_TAPED = BooleanProperty.create("taped"); + + // Recipe-related properties + public static final EnumProperty RECIPE_LOGIC_STATUS = EnumProperty.create("recipe_logic_status", RecipeLogic.Status.class); + public static final BooleanProperty IS_WORKING_ENABLED = BooleanProperty.create("working_enabled"); + public static final BooleanProperty IS_ACTIVE = BooleanProperty.create("active"); + + // Machine-specific properties + public static final BooleanProperty IS_STEEL_MACHINE = BooleanProperty.create("steel"); + public static final EnumProperty VENT_DIRECTION = EnumProperty.create("steam_vent", RelativeDirection.class); + + public static final EnumProperty CHARGER_STATE = EnumProperty.create("charger_state", ChargerMachine.State.class); + public static final BooleanProperty IS_FE_TO_EU = BooleanProperty.create("fe_to_eu"); + public static final BooleanProperty IS_TRANSFORM_UP = BooleanProperty.create("transform_up"); + public static final EnumProperty DIODE_AMP_MODE = EnumProperty.create("amp_mode", DiodePartMachine.AmpMode.class); + + public static final BooleanProperty IS_HPCA_PART_DAMAGED = BooleanProperty.create("hpca_part_damaged"); + public static final BooleanProperty IS_RANDOM_TICK_MODE = BooleanProperty.create("random_tick_mode"); + + public static final BooleanProperty HAS_ROTOR = BooleanProperty.create("has_rotor"); + public static final BooleanProperty IS_ROTOR_SPINNING = BooleanProperty.create("rotor_spinning"); + public static final BooleanProperty IS_EMISSIVE_ROTOR = BooleanProperty.create("emissive_rotor"); + +} +// spotless:on diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java index 94e99e60806..c28d46a94de 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SimpleSteamMachine.java @@ -11,6 +11,7 @@ import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.IExhaustVentMachine; import com.gregtechceu.gtceu.api.machine.feature.IUIMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; @@ -60,9 +61,9 @@ public SimpleSteamMachine(IMachineBlockEntity holder, boolean isHighPressure, Ob this.exportItems = createExportItemHandler(args); MachineRenderState renderState = getRenderState(); - if (renderState.hasProperty(IExhaustVentMachine.VENT_DIRECTION_PROPERTY)) { + if (renderState.hasProperty(GTMachineModelProperties.VENT_DIRECTION)) { // outputFacing will always be opposite the front facing on init - setRenderState(renderState.setValue(VENT_DIRECTION_PROPERTY, RelativeDirection.BACK)); + setRenderState(renderState.setValue(GTMachineModelProperties.VENT_DIRECTION, RelativeDirection.BACK)); } } @@ -118,14 +119,14 @@ public float getVentingDamage() { public void updateModelVentDirection() { MachineRenderState renderState = getRenderState(); - if (renderState.hasProperty(IExhaustVentMachine.VENT_DIRECTION_PROPERTY)) { + if (renderState.hasProperty(GTMachineModelProperties.VENT_DIRECTION)) { Direction upwardsDir = getUpwardsFacing(); // the up facing is already rotated if extended facing is enabled for the machine if (getFrontFacing() == Direction.UP && !allowExtendedFacing()) { upwardsDir = upwardsDir.getOpposite(); } var relative = RelativeDirection.findRelativeOf(getFrontFacing(), getVentingDirection(), upwardsDir); - setRenderState(renderState.setValue(VENT_DIRECTION_PROPERTY, relative)); + setRenderState(renderState.setValue(GTMachineModelProperties.VENT_DIRECTION, relative)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamBoilerMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamBoilerMachine.java index 032bcb57bfa..b42ad55dd79 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamBoilerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamBoilerMachine.java @@ -10,6 +10,7 @@ import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IDataInfoProvider; import com.gregtechceu.gtceu.api.machine.feature.IExplosionMachine; +import com.gregtechceu.gtceu.api.machine.feature.IInteractedMachine; import com.gregtechceu.gtceu.api.machine.feature.IUIMachine; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; @@ -42,11 +43,15 @@ import net.minecraft.sounds.SoundSource; import net.minecraft.util.RandomSource; import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; import net.minecraft.world.ItemInteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.neoforged.neoforge.fluids.FluidType; +import net.neoforged.neoforge.fluids.FluidUtil; import net.neoforged.neoforge.fluids.capability.IFluidHandler.FluidAction; import lombok.Getter; @@ -58,7 +63,8 @@ import java.util.List; public abstract class SteamBoilerMachine extends SteamWorkableMachine - implements IUIMachine, IExplosionMachine, IDataInfoProvider { + implements IUIMachine, IExplosionMachine, IDataInfoProvider, + IInteractedMachine { protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(SteamBoilerMachine.class, SteamWorkableMachine.MANAGED_FIELD_HOLDER); @@ -191,7 +197,7 @@ protected void updateCurrentTemperature() { if (getOffsetTimer() % 10 == 0) { if (currentTemperature >= 100) { - int fillAmount = (int) (getBaseSteamOutput() * ((float) currentTemperature / getMaxTemperature()) / 2); + int fillAmount = (int) getTotalSteamOutput(); boolean hasDrainedWater = !waterTank.drainInternal(1, FluidAction.EXECUTE).isEmpty(); var filledSteam = 0L; if (hasDrainedWater) { @@ -252,6 +258,12 @@ private double getTemperaturePercent() { protected abstract long getBaseSteamOutput(); + /** Returns the current total steam output every 10 ticks. */ + public long getTotalSteamOutput() { + if (currentTemperature < 100) return 0; + return (long) (getBaseSteamOutput() * ((float) currentTemperature / getMaxTemperature()) / 2); + } + /** * Recipe Modifier for Steam Boiler Machines - can be used as a valid {@link RecipeModifier} *

@@ -298,6 +310,17 @@ protected ItemInteractionResult onSoftMalletClick(Player playerIn, InteractionHa return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; } + @Override + public InteractionResult onUse(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, + BlockHitResult hit) { + if (!isRemote()) { + if (FluidUtil.interactWithFluidHandler(player, hand, waterTank)) { + return InteractionResult.SUCCESS; + } + } + return IInteractedMachine.super.onUse(state, world, pos, player, hand, hit); + } + ////////////////////////////////////// // ********** GUI ***********// ////////////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java index 42465f9801e..8b78aa5a27d 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamEnergyRecipeHandler.java @@ -16,7 +16,6 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -import java.util.Collections; import java.util.List; public class SteamEnergyRecipeHandler implements IRecipeHandler { @@ -31,6 +30,7 @@ public SteamEnergyRecipeHandler(NotifiableFluidTank steamTank, double conversion @Override public List handleRecipeInner(IO io, GTRecipe recipe, List left, boolean simulate) { + // <<<<<<< HEAD long eut = left.stream().reduce(EnergyStack.EMPTY, EnergyStack::sum).getTotalEU(); int totalSteam = GTMath.saturatedCast((long) Math.ceil(eut * conversionRate)); if (totalSteam > 0) { @@ -42,8 +42,32 @@ public List handleRecipeInner(IO io, GTRecipe recipe, List 0) { + // var steam = io == IO.IN ? FluidIngredient.of(GTMaterials.Steam.getFluidTag(), totalSteam) : + // FluidIngredient.of(GTMaterials.Steam.getFluid(totalSteam)); + // var list = new ArrayList(); + // list.add(steam); + // var leftSteam = steamTank.handleRecipeInner(io, recipe, list, simulate); + // if (leftSteam == null || leftSteam.isEmpty()) { + // it.remove(); + // } else { + // totalEU = (long) (leftSteam.get(0).getAmount() / conversionRate); + // it.set(new EnergyStack(totalEU)); + // } + // } + // >>>>>>> v7.1.0-1.20.1 } - return eut <= 0 ? null : Collections.singletonList(new EnergyStack(eut)); + return left.isEmpty() ? null : left; } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamMachine.java b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamMachine.java index 67c281aea90..0d774fe4fad 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/steam/SteamMachine.java @@ -3,6 +3,7 @@ import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.ITieredMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.data.material.GTMaterials; @@ -18,7 +19,7 @@ public abstract class SteamMachine extends MetaMachine implements ITieredMachine protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(SteamMachine.class, MetaMachine.MANAGED_FIELD_HOLDER); - public static final BooleanProperty STEEL_PROPERTY = BooleanProperty.create("steel"); + public static final BooleanProperty STEEL_PROPERTY = GTMachineModelProperties.IS_STEEL_MACHINE; @Getter public final boolean isHighPressure; diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java index 5c659270d0e..c92b8ad93b4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableFluidTank.java @@ -115,37 +115,31 @@ public List handleRecipeInner(IO io, GTRecipe recipe, List FluidStack[] visited = new FluidStack[storages.length]; for (var it = left.listIterator(); it.hasNext();) { var ingredient = it.next(); - if (ingredient.ingredient().hasNoFluids()) { + if (!(ingredient.ingredient() instanceof IntProviderFluidIngredient) && + ingredient.ingredient().hasNoFluids()) { it.remove(); continue; } FluidStack[] fluids; - int amount; - if (io == IO.OUT && ingredient.ingredient() instanceof IntProviderFluidIngredient provider) { + if (ingredient.ingredient() instanceof IntProviderFluidIngredient provider) { provider.setFluidStacks(null); provider.setSampledCount(-1); if (simulate) { fluids = new FluidStack[] { provider.getMaxSizeStack() }; - amount = provider.getCountProvider().getMaxValue(); } else { - fluids = provider.getStacks(); - if (fluids.length == 0 || fluids[0].isEmpty()) { - it.remove(); - continue; - } - amount = fluids[0].getAmount(); + fluids = provider.getFluidStacks(); } } else { fluids = ingredient.getFluids(); - if (fluids.length == 0 || fluids[0].isEmpty()) { - it.remove(); - continue; - } - amount = ingredient.amount(); } + if (fluids.length == 0 || fluids[0].isEmpty()) { + it.remove(); + continue; + } + int amount = fluids[0].getAmount(); if (io == IO.OUT && !allowSameFluids) { CustomFluidTank existing = null; @@ -182,7 +176,7 @@ public List handleRecipeInner(IO io, GTRecipe recipe, List if (io == IO.IN) { if (current.isEmpty()) continue; - if (ingredient.test(current)) { + if (ingredient.ingredient().test(current)) { var drained = storages[tank].drain(Math.min(count, amount), action); if (!drained.isEmpty()) { visited[tank] = drained.copyWithAmount(count - drained.getAmount()); @@ -230,7 +224,7 @@ public List handleRecipeInner(IO io, GTRecipe recipe, List @Override public boolean test(SizedFluidIngredient ingredient) { - return !this.isLocked() || ingredient.test(this.lockedFluid.getFluid()); + return !this.isLocked() || ingredient.ingredient().test(this.lockedFluid.getFluid()); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java index 76127c76e29..847be2684b9 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/NotifiableItemStackHandler.java @@ -11,6 +11,7 @@ import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.gregtechceu.gtceu.utils.GTTransferUtils; +import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; @@ -117,7 +118,7 @@ public static List handleRecipe(IO io, GTRecipe recipe, List handleRecipe(IO io, GTRecipe recipe, List outputStorageLimit) { + it.remove(); + continue; + } else if (simulate) { + amount = provider.getCountProvider().getMaxValue(); + } else { + amount = Math.min(output.getCount(), outputStorageLimit); } - } - if (provider.getCountProvider().getMinValue() > outputStorageLimit) { - it.remove(); - continue; - } else if (simulate) { - amount = provider.getCountProvider().getMaxValue(); - } else { - amount = Math.min(output.getCount(), outputStorageLimit); } } else { items = ingredient.getItems(); @@ -164,7 +167,7 @@ public static List handleRecipe(IO io, GTRecipe recipe, List handleRecipe(IO io, GTRecipe recipe, List cap) { return getHandlerMap().getOrDefault(cap, Collections.emptyList()); } + public @NotNull Set> getCapabilities() { + return getHandlerMap().keySet(); + } + + /** + * @return whether any of the capabilities in this RHL should bypass distinct checks + */ + public boolean doesCapabilityBypassDistinct() { + for (var capability : getCapabilities()) { + if (capability.shouldBypassDistinct()) return true; + } + return false; + } + public boolean isValid(IO extIO) { if (this == NO_DATA || handlerIO == IO.NONE) return false; return (extIO == IO.BOTH || handlerIO == IO.BOTH || extIO == handlerIO); @@ -182,6 +196,14 @@ public Map, List> handleRecipe(IO io, GTRecipe recip return copy; } + public List> getHandlersFlat() { + List> handlerList = new ArrayList<>(); + for (var handlerEntry : getHandlerMap().entrySet()) { + handlerList.addAll(handlerEntry.getValue()); + } + return handlerList; + } + private record Subscription(List subs) implements ISubscription { @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java index ff7725ed793..bac21d5803b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogic.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.IWorkable; +import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.gui.GuiTextures; @@ -9,13 +10,16 @@ import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; +import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.recipe.ActionResult; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.api.sound.AutoReleasedSound; -import com.gregtechceu.gtceu.config.ConfigHolder; +import com.gregtechceu.gtceu.common.cover.MachineControllerCover; import com.gregtechceu.gtceu.core.MixinHelpers; +import com.gregtechceu.gtceu.utils.GTMath; import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; import com.lowdragmc.lowdraglib.syncdata.IEnhancedManaged; @@ -60,8 +64,7 @@ public enum Status implements StringRepresentable { } } - public static final EnumProperty STATUS_PROPERTY = EnumProperty.create("recipe_logic_status", - RecipeLogic.Status.class); + public static final EnumProperty STATUS_PROPERTY = GTMachineModelProperties.RECIPE_LOGIC_STATUS; public static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(RecipeLogic.class); public final IRecipeLogicMachine machine; @@ -106,17 +109,22 @@ public enum Status implements StringRepresentable { @Persisted @Getter @Setter + @DescSynced protected int progress; @Getter @Persisted + @DescSynced protected int duration; @Getter(onMethod_ = @VisibleForTesting) protected boolean recipeDirty; @Persisted @Getter protected long totalContinuousRunningTime; + protected int runAttempt = 0; + protected int runDelay = 0; @Persisted @Setter + @Getter protected boolean suspendAfterFinish = false; @Getter protected final Map, Object2IntMap> chanceCaches = makeChanceCaches(); @@ -189,7 +197,11 @@ public void serverTick() { if (!isSuspend()) { if (!isIdle() && lastRecipe != null) { if (progress < duration) { - handleRecipeWorking(); + if (runDelay > 0) { + runDelay--; + } else { + handleRecipeWorking(); + } } if (progress >= duration) { onRecipeFinish(); @@ -263,22 +275,44 @@ public void handleRecipeWorking() { totalContinuousRunningTime++; } else { setWaiting(handleTick.reason()); + + // Machine isn't getting enough power, suspend after 5 attempts. + if (handleTick.io() == IO.IN && handleTick.capability() == EURecipeCapability.CAP) { + runAttempt++; + runAttempt = (int) GTMath.clamp(runAttempt, 0, 5); + if (runAttempt == 5) { + boolean preventPowerFail = false; + if (machine.self() instanceof IMultiController) { + var covers = machine.self().getCoverContainer().getCovers(); + for (var cover : covers) { + if (cover instanceof MachineControllerCover mcc) { + if (mcc.preventPowerFail()) { + preventPowerFail = true; + break; + } + } + } + } + + if (machine.self() instanceof IMultiController && !preventPowerFail) { + runAttempt = 0; + setStatus(Status.SUSPEND); + } + } + runDelay = runAttempt * 60; + } } } else { setWaiting(conditionResult.reason()); } - if (isWaiting()) { + if (isWaiting() || isSuspend()) { regressRecipe(); } } protected void regressRecipe() { if (progress > 0 && machine.regressWhenWaiting()) { - if (ConfigHolder.INSTANCE.machines.recipeProgressLowEnergy) { - this.progress = 1; - } else { - this.progress = Math.max(1, progress - 2); - } + this.progress = 1; } } @@ -360,9 +394,13 @@ public void setStatus(Status status) { if (this.status == Status.WORKING) { this.totalContinuousRunningTime = 0; } + if ((status == Status.WAITING || status == Status.SUSPEND) && suspendAfterFinish) { + status = Status.SUSPEND; + suspendAfterFinish = false; + } machine.notifyStatusChanged(this.status, status); this.status = status; - setRenderState(getRenderState().setValue(STATUS_PROPERTY, status)); + setRenderState(getRenderState().setValue(GTMachineModelProperties.RECIPE_LOGIC_STATUS, status)); updateTickSubscription(); if (this.status != Status.WAITING) { waitingReason = null; @@ -401,14 +439,13 @@ public boolean isSuspend() { } public boolean isWorkingEnabled() { - return !isSuspend(); + return !isSuspend() && !isSuspendAfterFinish(); } @Override public void setWorkingEnabled(boolean isWorkingAllowed) { - if (!isWorkingAllowed) { - setStatus(Status.SUSPEND); - } else { + setSuspendAfterFinish(!isWorkingAllowed); + if (isWorkingAllowed) { if (lastRecipe != null && duration > 0) { setStatus(Status.WORKING); } else { @@ -426,11 +463,40 @@ public boolean isActive() { return isWorking() || isWaiting() || (isSuspend() && isActive); } + public boolean hasCustomProgressLine() { + return false; + } + + /** + * Show the customized progress line instead of the regular duration progress time in the machine display. + *

+ * Must override and return {@code true} in {@link #hasCustomProgressLine()}. + * + * @return the customized progress line + */ + public @Nullable Component getCustomProgressLine() { + return null; + } + public void onRecipeFinish() { machine.afterWorking(); if (lastRecipe != null) { + runAttempt = 0; + runDelay = 0; consecutiveRecipes++; handleRecipeIO(lastRecipe, IO.OUT); + // Don't ready the next recipe after finish if suspend is set + // so that the modifiers won't be applied until re-starting. + if (suspendAfterFinish) { + setStatus(Status.SUSPEND); + consecutiveRecipes = 0; + progress = 0; + duration = 0; + isActive = false; + // Force a recipe recheck. + lastRecipe = null; + return; + } if (machine.alwaysTryModifyRecipe()) { if (lastOriginRecipe != null) { var modified = machine.fullModifyRecipe(lastOriginRecipe.copy()); @@ -445,14 +511,11 @@ public void onRecipeFinish() { } // try it again var recipeCheck = checkRecipe(lastRecipe); - if (!recipeDirty && !suspendAfterFinish && recipeCheck.isSuccess()) { + if (!recipeDirty && recipeCheck.isSuccess()) { setupRecipe(lastRecipe); } else { - if (suspendAfterFinish) { - setStatus(Status.SUSPEND); - suspendAfterFinish = false; - } else { - setStatus(Status.IDLE); + setStatus(Status.IDLE); + if (recipeCheck.io() != IO.IN || recipeCheck.capability() == EURecipeCapability.CAP) { waitingReason = recipeCheck.reason(); } consecutiveRecipes = 0; diff --git a/src/main/java/com/gregtechceu/gtceu/api/material/material/Material.java b/src/main/java/com/gregtechceu/gtceu/api/material/material/Material.java index 834cfd36a5e..75bc7a22455 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/material/material/Material.java +++ b/src/main/java/com/gregtechceu/gtceu/api/material/material/Material.java @@ -25,9 +25,11 @@ import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; +import net.minecraft.world.item.enchantment.Enchantment; import net.minecraft.world.level.material.Fluid; import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient; @@ -79,6 +81,7 @@ public class Material { /** * Chemical formula of this material */ + @Getter private String chemicalFormula; /** @@ -108,10 +111,6 @@ private String calculateChemicalFormula() { return ""; } - public String getChemicalFormula() { - return chemicalFormula; - } - public Material setFormula(String formula) { return setFormula(formula, true); } @@ -165,7 +164,8 @@ public String getModid() { * @return if the material should have recipes autogenerated */ public boolean shouldGenerateRecipesFor(@NotNull TagPrefix prefix) { - return !this.hasFlag(MaterialFlags.DISABLE_MATERIAL_RECIPES) && !ChemicalHelper.get(prefix, this).isEmpty(); + return (!this.hasFlag(MaterialFlags.NO_UNIFICATION) || + !this.hasFlag(MaterialFlags.DISABLE_MATERIAL_RECIPES)) && !ChemicalHelper.get(prefix, this).isEmpty(); } public void addFlags(MaterialFlag... flags) { @@ -513,13 +513,17 @@ public MaterialStack multiply(long amount) { } public boolean hasProperty(PropertyKey key) { - return getProperty(key) != null; + return properties.hasProperty(key); } public T getProperty(PropertyKey key) { return properties.getProperty(key); } + public void removeProperty(PropertyKey key) { + properties.removeProperty(key); + } + public void setProperty(PropertyKey key, IMaterialProperty property) { if (GTCEuAPI.materialManager.isFrozen()) { throw new IllegalStateException("Cannot add properties to a Material when registry is frozen!"); @@ -569,11 +573,15 @@ public static class Builder { private final MaterialInfo materialInfo; private final MaterialProperties properties; private final MaterialFlags flags; - private Set ignoredTagPrefixes = null; + private Set ignoredTagPrefixes = null; private final List> itemTags = new ArrayList<>(); + /* + * Temporary data used to determine the final material formula tooltip. + */ private String formula = null; + private boolean formatFormula = true; /* * The temporary list of components for this Material. @@ -582,7 +590,7 @@ public static class Builder { private List compositionSupplier; /* - * Temporary value to use to determine how to calculate default RGB + * Temporary value to use to determine how to calculate default RGB. */ private boolean averageRGB = false; @@ -603,21 +611,11 @@ public Builder(ResourceLocation resourceLocation) { flags = new MaterialFlags(); } - public Builder customTags(TagKey key) { - this.itemTags.add(key); - return this; - } - /* * Material Types */ - /** - * Add a {@link FluidProperty} to this Material.
- * Will be created as a {@link FluidStorageKeys#LIQUID}, without a Fluid Block. - * - * @throws IllegalArgumentException If a {@link FluidProperty} has already been added to this Material. - */ + /** @see #liquid */ public Builder fluid() { fluid(FluidStorageKeys.LIQUID, new FluidBuilder()); return this; @@ -625,9 +623,11 @@ public Builder fluid() { /** * Add a {@link FluidProperty} to this Material.
- * Will be created with the specified state a with standard {@link FluidBuilder} defaults. - *

+ * Will be created with the specified state and with standard {@link FluidBuilder} defaults.
* Can be called multiple times to add multiple fluids. + *
+ *
+ * See {@link #fluid(FluidStorageKey, FluidBuilder)} for setting other values. */ public Builder fluid(@NotNull FluidStorageKey key, @NotNull FluidState state) { return fluid(key, new FluidBuilder().state(state)); @@ -635,8 +635,9 @@ public Builder fluid(@NotNull FluidStorageKey key, @NotNull FluidState state) { /** * Add a {@link FluidProperty} to this Material.
- *

* Can be called multiple times to add multiple fluids. + * + * @see FluidBuilder */ public Builder fluid(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder) { properties.ensureSet(PropertyKey.FLUID); @@ -646,9 +647,21 @@ public Builder fluid(@NotNull FluidStorageKey key, @NotNull FluidBuilder builder } /** - * Add a liquid for this material. + * Add a liquid for this Material. + *
+ *
+ * Created without a Fluid Block.
+ * Temperature will default to: + *

    + *
  • The EBF temperature of this Material, if it has a {@link BlastProperty} + *
  • 1200K, if this Material has a {@link DustProperty} + *
  • 293K otherwise + *
+ *
+ * See {@link #liquid(FluidBuilder)} for setting your own value(s). * - * @see #fluid(FluidStorageKey, FluidState) + * @throws IllegalArgumentException If a {@link FluidStorageKeys#LIQUID LIQUID} has + * already been added to this Material. */ public Builder liquid() { return fluid(FluidStorageKeys.LIQUID, FluidState.LIQUID); @@ -656,21 +669,45 @@ public Builder liquid() { /** * Add a liquid for this material. + * + * @throws IllegalArgumentException If a {@link FluidStorageKeys#LIQUID LIQUID} has + * already been added to this Material. * - * @see #fluid(FluidStorageKey, FluidState) + * @see FluidBuilder */ public Builder liquid(@NotNull FluidBuilder builder) { return fluid(FluidStorageKeys.LIQUID, builder.state(FluidState.LIQUID)); } + /** + * Add a liquid for this Material.
+ * Created without a Fluid Block. + *
+ *
+ * See {@link #liquid(FluidBuilder)} for setting your own value(s). + * + * @throws IllegalArgumentException If a {@link FluidStorageKeys#LIQUID LIQUID} has + * already been added to this Material. + */ public Builder liquid(int temp) { return liquid(new FluidBuilder().temperature(temp)); } /** - * Add a plasma for this material. + * Add a plasma for this Material. + *
+ *
+ * Temperature will default to: + *
    + *
  • 10,000K + the EBF temperature of this Material, if it has a {@link BlastProperty} + *
  • 10,000K + the temperature of another fluid for this Material (liquid, then gas) + *
  • 10,000K otherwise + *
+ *
+ * See {@link #plasma(FluidBuilder)} for setting your own value(s). * - * @see #fluid(FluidStorageKey, FluidState) + * @throws IllegalArgumentException If a {@link FluidStorageKeys#PLASMA PLASMA} has + * already been added to this Material. */ public Builder plasma() { return fluid(FluidStorageKeys.PLASMA, FluidState.PLASMA); @@ -678,21 +715,43 @@ public Builder plasma() { /** * Add a plasma for this material. + * + * @throws IllegalArgumentException If a {@link FluidStorageKeys#PLASMA PLASMA} has + * already been added to this Material. * - * @see #fluid(FluidStorageKey, FluidState) + * @see FluidBuilder */ public Builder plasma(@NotNull FluidBuilder builder) { return fluid(FluidStorageKeys.PLASMA, builder.state(FluidState.PLASMA)); } + /** + * Add a liquid for this Material. + *
+ *
+ * See {@link #plasma(FluidBuilder)} for setting your own value(s). + * + * @throws IllegalArgumentException If a {@link FluidStorageKeys#PLASMA PLASMA} has + * already been added to this Material. + */ public Builder plasma(int temp) { return plasma(new FluidBuilder().temperature(temp)); } /** - * Add a gas for this material. + * Add a gas for this Material. + *
+ *
+ * Temperature will default to: + *
    + *
  • 100K + the EBF temperature of this Material, if it has a {@link BlastProperty} + *
  • 293K otherwise + *
+ *
+ * See {@link #gas(FluidBuilder)} for setting your own value(s). * - * @see #fluid(FluidStorageKey, FluidState) + * @throws IllegalArgumentException If a {@link FluidStorageKeys#GAS GAS} has + * already been added to this Material. */ public Builder gas() { return fluid(FluidStorageKeys.GAS, FluidState.GAS); @@ -700,20 +759,37 @@ public Builder gas() { /** * Add a gas for this material. + * + * @throws IllegalArgumentException If a {@link FluidStorageKeys#GAS GAS} has + * already been added to this Material. * - * @see #fluid(FluidStorageKey, FluidState) + * @see FluidBuilder */ public Builder gas(@NotNull FluidBuilder builder) { return fluid(FluidStorageKeys.GAS, builder.state(FluidState.GAS)); } + /** + * Add a gas for this Material. + *
+ *
+ * See {@link #gas(FluidBuilder)} for setting your own value(s). + * + * @throws IllegalArgumentException If a {@link FluidStorageKeys#GAS GAS} has + * already been added to this Material. + */ public Builder gas(int temp) { return gas(new FluidBuilder().temperature(temp)); } /** * Add a {@link DustProperty} to this Material.
- * Will be created with a Harvest Level of 2 and no Burn Time (Furnace Fuel). + *
+ * Sets Harvest Level to 2 if not already set.
+ * Sets Burn Time (Furnace Fuel) to 0 if not already set. + *
+ *
+ * See {@link #dust(int, int)} for setting your own value(s). * * @throws IllegalArgumentException If a {@link DustProperty} has already been added to this Material. */ @@ -724,7 +800,11 @@ public Builder dust() { /** * Add a {@link DustProperty} to this Material.
- * Will be created with no Burn Time (Furnace Fuel). + *
+ * Sets Burn Time (Furnace Fuel) to 0 if not already set. + *
+ *
+ * See {@link #dust(int, int)} for setting your own value(s). * * @param harvestLevel The Harvest Level of this block for Mining.
* If this Material also has a {@link ToolProperty}, this value will @@ -738,9 +818,10 @@ public Builder dust(int harvestLevel) { /** * Add a {@link DustProperty} to this Material. * - * @param harvestLevel The Harvest Level of this block for Mining.
+ * @param harvestLevel The Harvest Level of this block for Mining. 2 will make it require an Iron tool.
* If this Material also has a {@link ToolProperty}, this value will - * also be used to determine the tool's Mining Level. + * also be used to determine the tool's Mining level (-1). So 2 will make the tool harvest + * Diamonds. * @param burnTime The Burn Time (in ticks) of this Material as a Furnace Fuel. * @throws IllegalArgumentException If a {@link DustProperty} has already been added to this Material. */ @@ -751,8 +832,11 @@ public Builder dust(int harvestLevel, int burnTime) { /** * Add a {@link WoodProperty} to this Material.
- * Useful for marking a Material as Wood for various additional behaviors.
- * Will be created with a Harvest Level of 0, and a Burn Time of 300 (Furnace Fuel). + * Useful for marking a Material as Wood for various additional behaviors. + *
+ *
+ * Sets Harvest Level to 2 if not already set.
+ * Sets Burn Time (Furnace Fuel) to 0 if not already set. * * @throws IllegalArgumentException If a {@link DustProperty} has already been added to this Material. */ @@ -762,12 +846,15 @@ public Builder wood() { /** * Add a {@link WoodProperty} to this Material.
- * Useful for marking a Material as Wood for various additional behaviors.
- * Will be created with a Burn Time of 300 (Furnace Fuel). + * Useful for marking a Material as Wood for various additional behaviors. + *
+ *
+ * Sets Burn Time (Furnace Fuel) to 0 if not already set. * - * @param harvestLevel The Harvest Level of this block for Mining.
+ * @param harvestLevel The Harvest Level of this block for Mining. 2 will make it require an Iron tool.
* If this Material also has a {@link ToolProperty}, this value will - * also be used to determine the tool's Mining Level. + * also be used to determine the tool's Mining level (-1). So 2 will make the tool harvest + * Diamonds. * @throws IllegalArgumentException If a {@link DustProperty} has already been added to this Material. */ public Builder wood(int harvestLevel) { @@ -776,7 +863,7 @@ public Builder wood(int harvestLevel) { /** * Add a {@link WoodProperty} to this Material.
- * Useful for marking a Material as Wood for various additional behaviors.
+ * Useful for marking a Material as Wood for various additional behaviors. * * @param harvestLevel The Harvest Level of this block for Mining.
* If this Material also has a {@link ToolProperty}, this value will @@ -792,10 +879,17 @@ public Builder wood(int harvestLevel, int burnTime) { /** * Add an {@link IngotProperty} to this Material.
- * Will be created with a Harvest Level of 2 and no Burn Time (Furnace Fuel).
* Will automatically add a {@link DustProperty} to this Material if it does not already have one. + *
+ *
+ * Sets Harvest Level to 2 if not already set.
+ * Sets Burn Time (Furnace Fuel) to 0 if not already set. + *
+ *
+ * See {@link #ingot(int, int)} for setting your own value(s). * - * @throws IllegalArgumentException If an {@link IngotProperty} has already been added to this Material. + * @throws IllegalArgumentException If a {@link GemProperty} has already been added to this Material, or if + * an {@link IngotProperty} has already been added to this Material. */ public Builder ingot() { properties.ensureSet(PropertyKey.INGOT); @@ -804,15 +898,21 @@ public Builder ingot() { /** * Add an {@link IngotProperty} to this Material.
- * Will be created with no Burn Time (Furnace Fuel).
* Will automatically add a {@link DustProperty} to this Material if it does not already have one. + *
+ *
+ * Sets Burn Time (Furnace Fuel) to 0 if not already set. + *
+ *
+ * See {@link #ingot(int, int)} for setting your own value(s). * - * @param harvestLevel The Harvest Level of this block for Mining. 2 will make it require a iron tool.
+ * @param harvestLevel The Harvest Level of this block for Mining. 2 will make it require an Iron tool.
* If this Material also has a {@link ToolProperty}, this value will * also be used to determine the tool's Mining level (-1). So 2 will make the tool harvest - * diamonds.
+ * Diamonds.
* If this Material already had a Harvest Level defined, it will be overridden. - * @throws IllegalArgumentException If an {@link IngotProperty} has already been added to this Material. + * @throws IllegalArgumentException If a {@link GemProperty} has already been added to this Material, or if + * an {@link IngotProperty} has already been added to this Material. */ public Builder ingot(int harvestLevel) { return ingot(harvestLevel, 0); @@ -822,14 +922,15 @@ public Builder ingot(int harvestLevel) { * Add an {@link IngotProperty} to this Material.
* Will automatically add a {@link DustProperty} to this Material if it does not already have one. * - * @param harvestLevel The Harvest Level of this block for Mining. 2 will make it require a iron tool.
+ * @param harvestLevel The Harvest Level of this block for Mining. 2 will make it require an Iron tool.
* If this Material also has a {@link ToolProperty}, this value will * also be used to determine the tool's Mining level (-1). So 2 will make the tool harvest - * diamonds.
+ * Diamonds.
* If this Material already had a Harvest Level defined, it will be overridden. * @param burnTime The Burn Time (in ticks) of this Material as a Furnace Fuel.
* If this Material already had a Burn Time defined, it will be overridden. - * @throws IllegalArgumentException If an {@link IngotProperty} has already been added to this Material. + * @throws IllegalArgumentException If a {@link GemProperty} has already been added to this Material, or if + * an {@link IngotProperty} has already been added to this Material. */ public Builder ingot(int harvestLevel, int burnTime) { DustProperty prop = properties.getProperty(PropertyKey.DUST); @@ -844,10 +945,17 @@ public Builder ingot(int harvestLevel, int burnTime) { /** * Add a {@link GemProperty} to this Material.
- * Will be created with a Harvest Level of 2 and no Burn Time (Furnace Fuel).
* Will automatically add a {@link DustProperty} to this Material if it does not already have one. + *
+ *
+ * Sets Harvest Level to 2 if not already set.
+ * Sets Burn Time (Furnace Fuel) to 0 if not already set. + *
+ *
+ * See {@link #gem(int, int)} for setting your own value(s). * - * @throws IllegalArgumentException If a {@link GemProperty} has already been added to this Material. + * @throws IllegalArgumentException If an {@link IngotProperty} has already been added to this Material, or if + * a {@link GemProperty} has already been added to this Material. */ public Builder gem() { properties.ensureSet(PropertyKey.GEM); @@ -856,14 +964,21 @@ public Builder gem() { /** * Add a {@link GemProperty} to this Material.
- * Will be created with no Burn Time (Furnace Fuel).
* Will automatically add a {@link DustProperty} to this Material if it does not already have one. + *
+ *
+ * Sets Burn Time (Furnace Fuel) to 0 if not already set. + *
+ *
+ * See {@link #gem(int, int)} for setting your own value(s). * - * @param harvestLevel The Harvest Level of this block for Mining.
+ * @param harvestLevel The Harvest Level of this block for Mining. 2 will make it require an Iron tool.
* If this Material also has a {@link ToolProperty}, this value will - * also be used to determine the tool's Mining level.
+ * also be used to determine the tool's Mining level (-1). So 2 will make the tool harvest + * Diamonds.
* If this Material already had a Harvest Level defined, it will be overridden. - * @throws IllegalArgumentException If a {@link GemProperty} has already been added to this Material. + * @throws IllegalArgumentException If an {@link IngotProperty} has already been added to this Material, or if + * a {@link GemProperty} has already been added to this Material. */ public Builder gem(int harvestLevel) { return gem(harvestLevel, 0); @@ -879,6 +994,8 @@ public Builder gem(int harvestLevel) { * If this Material already had a Harvest Level defined, it will be overridden. * @param burnTime The Burn Time (in ticks) of this Material as a Furnace Fuel.
* If this Material already had a Burn Time defined, it will be overridden. + * @throws IllegalArgumentException If an {@link IngotProperty} has already been added to this Material, or if + * a {@link GemProperty} has already been added to this Material. */ public Builder gem(int harvestLevel, int burnTime) { DustProperty prop = properties.getProperty(PropertyKey.DUST); @@ -893,8 +1010,14 @@ public Builder gem(int harvestLevel, int burnTime) { /** * Add a {@link PolymerProperty} to this Material.
- * Will be created with a Harvest Level of 2 and no Burn Time (Furnace Fuel).
* Will automatically add a {@link DustProperty} to this Material if it does not already have one. + *
+ *
+ * Sets Harvest Level to 2 if not already set.
+ * Sets Burn Time (Furnace Fuel) to 0 if not already set. + *
+ *
+ * See {@link #polymer(int, int)} for setting your own value(s). * * @throws IllegalArgumentException If an {@link PolymerProperty} has already been added to this Material. */ @@ -906,7 +1029,12 @@ public Builder polymer() { /** * Add a {@link PolymerProperty} to this Material.
* Will automatically add a {@link DustProperty} to this Material if it does not already have one. - * Will have a burn time of 0 + *
+ *
+ * Sets Burn Time (Furnace Fuel) to 0 if not already set. + *
+ *
+ * See {@link #polymer(int, int)} for setting your own value(s). * * @param harvestLevel The Harvest Level of this block for Mining.
* If this Material also has a {@link ToolProperty}, this value will @@ -915,13 +1043,36 @@ public Builder polymer() { * @throws IllegalArgumentException If an {@link PolymerProperty} has already been added to this Material. */ public Builder polymer(int harvestLevel) { + return polymer(harvestLevel, 0); + } + + /** + * Add a {@link PolymerProperty} to this Material.
+ * Will automatically add a {@link DustProperty} to this Material if it does not already have one. + * + * @param harvestLevel The Harvest Level of this block for Mining.
+ * If this Material also has a {@link ToolProperty}, this value will + * also be used to determine the tool's Mining level.
+ * If this Material already had a Harvest Level defined, it will be overridden. + * @param burnTime The Burn Time (in ticks) of this Material as a Furnace Fuel.
+ * If this Material already had a Burn Time defined, it will be overridden. + * @throws IllegalArgumentException If an {@link PolymerProperty} has already been added to this Material. + */ + public Builder polymer(int harvestLevel, int burnTime) { DustProperty prop = properties.getProperty(PropertyKey.DUST); - if (prop == null) dust(harvestLevel, 0); + if (prop == null) dust(harvestLevel, burnTime); else if (prop.getHarvestLevel() == 2) prop.setHarvestLevel(harvestLevel); properties.ensureSet(PropertyKey.POLYMER); return this; } + /** + * Set the burn time of this Material as a Furnace Fuel.
+ * Will automatically add a {@link DustProperty} to this Material if it does not already have one. + * + * @param burnTime The Burn Time (in ticks) of this Material as a Furnace Fuel.
+ * If this Material already had a Burn Time defined, it will be overridden. + */ public Builder burnTime(int burnTime) { DustProperty prop = properties.getProperty(PropertyKey.DUST); if (prop == null) { @@ -934,8 +1085,14 @@ public Builder burnTime(int burnTime) { /** * Set the Color of this Material.
- * Defaults to 0xFFFFFF unless {@link Builder#colorAverage()} was called, where + * Defaults to 0xFFFFFF unless {@link #colorAverage()} was called, where * it will be a weighted average of the components of the Material. + *
+ *
+ * Will automatically color the Fluid of the Material. + *
+ *
+ * See {@link #color(int, boolean)} to set an override of the Fluid's color. * * @param color The RGB-formatted Color. */ @@ -946,7 +1103,7 @@ public Builder color(int color) { /** * Set the Color of this Material.
- * Defaults to 0xFFFFFF unless {@link Builder#colorAverage()} was called, where + * Defaults to 0xFFFFFF unless {@link Builder#colorAverage()} was called, where * it will be a weighted average of the components of the Material. * * @param color The RGB-formatted Color. @@ -960,7 +1117,7 @@ public Builder color(int color, boolean hasFluidColor) { /** * Set the secondary color of this Material.
- * Defaults to 0xFFFFFF unless {@link Builder#colorAverage()} was called, where + * Defaults to 0xFFFFFF unless {@link Builder#colorAverage()} was called, where * it will be a weighted average of the components of the Material. * * @param color The RGB-formatted Color. @@ -970,6 +1127,10 @@ public Builder secondaryColor(int color) { return this; } + /** + * Set the Color of this Material to be the average of the components specified in {@link #components}.
+ * Will default to 0xFFFFFF if a components list is not specified. + */ public Builder colorAverage() { this.averageRGB = true; return this; @@ -977,12 +1138,14 @@ public Builder colorAverage() { /** * Set the {@link MaterialIconSet} of this Material.
- * Defaults vary depending on if the Material has a:
+ *
+ * Defaults vary depending on if the Material has a: *
    *
  • {@link GemProperty}, it will default to {@link MaterialIconSet#GEM_VERTICAL} *
  • {@link IngotProperty} or {@link DustProperty}, it will default to {@link MaterialIconSet#DULL} *
  • {@link FluidProperty}, it will default to {@link MaterialIconSet#FLUID} *
+ *
* Default will be determined by first-found Property in this order, unless specified. * * @param iconSet The {@link MaterialIconSet} of this Material. @@ -992,6 +1155,14 @@ public Builder iconSet(MaterialIconSet iconSet) { return this; } + /** + * Set the components that make up this Material.
+ * This information is used for automatic decomposition, chemical formula generation, among other things. + * + * @param components An Object array formed as pairs of {@link Material} and Integer, representing the + * Material and the amount of said Material in this Material's composition. + * @throws IllegalArgumentException if the Object array is malformed. + */ public Builder components(Object... components) { Preconditions.checkArgument( components.length % 2 == 0, @@ -1010,21 +1181,37 @@ public Builder components(Object... components) { return this; } + /** + * Set the components that make up this Material.
+ * This information is used for automatic decomposition, chemical formula generation, among other things. + * + * @param components An array of {@link MaterialStack}, each representing the + * Material and the amount of said Material in this Material's composition. + */ public Builder componentStacks(MaterialStack... components) { composition = Arrays.asList(components); return this; } + /** + * Set the components that make up this Material.
+ * This information is used for automatic decomposition, chemical formula generation, among other things. + * + * @param components An {@link ImmutableList} of {@link MaterialStack}, each representing the + * Material and the amount of said Material in this Material's composition. + */ public Builder componentStacks(ImmutableList components) { composition = components; return this; } + /** @see #componentStacks(MaterialStack...) */ public Builder kjs$components(MaterialStackWrapper... components) { compositionSupplier = Arrays.asList(components); return this; } + /** @see #componentStacks(ImmutableList) componentStacks(ImmutableList<MaterialStack>) */ public Builder kjs$components(ImmutableList components) { compositionSupplier = components; return this; @@ -1058,7 +1245,9 @@ public Builder appendFlags(Collection f1, MaterialFlag... f2) { } /** - * Added {@link TagPrefix} to be ignored by this Material.
+ * Remove specific Items from this Material. + * + * @param prefixes The list of prefixes to ignore. */ public Builder ignoredTagPrefixes(TagPrefix... prefixes) { if (this.ignoredTagPrefixes == null) { @@ -1068,19 +1257,62 @@ public Builder ignoredTagPrefixes(TagPrefix... prefixes) { return this; } + /** + * Add a custom Item Tag to all items made from this Material. + * + * @param key The tag to add. + */ + public Builder customTags(TagKey key) { + this.itemTags.add(key); + return this; + } + + /** + * Set the Element of this Material.
+ * Should be effectively singleton; each element should only have 1 Material claiming to represent it. + * + * @param element The {@link Element} that this Material represents. + */ public Builder element(Element element) { this.materialInfo.element = element; return this; } + /** + * Set the Formula of this Material. + *
+ *
+ * Will override the automatically generated formula.
+ * Will automatically format numbers as subscripts. + * + * @param formula The formula for this Material. + */ public Builder formula(String formula) { this.formula = formula; return this; } /** - * Replaced the old toolStats methods which took many parameters. - * Use {@link ToolProperty.Builder} instead to create a Tool Property. + * Set the Formula of this Material. + *
+ *
+ * Will override the automatically generated formula.
+ * + * @param formula The formula for this Material. + * @param withFormatting Whether numbers should be formatted as subscripts. + */ + public Builder formula(String formula, boolean withFormatting) { + this.formula = formula; + this.formatFormula = withFormatting; + return this; + } + + /** + * Add a {@link ToolProperty} to this Material.
+ * Adds GregTech and Vanilla-substitute tools to this Material.
+ * Will automatically add an {@link IngotProperty} to this Material if it does not already have one. + * + * @see ToolProperty.Builder */ public Builder toolStats(ToolProperty toolProperty) { properties.setProperty(PropertyKey.TOOL, toolProperty); @@ -1088,51 +1320,130 @@ public Builder toolStats(ToolProperty toolProperty) { } /** - * Use {@link ArmorProperty.Builder} to create an Armor Property. + * Add an {@link ArmorProperty} to this Material.
+ * Adds Armors to this Material. + * + * @see ArmorProperty.Builder */ public Builder armorStats(ArmorProperty armorProperty) { properties.setProperty(PropertyKey.ARMOR, armorProperty); return this; } + /** + * Adds a {@link RotorProperty} to this Material, generating Turbine Rotors.
+ * Will automatically add an {@link IngotProperty} to this Material if it does not already have one. + * + * @param power The power of Turbine rotors made of this Material, used as a power multiplier with + * the Rotor Holder's tier. + * @param efficiency The efficiency of Turbine rotors made of this Material, used with the efficiency of the + * Rotor Holder: rotorEfficiency * holderEfficiency / 100 + * @param damage The damage running turbines with this Rotor should deal to the player when the Rotor + * Holder UI is opened. + * @param durability The durability of Turbine Rotors made of this Material. + */ + // dear god please refactor me public Builder rotorStats(int power, int efficiency, float damage, int durability) { properties.setProperty(PropertyKey.ROTOR, new RotorProperty(power, efficiency, damage, durability)); return this; } + /** @see #blast(int) */ public Builder blastTemp(int temp) { return blast(temp); } + /** @see #blast(int, BlastProperty.GasTier) */ public Builder blastTemp(int temp, BlastProperty.GasTier gasTier) { return blast(temp, gasTier); } + /** @see #blast(UnaryOperator) blast(UnaryOperator<BlastProperty.Builder>) */ public Builder blastTemp(int temp, BlastProperty.GasTier gasTier, int eutOverride) { return blast(b -> b.temp(temp, gasTier).blastStats(eutOverride)); } + /** @see #blast(UnaryOperator) blast(UnaryOperator<BlastProperty.Builder>) */ public Builder blastTemp(int temp, BlastProperty.GasTier gasTier, int eutOverride, int durationOverride) { return blast(b -> b.temp(temp, gasTier).blastStats(eutOverride, durationOverride)); } + /** + * Add an EBF Temperature and recipe to this Material.
+ * Will generate a Dust -> Ingot EBF recipe at 120 EU/t and a duration based off of the Material's composition. + *
+ *
+ * If the temperature is above 1750K, it will automatically add a Vacuum Freezer recipe and Hot + * Ingot.
+ * If the temperature is below 1000K, it will automatically add a PBF recipe in addition to the + * EBF recipe. + *
+ *
+ * See {@link #blast(UnaryOperator) blast(UnaryOperator<BlastProperty.Builder>)} for setting your own + * value(s). + * + * @param temp The temperature of the recipe in the EBF. + */ public Builder blast(int temp) { properties.setProperty(PropertyKey.BLAST, new BlastProperty(temp)); return this; } + /** + * Add an EBF Temperature and recipe to this Material.
+ * Will generate a Dust -> Ingot EBF recipe at 120 EU/t and a duration based off of the Material's composition. + *
+ *
+ * If the temperature is above 1750K, it will automatically add a Vacuum Freezer recipe and Hot + * Ingot.
+ * If the temperature is below 1000K, it will automatically add a PBF recipe in addition to the + * EBF recipe. + *
+ *
+ * See {@link #blast(UnaryOperator) blast(UnaryOperator<BlastProperty.Builder>)} for setting your own + * value(s). + * + * @param temp The temperature of the recipe in the EBF. + * @param gasTier The {@link BlastProperty.GasTier} of the Recipe. Will generate a second EBF recipe + * using the specified gas of the tier for a speed bonus. + */ public Builder blast(int temp, BlastProperty.GasTier gasTier) { properties.setProperty(PropertyKey.BLAST, new BlastProperty(temp, gasTier)); return this; } + /** + * Add an EBF Temperature and recipe to this Material.
+ * Will generate a Dust -> Ingot EBF recipe at 120 EU/t and a duration based off of the + * Material's composition. + *
+ *
+ * If the temperature is above 1750K, it will automatically add a Vacuum Freezer recipe and Hot + * Ingot.
+ * If the temperature is below 1000K, it will automatically add a PBF recipe in addition to the + * EBF recipe. + *
+ *
+ * + * Sample usage: + * + *
{@code
+         *     .blast(b -> b
+         *         .temp(1750)
+         *         .blastStats(VA[HV], 300)
+         *      )
+         *      // ...
+         * }
+ */ public Builder blast(UnaryOperator b) { properties.setProperty(PropertyKey.BLAST, b.apply(new BlastProperty.Builder()).build()); return this; } - // Tons of shortcut functions for adding various hazard effects. - + /** + * Remove the Hazard from this Material.
+ * Useful when a component of this Material would automatically apply an undesired hazard. + */ public Builder removeHazard() { properties.setProperty(PropertyKey.HAZARD, new HazardProperty(HazardProperty.HazardTrigger.NONE, GTMedicalConditions.NONE, @@ -1140,17 +1451,48 @@ public Builder removeHazard() { return this; } + /** + * Set a radioactive Hazard for this Material.
+ * Applies as a {@link GTMedicalConditions#CARCINOGEN carcinogenic} hazard with any trigger. + *
+ *
+ * Overrides the Hazard if one was already set. + * + * @param multiplier Multiplier for how quickly the condition will progress. + */ public Builder radioactiveHazard(float multiplier) { properties.setProperty(PropertyKey.HAZARD, new HazardProperty(HazardProperty.HazardTrigger.ANY, GTMedicalConditions.CARCINOGEN, multiplier, true)); return this; } + /** + * Set a Hazard for this Material. + *
+ *
+ * Overrides the Hazard if one was already set.
+ * Sets progression multiplier to 1.
+ * Will not apply the Hazard to derivative materials, i.e. materials with this Material in its components list. + * + * @param trigger The trigger type for this hazard. + * @param condition The condition applied by this hazard. + */ public Builder hazard(HazardProperty.HazardTrigger trigger, MedicalCondition condition) { properties.setProperty(PropertyKey.HAZARD, new HazardProperty(trigger, condition, 1, false)); return this; } + /** + * Set a Hazard for this Material. + *
+ *
+ * Overrides the Hazard if one was already set.
+ * Will not apply the Hazard to derivative materials, i.e. materials with this Material in its components list. + * + * @param trigger The trigger type for this hazard. + * @param condition The condition applied by this hazard. + * @param progressionMultiplier Multiplier for how quickly the condition will progress. + */ public Builder hazard(HazardProperty.HazardTrigger trigger, MedicalCondition condition, float progressionMultiplier) { properties.setProperty(PropertyKey.HAZARD, @@ -1158,6 +1500,16 @@ public Builder hazard(HazardProperty.HazardTrigger trigger, MedicalCondition con return this; } + /** + * Set a Hazard for this Material.
+ * Overrides the Hazard if one was already set. + * + * @param trigger The trigger type for this hazard. + * @param condition The condition applied by this hazard. + * @param progressionMultiplier Multiplier for how quickly the condition will progress. + * @param applyToDerivatives Whether the Hazard should be applied to materials with this Material in its + * components list. + */ public Builder hazard(HazardProperty.HazardTrigger trigger, MedicalCondition condition, float progressionMultiplier, boolean applyToDerivatives) { properties.setProperty(PropertyKey.HAZARD, @@ -1165,97 +1517,255 @@ public Builder hazard(HazardProperty.HazardTrigger trigger, MedicalCondition con return this; } + /** + * Set a Hazard for this Material. + *
+ *
+ * Overrides the Hazard if one was already set.
+ * Sets progression multiplier to 1. + * + * @param trigger The trigger type for this hazard. + * @param condition The condition applied by this hazard. + * @param applyToDerivatives Whether the Hazard should be applied to materials with this Material in its + * components list. + */ public Builder hazard(HazardProperty.HazardTrigger trigger, MedicalCondition condition, boolean applyToDerivatives) { properties.setProperty(PropertyKey.HAZARD, new HazardProperty(trigger, condition, 1, applyToDerivatives)); return this; } + /** + * Add an {@link OreProperty} to this Material.
+ * Automatically adds a {@link DustProperty} to this Material.
+ *
+ * Sets Ore Multiplier to 1 if not already set.
+ * Sets Byproduct Multiplier to 1 if not already set.
+ * Sets Emissive Textures to false if not already set. + *
+ *
+ * See {@link #ore(int, int, boolean)} for setting your own value(s). + */ public Builder ore() { properties.ensureSet(PropertyKey.ORE); return this; } + /** + * Add an {@link OreProperty} to this Material.
+ * Automatically adds a {@link DustProperty} to this Material.
+ *
+ * Sets Ore Multiplier to 1 if not already set.
+ * Sets Byproduct Multiplier to 1 if not already set. + *
+ *
+ * See {@link #ore(int, int, boolean)} for setting your own value(s). + * + * @param emissive Whether this Material's Ore Block should use emissive textures on the ore-vein texture + * overlay. + */ public Builder ore(boolean emissive) { properties.setProperty(PropertyKey.ORE, new OreProperty(1, 1, emissive)); return this; } + /** + * Add an {@link OreProperty} to this Material.
+ * Automatically adds a {@link DustProperty} to this Material.
+ *
+ * Sets Emissive Textures to false if not already set. + *
+ *
+ * See {@link #ore(int, int, boolean)} for setting your own value(s). + * + * @param oreMultiplier Crushed output multiplier when the Ore Block is macerated. + * @param byproductMultiplier Byproduct multiplier on some ore processing steps. + */ public Builder ore(int oreMultiplier, int byproductMultiplier) { properties.setProperty(PropertyKey.ORE, new OreProperty(oreMultiplier, byproductMultiplier)); return this; } + /** + * Add an {@link OreProperty} to this Material.
+ * Automatically adds a {@link DustProperty} to this Material. + * + * @param oreMultiplier Crushed output multiplier when the Ore Block is macerated. + * @param byproductMultiplier Byproduct multiplier on some ore processing steps. + * @param emissive Whether this Material's Ore Block should use emissive textures on the ore-vein + * texture overlay. + */ public Builder ore(int oreMultiplier, int byproductMultiplier, boolean emissive) { properties.setProperty(PropertyKey.ORE, new OreProperty(oreMultiplier, byproductMultiplier, emissive)); return this; } + /** + * Adds a Chemical Bath ore processing step to this Material's Ore, using 100L of the + * Fluid.
+ * Automatically adds an {@link OreProperty} to this Material if it does not already have one, + * with ore and byproduct multipliers of 1 and no emissive textures (if not already set). + * + * @param m The Material that is used as a Chemical Bath fluid for ore processing. + * This Material will be given a {@link FluidProperty} if it does not already have one, + * of type LIQUID and no Fluid block. + */ public Builder washedIn(Material m) { properties.ensureSet(PropertyKey.ORE); properties.getProperty(PropertyKey.ORE).setWashedIn(m); return this; } + /** + * Adds a Chemical Bath ore processing step to this Material's Ore.
+ * Automatically adds an {@link OreProperty} to this Material if it does not already have one, + * with ore and byproduct multipliers of 1 and no emissive textures (if not already set). + * + * @param m The Material that is used as a Chemical Bath fluid for ore processing. + * This Material will be given a {@link FluidProperty} if it does not already have one, + * of type LIQUID and no Fluid block. + * @param washedAmount The amount of the above Fluid required to wash the Ore. + */ public Builder washedIn(Material m, int washedAmount) { properties.ensureSet(PropertyKey.ORE); properties.getProperty(PropertyKey.ORE).setWashedIn(m, washedAmount); return this; } + /** + * Adds an Electromagnetic Separator recipe to this Material's Purified Dust, which outputs the passed + * Materials.
+ * Automatically adds an {@link OreProperty} to this Material if it does not already have one, + * with ore and byproduct multipliers of 1 and no emissive textures (if not already set). + * + * @param m The Materials which should be output by the Electromagnetic Separator in addition to a normal Dust + * of this Material. + */ public Builder separatedInto(Material... m) { properties.ensureSet(PropertyKey.ORE); properties.getProperty(PropertyKey.ORE).setSeparatedInto(m); return this; } + /** + * Sets the Material which this Material's Ore Block smelts to directly in a Furnace.
+ * Automatically adds an {@link OreProperty} to this Material if it does not already have one, + * with ore and byproduct multipliers of 1 and no emissive textures (if not already set). + * + * @param m The Material which should be output when smelting. + */ public Builder oreSmeltInto(Material m) { properties.ensureSet(PropertyKey.ORE); properties.getProperty(PropertyKey.ORE).setDirectSmeltResult(m); return this; } + /** + * Adds a Polarizer recipe to this Material's metal parts, outputting the provided Material.
+ * Automatically adds an {@link IngotProperty} to this Material if it does not already have one, + * with a harvest level of 2 and no Furnace burn time (if not already set). + * + * @param m The Material that this Material will be polarized into. + */ public Builder polarizesInto(Material m) { properties.ensureSet(PropertyKey.INGOT); properties.getProperty(PropertyKey.INGOT).setMagneticMaterial(m); return this; } + /** + * Sets the Material that this Material will automatically transform into in any Arc Furnace recipe.
+ * Automatically adds an {@link IngotProperty} to this Material if it does not already have one, + * with a harvest level of 2 and no Furnace burn time (if not already set). + * + * @param m The Material that this Material will turn into in any Arc Furnace recipes. + */ public Builder arcSmeltInto(Material m) { properties.ensureSet(PropertyKey.INGOT); properties.getProperty(PropertyKey.INGOT).setArcSmeltingInto(m); return this; } + /** + * Sets the Material that this Material's Ingot should macerate directly into.
+ * A good example is Magnetic Iron, which when macerated, will turn back into normal Iron.
+ * Automatically adds an {@link IngotProperty} to this Material if it does not already have one, + * with a harvest level of 2 and no Furnace burn time (if not already set). + * + * @param m The Material that this Material's Ingot should macerate directly into. + */ public Builder macerateInto(Material m) { properties.ensureSet(PropertyKey.INGOT); properties.getProperty(PropertyKey.INGOT).setMacerateInto(m); return this; } + /** + * Sets the Material that this Material's Ingot should smelt directly into in a Furnace.
+ * A good example is Magnetic Iron, which when smelted, will turn back into normal Iron.
+ * Automatically adds an {@link IngotProperty} to this Material if it does not already have one, + * with a harvest level of 2 and no Furnace burn time (if not already set). + * + * @param m The Material that this Material's Ingot should smelt directly into. + */ public Builder ingotSmeltInto(Material m) { properties.ensureSet(PropertyKey.INGOT); properties.getProperty(PropertyKey.INGOT).setSmeltingInto(m); return this; } + /** + * Adds Ore byproducts to this Material.
+ * Automatically adds an {@link OreProperty} to this Material if it does not already have one, + * with ore and byproduct multipliers of 1 and no emissive textures (if not already set). + * + * @param byproducts The list of Materials which serve as byproducts during ore processing. + */ public Builder addOreByproducts(Material... byproducts) { properties.ensureSet(PropertyKey.ORE); properties.getProperty(PropertyKey.ORE).setOreByProducts(byproducts); return this; } + /** + * Add Wires and Cables to this Material. + * + * @param voltage The voltage tier of this Cable. Should conform to standard GregTech voltage tiers. + * @param amperage The amperage of this Cable. Should be greater than zero. + * @param loss The loss-per-block of this Cable. A value of zero here will still have loss as wires. + */ public Builder cableProperties(long voltage, int amperage, int loss) { cableProperties(voltage, amperage, loss, false); return this; } + /** + * Add Wires and/or Cables to this Material. + * + * @param voltage The voltage tier of this Cable. Should conform to standard GregTech voltage tiers. + * @param amperage The amperage of this Cable. Should be greater than zero. + * @param loss The loss-per-block of this Cable. A value of zero here will still have loss as wires. + * @param isSuperCon Whether this Material is a Superconductor. If so, Cables will NOT be generated and + * the Wires will have zero cable loss, ignoring the loss parameter. + */ public Builder cableProperties(long voltage, int amperage, int loss, boolean isSuperCon) { properties.ensureSet(PropertyKey.DUST); properties.setProperty(PropertyKey.WIRE, new WireProperties(voltage, amperage, loss, isSuperCon)); return this; } + /** + * Add Wires and/or Cables to this Material. + * + * @param voltage The voltage tier of this Cable. Should conform to standard GregTech voltage tiers. + * @param amperage The amperage of this Cable. Should be greater than zero. + * @param loss The loss-per-block of this Cable. A value of zero here will still have loss as + * wires. + * @param isSuperCon Whether this Material is a Superconductor. If so, Cables will NOT be generated and + * the Wires will have zero cable loss, ignoring the loss parameter. + * @param criticalTemperature The critical temperature of this Material's Wires, if it is a Superconductor. + * Not currently utilized and intended for addons to use. + */ public Builder cableProperties(long voltage, int amperage, int loss, boolean isSuperCon, int criticalTemperature) { properties.ensureSet(PropertyKey.DUST); @@ -1264,10 +1774,32 @@ public Builder cableProperties(long voltage, int amperage, int loss, boolean isS return this; } + /** + * Add Fluid Pipes to this Material. + * + * @param maxTemp The maximum temperature of Fluid that this Pipe can handle before causing damage to the + * Pipe. + * @param throughput The rate at which Fluid can flow through this Pipe. + * @param gasProof Whether this Pipe can hold Gases. If not, some Gas will be lost as it travels through the + * Pipe. + */ public Builder fluidPipeProperties(int maxTemp, int throughput, boolean gasProof) { return fluidPipeProperties(maxTemp, throughput, gasProof, false, false, false); } + /** + * Add Fluid Pipes to this Material. + * + * @param maxTemp The maximum temperature of Fluid that this Pipe can handle before causing damage to the + * Pipe. + * @param throughput The rate at which Fluid can flow through this Pipe. + * @param gasProof Whether this Pipe can hold Gases. If not, some Gas will be lost as it travels through the + * Pipe. + * @param acidProof Whether this Pipe can hold Acids. If not, the Pipe may lose fluid or cause damage. + * @param cryoProof Whether this Pipe can hold Cryogenic Fluids (below 120K). If not, the Pipe may lose fluid + * or cause damage. + * @param plasmaProof Whether this Pipe can hold Plasmas. If not, the Pipe may lose fluid or cause damage. + */ public Builder fluidPipeProperties(int maxTemp, int throughput, boolean gasProof, boolean acidProof, boolean cryoProof, boolean plasmaProof) { properties.setProperty(PropertyKey.FLUID_PIPE, @@ -1275,11 +1807,36 @@ public Builder fluidPipeProperties(int maxTemp, int throughput, boolean gasProof return this; } + /** + * Add Item Pipes to this Material. + * + * @param priority Priority of this Item Pipe, used for the standard routing mode. + * @param stacksPerSec How many stacks of items can be moved per second (20 ticks). + */ public Builder itemPipeProperties(int priority, float stacksPerSec) { properties.setProperty(PropertyKey.ITEM_PIPE, new ItemPipeProperties(priority, stacksPerSec)); return this; } + /** + * Specify a default enchantment for tools made from this Material to have upon creation. + * + * @param enchant The default enchantment to apply to all tools made from this Material. + * @param level The level that the enchantment starts at when created. + */ + @Deprecated + public Builder addDefaultEnchant(ResourceKey enchant, int level) { + if (!properties.hasProperty(PropertyKey.TOOL)) // cannot assign default here + throw new IllegalArgumentException("Material cannot have an Enchant without Tools!"); + properties.getProperty(PropertyKey.TOOL).addEnchantmentForTools(enchant, level); + return this; + } + + /** + * Verify the passed information and finalize the Material. + * + * @return The finalized Material. + */ @HideFromJS public Material buildAndRegister() { materialInfo.componentList = composition.isEmpty() && this.compositionSupplier != null ? @@ -1306,7 +1863,7 @@ public Material buildAndRegister() { mat.setItemTags(itemTags); } if (formula != null) { - mat.setFormula(formula); + mat.setFormula(formula, formatFormula); } materialInfo.verifyInfo(properties, averageRGB); mat.registerMaterial(); diff --git a/src/main/java/com/gregtechceu/gtceu/api/material/material/info/MaterialFlags.java b/src/main/java/com/gregtechceu/gtceu/api/material/material/info/MaterialFlags.java index 2fad41c3115..71ca282b5bb 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/material/material/info/MaterialFlags.java +++ b/src/main/java/com/gregtechceu/gtceu/api/material/material/info/MaterialFlags.java @@ -43,9 +43,11 @@ public String toString() { /** * Add to material to disable its unification fully */ + @Deprecated + public static final MaterialFlag NO_UNIFICATION = new MaterialFlag.Builder("no_unification").build(); + public static final MaterialFlag DISABLE_MATERIAL_RECIPES = new MaterialFlag.Builder("disable_material_recipes") .build(); - /** * Enables electrolyzer decomposition recipe generation */ diff --git a/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/ArmorProperty.java b/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/ArmorProperty.java index b474a9d94fd..224ad8cd8b8 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/ArmorProperty.java +++ b/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/ArmorProperty.java @@ -1,5 +1,6 @@ package com.gregtechceu.gtceu.api.material.material.properties; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.material.ChemicalHelper; import com.gregtechceu.gtceu.api.material.material.Material; import com.gregtechceu.gtceu.api.registry.registrate.GTRegistrate; @@ -22,7 +23,6 @@ import com.google.common.base.Preconditions; import lombok.Getter; import lombok.Setter; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Range; @@ -56,9 +56,11 @@ public class ArmorProperty implements IMaterialProperty { private float knockbackResistance; @Setter - private Supplier<@Nullable Ingredient> repairIngredient; + private Supplier repairIngredient; private boolean noRepair; + @Setter + private String name = "metal"; @Getter @Setter private CustomTextureGetter customTextureGetter = (stack, entity, slot, overlay) -> null; @@ -101,7 +103,7 @@ public void verifyProperty(MaterialProperties properties) { } if (this.layers == null) { - this.layers = List.of(new ArmorMaterial.Layer(this.material.getResourceLocation(), "", this.dyeable)); + this.layers = List.of(new ArmorMaterial.Layer(GTCEu.id(this.name), "", this.dyeable)); } if (this.armorMaterial == null) { GTRegistrate registrate = GTRegistrate.createIgnoringListenerErrors(this.material.getModid()); @@ -112,11 +114,21 @@ public void verifyProperty(MaterialProperties properties) { } } - @SuppressWarnings("unused") + @SuppressWarnings("unused") // API, need to treat all of these as used public static class Builder { private final ArmorProperty armorProperty; + /** + * Create Armor for this Material. + * + * @param durabilityMultiplier The durability value of this Armor. Leather is 5, Iron is 15, Diamond is 33. + * @param protectionValues The protection values of each armor piece in the set.
+ * Ordered as Helmet, Chestplate, Leggings, Boots. + * @throws IllegalArgumentException If the protectionValues array parameter does not have exactly 4 entries. + * + * @see net.minecraft.world.item.ArmorMaterials + */ public static ArmorProperty.Builder of(int durabilityMultiplier, int[] protectionValues) { Preconditions.checkArgument(protectionValues != null && protectionValues.length == 4, "protectionValues must have 4 entries!"); @@ -127,27 +139,43 @@ private Builder(int durabilityMultiplier, int[] protectionValues) { armorProperty = new ArmorProperty(durabilityMultiplier, protectionValues); } + /** + * Set armors made from this Material as unbreakable, bypassing all durability. + */ public ArmorProperty.Builder unbreakable() { armorProperty.durabilityMultiplier = 0; return this; } + /** + * Set the base enchantability of a tool made from this Material. Iron is 14, Diamond is 10, Stone is 5. + */ public ArmorProperty.Builder enchantability(int enchantability) { armorProperty.enchantability = enchantability; return this; } + /** + * Set the protection value for a specific piece of armor made from this Material. + */ public ArmorProperty.Builder protectionValue(ArmorItem.Type type, int value) { armorProperty.protectionValues.put(type, value); return this; } + /** + * Set the protection values for all pieces of armor made from this Material. + * + * @throws IllegalArgumentException If the provided map does not have a value for all 4 armor pieces. + */ public ArmorProperty.Builder protectionValues(Map protectionValues) { + Preconditions.checkArgument(protectionValues != null && protectionValues.size() == 4, + "protectionValues must have 4 entries!"); armorProperty.protectionValues = protectionValues; return this; } - public ArmorProperty.Builder repairIngredient(@Nullable Supplier<@Nullable Ingredient> repairIngredient) { + public ArmorProperty.Builder repairIngredient(@Nullable Supplier repairIngredient) { if (repairIngredient == null) { armorProperty.repairIngredient = () -> null; armorProperty.noRepair = true; @@ -157,16 +185,32 @@ public ArmorProperty.Builder repairIngredient(@Nullable Supplier<@Nullable Ingre return this; } + /** + * Set the toughness granted for wearing armors made of this Material. + * Diamond is 2, Netherite is 3, other armors are 0. + * + * @see net.minecraft.world.item.ArmorMaterials + * @see Armor Toughness - Minecraft Wiki + */ public ArmorProperty.Builder toughness(float toughness) { armorProperty.toughness = toughness; return this; } + /** + * Set the knockback resistance granted for wearing armor made of this Material.
+ * Netherite is 0.1 (10%), other armors are 0. + * + * @see net.minecraft.world.item.ArmorMaterials + */ public ArmorProperty.Builder knockbackResistance(float knockbackResistance) { armorProperty.knockbackResistance = knockbackResistance; return this; } + /** + * Set whether armor made of this Material can be dyed, similar to Leather armor. + */ public ArmorProperty.Builder dyeable(boolean dyeable) { armorProperty.dyeable = dyeable; return this; @@ -181,7 +225,10 @@ public ArmorProperty.Builder layers(List layers) { return this; } - public ArmorProperty.Builder customTexture(ArmorProperty.@NotNull CustomTextureGetter textureGetter) { + /** + * Set a custom worn armor texture for armor made of this Material. + */ + public ArmorProperty.Builder customTexture(ArmorProperty.CustomTextureGetter textureGetter) { armorProperty.customTextureGetter = textureGetter; return this; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/BlastProperty.java b/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/BlastProperty.java index 66d086f7c0a..a9d93144c34 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/BlastProperty.java +++ b/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/BlastProperty.java @@ -147,6 +147,7 @@ public SizedFluidIngredient getFluid() { } } + @SuppressWarnings("unused") // API, need to treat all of these as used public static class Builder { private int temp; @@ -158,33 +159,69 @@ public static class Builder { public Builder() {} + /** + * Set the EBF temperature of this Material. + *
+ *
+ * If the temperature is above 1750K, it will automatically add a Vacuum Freezer recipe and Hot + * Ingot.
+ * If the temperature is below 1000K, it will automatically add a PBF recipe in addition to the + * EBF recipe. + * + * @param temperature The temperature of the recipe in the EBF. + */ public Builder temp(int temperature) { this.temp = temperature; return this; } + /** + * Set the EBF temperature and gas tier of this Material. + *
+ *
+ * If the temperature is above 1750K, it will automatically add a Vacuum Freezer recipe and Hot + * Ingot.
+ * If the temperature is below 1000K, it will automatically add a PBF recipe in addition to the + * EBF recipe. + * + * @param temperature The temperature of the recipe in the EBF. + * @param gasTier The {@link GasTier} of the Recipe. Will generate a second EBF recipe + * using the specified gas of the tier for a speed bonus. + */ public Builder temp(int temperature, GasTier gasTier) { this.temp = temperature; this.gasTier = gasTier; return this; } + /** + * Set the EU/t of the EBF recipe for this Material. + */ public Builder blastStats(int eutOverride) { this.eutOverride = eutOverride; return this; } + /** + * Set the EU/t and duration of the EBF recipe for this Material. + */ public Builder blastStats(int eutOverride, int durationOverride) { this.eutOverride = eutOverride; this.durationOverride = durationOverride; return this; } + /** + * Set the EU/t of the Vacuum Freezer recipe for the Hot Ingot of this Material. + */ public Builder vacuumStats(int eutOverride) { this.vacuumEUtOverride = eutOverride; return this; } + /** + * Set the EU/t and duration of the Vacuum Freezer recipe for the Hot Ingot of this Material. + */ public Builder vacuumStats(int eutOverride, int durationOverride) { this.vacuumEUtOverride = eutOverride; this.vacuumDurationOverride = durationOverride; diff --git a/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/MaterialProperties.java b/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/MaterialProperties.java index b8d2f204fdd..5fe52dc7a2a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/MaterialProperties.java +++ b/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/MaterialProperties.java @@ -37,7 +37,7 @@ public T getProperty(PropertyKey key) { } public boolean hasProperty(PropertyKey key) { - return propertyMap.get(key) != null; + return propertyMap.containsKey(key); } public void setProperty(PropertyKey key, IMaterialProperty value) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/ToolProperty.java b/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/ToolProperty.java index 0b8f8495550..dd5495524be 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/ToolProperty.java +++ b/src/main/java/com/gregtechceu/gtceu/api/material/material/properties/ToolProperty.java @@ -65,6 +65,10 @@ public class ToolProperty implements IMaterialProperty { @Setter private int harvestLevel; + @Getter + @Setter + private int prospectingDepth; + /** * Enchantability of tools made from this Material. *

@@ -124,6 +128,13 @@ public ToolProperty(float harvestSpeed, float attackDamage, int durability, int this.durability = durability; this.harvestLevel = harvestLevel; this.types = types; + this.prospectingDepth = this.harvestLevel * 2 + 1; + } + + public ToolProperty(float harvestSpeed, float attackDamage, int durability, int harvestLevel, int prospectingDepth, + GTToolType[] types) { + this(harvestSpeed, attackDamage, durability, harvestLevel, types); + this.prospectingDepth = prospectingDepth; } public ToolProperty() { @@ -169,10 +180,19 @@ public ToolProperty removeTypes(GTToolType... types) { return this; } + @SuppressWarnings("unused") // API, need to treat all of these as used public static class Builder { private final ToolProperty toolProperty; + /** + * Create Tools for this Material. + * + * @param harvestSpeed The mining speed of a tool made from this Material. + * @param attackDamage The attack damage of a tool made from this Material. + * @param durability The durability of a tool made from this Material. + * @param harvestLevel The harvest level that tools of this Material can mine. + */ public static Builder of(float harvestSpeed, float attackDamage, int durability, int harvestLevel) { return new Builder(harvestSpeed, attackDamage, durability, harvestLevel, new GTToolType[] { SWORD, @@ -212,6 +232,15 @@ public static Builder of(float harvestSpeed, float attackDamage, int durability, }); } + /** + * Create Tools for this Material. + * + * @param harvestSpeed The mining speed of a tool made from this Material. + * @param attackDamage The attack damage of a tool made from this Material. + * @param durability The durability of a tool made from this Material. + * @param harvestLevel The harvest level that tools of this Material can mine. + * @param types The types of tools that can be made of this Material. + */ public static Builder of(float harvestSpeed, float attackDamage, int durability, int harvestLevel, GTToolType... types) { return new Builder(harvestSpeed, attackDamage, durability, harvestLevel, types); @@ -221,46 +250,76 @@ private Builder(float harvestSpeed, float attackDamage, int durability, int harv toolProperty = new ToolProperty(harvestSpeed, attackDamage, durability, harvestLevel, types); } + /** + * Set the base enchantability of a tool made from this Material. Iron is 14, Diamond is 10, Stone is 5. + */ public Builder enchantability(int enchantability) { toolProperty.enchantability = enchantability; return this; } + /** + * Set the attack speed of a tool made from this Material (animation time). + */ public Builder attackSpeed(float attackSpeed) { toolProperty.attackSpeed = attackSpeed; return this; } + /** + * Disable crafting tools being made from this Material. + */ public Builder ignoreCraftingTools() { toolProperty.ignoreCraftingTools = true; return this; } + /** + * Set tools made from this Material as unbreakable, bypassing all durability. + */ public Builder unbreakable() { toolProperty.isUnbreakable = true; return this; } + /** + * Set the types of tools that can be made of this Material. + */ public Builder types(GTToolType... types) { toolProperty.types = types; return this; } + /** + * Add additional types of tools that can be made of this Material. + */ public Builder addTypes(GTToolType... types) { toolProperty.types = ArrayUtils.addAll(toolProperty.types, types); return this; } + /** + * Add a default enchantment to tools made of this Material. + * + * @param enchantment The default enchantment, applied on crafting the tool. + * @param level The level of the enchantment. + */ public Builder enchantment(ResourceKey enchantment, int level) { toolProperty.addEnchantmentForTools(enchantment, level); return this; } + /** + * Set tools made from this Material as magnetic, pulling mined blocks into your inventory. + */ public Builder magnetic() { toolProperty.isMagnetic = true; return this; } + /** + * Set a multiplier to the base durability of tools made from this Material. + */ public Builder durabilityMultiplier(int multiplier) { toolProperty.durabilityMultiplier = multiplier; return this; diff --git a/src/main/java/com/gregtechceu/gtceu/api/material/material/stack/MaterialStack.java b/src/main/java/com/gregtechceu/gtceu/api/material/material/stack/MaterialStack.java index aec68d4a3ed..a874ada2712 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/material/material/stack/MaterialStack.java +++ b/src/main/java/com/gregtechceu/gtceu/api/material/material/stack/MaterialStack.java @@ -24,6 +24,10 @@ public MaterialStack add(long amount) { return new MaterialStack(material, this.amount + amount); } + public MaterialStack multiply(float amount) { + return new MaterialStack(material, (long) (this.amount * amount)); + } + public MaterialStack multiply(long amount) { return new MaterialStack(material, this.amount * amount); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/misc/EnergyContainerList.java b/src/main/java/com/gregtechceu/gtceu/api/misc/EnergyContainerList.java index dc51c262b35..034603a682a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/misc/EnergyContainerList.java +++ b/src/main/java/com/gregtechceu/gtceu/api/misc/EnergyContainerList.java @@ -146,7 +146,7 @@ public long changeEnergy(long energyToAdd) { long energyAdded = 0L; for (IEnergyContainer container : this.energyContainerList) { energyAdded += container.changeEnergy(energyToAdd - energyAdded); - if (energyAdded >= energyToAdd) { + if (energyAdded == energyToAdd) { return energyAdded; } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/misc/ImageCache.java b/src/main/java/com/gregtechceu/gtceu/api/misc/ImageCache.java new file mode 100644 index 00000000000..de9b8410f25 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/misc/ImageCache.java @@ -0,0 +1,62 @@ +package com.gregtechceu.gtceu.api.misc; + +import com.gregtechceu.gtceu.GTCEu; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; + +public class ImageCache { + + public static final long REFRESH_SECS = 120; + public static final long EXPIRE_SECS = 300; + private static final byte[] NULL_MARKER = new byte[0]; + + private static boolean downloading = false; + + private static final LoadingCache CACHE = CacheBuilder.newBuilder() + .refreshAfterWrite(REFRESH_SECS, TimeUnit.SECONDS) + .expireAfterAccess(EXPIRE_SECS, TimeUnit.SECONDS) + .concurrencyLevel(3) + .build(CacheLoader.from(url -> { + if (downloading) return NULL_MARKER; + downloading = true; + + try (InputStream stream = new URL(url).openStream()) { + return stream.readAllBytes(); + } catch (IOException e) { + GTCEu.LOGGER.error("Could not load image {}", url, e); + downloading = false; + return NULL_MARKER; + } finally { + GTCEu.LOGGER.debug("Downloaded image {}! Executing callback", url); + downloading = false; + } + })); + + public static void queryServerImage(String url, Consumer callback) { + try { + if (downloading) return; + + byte[] image = CACHE.get(url); + if (image != NULL_MARKER) { + callback.accept(image); + } else { + CACHE.invalidate(url); + } + } catch (ExecutionException e) { + Throwable t = e; + if (t.getCause() != null) { + t = t.getCause(); + } + GTCEu.LOGGER.error("Could not load image {}", url, t); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/misc/virtualregistry/EntryTypes.java b/src/main/java/com/gregtechceu/gtceu/api/misc/virtualregistry/EntryTypes.java index 0e753479160..0f79aa26527 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/misc/virtualregistry/EntryTypes.java +++ b/src/main/java/com/gregtechceu/gtceu/api/misc/virtualregistry/EntryTypes.java @@ -1,6 +1,8 @@ package com.gregtechceu.gtceu.api.misc.virtualregistry; import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.misc.virtualregistry.entries.VirtualItemStorage; +import com.gregtechceu.gtceu.api.misc.virtualregistry.entries.VirtualRedstone; import com.gregtechceu.gtceu.api.misc.virtualregistry.entries.VirtualTank; import net.minecraft.core.HolderLookup; @@ -20,7 +22,10 @@ public final class EntryTypes { private static final Map> TYPES = new Object2ObjectOpenHashMap<>(); public static final EntryTypes ENDER_FLUID = addEntryType(GTCEu.id("ender_fluid"), VirtualTank::new); - // ENDER_ITEM("ender_item", null), + public static final EntryTypes ENDER_ITEM = addEntryType(GTCEu.id("ender_item"), + VirtualItemStorage::new); + public static final EntryTypes ENDER_REDSTONE = addEntryType(GTCEu.id("ender_redstone"), + VirtualRedstone::new); // ENDER_ENERGY("ender_energy", null), // ENDER_REDSTONE("ender_redstone", null); diff --git a/src/main/java/com/gregtechceu/gtceu/api/misc/virtualregistry/entries/VirtualItemStorage.java b/src/main/java/com/gregtechceu/gtceu/api/misc/virtualregistry/entries/VirtualItemStorage.java new file mode 100644 index 00000000000..01579a9896f --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/misc/virtualregistry/entries/VirtualItemStorage.java @@ -0,0 +1,71 @@ +package com.gregtechceu.gtceu.api.misc.virtualregistry.entries; + +import com.gregtechceu.gtceu.api.misc.virtualregistry.EntryTypes; +import com.gregtechceu.gtceu.api.misc.virtualregistry.VirtualEntry; +import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; + +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; + +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class VirtualItemStorage extends VirtualEntry { + + protected static final int DEFAULT_SLOT_AMOUNT = 1; + + @NotNull + @Getter + private final CustomItemStackHandler handler; + + protected static final String ITEM_KEY = "items"; + + public VirtualItemStorage() { + this(DEFAULT_SLOT_AMOUNT); + } + + public VirtualItemStorage(int slots) { + handler = new CustomItemStackHandler(slots); + } + + @Override + public EntryTypes getType() { + return EntryTypes.ENDER_ITEM; + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof VirtualItemStorage other)) return false; + return other.handler == this.handler; + } + + @Override + public CompoundTag serializeNBT(HolderLookup.Provider provider) { + CompoundTag tag = VirtualItemStorage.super.serializeNBT(provider); + tag.put(ITEM_KEY, handler.serializeNBT(provider)); + return tag; + } + + @Override + public void deserializeNBT(HolderLookup.Provider provider, CompoundTag nbt) { + super.deserializeNBT(provider, nbt); + handler.deserializeNBT(provider, nbt.getCompound(ITEM_KEY)); + } + + @Override + public boolean canRemove() { + return super.canRemove() && isEmpty(); + } + + public boolean isEmpty() { + for (int i = 0; i < handler.getSlots(); i++) { + if (!handler.getStackInSlot(i).isEmpty()) return false; + } + return true; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/misc/virtualregistry/entries/VirtualRedstone.java b/src/main/java/com/gregtechceu/gtceu/api/misc/virtualregistry/entries/VirtualRedstone.java new file mode 100644 index 00000000000..dd3d2d10391 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/misc/virtualregistry/entries/VirtualRedstone.java @@ -0,0 +1,75 @@ +package com.gregtechceu.gtceu.api.misc.virtualregistry.entries; + +import com.gregtechceu.gtceu.api.misc.virtualregistry.EntryTypes; +import com.gregtechceu.gtceu.api.misc.virtualregistry.VirtualEntry; + +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; + +import it.unimi.dsi.fastutil.objects.Object2ShortMap; +import it.unimi.dsi.fastutil.objects.Object2ShortOpenHashMap; +import lombok.Getter; + +import java.util.UUID; + +public class VirtualRedstone extends VirtualEntry { + + private static final String MEMBERS_KEY = "members"; + + @Getter + private final Object2ShortMap members = new Object2ShortOpenHashMap<>(); + + public VirtualRedstone() {} + + public int getSignal() { + return members.values().intStream().max().orElse(0); + } + + public void addMember(UUID uuid) { + members.put(uuid, (short) 0); + } + + public void setSignal(UUID uuid, int signal) { + if (!members.containsKey(uuid)) return; + members.put(uuid, (short) signal); + } + + public void removeMember(UUID uuid) { + members.removeShort(uuid); + } + + @Override + public EntryTypes getType() { + return EntryTypes.ENDER_REDSTONE; + } + + @Override + public CompoundTag serializeNBT(HolderLookup.Provider provider) { + CompoundTag tag = super.serializeNBT(provider); + CompoundTag tag2 = new CompoundTag(); + for (var entry : members.object2ShortEntrySet()) + tag2.putShort(entry.getKey().toString(), entry.getShortValue()); + tag.put(MEMBERS_KEY, tag2); + return tag; + } + + @Override + public void deserializeNBT(HolderLookup.Provider provider, CompoundTag nbt) { + super.deserializeNBT(provider, nbt); + CompoundTag tag = nbt.getCompound(MEMBERS_KEY); + for (String uuid : tag.getAllKeys()) { + members.put(UUID.fromString(uuid), tag.getShort(uuid)); + } + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof VirtualRedstone other)) return false; + return other.members == this.members; + } + + @Override + public boolean canRemove() { + return super.canRemove() && members.isEmpty(); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/BlockPattern.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/BlockPattern.java index 4a400c8e98f..738885beb39 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/BlockPattern.java +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/BlockPattern.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.api.multiblock.predicates.SimplePredicate; import com.gregtechceu.gtceu.api.multiblock.util.PatternMatchContext; import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; +import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.utils.BlockInfo; @@ -646,8 +647,7 @@ private static IntObjectPair getMatchStackWithHandler( if (rt != null) { return rt; } - } else if (candidates.stream() - .anyMatch(candidate -> ItemStack.isSameItemSameComponents(candidate, stack)) && + } else if (candidates.stream().anyMatch(candidate -> GTUtil.isSameItemSameTags(candidate, stack)) && !stack.isEmpty() && stack.getItem() instanceof BlockItem) { return IntObjectPair.of(i, handler); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/MultiblockState.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/MultiblockState.java index 4054a3ebe24..309087c8025 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/MultiblockState.java +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/MultiblockState.java @@ -63,14 +63,14 @@ public MultiblockState(Level world, BlockPos controllerPos) { this.matchContext = new PatternMatchContext(); } - protected void clean() { + public void clean() { this.matchContext.reset(); this.globalCount = new Object2IntOpenHashMap<>(); this.layerCount = new Object2IntOpenHashMap<>(); cache = new LongOpenHashSet(); } - protected boolean update(BlockPos posIn, TraceabilityPredicate predicate) { + public boolean update(BlockPos posIn, TraceabilityPredicate predicate) { this.pos = posIn; this.blockState = null; this.blockEntity = null; @@ -172,6 +172,11 @@ public void onBlockStateChanged(BlockPos pos, BlockState state) { } } else { IMultiController controller = getController(); + if (controller == null && error == UNLOAD_ERROR) { + if (!serverLevel.isLoaded(controllerPos)) { + GTCEu.LOGGER.info("Controller not loaded, pos {}", controllerPos); + } + } if (controller != null) { if (controller.isFormed() && state.getBlock() instanceof ActiveBlock) { LongSet activeBlocks = getMatchContext().getOrDefault("vaBlocks", LongSets.emptySet()); diff --git a/src/main/java/com/gregtechceu/gtceu/api/multiblock/Predicates.java b/src/main/java/com/gregtechceu/gtceu/api/multiblock/Predicates.java index 9f790970974..4c0394b84b3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/multiblock/Predicates.java +++ b/src/main/java/com/gregtechceu/gtceu/api/multiblock/Predicates.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; +import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.multiblock.IBatteryData; import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; import com.gregtechceu.gtceu.api.material.material.Material; @@ -67,6 +68,16 @@ public static TraceabilityPredicate blocks(IMachineBlock... blocks) { new PredicateBlocks(Arrays.stream(blocks).map(IMachineBlock::self).toArray(Block[]::new))); } + public static TraceabilityPredicate machines(MachineDefinition... definitions) { + ArrayList machineBlocks = new ArrayList<>(definitions.length); + for (var definition : definitions) { + if (definition != null) { + machineBlocks.add(definition.get()); + } + } + return blocks(machineBlocks.toArray(IMachineBlock[]::new)); + } + public static TraceabilityPredicate blockTag(TagKey tag) { return new TraceabilityPredicate(new PredicateBlockTag(tag)); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/IPlaceholderInfoProviderCover.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/IPlaceholderInfoProviderCover.java new file mode 100644 index 00000000000..02f0ea07bdc --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/IPlaceholderInfoProviderCover.java @@ -0,0 +1,19 @@ +package com.gregtechceu.gtceu.api.placeholder; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; + +import java.util.List; + +public interface IPlaceholderInfoProviderCover { + + long getTicksSincePlaced(); + + List getCreateDisplayTargetBuffer(); + + List getComputerCraftTextBuffer(); + + void setDisplayTargetBufferLine(int line, MutableComponent component); + + void setComputerCraftTextBufferLine(int line, MutableComponent component); +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/MultiLineComponent.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/MultiLineComponent.java new file mode 100644 index 00000000000..7c8b3db1267 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/MultiLineComponent.java @@ -0,0 +1,151 @@ +package com.gregtechceu.gtceu.api.placeholder; + +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.*; + +import com.mojang.serialization.Codec; +import lombok.Getter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.UnmodifiableView; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; + +public class MultiLineComponent extends ArrayList { + + public static final Codec CODEC = ComponentSerialization.CODEC.listOf() + .xmap(list -> { + if (((List) list) instanceof MultiLineComponent multiLine) { + return multiLine; + } + MultiLineComponent multiLine = new MultiLineComponent(); + for (Component c : list) { + multiLine.add(c.copy()); + } + return multiLine; + }, MultiLineComponent::toImmutable); + + public MultiLineComponent() {} + + @Getter + private boolean ignoreSpaces = false; + + public MultiLineComponent(List components) { + super(components); + } + + public static MultiLineComponent of(Component c) { + return new MultiLineComponent(List.of(c.copy())); + } + + public static MultiLineComponent literal(String s) { + return MultiLineComponent.of(Component.literal(s)); + } + + public static MultiLineComponent literal(long n) { + return MultiLineComponent.literal(String.valueOf(n)); + } + + public static MultiLineComponent literal(double n) { + return MultiLineComponent.literal(String.valueOf(n)); + } + + public static MultiLineComponent empty() { + return MultiLineComponent.of(CommonComponents.EMPTY); + } + + @Override + public boolean equals(Object o) { + if (o instanceof MultiLineComponent) + return Objects.equals(this.toString(), o.toString()); + return false; + } + + public boolean equalsString(String s) { + return Objects.equals(this.toString(), s); + } + + public String toString() { + StringBuilder out = new StringBuilder(); + if (this.isEmpty()) return out.toString(); + for (Component component : this) { + out.append(component.getString()); + out.append('\n'); + } + return out.substring(0, out.length() - 1); + } + + public double toDouble() { + if (this.isEmpty()) return 0; + if (this.size() > 1) throw new NumberFormatException(this.toString()); + return Double.parseDouble(this.get(0).getString()); + } + + public int toInt() { + if (this.isEmpty()) return 0; + if (this.size() > 1) throw new NumberFormatException(this.toString()); + return Integer.parseInt(this.get(0).getString()); + } + + public void append(@Nullable String s) { + if (s != null) { + this.getLast().append(s); + } + } + + public void append(char c) { + append(String.valueOf(c)); + } + + public MultiLineComponent append(@Nullable List lines) { + if (lines == null) return this; + if (lines.isEmpty()) return this; + for (Component line : lines) { + this.getLast().append(line); + this.add(Component.empty()); + } + this.removeLast(); + return this; + } + + public MultiLineComponent append(@NotNull Component line) { + this.getLast().append(line); + return this; + } + + public void appendNewline() { + this.add(Component.empty()); + } + + public MultiLineComponent withStyle(Style style) { + MultiLineComponent out = MultiLineComponent.empty(); + for (MutableComponent c : this) { + out.append(MultiLineComponent.of(c.withStyle(style))); + out.appendNewline(); + } + if (!out.isEmpty()) out.remove(out.size() - 1); + return out; + } + + public MultiLineComponent withStyle(ChatFormatting... style) { + MultiLineComponent out = MultiLineComponent.empty(); + for (MutableComponent c : this) { + out.append(c.withStyle(style)); + out.appendNewline(); + } + if (!out.isEmpty()) out.remove(out.size() - 1); + return out; + } + + public @UnmodifiableView List toImmutable() { + return Collections.unmodifiableList(this); + } + + public MultiLineComponent setIgnoreSpaces(boolean ignoreSpaces) { + this.ignoreSpaces = ignoreSpaces; + return this; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/Placeholder.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/Placeholder.java new file mode 100644 index 00000000000..0e80933bf96 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/Placeholder.java @@ -0,0 +1,39 @@ +package com.gregtechceu.gtceu.api.placeholder; + +import com.gregtechceu.gtceu.api.placeholder.exceptions.PlaceholderException; +import com.gregtechceu.gtceu.common.capability.PlaceholderSavedData; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; + +import lombok.Getter; + +import java.util.List; + +public abstract class Placeholder { + + @Getter + private final String name; + @Getter + private final int priority; + + public abstract MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException; + + public Placeholder(String name) { + this(name, 0); + } + + public Placeholder(String name, int priority) { + this.name = name; + this.priority = priority; + } + + protected CompoundTag getData(PlaceholderContext ctx) { + CompoundTag placeholderData = PlaceholderSavedData.getOrCreate((ServerLevel) ctx.level()) + .getPlaceholderData(this); + if (!placeholderData.contains(ctx.uuid().toString())) + placeholderData.put(ctx.uuid().toString(), new CompoundTag()); + return placeholderData.getCompound(ctx.uuid().toString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderContext.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderContext.java new file mode 100644 index 00000000000..6050d76b257 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderContext.java @@ -0,0 +1,20 @@ +package com.gregtechceu.gtceu.api.placeholder; + +import com.gregtechceu.gtceu.api.cover.CoverBehavior; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import net.neoforged.neoforge.items.ItemStackHandler; + +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; + +public record PlaceholderContext(Level level, + BlockPos pos, + Direction side, + @Nullable ItemStackHandler itemStackHandler, + @Nullable CoverBehavior cover, + @Nullable MultiLineComponent previousText, + UUID uuid) {} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderHandler.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderHandler.java new file mode 100644 index 00000000000..770e3b79ac0 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderHandler.java @@ -0,0 +1,199 @@ +package com.gregtechceu.gtceu.api.placeholder; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.placeholder.exceptions.PlaceholderException; +import com.gregtechceu.gtceu.api.placeholder.exceptions.UnclosedBracketException; +import com.gregtechceu.gtceu.api.placeholder.exceptions.UnexpectedBracketException; +import com.gregtechceu.gtceu.api.placeholder.exceptions.UnknownPlaceholderException; +import com.gregtechceu.gtceu.data.datagen.lang.LangHandler; +import com.gregtechceu.gtceu.utils.GTStringUtils; +import com.gregtechceu.gtceu.utils.GTUtil; + +import com.lowdragmc.lowdraglib.gui.texture.TextTexture; +import com.lowdragmc.lowdraglib.gui.widget.DraggableScrollableWidgetGroup; +import com.lowdragmc.lowdraglib.gui.widget.TextTextureWidget; +import com.lowdragmc.lowdraglib.gui.widget.Widget; +import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; +import com.lowdragmc.lowdraglib.gui.widget.codeeditor.language.LanguageDefinition; +import com.lowdragmc.lowdraglib.gui.widget.codeeditor.language.TokenTypes; + +import net.minecraft.ChatFormatting; +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.network.chat.MutableComponent; + +import java.util.*; +import java.util.function.Consumer; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class PlaceholderHandler { + + private static final char ARG_SEPARATOR = ' '; + private static final char PLACEHOLDER_BEGIN = '{'; + private static final char PLACEHOLDER_END = '}'; + private static final char ESCAPE = '\\'; + private static final char LITERAL_ESCAPE = '"'; + private static final char NEWLINE = '\n'; + private static final char ESCAPED_NEWLINE = 'n'; + + private static final Map placeholders = new HashMap<>(); + + public static final LanguageDefinition LANG_DEFINITION = new LanguageDefinition( + "Placeholders", + List.of( + TokenTypes.KEYWORD.createTokenType(PlaceholderHandler.getAllPlaceholderNames().stream().toList()), + TokenTypes.IDENTIFIER, + TokenTypes.STRING, + TokenTypes.COMMENT, + TokenTypes.NUMBER, + TokenTypes.OPERATOR, + TokenTypes.WHITESPACE, + TokenTypes.OTHER), + Set.of()); + + public static void addPlaceholder(Placeholder placeholder) { + if (placeholders.containsKey(placeholder.getName())) { + if (placeholders.get(placeholder.getName()).getPriority() <= placeholder.getPriority()) { + placeholders.put(placeholder.getName(), placeholder); + } + } else placeholders.put(placeholder.getName(), placeholder); + } + + public static boolean placeholderExists(MultiLineComponent placeholder) { + return placeholders.containsKey(placeholder.toString()); + } + + public static MultiLineComponent processPlaceholder(List placeholder, + PlaceholderContext context) throws PlaceholderException { + if (!placeholderExists(placeholder.get(0))) + throw new UnknownPlaceholderException(placeholder.get(0).toString()); + return placeholders.get(placeholder.get(0).toString()).apply(context, + placeholder.subList(1, placeholder.size())); + } + + public static MultiLineComponent processPlaceholders(String s, PlaceholderContext ctx) { + if (ctx.level().isClientSide) + GTCEu.LOGGER.warn("Placeholder processing is running on client instead of server!"); + List exceptions = new ArrayList<>(); + boolean escape = false; + boolean escapeNext = false; + boolean literalEscape = false; + int line = 1; + int symbol = 1; + Stack> stack = new Stack<>(); + stack.push(GTUtil.list(MultiLineComponent.empty())); + for (char c : s.toCharArray()) { + if (escape || (literalEscape && c != LITERAL_ESCAPE)) { + if (c == ESCAPED_NEWLINE && !literalEscape) { + GTUtil.getLast(stack.peek()).appendNewline(); + line++; + symbol = 0; + } else if (c == NEWLINE) continue; + else GTUtil.getLast(stack.peek()).append(c); + } else { + switch (c) { + case ESCAPE -> escapeNext = true; + case LITERAL_ESCAPE -> literalEscape = !literalEscape; + case NEWLINE -> { + GTUtil.getLast(stack.peek()).appendNewline(); + line++; + symbol = 0; + } + case ARG_SEPARATOR -> { + if (stack.size() == 1) GTUtil.getLast(stack.peek()).append(c); + else stack.peek().add(MultiLineComponent.empty()); + } + case PLACEHOLDER_BEGIN -> stack.push(GTUtil.list(MultiLineComponent.empty())); + case PLACEHOLDER_END -> { + List placeholder = stack.pop(); + try { + if (stack.isEmpty()) throw new UnexpectedBracketException(); + MultiLineComponent result = processPlaceholder(placeholder, ctx); + if (result.isIgnoreSpaces() || stack.size() == 1) { + GTUtil.getLast(stack.peek()).append(result); + } else { + for (int i = 0; i < result.size(); i++) { + MutableComponent component = result.get(i); + component.visit((style, string) -> { + String[] split = string.split(String.valueOf(ARG_SEPARATOR)); + for (int j = 0; j < split.length; j++) { + String idk = split[j]; + GTUtil.getLast(stack.peek()) + .append(MultiLineComponent.literal(idk).withStyle(style)); + if (j == split.length - 1) continue; + if (stack.size() == 1) { + GTUtil.getLast(stack.peek()).append(ARG_SEPARATOR); + } else { + stack.peek().add(MultiLineComponent.empty()); + } + } + return Optional.empty(); + }, component.getStyle()); + if (i != result.size() - 1) GTUtil.getLast(stack.peek()).appendNewline(); + } + } + } catch (PlaceholderException e) { + e.setLineInfo(line, symbol); + exceptions.add(e); + } catch (RuntimeException e) { + exceptions.add(e); + } + } + default -> GTUtil.getLast(stack.peek()).append(c); + } + } + escape = escapeNext; + escapeNext = false; + symbol++; + } + if (stack.size() > 1) { + PlaceholderException exception = new UnclosedBracketException(); + exception.setLineInfo(line, symbol); + exceptions.add(exception); + } + if (exceptions.isEmpty()) + return stack.peek().stream().reduce(MultiLineComponent.empty(), MultiLineComponent::append); + MultiLineComponent out = MultiLineComponent.empty(); + exceptions.forEach(exception -> { + out.append(exception.getMessage()); + out.appendNewline(); + }); + return out.withStyle(ChatFormatting.DARK_RED); + } + + public static Set getAllPlaceholderNames() { + return placeholders.keySet(); + } + + public static Widget getPlaceholderHandlerUI(String filter) { + DraggableScrollableWidgetGroup placeholderReference = new DraggableScrollableWidgetGroup(280, 15, 100, 200); + Consumer onSearch = (newSearch) -> { + placeholderReference.clearAllWidgets(); + int y = 2; + ArrayList placeholders = new ArrayList<>(getAllPlaceholderNames()); + placeholders.removeIf(s -> s == null || !s.contains(newSearch)); + placeholders.sort(String::compareTo); + for (String placeholder : placeholders) { + TextTextureWidget placeholderName = new TextTextureWidget(0, y, 80, 15, placeholder); + placeholderName.getTextTexture().type = TextTexture.TextType.LEFT; + placeholderName.setHoverTooltips(GTStringUtils + .toImmutable(LangHandler.getSingleOrMultiLang("gtceu.placeholder_info." + placeholder))); + placeholderReference.addWidget(placeholderName); + y += 15; + } + }; + onSearch.accept(filter); + TextTextureWidget placeholderReferenceLabel = new TextTextureWidget( + 280, 0, + 160, 15, + GTStringUtils.componentsToString( + LangHandler.getMultiLang("gtceu.gui.computer_monitor_cover.placeholder_reference"))); + placeholderReferenceLabel.getTextTexture().type = TextTexture.TextType.LEFT; + WidgetGroup out = new WidgetGroup(); + out.addWidget(placeholderReferenceLabel); + out.addWidget(placeholderReference); + return out; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderUtils.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderUtils.java new file mode 100644 index 00000000000..f3967260dda --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/PlaceholderUtils.java @@ -0,0 +1,52 @@ +package com.gregtechceu.gtceu.api.placeholder; + +import com.gregtechceu.gtceu.api.placeholder.exceptions.InvalidNumberException; +import com.gregtechceu.gtceu.api.placeholder.exceptions.NotEnoughArgsException; +import com.gregtechceu.gtceu.api.placeholder.exceptions.OutOfRangeException; +import com.gregtechceu.gtceu.api.placeholder.exceptions.WrongNumberOfArgsException; + +import java.util.List; + +public class PlaceholderUtils { + + public static void checkRange(String what, int min, int max, int n) throws OutOfRangeException { + if (n < min || n > max) throw new OutOfRangeException(what, min, max, n); + } + + public static int toInt(MultiLineComponent component) throws InvalidNumberException { + try { + return component.toInt(); + } catch (NumberFormatException e) { + throw new InvalidNumberException(component.toString()); + } + } + + public static double toDouble(MultiLineComponent component) throws InvalidNumberException { + try { + return component.toDouble(); + } catch (NumberFormatException e) { + throw new InvalidNumberException(component.toString()); + } + } + + public static void checkArgs(List args, int args_num) throws WrongNumberOfArgsException { + if (args.size() != args_num) throw new WrongNumberOfArgsException(args_num, args.size()); + } + + public static void checkArgs(List args, int args_num, + boolean allowMore) throws NotEnoughArgsException, WrongNumberOfArgsException { + if (!allowMore) checkArgs(args, args_num); + if (args.size() < args_num) throw new NotEnoughArgsException(args_num, args.size()); + } + + public static long toLong(MultiLineComponent component) throws InvalidNumberException { + if (component.isEmpty()) return 0L; + if (component.size() > 1) throw new InvalidNumberException(component.toString()); + + try { + return Long.parseLong(component.getFirst().getString()); + } catch (NumberFormatException e) { + throw new InvalidNumberException(component.toString()); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/InvalidArgsException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/InvalidArgsException.java new file mode 100644 index 00000000000..2eec004295c --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/InvalidArgsException.java @@ -0,0 +1,10 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +import net.minecraft.network.chat.Component; + +public class InvalidArgsException extends PlaceholderException { + + public InvalidArgsException() { + super(Component.translatable("gtceu.computer_monitor_cover.error.invalid_args").getString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/InvalidNumberException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/InvalidNumberException.java new file mode 100644 index 00000000000..ca2a5895ebf --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/InvalidNumberException.java @@ -0,0 +1,10 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +import net.minecraft.network.chat.Component; + +public class InvalidNumberException extends PlaceholderException { + + public InvalidNumberException(String number) { + super(Component.translatable("gtceu.computer_monitor_cover.error.invalid_number", number).getString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/MissingItemException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/MissingItemException.java new file mode 100644 index 00000000000..fa31f6c7206 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/MissingItemException.java @@ -0,0 +1,10 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +import net.minecraft.network.chat.Component; + +public class MissingItemException extends PlaceholderException { + + public MissingItemException(String item, int slot) { + super(Component.translatable("gtceu.computer_monitor_cover.error.missing_item", item, slot).getString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/NoMENetworkException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/NoMENetworkException.java new file mode 100644 index 00000000000..aecc8cfeba4 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/NoMENetworkException.java @@ -0,0 +1,10 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +import net.minecraft.network.chat.Component; + +public class NoMENetworkException extends PlaceholderException { + + public NoMENetworkException() { + super(Component.translatable("gtceu.computer_monitor_cover.error.no_ae").getString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/NotEnoughArgsException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/NotEnoughArgsException.java new file mode 100644 index 00000000000..b12b30db941 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/NotEnoughArgsException.java @@ -0,0 +1,10 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +import net.minecraft.network.chat.Component; + +public class NotEnoughArgsException extends PlaceholderException { + + public NotEnoughArgsException(int expected, int got) { + super(Component.translatable("gtceu.computer_monitor_cover.error.not_enough_args", expected, got).getString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/NotSupportedException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/NotSupportedException.java new file mode 100644 index 00000000000..7218faaaf40 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/NotSupportedException.java @@ -0,0 +1,10 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +import net.minecraft.network.chat.Component; + +public class NotSupportedException extends PlaceholderException { + + public NotSupportedException() { + super(Component.translatable("gtceu.computer_monitor_cover.error.not_supported").getString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/OutOfRangeException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/OutOfRangeException.java new file mode 100644 index 00000000000..76c047abad7 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/OutOfRangeException.java @@ -0,0 +1,11 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +import net.minecraft.network.chat.Component; + +public class OutOfRangeException extends PlaceholderException { + + public OutOfRangeException(String what, int min, int max, int provided) { + super(Component.translatable("gtceu.computer_monitor_cover.error.not_in_range", what, min, max, provided) + .getString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/PlaceholderException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/PlaceholderException.java new file mode 100644 index 00000000000..30882b11f89 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/PlaceholderException.java @@ -0,0 +1,22 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +public class PlaceholderException extends Exception { + + private String message; + private int line = 0, symbol = 0; + + public PlaceholderException(String message) { + super(message); + this.message = message; + } + + public void setLineInfo(int line, int symbol) { + this.line = line; + this.symbol = symbol; + } + + @Override + public String getMessage() { + return "%d:%d: %s".formatted(line, symbol, message); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/UnclosedBracketException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/UnclosedBracketException.java new file mode 100644 index 00000000000..17ad606f6cc --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/UnclosedBracketException.java @@ -0,0 +1,10 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +import net.minecraft.network.chat.Component; + +public class UnclosedBracketException extends PlaceholderException { + + public UnclosedBracketException() { + super(Component.translatable("gtceu.computer_monitor_cover.error.unclosed_bracket").getString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/UnexpectedBracketException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/UnexpectedBracketException.java new file mode 100644 index 00000000000..df9db034f83 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/UnexpectedBracketException.java @@ -0,0 +1,10 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +import net.minecraft.network.chat.Component; + +public class UnexpectedBracketException extends RuntimeException { + + public UnexpectedBracketException() { + super(Component.translatable("gtceu.computer_monitor_cover.error.unexpected_bracket").getString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/UnknownPlaceholderException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/UnknownPlaceholderException.java new file mode 100644 index 00000000000..fc9efe4916b --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/UnknownPlaceholderException.java @@ -0,0 +1,10 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +import net.minecraft.network.chat.Component; + +public class UnknownPlaceholderException extends PlaceholderException { + + public UnknownPlaceholderException(String name) { + super(Component.translatable("gtceu.computer_monitor_cover.error.no_placeholder", name).getString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/WrongNumberOfArgsException.java b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/WrongNumberOfArgsException.java new file mode 100644 index 00000000000..88e3f6f6da2 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/placeholder/exceptions/WrongNumberOfArgsException.java @@ -0,0 +1,11 @@ +package com.gregtechceu.gtceu.api.placeholder.exceptions; + +import net.minecraft.network.chat.Component; + +public class WrongNumberOfArgsException extends PlaceholderException { + + public WrongNumberOfArgsException(int expected, int got) { + super(Component.translatable("gtceu.computer_monitor_cover.error.wrong_number_of_args", expected, got) + .getString()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java index 8d4f795f70f..9294b66e51e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ActionResult.java @@ -1,5 +1,8 @@ package com.gregtechceu.gtceu.api.recipe; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; + import net.minecraft.network.chat.Component; import org.jetbrains.annotations.Nullable; @@ -8,17 +11,18 @@ * @param isSuccess is action success * @param reason if fail, fail reason */ -public record ActionResult(boolean isSuccess, @Nullable Component reason) { +public record ActionResult(boolean isSuccess, @Nullable Component reason, @Nullable RecipeCapability capability, + @Nullable IO io) { - public final static ActionResult SUCCESS = new ActionResult(true, null); - public final static ActionResult FAIL_NO_REASON = new ActionResult(false, null); + public final static ActionResult SUCCESS = new ActionResult(true, null, null, null); + public final static ActionResult FAIL_NO_REASON = new ActionResult(false, null, null, null); public final static ActionResult PASS_NO_CONTENTS = new ActionResult(true, - Component.translatable("gtceu.recipe_logic.no_contents")); + Component.translatable("gtceu.recipe_logic.no_contents"), null, null); public final static ActionResult FAIL_NO_CAPABILITIES = new ActionResult(false, - Component.translatable("gtceu.recipe_logic.no_capabilities")); + Component.translatable("gtceu.recipe_logic.no_capabilities"), null, null); - public static ActionResult fail(@Nullable Component component) { - return new ActionResult(false, component); + public static ActionResult fail(@Nullable Component component, @Nullable RecipeCapability capability, IO io) { + return new ActionResult(false, component, capability, io); } public Component reason() { diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java index 8b7c0667dc1..d785583a1ed 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializer.java @@ -12,6 +12,7 @@ import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; @@ -119,6 +120,12 @@ public static RecipeCondition conditionReader(RegistryFriendlyByteBuf buf) { return condition.fromNetwork(buf); } + public static RecipeCondition conditionReader(FriendlyByteBuf buf) { + // Consume the condition key that's set in conditionWriter + buf.readUtf(); + return RecipeCondition.fromNetwork(buf); + } + public static void conditionWriter(RegistryFriendlyByteBuf buf, RecipeCondition condition) { buf.writeResourceLocation(GTRegistries.RECIPE_CONDITIONS.getKey(condition.getType())); condition.toNetwork(buf); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java index ec3ad677f88..c2b96b7a81c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/GTRecipeType.java @@ -99,6 +99,8 @@ public class GTRecipeType implements RecipeType { private final Map> researchEntries = new Object2ObjectOpenHashMap<>(); @Getter private final List customRecipeLogicRunners = new ArrayList<>(); + @Getter + private int minRecipeConditions = 0; public GTRecipeType(ResourceLocation registryName, String group, RecipeType... proxyRecipes) { this.registryName = registryName; @@ -181,6 +183,10 @@ public GTRecipeType addDataInfo(Function dataInfo) { return this; } + public void setMinRecipeConditions(int n) { + minRecipeConditions = Math.max(minRecipeConditions, n); + } + /** * * @param recipeLogic A function which is passed the normal findRecipe() result. Returns null if no valid recipe for diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/OverclockingLogic.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/OverclockingLogic.java index ef649a096a5..292f4464e56 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/OverclockingLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/OverclockingLogic.java @@ -346,7 +346,7 @@ public ModifierFunction toModifier() { .eutMultiplier(eutMultiplier) .durationMultiplier(durationMultiplier) .addOCs(ocLevel) - .parallels(parallels) + .subtickParallels(parallels) .build(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java index 2cc422b2aff..91eb75495ae 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeHelper.java @@ -15,6 +15,7 @@ import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.api.tag.TagUtil; import com.gregtechceu.gtceu.common.recipe.builder.GTRecipeBuilder; +import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.utils.GTUtil; import net.minecraft.core.registries.BuiltInRegistries; @@ -29,6 +30,7 @@ import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient; import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Reference2IntMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; import org.jetbrains.annotations.Contract; @@ -229,15 +231,15 @@ public static ActionResult handleRecipe(IRecipeCapabilityHolder holder, GTRecipe RecipeRunner runner = new RecipeRunner(recipe, io, isTick, holder, chanceCaches, simulated); var result = runner.handle(contents); - if (result.isSuccess() || result.capability() == null) return result.result(); + if (result.isSuccess() || result.capability() == null) return result; - if (!simulated) { + if (!simulated && ConfigHolder.INSTANCE.dev.debug) { GTCEu.LOGGER.warn("IO {} Error while handling recipe {} outputs for {}", Component.translatable(io.tooltip).getString(), recipe, holder); } String key = "gtceu.recipe_logic.insufficient_" + (io == IO.IN ? "in" : "out"); return ActionResult.fail(Component.translatable(key) - .append(": ").append(result.capability().getName())); + .append(": ").append(result.capability().getName()), result.capability(), io); } public static ActionResult matchContents(IRecipeCapabilityHolder holder, GTRecipe recipe) { @@ -263,7 +265,7 @@ public static ActionResult checkConditions(GTRecipe recipe, @NotNull RecipeLogic } else if (!condition.check(recipe, recipeLogic)) { return ActionResult.fail(Component.translatable("gtceu.recipe_logic.condition_fails") .append(": ") - .append(condition.getTooltips())); + .append(condition.getTooltips()), null, null); } } @@ -278,7 +280,7 @@ public static ActionResult checkConditions(GTRecipe recipe, @NotNull RecipeLogic } if (!passed) { - return ActionResult.fail(component); + return ActionResult.fail(component, null, null); } } return ActionResult.SUCCESS; @@ -289,7 +291,7 @@ public static ActionResult checkConditions(GTRecipe recipe, @NotNull RecipeLogic * Returns the recipe itself if no valid trim limits are passed */ @Contract(pure = true) - public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Object2IntMap> trimLimits) { + public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Reference2IntMap> trimLimits) { // Fast return early if no trimming desired if (trimLimits.isEmpty() || trimLimits.values().intStream().allMatch(integer -> integer == -1)) { return recipe; @@ -315,7 +317,7 @@ public static GTRecipe trimRecipeOutputs(GTRecipe recipe, Object2IntMap, List> doTrim(Map, List> current, - Object2IntMap> trimLimits) { + Reference2IntMap> trimLimits) { Map, List> outputs = new Reference2ObjectOpenHashMap<>(current.size()); for (var entry : current.entrySet()) { @@ -356,10 +358,16 @@ public static Map, List> doTrim(Map> map) { - // Add undyed RHL's to every group that's not distinct, and also the undyed group itself. + // If they should bypass this system, add them to the BYPASS_DISTINCT group. + if (handler.doesCapabilityBypassDistinct()) { + map.computeIfAbsent(RecipeHandlerGroupDistinctness.BYPASS_DISTINCT, $ -> new ArrayList<>()).add(handler); + return; + } + // Add undyed RHL's to every group that's not distinct, bypass, and also the undyed group itself. if (key.equals(RecipeHandlerGroupColor.UNDYED)) { for (var entry : map.entrySet()) { if (entry.getKey().equals(RecipeHandlerGroupDistinctness.BUS_DISTINCT) || + entry.getKey().equals(RecipeHandlerGroupDistinctness.BYPASS_DISTINCT) || entry.getKey().equals(RecipeHandlerGroupColor.UNDYED)) { continue; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java index 0f87814ef9d..9a3579a6c96 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/RecipeRunner.java @@ -3,8 +3,8 @@ import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.capability.recipe.IRecipeCapabilityHolder; import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; +import com.gregtechceu.gtceu.api.machine.feature.IVoidable; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerGroup; -import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerGroupDistinctness; import com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerList; import com.gregtechceu.gtceu.api.recipe.chance.boost.ChanceBoostFunction; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; @@ -14,26 +14,19 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Predicate; +import static com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerGroupDistinctness.BUS_DISTINCT; +import static com.gregtechceu.gtceu.api.machine.trait.RecipeHandlerGroupDistinctness.BYPASS_DISTINCT; import static com.gregtechceu.gtceu.api.recipe.RecipeHelper.addToRecipeHandlerMap; -class RecipeRunner { - - record RecipeHandlingResult(ActionResult result, @Nullable RecipeCapability capability) { - - public static RecipeHandlingResult SUCCESS = new RecipeHandlingResult(ActionResult.SUCCESS, null); - - public boolean isSuccess() { - return result.isSuccess(); - } - } +public class RecipeRunner { private final GTRecipe recipe; private final IO io; @@ -43,6 +36,7 @@ public boolean isSuccess() { private final boolean simulated; private Map, List> recipeContents; private final Map, List> searchRecipeContents; + private final Predicate> outputVoid; public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, IRecipeCapabilityHolder holder, Map, Object2IntMap> chanceCaches, @@ -55,14 +49,15 @@ public RecipeRunner(GTRecipe recipe, IO io, boolean isTick, this.recipeContents = new Reference2ObjectOpenHashMap<>(); this.searchRecipeContents = simulated ? recipeContents : new Reference2ObjectOpenHashMap<>(); this.simulated = simulated; + this.outputVoid = cap -> holder instanceof IVoidable voidable && voidable.canVoidRecipeOutputs(cap); } @NotNull - public RecipeHandlingResult handle(Map, List> entries) { + public ActionResult handle(Map, List> entries) { fillContentMatchList(entries); if (searchRecipeContents.isEmpty()) { - return new RecipeHandlingResult(ActionResult.PASS_NO_CONTENTS, null); + return ActionResult.PASS_NO_CONTENTS; } return this.handleContents(); @@ -78,6 +73,7 @@ private void fillContentMatchList(Map, List> entrie for (var entry : entries.entrySet()) { RecipeCapability cap = entry.getKey(); if (!cap.doMatchInRecipe()) continue; + if (simulated && io == IO.OUT && outputVoid.test(cap)) continue; ChanceLogic logic = recipe.getChanceLogicForCapability(cap, this.io, this.isTick); List chancedContents = new ArrayList<>(); @@ -95,16 +91,17 @@ private void fillContentMatchList(Map, List> entrie if (cont.chance >= cont.maxChance) { contentList.add(cont.content); - } else { + } else if (cont.chance > 0 || cont.tierChanceBoost > 0) { chancedContents.add(cont); } + // Do not add Non-Consumed ingredients; they'd just get dropped after the chance roll anyway } // add chanced contents to the recipe content map if (!chancedContents.isEmpty()) { var cache = this.chanceCaches.get(cap); - chancedContents = logic.roll(chancedContents, function, recipeTier, chanceTier, cache, - recipe.parallels * recipe.batchParallels); + chancedContents = logic.roll(cap, chancedContents, function, recipeTier, chanceTier, cache, + recipe.getTotalRuns()); for (Content cont : chancedContents) { contentList.add(cont.content); @@ -115,20 +112,15 @@ private void fillContentMatchList(Map, List> entrie } } - private RecipeHandlingResult handleContents() { - var result = handleContentsInternal(io); - return result; - } - - private RecipeHandlingResult handleContentsInternal(IO capIO) { - if (recipeContents.isEmpty()) return RecipeHandlingResult.SUCCESS; - if (!capabilityProxies.containsKey(capIO)) { - return new RecipeHandlingResult(ActionResult.FAIL_NO_CAPABILITIES, null); + private ActionResult handleContents() { + if (recipeContents.isEmpty()) return ActionResult.SUCCESS; + if (!capabilityProxies.containsKey(io)) { + return ActionResult.FAIL_NO_CAPABILITIES; } - List handlers = capabilityProxies.getOrDefault(capIO, Collections.emptyList()); + List handlers = capabilityProxies.getOrDefault(io, Collections.emptyList()); // Only sort for non-tick outputs - if (!isTick && capIO.support(IO.OUT)) { + if (!isTick && io.support(IO.OUT)) { handlers.sort(RecipeHandlerList.COMPARATOR.reversed()); } @@ -137,51 +129,121 @@ private RecipeHandlingResult handleContentsInternal(IO capIO) { addToRecipeHandlerMap(handler.getGroup(), handler, handlerGroups); } // Specifically check distinct handlers first - for (RecipeHandlerList handler : handlerGroups.getOrDefault(RecipeHandlerGroupDistinctness.BUS_DISTINCT, - Collections.emptyList())) { + for (RecipeHandlerList handler : handlerGroups.getOrDefault(BUS_DISTINCT, Collections.emptyList())) { + // Handle the contents of this handler and also all the bypassed handlers var res = handler.handleRecipe(io, recipe, searchRecipeContents, true); - if (res.isEmpty()) { - if (!simulated) { - handler.handleRecipe(io, recipe, recipeContents, false); + if (!res.isEmpty()) { + for (RecipeHandlerList bypassHandler : handlerGroups.getOrDefault(BYPASS_DISTINCT, + Collections.emptyList())) { + res = bypassHandler.handleRecipe(io, recipe, res, true); + if (res.isEmpty()) break; } - recipeContents.clear(); - return RecipeHandlingResult.SUCCESS; } + if (io == IO.OUT) { + if (hasAnyNonVoidingContents(res)) continue; + } else if (io == IO.IN) { + if (!res.isEmpty()) continue; + } + if (!simulated) { + // Actually consume the contents of this handler and also all the bypassed handlers + recipeContents = handler.handleRecipe(io, recipe, recipeContents, false); + if (!recipeContents.isEmpty()) { + for (RecipeHandlerList bypassHandler : handlerGroups.getOrDefault(BYPASS_DISTINCT, + Collections.emptyList())) { + recipeContents = bypassHandler.handleRecipe(io, recipe, recipeContents, false); + if (recipeContents.isEmpty()) break; + } + } + } + recipeContents.clear(); + return ActionResult.SUCCESS; } - // Check the others + // Check the other groups. For every group, try consuming the ingredients, + // see if it succeeds. for (Map.Entry> handlerListEntry : handlerGroups.entrySet()) { - if (handlerListEntry.getKey() == RecipeHandlerGroupDistinctness.BUS_DISTINCT) continue; + if (handlerListEntry.getKey().equals(BUS_DISTINCT)) continue; // List to keep track of the remaining items for this RecipeHandlerGroup Map, List> copiedRecipeContents = searchRecipeContents; - boolean found = false; + for (RecipeHandlerList handler : handlerListEntry.getValue()) { copiedRecipeContents = handler.handleRecipe(io, recipe, copiedRecipeContents, true); if (copiedRecipeContents.isEmpty()) { - found = true; break; } } - if (!found) continue; - if (simulated) return RecipeHandlingResult.SUCCESS; - // Start actually removing items, keep track of the remaining items for this RecipeHandlerGroup - copiedRecipeContents = recipeContents; + // If we're already in the bypass_distinct group, don't check it twice. + if (!handlerListEntry.getKey().equals(BYPASS_DISTINCT)) { + for (RecipeHandlerList bypassHandler : handlerGroups.getOrDefault(BYPASS_DISTINCT, + Collections.emptyList())) { + copiedRecipeContents = bypassHandler.handleRecipe(io, recipe, copiedRecipeContents, true); + if (copiedRecipeContents.isEmpty()) { + break; + } + } + } + + if (io == IO.OUT) { + if (hasAnyNonVoidingContents(copiedRecipeContents)) continue; + } else if (io == IO.IN) { + if (!copiedRecipeContents.isEmpty()) continue; + } + if (simulated) return ActionResult.SUCCESS; + // Start actually removing items. + // Keep track of the remaining items for this RecipeHandlerGroup + // First go through the handlers of the group for (RecipeHandlerList handler : handlerListEntry.getValue()) { - copiedRecipeContents = handler.handleRecipe(io, recipe, copiedRecipeContents, false); - if (copiedRecipeContents.isEmpty()) { - recipeContents.clear(); - return RecipeHandlingResult.SUCCESS; + recipeContents = handler.handleRecipe(io, recipe, recipeContents, false); + if (recipeContents.isEmpty()) { + return ActionResult.SUCCESS; + } + } + // Then go through the handlers that bypass the distinctness system and empty those + // If we're already in the bypass_distinct group, don't check it twice. + if (!handlerListEntry.getKey().equals(BYPASS_DISTINCT)) { + for (RecipeHandlerList bypassHandler : handlerGroups.getOrDefault(BYPASS_DISTINCT, + Collections.emptyList())) { + recipeContents = bypassHandler.handleRecipe(io, recipe, recipeContents, false); + if (recipeContents.isEmpty()) { + return ActionResult.SUCCESS; + } } } } for (var entry : recipeContents.entrySet()) { + // void excess real output contents if it can be voided + if (!simulated && io == IO.OUT && this.outputVoid.test(entry.getKey())) { + entry.getValue().clear(); + } if (entry.getValue() != null && !entry.getValue().isEmpty()) { - return new RecipeHandlingResult(ActionResult.FAIL_NO_REASON, entry.getKey()); + return ActionResult.fail(null, entry.getKey(), io); + } + } + + // if, post voiding, we don't have stuff, pass instead of fail + boolean containsStuff = false; + for (var entry : recipeContents.entrySet()) { + if (!entry.getValue().isEmpty()) { + containsStuff = true; + break; } } + if (!containsStuff) { + return ActionResult.PASS_NO_CONTENTS; + } - return new RecipeHandlingResult(ActionResult.FAIL_NO_REASON, null); + return ActionResult.FAIL_NO_REASON; + } + + private boolean hasAnyNonVoidingContents(Map, List> contents) { + for (var entry : contents.entrySet()) { + if (outputVoid.test(entry.getKey())) continue; + if (!(entry.getValue() == null || entry.getValue().isEmpty())) { + return true; + } + } + return false; } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ResearchRecipeBuilder.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ResearchRecipeBuilder.java index 8d78bd8b1f1..68b6099e34c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ResearchRecipeBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ResearchRecipeBuilder.java @@ -1,6 +1,7 @@ package com.gregtechceu.gtceu.api.recipe; import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.recipe.ingredient.EnergyStack; import com.gregtechceu.gtceu.common.recipe.builder.GTRecipeBuilder; import com.gregtechceu.gtceu.data.item.GTDataComponents; import com.gregtechceu.gtceu.utils.GTStringUtils; @@ -19,7 +20,7 @@ public abstract class ResearchRecipeBuilder> protected FluidStack fluidResearchStack = FluidStack.EMPTY; protected ItemStack dataStack; protected String researchId; - protected int eut; + protected EnergyStack eut; public T researchStack(@NotNull ItemStack researchStack) { if (!researchStack.isEmpty()) { @@ -47,8 +48,12 @@ public T researchId(String researchId) { return (T) this; } - public T EUt(int eut) { - this.eut = eut; + public T EUt(long eut) { + return EUt(eut, 1); + } + + public T EUt(long eut, long amperage) { + this.eut = new EnergyStack(eut, amperage); return (T) this; } @@ -100,7 +105,7 @@ public ItemStack getDefaultDataItem() { public GTRecipeBuilder.ResearchRecipeEntry build() { validateResearchItem(); if (duration <= 0) duration = DEFAULT_SCANNER_DURATION; - if (eut <= 0) eut = DEFAULT_SCANNER_EUT; + if (eut == null || eut.voltage() <= 0) eut = new EnergyStack(DEFAULT_SCANNER_EUT, 1); return new GTRecipeBuilder.ResearchRecipeEntry(researchId, itemResearchStack, fluidResearchStack, dataStack, duration, eut, 0); } @@ -147,7 +152,7 @@ public GTRecipeBuilder.ResearchRecipeEntry build() { // "duration" is the total CWU/t. // Not called duration in API because logic does not treat it like normal duration. int duration = totalCWU; - if (eut <= 0) eut = DEFAULT_STATION_EUT; + if (eut == null || eut.voltage() <= 0) eut = new EnergyStack(DEFAULT_STATION_EUT, 1); return new GTRecipeBuilder.ResearchRecipeEntry(researchId, itemResearchStack, fluidResearchStack, dataStack, duration, eut, cwut); diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/category/GTRecipeCategory.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/category/GTRecipeCategory.java index 6966beb6a58..64eff587fb1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/category/GTRecipeCategory.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/category/GTRecipeCategory.java @@ -48,7 +48,7 @@ public GTRecipeCategory(@NotNull String categoryName, @NotNull GTRecipeType reci this.recipeType = recipeType; this.name = categoryName; this.registryKey = GTCEu.id(categoryName); - this.languageKey = "recipe_category.%s.%s".formatted(GTCEu.MOD_ID, categoryName); + this.languageKey = "%s.recipe.category.%s".formatted(GTCEu.MOD_ID, categoryName); } public static GTRecipeCategory registerDefault(@NotNull GTRecipeType recipeType) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/chance/logic/ChanceLogic.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/chance/logic/ChanceLogic.java index 6c03153fe19..ef40f4c689e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/chance/logic/ChanceLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/chance/logic/ChanceLogic.java @@ -2,8 +2,10 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.recipe.chance.boost.ChanceBoostFunction; import com.gregtechceu.gtceu.api.recipe.content.Content; +import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; import com.gregtechceu.gtceu.api.registry.GTRegistries; import net.minecraft.network.chat.Component; @@ -32,10 +34,10 @@ public abstract class ChanceLogic { public static final ChanceLogic OR = new ChanceLogic("or") { @Override - public @Unmodifiable List<@NotNull Content> roll(@NotNull @Unmodifiable List<@NotNull Content> chancedEntries, - @NotNull ChanceBoostFunction boostFunction, - int recipeTier, int chanceTier, - @Nullable Object2IntMap cache, int times) { + public @Unmodifiable List<@NotNull Content> roll(RecipeCapability cap, + @NotNull @Unmodifiable List<@NotNull Content> chancedEntries, + @NotNull ChanceBoostFunction boostFunction, int recipeTier, + int chanceTier, @Nullable Object2IntMap cache, int times) { ImmutableList.Builder builder = ImmutableList.builder(); for (Content entry : chancedEntries) { int maxChance = entry.maxChance; @@ -46,7 +48,7 @@ public abstract class ChanceLogic { int newChance = getChance(entry, boostFunction, recipeTier, chanceTier); int totalChance = times * newChance; int guaranteed = totalChance / maxChance; - if (guaranteed > 0) builder.addAll(Collections.nCopies(guaranteed, entry)); + if (guaranteed > 0) builder.add(entry.copyChanced(cap, ContentModifier.multiplier(guaranteed))); newChance = totalChance % maxChance; int cached = getCachedChance(entry, cache); @@ -78,10 +80,10 @@ public String toString() { public static final ChanceLogic AND = new ChanceLogic("and") { @Override - public @Unmodifiable List<@NotNull Content> roll(@NotNull @Unmodifiable List<@NotNull Content> chancedEntries, - @NotNull ChanceBoostFunction boostFunction, - int recipeTier, int chanceTier, - @Nullable Object2IntMap cache, int times) { + public @Unmodifiable List<@NotNull Content> roll(RecipeCapability cap, + @NotNull @Unmodifiable List<@NotNull Content> chancedEntries, + @NotNull ChanceBoostFunction boostFunction, int recipeTier, + int chanceTier, @Nullable Object2IntMap cache, int times) { ImmutableList.Builder builder = ImmutableList.builder(); for (int i = 0; i < times; ++i) { boolean failed = false; @@ -112,14 +114,16 @@ public String toString() { /** * Chanced Output Logic where only the first ingredient succeeding its roll will be produced + * Deprecated following the rewrite of XOR */ + @Deprecated public static final ChanceLogic FIRST = new ChanceLogic("first") { @Override - public @Unmodifiable List<@NotNull Content> roll(@NotNull @Unmodifiable List<@NotNull Content> chancedEntries, - @NotNull ChanceBoostFunction boostFunction, - int recipeTier, int chanceTier, - @Nullable Object2IntMap cache, int times) { + public @Unmodifiable List<@NotNull Content> roll(RecipeCapability cap, + @NotNull @Unmodifiable List<@NotNull Content> chancedEntries, + @NotNull ChanceBoostFunction boostFunction, int recipeTier, + int chanceTier, @Nullable Object2IntMap cache, int times) { ImmutableList.Builder builder = ImmutableList.builder(); for (int i = 0; i < times; ++i) { Content selected = null; @@ -156,10 +160,10 @@ public String toString() { public static final ChanceLogic XOR = new ChanceLogic("xor") { @Override - public @Unmodifiable List<@NotNull Content> roll(@NotNull @Unmodifiable List<@NotNull Content> chancedEntries, - @NotNull ChanceBoostFunction boostFunction, - int recipeTier, int chanceTier, - @Nullable Object2IntMap cache, int times) { + public @Unmodifiable List<@NotNull Content> roll(RecipeCapability cap, + @NotNull @Unmodifiable List<@NotNull Content> chancedEntries, + @NotNull ChanceBoostFunction boostFunction, int recipeTier, + int chanceTier, @Nullable Object2IntMap cache, int times) { // Have to set up a system where all chances are set to be out of 10000 IntList chancesOutOfTenThousand = new IntArrayList(); @@ -201,7 +205,21 @@ public String toString() { // Use the new, normalized list for the logic ImmutableList.Builder builder = ImmutableList.builder(); - for (int i = 0; i < times; ++i) { + // for high run counts: calculate guaranteed rolls + int nonGuaranteedTimes = times; + if (times > 1) { + for (Content entry : normalizedEntries) { + int newChance = getChance(entry, boostFunction, recipeTier, chanceTier); + int totalChance = times * newChance; + int guaranteed = totalChance / 10000; + if (guaranteed > 0) { + builder.add(entry.copyChanced(cap, ContentModifier.multiplier(guaranteed))); + nonGuaranteedTimes -= guaranteed; + } + } + } + // roll for non-guaranteed + for (int i = 0; i < nonGuaranteedTimes; ++i) { Content selected = null; int maxChance = getMaxChancedValue(); for (Content entry : normalizedEntries) { @@ -238,10 +256,10 @@ public String toString() { public static final ChanceLogic NONE = new ChanceLogic("none") { @Override - public @Unmodifiable List<@NotNull Content> roll(@NotNull @Unmodifiable List<@NotNull Content> chancedEntries, - @NotNull ChanceBoostFunction boostFunction, - int recipeTier, int chanceTier, - @Nullable Object2IntMap cache, int times) { + public @Unmodifiable List<@NotNull Content> roll(RecipeCapability cap, + @NotNull @Unmodifiable List<@NotNull Content> chancedEntries, + @NotNull ChanceBoostFunction boostFunction, int recipeTier, + int chanceTier, @Nullable Object2IntMap cache, int times) { return Collections.emptyList(); } @@ -322,11 +340,11 @@ static void updateCachedChance(Object ingredient, @Nullable Object2IntMap cac * @param times the number of times to roll * @return a list of the produced outputs, empty if roll fails */ - public abstract @Unmodifiable List<@NotNull Content> roll(@NotNull @Unmodifiable List<@NotNull Content> chancedEntries, + public abstract @Unmodifiable List<@NotNull Content> roll(RecipeCapability cap, + @NotNull @Unmodifiable List<@NotNull Content> chancedEntries, @NotNull ChanceBoostFunction boostFunction, - int recipeTier, - int chanceTier, @Nullable Object2IntMap cache, - int times); + int recipeTier, int chanceTier, + @Nullable Object2IntMap cache, int times); /** * Roll the chance and attempt to produce the output @@ -339,10 +357,11 @@ static void updateCachedChance(Object ingredient, @Nullable Object2IntMap cac * @return a list of the produced outputs */ @Unmodifiable - public List<@NotNull Content> roll(@NotNull @Unmodifiable List<@NotNull Content> chancedEntries, + public List<@NotNull Content> roll(RecipeCapability cap, + @NotNull @Unmodifiable List<@NotNull Content> chancedEntries, @NotNull ChanceBoostFunction boostFunction, int recipeTier, int chanceTier, int times) { - return roll(chancedEntries, boostFunction, recipeTier, chanceTier, null, times); + return roll(cap, chancedEntries, boostFunction, recipeTier, chanceTier, null, times); } @NotNull diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/condition/ConditionSerializeUtils.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/condition/ConditionSerializeUtils.java new file mode 100644 index 00000000000..8748391036d --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/condition/ConditionSerializeUtils.java @@ -0,0 +1,150 @@ +package com.gregtechceu.gtceu.api.recipe.condition; + +import com.gregtechceu.gtceu.api.registry.GTRegistries; + +import net.minecraft.core.Holder; +import net.minecraft.core.HolderSet; +import net.minecraft.core.Registry; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.Fluids; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +public class ConditionSerializeUtils { + + /** + * Encode a List> to a string encoding. + * HolderSets are separated by '|', and elements of a direct HolderSet are separated by ','. + * + * @param items The list of HolderSet to be encoded. + * @return A string encoding. + */ + public static String encodeHolderSets(List> items) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + + for (HolderSet holderSet : items) { + if (!first) { + sb.append("|"); + } + sb.append(encodeHolderSet(holderSet)); + first = false; + } + + return sb.toString(); + } + + /** + * Encode a single HolderSet to a string. + * If it's a tag, it's encoded as #+location. + * If it's a direct list, elements are separated by ','. + * + * @param holderSet The HolderSet to be encoded. + * @return The encoded string. + */ + public static String encodeHolderSet(HolderSet holderSet) { + return holderSet.unwrap().map( + // Case 1: Tag + tagKey -> "#" + tagKey.location(), + // Case 2: Direct list of holders + holders -> holders.stream() + .map(holder -> getStringFromHolder(holder)) + .collect(Collectors.joining(","))); + } + + /** + * Encode a Holder into a String. + * + * @param holder The Holder to be encoded. + * @return A string encoding (location or #+tag_location). + * @throws RuntimeException if the holder cannot be serialized. + */ + public static String getStringFromHolder(Holder holder) { + Optional> keyOpt = holder.unwrapKey(); + if (keyOpt.isPresent()) { + return keyOpt.get().location().toString(); + } + + Optional> tagOpt = holder.tags().findFirst(); + if (tagOpt.isPresent()) { + return "#" + tagOpt.get().location(); + } + throw new RuntimeException("Could not serialize holder: " + holder); + } + + /** + * Decode a string into a List>. + * + * @param encodedString The string encoding. + * @param registryKey The ResourceKey of the registry. + * @return The decoded list of HolderSet. + */ + public static List> decodeHolderSets(String encodedString, + ResourceKey> registryKey) { + List> result = new ArrayList<>(); + for (String token : encodedString.split("\\|")) { + if (!token.isBlank()) { + result.add(decodeSingleHolderSet(token, registryKey)); + } + } + return result; + } + + /** + * Decode a string into a HolderSet. + * + * @param encodedSet The encoded set string. + * @param registryKey The ResourceKey of the registry. + * @return The decoded HolderSet. + * @throws RuntimeException if an unknown ID is encountered. + */ + public static HolderSet decodeSingleHolderSet(String encodedSet, + ResourceKey> registryKey) { + encodedSet = encodedSet.trim(); + if (encodedSet.isEmpty()) { + return HolderSet.direct(List.of()); + } + + Registry registry = GTRegistries.builtinRegistry().registry(registryKey).get(); // Use the helper + + // Case 1: Tag-based holder set + if (encodedSet.startsWith("#")) { + ResourceLocation tagId = ResourceLocation.parse(encodedSet.substring(1)); + TagKey tagKey = TagKey.create(registryKey, tagId); + return registry.getOrCreateTag(tagKey); + } + + // Case 2: Direct list of items + String[] parts = encodedSet.split(","); + List> holders = new ArrayList<>(); + for (String part : parts) { + ResourceLocation rl = ResourceLocation.parse(part.trim()); + T item = registry.get(rl); + if (item != null && item != getDefaultEmptyValue(registryKey)) { // Use a generic default empty check + holders.add(registry.wrapAsHolder(item)); + } else { + throw new RuntimeException("Unknown ID for registry " + registryKey.location() + ": " + rl); + } + } + return HolderSet.direct(holders); + } + + // Helper to get the default "empty" value for a registry type + private static T getDefaultEmptyValue(ResourceKey> registryKey) { + // Compare ResourceLocation directly instead of ResourceKey objects + if (registryKey.location().equals(Registries.FLUID.location())) { + return (T) Fluids.EMPTY; + } else if (registryKey.location().equals(Registries.BLOCK.location())) { + return (T) Blocks.AIR; + } + throw new IllegalArgumentException( + "Unsupported registry type for default value lookup: " + registryKey.location()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/condition/RecipeCondition.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/condition/RecipeCondition.java index cc57c278f33..2db63f5a3cb 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/condition/RecipeCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/condition/RecipeCondition.java @@ -7,13 +7,21 @@ import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; -import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.resources.RegistryOps; +import net.minecraft.util.GsonHelper; +import com.google.gson.Gson; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.mojang.datafixers.Products; import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.JsonOps; import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.handler.codec.DecoderException; +import io.netty.handler.codec.EncoderException; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; @@ -73,20 +81,30 @@ public boolean check(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) public abstract RecipeCondition createTemplate(); @NotNull - public JsonObject serialize() { - JsonObject jsonObject = new JsonObject(); - if (isReverse) { - jsonObject.addProperty("reverse", true); - } - return jsonObject; + public final JsonObject serialize() { + var ops = RegistryOps.create(JsonOps.INSTANCE, GTRegistries.builtinRegistry()); + return CODEC.encodeStart(ops, this).getOrThrow().getAsJsonObject(); } - public void toNetwork(RegistryFriendlyByteBuf buf) { - buf.writeBoolean(isReverse); + public static RecipeCondition deserialize(@NotNull JsonObject config) { + var ops = RegistryOps.create(JsonOps.INSTANCE, GTRegistries.builtinRegistry()); + return CODEC.decode(ops, config).getOrThrow().getFirst(); } - public RecipeCondition fromNetwork(RegistryFriendlyByteBuf buf) { - isReverse = buf.readBoolean(); - return this; + public final void toNetwork(FriendlyByteBuf buf) { + var ops = RegistryOps.create(JsonOps.INSTANCE, GTRegistries.builtinRegistry()); + // Code below was taken from buf.writeJsonWithCodec to include our RegistryOps + DataResult dataresult = CODEC.encodeStart(ops, this); + buf.writeUtf(new Gson().toJson((JsonElement) dataresult.getOrThrow( + (p_261421_) -> new EncoderException("Failed to encode: " + p_261421_ + " " + String.valueOf(this))))); + } + + public static RecipeCondition fromNetwork(FriendlyByteBuf buf) { + var ops = RegistryOps.create(JsonOps.INSTANCE, GTRegistries.builtinRegistry()); + // Code below was taken from buf.readJsonWithCodec to include our RegistryOps + JsonElement jsonelement = (JsonElement) GsonHelper.fromJson(new Gson(), buf.readUtf(), JsonElement.class); + DataResult> dataresult = CODEC.parse(ops, jsonelement); + return (RecipeCondition) dataresult.getOrThrow( + (p_272382_) -> new DecoderException("Failed to decode json: " + p_272382_)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java index 6fd7ee037c8..59862e931dd 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/content/Content.java @@ -54,10 +54,16 @@ public static Codec codec(RecipeCapability capability) { // spotless:on } + /** + * Directly copies a Content. + */ public Content copy(RecipeCapability capability) { return new Content(capability.copyContent(content), chance, maxChance, tierChanceBoost); } + /** + * Applies a {@link ContentModifier} to a Content. Does not apply the Modifier if the Content has a Chance. + */ public Content copy(RecipeCapability capability, @NotNull ContentModifier modifier) { if (modifier == ContentModifier.IDENTITY || chance < maxChance) { return copy(capability); @@ -66,6 +72,17 @@ public Content copy(RecipeCapability capability, @NotNull ContentModifier mod } } + /** + * Applies a {@link ContentModifier} to a Content. Even if the content has a Chance. + */ + public Content copyChanced(RecipeCapability capability, @NotNull ContentModifier modifier) { + if (modifier == ContentModifier.IDENTITY) { + return copy(capability); + } else { + return new Content(capability.copyContent(content, modifier), chance, maxChance, tierChanceBoost); + } + } + public boolean isChanced() { return chance > 0 && chance < maxChance; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java new file mode 100644 index 00000000000..3ec2895d9cc --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IRangedIngredient.java @@ -0,0 +1,43 @@ +package com.gregtechceu.gtceu.api.recipe.ingredient; + +import com.gregtechceu.gtceu.api.GTValues; + +import net.minecraft.util.RandomSource; +import net.minecraft.util.valueproviders.IntProvider; + +import org.jetbrains.annotations.NotNull; + +public interface IRangedIngredient { + + IntProvider getCountProvider(); + + int getSampledCount(); + + void setSampledCount(int count); + + /** + * If this ingredient has not yet had its count rolled, rolls it and returns the roll. + * If it has, returns the existing roll. + * Passthrough method, invokes {@code rollSampledCount()} using the threadsafe {@link GTValues#RNG}. + * + * @return the amount rolled + */ + default int rollSampledCount() { + return rollSampledCount(GTValues.RNG); + } + + int rollSampledCount(@NotNull RandomSource random); + + /** + * @return the average roll of this ranged amount + */ + default double getMidRoll() { + return ((getCountProvider().getMaxValue() + getCountProvider().getMinValue()) / 2.0); + } + + default boolean isRolled() { + return getSampledCount() != -1; + } + + void reset(); +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java index dca32948f01..de386e36378 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredient.java @@ -1,15 +1,19 @@ package com.gregtechceu.gtceu.api.recipe.ingredient; import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.tag.GTIngredientTypes; import net.minecraft.util.RandomSource; import net.minecraft.util.valueproviders.IntProvider; import net.minecraft.util.valueproviders.UniformInt; +import net.neoforged.neoforge.common.util.NeoForgeExtraCodecs; import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.FluidType; import net.neoforged.neoforge.fluids.crafting.FluidIngredient; import net.neoforged.neoforge.fluids.crafting.FluidIngredientType; +import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import lombok.Getter; @@ -19,30 +23,51 @@ import java.util.stream.Stream; -public class IntProviderFluidIngredient extends FluidIngredient { +/** + * Allows a {@link FluidIngredient} to be created with a ranged {@code amount}, which will be randomly rolled upon + * recipe start (input) / completion (output). + * Instantiated using {@link IntProviderFluidIngredient#of()}, with a {@link FluidIngredient} + * and either an {@link IntProvider} or {@code int, int} range bounds (inclusive). + * Functions similarly to {@link IntProviderIngredient}. + */ +public class IntProviderFluidIngredient extends FluidIngredient implements IRangedIngredient { - // spotless: public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance .group( FluidIngredient.CODEC.fieldOf("inner").forGetter(IntProviderFluidIngredient::getInner), - IntProvider.CODEC.fieldOf("count_provider").forGetter(IntProviderFluidIngredient::getCountProvider)) + IntProvider.CODEC.fieldOf("count_provider").forGetter(IntProviderFluidIngredient::getCountProvider), + NeoForgeExtraCodecs.optionalFieldAlwaysWrite(Codec.INT, "sampledCount", FluidType.BUCKET_VOLUME) + .forGetter(IRangedIngredient::getSampledCount)) .apply(instance, IntProviderFluidIngredient::new)); - // spotless: + public static final FluidStack[] EMPTY_STACK_ARRAY = new FluidStack[0]; @Getter private final IntProvider countProvider; + /** + * The last result of {@link IntProviderFluidIngredient#rollSampledCount()}. -1 if not rolled. + */ + @Getter @Setter protected int sampledCount = -1; + /** + * The {@link FluidIngredient} to have a ranged amount. + */ @Getter private final FluidIngredient inner; @Setter - protected @NotNull FluidStack @Nullable [] fluidStacks = null; + protected FluidStack @Nullable [] fluidStacks = null; protected IntProviderFluidIngredient(FluidIngredient inner, IntProvider provider) { this.inner = inner; this.countProvider = provider; } + protected IntProviderFluidIngredient(FluidIngredient inner, IntProvider provider, int sampledCount) { + this.inner = inner; + this.countProvider = provider; + this.sampledCount = sampledCount; + } + public IntProviderFluidIngredient copy() { IntProviderFluidIngredient copied = new IntProviderFluidIngredient(this.inner, this.countProvider); copied.setSampledCount(this.sampledCount); @@ -50,11 +75,57 @@ public IntProviderFluidIngredient copy() { return copied; } - public FluidStack[] getFluids() { + /** + * An {@link IntProviderFluidIngredient} does not have an amount. + * You probably want either {@link IntProviderFluidIngredient#getStacks()} or + * {@link IntProviderFluidIngredient#getMaxSizeStack()}. + */ + @Deprecated + public int getAmount() { + if (ConfigHolder.INSTANCE.dev.debug) { + throw new IllegalCallerException("An IPFI should never have getAmount() called on it!"); + } + return -1; + } + + /** + * Gets a usable {@link FluidStack FluidStack[]} from this {@link IntProviderFluidIngredient}. + * If this ingredient has not yet had its {@link IntProviderFluidIngredient#sampledCount} rolled, rolls it. + * + * @return a {@link FluidStack FluidStack[]} with amount {@link IntProviderFluidIngredient#sampledCount} + */ + @Override + public Stream generateStacks() { if (fluidStacks == null) { - fluidStacks = inner.getStacks(); + int cachedAmount = rollSampledCount(GTValues.RNG); + if (cachedAmount == 0) { + return Stream.of(EMPTY_STACK_ARRAY); + } + var innerStacks = inner.getStacks(); + this.fluidStacks = new FluidStack[innerStacks.length]; for (int i = 0; i < fluidStacks.length; i++) { - fluidStacks[i] = fluidStacks[i].copyWithAmount(getSampledCount(GTValues.RNG)); + fluidStacks[i] = innerStacks[i].copyWithAmount(cachedAmount); + } + } + return Stream.of(fluidStacks); + } + + /** + * Gets a usable {@link FluidStack FluidStack[]} from this {@link IntProviderFluidIngredient}. + * If this ingredient has not yet had its {@link IntProviderFluidIngredient#sampledCount} rolled, rolls it. + * + * @return a {@link FluidStack FluidStack[]} with amount {@link IntProviderFluidIngredient#sampledCount} + */ + public FluidStack[] getFluidStacks() { + if (fluidStacks == null) { + int cachedAmount = rollSampledCount(GTValues.RNG); + if (cachedAmount == 0) { + return EMPTY_STACK_ARRAY; + } + var innerStacks = inner.getStacks(); + this.fluidStacks = new FluidStack[innerStacks.length]; + for (int i = 0; i < fluidStacks.length; i++) { + fluidStacks[i] = innerStacks[i].copyWithAmount(cachedAmount); } } return fluidStacks; @@ -65,11 +136,6 @@ public boolean test(@NotNull FluidStack stack) { return inner.test(stack); } - @Override - protected Stream generateStacks() { - return Stream.empty(); - } - @Override public boolean isSimple() { return false; @@ -80,13 +146,28 @@ public FluidIngredientType getType() { return GTIngredientTypes.INT_PROVIDER_FLUID_INGREDIENT.get(); } + /** + * Gets a {@link FluidStack} containing the maximum possible output from this {@link IntProviderFluidIngredient}. + * Mainly used for things like Recipe provider simulations to see if there is enough tank space to handle + * the recipe output. + * + * @return a {@link FluidStack} with amount {@link IntProvider#getMaxValue()} + */ public @NotNull FluidStack getMaxSizeStack() { FluidStack[] in = inner.getStacks(); if (in.length == 0) return FluidStack.EMPTY; return in[0].copyWithAmount(countProvider.getMaxValue()); } - public int getSampledCount(@NotNull RandomSource random) { + /** + * If this ingredient has not yet had its {@link IntProviderFluidIngredient#sampledCount} rolled, rolls it and + * returns the roll. + * If it has, returns the existing roll. + * + * @param random {@link RandomSource}, must be threadsafe, usually called using {@link GTValues#RNG}. + * @return the amount rolled + */ + public int rollSampledCount(@NotNull RandomSource random) { if (sampledCount == -1) { sampledCount = countProvider.sample(random); } @@ -95,7 +176,7 @@ public int getSampledCount(@NotNull RandomSource random) { @Override public int hashCode() { - return this.inner.hashCode() * 31 * this.countProvider.hashCode(); + return this.inner.hashCode();// * 31 * this.countProvider.hashCode(); } @Override @@ -114,6 +195,19 @@ public static boolean intProviderEqual(IntProvider o1, IntProvider o2) { return o1.getMinValue() == o2.getMinValue() && o1.getMaxValue() == o2.getMaxValue(); } + /** + * Resets the random roll on this ingredient + */ + @Override + public void reset() { + sampledCount = -1; + fluidStacks = null; + } + + /** + * @param inner {@link FluidIngredient} + * @param provider usually as {@link UniformInt#of(int, int)} + */ public static IntProviderFluidIngredient of(FluidIngredient inner, IntProvider provider) { return new IntProviderFluidIngredient(inner, provider); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java index d861ee41157..db706342813 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredient.java @@ -1,16 +1,21 @@ package com.gregtechceu.gtceu.api.recipe.ingredient; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.data.tag.GTIngredientTypes; +import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; import net.minecraft.util.valueproviders.IntProvider; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.neoforged.neoforge.common.crafting.ICustomIngredient; import net.neoforged.neoforge.common.crafting.IngredientType; +import net.neoforged.neoforge.common.util.NeoForgeExtraCodecs; +import net.neoforged.neoforge.fluids.FluidType; import com.google.common.base.Preconditions; +import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import lombok.Getter; @@ -23,31 +28,68 @@ import static com.gregtechceu.gtceu.api.recipe.ingredient.IntProviderFluidIngredient.intProviderEqual; -public class IntProviderIngredient implements ICustomIngredient { +/** + * Allows an {@link Ingredient} to be created with a ranged {@code count}, which will be randomly rolled upon recipe + * start (input) / completion (output). + * Instantiated using {@link IntProviderIngredient#of()}, with a {@link Ingredient} or {@link ItemStack}, + * and an {@link IntProvider}. + * Functions similarly to {@link IntProviderFluidIngredient}. + */ +public class IntProviderIngredient implements ICustomIngredient, IRangedIngredient { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( Ingredient.CODEC.fieldOf("inner").forGetter(IntProviderIngredient::getInner), - IntProvider.CODEC.fieldOf("count_provider").forGetter(IntProviderIngredient::getCountProvider)) + IntProvider.CODEC.fieldOf("count_provider").forGetter(IntProviderIngredient::getCountProvider), + NeoForgeExtraCodecs.optionalFieldAlwaysWrite(Codec.INT, "sampledCount", FluidType.BUCKET_VOLUME) + .forGetter(IRangedIngredient::getSampledCount)) .apply(instance, IntProviderIngredient::new)); + public static final ResourceLocation TYPE = GTCEu.id("int_provider"); + public static final ItemStack[] EMPTY_STACK_ARRAY = new ItemStack[0]; @Getter protected final IntProvider countProvider; + /** + * The last result of {@link IntProviderIngredient#rollSampledCount(RandomSource)}. -1 if not rolled. + */ + @Getter @Setter protected int sampledCount = -1; + /** + * The {@link Ingredient} to have a ranged amount. + */ @Getter protected final Ingredient inner; @Setter - protected @NotNull ItemStack @Nullable [] itemStacks = null; + protected ItemStack @NotNull [] itemStacks = null; protected IntProviderIngredient(Ingredient inner, IntProvider countProvider) { this.inner = inner; this.countProvider = countProvider; } - public static Ingredient of(Ingredient inner, IntProvider countProvider) { + protected IntProviderIngredient(Ingredient inner, IntProvider countProvider, int sampledCount) { + this.inner = inner; + this.countProvider = countProvider; + this.sampledCount = sampledCount; + } + + /** + * @param inner {@link Ingredient} + * @param countProvider usually as {@link net.minecraft.util.valueproviders.UniformInt#of(int, int)} + */ + public static IntProviderIngredient of(Ingredient inner, IntProvider countProvider) { Preconditions.checkArgument(countProvider.getMinValue() >= 0, "IntProviderIngredient must have a min value of at least 0."); - return new IntProviderIngredient(inner, countProvider).toVanilla(); + return new IntProviderIngredient(inner, countProvider); + } + + /** + * @param stack {@link ItemStack} + * @param countProvider usually as {@link net.minecraft.util.valueproviders.UniformInt#of(int, int)} + */ + public static IntProviderIngredient of(ItemStack stack, IntProvider countProvider) { + Ingredient inner = Ingredient.of(stack); + return of(inner, countProvider); } @Override @@ -55,11 +97,22 @@ public boolean test(@Nullable ItemStack stack) { return inner.test(stack); } + /** + * Gets a usable {@link ItemStack ItemStack[]} from this {@link IntProviderIngredient}. + * If this ingredient has not yet had its {@link IntProviderIngredient#sampledCount} rolled, rolls it. + * + * @return a {@link ItemStack ItemStack[]} with count {@link IntProviderIngredient#sampledCount} + */ public ItemStack[] getItemStacks() { if (itemStacks == null) { - itemStacks = inner.getItems(); + int cachedCount = rollSampledCount(); + if (cachedCount == 0) { + return EMPTY_STACK_ARRAY; + } + var innerStacks = inner.getItems(); + this.itemStacks = new ItemStack[innerStacks.length]; for (int i = 0; i < itemStacks.length; i++) { - itemStacks[i] = itemStacks[i].copyWithCount(getSampledCount(GTValues.RNG)); + itemStacks[i] = innerStacks[i].copyWithCount(cachedCount); } } return itemStacks; @@ -95,15 +148,39 @@ public IngredientType getType() { return GTIngredientTypes.INT_PROVIDER_INGREDIENT.get(); } + /** + * Gets a {@link ItemStack} containing the maximum possible output from this {@link IntProviderIngredient}. + * Mainly used for things like Recipe provider simulations to see if there is enough inventory space to handle + * the recipe output. + * + * @return a {@link ItemStack} with count {@link IntProvider#getMaxValue()} + */ public @NotNull ItemStack getMaxSizeStack() { if (inner.getItems().length == 0) return ItemStack.EMPTY; else return inner.getItems()[0].copyWithCount(countProvider.getMaxValue()); } - public int getSampledCount(@NotNull RandomSource random) { + /** + * If this ingredient has not yet had its {@link IntProviderIngredient#sampledCount} rolled, rolls it and returns + * the roll. + * If it has, returns the existing roll. + * + * @param random {@link RandomSource}, must be threadsafe, usually called using {@link GTValues#RNG}. + * @return the count rolled + */ + @Override + public int rollSampledCount(@NotNull RandomSource random) { if (sampledCount == -1) { sampledCount = countProvider.sample(random); } return sampledCount; } + + /** + * Resets the random roll on this ingredient + */ + public void reset() { + sampledCount = -1; + itemStacks = null; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/NBTPredicateIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/NBTPredicateIngredient.java new file mode 100644 index 00000000000..aecf958a9ac --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/NBTPredicateIngredient.java @@ -0,0 +1,103 @@ +// package com.gregtechceu.gtceu.api.recipe.ingredient; + +// import com.gregtechceu.gtceu.GTCEu; +// import com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate.NBTPredicate; +// import com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate.NBTPredicates; +// import com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate.TrueNBTPredicate; + +// import net.minecraft.network.FriendlyByteBuf; +// import net.minecraft.resources.ResourceLocation; +// import net.minecraft.util.GsonHelper; +// import net.minecraft.world.item.ItemStack; +// import net.minecraft.world.item.crafting.Ingredient; +// import net.neoforged.neoforge.common.crafting.CraftingHelper; +// import net.neoforged.neoforge.common.crafting.ICustomIngredient; +// import net.neoforged.neoforge.registries.ForgeRegistries; +// import net.neoforged.neoforge.fluids.FluidStack; + +// import com.google.gson.JsonElement; +// import com.google.gson.JsonObject; +// import org.jetbrains.annotations.NotNull; +// import org.jetbrains.annotations.Nullable; + +// import java.util.function.Predicate; +// import java.util.stream.Stream; + +// public class NBTPredicateIngredient implements ICustomIngredient { + +// public static final ResourceLocation TYPE = GTCEu.id("nbt_predicate"); +// public static final NBTPredicate ALWAYS_TRUE = new TrueNBTPredicate(); +// private final NBTPredicate predicate; +// private final ItemStack stack; + +// public NBTPredicateIngredient(ItemStack stack, NBTPredicate predicate) { +// super(Stream.of(new Ingredient.ItemValue(stack))); +// this.stack = stack; +// this.predicate = predicate; +// } + +// protected NBTPredicateIngredient(ItemStack stack) { +// this(stack, ALWAYS_TRUE); +// } + +// public static NBTPredicateIngredient of(ItemStack stack, NBTPredicate predicate) { +// return new NBTPredicateIngredient(stack, predicate); +// } + +// public static NBTPredicateIngredient of(ItemStack stack) { +// return NBTPredicateIngredient.of(stack, ALWAYS_TRUE); +// } + +// public boolean test(@Nullable ItemStack input) { +// if (input == null) { +// return false; +// } else { +// return this.stack.getItem() == input.getItem() && +// predicate.test(input.getOrCreateTag()); +// } +// } + +// public boolean isSimple() { +// return false; +// } + +// public @NotNull IIngredientSerializer getSerializer() { +// return NBTPredicateIngredient.Serializer.INSTANCE; +// } + +// public JsonElement toJson() { +// JsonObject json = new JsonObject(); +// json.addProperty("type", TYPE.toString()); +// json.addProperty("item", ForgeRegistries.ITEMS.getKey(this.stack.getItem()).toString()); +// json.addProperty("count", this.stack.getCount()); +// if (this.stack.hasTag()) { +// json.addProperty("nbt", this.stack.getTag().toString()); +// } +// json.add("predicate", predicate.toJson()); +// return json; +// } + +// public static class Serializer implements IIngredientSerializer { + +// public static final NBTPredicateIngredient.Serializer INSTANCE = new NBTPredicateIngredient.Serializer(); + +// public @NotNull NBTPredicateIngredient parse(FriendlyByteBuf buffer) { +// var stack = buffer.readItem(); +// var json = buffer.readUtf(); +// var predicate = NBTPredicates.fromJson(GsonHelper.parse(json)); +// return new NBTPredicateIngredient(stack, predicate); +// } + +// public @NotNull NBTPredicateIngredient parse(@NotNull JsonObject json) { +// var stack = CraftingHelper.getItemStack(json, true); +// var predicate = NBTPredicates.fromJson(GsonHelper.getAsJsonObject(json, "predicate")); + +// return new NBTPredicateIngredient(stack, predicate); +// } + +// public void write(FriendlyByteBuf buffer, NBTPredicateIngredient ingredient) { +// buffer.writeItem(ingredient.stack); +// buffer.writeUtf(ingredient.toJson().toString()); +// } +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/AllNBTPredicate.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/AllNBTPredicate.java new file mode 100644 index 00000000000..b65cefea04d --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/AllNBTPredicate.java @@ -0,0 +1,73 @@ +// package com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate; + +// import net.minecraft.nbt.CompoundTag; + +// import com.google.gson.JsonArray; +// import com.google.gson.JsonElement; +// import com.google.gson.JsonObject; + +// import java.util.ArrayList; +// import java.util.List; +// import java.util.stream.Collectors; + +// public class AllNBTPredicate extends NBTPredicate { + +// public static final String TYPE = "all"; + +// @Override +// public String getType() { +// return TYPE; +// } + +// private final List children; + +// public AllNBTPredicate(List children) { +// this.children = children; +// } + +// @Override +// public boolean test(CompoundTag tag) { +// for (NBTPredicate child : children) { +// if (!child.test(tag)) { +// return false; +// } +// } +// return true; +// } + +// @Override +// public JsonObject toJson() { +// JsonObject object = super.toJson(); +// JsonArray childArray = new JsonArray(); +// for (NBTPredicate child : children) { +// childArray.add(child.toJson()); +// } +// object.add("children", childArray); +// return object; +// } + +// public static NBTPredicate fromJson(JsonObject json) { +// if (!json.has("children") || !json.has("type")) { +// throw new IllegalStateException("Could not deserialize AllNBTPredicate: " + json); +// } +// if (!json.get("type").getAsString().equals(TYPE)) { +// throw new IllegalStateException( +// "Trying to deserialize AllNBTPredicate but was something else: " + json); +// } +// List children = new ArrayList<>(); +// for (JsonElement element : json.getAsJsonArray("children")) { +// children.add(NBTPredicates.fromJson(element.getAsJsonObject())); +// } + +// return new AllNBTPredicate(children); +// } + +// @Override +// public String toString() { +// return "AllNBTPredicate{" + +// "children=[" + children.stream() +// .map(Object::toString) +// .collect(Collectors.joining(", ")) + +// "]}"; +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/AnyNBTPredicate.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/AnyNBTPredicate.java new file mode 100644 index 00000000000..a4ae88ba900 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/AnyNBTPredicate.java @@ -0,0 +1,74 @@ +// package com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate; + +// import net.minecraft.nbt.CompoundTag; + +// import com.google.gson.JsonArray; +// import com.google.gson.JsonElement; +// import com.google.gson.JsonObject; + +// import java.util.ArrayList; +// import java.util.List; +// import java.util.stream.Collectors; + +// public class AnyNBTPredicate extends NBTPredicate { + +// public static final String TYPE = "any"; + +// @Override +// public String getType() { +// return TYPE; +// } + +// private final List children; + +// public AnyNBTPredicate(List children) { +// this.children = children; +// } + +// @Override +// public boolean test(CompoundTag tag) { +// for (NBTPredicate child : children) { +// if (child.test(tag)) { +// return true; +// } +// } +// return false; +// } + +// @Override +// public JsonObject toJson() { +// JsonObject object = super.toJson(); +// JsonArray childArray = new JsonArray(); +// for (NBTPredicate child : children) { +// childArray.add(child.toJson()); +// } +// object.add("children", childArray); +// return object; +// } + +// public static NBTPredicate fromJson(JsonObject json) { +// if (!json.has("children") || !json.has("type")) { +// throw new IllegalStateException("Could not deserialize AnyNBTPredicate: " + json); +// } +// if (!json.get("type").getAsString().equals(TYPE)) { +// throw new IllegalStateException( +// "Trying to deserialize AnyNBTPredicate but was something else: " + json); +// } + +// List children = new ArrayList<>(); +// for (JsonElement element : json.getAsJsonArray("children")) { +// children.add(NBTPredicates.fromJson(element.getAsJsonObject())); +// } + +// return new AnyNBTPredicate(children); +// } + +// @Override +// public String toString() { +// return "AnyNBTPredicate{" + +// "children=[" + children.stream() +// .map(Object::toString) +// .collect(Collectors.joining(", ")) + +// "]}"; +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/ComparisonNBTPredicate.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/ComparisonNBTPredicate.java new file mode 100644 index 00000000000..4ddeb5c1ff8 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/ComparisonNBTPredicate.java @@ -0,0 +1,95 @@ +// package com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate; + +// import net.minecraft.nbt.CompoundTag; +// import net.minecraft.nbt.NumericTag; +// import net.minecraft.nbt.Tag; + +// import com.google.gson.JsonObject; + +// import static com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate.NBTPredicateUtils.getNestedTag; + +// public class ComparisonNBTPredicate extends NBTPredicate { + +// public static final String TYPE = "compare"; + +// @Override +// public String getType() { +// return TYPE; +// } + +// private final String key; +// private final double value; +// private final boolean lessThan; +// private final boolean equals; + +// public ComparisonNBTPredicate(String key, double value) { +// this(key, value, false, false); +// } + +// public ComparisonNBTPredicate(String key, double value, boolean lessThan, boolean equals) { +// this.key = key; +// this.value = value; +// this.lessThan = lessThan; +// this.equals = equals; +// } + +// @Override +// public boolean test(CompoundTag tag) { +// Tag toCompare = getNestedTag(tag, key); +// if (toCompare != null) { +// if (toCompare instanceof NumericTag toCompareNum) { +// if (equals) { +// if (toCompareNum.getAsDouble() == value) { +// return true; +// } +// } +// if (lessThan) { +// return toCompareNum.getAsDouble() < value; +// } else { +// return toCompareNum.getAsDouble() > value; +// } +// } +// } +// return false; +// } + +// @Override +// public JsonObject toJson() { +// JsonObject object = super.toJson(); +// object.addProperty("key", key); +// object.addProperty("value", value); +// object.addProperty("lessThan", lessThan); +// object.addProperty("equals", equals); + +// return object; +// } + +// public static NBTPredicate fromJson(JsonObject json) { +// if (!json.has("key") || +// !json.has("value") || +// !json.has("lessThan") || +// !json.has("equals") || +// !json.has("type")) { +// throw new IllegalStateException("Could not deserialize ComparisonNBTPredicate: " + json); +// } +// if (!json.get("type").getAsString().equals(TYPE)) { +// throw new IllegalStateException( +// "Trying to deserialize ComparisonNBTPredicate but was something else: " + json); +// } +// String key = json.get("key").getAsString(); +// double value = json.get("value").getAsDouble(); +// boolean lessThan = json.get("lessThan").getAsBoolean(); +// boolean equals = json.get("equals").getAsBoolean(); +// return new ComparisonNBTPredicate(key, value, lessThan, equals); +// } + +// @Override +// public String toString() { +// return "ComparisonNBTPredicate{" + +// "key='" + key + '\'' + +// ", value=" + value + +// ", lessThan=" + lessThan + +// ", equals=" + equals + +// '}'; +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/EqualsNBTPredicate.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/EqualsNBTPredicate.java new file mode 100644 index 00000000000..a0997d4fca2 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/EqualsNBTPredicate.java @@ -0,0 +1,82 @@ +// package com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate; + +// import net.minecraft.nbt.CompoundTag; +// import net.minecraft.nbt.NumericTag; +// import net.minecraft.nbt.Tag; + +// import com.google.gson.JsonObject; + +// import static com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate.NBTPredicateUtils.getNestedTag; + +// public class EqualsNBTPredicate extends NBTPredicate { + +// public static final String TYPE = "equals"; + +// @Override +// public String getType() { +// return TYPE; +// } + +// private final String key; +// private final Tag value; +// private final boolean inverted; + +// public EqualsNBTPredicate(String key, Tag value) { +// this(key, value, false); +// } + +// public EqualsNBTPredicate(String key, Tag value, boolean inverted) { +// this.key = key; +// this.value = value; +// this.inverted = inverted; +// } + +// @Override +// public boolean test(CompoundTag tag) { +// Tag toCompare = getNestedTag(tag, key); +// if (toCompare == null) { +// return false; +// } else { +// // Mixed numeric types (e.g., int vs. double) +// if (toCompare instanceof NumericTag toCompareNum && +// value instanceof NumericTag valueNum) { +// return inverted ^ (toCompareNum.getAsDouble() == valueNum.getAsDouble()); +// } +// return inverted ^ toCompare.equals(value); +// } +// } + +// @Override +// public JsonObject toJson() { +// JsonObject object = super.toJson(); +// object.addProperty("key", key); +// object.add("value", NBTPredicateUtils.toJson(value)); +// object.addProperty("inverted", inverted); +// return object; +// } + +// public static NBTPredicate fromJson(JsonObject json) { +// if (!json.has("key") || !json.has("value") || !json.has("type")) { +// throw new IllegalStateException("Could not deserialize EqualsNBTPredicate: " + json); +// } +// if (!json.get("type").getAsString().equals(TYPE)) { +// throw new IllegalStateException("Trying to deserialize EqualsNBTPredicate but was something else: " + json); +// } +// String key = json.get("key").getAsString(); +// Tag value = NBTPredicateUtils.fromJson(json.get("value")); +// boolean inverted = false; +// if (json.has("inverted")) { +// inverted = json.get("inverted").getAsBoolean(); +// } +// return new EqualsNBTPredicate(key, value, inverted); +// } + +// @Override +// public String toString() { +// return "EqualsNBTPredicate{" + +// "key='" + key + '\'' + +// ", value=" + value + +// ", inverted=" + inverted + +// '}'; +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NBTPredicate.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NBTPredicate.java new file mode 100644 index 00000000000..74305b87575 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NBTPredicate.java @@ -0,0 +1,23 @@ +// package com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate; + +// import net.minecraft.nbt.CompoundTag; + +// import com.google.gson.JsonObject; +// import org.jetbrains.annotations.MustBeInvokedByOverriders; + +// import java.util.function.Predicate; + +// public abstract class NBTPredicate implements Predicate { + +// // FromJson is handled by the NBTPredicates +// @MustBeInvokedByOverriders +// public JsonObject toJson() { +// JsonObject object = new JsonObject(); +// object.addProperty("type", getType()); +// return object; +// }; + +// public abstract String getType(); + +// public abstract boolean test(CompoundTag tag); +// } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NBTPredicateUtils.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NBTPredicateUtils.java new file mode 100644 index 00000000000..1fd39496ad0 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NBTPredicateUtils.java @@ -0,0 +1,78 @@ +// package com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate; + +// import net.minecraft.nbt.CompoundTag; +// import net.minecraft.nbt.ListTag; +// import net.minecraft.nbt.NbtOps; +// import net.minecraft.nbt.Tag; + +// import com.google.gson.JsonElement; +// import com.mojang.serialization.JsonOps; + +// public final class NBTPredicateUtils { + +// private NBTPredicateUtils() {}; + +// public static JsonElement toJson(Tag tag) { +// return NbtOps.INSTANCE.convertTo(JsonOps.INSTANCE, tag); +// } + +// public static Tag fromJson(JsonElement e) { +// return JsonOps.INSTANCE.convertTo(NbtOps.INSTANCE, e); +// } + +// public static Tag getNestedTag(CompoundTag inputTag, String path) { +// String[] parts = path.split("\\."); + +// Tag current = inputTag; + +// for (String part : parts) { +// if (current == null) { +// return null; +// } + +// int bracketIndex = part.indexOf('['); + +// if (bracketIndex == -1) { +// // simple compound key +// if (!(current instanceof CompoundTag compound) || !compound.contains(part)) { +// return null; +// } +// current = compound.get(part); +// } else { +// // compound key with array index +// String key = part.substring(0, bracketIndex); +// String indexSection = part.substring(bracketIndex); // e.g. "[4][2]" +// if (!(current instanceof CompoundTag compound) || !compound.contains(key)) { +// return null; +// } +// Tag tag = compound.get(key); +// if (!(tag instanceof ListTag list)) { +// return null; +// } + +// // There can be multiple nested indices like arr[1][3] +// Tag element = tag; +// int from = 0; +// while (true) { +// int open = indexSection.indexOf('[', from); +// int close = indexSection.indexOf(']', from); +// if (open == -1 || close == -1) break; +// String numStr = indexSection.substring(open + 1, close); +// if (!(element instanceof ListTag innerList)) return null; +// int index; +// try { +// index = Integer.parseInt(numStr); +// } catch (NumberFormatException e) { +// return null; +// } +// if (index < 0 || index >= innerList.size()) return null; +// element = innerList.get(index); +// from = close + 1; +// } +// current = element; +// } +// } + +// return current; +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NBTPredicates.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NBTPredicates.java new file mode 100644 index 00000000000..28a6d75b5d4 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NBTPredicates.java @@ -0,0 +1,207 @@ +// package com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate; + +// import net.minecraft.nbt.ByteTag; +// import net.minecraft.nbt.DoubleTag; +// import net.minecraft.nbt.FloatTag; +// import net.minecraft.nbt.IntTag; +// import net.minecraft.nbt.StringTag; +// import net.minecraft.nbt.Tag; + +// import com.google.gson.JsonObject; +// import dev.latvian.mods.rhino.util.HideFromJS; +// import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; + +// import java.util.List; +// import java.util.Map; +// import java.util.function.Function; + +// public final class NBTPredicates { + +// private NBTPredicates() {}; + +// public static NBTPredicate eqInt(String key, int value) { +// return eq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate eq(String key, int value) { +// return new EqualsNBTPredicate(key, IntTag.valueOf(value)); +// } + +// public static NBTPredicate eqFloat(String key, float value) { +// return eq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate eq(String key, float value) { +// return new EqualsNBTPredicate(key, FloatTag.valueOf(value)); +// } + +// public static NBTPredicate eqDouble(String key, double value) { +// return eq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate eq(String key, double value) { +// return new EqualsNBTPredicate(key, DoubleTag.valueOf(value)); +// } + +// // Note: Bools are handled as bytes +// public static NBTPredicate eqBool(String key, boolean value) { +// return eq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate eq(String key, boolean value) { +// return new EqualsNBTPredicate(key, ByteTag.valueOf(value)); +// } + +// public static NBTPredicate eqByte(String key, byte value) { +// return eq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate eq(String key, byte value) { +// return new EqualsNBTPredicate(key, ByteTag.valueOf(value)); +// } + +// public static NBTPredicate eqTag(String key, Tag value) { +// return eq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate eq(String key, Tag value) { +// return new EqualsNBTPredicate(key, value); +// } + +// public static NBTPredicate eqString(String key, String value) { +// return eq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate eq(String key, String value) { +// return new EqualsNBTPredicate(key, StringTag.valueOf(value)); +// } + +// public static NBTPredicate neqInt(String key, int value) { +// return neq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate neq(String key, int value) { +// return new EqualsNBTPredicate(key, IntTag.valueOf(value), true); +// } + +// public static NBTPredicate neqFloat(String key, float value) { +// return neq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate neq(String key, float value) { +// return new EqualsNBTPredicate(key, FloatTag.valueOf(value), true); +// } + +// public static NBTPredicate neqDouble(String key, double value) { +// return neq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate neq(String key, double value) { +// return new EqualsNBTPredicate(key, DoubleTag.valueOf(value), true); +// } + +// // Note: Bools are handled as bytes +// public static NBTPredicate neqBool(String key, boolean value) { +// return neq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate neq(String key, boolean value) { +// return new EqualsNBTPredicate(key, ByteTag.valueOf(value), true); +// } + +// public static NBTPredicate neqByte(String key, byte value) { +// return neq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate neq(String key, byte value) { +// return new EqualsNBTPredicate(key, ByteTag.valueOf(value), true); +// } + +// public static NBTPredicate neqTag(String key, Tag value) { +// return neq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate neq(String key, Tag value) { +// return new EqualsNBTPredicate(key, value, true); +// } + +// public static NBTPredicate neqString(String key, String value) { +// return neq(key, value); +// } + +// @HideFromJS +// public static NBTPredicate neq(String key, String value) { +// return new EqualsNBTPredicate(key, StringTag.valueOf(value), true); +// } + +// public static NBTPredicate lte(String key, double value) { +// return new ComparisonNBTPredicate(key, value, true, true); +// } + +// public static NBTPredicate lt(String key, double value) { +// return new ComparisonNBTPredicate(key, value, true, false); +// } + +// public static NBTPredicate gte(String key, double value) { +// return new ComparisonNBTPredicate(key, value, false, true); +// } + +// public static NBTPredicate gt(String key, double value) { +// return new ComparisonNBTPredicate(key, value, false, false); +// } + +// public static NBTPredicate any(NBTPredicate... predicates) { +// return new AnyNBTPredicate(List.of(predicates)); +// } + +// @HideFromJS +// public static NBTPredicate any(List predicates) { +// return new AnyNBTPredicate(predicates); +// } + +// public static NBTPredicate all(NBTPredicate... predicates) { +// return new AllNBTPredicate(List.of(predicates)); +// } + +// @HideFromJS +// public static NBTPredicate all(List predicates) { +// return new AllNBTPredicate(predicates); +// } + +// public static NBTPredicate not(NBTPredicate predicate) { +// return new NotNBTPredicate(predicate); +// } + +// public static final Map> predicateCodecs = new +// Object2ObjectOpenHashMap<>(); + +// static { +// predicateCodecs.put(TrueNBTPredicate.TYPE, TrueNBTPredicate::fromJson); +// predicateCodecs.put(EqualsNBTPredicate.TYPE, EqualsNBTPredicate::fromJson); +// predicateCodecs.put(ComparisonNBTPredicate.TYPE, ComparisonNBTPredicate::fromJson); +// predicateCodecs.put(AllNBTPredicate.TYPE, AllNBTPredicate::fromJson); +// predicateCodecs.put(AnyNBTPredicate.TYPE, AnyNBTPredicate::fromJson); +// predicateCodecs.put(NotNBTPredicate.TYPE, NotNBTPredicate::fromJson); +// }; + +// public static NBTPredicate fromJson(JsonObject json) { +// if (!json.has("type")) { +// throw new IllegalStateException("Can't deserialize JSON without operation key: " + json); +// } +// String op = json.get("type").getAsString(); +// return predicateCodecs.get(op).apply(json); +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NotNBTPredicate.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NotNBTPredicate.java new file mode 100644 index 00000000000..3caf5d8d451 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/NotNBTPredicate.java @@ -0,0 +1,53 @@ +// package com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate; + +// import net.minecraft.nbt.CompoundTag; + +// import com.google.gson.JsonObject; + +// public class NotNBTPredicate extends NBTPredicate { + +// public static final String TYPE = "not"; + +// @Override +// public String getType() { +// return TYPE; +// } + +// private final NBTPredicate child; + +// public NotNBTPredicate(NBTPredicate child) { +// this.child = child; +// } + +// @Override +// public boolean test(CompoundTag tag) { +// return !child.test(tag); +// } + +// @Override +// public JsonObject toJson() { +// JsonObject object = super.toJson(); +// object.add("child", child.toJson()); +// return object; +// } + +// public static NBTPredicate fromJson(JsonObject json) { +// if (!json.has("child") || !json.has("type")) { +// throw new IllegalStateException("Could not deserialize NotNBTPredicate: " + json); +// } +// if (!json.get("type").getAsString().equals(TYPE)) { +// throw new IllegalStateException( +// "Trying to deserialize NotNBTPredicate but was something else: " + json); +// } + +// NBTPredicate child = NBTPredicates.fromJson(json.get("child").getAsJsonObject()); +// return new NotNBTPredicate(child); +// } + +// @Override +// public String toString() { +// return "NotNBTPredicate{" + +// "child=" + child + +// '}'; +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/TrueNBTPredicate.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/TrueNBTPredicate.java new file mode 100644 index 00000000000..55c9e89ab77 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ingredient/nbtpredicate/TrueNBTPredicate.java @@ -0,0 +1,32 @@ +// package com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate; + +// import net.minecraft.nbt.CompoundTag; + +// import com.google.gson.JsonObject; +// import lombok.NoArgsConstructor; + +// @NoArgsConstructor +// public class TrueNBTPredicate extends NBTPredicate { + +// public static final String TYPE = "true"; + +// @Override +// public String getType() { +// return TYPE; +// } + +// @Override +// public boolean test(CompoundTag tag) { +// return true; +// } + +// public static NBTPredicate fromJson(JsonObject json) { +// if (!json.has("type")) { +// throw new IllegalStateException("Could not deserialize TrueNBTPredicate: " + json); +// } +// if (!json.get("type").getAsString().equals(TYPE)) { +// throw new IllegalStateException("Trying to deserialize TrueNBTPredicate but was something else: " + json); +// } +// return new TrueNBTPredicate(); +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/kind/FacadeCoverRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/kind/FacadeCoverRecipe.java index b2ac0df1050..8ad3696e57c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/kind/FacadeCoverRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/kind/FacadeCoverRecipe.java @@ -47,14 +47,14 @@ public boolean matches(CraftingInput container, @NotNull Level level) { } foundBlockItem = true; } else if (item.is(IRON_PLATE_TAG)) { - if (++platesCount > 3) { + if (++platesCount > 1) { return false; } } else { return false; } } - return foundBlockItem && platesCount == 3; + return foundBlockItem && platesCount == 1; } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/kind/GTRecipe.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/kind/GTRecipe.java index aa80569a875..e355f543cb4 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/kind/GTRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/kind/GTRecipe.java @@ -49,6 +49,7 @@ public class GTRecipe implements Recipe { public CompoundTag data; public int duration; public int parallels = 1; + public int subtickParallels = 1; public int batchParallels = 1; public int ocLevel = 0; public final GTRecipeCategory recipeCategory; @@ -150,6 +151,7 @@ public GTRecipe copy(ContentModifier modifier, boolean modifyDuration) { copied.ocLevel = ocLevel; copied.parallels = parallels; copied.batchParallels = batchParallels; + copied.subtickParallels = subtickParallels; return copied; } @@ -240,6 +242,10 @@ public ChanceLogic getChanceLogicForCapability(RecipeCapability cap, IO io, b return new EnergyStack(v, a); } + public int getTotalRuns() { + return parallels * subtickParallels * batchParallels; + } + // Just check id as there *should* only ever be 1 instance of a recipe with this id. // If this doesn't work, fix. @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java index 9c7cd533e70..3d6a9747f75 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookup.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.common.item.armor.PowerlessJetpack; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.recipe.GTRecipeTypes; +import com.gregtechceu.gtceu.utils.GTUtil; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.world.item.ItemStack; @@ -145,7 +146,7 @@ public static ItemStack[] uniqueItems(@NotNull Collection inputs) { if (index > 0) { for (ItemStack unique : uniqueItems) { if (unique == null) break; - else if (ItemStack.isSameItemSameComponents(input, unique)) { + else if (GTUtil.isSameItemSameTags(input, unique)) { continue main; } } @@ -175,7 +176,9 @@ public GTRecipe recurseIngredientTreeFindRecipe(@NotNull List> ingredients, @NotNull Branch branchMap, @NotNull Predicate canHandle, - int index, int count, long skip) { + int index, int count, BitSet skip) { // exhausted all the ingredients, and didn't find anything if (count == ingredients.size()) return null; @@ -236,18 +239,20 @@ public GTRecipe recurseIngredientTreeFindRecipe(@NotNull List> ingredients, @NotNull Branch map, @NotNull Predicate canHandle, int currentIndex, int count, - long skip) { + BitSet skip) { // We loop around ingredients.size() if we reach the end. // only end when all ingredients are exhausted, or a recipe is found int i = (currentIndex + 1) % ingredients.size(); while (i != currentIndex) { // Have we already used this ingredient? If so, skip this one. - if (((skip & (1L << i)) == 0)) { + if (!(skip.get(i))) { // Recursive call // Increase the count, so the recursion can terminate if needed (ingredients is exhausted) // Append the current index to the skip list + BitSet copy = (BitSet) skip.clone(); + copy.set(i); GTRecipe found = recurseIngredientTreeFindRecipe(ingredients, map, canHandle, i, count + 1, - skip | (1L << i)); + copy); if (found != null) { return found; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/RecipeIterator.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/RecipeIterator.java index c54b84238e3..bf38f79cf8b 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/RecipeIterator.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/RecipeIterator.java @@ -6,6 +6,7 @@ import org.jetbrains.annotations.NotNull; +import java.util.BitSet; import java.util.Iterator; import java.util.List; import java.util.function.Predicate; @@ -39,9 +40,11 @@ public GTRecipe next() { // Try each ingredient as a starting point, save current index GTRecipe r = null; while (index < ingredients.size()) { + BitSet skipSet = new BitSet(); + skipSet.set(index); r = recipeMap.getLookup().recurseIngredientTreeFindRecipe(ingredients, recipeMap.getLookup().getLookup(), canHandle, - index, 0, (1L << index)); + index, 0, skipSet); ++index; if (r != null) break; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/RecipeManagerHandler.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/RecipeManagerHandler.java new file mode 100644 index 00000000000..86601b3f614 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/RecipeManagerHandler.java @@ -0,0 +1,65 @@ +package com.gregtechceu.gtceu.api.recipe.lookup; + +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; + +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.crafting.Recipe; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +/** + * Internal class handling adding recipes to GT's lookup system. + *

+ * Intended for use by {@link com.gregtechceu.gtceu.core.mixins.RecipeManagerMixin} and + * {@link com.gregtechceu.gtceu.integration.kjs.GregTechKubeJSPlugin} + */ +@ApiStatus.Internal +public final class RecipeManagerHandler { + + // /** + // * Adds proxy recipes to an {@link GTRecipeType}'s {@link GTRecipeLookup} and adds them to a list. + // * + // * @param recipesByID the recipes stored by their ID + // * @param gtRecipeType the recipe type to add the recipes to, which owns the proxy recipes + // * @param proxyRecipes the list of proxy recipes to populate + // */ + // public static void addProxyRecipesToLookup(@NotNull Map> recipesByID, + // @NotNull GTRecipeType gtRecipeType, @NotNull RecipeType proxyType, + // @NotNull List proxyRecipes) { + // var lookup = gtRecipeType.getLookup(); + // proxyRecipes.clear(); + // recipesByID.forEach((id, recipe) -> { + // if (recipe.getType() != proxyType) { + // // do not add recipes of incompatible type + // return; + // } + // RecipeHolder gtRecipe = gtRecipeType.toGTRecipe(new RecipeHolder<>(id, recipe)); + // proxyRecipes.add(gtRecipe); + // lookup.addRecipe(gtRecipe); + // }); + // } + + /** + * Adds recipes to an {@link GTRecipeType}'s {@link GTRecipeLookup} + * + * @param recipesByID the recipes stored by their ID + * @param gtRecipeType the recipe type to add recipes to + */ + public static void addRecipesToLookup(@NotNull Map> recipesByID, + @NotNull GTRecipeType gtRecipeType) { + var lookup = gtRecipeType.getLookup(); + for (var r : recipesByID.values()) { + if (r.getType() != gtRecipeType) { + // do not add recipes of incompatible type + continue; + } + if (r instanceof GTRecipe recipe) { + lookup.addRecipe(recipe); + } + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/CustomFluidMapIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/CustomFluidMapIngredient.java index 67c92ff4da2..8f6476533c3 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/CustomFluidMapIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/CustomFluidMapIngredient.java @@ -1,5 +1,6 @@ package com.gregtechceu.gtceu.api.recipe.lookup.ingredient.fluid; +import com.gregtechceu.gtceu.api.recipe.ingredient.IntProviderFluidIngredient; import com.gregtechceu.gtceu.api.recipe.lookup.ingredient.AbstractMapIngredient; import net.neoforged.neoforge.fluids.FluidStack; @@ -34,6 +35,15 @@ public static List from(FluidIngredient ingredient) { return ingredients; } + public static List from(IntProviderFluidIngredient ingredient) { + List ingredients = new ArrayList<>(); + FluidStack[] stacks = new FluidStack[] { ingredient.getMaxSizeStack() }; + for (FluidStack stack : stacks) { + ingredients.add(new CustomFluidMapIngredient(stack, ingredient)); + } + return ingredients; + } + @NotNull public static List from(FluidStack stack) { return Collections.singletonList(new CustomFluidMapIngredient(stack)); @@ -48,13 +58,7 @@ public boolean equals(Object o) { } if (this.ingredient != null) { if (other.ingredient != null) { - for (FluidStack stack : other.ingredient.getStacks()) { - if (!this.ingredient.test(stack)) return false; - } - for (FluidStack stack : this.ingredient.getStacks()) { - if (!other.ingredient.test(stack)) return false; - } - return true; + return ingredient.equals(other.ingredient); } else { return this.ingredient.test(other.stack); } @@ -67,7 +71,7 @@ public boolean equals(Object o) { @Override protected int hash() { - return stack.getFluidHolder().hashCode() * 31; + return FluidStack.hashFluidAndComponents(stack); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/FluidDataComponentMapIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/FluidDataComponentMapIngredient.java index 44efbe1c02d..4b291bf28ea 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/FluidDataComponentMapIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/FluidDataComponentMapIngredient.java @@ -97,4 +97,8 @@ public String toString() { public boolean isSpecialIngredient() { return true; } + + protected int hash() { + return componentIngredient.hashCode(); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/FluidStackMapIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/FluidStackMapIngredient.java index 18e0e6abf2c..5c16e61aa8c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/FluidStackMapIngredient.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/fluid/FluidStackMapIngredient.java @@ -1,5 +1,6 @@ package com.gregtechceu.gtceu.api.recipe.lookup.ingredient.fluid; +import com.gregtechceu.gtceu.api.recipe.ingredient.IntProviderFluidIngredient; import com.gregtechceu.gtceu.api.recipe.lookup.ingredient.AbstractMapIngredient; import net.minecraft.core.Holder; @@ -34,9 +35,14 @@ public static List from(@NotNull FluidStack stack) { return Collections.singletonList(new FluidStackMapIngredient(stack)); } + @NotNull + public static List from(@NotNull IntProviderFluidIngredient ingredient) { + return Collections.singletonList(new FluidStackMapIngredient(ingredient.getMaxSizeStack())); + } + @Override protected int hash() { - return stack.hashCode(); + return FluidStack.hashFluidAndComponents(stack); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/item/NBTPredicateItemStackMapIngredient.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/item/NBTPredicateItemStackMapIngredient.java new file mode 100644 index 00000000000..bf4b3574a70 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/item/NBTPredicateItemStackMapIngredient.java @@ -0,0 +1,85 @@ +// package com.gregtechceu.gtceu.api.recipe.lookup.ingredient.item; + +// import com.gregtechceu.gtceu.api.recipe.ingredient.NBTPredicateIngredient; +// import com.gregtechceu.gtceu.api.recipe.lookup.ingredient.AbstractMapIngredient; +// import com.gregtechceu.gtceu.utils.ItemStackHashStrategy; + +// import net.minecraft.world.item.ItemStack; + +// import it.unimi.dsi.fastutil.objects.ObjectArrayList; +// import org.jetbrains.annotations.NotNull; + +// import java.util.Collections; +// import java.util.List; + +// public class NBTPredicateItemStackMapIngredient extends ItemStackMapIngredient { + +// protected NBTPredicateIngredient nbtIngredient; + +// public NBTPredicateItemStackMapIngredient(ItemStack stack, NBTPredicateIngredient nbtIngredient) { +// super(stack, nbtIngredient); +// this.nbtIngredient = nbtIngredient; +// } + +// @NotNull +// public static List from(@NotNull NBTPredicateIngredient ingredient) { +// ObjectArrayList list = new ObjectArrayList<>(); +// for (ItemStack s : ingredient.getItems()) { +// list.add(new NBTPredicateItemStackMapIngredient(s, ingredient)); +// } +// return list; +// } + +// @NotNull +// public static List from(@NotNull ItemStack stack) { +// if (stack.getShareTag() != null) { +// return Collections.singletonList(new NBTPredicateItemStackMapIngredient(stack, +// NBTPredicateIngredient.of(stack))); +// } +// return Collections.emptyList(); +// } + +// @Override +// protected int hash() { +// return ItemStackHashStrategy.comparingItem().hashCode(stack) * 31; +// } + +// @Override +// public boolean equals(Object obj) { +// if (this == obj) { +// return true; +// } +// if (obj instanceof NBTPredicateItemStackMapIngredient other) { +// if (this.stack.getItem() != other.stack.getItem()) { +// return false; +// } +// if (this.nbtIngredient != null) { +// if (other.nbtIngredient != null) { +// if (this.nbtIngredient.getItems().length != other.nbtIngredient.getItems().length) +// return false; +// for (ItemStack stack : this.nbtIngredient.getItems()) { +// if (!other.nbtIngredient.test(stack)) { +// return false; +// } +// } +// return true; +// } else { +// this.nbtIngredient.test(other.stack); +// } +// } else if (other.nbtIngredient != null) { +// return other.nbtIngredient.test(this.stack); +// } +// } +// return false; +// } + +// @Override +// public String toString() { +// return "NBTPredicateItemStackMapIngredient{" + "item=" + stack + "}"; +// } + +// @Override +// public boolean isSpecialIngredient() { +// return true; +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ModifierFunction.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ModifierFunction.java index 1fde7b056fe..2ece837085a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ModifierFunction.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/modifier/ModifierFunction.java @@ -99,6 +99,7 @@ static FunctionBuilder builder() { final class FunctionBuilder { private int parallels = 1; + private int subtickParallels = 1; private int batchParallels = 1; private int addOCs = 0; private ContentModifier eutModifier = ContentModifier.IDENTITY; @@ -160,6 +161,7 @@ public ModifierFunction build() { newConditions, new ArrayList<>(recipe.ingredientActions), recipe.data, recipe.duration, recipe.recipeCategory); copied.parallels = recipe.parallels * parallels; + copied.subtickParallels = recipe.subtickParallels * subtickParallels; copied.ocLevel = recipe.ocLevel + addOCs; copied.batchParallels = recipe.batchParallels * batchParallels; if (recipe.data.getBoolean("duration_is_total_cwu")) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/recipe/ui/GTRecipeTypeUI.java b/src/main/java/com/gregtechceu/gtceu/api/recipe/ui/GTRecipeTypeUI.java index b7fa4dea9d4..b426584552e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/recipe/ui/GTRecipeTypeUI.java +++ b/src/main/java/com/gregtechceu/gtceu/api/recipe/ui/GTRecipeTypeUI.java @@ -408,7 +408,7 @@ protected IGuiTexture getOverlaysForSlot(boolean isOutput, RecipeCapability c * @return the height used to determine size of background texture in JEI */ public int getPropertyHeightShift() { - int maxPropertyCount = maxTooltips + recipeType.getDataInfos().size(); + int maxPropertyCount = maxTooltips + recipeType.getDataInfos().size() + recipeType.getMinRecipeConditions(); return maxPropertyCount * 10; // GTRecipeWidget#LINE_HEIGHT } diff --git a/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java b/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java index 1d3eab1dc98..55273fb01f1 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java +++ b/src/main/java/com/gregtechceu/gtceu/api/registry/GTRegistries.java @@ -24,17 +24,24 @@ import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.levelgen.feature.trunkplacers.TrunkPlacerType; +import net.minecraft.world.level.levelgen.placement.PlacementModifierType; import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.IEventBus; import net.neoforged.neoforge.common.NeoForge; +import net.neoforged.neoforge.common.loot.IGlobalLootModifier; +import net.neoforged.neoforge.registries.DeferredRegister; import net.neoforged.neoforge.registries.IdMappingEvent; +import net.neoforged.neoforge.registries.NeoForgeRegistries; import net.neoforged.neoforge.registries.RegisterEvent; import net.neoforged.neoforge.registries.RegistryBuilder; import com.google.common.collect.HashBasedTable; import com.google.common.collect.Table; +import com.mojang.serialization.MapCodec; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.UnmodifiableView; @@ -48,7 +55,6 @@ public final class GTRegistries { public static final ResourceKey> ORE_VEIN_REGISTRY = makeRegistryKey(GTCEu.id("ore_vein")); public static final ResourceKey> BEDROCK_FLUID_REGISTRY = makeRegistryKey(GTCEu.id("bedrock_fluid")); public static final ResourceKey> BEDROCK_ORE_REGISTRY = makeRegistryKey(GTCEu.id("bedrock_ore")); - public static final ResourceKey> ELEMENT_REGISTRY = makeRegistryKey(GTCEu.id("element")); public static final ResourceKey> TAG_PREFIX_REGISTRY = makeRegistryKey(GTCEu.id("tag_prefix")); public static final ResourceKey> MATERIAL_REGISTRY = makeRegistryKey(GTCEu.id("material")); @@ -107,6 +113,12 @@ private static MaterialRegistry makeMaterialRegistry() { private static final Table, ResourceLocation, Object> TO_REGISTER = HashBasedTable.create(); private static boolean isFrozen = true; + public static final DeferredRegister> TRUNK_PLACER_TYPE = DeferredRegister + .create(Registries.TRUNK_PLACER_TYPE, GTCEu.MOD_ID); + public static final DeferredRegister> PLACEMENT_MODIFIER = DeferredRegister + .create(Registries.PLACEMENT_MODIFIER_TYPE, GTCEu.MOD_ID); + public static final DeferredRegister> GLOBAL_LOOT_MODIFIES = DeferredRegister + .create(NeoForgeRegistries.Keys.GLOBAL_LOOT_MODIFIER_SERIALIZERS, GTCEu.MOD_ID); public static T register(Registry registry, ResourceLocation name, T value) { if (!isFrozen) { diff --git a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTRegistrate.java b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTRegistrate.java index 1b2230d2c12..05ab197574c 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTRegistrate.java +++ b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/GTRegistrate.java @@ -52,6 +52,7 @@ import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; public class GTRegistrate extends AbstractRegistrate { @@ -217,9 +218,21 @@ public GTBlockBuilder block(P parent, String name, @Nullable private RegistryEntry currentTab; - private static final Map, @Nullable RegistryEntry> TAB_LOOKUP = new IdentityHashMap<>(); + private static final Map, RegistryEntry> TAB_LOOKUP = new IdentityHashMap<>(); - public void creativeModeTab(@Nullable RegistryEntry currentTab) { + public RegistryEntry creativeModeTab() { + return this.currentTab; + } + + public void creativeModeTab(Supplier> currentTab) { + this.currentTab = currentTab.get(); + } + + public void resetCreativeModeTab() { + this.currentTab = null; + } + + public void creativeModeTab(RegistryEntry currentTab) { this.currentTab = currentTab; } diff --git a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MachineBuilder.java b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MachineBuilder.java index 2309b0f8f4e..c4a1844256a 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MachineBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MachineBuilder.java @@ -3,7 +3,6 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.block.IMachineBlock; -import com.gregtechceu.gtceu.api.blockentity.IPaintable; import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.gui.editor.EditableMachineUI; import com.gregtechceu.gtceu.api.item.MetaMachineItem; @@ -13,7 +12,7 @@ import com.gregtechceu.gtceu.api.machine.RotationState; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; -import com.gregtechceu.gtceu.api.machine.steam.SteamMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; @@ -60,8 +59,8 @@ import com.tterrag.registrate.util.nullness.NonNullUnaryOperator; import dev.latvian.mods.rhino.util.HideFromJS; import dev.latvian.mods.rhino.util.RemapPrefixForJS; -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Reference2IntMap; +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; @@ -111,7 +110,7 @@ public class MachineBuilder { @Setter private boolean allowExtendedFacing = false; @Setter - private boolean hasBER; + private boolean hasBER = ConfigHolder.INSTANCE.client.machinesHaveBERsByDefault; @Setter private boolean renderMultiblockWorldPreview = true; @Setter @@ -132,7 +131,7 @@ public class MachineBuilder { @Setter // getter for KJS private int tier; @Setter - private Object2IntMap> recipeOutputLimits = new Object2IntOpenHashMap<>(); + private Reference2IntMap> recipeOutputLimits = new Reference2IntOpenHashMap<>(); @Setter private int paintingColor = ConfigHolder.INSTANCE.client.getDefaultPaintingColor(); @Setter @@ -231,8 +230,8 @@ protected void initRecipeMachineModelProperties(GTRecipeType type) { if (type == GTRecipeTypes.DUMMY_RECIPES) { return; } - if (!modelProperties.containsKey(RecipeLogic.STATUS_PROPERTY)) { - modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE); + if (!modelProperties.containsKey(GTMachineModelProperties.RECIPE_LOGIC_STATUS)) { + modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE); } } @@ -249,7 +248,9 @@ public MachineBuilder tieredHullModel(ResourceLocation model) { } public MachineBuilder overlayTieredHullModel(String name) { - return overlayTieredHullModel(registrate.makeResourceLocation("block/machine/part/" + name)); + modelProperty(GTMachineModelProperties.IS_FORMED, false); + return overlayTieredHullModel( + ResourceLocation.fromNamespaceAndPath(registrate.getModid(), "block/machine/part/" + name)); } public MachineBuilder overlayTieredHullModel(ResourceLocation overlayModel) { @@ -263,7 +264,9 @@ public MachineBuilder colorOverlayTieredHullModel(String overlay) { public MachineBuilder colorOverlayTieredHullModel(String overlay, @Nullable String pipeOverlay, @Nullable String emissiveOverlay) { - ResourceLocation overlayTex = registrate.makeResourceLocation("block/overlay/machine/" + overlay); + modelProperty(GTMachineModelProperties.IS_FORMED, false); + ResourceLocation overlayTex = ResourceLocation.fromNamespaceAndPath(registrate.getModid(), + "block/overlay/machine/" + overlay); ResourceLocation pipeOverlayTex = pipeOverlay == null ? null : registrate.makeResourceLocation("block/overlay/machine/" + pipeOverlay); ResourceLocation emissiveOverlayTex = emissiveOverlay == null ? null : @@ -272,33 +275,52 @@ public MachineBuilder colorOverlayTieredHullModel(String overlay, } public MachineBuilder colorOverlayTieredHullModel(ResourceLocation overlay) { + modelProperty(GTMachineModelProperties.IS_FORMED, false); return colorOverlayTieredHullModel(overlay, null, null); } public MachineBuilder colorOverlayTieredHullModel(ResourceLocation overlay, @Nullable ResourceLocation pipeOverlay, @Nullable ResourceLocation emissiveOverlay) { - modelProperty(IPaintable.IS_PAINTED_PROPERTY, false); + modelProperty(GTMachineModelProperties.IS_PAINTED, false); return model(createColorOverlayTieredHullMachineModel(overlay, pipeOverlay, emissiveOverlay)); } public MachineBuilder overlaySteamHullModel(String name) { - return overlaySteamHullModel(registrate.makeResourceLocation("block/machine/part/" + name)); + modelProperty(GTMachineModelProperties.IS_FORMED, false); + return overlaySteamHullModel( + ResourceLocation.fromNamespaceAndPath(registrate.getModid(), "block/machine/part/" + name)); } public MachineBuilder overlaySteamHullModel(ResourceLocation overlayModel) { - modelProperty(SteamMachine.STEEL_PROPERTY, ConfigHolder.INSTANCE.machines.steelSteamMultiblocks); + modelProperty(GTMachineModelProperties.IS_STEEL_MACHINE, ConfigHolder.INSTANCE.machines.steelSteamMultiblocks); return model(createOverlaySteamHullMachineModel(overlayModel)); } public MachineBuilder colorOverlaySteamHullModel(String overlay) { - return colorOverlaySteamHullModel(overlay, null, null); + return colorOverlaySteamHullModel(overlay, (String) null, null); + } + + public MachineBuilder colorOverlaySteamHullModel(String overlay, + @Nullable String pipeOverlay, + @Nullable String emissiveOverlay) { + modelProperty(GTMachineModelProperties.IS_FORMED, false); + ResourceLocation overlayTex = ResourceLocation.fromNamespaceAndPath(registrate.getModid(), + "block/overlay/machine/" + overlay); + ResourceLocation pipeOverlayTex = pipeOverlay == null ? null : + ResourceLocation.fromNamespaceAndPath(registrate.getModid(), "block/overlay/machine/" + pipeOverlay); + ResourceLocation emissiveOverlayTex = emissiveOverlay == null ? null : + ResourceLocation.fromNamespaceAndPath(registrate.getModid(), + "block/overlay/machine/" + emissiveOverlay); + return colorOverlaySteamHullModel(overlayTex, pipeOverlayTex, emissiveOverlayTex); } public MachineBuilder colorOverlaySteamHullModel(String overlay, @Nullable ResourceLocation pipeOverlay, @Nullable String emissiveOverlay) { - ResourceLocation overlayTex = registrate.makeResourceLocation("block/overlay/machine/" + overlay); + modelProperty(GTMachineModelProperties.IS_FORMED, false); + ResourceLocation overlayTex = ResourceLocation.fromNamespaceAndPath(registrate.getModid(), + "block/overlay/machine/" + overlay); ResourceLocation pipeOverlayTex = pipeOverlay == null ? null : registrate.makeResourceLocation("block/overlay/machine/" + pipeOverlay); ResourceLocation emissiveOverlayTex = emissiveOverlay == null ? null : @@ -313,27 +335,27 @@ public MachineBuilder colorOverlaySteamHullModel(ResourceLocation ov public MachineBuilder colorOverlaySteamHullModel(ResourceLocation overlay, @Nullable ResourceLocation pipeOverlay, @Nullable ResourceLocation emissiveOverlay) { - modelProperty(IPaintable.IS_PAINTED_PROPERTY, false); + modelProperty(GTMachineModelProperties.IS_PAINTED, false); return model(createColorOverlaySteamHullMachineModel(overlay, pipeOverlay, emissiveOverlay)); } public MachineBuilder workableTieredHullModel(ResourceLocation workableModel) { - modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE); + modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE); return model(createWorkableTieredHullMachineModel(workableModel)); } public MachineBuilder simpleGeneratorModel(ResourceLocation workableModel) { - modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE); + modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE); return model(createSimpleGeneratorModel(workableModel)); } public MachineBuilder workableSteamHullModel(boolean isHighPressure, ResourceLocation workableModel) { - modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE); + modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE); return model(createWorkableSteamHullMachineModel(isHighPressure, workableModel)); } public MachineBuilder workableCasingModel(ResourceLocation baseCasing, ResourceLocation workableModel) { - modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE); + modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE); return model(createWorkableCasingMachineModel(baseCasing, workableModel)); } @@ -344,7 +366,7 @@ public MachineBuilder sidedOverlayCasingModel(ResourceLocation baseC public MachineBuilder sidedWorkableCasingModel(ResourceLocation baseCasing, ResourceLocation workableModel) { - modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE); + modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE); return model(createSidedWorkableCasingMachineModel(baseCasing, workableModel)); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MultiblockMachineBuilder.java b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MultiblockMachineBuilder.java index d4670d02cf9..77067735652 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MultiblockMachineBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/api/registry/registrate/MultiblockMachineBuilder.java @@ -14,6 +14,7 @@ import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockControllerMachine; import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.multiblock.BlockPattern; import com.gregtechceu.gtceu.api.multiblock.MultiblockShapeInfo; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; @@ -44,7 +45,7 @@ import com.tterrag.registrate.util.nullness.NonNullConsumer; import com.tterrag.registrate.util.nullness.NonNullUnaryOperator; import dev.latvian.mods.rhino.util.HideFromJS; -import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Reference2IntMap; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; @@ -88,7 +89,7 @@ public MultiblockMachineBuilder(GTRegistrate registrate, String name, allowExtendedFacing(true); allowCoverOnFront(true); // always add the formed property to multi controllers - modelProperty(IMultiController.IS_FORMED_PROPERTY, false); + modelProperty(GTMachineModelProperties.IS_FORMED, false); } public MultiblockMachineBuilder shapeInfo(Function shape) { @@ -183,7 +184,7 @@ public MultiblockMachineBuilder tier(int tier) { return (MultiblockMachineBuilder) super.tier(tier); } - public MultiblockMachineBuilder recipeOutputLimits(Object2IntMap> map) { + public MultiblockMachineBuilder recipeOutputLimits(Reference2IntMap> map) { return (MultiblockMachineBuilder) super.recipeOutputLimits(map); } @@ -338,7 +339,7 @@ public MultiblockMachineBuilder tooltips(@Nullable Component... components) { } @Override - public MultiblockMachineBuilder tooltips(List components) { + public MultiblockMachineBuilder tooltips(List components) { return (MultiblockMachineBuilder) super.tooltips(components); } diff --git a/src/main/java/com/gregtechceu/gtceu/api/tag/TagUtil.java b/src/main/java/com/gregtechceu/gtceu/api/tag/TagUtil.java index 0d7713256c5..9acecc8390e 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/tag/TagUtil.java +++ b/src/main/java/com/gregtechceu/gtceu/api/tag/TagUtil.java @@ -107,4 +107,8 @@ public static TagKey createFluidTag(String path) { public static TagKey createModFluidTag(String path) { return createModTag(Registries.FLUID, path); } + + public static TagKey optionalTag(ResourceKey> registryKey, ResourceLocation path) { + return TagKey.create(registryKey, path); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/api/worldgen/GTLayerPattern.java b/src/main/java/com/gregtechceu/gtceu/api/worldgen/GTLayerPattern.java index 1ce5a31da55..c9b70550a10 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/worldgen/GTLayerPattern.java +++ b/src/main/java/com/gregtechceu/gtceu/api/worldgen/GTLayerPattern.java @@ -34,19 +34,24 @@ public GTLayerPattern(List layers) { this.layers = layers; } - public Layer rollNext(@Nullable Layer previous, RandomSource random) { + public @Nullable Layer rollNext(@Nullable Layer previous, RandomSource random) { + if (layers.isEmpty()) return null; + if (layers.size() == 1) return layers.get(0); + int totalWeight = 0; - for (Layer layer : layers) - if (layer != previous) - totalWeight += layer.weight; + for (Layer layer : layers) { + if (layer != previous) totalWeight += layer.weight; + } + // totalWeight should be >0 here but better be safe than sorry + if (totalWeight <= 0) return null; + int rolled = random.nextInt(totalWeight); for (Layer layer : layers) { - if (layer == previous) - continue; + if (layer == previous) continue; + rolled -= layer.weight; - if (rolled < 0) - return layer; + if (rolled < 0) return layer; } return null; } @@ -92,6 +97,21 @@ public static class Layer { public final int weight; public Layer(List, Material>> targets, int minSize, int maxSize, int weight) { + if (minSize > maxSize) { + StringBuilder materialList = new StringBuilder().append(" with materials: "); + for (var target : targets) { + if (target.right().isPresent()) { + materialList.append(target.right().get().getName()).append(","); + } + } + if (!materialList.isEmpty()) { + materialList.deleteCharAt(materialList.length() - 1); + } + + throw new IllegalArgumentException( + "Layer must have minSize (%s) be lower than maxSize (%s)%s".formatted(minSize, maxSize, + materialList.toString())); + } this.targets = targets; this.minSize = minSize; this.maxSize = maxSize; diff --git a/src/main/java/com/gregtechceu/gtceu/api/worldgen/generator/veins/LayeredVeinGenerator.java b/src/main/java/com/gregtechceu/gtceu/api/worldgen/generator/veins/LayeredVeinGenerator.java index 20b5c48f73c..5c8f1ff33b5 100644 --- a/src/main/java/com/gregtechceu/gtceu/api/worldgen/generator/veins/LayeredVeinGenerator.java +++ b/src/main/java/com/gregtechceu/gtceu/api/worldgen/generator/veins/LayeredVeinGenerator.java @@ -71,7 +71,9 @@ public Map generate(WorldGenLevel level, RandomSource if (patternPool.isEmpty()) return Map.of(); - GTLayerPattern layerPattern = patternPool.get(random.nextInt(patternPool.size())); + // minor optimization, usually only one layer pool exists + GTLayerPattern layerPattern = patternPool.size() == 1 ? + patternPool.get(0) : patternPool.get(random.nextInt(patternPool.size())); int size = entry.clusterSize().sample(random); float density = entry.density(); @@ -97,37 +99,54 @@ public Map generate(WorldGenLevel level, RandomSource for (int xOffset = 0; xOffset < width; xOffset++) { float sizeFractionX = xOffset * 2f / width - 1; - if ((sizeFractionX * sizeFractionX) > 1) + float xSizeSqr = sizeFractionX * sizeFractionX; + if (xSizeSqr > 1) continue; for (int yOffset = 0; yOffset < height; yOffset++) { float sizeFractionY = yOffset * 2f / height - 1; - if ((sizeFractionX * sizeFractionX) + (sizeFractionY * sizeFractionY) > 1) + float ySizeSqr = sizeFractionY * sizeFractionY; + if (xSizeSqr + ySizeSqr > 1) continue; if (level.isOutsideBuildHeight(yMin + yOffset)) continue; for (int zOffset = 0; zOffset < length; zOffset++) { float sizeFractionZ = zOffset * 2f / length - 1; + float zSizeSqr = sizeFractionZ * sizeFractionZ; + // OPTIMIZATION: all values in layerDiameterOffsets are in the [0,1] range, so + // check if the size is >1 before doing any of that math + if (xSizeSqr + ySizeSqr + zSizeSqr > 1) + continue; int layerIndex = layerCoordinate == 0 ? zOffset : layerCoordinate == 1 ? xOffset : yOffset; - if (slantyCoordinate != layerCoordinate) + if (slantyCoordinate != layerCoordinate) { layerIndex += Mth.floor( - slantyCoordinate == 0 ? zOffset : slantyCoordinate == 1 ? xOffset : yOffset * slope); + slantyCoordinate == 0 ? zOffset : slantyCoordinate == 1 ? xOffset : yOffset) * slope; + } while (layerIndex >= resolvedLayers.size()) { GTLayerPattern.Layer next = layerPattern.rollNext( resolvedLayers.isEmpty() ? null : resolvedLayers.getLast(), random); - float offset = random.nextFloat() * .5f + .5f; + + float offset = random.nextFloat() * 0.5f + 0.5f; + // insert the previous layer if this one is null (e.g. invalid) + if (next == null) { + if (resolvedLayers.isEmpty()) { + continue; + } + resolvedLayers.add(resolvedLayers.get(resolvedLayers.size() - 1)); + layerDiameterOffsets.add(offset); + continue; + } for (int i = 0; i < next.minSize + random.nextInt(1 + next.maxSize - next.minSize); i++) { resolvedLayers.add(next); layerDiameterOffsets.add(offset); } } - if ((sizeFractionX * sizeFractionX) + (sizeFractionY * sizeFractionY) + - (sizeFractionZ * sizeFractionZ) > 1 * layerDiameterOffsets.getFloat(layerIndex)) + if (xSizeSqr + ySizeSqr + zSizeSqr > layerDiameterOffsets.getFloat(layerIndex)) continue; GTLayerPattern.Layer layer = resolvedLayers.get(layerIndex); diff --git a/src/main/java/com/gregtechceu/gtceu/client/ClientInit.java b/src/main/java/com/gregtechceu/gtceu/client/ClientInit.java index b61c534d0d6..2bb50bed435 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/ClientInit.java +++ b/src/main/java/com/gregtechceu/gtceu/client/ClientInit.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.cosmetics.event.RegisterGTCapesEvent; import com.gregtechceu.gtceu.api.item.IComponentItem; import com.gregtechceu.gtceu.api.item.IGTTool; import com.gregtechceu.gtceu.api.item.LampBlockItem; @@ -10,14 +11,20 @@ import com.gregtechceu.gtceu.client.particle.HazardParticle; import com.gregtechceu.gtceu.client.particle.MufflerParticle; import com.gregtechceu.gtceu.client.renderer.entity.GTExplosiveRenderer; -import com.gregtechceu.gtceu.client.renderer.item.decorator.*; +import com.gregtechceu.gtceu.client.renderer.item.decorator.GTComponentItemDecorator; +import com.gregtechceu.gtceu.client.renderer.item.decorator.GTLampItemOverlayRenderer; +import com.gregtechceu.gtceu.client.renderer.item.decorator.GTTankItemFluidPreview; +import com.gregtechceu.gtceu.client.renderer.item.decorator.GTToolBarRenderer; import com.gregtechceu.gtceu.client.renderer.machine.DynamicRenderManager; import com.gregtechceu.gtceu.client.renderer.machine.impl.*; +import com.gregtechceu.gtceu.common.item.DrumMachineItem; +import com.gregtechceu.gtceu.common.item.QuantumTankMachineItem; import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.entity.GTEntityTypes; import com.gregtechceu.gtceu.data.fluid.GTFluids; import com.gregtechceu.gtceu.data.particle.GTParticleTypes; +import com.gregtechceu.gtceu.forge.CommonEventListener; import com.gregtechceu.gtceu.integration.map.ClientCacheManager; import com.gregtechceu.gtceu.integration.map.cache.client.GTClientCache; import com.gregtechceu.gtceu.integration.map.ftbchunks.FTBChunksPlugin; @@ -25,6 +32,7 @@ import com.gregtechceu.gtceu.integration.map.layer.builtin.FluidRenderLayer; import com.gregtechceu.gtceu.integration.map.layer.builtin.OreRenderLayer; import com.gregtechceu.gtceu.utils.input.KeyBind; +import com.gregtechceu.gtceu.utils.input.SyncedKeyMapping; import net.minecraft.client.renderer.entity.ThrownItemRenderer; import net.minecraft.core.component.DataComponents; @@ -50,6 +58,7 @@ public static void init(IEventBus modBus) { ClientCacheManager.registerClientCache(GTClientCache.instance, "gtceu"); Layers.registerLayer(OreRenderLayer::new, "ore_veins"); Layers.registerLayer(FluidRenderLayer::new, "bedrock_fluids"); + CommonEventListener.registerCapes(new RegisterGTCapesEvent()); } initializeDynamicRenders(); } @@ -73,12 +82,19 @@ public static void onRegisterItemDecorations(RegisterItemDecorationsEvent event) if (item instanceof LampBlockItem) { event.register(item, GTLampItemOverlayRenderer.INSTANCE); } + if (item instanceof DrumMachineItem) { + event.register(item, GTTankItemFluidPreview.DRUM); + } + if (item instanceof QuantumTankMachineItem) { + event.register(item, GTTankItemFluidPreview.QUANTUM_TANK); + } } } @SubscribeEvent public static void registerKeyBindings(RegisterKeyMappingsEvent event) { KeyBind.onRegisterKeyBinds(event); + SyncedKeyMapping.onRegisterKeyBinds(event); } @SubscribeEvent @@ -109,6 +125,9 @@ public static void initializeDynamicRenders() { DynamicRenderManager.register(GTCEu.id("boiler_multi_parts"), BoilerMultiPartRender.TYPE); DynamicRenderManager.register(GTCEu.id("fluid_area"), FluidAreaRender.TYPE); + DynamicRenderManager.register(GTCEu.id("growing_plant"), GrowingPlantRender.TYPE); + + DynamicRenderManager.register(GTCEu.id("central_monitor"), CentralMonitorRender.TYPE); } @SubscribeEvent diff --git a/src/main/java/com/gregtechceu/gtceu/client/forge/ForgeClientEventListener.java b/src/main/java/com/gregtechceu/gtceu/client/forge/ForgeClientEventListener.java index 70023f64dab..2aca74d35d1 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/forge/ForgeClientEventListener.java +++ b/src/main/java/com/gregtechceu/gtceu/client/forge/ForgeClientEventListener.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.block.BlockAttributes; import com.gregtechceu.gtceu.api.cosmetics.CapeRegistry; import com.gregtechceu.gtceu.api.item.tool.ToolHelper; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; @@ -26,6 +27,9 @@ import net.minecraft.core.BlockPos; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.ai.attributes.AttributeInstance; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.crafting.RecipeManager; import net.minecraft.world.level.block.entity.BlockEntity; @@ -47,8 +51,9 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; -@EventBusSubscriber(modid = GTCEu.MOD_ID, bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT) +@EventBusSubscriber(modid = GTCEu.MOD_ID, value = Dist.CLIENT) @OnlyIn(Dist.CLIENT) public class ForgeClientEventListener { @@ -84,6 +89,51 @@ public static void onPlayerRender(RenderPlayerEvent.Pre event) { } } + @SubscribeEvent + public static void updateFOV(ComputeFovModifierEvent event) { + Player player = event.getPlayer(); + + AttributeInstance moveSpeed = player.getAttribute(Attributes.MOVEMENT_SPEED); + if (moveSpeed == null || moveSpeed.getModifier(BlockAttributes.BLOCK_SPEED_BOOST) == null) return; + boolean flying = player.getAbilities().flying; + float originalFov = flying ? 1.1F : 1.0F; + float walkSpeed = player.getAbilities().getWalkingSpeed(); + + originalFov *= ((float) moveSpeed.getBaseValue() / walkSpeed + 1.0F) / 2.0F; + if (walkSpeed == 0.0F || Float.isNaN(originalFov) || + Float.isInfinite(originalFov)) { + return; + } + + float newFov = flying ? 1.1F : 1.0F; + newFov *= ((float) getValueWithoutWalkingBoost(moveSpeed) / walkSpeed + 1.0F) / + 2.0F; + + event.setNewFovModifier(newFov / originalFov); + } + + private static double getValueWithoutWalkingBoost(AttributeInstance attrib) { + double base = attrib.getBaseValue(); + Map> mods = attrib.getModifiers().stream() + .collect(Collectors.groupingBy(t -> t.operation())); + + for (AttributeModifier mod : mods.get(AttributeModifier.Operation.ADD_VALUE)) { + base += mod.amount(); + } + + double applied = base; + for (AttributeModifier mod : mods.get(AttributeModifier.Operation.ADD_MULTIPLIED_BASE)) { + if (mod.id() == BlockAttributes.BLOCK_SPEED_BOOST) continue; + applied += base * mod.amount(); + } + + for (AttributeModifier mod : mods.get(AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL)) { + applied *= 1 + mod.amount(); + } + + return attrib.getAttribute().value().sanitizeValue(applied); + } + @SubscribeEvent public static void onBlockHighlightEvent(RenderHighlightEvent.Block event) { BlockHighlightRenderer.renderBlockHighlight(event.getPoseStack(), event.getCamera(), event.getTarget(), diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java index c66ad2924b5..ad6f6c2b080 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/machine/MachineModel.java @@ -63,7 +63,7 @@ import static com.gregtechceu.gtceu.api.machine.IMachineBlockEntity.*; public final class MachineModel extends BaseBakedModel implements ICoverableRenderer, - IMachineRendererModel, IBlockEntityRendererBakedModel { + IBlockEntityRendererBakedModel { public static final ResourceLocation PIPE_OVERLAY = GTCEu.id("block/overlay/machine/overlay_pipe"); public static final ResourceLocation FLUID_OUTPUT_OVERLAY = GTCEu.id("block/overlay/machine/overlay_fluid_output"); @@ -224,14 +224,6 @@ public List getMachineQuads(@Nullable BlockState blockState, @Nullabl BlockPos pos = modelData.get(MODEL_DATA_POS); MetaMachine machine = (level == null || pos == null) ? null : MetaMachine.getMachine(level, pos); - return getRenderQuads(machine, level, pos, blockState, side, rand, modelData, renderType); - } - - @Override - public @NotNull List getRenderQuads(@Nullable MetaMachine machine, @Nullable BlockAndTintGetter level, - @Nullable BlockPos pos, @Nullable BlockState blockState, - @Nullable Direction side, RandomSource rand, - @NotNull ModelData modelData, @Nullable RenderType renderType) { // render machine quads List quads = renderMachine(machine, level, pos, blockState, side, rand, modelData, renderType); if (machine == null) { @@ -391,24 +383,22 @@ private List renderPartOverrides(MachineModel controllerModel, IMulti @Override public boolean isCustomRenderer() { - return isBlockEntityRenderer(); - } - - @Override - public boolean isBlockEntityRenderer() { - if (dynamicRenders.isEmpty()) return false; - for (DynamicRender render : dynamicRenders) { - if (render.isBlockEntityRenderer()) return true; - } - return false; + return true; } @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public void render(MetaMachine machine, float partialTick, - PoseStack poseStack, MultiBufferSource buffer, + public void render(@NotNull BlockEntity blockEntity, float partialTick, + @NotNull PoseStack poseStack, @NotNull MultiBufferSource buffer, int packedLight, int packedOverlay) { + if (!(blockEntity instanceof IMachineBlockEntity machineBE)) return; + if (machineBE.getDefinition() != getDefinition()) return; + ICoverableRenderer.super.renderDynamicCovers(machineBE.getMetaMachine(), partialTick, poseStack, buffer, + packedLight, + packedOverlay); if (dynamicRenders.isEmpty()) return; + + MetaMachine machine = machineBE.getMetaMachine(); Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition(); for (DynamicRender model : dynamicRenders) { if (!model.shouldRender(machine, cameraPos)) { @@ -430,9 +420,14 @@ public void renderByItem(ItemStack stack, ItemDisplayContext displayContext, @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public AABB getRenderBoundingBox(MetaMachine machine) { - AABB bounds = IMachineRendererModel.super.getRenderBoundingBox(machine); + public AABB getRenderBoundingBox(BlockEntity blockEntity) { + AABB bounds = IBlockEntityRendererBakedModel.super.getRenderBoundingBox(blockEntity); + + if (!(blockEntity instanceof IMachineBlockEntity machineBE)) return bounds; + if (machineBE.getDefinition() != getDefinition()) return bounds; if (dynamicRenders.isEmpty()) return bounds; + + MetaMachine machine = machineBE.getMetaMachine(); for (DynamicRender model : dynamicRenders) { bounds = bounds.minmax(model.getRenderBoundingBox(machine)); } @@ -441,8 +436,12 @@ public AABB getRenderBoundingBox(MetaMachine machine) { @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public boolean shouldRenderOffScreen(MetaMachine machine) { + public boolean shouldRenderOffScreen(BlockEntity blockEntity) { + if (!(blockEntity instanceof IMachineBlockEntity machineBE)) return false; + if (machineBE.getDefinition() != getDefinition()) return false; if (dynamicRenders.isEmpty()) return false; + + MetaMachine machine = machineBE.getMetaMachine(); for (DynamicRender render : dynamicRenders) { if (render.shouldRenderOffScreen(machine)) return true; } @@ -451,8 +450,13 @@ public boolean shouldRenderOffScreen(MetaMachine machine) { @SuppressWarnings({ "rawtypes", "unchecked" }) @Override - public boolean shouldRender(MetaMachine machine, Vec3 cameraPos) { + public boolean shouldRender(BlockEntity blockEntity, @NotNull Vec3 cameraPos) { + if (!(blockEntity instanceof IMachineBlockEntity machineBE)) return false; + if (machineBE.getDefinition() != getDefinition()) return false; + if (machineBE.getMetaMachine().getCoverContainer().hasDynamicCovers()) return true; if (dynamicRenders.isEmpty()) return false; + + MetaMachine machine = machineBE.getMetaMachine(); for (DynamicRender model : dynamicRenders) { if (model.shouldRender(machine, Minecraft.getInstance().gameRenderer.getMainCamera().getPosition())) { return true; @@ -464,8 +468,6 @@ public boolean shouldRender(MetaMachine machine, Vec3 cameraPos) { @Override public int getViewDistance() { int distance = 0; - if (dynamicRenders.isEmpty()) return distance; - for (DynamicRender model : dynamicRenders) { distance = Math.max(distance, model.getViewDistance()); } @@ -476,14 +478,4 @@ public int getViewDistance() { public BlockEntityType getBlockEntityType() { return getDefinition().getBlockEntityType(); } - - @Override - public void render(@NotNull BlockEntity blockEntity, float partialTick, - @NotNull PoseStack poseStack, @NotNull MultiBufferSource buffer, - int packedLight, int packedOverlay) { - if (!(blockEntity instanceof IMachineBlockEntity machineBE)) return; - if (machineBE.getDefinition() != getDefinition()) return; - - this.render(machineBE.getMetaMachine(), partialTick, poseStack, buffer, packedLight, packedOverlay); - } } diff --git a/src/main/java/com/gregtechceu/gtceu/client/model/machine/multipart/MultiPartBakedModel.java b/src/main/java/com/gregtechceu/gtceu/client/model/machine/multipart/MultiPartBakedModel.java index 513c012c026..d06d8003826 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/model/machine/multipart/MultiPartBakedModel.java +++ b/src/main/java/com/gregtechceu/gtceu/client/model/machine/multipart/MultiPartBakedModel.java @@ -122,7 +122,9 @@ public ChunkRenderTypeSet getRenderTypes(BlockState state, RandomSource rand, Mo BlockPos pos = modelData.get(MODEL_DATA_POS); var machine = (level == null || pos == null) ? null : MetaMachine.getMachine(level, pos); - if (machine == null) return IDynamicBakedModel.super.getRenderTypes(state, rand, modelData); + // When machine is null (BE not loaded yet), use the default model's render types + // to ensure we still render something instead of being invisible + if (machine == null) return defaultModel.getRenderTypes(state, rand, modelData); var renderTypeSets = new LinkedList(); var selectors = getSelectors(machine.getRenderState()); diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockEntityWithBERModelRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockEntityWithBERModelRenderer.java index 0a6ebd861f4..28e283b6c13 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockEntityWithBERModelRenderer.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockEntityWithBERModelRenderer.java @@ -53,8 +53,12 @@ public void render(T blockEntity, float partialTick, Level level = blockEntity.getLevel(); BlockPos pos = blockEntity.getBlockPos(); - // noinspection DataFlowIssue - ModelData modelData = level.getModelData(pos); + ModelData modelData; + // noinspection DataFlowIssue,UnstableApiUsage + if (level.getModelDataManager() == null || (modelData = level.getModelDataManager().getAt(pos)) == null) { + modelData = ModelData.EMPTY; + } + long randomSeed = blockState.getSeed(pos); RandomSource random = RandomSource.create(); random.setSeed(randomSeed); diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockHighlightRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockHighlightRenderer.java index 5a314a1586a..de9973f92d6 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockHighlightRenderer.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/BlockHighlightRenderer.java @@ -37,8 +37,9 @@ import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; import org.jetbrains.annotations.Nullable; -import org.joml.Matrix4f; +import org.joml.Quaternionfc; import org.joml.Vector3f; +import org.joml.Vector3fc; import java.util.Set; import java.util.function.Function; @@ -56,6 +57,7 @@ public static void renderBlockHighlight(PoseStack poseStack, Camera camera, Bloc if (level != null && player != null) { ItemStack held = player.getMainHandItem(); BlockPos blockPos = target.getBlockPos(); + Vector3fc blockCenter = blockPos.getCenter().toVector3f(); Set toolType = ToolHelper.getToolTypes(held); BlockEntity blockEntity = level.getBlockEntity(blockPos); @@ -87,7 +89,7 @@ public static void renderBlockHighlight(PoseStack poseStack, Camera camera, Bloc if (gridHighlight == null) { return; } - var state = level.getBlockState(blockPos); + BlockState state = level.getBlockState(blockPos); poseStack.pushPose(); if (gridHighlight.shouldRenderGrid(player, blockPos, state, held, toolType)) { final IToolGridHighLight finalGridHighlight = gridHighlight; @@ -100,13 +102,12 @@ public static void renderBlockHighlight(PoseStack poseStack, Camera camera, Bloc RenderSystem.disableDepthTest(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); + poseStack.translate(facing.getStepX() * 0.01f, facing.getStepY() * 0.01f, facing.getStepZ() * 0.01f); - RenderUtil.moveToFace(poseStack, - blockPos.getX() - cameraPos.x(), - blockPos.getY() - cameraPos.y(), - blockPos.getZ() - cameraPos.z(), - facing); + poseStack.translate(-cameraPos.x(), -cameraPos.y(), -cameraPos.z()); + + RenderUtil.moveToFace(poseStack, blockCenter, facing); if (facing.getAxis() == Direction.Axis.Y) { RenderUtil.rotateToFace(poseStack, facing, Direction.SOUTH); } else { @@ -162,43 +163,41 @@ private static void drawGridOverlays(PoseStack poseStack, MultiBufferSource buff BlockHitResult blockHitResult, Function texture) { rColour = gColour = 0.2F + (float) Math.sin((System.currentTimeMillis() % (Mth.PI * 800)) / 800) / 2; bColour = 1f; - var blockPos = blockHitResult.getBlockPos(); - var facing = blockHitResult.getDirection(); + BlockPos blockPos = blockHitResult.getBlockPos(); float minX = blockPos.getX(); float maxX = blockPos.getX() + 1; float minY = blockPos.getY(); float maxY = blockPos.getY() + 1; float maxZ = blockPos.getZ() + 1.01f; - var attachSide = ICoverable.traceCoverSide(blockHitResult); - var topRight = new Vector3f(maxX, maxY, maxZ); - var bottomRight = new Vector3f(maxX, minY, maxZ); - var bottomLeft = new Vector3f(minX, minY, maxZ); - var topLeft = new Vector3f(minX, maxY, maxZ); - var shift = new Vector3f(0.25f, 0, 0); - var shiftVert = new Vector3f(0, 0.25f, 0); + Direction attachSide = ICoverable.traceCoverSide(blockHitResult); + Vector3f topRight = new Vector3f(maxX, maxY, maxZ); + Vector3f bottomRight = new Vector3f(maxX, minY, maxZ); + Vector3f bottomLeft = new Vector3f(minX, minY, maxZ); + Vector3f topLeft = new Vector3f(minX, maxY, maxZ); + Vector3f shiftX = new Vector3f(0.25f, 0, 0); + Vector3f shiftY = new Vector3f(0, 0.25f, 0); - var cubeCenter = blockPos.getCenter().toVector3f(); + Vector3f cubeCenter = blockPos.getCenter().toVector3f(); topRight.sub(cubeCenter); bottomRight.sub(cubeCenter); bottomLeft.sub(cubeCenter); topLeft.sub(cubeCenter); - var south = Direction.SOUTH.step(); - var frontVec = getDirectionAxis(facing); - var rotationAngle = getRotationAngle(south, frontVec); - var rotationAxis = getRotationAxis(south, frontVec); - topRight.rotateAxis(rotationAngle, rotationAxis.x(), rotationAxis.y(), rotationAxis.z()); - bottomRight.rotateAxis(rotationAngle, rotationAxis.x(), rotationAxis.y(), rotationAxis.z()); - bottomLeft.rotateAxis(rotationAngle, rotationAxis.x(), rotationAxis.y(), rotationAxis.z()); - topLeft.rotateAxis(rotationAngle, rotationAxis.x(), rotationAxis.y(), rotationAxis.z()); - - Direction front = facing; - Direction back = facing.getOpposite(); - Direction left = RelativeDirection.LEFT.getActualDirection(facing); - Direction right = RelativeDirection.RIGHT.getActualDirection(facing); - Direction top = RelativeDirection.UP.getActualDirection(facing); - Direction bottom = RelativeDirection.DOWN.getActualDirection(facing); + Direction front = blockHitResult.getDirection(); + Direction back = front.getOpposite(); + Direction left = RelativeDirection.LEFT.getActualDirection(front); + Direction right = RelativeDirection.RIGHT.getActualDirection(front); + Direction top = RelativeDirection.UP.getActualDirection(front); + Direction bottom = RelativeDirection.DOWN.getActualDirection(front); + + Quaternionfc rotation = getRotation(Direction.SOUTH, front); + topRight.rotate(rotation); + bottomRight.rotate(rotation); + bottomLeft.rotate(rotation); + topLeft.rotate(rotation); + shiftX.rotate(rotation); + shiftY.rotate(rotation); ResourceTexture leftBlocked = texture.apply(left); ResourceTexture rightBlocked = texture.apply(right); @@ -212,33 +211,28 @@ private static void drawGridOverlays(PoseStack poseStack, MultiBufferSource buff bottomLeft.add(cubeCenter); topLeft.add(cubeCenter); - var buffer = bufferSource.getBuffer(RenderType.lines()); + poseStack.pushPose(); + poseStack.translate(-cameraPos.x(), -cameraPos.y(), -cameraPos.z()); + + VertexConsumer buffer = bufferSource.getBuffer(RenderType.lines()); RenderSystem.lineWidth(3); - var mat = poseStack.last().pose(); + PoseStack.Pose pose = poseStack.last(); // straight top bottom lines - drawLine(mat, buffer, new Vector3f(topRight).add(new Vector3f(shift).mul(-1)), - new Vector3f(bottomRight).add(new Vector3f(shift).mul(-1))); - - drawLine(mat, buffer, new Vector3f(bottomLeft).add(shift), new Vector3f(topLeft).add(shift)); - + drawLine(pose, buffer, new Vector3f(topRight).sub(shiftX), new Vector3f(bottomRight).sub(shiftX)); + drawLine(pose, buffer, new Vector3f(bottomLeft).add(shiftX), new Vector3f(topLeft).add(shiftX)); // straight side to side lines - drawLine(mat, buffer, new Vector3f(topLeft).add(new Vector3f(shiftVert).mul(-1)), - new Vector3f(topRight).add(new Vector3f(shiftVert).mul(-1))); - - drawLine(mat, buffer, new Vector3f(bottomLeft).add(shiftVert), - new Vector3f(bottomRight).add(shiftVert)); + drawLine(pose, buffer, new Vector3f(topLeft).sub(shiftY), new Vector3f(topRight).sub(shiftY)); + drawLine(pose, buffer, new Vector3f(bottomLeft).add(shiftY), new Vector3f(bottomRight).add(shiftY)); - poseStack.pushPose(); RenderSystem.disableDepthTest(); RenderSystem.enableBlend(); RenderSystem.defaultBlendFunc(); - poseStack.translate(facing.getStepX() * 0.01f, facing.getStepY() * 0.01f, facing.getStepZ() * 0.01f); - RenderUtil.moveToFace(poseStack, - blockPos.getX() - cameraPos.x(), - blockPos.getY() - cameraPos.y(), - blockPos.getZ() - cameraPos.z(), - facing); - RenderUtil.rotateToFace(poseStack, facing, Direction.SOUTH); + + poseStack.pushPose(); + poseStack.translate(front.getStepX() * 0.01f, front.getStepY() * 0.01f, front.getStepZ() * 0.01f); + + RenderUtil.moveToFace(poseStack, cubeCenter, front); + RenderUtil.rotateToFace(poseStack, front, Direction.SOUTH); poseStack.scale(1f / 16, 1f / 16, 0); poseStack.translate(-8, -8, 0); poseStack.scale(0.9f, 0.9f, 1); @@ -272,18 +266,20 @@ private static void drawGridOverlays(PoseStack poseStack, MultiBufferSource buff } RenderSystem.disableBlend(); RenderSystem.enableDepthTest(); + + poseStack.popPose(); poseStack.popPose(); } - private static void drawLine(Matrix4f mat, VertexConsumer buffer, Vector3f from, Vector3f to) { - var normal = new Vector3f(from).sub(to); + private static void drawLine(PoseStack.Pose pose, VertexConsumer buffer, Vector3fc from, Vector3fc to) { + Vector3f normal = from.sub(to, new Vector3f()); - buffer.addVertex(mat, from.x, from.y, from.z) + buffer.addVertex(pose.pose(), from.x(), from.y(), from.z()) .setColor(rColour, gColour, bColour, 1f) - .setNormal(normal.x, normal.y, normal.z); - buffer.addVertex(mat, to.x, to.y, to.z) + .setNormal(normal.x(), normal.y(), normal.z()); + buffer.addVertex(pose.pose(), to.x(), to.y(), to.z()) .setColor(rColour, gColour, bColour, 1f) - .setNormal(normal.x, normal.y, normal.z); + .setNormal(normal.x(), normal.y(), normal.z()); } private static void drawResourceTexture(PoseStack poseStack, MultiBufferSource bufferSource, diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/GTRenderTypes.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/GTRenderTypes.java index 22e3acc110b..de06f64951f 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/GTRenderTypes.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/GTRenderTypes.java @@ -1,13 +1,17 @@ package com.gregtechceu.gtceu.client.renderer; +import net.minecraft.Util; import net.minecraft.client.renderer.RenderStateShard; import net.minecraft.client.renderer.RenderType; +import net.minecraft.resources.ResourceLocation; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; import com.mojang.blaze3d.vertex.DefaultVertexFormat; import com.mojang.blaze3d.vertex.VertexFormat; +import java.util.function.Function; + @OnlyIn(Dist.CLIENT) public class GTRenderTypes extends RenderType { @@ -18,6 +22,16 @@ public class GTRenderTypes extends RenderType { .setShaderState(RenderStateShard.POSITION_COLOR_SHADER) .setTransparencyState(RenderStateShard.TRANSLUCENT_TRANSPARENCY) .createCompositeState(false)); + private static final Function GUI_TEXTURE = Util.memoize((texture) -> { + return create("gui_texture", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, + RenderType.TRANSIENT_BUFFER_SIZE, false, true, + RenderType.CompositeState.builder() + .setShaderState(RENDERTYPE_TEXT_SHADER) + .setTextureState(new RenderStateShard.TextureStateShard(texture, false, false)) + .setTransparencyState(TRANSLUCENT_TRANSPARENCY) + .setLightmapState(LIGHTMAP) + .createCompositeState(false)); + }); private GTRenderTypes(String name, VertexFormat format, VertexFormat.Mode mode, int bufferSize, boolean affectsCrumbling, boolean sortOnUpload, Runnable setupState, Runnable clearState) { @@ -27,4 +41,8 @@ private GTRenderTypes(String name, VertexFormat format, VertexFormat.Mode mode, public static RenderType getLightRing() { return LIGHT_RING; } + + public static RenderType guiTexture(ResourceLocation texture) { + return GUI_TEXTURE.apply(texture); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/cover/CoverTextRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/cover/CoverTextRenderer.java new file mode 100644 index 00000000000..95efa90be76 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/cover/CoverTextRenderer.java @@ -0,0 +1,56 @@ +package com.gregtechceu.gtceu.client.renderer.cover; + +import com.gregtechceu.gtceu.api.machine.MetaMachine; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.util.FormattedCharSequence; + +import com.mojang.blaze3d.vertex.PoseStack; +import lombok.Setter; + +import java.util.List; +import java.util.function.Supplier; + +public class CoverTextRenderer implements IDynamicCoverRenderer { + + private static final float TEXT_SCALE = 1 / 144f; + + @Setter + private Supplier> text; + + public CoverTextRenderer(Supplier> text) { + this.text = text; + } + + @Override + public void render(MetaMachine machine, Direction face, float partialTick, PoseStack poseStack, + MultiBufferSource buffer, int packedLight, int packedOverlay) { + poseStack.translate(3 / 16f, 3 / 16f, 0); + poseStack.scale(TEXT_SCALE, TEXT_SCALE, TEXT_SCALE); + int y = 0; + for (Component s : text.get()) { + boolean didAnything = false; + for (FormattedCharSequence line : Minecraft.getInstance().font.split(s, 90)) { + if (y >= 90) return; + Minecraft.getInstance().font.drawInBatch( + line, + 0, y, + 0x72e500, + false, + poseStack.last().pose(), + buffer, + Font.DisplayMode.NORMAL, + 0, + LightTexture.FULL_BRIGHT); + y += Minecraft.getInstance().font.lineHeight; + didAnything = true; + } + if (!didAnything) y += Minecraft.getInstance().font.lineHeight; + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/cover/ICoverableRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/cover/ICoverableRenderer.java index e645c160155..3cfab122062 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/cover/ICoverableRenderer.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/cover/ICoverableRenderer.java @@ -2,10 +2,14 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.ICoverable; +import com.gregtechceu.gtceu.api.cover.CoverBehavior; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.client.util.RenderUtil; import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.client.bakedpipeline.FaceQuad; +import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.texture.TextureAtlas; @@ -19,6 +23,7 @@ import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.neoforge.client.model.data.ModelData; +import com.mojang.blaze3d.vertex.PoseStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -68,4 +73,22 @@ default void renderCovers(List quads, @NotNull ICoverable coverable, } } } + + @OnlyIn(Dist.CLIENT) + default void renderDynamicCovers(MetaMachine machine, float partialTick, PoseStack poseStack, + MultiBufferSource buffer, int packedLight, int packedOverlay) { + ICoverable coverable = machine.getCoverContainer(); + for (Direction face : GTUtil.DIRECTIONS) { + CoverBehavior cover = coverable.getCoverAtSide(face); + IDynamicCoverRenderer renderer = cover != null ? cover.getDynamicRenderer().get() : null; + if (renderer != null) { + poseStack.pushPose(); + RenderUtil.moveToFace(poseStack, .5f, .5f, .5f, face); + RenderUtil.rotateToFace(poseStack, face, Direction.NORTH); + poseStack.translate(-.5f, -.5f, .01f); + renderer.render(machine, face, partialTick, poseStack, buffer, packedLight, packedOverlay); + poseStack.popPose(); + } + } + } } diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/cover/IDynamicCoverRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/cover/IDynamicCoverRenderer.java new file mode 100644 index 00000000000..87e3b07670b --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/cover/IDynamicCoverRenderer.java @@ -0,0 +1,14 @@ +package com.gregtechceu.gtceu.client.renderer.cover; + +import com.gregtechceu.gtceu.api.machine.MetaMachine; + +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.core.Direction; + +import com.mojang.blaze3d.vertex.PoseStack; + +public interface IDynamicCoverRenderer { + + void render(MetaMachine machine, Direction face, float partialTick, PoseStack poseStack, MultiBufferSource buffer, + int packedLight, int packedOverlay); +} diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/item/ToolChargeBarRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/item/ToolChargeBarRenderer.java index 383e469f46e..f2ebebbbdb0 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/item/ToolChargeBarRenderer.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/item/ToolChargeBarRenderer.java @@ -37,8 +37,8 @@ public static void render(GuiGraphics graphics, int level, int xPosition, int yP int x = xPosition + 2; int y = yPosition + 13 - offset; - graphics.fill(RenderType.guiOverlay(), x, y, x + 13, y + (shadow ? 2 : 1), 400, colorShadow); - DrawUtil.fillHorizontalGradient(graphics, RenderType.guiOverlay(), x, y, x + level, y + 1, left, right, 400); + graphics.fill(RenderType.gui(), x, y, x + 13, y + (shadow ? 2 : 1), 190, colorShadow); + DrawUtil.fillHorizontalGradient(graphics, RenderType.gui(), x, y, x + level, y + 1, left, right, 190); // graphics.fill(RenderType.guiOverlay(), x + BAR_W, y, x + BAR_W - level, y - 1, colorBG); } diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/item/decorator/GTTankItemFluidPreview.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/item/decorator/GTTankItemFluidPreview.java new file mode 100644 index 00000000000..3095517848a --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/item/decorator/GTTankItemFluidPreview.java @@ -0,0 +1,109 @@ +package com.gregtechceu.gtceu.client.renderer.item.decorator; + +import com.gregtechceu.gtceu.config.ConfigHolder; +import com.gregtechceu.gtceu.utils.GTUtil; + +import com.lowdragmc.lowdraglib.gui.util.DrawerHelper; + +import net.minecraft.client.gui.Font; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.client.IItemDecorator; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.capability.IFluidHandlerItem; + +import com.mojang.blaze3d.systems.RenderSystem; +import lombok.Getter; +import lombok.Setter; +import org.jetbrains.annotations.Range; + +/** + * An Item Decorator to render including fluid icons for items with {@link ForgeCapabilities#FLUID_HANDLER_ITEM}. + *

+ * The fluid type count can be up to 4, set by {@link #setMaxRenderCount(int)}, 1 by default. + * + * @author Taskeren + */ +public class GTTankItemFluidPreview implements IItemDecorator { + + public static final GTTankItemFluidPreview DRUM = new GTTankItemFluidPreview() { + + @Override + public boolean render(GuiGraphics guiGraphics, Font font, ItemStack itemStack, int x, int y) { + if (!ConfigHolder.INSTANCE.client.tankItemFluidPreview.drum) return false; + return super.render(guiGraphics, font, itemStack, x, y); + } + }; + + public static final GTTankItemFluidPreview QUANTUM_TANK = new GTTankItemFluidPreview() { + + @Override + public boolean render(GuiGraphics guiGraphics, Font font, ItemStack itemStack, int x, int y) { + if (!ConfigHolder.INSTANCE.client.tankItemFluidPreview.quantumTank) return false; + return super.render(guiGraphics, font, itemStack, x, y); + } + }; + + /** + * The fluid icon draw offset to the icon top-left, it should be in order of bottom-right, bottom-left, top-right, + * top-left. + */ + private static final float[][] OFFSET = { { 8, 8 }, { 0, 8 }, { 8, 0 }, { 0, 0 } }; + + /** + * The maximum count of fluids to be rendered, in range from 0 (render nothing) to 4. + */ + @Getter + @Range(from = 0, to = 4) + private int maxRenderCount = 1; + + /** + * If {@code true}, the fluid icon is rendered on top of the item. + */ + @Getter + @Setter + private boolean renderOnTopOfItem = true; + + @Getter + @Setter + private boolean requireShiftKeyDown = false; + + public void setMaxRenderCount(int maxRenderCount) { + if (maxRenderCount < 0 || maxRenderCount > 4) { + throw new IllegalArgumentException("maxRenderCount must be between 0 and 4"); + } + this.maxRenderCount = maxRenderCount; + } + + @Override + public boolean render(GuiGraphics guiGraphics, Font font, ItemStack itemStack, int x, int y) { + if (isRequireShiftKeyDown() && !GTUtil.isShiftDown()) { + return false; + } + + IFluidHandlerItem optional = itemStack.getCapability(Capabilities.FluidHandler.ITEM); + + if (isRenderOnTopOfItem()) { + RenderSystem.disableDepthTest(); + } + + IFluidHandlerItem fluidHandler = optional; + for (int index = 0, renderedCount = 0; index < fluidHandler.getTanks() && + renderedCount < getMaxRenderCount(); index++) { + FluidStack fluidInTank = fluidHandler.getFluidInTank(index); + if (!fluidInTank.isEmpty()) { + DrawerHelper.drawFluidForGui( + guiGraphics, + fluidInTank, + x + OFFSET[renderedCount][0], + y + OFFSET[renderedCount][1], + 8.0F, + 8.0F); + renderedCount++; + } + } + + return true; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/DynamicRenderHelper.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/DynamicRenderHelper.java index 904d771251f..e2b48097e62 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/DynamicRenderHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/DynamicRenderHelper.java @@ -6,10 +6,15 @@ import com.gregtechceu.gtceu.common.block.BoilerFireboxType; import net.minecraft.client.renderer.LightTexture; +import net.minecraft.core.Vec3i; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; +import org.jetbrains.annotations.Nullable; +import org.joml.Vector3f; + +import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.function.Supplier; @@ -28,6 +33,38 @@ public class DynamicRenderHelper { return new FluidAreaRender(fluidBlockRenderer, fixedFluid, drawFaces); } + public static DynamicRender makeGrowingPlantRender(Vec3i... offsets) { + return makeGrowingPlantRender(null, null, offsets); + } + + public static DynamicRender makeGrowingPlantRender(@Nullable Block growingBlock, + @Nullable GrowingPlantRender.GrowthMode growthMode, + Vec3i... offsets) { + return makeGrowingPlantRender(growingBlock, growthMode, Arrays.stream(offsets) + .map(v -> new Vector3f(v.getX(), v.getY(), v.getZ())) + .toList()); + } + + public static DynamicRender makeGrowingPlantRender(Vector3f... offsets) { + return makeGrowingPlantRender(null, null, offsets); + } + + public static DynamicRender makeGrowingPlantRender(@Nullable Block growingBlock, + @Nullable GrowingPlantRender.GrowthMode growthMode, + Vector3f... offsets) { + return makeGrowingPlantRender(growingBlock, growthMode, Arrays.asList(offsets)); + } + + public static DynamicRender makeGrowingPlantRender(List offsets) { + return makeGrowingPlantRender(null, null, offsets); + } + + public static DynamicRender makeGrowingPlantRender(@Nullable Block growingBlock, + @Nullable GrowingPlantRender.GrowthMode growthMode, + List offsets) { + return new GrowingPlantRender(offsets, Optional.ofNullable(growingBlock), Optional.ofNullable(growthMode)); + } + public static DynamicRender makeRecipeFluidAreaRender() { return makeFluidAreaRender(FluidBlockRenderer.Builder.create() .setFaceOffset(-0.125f) @@ -53,4 +90,8 @@ public class DynamicRenderHelper { public static DynamicRender createQuantumTankRender() { return new QuantumTankFluidRender(); } + + public static DynamicRender createCentralMonitorRender() { + return new CentralMonitorRender(); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/BoilerMultiPartRender.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/BoilerMultiPartRender.java index b3555111c1a..634d4d9ed3c 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/BoilerMultiPartRender.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/BoilerMultiPartRender.java @@ -11,7 +11,6 @@ import com.gregtechceu.gtceu.client.renderer.machine.DynamicRenderType; import com.gregtechceu.gtceu.client.util.ModelUtils; import com.gregtechceu.gtceu.common.block.BoilerFireboxType; -import com.gregtechceu.gtceu.common.machine.multiblock.steam.LargeBoilerMachine; import com.gregtechceu.gtceu.data.block.GTBlocks; import net.minecraft.client.renderer.MultiBufferSource; @@ -39,7 +38,7 @@ import java.util.List; import java.util.function.Supplier; -public class BoilerMultiPartRender extends DynamicRender +public class BoilerMultiPartRender extends DynamicRender implements IControllerModelRenderer { // spotless:off @@ -48,7 +47,7 @@ public class BoilerMultiPartRender extends DynamicRender TYPE = new DynamicRenderType<>(BoilerMultiPartRender.CODEC); + public static final DynamicRenderType TYPE = new DynamicRenderType<>(BoilerMultiPartRender.CODEC); // spotless:on @Getter @@ -72,16 +71,17 @@ public BoilerMultiPartRender(BlockState fireboxIdle, BlockState fireboxActive, B } @Override - public DynamicRenderType getType() { + public DynamicRenderType getType() { return TYPE; } @Override - public void render(LargeBoilerMachine machine, float partialTick, PoseStack poseStack, MultiBufferSource buffer, + public void render(MultiblockControllerMachine machine, float partialTick, PoseStack poseStack, + MultiBufferSource buffer, int packedLight, int packedOverlay) {} @Override - public boolean shouldRender(LargeBoilerMachine machine, Vec3 cameraPos) { + public boolean shouldRender(MultiblockControllerMachine machine, Vec3 cameraPos) { return false; } diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/CentralMonitorRender.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/CentralMonitorRender.java new file mode 100644 index 00000000000..ef10c39b30c --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/CentralMonitorRender.java @@ -0,0 +1,95 @@ +package com.gregtechceu.gtceu.client.renderer.machine.impl; + +import com.gregtechceu.gtceu.api.capability.IMonitorComponent; +import com.gregtechceu.gtceu.api.item.ComponentItem; +import com.gregtechceu.gtceu.api.item.component.IItemComponent; +import com.gregtechceu.gtceu.api.item.component.IMonitorModuleItem; +import com.gregtechceu.gtceu.client.renderer.machine.DynamicRender; +import com.gregtechceu.gtceu.client.renderer.machine.DynamicRenderType; +import com.gregtechceu.gtceu.client.util.RenderUtil; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; + +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; + +public class CentralMonitorRender extends DynamicRender { + + // spotless:off + public static final Codec CODEC = Codec.unit(CentralMonitorRender::new); + public static final DynamicRenderType TYPE = new DynamicRenderType(MapCodec.unit(CentralMonitorRender::new)); + // spotless:on + private static final float SCREEN_OFFSET_Z = 0.01f; + + public CentralMonitorRender() {} + + @Override + public DynamicRenderType getType() { + return TYPE; + } + + @Override + public void render(CentralMonitorMachine machine, float partialTick, PoseStack poseStack, MultiBufferSource buffer, + int packedLight, int packedOverlay) { + poseStack.pushPose(); + RenderUtil.moveToFace(poseStack, 0.5f, 0.5f, 0.5f, machine.getFrontFacing()); + RenderUtil.rotateToFace(poseStack, machine.getFrontFacing(), machine.getUpwardsFacing()); + poseStack.translate(-machine.getRightDist() - 0.5f, -machine.getUpDist() - 0.5f, SCREEN_OFFSET_Z); + + if (machine.getRecipeLogic().isActive()) { + for (MonitorGroup group : machine.getMonitorGroups()) { + ItemStack itemStack = group.getItemStackHandler().getStackInSlot(0); + if (!(itemStack.getItem() instanceof ComponentItem item)) { + continue; + } + for (IItemComponent component : item.getComponents()) { + if (!(component instanceof IMonitorModuleItem module)) { + continue; + } + poseStack.pushPose(); + module.getRenderer(group.getItemStackHandler().getStackInSlot(0), machine, group) + .render(machine, group, partialTick, poseStack, buffer, packedLight, packedOverlay); + poseStack.popPose(); + } + } + } + poseStack.popPose(); + } + + @Override + public boolean shouldRenderOffScreen(CentralMonitorMachine machine) { + return true; + } + + @Override + public boolean shouldRender(CentralMonitorMachine machine, Vec3 cameraPos) { + return machine.isFormed(); + } + + @Override + public AABB getRenderBoundingBox(CentralMonitorMachine machine) { + BlockPos pos = machine.getPos(); + BoundingBox bounds = new BoundingBox( + pos.getX() - 1, pos.getY() - 1, pos.getZ() - 1, + pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1); + + for (int row = 0; row <= machine.getUpDist() + machine.getDownDist(); row++) { + for (int col = 0; col <= machine.getLeftDist() + machine.getRightDist(); col++) { + IMonitorComponent component = machine.getComponent(row, col); + if (component != null && component.isMonitor()) { + // noinspection deprecation + bounds.encapsulate(component.getPos()); + } + } + } + return AABB.of(bounds); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FluidAreaRender.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FluidAreaRender.java index bfa2b3de355..ab5f4f042ce 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FluidAreaRender.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FluidAreaRender.java @@ -14,6 +14,7 @@ import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.phys.AABB; import net.neoforged.neoforge.client.RenderTypeHelper; import com.mojang.blaze3d.vertex.PoseStack; @@ -97,26 +98,40 @@ public void render(IFluidRenderMulti machine, float partialTick, return; } - poseStack.pushPose(); - var pose = poseStack.last().pose(); - var fluidRenderType = ItemBlockRenderTypes.getRenderLayer(cachedFluid.defaultFluidState()); var consumer = buffer.getBuffer(RenderTypeHelper.getEntityRenderType(fluidRenderType, false)); for (RelativeDirection face : this.drawFaces) { + poseStack.pushPose(); + var pose = poseStack.last().pose(); + var dir = face.getRelative(machine.self().getFrontFacing(), machine.self().getUpwardsFacing(), machine.self().isFlipped()); if (dir.getAxis() != Direction.Axis.Y) dir = dir.getOpposite(); fluidBlockRenderer.drawPlane(dir, machine.getFluidOffsets(), pose, consumer, cachedFluid, RenderUtil.FluidTextureType.STILL, packedOverlay, machine.self().getPos()); + poseStack.popPose(); } - - poseStack.popPose(); } private Optional getFixedFluid() { if (fixedFluid) return Optional.ofNullable(cachedFluid); else return Optional.empty(); } + + @Override + public boolean shouldRenderOffScreen(IFluidRenderMulti machine) { + return true; + } + + @Override + public AABB getRenderBoundingBox(IFluidRenderMulti machine) { + AABB box = super.getRenderBoundingBox(machine); + var offsets = machine.getFluidOffsets(); + for (var offset : offsets) { + box = box.minmax(new AABB(offset)); + } + return box.inflate(getViewDistance()); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FusionRingRender.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FusionRingRender.java index 9f57e24ed7e..52c9ae9977e 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FusionRingRender.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/FusionRingRender.java @@ -1,16 +1,12 @@ package com.gregtechceu.gtceu.client.renderer.machine.impl; -import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; import com.gregtechceu.gtceu.client.renderer.GTRenderTypes; import com.gregtechceu.gtceu.client.renderer.machine.DynamicRender; import com.gregtechceu.gtceu.client.renderer.machine.DynamicRenderType; -import com.gregtechceu.gtceu.client.util.BloomUtils; import com.gregtechceu.gtceu.client.util.RenderBufferHelper; import com.gregtechceu.gtceu.common.machine.multiblock.electric.FusionReactorMachine; -import com.lowdragmc.shimmer.client.shader.RenderUtils; - import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.util.Mth; @@ -56,13 +52,13 @@ public void render(FusionReactorMachine machine, float partialTick, if (!machine.recipeLogic.isWorking() && delta <= 0) { return; } - if (GTCEu.Mods.isShimmerLoaded()) { - PoseStack finalStack = RenderUtils.copyPoseStack(poseStack); - BloomUtils.entityBloom(source -> renderLightRing(machine, partialTick, finalStack, - source.getBuffer(GTRenderTypes.getLightRing()))); - } else { - renderLightRing(machine, partialTick, poseStack, buffer.getBuffer(GTRenderTypes.getLightRing())); - } + // if (GTCEu.Mods.isShimmerLoaded()) { + // PoseStack finalStack = RenderUtils.copyPoseStack(poseStack); + // BloomUtils.entityBloom(source -> renderLightRing(machine, partialTick, finalStack, + // source.getBuffer(GTRenderTypes.getLightRing()))); + // } else { + renderLightRing(machine, partialTick, poseStack, buffer.getBuffer(GTRenderTypes.getLightRing())); + // } } @OnlyIn(Dist.CLIENT) diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/GrowingPlantRender.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/GrowingPlantRender.java new file mode 100644 index 00000000000..3fc6f3ddb7d --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/GrowingPlantRender.java @@ -0,0 +1,505 @@ +package com.gregtechceu.gtceu.client.renderer.machine.impl; + +import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.recipe.content.Content; +import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; +import com.gregtechceu.gtceu.client.renderer.machine.DynamicRender; +import com.gregtechceu.gtceu.client.renderer.machine.DynamicRenderType; +import com.gregtechceu.gtceu.client.util.RenderUtil; +import com.gregtechceu.gtceu.config.ConfigHolder; +import com.gregtechceu.gtceu.core.mixins.GrowingPlantBlockAccessor; +import com.gregtechceu.gtceu.core.mixins.IntegerPropertyAccessor; +import com.gregtechceu.gtceu.core.mixins.StemBlockAccessor; +import com.gregtechceu.gtceu.data.tag.CustomTags; +import com.gregtechceu.gtceu.utils.GTMath; +import com.gregtechceu.gtceu.utils.memoization.GTMemoizer; + +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.tags.BlockTags; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.util.Mth; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.*; +import net.minecraft.world.level.levelgen.structure.BoundingBox; +import net.minecraft.world.phys.AABB; +import net.neoforged.neoforge.common.crafting.SizedIngredient; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import lombok.Getter; +import org.apache.commons.lang3.function.TriFunction; +import org.jetbrains.annotations.Nullable; +import org.joml.Vector3f; +import org.joml.Vector3fc; + +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class GrowingPlantRender extends DynamicRender { + + // spotless:off + @SuppressWarnings("deprecation") + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + ExtraCodecs.VECTOR3F.listOf().fieldOf("offsets").forGetter(GrowingPlantRender::getOffsets), + BuiltInRegistries.BLOCK.byNameCodec().optionalFieldOf("growing_block").forGetter(GrowingPlantRender::getGrowingBlock), + GrowthMode.CODEC.optionalFieldOf("growth_mode").forGetter(GrowingPlantRender::getGrowthMode) + ).apply(instance, GrowingPlantRender::new)); + public static final DynamicRenderType TYPE = new DynamicRenderType<>(GrowingPlantRender.CODEC); + // spotless:on + + private static final float EPSILON = 1e-25f; + + @Getter + private final List offsets; + @Getter + private final Optional growingBlock; + @Getter + private final Optional growthMode; + + public GrowingPlantRender(List offsets) { + this(offsets, Optional.empty(), Optional.empty()); + } + + public GrowingPlantRender(List offsets, Optional growingBlock, Optional growthMode) { + this.offsets = offsets; + this.growingBlock = growingBlock; + this.growthMode = growthMode; + } + + @Override + public DynamicRenderType getType() { + return TYPE; + } + + @Override + public int getViewDistance() { + return 32; + } + + @Override + public AABB getRenderBoundingBox(IRecipeLogicMachine machine) { + final BlockPos pos = machine.self().getPos(); + + List positions = new ArrayList<>(); + Collections.addAll(positions, pos.offset(-1, 0, -1), pos.offset(2, 2, 2)); + for (Vector3f offset : this.offsets) { + positions.add(BlockPos.containing(offset.x(), offset.y(), offset.z())); + } + + return BoundingBox.encapsulatingPositions(positions).map(AABB::of) + .orElseGet(() -> super.getRenderBoundingBox(machine)); + } + + @Override + public void render(IRecipeLogicMachine rlm, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, + int packedLight, int packedOverlay) { + if (!ConfigHolder.INSTANCE.client.renderer.renderGrowingPlants) return; + if (!rlm.isActive()) return; + final RecipeLogic recipeLogic = rlm.getRecipeLogic(); + + Optional currentBlock = this.growingBlock + .or(() -> Optional.ofNullable(recipeLogic.getLastRecipe()).flatMap(this::findGrowing)); + if (currentBlock.isEmpty()) return; + Block growing = currentBlock.get(); + BlockState state = growing.defaultBlockState(); + + double progress = recipeLogic.getProgressPercent(); + GrowthMode mode = this.growthMode.orElseGet(() -> getGrowthModeForBlock(growing)); + + // a couple of special case replacements in case of small mistakes in manual configuration + if (this.growthMode.isPresent() && !mode.predicate().test(growing)) { + if (mode == GrowthMode.GROWING_PLANT && GrowthMode.DOUBLE_TRANSLATE.predicate.test(growing)) { + mode = GrowthMode.DOUBLE_TRANSLATE; + } + if (mode == GrowthMode.AGE_4 && GrowthMode.PICKLES.predicate().test(growing)) { + // special case the pickles property to work if using age_4 + mode = GrowthMode.PICKLES; + } else if (mode == GrowthMode.AGE_4 && GrowthMode.FLOWER_AMOUNT.predicate().test(growing)) { + // special case the flower amount property to work if using age_4 + mode = GrowthMode.FLOWER_AMOUNT; + } else if (mode == GrowthMode.AGE_7 && GrowthMode.STEM.predicate().test(growing)) { + // special case stem plants to show stems + mode = GrowthMode.STEM; + } else { + // generic incompatibility, use default mode + mode = GrowthMode.SCALE; + } + } + + MetaMachine machine = rlm.self(); + Level level = machine.getLevel(); + assert level != null; + BlockPos machinePos = machine.getPos(); + + var statesToDraw = mode.renderFunction().configureState(level, state, progress); + + for (Vector3fc offset : this.getOffsets()) { + poseStack.pushPose(); + + Vector3f rotated = new Vector3f(offset); + rotated.rotateX(-Mth.HALF_PI); + machine.getFrontFacing().getRotation().transform(rotated); + poseStack.translate(rotated.x(), rotated.y() + EPSILON, rotated.z()); + + BlockPos pos = machinePos.offset(BlockPos.containing(rotated.x(), rotated.y(), rotated.z())); + for (StateWithOffset toDraw : statesToDraw) { + poseStack.pushPose(); + Vector3fc translation = toDraw.offset; + poseStack.translate(translation.x(), translation.y(), translation.z()); + + mode.renderFunction().renderGrowingBlock(level, pos, rotated, toDraw.state, + progress, bufferSource, poseStack); + + poseStack.popPose(); + } + + poseStack.popPose(); + } + } + + public void drawBlocks(BlockAndTintGetter level, BlockPos machinePos, Direction frontFacing, + double progress, GrowthMode mode, BlockState state, + PoseStack poseStack, MultiBufferSource bufferSource) { + for (final Vector3fc offset : getOffsets()) { + poseStack.pushPose(); + + Vector3f rotated = new Vector3f(offset); + rotated.rotateX(-Mth.HALF_PI); + frontFacing.getRotation().transform(rotated); + poseStack.translate(rotated.x(), rotated.y(), rotated.z()); + + poseStack.translate(0, 1 + EPSILON, 0); + poseStack.translate(0.0, (progress * 2) % (1 + EPSILON) - 1, 0.0); + if (mode == GrowthMode.GROWING_PLANT && state.getBlock() instanceof GrowingPlantBlock gp) { + poseStack.last().pose().rotateAround( + ((GrowingPlantBlockAccessor) gp).gtceu$getGrowthDirection().getRotation(), 0.5f, 0.5f, 0.5f); + } + RenderUtil.drawBlock(level, machinePos, state, bufferSource, poseStack); + + poseStack.popPose(); + } + } + + protected Optional findGrowing(GTRecipe recipe) { + return RECIPE_BLOCK_CACHE.apply(recipe); + } + + private static final Function> RECIPE_BLOCK_CACHE = GTMemoizer + .memoizeFunctionWeakIdent(recipe -> { + List allItemContents = new ArrayList<>(); + allItemContents.addAll(recipe.getInputContents(ItemRecipeCapability.CAP)); + allItemContents.addAll(recipe.getTickInputContents(ItemRecipeCapability.CAP)); + allItemContents.addAll(recipe.getOutputContents(ItemRecipeCapability.CAP)); + allItemContents.addAll(recipe.getTickOutputContents(ItemRecipeCapability.CAP)); + return allItemContents.stream() + .map(Content::getContent).map(ItemRecipeCapability.CAP::of) + .map(SizedIngredient::getItems).flatMap(Arrays::stream) + .map(ItemStack::getItem) + .filter(BlockItem.class::isInstance) + .findFirst() + .map(BlockItem.class::cast) + .map(BlockItem::getBlock); + }); + + protected GrowthMode getGrowthModeForBlock(Block block) { + if (block instanceof GrowingPlantBlock) { + return GrowthMode.GROWING_PLANT; + } + if (block instanceof StemBlock) { + return GrowthMode.STEM; + } + + BlockState state = block.defaultBlockState(); + IntegerProperty ageProp = findAgeProperty(state.getProperties()); + if (ageProp != null) { + GrowthMode mode = GrowthMode.MODE_BY_PROPERTY.get(ageProp); + if (mode != null) return mode; + } + + if (state.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF) || + state.hasProperty(BlockStateProperties.HALF) || + state.is(CustomTags.TALL_PLANTS)) { + return GrowthMode.DOUBLE_TRANSLATE; + } else if (state.is(BlockTags.FLOWERS)) { + return GrowthMode.TRANSLATE; + } + // default to SCALE + return GrowthMode.SCALE; + } + + public static @Nullable IntegerProperty findAgeProperty(Collection> properties) { + for (Property prop : properties) { + if ((prop.getName().equals("age") || prop.getName().equals("pickles") || + prop.getName().equals("flower_amount")) && + prop instanceof IntegerProperty intProp) { + return intProp; + } + } + return null; + } + + public record GrowthMode(String name, + Predicate predicate, + RenderFunction renderFunction) { + + public static final Map VALUES = new HashMap<>(); + public static final Map MODE_BY_PROPERTY = new HashMap<>(); + + public static final GrowthMode NONE = new GrowthMode("none", RenderFunction.NO_OP); + public static final GrowthMode SCALE = new GrowthMode("scale", RenderFunction.SCALE); + public static final GrowthMode TRANSLATE = new GrowthMode("translate", RenderFunction.TRANSLATE); + + public static final GrowthMode DOUBLE_TRANSLATE = new GrowthMode("double_translate", + RenderFunction.DOUBLE_BLOCK); + public static final GrowthMode GROWING_PLANT = new GrowthMode("growing_plant", + block -> block instanceof GrowingPlantBlock, RenderFunction.GROWING_PLANT); + + public static final GrowthMode STEM = new GrowthMode("stem", block -> block instanceof StemBlock, + RenderFunction.STEM); + + // all the different age properties. not going to add extras, though. + public static final GrowthMode AGE_1 = ofIntegerProperty("age_1", BlockStateProperties.AGE_1); + public static final GrowthMode AGE_2 = ofIntegerProperty("age_2", BlockStateProperties.AGE_2); + public static final GrowthMode AGE_3 = ofIntegerProperty("age_3", BlockStateProperties.AGE_3); + public static final GrowthMode AGE_4 = ofIntegerProperty("age_4", BlockStateProperties.AGE_4); + public static final GrowthMode AGE_5 = ofIntegerProperty("age_5", BlockStateProperties.AGE_5); + public static final GrowthMode AGE_7 = ofIntegerProperty("age_7", BlockStateProperties.AGE_7); + public static final GrowthMode AGE_15 = ofIntegerProperty("age_15", BlockStateProperties.AGE_15); + public static final GrowthMode AGE_25 = ofIntegerProperty("age_25", BlockStateProperties.AGE_25); + + public static final GrowthMode PICKLES = ofIntegerProperty("pickles", BlockStateProperties.PICKLES, 0, 4); + public static final GrowthMode FLOWER_AMOUNT = ofIntegerProperty("flower_amount", + BlockStateProperties.FLOWER_AMOUNT, 0, 4); + + private static final Codec CODEC = Codec.STRING.comapFlatMap(name -> { + GrowthMode mode = VALUES.get(name); + if (mode != null) { + return DataResult.success(mode); + } else { + // default to SCALE in case of an error + return DataResult.error(() -> "Could not find growth mode named " + name, SCALE); + } + }, GrowthMode::name); + + public GrowthMode { + VALUES.put(name, this); + } + + public GrowthMode(String name, RenderFunction renderFunction) { + this(name, block -> true, renderFunction); + } + + public static GrowthMode ofIntegerProperty(String name, IntegerProperty property) { + return ofIntegerProperty(name, property, OptionalInt.empty(), OptionalInt.empty()); + } + + public static GrowthMode ofIntegerProperty(String name, IntegerProperty property, int min, int max) { + return ofIntegerProperty(name, property, OptionalInt.of(min), OptionalInt.of(max)); + } + + public static GrowthMode ofIntegerProperty(String name, IntegerProperty property, OptionalInt min, + OptionalInt max) { + GrowthMode mode = new GrowthMode(name, + block -> block.getStateDefinition().getProperties().contains(property), + RenderFunction.byIntegerProperty(property, min, max)); + MODE_BY_PROPERTY.put(property, mode); + return mode; + } + } + + @FunctionalInterface + public interface RenderFunction { + + void renderGrowingBlock(BlockAndTintGetter level, BlockPos pos, Vector3f offset, BlockState state, + double progress, MultiBufferSource bufferSource, PoseStack poseStack); + + default Collection configureState(BlockAndTintGetter level, BlockState state, + double progress) { + return Collections.singleton(new StateWithOffset(state)); + } + + RenderFunction NO_OP = (level, pos, offset, state, progress, bufferSource, poseStack) -> {}; + + RenderFunction SCALE = (level, pos, offset, state, progress, bufferSource, poseStack) -> { + poseStack.last().pose().scaleAround((float) progress, 0.5f, 0.0f, 0.5f); + poseStack.last().normal().scale((float) progress); + + RenderUtil.drawBlock(level, pos, state, bufferSource, poseStack); + }; + + RenderFunction.ConfigureOnly TRANSLATE = (level, state, progress) -> { + Vector3fc translation = new Vector3f(0, (float) (progress - 1), 0); + return Collections.singleton(new StateWithOffset(state, translation)); + }; + + RenderFunction.ConfigureOnly DOUBLE_BLOCK = (level, state, progress) -> { + Vector3fc translation = new Vector3f(0, (float) (progress * 2 - 1), 0); + + if (progress > 0.5) { + Vector3fc bottomTranslation = new Vector3f(translation.x(), translation.y() - 1, translation.z()); + + BlockState topState = state; + if (state.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)) { + topState = topState.trySetValue(BlockStateProperties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.UPPER); + } else if (state.hasProperty(BlockStateProperties.HALF)) { + topState = topState.trySetValue(BlockStateProperties.HALF, Half.TOP); + } + + return Arrays.asList(new StateWithOffset(state, bottomTranslation), + new StateWithOffset(topState, translation)); + } else { + if (state.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)) { + state = state.trySetValue(BlockStateProperties.DOUBLE_BLOCK_HALF, DoubleBlockHalf.UPPER); + } else if (state.hasProperty(BlockStateProperties.HALF)) { + state = state.trySetValue(BlockStateProperties.HALF, Half.TOP); + } + + return Collections.singleton(new StateWithOffset(state, translation)); + } + }; + + RenderFunction GROWING_PLANT = new RenderFunction() { + + @Override + public void renderGrowingBlock(BlockAndTintGetter level, BlockPos pos, Vector3f offset, BlockState state, + double progress, MultiBufferSource bufferSource, PoseStack poseStack) { + GrowingPlantBlockAccessor accessor = (GrowingPlantBlockAccessor) state.getBlock(); + poseStack.rotateAround(accessor.gtceu$getGrowthDirection().getRotation(), 0.5f, 0.5f, 0.5f); + + RenderUtil.drawBlock(level, pos, state, bufferSource, poseStack); + } + + @Override + public Collection configureState(BlockAndTintGetter level, BlockState state, + double progress) { + GrowingPlantBlockAccessor accessor = (GrowingPlantBlockAccessor) state.getBlock(); + + Vector3fc translation = new Vector3f(0, (float) (progress * 2 - 1), 0); + + if (progress < 0.5) { + BlockState headState = accessor.gtceu$getHeadBlock().defaultBlockState(); + IntegerProperty ageProp = findAgeProperty(headState.getProperties()); + if (ageProp != null) { + IntegerPropertyAccessor prop = (IntegerPropertyAccessor) ageProp; + int minValue = prop.gtceu$getMin(); + int maxValue = prop.gtceu$getMax(); + + int stage = GTMath.lerpInt(progress, minValue, maxValue + 1); + headState = headState.trySetValue(ageProp, Math.min(stage, maxValue)); + } + + if (progress >= 0.25 && headState.hasProperty(BlockStateProperties.BERRIES)) { + headState = headState.trySetValue(CaveVines.BERRIES, true); + } + + return Collections.singleton(new StateWithOffset(headState, translation)); + } else { + BlockState headState = accessor.gtceu$getHeadBlock().defaultBlockState(); + IntegerProperty ageProp = findAgeProperty(headState.getProperties()); + if (ageProp != null) { + headState = headState.trySetValue(ageProp, ((IntegerPropertyAccessor) ageProp).gtceu$getMax()); + } + if (headState.hasProperty(BlockStateProperties.BERRIES)) { + headState = headState.trySetValue(CaveVines.BERRIES, true); + } + + BlockState bodyState = accessor.gtceu$getBodyBlock().defaultBlockState(); + if (progress >= 0.75 && bodyState.hasProperty(BlockStateProperties.BERRIES)) { + bodyState = bodyState.trySetValue(CaveVines.BERRIES, true); + } + Vector3fc bodyTranslation = new Vector3f(translation.x(), translation.y() - 1, translation.z()); + + return Arrays.asList(new StateWithOffset(bodyState, bodyTranslation), + new StateWithOffset(headState, translation)); + } + } + }; + + RenderFunction.ConfigureOnly STEM = (level, state, progress) -> { + final StemBlock block = (StemBlock) state.getBlock(); + final int growthStage = GTMath.lerpInt(progress, 0, StemBlock.MAX_AGE + 2); + if (growthStage > StemBlock.MAX_AGE) + return List.of(new StateWithOffset(((StemBlockAccessor) block).gtceu$getFruit().defaultBlockState())); + state = state.trySetValue(StemBlock.AGE, growthStage); + return List.of(new StateWithOffset(state)); + }; + + TriFunction PROPERTY_FUNCTION_CACHE = GTMemoizer + .memoize((property, setMin, setMax) -> { + IntegerPropertyAccessor accessor = (IntegerPropertyAccessor) property; + final int presumedMinValue = accessor.gtceu$getMin(); + final int presumedMaxValue = accessor.gtceu$getMax(); + return (level, state, progress) -> { + final int min = setMin.orElse(presumedMinValue); + final int betterMaxValue = state.getBlock() instanceof CropBlock crop ? + Math.max(presumedMaxValue, crop.getMaxAge()) : presumedMaxValue; + final int max = setMax.orElse(betterMaxValue); + int growthStage = GTMath.lerpInt(progress, min, max + 1); + if (growthStage < presumedMinValue) { + return Collections.emptySet(); + } + if (state.getBlock() instanceof CropBlock crop) { + state = crop.getStateForAge(Math.min(growthStage, betterMaxValue)); + } else { + state = state.trySetValue(property, Math.min(growthStage, betterMaxValue)); + } + if (state.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)) { + final var topState = state.trySetValue(BlockStateProperties.DOUBLE_BLOCK_HALF, + DoubleBlockHalf.UPPER); + return List.of(new StateWithOffset(state), + new StateWithOffset(topState, new Vector3f(0, 1, 0))); + } + if (state.hasProperty(BlockStateProperties.HALF)) { + final var topState = state.trySetValue(BlockStateProperties.HALF, Half.TOP); + return List.of(new StateWithOffset(state), + new StateWithOffset(topState, new Vector3f(0, 1, 0))); + } + + return List.of(new StateWithOffset(state)); + }; + }); + + static RenderFunction.ConfigureOnly byIntegerProperty(IntegerProperty property, OptionalInt min, + OptionalInt max) { + return PROPERTY_FUNCTION_CACHE.apply(property, min, max); + } + + @FunctionalInterface + interface ConfigureOnly extends RenderFunction { + + @Override + default void renderGrowingBlock(BlockAndTintGetter level, BlockPos pos, Vector3f offset, BlockState state, + double progress, MultiBufferSource bufferSource, PoseStack poseStack) { + RenderUtil.drawBlock(level, pos, state, bufferSource, poseStack); + } + + @Override + Collection configureState(BlockAndTintGetter level, BlockState state, double progress); + } + } + + public record StateWithOffset(BlockState state, Vector3fc offset) { + + private static final Vector3fc ZERO_VECTOR = new Vector3f(); + + public StateWithOffset(BlockState state) { + this(state, ZERO_VECTOR); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/QuantumChestItemRender.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/QuantumChestItemRender.java index 44ada84b87f..53e8905bf32 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/QuantumChestItemRender.java +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/machine/impl/QuantumChestItemRender.java @@ -97,12 +97,10 @@ public void renderChestItem(PoseStack poseStack, MultiBufferSource buffer, float poseStack.pushPose(); poseStack.translate(0.5f, 0.5f, 0.5f); if (frontFacing.getAxis() == Direction.Axis.Y) { - var north = Direction.NORTH.step(); - var front = frontFacing.step(); - var rotationAngle = getRotationAngle(north, front); - poseStack.mulPose(new Quaternionf().fromAxisAngleRad(getRotationAxis(north, front), rotationAngle)); + Quaternionf rotation = getRotation(Direction.NORTH, frontFacing); + poseStack.mulPose(rotation); } - poseStack.mulPose(new Quaternionf().rotateAxis(totalTick * Mth.TWO_PI / 80, 0, 1, 0)); + poseStack.mulPose(new Quaternionf().rotateY(totalTick * Mth.TWO_PI / 80)); poseStack.scale(0.6f, 0.6f, 0.6f); itemRenderer.renderStatic(itemStack, ItemDisplayContext.FIXED, @@ -132,7 +130,7 @@ public static void drawAmountText(PoseStack poseStack, MultiBufferSource buffer, poseStack.translate(frontFacing.getStepX() * -1 / 16f, frontFacing.getStepY() * -1 / 16f, frontFacing.getStepZ() * -1 / 16f); - RenderUtil.moveToFace(poseStack, 0, 0, 0, frontFacing); + RenderUtil.moveToFace(poseStack, 0.5f, 0.5f, 0.5f, frontFacing); RenderUtil.rotateToFace(poseStack, frontFacing, Direction.NORTH); poseStack.scale(1f / 64, 1f / 64, 0); poseStack.translate(-32, -32, 0); diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/IMonitorRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/IMonitorRenderer.java new file mode 100644 index 00000000000..4a6e202b51a --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/IMonitorRenderer.java @@ -0,0 +1,17 @@ +package com.gregtechceu.gtceu.client.renderer.monitor; + +import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; + +import net.minecraft.client.renderer.MultiBufferSource; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; + +import com.mojang.blaze3d.vertex.PoseStack; + +public interface IMonitorRenderer { + + @OnlyIn(Dist.CLIENT) + void render(CentralMonitorMachine machine, MonitorGroup group, float partialTick, PoseStack poseStack, + MultiBufferSource buffer, int packedLight, int packedOverlay); +} diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorImageRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorImageRenderer.java new file mode 100644 index 00000000000..6a178e8661a --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorImageRenderer.java @@ -0,0 +1,49 @@ +package com.gregtechceu.gtceu.client.renderer.monitor; + +import com.gregtechceu.gtceu.client.renderer.GTRenderTypes; +import com.gregtechceu.gtceu.client.util.ClientImageCache; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; +import com.gregtechceu.gtceu.utils.GTUtil; + +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import org.joml.Matrix4f; + +public class MonitorImageRenderer implements IMonitorRenderer { + + private final String url; + + public MonitorImageRenderer(String url) { + this.url = url; + } + + @Override + public void render(CentralMonitorMachine machine, MonitorGroup group, float partialTick, PoseStack poseStack, + MultiBufferSource buffer, int packedLight, int packedOverlay) { + BlockPos rel = group.getRow(0, machine::toRelative).get(0); + BlockPos size = GTUtil.getLast(group.getRow(-1, machine::toRelative)) + .offset(-rel.getX() + 1, -rel.getY() + 1, -rel.getZ() + 1); + + poseStack.translate(rel.getX(), rel.getY(), rel.getZ()); + + ResourceLocation textureId = ClientImageCache.getOrLoadTexture(url); + if (textureId == null) return; + + VertexConsumer consumer = buffer.getBuffer(GTRenderTypes.guiTexture(textureId)); + Matrix4f pose = poseStack.last().pose(); + + float minX = 0, maxX = size.getX(); + float minY = 0, maxY = size.getY(); + + consumer.addVertex(pose, minX, maxY, 0).setColor(0xFFFFFFFF).setUv(0, 1).setLight(LightTexture.FULL_BRIGHT); + consumer.addVertex(pose, maxX, maxY, 0).setColor(0xFFFFFFFF).setUv(1, 1).setLight(LightTexture.FULL_BRIGHT); + consumer.addVertex(pose, maxX, minY, 0).setColor(0xFFFFFFFF).setUv(1, 0).setLight(LightTexture.FULL_BRIGHT); + consumer.addVertex(pose, minX, minY, 0).setColor(0xFFFFFFFF).setUv(0, 0).setLight(LightTexture.FULL_BRIGHT); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorTextRenderer.java b/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorTextRenderer.java new file mode 100644 index 00000000000..029a85b5223 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/client/renderer/monitor/MonitorTextRenderer.java @@ -0,0 +1,76 @@ +package com.gregtechceu.gtceu.client.renderer.monitor; + +import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Font; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.util.FormattedCharSequence; + +import com.mojang.blaze3d.vertex.PoseStack; + +import java.util.List; + +public class MonitorTextRenderer implements IMonitorRenderer { + + private static final float TEXT_SCALE = 1 / 144f; + private final List text; + private final float scale; + + public MonitorTextRenderer(List text, double scale) { + this.text = text; + this.scale = (float) scale; + } + + @Override + public void render(CentralMonitorMachine machine, MonitorGroup group, float partialTick, PoseStack poseStack, + MultiBufferSource buffer, int packedLight, int packedOverlay) { + try { + BlockPos rel = group.getRow(0, machine::toRelative).get(0); + int row = 0; + int columns = group.getRow(0, machine::toRelative).size(); + poseStack.translate(rel.getX(), rel.getY(), rel.getZ()); + poseStack.scale(TEXT_SCALE * scale, TEXT_SCALE * scale, TEXT_SCALE * scale); + float y = 9; + for (Component s : text) { + boolean didAnything = false; + for (FormattedCharSequence line : Minecraft.getInstance().font.split(s, + Math.round(columns * 135 / scale))) { + if (y >= 144) { + try { + row++; + columns = group.getRow(row, machine::toRelative).size(); + y -= 144; + poseStack.translate(-rel.getX() / (TEXT_SCALE * scale), -rel.getY() / (TEXT_SCALE * scale), + -rel.getZ() / (TEXT_SCALE * scale)); + rel = group.getRow(row, machine::toRelative).get(0); + poseStack.translate(rel.getX() / (TEXT_SCALE * scale), rel.getY() / (TEXT_SCALE * scale), + rel.getZ() / (TEXT_SCALE * scale)); + } catch (IndexOutOfBoundsException e) { + return; + } + } + Minecraft.getInstance().font.drawInBatch( + line, + 9, y, + 0xFFFFFF, + false, + poseStack.last().pose(), + buffer, + Font.DisplayMode.NORMAL, + 0, + LightTexture.FULL_BRIGHT); + y += Minecraft.getInstance().font.lineHeight * scale; + didAnything = true; + } + if (!didAnything) { + y += Minecraft.getInstance().font.lineHeight * scale; + } + } + } catch (IndexOutOfBoundsException ignored) {} + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/client/util/BloomUtils.java b/src/main/java/com/gregtechceu/gtceu/client/util/BloomUtils.java index 599e4f9eb07..2fd44bf5290 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/util/BloomUtils.java +++ b/src/main/java/com/gregtechceu/gtceu/client/util/BloomUtils.java @@ -1,6 +1,6 @@ package com.gregtechceu.gtceu.client.util; -import com.lowdragmc.shimmer.client.postprocessing.PostProcessing; +// import com.lowdragmc.shimmer.client.postprocessing.PostProcessing; import net.minecraft.client.renderer.MultiBufferSource; import net.neoforged.api.distmarker.Dist; @@ -14,6 +14,6 @@ public class BloomUtils { public static void entityBloom(Consumer sourceConsumer) { // Shimmer will call PostProcessing.BLOOM_UNREAL.renderEntityPost in LevelRenderer#renderLevel // We probably don't need to call it ourselves - PostProcessing.BLOOM_UNREAL.postEntity(sourceConsumer); + // PostProcessing.BLOOM_UNREAL.postEntity(sourceConsumer); } } diff --git a/src/main/java/com/gregtechceu/gtceu/client/util/ClientImageCache.java b/src/main/java/com/gregtechceu/gtceu/client/util/ClientImageCache.java new file mode 100644 index 00000000000..90b52aaf4ad --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/client/util/ClientImageCache.java @@ -0,0 +1,105 @@ +package com.gregtechceu.gtceu.client.util; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.misc.ImageCache; +import com.gregtechceu.gtceu.common.network.GTNetwork; +import com.gregtechceu.gtceu.common.network.packets.CPacketImageRequest; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.AbstractTexture; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.SimpleTexture; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.mojang.blaze3d.platform.NativeImage; +import org.apache.commons.lang3.ArrayUtils; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +@OnlyIn(Dist.CLIENT) +public class ClientImageCache { + + private static final Map imageParts = new HashMap<>(); + + private static boolean downloading = false; + // TODO make some kind of loading icon for this + private static final AbstractTexture LOADING_TEXTURE_MARKER = new SimpleTexture( + GTCEu.id("textures/block/void.png")); + private static final LoadingCache CACHE = CacheBuilder.newBuilder() + .refreshAfterWrite(ImageCache.REFRESH_SECS, TimeUnit.SECONDS) + .expireAfterAccess(ImageCache.EXPIRE_SECS, TimeUnit.SECONDS) + .build(CacheLoader.from(url -> { + if (!downloading) { + downloading = true; + GTCEu.LOGGER.debug("Requesting image {}", url); + GTNetwork.sendToServer(new CPacketImageRequest(url)); + } + return LOADING_TEXTURE_MARKER; + })); + + private static @NotNull ResourceLocation getUrlTextureId(String url) { + return GTCEu.id("textures/central_monitor/image_" + url.hashCode()); + } + + public static @Nullable ResourceLocation getOrLoadTexture(String url) { + AbstractTexture texture = null; + + try { + texture = CACHE.get(url); + } catch (ExecutionException e) { + Throwable t = e; + if (t.getCause() != null) { + t = t.getCause(); + } + GTCEu.LOGGER.error("Could not load image {}", url, t); + } + if (texture == null || texture == LOADING_TEXTURE_MARKER) { + return null; + } + + return getUrlTextureId(url); + } + + @ApiStatus.Internal + public static void receiveImagePart(String url, byte[] imagePart, int index, + final int totalParts) throws IOException { + byte[][] parts = imageParts.computeIfAbsent(url, $ -> new byte[totalParts][]); + parts[index] = imagePart; + + if (index == totalParts - 1) { + byte[] imageBytes = new byte[imagePart.length]; + int currentIndex = 0; + for (byte[] part : parts) { + imageBytes = ArrayUtils.insert(currentIndex, imageBytes, part); + currentIndex += part.length; + } + + saveTexture(url, imageBytes); + imageParts.remove(url); + downloading = false; + } + } + + private static void saveTexture(String url, byte[] imageBytes) throws IOException { + ByteBuffer buffer = ByteBuffer.allocateDirect(imageBytes.length); + buffer.put(imageBytes).flip(); + DynamicTexture texture = new DynamicTexture(NativeImage.read(buffer)); + + Minecraft.getInstance().getTextureManager().register(getUrlTextureId(url), texture); + + CACHE.put(url, texture); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/client/util/ExtendedBlockModelRotation.java b/src/main/java/com/gregtechceu/gtceu/client/util/ExtendedBlockModelRotation.java index ed5e26fac7f..a6ddce39347 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/util/ExtendedBlockModelRotation.java +++ b/src/main/java/com/gregtechceu/gtceu/client/util/ExtendedBlockModelRotation.java @@ -22,29 +22,29 @@ public enum ExtendedBlockModelRotation { DOWN_EAST(90, 0, 90), UP_SOUTH(270, 0, 0), - UP_WEST(270, 0, 90), + UP_WEST(270, 0, 270), UP_NORTH(270, 0, 180), - UP_EAST(270, 0, 270), + UP_EAST(270, 0, 90), NORTH_SOUTH(0, 0, 180), - NORTH_WEST(0, 0, 270), + NORTH_WEST(0, 0, 90), NORTH_NORTH(0, 0, 0), // Default - NORTH_EAST(0, 0, 90), + NORTH_EAST(0, 0, 270), SOUTH_SOUTH(0, 180, 180), - SOUTH_WEST(0, 180, 270), + SOUTH_WEST(0, 180, 90), SOUTH_NORTH(0, 180, 0), - SOUTH_EAST(0, 180, 90), + SOUTH_EAST(0, 180, 270), WEST_SOUTH(0, 270, 180), - WEST_WEST(0, 270, 270), + WEST_WEST(0, 270, 90), WEST_NORTH(0, 270, 0), - WEST_EAST(0, 270, 90), + WEST_EAST(0, 270, 270), EAST_SOUTH(0, 90, 180), - EAST_WEST(0, 90, 270), + EAST_WEST(0, 90, 90), EAST_NORTH(0, 90, 0), - EAST_EAST(0, 90, 90); + EAST_EAST(0, 90, 270); public static final ExtendedBlockModelRotation[] VALUES = values(); diff --git a/src/main/java/com/gregtechceu/gtceu/client/util/ModelUtils.java b/src/main/java/com/gregtechceu/gtceu/client/util/ModelUtils.java index 00f7a116ebf..69d8fd34f3c 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/util/ModelUtils.java +++ b/src/main/java/com/gregtechceu/gtceu/client/util/ModelUtils.java @@ -38,7 +38,7 @@ import java.util.List; import java.util.Map; -@EventBusSubscriber(modid = GTCEu.MOD_ID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) +@EventBusSubscriber(modid = GTCEu.MOD_ID, value = Dist.CLIENT) public class ModelUtils { private ModelUtils() {} diff --git a/src/main/java/com/gregtechceu/gtceu/client/util/RenderBufferHelper.java b/src/main/java/com/gregtechceu/gtceu/client/util/RenderBufferHelper.java index fb481cca302..c0b7bf24252 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/util/RenderBufferHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/client/util/RenderBufferHelper.java @@ -1,5 +1,7 @@ package com.gregtechceu.gtceu.client.util; +import com.gregtechceu.gtceu.utils.GTMatrixUtils; + import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.core.Direction; @@ -9,7 +11,7 @@ import com.mojang.blaze3d.vertex.*; import org.joml.Matrix4f; -import org.joml.Vector3f; +import org.joml.Vector3fc; import java.util.EnumSet; import java.util.Set; @@ -156,7 +158,7 @@ public static void renderCubeFace(VertexConsumer buffer, PoseStack.Pose pose, float x2, float y2, float z2, float u2, float v2, float x3, float y3, float z3, float u3, float v3, float x4, float y4, float z4, float u4, float v4) { - Vector3f normal = normalDir.step(); + Vector3fc normal = GTMatrixUtils.getDirectionAxis(normalDir); vertex(buffer, pose, x1, y1, z1, color, u1, v1, combinedLight, normal.x(), normal.y(), normal.z()); vertex(buffer, pose, x2, y2, z2, color, u2, v2, combinedLight, normal.x(), normal.y(), normal.z()); diff --git a/src/main/java/com/gregtechceu/gtceu/client/util/RenderUtil.java b/src/main/java/com/gregtechceu/gtceu/client/util/RenderUtil.java index f41baa931b5..897d09b7b80 100644 --- a/src/main/java/com/gregtechceu/gtceu/client/util/RenderUtil.java +++ b/src/main/java/com/gregtechceu/gtceu/client/util/RenderUtil.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.data.item.GTDataComponents; import com.gregtechceu.gtceu.utils.GTMatrixUtils; +import com.gregtechceu.gtceu.utils.GTUtil; import com.gregtechceu.gtceu.utils.ResearchManager; import com.lowdragmc.lowdraglib.gui.util.DrawerHelper; @@ -15,20 +16,33 @@ import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; +import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; +import net.minecraft.util.RandomSource; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.RenderShape; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.phys.Vec3; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; +import net.neoforged.neoforge.client.RenderTypeHelper; import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; +import net.neoforged.neoforge.client.extensions.common.IClientItemExtensions; +import net.neoforged.neoforge.client.model.data.ModelData; import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient; @@ -195,10 +209,47 @@ public static Vector3f transformVertex(Vector3fc vertex, Direction direction, return fluid; } - public static void moveToFace(PoseStack poseStack, double x, double y, double z, Direction face) { - poseStack.translate(x + 0.5d + face.getStepX() * 0.5d, - y + 0.5d + face.getStepY() * 0.5d, - z + 0.5d + face.getStepZ() * 0.5d); + public static void moveToFace(PoseStack poseStack, Vector3fc pos, Direction face) { + moveToFace(poseStack, pos.x(), pos.y(), pos.z(), face); + } + + public static void moveToFace(PoseStack poseStack, float x, float y, float z, Direction face) { + poseStack.translate(Math.fma(face.getStepX(), 0.5f, x), + Math.fma(face.getStepY(), 0.5f, y), + Math.fma(face.getStepZ(), 0.5f, z)); + } + + public static void drawBlock(BlockAndTintGetter level, BlockPos pos, BlockState state, + MultiBufferSource bufferSource, PoseStack poseStack) { + int packedLight = LevelRenderer.getLightColor(level, state, pos); + + RenderShape renderShape = state.getRenderShape(); + if (renderShape == RenderShape.INVISIBLE) { + return; + } else if (renderShape == RenderShape.ENTITYBLOCK_ANIMATED) { + // if it's a block entity, use the BEWLR to render it instead of the empty block model + ItemStack stack = new ItemStack(state.getBlock()); + IClientItemExtensions.of(stack).getCustomRenderer().renderByItem(stack, ItemDisplayContext.NONE, + poseStack, bufferSource, packedLight, OverlayTexture.NO_OVERLAY); + return; + } + + BlockRenderDispatcher blockRenderer = Minecraft.getInstance().getBlockRenderer(); + BakedModel model = blockRenderer.getBlockModel(state); + ModelData modelData = model.getModelData(level, pos, state, ModelData.EMPTY); + + int blockColor = Minecraft.getInstance().getBlockColors().getColor(state, level, pos, 0); + float r = (float) (blockColor >> 16 & 0xFF) / 255.0F; + float g = (float) (blockColor >> 8 & 0xFF) / 255.0F; + float b = (float) (blockColor & 0xFF) / 255.0F; + + for (RenderType renderType : model.getRenderTypes(state, RandomSource.create(42), modelData)) { + blockRenderer.getModelRenderer().renderModel(poseStack.last(), + bufferSource.getBuffer(RenderTypeHelper.getEntityRenderType(renderType, false)), + state, model, r, g, b, + packedLight, OverlayTexture.NO_OVERLAY, + modelData, renderType); + } } /** @@ -216,12 +267,12 @@ public static void rotateToFace(PoseStack poseStack, Direction face, Direction s Quaternionf rotation = new Quaternionf(); if (face.getAxis() == Direction.Axis.Y) { poseStack.scale(1.0f, -1.0f, 1.0f); - rotation.rotateAxis(rotationAngle, new Vector3f(1, 0, 0)); + rotation.rotateX(rotationAngle); } else { poseStack.scale(-1.0f, -1.0f, -1.0f); - rotation.rotateAxis(rotationAngle, new Vector3f(0, 1, 0)); + rotation.rotateY(rotationAngle); } - rotation.rotateAxis(getSpinAngle(spin, face), new Vector3f(0, 0, 1)); + rotation.rotateZ(getSpinAngle(spin, face)); poseStack.mulPose(rotation); } @@ -251,7 +302,7 @@ public static boolean renderResearchItemContent(GuiGraphics graphics, Operation< ItemStack[] items = ItemRecipeCapability.CAP.of(outputs.getFirst().content).getItems(); if (items.length > 0) { ItemStack output = items[0]; - if (!output.isEmpty() && !ItemStack.isSameItemSameComponents(output, stack)) { + if (!output.isEmpty() && !GTUtil.isSameItemSameTags(output, stack)) { originalMethod.call(entity, level, output, x, y, seed, z); return true; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/CommonInit.java b/src/main/java/com/gregtechceu/gtceu/common/CommonInit.java index db1b91fffd6..6fb569f11dc 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/CommonInit.java +++ b/src/main/java/com/gregtechceu/gtceu/common/CommonInit.java @@ -81,13 +81,16 @@ import com.gregtechceu.gtceu.data.misc.GTDimensionMarkers; import com.gregtechceu.gtceu.data.misc.GTValueProviderTypes; import com.gregtechceu.gtceu.data.particle.GTParticleTypes; +import com.gregtechceu.gtceu.data.placeholder.GTPlaceholders; import com.gregtechceu.gtceu.data.recipe.*; import com.gregtechceu.gtceu.data.sound.GTSoundEntries; import com.gregtechceu.gtceu.data.tag.GTIngredientTypes; import com.gregtechceu.gtceu.data.tools.GTToolBehaviors; import com.gregtechceu.gtceu.data.tools.GTToolTiers; import com.gregtechceu.gtceu.data.worldgen.GTFeatures; +import com.gregtechceu.gtceu.integration.ae2.GTAEPlaceholders; import com.gregtechceu.gtceu.integration.cctweaked.CCTweakedPlugin; +import com.gregtechceu.gtceu.integration.create.GTCreateIntegration; import com.gregtechceu.gtceu.integration.kjs.GTCEuStartupEvents; import com.gregtechceu.gtceu.integration.kjs.GTKubeJSPlugin; import com.gregtechceu.gtceu.integration.kjs.events.MaterialModificationKubeEvent; @@ -192,6 +195,13 @@ public static void onRegister(RegisterEvent event) { } didRunRegistration = true; + if (ConfigHolder.INSTANCE.compat.createCompat && GTCEu.Mods.isCreateLoaded()) { + GTCreateIntegration.init(); + } + if (GTCEu.Mods.isAE2Loaded()) { + GTAEPlaceholders.init(); + } + GTElements.init(); MaterialIconSet.init(); MaterialIconType.init(); @@ -200,6 +210,7 @@ public static void onRegister(RegisterEvent event) { GTSoundEntries.init(); GTDamageTypes.init(); + GTPlaceholders.initPlaceholders(); GTBlocks.init(); GTFluids.init(); @@ -343,10 +354,6 @@ public static void commonSetup(FMLCommonSetupEvent event) { FluidIngredient inner = ingredient.ingredient(); return MapIngredientTypeManager.getFrom(inner, FluidRecipeCapability.CAP); }); - MapIngredientTypeManager.registerMapIngredient(IntProviderFluidIngredient.class, (ingredient) -> { - FluidIngredient inner = ingredient.getInner(); - return MapIngredientTypeManager.getFrom(inner, FluidRecipeCapability.CAP); - }); MapIngredientTypeManager.registerMapIngredient(CompoundFluidIngredient.class, (ingredient) -> { List list = new ObjectArrayList<>(); for (FluidIngredient child : ingredient.children()) { @@ -358,7 +365,7 @@ public static void commonSetup(FMLCommonSetupEvent event) { MapIngredientTypeManager.registerMapIngredient(DataComponentFluidIngredient.class, FluidDataComponentMapIngredient::from); MapIngredientTypeManager.registerMapIngredient(FluidIngredient.class, FluidTagMapIngredient::from); MapIngredientTypeManager.registerMapIngredient(SingleFluidIngredient.class, FluidStackMapIngredient::from); - MapIngredientTypeManager.registerMapIngredient(SingleFluidIngredient.class, FluidStackMapIngredient::from); + MapIngredientTypeManager.registerMapIngredient(IntProviderFluidIngredient.class, FluidStackMapIngredient::from); MapIngredientTypeManager.registerMapIngredient(IntersectionFluidIngredient.class, IntersectionMapIngredient::from); MapIngredientTypeManager.registerMapIngredient(FluidStack.class, FluidTagMapIngredient::from); diff --git a/src/main/java/com/gregtechceu/gtceu/common/block/BatteryBlock.java b/src/main/java/com/gregtechceu/gtceu/common/block/BatteryBlock.java index fb9d7d1db70..aed099c4c60 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/block/BatteryBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/common/block/BatteryBlock.java @@ -1,7 +1,6 @@ package com.gregtechceu.gtceu.common.block; import com.gregtechceu.gtceu.api.GTValues; -import com.gregtechceu.gtceu.api.block.AppearanceBlock; import com.gregtechceu.gtceu.api.machine.multiblock.IBatteryData; import com.gregtechceu.gtceu.utils.FormattingUtil; @@ -10,13 +9,17 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.block.Block; import lombok.Getter; import java.util.List; import java.util.Locale; -public class BatteryBlock extends AppearanceBlock { +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +public class BatteryBlock extends Block { @Getter private final IBatteryData data; diff --git a/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java b/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java index 906a49e53ea..4b79ea633ab 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/common/block/CableBlock.java @@ -2,11 +2,11 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; -import com.gregtechceu.gtceu.api.block.MaterialBlock; import com.gregtechceu.gtceu.api.block.MaterialPipeBlock; import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity; import com.gregtechceu.gtceu.api.capability.GTCapability; import com.gregtechceu.gtceu.api.capability.IToolable; +import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.material.material.Material; import com.gregtechceu.gtceu.api.material.material.properties.PropertyKey; import com.gregtechceu.gtceu.api.material.material.properties.WireProperties; @@ -141,7 +141,7 @@ public void entityInside(BlockState state, Level level, BlockPos pos, Entity ent if (!pipeNode.getFrameMaterial().isNull()) { BlockState frameState = GTMaterialBlocks.MATERIAL_BLOCKS.get(TagPrefix.frameGt, pipeNode.getFrameMaterial()) .getDefaultState(); - ((MaterialBlock) frameState.getBlock()).entityInside(frameState, level, pos, entity); + frameState.entityInside(level, pos, entity); return; } if (level.isClientSide) return; @@ -164,4 +164,9 @@ public void entityInside(BlockState state, Level level, BlockPos pos, Entity ent } } } + + @Override + public GTToolType getPipeTuneTool() { + return GTToolType.WIRE_CUTTER; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/block/LaserPipeBlock.java b/src/main/java/com/gregtechceu/gtceu/common/block/LaserPipeBlock.java index a5e3f46b3b2..d3569125931 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/block/LaserPipeBlock.java +++ b/src/main/java/com/gregtechceu/gtceu/common/block/LaserPipeBlock.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.capability.GTCapability; import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; import com.gregtechceu.gtceu.api.capability.IToolable; +import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.pipenet.IPipeNode; import com.gregtechceu.gtceu.client.model.PipeModel; import com.gregtechceu.gtceu.client.renderer.block.PipeBlockRenderer; @@ -139,4 +140,9 @@ public boolean canPipeConnectToBlock(IPipeNode type, BlockPos pos, return new LaserPipeBlockEntity(type, pos, blockState); } + public static void onBlockEntityRegister(BlockEntityType cableBlockEntityBlockEntityType) {} + @Override public boolean canHaveBlockedFaces() { return false; diff --git a/src/main/java/com/gregtechceu/gtceu/common/capability/PlaceholderSavedData.java b/src/main/java/com/gregtechceu/gtceu/common/capability/PlaceholderSavedData.java new file mode 100644 index 00000000000..0a32f9c25cb --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/capability/PlaceholderSavedData.java @@ -0,0 +1,49 @@ +package com.gregtechceu.gtceu.common.capability; + +import com.gregtechceu.gtceu.api.placeholder.Placeholder; + +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.saveddata.SavedData; + +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class PlaceholderSavedData extends SavedData { + + private final ServerLevel level; + private final CompoundTag tag; + + public static PlaceholderSavedData getOrCreate(ServerLevel level) { + return level.getDataStorage() + .computeIfAbsent( + new SavedData.Factory(() -> new PlaceholderSavedData(level), + (tag, provider) -> new PlaceholderSavedData(level, tag, provider)), + "gtceu_placeholder_data"); + } + + public PlaceholderSavedData(ServerLevel level) { + this(level, new CompoundTag(), (HolderLookup.Provider) null); + } + + public PlaceholderSavedData(ServerLevel level, CompoundTag tag, @Nullable HolderLookup.Provider provider) { + this.level = level; + this.tag = tag.getCompound("data"); + } + + public CompoundTag getPlaceholderData(Placeholder placeholder) { + if (!tag.contains(placeholder.getName())) + tag.put(placeholder.getName(), new CompoundTag()); + return tag.getCompound(placeholder.getName()); + } + + @Override + public CompoundTag save(CompoundTag tag, HolderLookup.Provider provider) { + tag.put("data", this.tag); + return tag; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/cosmetics/GTCapes.java b/src/main/java/com/gregtechceu/gtceu/common/cosmetics/GTCapes.java index b7018839ff7..5e85867c336 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cosmetics/GTCapes.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cosmetics/GTCapes.java @@ -55,14 +55,16 @@ public static void registerGTCapes(RegisterGTCapesEvent event) { } public static void giveDevCapes(RegisterGTCapesEvent event) { - // updated on 8.4.2025 - screret + // updated on 25.11.2025 - Reabstraction event.unlockCapeFor(UUID.fromString("a24a9108-23d2-43fc-8db7-43f809d017db"), GREGTECH_CAPE); // ALongStringOfNumbers event.unlockCapeFor(UUID.fromString("fbd96f69-60f9-481c-b71e-4b190cd5fc72"), GREGTECH_CAPE); // Anne-Marie event.unlockCapeFor(UUID.fromString("77e2129d-8f68-4025-9394-df946f1f3aee"), GREGTECH_CAPE); // Brachy84 event.unlockCapeFor(UUID.fromString("c1377a67-4585-46b6-b70e-dfaa419f1e71"), GREGTECH_CAPE); // BraggestSage833 event.unlockCapeFor(UUID.fromString("aaf70ec1-ac70-494f-9966-ea5933712750"), GREGTECH_CAPE); // Bruberu + event.unlockCapeFor(UUID.fromString("274846e6-1d07-4e59-8dea-f4f73e76f9fb"), GREGTECH_CAPE); // DilithiumThoride event.unlockCapeFor(UUID.fromString("c43b3c3d-7da6-4c2b-b335-703fce2ed795"), GREGTECH_CAPE); // Ghostipedia event.unlockCapeFor(UUID.fromString("88374b6a-4710-46cd-bb04-a1580905a918"), GREGTECH_CAPE); // Ghzdude + event.unlockCapeFor(UUID.fromString("fe4bafe8-8ea9-494a-b4e9-29397cea89fc"), GREGTECH_CAPE); // Gustavo event.unlockCapeFor(UUID.fromString("5d7073e3-882f-4c4a-94b3-0e5ba1c11e02"), GREGTECH_CAPE); // htmlcsjs event.unlockCapeFor(UUID.fromString("c18c1d7f-3174-42c6-81dc-3c7ff9f720c3"), GREGTECH_CAPE); // jurrejelle event.unlockCapeFor(UUID.fromString("29f1e04c-58d8-4a3b-9eff-f85be7825256"), GREGTECH_CAPE); // kross000 @@ -73,9 +75,11 @@ public static void giveDevCapes(RegisterGTCapesEvent event) { event.unlockCapeFor(UUID.fromString("5cb66945-2ca4-498d-8c9a-29a676769363"), GREGTECH_CAPE); // omergunr100 event.unlockCapeFor(UUID.fromString("4a57640e-c1b1-4413-a6ab-e9a8b60ec167"), GREGTECH_CAPE); // PrototypeTrousers event.unlockCapeFor(UUID.fromString("12892f29-9eef-47ed-b8fb-df3e0e90db0c"), GREGTECH_CAPE); // Quarri6343 + event.unlockCapeFor(UUID.fromString("0dcf2321-0b68-4e37-95bc-6a3c72f8ca4d"), GREGTECH_CAPE); // Reabstraction event.unlockCapeFor(UUID.fromString("1184eb79-5831-4f7d-b8f4-3a46fccf7a1d"), GREGTECH_CAPE); // screret event.unlockCapeFor(UUID.fromString("a82fb558-64f9-4dd6-a87d-84040e84bb43"), GREGTECH_CAPE); // serenibyss event.unlockCapeFor(UUID.fromString("f76fc8b3-ac6b-44b9-9023-76edaf3d5909"), GREGTECH_CAPE); // spicierspace153 + event.unlockCapeFor(UUID.fromString("24ab5496-0c9d-45d7-bfa6-c57760263be6"), GREGTECH_CAPE); // TarLaboratories event.unlockCapeFor(UUID.fromString("5c2933b3-5340-4356-81e7-783c53bd7845"), GREGTECH_CAPE); // Tech22 event.unlockCapeFor(UUID.fromString("30628e4c-f7ac-427f-8ca7-aab2c0572be8"), GREGTECH_CAPE); // TheLastKumquat event.unlockCapeFor(UUID.fromString("e6e784af-bd04-46ad-8141-47b8b9102cb9"), GREGTECH_CAPE); // Tictim diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/ComputerMonitorCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/ComputerMonitorCover.java index 86b0837504c..4a57eae90d1 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/ComputerMonitorCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/ComputerMonitorCover.java @@ -1,15 +1,119 @@ package com.gregtechceu.gtceu.common.cover; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.ICoverable; import com.gregtechceu.gtceu.api.cover.CoverBehavior; import com.gregtechceu.gtceu.api.cover.CoverDefinition; +import com.gregtechceu.gtceu.api.cover.IUICover; +import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; +import com.gregtechceu.gtceu.api.machine.TickableSubscription; +import com.gregtechceu.gtceu.api.machine.feature.IDataStickInteractable; +import com.gregtechceu.gtceu.api.placeholder.IPlaceholderInfoProviderCover; +import com.gregtechceu.gtceu.api.placeholder.MultiLineComponent; +import com.gregtechceu.gtceu.api.placeholder.PlaceholderContext; +import com.gregtechceu.gtceu.api.placeholder.PlaceholderHandler; +import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; +import com.gregtechceu.gtceu.client.renderer.cover.CoverTextRenderer; +import com.gregtechceu.gtceu.client.renderer.cover.IDynamicCoverRenderer; +import com.gregtechceu.gtceu.common.item.datacomponents.ComputerMonitorConfig; +import com.gregtechceu.gtceu.data.datagen.lang.LangHandler; +import com.gregtechceu.gtceu.data.item.GTDataComponents; +import com.gregtechceu.gtceu.integration.create.GTCreateIntegration; +import com.gregtechceu.gtceu.utils.GTStringUtils; +import com.gregtechceu.gtceu.utils.GTUtil; +import com.lowdragmc.lowdraglib.gui.texture.ResourceBorderTexture; +import com.lowdragmc.lowdraglib.gui.widget.*; +import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; +import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; +import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; + +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; + +import lombok.Getter; +import lombok.Setter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.function.Supplier; + +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class ComputerMonitorCover extends CoverBehavior + implements IUICover, IDataStickInteractable, IPlaceholderInfoProviderCover { + + public static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(ComputerMonitorCover.class, + CoverBehavior.MANAGED_FIELD_HOLDER); -public class ComputerMonitorCover extends CoverBehavior { + private @Nullable TickableSubscription subscription; + private final CoverTextRenderer renderer; + @Persisted + @Getter + private final List formatStringArgs = new ArrayList<>(8); + @Persisted + @Getter + private final List formatStringLines = new ArrayList<>(8); + @Persisted + @DescSynced + @Getter + private List text = new ArrayList<>(); + @Persisted + public final CustomItemStackHandler itemHandler = new CustomItemStackHandler(8); + @Setter + private String placeholderSearch = ""; + @Setter + @Getter + @Persisted + private int updateInterval = 100; + @Getter + @Persisted + private long ticksSincePlaced = 0; + @Persisted + @Getter + private final List createDisplayTargetBuffer = new ArrayList<>(); + @Persisted + @Getter + private final List computerCraftTextBuffer = new ArrayList<>(); + @Persisted + @Getter + private final UUID placeholderUUID; public ComputerMonitorCover(CoverDefinition definition, ICoverable coverHolder, Direction attachedSide) { super(definition, coverHolder, attachedSide); + renderer = new CoverTextRenderer(this::getText); + placeholderUUID = UUID.randomUUID(); + for (int i = 0; i < 100; i++) { + createDisplayTargetBuffer.add(Component.empty()); + computerCraftTextBuffer.add(Component.empty()); + } + } + + public List getRenderedText() { + String s = formatStringLines.stream().reduce((a, b) -> a + "\n" + b).orElse(""); + List tmp = new ArrayList<>(formatStringArgs); + tmp = tmp.stream().map(str -> '{' + str + '}').toList(); + return PlaceholderHandler.processPlaceholders( + GTStringUtils.replace(s, "\\{}", tmp), + new PlaceholderContext(coverHolder.getLevel(), coverHolder.getPos(), attachedSide, itemHandler, + this, new MultiLineComponent(text), placeholderUUID)); + } + + public void setDisplayTargetBufferLine(int line, MutableComponent component) { + createDisplayTargetBuffer.set(line, component); + } + + @Override + public void setComputerCraftTextBufferLine(int line, MutableComponent component) { + computerCraftTextBuffer.set(line, component); } @Override @@ -17,5 +121,160 @@ public boolean canPipePassThrough() { return false; } - // No implementation here, this cover is just for decorative purposes + @Override + public Supplier getDynamicRenderer() { + return () -> renderer; + } + + @Override + public @NotNull ManagedFieldHolder getFieldHolder() { + return MANAGED_FIELD_HOLDER; + } + + @Override + public Widget createUIWidget() { + int textFieldWidth = 160, horizontalPadding = 10, verticalPadding = 2; + final WidgetGroup group = new WidgetGroup(0, 0, 2 * textFieldWidth + 3 * horizontalPadding, 150); + final WidgetGroup mainPage = new WidgetGroup(0, 0, 2 * textFieldWidth + 3 * horizontalPadding, 150); + final WidgetGroup formatStringArgsPage = new WidgetGroup(0, 0, 2 * textFieldWidth + 3 * horizontalPadding, 150); + for (int i = 0; i < 8; i++) { + TextFieldWidget formatStringInput = new TextFieldWidget(); + formatStringInput.setSize(textFieldWidth, 15); + formatStringInput.setSelfPosition(horizontalPadding + textFieldWidth / 2, + 10 + verticalPadding + i * (15 + verticalPadding)); + formatStringInput.setHoverTooltips(GTStringUtils.toImmutable( + LangHandler.getMultiLang("gtceu.gui.computer_monitor_cover.main_textbox_tooltip", i + 1))); + int finalI = i; + if (i >= formatStringLines.size()) formatStringLines.add(""); + formatStringInput.setCurrentString(formatStringLines.get(i)); + formatStringInput.setTextResponder((s) -> formatStringLines.set(finalI, s)); + mainPage.addWidget(formatStringInput); + SlotWidget slot = new com.gregtechceu.gtceu.api.gui.widget.SlotWidget( + itemHandler, + i, + horizontalPadding + 50, + 20 * i); + slot.setBackgroundTexture(SlotWidget.ITEM_SLOT_TEXTURE); + slot.setHoverTooltips(GTStringUtils + .toImmutable(LangHandler.getMultiLang("gtceu.gui.computer_monitor_cover.slot_tooltip", i + 1))); + mainPage.addWidget(slot); + } + for (int i = 0; i < 8; i++) { + TextFieldWidget formatStringArgsInput = new TextFieldWidget(); + formatStringArgsInput.setSize(textFieldWidth, 15); + formatStringArgsInput.setSelfPosition(textFieldWidth / 2 + horizontalPadding, + 10 + verticalPadding + i * (15 + verticalPadding)); + formatStringArgsInput.setHoverTooltips(GTStringUtils.toImmutable( + LangHandler.getMultiLang("gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip", + GTStringUtils.getIntOrderingSuffix(i + 1)))); + + int finalI = i; + if (i >= formatStringArgs.size()) formatStringArgs.add(""); + formatStringArgsInput.setCurrentString(formatStringArgs.get(i)); + formatStringArgsInput.setTextResponder((s) -> formatStringArgs.set(finalI, s)); + formatStringArgsPage.addWidget(formatStringArgsInput); + } + ButtonWidget switchToFormatStringArgsPageButton = new ButtonWidget( + horizontalPadding + 50, + 10 * (15 + verticalPadding) + verticalPadding, + 20, 20, + new ResourceBorderTexture(), + clickData -> { + group.clearAllWidgets(); + group.addWidget(formatStringArgsPage); + }); + ButtonWidget switchBack = new ButtonWidget( + horizontalPadding + 50, + 10 * (15 + verticalPadding) + verticalPadding, + 20, 20, + new ResourceBorderTexture(), + clickData -> { + group.clearAllWidgets(); + group.addWidget(mainPage); + }); + mainPage.addWidget(PlaceholderHandler.getPlaceholderHandlerUI("")); + // TextFieldWidget searchBox = new TextFieldWidget(280, 0, 80, 15, null, onSearch); + // searchBox.setHoverTooltips("Search"); + // mainPage.addWidget(searchBox); + IntInputWidget updateIntervalInput = new IntInputWidget(0, 0, 60, 20, this::getUpdateInterval, + this::setUpdateInterval); + updateIntervalInput.setMin(1); + updateIntervalInput.setMax(60 * 20); + updateIntervalInput + .setHoverTooltips(Component.translatable("gtceu.gui.computer_monitor_cover.update_interval")); + mainPage.addWidget(updateIntervalInput); + switchToFormatStringArgsPageButton + .setHoverTooltips(Component.translatable("gtceu.gui.computer_monitor_cover.edit_blank_placeholders")); + switchBack.setHoverTooltips(Component.translatable("gtceu.gui.computer_monitor_cover.edit_displayed_text")); + mainPage.addWidget(switchToFormatStringArgsPageButton); + formatStringArgsPage.addWidget(switchBack); + group.addWidget(mainPage); + return group; + } + + @Override + public void onLoad() { + super.onLoad(); + subscription = coverHolder.subscribeServerTick(subscription, this::update); + } + + private void update() { + ticksSincePlaced++; + if (coverHolder.getOffsetTimer() % updateInterval == 0) { + try { + if (GTCEu.Mods.isCreateLoaded()) + GTCreateIntegration.TemporaryRedstoneLinkTransmitter.destroyAll(); + setRedstoneSignalOutput(0); + text = getRenderedText(); + } catch (RuntimeException e) { + text = GTUtil.list( + Component.translatable("gtceu.computer_monitor_cover.error.exception", e.getMessage())); + } + } + } + + @Override + public void onRemoved() { + super.onRemoved(); + if (subscription != null) { + subscription.unsubscribe(); + } + } + + @Override + public boolean canConnectRedstone() { + return true; + } + + @Override + public List getAdditionalDrops() { + List drops = super.getAdditionalDrops(); + for (int i = 0; i < 8; i++) { + if (!itemHandler.getStackInSlot(i).isEmpty()) { + drops.add(itemHandler.getStackInSlot(i)); + } + } + return drops; + } + + @Override + public InteractionResult onDataStickUse(Player player, ItemStack dataStick) { + ComputerMonitorConfig config = dataStick.get(GTDataComponents.COMPUTER_MONITOR_CONFIG); + if (config == null) return InteractionResult.FAIL; + + formatStringLines.clear(); + formatStringLines.addAll(config.lines()); + + formatStringArgs.clear(); + formatStringArgs.addAll(config.args()); + updateInterval = config.updateInterval(); + return InteractionResult.sidedSuccess(player.level().isClientSide); + } + + @Override + public InteractionResult onDataStickShiftUse(Player player, ItemStack dataStick) { + dataStick.set(GTDataComponents.COMPUTER_MONITOR_CONFIG, + new ComputerMonitorConfig(formatStringLines, formatStringArgs, updateInterval)); + return InteractionResult.sidedSuccess(player.level().isClientSide); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java index bd8005e0c1e..ff34bb6fbed 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/ConveyorCover.java @@ -19,6 +19,7 @@ import com.gregtechceu.gtceu.common.blockentity.ItemPipeBlockEntity; import com.gregtechceu.gtceu.common.cover.data.DistributionMode; import com.gregtechceu.gtceu.common.cover.data.ManualIOMode; +import com.gregtechceu.gtceu.utils.GTUtil; import com.gregtechceu.gtceu.utils.ItemStackHashStrategy; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; @@ -274,7 +275,7 @@ protected static boolean moveInventoryItemsExact(IItemHandler sourceInventory, I int slotIndex = itemInfo.slots.getInt(i); ItemStack extractedStack = sourceInventory.extractItem(slotIndex, itemsLeftToExtract, true); if (!extractedStack.isEmpty() && - ItemStack.isSameItemSameComponents(resultStack, extractedStack)) { + GTUtil.isSameItemSameTags(resultStack, extractedStack)) { totalExtractedCount += extractedStack.getCount(); itemsLeftToExtract -= extractedStack.getCount(); } @@ -306,7 +307,7 @@ protected static boolean moveInventoryItemsExact(IItemHandler sourceInventory, I int slotIndex = itemInfo.slots.getInt(i); ItemStack extractedStack = sourceInventory.extractItem(slotIndex, itemsLeftToExtract, false); if (!extractedStack.isEmpty() && - ItemStack.isSameItemSameComponents(resultStack, extractedStack)) { + GTUtil.isSameItemSameTags(resultStack, extractedStack)) { itemsLeftToExtract -= extractedStack.getCount(); } if (itemsLeftToExtract == 0) { @@ -414,6 +415,13 @@ protected static class GroupItemInfo { public int totalCount; } + public boolean shouldRespectDistributionMode() { + return ((io == IO.IN) ? + (coverHolder.getLevel().getBlockEntity(coverHolder.getPos()) instanceof ItemPipeBlockEntity) : + (coverHolder.getLevel().getBlockEntity(coverHolder.getPos() + .relative(attachedSide)) instanceof ItemPipeBlockEntity)); + } + ////////////////////////////////////// // *********** GUI ***********// ////////////////////////////////////// @@ -425,6 +433,12 @@ public Widget createUIWidget() { group.addWidget(new IntInputWidget(10, 20, 156, 20, () -> this.transferRate, this::setTransferRate) .setMin(1).setMax(maxItemTransferRate)); + final EnumSelectorWidget distributionSelector = new EnumSelectorWidget<>(146, 67, 20, 20, + DistributionMode.values(), distributionMode, this::setDistributionMode); + + distributionSelector.setVisible(shouldRespectDistributionMode()); + group.addWidget(distributionSelector); + ioModeSwitch = new SwitchWidget(10, 45, 20, 20, (clickData, value) -> { setIo(value ? IO.IN : IO.OUT); @@ -502,10 +516,15 @@ public CoverableItemHandlerWrapper(IItemHandlerModifiable delegate) { @NotNull @Override public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - if (io == IO.OUT && manualIOMode == ManualIOMode.DISABLED) { - return stack; + if (io == IO.OUT) { + if (manualIOMode == ManualIOMode.DISABLED) { + return stack; + } + if (manualIOMode == ManualIOMode.UNFILTERED) { + return super.insertItem(slot, stack, simulate); + } } - if (manualIOMode == ManualIOMode.FILTERED && !filterHandler.test(stack)) { + if (!filterHandler.test(stack)) { return stack; } return super.insertItem(slot, stack, simulate); @@ -514,17 +533,19 @@ public ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate @NotNull @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (io == IO.IN && manualIOMode == ManualIOMode.DISABLED) { - return ItemStack.EMPTY; - } - if (manualIOMode == ManualIOMode.FILTERED) { - ItemStack result = super.extractItem(slot, amount, true); - if (result.isEmpty() || !filterHandler.test(result)) { + if (io == IO.IN) { + if (manualIOMode == ManualIOMode.DISABLED) { return ItemStack.EMPTY; } - return simulate ? result : super.extractItem(slot, amount, false); + if (manualIOMode == ManualIOMode.UNFILTERED) { + return super.extractItem(slot, amount, simulate); + } + } + ItemStack result = super.extractItem(slot, amount, true); + if (result.isEmpty() || !filterHandler.test(result)) { + return ItemStack.EMPTY; } - return super.extractItem(slot, amount, simulate); + return simulate ? result : super.extractItem(slot, amount, false); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/FacadeCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/FacadeCover.java index 736acde20b2..9f3af605d81 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/FacadeCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/FacadeCover.java @@ -42,7 +42,7 @@ public ManagedFieldHolder getFieldHolder() { } @Override - public void onAttached(ItemStack itemStack, ServerPlayer player) { + public void onAttached(ItemStack itemStack, @Nullable ServerPlayer player) { super.onAttached(itemStack, player); this.facadeState = FacadeItemBehaviour.getFacadeState(itemStack); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/FluidFilterCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/FluidFilterCover.java index ef82ff7e04d..b5a2d4f020f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/FluidFilterCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/FluidFilterCover.java @@ -35,6 +35,7 @@ public class FluidFilterCover extends CoverBehavior implements IUICover { @Getter protected FilterMode filterMode = FilterMode.FILTER_INSERT; private FilteredFluidHandlerWrapper fluidFilterWrapper; + @Persisted @Setter @Getter protected ManualIOMode allowFlow = ManualIOMode.DISABLED; @@ -97,20 +98,34 @@ public FilteredFluidHandlerWrapper(IFluidHandlerModifiable delegate) { @Override public int fill(FluidStack resource, FluidAction action) { - if ((filterMode == FilterMode.FILTER_EXTRACT) && allowFlow == ManualIOMode.UNFILTERED) - return super.fill(resource, action); - if (filterMode != FilterMode.FILTER_EXTRACT && getFluidFilter().test(resource)) - return super.fill(resource, action); - return 0; + if (filterMode == FilterMode.FILTER_EXTRACT) { + if (allowFlow == ManualIOMode.DISABLED) { + return 0; + } + if (allowFlow == ManualIOMode.UNFILTERED) { + return super.fill(resource, action); + } + } + if (!getFluidFilter().test(resource)) { + return 0; + } + return super.fill(resource, action); } @Override public FluidStack drain(FluidStack resource, FluidAction action) { - if ((filterMode == FilterMode.FILTER_INSERT) && allowFlow == ManualIOMode.UNFILTERED) - return super.drain(resource, action); - if (filterMode != FilterMode.FILTER_INSERT && getFluidFilter().test(resource)) - return super.drain(resource, action); - return FluidStack.EMPTY; + if (filterMode == FilterMode.FILTER_INSERT) { + if (allowFlow == ManualIOMode.DISABLED) { + return FluidStack.EMPTY; + } + if (allowFlow == ManualIOMode.UNFILTERED) { + return super.drain(resource, action); + } + } + if (!getFluidFilter().test(resource)) { + return FluidStack.EMPTY; + } + return super.drain(resource, action); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java index 9c766312663..a0fd601d2ec 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/ItemFilterCover.java @@ -41,6 +41,7 @@ public class ItemFilterCover extends CoverBehavior implements IUICover { @Getter protected FilterMode filterMode = FilterMode.FILTER_INSERT; private FilteredItemHandlerWrapper itemFilterWrapper; + @Persisted @Setter @Getter protected ManualIOMode allowFlow = ManualIOMode.DISABLED; @@ -82,7 +83,7 @@ public boolean canAttach() { } @Override - public void onAttached(ItemStack itemStack, ServerPlayer player) { + public void onAttached(ItemStack itemStack, @Nullable ServerPlayer player) { super.onAttached(itemStack, player); } @@ -110,25 +111,35 @@ public FilteredItemHandlerWrapper(IItemHandlerModifiable delegate) { @Override public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - if ((filterMode == FilterMode.FILTER_EXTRACT) && allowFlow == ManualIOMode.UNFILTERED) - return super.insertItem(slot, stack, simulate); - if (filterMode != FilterMode.FILTER_EXTRACT && getItemFilter().test(stack)) { - return super.insertItem(slot, stack, simulate); + if (filterMode == FilterMode.FILTER_EXTRACT) { + if (allowFlow == ManualIOMode.DISABLED) { + return stack; + } + if (allowFlow == ManualIOMode.UNFILTERED) { + return super.insertItem(slot, stack, simulate); + } + } + if (!getItemFilter().test(stack)) { + return stack; } - return stack; + return super.insertItem(slot, stack, simulate); } @Override public @NotNull ItemStack extractItem(int slot, int amount, boolean simulate) { - ItemStack result = super.extractItem(slot, amount, true); - if (result.isEmpty() && (filterMode == FilterMode.FILTER_INSERT) && allowFlow == ManualIOMode.UNFILTERED) { - return super.extractItem(slot, amount, false); + if (filterMode == FilterMode.FILTER_INSERT) { + if (allowFlow == ManualIOMode.DISABLED) { + return ItemStack.EMPTY; + } + if (allowFlow == ManualIOMode.UNFILTERED) { + return super.extractItem(slot, amount, simulate); + } } - - if (filterMode != FilterMode.FILTER_INSERT && getItemFilter().test(result)) { - return super.extractItem(slot, amount, false); + ItemStack result = super.extractItem(slot, amount, true); + if (result.isEmpty() || !getItemFilter().test(result)) { + return ItemStack.EMPTY; } - return ItemStack.EMPTY; + return simulate ? result : super.extractItem(slot, amount, false); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/MachineControllerCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/MachineControllerCover.java index 6b7b5cc4a2e..0ba8f88cd5c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/MachineControllerCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/MachineControllerCover.java @@ -10,6 +10,7 @@ import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; import com.gregtechceu.gtceu.api.gui.widget.PhantomSlotWidget; import com.gregtechceu.gtceu.api.gui.widget.ToggleButtonWidget; +import com.gregtechceu.gtceu.api.machine.MachineCoverContainer; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.gregtechceu.gtceu.common.cover.data.ControllerMode; @@ -33,11 +34,11 @@ import net.minecraft.world.level.block.Block; import lombok.Getter; +import lombok.experimental.Accessors; import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.List; -import java.util.Optional; import java.util.stream.Collectors; public class MachineControllerCover extends CoverBehavior implements IUICover { @@ -66,6 +67,11 @@ public ManagedFieldHolder getFieldHolder() { @Nullable private ControllerMode controllerMode = ControllerMode.MACHINE; + @Getter + @Accessors(fluent = true) + @Persisted + private boolean preventPowerFail = false; + public MachineControllerCover(CoverDefinition definition, ICoverable coverHolder, Direction attachedSide) { super(definition, coverHolder, attachedSide); } @@ -76,7 +82,7 @@ public boolean canAttach() { } @Override - public void onAttached(ItemStack itemStack, ServerPlayer player) { + public void onAttached(ItemStack itemStack, @Nullable ServerPlayer player) { super.onAttached(itemStack, player); var allowedModes = getAllowedModes(); @@ -198,7 +204,7 @@ public Widget createUIWidget() { if (controllerMode != null && getControllable(controllerMode.side) == null) { setControllerMode(null); } - WidgetGroup group = new WidgetGroup(0, 0, 176, 75); + WidgetGroup group = new WidgetGroup(0, 0, 176, 95); group.addWidget(new LabelWidget(10, 5, "cover.machine_controller.title")); group.addWidget(new IntInputWidget(10, 20, 131, 20, @@ -216,6 +222,12 @@ public Widget createUIWidget() { .isMultiLang() .setTooltipText("cover.machine_controller.invert")); + group.addWidget(new LabelWidget(10, 72, "cover.machine_controller.suspend_powerfail")); + group.addWidget(new ToggleButtonWidget(147, 68, 18, 18, GuiTextures.BUTTON_POWER, + this::preventPowerFail, (data) -> { + preventPowerFail = data; + })); + sideCoverSlot = new CustomItemStackHandler(1); group.addWidget(new PhantomSlotWidget(sideCoverSlot, 0, 147, 46) { @@ -262,19 +274,22 @@ private void updateCoverSlot() { return; } - Optional.ofNullable(controllerMode) - .map(mode -> mode.side) - .map(coverHolder::getCoverAtSide) - .map(CoverBehavior::getAttachItem) - .map(ItemStack::copy) - .ifPresentOrElse( - item -> { - sideCoverSlot.setStackInSlot(0, item); - sideCoverSlot.onContentsChanged(0); - }, - () -> { - sideCoverSlot.setStackInSlot(0, ItemStack.EMPTY); - sideCoverSlot.onContentsChanged(0); - }); + if (controllerMode == null) { + sideCoverSlot.setStackInSlot(0, ItemStack.EMPTY); + sideCoverSlot.onContentsChanged(0); + } else { + var side = controllerMode.side; + if (side == null && coverHolder instanceof MachineCoverContainer coverContainer) { + sideCoverSlot.setStackInSlot(0, coverContainer.getMachine().getDefinition().asStack()); + } else { + var cover = coverHolder.getCoverAtSide(side); + if (cover != null) { + sideCoverSlot.setStackInSlot(0, cover.getAttachItem().copy()); + } else { + sideCoverSlot.setStackInSlot(0, ItemStack.EMPTY); + } + } + sideCoverSlot.onContentsChanged(0); + } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/MonitorCoverConfig.java b/src/main/java/com/gregtechceu/gtceu/common/cover/MonitorCoverConfig.java new file mode 100644 index 00000000000..0edb25e2378 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/MonitorCoverConfig.java @@ -0,0 +1,41 @@ +package com.gregtechceu.gtceu.common.cover; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; + +import java.util.ArrayList; +import java.util.List; + +public record MonitorCoverConfig( + List lines, + List args, + int updateInterval) { + + public List getLines() { + return new ArrayList(lines); + } + + public List getArgs() { + return new ArrayList(args); + } + + public int getUpdateInterval() { + return updateInterval; + } + + public static final Codec CODEC = RecordCodecBuilder.create(i -> i.group( + Codec.STRING.listOf().fieldOf("lines").forGetter(MonitorCoverConfig::lines), + Codec.STRING.listOf().fieldOf("args").forGetter(MonitorCoverConfig::args), + Codec.INT.fieldOf("updateInterval").forGetter(MonitorCoverConfig::updateInterval)) + .apply(i, MonitorCoverConfig::new)); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.STRING_UTF8.apply(ByteBufCodecs.list()), MonitorCoverConfig::lines, + ByteBufCodecs.STRING_UTF8.apply(ByteBufCodecs.list()), MonitorCoverConfig::args, + ByteBufCodecs.INT, MonitorCoverConfig::updateInterval, + MonitorCoverConfig::new); +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/PumpCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/PumpCover.java index a9116894c2e..ca4835bedaf 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/PumpCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/PumpCover.java @@ -362,10 +362,15 @@ public CoverableFluidHandlerWrapper(IFluidHandlerModifiable delegate) { @Override public int fill(FluidStack resource, FluidAction action) { - if (io == IO.OUT && manualIOMode == ManualIOMode.DISABLED) { - return 0; + if (io == IO.OUT) { + if (manualIOMode == ManualIOMode.DISABLED) { + return 0; + } + if (manualIOMode == ManualIOMode.UNFILTERED) { + return super.fill(resource, action); + } } - if (!filterHandler.test(resource) && manualIOMode == ManualIOMode.FILTERED) { + if (!filterHandler.test(resource)) { return 0; } return super.fill(resource, action); @@ -373,10 +378,15 @@ public int fill(FluidStack resource, FluidAction action) { @Override public FluidStack drain(FluidStack resource, FluidAction action) { - if (io == IO.IN && manualIOMode == ManualIOMode.DISABLED) { - return FluidStack.EMPTY; + if (io == IO.IN) { + if (manualIOMode == ManualIOMode.DISABLED) { + return FluidStack.EMPTY; + } + if (manualIOMode == ManualIOMode.UNFILTERED) { + return super.drain(resource, action); + } } - if (manualIOMode == ManualIOMode.FILTERED && !filterHandler.test(resource)) { + if (!filterHandler.test(resource)) { return FluidStack.EMPTY; } return super.drain(resource, action); diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/RobotArmCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/RobotArmCover.java index e9b84cabc79..ee8480898d9 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/RobotArmCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/RobotArmCover.java @@ -20,6 +20,7 @@ import net.neoforged.neoforge.items.IItemHandler; import lombok.Getter; +import lombok.Setter; import org.jetbrains.annotations.NotNull; import java.util.Iterator; @@ -37,6 +38,7 @@ public class RobotArmCover extends ConveyorCover { @Persisted @Getter + @Setter protected int globalTransferLimit; protected int itemsTransferBuffered; @@ -177,7 +179,7 @@ protected void buildAdditionalUI(WidgetGroup group) { group.addWidget(this.stackSizeInput); } - private void setTransferMode(TransferMode transferMode) { + public void setTransferMode(TransferMode transferMode) { this.transferMode = transferMode; configureStackSizeInput(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/WirelessTransmitterCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/WirelessTransmitterCover.java new file mode 100644 index 00000000000..a4e35e85dee --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/WirelessTransmitterCover.java @@ -0,0 +1,75 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.api.capability.ICoverable; +import com.gregtechceu.gtceu.api.cover.CoverBehavior; +import com.gregtechceu.gtceu.api.cover.CoverDefinition; +import com.gregtechceu.gtceu.api.machine.feature.IDataStickInteractable; +import com.gregtechceu.gtceu.api.placeholder.IPlaceholderInfoProviderCover; +import com.gregtechceu.gtceu.data.item.GTDataComponents; + +import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; + +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class WirelessTransmitterCover extends CoverBehavior + implements IDataStickInteractable, IPlaceholderInfoProviderCover { + + private static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder( + WirelessTransmitterCover.class, CoverBehavior.MANAGED_FIELD_HOLDER); + + @Getter + private final List createDisplayTargetBuffer = new ArrayList<>(); + @Getter + private final List computerCraftTextBuffer = new ArrayList<>(); + + public WirelessTransmitterCover(CoverDefinition definition, ICoverable coverHolder, Direction attachedSide) { + super(definition, coverHolder, attachedSide); + for (int i = 0; i < 100; i++) { + createDisplayTargetBuffer.add(Component.empty()); + computerCraftTextBuffer.add(Component.empty()); + } + } + + @Override + public InteractionResult onDataStickUse(Player player, ItemStack dataStick) { + dataStick.set(GTDataComponents.MONITOR_TARGET, coverHolder.getPos()); + dataStick.set(GTDataComponents.MONITOR_TARGET_FACE, attachedSide); + dataStick.set(GTDataComponents.MONITOR_TARGET_DIMENSION, coverHolder.getLevel().dimension()); + return InteractionResult.SUCCESS; + } + + @Override + public long getTicksSincePlaced() { + return coverHolder.getOffsetTimer(); + } + + @Override + public void setDisplayTargetBufferLine(int line, MutableComponent component) { + createDisplayTargetBuffer.set(line, component); + } + + @Override + public void setComputerCraftTextBufferLine(int line, MutableComponent component) { + computerCraftTextBuffer.set(line, component); + } + + @Override + public ManagedFieldHolder getFieldHolder() { + return MANAGED_FIELD_HOLDER; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/detector/AdvancedEnergyDetectorCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/detector/AdvancedEnergyDetectorCover.java index 7fa215b0d7f..c668abe62d8 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/detector/AdvancedEnergyDetectorCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/detector/AdvancedEnergyDetectorCover.java @@ -67,13 +67,13 @@ protected void update() { IEnergyInfoProvider energyInfoProvider = getEnergyInfoProvider(); if (energyInfoProvider == null) return; - var energyInfo = energyInfoProvider.getEnergyInfo(); - var isBigInt = energyInfoProvider.supportsBigIntEnergyValues(); + IEnergyInfoProvider.EnergyInfo energyInfo = energyInfoProvider.getEnergyInfo(); + boolean isBigInt = energyInfoProvider.supportsBigIntEnergyValues(); if (isBigInt) { if (usePercent) { if (energyInfo.capacity().compareTo(BigInteger.ZERO) > 0) { - var ratio = GTMath.ratio(energyInfo.stored(), energyInfo.capacity()); + float ratio = GTMath.ratio(energyInfo.stored(), energyInfo.capacity()); setRedstoneSignalOutput(computeLatchedRedstoneBetweenValues(ratio * 100, maxValue, minValue, isInverted(), redstoneSignalOutput)); } else { @@ -87,7 +87,7 @@ protected void update() { } else { if (usePercent) { if (energyInfo.capacity().longValue() > 0) { - var ratio = energyInfo.stored().longValue() / energyInfo.capacity().longValue(); + float ratio = energyInfo.stored().floatValue() / energyInfo.capacity().floatValue(); setRedstoneSignalOutput(computeLatchedRedstoneBetweenValues(ratio * 100, maxValue, minValue, isInverted(), redstoneSignalOutput)); } else { @@ -177,8 +177,10 @@ private void initializeMinMaxInputs(boolean wasPercent) { // This needs to be after setting the maximum, because otherwise the converted value would be // limited to 100. if (wasPercent) { - minValueInput.setValue(GTMath.clamp((long) ((minValue / 100.0) * energyCapacity), 0, energyCapacity)); - maxValueInput.setValue(GTMath.clamp((long) ((maxValue / 100.0) * energyCapacity), 0, energyCapacity)); + minValueInput.setValue( + GTMath.clamp((long) Math.ceil((minValue / 100.0) * energyCapacity), 0, energyCapacity)); + maxValueInput.setValue( + GTMath.clamp((long) Math.ceil((maxValue / 100.0) * energyCapacity), 0, energyCapacity)); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/detector/ItemDetectorCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/detector/ItemDetectorCover.java index e63bedbbc35..03011e4fa76 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/detector/ItemDetectorCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/detector/ItemDetectorCover.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.api.capability.ICoverable; import com.gregtechceu.gtceu.api.cover.CoverDefinition; +import com.gregtechceu.gtceu.data.tag.CustomTags; import com.gregtechceu.gtceu.utils.GTTransferUtils; import com.gregtechceu.gtceu.utils.RedstoneUtil; @@ -37,6 +38,7 @@ protected void update() { return; for (int i = 0; i < handler.getSlots(); i++) { + if (handler.getStackInSlot(i).is(CustomTags.SKIP_ITEM_DETECTOR)) continue; storedItems += handler.getStackInSlot(i).getCount(); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/ender/AbstractEnderLinkCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/ender/AbstractEnderLinkCover.java index 5e36cf6bb57..18049c01ebb 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/ender/AbstractEnderLinkCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/ender/AbstractEnderLinkCover.java @@ -93,7 +93,7 @@ public void onLoad() { public abstract boolean canAttach(); @Override - public void onAttached(@NotNull ItemStack itemStack, @NotNull ServerPlayer player) { + public void onAttached(@NotNull ItemStack itemStack, @Nullable ServerPlayer player) { super.onAttached(itemStack, player); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/ender/EnderItemLinkCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/ender/EnderItemLinkCover.java new file mode 100644 index 00000000000..117ce06112a --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/ender/EnderItemLinkCover.java @@ -0,0 +1,121 @@ +package com.gregtechceu.gtceu.common.cover.ender; + +import com.gregtechceu.gtceu.api.capability.ICoverable; +import com.gregtechceu.gtceu.api.cover.CoverDefinition; +import com.gregtechceu.gtceu.api.cover.filter.FilterHandler; +import com.gregtechceu.gtceu.api.cover.filter.FilterHandlers; +import com.gregtechceu.gtceu.api.cover.filter.ItemFilter; +import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; +import com.gregtechceu.gtceu.api.misc.virtualregistry.EntryTypes; +import com.gregtechceu.gtceu.api.misc.virtualregistry.VirtualEnderRegistry; +import com.gregtechceu.gtceu.api.misc.virtualregistry.VirtualEntry; +import com.gregtechceu.gtceu.api.misc.virtualregistry.entries.VirtualItemStorage; +import com.gregtechceu.gtceu.utils.GTTransferUtils; + +import com.lowdragmc.lowdraglib.gui.widget.Widget; +import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; +import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; +import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; +import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; + +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.items.IItemHandler; + +import lombok.Getter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class EnderItemLinkCover extends AbstractEnderLinkCover { + + public static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(EnderItemLinkCover.class, + AbstractEnderLinkCover.MANAGED_FIELD_HOLDER); + + protected static final int TRANSFER_RATE = 8; + + @Persisted + @DescSynced + protected VirtualItemStorage storage; + protected int itemsLeftToTransferLastSecond; + @Getter + @Persisted + @DescSynced + protected FilterHandler filterHandler; + + public EnderItemLinkCover(CoverDefinition definition, ICoverable coverHolder, Direction attachedSide) { + super(definition, coverHolder, attachedSide); + itemsLeftToTransferLastSecond = TRANSFER_RATE * 20; + filterHandler = FilterHandlers.item(this); + if (!isRemote()) storage = VirtualEnderRegistry.getInstance().getOrCreateEntry(getOwner(), + EntryTypes.ENDER_ITEM, getChannelName()); + } + + @Override + public boolean canAttach() { + return true; + } + + @Override + protected String identifier() { + return "EILink#"; + } + + @Override + protected VirtualItemStorage getEntry() { + return storage; + } + + @Override + protected void setEntry(VirtualEntry entry) { + storage = (VirtualItemStorage) entry; + } + + @Override + protected EntryTypes getEntryType() { + return EntryTypes.ENDER_ITEM; + } + + @Override + protected void transfer() { + long timer = coverHolder.getOffsetTimer(); + if (itemsLeftToTransferLastSecond > 0) { + itemsLeftToTransferLastSecond -= doTransferItems(itemsLeftToTransferLastSecond); + } + if (timer % 20 == 0) itemsLeftToTransferLastSecond = TRANSFER_RATE * 20; + } + + private int doTransferItems(int max) { + IItemHandler ownHandler = getOwnItemHandler(); + if (ownHandler == null) return 0; + return switch (io) { + case IN -> GTTransferUtils.transferItemsFiltered(ownHandler, storage.getHandler(), + filterHandler.getFilter(), max); + case OUT -> GTTransferUtils.transferItemsFiltered(storage.getHandler(), ownHandler, + filterHandler.getFilter(), max); + default -> 0; + }; + } + + public @Nullable IItemHandler getOwnItemHandler() { + return coverHolder.getItemHandlerCap(attachedSide, false); + } + + @Override + protected Widget addVirtualEntryWidget(VirtualEntry entry, int x, int y, int width, int height, boolean canClick) { + WidgetGroup group = new WidgetGroup(x, y, width, height); + for (int i = 0; i < ((VirtualItemStorage) entry).getHandler().getSlots(); i++) { + group.addWidget(new SlotWidget(((VirtualItemStorage) entry).getHandler(), i, 8 * i, 0, canClick, canClick)); + } + return group; + } + + @Override + protected String getUITitle() { + return "cover.ender_item_link.title"; + } + + @Override + public @NotNull ManagedFieldHolder getFieldHolder() { + return MANAGED_FIELD_HOLDER; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/ender/EnderRedstoneLinkCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/ender/EnderRedstoneLinkCover.java new file mode 100644 index 00000000000..919d907a63d --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/ender/EnderRedstoneLinkCover.java @@ -0,0 +1,106 @@ +package com.gregtechceu.gtceu.common.cover.ender; + +import com.gregtechceu.gtceu.api.capability.ICoverable; +import com.gregtechceu.gtceu.api.cover.CoverDefinition; +import com.gregtechceu.gtceu.api.misc.virtualregistry.EntryTypes; +import com.gregtechceu.gtceu.api.misc.virtualregistry.VirtualEntry; +import com.gregtechceu.gtceu.api.misc.virtualregistry.entries.VirtualRedstone; + +import com.lowdragmc.lowdraglib.gui.widget.Widget; +import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; +import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; +import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; +import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; + +import net.minecraft.core.Direction; + +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public class EnderRedstoneLinkCover extends AbstractEnderLinkCover { + + public static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(EnderRedstoneLinkCover.class, + AbstractEnderLinkCover.MANAGED_FIELD_HOLDER); + + @Persisted + @DescSynced + private VirtualRedstone storage; + @Persisted + @DescSynced + private final UUID uuid; + + public EnderRedstoneLinkCover(CoverDefinition definition, ICoverable coverHolder, Direction attachedSide) { + super(definition, coverHolder, attachedSide); + if (!isRemote()) { + uuid = UUID.randomUUID(); + setVirtualEntry(); + } else uuid = null; + } + + @Override + public boolean canAttach() { + return true; + } + + @Override + protected String identifier() { + return "ERLink#"; + } + + @Override + protected VirtualRedstone getEntry() { + return storage; + } + + @Override + protected void setEntry(VirtualEntry entry) { + if (storage != null) storage.removeMember(uuid); + storage = (VirtualRedstone) entry; + storage.addMember(uuid); + } + + @Override + protected EntryTypes getEntryType() { + return EntryTypes.ENDER_REDSTONE; + } + + @Override + protected void transfer() { + switch (io) { + case IN -> storage.setSignal(uuid, getSignalInput()); + case OUT -> setRedstoneSignalOutput(storage.getSignal()); + } + } + + @Override + protected Widget addVirtualEntryWidget(VirtualEntry entry, int x, int y, int width, int height, boolean canClick) { + return new WidgetGroup(x, y, width, height); + } + + @Override + protected String getUITitle() { + return "cover.ender_redstone_link.title"; + } + + @Override + public boolean canConnectRedstone() { + return true; + } + + @Override + public void onRemoved() { + storage.removeMember(uuid); + super.onRemoved(); + } + + protected int getSignalInput() { + return coverHolder.getLevel().getSignal(coverHolder.getPos().relative(attachedSide), + attachedSide.getOpposite()); + } + + @Override + public @NotNull ManagedFieldHolder getFieldHolder() { + return MANAGED_FIELD_HOLDER; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedItemVoidingCover.java b/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedItemVoidingCover.java index 2ffd4baf4aa..191ac422af0 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedItemVoidingCover.java +++ b/src/main/java/com/gregtechceu/gtceu/common/cover/voiding/AdvancedItemVoidingCover.java @@ -7,6 +7,7 @@ import com.gregtechceu.gtceu.api.gui.widget.EnumSelectorWidget; import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; import com.gregtechceu.gtceu.common.cover.data.VoidingMode; +import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; @@ -68,7 +69,7 @@ private void voidOverflow(IItemHandler handler) { for (int slot = 0; slot < handler.getSlots(); slot++) { ItemStack is = handler.getStackInSlot(slot); - if (!is.isEmpty() && ItemStack.isSameItemSameComponents(is, itemInfo.itemStack)) { + if (!is.isEmpty() && GTUtil.isSameItemSameTags(is, itemInfo.itemStack)) { ItemStack extracted = handler.extractItem(slot, itemToVoidAmount, false); if (!extracted.isEmpty()) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/datafixer/fixes/DataItemComponentFix.java b/src/main/java/com/gregtechceu/gtceu/common/datafixer/fixes/DataItemComponentFix.java new file mode 100644 index 00000000000..3c996b22eb2 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/datafixer/fixes/DataItemComponentFix.java @@ -0,0 +1,21 @@ +package com.gregtechceu.gtceu.common.datafixer.fixes; + +import net.minecraft.util.datafix.fixes.ItemStackComponentRemainderFix; + +import com.mojang.datafixers.schemas.Schema; +import com.mojang.serialization.Dynamic; +import org.jetbrains.annotations.Nullable; + +public class DataItemComponentFix extends ItemStackComponentRemainderFix { + + public DataItemComponentFix(Schema outputSchema) { + super(outputSchema, "GTDataItemComponentFix", "gtceu:data_item"); + } + + @SuppressWarnings("NullableProblems") // this method is passed to Optional#map, where null is a valid return value. + @Override + protected @Nullable Dynamic fixComponent(Dynamic tag) { + // remove the old tag entirely to be replaced with the new one + return null; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/QuantumTankMachineItem.java b/src/main/java/com/gregtechceu/gtceu/common/item/QuantumTankMachineItem.java new file mode 100644 index 00000000000..3d725485ff9 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/QuantumTankMachineItem.java @@ -0,0 +1,40 @@ +package com.gregtechceu.gtceu.common.item; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.block.IMachineBlock; +import com.gregtechceu.gtceu.api.item.MetaMachineItem; +import com.gregtechceu.gtceu.api.misc.forge.QuantumFluidHandlerItemStack; +import com.gregtechceu.gtceu.common.machine.storage.QuantumTankMachine; + +import net.neoforged.neoforge.capabilities.Capabilities; +import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent; + +public class QuantumTankMachineItem extends MetaMachineItem { + + public QuantumTankMachineItem(IMachineBlock block, Properties properties) { + super(block, properties); + } + + public static QuantumTankMachineItem create(IMachineBlock block, Properties props) { + return new QuantumTankMachineItem(block, props); + } + + public void attachCapabilities(RegisterCapabilitiesEvent event) { + long capacity = 0L; + + if (!QuantumTankMachine.TANK_CAPACITY.containsKey(getDefinition())) { + GTCEu.LOGGER.error( + "Quantum tank " + getDefinition().getName() + + " does not have a registered TANK_CAPACITY, using capacity 0."); + } else { + capacity = QuantumTankMachine.TANK_CAPACITY.getLong(getDefinition()); + } + + final long finalCapacity = capacity; + + event.registerItem( + Capabilities.FluidHandler.ITEM, + (stack, ignored) -> new QuantumFluidHandlerItemStack(stack, finalCapacity), + this); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/armor/GTArmorItem.java b/src/main/java/com/gregtechceu/gtceu/common/item/armor/GTArmorItem.java index 6750db01760..7ef64abfe54 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/armor/GTArmorItem.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/armor/GTArmorItem.java @@ -7,6 +7,7 @@ import com.lowdragmc.lowdraglib.Platform; import net.minecraft.client.color.item.ItemColor; +import net.minecraft.core.Holder; import net.minecraft.locale.Language; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; @@ -26,8 +27,9 @@ public class GTArmorItem extends ArmorItem { public final Material material; public final ArmorProperty armorProperty; - public GTArmorItem(ArmorItem.Type type, Properties properties, Material material, ArmorProperty armorProperty) { - super(armorProperty.getArmorMaterial(), type, properties); + public GTArmorItem(Holder armorMaterial, ArmorItem.Type type, Properties properties, + Material material, ArmorProperty armorProperty) { + super(armorMaterial, type, properties); this.material = material; this.armorProperty = armorProperty; if (Platform.isClient()) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/armor/IJetpack.java b/src/main/java/com/gregtechceu/gtceu/common/item/armor/IJetpack.java index c37a5a84063..61d45ab3ae1 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/armor/IJetpack.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/armor/IJetpack.java @@ -3,7 +3,7 @@ import com.gregtechceu.gtceu.api.item.armor.ArmorUtils; import com.gregtechceu.gtceu.api.item.datacomponents.GTArmor; import com.gregtechceu.gtceu.data.item.GTDataComponents; -import com.gregtechceu.gtceu.utils.input.KeyBind; +import com.gregtechceu.gtceu.utils.input.SyncedKeyMappings; import net.minecraft.core.particles.ParticleOptions; import net.minecraft.core.particles.ParticleTypes; @@ -51,7 +51,12 @@ default double getSidewaysSpeed() { return 0.0D; } - default @Nullable ParticleOptions getParticle() { + default boolean removeMiningSpeedPenalty() { + return true; + } + + @Nullable + default ParticleOptions getParticle() { return ParticleTypes.LARGE_SMOKE; } @@ -76,8 +81,8 @@ default void performFlying(@NotNull Player player, boolean flightEnabled, boolea return; } - boolean flyKeyDown = KeyBind.VANILLA_JUMP.isKeyDown(player); - boolean descendKeyDown = KeyBind.VANILLA_SNEAK.isKeyDown(player); + boolean flyKeyDown = SyncedKeyMappings.VANILLA_JUMP.isKeyDown(player); + boolean descendKeyDown = SyncedKeyMappings.VANILLA_SNEAK.isKeyDown(player); double currentAccel = getVerticalAcceleration() * (deltaY < 0.3D ? 2.5D : 1.0D); if (!player.onGround() && player.getSleepingPos().isEmpty() && canUseEnergy(stack, getEnergyPerUse())) { @@ -121,10 +126,18 @@ default void performFlying(@NotNull Player player, boolean flightEnabled, boolea // Make sure they aren't using elytra movement if (!player.isFallFlying()) { Vec3 movement = new Vec3(0, 0, 0); - if (KeyBind.VANILLA_FORWARD.isKeyDown(player)) movement = movement.add(0, 0, speedForward); - if (KeyBind.VANILLA_BACKWARD.isKeyDown(player)) movement = movement.add(0, 0, -speedSideways * 0.8f); - if (KeyBind.VANILLA_LEFT.isKeyDown(player)) movement = movement.add(speedSideways, 0, 0); - if (KeyBind.VANILLA_RIGHT.isKeyDown(player)) movement = movement.add(-speedSideways, 0, 0); + if (SyncedKeyMappings.VANILLA_FORWARD.isKeyDown(player)) { + movement = movement.add(0, 0, speedForward); + } + if (SyncedKeyMappings.VANILLA_BACKWARD.isKeyDown(player)) { + movement = movement.add(0, 0, -speedSideways * 0.8f); + } + if (SyncedKeyMappings.VANILLA_LEFT.isKeyDown(player)) { + movement = movement.add(speedSideways, 0, 0); + } + if (SyncedKeyMappings.VANILLA_RIGHT.isKeyDown(player)) { + movement = movement.add(-speedSideways, 0, 0); + } var dist = movement.length(); if (dist >= 1.0E-7) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/armor/QuarkTechSuite.java b/src/main/java/com/gregtechceu/gtceu/common/item/armor/QuarkTechSuite.java index c192e17edae..8a2bc9639d6 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/armor/QuarkTechSuite.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/armor/QuarkTechSuite.java @@ -10,6 +10,7 @@ import com.gregtechceu.gtceu.data.item.GTDataComponents; import com.gregtechceu.gtceu.data.item.GTItems; import com.gregtechceu.gtceu.utils.input.KeyBind; +import com.gregtechceu.gtceu.utils.input.SyncedKeyMappings; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; @@ -89,9 +90,11 @@ public void onArmorTick(Level level, Player player, ItemStack stack) { boolean ret = false; if (type == ArmorItem.Type.HELMET) { - ret = supplyAir(item, player) || supplyFood(item, player); - removeNegativeEffects(item, player); + if (!level.isClientSide) { + ret = supplyAir(item, player) || supplyFood(item, player); + removeNegativeEffects(item, player); + } boolean nightVision = data.nightVision(); if (toggleTimer == 0 && KeyBind.ARMOR_MODE_SWITCH.isKeyDown(player)) { @@ -131,9 +134,9 @@ public void onArmorTick(Level level, Player player, ItemStack stack) { if (player.isOnFire()) player.extinguishFire(); } else if (type == ArmorItem.Type.LEGGINGS) { boolean canUseEnergy = item.canUse(energyPerUse / 100); - boolean sprinting = KeyBind.VANILLA_FORWARD.isKeyDown(player) && player.isSprinting(); - boolean jumping = KeyBind.VANILLA_JUMP.isKeyDown(player); - boolean sneaking = KeyBind.VANILLA_SNEAK.isKeyDown(player); + boolean sprinting = SyncedKeyMappings.VANILLA_FORWARD.isKeyDown(player) && player.isSprinting(); + boolean jumping = SyncedKeyMappings.VANILLA_JUMP.isKeyDown(player); + boolean sneaking = SyncedKeyMappings.VANILLA_SNEAK.isKeyDown(player); if (canUseEnergy && sprinting) { if (runningTimer == 0) { @@ -162,7 +165,7 @@ public void onArmorTick(Level level, Player player, ItemStack stack) { data.runningTimer(runningTimer); } else if (type == ArmorItem.Type.BOOTS) { boolean canUseEnergy = item.canUse(energyPerUse / 100); - boolean jumping = KeyBind.VANILLA_JUMP.isKeyDown(player); + boolean jumping = SyncedKeyMappings.VANILLA_JUMP.isKeyDown(player); boolean boostedJump = data.boostedJump(); if (boostedJumpTimer == 0 && KeyBind.BOOTS_ENABLE.isKeyDown(player)) { boostedJump = !boostedJump; diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ColorSprayBehaviour.java b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ColorSprayBehaviour.java index 5d5ca22da47..31dbe9b9adc 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ColorSprayBehaviour.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ColorSprayBehaviour.java @@ -287,7 +287,7 @@ private static boolean recolorBlockState(Level level, BlockPos pos, DyeColor col BlockState state = level.getBlockState(pos); for (Property property : state.getProperties()) { if (property.getValueClass() == DyeColor.class) { - state.setValue(property, color); + level.setBlockAndUpdate(pos, state.setValue(property, color)); return true; } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/CoverPlaceBehavior.java b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/CoverPlaceBehavior.java index 5dfe0415c88..745afef1615 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/CoverPlaceBehavior.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/CoverPlaceBehavior.java @@ -6,7 +6,7 @@ import com.gregtechceu.gtceu.api.item.IComponentItem; import com.gregtechceu.gtceu.api.item.component.IInteractionItem; import com.gregtechceu.gtceu.api.item.component.IItemComponent; -import com.gregtechceu.gtceu.data.item.GTItemAbilities; +import com.gregtechceu.gtceu.api.item.tool.GTToolType; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.InteractionResult; @@ -56,8 +56,9 @@ public static boolean isCoverBehaviorItem(ItemStack itemStack, @Nullable Boolean } } } - } else if (itemStack.canPerformAction(GTItemAbilities.INTERACT_WITH_COVER) || - itemStack.canPerformAction(GTItemAbilities.CROWBAR_REMOVE_COVER)) { + } else if (GTToolType.CROWBAR.matchTags.stream().anyMatch(itemStack::is) || + GTToolType.SOFT_MALLET.matchTags.stream().anyMatch(itemStack::is) || + GTToolType.SCREWDRIVER.matchTags.stream().anyMatch(itemStack::is)) { return hasCoverSupplier == null || hasCoverSupplier.getAsBoolean(); } return false; diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/DataItemBehavior.java b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/DataItemBehavior.java index a7eee72eea8..cb889a645e8 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/DataItemBehavior.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/DataItemBehavior.java @@ -1,6 +1,8 @@ package com.gregtechceu.gtceu.common.item.behavior; import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; +import com.gregtechceu.gtceu.api.capability.ICoverable; import com.gregtechceu.gtceu.api.item.component.IAddInformation; import com.gregtechceu.gtceu.api.item.component.IInteractionItem; import com.gregtechceu.gtceu.api.machine.feature.IDataStickInteractable; @@ -10,14 +12,29 @@ import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.UUIDUtil; +import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; +import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import java.util.List; +import java.util.UUID; public class DataItemBehavior implements IInteractionItem, IAddInformation { @@ -25,9 +42,51 @@ public class DataItemBehavior implements IInteractionItem, IAddInformation { protected DataItemBehavior() {} + @Override + public InteractionResultHolder use(ItemStack item, Level level, Player player, + InteractionHand usedHand) { + if (player.isShiftKeyDown()) { + ItemStack stack = player.getItemInHand(usedHand); + // stack.getOrCreateTag().putString("boundPlayerName", + // Component.Serializer.toJson(player.getDisplayName())); + int perm = 0; + while (player.hasPermissions(perm)) perm++; + // stack.getOrCreateTag().putInt("boundPlayerPermLevel", perm - 1); + // stack.getOrCreateTag().putString("boundPlayerUUID", player.getStringUUID()); + stack.set(GTDataComponents.DATA_BOUND_PLAYER, new BoundPlayer(player.getUUID(), perm, player.getName())); + return new InteractionResultHolder<>(InteractionResult.SUCCESS, stack); + } + return IInteractionItem.super.use(item, level, player, usedHand); + } + @Override public void appendHoverText(ItemStack stack, Item.TooltipContext context, List tooltipComponents, TooltipFlag isAdvanced) { + var boundPlayer = stack.getOrDefault(GTDataComponents.DATA_BOUND_PLAYER, null); + if (boundPlayer != null) { + MutableComponent name = MutableComponent.create(boundPlayer.displayName().getContents()); + tooltipComponents.add(Component.translatable("gtceu.tooltip.player_bind", name)); + } + var target = stack.getOrDefault(GTDataComponents.MONITOR_TARGET, null); + if (target != null) { + tooltipComponents.add(Component.translatable( + "gtceu.tooltip.wireless_transmitter_bind", + Component.literal("" + target.getX()).withStyle(ChatFormatting.GOLD), + Component.literal("" + target.getY()).withStyle(ChatFormatting.GOLD), + Component.literal("" + target.getZ()).withStyle(ChatFormatting.GOLD), + Component.literal(stack.getOrDefault(GTDataComponents.MONITOR_TARGET_FACE, Direction.UP).getName()) + .withStyle(ChatFormatting.DARK_PURPLE))); + } + var conf = stack.getOrDefault(GTDataComponents.MONITOR_COVER_CONFIG, null); + if (conf != null) { + tooltipComponents.add(Component.translatable("gtceu.tooltip.computer_monitor_config")); + } + var coverData = stack.getOrDefault(GTDataComponents.COMPUTER_MONITOR_DATA, null); + if (coverData != null) { + tooltipComponents.add( + Component.translatable("gtceu.tooltip.computer_monitor_data", + coverData)); + } ResearchManager.ResearchItem researchData = stack.get(GTDataComponents.RESEARCH_ITEM); if (researchData == null) { BlockPos pos = stack.get(GTDataComponents.DATA_COPY_POS); @@ -44,6 +103,18 @@ private static Component makePosPart(int coordinate) { @Override public InteractionResult onItemUseFirst(ItemStack itemStack, UseOnContext context) { + ICoverable coverable = GTCapabilityHelper.getCoverable(context.getLevel(), context.getClickedPos(), + context.getClickedFace()); + if (coverable != null && + coverable.getCoverAtSide(context.getClickedFace()) instanceof IDataStickInteractable interactable) { + if (context.isSecondaryUseActive()) { + if (!itemStack.has(GTDataComponents.RESEARCH_ITEM)) { + return interactable.onDataStickShiftUse(context.getPlayer(), itemStack); + } + } else { + return interactable.onDataStickUse(context.getPlayer(), itemStack); + } + } if (context.getLevel().getBlockEntity(context.getClickedPos()) instanceof MetaMachineBlockEntity blockEntity) { var machine = blockEntity.getMetaMachine(); if (!MachineOwner.canOpenOwnerMachine(context.getPlayer(), machine)) { @@ -63,4 +134,22 @@ public InteractionResult onItemUseFirst(ItemStack itemStack, UseOnContext contex } return InteractionResult.sidedSuccess(context.getLevel().isClientSide); } + + public static record BoundPlayer(UUID uuid, int perm, Component displayName) { + + public static Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + UUIDUtil.CODEC.fieldOf("uuid").forGetter(val -> val.uuid), + Codec.INT.fieldOf("perm").forGetter(val -> val.perm), + ComponentSerialization.CODEC.fieldOf("name").forGetter(val -> val.displayName)) + .apply(instance, BoundPlayer::new)); + public static StreamCodec STREAM_CODEC = StreamCodec.composite( + UUIDUtil.STREAM_CODEC, BoundPlayer::uuid, + ByteBufCodecs.INT, BoundPlayer::perm, + ComponentSerialization.STREAM_CODEC, BoundPlayer::displayName, + BoundPlayer::new); + + public BoundPlayer(UUID uuid, Integer perm, Component name) { + this(uuid, perm.intValue(), name); + } + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ItemFluidContainer.java b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ItemFluidContainer.java index 5acb7af82b2..37844c2b4f6 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ItemFluidContainer.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/behavior/ItemFluidContainer.java @@ -15,7 +15,7 @@ public ItemStack getRecipeRemained(ItemStack itemStack) { var drained = handler.drain(FluidType.BUCKET_VOLUME, FluidAction.SIMULATE); if (drained.getAmount() != FluidType.BUCKET_VOLUME) return ItemStack.EMPTY; handler.drain(FluidType.BUCKET_VOLUME, FluidAction.EXECUTE); - return handler.getContainer(); + return ItemStack.EMPTY; }).orElse(itemStack); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/BindingData.java b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/BindingData.java new file mode 100644 index 00000000000..d388598de8b --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/BindingData.java @@ -0,0 +1,62 @@ +package com.gregtechceu.gtceu.common.item.datacomponents; + +import net.minecraft.core.UUIDUtil; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipProvider; +import net.minecraft.world.level.EntityGetter; +import net.neoforged.neoforge.common.UsernameCache; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import org.jetbrains.annotations.Nullable; + +import java.util.UUID; +import java.util.function.Consumer; + +public record BindingData(int permissionLevel, UUID uuid) implements TooltipProvider { + + // spotless:off + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + ExtraCodecs.NON_NEGATIVE_INT.fieldOf("permission_level").forGetter(BindingData::permissionLevel), + UUIDUtil.STRING_CODEC.fieldOf("uuid").forGetter(BindingData::uuid) + ).apply(instance, BindingData::new)); + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.VAR_INT, BindingData::permissionLevel, + UUIDUtil.STREAM_CODEC, BindingData::uuid, + BindingData::new + ); + //spotless:on + + public @Nullable Component getBoundPlayerName(@Nullable EntityGetter level) { + if (level != null) { + Player player = level.getPlayerByUUID(this.uuid); + if (player != null) { + return player.getDisplayName(); + } + } else { + String lastUsername = UsernameCache.getLastKnownUsername(this.uuid); + if (lastUsername != null) { + return Component.literal(lastUsername); + } + } + return null; + } + + @Override + public void addToTooltip(Item.TooltipContext context, Consumer tooltipAdder, TooltipFlag tooltipFlag) { + Component displayName = getBoundPlayerName(context.level()); + if (displayName == null) { + displayName = Component.translatable("gtceu.tooltip.player_name.unknown"); + } + + tooltipAdder.accept(Component.translatable("gtceu.tooltip.player_bind", displayName)); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/ComputerMonitorConfig.java b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/ComputerMonitorConfig.java new file mode 100644 index 00000000000..4e4a36dda21 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/ComputerMonitorConfig.java @@ -0,0 +1,49 @@ +package com.gregtechceu.gtceu.common.item.datacomponents; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.TooltipProvider; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.buffer.ByteBuf; +import lombok.With; + +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; + +public record ComputerMonitorConfig(@With List lines, @With List args, @With int updateInterval) + implements TooltipProvider { + + //spotless:off + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.STRING.listOf().fieldOf("lines").forGetter(ComputerMonitorConfig::lines), + Codec.STRING.listOf().fieldOf("arguments").forGetter(ComputerMonitorConfig::args), + ExtraCodecs.POSITIVE_INT.fieldOf("update_interval").forGetter(ComputerMonitorConfig::updateInterval) + ).apply(instance, ComputerMonitorConfig::new)); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.STRING_UTF8.apply(ByteBufCodecs.list()), ComputerMonitorConfig::lines, + ByteBufCodecs.STRING_UTF8.apply(ByteBufCodecs.list()), ComputerMonitorConfig::args, + ByteBufCodecs.VAR_INT, ComputerMonitorConfig::updateInterval, + ComputerMonitorConfig::new + ); + //spotless:on + + public static final ComputerMonitorConfig EMPTY = new ComputerMonitorConfig(Collections.emptyList(), + Collections.emptyList(), 100); + + public ComputerMonitorConfig { + lines = Collections.unmodifiableList(lines); + args = Collections.unmodifiableList(args); + } + + @Override + public void addToTooltip(Item.TooltipContext context, Consumer tooltipAdder, TooltipFlag tooltipFlag) { + tooltipAdder.accept(Component.translatable("gtceu.tooltip.computer_monitor_config")); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/DataItem.java b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/DataItem.java new file mode 100644 index 00000000000..c5c840215fe --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/DataItem.java @@ -0,0 +1,29 @@ +package com.gregtechceu.gtceu.common.item.datacomponents; + +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.util.ExtraCodecs; + +import com.google.common.base.Preconditions; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.buffer.ByteBuf; + +public record DataItem(boolean requireDataBank, int capacity) { + + // spotless:off + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codec.BOOL.fieldOf("requires_data_bank").forGetter(DataItem::requireDataBank), + ExtraCodecs.POSITIVE_INT.fieldOf("capacity").forGetter(DataItem::capacity) + ).apply(instance, DataItem::new)); + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + ByteBufCodecs.BOOL, DataItem::requireDataBank, + ByteBufCodecs.VAR_INT, DataItem::capacity, + DataItem::new + ); + // spotless:on + + public DataItem { + Preconditions.checkArgument(capacity > 0, "Capacity must be positive"); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/FormatStringList.java b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/FormatStringList.java new file mode 100644 index 00000000000..ab0eab43b09 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/FormatStringList.java @@ -0,0 +1,69 @@ +package com.gregtechceu.gtceu.common.item.datacomponents; + +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; + +import com.mojang.serialization.Codec; +import io.netty.buffer.ByteBuf; + +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public record FormatStringList(List lines) { + + public static final Codec CODEC = Codec.STRING.listOf() + .xmap(FormatStringList::new, FormatStringList::lines); + public static final StreamCodec STREAM_CODEC = ByteBufCodecs.STRING_UTF8 + .apply(ByteBufCodecs.list()) + .map(FormatStringList::new, FormatStringList::lines); + + public static final FormatStringList EMPTY = new FormatStringList(Collections.emptyList()); + + public FormatStringList { + lines = Collections.unmodifiableList(lines); + } + + public Mutable mutable() { + return new Mutable(this.lines); + } + + public static class Mutable extends AbstractList { + + private final List lines; + + public Mutable(List lines) { + this.lines = new ArrayList<>(lines); + } + + public FormatStringList toImmutable() { + return new FormatStringList(this.lines); + } + + @Override + public String get(int index) { + return lines.get(index); + } + + @Override + public int size() { + return lines.size(); + } + + @Override + public boolean add(String s) { + return lines.add(s); + } + + @Override + public boolean remove(Object o) { + return lines.remove(o); + } + + @Override + public String remove(int index) { + return lines.remove(index); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/TextLineList.java b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/TextLineList.java new file mode 100644 index 00000000000..9cf9a65d329 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/TextLineList.java @@ -0,0 +1,39 @@ +package com.gregtechceu.gtceu.common.item.datacomponents; + +import com.gregtechceu.gtceu.api.placeholder.MultiLineComponent; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.util.Mth; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import lombok.With; + +import java.util.Collections; +import java.util.List; + +public record TextLineList(@With List lines, @With float scale) { + + // spotless:off + public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + ComponentSerialization.CODEC.listOf().fieldOf("lines").forGetter(TextLineList::lines), + Codec.FLOAT.fieldOf("scale").forGetter(TextLineList::scale) + ).apply(instance, TextLineList::new)); + // spotless:on + + public static final TextLineList EMPTY = new TextLineList(Collections.emptyList(), 1.0f); + + public TextLineList { + lines = Collections.unmodifiableList(lines); + scale = Mth.clamp(scale, 0.0001f, 1000f); + } + + public MultiLineComponent toMultiLineComponent() { + MultiLineComponent multiLine = new MultiLineComponent(); + for (Component c : this.lines) { + multiLine.add(c.copy()); + } + return multiLine; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/package-info.java b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/package-info.java new file mode 100644 index 00000000000..bf9365bc939 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/datacomponents/package-info.java @@ -0,0 +1,9 @@ +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +@FieldsAreNonnullByDefault +package com.gregtechceu.gtceu.common.item.datacomponents; + +import net.minecraft.FieldsAreNonnullByDefault; +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/modules/ImageModuleBehaviour.java b/src/main/java/com/gregtechceu/gtceu/common/item/modules/ImageModuleBehaviour.java new file mode 100644 index 00000000000..e6fe7583aa0 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/modules/ImageModuleBehaviour.java @@ -0,0 +1,57 @@ +package com.gregtechceu.gtceu.common.item.modules; + +import com.gregtechceu.gtceu.api.gui.GuiTextures; +import com.gregtechceu.gtceu.api.item.component.IMonitorModuleItem; +import com.gregtechceu.gtceu.client.renderer.monitor.IMonitorRenderer; +import com.gregtechceu.gtceu.client.renderer.monitor.MonitorImageRenderer; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; +import com.gregtechceu.gtceu.common.network.GTNetwork; +import com.gregtechceu.gtceu.common.network.packets.SCPacketMonitorGroupNBTChange; +import com.gregtechceu.gtceu.data.item.GTDataComponents; + +import com.lowdragmc.lowdraglib.gui.widget.ButtonWidget; +import com.lowdragmc.lowdraglib.gui.widget.TextFieldWidget; +import com.lowdragmc.lowdraglib.gui.widget.Widget; +import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; + +import net.minecraft.world.item.ItemStack; + +public class ImageModuleBehaviour implements IMonitorModuleItem { + + @Override + public IMonitorRenderer getRenderer(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) { + return new MonitorImageRenderer(stack.getOrDefault(GTDataComponents.IMAGE_MODULE_URL, null)); + } + + @Override + public Widget createUIWidget(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) { + WidgetGroup builder = new WidgetGroup(); + TextFieldWidget textField = new TextFieldWidget(0, 0, 100, 10, null, null); + textField.setCurrentString(stack.getOrDefault(GTDataComponents.IMAGE_MODULE_URL, null)); + + ButtonWidget saveButton = new ButtonWidget(-40, 22, 20, 20, click -> { + if (!click.isRemote) return; + + stack.set(GTDataComponents.IMAGE_MODULE_URL, textField.getCurrentString()); + GTNetwork.sendToServer(new SCPacketMonitorGroupNBTChange(stack, group, machine)); + }); + saveButton.setButtonTexture(GuiTextures.BUTTON_CHECK); + builder.addWidget(textField); + builder.addWidget(saveButton); + return builder; + } + + @Override + public String getType() { + return "image"; + } + + public String getUrl(ItemStack stack) { + return stack.get(GTDataComponents.IMAGE_MODULE_URL); + } + + public void setUrl(ItemStack stack, String url) { + stack.set(GTDataComponents.IMAGE_MODULE_URL, url); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/modules/TextModuleBehaviour.java b/src/main/java/com/gregtechceu/gtceu/common/item/modules/TextModuleBehaviour.java new file mode 100644 index 00000000000..91f7ae6e8fe --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/modules/TextModuleBehaviour.java @@ -0,0 +1,160 @@ +package com.gregtechceu.gtceu.common.item.modules; + +import com.gregtechceu.gtceu.api.gui.GuiTextures; +import com.gregtechceu.gtceu.api.item.component.IAddInformation; +import com.gregtechceu.gtceu.api.item.component.IMonitorModuleItem; +import com.gregtechceu.gtceu.api.placeholder.MultiLineComponent; +import com.gregtechceu.gtceu.api.placeholder.PlaceholderContext; +import com.gregtechceu.gtceu.api.placeholder.PlaceholderHandler; +import com.gregtechceu.gtceu.client.renderer.monitor.IMonitorRenderer; +import com.gregtechceu.gtceu.client.renderer.monitor.MonitorTextRenderer; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; +import com.gregtechceu.gtceu.common.network.GTNetwork; +import com.gregtechceu.gtceu.common.network.packets.SCPacketMonitorGroupNBTChange; +import com.gregtechceu.gtceu.data.item.GTDataComponents; + +import com.lowdragmc.lowdraglib.gui.widget.ButtonWidget; +import com.lowdragmc.lowdraglib.gui.widget.TextFieldWidget; +import com.lowdragmc.lowdraglib.gui.widget.Widget; +import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; +import com.lowdragmc.lowdraglib.gui.widget.codeeditor.CodeEditorWidget; + +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.util.Mth; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; + +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; +import java.util.function.Supplier; + +public class TextModuleBehaviour implements IMonitorModuleItem, IAddInformation { + + private void updateText(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) { + StringBuilder formatStringLines = new StringBuilder(); + List tag = stack.get(GTDataComponents.TEXT_MODULE_STRING_LINES); + for (String value : tag) + formatStringLines.append(value).append('\n'); + if (!stack.has(GTDataComponents.PLACEHOLDER_UUID)) { + stack.set(GTDataComponents.PLACEHOLDER_UUID, UUID.randomUUID()); + } + MultiLineComponent text = PlaceholderHandler.processPlaceholders( + getPlaceholderText(stack), + new PlaceholderContext( + group.getTargetLevel(machine.getLevel()), + group.getTarget(machine.getLevel()), + group.getTargetCoverSide(), + group.getPlaceholderSlotsHandler(), + group.getTargetCover(machine.getLevel()), + null, + stack.get(GTDataComponents.PLACEHOLDER_UUID))); + stack.set(GTDataComponents.TEXT_MODULE_TEXT, text.toImmutable()); + } + + @Override + public void tick(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) { + this.updateText(stack, machine, group); + } + + @Override + public IMonitorRenderer getRenderer(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) { + return new MonitorTextRenderer( + stack.getOrDefault(GTDataComponents.TEXT_MODULE_TEXT, List.of()), + Math.max(stack.getOrDefault(GTDataComponents.TEXT_MODULE_SCALE, 1.0).doubleValue(), .0001)); + } + + @Override + public Widget createUIWidget(ItemStack stack, CentralMonitorMachine machine, MonitorGroup group) { + WidgetGroup builder = new WidgetGroup(); + CodeEditorWidget editor = new CodeEditorWidget(0, 0, 120, 80); + // editor.codeEditor.setLanguageDefinition(PlaceholderHandler.LANG_DEFINITION); + TextFieldWidget scaleInput = new TextFieldWidget( + -50, 47, + 40, 10, + null, + null); + ButtonWidget saveButton = new ButtonWidget(-40, 22, 20, 20, click -> { + if (!click.isRemote) return; + stack.set(GTDataComponents.TEXT_MODULE_STRING_LINES, editor.getLines()); + try { + stack.set(GTDataComponents.TEXT_MODULE_SCALE, Double.parseDouble(scaleInput.getCurrentString())); + } catch (NumberFormatException ignored) {} + GTNetwork.sendToServer(new SCPacketMonitorGroupNBTChange(stack, group, machine)); + }); + saveButton.setButtonTexture(GuiTextures.BUTTON_CHECK); + List tmp = new ArrayList<>(); + Supplier scaleInputSupplier = () -> { + if (tmp.isEmpty()) tmp.add(true); + else scaleInput.setTextSupplier(null); + if (!stack.has(GTDataComponents.TEXT_MODULE_SCALE)) { + stack.set(GTDataComponents.TEXT_MODULE_SCALE, 1.0); + GTNetwork.sendToServer(new SCPacketMonitorGroupNBTChange(stack, group, machine)); + return "1"; + } + return String.valueOf(Mth.clamp(stack.get(GTDataComponents.TEXT_MODULE_SCALE), .0001, 1000)); + }; + scaleInput.setTextSupplier(scaleInputSupplier); + scaleInput.setHoverTooltips(Component.translatable("gtceu.gui.central_monitor.text_scale")); + List formatStringLines = stack.getOrDefault(GTDataComponents.TEXT_MODULE_STRING_LINES, List.of()); + editor.setLines(formatStringLines); + builder.addWidget(editor); + builder.addWidget(saveButton); + Widget placeholderReference = PlaceholderHandler.getPlaceholderHandlerUI(""); + builder.addWidget(scaleInput); + placeholderReference.setSelfPosition(-100, -50); + builder.addWidget(placeholderReference); + return builder; + } + + @Override + public String getType() { + return "text"; + } + + public MultiLineComponent getText(ItemStack stack) { + return new MultiLineComponent(stack.get(GTDataComponents.TEXT_MODULE_TEXT).stream() + .map(m -> MutableComponent.create(m.getContents())).toList()); + } + + public double getScale(ItemStack stack) { + return Math.max(stack.get(GTDataComponents.TEXT_MODULE_SCALE), .0001); + } + + public void setScale(ItemStack stack, double scale) { + stack.set(GTDataComponents.TEXT_MODULE_SCALE, scale); + } + + public void setPlaceholderText(ItemStack stack, String text) { + List listTag = new ArrayList<>(); + for (String line : text.split("\n")) listTag.add(line); + stack.set(GTDataComponents.TEXT_MODULE_STRING_LINES, listTag); + } + + public String getPlaceholderText(ItemStack stack) { + StringBuilder formatStringLines = new StringBuilder(); + List tag = stack.get(GTDataComponents.TEXT_MODULE_STRING_LINES); + for (String value : tag) { + formatStringLines.append(value).append('\n'); + } + return formatStringLines.toString(); + } + + @Override + public void appendHoverText(ItemStack stack, @Nullable Item.TooltipContext context, + List tooltipComponents, + TooltipFlag isAdvanced) { + if (isAdvanced.isAdvanced()) { + tooltipComponents.add(Component.literal("Placeholder text:").withStyle(ChatFormatting.GOLD)); + tooltipComponents.addAll(MultiLineComponent.literal(getPlaceholderText(stack))); + tooltipComponents.add(Component.literal("Processed text:").withStyle(ChatFormatting.GOLD)); + tooltipComponents.addAll(getText(stack)); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/tool/ToolEventHandlers.java b/src/main/java/com/gregtechceu/gtceu/common/item/tool/ToolEventHandlers.java index 1acf8149191..068f5a0b2cf 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/tool/ToolEventHandlers.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/tool/ToolEventHandlers.java @@ -17,7 +17,6 @@ import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.decoration.ItemFrame; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; @@ -142,13 +141,16 @@ public static List onHarvestDrops(Player player, ItemStack tool, Serv Iterator dropItr = drops.iterator(); while (dropItr.hasNext()) { ItemStack dropStack = dropItr.next(); - ItemEntity drop = new ItemEntity(EntityType.ITEM, level); - drop.setItem(dropStack); + // Place close to the player for sanity reasons (Instead of XYZ=0,0,0) + ItemEntity drop = new ItemEntity(level, player.getX(), player.getY(), player.getZ(), dropStack); - if (fireItemPickupEvent(drop, player) || player.addItem(dropStack)) { + if (fireItemPickupEvent(drop, player) && player.addItem(dropStack)) { EventHooks.fireItemPickupPost(drop, player, dropStack.copy()); dropItr.remove(); } + + // Just in case, destroy it + drop.discard(); } } return drops; diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/HarvestCropsBehavior.java b/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/HarvestCropsBehavior.java index ef9ae17ed5c..247118f3d8c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/HarvestCropsBehavior.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/HarvestCropsBehavior.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.item.tool.behavior.ToolBehaviorType; import com.gregtechceu.gtceu.data.item.GTItemAbilities; import com.gregtechceu.gtceu.data.tools.GTToolBehaviors; +import com.gregtechceu.gtceu.utils.GTUtil; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; @@ -97,7 +98,7 @@ private static boolean harvestBlockRoutine(BlockPos pos, UseOnContext context) { var drops = Block.getDrops(blockState, (ServerLevel) level, pos, null); boolean removedSeed = false; for (ItemStack drop : drops) { - if (!removedSeed && ItemStack.isSameItemSameComponents(drop, seed)) { + if (!removedSeed && GTUtil.isSameItemSameTags(drop, seed)) { drop.shrink(1); removedSeed = true; if (drop.isEmpty()) continue; diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/ProspectingBehavior.java b/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/ProspectingBehavior.java new file mode 100644 index 00000000000..4e28d373f94 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/ProspectingBehavior.java @@ -0,0 +1,97 @@ +package com.gregtechceu.gtceu.common.item.tool.behavior; + +import com.gregtechceu.gtceu.api.item.IGTTool; +import com.gregtechceu.gtceu.api.item.tool.behavior.IToolBehavior; +import com.gregtechceu.gtceu.api.item.tool.behavior.ToolBehaviorType; +import com.gregtechceu.gtceu.data.tools.GTToolBehaviors; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.item.context.UseOnContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.Fluids; +import net.neoforged.neoforge.common.Tags; + +import com.mojang.serialization.Codec; +import io.netty.buffer.ByteBuf; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class ProspectingBehavior implements IToolBehavior { + + public static final ProspectingBehavior INSTANCE = new ProspectingBehavior(); + public static final Codec CODEC = Codec.unit(INSTANCE); + public static final StreamCodec STREAM_CODEC = StreamCodec.unit(INSTANCE); + + @Override + public @NotNull InteractionResult onItemUse(UseOnContext context) { + if (context.getItemInHand().getItem() instanceof IGTTool tool) { + int tier = tool.getTotalHarvestLevel(); + int depth = tool.getProspectingDepth(); + findOres(context.getLevel(), context.getClickedPos(), context.getClickedFace(), depth).forEach(c -> { + if (context.getPlayer() != null && context.getLevel().isClientSide()) + context.getPlayer().sendSystemMessage(c); + }); + return InteractionResult.SUCCESS; + } else return IToolBehavior.super.onItemUse(context); + } + + private static List findOres(Level level, BlockPos pos, Direction direction, int depth) { + Set foundBlocks = new HashSet<>(); + Set foundFluids = new HashSet<>(); + for (int i = 0; i < depth; i++) { + for (BlockPos position : getSurroundingBlocks(pos, direction)) { + if (!level.getFluidState(position).isEmpty()) + foundFluids.add(level.getFluidState(position).getType()); + else foundBlocks.add(level.getBlockState(position)); + } + if (direction.getAxis().isHorizontal()) { + for (BlockPos position : getSurroundingBlocks(pos.below(), direction)) { + if (!level.getFluidState(position).isEmpty()) + foundFluids.add(level.getFluidState(position).getType()); + else foundBlocks.add(level.getBlockState(position)); + } + } + pos = pos.relative(direction.getOpposite()); + } + List out = new ArrayList<>(); + int cnt = 0; + for (BlockState state : foundBlocks) { + if (state.is(Tags.Blocks.ORES)) { + out.add(Component.translatable("item.gtceu.tool.behavior.prospecting.ore", state.getBlock().getName())); + } else if (state.isAir()) out.add(Component.translatable("item.gtceu.tool.behavior.prospecting.air")); + else cnt++; + } + for (Fluid state : foundFluids) { + if (state.isSame(Fluids.WATER)) + out.add(Component.translatable("item.gtceu.tool.behavior.prospecting.water")); + if (state.isSame(Fluids.LAVA)) out.add(Component.translatable("item.gtceu.tool.behavior.prospecting.lava")); + } + if (cnt >= 2) out.add(Component.translatable("item.gtceu.tool.behavior.prospecting.changing")); + return out; + } + + private static List getSurroundingBlocks(BlockPos pos, Direction dir) { + List out = new ArrayList<>(); + for (Direction direction : Direction.values()) { + if (direction.getAxis() != dir.getAxis()) out.add(pos.relative(direction)); + } + out.add(pos); + return out; + } + + @Override + public ToolBehaviorType getType() { + return GTToolBehaviors.PROSPECTING; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/ToolModeSwitchBehavior.java b/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/ToolModeSwitchBehavior.java index 5235e60954a..9109715aade 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/ToolModeSwitchBehavior.java +++ b/src/main/java/com/gregtechceu/gtceu/common/item/tool/behavior/ToolModeSwitchBehavior.java @@ -1,22 +1,35 @@ package com.gregtechceu.gtceu.common.item.tool.behavior; +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.item.tool.GTToolType; +import com.gregtechceu.gtceu.api.item.tool.ToolHelper; import com.gregtechceu.gtceu.api.item.tool.behavior.IToolBehavior; import com.gregtechceu.gtceu.api.item.tool.behavior.ToolBehaviorType; import com.gregtechceu.gtceu.data.item.GTDataComponents; import com.gregtechceu.gtceu.data.item.GTItemAbilities; +import com.gregtechceu.gtceu.data.sound.GTSoundEntries; +import com.gregtechceu.gtceu.data.tag.CustomTags; import com.gregtechceu.gtceu.data.tools.GTToolBehaviors; +import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.level.ServerLevel; import net.minecraft.util.StringRepresentable; import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.context.UseOnContext; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; import net.neoforged.neoforge.common.ItemAbility; import com.mojang.serialization.Codec; @@ -25,6 +38,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; +import java.util.Set; public class ToolModeSwitchBehavior implements IToolBehavior { @@ -47,18 +61,51 @@ public boolean canPerformAction(ItemStack stack, ItemAbility action) { } @Override - public @NotNull InteractionResultHolder onItemRightClick(@NotNull Level level, @NotNull Player player, - @NotNull InteractionHand hand) { - var held = player.getItemInHand(hand); - if (level.isClientSide || !player.isShiftKeyDown()) { - return InteractionResultHolder.pass(held); + public @NotNull InteractionResult onItemUse(UseOnContext context) { + Level world = context.getLevel(); + BlockHitResult blockHitResult = context.getHitResult(); + Player player = context.getPlayer(); + ItemStack itemStack = context.getItemInHand(); + BlockState state = world.getBlockState(blockHitResult.getBlockPos()); + BlockPos pos = blockHitResult.getBlockPos(); + Set toolTypes = ToolHelper.getToolTypes(itemStack); + // Copied and adapted from + // https://github.com/Creators-of-Create/Create/blob/mc1.20.1/dev/src/main/java/com/simibubi/create/content/equipment/wrench/WrenchItem.java + if (toolTypes.contains(GTToolType.WRENCH) && GTCEu.Mods.isCreateLoaded() && + state.is(CustomTags.CREATE_WRENCH_PICKUP)) { + if (!(world instanceof ServerLevel serverLevel)) + return InteractionResult.SUCCESS; + if (player != null && !player.isCreative()) + Block.getDrops(state, serverLevel, pos, world.getBlockEntity(pos), player, itemStack) + .forEach(stack -> player.getInventory().placeItemBackInInventory(stack)); + state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, true); + world.destroyBlock(pos, false); + GTSoundEntries.WRENCH_TOOL.playOnServer(serverLevel, pos, 1, GTValues.RNG.nextFloat() * .5f + .5f); + return InteractionResult.SUCCESS; } - var newMode = held.getOrDefault(GTDataComponents.TOOL_MODE, ModeType.BOTH).nextMode(); - held.set(GTDataComponents.TOOL_MODE, newMode); - player.displayClientMessage(Component.translatable("metaitem.machine_configuration.mode", newMode.getName()), - true); - return InteractionResultHolder.success(held); + if (player != null) + world.getBlockState(pos).useItemOn(itemStack, world, player, context.getHand(), blockHitResult); + return InteractionResult.SUCCESS; + } + + @Override + public @NotNull InteractionResultHolder onItemRightClick(@NotNull Level world, @NotNull Player player, + @NotNull InteractionHand hand) { + var itemStack = player.getItemInHand(hand); + if (player.isShiftKeyDown()) { + var toolTypes = ToolHelper.getToolTypes(itemStack); + if (toolTypes.contains(GTToolType.WRENCH)) { + var newMode = itemStack.getOrDefault(GTDataComponents.TOOL_MODE, ModeType.BOTH).nextMode(); + itemStack.set(GTDataComponents.TOOL_MODE, newMode); + + player.displayClientMessage( + Component.translatable("metaitem.machine_configuration.mode", newMode.getName()), + true); + } + return InteractionResultHolder.success(itemStack); + } + return InteractionResultHolder.success(itemStack); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BatteryBufferMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BatteryBufferMachine.java index 1b1288077cc..5584c7c71e8 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BatteryBufferMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/BatteryBufferMachine.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; import com.gregtechceu.gtceu.api.capability.IControllable; import com.gregtechceu.gtceu.api.capability.IElectricItem; +import com.gregtechceu.gtceu.api.capability.IMonitorComponent; import com.gregtechceu.gtceu.api.capability.compat.FeCompat; import com.gregtechceu.gtceu.api.gui.GuiTextures; import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; @@ -17,6 +18,7 @@ import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; +import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; import com.lowdragmc.lowdraglib.gui.widget.Widget; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; @@ -33,7 +35,7 @@ import java.util.List; public class BatteryBufferMachine extends TieredEnergyMachine - implements IControllable, IFancyUIMachine, IMachineLife { + implements IControllable, IFancyUIMachine, IMachineLife, IMonitorComponent { public static final long AMPS_PER_BATTERY = 2L; @@ -199,6 +201,11 @@ public void onMachineRemoved() { clearInventory(batteryInventory); } + @Override + public IGuiTexture getComponentIcon() { + return GuiTextures.BUTTON_CHECK; // temporary + } + protected class EnergyBatteryTrait extends NotifiableEnergyContainer { protected EnergyBatteryTrait(int inventorySize) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ChargerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ChargerMachine.java index 6806f84c449..42b3f8fc02f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ChargerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ChargerMachine.java @@ -9,6 +9,7 @@ import com.gregtechceu.gtceu.api.machine.TieredEnergyMachine; import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.NotifiableEnergyContainer; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.gregtechceu.gtceu.config.ConfigHolder; @@ -61,8 +62,7 @@ public enum State implements StringRepresentable { } } - public static final EnumProperty STATE_PROPERTY = EnumProperty.create("charger_state", - ChargerMachine.State.class); + public static final EnumProperty STATE_PROPERTY = GTMachineModelProperties.CHARGER_STATE; @Persisted @Getter @@ -101,7 +101,13 @@ protected NotifiableEnergyContainer createEnergyContainer(Object... args) { } protected CustomItemStackHandler createChargerInventory(Object... args) { - var handler = new CustomItemStackHandler(this.inventorySize); + var handler = new CustomItemStackHandler(this.inventorySize) { + + @Override + public int getSlotLimit(int slot) { + return 1; + } + }; handler.setFilter(item -> GTCapabilityHelper.getElectricItem(item) != null || (ConfigHolder.INSTANCE.compat.energy.nativeEUToFE && GTCapabilityHelper.getForgeEnergyItem(item) != null)); @@ -189,7 +195,7 @@ private List getNonFullElectricItem() { private void changeState(State newState) { if (state != newState) { state = newState; - setRenderState(getRenderState().setValue(STATE_PROPERTY, newState)); + setRenderState(getRenderState().setValue(GTMachineModelProperties.CHARGER_STATE, newState)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ConverterMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ConverterMachine.java index 1fcea4932ca..c5c02c434db 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ConverterMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ConverterMachine.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.TieredEnergyMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.NotifiableEnergyContainer; import com.gregtechceu.gtceu.common.machine.trait.ConverterTrait; import com.gregtechceu.gtceu.data.item.GTItemAbilities; @@ -31,7 +32,7 @@ public class ConverterMachine extends TieredEnergyMachine { protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(ConverterMachine.class, TieredEnergyMachine.MANAGED_FIELD_HOLDER); - public static final BooleanProperty FE_TO_EU_PROPERTY = BooleanProperty.create("fe_to_eu"); + public static final BooleanProperty FE_TO_EU_PROPERTY = GTMachineModelProperties.IS_FE_TO_EU; public ConverterMachine(IMachineBlockEntity holder, int tier, int amps, Object... args) { super(holder, tier, args, amps); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/HullMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/HullMachine.java index c5ac2248233..e860457f47c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/HullMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/HullMachine.java @@ -2,12 +2,15 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.capability.IMonitorComponent; +import com.gregtechceu.gtceu.api.gui.GuiTextures; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.multiblock.part.MultiblockPartMachine; import com.gregtechceu.gtceu.api.machine.multiblock.part.TieredPartMachine; import com.gregtechceu.gtceu.api.machine.trait.NotifiableEnergyContainer; import com.gregtechceu.gtceu.integration.ae2.machine.trait.GridNodeHostTrait; +import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; @@ -19,7 +22,7 @@ import appeng.me.helpers.IGridConnectedBlockEntity; import org.jetbrains.annotations.NotNull; -public class HullMachine extends TieredPartMachine { +public class HullMachine extends TieredPartMachine implements IMonitorComponent { protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(HullMachine.class, MultiblockPartMachine.MANAGED_FIELD_HOLDER); @@ -105,4 +108,9 @@ public int tintColor(int index) { } return super.tintColor(index); } + + @Override + public IGuiTexture getComponentIcon() { + return GuiTextures.BUTTON_CHECK; // temporary (until there's a texture that is not fully 16x16 for this) + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ItemCollectorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ItemCollectorMachine.java index d53666713a5..7525e666e5c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ItemCollectorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/ItemCollectorMachine.java @@ -18,6 +18,7 @@ import com.gregtechceu.gtceu.api.machine.feature.IAutoOutputItem; import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; import com.gregtechceu.gtceu.config.ConfigHolder; @@ -232,7 +233,7 @@ public void updateCollectionSubscription() { public void setActive(boolean active) { this.active = active; - setRenderState(getRenderState().setValue(IWorkable.ACTIVE_PROPERTY, active)); + setRenderState(getRenderState().setValue(GTMachineModelProperties.IS_ACTIVE, active)); } public void update() { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/MinerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/MinerMachine.java index e9b4fa16496..95bee89581d 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/MinerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/MinerMachine.java @@ -335,6 +335,7 @@ protected static EditableUI createBatterySlot() { private void addDisplayText(@NotNull List textList) { int workingArea = IMiner.getWorkingArea(getRecipeLogic().getCurrentRadius()); + textList.add(recipeLogic.getCustomProgressLine()); textList.add(Component.translatable("gtceu.machine.miner.startx", getRecipeLogic().getX()).append(" ") .append(Component.translatable("gtceu.machine.miner.minex", getRecipeLogic().getMineX()))); textList.add(Component.translatable("gtceu.machine.miner.starty", getRecipeLogic().getY()).append(" ") diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/TransformerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/TransformerMachine.java index 926a37c988b..e2000e7ad10 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/TransformerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/TransformerMachine.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.capability.IControllable; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.TieredEnergyMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.NotifiableEnergyContainer; import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; @@ -28,7 +29,7 @@ public class TransformerMachine extends TieredEnergyMachine implements IControll protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(TransformerMachine.class, TieredEnergyMachine.MANAGED_FIELD_HOLDER); - public static final BooleanProperty TRANSFORM_UP_PROPERTY = BooleanProperty.create("transform_up"); + public static final BooleanProperty TRANSFORM_UP_PROPERTY = GTMachineModelProperties.IS_TRANSFORM_UP; @Persisted @DescSynced @@ -116,7 +117,7 @@ public void setTransformUp(boolean isTransformUp) { if (this.isTransformUp != isTransformUp && !isRemote()) { this.isTransformUp = isTransformUp; updateEnergyContainer(isTransformUp); - setRenderState(getRenderState().setValue(TRANSFORM_UP_PROPERTY, isTransformUp)); + setRenderState(getRenderState().setValue(GTMachineModelProperties.IS_TRANSFORM_UP, isTransformUp)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/WorldAcceleratorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/WorldAcceleratorMachine.java index f96827dfd0a..ec3d9104fb0 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/electric/WorldAcceleratorMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/electric/WorldAcceleratorMachine.java @@ -5,12 +5,12 @@ import com.gregtechceu.gtceu.api.blockentity.PipeBlockEntity; import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; import com.gregtechceu.gtceu.api.capability.IControllable; -import com.gregtechceu.gtceu.api.capability.IWorkable; import com.gregtechceu.gtceu.api.gui.GuiTextures; import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.TieredEnergyMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.NotifiableEnergyContainer; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.item.GTItemAbilities; @@ -58,7 +58,7 @@ public class WorldAcceleratorMachine extends TieredEnergyMachine implements ICon // Hard-coded blacklist for blockentities private static final List blockEntityClassNamesBlackList = new ArrayList<>(); - public static final BooleanProperty RANDOM_TICK_PROPERTY = BooleanProperty.create("random_tick_mode"); + public static final BooleanProperty RANDOM_TICK_PROPERTY = GTMachineModelProperties.IS_RANDOM_TICK_MODE; protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder( WorldAcceleratorMachine.class, TieredEnergyMachine.MANAGED_FIELD_HOLDER); @@ -108,12 +108,12 @@ public void updateSubscription() { if (isWorkingEnabled && drainEnergy(true)) { tickSubs = subscribeServerTick(tickSubs, this::update); active = true; - setRenderState(getRenderState().setValue(IWorkable.ACTIVE_PROPERTY, true)); + setRenderState(getRenderState().setValue(GTMachineModelProperties.IS_ACTIVE, true)); } else if (tickSubs != null) { tickSubs.unsubscribe(); tickSubs = null; active = false; - setRenderState(getRenderState().setValue(IWorkable.ACTIVE_PROPERTY, false)); + setRenderState(getRenderState().setValue(GTMachineModelProperties.IS_ACTIVE, false)); } } @@ -218,7 +218,7 @@ public void onUnload() { public void setWorkingEnabled(boolean workingEnabled) { isWorkingEnabled = workingEnabled; - setRenderState(getRenderState().setValue(WORKING_ENABLED_PROPERTY, isWorkingEnabled)); + setRenderState(getRenderState().setValue(GTMachineModelProperties.IS_WORKING_ENABLED, isWorkingEnabled)); updateSubscription(); } @@ -255,7 +255,7 @@ protected ItemInteractionResult onSoftMalletClick(Player playerIn, InteractionHa BlockHitResult hitResult) { if (!isRemote()) { isRandomTickMode = !isRandomTickMode; - setRenderState(getRenderState().setValue(RANDOM_TICK_PROPERTY, isRandomTickMode)); + setRenderState(getRenderState().setValue(GTMachineModelProperties.IS_RANDOM_TICK_MODE, isRandomTickMode)); playerIn.sendSystemMessage(Component.translatable(isRandomTickMode ? "gtceu.machine.world_accelerator.mode_entity" : "gtceu.machine.world_accelerator.mode_tile")); scheduleRenderUpdate(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java index befaa5a68ab..c0a0378695f 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineMachine.java @@ -1,14 +1,22 @@ package com.gregtechceu.gtceu.common.machine.multiblock.electric; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; +import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockControllerMachine; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; +import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; +import com.gregtechceu.gtceu.api.recipe.ActionResult; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.config.ConfigHolder; @@ -19,10 +27,10 @@ import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient; +import it.unimi.dsi.fastutil.objects.Object2IntMap; import lombok.Getter; import lombok.experimental.Accessors; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.util.*; @@ -43,16 +51,8 @@ public AssemblyLineMachine(IMachineBlockEntity holder) { } @Override - public boolean beforeWorking(@Nullable GTRecipe recipe) { - if (recipe == null) return false; - if (!super.beforeWorking(recipe)) return false; - - var config = ConfigHolder.INSTANCE.machines; - if (!config.orderedAssemblyLineItems && !config.orderedAssemblyLineFluids) return true; - if (!checkItemInputs(recipe)) return false; - - if (!config.orderedAssemblyLineFluids) return true; - return checkFluidInputs(recipe); + protected RecipeLogic createRecipeLogic(Object... args) { + return new AsslineRecipeLogic(this); } public static Comparator partSorter(MultiblockControllerMachine mc) { @@ -60,8 +60,9 @@ public static Comparator partSorter(MultiblockControllerMachine mc) RelativeDirection.RIGHT.getSorter(mc.getFrontFacing(), mc.getUpwardsFacing(), mc.isFlipped())); } - private boolean checkItemInputs(@NotNull GTRecipe recipe) { - var itemInputs = recipe.inputs.getOrDefault(ItemRecipeCapability.CAP, Collections.emptyList()); + private boolean checkItemInputs(@NotNull GTRecipe recipe, boolean isTick) { + var itemInputs = (isTick ? recipe.tickInputs : recipe.inputs).getOrDefault(ItemRecipeCapability.CAP, + Collections.emptyList()); if (itemInputs.isEmpty()) return true; int inputsSize = itemInputs.size(); var itemHandlers = getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP); @@ -74,8 +75,6 @@ private boolean checkItemInputs(@NotNull GTRecipe recipe) { .map(ItemStack.class::cast) .filter(s -> !s.isEmpty()) .findFirst()) - - .dropWhile(Optional::isEmpty) .limit(inputsSize) .map(o -> o.orElse(ItemStack.EMPTY)) .toList(); @@ -93,8 +92,50 @@ private boolean checkItemInputs(@NotNull GTRecipe recipe) { return true; } - private boolean checkFluidInputs(@NotNull GTRecipe recipe) { - var fluidInputs = recipe.inputs.getOrDefault(FluidRecipeCapability.CAP, Collections.emptyList()); + private ActionResult consumeItemContents(@NotNull GTRecipe recipe, boolean isTick) { + var itemInputs = (isTick ? recipe.tickInputs : recipe.inputs).getOrDefault(ItemRecipeCapability.CAP, + Collections.emptyList()); + if (itemInputs.isEmpty()) return ActionResult.SUCCESS; + int inputsSize = itemInputs.size(); + var itemHandlers = getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP); + if (itemHandlers.size() < inputsSize) return ActionResult.FAIL_NO_REASON; + + var itemInventory = itemHandlers.stream() + .filter(IRecipeHandler::shouldSearchContent).toList(); + + if (itemInventory.size() < inputsSize) return ActionResult.FAIL_NO_REASON; + + for (int i = 0; i < inputsSize; i++) { + SizedIngredient recipeStack = ItemRecipeCapability.CAP.of(itemInputs.get(i).content); + var currentBus = itemInventory.get(i); + if (!(currentBus instanceof NotifiableItemStackHandler itemBus)) throw new RuntimeException( + "Handler in Assline.consumeItemContent's ItemRecipeCapability.IN was not of type NotifiableItemStackHandler"); + List left = itemBus.handleRecipeInner(IO.IN, recipe, new ArrayList<>(List.of(recipeStack)), + true); + if (!(left == null || left.isEmpty())) return ActionResult.FAIL_NO_REASON; + } + // If we get here, the recipe should be consumable + + for (int i = 0; i < inputsSize; i++) { + SizedIngredient recipeStack = ItemRecipeCapability.CAP.of(itemInputs.get(i).content); + var currentBus = itemInventory.get(i); + if (!(currentBus instanceof NotifiableItemStackHandler itemBus)) throw new RuntimeException( + "Handler in Assline.consumeItemContent's ItemRecipeCapability.IN was not of type NotifiableItemStackHandler"); + List left = itemBus.handleRecipeInner(IO.IN, recipe, new ArrayList<>(List.of(recipeStack)), + false); + if (!(left == null || left.isEmpty())) { + GTCEu.LOGGER.error( + "Recipe in Assline.consumeItemContents was true when simulating, but false when consuming."); + return ActionResult.FAIL_NO_REASON; + } + } + + return ActionResult.SUCCESS; + } + + private boolean checkFluidInputs(@NotNull GTRecipe recipe, boolean isTick) { + var fluidInputs = (isTick ? recipe.tickInputs : recipe.inputs).getOrDefault(FluidRecipeCapability.CAP, + Collections.emptyList()); if (fluidInputs.isEmpty()) return true; int inputsSize = fluidInputs.size(); var fluidHandlers = getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP); @@ -107,7 +148,6 @@ private boolean checkFluidInputs(@NotNull GTRecipe recipe) { .map(FluidStack.class::cast) .filter(f -> !f.isEmpty()) .findFirst()) - .dropWhile(Optional::isEmpty) .limit(inputsSize) .map(o -> o.orElse(FluidStack.EMPTY)) .toList(); @@ -123,4 +163,142 @@ private boolean checkFluidInputs(@NotNull GTRecipe recipe) { } return true; } + + private ActionResult consumeFluidContents(@NotNull GTRecipe recipe, boolean isTick) { + var fluidInputs = (isTick ? recipe.tickInputs : recipe.inputs).getOrDefault(FluidRecipeCapability.CAP, + Collections.emptyList()); + if (fluidInputs.isEmpty()) return ActionResult.SUCCESS; + int fluidsSize = fluidInputs.size(); + var fluidHandlers = getCapabilitiesFlat(IO.IN, FluidRecipeCapability.CAP); + if (fluidHandlers.size() < fluidsSize) return ActionResult.FAIL_NO_REASON; + + var fluidInventory = fluidHandlers.stream() + .filter(IRecipeHandler::shouldSearchContent).toList(); + + if (fluidInventory.size() < fluidsSize) return ActionResult.FAIL_NO_REASON; + + for (int i = 0; i < fluidsSize; i++) { + SizedFluidIngredient recipeStack = FluidRecipeCapability.CAP.of(fluidInputs.get(i).content); + var currentBus = fluidInventory.get(i); + if (!(currentBus instanceof NotifiableFluidTank fluidTank)) throw new RuntimeException( + "Handler in Assline.consumeItemContent's FluidRecipeCapability.IN was not of type NotifiableFluidTank"); + List left = fluidTank.handleRecipeInner(IO.IN, recipe, + new ArrayList<>(List.of(recipeStack)), true); + if (!(left == null || left.isEmpty())) return ActionResult.FAIL_NO_REASON; + } + // If we get here, the recipe should be consumable + + for (int i = 0; i < fluidsSize; i++) { + SizedFluidIngredient recipeStack = FluidRecipeCapability.CAP.of(fluidInputs.get(i).content); + var currentBus = fluidInventory.get(i); + if (!(currentBus instanceof NotifiableFluidTank fluidTank)) throw new RuntimeException( + "Handler in Assline.consumeItemContent's FluidRecipeCapability.IN was not of type NotifiableFluidTank"); + List left = fluidTank.handleRecipeInner(IO.IN, recipe, + new ArrayList<>(List.of(recipeStack)), false); + if (!(left == null || left.isEmpty())) { + GTCEu.LOGGER.error( + "Recipe in Assline.consumeFluidContents was true when simulating, but false when consuming."); + return ActionResult.FAIL_NO_REASON; + } + } + + return ActionResult.SUCCESS; + } + + private ActionResult consumeAll(@NotNull GTRecipe recipe, boolean isTick, + Map, Object2IntMap> chanceCaches) { + GTRecipe copyWithItems = recipe.copy(); + copyWithItems.inputs.clear(); + copyWithItems.tickInputs.clear(); + + GTRecipe copyWithFluids = recipe.copy(); + copyWithFluids.inputs.clear(); + copyWithFluids.tickInputs.clear(); + + GTRecipe copyWithoutItemsFluids = recipe.copy(); + copyWithoutItemsFluids.inputs.clear(); + copyWithoutItemsFluids.tickInputs.clear(); + + for (var entry : recipe.inputs.entrySet()) { + if (entry.getKey().equals(FluidRecipeCapability.CAP)) { + copyWithFluids.inputs.put(entry.getKey(), entry.getValue()); + } else if (entry.getKey().equals(ItemRecipeCapability.CAP)) { + copyWithItems.inputs.put(entry.getKey(), entry.getValue()); + } else { + copyWithoutItemsFluids.inputs.put(entry.getKey(), entry.getValue()); + } + } + for (var entry : recipe.tickInputs.entrySet()) { + if (entry.getKey().equals(FluidRecipeCapability.CAP)) { + copyWithFluids.tickInputs.put(entry.getKey(), entry.getValue()); + } else if (entry.getKey().equals(ItemRecipeCapability.CAP)) { + copyWithItems.tickInputs.put(entry.getKey(), entry.getValue()); + } else { + copyWithoutItemsFluids.tickInputs.put(entry.getKey(), entry.getValue()); + } + } + var config = ConfigHolder.INSTANCE.machines; + ActionResult result; + if (config.orderedAssemblyLineItems) { + result = consumeItemContents(copyWithItems, isTick); + } else { + result = isTick ? + RecipeHelper.handleTickRecipeIO(this, copyWithItems, IO.IN, chanceCaches) : + RecipeHelper.handleRecipeIO(this, copyWithItems, IO.IN, chanceCaches); + } + if (!result.isSuccess()) return result; + + if (config.orderedAssemblyLineFluids) { + result = consumeFluidContents(copyWithFluids, isTick); + } else { + result = isTick ? + RecipeHelper.handleTickRecipeIO(this, copyWithFluids, IO.IN, chanceCaches) : + RecipeHelper.handleRecipeIO(this, copyWithFluids, IO.IN, chanceCaches); + } + if (!result.isSuccess()) return result; + + return isTick ? + RecipeHelper.handleTickRecipeIO(this, copyWithoutItemsFluids, IO.IN, chanceCaches) : + RecipeHelper.handleRecipeIO(this, copyWithoutItemsFluids, IO.IN, chanceCaches); + } + + class AsslineRecipeLogic extends RecipeLogic { + + public AsslineRecipeLogic(IRecipeLogicMachine machine) { + super(machine); + } + + @Override + protected ActionResult handleRecipeIO(GTRecipe recipe, IO io) { + if (io.equals(IO.IN)) { + return consumeAll(recipe, false, this.getChanceCaches()); + } + return RecipeHelper.handleRecipeIO(machine, recipe, io, this.chanceCaches); + } + + @Override + protected ActionResult handleTickRecipeIO(GTRecipe recipe, IO io) { + if (io.equals(IO.IN)) { + return consumeAll(recipe, true, this.getChanceCaches()); + } + return RecipeHelper.handleTickRecipeIO(machine, recipe, io, this.chanceCaches); + } + + @Override + protected ActionResult matchRecipe(GTRecipe recipe) { + // Match by normal inputs first + ActionResult normalMatch = RecipeHelper.matchContents(machine, recipe); + if (!normalMatch.isSuccess()) return normalMatch; + + var config = ConfigHolder.INSTANCE.machines; + if (!config.orderedAssemblyLineItems && !config.orderedAssemblyLineFluids) return ActionResult.SUCCESS; + if (!checkItemInputs(recipe, false)) return ActionResult.FAIL_NO_REASON; + if (!checkItemInputs(recipe, true)) return ActionResult.FAIL_NO_REASON; + + if (!config.orderedAssemblyLineFluids) return ActionResult.SUCCESS; + if (!checkFluidInputs(recipe, false)) return ActionResult.FAIL_NO_REASON; + if (!checkFluidInputs(recipe, true)) return ActionResult.FAIL_NO_REASON; + return ActionResult.SUCCESS; + } + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CentralMonitorMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CentralMonitorMachine.java new file mode 100644 index 00000000000..0cda5314588 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/CentralMonitorMachine.java @@ -0,0 +1,691 @@ +package com.gregtechceu.gtceu.common.machine.multiblock.electric; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; +import com.gregtechceu.gtceu.api.capability.ICentralMonitor; +import com.gregtechceu.gtceu.api.capability.IMonitorComponent; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.api.gui.GuiTextures; +import com.gregtechceu.gtceu.api.gui.widget.IntInputWidget; +import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; +import com.gregtechceu.gtceu.api.item.IComponentItem; +import com.gregtechceu.gtceu.api.item.component.IItemComponent; +import com.gregtechceu.gtceu.api.item.component.IMonitorModuleItem; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.feature.IDataInfoProvider; +import com.gregtechceu.gtceu.api.machine.feature.IMachineLife; +import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockDisplayText; +import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.misc.EnergyContainerList; +import com.gregtechceu.gtceu.api.multiblock.*; +import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; +import com.gregtechceu.gtceu.common.item.behavior.PortableScannerBehavior; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; +import com.gregtechceu.gtceu.common.machine.trait.CentralMonitorLogic; +import com.gregtechceu.gtceu.common.network.GTNetwork; +import com.gregtechceu.gtceu.common.network.packets.SCPacketMonitorGroupNBTChange; +import com.gregtechceu.gtceu.data.block.GTBlocks; +import com.gregtechceu.gtceu.data.datagen.lang.LangHandler; +import com.gregtechceu.gtceu.data.machine.GTMachines; +import com.gregtechceu.gtceu.utils.GTStringUtils; +import com.gregtechceu.gtceu.utils.GTUtil; + +import com.lowdragmc.lowdraglib.gui.texture.*; +import com.lowdragmc.lowdraglib.gui.widget.*; +import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; +import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; +import com.lowdragmc.lowdraglib.syncdata.annotation.RequireRerender; +import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; + +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.util.Mth; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.neoforged.neoforge.items.IItemHandler; + +import lombok.Getter; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.util.*; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Stream; + +import javax.annotation.ParametersAreNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class CentralMonitorMachine extends WorkableElectricMultiblockMachine + implements IMonitorComponent, IDataInfoProvider, IMachineLife, ICentralMonitor { + + public static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(CentralMonitorMachine.class, + WorkableMultiblockMachine.MANAGED_FIELD_HOLDER); + + @Persisted + @DescSynced + @Getter + private int leftDist = 0, rightDist = 0, upDist = 0, downDist = 0; + @Persisted + @DescSynced + @Getter + @RequireRerender + private final List monitorGroups = new ArrayList<>(); + private final Set selectedComponents = new HashSet<>(); + private final List selectedTargets = new ArrayList<>(); + + private MultiblockState patternFindingState; + + private static TraceabilityPredicate MULTI_PREDICATE = null; + + public CentralMonitorMachine(IMachineBlockEntity holder) { + super(holder); + } + + public static TraceabilityPredicate getMultiPredicate() { + if (MULTI_PREDICATE == null) { + MULTI_PREDICATE = Predicates.abilities(PartAbility.INPUT_ENERGY) + .setMinGlobalLimited(1).setMaxGlobalLimited(2).setPreviewCount(1) + .or(Predicates.abilities(PartAbility.DATA_ACCESS).setPreviewCount(1) + .or(Predicates.machines(GTMachines.BATTERY_BUFFER_4).setPreviewCount(0)) + .or(Predicates.machines(GTMachines.BATTERY_BUFFER_16).setPreviewCount(0)) + .setMaxGlobalLimited(4)) + .or(Predicates.machines(GTMachines.HULL)) + .or(Predicates.machines(GTMachines.MONITOR)) + .or(Predicates.machines(GTMachines.ADVANCED_MONITOR)) + .or(Predicates.blocks(GTBlocks.CASING_ALUMINIUM_FROSTPROOF.get())); + } + return MULTI_PREDICATE; + } + + @Override + public ManagedFieldHolder getFieldHolder() { + return MANAGED_FIELD_HOLDER; + } + + @Override + public void onStructureInvalid() { + super.onStructureInvalid(); + this.clearPatternFindingState(); + } + + @Override + public CentralMonitorLogic getRecipeLogic() { + return (CentralMonitorLogic) super.getRecipeLogic(); + } + + @Override + protected RecipeLogic createRecipeLogic(Object... args) { + return new CentralMonitorLogic(this); + } + + public @Nullable EnergyContainerList getFormedEnergyContainer() { + return this.energyContainer; + } + + public void tick() { + Level level = getLevel(); + if (level == null) { + return; + } + + for (MonitorGroup group : monitorGroups) { + ItemStack stack = group.getItemStackHandler().getStackInSlot(0); + if (stack.isEmpty() || !(stack.getItem() instanceof IComponentItem componentItem)) { + continue; + } + + for (IItemComponent component : componentItem.getComponents()) { + if (!(component instanceof IMonitorModuleItem module)) { + continue; + } + module.tick(stack, this, group); + GTNetwork.sendToAllPlayersTrackingChunk(level.getChunkAt(getPos()), + new SCPacketMonitorGroupNBTChange(stack, group, this)); + } + } + } + + @Override + public void onUnload() { + super.onUnload(); + this.clearPatternFindingState(); + } + + protected void clearPatternFindingState() { + if (this.patternFindingState != null) + this.patternFindingState.clean(); + this.patternFindingState = null; + } + + protected MultiblockState getPatternFindingState() { + if (this.patternFindingState == null) { + this.patternFindingState = new MultiblockState(getLevel(), getPos()); + this.patternFindingState.clean(); + } + return this.patternFindingState; + } + + public boolean isValidMonitorBlock(Level level, BlockPos pos) { + if (level.isOutsideBuildHeight(pos)) return false; + + MultiblockState state = getPatternFindingState(); + if (!state.update(pos, getMultiPredicate())) { + return false; + } + state.io = IO.BOTH; + + return Stream.concat(state.predicate.common.stream(), state.predicate.limited.stream()) + .anyMatch(predicate -> predicate.test(state)); + } + + public void updateStructureDimensions() { + Level level = getLevel(); + if (level == null) return; + + Direction front = getFrontFacing(); + Direction spin = getUpwardsFacing(); + + Direction left = RelativeDirection.LEFT.getRelative(front, spin, false); + Direction right = RelativeDirection.RIGHT.getRelative(front, spin, false); + Direction up = RelativeDirection.UP.getRelative(front, spin, false); + Direction down = RelativeDirection.DOWN.getRelative(front, spin, false); + BlockPos.MutableBlockPos posLeft = getPos().mutable().move(left); + BlockPos.MutableBlockPos posRight = getPos().mutable().move(right); + BlockPos.MutableBlockPos posUp = getPos().mutable().move(up); + BlockPos.MutableBlockPos posDown = getPos().mutable().move(down); + this.leftDist = 0; + this.rightDist = 0; + this.upDist = 0; + this.downDist = 0; + + while (isValidMonitorBlock(level, posLeft)) { + posLeft.move(left); + leftDist++; + } + while (isValidMonitorBlock(level, posRight)) { + posRight.move(right); + rightDist++; + } + while (isValidMonitorBlockRow(level, posUp, leftDist, rightDist, left, right)) { + posUp.move(up); + upDist++; + } + while (isValidMonitorBlockRow(level, posDown, leftDist, rightDist, left, right)) { + posDown.move(down); + downDist++; + } + } + + private boolean isValidMonitorBlockRow(Level level, BlockPos pos, int leftDist, int rightDist, Direction left, + Direction right) { + BlockPos.MutableBlockPos mutable = pos.mutable(); + mutable.move(left, leftDist); + for (int i = 0; i < leftDist + rightDist; i++) { + if (!isValidMonitorBlock(level, mutable)) return false; + mutable.move(right); + } + return isValidMonitorBlock(level, mutable); + } + + @Override + public BlockPattern getPattern() { + updateStructureDimensions(); + if (leftDist + rightDist < 1 || upDist + downDist < 1) { + leftDist = 3; + rightDist = 0; + upDist = 1; + downDist = 1; + } + + StringBuilder[] pattern = new StringBuilder[upDist + downDist + 1]; + for (int i = 0; i < upDist + downDist + 1; i++) { + pattern[i] = new StringBuilder(leftDist + rightDist + 1); + for (int j = 0; j < leftDist + rightDist + 1; j++) { + if (i == downDist && j == rightDist) + pattern[i].append('C'); // controller + else + pattern[i].append('B'); // any valid block + } + } + + String[] aisle = new String[upDist + downDist + 1]; + for (int i = 0; i < upDist + downDist + 1; i++) { + aisle[i] = pattern[i].toString(); + } + + return FactoryBlockPattern.start() + .aisle(aisle) + .where('B', getMultiPredicate()) + .where('C', Predicates.controller(Predicates.blocks(this.getDefinition().get()))) + .build(); + } + + public BlockPos toRelative(BlockPos pos) { + Direction front = getFrontFacing(); + Direction spin = getUpwardsFacing(); + boolean flipped = isFlipped(); + Direction right = RelativeDirection.RIGHT.getRelative(front, spin, flipped); + Direction up = RelativeDirection.UP.getRelative(front, spin, flipped); + + BlockPos tmp = getPos().mutable().move(right, rightDist).move(up, upDist); + + return new BlockPos(Math.abs(tmp.get(right.getAxis()) - pos.get(right.getAxis())), + Math.abs(tmp.get(up.getAxis()) - pos.get(up.getAxis())), + 0); + } + + @Nullable + public IMonitorComponent getComponent(int row, int col) { + Level level = getLevel(); + if (level == null) return null; + + Direction front = getFrontFacing(); + Direction spin = getUpwardsFacing(); + boolean flipped = isFlipped(); + + Direction left = RelativeDirection.LEFT.getRelative(front, spin, flipped); + Direction up = RelativeDirection.UP.getRelative(front, spin, flipped); + + col = leftDist + rightDist - col; + BlockPos pos = getPos().relative(left, leftDist - col).relative(up, upDist - row); + + return GTCapabilityHelper.getMonitorComponent(level, pos, null); + } + + public boolean isMonitor(int row, int col) { + IMonitorComponent component = this.getComponent(row, col); + if (component == null) return false; + return component.isMonitor(); + } + + private IGuiTexture getComponentTexture(int row, int col) { + if (row < 0 || col < 0 || row > downDist + upDist + 1 || col > leftDist + rightDist + 1) + return GuiTextures.BLANK_TRANSPARENT; + IMonitorComponent component = getComponent(row, col); + if (component == null) return GuiTextures.BLANK_TRANSPARENT; + return component.getComponentIcon(); + } + + private boolean isInAnyGroup(IMonitorComponent component) { + return monitorGroups.stream().anyMatch(group -> group.contains(component.getPos())); + } + + @Override + public void addDisplayText(List textList) { + MultiblockDisplayText.builder(textList, isFormed()) + .addWorkingStatusLine(); + getDefinition().getAdditionalDisplay().accept(this, textList); + } + + @Override + public Widget createUIWidget() { + updateStructureDimensions(); + selectedComponents.clear(); + WidgetGroup builder = (WidgetGroup) super.createUIWidget(); + + WidgetGroup main = new WidgetGroup(); + DraggableScrollableWidgetGroup componentSelection = new DraggableScrollableWidgetGroup(0, 10, 200, 110); + main.addWidget(componentSelection); + WidgetGroup options = new WidgetGroup(-100, 20, 60, 20); + WidgetGroup groupConfig = new WidgetGroup(10, 30, 100, 100); + groupConfig.setVisible(false); + + ButtonWidget infoWidget = new ButtonWidget(200, 10, 20, 20, null); + infoWidget.setButtonTexture(GuiTextures.INFO_ICON); + infoWidget.setHoverTooltips( + GTStringUtils.toImmutable(LangHandler.getSingleOrMultiLang("gtceu.central_monitor.info_tooltip"))); + builder.addWidget(infoWidget); + List configGroup = new ArrayList<>(); + configGroup.add(null); + + Consumer openGroupConfig = (group) -> { + configGroup.set(0, group); + if (group == null) { + main.setVisible(true); + groupConfig.setVisible(false); + return; + } + groupConfig.clearAllWidgets(); + groupConfig.addWidget(new LabelWidget(0, 5, () -> { + String currentName = ""; + if (configGroup.get(0) != null) { + currentName = configGroup.get(0).getName(); + } + return Component.translatable("gtceu.central_monitor.gui.currently_editing", currentName).getString(); + })); + for (int i = 0; i < 8; i++) { + SlotWidget slot = new SlotWidget(group.getPlaceholderSlotsHandler(), i, -38, 16 * i + 46); + slot.setHoverTooltips(GTStringUtils + .toImmutable(LangHandler.getMultiLang("gtceu.gui.computer_monitor_cover.slot_tooltip", i + 1))); + groupConfig.addWidget(slot); + } + SlotWidget slot = new SlotWidget( + group.getItemStackHandler(), 0, + 0, 20); + WidgetGroup itemUI = new WidgetGroup(40, 20, 100, 100); + Runnable changeListener = () -> { + if (slot.getLastItem().is(slot.getItem().getItem())) return; + itemUI.clearAllWidgets(); + if (slot.getItem().getItem() instanceof IComponentItem item) { + for (IItemComponent component : item.getComponents()) { + if (component instanceof IMonitorModuleItem module) { + itemUI.addWidget(module.createUIWidget(slot.getItem(), this, group)); + } + } + } + }; + slot.setChangeListener(changeListener); + changeListener.run(); + groupConfig.addWidget(itemUI); + groupConfig.addWidget(slot); + main.setVisible(false); + groupConfig.setVisible(true); + }; + builder.addWidget(groupConfig); + DraggableScrollableWidgetGroup groupList = new DraggableScrollableWidgetGroup(-100, 50, 70, 80); + + List>>> imageButtons = new ArrayList<>(); + Map rightClickCallbacks = new HashMap<>(); + int[] dataSlot = new int[2]; // list to be able to modify it in lambdas + dataSlot[0] = 1; // the slot (index starts from 1) + dataSlot[1] = 9; // amount of slots + IntInputWidget dataSlotInput = new IntInputWidget(120, 20, 60, -20, () -> dataSlot[0], + n -> dataSlot[0] = Mth.clamp(n, 1, dataSlot[1])); + dataSlotInput.setVisible(false); + builder.addWidget(dataSlotInput); + + Consumer addGroupToList = group -> { + ButtonWidget label = new ButtonWidget(20, groupList.widgets.size() * 15 + 5, 60, 10, null); + TextTexture text = new TextTexture(group.getName()); + text.setType(TextTexture.TextType.LEFT); + label.setButtonTexture(text); + label.setOnPressCallback(click -> { + group.getRelativePositions().forEach(pos -> { + BlockPos rel = toRelative(pos); + if (imageButtons.size() - 1 < rel.getY()) return; + if (imageButtons.get(rel.getY()).size() - 1 < rel.getX()) return; + imageButtons.get(rel.getY()).get(rel.getX()).accept(null); + }); + if (group.getTargetRaw() != null) { + rightClickCallbacks.getOrDefault(group.getTargetRaw(), () -> {}).run(); + } + }); + groupList.addWidget(label); + + ButtonWidget configButton = new ButtonWidget( + 0, label.getSelfPositionY() - 3, + 16, 16, + GuiTextures.IO_CONFIG_COVER_SETTINGS, + click -> { + if (configGroup.get(0) == null) { + openGroupConfig.accept(group); + } else { + openGroupConfig.accept(null); + } + }); + groupList.addWidget(configButton); + }; + + monitorGroups.forEach(addGroupToList); + builder.addWidget(groupList); + main.addWidget(options); + ButtonWidget removeFromGroupButton = new ButtonWidget(0, 0, 60, 20, null); + removeFromGroupButton.setButtonTexture(new TextTexture("gtceu.central_monitor.gui.remove_from_group")); + removeFromGroupButton.setVisible(false); + ButtonWidget setTargetButton = new ButtonWidget(0, 15, 60, 20, null); + setTargetButton.setButtonTexture(new TextTexture("gtceu.central_monitor.gui.set_target")); + setTargetButton.setVisible(false); + ButtonWidget createGroupButton = new ButtonWidget(0, 0, 60, 20, null); + createGroupButton.setOnPressCallback(click -> { + MonitorGroup group = new MonitorGroup( + Component.translatable("gtceu.gui.central_monitor.group_default_name", monitorGroups.size() + 1) + .getString()); + for (IMonitorComponent component : selectedComponents) { + if (isInAnyGroup(component)) return; + group.add(component.getPos()); + } + monitorGroups.add(group); + addGroupToList.accept(group); + + createGroupButton.setVisible(false); + removeFromGroupButton.setVisible(true); + Iterator it = selectedComponents.iterator(); + while (it.hasNext()) { + IMonitorComponent c = it.next(); + BlockPos rel = toRelative(c.getPos()); + imageButtons.get(rel.getY()).get(rel.getX()).accept(it); + } + if (!selectedTargets.isEmpty()) { + rightClickCallbacks.getOrDefault(selectedTargets.get(0).getPos(), () -> {}).run(); + } + }); + setTargetButton.setOnPressCallback(click -> { + MonitorGroup group = null; + for (MonitorGroup group2 : monitorGroups) { + for (IMonitorComponent component : selectedComponents) { + if (group2.contains(component.getPos())) { + group = group2; + break; + } + } + if (group != null) break; + } + if (group == null) return; + if (selectedTargets.isEmpty()) group.setTarget(null); + else { + group.setTarget(selectedTargets.get(0).getPos()); + group.setDataSlot(dataSlot[0] - 1); + } + }); + removeFromGroupButton.setOnPressCallback(click -> { + for (MonitorGroup group : monitorGroups) { + for (IMonitorComponent component : selectedComponents) group.remove(component.getPos()); + } + Iterator itg = monitorGroups.iterator(); + while (itg.hasNext()) { + MonitorGroup group = itg.next(); + if (group.isEmpty()) { + clearInventory(group.getItemStackHandler()); + clearInventory(group.getPlaceholderSlotsHandler()); + itg.remove(); + } + } + groupList.clearAllWidgets(); + monitorGroups.forEach(addGroupToList); + + removeFromGroupButton.setVisible(false); + createGroupButton.setVisible(true); + Iterator it = selectedComponents.iterator(); + while (it.hasNext()) { + IMonitorComponent c = it.next(); + BlockPos rel = toRelative(c.getPos()); + if (imageButtons.size() - 1 < rel.getY()) continue; + if (imageButtons.get(rel.getY()).size() - 1 < rel.getX()) continue; + imageButtons.get(rel.getY()).get(rel.getX()).accept(it); + } + if (!selectedTargets.isEmpty()) { + rightClickCallbacks.getOrDefault(selectedTargets.get(0).getPos(), () -> {}).run(); + } + }); + createGroupButton.setButtonTexture(new TextTexture("gtceu.central_monitor.gui.create_group")); + createGroupButton.setVisible(false); + options.addWidget(removeFromGroupButton); + options.addWidget(createGroupButton); + options.addWidget(setTargetButton); + int startX = 20; + int startY = 30; + for (int row = 0; row <= downDist + upDist; row++) { + imageButtons.add(new ArrayList<>()); + for (int col = 0; col <= leftDist + rightDist; col++) { + IGuiTexture texture = getComponentTexture(row, col); + GuiTextureGroup textures = new GuiTextureGroup(texture, new ColorBorderTexture(2, 0xFFFFFF)); + IMonitorComponent component = getComponent(row, col); + if (component == null) { + GTUtil.getLast(imageButtons).add(it -> {}); + continue; + } + ButtonWidget img = new ButtonWidget(startX + (16 * col), startY + (16 * row), 16, 16, textures, null); + Consumer> callback = (it) -> { + if (!component.isMonitor()) return; + if (selectedComponents.contains(component)) { + if (it == null) { + selectedComponents.remove(component); + } else { + it.remove(); + } + + if (!selectedTargets.isEmpty() && selectedTargets.get(0) == component) { + ColorRectTexture rect = new ColorRectTexture(Color.BLUE); + textures.setTextures(rect, texture); + } else { + textures.setTextures(texture); + } + + createGroupButton.setVisible(selectedComponents.stream().noneMatch(this::isInAnyGroup)); + removeFromGroupButton.setVisible(selectedComponents.stream().allMatch(this::isInAnyGroup)); + setTargetButton.setVisible(removeFromGroupButton.isVisible()); + + if (selectedComponents.isEmpty()) { + createGroupButton.setVisible(false); + removeFromGroupButton.setVisible(false); + setTargetButton.setVisible(false); + } + } else { + boolean inAnyGroup = isInAnyGroup(component); + // yes I know this is terrible but if it works don't touch it :) + if (selectedComponents.isEmpty() && !inAnyGroup) createGroupButton.setVisible(true); + if (inAnyGroup) createGroupButton.setVisible(false); + if (selectedComponents.isEmpty() && inAnyGroup) { + removeFromGroupButton.setVisible(true); + setTargetButton.setVisible(true); + } + if (!inAnyGroup) { + removeFromGroupButton.setVisible(false); + setTargetButton.setVisible(false); + } + selectedComponents.add(component); + ColorRectTexture rect = new ColorRectTexture( + (selectedTargets.isEmpty() || selectedTargets.get(0) != component) ? Color.RED : + Color.PINK); + textures.setTextures(rect, texture); + } + if (isInAnyGroup(component)) { + monitorGroups.forEach(group -> { + if (group.contains(component.getPos())) { + img.setHoverTooltips( + Component.translatable("gtceu.gui.central_monitor.group", group.getName())); + } + }); + } else { + img.setHoverTooltips(Component.translatable("gtceu.gui.central_monitor.group", + Component.translatable("gtceu.gui.central_monitor.none"))); + } + }; + Runnable rightClickCallback = () -> { + if (!selectedTargets.isEmpty()) { + if (selectedTargets.get(0).getPos() == component.getPos()) { + selectedTargets.clear(); + if (selectedComponents.contains(component)) { + ColorRectTexture rect = new ColorRectTexture(Color.RED); + textures.setTextures(rect, texture); + } else { + textures.setTextures(texture); + } + dataSlotInput.setVisible(false); + return; + } else { + try { + rightClickCallbacks.get(selectedTargets.get(0).getPos()).run(); + } catch (StackOverflowError e) { + GTCEu.LOGGER.error( + "Stack overflow when right-clicking monitor component {} at {} (selectedTarget is {} at {})", + component, component.getPos(), selectedTargets.get(0), + selectedTargets.get(0).getPos()); + } + } + } + selectedTargets.add(component); + ColorRectTexture rect; + if (selectedComponents.contains(component)) { + rect = new ColorRectTexture(Color.PINK); + } else { + rect = new ColorRectTexture(Color.BLUE); + } + textures.setTextures(rect, texture); + if (component.getDataItems() != null) { + IItemHandler dataItems = component.getDataItems(); + MonitorGroup selectedGroup = null; + for (MonitorGroup group : monitorGroups) { + for (IMonitorComponent c : selectedComponents) { + if (group.contains(c.getPos())) { + if (selectedGroup == null || selectedGroup == group) { + selectedGroup = group; + } else { + selectedGroup = null; + break; + } + } + } + } + if (selectedGroup != null) { + dataSlot[0] = selectedGroup.getDataSlot() + 1; + } + dataSlot[1] = dataItems.getSlots(); + dataSlotInput.setVisible(true); + } + }; + if (isInAnyGroup(component)) { + monitorGroups.forEach(group -> { + if (group.contains(component.getPos())) img.setHoverTooltips( + Component.translatable("gtceu.gui.central_monitor.group", group.getName())); + }); + } else { + img.setHoverTooltips(Component.translatable("gtceu.gui.central_monitor.group", + Component.translatable("gtceu.gui.central_monitor.none"))); + } + img.setOnPressCallback(click -> { + if (click.button == 0) callback.accept(null); + else if (click.button == 1) rightClickCallback.run(); + }); + componentSelection.addWidget(img); + GTUtil.getLast(imageButtons).add(callback); + rightClickCallbacks.put(component.getPos(), rightClickCallback); + } + } + builder.addWidget(main); + return builder; + } + + @Override + public IGuiTexture getComponentIcon() { + return ResourceTexture.fromSpirit(GTCEu.id("block/multiblock/network_switch/overlay_front_active")); + } + + @Override + public @NotNull List getDebugInfo(Player player, int logLevel, + PortableScannerBehavior.DisplayMode mode) { + return List.of(Component.translatable("gtceu.central_monitor.size", leftDist, rightDist, upDist, downDist)); + } + + @Override + public @NotNull List getDataInfo(PortableScannerBehavior.DisplayMode mode) { + return List.of(Component.translatable("gtceu.central_monitor.size", leftDist, rightDist, upDist, downDist)); + } + + @Override + public void onMachineRemoved() { + for (MonitorGroup group : monitorGroups) { + clearInventory(group.getItemStackHandler()); + clearInventory(group.getPlaceholderSlotsHandler()); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java index 13ddaab502e..f6aac622673 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/DistillationTowerMachine.java @@ -146,7 +146,7 @@ public int limitFluidParallel(GTRecipe recipe, int multiplier, boolean tick) { while (minMultiplier != maxMultiplier) { GTRecipe copy = modifyOutputs(recipe, ContentModifier.multiplier(multiplier)); - boolean filled = getRecipeLogic().applyFluidOutputs(copy, FluidAction.SIMULATE); + boolean filled = getRecipeLogic().applyFluidOutputs(copy, FluidAction.SIMULATE, getVoidingMode()); int[] bin = ParallelLogic.adjustMultiplier(filled, minMultiplier, multiplier, maxMultiplier); minMultiplier = bin[0]; multiplier = bin[1]; @@ -213,11 +213,10 @@ private ActionResult matchDTRecipe(GTRecipe recipe) { if (!result.isSuccess()) return result; } - if (!applyFluidOutputs(recipe, FluidAction.SIMULATE)) { - return ActionResult - .fail(Component.translatable("gtceu.recipe_logic.insufficient_out") - .append(": ") - .append(FluidRecipeCapability.CAP.getName())); + if (!applyFluidOutputs(recipe, FluidAction.SIMULATE, machine.getVoidingMode())) { + return ActionResult.fail(Component.translatable("gtceu.recipe_logic.insufficient_out") + .append(": ") + .append(FluidRecipeCapability.CAP.getName()), FluidRecipeCapability.CAP, IO.OUT); } return ActionResult.SUCCESS; @@ -257,17 +256,17 @@ protected ActionResult handleRecipeIO(GTRecipe recipe, IO io) { RecipeHelper.handleRecipe(this.machine, recipe, io, out, chanceCaches, false, false); } - if (applyFluidOutputs(recipe, FluidAction.EXECUTE)) { + if (applyFluidOutputs(recipe, FluidAction.EXECUTE, this.machine.getVoidingMode())) { workingRecipe = null; return ActionResult.SUCCESS; } return ActionResult.fail(Component.translatable("gtceu.recipe_logic.insufficient_out") .append(": ") - .append(FluidRecipeCapability.CAP.getName())); + .append(FluidRecipeCapability.CAP.getName()), FluidRecipeCapability.CAP, IO.OUT); } - private boolean applyFluidOutputs(GTRecipe recipe, FluidAction action) { + private boolean applyFluidOutputs(GTRecipe recipe, FluidAction action, VoidingMode voidMode) { var fluids = recipe.getOutputContents(FluidRecipeCapability.CAP) .stream() .map(Content::getContent) @@ -293,7 +292,7 @@ private boolean applyFluidOutputs(GTRecipe recipe, FluidAction action) { int filled = (handler instanceof NotifiableFluidTank nft) ? nft.fillInternal(fluid, action) : handler.fill(fluid, action); - if (filled != fluid.getAmount()) valid = false; + if (filled != fluid.getAmount() && !voidMode.canVoid(FluidRecipeCapability.CAP)) valid = false; if (action.simulate() && !valid) break; } return valid; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/monitor/MonitorGroup.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/monitor/MonitorGroup.java new file mode 100644 index 00000000000..467e105eda8 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/monitor/MonitorGroup.java @@ -0,0 +1,136 @@ +package com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor; + +import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; +import com.gregtechceu.gtceu.api.capability.ICoverable; +import com.gregtechceu.gtceu.api.capability.IMonitorComponent; +import com.gregtechceu.gtceu.api.cover.CoverBehavior; +import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; +import com.gregtechceu.gtceu.data.item.GTDataComponents; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.Vec3i; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; + +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; +import lombok.Getter; +import lombok.Setter; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.function.UnaryOperator; + +public class MonitorGroup { + + private final Set monitorPositions = new HashSet<>(); + @Getter + private final String name; + @Getter + private final CustomItemStackHandler itemStackHandler; + @Getter + private final CustomItemStackHandler placeholderSlotsHandler; + @Setter + private @Nullable BlockPos target; + @Setter + @Getter + private @Nullable Direction targetCoverSide; + @Setter + @Getter + private int dataSlot = 0; + + public MonitorGroup(String name) { + this(name, new CustomItemStackHandler(1), new CustomItemStackHandler(8)); + } + + public MonitorGroup(String name, CustomItemStackHandler handler, CustomItemStackHandler placeholderSlotsHandler) { + this.name = name; + this.itemStackHandler = handler; + this.placeholderSlotsHandler = placeholderSlotsHandler; + } + + public void add(BlockPos pos) { + monitorPositions.add(pos); + } + + public void remove(BlockPos pos) { + monitorPositions.remove(pos); + } + + public List getRow(int row, UnaryOperator toRelative) throws IndexOutOfBoundsException { + IntSet yLevelsSet = new IntOpenHashSet(); + for (BlockPos pos : monitorPositions) { + yLevelsSet.add(toRelative.apply(pos).getY()); + } + if (row < 0) row += yLevelsSet.size(); + int y = yLevelsSet.intStream().sorted().toArray()[row]; + List rowPositions = new ArrayList<>(); + for (BlockPos pos : monitorPositions) { + if (toRelative.apply(pos).getY() == y) { + rowPositions.add(toRelative.apply(pos)); + } + } + rowPositions.sort(Comparator.comparingInt(Vec3i::getX)); + return rowPositions; + } + + public boolean contains(BlockPos pos) { + return monitorPositions.contains(pos); + } + + public boolean isEmpty() { + return monitorPositions.isEmpty(); + } + + public Set getRelativePositions() { + return monitorPositions; + } + + public @Nullable CoverBehavior getTargetCover(Level level) { + if (getTarget(level) != null && targetCoverSide != null) { + ICoverable coverable = GTCapabilityHelper.getCoverable(level, getTarget(level), targetCoverSide); + if (coverable != null) return coverable.getCoverAtSide(targetCoverSide); + } + return null; + } + + public @Nullable BlockPos getTargetRaw() { + return target; + } + + public @Nullable BlockPos getTarget(Level level) { + if (target == null) return null; + + IMonitorComponent component = GTCapabilityHelper.getMonitorComponent(level, target, null); + if (component != null && component.getDataItems() != null) { + ItemStack stack = component.getDataItems().getStackInSlot(dataSlot); + BlockPos pos = stack.getOrDefault(GTDataComponents.MONITOR_TARGET, null); + if (pos == null) { + return null; + } + Direction face = stack.getOrDefault(GTDataComponents.MONITOR_TARGET_FACE, null); + if (face == null) { + return null; + } + setTargetCoverSide(face); + return pos; + } + return target; + } + + public Level getTargetLevel(Level level) { + if (target == null) return level; + + IMonitorComponent component = GTCapabilityHelper.getMonitorComponent(level, target, null); + if (component != null && component.getDataItems() != null) { + ItemStack stack = component.getDataItems().getStackInSlot(dataSlot); + var dim = stack.getOrDefault(GTDataComponents.MONITOR_TARGET_DIMENSION, null); + if (dim == null) return level; + if (level.getServer() == null) return level; + return level.getServer() + .getLevel(dim); + } + return level; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java index 6683a1f97ab..c44bfee0176 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/DataBankMachine.java @@ -157,8 +157,9 @@ public void tick() { if (consumed == energyToConsume) { getRecipeLogic().setStatus(RecipeLogic.Status.WORKING); } else { - getRecipeLogic().setWaiting(Component.translatable("gtceu.recipe_logic.insufficient_in") - .append(": ").append(EURecipeCapability.CAP.getName())); + getRecipeLogic() + .setWaiting(Component.translatable("gtceu.recipe_logic.insufficient_in") + .append(": ").append(EURecipeCapability.CAP.getName())); } } } else { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java index 12545b4cff0..f19b1bb2498 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/HPCAMachine.java @@ -20,7 +20,6 @@ import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; import com.gregtechceu.gtceu.api.transfer.fluid.FluidHandlerList; import com.gregtechceu.gtceu.config.ConfigHolder; -import com.gregtechceu.gtceu.data.material.GTMaterials; import com.gregtechceu.gtceu.utils.FormattingUtil; import com.gregtechceu.gtceu.utils.GTTransferUtils; import com.gregtechceu.gtceu.utils.GTUtil; @@ -38,15 +37,16 @@ import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; import net.minecraft.ChatFormatting; +import net.minecraft.MethodsReturnNonnullByDefault; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; import net.minecraft.server.TickTask; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.material.Fluid; import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.capability.IFluidHandler; @@ -61,6 +61,12 @@ import java.util.*; import java.util.function.Supplier; +import javax.annotation.ParametersAreNonnullByDefault; + +import static com.gregtechceu.gtceu.data.tag.CustomTags.HPCA_COOLANTS; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault public class HPCAMachine extends WorkableElectricMultiblockMachine implements IOpticalComputationProvider, IControllable { @@ -159,6 +165,7 @@ protected void updateTickSubscription() { @Override public void onStructureInvalid() { + this.updateActive(false); super.onStructureInvalid(); this.energyContainer = new EnergyContainerList(new ArrayList<>()); this.hpcaHandler.onStructureInvalidate(); @@ -204,6 +211,15 @@ public void tick() { // passively cool (slowly) if not active temperature = Math.max(IDLE_TEMPERATURE, temperature - 0.25); } + this.updateActive(this.getEnergyContainer().getEnergyStored() > 0); + } + + private void updateActive(boolean active) { + for (var part : getParts()) { + if (part instanceof IHPCAComponentHatch hpcaPart) { + hpcaPart.setActive(active); + } + } } private void consumeEnergy() { @@ -473,52 +489,46 @@ public double calculateTemperatureChange(IFluidHandler coolantTank, boolean forc } if (forceCoolWithActive || maxActiveCooling <= temperatureChange) { // try to fully utilize active coolers - FluidStack coolantStack = GTTransferUtils.drainFluidAccountNotifiableList(coolantTank, - getCoolantStack(maxCoolantDrain), IFluidHandler.FluidAction.EXECUTE); - if (!coolantStack.isEmpty()) { - long coolantDrained = coolantStack.getAmount(); - if (coolantDrained == maxCoolantDrain) { - // coolant requirement was fully met - temperatureChange -= maxActiveCooling; - } else { - // coolant requirement was only partially met, cool proportional to fluid amount drained - // a * (b / c) - temperatureChange -= maxActiveCooling * (1.0 * coolantDrained / maxCoolantDrain); - } + int remainingCoolant = maxCoolantDrain; + for (var fluid : BuiltInRegistries.FLUID.getTagOrEmpty(HPCA_COOLANTS)) { + FluidStack drained = GTTransferUtils.drainFluidAccountNotifiableList(coolantTank, + new FluidStack(fluid, remainingCoolant), IFluidHandler.FluidAction.EXECUTE); + remainingCoolant -= drained.getAmount(); + if (remainingCoolant <= 0) break; + } + if (remainingCoolant <= 0) { + // coolant requirement was fully met + temperatureChange -= maxActiveCooling; + } else { + // coolant requirement was only partially met, cool proportional to fluid amount drained + // a * (b / c) + int coolantDrained = maxCoolantDrain - remainingCoolant; + temperatureChange -= maxActiveCooling * (1.0 * coolantDrained / maxCoolantDrain); } } else if (temperatureChange > 0) { // try to partially utilize active coolers to stabilize to zero double temperatureToDecrease = Math.min(temperatureChange, maxActiveCooling); int coolantToDrain = Math.max(1, (int) (maxCoolantDrain * (temperatureToDecrease / maxActiveCooling))); - FluidStack coolantStack = GTTransferUtils.drainFluidAccountNotifiableList(coolantTank, - getCoolantStack(coolantToDrain), IFluidHandler.FluidAction.EXECUTE); - if (!coolantStack.isEmpty()) { - int coolantDrained = coolantStack.getAmount(); - if (coolantDrained == coolantToDrain) { - // successfully stabilized to zero - return 0; - } else { - // coolant requirement was only partially met, cool proportional to fluid amount drained - // a * (b / c) - temperatureChange -= temperatureToDecrease * (1.0 * coolantDrained / coolantToDrain); - } + int remainingCoolant = coolantToDrain; + for (var fluid : BuiltInRegistries.FLUID.getTagOrEmpty(HPCA_COOLANTS)) { + FluidStack drained = GTTransferUtils.drainFluidAccountNotifiableList(coolantTank, + new FluidStack(fluid, remainingCoolant), IFluidHandler.FluidAction.EXECUTE); + remainingCoolant -= drained.getAmount(); + if (remainingCoolant <= 0) break; + } + if (remainingCoolant <= 0) { + // successfully stabilized to zero + return 0; + } else { + // coolant requirement was only partially met, cool proportional to fluid amount drained + // a * (b / c) + int coolantDrained = (coolantToDrain - remainingCoolant); + temperatureChange -= temperatureToDecrease * (1.0 * coolantDrained / coolantToDrain); } } return temperatureChange; } - /** - * Get the coolant stack for this HPCA. Eventually this could be made more diverse with different - * coolants from different Active Cooler components, but currently it is just a fixed Fluid. - */ - public FluidStack getCoolantStack(int amount) { - return new FluidStack(getCoolant(), amount); - } - - private Fluid getCoolant() { - return GTMaterials.PCBCoolant.getFluid(); - } - /** * Roll a 1/200 chance to damage a HPCA component marked as damageable. Randomly selects the component. * If called every tick, this succeeds on average once every 10 seconds. @@ -541,6 +551,7 @@ public void attemptDamageHPCA() { /** Allocate computation on a given request. Allocates for one tick. */ public int allocateCWUt(int cwut, boolean simulate) { + if (cwut == 0) return 0; int maxCWUt = getMaxCWUt(); int availableCWUt = maxCWUt - this.allocatedCWUt; int toAllocate = Math.min(cwut, availableCWUt); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java index 474cc0cd886..c8b905fadf6 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/research/NetworkSwitchMachine.java @@ -135,7 +135,7 @@ public void addDisplayText(List textList) { */ /** Handles computation load across multiple receivers and to multiple transmitters. */ - private static class MultipleComputationHandler extends NotifiableComputationContainer { + private class MultipleComputationHandler extends NotifiableComputationContainer { // providers in the NS provide distributable computation to the NS private final Set providers = new ObjectOpenHashSet<>(); @@ -146,6 +146,9 @@ private static class MultipleComputationHandler extends NotifiableComputationCon @Getter(value = AccessLevel.PRIVATE) private int EUt; + private boolean tickSaturated; + private long timerCWUt = -1; + public MultipleComputationHandler(MetaMachine machine) { super(machine, IO.IN, false); } @@ -169,6 +172,21 @@ public int requestCWUt(int cwut, boolean simulate, @NotNull Collection bridgeSeen = new ArrayList<>(seen); int allocatedCWUt = 0; for (var provider : providers) { @@ -178,6 +196,12 @@ public int requestCWUt(int cwut, boolean simulate, @NotNull Collection - * + * * @param machine a {@link LargeTurbineMachine} * @param recipe recipe * @return A {@link ModifierFunction} for the given Turbine Multiblock and recipe @@ -103,9 +151,15 @@ public static ModifierFunction recipeModifier(@NotNull MetaMachine machine, @Not if (EUt.isEmpty() || turbineMaxVoltage <= EUt.voltage() || holderEfficiency <= 0) return ModifierFunction.NULL; // get the amount of parallel required to match the desired output voltage + // Max Parallel is Ceilinged not Floored to ensure the output voltage is actually met, + // at the cost of slightly increased fuel int maxParallel = (int) (turbineMaxVoltage / EUt.getTotalEU()); + if (turbineMaxVoltage % EUt.getTotalEU() != 0) maxParallel++; + int actualParallel = ParallelLogic.getParallelAmountFast(turbineMachine, recipe, maxParallel); - double eutMultiplier = turbineMachine.productionBoost() * actualParallel; + double eutMultiplier = (maxParallel == actualParallel) ? + turbineMachine.productionBoost() * turbineMaxVoltage / EUt.voltage() : + turbineMachine.productionBoost() * actualParallel; return ModifierFunction.builder() .inputModifier(ContentModifier.multiplier(actualParallel)) @@ -123,7 +177,8 @@ public boolean regressWhenWaiting() { @Override public boolean canVoidRecipeOutputs(RecipeCapability capability) { - return capability != EURecipeCapability.CAP; + // void both eu and fluid tick outputs + return true; } ////////////////////////////////////// @@ -144,8 +199,7 @@ public void addDisplayText(List textList) { rotorHolder.getTotalEfficiency())); long maxProduction = getOverclockVoltage(); - long currentProduction = isActive() && recipeLogic.getLastRecipe() != null ? - recipeLogic.getLastRecipe().getOutputEUt().voltage() : 0; + long currentProduction = getCurrentProduction(); if (isActive()) { textList.add(3, Component.translatable("gtceu.multiblock.turbine.energy_per_tick", diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DataAccessHatchMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DataAccessHatchMachine.java index 8d1955e4788..959261e7360 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DataAccessHatchMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DataAccessHatchMachine.java @@ -1,7 +1,9 @@ package com.gregtechceu.gtceu.common.machine.multiblock.part; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.capability.IDataAccessHatch; +import com.gregtechceu.gtceu.api.capability.IMonitorComponent; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.gui.GuiTextures; @@ -21,6 +23,8 @@ import com.gregtechceu.gtceu.utils.ItemStackHashStrategy; import com.gregtechceu.gtceu.utils.ResearchManager; +import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; +import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; import com.lowdragmc.lowdraglib.gui.widget.Widget; import com.lowdragmc.lowdraglib.gui.widget.WidgetGroup; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; @@ -31,6 +35,7 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.BlockHitResult; +import net.neoforged.neoforge.items.IItemHandler; import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; @@ -40,7 +45,7 @@ import java.util.*; public class DataAccessHatchMachine extends TieredPartMachine - implements IMachineLife, IDataAccessHatch, IDataInfoProvider { + implements IMachineLife, IDataAccessHatch, IDataInfoProvider, IMonitorComponent { protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder( DataAccessHatchMachine.class, MultiblockPartMachine.MANAGED_FIELD_HOLDER); @@ -103,7 +108,12 @@ public boolean shouldOpenUI(Player player, InteractionHand hand, BlockHitResult } protected int getInventorySize() { - return getTier() == GTValues.LuV ? 16 : 9; + return switch (getTier()) { + case GTValues.LuV -> 16; + case GTValues.EV -> 9; + case GTValues.HV -> 4; + default -> 1; + }; } @Override @@ -179,4 +189,14 @@ public GTRecipe modifyRecipe(GTRecipe recipe) { public ManagedFieldHolder getFieldHolder() { return MANAGED_FIELD_HOLDER; } + + @Override + public IGuiTexture getComponentIcon() { + return new ResourceTexture(GTCEu.id("textures/item/data_module.png")).getSubTexture(0, 0, 1, 1 / 13f); + } + + @Override + public IItemHandler getDataItems() { + return importItems.storage; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DiodePartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DiodePartMachine.java index e410d4be899..cd3ea0a4d85 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DiodePartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DiodePartMachine.java @@ -1,15 +1,16 @@ package com.gregtechceu.gtceu.common.machine.multiblock.part; -import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.multiblock.part.TieredIOPartMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.NotifiableEnergyContainer; import com.gregtechceu.gtceu.data.item.GTItemAbilities; import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; +import com.lowdragmc.lowdraglib.syncdata.annotation.UpdateListener; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; import net.minecraft.core.Direction; @@ -64,7 +65,7 @@ public static AmpMode getByValue(int amps) { } } - public static final EnumProperty AMP_MODE_PROPERTY = EnumProperty.create("amp_mode", AmpMode.class); + public static final EnumProperty AMP_MODE_PROPERTY = GTMachineModelProperties.DIODE_AMP_MODE; // spotless:on public static int MAX_AMPS = 16; @@ -75,6 +76,7 @@ public static AmpMode getByValue(int amps) { @Getter @DescSynced @Persisted(key = "amp_mode") + @UpdateListener(methodName = "onAmpUpdated") private int amps; public DiodePartMachine(IMachineBlockEntity holder, int tier) { @@ -105,9 +107,7 @@ protected int getMaxAmperage() { @Override public void onLoad() { super.onLoad(); - - if (!GTCEu.isClientThread()) - reinitializeEnergyContainer(); + reinitializeEnergyContainer(); } protected void reinitializeEnergyContainer() { @@ -139,11 +139,8 @@ protected ItemInteractionResult onSoftMalletClick(Player playerIn, InteractionHa return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; } cycleAmpMode(); - if (getLevel().isClientSide) { - setRenderState(getRenderState() - .setValue(AMP_MODE_PROPERTY, AmpMode.getByValue(this.amps))); - - scheduleRenderUpdate(); + if (!isRemote()) { + this.scheduleRenderUpdate(); playerIn.sendSystemMessage(Component.translatable("gtceu.machine.diode.message", amps)); return ItemInteractionResult.SUCCESS; } @@ -154,4 +151,18 @@ protected ItemInteractionResult onSoftMalletClick(Player playerIn, InteractionHa public ManagedFieldHolder getFieldHolder() { return MANAGED_FIELD_HOLDER; } + + @SuppressWarnings("unused") + public void onAmpUpdated(int newValue, int oldValue) { + this.scheduleRenderUpdate(); + } + + @Override + public void scheduleRenderUpdate() { + if (!isRemote()) { + setRenderState(getRenderState() + .setValue(GTMachineModelProperties.DIODE_AMP_MODE, AmpMode.getByValue(this.amps))); + super.scheduleRenderUpdate(); + } + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java index fb44c51f849..79d075919e6 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/DualHatchPartMachine.java @@ -91,7 +91,7 @@ protected void updateInventorySubscription() { this.hasFluidHandler = false; } - if (isWorkingEnabled() && (canOutput || io == IO.IN) && (hasItemHandler || hasFluidHandler)) { + if (isWorkingEnabled() && (canOutput || io.support(IO.IN)) && (hasItemHandler || hasFluidHandler)) { autoIOSubs = subscribeServerTick(autoIOSubs, this::autoIO); } else if (autoIOSubs != null) { autoIOSubs.unsubscribe(); @@ -103,14 +103,15 @@ protected void updateInventorySubscription() { protected void autoIO() { if (getOffsetTimer() % 5 == 0) { if (isWorkingEnabled()) { - if (io == IO.OUT) { + if (io.support(IO.OUT)) { if (hasItemHandler) { getInventory().exportToNearby(getFrontFacing()); } if (hasFluidHandler) { tank.exportToNearby(getFrontFacing()); } - } else if (io == IO.IN) { + } + if (io.support(IO.IN)) { if (hasItemHandler) { getInventory().importFromNearby(getFrontFacing()); } @@ -168,7 +169,8 @@ public Widget createUIWidget() { container.addWidget(new SlotWidget( getInventory().storage, index++, 4 + x * 18, 4 + y * 18, true, io.support(IO.IN)) .setBackgroundTexture(GuiTextures.SLOT) - .setIngredientIO(this.io == IO.IN ? IngredientIO.INPUT : IngredientIO.OUTPUT)); + .setIngredientIO(this.io == IO.IN ? IngredientIO.INPUT : + this.io == IO.OUT ? IngredientIO.OUTPUT : IngredientIO.BOTH)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/EnergyHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/EnergyHatchPartMachine.java index e7907f19abf..e97f6a1b368 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/EnergyHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/EnergyHatchPartMachine.java @@ -9,7 +9,6 @@ import com.gregtechceu.gtceu.api.machine.trait.NotifiableEnergyContainer; import com.gregtechceu.gtceu.config.ConfigHolder; -import com.lowdragmc.lowdraglib.syncdata.ISubscription; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; @@ -18,7 +17,6 @@ import net.minecraft.world.phys.BlockHitResult; import lombok.Getter; -import org.jetbrains.annotations.Nullable; public class EnergyHatchPartMachine extends TieredIOPartMachine implements IExplosionMachine { @@ -27,9 +25,7 @@ public class EnergyHatchPartMachine extends TieredIOPartMachine implements IExpl @Persisted public final NotifiableEnergyContainer energyContainer; - protected TickableSubscription explosionSubs; - @Nullable - protected ISubscription energyListener; + protected TickableSubscription explosionSub; @Getter protected int amperage; @@ -71,39 +67,29 @@ public boolean shouldOpenUI(Player player, InteractionHand hand, BlockHitResult @Override public void onLoad() { super.onLoad(); - // if machine need do check explosion conditions - if (ConfigHolder.INSTANCE.machines.shouldWeatherOrTerrainExplosion && shouldWeatherOrTerrainExplosion()) { - energyListener = energyContainer.addChangedListener(this::updateExplosionSubscription); - updateExplosionSubscription(); + if (!isRemote() && ConfigHolder.INSTANCE.machines.shouldWeatherOrTerrainExplosion && + shouldWeatherOrTerrainExplosion()) { + explosionSub = subscribeServerTick(this::checkExplosion); + checkExplosion(); } } @Override public void onUnload() { super.onUnload(); - if (energyListener != null) { - energyListener.unsubscribe(); - energyListener = null; + if (explosionSub != null) { + explosionSub.unsubscribe(); + explosionSub = null; } } ////////////////////////////////////// // ******** Explosion ********// ////////////////////////////////////// - - protected void updateExplosionSubscription() { - if (ConfigHolder.INSTANCE.machines.shouldWeatherOrTerrainExplosion && shouldWeatherOrTerrainExplosion() && - energyContainer.getEnergyStored() > 0) { - explosionSubs = subscribeServerTick(explosionSubs, this::checkExplosion); - } else if (explosionSubs != null) { - explosionSubs.unsubscribe(); - explosionSubs = null; - } - } - protected void checkExplosion() { - checkWeatherOrTerrainExplosion(tier, tier * 10); - updateExplosionSubscription(); + if (energyContainer.getEnergyStored() > 0) { + checkWeatherOrTerrainExplosion(tier, tier * 10); + } } ////////////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/FluidHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/FluidHatchPartMachine.java index f6d34d5fb06..ec538dced44 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/FluidHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/FluidHatchPartMachine.java @@ -103,7 +103,7 @@ public static int getTankCapacity(int initialCapacity, int tier) { } protected NotifiableItemStackHandler createCircuitItemHandler(Object... args) { - if (args.length > 0 && args[0] instanceof IO io && io == IO.IN) { + if (args.length > 0 && args[0] instanceof IO io && io.support(IO.IN)) { return new NotifiableItemStackHandler(this, 1, IO.IN, IO.NONE) .setFilter(IntCircuitBehaviour::isIntegratedCircuit); } else { @@ -193,7 +193,7 @@ protected void updateTankSubscription() { } protected void updateTankSubscription(Direction newFacing) { - if (isWorkingEnabled() && ((io == IO.OUT && !tank.isEmpty()) || io == IO.IN) && + if (isWorkingEnabled() && ((io.support(IO.OUT) && !tank.isEmpty()) || io.support(IO.IN)) && GTTransferUtils.hasAdjacentFluidHandler(getLevel(), getPos(), newFacing)) { autoIOSubs = subscribeServerTick(autoIOSubs, this::autoIO); } else if (autoIOSubs != null) { @@ -205,9 +205,9 @@ protected void updateTankSubscription(Direction newFacing) { protected void autoIO() { if (getOffsetTimer() % 5 == 0) { if (isWorkingEnabled()) { - if (io == IO.OUT) { + if (io.support(IO.OUT)) { tank.exportToNearby(getFrontFacing()); - } else if (io == IO.IN) { + } else if (io.support(IO.IN)) { tank.importFromNearby(getFrontFacing()); } } @@ -237,11 +237,11 @@ public boolean swapIO() { BlockPos blockPos = getHolder().pos(); MachineDefinition newDefinition = null; - if (io == IO.IN) { + if (io.support(IO.IN)) { if (this.slots == 1) newDefinition = GTMachines.FLUID_EXPORT_HATCH[this.getTier()]; else if (this.slots == 4) newDefinition = GTMachines.FLUID_EXPORT_HATCH_4X[this.getTier()]; else if (this.slots == 9) newDefinition = GTMachines.FLUID_EXPORT_HATCH_9X[this.getTier()]; - } else if (io == IO.OUT) { + } else if (io.support(IO.OUT)) { if (this.slots == 1) newDefinition = GTMachines.FLUID_IMPORT_HATCH[this.getTier()]; else if (this.slots == 4) newDefinition = GTMachines.FLUID_IMPORT_HATCH_4X[this.getTier()]; else if (this.slots == 9) newDefinition = GTMachines.FLUID_IMPORT_HATCH_9X[this.getTier()]; @@ -272,7 +272,7 @@ public boolean swapIO() { @Override public void attachConfigurators(ConfiguratorPanel configuratorPanel) { super.attachConfigurators(configuratorPanel); - if (isCircuitSlotEnabled() && this.io == IO.IN) { + if (isCircuitSlotEnabled() && this.io.support(IO.IN)) { configuratorPanel.attachConfigurators(new CircuitFancyConfigurator(circuitInventory.storage)); } } @@ -292,7 +292,7 @@ protected Widget createSingleSlotGUI() { TankWidget tankWidget; // Add input/output-specific widgets - if (this.io == IO.OUT) { + if (this.io.support(IO.OUT)) { // if this is an output hatch, assign tankWidget to the phantom widget displaying the locked fluid... group.addWidget(tankWidget = new PhantomFluidWidget(this.tank.getLockedFluid(), 0, 67, 40, 18, 18, () -> this.tank.getLockedFluid().getFluid(), f -> { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java index 74534da46cd..d228ae69d58 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachine.java @@ -98,7 +98,7 @@ protected NotifiableItemStackHandler createInventory(Object... args) { } protected NotifiableItemStackHandler createCircuitItemHandler(Object... args) { - if (args.length > 0 && args[0] instanceof IO io && io == IO.IN) { + if (args.length > 0 && args[0] instanceof IO io && io.support(IO.IN)) { return new NotifiableItemStackHandler(this, 1, IO.IN, IO.NONE) .setFilter(IntCircuitBehaviour::isIntegratedCircuit); } else { @@ -213,7 +213,7 @@ protected void updateInventorySubscription() { } protected void updateInventorySubscription(Direction newFacing) { - if (isWorkingEnabled() && ((io == IO.OUT && !getInventory().isEmpty()) || io == IO.IN) && + if (isWorkingEnabled() && ((io.support(IO.OUT) && !getInventory().isEmpty()) || io.support(IO.IN)) && GTTransferUtils.hasAdjacentItemHandler(getLevel(), getPos(), newFacing)) { autoIOSubs = subscribeServerTick(autoIOSubs, this::autoIO); } else if (autoIOSubs != null) { @@ -229,6 +229,9 @@ protected void autoIO() { getInventory().exportToNearby(getFrontFacing()); } else if (io == IO.IN) { getInventory().importFromNearby(getFrontFacing()); + } else if (io == IO.BOTH) { + getInventory().importFromNearby(getFrontFacing()); + getInventory().exportToNearby(getFrontFacing().getOpposite()); } } updateInventorySubscription(); @@ -256,9 +259,9 @@ protected ItemInteractionResult onScrewdriverClick(Player playerIn, InteractionH public boolean swapIO() { BlockPos blockPos = getHolder().pos(); MachineDefinition newDefinition = null; - if (io == IO.IN) { + if (io.support(IO.IN)) { newDefinition = GTMachines.ITEM_EXPORT_BUS[this.getTier()]; - } else if (io == IO.OUT) { + } else if (io.support(IO.OUT)) { newDefinition = GTMachines.ITEM_IMPORT_BUS[this.getTier()]; } if (newDefinition == null) return false; @@ -285,9 +288,9 @@ public boolean swapIO() { ////////////////////////////////////// public void attachConfigurators(ConfiguratorPanel configuratorPanel) { - if (this.io == IO.OUT) { + if (this.io.support(IO.OUT)) { IDistinctPart.super.superAttachConfigurators(configuratorPanel); - } else if (this.io == IO.IN) { + } else if (this.io.support(IO.IN)) { IDistinctPart.super.attachConfigurators(configuratorPanel); if (hasCircuitSlot && isCircuitSlotEnabled()) { configuratorPanel.attachConfigurators(new CircuitFancyConfigurator(circuitInventory.storage)); @@ -311,7 +314,7 @@ public Widget createUIWidget() { container.addWidget( new SlotWidget(getInventory().storage, index++, 4 + x * 18, 4 + y * 18, true, io.support(IO.IN)) .setBackgroundTexture(GuiTextures.SLOT) - .setIngredientIO(this.io == IO.IN ? IngredientIO.INPUT : IngredientIO.OUTPUT)); + .setIngredientIO(this.io.support(IO.IN) ? IngredientIO.INPUT : IngredientIO.OUTPUT)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/MaintenanceHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/MaintenanceHatchPartMachine.java index f3df62b6f4d..cffa8b27303 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/MaintenanceHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/MaintenanceHatchPartMachine.java @@ -13,7 +13,9 @@ import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMaintenanceMachine; import com.gregtechceu.gtceu.api.machine.multiblock.part.MultiblockPartMachine; import com.gregtechceu.gtceu.api.machine.multiblock.part.TieredPartMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; +import com.gregtechceu.gtceu.client.model.machine.MachineRenderState; import com.gregtechceu.gtceu.data.item.GTItems; import com.gregtechceu.gtceu.utils.FormattingUtil; @@ -125,6 +127,13 @@ public void onLoad() { super.onLoad(); if (!isRemote()) { updateMaintenanceSubscription(); + + // fix the model being invalid after the tape property rename + MachineRenderState renderState = getRenderState(); + if (renderState.hasProperty(GTMachineModelProperties.IS_TAPED) && + this.isTaped != renderState.getValue(GTMachineModelProperties.IS_TAPED)) { + setRenderState(renderState.setValue(GTMachineModelProperties.IS_TAPED, this.isTaped)); + } } } @@ -295,7 +304,7 @@ public boolean isFullAuto() { public void setTaped(boolean isTaped) { if (this.isTaped != isTaped) { this.isTaped = isTaped; - setRenderState(getRenderState().setValue(MAINTENANCE_TAPED_PROPERTY, isTaped)); + setRenderState(getRenderState().setValue(GTMachineModelProperties.IS_TAPED, isTaped)); } } @@ -321,7 +330,7 @@ public ItemInteractionResult onUseWithItem(ItemStack stack, BlockState state, Le if (consumeDuctTape(player, stack)) { fixAllMaintenanceProblems(); setTaped(true); - return ItemInteractionResult.CONSUME; + return ItemInteractionResult.SUCCESS; } } return ItemInteractionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/MufflerPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/MufflerPartMachine.java index 7adfc696adb..eaf68a29b04 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/MufflerPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/MufflerPartMachine.java @@ -5,19 +5,21 @@ import com.gregtechceu.gtceu.api.gui.UITemplate; import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; -import com.gregtechceu.gtceu.api.machine.feature.IUIMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMufflerMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; import com.gregtechceu.gtceu.api.machine.multiblock.part.MultiblockPartMachine; import com.gregtechceu.gtceu.api.machine.multiblock.part.TieredPartMachine; import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; +import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.gui.modular.ModularUI; import com.lowdragmc.lowdraglib.gui.widget.LabelWidget; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; +import net.minecraft.core.BlockPos; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.neoforged.api.distmarker.Dist; @@ -25,10 +27,11 @@ import net.neoforged.neoforge.items.ItemHandlerHelper; import lombok.Getter; +import org.jetbrains.annotations.MustBeInvokedByOverriders; import java.util.stream.IntStream; -public class MufflerPartMachine extends TieredPartMachine implements IMufflerMachine, IUIMachine { +public class MufflerPartMachine extends TieredPartMachine implements IMufflerMachine { protected static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(MufflerPartMachine.class, MultiblockPartMachine.MANAGED_FIELD_HOLDER); @@ -38,6 +41,8 @@ public class MufflerPartMachine extends TieredPartMachine implements IMufflerMac @Persisted private final CustomItemStackHandler inventory; + private TickableSubscription snowSubscription; + public MufflerPartMachine(IMachineBlockEntity holder, int tier) { super(holder, tier); this.recoveryChance = Math.max(1, tier * 10); @@ -83,6 +88,36 @@ public void clientTick() { } } + @Override + public void addedToController(IMultiController controller) { + super.addedToController(controller); + if (snowSubscription == null) { + this.snowSubscription = subscribeServerTick(null, this::tryBreakSnow); + } + } + + @MustBeInvokedByOverriders + @Override + public void removedFromController(IMultiController controller) { + super.removedFromController(controller); + if (controllers.isEmpty()) { + unsubscribe(snowSubscription); + snowSubscription = null; + } + } + + private void tryBreakSnow() { + if (getOffsetTimer() % 10 == 0) { + for (IMultiController controller : getControllers()) { + if (controller instanceof IRecipeLogicMachine recipeLogicMachine && + recipeLogicMachine.getRecipeLogic().isWorking()) { + BlockPos mufflerPos = getPos().relative(getFrontFacing()); + GTUtil.tryBreakSnow(getLevel(), mufflerPos, getLevel().getBlockState(mufflerPos), true); + } + } + } + } + ////////////////////////////////////// // ********** GUI ***********// ////////////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ParallelHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ParallelHatchPartMachine.java index 481844ea822..ad8baf58b49 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ParallelHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ParallelHatchPartMachine.java @@ -35,6 +35,7 @@ public class ParallelHatchPartMachine extends TieredPartMachine implements IFanc public ParallelHatchPartMachine(IMachineBlockEntity holder, int tier) { super(holder, tier); this.maxParallel = (int) Math.pow(4, tier - GTValues.EV); + this.currentParallel = maxParallel; } public void setCurrentParallel(int parallelAmount) { diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/RotorHolderPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/RotorHolderPartMachine.java index f2f51864bc0..85e203dafd7 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/RotorHolderPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/RotorHolderPartMachine.java @@ -38,6 +38,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties.*; + public class RotorHolderPartMachine extends TieredPartMachine implements IMachineLife, IRotorHolderMachine, IInteractedMachine { @@ -136,13 +138,13 @@ private void onRotorInventoryChanged() { boolean emissive = this.rotorMaterial.hasProperty(PropertyKey.ORE) && this.rotorMaterial.getProperty(PropertyKey.ORE).isEmissive(); setRenderState(getRenderState() - .setValue(HAS_ROTOR_PROPERTY, true) - .setValue(EMISSIVE_ROTOR_PROPERTY, emissive)); + .setValue(HAS_ROTOR, true) + .setValue(IS_EMISSIVE_ROTOR, emissive)); } else { this.rotorMaterial = GTMaterials.NULL; setRenderState(getRenderState() - .setValue(HAS_ROTOR_PROPERTY, false) - .setValue(EMISSIVE_ROTOR_PROPERTY, false)); + .setValue(HAS_ROTOR, false) + .setValue(IS_EMISSIVE_ROTOR, false)); } } @@ -174,7 +176,7 @@ private void updateRotorSpeed() { public void setRotorSpeed(int rotorSpeed) { if ((this.rotorSpeed > 0 && rotorSpeed <= 0) || (this.rotorSpeed <= 0 && rotorSpeed > 0)) { - setRenderState(getRenderState().setValue(ROTOR_SPINNING_PROPERTY, rotorSpeed > 0)); + setRenderState(getRenderState().setValue(IS_ROTOR_SPINNING, rotorSpeed > 0)); } this.rotorSpeed = rotorSpeed; } @@ -216,8 +218,10 @@ public void setRotorStack(ItemStack rotorStack) { public InteractionResult onUse(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { if (!isRemote() && getRotorSpeed() > 0 && !player.isCreative()) { - player.hurt(level.damageSources().source(GTDamageTypes.TURBINE), - TurbineRotorBehaviour.getBehaviour(getRotorStack()).getDamage(getRotorStack())); + TurbineRotorBehaviour behaviour = TurbineRotorBehaviour.getBehaviour(getRotorStack()); + if (behaviour != null) { + player.hurt(level.damageSources().source(GTDamageTypes.TURBINE), behaviour.getDamage(getRotorStack())); + } return InteractionResult.FAIL; } return InteractionResult.PASS; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/hpca/HPCAComponentPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/hpca/HPCAComponentPartMachine.java index 67b0fc89d58..31c5e5fd0c8 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/hpca/HPCAComponentPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/hpca/HPCAComponentPartMachine.java @@ -1,11 +1,10 @@ package com.gregtechceu.gtceu.common.machine.multiblock.part.hpca; import com.gregtechceu.gtceu.api.capability.IHPCAComponentHatch; -import com.gregtechceu.gtceu.api.capability.IWorkable; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.feature.IMachineModifyDrops; -import com.gregtechceu.gtceu.api.machine.feature.multiblock.IWorkableMultiController; import com.gregtechceu.gtceu.api.machine.multiblock.part.MultiblockPartMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.client.model.machine.MachineRenderState; import com.gregtechceu.gtceu.data.block.GTBlocks; @@ -64,11 +63,6 @@ public final boolean isBridge() { return doesAllowBridging() && !(canBeDamaged() && isDamaged()); } - @Override - public boolean replacePartModelWhenFormed() { - return false; - } - @Override public boolean isDamaged() { return canBeDamaged() && damaged; @@ -82,28 +76,17 @@ public void setDamaged(boolean damaged) { markDirty(); MachineRenderState state = getRenderState(); - if (state.hasProperty(HPCA_PART_DAMAGED_PROPERTY)) { - setRenderState(state.setValue(HPCA_PART_DAMAGED_PROPERTY, damaged)); + if (state.hasProperty(GTMachineModelProperties.IS_HPCA_PART_DAMAGED)) { + setRenderState(state.setValue(GTMachineModelProperties.IS_HPCA_PART_DAMAGED, damaged)); } } } - @Override - public boolean beforeWorking(IWorkableMultiController controller) { - MachineRenderState state = getRenderState(); - if (state.hasProperty(IWorkable.ACTIVE_PROPERTY)) { - setRenderState(state.setValue(IWorkable.ACTIVE_PROPERTY, true)); - } - return super.beforeWorking(controller); - } - - @Override - public boolean afterWorking(IWorkableMultiController controller) { + public void setActive(boolean active) { MachineRenderState state = getRenderState(); - if (state.hasProperty(IWorkable.ACTIVE_PROPERTY)) { - setRenderState(state.setValue(IWorkable.ACTIVE_PROPERTY, false)); + if (state.hasProperty(GTMachineModelProperties.IS_ACTIVE)) { + setRenderState(state.setValue(GTMachineModelProperties.IS_ACTIVE, active)); } - return super.afterWorking(controller); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/monitor/AdvancedMonitorPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/monitor/AdvancedMonitorPartMachine.java new file mode 100644 index 00000000000..7d1a45d847a --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/monitor/AdvancedMonitorPartMachine.java @@ -0,0 +1,93 @@ +package com.gregtechceu.gtceu.common.machine.multiblock.part.monitor; + +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.TickableSubscription; +import com.gregtechceu.gtceu.api.machine.feature.IInteractedMachine; +import com.gregtechceu.gtceu.api.machine.multiblock.part.MultiblockPartMachine; +import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; + +import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; +import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; + +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; + +import lombok.Getter; +import org.jetbrains.annotations.Nullable; + +@MethodsReturnNonnullByDefault +public class AdvancedMonitorPartMachine extends MonitorPartMachine implements IInteractedMachine { + + private static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder( + AdvancedMonitorPartMachine.class, MultiblockPartMachine.MANAGED_FIELD_HOLDER); + + @Getter + @Persisted + private double clickPosX; + @Getter + @Persisted + private double clickPosY; + @Getter + @Persisted + private boolean clicked; + @Persisted + private boolean resetClickedNextTick = false; + + @Nullable + private TickableSubscription clickResetSubscription; + + public AdvancedMonitorPartMachine(IMachineBlockEntity holder) { + super(holder); + } + + @Override + public InteractionResult onUse(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, + BlockHitResult hit) { + if (hit.getDirection() != getFrontFacing()) + return IInteractedMachine.super.onUse(state, world, pos, player, hand, hit); + clicked = true; + clickPosX = hit.getLocation() + .get(RelativeDirection.RIGHT.getRelative(getFrontFacing(), getUpwardsFacing(), false).getAxis()); + clickPosY = hit.getLocation() + .get(getFrontFacing().getAxis().isVertical() ? Direction.Axis.X : Direction.Axis.Y); + clickPosX -= Math.floor(clickPosX); + if (clickPosX < 0) clickPosX++; + clickPosY -= Math.floor(clickPosY); + if (clickPosY < 0) clickPosY++; + return InteractionResult.SUCCESS; + } + + public void resetClicked() { + resetClickedNextTick = true; + } + + private void unsetClicked() { + if (resetClickedNextTick) { + clicked = false; + } + resetClickedNextTick = false; + } + + @Override + public ManagedFieldHolder getFieldHolder() { + return MANAGED_FIELD_HOLDER; + } + + @Override + public void onLoad() { + super.onLoad(); + clickResetSubscription = subscribeServerTick(this::unsetClicked); + } + + @Override + public void onUnload() { + unsubscribe(clickResetSubscription); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/monitor/MonitorComponentPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/monitor/MonitorComponentPartMachine.java new file mode 100644 index 00000000000..220bd378673 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/monitor/MonitorComponentPartMachine.java @@ -0,0 +1,12 @@ +package com.gregtechceu.gtceu.common.machine.multiblock.part.monitor; + +import com.gregtechceu.gtceu.api.capability.IMonitorComponent; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.multiblock.part.MultiblockPartMachine; + +public abstract class MonitorComponentPartMachine extends MultiblockPartMachine implements IMonitorComponent { + + public MonitorComponentPartMachine(IMachineBlockEntity holder) { + super(holder); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/monitor/MonitorPartMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/monitor/MonitorPartMachine.java new file mode 100644 index 00000000000..4f999166910 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/part/monitor/MonitorPartMachine.java @@ -0,0 +1,33 @@ +package com.gregtechceu.gtceu.common.machine.multiblock.part.monitor; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; + +import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; +import com.lowdragmc.lowdraglib.gui.texture.ResourceTexture; + +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.BlockHitResult; + +public class MonitorPartMachine extends MonitorComponentPartMachine { + + public MonitorPartMachine(IMachineBlockEntity holder) { + super(holder); + } + + @Override + public boolean isMonitor() { + return true; + } + + @Override + public IGuiTexture getComponentIcon() { + return ResourceTexture.fromSpirit(GTCEu.id("item/computer_monitor_cover")); + } + + @Override + public boolean shouldOpenUI(Player player, InteractionHand hand, BlockHitResult hit) { + return false; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/CharcoalPileIgniterMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/CharcoalPileIgniterMachine.java index 434481a0676..6a6804f2bc3 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/CharcoalPileIgniterMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/CharcoalPileIgniterMachine.java @@ -59,7 +59,7 @@ public class CharcoalPileIgniterMachine extends WorkableMultiblockMachine implem private static final int MIN_RADIUS = 1; private static final int MIN_DEPTH = 2; - + private static final int MAX_HEIGHT = 5; private final Collection logPos = new ObjectOpenHashSet<>(); @DescSynced @@ -249,7 +249,7 @@ public void updateDimensions() { int fDist = 0; int hDist = 0; - for (int i = 1; i < 6; i++) { + for (int i = 1; i <= MAX_HEIGHT; i++) { if (lDist != 0 && rDist != 0 && hDist != 0) break; if (lDist == 0 && isBlockWall(level, lPos, left)) lDist = i; if (rDist == 0 && isBlockWall(level, rPos, right)) rDist = i; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/CokeOvenMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/CokeOvenMachine.java index 3cda4650548..599974c91a3 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/CokeOvenMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/CokeOvenMachine.java @@ -21,7 +21,13 @@ import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.util.RandomSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.neoforged.neoforge.fluids.FluidUtil; public class CokeOvenMachine extends PrimitiveWorkableMachine implements IUIMachine { @@ -79,4 +85,19 @@ public void animateTick(RandomSource random) { getLevel().addParticle(ParticleTypes.FLAME, x, y, z, 0, 0, 0); } } + + @Override + public InteractionResult onUse(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, + BlockHitResult hit) { + if (!isRemote()) { + if (super.onUse(state, world, pos, player, hand, hit) == InteractionResult.SUCCESS) { + return InteractionResult.SUCCESS; + } + if (FluidUtil.interactWithFluidHandler(player, hand, exportFluids)) { + return InteractionResult.SUCCESS; + } + return InteractionResult.PASS; + } + return super.onUse(state, world, pos, player, hand, hit); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitiveBlastFurnaceMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitiveBlastFurnaceMachine.java index 0716dc283d2..a36a79d6b8b 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitiveBlastFurnaceMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/primitive/PrimitiveBlastFurnaceMachine.java @@ -11,8 +11,10 @@ import com.gregtechceu.gtceu.api.machine.feature.IUIMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IFluidRenderMulti; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; import com.gregtechceu.gtceu.config.ConfigHolder; +import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.gui.modular.ModularUI; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; @@ -29,6 +31,7 @@ import net.minecraft.sounds.SoundSource; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.OnlyIn; @@ -86,15 +89,23 @@ public void onUnload() { public void onStructureFormed() { super.onStructureFormed(); IFluidRenderMulti.super.onStructureFormed(); - this.hurtSubscription = subscribeServerTick(this.hurtSubscription, this::hurtEntities); } @Override public void onStructureInvalid() { super.onStructureInvalid(); IFluidRenderMulti.super.onStructureInvalid(); - unsubscribe(hurtSubscription); - hurtSubscription = null; + } + + @Override + public void notifyStatusChanged(RecipeLogic.Status oldStatus, RecipeLogic.Status newStatus) { + super.notifyStatusChanged(oldStatus, newStatus); + if (newStatus == RecipeLogic.Status.WORKING) { + this.hurtSubscription = subscribeServerTick(this.hurtSubscription, this::hurtEntitiesAndBreakSnow); + } else if (oldStatus == RecipeLogic.Status.WORKING && hurtSubscription != null) { + unsubscribe(hurtSubscription); + hurtSubscription = null; + } } @Override @@ -193,8 +204,13 @@ public void animateTick(RandomSource random) { } } - private void hurtEntities() { + private void hurtEntitiesAndBreakSnow() { BlockPos middlePos = self().getPos().offset(getFrontFacing().getOpposite().getNormal()); getLevel().getEntities(null, new AABB(middlePos)).forEach(e -> e.hurt(e.damageSources().lava(), 3.0f)); + + if (getOffsetTimer() % 10 == 0) { + BlockState state = getLevel().getBlockState(middlePos); + GTUtil.tryBreakSnow(getLevel(), middlePos, state, true); + } } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java index 38461b01b62..e81b5149464 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/multiblock/steam/LargeBoilerMachine.java @@ -1,16 +1,16 @@ package com.gregtechceu.gtceu.common.machine.multiblock.steam; import com.gregtechceu.gtceu.api.GTValues; -import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; -import com.gregtechceu.gtceu.api.capability.recipe.IO; -import com.gregtechceu.gtceu.api.capability.recipe.IRecipeHandler; +import com.gregtechceu.gtceu.api.capability.recipe.*; import com.gregtechceu.gtceu.api.gui.GuiTextures; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.TickableSubscription; import com.gregtechceu.gtceu.api.machine.feature.IExplosionMachine; +import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IDisplayUIMachine; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.api.recipe.modifier.ModifierFunction; import com.gregtechceu.gtceu.api.recipe.modifier.RecipeModifier; @@ -20,6 +20,7 @@ import com.lowdragmc.lowdraglib.gui.texture.IGuiTexture; import com.lowdragmc.lowdraglib.gui.util.ClickData; import com.lowdragmc.lowdraglib.gui.widget.ComponentPanelWidget; +import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; @@ -38,8 +39,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.List; +import java.util.*; public class LargeBoilerMachine extends WorkableMultiblockMachine implements IExplosionMachine, IDisplayUIMachine { @@ -68,9 +68,15 @@ public ManagedFieldHolder getFieldHolder() { return MANAGED_FIELD_HOLDER; } - ////////////////////////////////////// - // ****** Recipe Logic ******// - ////////////////////////////////////// + @Override + protected RecipeLogic createRecipeLogic(Object... args) { + return new LargeBoilerMachine.LargeBoilerRecipeLogic(this); + } + + @Override + public LargeBoilerMachine.LargeBoilerRecipeLogic getRecipeLogic() { + return (LargeBoilerMachine.LargeBoilerRecipeLogic) super.getRecipeLogic(); + } @Override public void onStructureFormed() { @@ -188,7 +194,8 @@ public boolean onWorking() { /** * Recipe Modifier for Large Boiler Machines - can be used as a valid {@link RecipeModifier} *

- * Duration is multiplied by {@code 100 / throttle} if throttle is less than 100 + * Does not modify recipe. Real recipe duration is determined by + * {@link LargeBoilerRecipeLogic#modifyFuelBurnTime(int)} *

* * @param machine a {@link LargeBoilerMachine} @@ -196,13 +203,7 @@ public boolean onWorking() { * @return A {@link ModifierFunction} for the given Large Boiler and recipe */ public static ModifierFunction recipeModifier(@NotNull MetaMachine machine, @NotNull GTRecipe recipe) { - if (!(machine instanceof LargeBoilerMachine largeBoilerMachine)) { - return RecipeModifier.nullWrongType(LargeBoilerMachine.class, machine); - } - if (largeBoilerMachine.throttle == 100) return ModifierFunction.IDENTITY; - return ModifierFunction.builder() - .durationMultiplier(100.0 / largeBoilerMachine.throttle) - .build(); + return ModifierFunction.IDENTITY; } public void addDisplayText(List textList) { @@ -232,6 +233,7 @@ public void handleDisplayClick(String componentData, ClickData clickData) { if (!clickData.isRemote) { int result = componentData.equals("add") ? 5 : -5; this.throttle = Mth.clamp(throttle + result, 25, 100); + this.getRecipeLogic().modifyFuelBurnTime(this.throttle); } } @@ -239,4 +241,35 @@ public void handleDisplayClick(String componentData, ClickData clickData) { public IGuiTexture getScreenTexture() { return GuiTextures.DISPLAY_STEAM.get(maxTemperature > 800); } + + public static class LargeBoilerRecipeLogic extends RecipeLogic { + + @Persisted + @DescSynced + @Getter + int currentThrottle; + + public LargeBoilerRecipeLogic(IRecipeLogicMachine machine) { + super(machine); + currentThrottle = 100; + } + + @Override + public void setupRecipe(GTRecipe recipe) { + super.setupRecipe(recipe); + if (lastRecipe != null) { + currentThrottle = ((LargeBoilerMachine) machine).getThrottle(); + duration = (int) Math.round(lastRecipe.duration / (currentThrottle / 100.0)); + } + } + + public void modifyFuelBurnTime(int newThrottle) { + if (lastRecipe != null) { + double newThrottleMultiplier = (double) currentThrottle / newThrottle; + duration = (int) Math.round(lastRecipe.duration / (newThrottle / 100.0)); + progress = (int) Math.round(newThrottleMultiplier * progress); + } + currentThrottle = newThrottle; + } + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/owner/ArgonautsOwner.java b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/ArgonautsOwner.java index b78f79bebf5..efd21d6c0dc 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/owner/ArgonautsOwner.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/ArgonautsOwner.java @@ -1,94 +1,94 @@ -package com.gregtechceu.gtceu.common.machine.owner; - -import com.gregtechceu.gtceu.GTCEu; - -import net.minecraft.network.chat.Component; -import net.neoforged.neoforge.server.ServerLifecycleHooks; - -import earth.terrarium.argonauts.api.client.guild.GuildClientApi; -import earth.terrarium.argonauts.api.guild.Guild; -import earth.terrarium.argonauts.api.guild.GuildApi; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.UnmodifiableView; - -import java.util.*; - -public non-sealed class ArgonautsOwner extends MachineOwner { - - private static final Component displayName = Component.translatable("gtceu.ownership.name.argonauts"); - - public ArgonautsOwner(UUID playerUUID) { - super(playerUUID); - } - - public @Nullable Guild getPlayerGuild(UUID playerUUID) { - if (GTCEu.isClientThread()) { - return GuildClientApi.API.getPlayerGuild(playerUUID); - } else { - return GuildApi.API.getPlayerGuild(ServerLifecycleHooks.getCurrentServer(), playerUUID); - } - } - - public @Nullable Guild getGuild() { - return getPlayerGuild(playerUUID); - } - - @UnmodifiableView - @Override - public @NotNull Set getMembers() { - var guild = getGuild(); - if (guild == null) return Collections.emptySet(); - Set members = new HashSet<>(guild.members().size()); - for (var member : guild.members().allMembers()) { - members.add(member.profile().getId()); - } - return members; - } - - @Override - public boolean isPlayerInTeam(UUID playerUUID) { - if (this.playerUUID.equals(playerUUID)) return true; - var otherGuild = getPlayerGuild(playerUUID); - return otherGuild != null && otherGuild.equals(getGuild()); - } - - @Override - public boolean isPlayerFriendly(UUID playerUUID) { - var guild = getGuild(); - if (guild == null) { - return this.playerUUID.equals(playerUUID); - } - return guild.isPublic() || guild.members().isMember(playerUUID) || guild.members().isAllied(playerUUID); - } - - @Override - public UUID getUUID() { - var guild = getGuild(); - return guild != null ? guild.id() : EMPTY; - } - - @Override - public String getName() { - var guild = getGuild(); - return guild != null ? guild.displayName().getString() : - Component.translatable("gtceu.tooltip.status.trinary.unknown").getString(); - } - - @Override - public Component getTypeDisplayName() { - return displayName; - } - - @Override - public void displayInfo(List compList) { - super.displayInfo(compList); - compList.add(Component.translatable("behavior.portable_scanner.guild_name", getName())); - MachineOwner.displayPlayerInfo(compList, playerUUID); - } - - @Override - public boolean equals(Object object) { - return object instanceof ArgonautsOwner && super.equals(object); - } -} +// package com.gregtechceu.gtceu.common.machine.owner; + +// import com.gregtechceu.gtceu.GTCEu; + +// import net.minecraft.network.chat.Component; +// import net.neoforged.neoforge.server.ServerLifecycleHooks; + +// import earth.terrarium.argonauts.api.client.guild.GuildClientApi; +// import earth.terrarium.argonauts.api.guild.Guild; +// import earth.terrarium.argonauts.api.guild.GuildApi; +// import org.jetbrains.annotations.NotNull; +// import org.jetbrains.annotations.Nullable; +// import org.jetbrains.annotations.UnmodifiableView; + +// import java.util.*; + +// public non-sealed class ArgonautsOwner extends MachineOwner { + +// private static final Component displayName = Component.translatable("gtceu.ownership.name.argonauts"); + +// public ArgonautsOwner(UUID playerUUID) { +// super(playerUUID); +// } + +// public @Nullable Guild getPlayerGuild(UUID playerUUID) { +// if (GTCEu.isClientThread()) { +// return GuildClientApi.API.getPlayerGuild(playerUUID); +// } else { +// return GuildApi.API.getPlayerGuild(ServerLifecycleHooks.getCurrentServer(), playerUUID); +// } +// } + +// public @Nullable Guild getGuild() { +// return getPlayerGuild(playerUUID); +// } + +// @UnmodifiableView +// @Override +// public @NotNull Set getMembers() { +// var guild = getGuild(); +// if (guild == null) return Collections.emptySet(); +// Set members = new HashSet<>(guild.members().size()); +// for (var member : guild.members().allMembers()) { +// members.add(member.profile().getId()); +// } +// return members; +// } + +// @Override +// public boolean isPlayerInTeam(UUID playerUUID) { +// if (this.playerUUID.equals(playerUUID)) return true; +// var otherGuild = getPlayerGuild(playerUUID); +// return otherGuild != null && otherGuild.equals(getGuild()); +// } + +// @Override +// public boolean isPlayerFriendly(UUID playerUUID) { +// var guild = getGuild(); +// if (guild == null) { +// return this.playerUUID.equals(playerUUID); +// } +// return guild.isPublic() || guild.members().isMember(playerUUID) || guild.members().isAllied(playerUUID); +// } + +// @Override +// public UUID getUUID() { +// var guild = getGuild(); +// return guild != null ? guild.id() : EMPTY; +// } + +// @Override +// public String getName() { +// var guild = getGuild(); +// return guild != null ? guild.displayName().getString() : +// Component.translatable("gtceu.tooltip.status.trinary.unknown").getString(); +// } + +// @Override +// public Component getTypeDisplayName() { +// return displayName; +// } + +// @Override +// public void displayInfo(List compList) { +// super.displayInfo(compList); +// compList.add(Component.translatable("behavior.portable_scanner.guild_name", getName())); +// MachineOwner.displayPlayerInfo(compList, playerUUID); +// } + +// @Override +// public boolean equals(Object object) { +// return object instanceof ArgonautsOwner && super.equals(object); +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/owner/MachineOwner.java b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/MachineOwner.java index cc4fdbb7fe2..10725b28714 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/owner/MachineOwner.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/owner/MachineOwner.java @@ -20,7 +20,7 @@ import java.util.*; import java.util.function.Function; -public abstract sealed class MachineOwner permits PlayerOwner, FTBOwner, ArgonautsOwner { +public abstract sealed class MachineOwner permits PlayerOwner, FTBOwner { private static Function machineOwnerGenerator; public static final UUID EMPTY = new UUID(0, 0); @@ -44,8 +44,8 @@ public static void init() { var event = new RegisterOwnerTypeEvent(); if (GTCEu.Mods.isFTBTeamsLoaded()) { event.register(0, FTBOwner::new); - } else if (GTCEu.Mods.isArgonautsLoaded()) { - event.register(0, ArgonautsOwner::new); + // } else if (GTCEu.Mods.isArgonautsLoaded()) { + // event.register(0, ArgonautsOwner::new); } else { event.register(0, PlayerOwner::new); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/steam/SteamLiquidBoilerMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/steam/SteamLiquidBoilerMachine.java index 5b76325aa41..c8ad7134dd5 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/steam/SteamLiquidBoilerMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/steam/SteamLiquidBoilerMachine.java @@ -14,11 +14,18 @@ import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; +import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.util.RandomSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.phys.BlockHitResult; import net.neoforged.neoforge.fluids.FluidType; +import net.neoforged.neoforge.fluids.FluidUtil; import it.unimi.dsi.fastutil.objects.Object2BooleanMap; import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap; @@ -86,4 +93,19 @@ protected void randomDisplayTick(RandomSource random, float x, float y, float z) 0.0F); } } + + @Override + public InteractionResult onUse(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, + BlockHitResult hit) { + if (!isRemote()) { + if (super.onUse(state, world, pos, player, hand, hit) == InteractionResult.SUCCESS) { + return InteractionResult.SUCCESS; + } + if (FluidUtil.interactWithFluidHandler(player, hand, fuelTank)) { + return InteractionResult.SUCCESS; + } + return InteractionResult.PASS; + } + return super.onUse(state, world, pos, player, hand, hit); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CrateMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CrateMachine.java index ce51acfa144..fd7e8b40abc 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CrateMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CrateMachine.java @@ -8,6 +8,7 @@ import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.*; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; import com.gregtechceu.gtceu.api.material.material.Material; import com.gregtechceu.gtceu.data.item.GTDataComponents; @@ -27,6 +28,7 @@ import net.minecraft.util.Unit; import net.minecraft.world.InteractionHand; import net.minecraft.world.ItemInteractionResult; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.ItemContainerContents; @@ -38,13 +40,15 @@ import lombok.Getter; import org.jetbrains.annotations.NotNull; +import javax.annotation.Nullable; + public class CrateMachine extends MetaMachine implements IUIMachine, IMachineLife, IDropSaveMachine, IInteractedMachine { public static final ManagedFieldHolder MANAGED_FIELD_HOLDER = new ManagedFieldHolder(CrateMachine.class, MetaMachine.MANAGED_FIELD_HOLDER); - public static final BooleanProperty TAPED_PROPERTY = BooleanProperty.create("taped"); + public static final BooleanProperty TAPED_PROPERTY = GTMachineModelProperties.IS_TAPED; @Override public @NotNull ManagedFieldHolder getFieldHolder() { @@ -113,7 +117,7 @@ public ItemInteractionResult onUseWithItem(ItemStack stack, BlockState state, Le } @Override - public void applyImplicitComponents(MetaMachineBlockEntity.@NotNull ExDataComponentInput componentInput) { + public void applyImplicitComponents(MetaMachineBlockEntity.ExDataComponentInput componentInput) { super.applyImplicitComponents(componentInput); if (componentInput.get(DataComponents.CONTAINER) != null) { var contents = componentInput.getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY); @@ -122,8 +126,19 @@ public void applyImplicitComponents(MetaMachineBlockEntity.@NotNull ExDataCompon } } + public void onMachinePlaced(@Nullable LivingEntity player, ItemStack stack) { + IMachineLife.super.onMachinePlaced(player, stack); + // CompoundTag tag = stack.getTag(); + if (stack.getOrDefault(GTDataComponents.TAPED, null) != null) { + var contents = stack.getOrDefault(DataComponents.CONTAINER, ItemContainerContents.EMPTY); + contents.copyInto(inventory.storage.getStacks()); + setRenderState(getRenderState().setValue(TAPED_PROPERTY, false)); + } + setRenderState(getRenderState().setValue(GTMachineModelProperties.IS_TAPED, isTaped)); + } + @Override - public void collectImplicitComponents(DataComponentMap.@NotNull Builder components) { + public void collectImplicitComponents(DataComponentMap.Builder components) { super.collectImplicitComponents(components); if (isTaped) { components.set(GTDataComponents.TAPED, Unit.INSTANCE); @@ -132,7 +147,7 @@ public void collectImplicitComponents(DataComponentMap.@NotNull Builder componen } @Override - public void removeItemComponentsFromTag(@NotNull CompoundTag tag) { + public void removeItemComponentsFromTag(CompoundTag tag) { super.removeItemComponentsFromTag(tag); tag.remove("isTaped"); tag.remove("inventory"); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeChestMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeChestMachine.java index 3306c239094..eaceace6779 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeChestMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/CreativeChestMachine.java @@ -8,6 +8,7 @@ import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.data.item.GTDataComponents; +import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; import com.lowdragmc.lowdraglib.gui.texture.ResourceBorderTexture; @@ -187,7 +188,7 @@ public void setStackInSlot(int index, ItemStack stack) { @Override public @NotNull ItemStack insertItem(int slot, @NotNull ItemStack stack, boolean simulate) { - if (!stored.isEmpty() && ItemStack.isSameItemSameComponents(stored, stack)) return ItemStack.EMPTY; + if (!stored.isEmpty() && GTUtil.isSameItemSameTags(stored, stack)) return ItemStack.EMPTY; return stack; } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/DrumMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/DrumMachine.java index be82a4782ee..25a71c63deb 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/DrumMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/DrumMachine.java @@ -13,6 +13,7 @@ import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.api.material.material.Material; import com.gregtechceu.gtceu.api.material.material.properties.PropertyKey; +import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.item.GTDataComponents; import com.gregtechceu.gtceu.utils.GTTransferUtils; @@ -59,6 +60,8 @@ public class DrumMachine extends MetaMachine implements IAutoOutputFluid, IDropS @DescSynced @RequireRerender protected boolean autoOutputFluids; + @Persisted + protected boolean allowInputFromOutputSideFluids; @Getter private final int maxStoredFluids; @Persisted @@ -163,14 +166,20 @@ public void setAutoOutputFluids(boolean allow) { updateAutoOutputSubscription(); } + private static boolean canInputFluidsFromOutputSide() { + return ConfigHolder.INSTANCE.machines.allowDrumsInputFluidsFromOutputSide; + } + @Override public boolean isAllowInputFromOutputSideFluids() { - return false; + return canInputFluidsFromOutputSide() && this.allowInputFromOutputSideFluids; } - // always is facing down, and can never accept fluids from output side + // always is facing down, and can never accept fluids from output side by default @Override - public void setAllowInputFromOutputSideFluids(boolean allow) {} + public void setAllowInputFromOutputSideFluids(boolean allow) { + this.allowInputFromOutputSideFluids = allow; + } @Override public void setOutputFacingFluids(@Nullable Direction outputFacing) { @@ -231,27 +240,65 @@ protected ItemInteractionResult onScrewdriverClick(Player playerIn, InteractionH Direction gridSide, BlockHitResult hitResult) { if (!isRemote()) { - if (!playerIn.isShiftKeyDown()) { + if (canInputFluidsFromOutputSide()) { + setAllowInputFromOutputSideFluids(!isAllowInputFromOutputSideFluids()); + playerIn.sendSystemMessage( + Component + .translatable("gtceu.machine.basic.input_from_output_side." + + (isAllowInputFromOutputSideFluids() ? "allow" : "disallow")) + .append(Component.translatable("gtceu.creative.tank.fluid"))); + } else if (!playerIn.isShiftKeyDown()) { setAutoOutputFluids(!isAutoOutputFluids()); playerIn.sendSystemMessage(Component .translatable("gtceu.machine.drum." + (autoOutputFluids ? "enable" : "disable") + "_output")); return ItemInteractionResult.SUCCESS; } + return ItemInteractionResult.SUCCESS; } return super.onScrewdriverClick(playerIn, hand, held, gridSide, hitResult); } + @Override + protected ItemInteractionResult onSoftMalletClick(Player playerIn, InteractionHand hand, ItemStack held, + Direction gridSide, + BlockHitResult hitResult) { + if (!isRemote()) { + if (!playerIn.isShiftKeyDown()) { + setAutoOutputFluids(!isAutoOutputFluids()); + playerIn.sendSystemMessage(Component + .translatable("gtceu.machine.drum." + (autoOutputFluids ? "enable" : "disable") + "_output")); + return ItemInteractionResult.SUCCESS; + } + } + return super.onSoftMalletClick(playerIn, hand, held, gridSide, hitResult); + } + ////////////////////////////////////// // ******* Rendering ********// ////////////////////////////////////// + + @Override + public boolean shouldRenderGrid(Player player, BlockPos pos, BlockState state, ItemStack held, + Set toolTypes) { + return super.shouldRenderGrid(player, pos, state, held, toolTypes) || + toolTypes.contains(GTToolType.SOFT_MALLET) || toolTypes.contains(GTToolType.SCREWDRIVER); + } + @Override public ResourceTexture sideTips(Player player, BlockPos pos, BlockState state, Set toolTypes, ItemStack held, Direction side) { - if (toolTypes.contains(GTToolType.SCREWDRIVER)) { + if (toolTypes.contains(GTToolType.SOFT_MALLET) || + (!canInputFluidsFromOutputSide() && toolTypes.contains(GTToolType.SCREWDRIVER))) { if (side == getOutputFacingFluids()) { return isAutoOutputFluids() ? GuiTextures.TOOL_DISABLE_AUTO_OUTPUT : GuiTextures.TOOL_AUTO_OUTPUT; } } + if (canInputFluidsFromOutputSide() && toolTypes.contains(GTToolType.SCREWDRIVER)) { + if (side == getOutputFacingFluids()) { + return GuiTextures.TOOL_ALLOW_INPUT; + } + } + return super.sideTips(player, pos, state, toolTypes, held, side); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumChestMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumChestMachine.java index 0bc1528518c..e7be7914af4 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumChestMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumChestMachine.java @@ -26,6 +26,7 @@ import com.gregtechceu.gtceu.utils.FormattingUtil; import com.gregtechceu.gtceu.utils.GTMath; import com.gregtechceu.gtceu.utils.GTTransferUtils; +import com.gregtechceu.gtceu.utils.GTUtil; import com.lowdragmc.lowdraglib.gui.editor.Icons; import com.lowdragmc.lowdraglib.gui.texture.GuiTextureGroup; @@ -53,7 +54,6 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; -import net.neoforged.neoforge.common.Tags; import net.neoforged.neoforge.items.IItemHandlerModifiable; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; @@ -332,7 +332,7 @@ private static boolean isDoubleHit(UUID uuid) { @Override public boolean onLeftClick(Player player, Level world, InteractionHand hand, BlockPos pos, Direction direction) { if (direction == getFrontFacing() && !isRemote()) { - if (player.getItemInHand(hand).is(Tags.Items.TOOLS_WRENCH)) return false; + if (GTToolType.WRENCH.matchTags.stream().anyMatch(player.getItemInHand(hand)::is)) return false; if (!stored.isEmpty()) { // pull var drained = cache.extractItem(0, player.isShiftKeyDown() ? stored.getMaxStackSize() : 1, false); if (!drained.isEmpty()) { @@ -439,7 +439,7 @@ public Widget createUIWidget() { } })) .addWidget(new PhantomSlotWidget(lockedItem, 0, 58, 41, - stack -> stored.isEmpty() || ItemStack.isSameItemSameComponents(stack, stored)) + stack -> stored.isEmpty() || GTUtil.isSameItemSameTags(stack, stored)) .setMaxStackSize(1)) .addWidget(new ToggleButtonWidget(4, 41, 18, 18, GuiTextures.BUTTON_ITEM_OUTPUT, this::isAutoOutputItems, this::setAutoOutputItems) @@ -496,7 +496,7 @@ public ResourceTexture sideTips(Player player, BlockPos pos, BlockState state, S protected class ItemCache extends MachineTrait implements IItemHandlerModifiable { private final Predicate filter = i -> !isLocked() || - ItemStack.isSameItemSameComponents(i, getLockedItem()); + GTUtil.isSameItemSameTags(i, getLockedItem()); public ItemCache(MetaMachine holder) { super(holder); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumTankMachine.java b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumTankMachine.java index 2c83c3ca6dd..e95802428a4 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumTankMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/storage/QuantumTankMachine.java @@ -15,6 +15,7 @@ import com.gregtechceu.gtceu.api.machine.feature.IFancyUIMachine; import com.gregtechceu.gtceu.api.machine.feature.IInteractedMachine; import com.gregtechceu.gtceu.api.machine.trait.MachineTrait; +import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.api.transfer.fluid.CustomFluidTank; import com.gregtechceu.gtceu.api.transfer.fluid.IFluidHandlerModifiable; import com.gregtechceu.gtceu.core.MixinHelpers; @@ -59,9 +60,11 @@ import it.unimi.dsi.fastutil.objects.Object2LongMap; import lombok.Getter; import lombok.Setter; +import org.apache.logging.log4j.LogManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Objects; import java.util.Set; import java.util.function.Predicate; @@ -156,8 +159,12 @@ public boolean saveBreak() { @Override public void saveCustomPersistedData(@NotNull CompoundTag tag, boolean forDrop) { super.saveCustomPersistedData(tag, forDrop); - if (!forDrop) tag.put("lockedFluid", lockedFluid.serializeNBT(MixinHelpers.getCurrentBERegistries())); - tag.put("stored", stored.save(MixinHelpers.getCurrentBERegistries())); + if (!forDrop) tag.put("lockedFluid", lockedFluid.serializeNBT(GTRegistries.builtinRegistry())); + if (!stored.isEmpty()) { + tag.put("stored", stored.save(GTRegistries.builtinRegistry())); + } else { + tag.remove("stored"); + } tag.putLong("storedAmount", storedAmount); } @@ -166,10 +173,18 @@ public void loadCustomPersistedData(@NotNull CompoundTag tag) { super.loadCustomPersistedData(tag); var from = tag.contains("cache") ? tag.getCompound("cache") : tag; - this.lockedFluid.readFromNBT(MixinHelpers.getCurrentBERegistries(), from.getCompound("lockedFluid")); - - var stored = FluidStack.parseOptional(MixinHelpers.getCurrentBERegistries(), tag.getCompound("stored")); - this.stored = stored.copyWithAmount(FluidType.BUCKET_VOLUME); + var registry = Objects.requireNonNullElse(MixinHelpers.getCurrentBERegistries(), + GTRegistries.builtinRegistry()); + this.lockedFluid.readFromNBT(registry, from.getCompound("lockedFluid")); + + if (tag.contains("stored")) { + var v = MixinHelpers.getCurrentBERegistries(); + LogManager.getLogger().warn("{}", v); + var stored = FluidStack.parseOptional(registry, tag.getCompound("stored")); + this.stored = stored.copyWithAmount(FluidType.BUCKET_VOLUME); + } else { + this.stored = FluidStack.EMPTY; + } if (!tag.contains("storedAmount")) this.storedAmount = stored.getAmount(); else this.storedAmount = tag.getLong("storedAmount"); diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/CentralMonitorLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/CentralMonitorLogic.java new file mode 100644 index 00000000000..0d4b9cec954 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/CentralMonitorLogic.java @@ -0,0 +1,75 @@ +package com.gregtechceu.gtceu.common.machine.trait; + +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.capability.IWorkable; +import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.misc.EnergyContainerList; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine; + +import net.minecraft.util.Mth; + +public class CentralMonitorLogic extends RecipeLogic implements IWorkable { + + private static final int BASE_UPDATE_INTERVAL = 8 * 20; + + public CentralMonitorLogic(IRecipeLogicMachine machine) { + super(machine); + } + + public CentralMonitorMachine getMachine() { + return (CentralMonitorMachine) machine; + } + + private boolean consumeEnergy() { + int tier = Mth.clamp(getMachine().getTier(), GTValues.ULV, GTValues.MAX); + long energyToDrain = GTValues.VA[tier]; + EnergyContainerList energyContainer = getMachine().getFormedEnergyContainer(); + if (energyContainer == null) { + return false; + } + + long resultEnergy = energyContainer.getEnergyStored() - energyToDrain; + if (resultEnergy >= 0L && resultEnergy <= energyContainer.getEnergyCapacity()) { + energyContainer.removeEnergy(energyToDrain); + return true; + } + return false; + } + + private int getUpdateInterval() { + int interval = BASE_UPDATE_INTERVAL; + for (int i = 1; i < getMachine().getTier(); i++) { + interval /= 2; + } + return Math.max(interval, 1); + } + + @Override + public void serverTick() { + if (!getMachine().isFormed() || !isWorkingEnabled()) { + setStatus(Status.IDLE); + } else if (consumeEnergy()) { + setStatus(Status.WORKING); + isActive = true; + progress = (progress + 1) % getUpdateInterval(); + if (progress == 0) { + getMachine().tick(); + } + } else { + setStatus(Status.WAITING); + isActive = false; + progress = Math.max(progress - 2, 1); + } + } + + @Override + public int getMaxProgress() { + return getUpdateInterval(); + } + + @Override + public boolean isActive() { + return getMachine().isFormed() && this.isActive; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/CleanroomLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/CleanroomLogic.java index 9f17bb636ac..dd83079f14a 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/CleanroomLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/CleanroomLogic.java @@ -8,7 +8,6 @@ import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.common.capability.EnvironmentalHazardSavedData; import com.gregtechceu.gtceu.common.machine.multiblock.electric.CleanroomMachine; -import com.gregtechceu.gtceu.config.ConfigHolder; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; @@ -70,11 +69,7 @@ public void serverTick() { // drain the energy if (!consumeEnergy()) { if (progress > 0 && machine.regressWhenWaiting()) { - if (ConfigHolder.INSTANCE.machines.recipeProgressLowEnergy) { - this.progress = 1; - } else { - this.progress = Math.max(1, progress - 2); - } + this.progress = 1; } // the cleanroom does not have enough energy, so it looses cleanliness diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/ConverterTrait.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/ConverterTrait.java index db2c3317dd9..69403343fde 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/ConverterTrait.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/ConverterTrait.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; import com.gregtechceu.gtceu.api.capability.compat.FeCompat; import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.MachineTrait; import com.gregtechceu.gtceu.api.machine.trait.NotifiableEnergyContainer; import com.gregtechceu.gtceu.common.machine.electric.ConverterMachine; @@ -58,7 +59,7 @@ public ManagedFieldHolder getFieldHolder() { public void setFeToEu(boolean feToEu) { this.feToEu = feToEu; - setRenderState(getRenderState().setValue(ConverterMachine.FE_TO_EU_PROPERTY, feToEu)); + setRenderState(getRenderState().setValue(GTMachineModelProperties.IS_FE_TO_EU, feToEu)); machine.notifyBlockUpdate(); } @@ -102,7 +103,7 @@ public FEContainer(MetaMachine machine) { @Override public int receiveEnergy(int maxReceive, boolean simulate) { if (!feToEu || maxReceive <= 0) return 0; - int received = Math.min(this.getMaxEnergyStored() - this.getEnergyStored(), maxReceive); + int received = (int) (Math.min(this.getMaxLongEnergyStored() - this.getLongEnergyStored(), maxReceive)); received -= received % FeCompat.ratio(true); // avoid rounding issues if (!simulate) { addEnergy(FeCompat.toEu(received, FeCompat.ratio(true))); @@ -110,6 +111,14 @@ public int receiveEnergy(int maxReceive, boolean simulate) { return received; } + public long getMaxLongEnergyStored() { + return FeCompat.toFeLong(ConverterTrait.this.getEnergyCapacity(), FeCompat.ratio(feToEu)); + } + + public long getLongEnergyStored() { + return FeCompat.toFeLong(ConverterTrait.this.getEnergyStored(), FeCompat.ratio(feToEu)); + } + @Override public int extractEnergy(int maxExtract, boolean simulate) { return 0; diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java index e26241d652d..4fb4ece8216 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/customlogic/MaceratorLogic.java @@ -47,7 +47,7 @@ public enum MaceratorLogic implements GTRecipeType.ICustomRecipeLogic { return null; } - private @Nullable GTRecipe search(ItemStack stack) { + public @Nullable GTRecipe search(ItemStack stack) { var turbineBehaviour = TurbineRotorBehaviour.getBehaviour(stack); if (turbineBehaviour != null) { float durability = 1.f - (float) turbineBehaviour.getPartDamage(stack) / diff --git a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java index bc901dbb52f..750c7afbe53 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java +++ b/src/main/java/com/gregtechceu/gtceu/common/machine/trait/miner/MinerLogic.java @@ -3,6 +3,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.capability.IMiner; import com.gregtechceu.gtceu.api.capability.recipe.*; +import com.gregtechceu.gtceu.api.item.MaterialBlockItem; import com.gregtechceu.gtceu.api.item.tool.GTToolType; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.feature.IRecipeLogicMachine; @@ -69,6 +70,7 @@ public class MinerLogic extends RecipeLogic implements IRecipeCapabilityHolder { @Getter public ItemStack pickaxeTool; private final LinkedList blocksToMine = new LinkedList<>(); + private int blocksToMineOriginalCount = 0; @Getter @Persisted protected int x = Integer.MAX_VALUE; @@ -186,7 +188,16 @@ public void inValid() { this.pipeLength = 0; } - private static BlockState findMiningReplacementBlock(Level level) { + private static BlockState findMiningReplacementBlock(Level level, BlockPos pos) { + if (ConfigHolder.INSTANCE.machines.replaceWithCobbleVersion) { + BlockState oreState = level.getBlockState(pos); + if (oreState.getBlock().asItem() instanceof MaterialBlockItem matBlockItem) { + var prefix = matBlockItem.tagPrefix; + if (!GTBlocks.COBBLE_BLOCKS.containsKey(prefix)) return Blocks.COBBLESTONE.defaultBlockState(); + return GTBlocks.COBBLE_BLOCKS.get(prefix).get(); + } + } + try { return BlockStateParser.parseForBlock(level.holderLookup(Registries.BLOCK), ConfigHolder.INSTANCE.machines.replaceMinedBlocksWith, false).blockState(); @@ -369,13 +380,18 @@ protected boolean doPostProcessing(NonNullList blockDrops, BlockState var matches = machine.getRecipeType().searchRecipe(this, r -> RecipeHelper.matchContents(this, r).isSuccess()); + GTRecipe recipe = null; // attempt ore block that has a static gt recipe while (matches.hasNext()) { GTRecipe match = matches.next(); if (match == null) continue; + recipe = match; + break; + } - long eut = match.getInputEUt().getTotalEU(); + if (recipe != null) { + long eut = recipe.getInputEUt().getTotalEU(); if (GTUtil.getTierByVoltage(eut) <= getVoltageTier()) { - if (RecipeHelper.handleRecipeIO(this, match, IO.OUT, this.chanceCaches).isSuccess()) { + if (RecipeHelper.handleRecipeIO(this, recipe, IO.OUT, this.chanceCaches).isSuccess()) { blockDrops.clear(); var result = new ArrayList(); for (int i = 0; i < outputItemHandler.storage.getSlots(); ++i) { @@ -432,10 +448,11 @@ private void mineAndInsertItems(NonNullList blockDrops, ServerLevel w if (handler != null) { if (GTTransferUtils.addItemsToItemHandler(handler, true, blockDrops)) { GTTransferUtils.addItemsToItemHandler(handler, false, blockDrops); - world.setBlock(blocksToMine.getFirst(), findMiningReplacementBlock(world), 3); - mineX = blocksToMine.getFirst().getX(); - mineZ = blocksToMine.getFirst().getZ(); - mineY = blocksToMine.getFirst().getY(); + var pos = blocksToMine.getFirst(); + world.setBlock(pos, findMiningReplacementBlock(world, pos), 3); + mineX = pos.getX(); + mineZ = pos.getZ(); + mineY = pos.getY(); blocksToMine.removeFirst(); onMineOperation(); @@ -493,8 +510,10 @@ private boolean checkCoordinatesInvalid() { * Checks whether there are any more blocks to mine, if there are currently none queued */ public void checkBlocksToMine() { - if (blocksToMine.isEmpty()) + if (blocksToMine.isEmpty()) { blocksToMine.addAll(getBlocksToMine()); + blocksToMineOriginalCount = blocksToMine.size(); + } } /** @@ -632,4 +651,16 @@ public void onRemove() { } } } + + @Override + public boolean hasCustomProgressLine() { + return true; + } + + @Nullable + @Override + public Component getCustomProgressLine() { + return Component.translatable("gtceu.machine.miner.progress", blocksToMineOriginalCount - blocksToMine.size(), + blocksToMineOriginalCount); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/network/GTNetwork.java b/src/main/java/com/gregtechceu/gtceu/common/network/GTNetwork.java index 4422c975f16..ea993d220c9 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/network/GTNetwork.java +++ b/src/main/java/com/gregtechceu/gtceu/common/network/GTNetwork.java @@ -7,6 +7,10 @@ import com.gregtechceu.gtceu.common.network.packets.prospecting.SPacketProspectBedrockOre; import com.gregtechceu.gtceu.common.network.packets.prospecting.SPacketProspectOre; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.chunk.LevelChunk; +import net.neoforged.neoforge.network.PacketDistributor; import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent; import net.neoforged.neoforge.network.registration.PayloadRegistrar; @@ -28,6 +32,41 @@ public static void registerPayloads(RegisterPayloadHandlersEvent event) { registar.playToClient(SPacketProspectBedrockOre.TYPE, SPacketProspectBedrockOre.CODEC, SPacketProspectBedrockOre::execute); registar.playToClient(SPacketSendWorldID.TYPE, SPacketSendWorldID.CODEC, SPacketSendWorldID::execute); registar.playBidirectional(SCPacketShareProspection.TYPE, SCPacketShareProspection.CODEC, SCPacketShareProspection::execute); - // spotless:on + // spotless:on } + + public static void sendToServer(CustomPacketPayload packet) { + PacketDistributor.sendToServer(packet); + } + + // public static void sendToPlayersInLevel(ResourceKey level, INetPacket packet) { + // INSTANCE.send(PacketDistributor.DIMENSION.with(() -> level), packet); + // } + + // public static void sendToPlayersNearPoint(PacketDistributor.TargetPoint point, INetPacket packet) { + // INSTANCE.send(PacketDistributor.NEAR.with(() -> point), packet); + // } + + // public static void sendToAllPlayersTrackingEntity(Entity entity, boolean includeSelf, INetPacket packet) { + // INSTANCE.send(includeSelf ? PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> entity) : + // PacketDistributor.TRACKING_ENTITY.with(() -> entity), packet); + // } + + public static void sendToAllPlayersTrackingChunk(LevelChunk chunk, CustomPacketPayload packet) { + PacketDistributor.sendToPlayersTrackingChunk((ServerLevel) chunk.getLevel(), chunk.getPos(), packet); + } + + // public static void sendToAll(INetPacket packet) { + // INSTANCE.send(PacketDistributor.ALL.noArg(), packet); + // } + + // public static void sendToPlayer(ServerPlayer player, INetPacket packet) { + // INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), packet); + // } + + // public static void reply(NetworkEvent.Context context, INetPacket packet) { + // INSTANCE.reply(packet, context); + // } + + // public interface INetPacket { } diff --git a/src/main/java/com/gregtechceu/gtceu/common/network/packets/CPacketImageRequest.java b/src/main/java/com/gregtechceu/gtceu/common/network/packets/CPacketImageRequest.java new file mode 100644 index 00000000000..15675822945 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/network/packets/CPacketImageRequest.java @@ -0,0 +1,49 @@ +package com.gregtechceu.gtceu.common.network.packets; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.misc.ImageCache; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.network.handling.IPayloadContext; + +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +public class CPacketImageRequest implements CustomPacketPayload { + + public static final ResourceLocation ID = GTCEu.id("image_request"); + public static final Type TYPE = new Type<>(ID); + public static final StreamCodec CODEC = StreamCodec + .ofMember(CPacketImageRequest::encode, CPacketImageRequest::new); + + private final String url; + + public CPacketImageRequest(String url) { + this.url = url; + } + + public CPacketImageRequest(FriendlyByteBuf buf) { + this.url = buf.readUtf(); + } + + public void encode(FriendlyByteBuf buffer) { + buffer.writeUtf(url); + } + + public void execute(IPayloadContext context) { + ImageCache.queryServerImage(url, image -> { + try { + SPacketImageResponse.sendImage(url, image, context); + } catch (IOException ignored) {} + }); + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/network/packets/CPacketKeyDown.java b/src/main/java/com/gregtechceu/gtceu/common/network/packets/CPacketKeyDown.java new file mode 100644 index 00000000000..a58f665e0eb --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/network/packets/CPacketKeyDown.java @@ -0,0 +1,59 @@ +package com.gregtechceu.gtceu.common.network.packets; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.utils.input.SyncedKeyMapping; + +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.neoforged.neoforge.network.handling.IPayloadContext; + +import it.unimi.dsi.fastutil.ints.Int2BooleanMap; +import it.unimi.dsi.fastutil.ints.Int2BooleanOpenHashMap; +import org.jetbrains.annotations.NotNull; + +public class CPacketKeyDown implements CustomPacketPayload { + + public static final ResourceLocation ID = GTCEu.id("key_down"); + public static final Type TYPE = new Type<>(ID); + public static final StreamCodec CODEC = StreamCodec + .ofMember(CPacketKeyDown::encode, CPacketKeyDown::new); + + private final Int2BooleanMap updateKeys; + + public CPacketKeyDown(Int2BooleanMap updateKeys) { + this.updateKeys = updateKeys; + } + + public CPacketKeyDown(RegistryFriendlyByteBuf buf) { + this.updateKeys = new Int2BooleanOpenHashMap(); + int size = buf.readInt(); + for (int i = 0; i < size; i++) { + updateKeys.put(buf.readInt(), buf.readBoolean()); + } + } + + public void encode(RegistryFriendlyByteBuf buf) { + buf.writeInt(updateKeys.size()); + for (var entry : updateKeys.int2BooleanEntrySet()) { + buf.writeInt(entry.getIntKey()); + buf.writeBoolean(entry.getBooleanValue()); + } + } + + public void execute(IPayloadContext context) { + if (context.player() instanceof ServerPlayer player) { + for (var entry : updateKeys.int2BooleanEntrySet()) { + SyncedKeyMapping keyMapping = SyncedKeyMapping.getFromSyncId(entry.getIntKey()); + keyMapping.serverActivate(entry.getBooleanValue(), player); + } + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/network/packets/CPacketKeysPressed.java b/src/main/java/com/gregtechceu/gtceu/common/network/packets/CPacketKeysPressed.java index 1548d0f9d48..8d12d907a17 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/network/packets/CPacketKeysPressed.java +++ b/src/main/java/com/gregtechceu/gtceu/common/network/packets/CPacketKeysPressed.java @@ -16,6 +16,7 @@ import java.util.List; +@Deprecated @SuppressWarnings("unchecked") @NoArgsConstructor public class CPacketKeysPressed implements CustomPacketPayload { diff --git a/src/main/java/com/gregtechceu/gtceu/common/network/packets/SCPacketMonitorGroupNBTChange.java b/src/main/java/com/gregtechceu/gtceu/common/network/packets/SCPacketMonitorGroupNBTChange.java new file mode 100644 index 00000000000..9406f05aec5 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/network/packets/SCPacketMonitorGroupNBTChange.java @@ -0,0 +1,83 @@ +package com.gregtechceu.gtceu.common.network.packets; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.CentralMonitorMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; + +import net.minecraft.client.Minecraft; +import net.minecraft.core.BlockPos; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.neoforged.neoforge.common.util.LogicalSidedProvider; +import net.neoforged.neoforge.network.handling.IPayloadContext; + +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +public class SCPacketMonitorGroupNBTChange implements CustomPacketPayload { + + public static final ResourceLocation ID = GTCEu.id("spacket_monitor_group_nbt_change"); + public static final Type TYPE = new Type<>(ID); + public static final StreamCodec CODEC = StreamCodec + .ofMember(SCPacketMonitorGroupNBTChange::encode, SCPacketMonitorGroupNBTChange::new); + + private final ItemStack stack; + private final int monitorGroupId; + private final BlockPos pos; + + public SCPacketMonitorGroupNBTChange(ItemStack stack, MonitorGroup group, CentralMonitorMachine machine) { + this.stack = stack; + this.monitorGroupId = machine.getMonitorGroups().indexOf(group); + this.pos = machine.getPos(); + } + + public SCPacketMonitorGroupNBTChange(RegistryFriendlyByteBuf buf) { + this.stack = ItemStack.STREAM_CODEC.decode(buf); + this.monitorGroupId = buf.readVarInt(); + this.pos = buf.readBlockPos(); + } + + public void encode(RegistryFriendlyByteBuf buffer) { + ItemStack.STREAM_CODEC.encode(buffer, stack); + // buffer.writeItemStack(stack, false); + buffer.writeVarInt(monitorGroupId); + buffer.writeBlockPos(pos); + } + + public void execute(IPayloadContext context) { + Level level = LogicalSidedProvider.CLIENTWORLD.get(context.flow().getReceptionSide()) + .or(() -> { + if (context.player() instanceof ServerPlayer player) { + return Optional.ofNullable(player).map(ServerPlayer::level); + } + return Optional.empty(); + }) + .orElse(null); + if (level == null) return; + + MetaMachine machine = MetaMachine.getMachine(level, pos); + if (machine instanceof CentralMonitorMachine centralMonitor) { + centralMonitor.getMonitorGroups().get(monitorGroupId) + .getItemStackHandler().setStackInSlot(0, stack); + } + } + + private static class ClientCallWrapper { + + private static Level getClientLevel() { + return Minecraft.getInstance().level; + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/network/packets/SPacketImageResponse.java b/src/main/java/com/gregtechceu/gtceu/common/network/packets/SPacketImageResponse.java new file mode 100644 index 00000000000..29990bafc68 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/network/packets/SPacketImageResponse.java @@ -0,0 +1,87 @@ +package com.gregtechceu.gtceu.common.network.packets; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.client.util.ClientImageCache; +import com.gregtechceu.gtceu.utils.GTMath; + +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.network.handling.IPayloadContext; + +import org.apache.commons.lang3.ArrayUtils; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; + +public class SPacketImageResponse implements CustomPacketPayload { + + public static final ResourceLocation ID = GTCEu.id("packet_image_response"); + public static final Type TYPE = new Type<>(ID); + public static final StreamCodec CODEC = StreamCodec + .ofMember(SPacketImageResponse::encode, SPacketImageResponse::new); + + private static final int MAX_BYTES_PER_PACKET = 120000; + + private final byte[] imagePart; + private final String url; + private final int index; + private final int totalSize; + + public SPacketImageResponse(String url, byte[] imagePart, int index, int totalSize) { + this.url = url; + this.imagePart = imagePart; + this.index = index; + this.totalSize = totalSize; + } + + public SPacketImageResponse(FriendlyByteBuf buf) { + this.index = buf.readInt(); + this.totalSize = buf.readInt(); + this.url = buf.readUtf(); + this.imagePart = buf.readByteArray(); + } + + public void encode(FriendlyByteBuf buffer) { + buffer.writeInt(index); + buffer.writeInt(totalSize); + buffer.writeUtf(url); + buffer.writeByteArray(imagePart); + } + + public void execute(IPayloadContext context) { + if (imagePart == null) { + return; + } + try { + ClientImageCache.receiveImagePart(url, imagePart, index, totalSize); + } catch (IOException ignored) {} + } + + public static void sendImage(String url, byte[] imageBytes, IPayloadContext context) throws IOException { + if (imageBytes.length < MAX_BYTES_PER_PACKET) { + context.reply(new SPacketImageResponse(url, imageBytes, 0, 1)); + } else { + int packetCount = GTMath.ceilDiv(imageBytes.length, MAX_BYTES_PER_PACKET); + int arrayIndex = 0; + + for (int i = 0; i < packetCount; i++) { + int remaining = imageBytes.length - arrayIndex; + if (remaining <= 0) { + break; + } + + byte[] part = ArrayUtils.subarray(imageBytes, arrayIndex, arrayIndex + MAX_BYTES_PER_PACKET); + context.reply(new SPacketImageResponse(url, part, i, packetCount)); + + arrayIndex += MAX_BYTES_PER_PACKET; + } + } + } + + @Override + public @NotNull Type type() { + return TYPE; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetHandler.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetHandler.java index 958e09d1498..47c1d174e40 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetHandler.java @@ -13,6 +13,7 @@ import com.gregtechceu.gtceu.common.cover.data.DistributionMode; import com.gregtechceu.gtceu.common.cover.data.FilterMode; import com.gregtechceu.gtceu.utils.FacingPos; +import com.gregtechceu.gtceu.utils.GTUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -114,7 +115,7 @@ public static boolean checkImportCover(CoverBehavior cover, boolean onPipe, Item } public ItemStack insertFirst(ItemStack stack, boolean simulate) { - for (ItemRoutePath inv : net.getNetData(pipe.getPipePos(), facing)) { + for (ItemRoutePath inv : net.getNetData(pipe.getPipePos(), facing, ItemRoutePathSet.FULL)) { stack = insert(inv, stack, simulate); if (stack.isEmpty()) return ItemStack.EMPTY; @@ -123,68 +124,243 @@ public ItemStack insertFirst(ItemStack stack, boolean simulate) { } public ItemStack insertRoundRobin(ItemStack stack, boolean simulate, boolean global) { - List routePaths = net.getNetData(pipe.getPipePos(), facing); - if (routePaths.isEmpty()) - return stack; - if (routePaths.size() == 1) - return insert(routePaths.get(0), stack, simulate); + List routePaths = net.getNetData(pipe.getPipePos(), facing, ItemRoutePathSet.FULL); + if (routePaths.isEmpty()) return stack; List routePathsCopy = new ArrayList<>(routePaths); - if (global) { - stack = insertToHandlersEnhanced(routePathsCopy, stack, routePaths.size(), simulate); - } else { - stack = insertToHandlers(routePathsCopy, stack, simulate); - if (!stack.isEmpty() && !routePathsCopy.isEmpty()) - stack = insertToHandlers(routePathsCopy, stack, simulate); + CoverBehavior pipeCover = pipe.getCoverContainer().getCoverAtSide(facing); + CoverBehavior tileCover = getCoverOnNeighbour(pipe.getPipePos(), facing); + + boolean pipeConveyor = pipeCover instanceof ConveyorCover, tileConveyor = tileCover instanceof ConveyorCover; + // abort if there are two conveyors + if (pipeConveyor && tileConveyor) return stack; + + if (tileCover != null && !checkImportCover(tileCover, false, stack)) + return stack; + + if (!pipeConveyor && !tileConveyor) + return insertFirst(stack, simulate); + + ConveyorCover conveyor = (ConveyorCover) (pipeConveyor ? pipeCover : tileCover); + + if (conveyor == null) return distributeHighestPriority(routePathsCopy, stack, simulate); + + switch (conveyor.getDistributionMode()) { + case INSERT_FIRST -> stack = distributeHighestPriority(routePathsCopy, stack, simulate); + case ROUND_ROBIN_GLOBAL -> stack = distributeEqually(routePathsCopy, stack, simulate); + case ROUND_ROBIN_PRIO -> stack = distributeEquallyNoRestrictive(stack, simulate); } return stack; } /** - * Inserts items equally to all handlers - * if it couldn't insert all items, the handler will be removed + * Distributes items to handlers, attempting to fill handlers with a higher priority first + */ + private ItemStack distributeHighestPriority(List copy, ItemStack stack, boolean simulate) { + for (ItemRoutePath inv : copy) { + stack = insertIntoTarget(inv, stack, simulate, false); + if (stack.isEmpty()) return ItemStack.EMPTY; + } + return stack; + } + + /** + * Equally distributes items to all handlers. * * @param copy to insert to * @param stack to insert * @param simulate simulate * @return remainder */ - private ItemStack insertToHandlers(List copy, ItemStack stack, boolean simulate) { - Iterator routePathIterator = copy.listIterator(); - int inserted = 0; - int count = stack.getCount(); - int c = count / copy.size(); - int m = c == 0 ? count % copy.size() : 0; - while (routePathIterator.hasNext()) { - ItemRoutePath routePath = routePathIterator.next(); - - int amount = c; - if (m > 0) { - amount++; - m--; + private ItemStack distributeEqually(List copy, ItemStack stack, boolean simulate) { + List transferred = new ArrayList<>(); + IntList steps = new IntArrayList(); + int min = Integer.MAX_VALUE; + ItemStack simStack; + + // find inventories that are not full and get the amount that was inserted in total + for (ItemRoutePath inv : copy) { + simStack = stack.copy(); + int ins = stack.getCount() - insertIntoTarget(inv, simStack, true, true).getCount(); + if (ins <= 0) + continue; + int didTransfer = didTransferTo(inv, simulate); + EnhancedRoundRobinData data = new EnhancedRoundRobinData(inv, ins, didTransfer); + transferred.add(data); + + min = Math.min(min, didTransfer); + + if (!steps.contains(didTransfer)) { + steps.add(didTransfer); } - amount = Math.min(amount, stack.getCount() - inserted); - if (amount == 0) break; - ItemStack toInsert = stack.copy(); - toInsert.setCount(amount); - int r = insert(routePath, toInsert, simulate).getCount(); - if (r < amount) { - inserted += (amount - r); + } + + if (transferred.isEmpty() || steps.isEmpty()) + return stack; + + if (!simulate && min < Integer.MAX_VALUE) { + decrementBy(min); + } + + transferred.sort(Comparator.comparingInt(data -> data.transferred)); + steps.sort(Integer::compare); + + if (transferred.get(0).transferred != steps.getInt(0)) { + return stack; + } + + int amount = stack.getCount(); + int c = amount / transferred.size(); + int m = amount % transferred.size(); + List transferredCopy = new ArrayList<>(transferred); + int nextStep = steps.removeInt(0); + + // equally distribute items over all inventories + // it takes into account how much was inserted in total + // f.e. if inv1 has 2 inserted and inv2 has 6 inserted, it will first try to insert 4 into inv1 so that both + // have 6 and then it will distribute the rest equally + outer: + while (amount > 0 && !transferredCopy.isEmpty()) { + Iterator iterator = transferredCopy.iterator(); + while (iterator.hasNext()) { + EnhancedRoundRobinData data = iterator.next(); + if (nextStep >= 0 && data.transferred >= nextStep) + break; + + int toInsert; + if (nextStep <= 0) { + if (amount <= m) { + // break outer; + toInsert = 1; + } else { + toInsert = Math.min(c, amount); + } + } else { + toInsert = Math.min(amount, nextStep - data.transferred); + } + if (data.toTransfer + toInsert >= data.maxInsertable) { + data.toTransfer = data.maxInsertable; + iterator.remove(); + } else { + data.toTransfer += toInsert; + } + + data.transferred += toInsert; + + if ((amount -= toInsert) == 0) { + break outer; + } } - if (r == 1 && c == 0 && amount == 1) { - m++; + + for (EnhancedRoundRobinData data : transferredCopy) { + if (data.transferred < nextStep) + continue outer; + } + if (steps.isEmpty()) { + if (nextStep >= 0) { + c = amount / transferredCopy.size(); + m = amount % transferredCopy.size(); + nextStep = -1; + } + } else { + nextStep = steps.removeInt(0); } + } + + int inserted = 0; - if (r > 0) - routePathIterator.remove(); + // finally actually insert the item + for (EnhancedRoundRobinData data : transferred) { + ItemStack toInsert = stack.copy(); + toInsert.setCount(data.toTransfer); + int ins = data.toTransfer - insertIntoTarget(data.routePath, toInsert, simulate, false).getCount(); + inserted += ins; + transferTo(data.routePath, simulate, ins); } ItemStack remainder = stack.copy(); - remainder.setCount(count - inserted); + remainder.shrink(inserted); return remainder; } + ///////////////////////////////////// + // *** ENDPOINT INSERTION LOGIC ***// + ///////////////////////////////////// + + /// Insert items into a target inventory using the specified route + private ItemStack insertIntoTarget(ItemRoutePath routePath, ItemStack stack, boolean simulate, + boolean ignoreLimit) { + int allowed = ignoreLimit ? stack.getCount() : + checkTransferable(routePath.getProperties().getTransferRate(), stack.getCount(), simulate); + if (allowed == 0 || !routePath.matchesFilters(stack)) { + return stack; + } + CoverBehavior pipeCover = routePath.getTargetPipe().getCoverContainer() + .getCoverAtSide(routePath.getTargetFacing()); + CoverBehavior tileCover = getCoverOnNeighbour(routePath.getTargetPipe().getPipePos(), + routePath.getTargetFacing()); + + if (pipeCover != null) { + var defaultHandler = new ItemStackHandler(1); + defaultHandler.setStackInSlot(0, stack.copy()); + IItemHandlerModifiable itemHandler = pipeCover.getItemHandlerCap(defaultHandler); + if (itemHandler == null || (itemHandler != defaultHandler && + (allowed = itemHandler.extractItem(0, allowed, true).getCount()) <= 0)) { + return stack; + } + } + IItemHandler neighbourHandler = routePath.getHandler(net.getLevel()); + if (pipeCover instanceof RobotArmCover robotArm && robotArm.getIo() == IO.OUT) { + return insertOverRobotArm(neighbourHandler, robotArm, stack, simulate, allowed, ignoreLimit); + } + if (tileCover instanceof RobotArmCover robotArm && robotArm.getIo() == IO.IN) { + return insertOverRobotArm(neighbourHandler, robotArm, stack, simulate, allowed, ignoreLimit); + } + + return insertIntoDestination(neighbourHandler, stack, simulate, allowed, ignoreLimit); + } + + /// Insert into the actual destination + private ItemStack insertIntoDestination(IItemHandler handler, ItemStack stack, boolean simulate, int allowed, + boolean ignoreLimit) { + if (stack.getCount() == allowed) { + ItemStack re = ItemHandlerHelper.insertItemStacked(handler, stack, simulate); + if (!ignoreLimit) + transfer(simulate, stack.getCount() - re.getCount()); + return re; + } + ItemStack toInsert = stack.copy(); + toInsert.setCount(Math.min(allowed, stack.getCount())); + int r = ItemHandlerHelper.insertItemStacked(handler, toInsert, simulate).getCount(); + if (!ignoreLimit) + transfer(simulate, toInsert.getCount() - r); + ItemStack remainder = stack.copy(); + remainder.setCount(r + (stack.getCount() - toInsert.getCount())); + return remainder; + } + + private ItemStack distributeEquallyNoRestrictive(ItemStack stack, + boolean simulate) { + // Round-robin distribute to all non-Restrictive destinations + List routePathsNonRestrictedCopy = new ArrayList<>( + net.getNetData(pipe.getPipePos(), facing, ItemRoutePathSet.NONRESTRICTED)); + ItemStack remainsNonRestricted; + if (routePathsNonRestrictedCopy.isEmpty()) { + remainsNonRestricted = stack; + } else { + remainsNonRestricted = distributeEqually(routePathsNonRestrictedCopy, stack, simulate); + } + // if anything is left, distribute to Restrictive destinations + if (!remainsNonRestricted.isEmpty()) { + List routePathsRestrictiveCopy = new ArrayList<>( + net.getNetData(pipe.getPipePos(), facing, ItemRoutePathSet.RESTRICTED)); + return distributeEqually(routePathsRestrictiveCopy, remainsNonRestricted, simulate); + } else { + return ItemStack.EMPTY; + } + } + private ItemStack insertToHandlersEnhanced(List copy, ItemStack stack, int dest, boolean simulate) { List transferred = new ArrayList<>(); IntList steps = new IntArrayList(); @@ -367,11 +543,10 @@ public ItemStack insertOverRobotArm(IItemHandler handler, RobotArmCover arm, Ite case TRANSFER_ANY: return insert(handler, stack, simulate, allowed, ignoreLimit); case KEEP_EXACT: - if (arm.getFilterHandler().getFilter().supportsAmounts()) { - count = rate - countStack(handler, stack, arm); - } else { - count = rate; + if (rate == Integer.MAX_VALUE) { + rate = arm.getGlobalTransferLimit(); } + count = rate - countStack(handler, stack, arm); if (count <= 0) return stack; count = Math.min(allowed, Math.min(stack.getCount(), count)); return insert(handler, stack, simulate, count, ignoreLimit); @@ -401,7 +576,7 @@ public static int countStack(IItemHandler handler, ItemStack stack, RobotArmCove ItemStack slot = handler.getStackInSlot(i); if (slot.isEmpty()) continue; if (ignoreNBT && !ItemStack.isSameItem(stack, slot)) continue; - else if (!ItemStack.isSameItemSameComponents(stack, slot)) continue; + if (!ignoreNBT && !GTUtil.isSameItemSameTags(stack, slot)) continue; if (arm.getFilterHandler().getFilter().test(slot)) { count += slot.getCount(); } diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetWalker.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetWalker.java index 6e8e76de18a..e7e6c86ce36 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetWalker.java +++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemNetWalker.java @@ -47,6 +47,7 @@ public static List createNetData(ItemPipeNet pipeNet, BlockPos so private final EnumMap>> nextFilters = new EnumMap<>(Direction.class); private BlockPos sourcePipe; private Direction facingToHandler; + private boolean isRestricted = false; protected ItemNetWalker(ItemPipeNet world, BlockPos sourcePipe, int distance, List inventories, ItemPipeProperties properties) { @@ -86,6 +87,7 @@ protected void checkPipe(ItemPipeBlockEntity pipeTile, BlockPos pos) { } nextFilters.clear(); ItemPipeProperties pipeProperties = pipeTile.getNodeData(); + if (pipeTile.getPipeType().isRestrictive()) this.isRestricted = true; if (minProperties == null) { minProperties = pipeProperties; } else { @@ -107,7 +109,8 @@ protected void checkNeighbour(ItemPipeBlockEntity pipeTile, BlockPos pipePos, Di if (moreFilters != null && !moreFilters.isEmpty()) { filters.addAll(moreFilters); } - inventories.add(new ItemRoutePath(pipeTile, faceToNeighbour, getWalkedBlocks(), minProperties, filters)); + inventories.add(new ItemRoutePath(pipeTile, faceToNeighbour, getWalkedBlocks(), minProperties, isRestricted, + filters)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeNet.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeNet.java index 6be61792ba9..7d81b334bac 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeNet.java +++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemPipeNet.java @@ -14,13 +14,20 @@ public class ItemPipeNet extends PipeNet { private final Map> NET_DATA = new HashMap<>(); + private final Map> NET_DATA_NO_RESTRICTIVE = new HashMap<>(); + private final Map> NET_DATA_ONLY_RESTRICTIVE = new HashMap<>(); public ItemPipeNet(LevelPipeNet> world) { super(world); } - public List getNetData(BlockPos pipePos, Direction facing) { - List data = NET_DATA.get(pipePos); + public List getNetData(BlockPos pipePos, Direction facing, ItemRoutePathSet ITEMNETSET) { + List data = switch (ITEMNETSET) { + case FULL -> NET_DATA.get(pipePos); + case NONRESTRICTED -> NET_DATA_NO_RESTRICTIVE.get(pipePos); + case RESTRICTED -> NET_DATA_ONLY_RESTRICTIVE.get(pipePos); + }; + if (data == null) { data = ItemNetWalker.createNetData(this, pipePos, facing); if (data == null) { @@ -28,27 +35,54 @@ public List getNetData(BlockPos pipePos, Direction facing) { return Collections.emptyList(); } data.sort(Comparator.comparingInt(inv -> inv.getProperties().getPriority())); + + // split between the three lists + // Making the walker explicitly return only one of the lists would be too API-intrusive for a non-X.0.0 + // release + List nonRestricted = new ArrayList<>(), restricted = new ArrayList<>(); + for (ItemRoutePath route : data) { + if (route.isRestrictive()) { + restricted.add(route); + } else { + nonRestricted.add(route); + } + } + NET_DATA.put(pipePos, data); + NET_DATA_NO_RESTRICTIVE.put(pipePos, nonRestricted); + NET_DATA_ONLY_RESTRICTIVE.put(pipePos, restricted); + + data = switch (ITEMNETSET) { + case FULL -> NET_DATA.get(pipePos); + case NONRESTRICTED -> NET_DATA_NO_RESTRICTIVE.get(pipePos); + case RESTRICTED -> NET_DATA_ONLY_RESTRICTIVE.get(pipePos); + }; } return data; } @Override public void onNeighbourUpdate(BlockPos fromPos) { + clearNetData(); + } + + private void clearNetData() { NET_DATA.clear(); + NET_DATA_ONLY_RESTRICTIVE.clear(); + NET_DATA_NO_RESTRICTIVE.clear(); } @Override public void onPipeConnectionsUpdate() { - NET_DATA.clear(); + clearNetData(); } @Override protected void transferNodeData(Map> transferredNodes, PipeNet parentNet) { super.transferNodeData(transferredNodes, parentNet); - NET_DATA.clear(); - ((ItemPipeNet) parentNet).NET_DATA.clear(); + clearNetData(); + ((ItemPipeNet) parentNet).clearNetData(); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemRoutePath.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemRoutePath.java index 947b1416da0..ae12216f732 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemRoutePath.java +++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemRoutePath.java @@ -31,14 +31,17 @@ public class ItemRoutePath implements IRoutePath { @Getter private final ItemPipeProperties properties; private final Predicate filters; + @Getter + private final boolean restrictive; public ItemRoutePath(ItemPipeBlockEntity targetPipe, @NotNull Direction facing, int distance, - ItemPipeProperties properties, + ItemPipeProperties properties, boolean restrictive, List> filters) { this.targetPipe = targetPipe; this.targetFacing = facing; this.distance = distance; this.properties = properties; + this.restrictive = restrictive; this.filters = stack -> { for (Predicate filter : filters) if (!filter.test(stack)) return false; diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemRoutePathSet.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemRoutePathSet.java new file mode 100644 index 00000000000..dc9f8f385fc --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/item/ItemRoutePathSet.java @@ -0,0 +1,23 @@ +package com.gregtechceu.gtceu.common.pipelike.item; + +/** + * The set of {@link ItemRoutePath} connections to fetch from an {@link ItemPipeNet}: All, Non-Restrictive, or Only + * Restrictive + */ +public enum ItemRoutePathSet { + + /** + * the full set of item pipe net routes + */ + FULL, + /** + * only the subset of item pipe net routes that include at least one Restrictive Pipe + */ + RESTRICTED, + /** + * only the subset of item pipe net routes that do not include at least one Restrictive Pipe + */ + NONRESTRICTED; + + ItemRoutePathSet() {} +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/pipelike/optical/OpticalNetHandler.java b/src/main/java/com/gregtechceu/gtceu/common/pipelike/optical/OpticalNetHandler.java index dc85f099b60..a6755c2190c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/pipelike/optical/OpticalNetHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/common/pipelike/optical/OpticalNetHandler.java @@ -10,6 +10,7 @@ import net.minecraft.core.Direction; import net.minecraft.world.level.Level; +import lombok.Getter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -21,6 +22,7 @@ public class OpticalNetHandler implements IDataAccessHatch, IOpticalComputationP private final Level world; private final Direction facing; + @Getter private OpticalPipeNet net; public OpticalNetHandler(OpticalPipeNet net, @NotNull OpticalPipeBlockEntity pipe, @Nullable Direction facing) { @@ -34,10 +36,6 @@ public void updateNetwork(OpticalPipeNet net) { this.net = net; } - public OpticalPipeNet getNet() { - return net; - } - @Override public boolean isRecipeAvailable(@NotNull GTRecipe recipe, @NotNull Collection seen) { boolean isAvailable = traverseRecipeAvailable(recipe, seen); @@ -52,6 +50,7 @@ public boolean isCreative() { @Override public int requestCWUt(int cwut, boolean simulate, @NotNull Collection seen) { + if (cwut == 0) return 0; int provided = traverseRequestCWUt(cwut, simulate, seen); if (provided > 0) setPipesActive(); return provided; diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/builder/GTRecipeBuilder.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/builder/GTRecipeBuilder.java index 551e211f5a3..9212142249c 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/builder/GTRecipeBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/builder/GTRecipeBuilder.java @@ -19,17 +19,22 @@ import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.ingredient.*; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; +import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.api.tag.TagPrefix; import com.gregtechceu.gtceu.common.item.behavior.IntCircuitBehaviour; import com.gregtechceu.gtceu.common.recipe.condition.*; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.item.GTDataComponents; import com.gregtechceu.gtceu.data.recipe.GTRecipeTypes; +import com.gregtechceu.gtceu.utils.GTUtil; import com.gregtechceu.gtceu.utils.ResearchManager; +import com.gregtechceu.gtceu.utils.codec.CodecUtils; +import net.minecraft.core.HolderSet; import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; +import net.minecraft.resources.RegistryOps; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; @@ -41,12 +46,16 @@ import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.Fluid; import net.neoforged.neoforge.common.crafting.SizedIngredient; import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.crafting.FluidIngredient; import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient; +import com.google.gson.JsonObject; +import com.mojang.serialization.JsonOps; import dev.ftb.mods.ftbquests.quest.QuestObjectBase; import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; import lombok.Getter; @@ -82,7 +91,6 @@ public class GTRecipeBuilder { public ResourceLocation id; @Setter public GTRecipeType recipeType; - @Setter public int duration = 100; @Setter public boolean perTick; @@ -103,8 +111,10 @@ public class GTRecipeBuilder { private final Collection researchRecipeEntries = new ArrayList<>(); private boolean generatingRecipes = true; + // material stacks that are from already resolved inputs private List tempItemStacks = new ArrayList<>(); private List tempItemMaterialStacks = new ArrayList<>(); + // temporary buffer for unresolved item stacks where decomp is found post recipe addition private List tempFluidStacks = new ArrayList<>(); public GTRecipeBuilder(ResourceLocation id, GTRecipeType recipeType) { @@ -163,6 +173,7 @@ public GTRecipeBuilder copy(ResourceLocation id) { } public GTRecipeBuilder copyFrom(GTRecipeBuilder builder) { + recipeType.setMinRecipeConditions(builder.conditions.size()); return builder.copy(builder.id).onSave(null).recipeType(recipeType).category(recipeCategory); } @@ -202,6 +213,15 @@ public GTRecipeBuilder output(RecipeCapability capability, T... obj) { public GTRecipeBuilder addCondition(RecipeCondition condition) { conditions.add(condition); + recipeType.setMinRecipeConditions(conditions.size()); + return this; + } + + public GTRecipeBuilder duration(int duration) { + if (duration < 0) { + GTCEu.LOGGER.error("Recipe duration must be non negative, id: {}", this.id); + } + this.duration = Math.max(duration, 0); return this; } @@ -287,6 +307,8 @@ public GTRecipeBuilder inputItems(Object input) { case MaterialEntry entry -> inputItems(entry); case TagKey tag -> inputItems((TagKey) tag); case MachineDefinition machine -> inputItems(machine); + case IntProviderIngredient ingredient -> inputItems( + new SizedIngredient(ingredient.toVanilla(), ingredient.getCountProvider().getMaxValue())); default -> { GTCEu.LOGGER.error( """ @@ -309,6 +331,8 @@ public GTRecipeBuilder inputItems(Object input, int count) { case MaterialEntry entry -> inputItems(entry, count); case TagKey tag -> inputItems((TagKey) tag, count); case MachineDefinition machine -> inputItems(machine, count); + case IntProviderIngredient ingredient -> inputItems( + new SizedIngredient(ingredient.toVanilla(), ingredient.getCountProvider().getMaxValue())); default -> { GTCEu.LOGGER.error( """ @@ -322,18 +346,14 @@ public GTRecipeBuilder inputItems(Object input, int count) { } public GTRecipeBuilder inputItems(Ingredient input) { - if (intProviderInputError(input, 0)) { - return this; - } else if (missingIngredientError(0, true, ItemRecipeCapability.CAP, input::isEmpty)) { + if (missingIngredientError(0, true, ItemRecipeCapability.CAP, input::isEmpty)) { return this; } return input(ItemRecipeCapability.CAP, new SizedIngredient(input, 1)); } public GTRecipeBuilder inputItems(Ingredient input, int count) { - if (intProviderInputError(input, 0)) { - return this; - } else if (missingIngredientError(0, true, ItemRecipeCapability.CAP, input::isEmpty)) { + if (missingIngredientError(0, true, ItemRecipeCapability.CAP, input::isEmpty)) { return this; } return input(ItemRecipeCapability.CAP, new SizedIngredient(input, count)); @@ -343,9 +363,7 @@ public GTRecipeBuilder inputItems(Ingredient... inputs) { List ingredients = new ArrayList<>(); for (int i = 0; i < inputs.length; i++) { var ingredient = inputs[i]; - if (intProviderInputError(ingredient, i)) { - return this; - } else if (missingIngredientError(i, true, ItemRecipeCapability.CAP, ingredient::isEmpty)) { + if (missingIngredientError(i, true, ItemRecipeCapability.CAP, ingredient::isEmpty)) { return this; } else { ingredients.add(new SizedIngredient(ingredient, 1)); @@ -355,9 +373,7 @@ public GTRecipeBuilder inputItems(Ingredient... inputs) { } public GTRecipeBuilder inputItems(SizedIngredient input) { - if (intProviderInputError(input.ingredient(), 0)) { - return this; - } else if (missingIngredientError(0, true, ItemRecipeCapability.CAP, input.ingredient()::isEmpty)) { + if (missingIngredientError(0, true, ItemRecipeCapability.CAP, input.ingredient()::isEmpty)) { return this; } return input(ItemRecipeCapability.CAP, input); @@ -367,9 +383,7 @@ public GTRecipeBuilder inputItems(SizedIngredient... inputs) { List ingredients = new ArrayList<>(); for (int i = 0; i < inputs.length; i++) { var ingredient = inputs[i]; - if (intProviderInputError(ingredient.ingredient(), i)) { - return this; - } else if (missingIngredientError(i, true, ItemRecipeCapability.CAP, ingredient.ingredient()::isEmpty)) { + if (missingIngredientError(i, true, ItemRecipeCapability.CAP, ingredient.ingredient()::isEmpty)) { return this; } else { ingredients.add(ingredient); @@ -381,23 +395,8 @@ public GTRecipeBuilder inputItems(SizedIngredient... inputs) { public GTRecipeBuilder inputItems(ItemStack input) { if (missingIngredientError(0, true, ItemRecipeCapability.CAP, input::isEmpty)) { return this; - } else { - var matInfo = ItemMaterialData.getMaterialInfo(input.getItem()); - var unresolvedMatInfo = ItemMaterialData.UNRESOLVED_ITEM_MATERIAL_INFO.get(input); - if (chance == maxChance && chance != 0) { - if (unresolvedMatInfo != null) { - tempItemStacks.add(input); - } - if (matInfo != null) { - for (var matStack : matInfo.getMaterials()) { - tempItemMaterialStacks.add(matStack.multiply(input.getCount())); - } - } else if (unresolvedMatInfo == null) { - tempItemStacks.add(input); - } - - } } + gatherMaterialInfoFromStack(input); return input(ItemRecipeCapability.CAP, RecipeHelper.makeSizedIngredient(input)); } @@ -408,16 +407,7 @@ public GTRecipeBuilder inputItems(ItemStack... inputs) { if (missingIngredientError(i, true, ItemRecipeCapability.CAP, itemStack::isEmpty)) { return this; } else { - var matInfo = ItemMaterialData.getMaterialInfo(itemStack.getItem()); - if (chance == maxChance && chance != 0) { - if (matInfo != null) { - for (var matStack : matInfo.getMaterials()) { - tempItemMaterialStacks.add(matStack.multiply(itemStack.getCount())); - } - } else { - tempItemStacks.add(itemStack); - } - } + gatherMaterialInfoFromStack(itemStack); ingredients.add(RecipeHelper.makeSizedIngredient(itemStack)); } } @@ -492,13 +482,53 @@ public GTRecipeBuilder inputItems(MachineDefinition machine, int count) { return inputItems(machine.asStack(count)); } + public GTRecipeBuilder inputItemRanged(IntProviderIngredient provider) { + return inputItems(provider); + } + + public GTRecipeBuilder inputItemsRanged(ItemStack input, IntProvider intProvider) { + return inputItemRanged(IntProviderIngredient.of(input, intProvider)); + } + + public GTRecipeBuilder inputItemsRanged(Item input, IntProvider intProvider) { + return inputItemsRanged(new ItemStack(input), intProvider); + } + + public GTRecipeBuilder inputItemsRanged(Supplier input, IntProvider intProvider) { + return inputItemsRanged(new ItemStack(input.get().asItem()), intProvider); + } + + public GTRecipeBuilder inputItemsRanged(TagPrefix orePrefix, Material material, IntProvider intProvider) { + var item = ChemicalHelper.get(orePrefix, material, 1); + if (item.isEmpty()) { + GTCEu.LOGGER.error("Tried to set input ranged item stack that doesn't exist, TagPrefix: {}, Material: {}", + orePrefix, material); + } + return inputItemsRanged(item, intProvider); + } + + public GTRecipeBuilder inputItemsRanged(MachineDefinition machine, IntProvider intProvider) { + return inputItemsRanged(machine.asStack(), intProvider); + } + + // public GTRecipeBuilder inputItemNbtPredicate(ItemStack stack, NBTPredicate predicate) { + // if (missingIngredientError(0, true, ItemRecipeCapability.CAP, stack::isEmpty)) { + // return this; + // } + // gatherMaterialInfoFromStack(stack); + // return inputItems(NBTPredicateIngredient.of(stack, predicate)); + // } + public GTRecipeBuilder outputItems(Object output) { return switch (output) { case Item item -> outputItems(item); + case Ingredient ingredient -> outputItems(ingredient); case Supplier supplier when supplier.get() instanceof ItemLike item -> outputItems(item.asItem()); case ItemStack stack -> outputItems(stack); case MaterialEntry entry -> outputItems(entry); case MachineDefinition machine -> outputItems(machine); + case IntProviderIngredient ingredient -> outputItems( + new SizedIngredient(ingredient.toVanilla(), ingredient.getCountProvider().getMaxValue())); default -> { GTCEu.LOGGER.error(""" Output item is not one of: @@ -512,10 +542,13 @@ public GTRecipeBuilder outputItems(Object output) { public GTRecipeBuilder outputItems(Object output, int count) { return switch (output) { case Item item -> outputItems(item, count); + case Ingredient ingredient -> outputItems(ingredient, count); case Supplier supplier when supplier.get() instanceof ItemLike item -> outputItems(item.asItem(), count); case ItemStack stack -> outputItems(stack.copyWithCount(count)); case MaterialEntry entry -> outputItems(entry, count); case MachineDefinition machine -> outputItems(machine, count); + case IntProviderIngredient ingredient -> outputItems( + new SizedIngredient(ingredient.toVanilla(), ingredient.getCountProvider().getMaxValue())); default -> { GTCEu.LOGGER.error(""" Output item is not one of: @@ -526,6 +559,10 @@ public GTRecipeBuilder outputItems(Object output, int count) { }; } + public GTRecipeBuilder outputItems(Ingredient input) { + return outputItems(input, 1); + } + public GTRecipeBuilder outputItems(Ingredient input, int count) { return output(ItemRecipeCapability.CAP, new SizedIngredient(input, count)); } @@ -607,9 +644,12 @@ protected GTRecipeBuilder outputItems(SizedIngredient ingredient) { return output(ItemRecipeCapability.CAP, ingredient); } + public GTRecipeBuilder outputItemRanged(IntProviderIngredient provider) { + return outputItems(provider); + } + public GTRecipeBuilder outputItemsRanged(ItemStack output, IntProvider intProvider) { - Ingredient inner = IntProviderIngredient.of(RecipeHelper.makeItemIngredient(output), intProvider); - return outputItems(new SizedIngredient(inner, 1)); + return outputItemRanged(IntProviderIngredient.of(output, intProvider)); } public GTRecipeBuilder outputItemsRanged(Item input, IntProvider intProvider) { @@ -700,7 +740,7 @@ public GTRecipeBuilder circuitMeta(int configuration) { return notConsumable(IntCircuitIngredient.circuit(configuration)); } - public GTRecipeBuilder chancedInput(ItemStack stack, int chance, int tierChanceBoost) { + public GTRecipeBuilder chancedInput(Ingredient stack, int chance, int tierChanceBoost) { if (checkChanceAndPrintError(chance)) { return this; } @@ -714,7 +754,7 @@ public GTRecipeBuilder chancedInput(ItemStack stack, int chance, int tierChanceB return this; } - public GTRecipeBuilder chancedInput(FluidStack stack, int chance, int tierChanceBoost) { + public GTRecipeBuilder chancedInput(SizedFluidIngredient stack, int chance, int tierChanceBoost) { if (checkChanceAndPrintError(chance)) { return this; } @@ -728,7 +768,7 @@ public GTRecipeBuilder chancedInput(FluidStack stack, int chance, int tierChance return this; } - public GTRecipeBuilder chancedOutput(ItemStack stack, int chance, int tierChanceBoost) { + public GTRecipeBuilder chancedOutput(Ingredient stack, int chance, int tierChanceBoost) { if (checkChanceAndPrintError(chance)) { return this; } @@ -742,7 +782,7 @@ public GTRecipeBuilder chancedOutput(ItemStack stack, int chance, int tierChance return this; } - public GTRecipeBuilder chancedOutput(FluidStack stack, int chance, int tierChanceBoost) { + public GTRecipeBuilder chancedOutput(SizedFluidIngredient stack, int chance, int tierChanceBoost) { if (checkChanceAndPrintError(chance)) { return this; } @@ -756,6 +796,22 @@ public GTRecipeBuilder chancedOutput(FluidStack stack, int chance, int tierChanc return this; } + public GTRecipeBuilder chancedInput(ItemStack stack, int chance, int tierChanceBoost) { + return chancedInput(Ingredient.of(stack), chance, tierChanceBoost); + } + + public GTRecipeBuilder chancedInput(FluidStack stack, int chance, int tierChanceBoost) { + return chancedInput(SizedFluidIngredient.of(stack), chance, tierChanceBoost); + } + + public GTRecipeBuilder chancedOutput(ItemStack stack, int chance, int tierChanceBoost) { + return chancedOutput(Ingredient.of(stack), chance, tierChanceBoost); + } + + public GTRecipeBuilder chancedOutput(FluidStack stack, int chance, int tierChanceBoost) { + return chancedOutput(SizedFluidIngredient.of(stack), chance, tierChanceBoost); + } + public GTRecipeBuilder chancedOutput(TagPrefix tag, Material mat, int chance, int tierChanceBoost) { return chancedOutput(ChemicalHelper.get(tag, mat), chance, tierChanceBoost); } @@ -963,10 +1019,29 @@ public GTRecipeBuilder inputFluids(FluidStack... inputs) { return input(FluidRecipeCapability.CAP, ingredients.toArray(SizedFluidIngredient[]::new)); } + public GTRecipeBuilder inputFluidsRanged(IntProviderFluidIngredient provider) { + return inputFluids(provider); + } + + protected GTRecipeBuilder inputFluidsRanged(FluidIngredient input, IntProvider intProvider) { + return inputFluidsRanged(IntProviderFluidIngredient.of(input, intProvider)); + } + + public GTRecipeBuilder inputFluidsRanged(FluidStack input, IntProvider intProvider) { + return inputFluidsRanged(FluidIngredient.of(input), intProvider); + } + public GTRecipeBuilder inputFluids(SizedFluidIngredient... inputs) { return input(FluidRecipeCapability.CAP, inputs); } + public GTRecipeBuilder inputFluids(IntProviderFluidIngredient... inputs) { + return input(FluidRecipeCapability.CAP, + Arrays.stream(inputs).map( + ingredient -> new SizedFluidIngredient(ingredient, ingredient.getCountProvider().getMaxValue())) + .toList().toArray(new SizedFluidIngredient[0])); + } + public GTRecipeBuilder outputFluids(FluidStack output) { return output(FluidRecipeCapability.CAP, SizedFluidIngredient.of(output)); } @@ -980,12 +1055,23 @@ public GTRecipeBuilder outputFluids(SizedFluidIngredient... outputs) { return output(FluidRecipeCapability.CAP, outputs); } - public GTRecipeBuilder outputFluidsRanged(FluidStack output, IntProvider intProvider) { - return outputFluidsRanged(FluidIngredient.of(output), intProvider); + public GTRecipeBuilder outputFluids(IntProviderFluidIngredient... outputs) { + return output(FluidRecipeCapability.CAP, + Arrays.stream(outputs).map( + ingredient -> new SizedFluidIngredient(ingredient, ingredient.getCountProvider().getMaxValue())) + .toList().toArray(new SizedFluidIngredient[0])); + } + + public GTRecipeBuilder outputFluidsRanged(IntProviderFluidIngredient provider) { + return outputFluids(provider); } protected GTRecipeBuilder outputFluidsRanged(FluidIngredient output, IntProvider intProvider) { - return outputFluids(new SizedFluidIngredient(IntProviderFluidIngredient.of(output, intProvider), 1)); + return outputFluidsRanged(IntProviderFluidIngredient.of(output, intProvider)); + } + + public GTRecipeBuilder outputFluidsRanged(FluidStack output, IntProvider intProvider) { + return outputFluidsRanged(FluidIngredient.of(output), intProvider); } ////////////////////////////////////// @@ -1113,42 +1199,170 @@ public GTRecipeBuilder environmentalHazard(MedicalCondition condition) { return environmentalHazard(condition, false); } - public GTRecipeBuilder daytime(boolean isNight) { - return addCondition(new DaytimeCondition().setReverse(isNight)); + public final GTRecipeBuilder adjacentFluids(Fluid... fluids) { + return adjacentFluids(false, fluids); } - public GTRecipeBuilder daytime() { - return daytime(false); + public final GTRecipeBuilder adjacentFluids(boolean isReverse, Fluid... fluids) { + if (fluids.length > GTUtil.NON_CORNER_NEIGHBOURS.size()) { + GTCEu.LOGGER.error("Has too many fluids, not adding to recipe, id: {}", this.id); + return this; + } + return addCondition(AdjacentFluidCondition.fromFluids(fluids).setReverse(isReverse)); } - public GTRecipeBuilder heraclesQuest(String questId, boolean isReverse) { - if (!GTCEu.Mods.isHeraclesLoaded()) { - GTCEu.LOGGER.error("Heracles not loaded!"); + public final GTRecipeBuilder adjacentFluid(Fluid... fluids) { + return adjacentFluid(false, fluids); + } + + public final GTRecipeBuilder adjacentFluid(boolean isReverse, Fluid... fluids) { + if (fluids.length > GTUtil.NON_CORNER_NEIGHBOURS.size()) { + GTCEu.LOGGER.error("Has too many fluids, not adding to recipe, id: {}", this.id); return this; } - if (questId.isEmpty()) { - GTCEu.LOGGER.error("Quest ID cannot be empty for recipe {}", this.id); + return addCondition(AdjacentFluidCondition.fromFluids(fluids).setReverse(isReverse)); + } + + @SafeVarargs + public final GTRecipeBuilder adjacentFluidTag(TagKey... tags) { + return adjacentFluidTag(false, tags); + } + + @SafeVarargs + public final GTRecipeBuilder adjacentFluidTag(boolean isReverse, TagKey... tags) { + if (tags.length > GTUtil.NON_CORNER_NEIGHBOURS.size()) { + GTCEu.LOGGER.error("Has too many fluids, not adding to recipe, id: {}", this.id); + return this; + } + return addCondition(AdjacentFluidCondition.fromTags(tags).setReverse(isReverse)); + } + + @SafeVarargs + public final GTRecipeBuilder adjacentFluid(TagKey... tags) { + return adjacentFluid(false, tags); + } + + @SafeVarargs + public final GTRecipeBuilder adjacentFluid(boolean isReverse, TagKey... tags) { + if (tags.length > GTUtil.NON_CORNER_NEIGHBOURS.size()) { + GTCEu.LOGGER.error("Has too many fluids, not adding to recipe, id: {}", this.id); return this; } - return addCondition(new HeraclesQuestCondition(isReverse, questId)); + return addCondition(AdjacentFluidCondition.fromTags(tags).setReverse(isReverse)); } - public GTRecipeBuilder heraclesQuest(String questId) { - return heraclesQuest(questId, false); + public GTRecipeBuilder adjacentFluid(Collection> fluids) { + return adjacentFluid(fluids, false); } - public GTRecipeBuilder gameStage(String stageName) { - return gameStage(stageName, false); + public GTRecipeBuilder adjacentFluid(Collection> fluids, boolean isReverse) { + if (fluids.size() > GTUtil.NON_CORNER_NEIGHBOURS.size()) { + GTCEu.LOGGER.error("Has too many fluids, not adding to recipe, id: {}", this.id); + return this; + } + return addCondition(new AdjacentFluidCondition(isReverse, new ArrayList<>(fluids))); + } + + public GTRecipeBuilder adjacentBlocks(Block... blocks) { + return adjacentBlocks(false, blocks); + } + + public GTRecipeBuilder adjacentBlocks(boolean isReverse, Block... blocks) { + if (blocks.length > GTUtil.NON_CORNER_NEIGHBOURS.size()) { + GTCEu.LOGGER.error("Has too many blocks, not adding to recipe, id: {}", this.id); + return this; + } + return addCondition(AdjacentBlockCondition.fromBlocks(blocks).setReverse(isReverse)); + } + + public GTRecipeBuilder adjacentBlock(Block... blocks) { + return adjacentBlock(false, blocks); } - public GTRecipeBuilder gameStage(String stageName, boolean isReverse) { - if (!GTCEu.Mods.isGameStagesLoaded()) { - GTCEu.LOGGER.warn("GameStages is not loaded, ignoring recipe condition"); + public GTRecipeBuilder adjacentBlock(boolean isReverse, Block... blocks) { + if (blocks.length > GTUtil.NON_CORNER_NEIGHBOURS.size()) { + GTCEu.LOGGER.error("Has too many blocks, not adding to recipe, id: {}", this.id); return this; } - return addCondition(new GameStageCondition(isReverse, stageName)); + return addCondition(AdjacentBlockCondition.fromBlocks(blocks).setReverse(isReverse)); } + @SafeVarargs + public final GTRecipeBuilder adjacentBlock(TagKey... tags) { + return adjacentBlock(false, tags); + } + + @SafeVarargs + public final GTRecipeBuilder adjacentBlock(boolean isReverse, TagKey... tags) { + if (tags.length > GTUtil.NON_CORNER_NEIGHBOURS.size()) { + GTCEu.LOGGER.error("Has too many blocks, not adding to recipe, id: {}", this.id); + return this; + } + return addCondition(AdjacentBlockCondition.fromTags(tags).setReverse(isReverse)); + } + + @SafeVarargs + public final GTRecipeBuilder adjacentBlockTag(TagKey... tags) { + return adjacentBlockTag(false, tags); + } + + @SafeVarargs + public final GTRecipeBuilder adjacentBlockTag(boolean isReverse, TagKey... tags) { + if (tags.length > GTUtil.NON_CORNER_NEIGHBOURS.size()) { + GTCEu.LOGGER.error("Has too many blocks, not adding to recipe, id: {}", this.id); + return this; + } + return addCondition(AdjacentBlockCondition.fromTags(tags).setReverse(isReverse)); + } + + public GTRecipeBuilder adjacentBlock(Collection> blocks) { + return adjacentBlock(blocks, false); + } + + public GTRecipeBuilder adjacentBlock(Collection> blocks, boolean isReverse) { + if (blocks.size() > GTUtil.NON_CORNER_NEIGHBOURS.size()) { + GTCEu.LOGGER.error("Has too many blocks, not adding to recipe, id: {}", this.id); + return this; + } + return addCondition(new AdjacentBlockCondition(isReverse, new ArrayList<>(blocks))); + } + + public GTRecipeBuilder daytime(boolean isNight) { + return addCondition(new DaytimeCondition().setReverse(isNight)); + } + + public GTRecipeBuilder daytime() { + return daytime(false); + } + + // public GTRecipeBuilder heraclesQuest(String questId, boolean isReverse) { + // if (!GTCEu.Mods.isHeraclesLoaded()) { + // GTCEu.LOGGER.error("Heracles not loaded!"); + // return this; + // } + // if (questId.isEmpty()) { + // GTCEu.LOGGER.error("Quest ID cannot be empty for recipe {}", this.id); + // return this; + // } + // return addCondition(new HeraclesQuestCondition(isReverse, questId)); + // } + + // public GTRecipeBuilder heraclesQuest(String questId) { + // return heraclesQuest(questId, false); + // } + + // public GTRecipeBuilder gameStage(String stageName) { + // return gameStage(stageName, false); + // } + + // public GTRecipeBuilder gameStage(String stageName, boolean isReverse) { + // if (!GTCEu.Mods.isGameStagesLoaded()) { + // GTCEu.LOGGER.warn("GameStages is not loaded, ignoring recipe condition"); + // return this; + // } + // return addCondition(new GameStageCondition(isReverse, stageName)); + // } + public GTRecipeBuilder ftbQuest(String questId, boolean isReverse) { if (!GTCEu.Mods.isFTBQuestsLoaded()) { GTCEu.LOGGER.error("FTBQuests is not loaded!"); @@ -1281,6 +1495,42 @@ public GTRecipeBuilder setTempFluidMaterialStacks(List stacks) { return this; } + public GTRecipeBuilder setTempItemStacks(List stacks) { + tempItemStacks = stacks; + return this; + } + + public void toJson(JsonObject json) { + var ops = RegistryOps.create(JsonOps.INSTANCE, GTRegistries.builtinRegistry()); + JsonObject serialized = CodecUtils.encodeMap(build(), GTRecipeSerializer.CODEC, ops) + .getOrThrow().getAsJsonObject(); + for (String key : serialized.keySet()) { + json.add(key, serialized.get(key)); + } + } + + // public JsonObject capabilitiesToJson(Map, List> contents) { + // JsonObject jsonObject = new JsonObject(); + // contents.forEach((cap, list) -> { + // JsonArray contentsJson = new JsonArray(); + // for (Content content : list) { + // contentsJson.add(cap.serializer.toJsonContent(content)); + // } + // jsonObject.add(GTRegistries.RECIPE_CAPABILITIES.getKey(cap), contentsJson); + // }); + // return jsonObject; + // } + + // public JsonObject chanceLogicsToJson(Map, ChanceLogic> chanceLogics) { + // JsonObject jsonObject = new JsonObject(); + // chanceLogics.forEach((cap, logic) -> { + // String capId = GTRegistries.RECIPE_CAPABILITIES.getKey(cap).toString(); + // String logicId = GTRegistries.CHANCE_LOGICS.getKey(logic).toString(); + // jsonObject.addProperty(capId, logicId); + // }); + // return jsonObject; + // } + public void save(RecipeOutput output) { if (onSave != null) { onSave.accept(this, output); @@ -1318,6 +1568,24 @@ public void save(RecipeOutput output) { output.accept(id.withPrefix(recipeType.registryName.getPath() + "/"), build(), null); } + private void gatherMaterialInfoFromStack(ItemStack input) { + var matInfo = ItemMaterialData.getMaterialInfo(input.getItem()); + var unresolvedMatInfo = ItemMaterialData.UNRESOLVED_ITEM_MATERIAL_INFO.get(input); + if (chance == maxChance && chance != 0) { + if (unresolvedMatInfo != null) { + tempItemStacks.add(input); + } + if (matInfo != null) { + for (var matStack : matInfo.getMaterials()) { + tempItemMaterialStacks.add(matStack.multiply(input.getCount())); + } + } else if (unresolvedMatInfo == null) { + tempItemStacks.add(input); + } + + } + } + private void addOutputMaterialInfo() { var itemOutputs = output.getOrDefault(ItemRecipeCapability.CAP, new ArrayList<>()); var itemInputs = input.getOrDefault(ItemRecipeCapability.CAP, new ArrayList<>()); @@ -1429,16 +1697,6 @@ protected void warnTooManyIngredients(RecipeCapability capability, } } - protected boolean intProviderInputError(Ingredient ingredient, int index) { - if (ingredient.getCustomIngredient() instanceof IntProviderIngredient) { - int size = (perTick ? tickOutput : output).getOrDefault(ItemRecipeCapability.CAP, List.of()).size(); - GTCEu.LOGGER.error("Using int provider ingredients as inputs is not supported!" + - "Input {} in recipe {} will be skipped.", size + index, id); - return true; - } - return false; - } - protected boolean missingIngredientError(int index, boolean isInput, RecipeCapability cap, BooleanSupplier empty) { if (empty.getAsBoolean()) { @@ -1491,7 +1749,7 @@ public int getSolderMultiplier() { */ public record ResearchRecipeEntry(@NotNull String researchId, @NotNull ItemStack researchItem, @NotNull FluidStack researchFluid, - @NotNull ItemStack dataStack, int duration, int EUt, int CWUt) { + @NotNull ItemStack dataStack, int duration, EnergyStack EUt, int CWUt) { } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentBlockCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentBlockCondition.java index 7a6f139b320..356746c0aa9 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentBlockCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentBlockCondition.java @@ -7,26 +7,91 @@ import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; import com.gregtechceu.gtceu.utils.GTUtil; -import net.minecraft.core.Direction; +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderSet; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import lombok.Getter; import lombok.NoArgsConstructor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +import static com.gregtechceu.gtceu.api.recipe.condition.ConditionSerializeUtils.decodeHolderSets; +import static com.gregtechceu.gtceu.api.recipe.condition.ConditionSerializeUtils.encodeHolderSets; @NoArgsConstructor public class AdjacentBlockCondition extends RecipeCondition { - public static final MapCodec CODEC = RecordCodecBuilder - .mapCodec(instance -> RecipeCondition.isReverse(instance) - .apply(instance, AdjacentBlockCondition::new)); - public final static AdjacentBlockCondition INSTANCE = new AdjacentBlockCondition(); + // spotless:off + public static final MapCodec CODEC = + RecordCodecBuilder.mapCodec(instance -> RecipeCondition.isReverse(instance).and( + Codec.STRING.fieldOf("blockString").forGetter(AdjacentBlockCondition::getBlockString) + ).apply(instance, AdjacentBlockCondition::new)); + // spotless:on + + @Getter + private @NotNull String blockString = ""; + + private @Nullable List> blocks = null; + + public void setBlocks(@NotNull List> blocks) { + this.blocks = blocks; + this.blockString = encodeHolderSets(blocks); + } + + public List> getBlocks() { + if (blocks == null) { + blocks = decodeHolderSets(getBlockString(), Registries.BLOCK); + } + return blocks; + } + + public AdjacentBlockCondition(@NotNull List> blocks) { + setBlocks(blocks); + } + + public AdjacentBlockCondition(boolean isReverse, @NotNull List> blocks) { + super(isReverse); + setBlocks(blocks); + } - public AdjacentBlockCondition(boolean isReverse) { + public AdjacentBlockCondition(boolean isReverse, String blockString) { super(isReverse); + this.blockString = blockString; + } + + public static AdjacentBlockCondition fromBlocks(Collection blocks) { + return new AdjacentBlockCondition(blocks.stream() + .map(Block::builtInRegistryHolder) + .>map(HolderSet::direct) + .toList()); + } + + public static AdjacentBlockCondition fromBlocks(Block... blocks) { + return fromBlocks(Arrays.asList(blocks)); + } + + public static AdjacentBlockCondition fromTags(Collection> tags) { + return new AdjacentBlockCondition(tags.stream() + .>map(BuiltInRegistries.BLOCK::getOrCreateTag) + .toList()); + } + + @SafeVarargs + public static AdjacentBlockCondition fromTags(TagKey... tags) { + return fromTags(Arrays.asList(tags)); } @Override @@ -41,22 +106,46 @@ public Component getTooltips() { @Override public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { - var blockA = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(recipe.data.getString("blockA"))); - var blockB = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(recipe.data.getString("blockB"))); - boolean hasBlockA = false, hasBlockB = false; - var level = recipeLogic.machine.self().getLevel(); - var pos = recipeLogic.machine.self().getPos(); - for (Direction side : GTUtil.DIRECTIONS) { - if (side.getAxis() != Direction.Axis.Y) { - var block = level.getBlockState(pos.relative(side)); - if (block.getBlock() == blockA) hasBlockA = true; - if (block.getBlock() == blockA) hasBlockB = true; - if (hasBlockA && hasBlockB) return true; + Level level = recipeLogic.getMachine().getLevel(); + BlockPos pos = recipeLogic.getMachine().getPos(); + if (level == null) { + return false; + } + Set> remainingBlocks = new HashSet<>(getOrInitBlocks(recipe)); + if (remainingBlocks.isEmpty()) { + return true; + } + + for (BlockPos offset : GTUtil.NON_CORNER_NEIGHBOURS) { + BlockState block = level.getBlockState(pos.offset(offset)); + for (var it = remainingBlocks.iterator(); it.hasNext();) { + if (block.is(it.next())) { + it.remove(); + break; + } } + if (remainingBlocks.isEmpty()) return true; } return false; } + public @NotNull List> getOrInitBlocks(@NotNull GTRecipe recipe) { + if (getBlocks().isEmpty() || (recipe.data.contains("blockA") && recipe.data.contains("blockB"))) { + List> blocks = new ArrayList<>(); + + Block blockA = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(recipe.data.getString("blockA"))); + if (!blockA.defaultBlockState().isAir()) { + blocks.add(HolderSet.direct(blockA.builtInRegistryHolder())); + } + Block blockB = BuiltInRegistries.BLOCK.get(ResourceLocation.parse(recipe.data.getString("blockB"))); + if (!blockB.defaultBlockState().isAir()) { + blocks.add(HolderSet.direct(blockB.builtInRegistryHolder())); + } + setBlocks(blocks); + } + return getBlocks(); + } + @Override public RecipeCondition createTemplate() { return new AdjacentBlockCondition(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentFluidCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentFluidCondition.java new file mode 100644 index 00000000000..e335adc4fae --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentFluidCondition.java @@ -0,0 +1,155 @@ +package com.gregtechceu.gtceu.common.recipe.condition; + +import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +import com.gregtechceu.gtceu.api.recipe.condition.RecipeCondition; +import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; +import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; +import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; +import com.gregtechceu.gtceu.utils.GTUtil; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderSet; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.FluidState; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +import static com.gregtechceu.gtceu.api.recipe.condition.ConditionSerializeUtils.decodeHolderSets; +import static com.gregtechceu.gtceu.api.recipe.condition.ConditionSerializeUtils.encodeHolderSets; + +@NoArgsConstructor +public class AdjacentFluidCondition extends RecipeCondition { + + // spotless:off + public static final MapCodec CODEC = + RecordCodecBuilder.mapCodec(instance -> RecipeCondition.isReverse(instance).and( + Codec.STRING.fieldOf("fluidString").forGetter(AdjacentFluidCondition::getFluidString) + ).apply(instance, AdjacentFluidCondition::new)); + // spotless:on + + @Getter + private @NotNull String fluidString = ""; + + private @Nullable List> fluids = null; + + public void setFluids(@NotNull List> fluids) { + this.fluids = fluids; + this.fluidString = encodeHolderSets(fluids); + } + + public List> getFluids() { + if (fluids == null) { + fluids = decodeHolderSets(getFluidString(), Registries.FLUID); + } + return fluids; + } + + public AdjacentFluidCondition(@NotNull List> fluids) { + this.setFluids(fluids); + } + + public AdjacentFluidCondition(boolean isReverse, String fluidString) { + super(isReverse); + this.fluidString = fluidString; + } + + public AdjacentFluidCondition(boolean isReverse, @NotNull List> fluids) { + super(isReverse); + this.setFluids(fluids); + } + + public static AdjacentFluidCondition fromFluids(Collection fluids) { + return new AdjacentFluidCondition(fluids.stream() + .map(Fluid::builtInRegistryHolder) + .>map(HolderSet::direct) + .toList()); + } + + public static AdjacentFluidCondition fromFluids(Fluid... fluids) { + return fromFluids(Arrays.asList(fluids)); + } + + public static AdjacentFluidCondition fromTags(Collection> tags) { + return new AdjacentFluidCondition(tags.stream() + .>map(BuiltInRegistries.FLUID::getOrCreateTag) + .toList()); + } + + @SafeVarargs + public static AdjacentFluidCondition fromTags(TagKey... tags) { + return fromTags(Arrays.asList(tags)); + } + + @Override + public RecipeConditionType getType() { + return GTRecipeConditions.ADJACENT_FLUID; + } + + @Override + public Component getTooltips() { + return Component.translatable("recipe.condition.adjacent_fluid.tooltip"); + } + + @Override + public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { + Level level = recipeLogic.getMachine().getLevel(); + BlockPos pos = recipeLogic.getMachine().getPos(); + if (level == null) { + return false; + } + Set> remainingFluids = new HashSet<>(getOrInitFluids(recipe)); + if (remainingFluids.isEmpty()) { + return true; + } + + for (BlockPos offset : GTUtil.NON_CORNER_NEIGHBOURS) { + FluidState fluid = level.getFluidState(pos.offset(offset)); + if (!fluid.isSource()) continue; + for (var it = remainingFluids.iterator(); it.hasNext();) { + if (fluid.is(it.next())) { + it.remove(); + break; + } + } + if (remainingFluids.isEmpty()) return true; + } + return false; + } + + public @NotNull List> getOrInitFluids(@NotNull GTRecipe recipe) { + if (this.getFluids().isEmpty() || (recipe.data.contains("fluidA") && recipe.data.contains("fluidB"))) { + List> fluids = new ArrayList<>(); + + Fluid fluidA = BuiltInRegistries.FLUID.get(ResourceLocation.parse(recipe.data.getString("fluidA"))); + if (!fluidA.defaultFluidState().isEmpty()) { + fluids.add(HolderSet.direct(fluidA.builtInRegistryHolder())); + } + Fluid fluidB = BuiltInRegistries.FLUID.get(ResourceLocation.parse(recipe.data.getString("fluidB"))); + if (!fluidB.defaultFluidState().isEmpty()) { + fluids.add(HolderSet.direct(fluidB.builtInRegistryHolder())); + } + + this.setFluids(fluids); + } + return this.getFluids(); + } + + @Override + public RecipeCondition createTemplate() { + return new AdjacentFluidCondition(); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/BiomeCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/BiomeCondition.java index b0439a909f9..dafa86a3ced 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/BiomeCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/BiomeCondition.java @@ -8,7 +8,6 @@ import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; -import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.codec.StreamCodec; import net.minecraft.resources.ResourceKey; @@ -16,7 +15,6 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; -import com.google.gson.JsonObject; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import io.netty.buffer.ByteBuf; @@ -75,25 +73,4 @@ public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic reci public BiomeCondition createTemplate() { return new BiomeCondition(); } - - @NotNull - @Override - public JsonObject serialize() { - JsonObject config = super.serialize(); - config.addProperty("biome", biome.location().toString()); - return config; - } - - @Override - public BiomeCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - biome = RESOURCE_KEY_STREAM_CODEC.decode(buf); - return this; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - buf.writeResourceKey(biome); - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/CleanroomCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/CleanroomCondition.java index 38789c95b09..97e2f742bc2 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/CleanroomCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/CleanroomCondition.java @@ -12,10 +12,8 @@ import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; -import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; -import com.google.gson.JsonObject; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import lombok.AllArgsConstructor; @@ -67,27 +65,6 @@ public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic reci return true; } - @NotNull - @Override - public JsonObject serialize() { - JsonObject value = super.serialize(); - value.addProperty("cleanroom", cleanroom.name()); - return value; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - buf.writeUtf(this.cleanroom.name()); - } - - @Override - public RecipeCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - this.cleanroom = CleanroomType.getByNameOrDefault(buf.readUtf()); - return this; - } - @Override public RecipeCondition createTemplate() { return new CleanroomCondition(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java index b9594378785..7069e6eeabf 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/DimensionCondition.java @@ -15,7 +15,6 @@ import com.lowdragmc.lowdraglib.jei.IngredientIO; import net.minecraft.core.registries.Registries; -import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -23,7 +22,6 @@ import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; -import com.google.gson.JsonObject; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import lombok.Getter; @@ -94,25 +92,4 @@ public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic reci public DimensionCondition createTemplate() { return new DimensionCondition(); } - - @NotNull - @Override - public JsonObject serialize() { - JsonObject config = super.serialize(); - config.addProperty("dimension", dimension.toString()); - return config; - } - - @Override - public DimensionCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - dimension = buf.readResourceKey(Registries.DIMENSION); - return this; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - buf.writeResourceKey(dimension); - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EUToStartCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EUToStartCondition.java index 81e4f6c32b8..57a6d1548bc 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EUToStartCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EUToStartCondition.java @@ -7,10 +7,8 @@ import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; -import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; -import com.google.gson.JsonObject; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -57,25 +55,4 @@ public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic reci public RecipeCondition createTemplate() { return new EUToStartCondition(); } - - @NotNull - @Override - public JsonObject serialize() { - JsonObject config = super.serialize(); - config.addProperty("euToStart", euToStart); - return config; - } - - @Override - public RecipeCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - euToStart = buf.readLong(); - return this; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - buf.writeLong(euToStart); - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EnvironmentalHazardCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EnvironmentalHazardCondition.java index 472a3489132..8699fb02718 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EnvironmentalHazardCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/EnvironmentalHazardCondition.java @@ -10,11 +10,9 @@ import com.gregtechceu.gtceu.data.medicalcondition.GTMedicalConditions; import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; -import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; -import com.google.gson.JsonObject; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import lombok.AllArgsConstructor; @@ -65,27 +63,6 @@ public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic reci return zone != null && zone.strength() > 0; } - @NotNull - @Override - public JsonObject serialize() { - JsonObject value = super.serialize(); - value.addProperty("condition", condition.name); - return value; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - buf.writeUtf(this.condition.name); - } - - @Override - public EnvironmentalHazardCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - this.condition = MedicalCondition.CONDITIONS.get(buf.readUtf()); - return this; - } - @Override public EnvironmentalHazardCondition createTemplate() { return new EnvironmentalHazardCondition(); diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/FTBQuestCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/FTBQuestCondition.java index 7597152360d..753e9e71daa 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/FTBQuestCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/FTBQuestCondition.java @@ -8,10 +8,8 @@ import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; -import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; -import com.google.gson.JsonObject; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -79,24 +77,4 @@ public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic reci public RecipeCondition createTemplate() { return new FTBQuestCondition(); } - - @Override - public @NotNull JsonObject serialize() { - var obj = super.serialize(); - obj.addProperty("questId", parsedQuestId); - return obj; - } - - @Override - public FTBQuestCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - parsedQuestId = buf.readLong(); - return this; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - buf.writeLong(parsedQuestId); - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/GameStageCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/GameStageCondition.java index 6eb3894624b..9767098a7d9 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/GameStageCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/GameStageCondition.java @@ -1,90 +1,67 @@ -package com.gregtechceu.gtceu.common.recipe.condition; - -import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; -import com.gregtechceu.gtceu.api.recipe.condition.RecipeCondition; -import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; -import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; -import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; -import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; - -import net.darkhax.gamestages.data.GameStageSaveHandler; -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.chat.Component; - -import com.google.gson.JsonObject; -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import lombok.NoArgsConstructor; -import org.jetbrains.annotations.NotNull; - -@NoArgsConstructor -public class GameStageCondition extends RecipeCondition { - - public static final MapCodec CODEC = RecordCodecBuilder - .mapCodec(instance -> RecipeCondition.isReverse(instance) - .and(Codec.STRING.fieldOf("stageName").forGetter(val -> val.stageName)) - .apply(instance, GameStageCondition::new)); - - private String stageName; - - public final static GameStageCondition INSTANCE = new GameStageCondition(); - - public GameStageCondition(String stageName) { - this(false, stageName); - } - - public GameStageCondition(boolean isReverse, String stageName) { - super(isReverse); - this.stageName = stageName; - } - - @Override - public RecipeConditionType getType() { - return GTRecipeConditions.GAMESTAGE; - } - - @Override - public Component getTooltips() { - if (isReverse) return Component.translatable("recipe.condition.gamestage.locked_stage", stageName); - return Component.translatable("recipe.condition.gamestage.unlocked_stage", stageName); - } - - @Override - public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { - MachineOwner owner = recipeLogic.machine.self().getOwner(); - if (owner == null) return false; - for (var player : owner.getMembers()) { - var playerData = GameStageSaveHandler.getPlayerData(player); - if (playerData != null && playerData.hasStage(stageName)) { - return true; - } - } - return false; - } - - @Override - public RecipeCondition createTemplate() { - return new GameStageCondition(); - } - - @Override - public @NotNull JsonObject serialize() { - var obj = super.serialize(); - obj.addProperty("stageName", stageName); - return obj; - } - - @Override - public GameStageCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - stageName = buf.readUtf(); - return this; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - buf.writeUtf(stageName); - } -} +// package com.gregtechceu.gtceu.common.recipe.condition; + +// import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +// import com.gregtechceu.gtceu.api.recipe.condition.RecipeCondition; +// import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; +// import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; +// import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; +// import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; + +// import net.darkhax.gamestages.data.GameStageSaveHandler; +// import net.minecraft.network.chat.Component; + +// import com.mojang.serialization.Codec; +// import com.mojang.serialization.codecs.RecordCodecBuilder; +// import lombok.NoArgsConstructor; +// import org.jetbrains.annotations.NotNull; + +// @NoArgsConstructor +// public class GameStageCondition extends RecipeCondition { + +// public static final MapCodec CODEC = RecordCodecBuilder +// .mapCodec(instance -> RecipeCondition.isReverse(instance) +// .and(Codec.STRING.fieldOf("stageName").forGetter(val -> val.stageName)) +// .apply(instance, GameStageCondition::new)); + +// private String stageName; + +// public final static GameStageCondition INSTANCE = new GameStageCondition(); + +// public GameStageCondition(String stageName) { +// this(false, stageName); +// } + +// public GameStageCondition(boolean isReverse, String stageName) { +// super(isReverse); +// this.stageName = stageName; +// } + +// @Override +// public RecipeConditionType getType() { +// return GTRecipeConditions.GAMESTAGE; +// } + +// @Override +// public Component getTooltips() { +// if (isReverse) return Component.translatable("recipe.condition.gamestage.locked_stage", stageName); +// return Component.translatable("recipe.condition.gamestage.unlocked_stage", stageName); +// } + +// @Override +// public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { +// MachineOwner owner = recipeLogic.machine.self().getOwner(); +// if (owner == null) return false; +// for (var player : owner.getMembers()) { +// var playerData = GameStageSaveHandler.getPlayerData(player); +// if (playerData != null && playerData.hasStage(stageName)) { +// return true; +// } +// } +// return false; +// } + +// @Override +// public RecipeCondition createTemplate() { +// return new GameStageCondition(); +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/HeraclesQuestCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/HeraclesQuestCondition.java index 3ad133771b9..985fad0626a 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/HeraclesQuestCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/HeraclesQuestCondition.java @@ -1,100 +1,106 @@ -package com.gregtechceu.gtceu.common.recipe.condition; - -import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; -import com.gregtechceu.gtceu.api.recipe.condition.RecipeCondition; -import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; -import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; -import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; -import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; - -import net.minecraft.network.RegistryFriendlyByteBuf; -import net.minecraft.network.chat.Component; - -import com.google.gson.JsonObject; -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import earth.terrarium.heracles.common.handlers.progress.QuestProgressHandler; -import earth.terrarium.heracles.common.handlers.progress.QuestsProgress; -import earth.terrarium.heracles.common.handlers.quests.QuestHandler; -import lombok.NoArgsConstructor; -import org.jetbrains.annotations.NotNull; - -@NoArgsConstructor -public class HeraclesQuestCondition extends RecipeCondition { - - public static final MapCodec CODEC = RecordCodecBuilder - .mapCodec(instance -> RecipeCondition.isReverse(instance) - .and(Codec.STRING.fieldOf("questId").forGetter(val -> val.questId)) - .apply(instance, HeraclesQuestCondition::new)); - - public final static HeraclesQuestCondition INSTANCE = new HeraclesQuestCondition(); - - private String questId; - - public HeraclesQuestCondition(String questId) { - this.questId = questId; - }; - - public HeraclesQuestCondition(boolean isReverse, String questId) { - super(isReverse); - this.questId = questId; - } - - @Override - public RecipeConditionType getType() { - return GTRecipeConditions.HERACLES_QUEST; - } - - @Override - public Component getTooltips() { - String questTitle = QuestHandler.get(questId).display().title().toString(); - - if (isReverse) { - return Component.translatable("recipe.condition.quest.not_completed.tooltip", questTitle); - } else { - return Component.translatable("recipe.condition.quest.completed.tooltip", questTitle); - } - } - - @Override - public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { - MachineOwner owner = recipeLogic.machine.self().getOwner(); - if (owner == null) return false; - for (var player : owner.getMembers()) { - QuestsProgress questsProgress = QuestProgressHandler - .getProgress(GTCEu.getMinecraftServer(), player); - var progress = questsProgress.getProgress(questId); - if (progress != null && (progress.isComplete() || QuestHandler.get(questId).tasks().isEmpty())) { - return true; - } - } - return false; - } - - @Override - public HeraclesQuestCondition createTemplate() { - return new HeraclesQuestCondition(); - } - - @Override - public @NotNull JsonObject serialize() { - var obj = super.serialize(); - obj.addProperty("questId", questId); - return obj; - } - - @Override - public HeraclesQuestCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - questId = buf.readUtf(); - return this; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - buf.writeUtf(questId); - } -} +// package com.gregtechceu.gtceu.common.recipe.condition; + +// import com.gregtechceu.gtceu.GTCEu; +// import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; +// import com.gregtechceu.gtceu.api.recipe.condition.RecipeCondition; +// import com.gregtechceu.gtceu.api.recipe.condition.RecipeConditionType; +// import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; +// import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; +// import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; + +// import net.minecraft.network.RegistryFriendlyByteBuf; +// import net.minecraft.network.chat.Component; + +// import net.minecraft.network.chat.Component; +// import net.neoforged.neoforge.server.ServerLifecycleHooks; +// import com.google.gson.JsonObject; +// import com.mojang.serialization.Codec; +// import com.mojang.serialization.MapCodec; +// import com.mojang.serialization.codecs.RecordCodecBuilder; +// import earth.terrarium.heracles.common.handlers.progress.QuestProgressHandler; +// import earth.terrarium.heracles.common.handlers.progress.QuestsProgress; +// import earth.terrarium.heracles.common.handlers.quests.QuestHandler; +// import lombok.NoArgsConstructor; +// import org.jetbrains.annotations.NotNull; + +// @NoArgsConstructor +// public class HeraclesQuestCondition extends RecipeCondition { + +// public static final MapCodec CODEC = RecordCodecBuilder +// .mapCodec(instance -> RecipeCondition.isReverse(instance) +// .and(Codec.STRING.fieldOf("questId").forGetter(val -> val.questId)) +// .apply(instance, HeraclesQuestCondition::new)); + +// public final static HeraclesQuestCondition INSTANCE = new HeraclesQuestCondition(); + +// private String questId; + +// public HeraclesQuestCondition(String questId) { +// this.questId = questId; +// }; + +// public HeraclesQuestCondition(boolean isReverse, String questId) { +// super(isReverse); +// this.questId = questId; +// } + +// @Override +// public RecipeConditionType getType() { +// return GTRecipeConditions.HERACLES_QUEST; +// } + +// @Override +// public Component getTooltips() { +// String questTitle = QuestHandler.get(questId).display().title().toString(); + +// if (isReverse) { +// return Component.translatable("recipe.condition.quest.not_completed.tooltip", questTitle); +// } else { +// return Component.translatable("recipe.condition.quest.completed.tooltip", questTitle); +// } +// } + +// @Override +// public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { +// MachineOwner owner = recipeLogic.machine.self().getOwner(); +// if (owner == null) return false; +// for (var player : owner.getMembers()) { +// QuestsProgress questsProgress = QuestProgressHandler +// .getProgress(GTCEu.getMinecraftServer(), player); +// var progress = questsProgress.getProgress(questId); +// if (progress != null && (progress.isComplete() || QuestHandler.get(questId).tasks().isEmpty())) { +// return true; +// } +// } +// return false; +// } + +// @Override +// public HeraclesQuestCondition createTemplate() { +// return new HeraclesQuestCondition(); +// } + +// @Override +// public @NotNull JsonObject serialize() { +// var obj = super.serialize(); +// obj.addProperty("questId", questId); +// return obj; +// } + +// @Override +// public HeraclesQuestCondition fromNetwork(RegistryFriendlyByteBuf buf) { +// super.fromNetwork(buf); +// questId = buf.readUtf(); +// return this; +// } + +// @Override +// public void toNetwork(RegistryFriendlyByteBuf buf) { +// super.toNetwork(buf); +// buf.writeUtf(questId); +// } +// @Override +// public RecipeCondition createTemplate() { +// return new HeraclesQuestCondition(); +// } +// } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/PositionYCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/PositionYCondition.java index 597adbb6680..4a8354ec683 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/PositionYCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/PositionYCondition.java @@ -6,10 +6,8 @@ import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; -import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; -import com.google.gson.JsonObject; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -69,28 +67,4 @@ public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic reci public PositionYCondition createTemplate() { return new PositionYCondition(); } - - @NotNull - @Override - public JsonObject serialize() { - JsonObject config = super.serialize(); - config.addProperty("min", this.min); - config.addProperty("max", this.max); - return config; - } - - @Override - public PositionYCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - min = buf.readVarInt(); - max = buf.readVarInt(); - return this; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - buf.writeVarInt(min); - buf.writeVarInt(max); - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RainingCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RainingCondition.java index e2f44c4d888..2998194de8e 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RainingCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/RainingCondition.java @@ -6,11 +6,9 @@ import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; -import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.world.level.Level; -import com.google.gson.JsonObject; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -61,25 +59,4 @@ public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic reci public RainingCondition createTemplate() { return new RainingCondition(); } - - @NotNull - @Override - public JsonObject serialize() { - JsonObject config = super.serialize(); - config.addProperty("level", level); - return config; - } - - @Override - public RainingCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - level = buf.readFloat(); - return this; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - buf.writeFloat(level); - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ResearchCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ResearchCondition.java index 6c7aabec1b1..a0aec5edf1b 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ResearchCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ResearchCondition.java @@ -7,11 +7,8 @@ import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; -import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; -import com.google.gson.JsonObject; -import com.mojang.serialization.JsonOps; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import lombok.AllArgsConstructor; @@ -46,27 +43,6 @@ public Component getTooltips() { return Component.translatable("gtceu.recipe.research"); } - @NotNull - @Override - public JsonObject serialize() { - JsonObject value = super.serialize(); - value.add("research", ResearchData.CODEC.encodeStart(JsonOps.INSTANCE, this.data).getOrThrow()); - return value; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - this.data.toNetwork(buf); - } - - @Override - public ResearchCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - this.data = ResearchData.fromNetwork(buf); - return this; - } - @Override public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic recipeLogic) { return true; diff --git a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ThunderCondition.java b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ThunderCondition.java index aedd2a93321..3b651dd9e41 100644 --- a/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ThunderCondition.java +++ b/src/main/java/com/gregtechceu/gtceu/common/recipe/condition/ThunderCondition.java @@ -6,11 +6,9 @@ import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.data.recipe.GTRecipeConditions; -import net.minecraft.network.RegistryFriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.world.level.Level; -import com.google.gson.JsonObject; import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; @@ -61,25 +59,4 @@ public boolean testCondition(@NotNull GTRecipe recipe, @NotNull RecipeLogic reci public ThunderCondition createTemplate() { return new ThunderCondition(); } - - @NotNull - @Override - public JsonObject serialize() { - JsonObject config = super.serialize(); - config.addProperty("level", level); - return config; - } - - @Override - public ThunderCondition fromNetwork(RegistryFriendlyByteBuf buf) { - super.fromNetwork(buf); - level = buf.readFloat(); - return this; - } - - @Override - public void toNetwork(RegistryFriendlyByteBuf buf) { - super.toNetwork(buf); - buf.writeFloat(level); - } } diff --git a/src/main/java/com/gregtechceu/gtceu/common/valueprovider/ModifiedIntProvider.java b/src/main/java/com/gregtechceu/gtceu/common/valueprovider/ModifiedIntProvider.java new file mode 100644 index 00000000000..014deb864a5 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/common/valueprovider/ModifiedIntProvider.java @@ -0,0 +1,32 @@ +package com.gregtechceu.gtceu.common.valueprovider; + +import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; + +import net.minecraft.util.valueproviders.BiasedToBottomInt; +import net.minecraft.util.valueproviders.ConstantFloat; +import net.minecraft.util.valueproviders.IntProvider; +import net.minecraft.util.valueproviders.UniformInt; + +/** + * Returns a new {@link IntProvider} with a {@link ContentModifier} applied. Mainly for use in modifying the providers + * used in {@link com.gregtechceu.gtceu.api.recipe.ingredient.IntProviderIngredient} + * and {@link com.gregtechceu.gtceu.api.recipe.ingredient.IntProviderFluidIngredient} + * for recipe batches/parallels. + */ +public class ModifiedIntProvider { + + public static IntProvider of(IntProvider source, ContentModifier modifier) { + if (source instanceof UniformInt uniform) { + return UniformInt.of(modifier.apply(uniform.getMinValue()), modifier.apply(uniform.getMaxValue())); + } + if (source instanceof BiasedToBottomInt biased) { + return BiasedToBottomInt.of(modifier.apply(biased.getMinValue()), modifier.apply(biased.getMaxValue())); + } + return new FlooredInt( + new AddedFloat( + new MultipliedFloat( + new CastedFloat(source), + ConstantFloat.of((float) modifier.multiplier())), + ConstantFloat.of((float) modifier.addition()))); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java b/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java index 8dfe0048e24..5b04b0ae9a7 100644 --- a/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java +++ b/src/main/java/com/gregtechceu/gtceu/config/ConfigHolder.java @@ -9,7 +9,6 @@ import dev.toma.configuration.config.Config; import dev.toma.configuration.config.Configurable; import dev.toma.configuration.config.format.ConfigFormats; -import org.jetbrains.annotations.ApiStatus; @Config(id = GTCEu.MOD_ID) public class ConfigHolder { @@ -17,14 +16,10 @@ public class ConfigHolder { public static ConfigHolder INSTANCE; private static final Object LOCK = new Object(); - @ApiStatus.Internal - public static dev.toma.configuration.config.ConfigHolder INTERNAL_INSTANCE; - public static void init() { synchronized (LOCK) { - if (INSTANCE == null || INTERNAL_INSTANCE == null) { - INTERNAL_INSTANCE = Configuration.registerConfig(ConfigHolder.class, ConfigFormats.YAML); - INSTANCE = INTERNAL_INSTANCE.getConfigInstance(); + if (INSTANCE == null) { + INSTANCE = Configuration.registerConfig(ConfigHolder.class, ConfigFormats.yaml()).getConfigInstance(); } } } @@ -62,8 +57,8 @@ public static class RecipeConfigs { @Configurable @Configurable.Comment({ "Change the recipe of Rods in the Lathe to 1 Rod and 2 Small Piles of Dust, instead of 2 Rods.", - "Default: false" }) - public boolean harderRods = false; // default false + "Default: true" }) + public boolean harderRods = true; // default true @Configurable @Configurable.Comment({ "Whether to make crafting recipes for Bricks, Firebricks, Nether Bricks, and Coke Bricks harder.", @@ -99,8 +94,8 @@ public static class RecipeConfigs { public boolean nerfPaperCrafting = true; // default true @Configurable @Configurable.Comment({ "Recipes for items like Iron Doors, Trapdoors, Anvil" + - " require Iron Plates, Rods, and more.", "Default: false" }) - public boolean hardAdvancedIronRecipes = false; // default false + " require Iron Plates, Rods, and more.", "Default: true" }) + public boolean hardAdvancedIronRecipes = true; // default true @Configurable @Configurable.Comment({ "Whether to make coloring blocks like Concrete or Glass harder.", "Default: false" }) public boolean hardDyeRecipes = false; // default false @@ -132,8 +127,33 @@ public static class RecipeConfigs { @Configurable @Configurable.Comment({ "Whether tools should have enchants or not. Like the flint sword getting fire aspect.", - "Default: true" }) - public boolean enchantedTools = true; + "Default: false" }) + public boolean enchantedTools = false; + + @Configurable + @Configurable.Comment({ "Whether to enable macerator decomposition recycling", "Default: true" }) + public boolean enableMaceratorRecycling = true; + @Configurable + @Configurable.Comment({ "Percentage yield of macerator decomposition recycling outputs, 1.0 means 100%", + "Default: 1.0f" }) + @Configurable.DecimalRange(min = 0.0f, max = 1.0f) + public float maceratorRecyclingYield = 1.0f; + @Configurable + @Configurable.Comment({ "Whether to enable arc furnace decomposition recycling", "Default: true" }) + public boolean enableArcRecycling = true; + @Configurable + @Configurable.Comment({ "Percentage yield of arc furnace decomposition recycling outputs, 1.0 means 100%", + "Default: 1.0f" }) + @Configurable.DecimalRange(min = 0.0f, max = 1.0f) + public float arcRecyclingYield = 1.0f; + @Configurable + @Configurable.Comment({ "Whether to enable extractor decomposition recycling", "Default: true" }) + public boolean enableExtractorRecycling = true; + @Configurable + @Configurable.Comment({ "Percentage yield of extractor decomposition recycling outputs, 1.0 means 100%", + "Default: 1.0f" }) + @Configurable.DecimalRange(min = 0.0f, max = 1.0f) + public float extractorRecyclingYield = 1.0f; } public static class CompatibilityConfigs { @@ -182,6 +202,10 @@ public static class CompatibilityConfigs { @Configurable.Comment({ "Whether dimension markers should show the dimension tier value.", "Default: false" }) public boolean showDimensionTier = false; + @Configurable + @Configurable.Comment({ "Whether Create compatibility will be available.", "Default: true" }) + public boolean createCompat = true; + public static class EnergyCompatConfig { @Configurable @@ -196,13 +220,13 @@ public static class EnergyCompatConfig { @Configurable @Configurable.Comment({ "Forge Energy to GTEU ratio for converting FE to EU.", "Only affects converters.", "Default: 4 FE == 1 EU" }) - @Configurable.Range(min = 1, max = 16) + @Configurable.Range(min = 1, max = Integer.MAX_VALUE) public int feToEuRatio = 4; @Configurable @Configurable.Comment({ "GTEU to Forge Energy ratio for converting EU to FE.", "Affects native conversion and Converters.", "Default: 4 FE == 1 EU" }) - @Configurable.Range(min = 1, max = 16) + @Configurable.Range(min = 1, max = Integer.MAX_VALUE) public int euToFeRatio = 4; } @@ -211,13 +235,13 @@ public static class AE2CompatConfig { @Configurable @Configurable.Comment({ "The interval between ME Hatch/Bus interact ME network.", "It may cause lag if the interval is too small.", "Default: 2 sec" }) - @Configurable.Range(min = 1, max = 80) + @Configurable.Range(min = 1) // Do Not Set a Maximum, if someone wants >80 ticks let them. public int updateIntervals = 40; @Configurable - @Configurable.Comment({ "The energy consumption of ME Hatch/Bus.", "Default: 1.0AE/t" }) - @Configurable.DecimalRange(min = 0.0, max = 10.0) - public double meHatchEnergyUsage = 1.0; + @Configurable.Comment({ "The energy consumption of ME Hatch/Bus.", "Default: 4.0AE/t" }) + @Configurable.DecimalRange(min = 0.0, max = Integer.MAX_VALUE) + public double meHatchEnergyUsage = 4.0; } public static class MinimapCompatConfig { @@ -230,12 +254,12 @@ public static class MinimapCompatConfig { @Configurable @Configurable.Comment({ "The radius, in blocks, that picking up a surface rock will search for veins in.", "-1 to disable.", "Default: 24" }) - @Configurable.Range(min = 1) + @Configurable.Range(min = -1) public int surfaceRockProspectRange = 24; @Configurable @Configurable.Comment({ "The radius, in blocks, that clicking an ore block will search for veins in.", "-1 to disable", "Default: 24" }) - @Configurable.Range(min = 1) + @Configurable.Range(min = -1) public int oreBlockProspectRange = 24; @Configurable @@ -343,11 +367,6 @@ public static class WorldGenConfigs { @Configurable.DecimalRange(min = 0f, max = 1f) public float rubberTreeSpawnChance = 0.5f; - @Configurable - @Configurable.Comment({ "Should all Stone Types drop unique Ore Item Blocks?", - "Default: false (meaning only Stone, Netherrack, and Endstone)" }) - public boolean allUniqueStoneTypes = false; - @Configurable @Configurable.Comment({ "Should Sand-like ores fall?", "This includes gravel, sand, and red sand ores.", "Default: false (no falling ores)" }) @@ -418,16 +437,11 @@ public static class OreVeinConfigs { public static class MachineConfigs { - @Configurable - @Configurable.Comment({ "Whether insufficient energy supply should reset Machine recipe progress to zero.", - "If true, progress will reset.", "If false, progress will decrease to zero with 2x speed", - "Default: true" }) - public boolean recipeProgressLowEnergy = true; @Configurable @Configurable.Comment({ "Whether to require a Wrench, Wirecutter, or other GregTech tools to break machines, casings, wires, and more.", - "Default: false" }) - public boolean requireGTToolsForBlocks = false; + "Default: true" }) + public boolean requireGTToolsForBlocks = true; @Configurable @Configurable.Comment({ "Whether machines explode in rainy weather or when placed next to certain terrain, such as fire or lava", @@ -467,6 +481,11 @@ public static class MachineConfigs { "This does nothing if enableCleanroom is false.", "Default: false" }) public boolean cleanMultiblocks = false; @Configurable + @Configurable.Comment({ + "Whether the miner should attempt to replace the block mined with a cobbled version of the ore", + "Default: true" }) + public boolean replaceWithCobbleVersion = true; + @Configurable @Configurable.Comment({ "Block to replace mined ores with in the miner and multiblock miner.", "Default: minecraft:cobblestone" }) public String replaceMinedBlocksWith = "minecraft:cobblestone"; @@ -476,6 +495,12 @@ public static class MachineConfigs { @Configurable @Configurable.Comment({ "Whether to enable the Maintenance Hatch, required for Multiblocks.", "Default: true" }) public boolean enableMaintenance = true; + @Configurable + @Configurable.Comment({ + "How often to check for maintenance, rolling a 1/6000 chance every X ticks (before secondary effects like Configurable Maintenance Hatch).", + "In default settings, this equates to a 5% chance every hour of a machine running.", + "Default: 1000 (ticks)" }) + public int maintenanceCheckRate = 1000; @Configurable @Configurable.Comment({ @@ -552,8 +577,8 @@ public static class MachineConfigs { public boolean orderedAssemblyLineItems = true; @Configurable @Configurable.Comment({ "Whether the Assembly Line should require the fluid inputs to be in order.", - "(Requires Ordered Assembly Line Item Inputs to be enabled.)", "Default: false" }) - public boolean orderedAssemblyLineFluids = false; + "(Requires Ordered Assembly Line Item Inputs to be enabled.)", "Default: true" }) + public boolean orderedAssemblyLineFluids = true; @Configurable @Configurable.Comment({ @@ -562,6 +587,10 @@ public static class MachineConfigs { }) public int steamMultiParallelAmount = 8; + @Configurable + @Configurable.Comment("Whether the Drums can input fluids from the output side (bottom).") + public boolean allowDrumsInputFluidsFromOutputSide = false; + @Configurable @Configurable.Comment("Small Steam Boiler Options") public SmallBoilers smallBoilers = new SmallBoilers(); @@ -666,7 +695,7 @@ public static class ToolConfigs { @Configurable.Range(min = 0, max = 14) public int voltageTierQuarkTech = 5; @Configurable - @Configurable.Comment({ "Advanced QuarkTech Suit Chestplate Voltage Tier.", "Default: 5 (LuV)" }) + @Configurable.Comment({ "Advanced QuarkTech Suit Chestplate Voltage Tier.", "Default: 6 (LuV)" }) @Configurable.Range(min = 0, max = 14) public int voltageTierAdvQuarkTech = 6; @Configurable @@ -724,6 +753,11 @@ public static class ClientConfigs { @Configurable.Comment({ "Whether or not to enable Emissive Textures for GregTech Machines.", "Default: true" }) public boolean machinesEmissiveTextures = true; @Configurable + @Configurable.Comment({ + "Whether most machines will have block entity renderers, mainly used for rendering certain covers. (Restart required)", + "Disable if experiencing performance issues.", "Default: true" }) + public boolean machinesHaveBERsByDefault = true; + @Configurable @Configurable.Comment({ "Whether or not sounds should be played when using tools outside of crafting.", "Default: true" }) public boolean toolUseSounds = true; @@ -760,6 +794,8 @@ public static class ClientConfigs { public ArmorHud armorHud = new ArmorHud(); @Configurable public RendererConfigs renderer = new RendererConfigs(); + @Configurable + public TankItemFluidPreview tankItemFluidPreview = new TankItemFluidPreview(); public int getDefaultPaintingColor() { // OR with full alpha to differentiate from a machine that's painted white (map color 0xffffff) @@ -782,6 +818,16 @@ public static class ArmorHud { @Configurable.Range(min = 0, max = 100) public int hudOffsetY = 0; } + + public static class TankItemFluidPreview { + + @Configurable + @Configurable.Comment({ "Set true to render the including fluid icons to GT Drums" }) + public boolean drum = false; + @Configurable + @Configurable.Comment({ "Set true to render the including fluid icons to Super (Quantum) Tanks" }) + public boolean quantumTank = false; + } } public static class DeveloperConfigs { @@ -811,6 +857,10 @@ public static class RendererConfigs { @Configurable.Comment({ "Render fluids in multiblocks that support them?", "Default: true" }) public boolean renderFluids = true; + @Configurable + @Configurable.Comment({ "Render growing plants in multiblocks that support them?", "Default: true" }) + public boolean renderGrowingPlants = true; + @Configurable @Configurable.Comment({ "Whether or not to color tiered machine highlights in the tier color", "Default: true" }) diff --git a/src/main/java/com/gregtechceu/gtceu/core/IMappedRegistryAccess.java b/src/main/java/com/gregtechceu/gtceu/core/IMappedRegistryAccess.java index 26a3de6d2ce..01639cba866 100644 --- a/src/main/java/com/gregtechceu/gtceu/core/IMappedRegistryAccess.java +++ b/src/main/java/com/gregtechceu/gtceu/core/IMappedRegistryAccess.java @@ -39,4 +39,30 @@ public interface IMappedRegistryAccess { default Map, RegistrationInfo> gtceu$getRegistrationInfos() { throw new AssertionError(); } + + /// FOR TESTING ONLY; THIS WILL FUCK UP THINGS IF THINGS ARE IN USE! + default void gtceu$remove(ResourceKey key) { + if (this.gtceu$isFrozen()) { + throw new IllegalStateException("Cannot remove entry from a frozen registry: " + key); + } + + Holder.Reference ref = this.gtceu$getByKey().remove(key); + if (ref == null) { + return; // not present, nothing to remove + } + + this.gtceu$getByLocation().remove(key.location()); + + T value = ref.value(); + this.gtceu$getByValue().remove(value); + + int id = this.gtceu$getToId().removeInt(value); + ObjectList> byId = this.gtceu$getById(); + + if (id >= 0 && id < byId.size()) { + byId.set(id, null); + } + + this.gtceu$getRegistrationInfos().remove(key); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/core/MixinHelpers.java b/src/main/java/com/gregtechceu/gtceu/core/MixinHelpers.java index a72cffc2b69..eb0685d6910 100644 --- a/src/main/java/com/gregtechceu/gtceu/core/MixinHelpers.java +++ b/src/main/java/com/gregtechceu/gtceu/core/MixinHelpers.java @@ -192,14 +192,33 @@ public static void generateGTDynamicTags(Map new ArrayList<>()).addAll(entries); if (material.hasProperty(PropertyKey.WOOD)) { - tagMap.computeIfAbsent(BlockTags.MINEABLE_WITH_AXE.location(), path -> new ArrayList<>()) - .addAll(entries); + // Wood blocks with this tag always allow a Wrench, but only allow an Axe if the config is + // not set. Pickaxe is never allowed (special case) + if (entry.tagPrefix().miningToolTag() + .contains(CustomTags.MINEABLE_WITH_CONFIG_VALID_PICKAXE_WRENCH)) { + tagMap.computeIfAbsent(CustomTags.MINEABLE_WITH_WRENCH.location(), + path -> new ArrayList<>()).addAll(entries); + if (!ConfigHolder.INSTANCE.machines.requireGTToolsForBlocks) { + tagMap.computeIfAbsent(BlockTags.MINEABLE_WITH_AXE.location(), + path -> new ArrayList<>()) + .addAll(entries); + } + } else { + // Other wood stuff should still get the Axe tag + tagMap.computeIfAbsent(BlockTags.MINEABLE_WITH_AXE.location(), path -> new ArrayList<>()) + .addAll(entries); + } } else { for (var tag : entry.tagPrefix().miningToolTag()) { tagMap.computeIfAbsent(tag.location(), path -> new ArrayList<>()).addAll(entries); } } } + + if (entry.tagPrefix() == TagPrefix.frameGt) { + tagMap.computeIfAbsent(CustomTags.SLOW_WALKABLE_BLOCKS.location(), path -> new ArrayList<>()) + .addAll(entries); + } }); GTRegistries.MACHINES.forEach(machine -> { @@ -293,11 +312,6 @@ public static void generateGTDynamicLoot(TriConsumer defensiveCopy = new HashSet<>(mwsd.getControllersInChunk(chunk.getPos())); for (MultiblockState structure : defensiveCopy) { - if (structure.getController() == null || !structure.getController().isFormed()) { - // skip for unloaded/unformed multiblocks - continue; - } if (structure.isPosInCache(pos)) { serverLevel.getServer().executeBlocking(() -> structure.onBlockStateChanged(pos, newState)); } diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/MultiVariantMixin.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/MultiVariantMixin.java new file mode 100644 index 00000000000..0929f70ff1b --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/MultiVariantMixin.java @@ -0,0 +1,35 @@ +package com.gregtechceu.gtceu.core.mixins; + +import net.minecraft.client.renderer.block.model.MultiVariant; +import net.minecraft.client.renderer.block.model.Variant; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.*; +import net.minecraft.resources.ResourceLocation; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +import java.util.function.Function; + +import javax.annotation.Nullable; + +@Mixin(MultiVariant.class) +public class MultiVariantMixin { + + /** + * @author RubenVerg + * @reason Use two-argument version of bake + */ + @Nullable + @Overwrite + @SuppressWarnings("deprecation") + public BakedModel bake(ModelBaker pBaker, Function pSpriteGetter, ModelState pState, + ResourceLocation pLocation) { + var builder = new WeightedBakedModel.Builder(); + for (Variant variant : ((MultiVariant) ((Object) this)).getVariants()) { + final var baked = pBaker.bake(variant.getModelLocation(), variant); + builder.add(baked, variant.getWeight()); + } + return builder.build(); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/StemBlockAccessor.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/StemBlockAccessor.java new file mode 100644 index 00000000000..4b1b6b3cc68 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/StemBlockAccessor.java @@ -0,0 +1,14 @@ +package com.gregtechceu.gtceu.core.mixins; + +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.StemBlock; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(StemBlock.class) +public interface StemBlockAccessor { + + @Accessor("fruit") + Block gtceu$getFruit(); +} diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/client/ItemEntityMixin.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/client/ItemEntityMixin.java new file mode 100644 index 00000000000..f07089bc5de --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/client/ItemEntityMixin.java @@ -0,0 +1,32 @@ +package com.gregtechceu.gtceu.core.mixins.client; + +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.material.ChemicalHelper; +import com.gregtechceu.gtceu.api.tag.TagPrefix; +import com.gregtechceu.gtceu.data.sound.GTSoundEntries; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.item.ItemEntity; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ItemEntity.class) +public class ItemEntityMixin { + + @Unique + private boolean gtceu$wasOnGround = ((Entity) (Object) this).onGround(); + + @Inject(method = "tick", at = @At(value = "HEAD")) + public void beforeTick(CallbackInfo ci) { + ItemEntity entity = (ItemEntity) (Object) this; + if (GTValues.FOOLS.getAsBoolean() && !gtceu$wasOnGround && entity.onGround() && + ChemicalHelper.getPrefix(entity.getItem().getItem()) == TagPrefix.rodLong) { + GTSoundEntries.METAL_PIPE.playFrom(entity, 10, 1); + } + gtceu$wasOnGround = entity.onGround(); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/core/mixins/client/LevelRendererMixin.java b/src/main/java/com/gregtechceu/gtceu/core/mixins/client/LevelRendererMixin.java index 1c36015b6e3..211055e60ff 100644 --- a/src/main/java/com/gregtechceu/gtceu/core/mixins/client/LevelRendererMixin.java +++ b/src/main/java/com/gregtechceu/gtceu/core/mixins/client/LevelRendererMixin.java @@ -7,6 +7,7 @@ import com.gregtechceu.gtceu.api.item.tool.ToolHelper; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.feature.ITieredMachine; +import com.gregtechceu.gtceu.api.machine.steam.SteamMachine; import com.gregtechceu.gtceu.api.material.ChemicalHelper; import com.gregtechceu.gtceu.api.material.material.stack.MaterialEntry; import com.gregtechceu.gtceu.api.pipenet.IPipeNode; @@ -108,14 +109,15 @@ private void renderLevel(DeltaTracker partialTick, boolean renderBlockOutline, C UseOnContext context = new UseOnContext(minecraft.player, InteractionHand.MAIN_HAND, hitResult); var positions = ToolHelper.getHarvestableBlocks(aoeDefinition, context); - Vec3 vec3 = camera.getPosition(); - double camX = vec3.x(); - double camY = vec3.y(); - double camZ = vec3.z(); + Vec3 camPos = camera.getPosition(); + + poseStack.pushPose(); + poseStack.translate(-camPos.x(), -camPos.y(), -camPos.z()); for (BlockPos pos : positions) { poseStack.pushPose(); - poseStack.translate(pos.getX() - camX, pos.getY() - camY, pos.getZ() - camZ); + poseStack.translate(pos.getX(), pos.getY(), pos.getZ()); + PoseStack.Pose last = poseStack.last(); VertexConsumer breakProgressDecal = new SheetedDecalTextureGenerator( this.renderBuffers.crumblingBufferSource() @@ -126,6 +128,8 @@ private void renderLevel(DeltaTracker partialTick, boolean renderBlockOutline, C level, poseStack, breakProgressDecal, modelData); poseStack.popPose(); } + + poseStack.popPose(); } @Shadow @@ -187,9 +191,14 @@ private static void renderShape(PoseStack poseStack, VertexConsumer consumer, Vo doRenderColoredOutline = true; rgb = materialEntry.material().getMaterialRGB(); } else if (level.getBlockEntity(pos) instanceof IMachineBlockEntity mbe) { - if (rendererCfg.coloredTieredMachineOutline && mbe.getMetaMachine() instanceof ITieredMachine tiered) { - doRenderColoredOutline = true; - rgb = GTValues.VCM[tiered.getTier()]; + if (rendererCfg.coloredTieredMachineOutline) { + if (mbe.getMetaMachine() instanceof SteamMachine steam) { + doRenderColoredOutline = true; + rgb = steam.isHighPressure() ? GTValues.VC_HP_STEAM : GTValues.VC_LP_STEAM; + } else if (mbe.getMetaMachine() instanceof ITieredMachine tiered) { + doRenderColoredOutline = true; + rgb = GTValues.VCM[tiered.getTier()]; + } } } else if (rendererCfg.coloredWireOutline && level.getBlockEntity(pos) instanceof IPipeNode pipe) { doRenderColoredOutline = true; diff --git a/src/main/java/com/gregtechceu/gtceu/data/block/GTBlocks.java b/src/main/java/com/gregtechceu/gtceu/data/block/GTBlocks.java index 42882b25be5..455cb37faa5 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/block/GTBlocks.java +++ b/src/main/java/com/gregtechceu/gtceu/data/block/GTBlocks.java @@ -51,6 +51,7 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.grower.TreeGrower; import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockSetType; import net.minecraft.world.level.block.state.properties.WoodType; import net.minecraft.world.level.material.MapColor; @@ -1174,6 +1175,7 @@ public static ItemColor leavesItemColor() { GTCEu.id("block/casings/signs/machine_casing_stripes_b")); public static Table> STONE_BLOCKS; + public static Map> COBBLE_BLOCKS = new HashMap<>(); public static BlockEntry RED_GRANITE; public static BlockEntry MARBLE; @@ -1249,6 +1251,12 @@ public static void generateStoneBlocks() { } STONE_BLOCKS = builder.build(); + STONE_BLOCKS.row(StoneBlockType.COBBLE).forEach((ore, block) -> { + if (ore.generateBlocks) { + GTBlocks.registerCobbleBlock(ore.getTagPrefix(), block::getDefaultState); + } + }); + RED_GRANITE = STONE_BLOCKS.get(StoneBlockType.STONE, StoneTypes.RED_GRANITE); MARBLE = STONE_BLOCKS.get(StoneBlockType.STONE, StoneTypes.MARBLE); LIGHT_CONCRETE = STONE_BLOCKS.get(StoneBlockType.STONE, StoneTypes.CONCRETE_LIGHT); @@ -1382,9 +1390,18 @@ S2 extends BlockBuilder> NonNullFunction unificationBlock(@NotNull }; } + public static void registerCobbleBlock(TagPrefix orePrefix, Supplier state) { + COBBLE_BLOCKS.put(orePrefix, state); + } + + public static void removeCobbleBlock(TagPrefix orePrefix) { + COBBLE_BLOCKS.remove(orePrefix); + } + public static void init() { // Decor Blocks generateStoneBlocks(); + initializeCobbleReplacements(); // Procedural Pipes/Wires REGISTRATE.creativeModeTab(GTCreativeModeTabs.MATERIAL_PIPE); @@ -1396,6 +1413,23 @@ public static void init() { GCYMBlocks.init(); } + private static void initializeCobbleReplacements() { + // replacement blocks for mc based stone types + registerCobbleBlock(TagPrefix.ore, Blocks.COBBLESTONE::defaultBlockState); + registerCobbleBlock(TagPrefix.oreDeepslate, Blocks.COBBLED_DEEPSLATE::defaultBlockState); + registerCobbleBlock(TagPrefix.oreAndesite, Blocks.ANDESITE::defaultBlockState); + registerCobbleBlock(TagPrefix.oreDiorite, Blocks.DIORITE::defaultBlockState); + registerCobbleBlock(TagPrefix.oreGranite, Blocks.GRANITE::defaultBlockState); + registerCobbleBlock(TagPrefix.oreSand, Blocks.SAND::defaultBlockState); + registerCobbleBlock(TagPrefix.oreGravel, Blocks.GRAVEL::defaultBlockState); + registerCobbleBlock(TagPrefix.oreRedSand, Blocks.RED_SAND::defaultBlockState); + registerCobbleBlock(TagPrefix.oreBasalt, Blocks.BASALT::defaultBlockState); + registerCobbleBlock(TagPrefix.oreBlackstone, Blocks.BLACKSTONE::defaultBlockState); + registerCobbleBlock(TagPrefix.oreEndstone, Blocks.END_STONE::defaultBlockState); + registerCobbleBlock(TagPrefix.oreNetherrack, Blocks.NETHERRACK::defaultBlockState); + registerCobbleBlock(TagPrefix.oreTuff, Blocks.TUFF::defaultBlockState); + } + public static boolean doMetalPipe(Material material) { return GTValues.FOOLS.getAsBoolean() && material.hasProperty(PropertyKey.INGOT) && !material.hasProperty(PropertyKey.POLYMER) && !material.hasProperty(PropertyKey.WOOD); diff --git a/src/main/java/com/gregtechceu/gtceu/data/cover/GTCovers.java b/src/main/java/com/gregtechceu/gtceu/data/cover/GTCovers.java index dc1b0dcadb8..e9c0a48cfc1 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/cover/GTCovers.java +++ b/src/main/java/com/gregtechceu/gtceu/data/cover/GTCovers.java @@ -9,6 +9,8 @@ import com.gregtechceu.gtceu.common.cover.*; import com.gregtechceu.gtceu.common.cover.detector.*; import com.gregtechceu.gtceu.common.cover.ender.EnderFluidLinkCover; +import com.gregtechceu.gtceu.common.cover.ender.EnderItemLinkCover; +import com.gregtechceu.gtceu.common.cover.ender.EnderRedstoneLinkCover; import com.gregtechceu.gtceu.common.cover.voiding.AdvancedFluidVoidingCover; import com.gregtechceu.gtceu.common.cover.voiding.AdvancedItemVoidingCover; import com.gregtechceu.gtceu.common.cover.voiding.FluidVoidingCover; @@ -37,8 +39,13 @@ public class GTCovers { public final static CoverDefinition INFINITE_WATER = register("infinite_water", InfiniteWaterCover::new); public final static CoverDefinition ENDER_FLUID_LINK = register("ender_fluid_link", EnderFluidLinkCover::new); + public final static CoverDefinition ENDER_ITEM_LINK = register("ender_item_link", EnderItemLinkCover::new); + public final static CoverDefinition ENDER_REDSTONE_LINK = register("ender_redstone_link", + EnderRedstoneLinkCover::new); public final static CoverDefinition SHUTTER = register("shutter", ShutterCover::new); public final static CoverDefinition COVER_STORAGE = register("storage", StorageCover::new); + public final static CoverDefinition WIRELESS_TRANSMITTER = register("wireless_transmitter", + WirelessTransmitterCover::new); public final static CoverDefinition[] CONVEYORS = registerTiered("conveyor", ConveyorCover::new, () -> tier -> new IOCoverRenderer( @@ -66,6 +73,10 @@ public class GTCovers { public final static CoverDefinition MACHINE_CONTROLLER = register("machine_controller", MachineControllerCover::new); + // public final static CoverDefinition WIRELESS_TRANSMITTER = register( + // "wireless_transmitter", + // WirelessTransmitterCover::new, + // () -> () -> new SimpleCoverRenderer(GTCEu.id("block/cover/wireless_transmitter"))); // Voiding public final static CoverDefinition ITEM_VOIDING = register("item_voiding", ItemVoidingCover::new); diff --git a/src/main/java/com/gregtechceu/gtceu/data/datafixer/GTDataFixers.java b/src/main/java/com/gregtechceu/gtceu/data/datafixer/GTDataFixers.java index c641b38e690..b3cf67f5075 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/datafixer/GTDataFixers.java +++ b/src/main/java/com/gregtechceu/gtceu/data/datafixer/GTDataFixers.java @@ -3,10 +3,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTCEuAPI; import com.gregtechceu.gtceu.api.datafixer.DataFixesInternals; -import com.gregtechceu.gtceu.common.datafixer.fixes.EntityDamageBehaviorFix; -import com.gregtechceu.gtceu.common.datafixer.fixes.GTItemStackComponentizationFix; -import com.gregtechceu.gtceu.common.datafixer.fixes.GTToolComponentFix; -import com.gregtechceu.gtceu.common.datafixer.fixes.OilVariantsRenameFix; +import com.gregtechceu.gtceu.common.datafixer.fixes.*; import com.gregtechceu.gtceu.config.ConfigHolder; import net.minecraft.util.datafix.DataFixTypes; @@ -63,12 +60,18 @@ public static void addFixers(DataFixerBuilder builder) { builder.addFixer(ItemRenameFix.create(schemaV1, "advanced_nanomuscle_chestplate rename fix", createRenamer("gtceu:avanced_nanomuscle_chestplate", "gtceu:advanced_nanomuscle_chestplate"))); - builder.addFixer(ItemRenameFix.create(schemaV1, "U238 rename fix", - createRenamer(Pattern.compile("gtceu:uranium_"), "gtceu:uranium_238_"))); - builder.addFixer(ItemRenameFix.create(schemaV1, "Pu239 rename fix", - createRenamer(Pattern.compile("gtceu:plutonium_"), "gtceu:plutonium_239_"))); - builder.addFixer(ItemRenameFix.create(schemaV1, "Red granite rename fix", - createRenamer(Pattern.compile("gtceu:granite_red"), "gtceu:red_granite"))); + builder.addFixer(ItemRenameFix.create(schemaV1, "U238 item rename fix", + createRenamer(Pattern.compile("gtceu:(.*)uranium_"), "gtceu:$1uranium_238_"))); + builder.addFixer(BlockRenameFix.create(schemaV1, "U238 block rename fix", + createRenamer(Pattern.compile("gtceu:(.*)uranium_"), "gtceu:$1uranium_238_"))); + builder.addFixer(ItemRenameFix.create(schemaV1, "Pu239 item rename fix", + createRenamer(Pattern.compile("gtceu:(.*)plutonium_"), "gtceu:$1plutonium_239_"))); + builder.addFixer(BlockRenameFix.create(schemaV1, "Pu239 block rename fix", + createRenamer(Pattern.compile("gtceu:(.*)plutonium_"), "gtceu:$1plutonium_239_"))); + builder.addFixer(ItemRenameFix.create(schemaV1, "Red granite item rename fix", + createRenamer(Pattern.compile("gtceu:(.*)granite_red"), "gtceu:$1red_granite"))); + builder.addFixer(BlockRenameFix.create(schemaV1, "Red granite block rename fix", + createRenamer(Pattern.compile("gtceu:(.*)granite_red"), "gtceu:$1red_granite"))); builder.addFixer(ItemRenameFix.create(schemaV1, "Raw oil bucket rename fix", createRenamer(OilVariantsRenameFix.RENAMED_ITEM_IDS))); @@ -78,7 +81,7 @@ public static void addFixers(DataFixerBuilder builder) { builder.addFixer(new GTItemStackComponentizationFix(schemaV1)); Schema schemaV2 = builder.addSchema(2, SAME_NAMESPACED); builder.addFixer(ItemRenameFix.create(schemaV2, "Tungstensteel rename fix", - createRenamer(Pattern.compile("gtceu:tungstensteel"), "gtceu:tungsten_steel"))); + createRenamer(Pattern.compile("gtceu:(.*)tungstensteel"), "gtceu:$1tungsten_steel"))); builder.addFixer(ItemRenameFix.create(schemaV2, "Palladium Substation Casing item rename fix", createRenamer("gtceu:palladium_substation", "gtceu:palladium_substation_casing"))); @@ -88,6 +91,13 @@ public static void addFixers(DataFixerBuilder builder) { Schema schemaV3 = builder.addSchema(3, SAME_NAMESPACED); builder.addFixer(new GTToolComponentFix(schemaV3)); builder.addFixer(new EntityDamageBehaviorFix(schemaV3)); + + Schema schemaV4 = builder.addSchema(4, SAME_NAMESPACED); + builder.addFixer(new DataItemComponentFix(schemaV4)); + builder.addFixer(ItemRenameFix.create(schemaV1, "Limonite rename fix", + createRenamer(Pattern.compile("gtceu:(.*)yellow_limonite"), "gtceu:$1limonite"))); + builder.addFixer(BlockRenameFix.create(schemaV1, "Limonite rename fix", + createRenamer(Pattern.compile("gtceu:(.*)yellow_limonite"), "gtceu:$1limonite"))); } private static UnaryOperator createRenamer(String oldName, String newName) { diff --git a/src/main/java/com/gregtechceu/gtceu/data/datagen/GTVanillaDatagen.java b/src/main/java/com/gregtechceu/gtceu/data/datagen/GTVanillaDatagen.java index 6dbac8c67f6..06a98b786b8 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/datagen/GTVanillaDatagen.java +++ b/src/main/java/com/gregtechceu/gtceu/data/datagen/GTVanillaDatagen.java @@ -23,7 +23,7 @@ import java.util.Set; -@EventBusSubscriber(modid = GTCEu.MOD_ID, bus = EventBusSubscriber.Bus.MOD) +@EventBusSubscriber(modid = GTCEu.MOD_ID) public class GTVanillaDatagen { @SubscribeEvent diff --git a/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/ConfigurationLang.java b/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/ConfigurationLang.java index 99823098b41..36483223dbf 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/ConfigurationLang.java +++ b/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/ConfigurationLang.java @@ -4,6 +4,8 @@ import com.gregtechceu.gtceu.config.ConfigHolder; import com.tterrag.registrate.providers.RegistrateLangProvider; +import dev.toma.configuration.Configuration; +import dev.toma.configuration.config.format.ConfigFormats; import dev.toma.configuration.config.value.ConfigValue; import dev.toma.configuration.config.value.ObjectValue; @@ -14,7 +16,8 @@ public class ConfigurationLang { public static void init(RegistrateLangProvider provider) { - dfs(provider, new HashSet<>(), ConfigHolder.INTERNAL_INSTANCE.getValueMap()); + dfs(provider, new HashSet<>(), + Configuration.registerConfig(ConfigHolder.class, ConfigFormats.yaml()).getValueMap()); } private static void dfs(RegistrateLangProvider provider, Set added, Map> map) { diff --git a/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/IntegrationLang.java b/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/IntegrationLang.java index f2f10a90a14..3c07cf41365 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/IntegrationLang.java +++ b/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/IntegrationLang.java @@ -97,6 +97,9 @@ private static void initWailaLikeLang(RegistrateLangProvider provider) { provider.add("gtceu.jade.progress_sec", "%s / %s s"); provider.add("gtceu.jade.progress_tick", "%s / %s t"); provider.add("gtceu.jade.cleaned_this_second", "Cleaned hazard: %s/s"); + provider.add("gtceu.jade.fluid_use", "%s mB/t"); + provider.add("gtceu.jade.amperage_use", "%s A"); + provider.add("gtceu.jade.at", " @ "); provider.add("gtceu.top.energy_stored", " / %d EU"); provider.add("gtceu.top.progress_computation", " / %s CWU"); diff --git a/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/ItemLang.java b/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/ItemLang.java index 4e670b346e1..19a41074092 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/ItemLang.java +++ b/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/ItemLang.java @@ -30,14 +30,14 @@ private static void initGeneratedNames(RegistrateLangProvider provider) { } // Recipe Categories - provider.add("recipe_category.gtceu.arc_furnace_recycling", "Plasma Scrapping"); - provider.add("recipe_category.gtceu.macerator_recycling", "Part Grinding"); - provider.add("recipe_category.gtceu.extractor_recycling", "Scrap Remelting"); - provider.add("recipe_category.gtceu.ore_crushing", "Ore Grinding"); - provider.add("recipe_category.gtceu.ore_forging", "Ore Crushing"); - provider.add("recipe_category.gtceu.ore_bathing", "Ore Treating"); - provider.add("recipe_category.gtceu.chem_dyes", "Chemical Dyeing"); - provider.add("recipe_category.gtceu.ingot_molding", "Metal Molding"); + provider.add("gtceu.recipe.category.arc_furnace_recycling", "Arc Scrapping"); + provider.add("gtceu.recipe.category.macerator_recycling", "Part Grinding"); + provider.add("gtceu.recipe.category.extractor_recycling", "Scrap Remelting"); + provider.add("gtceu.recipe.category.ore_crushing", "Ore Grinding"); + provider.add("gtceu.recipe.category.ore_forging", "Ore Crushing"); + provider.add("gtceu.recipe.category.ore_bathing", "Ore Treating"); + provider.add("gtceu.recipe.category.chem_dyes", "Chemical Dyeing"); + provider.add("gtceu.recipe.category.ingot_molding", "Metal Molding"); // TagPrefix for (TagPrefix tagPrefix : GTRegistries.TAG_PREFIXES) { @@ -331,7 +331,7 @@ private static void initItemTooltips(RegistrateLangProvider provider) { multilineLang(provider, "item.gtceu.advanced_item_voiding_cover.tooltip", "§7Voids §fItems§7 with amount control as §fCover§7.\nActivate with §fSoft Mallet§7 after placement."); multilineLang(provider, "item.gtceu.facade_cover.tooltip", - "§7Decorative Outfit §fCover§7.\n§7Crafted using 3 Iron Plates and any block"); + "§7Decorative Outfit §fCover§7.\n§7Crafted using an Iron Plate and any block"); provider.add("item.gtceu.computer_monitor_cover.tooltip", "§7Displays §fData§7 as §fCover§7."); provider.add("item.gtceu.shutter_module_cover.tooltip", "§fBlocks Transfer§7 through attached Side as §fCover§7."); diff --git a/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/LangHandler.java b/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/LangHandler.java index aafcb5510ae..19bf8012fe5 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/LangHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/LangHandler.java @@ -57,7 +57,7 @@ public static void init(RegistrateLangProvider provider) { provider.add("recipe.condition.biome.tooltip", "Biome: %s"); provider.add("recipe.condition.pos_y.tooltip", "Y Level: %d <= Y <= %d"); provider.add("recipe.condition.steam_vent.tooltip", "Clean steam vent"); - provider.add("recipe.condition.rock_breaker.tooltip", "Fluid blocks around"); + provider.add("recipe.condition.adjacent_fluid.tooltip", "Fluid blocks around"); provider.add("recipe.condition.adjacent_block.tooltip", "Blocks around"); provider.add("recipe.condition.eu_to_start.tooltip", "EU to Start: %d%s"); provider.add("recipe.condition.daytime.day.tooltip", "Requires day time to work"); @@ -196,7 +196,13 @@ public static void init(RegistrateLangProvider provider) { provider.add("item.gtceu.tool.behavior.crop_harvesting", "§aHarvester: §fHarvests Crops"); provider.add("item.gtceu.tool.behavior.plunger", "§9Plumber: §fDrains Fluids"); provider.add("item.gtceu.tool.behavior.block_rotation", "§2Mechanic: §fRotates Blocks"); + provider.add("item.gtceu.tool.behavior.dowse_campfire", "§1Firefighter: §fDowses Campfires"); provider.add("item.gtceu.tool.behavior.damage_boost", "§4Damage Boost: §fExtra damage against %s"); + provider.add("item.gtceu.tool.behavior.prospecting.ore", "Found ore: %s"); + provider.add("item.gtceu.tool.behavior.prospecting.air", "Found an air pocket"); + provider.add("item.gtceu.tool.behavior.prospecting.water", "Found water"); + provider.add("item.gtceu.tool.behavior.prospecting.lava", "Found lava"); + provider.add("item.gtceu.tool.behavior.prospecting.changing", "Detected material change"); replace(provider, "item.gtceu.tool.sword", "%s Sword"); replace(provider, "item.gtceu.tool.pickaxe", "%s Pickaxe"); replace(provider, "item.gtceu.tool.shovel", "%s Shovel"); @@ -416,7 +422,7 @@ public static void init(RegistrateLangProvider provider) { multilineLang(provider, "cover.conveyor.distribution.round_robin_global", "Distribution Mode: §bRound Robin\n§7Splits items equally across connected inventories"); multilineLang(provider, "cover.conveyor.distribution.round_robin_prio", - "Distribution Mode: §bRound Robin with Priority\n§7Tries to split items across connected inventories and considers higher priorities first.\n§7Restrictive item pipes lower the priority of a path."); + "Distribution Mode: §bRound Robin with Restriction\n§7Tries to split items equally across connected inventories.\n§7Will not send items down Restrictive item pipes unless no other paths are available."); multilineLang(provider, "cover.conveyor.distribution.insert_first", "Distribution Mode: §bPriority\n§7Will insert into the first inventory with the highest priority it can find.\n§7Restrictive item pipes lower the priority of a path."); multilineLang(provider, "cover.conveyor.blocks_input.enabled", @@ -460,6 +466,7 @@ public static void init(RegistrateLangProvider provider) { multilineLang(provider, "cover.machine_controller.invert.disabled", "§eNormal§r - in this mode, the cover will require a signal weaker than the set redstone level to run"); provider.add("cover.machine_controller.redstone", "Min Redstone Strength: %d"); + provider.add("cover.machine_controller.suspend_powerfail", "Prevent Power Failing:"); provider.add("cover.machine_controller.mode.machine", "Control Machine"); provider.add("cover.machine_controller.mode.cover_up", "Control Cover (Top)"); provider.add("cover.machine_controller.mode.cover_down", "Control Cover (Bottom)"); @@ -469,6 +476,8 @@ public static void init(RegistrateLangProvider provider) { provider.add("cover.machine_controller.mode.cover_west", "Control Cover (West)"); provider.add("cover.machine_controller.mode.null", "Control Nothing"); provider.add("cover.ender_fluid_link.title", "Ender Fluid Link"); + provider.add("cover.ender_item_link.title", "Ender Item Link"); + provider.add("cover.ender_redstone_link.title", "Ender Redstone Link"); provider.add("cover.ender_fluid_link.iomode.enabled", "I/O Enabled"); provider.add("cover.ender_fluid_link.iomode.disabled", "I/O Disabled"); provider.add("cover.ender_fluid_link.tooltip.channel_description", "Set channel description with input text"); @@ -529,9 +538,9 @@ public static void init(RegistrateLangProvider provider) { provider.add("item.gtceu.bucket", "%s Bucket"); replace(provider, GTMaterials.FullersEarth.getUnlocalizedName(), "Fuller's Earth"); - // greg's humor is now on 1.21... - replace(provider, GTMaterials.Cooperite.getUnlocalizedName(), "Sheldonite"); - + replace(provider, GTMaterials.Cooperite.getUnlocalizedName(), "Sheldonite"); // greg's humor is now on + // 1.19... + replace(provider, GTMaterials.YellowLimonite.getUnlocalizedName(), "Yellow Limonite"); replace(provider, GTMaterials.HSSG.getUnlocalizedName(), "HSS-G"); replace(provider, GTMaterials.HSSE.getUnlocalizedName(), "HSS-E"); replace(provider, GTMaterials.HSSS.getUnlocalizedName(), "HSS-S"); @@ -596,6 +605,11 @@ public static void init(RegistrateLangProvider provider) { replace(provider, GTMaterials.IncoloyMA956.getUnlocalizedName(), "Incoloy MA-956"); replace(provider, GTMaterials.Stellite100.getUnlocalizedName(), "Stellite-100"); replace(provider, GTMaterials.HastelloyC276.getUnlocalizedName(), "Hastelloy C-276"); + replace(provider, GTMaterials.HeavyOil.getUnlocalizedName(), "Heavy Oil"); + replace(provider, GTMaterials.LightOil.getUnlocalizedName(), "Light Oil"); + replace(provider, GTMaterials.RawOil.getUnlocalizedName(), "Raw Oil"); + replace(provider, GTMaterials.Oil.getUnlocalizedName(), "Oil"); + replace(provider, GTMaterials.Creosote.getUnlocalizedName(), "Creosote"); replace(provider, GTBlocks.BATTERY_EMPTY_TIER_I.get().getDescriptionId(), "Empty Tier I Capacitor"); replace(provider, GTBlocks.BATTERY_LAPOTRONIC_EV.get().getDescriptionId(), "EV Lapotronic Capacitor"); @@ -750,7 +764,7 @@ public static void init(RegistrateLangProvider provider) { provider.add("behaviour.soft_hammer", "Activates and Deactivates Machines"); provider.add("behaviour.soft_hammer.enabled", "Working Enabled"); provider.add("behaviour.soft_hammer.disabled", "Working Disabled"); - provider.add("behaviour.soft_hammer.idle_after_cycle", "Pause machine after current cycle"); + provider.add("behaviour.soft_hammer.disabled_cycle", "Working Disabled after current cycle"); provider.add("behaviour.lighter.tooltip.description", "Can light things on fire"); provider.add("behaviour.lighter.tooltip.usage", "Shift-right click to open/close"); provider.add("behaviour.lighter.fluid.tooltip", "Can light things on fire with Butane or Propane"); @@ -923,6 +937,10 @@ public static void init(RegistrateLangProvider provider) { provider.add("gtceu.part_sharing.enabled", "Multiblock Sharing §aEnabled"); provider.add("gtceu.universal.liters", "%s mB"); provider.add("gtceu.universal.kiloliters", "%s B"); + provider.add("gtceu.universal.parentheses", "(%s)"); + provider.add("gtceu.universal.spaced_parentheses", "( %s )"); + provider.add("gtceu.universal.padded_parentheses", " (%s) "); + provider.add("gtceu.universal.padded_spaced_parentheses", " ( %s ) "); provider.add("gtceu.universal.tooltip.voltage_in", "§aVoltage IN: §f%d EU/t (%s§f)"); provider.add("gtceu.universal.tooltip.max_voltage_in", "§aMax Voltage IN: §f%d (%s§f)"); provider.add("gtceu.universal.tooltip.voltage_out", "§aVoltage OUT: §f%d EU/t (%s§f)"); @@ -992,6 +1010,7 @@ public static void init(RegistrateLangProvider provider) { provider.add("gtceu.recipe.scan_for_research", "Scan for Assembly Line"); provider.add("gtceu.recipe.computation_per_tick", "Min. Computation: %s CWU/t"); provider.add("gtceu.recipe.total_computation", "Computation: %s CWU"); + provider.add("gtceu.recipe.byproduct_tier", "Byproducts from %s§r+"); provider.add("gtceu.fluid.click_to_fill", "§7Click with a Fluid Container to §bfill §7the tank (Shift-click for a full stack)."); provider.add("gtceu.fluid.click_combined", @@ -1071,11 +1090,12 @@ public static void init(RegistrateLangProvider provider) { "Chunk Mode Enabled: Click to Disable.\n§7Switching requires an idle machine."); multilineLang(provider, "gtceu.gui.chunkmode.disabled", "Chunk Mode Disabled: Click to Enable.\n§7Switching requires an idle machine."); - multilineLang(provider, "gtceu.gui.multiblock_item_voiding", "Voiding Mode\n§7Voiding §6Items"); - multilineLang(provider, "gtceu.gui.multiblock_fluid_voiding", "Voiding Mode\n§7Voiding §9Fluids"); - multilineLang(provider, "gtceu.gui.multiblock_item_fluid_voiding", - "Voiding Mode\n§7Voiding §6Items §7and §9Fluids"); - multilineLang(provider, "gtceu.gui.multiblock_no_voiding", "Voiding Mode\n§7Voiding Nothing"); + provider.add("gtceu.gui.multiblock.voiding_mode", "Voiding Mode:"); + provider.add("gtceu.gui.item_voiding", "§7Voiding §6Items"); + provider.add("gtceu.gui.fluid_voiding", "§7Voiding §9Fluids"); + provider.add("gtceu.gui.all_voiding", + "§7Voiding §cAll"); + provider.add("gtceu.gui.no_voiding", "§7Voiding Nothing"); multilineLang(provider, "gtceu.gui.fisher_mode.tooltip", "Toggle junk items\nOff costs 2 string per operation"); provider.add("ore.spawnlocation.name", "Ore Spawn Information"); @@ -1137,7 +1157,9 @@ public static void init(RegistrateLangProvider provider) { provider.add("gtceu.multiblock.not_enough_energy", "WARNING: Machine needs more energy."); provider.add("gtceu.multiblock.not_enough_energy_output", "WARNING: Energy Dynamo Tier Too Low!"); provider.add("gtceu.multiblock.waiting", "WARNING: Machine is waiting."); - provider.add("gtceu.multiblock.batch_enabled", "Batching Mode: Enabled (%sx)"); + provider.add("gtceu.multiblock.total_runs", "Performing %d Recipes at once"); + provider.add("gtceu.multiblock.batch_enabled", "- %dx from Batching"); + provider.add("gtceu.multiblock.subtick_parallels", "- %dx from Overclocking"); provider.add("gtceu.machine.batch_enabled", "Batching Enabled"); provider.add("gtceu.machine.batch_disabled", "Batching Disabled"); provider.add("gtceu.multiblock.progress_percent", "Progress: %s%%"); @@ -1178,7 +1200,7 @@ public static void init(RegistrateLangProvider provider) { provider.add("gtceu.multiblock.universal.distinct.info", "If enabled, each Item Input Bus will be treated as fully distinct from each other for recipe lookup. Useful for things like Programmed Circuits, Extruder Shapes, etc."); provider.add("gtceu.multiblock.parallel", "Performing up to %d Recipes in Parallel"); - provider.add("gtceu.multiblock.parallel.exact", "Performing %d Recipes in Parallel"); + provider.add("gtceu.multiblock.parallel.exact", "- %dx from Parallels"); provider.add("gtceu.multiblock.multiple_recipemaps.header", "Machine Mode:"); provider.add("gtceu.multiblock.multiple_recipemaps.tooltip", "Screwdriver the controller to change which machine mode to use."); @@ -1268,6 +1290,7 @@ public static void init(RegistrateLangProvider provider) { provider.add("config.jade.plugin_gtceu.multiblock_structure", "[GTCEu] MultiBlock Structure"); provider.add("config.jade.plugin_gtceu.parallel_info", "[GTCEu] Parallel Info"); provider.add("config.jade.plugin_gtceu.primitive_pump", "[GTCEu] Primitive Pump Info"); + provider.add("config.jade.plugin_gtceu.data_bank", "[GTCEu] Data Bank Info"); provider.add("config.jade.plugin_gtceu.transformer", "[GTCEu] Transformer Info"); provider.add("config.jade.plugin_gtceu.stained_color", "[GTCEu] Stained Block Info"); provider.add("config.jade.plugin_gtceu.me_pattern_buffer", "[GTCEu] Pattern Buffer Info"); @@ -1295,16 +1318,46 @@ public static void init(RegistrateLangProvider provider) { "allow items input from the output side"); provider.add("gtceu.gui.item_auto_output.allow_input.disabled", "disable items input from the output side"); + provider.add("gtceu.gui.item_auto_output.enabled", "Item Auto Output: §aEnabled"); + provider.add("gtceu.gui.item_auto_output.disabled", "Item Auto Output: §cDisabled"); + multilineLang(provider, "gtceu.gui.item_auto_output.unselected", + """ + Item Auto Output + §7Select a side of the machine to configure its output. + """); + multilineLang(provider, "gtceu.gui.item_auto_output.other_direction", + """ + Item Auto Output: §6Other Direction + §7The machine's item output is set to another direction. + §7Click to move the output to the currently selected side. + """); provider.add("gtceu.gui.fluid_auto_output.allow_input.enabled", "allow fluids input from the output side"); provider.add("gtceu.gui.fluid_auto_output.allow_input.disabled", "disable fluids input from the output side"); + provider.add("gtceu.gui.fluid_auto_output.enabled", "Fluid Auto Output: §aEnabled"); + provider.add("gtceu.gui.fluid_auto_output.disabled", "Fluid Auto Output: §cDisabled"); + multilineLang(provider, "gtceu.gui.fluid_auto_output.unselected", + """ + Fluid Auto Output + §7Select a side of the machine to configure its output. + """); + multilineLang(provider, "gtceu.gui.fluid_auto_output.other_direction", + """ + Fluid Auto Output: §6Other Direction + §7The machine's fluid output is set to another direction. + §7Click to move the output to the currently selected side. + """); provider.add("gtceu.gui.auto_output.name", "auto"); provider.add("gtceu.gui.overclock.title", "Overclock Tier"); provider.add("gtceu.gui.overclock.range", "Available Tiers [%s, %s]"); + provider.add("gtceu.gui.directional_setting.title", "Directional Setting"); + provider.add("gtceu.gui.directional_setting.tab_tooltip", "Change Directional Setting"); + provider.add("gtceu.gui.machinemode.title", "Active Machine Mode"); provider.add("gtceu.gui.machinemode", "Active Machine Mode: %s"); + provider.add("gtceu.gui.machinemode.tab_tooltip", "Change active Machine Mode"); provider.add("gtceu.machine.available_recipe_map_1.tooltip", "Available Recipe Types: %s"); provider.add("gtceu.machine.available_recipe_map_2.tooltip", "Available Recipe Types: %s, %s"); provider.add("gtceu.machine.available_recipe_map_3.tooltip", "Available Recipe Types: %s, %s, %s"); @@ -1322,6 +1375,8 @@ public static void init(RegistrateLangProvider provider) { provider.add("gtceu.gui.content.chance_boosted_logic", "Chance at Tier: %s%% (%s)"); provider.add("gtceu.gui.content.count_range", "%s-%sx"); provider.add("gtceu.gui.content.fluid_range", "%s-%smB"); + provider.add("gtceu.gui.content.range", "%s-%s"); + provider.add("gtceu.gui.content.times_item", "x %s"); provider.add("gtceu.chance_logic.or", "OR"); provider.add("gtceu.chance_logic.and", "AND"); @@ -1409,6 +1464,319 @@ public static void init(RegistrateLangProvider provider) { provider.add("gtceu.tooltip.status.trinary.false", "False"); provider.add("gtceu.tooltip.status.trinary.true", "True"); provider.add("gtceu.tooltip.status.trinary.unknown", "Unknown"); + + provider.add("gtceu.tooltip.wireless_transmitter_bind", + "Binding to a transmitter cover at %s %s %s facing %s in %s"); + provider.add("gtceu.tooltip.computer_monitor_config", "Storing computer monitor cover configuration data"); + provider.add("gtceu.tooltip.computer_monitor_data", "Storing data: %s"); + provider.add("gtceu.tooltip.player_name.placeholder_processor", "Placeholder processor"); + provider.add("gtceu.tooltip.player_name.unknown", "Unknown player"); + + provider.add("gtceu.display_source.computer_monitor_cover", "Computer Monitor Cover"); + provider.add("gtceu.display_target.computer_monitor_cover", "Computer Monitor Cover"); + multiLang(provider, "gtceu.placeholder_info.energy", + "Returns the amount of energy stored.", + "Usage:", + " {energy} -> the amount of energy stored"); + multiLang(provider, "gtceu.placeholder_info.energyCapacity", + "Returns the max amount of energy that can be stored", + "Usage:", + "{energyCapacity} -> the energy capacity"); + multiLang(provider, "gtceu.placeholder_info.itemCount", + "Returns the amount of items (can be filtered).", + "Usage:", + " {itemCount} -> total item amount", + " {itemCount } -> amount of items with ids equal to item_id", + " {itemCount filter } -> amount of items matching filter in specified slot of this cover"); + multiLang(provider, "gtceu.placeholder_info.calc", + "Returns the result of a math function or operation.", + "Usage:", + " {calc } -> any_string", + " {calc } -> the result of the specified operation", + " {calc <+|-|*|/|//|>>|<<|%> } -> the result of the specified operation"); + multiLang(provider, "gtceu.placeholder_info.if", + "Returns one of the arguments depending on the condition. The condition is considered true if it is not an empty string and is not equal to 0.", + "Usage:", + " {if [returned_if_false]}"); + multiLang(provider, "gtceu.placeholder_info.obf", + "Returns the text from the first argument, obfuscated.", + "Usage:", + " {obf } -> obfuscated text"); + multiLang(provider, "gtceu.placeholder_info.underline", + "Returns the text from the first argument, underlined", + "Usage:", + " {underline } -> underlined text"); + multiLang(provider, "gtceu.placeholder_info.strike", + "Returns the text from the first text, displaying it as if it was crossed out", + "Usage:", + " {strike } -> crossed-out text"); + multiLang(provider, "gtceu.placeholder_info.color", + "Returns the text from the second argument, colored with the color from the first argument. All default minecraft chat colors can be used.", + "Usage:", + " {color } -> colored text"); + multiLang(provider, "gtceu.placeholder_info.tick", + "Returns the amount of ticks passed from when this cover was placed.", + "Usage:", + " {tick} -> the amount of ticks"); + multiLang(provider, "gtceu.placeholder_info.block", "Returns the block symbol (█).", + "Usage:", + " {block} -> '█'"); + multiLang(provider, "gtceu.placeholder_info.repeat", + "Returns the text from the second arguments, repeated the amount of times specified in the first argument.", + "Usage:", + " {repeat } -> text repeated the specified amount of times"); + multiLang(provider, "gtceu.placeholder_info.random", + "Returns a random number in the specified interval (inclusive).", + "Usage:", + " {random } -> a random number between min and max (inclusive)"); + multiLang(provider, "gtceu.placeholder_info.select", + "Returns the argument at the specified index (starting from 0)", + "Usage:", + " {select [arg1] [arg2] [arg3] ... -> argument at the specified index"); + multiLang(provider, "gtceu.placeholder_info.redstone", + "Returns the redstone signal strength or sets the redstone output strength", + "Usage:", + " {redstone get } -> redstone signal strength (0-15) at the specified side", + " {redstone get link } -> redstone signal strength of a Create redstone link frequency specified by a linked controller in slot #slot_index. freq_slot_index is the index of the frequency inside the controller (from left to right, 0-6)", + " {redstone set } -> empty string, sets the redstone output strength from this cover's side", + " {redstone set link } -> empty string, broadcasts the specified redstone power on the specified Create redstone link frequency"); + multiLang(provider, "gtceu.placeholder_info.fluidCount", + "Returns the amount of fluids (can be filtered).", + "Usage:", + " {fluidCount [fluidId]} -> the amount of all fluids, or the fluid with fluidId if specified"); + multiLang(provider, "gtceu.placeholder_info.displayTarget", + "Returns the specified line that was transmitted to this cover using a display link.", + "Usage:", + " {displayTarget } -> the text on the specified line (line number is 1-100)"); + multiLang(provider, "gtceu.placeholder_info.previousText", + "Returns the text that was previously displayed by this cover at the specified line (before line-wrapping).", + "Usage:", + " {previousText } -> the text previously displayed on the specified line (index starts at 1)"); + multiLang(provider, "gtceu.placeholder_info.ae2itemCount", + "Same as itemCount, but counts items in the ME network of the block this cover is attached to.", + "Note that counting by filter or all items may cause lag!", + "Usage:", + " {itemCount} -> total item amount", + " {itemCount } -> amount of items with ids equal to item_id", + " {itemCount filter } -> amount of items matching filter in specified slot of this cover"); + multiLang(provider, "gtceu.placeholder_info.ae2fluidCount", + "Same as fluidCount, but counts items in the ME network of the block this cover is attached to.", + "Note that counting all fluids may cause lag!", + "Usage:", + " {fluidCount [fluidId]} -> the amount of all fluids, or the fluid with fluidId if specified"); + multiLang(provider, "gtceu.placeholder_info.progress", + "Returns the progress of the currently running recipe of the block this cover is attached to.", + "Note that progress is an integer between 0 and {maxProgress}", + "Usage:", + " {progress} -> the progress of the currently running recipe"); + multiLang(provider, "gtceu.placeholder_info.maxProgress", + "Returns the maximum progress of the currently running recipe of the block this cover is attached to.", + "Example: 'Progress: {calc {calc {progress} / {maxProgress}} * 100}%'", + "Usage:", + " {maxProgress} -> the max progress of the currently running recipe"); + multiLang(provider, "gtceu.placeholder_info.maintenance", + "Returns a 1 if there are maintenance problems in the block the cover is attached to, 0 otherwise.", + "Example: 'Maintenance status: {if {maintenance} FIXING\\ REQUIRED OK}'", + "Usage:", + " {maintenance} -> whether there are maintenance problems"); + multiLang(provider, "gtceu.placeholder_info.active", + "Returns a 1 if the block the cover is attached to is currently running a recipe, 0 otherwise.", + "Usage:", + " {active} -> whether there's a currently running recipe"); + multiLang(provider, "gtceu.placeholder_info.voltage", + "Returns the voltage in the wire/cable the cover is on.", + "Usage:", + " {voltage} -> the voltage in the wire/cable"); + multiLang(provider, "gtceu.placeholder_info.amperage", + "Returns the amperage in the wire/cable the cover is on.", + "Usage:", + " {amperage} -> the amperate in the wire/cable"); + multiLang(provider, "gtceu.placeholder_info.ae2energy", + "Returns the energy currently stored in the ME network of the block this cover is on.", + "Usage:", + " {ae2energy} -> the energy in the ME network (in AE units)"); + multiLang(provider, "gtceu.placeholder_info.ae2maxPower", + "Returns the energy capacity of the ME network of the block this cover is on.", + "Usage:", + " {ae2maxPower} -> the energy capacity of the ME network"); + multiLang(provider, "gtceu.placeholder_info.ae2powerUsage", + "Returns the energy consumption of the ME network of the block this cover is on.", + "Usage:", + " {ae2powerUsage} -> the energy consumption of the ME network"); + multiLang(provider, "gtceu.placeholder_info.ae2spatial", + "Returns information about spatial I/O in the ME network of the block this cover is on.", + "Usage:", + " {ae2spatial power} -> the amount of power required to initiate spatial I/O", + " {ae2spatial efficiency} -> the efficiency of the Spatial Containment Structure (SPS)", + " {ae2spatial size} -> the size of the SPS along the specified axis (example: 'Size: {sizeX}x{sizeY}x{sizeZ}')"); + multiLang(provider, "gtceu.placeholder_info.ae2crafting", + "Returns information about auto-crafting in the ME network of the block this cover is on.", + "Usage:", + " {ae2crafting get amount} -> the amount of crafting CPUs in the ME network", + " {ae2crafting get storage} -> the amount of crafting storage the specified CPU has", + " {ae2crafting get threads} -> the amount of co-processors the specified CPU has", + " {ae2crafting get name} -> the name of the specified crafting CPU", + " {ae2crafting get selectionMode} -> the selection mode of the specified crafting CPU (used for manual, automatic or both requests)", + " {ae2crafting get amount} -> the amount of the item that was requested, or 0 if the CPU is idle", + " {ae2crafting get item} -> the display name of the item that was requested, or 0 if the CPU is idle", + " {ae2crafting get progress} -> the crafting job progress, or 0 if the CPU is idle", + " {ae2crafting get time} -> the amount of time elapsed from the start of the craft (in nanoseconds), or 0 if the CPU is idle"); + multiLang(provider, "gtceu.placeholder_info.count", + "Returns how many of the provided arguments are equal to the first (compared as strings, so \"0\" != \"0.0\")", + "Usage:", + " {count [arg2] [arg3] [arg4] ...} -> the amount of arguments that are equal to the first"); + multiLang(provider, "gtceu.placeholder_info.data", + "Stores or retrieves some data from a data item (data stick/orb/module) in one of the slots.", + "If you leave the argument empty, it will be replaced with the value p (p is an integer from 0 to (capacity - 1) that is stored in the data item nbt).", + "Usage:", + " {data get } -> the data stored in the item in the specified slot", + " {data set } -> sets the data stored in the item in the specified slot, returns an empty string", + " {data getp } -> p", + " {data setp } -> sets p, returns an empty string", + " {data inc } -> increments p by 1, if p becomes more than or equal to capacity, sets p to 0", + " {data dec } -> decrements p by 1, if p becomes less than 0, sets p to (capacity - 1)"); + multiLang(provider, "gtceu.placeholder_info.combine", + "Combines all of it's arguments into a single string (by escaping all spaces between the arguments)", + "Example: {combine abc def ghi jkl mno} -> \"abc\\ def\\ ghi\\ jkl\\ mno\"", + "Usage:", + " {combine [arg1] [arg2] [arg3] ...} -> a string that will be treated as a single argument in further placeholders"); + multiLang(provider, "gtceu.placeholder_info.nbt", + "Returns the nbt data of the item in the specified slot", + "Usage:", + " {nbt [key1] [key2] [key3] ...} -> item_nbt[key1][key2][key3][...]"); + multiLang(provider, "gtceu.placeholder_info.toChars", + "Returns the characters of the provided string with spaces between them", + "Example: {toChars example} -> 'e x a m p l e'", + "Usage:", + " {toChars } -> characters"); + multiLang(provider, "gtceu.placeholder_info.toAscii", + "Returns the ASCII code of the provided character", + "Usage:", + " {toAscii } -> ASCII code of the character"); + multiLang(provider, "gtceu.placeholder_info.fromAscii", + "Returns the character represented by the provided ASCII code", + "Usage:", + " {fromAscii } -> a character"); + multiLang(provider, "gtceu.gui.computer_monitor_cover.placeholder_reference", + "All placeholders:", + "(hover for more info)"); + multiLang(provider, "gtceu.placeholder_info.subList", + "Returns arguments from with indexes from l (inclusive) to r (exclusive) (starting from 0)", + "Usage:", + " {subList [arg0] [arg1] ...} -> all arguments with indexes from l to r separated by spaces"); + multiLang(provider, "gtceu.placeholder_info.cmp", + "Returns a 1 or 0 based on the expression in it's arguments", + "Usage:", + " {cmp } -> 1 or 0, operator is one of >, <, >=, <=, ==, !="); + multiLang(provider, "gtceu.placeholder_info.bf", + "Usage:", + " {bf } -> empty string"); + multiLang(provider, "gtceu.placeholder_info.cmd", + "Executes Minecraft commands and returns their output.", + "Requires a data item bound to a player, bind any data item to yourself by right-clicking with it.", + "Usage:", + " {cmd } -> command output"); + multiLang(provider, "gtceu.placeholder_info.tm", + "Returns the ™ symbol", + "Usage:", + " {tm} -> the ™ symbol"); + multiLang(provider, "gtceu.placeholder_info.formatInt", + "Returns a string representation of the provided integer", + "Example: {formatInt 1236457} -> 1.24M", + "Usage:", + " {formatInt } -> string representation of the int"); + multiLang(provider, "gtceu.placeholder_info.click", + "Returns whether the targeted advanced monitor was clicked before the current tick", + "Usage:", + " {click} -> \"1\" if the targeted advanced monitor was clicked, \"0\" otherwise", + " {click x} -> the x position of the last click (between 0 and 1)", + " {click y} -> the y position of the last click (between 0 and 1)"); + multiLang(provider, "gtceu.placeholder_info.ender", + "Interacts with ender link covers", + "Can interact with private channels if provided with a data item bound to a player", + "Usage:", + " {ender item [player_data_item_slot]} -> item count", + " {ender itemPull [player_data_item_slot]} -> pull 1 item from the ender link's buffer", + " {ender itemPush [player_data_item_slot]} -> push 1 item to the ender link's buffer", + " {ender itemId [player_data_item_slot]} -> the id of the item in the ender link's buffer (ex. \"26 minecraft:dirt\")", + " {ender fluid [player_data_item_slot]} -> fluid count", + " {ender redstone [player_data_item_slot] -> redstone signal level", + " {ender redstone -> sets the redstone signal outputed to the ender redstone link, returns empty string", + "The player_data_item_slot argument may be left empty (not 0, empty string)"); + multiLang(provider, "gtceu.placeholder_info.eval", + "Returns the result of evaluating the provided string which may placeholders", + "Usage:", + " {eval abcdefg} -> abcdefg", + " {eval \"repeating a: {repeat 5 \\\"a \\\"}\" -> repeating a: a a a a a ", + " {eval \\\"\"{some random text}\"\\\" -> {some random text}", + " {eval \"text \"\\\"\"{something with spaces}\"\\\"\" more text\" -> text {something with spaces} more text"); + multiLang(provider, "gtceu.placeholder_info.bufferText", + "Returns the text from a buffer accessible by ComputerCraft", + "Usage:", + " {bufferText } -> text from the buffer on the specified line (line is 1-100)"); + multiLang(provider, "gtceu.placeholder_info.blockNbt", + "Returns the NBT of the block entity", + "Usage:", + " {blockNbt} -> full block entity nbt", + " {blockNbt [key1] [key2] ...} -> part of the nbt"); + provider.add("gtceu.ender_item_link_cover.title", "Ender Item Link"); + provider.add("gtceu.ender_item_link_cover.tooltip", + "§7Transports §fItems§7 with a §fWireless §dEnder§f Connection§7 as §fCover§7."); + provider.add("gtceu.ender_redstone_link_cover.title", "Ender Redstone Link"); + provider.add("gtceu.ender_redstone_link_cover.label", "Redstone power: %d"); + provider.add("gtceu.ender_redstone_link_cover.tooltip", + "§7Transmits §fRedstone signals§7 with a §fWireless §dEnder§f Connection§7 as §fCover§7."); + provider.add("gtceu.gui.computer_monitor_cover.update_interval", "Update interval (in ticks)"); + provider.add("gtceu.gui.computer_monitor_cover.edit_blank_placeholders", "Edit blank placeholders"); + provider.add("gtceu.gui.computer_monitor_cover.edit_displayed_text", "Edit displayed text"); + provider.add("gtceu.gui.central_monitor.text_scale", "Text scale"); + provider.add("gtceu.gui.central_monitor.group", "Group: %s"); + provider.add("gtceu.gui.central_monitor.group_default_name", "Group #%d"); + provider.add("gtceu.gui.central_monitor.none", "none"); + provider.add("gtceu.central_monitor.size", "Size: (%d+1+%d)x(%d+1+%d)"); + provider.add("gtceu.computer_monitor_cover.error.invalid_number", "Invalid number '%s'!"); + provider.add("gtceu.computer_monitor_cover.error.wrong_number_of_args", "Expected %d args, got %d!"); + provider.add("gtceu.computer_monitor_cover.error.not_enough_args", "Expected at least %d args, got %d!"); + provider.add("gtceu.computer_monitor_cover.error.no_cover", "No cover!"); + provider.add("gtceu.computer_monitor_cover.error.exception", "Unexpected exception occurred: %s"); + provider.add("gtceu.computer_monitor_cover.error.not_in_range", + "Expected %s to be between %d and %d (inclusive), got %d"); + provider.add("gtceu.computer_monitor_cover.error.invalid_args", "Invalid arguments!"); + provider.add("gtceu.computer_monitor_cover.error.missing_item", "Missing %s in slot %d!"); + provider.add("gtceu.computer_monitor_cover.error.bf_invalid_num", + "Invalid number at index %d when processing symbol number %d"); + provider.add("gtceu.computer_monitor_cover.error.bf_invalid", "Invalid character at %d"); + multiLang(provider, "gtceu.gui.computer_monitor_cover.main_textbox_tooltip", + "Input string to display on line %d here.", + "It can have placeholders, for example: 'Energy: {energy}/{energyCapacity} EU'", + "Placeholders can also be inside other placeholders."); + multiLang(provider, "gtceu.gui.computer_monitor_cover.slot_tooltip", + "A slot for items that some placeholders can reference", + "Slot number: %d"); + multiLang(provider, "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip", + "Input placeholder to be used in place of %s '{}' here.", + "For example, you can have a string 'Energy: {}/{} EU' and 'energy' and 'energyCapacity' in these text boxes.");; + provider.add("gtceu.computer_monitor_cover.error.no_placeholder", "No such placeholder: '%s'!"); + provider.add("gtceu.computer_monitor_cover.error.unclosed_bracket", "Unclosed bracket!"); + provider.add("gtceu.computer_monitor_cover.error.unexpected_bracket", "Unexpected closing bracket!"); + provider.add("gtceu.computer_monitor_cover.error.no_ae", "Cover holder does not have an AE2 network!"); + provider.add("gtceu.computer_monitor_cover.error.not_supported", + "This feature is not supported by this block/cover!"); + provider.add("gtceu.central_monitor.gui.create_group", "Create group"); + provider.add("gtceu.central_monitor.gui.remove_from_group", "Remove from group"); + provider.add("gtceu.central_monitor.gui.set_target", "Set target"); + provider.add("gtceu.central_monitor.gui.currently_editing", "Currently editing: %s"); + multiLang(provider, "gtceu.central_monitor.info_tooltip", + "In order to use monitors, you have to split them into groups first. A group may only have 1 module in it.", + "Select them by left-clicking, then click 'Create group'.", + "Then in the settings page for the group you can insert a module, you can configure it in the same page.", + "To delete a group, select all of it's components and click 'Remove from group'.", + "You can quickly select all components of a group by clicking on it's name. Click again to unselect.", + "Some modules may display things depending on the block they target, to set a target for a group select any component of that group and right-click on the target component.", + "You may wish to select a target that is not in the multiblock, you have to use the wireless transmitter cover for that.", + "Place the cover on the target block, right-click it with a data stick and put that data stick into a data access hatch in the multiblock.", + "Then select the data access hatch as the target, and set the slot index of your data stick in the number field that appeared."); + provider.add("gtceu.tooltip.player_bind", "Bound to player: %s"); } /** diff --git a/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/MachineLang.java b/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/MachineLang.java index 2f6bbfb4e35..f83401da82e 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/MachineLang.java +++ b/src/main/java/com/gregtechceu/gtceu/data/datagen/lang/MachineLang.java @@ -27,8 +27,8 @@ protected static void init(RegistrateLangProvider provider) { provider.add("gtceu.machine.lp_steam_extractor.tooltip", "§7Extracting your first Rubber"); provider.add("gtceu.machine.hp_steam_extractor.tooltip", "§7Extracting your first Rubber"); - provider.add("gtceu.machine.lp_steam_macerator.tooltip", "§7Macerating your Ores"); - provider.add("gtceu.machine.hp_steam_macerator.tooltip", "§7Macerating your Ores"); + provider.add("gtceu.machine.lp_steam_macerator.tooltip", "§7Macerating your Ores without Byproducts"); + provider.add("gtceu.machine.hp_steam_macerator.tooltip", "§7Macerating your Ores without Byproducts"); provider.add("gtceu.machine.lp_steam_compressor.tooltip", "§7Compressing Items"); provider.add("gtceu.machine.hp_steam_compressor.tooltip", "§7Compressing Items"); provider.add("gtceu.machine.lp_steam_forge_hammer.tooltip", "§7Forge Hammer"); @@ -51,9 +51,9 @@ protected static void init(RegistrateLangProvider provider) { "§7Mines block on front face and collects its drops"); provider.add("gtceu.machine.block_breaker.speed_bonus", "§eSpeed Bonus: §f%d%%"); - provider.add("gtceu.machine.boiler.info.heating.up", "§cHeating up§r%s"); - provider.add("gtceu.machine.boiler.info.cooling.down", "§9Cooling down§r%s"); - provider.add("gtceu.machine.boiler.info.producing.steam", " §a(boiling water)"); + provider.add("gtceu.machine.boiler.info.heating.up", "§cHeating§r"); + provider.add("gtceu.machine.boiler.info.cooling.down", "§9Cooling§r"); + provider.add("gtceu.machine.boiler.info.production.data", "§aProducing %s§a mB/t"); /////////////////////////////////////////////////// // Standard Machines // @@ -484,6 +484,7 @@ protected static void init(RegistrateLangProvider provider) { provider.add("gtceu.machine.miner.minez", "mZ: %d"); provider.add("gtceu.machine.miner.radius", "Radius: %d"); provider.add("gtceu.machine.miner.chunkradius", "Chunk Radius: %d"); + provider.add("gtceu.machine.miner.progress", "Progress: %d/%d"); provider.add("gtceu.machine.fluid_drilling_rig.description", "§7Drills fluids from veins under bedrock."); @@ -801,6 +802,21 @@ protected static void init(RegistrateLangProvider provider) { provider.add("gtceu.machine.me.fluid_import.data_stick.name", "§oME Input Hatch Configuration Data"); + provider.add("gtceu.gui.title.adv_stocking_config.min_item_count", + "Min. Item Count"); + provider.add("gtceu.gui.title.adv_stocking_config.min_fluid_count", + "Min. Fluid Count"); + provider.add("gtceu.gui.adv_stocking_config.min_item_count", + "Minimum Item Stack Size for Automated Pulling"); + provider.add("gtceu.gui.adv_stocking_config.min_fluid_count", + "Minimum Fluid Stack Size for Automated Pulling"); + provider.add("gtceu.gui.title.adv_stocking_config.ticks_per_cycle", + "Ticks Per Cycle"); + provider.add("gtceu.gui.adv_stocking_config.ticks_per_cycle", + "Delay between item list updates"); + provider.add("gtceu.gui.adv_stocking_config.title", + "Configure Automatic Stocking"); + multiLang(provider, "gtceu.machine.rotor_holder.tooltip", "Rotor Holder for Multiblocks", "Holds Rotor in place so it will not fly away"); diff --git a/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/BlockTagLoader.java b/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/BlockTagLoader.java index 75777b29dbe..72660974aab 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/BlockTagLoader.java +++ b/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/BlockTagLoader.java @@ -1,11 +1,14 @@ package com.gregtechceu.gtceu.data.datagen.tag; +import com.gregtechceu.gtceu.common.block.StoneTypes; +import com.gregtechceu.gtceu.data.block.GTBlocks; import com.gregtechceu.gtceu.data.machine.GTMachines; import com.gregtechceu.gtceu.data.material.GTMaterials; import com.gregtechceu.gtceu.data.tag.CustomTags; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.BlockTags; +import net.minecraft.tags.TagKey; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.neoforged.neoforge.common.Tags; @@ -15,31 +18,64 @@ public class BlockTagLoader { public static void init(RegistrateTagsProvider.IntrinsicImpl provider) { + provider.addTag(CustomTags.CONCRETE_BLOCK) + .add(Blocks.WHITE_CONCRETE, Blocks.ORANGE_CONCRETE, Blocks.MAGENTA_CONCRETE, Blocks.LIGHT_BLUE_CONCRETE, + Blocks.YELLOW_CONCRETE, Blocks.LIME_CONCRETE, Blocks.PINK_CONCRETE, Blocks.GRAY_CONCRETE, + Blocks.LIGHT_GRAY_CONCRETE, Blocks.CYAN_CONCRETE, Blocks.PURPLE_CONCRETE, Blocks.BLUE_CONCRETE, + Blocks.BROWN_CONCRETE, Blocks.GREEN_CONCRETE, Blocks.RED_CONCRETE, Blocks.BLACK_CONCRETE); + provider.addTag(CustomTags.CONCRETE_POWDER_BLOCK) + .add(Blocks.WHITE_CONCRETE_POWDER, Blocks.ORANGE_CONCRETE_POWDER, Blocks.MAGENTA_CONCRETE_POWDER, + Blocks.LIGHT_BLUE_CONCRETE_POWDER, Blocks.YELLOW_CONCRETE_POWDER, Blocks.LIME_CONCRETE_POWDER, + Blocks.PINK_CONCRETE_POWDER, Blocks.GRAY_CONCRETE_POWDER, Blocks.LIGHT_GRAY_CONCRETE_POWDER, + Blocks.CYAN_CONCRETE_POWDER, Blocks.PURPLE_CONCRETE_POWDER, Blocks.BLUE_CONCRETE_POWDER, + Blocks.BROWN_CONCRETE_POWDER, Blocks.GREEN_CONCRETE_POWDER, Blocks.RED_CONCRETE_POWDER, + Blocks.BLACK_CONCRETE_POWDER); + + var speedConcretes = provider.addTag(CustomTags.VERY_FAST_WALKABLE_BLOCKS); + speedConcretes.add(GTBlocks.LIGHT_CONCRETE.get(), GTBlocks.DARK_CONCRETE.get()); + + GTBlocks.STONE_BLOCKS.column(StoneTypes.CONCRETE_LIGHT) + .forEach((type, block) -> speedConcretes.add(block.get())); + GTBlocks.STONE_BLOCKS.column(StoneTypes.CONCRETE_DARK) + .forEach((type, block) -> speedConcretes.add(block.get())); + + var studs = provider.addTag(CustomTags.FAST_WALKABLE_BLOCKS); + GTBlocks.STUDS.forEach((color, block) -> studs.add(block.get())); + provider.addTag(CustomTags.ENDSTONE_ORE_REPLACEABLES) .addTag(Tags.Blocks.END_STONES); provider.addTag(CustomTags.NEEDS_NEUTRONIUM_TOOL); provider.addTag(CustomTags.NEEDS_DURANIUM_TOOL); - provider.addTag(CustomTags.INCORRECT_FOR_DURANIUM_TOOL) - .addTag(CustomTags.NEEDS_NEUTRONIUM_TOOL); - provider.addTag(BlockTags.INCORRECT_FOR_DIAMOND_TOOL) - .addTag(Tags.Blocks.NEEDS_NETHERITE_TOOL) - .addTag(CustomTags.NEEDS_DURANIUM_TOOL) - .addTag(CustomTags.NEEDS_NEUTRONIUM_TOOL); - provider.addTag(BlockTags.INCORRECT_FOR_NETHERITE_TOOL) - .addTag(CustomTags.NEEDS_DURANIUM_TOOL) - .addTag(CustomTags.NEEDS_NEUTRONIUM_TOOL); + @SuppressWarnings("unchecked") + TagKey[] newToolRequirements = new TagKey[] { + CustomTags.NEEDS_NEUTRONIUM_TOOL, + CustomTags.NEEDS_DURANIUM_TOOL + }; + @SuppressWarnings("unchecked") + TagKey[] incorrectForToolTags = new TagKey[] { + BlockTags.INCORRECT_FOR_NETHERITE_TOOL, + BlockTags.INCORRECT_FOR_DIAMOND_TOOL, + BlockTags.INCORRECT_FOR_IRON_TOOL, + BlockTags.INCORRECT_FOR_GOLD_TOOL, + BlockTags.INCORRECT_FOR_STONE_TOOL, + BlockTags.INCORRECT_FOR_WOODEN_TOOL + }; + for (TagKey tag : incorrectForToolTags) { + provider.addTag(tag).addTags(newToolRequirements); + } + // do these manually + provider.addTag(CustomTags.INCORRECT_FOR_NEUTRONIUM_TOOL); + provider.addTag(CustomTags.INCORRECT_FOR_DURANIUM_TOOL).addTag(CustomTags.NEEDS_NEUTRONIUM_TOOL); // this is awful. I don't care, though. - // spotless:off provider.addTag(BlockTags.REPLACEABLE) .add(GTMaterials.Oil.getFluid().defaultFluidState().createLegacyBlock().getBlock()) .add(GTMaterials.LightOil.getFluid().defaultFluidState().createLegacyBlock().getBlock()) .add(GTMaterials.HeavyOil.getFluid().defaultFluidState().createLegacyBlock().getBlock()) .add(GTMaterials.RawOil.getFluid().defaultFluidState().createLegacyBlock().getBlock()) .add(GTMaterials.NaturalGas.getFluid().defaultFluidState().createLegacyBlock().getBlock()); - // spotless:on provider.addTag(BlockTags.MINEABLE_WITH_AXE) .add(GTMachines.WOODEN_DRUM.getBlock()) diff --git a/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/FluidTagLoader.java b/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/FluidTagLoader.java index d9623fa6b04..e1c6252a243 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/FluidTagLoader.java +++ b/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/FluidTagLoader.java @@ -11,5 +11,6 @@ public class FluidTagLoader { public static void init(RegistrateTagsProvider.IntrinsicImpl provider) { provider.addTag(CustomTags.LIGHTER_FLUIDS).add(GTMaterials.Butane.getFluid(), GTMaterials.Propane.getFluid()); + provider.addTag(CustomTags.HPCA_COOLANTS).add(GTMaterials.PCBCoolant.getFluid()); } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/ItemTagLoader.java b/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/ItemTagLoader.java index c4b8764bff2..92b9e43f6b4 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/ItemTagLoader.java +++ b/src/main/java/com/gregtechceu/gtceu/data/datagen/tag/ItemTagLoader.java @@ -190,6 +190,14 @@ public static void init(RegistrateItemTagsProvider provider) { .addOptional(GTItems.SENSOR_UIV.getId()) .addOptional(GTItems.SENSOR_UXV.getId()) .addOptional(GTItems.SENSOR_OpV.getId()); + + provider.addTag(CustomTags.TOOLS_IGNITER) + .addTag(ItemTags.CREEPER_IGNITERS); + + // Add sodalite and lazurite as enchanting fuels + provider.addTag(Tags.Items.ENCHANTING_FUELS) + .add(GTMaterialItems.MATERIAL_ITEMS.get(gem, Lazurite).get()) + .add(GTMaterialItems.MATERIAL_ITEMS.get(gem, Sodalite).get()); } private static IntrinsicHolderTagsProvider.IntrinsicTagAppender addTag(RegistrateItemTagsProvider provider, diff --git a/src/main/java/com/gregtechceu/gtceu/data/inject/GTSyncedFieldAccessors.java b/src/main/java/com/gregtechceu/gtceu/data/inject/GTSyncedFieldAccessors.java index 5eb65cea325..c23576e22bd 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/inject/GTSyncedFieldAccessors.java +++ b/src/main/java/com/gregtechceu/gtceu/data/inject/GTSyncedFieldAccessors.java @@ -3,12 +3,16 @@ import com.gregtechceu.gtceu.api.material.material.Material; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; import com.gregtechceu.gtceu.client.model.machine.MachineRenderState; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; import com.gregtechceu.gtceu.syncdata.*; import com.lowdragmc.lowdraglib.syncdata.IAccessor; +import com.lowdragmc.lowdraglib.syncdata.payload.FluidStackPayload; import com.lowdragmc.lowdraglib.syncdata.payload.FriendlyBufPayload; import com.lowdragmc.lowdraglib.syncdata.payload.NbtTagPayload; +import net.neoforged.neoforge.fluids.FluidStack; + import static com.lowdragmc.lowdraglib.syncdata.TypedPayloadRegistries.*; public class GTSyncedFieldAccessors { @@ -18,9 +22,13 @@ public class GTSyncedFieldAccessors { public static void init() { register(FriendlyBufPayload.class, FriendlyBufPayload::new, GT_RECIPE_TYPE_ACCESSOR, 1000); register(NbtTagPayload.class, NbtTagPayload::new, VirtualTankAccessor.INSTANCE, 2); + register(NbtTagPayload.class, NbtTagPayload::new, VirtualItemStorageAccessor.INSTANCE, 2); + register(NbtTagPayload.class, NbtTagPayload::new, VirtualRedstoneAccessor.INSTANCE, 2); registerSimple(MachineRenderStatePayload.class, MachineRenderStatePayload::new, MachineRenderState.class, 1); registerSimple(MaterialPayload.class, MaterialPayload::new, Material.class, 1); registerSimple(GTRecipePayload.class, GTRecipePayload::new, GTRecipe.class, 100); + registerSimple(FluidStackPayload.class, FluidStackPayload::new, FluidStack.class, -1); + registerSimple(MonitorGroupPayload.class, MonitorGroupPayload::new, MonitorGroup.class, 1); } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/item/GTDataComponents.java b/src/main/java/com/gregtechceu/gtceu/data/item/GTDataComponents.java index dfac8b672b1..94b70e5c127 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/item/GTDataComponents.java +++ b/src/main/java/com/gregtechceu/gtceu/data/item/GTDataComponents.java @@ -8,18 +8,28 @@ import com.gregtechceu.gtceu.api.item.datacomponents.*; import com.gregtechceu.gtceu.api.material.material.Material; import com.gregtechceu.gtceu.api.registry.GTRegistries; +import com.gregtechceu.gtceu.common.cover.MonitorCoverConfig; +import com.gregtechceu.gtceu.common.item.behavior.DataItemBehavior; import com.gregtechceu.gtceu.common.item.behavior.ItemMagnetBehavior; +import com.gregtechceu.gtceu.common.item.datacomponents.*; import com.gregtechceu.gtceu.common.item.tool.behavior.ToolModeSwitchBehavior; import com.gregtechceu.gtceu.utils.ResearchManager; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.UUIDUtil; import net.minecraft.core.component.DataComponentType; +import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; import net.minecraft.network.codec.ByteBufCodecs; import net.minecraft.network.codec.StreamCodec; +import net.minecraft.resources.ResourceKey; import net.minecraft.util.Unit; import net.minecraft.world.item.component.CustomData; import net.minecraft.world.item.enchantment.ItemEnchantments; +import net.minecraft.world.level.Level; import net.neoforged.neoforge.fluids.SimpleFluidContent; import net.neoforged.neoforge.registries.DeferredHolder; import net.neoforged.neoforge.registries.DeferredRegister; @@ -27,6 +37,9 @@ import com.mojang.serialization.Codec; import io.netty.buffer.ByteBuf; +import java.util.List; +import java.util.UUID; + public class GTDataComponents { private static final StreamCodec UNIT_STREAM_CODEC = StreamCodec.unit(Unit.INSTANCE); @@ -83,9 +96,9 @@ public class GTDataComponents { public static final DeferredHolder, DataComponentType> RESEARCH_ITEM = DATA_COMPONENTS .registerComponentType("research_item", builder -> builder.persistent(ResearchManager.ResearchItem.CODEC) .networkSynchronized(ResearchManager.ResearchItem.STREAM_CODEC)); - public static final DeferredHolder, DataComponentType> DATA_ITEM = DATA_COMPONENTS - .registerComponentType("data_item", builder -> builder.persistent(Codec.BOOL) - .networkSynchronized(ByteBufCodecs.BOOL)); + public static final DeferredHolder, DataComponentType> DATA_ITEM = DATA_COMPONENTS + .registerComponentType("data_item", builder -> builder.persistent(DataItem.CODEC) + .networkSynchronized(DataItem.STREAM_CODEC)); public static final DeferredHolder, DataComponentType> MAGNET = DATA_COMPONENTS .registerComponentType("magnet", builder -> builder.persistent(ItemMagnetBehavior.MagnetComponent.CODEC) @@ -93,6 +106,7 @@ public class GTDataComponents { public static final DeferredHolder, DataComponentType> SCANNER_MODE = DATA_COMPONENTS .registerComponentType("scanner_mode", builder -> builder.persistent(Codec.BYTE).networkSynchronized(ByteBufCodecs.BYTE)); + public static final DeferredHolder, DataComponentType> SIMPLE_FLUID_FILTER = DATA_COMPONENTS .registerComponentType("simple_fluid_filter", builder -> builder.persistent(SimpleFluidFilter.CODEC)); public static final DeferredHolder, DataComponentType> SIMPLE_ITEM_FILTER = DATA_COMPONENTS @@ -105,18 +119,42 @@ public class GTDataComponents { builder -> builder.persistent(SmartItemFilter.SmartFilteringMode.CODEC)); public static final DeferredHolder, DataComponentType> CIRCUIT_CONFIG = DATA_COMPONENTS .registerComponentType("circuit_config", builder -> builder.persistent(Codec.INT)); + public static final DeferredHolder, DataComponentType> FLUID_CONTENT = DATA_COMPONENTS .registerComponentType("fluid_content", builder -> builder.persistent(SimpleFluidContent.CODEC) .networkSynchronized(SimpleFluidContent.STREAM_CODEC)); public static final DeferredHolder, DataComponentType> ENERGY_CONTENT = DATA_COMPONENTS .registerComponentType("energy_content", builder -> builder.persistent(SimpleEnergyContent.CODEC) .networkSynchronized(SimpleEnergyContent.STREAM_CODEC)); + + public static final DeferredHolder, DataComponentType> BINDING_DATA = DATA_COMPONENTS + .registerComponentType("binding_data", builder -> builder.persistent(BindingData.CODEC) + .networkSynchronized(BindingData.STREAM_CODEC)); public static final DeferredHolder, DataComponentType> DATA_COPY_POS = DATA_COMPONENTS .registerComponentType("data_copy_pos", builder -> builder.persistent(BlockPos.CODEC) .networkSynchronized(BlockPos.STREAM_CODEC)); public static final DeferredHolder, DataComponentType> DATA_COPY_TAG = DATA_COMPONENTS .registerComponentType("data_copy_tag", builder -> builder.persistent(CustomData.CODEC) .networkSynchronized(CustomData.STREAM_CODEC)); + public static final DeferredHolder, DataComponentType> MONITOR_COVER_CONFIG = DATA_COMPONENTS + .registerComponentType("monitor_cover_config", builder -> builder.persistent(MonitorCoverConfig.CODEC) + .networkSynchronized(MonitorCoverConfig.STREAM_CODEC)); + + public static final DeferredHolder, DataComponentType> FORMAT_STRING_LIST = DATA_COMPONENTS + .registerComponentType("format_string_list", builder -> builder.persistent(FormatStringList.CODEC) + .networkSynchronized(FormatStringList.STREAM_CODEC)); + public static final DeferredHolder, DataComponentType> COMPUTER_MONITOR_DATA = DATA_COMPONENTS + .registerComponentType("computer_monitor_cover_data", builder -> builder.persistent(FormatStringList.CODEC) + .networkSynchronized(FormatStringList.STREAM_CODEC)); + public static final DeferredHolder, DataComponentType> COMPUTER_MONITOR_CONFIG = DATA_COMPONENTS + .registerComponentType("computer_monitor_cover_config", + builder -> builder.persistent(ComputerMonitorConfig.CODEC) + .networkSynchronized(ComputerMonitorConfig.STREAM_CODEC)); + public static final DeferredHolder, DataComponentType> COMPUTER_MONITOR_P = DATA_COMPONENTS + .registerComponentType("computer_monitor_cover_p", builder -> builder.persistent(Codec.INT) + .networkSynchronized(ByteBufCodecs.VAR_INT)); + public static final DeferredHolder, DataComponentType> TEXT_LINE_LIST = DATA_COMPONENTS + .registerComponentType("text_line_list", builder -> builder.persistent(TextLineList.CODEC)); // machine info public static final DeferredHolder, DataComponentType> LARGE_ITEM_CONTENT = DATA_COMPONENTS @@ -137,13 +175,49 @@ public class GTDataComponents { // misc public static final DeferredHolder, DataComponentType> FACADE = DATA_COMPONENTS - .registerComponentType("facade", - builder -> builder.persistent(FacadeWrapper.CODEC).networkSynchronized(FacadeWrapper.STREAM_CODEC)); + .registerComponentType("facade", builder -> builder.persistent(FacadeWrapper.CODEC) + .networkSynchronized(FacadeWrapper.STREAM_CODEC)); public static final DeferredHolder, DataComponentType> LAMP_DATA = DATA_COMPONENTS - .registerComponentType("lamp", - builder -> builder.persistent(LampBlockItem.LampData.CODEC) - .networkSynchronized(LampBlockItem.LampData.STREAM_CODEC)); + .registerComponentType("lamp", builder -> builder.persistent(LampBlockItem.LampData.CODEC) + .networkSynchronized(LampBlockItem.LampData.STREAM_CODEC)); public static final DeferredHolder, DataComponentType> LIGHTER_OPEN = DATA_COMPONENTS .registerComponentType("lighter_open", builder -> builder.persistent(Codec.BOOL).networkSynchronized(ByteBufCodecs.BOOL)); + + public static final DeferredHolder, DataComponentType> TEXT_MODULE_SCALE = DATA_COMPONENTS + .registerComponentType("text_module_scale", builder -> builder.persistent(Codec.DOUBLE) + .networkSynchronized(ByteBufCodecs.DOUBLE)); + public static final DeferredHolder, DataComponentType>> TEXT_MODULE_STRING_LINES = DATA_COMPONENTS + .registerComponentType("text_module_string_lines", builder -> builder.persistent(Codec.list(Codec.STRING)) + .networkSynchronized(ByteBufCodecs.STRING_UTF8.apply(ByteBufCodecs.list()))); + public static final DeferredHolder, DataComponentType>> TEXT_MODULE_TEXT = DATA_COMPONENTS + .registerComponentType("text_module_text", + builder -> builder.persistent(Codec.list(ComponentSerialization.CODEC)) + .networkSynchronized(ComponentSerialization.STREAM_CODEC.apply(ByteBufCodecs.list()))); + public static final DeferredHolder, DataComponentType> IMAGE_MODULE_URL = DATA_COMPONENTS + .registerComponentType("image_module_url", builder -> builder.persistent(Codec.STRING) + .networkSynchronized(ByteBufCodecs.STRING_UTF8)); + public static final DeferredHolder, DataComponentType> MONITOR_TARGET = DATA_COMPONENTS + .registerComponentType("monitor_target", builder -> builder.persistent(BlockPos.CODEC) + .networkSynchronized(BlockPos.STREAM_CODEC)); + public static final DeferredHolder, DataComponentType> MONITOR_TARGET_FACE = DATA_COMPONENTS + .registerComponentType("monitor_target_face", builder -> builder.persistent(Direction.CODEC) + .networkSynchronized(Direction.STREAM_CODEC)); + public static final DeferredHolder, DataComponentType>> MONITOR_TARGET_DIMENSION = DATA_COMPONENTS + .registerComponentType("monitor_target_dimension", + builder -> builder.persistent(ResourceKey.codec(Registries.DIMENSION)) + .networkSynchronized(ResourceKey.streamCodec(Registries.DIMENSION))); + public static final DeferredHolder, DataComponentType> DATA_BOUND_PLAYER = DATA_COMPONENTS + .registerComponentType("data_bound_player", + builder -> builder.persistent(DataItemBehavior.BoundPlayer.CODEC) + .networkSynchronized(DataItemBehavior.BoundPlayer.STREAM_CODEC)); + public static final DeferredHolder, DataComponentType> ENDER_REDSTONE_LINK_TRANSMITTER_UUID = DATA_COMPONENTS + .registerComponentType("ender_redstone_link_transmitter_uuid", + builder -> builder.persistent(UUIDUtil.CODEC) + .networkSynchronized(UUIDUtil.STREAM_CODEC)); + public static final DeferredHolder, DataComponentType> PLACEHOLDER_UUID = DATA_COMPONENTS + .registerComponentType("placeholder_uuid", + builder -> builder.persistent(UUIDUtil.CODEC) + .networkSynchronized(UUIDUtil.STREAM_CODEC)); + // enderRedstoneLinkTransmitterUUID } diff --git a/src/main/java/com/gregtechceu/gtceu/data/item/GTItems.java b/src/main/java/com/gregtechceu/gtceu/data/item/GTItems.java index 28144fd6a3d..ebc5d52bb86 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/item/GTItems.java +++ b/src/main/java/com/gregtechceu/gtceu/data/item/GTItems.java @@ -23,8 +23,9 @@ import com.gregtechceu.gtceu.api.tag.TagUtil; import com.gregtechceu.gtceu.common.item.armor.*; import com.gregtechceu.gtceu.common.item.behavior.*; -import com.gregtechceu.gtceu.common.item.behavior.LighterBehavior; -import com.gregtechceu.gtceu.common.item.behavior.MetaMachineConfigCopyBehaviour; +import com.gregtechceu.gtceu.common.item.datacomponents.DataItem; +import com.gregtechceu.gtceu.common.item.modules.ImageModuleBehaviour; +import com.gregtechceu.gtceu.common.item.modules.TextModuleBehaviour; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.cover.GTCovers; import com.gregtechceu.gtceu.data.datagen.lang.LangHandler; @@ -53,7 +54,6 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.food.FoodProperties; import net.minecraft.world.item.*; -import net.minecraft.world.item.Item; import net.minecraft.world.level.ItemLike; import net.minecraft.world.level.block.LayeredCauldronBlock; import net.minecraft.world.level.material.Fluids; @@ -127,7 +127,7 @@ public class GTItems { .register(); @SuppressWarnings("unchecked") - public static final ItemEntry[] SHAPE_MOLDS = new ItemEntry[13]; + public static final ItemEntry[] SHAPE_MOLDS = new ItemEntry[18]; public static final ItemEntry SHAPE_MOLD_PLATE; public static final ItemEntry SHAPE_MOLD_GEAR; public static final ItemEntry SHAPE_MOLD_BOTTLE; @@ -141,6 +141,11 @@ public class GTItems { public static final ItemEntry SHAPE_MOLD_GEAR_SMALL; public static final ItemEntry SHAPE_MOLD_ROTOR; public static final ItemEntry SHAPE_MOLD_PILL; + public static final ItemEntry SHAPE_MOLD_PIPE_TINY; + public static final ItemEntry SHAPE_MOLD_PIPE_SMALL; + public static final ItemEntry SHAPE_MOLD_PIPE_NORMAL; + public static final ItemEntry SHAPE_MOLD_PIPE_LARGE; + public static final ItemEntry SHAPE_MOLD_PIPE_HUGE; static { SHAPE_MOLDS[0] = SHAPE_MOLD_PLATE = REGISTRATE.item("plate_casting_mold", Item::new) @@ -195,8 +200,29 @@ public class GTItems { .lang("Casting Mold (Pill)") .onRegister(materialInfo(new ItemMaterialInfo(new MaterialStack(GTMaterials.Steel, GTValues.M * 4)))) .register(); + SHAPE_MOLDS[13] = SHAPE_MOLD_PIPE_TINY = REGISTRATE.item("tiny_pipe_casting_mold", Item::new) + .lang("Casting Mold (Tiny Pipe)") + .onRegister(materialInfo(new ItemMaterialInfo(new MaterialStack(GTMaterials.Steel, GTValues.M * 4)))) + .register(); + SHAPE_MOLDS[14] = SHAPE_MOLD_PIPE_SMALL = REGISTRATE.item("small_pipe_casting_mold", Item::new) + .lang("Casting Mold (Small Pipe)") + .onRegister(materialInfo(new ItemMaterialInfo(new MaterialStack(GTMaterials.Steel, GTValues.M * 4)))) + .register(); + SHAPE_MOLDS[15] = SHAPE_MOLD_PIPE_NORMAL = REGISTRATE.item("normal_pipe_casting_mold", Item::new) + .lang("Casting Mold (Normal Pipe)") + .onRegister(materialInfo(new ItemMaterialInfo(new MaterialStack(GTMaterials.Steel, GTValues.M * 4)))) + .register(); + SHAPE_MOLDS[16] = SHAPE_MOLD_PIPE_LARGE = REGISTRATE.item("large_pipe_casting_mold", Item::new) + .lang("Casting Mold (Large Pipe)") + .onRegister(materialInfo(new ItemMaterialInfo(new MaterialStack(GTMaterials.Steel, GTValues.M * 4)))) + .register(); + SHAPE_MOLDS[17] = SHAPE_MOLD_PIPE_HUGE = REGISTRATE.item("huge_pipe_casting_mold", Item::new) + .lang("Casting Mold (Huge Pipe)") + .onRegister(materialInfo(new ItemMaterialInfo(new MaterialStack(GTMaterials.Steel, GTValues.M * 4)))) + .register(); } + @SuppressWarnings("unchecked") public static final ItemEntry[] SHAPE_EXTRUDERS = new ItemEntry[27]; public static ItemEntry SHAPE_EXTRUDER_PLATE; public static ItemEntry SHAPE_EXTRUDER_ROD; @@ -1431,15 +1457,15 @@ public static ItemEntry createFluidCell(Material mat, int capacit public static ItemEntry TOOL_DATA_STICK = REGISTRATE.item("data_stick", ComponentItem::new) .lang("Data Stick").onRegister(attach(DataItemBehavior.INSTANCE)) - .properties(p -> p.component(GTDataComponents.DATA_ITEM, false)) + .properties(p -> p.component(GTDataComponents.DATA_ITEM, new DataItem(false, 8))) .register(); public static ItemEntry TOOL_DATA_ORB = REGISTRATE.item("data_orb", ComponentItem::new) .lang("Data Orb").onRegister(attach(DataItemBehavior.INSTANCE)) - .properties(p -> p.component(GTDataComponents.DATA_ITEM, false)) + .properties(p -> p.component(GTDataComponents.DATA_ITEM, new DataItem(false, 64))) .register(); public static ItemEntry TOOL_DATA_MODULE = REGISTRATE.item("data_module", ComponentItem::new) .lang("Data Module").onRegister(attach(DataItemBehavior.INSTANCE)) - .properties(p -> p.component(GTDataComponents.DATA_ITEM, true)) + .properties(p -> p.component(GTDataComponents.DATA_ITEM, new DataItem(true, 256))) .register(); public static final Map> GLASS_LENSES = new HashMap<>(); @@ -1801,6 +1827,11 @@ public static ItemEntry createFluidCell(Material mat, int capacit new CoverPlaceBehavior(GTCovers.FLUID_FILTER))) .onRegister(materialInfo(new ItemMaterialInfo(new MaterialStack(GTMaterials.Zinc, GTValues.M * 3 / 2)))) .register(); + public static ItemEntry COVER_WIRELESS_TRANSMITTER = REGISTRATE + .item("wireless_transmitter_cover", ComponentItem::new) + .lang("Wireless Transmitter") + .onRegister(attach(new CoverPlaceBehavior(GTCovers.WIRELESS_TRANSMITTER))) + .register(); public static ItemEntry COVER_MACHINE_CONTROLLER = REGISTRATE .item("machine_controller_cover", ComponentItem::new) @@ -1883,6 +1914,17 @@ public static ItemEntry createFluidCell(Material mat, int capacit .onRegister(attach(new CoverPlaceBehavior(GTCovers.ENDER_FLUID_LINK))) .register(); + public static ItemEntry COVER_ENDER_ITEM_LINK = REGISTRATE + .item("ender_item_link_cover", ComponentItem::new) + .lang("Ender Item Link") + .onRegister(attach(new CoverPlaceBehavior(GTCovers.ENDER_ITEM_LINK))) + .register(); + public static ItemEntry COVER_ENDER_REDSTONE_LINK = REGISTRATE + .item("ender_redstone_link_cover", ComponentItem::new) + .lang("Ender Redstone Link") + .onRegister(attach(new CoverPlaceBehavior(GTCovers.ENDER_REDSTONE_LINK))) + .register(); + public static ItemEntry COVER_FLUID_VOIDING = REGISTRATE .item("fluid_voiding_cover", ComponentItem::new) .lang("Fluid Voiding Cover") @@ -2002,6 +2044,7 @@ public static ItemEntry createFluidCell(Material mat, int capacit .onRegister(modelPredicate(GTCEu.id("circuit"), (itemStack) -> IntCircuitBehaviour.getCircuitConfiguration(itemStack) / 100f)) .onRegister(attach(new IntCircuitBehaviour())) + .tag(CustomTags.SKIP_ITEM_DETECTOR) .register(); // public static ItemEntry FOAM_SPRAYER = REGISTRATE.item("foam_sprayer", @@ -2442,7 +2485,7 @@ public static ItemEntry createFluidCell(Material mat, int capacit public static ItemEntry ELECTRIC_JETPACK = REGISTRATE .item("electric_jetpack", (p) -> new ArmorComponentItem(GTArmorMaterials.JETPACK, ArmorItem.Type.CHESTPLATE, p) - .setArmorLogic(new Jetpack(30, + .setArmorLogic(new Jetpack(15, 1_000_000L * (long) Math.max(1, Math.pow(4, ConfigHolder.INSTANCE.tools.voltageTierImpeller - 2)), ConfigHolder.INSTANCE.tools.voltageTierImpeller))) @@ -2457,7 +2500,7 @@ public static ItemEntry createFluidCell(Material mat, int capacit public static ItemEntry ELECTRIC_JETPACK_ADVANCED = REGISTRATE .item("advanced_electric_jetpack", (p) -> new ArmorComponentItem(GTArmorMaterials.JETPACK, ArmorItem.Type.CHESTPLATE, p) - .setArmorLogic(new AdvancedJetpack(512, + .setArmorLogic(new AdvancedJetpack(256, 6_400_000L * (long) Math.max(1, Math.pow(4, ConfigHolder.INSTANCE.tools.voltageTierAdvImpeller - 4)), ConfigHolder.INSTANCE.tools.voltageTierAdvImpeller))) @@ -2538,7 +2581,19 @@ public static ItemEntry createFluidCell(Material mat, int capacit .lang("Treated Wood Boat with Chest") .register(); - public static void init() {} + public static ItemEntry TEXT_MODULE = REGISTRATE.item("text_module", ComponentItem::new) + .onRegister(attach(new TextModuleBehaviour())) + .register(); + + public static ItemEntry IMAGE_MODULE = REGISTRATE.item("image_module", ComponentItem::new) + .onRegister(attach(new ImageModuleBehaviour())) + .register(); + + public static void init() { + // GTMaterialItems.generateMaterialItems(); + // GTMaterialItems.generateTools(); + // GTMaterialItems.generateArmors(); + } public static NonNullConsumer materialInfo(ItemMaterialInfo materialInfo) { return item -> ItemMaterialData.registerMaterialInfo(item, materialInfo); diff --git a/src/main/java/com/gregtechceu/gtceu/data/item/GTMaterialItems.java b/src/main/java/com/gregtechceu/gtceu/data/item/GTMaterialItems.java index 6179022a09e..17d5c00473f 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/item/GTMaterialItems.java +++ b/src/main/java/com/gregtechceu/gtceu/data/item/GTMaterialItems.java @@ -228,7 +228,7 @@ private static void generateArmor(final Material material, final ArmorItem.Type final ArmorProperty property = material.getProperty(PropertyKey.ARMOR); String id = "%s_%s".formatted(material.getName(), type.getName()); ARMOR_ITEMS.put(material, type, registrate - .item(id, p -> new GTArmorItem(type, p, material, property)) + .item(id, p -> new GTArmorItem(property.getArmorMaterial(), type, p, material, property)) .properties(p -> p.durability(type.getDurability(property.getDurabilityMultiplier()))) .setData(ProviderType.LANG, NonNullBiConsumer.noop()) .model(NonNullBiConsumer.noop()) diff --git a/src/main/java/com/gregtechceu/gtceu/data/machine/GCYMMachines.java b/src/main/java/com/gregtechceu/gtceu/data/machine/GCYMMachines.java index 87346f82467..13ff48fcbc9 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/machine/GCYMMachines.java +++ b/src/main/java/com/gregtechceu/gtceu/data/machine/GCYMMachines.java @@ -9,6 +9,7 @@ import com.gregtechceu.gtceu.api.machine.multiblock.CoilWorkableElectricMultiblockMachine; import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.material.ChemicalHelper; import com.gregtechceu.gtceu.api.multiblock.FactoryBlockPattern; @@ -38,6 +39,7 @@ import static com.gregtechceu.gtceu.api.GTValues.*; import static com.gregtechceu.gtceu.api.machine.multiblock.PartAbility.*; +import static com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties.IS_FORMED; import static com.gregtechceu.gtceu.api.multiblock.Predicates.*; import static com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection.*; import static com.gregtechceu.gtceu.common.registry.GTRegistration.REGISTRATE; @@ -67,7 +69,8 @@ public static void init() {} } + " Parallel Control Hatch") .rotationState(RotationState.ALL) .abilities(PartAbility.PARALLEL_HATCH) - .modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE) + .modelProperty(IS_FORMED, false) + .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE) .model(createWorkableTieredHullMachineModel( GTCEu.id("block/machines/parallel_hatch_mk" + (tier - 4))) .andThen((ctx, prov, model) -> { @@ -131,7 +134,7 @@ public static void init() {} .where('T', Predicates.blocks(CASING_TITANIUM_PIPE.get())) .build()) .hasBER(true) - .modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE) + .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE) .model(createWorkableCasingMachineModel(GTCEu.id("block/casings/gcym/watertight_casing"), GTCEu.id("block/multiblock/gcym/large_chemical_bath")) .andThen(b -> b.addDynamicRenderer(DynamicRenderHelper::makeRecipeFluidAreaRender))) @@ -192,7 +195,7 @@ public static void init() {} .where('#', Predicates.any()) .build()) .hasBER(true) - .modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE) + .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE) .model(createWorkableCasingMachineModel(GTCEu.id("block/casings/gcym/reaction_safe_mixing_casing"), GTCEu.id("block/multiblock/gcym/large_mixer")) .andThen(b -> b.addDynamicRenderer(DynamicRenderHelper::makeRecipeFluidAreaRender))) diff --git a/src/main/java/com/gregtechceu/gtceu/data/machine/GTMachineUtils.java b/src/main/java/com/gregtechceu/gtceu/data/machine/GTMachineUtils.java index 308cef23afd..b559887108d 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/machine/GTMachineUtils.java +++ b/src/main/java/com/gregtechceu/gtceu/data/machine/GTMachineUtils.java @@ -15,6 +15,7 @@ import com.gregtechceu.gtceu.api.machine.feature.multiblock.IRotorHolderMachine; import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockControllerMachine; import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.steam.SimpleSteamMachine; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.material.material.Material; @@ -27,6 +28,7 @@ import com.gregtechceu.gtceu.api.multiblock.predicates.SimplePredicate; import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.registry.registrate.GTRegistrate; import com.gregtechceu.gtceu.api.registry.registrate.MachineBuilder; import com.gregtechceu.gtceu.api.registry.registrate.MultiblockMachineBuilder; import com.gregtechceu.gtceu.api.tag.TagPrefix; @@ -86,14 +88,16 @@ import java.util.stream.IntStream; import static com.gregtechceu.gtceu.api.GTValues.*; -import static com.gregtechceu.gtceu.api.GTValues.UV; -import static com.gregtechceu.gtceu.api.capability.recipe.IO.IN; +import static com.gregtechceu.gtceu.api.capability.recipe.IO.*; +import static com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties.IS_FORMED; import static com.gregtechceu.gtceu.api.multiblock.Predicates.*; import static com.gregtechceu.gtceu.api.multiblock.Predicates.autoAbilities; +import static com.gregtechceu.gtceu.common.machine.storage.QuantumTankMachine.TANK_CAPACITY; import static com.gregtechceu.gtceu.common.registry.GTRegistration.REGISTRATE; +import static com.gregtechceu.gtceu.data.block.GTBlocks.*; import static com.gregtechceu.gtceu.data.block.GTBlocks.ALL_FIREBOXES; -import static com.gregtechceu.gtceu.data.misc.GTCreativeModeTabs.MACHINE; import static com.gregtechceu.gtceu.data.model.GTMachineModels.*; +import static com.gregtechceu.gtceu.data.recipe.GTRecipeTypes.*; import static com.gregtechceu.gtceu.data.recipe.GTRecipeTypes.DUMMY_RECIPES; import static com.gregtechceu.gtceu.utils.FormattingUtil.toEnglishName; @@ -131,24 +135,44 @@ public class GTMachineUtils { public static MachineDefinition[] registerSimpleMachines(String name, GTRecipeType recipeType, Int2IntFunction tankScalingFunction, boolean hasPollutionDebuff) { - return registerSimpleMachines(name, recipeType, tankScalingFunction, hasPollutionDebuff, ELECTRIC_TIERS); + return registerSimpleMachines(REGISTRATE, name, recipeType, tankScalingFunction, hasPollutionDebuff); + } + + public static MachineDefinition[] registerSimpleMachines(GTRegistrate registrate, String name, + GTRecipeType recipeType, + Int2IntFunction tankScalingFunction, + boolean hasPollutionDebuff) { + return registerSimpleMachines(registrate, name, recipeType, tankScalingFunction, hasPollutionDebuff, + ELECTRIC_TIERS); } public static MachineDefinition[] registerSimpleMachines(String name, GTRecipeType recipeType, Int2IntFunction tankScalingFunction) { - return registerSimpleMachines(name, recipeType, tankScalingFunction, false); + return registerSimpleMachines(REGISTRATE, name, recipeType, tankScalingFunction); + } + + public static MachineDefinition[] registerSimpleMachines(GTRegistrate registrate, String name, + GTRecipeType recipeType, + Int2IntFunction tankScalingFunction) { + return registerSimpleMachines(registrate, name, recipeType, tankScalingFunction, false); } public static MachineDefinition[] registerSimpleMachines(String name, GTRecipeType recipeType) { - return registerSimpleMachines(name, recipeType, defaultTankSizeFunction); + return registerSimpleMachines(REGISTRATE, name, recipeType); + } + + public static MachineDefinition[] registerSimpleMachines(GTRegistrate registrate, String name, + GTRecipeType recipeType) { + return registerSimpleMachines(registrate, name, recipeType, defaultTankSizeFunction); } - public static MachineDefinition[] registerSimpleMachines(String name, + public static MachineDefinition[] registerSimpleMachines(GTRegistrate registrate, + String name, GTRecipeType recipeType, Int2IntFunction tankScalingFunction, boolean hasPollutionDebuff, int... tiers) { - return registerTieredMachines(name, + return registerTieredMachines(registrate, name, (holder, tier) -> new SimpleTieredMachine(holder, tier, tankScalingFunction), (tier, builder) -> { if (hasPollutionDebuff) { builder.recipeModifiers(GTRecipeModifiers.ENVIRONMENT_REQUIREMENT @@ -176,9 +200,17 @@ public static MachineDefinition[] registerTieredMachines(String name, BiFunction factory, BiFunction, MachineDefinition> builder, int... tiers) { + return registerTieredMachines(REGISTRATE, name, factory, builder, tiers); + } + + public static MachineDefinition[] registerTieredMachines(GTRegistrate registrate, + String name, + BiFunction factory, + BiFunction, MachineDefinition> builder, + int... tiers) { MachineDefinition[] definitions = new MachineDefinition[GTValues.TIER_COUNT]; for (int tier : tiers) { - var register = REGISTRATE + var register = registrate .machine(GTValues.VN[tier].toLowerCase(Locale.ROOT) + "_" + name, holder -> factory.apply(holder, tier)) .tier(tier); @@ -190,12 +222,18 @@ public static MachineDefinition[] registerTieredMachines(String name, public static Pair registerSteamMachines(String name, BiFunction factory, BiFunction, MachineDefinition> builder) { + return registerSteamMachines(REGISTRATE, name, factory, builder); + } + + public static Pair registerSteamMachines(GTRegistrate registrate, String name, + BiFunction factory, + BiFunction, MachineDefinition> builder) { MachineDefinition lowTier = builder.apply(false, - REGISTRATE.machine("lp_%s".formatted(name), holder -> factory.apply(holder, false)) + registrate.machine("lp_%s".formatted(name), holder -> factory.apply(holder, false)) .langValue("Low Pressure " + FormattingUtil.toEnglishName(name)) .tier(0)); MachineDefinition highTier = builder.apply(true, - REGISTRATE.machine("hp_%s".formatted(name), holder -> factory.apply(holder, true)) + registrate.machine("hp_%s".formatted(name), holder -> factory.apply(holder, true)) .langValue("High Pressure " + FormattingUtil.toEnglishName(name)) .tier(1)); return Pair.of(lowTier, highTier); @@ -204,6 +242,14 @@ public static Pair registerSteamMachines(S public static MachineDefinition[] registerFluidHatches(String name, String displayName, String tooltip, IO io, int initialCapacity, int slots, int[] tiers, PartAbility... abilities) { + return registerFluidHatches(REGISTRATE, name, displayName, tooltip, io, initialCapacity, slots, tiers, + abilities); + } + + public static MachineDefinition[] registerFluidHatches(GTRegistrate registrate, String name, String displayName, + String tooltip, + IO io, int initialCapacity, int slots, + int[] tiers, PartAbility... abilities) { final String pipeOverlay; if (slots >= 9) { pipeOverlay = "overlay_pipe_9x"; @@ -212,15 +258,16 @@ public static MachineDefinition[] registerFluidHatches(String name, String displ } else { pipeOverlay = null; } - final String ioOverlay = io == IO.OUT ? "overlay_pipe_out_emissive" : "overlay_pipe_in_emissive"; - final String emissiveOverlay = slots > 4 ? OVERLAY_FLUID_HATCH_HALF_PX_TEX : OVERLAY_FLUID_HATCH_TEX; - return registerTieredMachines(name, + final String ioOverlay = io == OUT ? OVERLAY_FLUID_HATCH_OUTPUT : OVERLAY_FLUID_HATCH_INPUT; + final String emissiveOverlay = io == OUT ? "overlay_pipe_out_emissive" : "overlay_pipe_in_emissive"; + return registerTieredMachines(registrate, name, (holder, tier) -> new FluidHatchPartMachine(holder, tier, io, initialCapacity, slots), (tier, builder) -> { builder.langValue(VNF[tier] + ' ' + displayName) .rotationState(RotationState.ALL) .colorOverlayTieredHullModel(ioOverlay, pipeOverlay, emissiveOverlay) .abilities(abilities) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.machine." + tooltip + ".tooltip")) .allowCoverOnFront(true); @@ -239,7 +286,12 @@ public static MachineDefinition[] registerFluidHatches(String name, String displ } public static MachineDefinition[] registerTransformerMachines(String langName, int baseAmp) { - return registerTieredMachines("transformer_%da".formatted(baseAmp), + return registerTransformerMachines(REGISTRATE, langName, baseAmp); + } + + public static MachineDefinition[] registerTransformerMachines(GTRegistrate registrate, String langName, + int baseAmp) { + return registerTieredMachines(registrate, "transformer_%da".formatted(baseAmp), (holder, tier) -> new TransformerMachine(holder, tier, baseAmp), (tier, builder) -> builder .rotationState(RotationState.ALL) @@ -249,7 +301,7 @@ public static MachineDefinition[] registerTransformerMachines(String langName, i case 3 -> VC[tier]; default -> -1; }) - .modelProperty(TransformerMachine.TRANSFORM_UP_PROPERTY, false) + .modelProperty(GTMachineModelProperties.IS_TRANSFORM_UP, false) .model(createTransformerModel(baseAmp)) .langValue("%s %sTransformer".formatted(VCF[tier] + VOLTAGE_NAMES[tier] + ChatFormatting.RESET, langName.isEmpty() ? "" : langName + " ")) @@ -274,7 +326,16 @@ public static MachineDefinition[] registerSimpleGenerator(String name, Int2IntFunction tankScalingFunction, float hazardStrengthPerOperation, int... tiers) { - return registerTieredMachines(name, + return registerSimpleGenerator(REGISTRATE, name, recipeType, tankScalingFunction, hazardStrengthPerOperation, + tiers); + } + + public static MachineDefinition[] registerSimpleGenerator(GTRegistrate registrate, String name, + GTRecipeType recipeType, + Int2IntFunction tankScalingFunction, + float hazardStrengthPerOperation, + int... tiers) { + return registerTieredMachines(registrate, name, (holder, tier) -> new SimpleGeneratorMachine(holder, tier, hazardStrengthPerOperation * tier, tankScalingFunction), (tier, builder) -> builder @@ -294,17 +355,28 @@ public static MachineDefinition[] registerSimpleGenerator(String name, public static Pair registerSimpleSteamMachines(String name, GTRecipeType recipeType) { - return registerSteamMachines("steam_" + name, SimpleSteamMachine::new, (pressure, builder) -> builder - .rotationState(RotationState.ALL) - .recipeType(recipeType) - .recipeModifier(SimpleSteamMachine::recipeModifier) - .modelProperty(SimpleSteamMachine.VENT_DIRECTION_PROPERTY, RelativeDirection.BACK) - .workableSteamHullModel(pressure, GTCEu.id("block/machines/" + name)) - .register()); + return registerSimpleSteamMachines(REGISTRATE, name, recipeType); + } + + public static Pair registerSimpleSteamMachines(GTRegistrate registrate, + String name, + GTRecipeType recipeType) { + return registerSteamMachines(registrate, "steam_" + name, SimpleSteamMachine::new, + (pressure, builder) -> builder + .rotationState(RotationState.ALL) + .recipeType(recipeType) + .recipeModifier(SimpleSteamMachine::recipeModifier) + .modelProperty(GTMachineModelProperties.VENT_DIRECTION, RelativeDirection.BACK) + .workableSteamHullModel(pressure, GTCEu.id("block/machines/" + name)) + .register()); } public static MachineDefinition[] registerBatteryBuffer(int batterySlotSize) { - return registerTieredMachines("battery_buffer_" + batterySlotSize + "x", + return registerBatteryBuffer(REGISTRATE, batterySlotSize); + } + + public static MachineDefinition[] registerBatteryBuffer(GTRegistrate registrate, int batterySlotSize) { + return registerTieredMachines(registrate, "battery_buffer_" + batterySlotSize + "x", (holder, tier) -> new BatteryBufferMachine(holder, tier, batterySlotSize), (tier, builder) -> builder .rotationState(RotationState.ALL) @@ -326,11 +398,15 @@ public static MachineDefinition[] registerBatteryBuffer(int batterySlotSize) { } public static MachineDefinition[] registerCharger(int itemSlotSize) { - return registerTieredMachines("charger_" + itemSlotSize + "x", + return registerCharger(REGISTRATE, itemSlotSize); + } + + public static MachineDefinition[] registerCharger(GTRegistrate registrate, int itemSlotSize) { + return registerTieredMachines(registrate, "charger_" + itemSlotSize + "x", (holder, tier) -> new ChargerMachine(holder, tier, itemSlotSize), (tier, builder) -> builder .rotationState(RotationState.ALL) - .modelProperty(ChargerMachine.STATE_PROPERTY, ChargerMachine.State.IDLE) + .modelProperty(GTMachineModelProperties.CHARGER_STATE, ChargerMachine.State.IDLE) .model(GTMachineModels.createChargerModel()) .langValue("%s %sx Turbo Charger".formatted( VCF[tier] + VOLTAGE_NAMES[tier] + ChatFormatting.RESET, @@ -346,17 +422,24 @@ public static MachineDefinition[] registerCharger(int itemSlotSize) { } public static MachineDefinition[] registerConverter(int amperage) { + return registerConverter(REGISTRATE, amperage); + } + + public static MachineDefinition[] registerConverter(GTRegistrate registrate, int amperage) { + final var tab = registrate.creativeModeTab(); + if (!ConfigHolder.INSTANCE.compat.energy.enableFEConverters) { - REGISTRATE.creativeModeTab(null); + // REGISTRATE.creativeModeTab(null); + registrate.creativeModeTab(() -> null); } - MachineDefinition[] converters = registerTieredMachines(amperage + "a_energy_converter", + MachineDefinition[] converters = registerTieredMachines(registrate, amperage + "a_energy_converter", (holder, tier) -> new ConverterMachine(holder, tier, amperage), (tier, builder) -> builder .rotationState(RotationState.ALL) .langValue("%s %s§eA§r Energy Converter".formatted(VCF[tier] + VN[tier] + ChatFormatting.RESET, amperage)) - .modelProperty(ConverterMachine.FE_TO_EU_PROPERTY, false) + .modelProperty(GTMachineModelProperties.IS_FE_TO_EU, false) .model(GTMachineModels.createConverterModel(amperage)) .tooltips(Component.translatable("gtceu.machine.energy_converter.description"), Component.translatable("gtceu.machine.energy_converter.tooltip_tool_usage"), @@ -372,14 +455,20 @@ public static MachineDefinition[] registerConverter(int amperage) { ALL_TIERS); if (!ConfigHolder.INSTANCE.compat.energy.enableFEConverters) { - REGISTRATE.creativeModeTab(MACHINE); + // REGISTRATE.creativeModeTab(MACHINE); + registrate.creativeModeTab(() -> tab); } return converters; } public static MachineDefinition[] registerLaserHatch(IO io, int amperage, PartAbility ability) { + return registerLaserHatch(REGISTRATE, io, amperage, ability); + } + + public static MachineDefinition[] registerLaserHatch(GTRegistrate registrate, IO io, int amperage, + PartAbility ability) { String name = io == IN ? "target" : "source"; - return registerTieredMachines(amperage + "a_laser_" + name + "_hatch", + return registerTieredMachines(registrate, amperage + "a_laser_" + name + "_hatch", (holder, tier) -> new LaserHatchPartMachine(holder, io, tier, amperage), (tier, builder) -> builder .langValue(VNF[tier] + "§r " + FormattingUtil.formatNumbers(amperage) + "§eA§r Laser " + FormattingUtil.toEnglishName(name) + " Hatch") @@ -395,19 +484,25 @@ public static MachineDefinition[] registerLaserHatch(IO io, int amperage, PartAb EnergyHatchPartMachine.getHatchEnergyCapacity(tier, amperage))), Component.translatable("gtceu.part_sharing.disabled")) .abilities(ability) + .modelProperty(IS_FORMED, false) .overlayTieredHullModel("laser_" + name + "_hatch") .register(), HIGH_TIERS); } public static MachineDefinition registerCrate(Material material, int capacity, String lang) { + return registerCrate(REGISTRATE, material, capacity, lang); + } + + public static MachineDefinition registerCrate(GTRegistrate registrate, Material material, int capacity, + String lang) { final boolean wooden = material.hasProperty(PropertyKey.WOOD); - return REGISTRATE.machine(material.getName() + "_crate", holder -> new CrateMachine(holder, material, capacity)) + return registrate.machine(material.getName() + "_crate", holder -> new CrateMachine(holder, material, capacity)) .langValue(lang) .rotationState(RotationState.NONE) .tooltips(Component.translatable("gtceu.universal.tooltip.item_storage_capacity", capacity)) - .modelProperty(CrateMachine.TAPED_PROPERTY, false) + .modelProperty(GTMachineModelProperties.IS_TAPED, false) .model(GTMachineModels.createCrateModel(wooden)) .paintingColor(wooden ? 0xFFFFFF : material.getMaterialRGB()) .itemColor((s, t) -> wooden ? 0xFFFFFF : material.getMaterialRGB()) @@ -415,8 +510,13 @@ public static MachineDefinition registerCrate(Material material, int capacity, S } public static MachineDefinition registerDrum(Material material, int capacity, String lang) { + return registerDrum(REGISTRATE, material, capacity, lang); + } + + public static MachineDefinition registerDrum(GTRegistrate registrate, Material material, int capacity, + String lang) { boolean wooden = material.hasProperty(PropertyKey.WOOD); - var definition = REGISTRATE + var definition = registrate .machine(material.getName() + "_drum", MachineDefinition::new, holder -> new DrumMachine(holder, material, capacity), MetaMachineBlock::new, (holder, prop) -> DrumMachineItem.create(holder, prop, material), @@ -442,12 +542,25 @@ public static MachineDefinition registerDrum(Material material, int capacity, St } public static MachineDefinition[] registerQuantumTanks(String name, int... tiers) { + return registerQuantumTanks(REGISTRATE, name, tiers); + } + + public static MachineDefinition[] registerQuantumTanks(GTRegistrate registrate, String name, int... tiers) { MachineDefinition[] definitions = new MachineDefinition[GTValues.TIER_COUNT]; for (int tier : tiers) { long maxAmount = 4000 * FluidType.BUCKET_VOLUME * (long) Math.pow(2, tier - 1); + // <<<<<<< HEAD:src/main/java/com/gregtechceu/gtceu/data/machine/GTMachineUtils.java var register = REGISTRATE .machine(GTValues.VN[tier].toLowerCase(Locale.ROOT) + "_" + name, (holder) -> new QuantumTankMachine(holder, tier, maxAmount)) + // ======= + // var register = registrate.machine( + // GTValues.VN[tier].toLowerCase(Locale.ROOT) + "_" + name, + // MachineDefinition::new, (holder) -> new QuantumTankMachine(holder, tier, maxAmount), + // MetaMachineBlock::new, QuantumTankMachineItem::new, + // MetaMachineBlockEntity::new) + // >>>>>>> + // v7.1.0-1.20.1:src/main/java/com/gregtechceu/gtceu/common/data/machines/GTMachineUtils.java .langValue(toEnglishName(name) + " " + LVT[tier]) .blockProp(Block.Properties::dynamicShape) .rotationState(RotationState.ALL) @@ -468,7 +581,11 @@ public static MachineDefinition[] registerQuantumTanks(String name, int... tiers } public static MachineDefinition[] registerQuantumChests(String name, int... tiers) { - return registerTieredMachines(name, + return registerQuantumChests(REGISTRATE, name, tiers); + } + + public static MachineDefinition[] registerQuantumChests(GTRegistrate registrate, String name, int... tiers) { + return registerTieredMachines(registrate, name, (holder, tier) -> new QuantumChestMachine(holder, tier, tier == MAX ? Long.MAX_VALUE : 4_000_000 * (long) Math.pow(2, tier - 1)), (tier, builder) -> builder.langValue(toEnglishName(name) + " " + LVT[tier]) @@ -498,12 +615,23 @@ public static MultiblockMachineDefinition registerMultiblockTank(String name, St Supplier valve, @Nullable PropertyFluidFilter filter, BiConsumer rendererSetup) { - MultiblockMachineBuilder builder = REGISTRATE + return registerMultiblockTank(REGISTRATE, name, displayName, capacity, casing, valve, filter, rendererSetup); + } + + public static MultiblockMachineDefinition registerMultiblockTank(GTRegistrate registrate, String name, + String displayName, int capacity, + Supplier casing, + Supplier valve, + @Nullable PropertyFluidFilter filter, + BiConsumer rendererSetup) { + MultiblockMachineBuilder builder = registrate .multiblock(name, holder -> new MultiblockTankMachine(holder, capacity, filter)) .langValue(displayName) .tooltips( Component.translatable("gtceu.machine.multiblock.tank.tooltip"), - Component.translatable("gtceu.universal.tooltip.fluid_storage_capacity", capacity)) + Component.translatable("gtceu.universal.tooltip.fluid_storage_capacity", capacity), + (filter != null) ? Component.translatable("gtceu.fluid_pipe.max_temperature", + filter.getMaxFluidTemperature()) : null) .rotationState(RotationState.ALL) .recipeType(DUMMY_RECIPES) .pattern(definition -> FactoryBlockPattern.start() @@ -522,7 +650,13 @@ public static MultiblockMachineDefinition registerMultiblockTank(String name, St public static MachineDefinition registerTankValve(String name, String displayName, boolean isMetal, BiConsumer, ResourceLocation> rendererSetup) { - MachineBuilder builder = REGISTRATE + return registerTankValve(REGISTRATE, name, displayName, isMetal, rendererSetup); + } + + public static MachineDefinition registerTankValve(GTRegistrate registrate, String name, String displayName, + boolean isMetal, + BiConsumer, ResourceLocation> rendererSetup) { + MachineBuilder builder = registrate .machine(name, holder -> new TankValvePartMachine(holder, isMetal)) .langValue(displayName) .tooltips(Component.translatable("gtceu.machine.tank_valve.tooltip"), @@ -536,9 +670,16 @@ public static MultiblockMachineDefinition[] registerTieredMultis(String name, BiFunction factory, BiFunction builder, int... tiers) { + return registerTieredMultis(REGISTRATE, name, factory, builder, tiers); + } + + public static MultiblockMachineDefinition[] registerTieredMultis(GTRegistrate registrate, String name, + BiFunction factory, + BiFunction builder, + int... tiers) { MultiblockMachineDefinition[] definitions = new MultiblockMachineDefinition[GTValues.TIER_COUNT]; for (int tier : tiers) { - var register = REGISTRATE + var register = registrate .multiblock(GTValues.VN[tier].toLowerCase(Locale.ROOT) + "_" + name, holder -> factory.apply(holder, tier)) .tier(tier); @@ -552,8 +693,18 @@ public static MultiblockMachineDefinition registerLargeBoiler(String name, Suppl Supplier fireBox, ResourceLocation texture, BoilerFireboxType firebox, int maxTemperature, int heatSpeed) { + return registerLargeBoiler(REGISTRATE, name, casing, pipe, fireBox, texture, firebox, maxTemperature, + heatSpeed); + } + + public static MultiblockMachineDefinition registerLargeBoiler(GTRegistrate registrate, String name, + Supplier casing, + Supplier pipe, + Supplier fireBox, + ResourceLocation texture, BoilerFireboxType firebox, + int maxTemperature, int heatSpeed) { // spotless:off - return REGISTRATE + return registrate .multiblock("%s_large_boiler".formatted(name), holder -> new LargeBoilerMachine(holder, maxTemperature, heatSpeed)) .langValue("Large %s Boiler".formatted(FormattingUtil.toEnglishName(name))) @@ -592,7 +743,7 @@ public static MultiblockMachineDefinition registerLargeBoiler(String name, Suppl .recoveryItems( () -> new ItemLike[] { GTMaterialItems.MATERIAL_ITEMS.get(TagPrefix.dustTiny, GTMaterials.Ash).get() }) - .modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE) + .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE) .model(createWorkableCasingMachineModel(texture, GTCEu.id("block/multiblock/generator/large_%s_boiler".formatted(name))) .andThen(b -> b.addDynamicRenderer(() -> DynamicRenderHelper.makeBoilerPartRender(firebox, casing)))) @@ -613,7 +764,17 @@ public static MultiblockMachineDefinition registerLargeCombustionEngine(String n Supplier intake, ResourceLocation casingTexture, ResourceLocation overlayModel) { - return REGISTRATE.multiblock(name, holder -> new LargeCombustionEngineMachine(holder, tier)) + return registerLargeCombustionEngine(REGISTRATE, name, tier, casing, gear, intake, casingTexture, overlayModel); + } + + public static MultiblockMachineDefinition registerLargeCombustionEngine(GTRegistrate registrate, + String name, int tier, + Supplier casing, + Supplier gear, + Supplier intake, + ResourceLocation casingTexture, + ResourceLocation overlayModel) { + return registrate.multiblock(name, holder -> new LargeCombustionEngineMachine(holder, tier)) .rotationState(RotationState.ALL) .recipeType(GTRecipeTypes.COMBUSTION_GENERATOR_FUELS) .generator(true) @@ -662,7 +823,17 @@ public static MultiblockMachineDefinition registerLargeTurbine(String name, int Supplier gear, ResourceLocation casingTexture, ResourceLocation overlayModel) { - return registerLargeTurbine(name, tier, recipeType, casing, gear, casingTexture, overlayModel, true); + return registerLargeTurbine(REGISTRATE, name, tier, recipeType, casing, gear, casingTexture, overlayModel); + } + + public static MultiblockMachineDefinition registerLargeTurbine(GTRegistrate registrate, + String name, int tier, GTRecipeType recipeType, + Supplier casing, + Supplier gear, + ResourceLocation casingTexture, + ResourceLocation overlayModel) { + return registerLargeTurbine(registrate, name, tier, recipeType, casing, gear, casingTexture, overlayModel, + true); } public static MultiblockMachineDefinition registerLargeTurbine(String name, int tier, GTRecipeType recipeType, @@ -671,7 +842,18 @@ public static MultiblockMachineDefinition registerLargeTurbine(String name, int ResourceLocation casingTexture, ResourceLocation overlayModel, boolean needsMuffler) { - return REGISTRATE.multiblock(name, holder -> new LargeTurbineMachine(holder, tier)) + return registerLargeTurbine(REGISTRATE, name, tier, recipeType, casing, gear, casingTexture, overlayModel, + needsMuffler); + } + + public static MultiblockMachineDefinition registerLargeTurbine(GTRegistrate registrate, + String name, int tier, GTRecipeType recipeType, + Supplier casing, + Supplier gear, + ResourceLocation casingTexture, + ResourceLocation overlayModel, + boolean needsMuffler) { + return registrate.multiblock(name, holder -> new LargeTurbineMachine(holder, tier)) .rotationState(RotationState.ALL) .recipeType(recipeType) .generator(true) diff --git a/src/main/java/com/gregtechceu/gtceu/data/machine/GTMachines.java b/src/main/java/com/gregtechceu/gtceu/data/machine/GTMachines.java index d3c037834c2..99a47856c28 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/machine/GTMachines.java +++ b/src/main/java/com/gregtechceu/gtceu/data/machine/GTMachines.java @@ -4,15 +4,14 @@ import com.gregtechceu.gtceu.api.GTCEuAPI; import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.capability.IMiner; -import com.gregtechceu.gtceu.api.capability.IWorkable; import com.gregtechceu.gtceu.api.capability.recipe.IO; import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.RotationState; import com.gregtechceu.gtceu.api.machine.SimpleTieredMachine; -import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; import com.gregtechceu.gtceu.api.machine.multiblock.CleanroomType; import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.steam.SimpleSteamMachine; import com.gregtechceu.gtceu.api.machine.steam.SteamBoilerMachine; import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; @@ -22,6 +21,8 @@ import com.gregtechceu.gtceu.client.util.TooltipHelper; import com.gregtechceu.gtceu.common.machine.electric.*; import com.gregtechceu.gtceu.common.machine.multiblock.part.*; +import com.gregtechceu.gtceu.common.machine.multiblock.part.monitor.AdvancedMonitorPartMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.part.monitor.MonitorPartMachine; import com.gregtechceu.gtceu.common.machine.steam.SteamLiquidBoilerMachine; import com.gregtechceu.gtceu.common.machine.steam.SteamMinerMachine; import com.gregtechceu.gtceu.common.machine.steam.SteamSolarBoiler; @@ -53,8 +54,8 @@ import java.util.function.BiConsumer; import static com.gregtechceu.gtceu.api.GTValues.*; -import static com.gregtechceu.gtceu.api.capability.recipe.IO.IN; -import static com.gregtechceu.gtceu.api.capability.recipe.IO.OUT; +import static com.gregtechceu.gtceu.api.capability.recipe.IO.*; +import static com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties.*; import static com.gregtechceu.gtceu.common.registry.GTRegistration.REGISTRATE; import static com.gregtechceu.gtceu.data.machine.GTMachineUtils.*; import static com.gregtechceu.gtceu.data.machine.GTMachineUtils.ALL_TIERS; @@ -119,7 +120,7 @@ public class GTMachines { .recipeType(GTRecipeTypes.MACERATOR_RECIPES) .recipeModifier(SimpleSteamMachine::recipeModifier) .addOutputLimit(ItemRecipeCapability.CAP, 1) - .modelProperty(SimpleSteamMachine.VENT_DIRECTION_PROPERTY, RelativeDirection.BACK) + .modelProperty(GTMachineModelProperties.VENT_DIRECTION, RelativeDirection.BACK) .workableSteamHullModel(pressure, GTCEu.id("block/machines/macerator")) .register()); public static final Pair STEAM_COMPRESSOR = registerSimpleSteamMachines( @@ -147,7 +148,7 @@ public class GTMachines { int maxArea = IMiner.getWorkingArea(isHP ? 6 : 4); tooltip.add(Component.translatable("gtceu.universal.tooltip.working_area", maxArea, maxArea)); }) - .modelProperty(SteamMinerMachine.VENT_DIRECTION_PROPERTY, RelativeDirection.UP) + .modelProperty(GTMachineModelProperties.VENT_DIRECTION, RelativeDirection.UP) .workableSteamHullModel(isHP, isHP ? GTCEu.id("block/machines/high_pressure_steam_miner") : GTCEu.id("block/machines/steam_miner")) @@ -162,6 +163,7 @@ public class GTMachines { .rotationState(RotationState.ALL) .overlayTieredHullModel("hull") .abilities(PartAbility.PASSTHROUGH_HATCH) + .modelProperty(IS_FORMED, false) .langValue("%s §fMachine Hull".formatted(VNF[tier])) .tooltips(Component.translatable("gtceu.machine.hull.tooltip")) .register(), @@ -308,7 +310,8 @@ public class GTMachines { .langValue("Long Distance Item Pipeline Endpoint") .rotationState(RotationState.ALL) .tier(LV) - .blockModel(GTModels.createModelBlockState(GTCEu.id("block/machine/long_distance_item_pipeline_endpoint"))) + .modelProperty(IS_FORMED, false) + .overlayTieredHullModel("long_distance_item_pipeline_endpoint") .tooltips(LangHandler.getMultiLang("gtceu.machine.endpoint.tooltip")) .tooltipBuilder((stack, tooltip) -> { if (ConfigHolder.INSTANCE.machines.ldItemPipeMinDistance > 0) { @@ -323,14 +326,15 @@ public class GTMachines { .langValue("Long Distance Fluid Pipeline Endpoint") .rotationState(RotationState.ALL) .tier(LV) - .blockModel(GTModels.createModelBlockState(GTCEu.id("block/machine/long_distance_fluid_pipeline_endpoint"))) + .modelProperty(IS_FORMED, false) + .overlayTieredHullModel("long_distance_fluid_pipeline_endpoint") .tooltips(Component.translatable("gtceu.machine.endpoint.tooltip.0"), Component.translatable("gtceu.machine.endpoint.tooltip.1"), Component.translatable("gtceu.machine.endpoint.tooltip.2")) .tooltipBuilder((stack, tooltip) -> { if (ConfigHolder.INSTANCE.machines.ldFluidPipeMinDistance > 0) { tooltip.add(Component.translatable("gtceu.machine.endpoint.tooltip.min_length", - ConfigHolder.INSTANCE.machines.ldItemPipeMinDistance)); + ConfigHolder.INSTANCE.machines.ldFluidPipeMinDistance)); } }) .register(); @@ -434,9 +438,9 @@ public class GTMachines { .rotationState(RotationState.NONE) .langValue("%s World Accelerator %s".formatted(VLVH[tier], VLVT[tier])) .recipeType(DUMMY_RECIPES) - .modelProperty(WorldAcceleratorMachine.RANDOM_TICK_PROPERTY, true) - .modelProperty(WorldAcceleratorMachine.WORKING_ENABLED_PROPERTY, true) - .modelProperty(IWorkable.ACTIVE_PROPERTY, false) + .modelProperty(GTMachineModelProperties.IS_RANDOM_TICK_MODE, true) + .modelProperty(GTMachineModelProperties.IS_WORKING_ENABLED, true) + .modelProperty(GTMachineModelProperties.IS_ACTIVE, false) .model(createWorldAcceleratorModel(GTCEu.id("block/machines/world_accelerator_te"), GTCEu.id("block/machines/world_accelerator"))) .tooltipBuilder((stack, tooltip) -> { @@ -463,8 +467,8 @@ public class GTMachines { .rotationState(RotationState.NONE) .langValue("%s Item Collector %s".formatted(VLVH[tier], VLVT[tier])) .recipeType(DUMMY_RECIPES) - .modelProperty(IWorkable.ACTIVE_PROPERTY, false) - .modelProperty(IWorkable.WORKING_ENABLED_PROPERTY, false) + .modelProperty(GTMachineModelProperties.IS_ACTIVE, false) + .modelProperty(GTMachineModelProperties.IS_WORKING_ENABLED, false) .editableUI(ItemCollectorMachine.EDITABLE_UI_CREATOR.apply(GTCEu.id("item_collector"), ItemCollectorMachine.getINVENTORY_SIZES()[tier])) .model(createItemCollectorModel(GTCEu.id("block/machines/item_collector"))) @@ -609,7 +613,8 @@ public class GTMachines { .langValue(VNF[tier] + " Input Bus") .rotationState(RotationState.ALL) .abilities(PartAbility.IMPORT_ITEMS) - .colorOverlayTieredHullModel("overlay_pipe_in_emissive", null, OVERLAY_ITEM_HATCH) + .modelProperty(IS_FORMED, false) + .colorOverlayTieredHullModel(OVERLAY_ITEM_HATCH_INPUT, "overlay_pipe", "overlay_pipe_in_emissive") .tooltips(Component.translatable("gtceu.machine.item_bus.import.tooltip"), Component.translatable("gtceu.universal.tooltip.item_storage_capacity", (1 + Math.min(9, tier)) * (1 + Math.min(9, tier)))) @@ -623,7 +628,8 @@ public class GTMachines { .langValue(VNF[tier] + " Output Bus") .rotationState(RotationState.ALL) .abilities(PartAbility.EXPORT_ITEMS) - .colorOverlayTieredHullModel("overlay_pipe_out_emissive", null, OVERLAY_ITEM_HATCH) + .modelProperty(IS_FORMED, false) + .colorOverlayTieredHullModel(OVERLAY_ITEM_HATCH_OUTPUT, "overlay_pipe", "overlay_pipe_out_emissive") .tooltips(Component.translatable("gtceu.machine.item_bus.export.tooltip"), Component.translatable("gtceu.universal.tooltip.item_storage_capacity", (1 + Math.min(9, tier)) * (1 + Math.min(9, tier)))) @@ -673,6 +679,7 @@ public class GTMachines { .langValue(VNF[tier] + " Energy Hatch") .rotationState(RotationState.ALL) .abilities(PartAbility.INPUT_ENERGY) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.universal.tooltip.voltage_in", FormattingUtil.formatNumbers(V[tier]), VNF[tier]), Component.translatable("gtceu.universal.tooltip.amperage_in", 2), @@ -690,6 +697,7 @@ public class GTMachines { .langValue(VNF[tier] + " Dynamo Hatch") .rotationState(RotationState.ALL) .abilities(PartAbility.OUTPUT_ENERGY) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.universal.tooltip.voltage_out", FormattingUtil.formatNumbers(V[tier]), VNF[tier]), Component.translatable("gtceu.universal.tooltip.amperage_out", 2), @@ -707,6 +715,7 @@ public class GTMachines { .langValue(VNF[tier] + " 4A Energy Hatch") .rotationState(RotationState.ALL) .abilities(PartAbility.INPUT_ENERGY) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.universal.tooltip.voltage_in", FormattingUtil.formatNumbers(V[tier]), VNF[tier]), Component.translatable("gtceu.universal.tooltip.amperage_in", 4), @@ -724,6 +733,7 @@ public class GTMachines { .langValue(VNF[tier] + " 4A Dynamo Hatch") .rotationState(RotationState.ALL) .abilities(PartAbility.OUTPUT_ENERGY) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.universal.tooltip.voltage_out", FormattingUtil.formatNumbers(V[tier]), VNF[tier]), Component.translatable("gtceu.universal.tooltip.amperage_out", 4), @@ -741,6 +751,7 @@ public class GTMachines { .langValue(VNF[tier] + " 16A Energy Hatch") .rotationState(RotationState.ALL) .abilities(PartAbility.INPUT_ENERGY) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.universal.tooltip.voltage_in", FormattingUtil.formatNumbers(V[tier]), VNF[tier]), Component.translatable("gtceu.universal.tooltip.amperage_in", 16), @@ -758,6 +769,7 @@ public class GTMachines { .langValue(VNF[tier] + " 16A Dynamo Hatch") .rotationState(RotationState.ALL) .abilities(PartAbility.OUTPUT_ENERGY) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.universal.tooltip.voltage_out", FormattingUtil.formatNumbers(V[tier]), VNF[tier]), Component.translatable("gtceu.universal.tooltip.amperage_out", 16), @@ -776,6 +788,7 @@ public class GTMachines { .langValue(VNF[tier] + " 64A Substation Energy Hatch") .rotationState(RotationState.ALL) .abilities(PartAbility.SUBSTATION_INPUT_ENERGY) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.universal.tooltip.voltage_in", FormattingUtil.formatNumbers(V[tier]), VNF[tier]), Component.translatable("gtceu.universal.tooltip.amperage_in", 64), @@ -794,6 +807,7 @@ public class GTMachines { .langValue(VNF[tier] + " 64A Substation Dynamo Hatch") .rotationState(RotationState.ALL) .abilities(PartAbility.SUBSTATION_OUTPUT_ENERGY) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.universal.tooltip.voltage_out", FormattingUtil.formatNumbers(V[tier]), VNF[tier]), Component.translatable("gtceu.universal.tooltip.amperage_out", 64), @@ -811,6 +825,7 @@ public class GTMachines { .langValue("Muffler Hatch " + VNF[tier]) .rotationState(RotationState.ALL) .abilities(PartAbility.MUFFLER) + .modelProperty(IS_FORMED, false) .overlayTieredHullModel("muffler_hatch") .tooltips(LangHandler.getFromMultiLang("gtceu.machine.muffler_hatch.tooltip", 0), Component.translatable("gtceu.muffler.recovery_tooltip", Math.max(1, tier * 10)), @@ -824,7 +839,8 @@ public class GTMachines { .machine("steam_input_bus", holder -> new SteamItemBusPartMachine(holder, IN)) .rotationState(RotationState.ALL) .abilities(PartAbility.STEAM_IMPORT_ITEMS) - .colorOverlaySteamHullModel("overlay_pipe_in_emissive", null, OVERLAY_ITEM_HATCH) + .modelProperty(IS_FORMED, false) + .colorOverlaySteamHullModel(OVERLAY_ITEM_HATCH_INPUT, "overlay_pipe", "overlay_pipe_in_emissive") .langValue("Steam Input Bus") .tooltips(Component.translatable("gtceu.machine.item_bus.import.tooltip"), Component.translatable("gtceu.machine.steam_bus.tooltip"), @@ -836,7 +852,8 @@ public class GTMachines { .machine("steam_output_bus", holder -> new SteamItemBusPartMachine(holder, OUT)) .rotationState(RotationState.ALL) .abilities(PartAbility.STEAM_EXPORT_ITEMS) - .colorOverlaySteamHullModel("overlay_pipe_out_emissive", null, OVERLAY_ITEM_HATCH) + .modelProperty(IS_FORMED, false) + .colorOverlaySteamHullModel(OVERLAY_ITEM_HATCH_OUTPUT, "overlay_pipe", "overlay_pipe_out_emissive") .langValue("Steam Output Bus") .tooltips(Component.translatable("gtceu.machine.item_bus.export.tooltip"), Component.translatable("gtceu.machine.steam_bus.tooltip"), @@ -848,6 +865,7 @@ public class GTMachines { .machine("steam_input_hatch", SteamHatchPartMachine::new) .rotationState(RotationState.ALL) .abilities(PartAbility.STEAM) + .modelProperty(IS_FORMED, false) .overlaySteamHullModel("steam_hatch") .tooltips(Component.translatable("gtceu.universal.tooltip.fluid_storage_capacity", SteamHatchPartMachine.INITIAL_TANK_CAPACITY), @@ -857,6 +875,7 @@ public class GTMachines { public static final MachineDefinition COKE_OVEN_HATCH = REGISTRATE.machine("coke_oven_hatch", CokeOvenHatch::new) .rotationState(RotationState.ALL) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.part_sharing.disabled")) .simpleModel(GTCEu.id("block/machine/part/coke_oven_hatch")) .register(); @@ -864,6 +883,7 @@ public class GTMachines { public static final MachineDefinition PUMP_HATCH = REGISTRATE.machine("pump_hatch", PumpHatchPartMachine::new) .rotationState(RotationState.ALL) .abilities(PartAbility.PUMP_FLUID_HATCH) + .modelProperty(IS_FORMED, false) .model(createBasicReplaceableTextureMachineModel(GTCEu.id("block/machine/part/pump_hatch"))) .register(); @@ -871,8 +891,9 @@ public class GTMachines { .machine("maintenance_hatch", (blockEntity) -> new MaintenanceHatchPartMachine(blockEntity, false)) .rotationState(RotationState.ALL) .abilities(PartAbility.MAINTENANCE) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.part_sharing.disabled")) - .modelProperty(MaintenanceHatchPartMachine.MAINTENANCE_TAPED_PROPERTY, false) + .modelProperty(GTMachineModelProperties.IS_TAPED, false) .model(createMaintenanceModel(GTCEu.id("block/machine/part/maintenance_hatch"))) .tier(LV) .register(); @@ -883,7 +904,8 @@ public class GTMachines { .rotationState(RotationState.ALL) .abilities(PartAbility.MAINTENANCE) .tooltips(Component.translatable("gtceu.part_sharing.disabled")) - .modelProperty(MaintenanceHatchPartMachine.MAINTENANCE_TAPED_PROPERTY, false) + .modelProperty(IS_FORMED, false) + .modelProperty(GTMachineModelProperties.IS_TAPED, false) .model(createMaintenanceModel(GTCEu.id("block/machine/part/configurable_maintenance_hatch"))) .tier(HV) .register(); @@ -893,6 +915,7 @@ public class GTMachines { holder -> new CleaningMaintenanceHatchPartMachine(holder, CleanroomType.CLEANROOM)) .rotationState(RotationState.ALL) .abilities(PartAbility.MAINTENANCE) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.part_sharing.disabled"), Component.translatable("gtceu.machine.maintenance_hatch_cleanroom_auto.tooltip.0"), Component.translatable("gtceu.machine.maintenance_hatch_cleanroom_auto.tooltip.1")) @@ -908,6 +931,7 @@ public class GTMachines { .machine("auto_maintenance_hatch", AutoMaintenanceHatchPartMachine::new) .rotationState(RotationState.ALL) .abilities(PartAbility.MAINTENANCE) + .modelProperty(IS_FORMED, false) .tooltips(Component.translatable("gtceu.part_sharing.disabled")) .overlayTieredHullModel(GTCEu.id("block/machine/part/auto_maintenance_hatch")) .tier(HV) @@ -919,6 +943,7 @@ public class GTMachines { .langValue("%s Item Passthrough Hatch".formatted(VNF[tier])) .rotationState(RotationState.ALL) .abilities(PartAbility.PASSTHROUGH_HATCH) + .modelProperty(IS_FORMED, false) .overlayTieredHullModel("item_passthrough_hatch") .tooltips( Component.translatable("gtceu.universal.tooltip.item_storage_capacity", @@ -934,6 +959,7 @@ public class GTMachines { .langValue("%s Fluid Passthrough Hatch".formatted(VNF[tier])) .rotationState(RotationState.ALL) .abilities(PartAbility.PASSTHROUGH_HATCH) + .modelProperty(IS_FORMED, false) .overlayTieredHullModel("fluid_passthrough_hatch") .tooltips( Component.translatable("gtceu.universal.tooltip.fluid_storage_capacity_mult", tier + 1, @@ -948,6 +974,7 @@ public class GTMachines { .tier(EV) .rotationState(RotationState.ALL) .abilities(PartAbility.IMPORT_FLUIDS) + .modelProperty(IS_FORMED, false) .tooltips( Component.translatable("gtceu.universal.tooltip.fluid_storage_capacity", FormattingUtil.formatNumbers(ReservoirHatchPartMachine.FLUID_AMOUNT)), @@ -962,6 +989,7 @@ public class GTMachines { .langValue("%s Dual Input Hatch".formatted(VNF[tier])) .rotationState(RotationState.ALL) .abilities(DUAL_INPUT_HATCH_ABILITIES) + .modelProperty(IS_FORMED, false) .overlayTieredHullModel("dual_input_hatch") .tooltips( Component.translatable("gtceu.machine.dual_hatch.import.tooltip"), @@ -984,6 +1012,7 @@ public class GTMachines { .langValue("%s Dual Output Hatch".formatted(VNF[tier])) .rotationState(RotationState.ALL) .abilities(DUAL_OUTPUT_HATCH_ABILITIES) + .modelProperty(IS_FORMED, false) .overlayTieredHullModel("dual_output_hatch") .tooltips( Component.translatable("gtceu.machine.dual_hatch.export.tooltip"), @@ -1005,7 +1034,8 @@ public class GTMachines { .langValue("%s Diode".formatted(VNF[tier])) .rotationState(RotationState.ALL) .abilities(PartAbility.PASSTHROUGH_HATCH) - .modelProperty(DiodePartMachine.AMP_MODE_PROPERTY, DiodePartMachine.AmpMode.MODE_1A) + .modelProperty(IS_FORMED, false) + .modelProperty(GTMachineModelProperties.DIODE_AMP_MODE, DiodePartMachine.AmpMode.MODE_1A) .model(createDiodeModel()) .tooltips(Component.translatable("gtceu.machine.diode.tooltip_general"), Component.translatable("gtceu.machine.diode.tooltip_starts_at"), @@ -1023,10 +1053,10 @@ public class GTMachines { .langValue("%s Rotor Holder".formatted(VNF[tier])) .rotationState(RotationState.ALL) .abilities(PartAbility.ROTOR_HOLDER) - .modelProperty(IMultiController.IS_FORMED_PROPERTY, false) - .modelProperty(RotorHolderPartMachine.HAS_ROTOR_PROPERTY, false) - .modelProperty(RotorHolderPartMachine.ROTOR_SPINNING_PROPERTY, false) - .modelProperty(RotorHolderPartMachine.EMISSIVE_ROTOR_PROPERTY, false) + .modelProperty(IS_FORMED, false) + .modelProperty(HAS_ROTOR, false) + .modelProperty(IS_ROTOR_SPINNING, false) + .modelProperty(IS_EMISSIVE_ROTOR, false) .model(createRotorHolderModel()) .tooltips(LangHandler.getMultiLang("gtceu.machine.rotor_holder.tooltip")) .tooltips(Component.translatable("gtceu.part_sharing.disabled")) @@ -1045,6 +1075,20 @@ public class GTMachines { PartAbility.INPUT_LASER); public static final MachineDefinition[] LASER_OUTPUT_HATCH_4096 = registerLaserHatch(OUT, 4096, PartAbility.OUTPUT_LASER); + public static final MachineDefinition MONITOR = REGISTRATE.machine("monitor", MonitorPartMachine::new) + .rotationState(RotationState.ALL) + .model(createOverlayCasingMachineModel(GTCEu.id("block/casings/solid/machine_casing_frost_proof"), + GTCEu.id("block/machine/part/computer_monitor"))) + .tier(MV) + .register(); + public static final MachineDefinition ADVANCED_MONITOR = REGISTRATE + .machine("advanced_monitor", AdvancedMonitorPartMachine::new) + .rotationState(RotationState.ALL) + .model(createOverlayCasingMachineModel(GTCEu.id("block/casings/solid/machine_casing_clean_stainless_steel"), + GTCEu.id("block/machine/part/computer_monitor"))) + .tier(HV) + .allowExtendedFacing(true) + .register(); public static void init() { GTMultiMachines.init(); diff --git a/src/main/java/com/gregtechceu/gtceu/data/machine/GTMultiMachines.java b/src/main/java/com/gregtechceu/gtceu/data/machine/GTMultiMachines.java index 554800e667f..e6e9d479e37 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/machine/GTMultiMachines.java +++ b/src/main/java/com/gregtechceu/gtceu/data/machine/GTMultiMachines.java @@ -11,6 +11,7 @@ import com.gregtechceu.gtceu.api.machine.multiblock.CoilWorkableElectricMultiblockMachine; import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.multiblock.FactoryBlockPattern; import com.gregtechceu.gtceu.api.multiblock.MultiblockShapeInfo; @@ -21,6 +22,7 @@ import com.gregtechceu.gtceu.client.util.TooltipHelper; import com.gregtechceu.gtceu.common.block.BoilerFireboxType; import com.gregtechceu.gtceu.common.machine.multiblock.electric.*; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.BedrockOreMinerMachine; import com.gregtechceu.gtceu.common.machine.multiblock.primitive.CharcoalPileIgniterMachine; import com.gregtechceu.gtceu.common.machine.multiblock.primitive.CokeOvenMachine; import com.gregtechceu.gtceu.common.machine.multiblock.primitive.PrimitiveBlastFurnaceMachine; @@ -123,10 +125,12 @@ public class GTMultiMachines { .appearanceBlock(CASING_PRIMITIVE_BRICKS) .pattern(definition -> FactoryBlockPattern.start() .aisle("XXX", "XXX", "XXX", "XXX") - .aisle("XXX", "X#X", "X#X", "X#X") + .aisle("XXX", "X&X", "X#X", "X#X") .aisle("XXX", "XYX", "XXX", "XXX") .where('X', blocks(CASING_PRIMITIVE_BRICKS.get())) .where('#', Predicates.air()) + .where('&', Predicates.air() + .or(Predicates.custom(bws -> GTUtil.isBlockSnow(bws.getBlockState()), null))) .where('Y', Predicates.controller(blocks(definition.getBlock()))) .build()) .register(); @@ -577,11 +581,11 @@ public class GTMultiMachines { .where('F', Predicates.frames(GTMaterials.TreatedWood)) .where('H', Predicates.abilities(PartAbility.PUMP_FLUID_HATCH) - .or(blocks(FLUID_EXPORT_HATCH[LV].get(), FLUID_EXPORT_HATCH[MV].get()))) + .or(blocks(FLUID_EXPORT_HATCH[ULV].get(), FLUID_EXPORT_HATCH[LV].get()))) .where('#', Predicates.any()) .build()) .allowExtendedFacing(false) - .modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE) + .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE) .model(createSidedWorkableCasingMachineModel(GTCEu.id("block/casings/pump_deck"), GTCEu.id("block/multiblock/primitive_pump")) .andThen(builder -> { @@ -638,7 +642,7 @@ public class GTMultiMachines { .where('F', blocks(FIREBOX_BRONZE.get()) .or(Predicates.abilities(PartAbility.STEAM).setExactLimit(1))) .build()) - .modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE) + .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE) .model(createWorkableCasingMachineModel(GTCEu.id("block/casings/solid/machine_casing_bronze_plated_bricks"), GTCEu.id("block/multiblock/steam_oven")) .andThen(b -> b.addDynamicRenderer( @@ -732,7 +736,7 @@ public class GTMultiMachines { shapeInfos.add(baseBuilder.build()); return shapeInfos; }) - .modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE) + .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE) .model(createWorkableCasingMachineModel(FusionReactorMachine.getCasingType(tier).getTexture(), GTCEu.id("block/multiblock/fusion_reactor")) .andThen(b -> b.addDynamicRenderer(DynamicRenderHelper::createFusionRingRender))) @@ -795,14 +799,14 @@ public class GTMultiMachines { .where('#', any()) .build()) .allowExtendedFacing(true) - .modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE) + .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE) .model(createWorkableCasingMachineModel( MATERIALS_TO_CASING_TEXTURES.get(LargeMinerMachine.getMaterial(tier)), GTCEu.id("block/multiblock/large_miner")) .andThen((ctx, prov, modelBuilder) -> { // replace the parent model for the formed large miner modelBuilder.replaceForAllStates((state, models) -> { - if (!state.getValue(LargeMinerMachine.IS_FORMED_PROPERTY)) { + if (!state.getValue(GTMachineModelProperties.IS_FORMED)) { return models; } @@ -1052,6 +1056,10 @@ public class GTMultiMachines { .rotationState(RotationState.NONE) .recipeType(DUMMY_RECIPES) .appearanceBlock(BRONZE_HULL) + .tooltips(Component.translatable("gtceu.machine.charcoal_pile.tooltip.0"), + Component.translatable("gtceu.machine.charcoal_pile.tooltip.1"), + Component.translatable("gtceu.machine.charcoal_pile.tooltip.2"), + Component.translatable("gtceu.machine.charcoal_pile.tooltip.3")) .pattern((def) -> FactoryBlockPattern.start() .aisle(" ", " XXX ", " XXX ", " XXX ", " ") .aisle(" BBB ", "XCCCX", "XCCCX", "XCCCX", " DDD ") @@ -1116,6 +1124,17 @@ public class GTMultiMachines { new PropertyFluidFilter(340, false, false, false, false), (builder, overlay) -> builder.sidedWorkableCasingModel(GTCEu.id("block/casings/wood_wall"), overlay)); + public static final MachineDefinition BRONZE_TANK_VALVE = GTMachineUtils.registerTankValve( + "bronze_tank_valve", "Bronze Tank Valve", true, + (builder, overlay) -> builder + .workableCasingModel(GTCEu.id("block/casings/solid/machine_casing_bronze_plated_bricks"), overlay)); + public static final MultiblockMachineDefinition BRONZE_MULTIBLOCK_TANK = registerMultiblockTank( + "bronze_multiblock_tank", "Bronze Multiblock Tank", 500 * 1000, + CASING_BRONZE_BRICKS, BRONZE_TANK_VALVE::getBlock, + new PropertyFluidFilter(1696, true, false, false, false), + (builder, overlay) -> builder + .workableCasingModel(GTCEu.id("block/casings/solid/machine_casing_bronze_plated_bricks"), overlay)); + public static final MachineDefinition STEEL_TANK_VALVE = GTMachineUtils.registerTankValve( "steel_tank_valve", "Steel Tank Valve", true, (builder, overlay) -> builder.workableCasingModel( @@ -1127,5 +1146,23 @@ public class GTMultiMachines { (builder, overlay) -> builder.workableCasingModel( GTCEu.id("block/casings/solid/machine_casing_solid_steel"), overlay)); + public static final MultiblockMachineDefinition CENTRAL_MONITOR = REGISTRATE + .multiblock("central_monitor", CentralMonitorMachine::new) + .rotationState(RotationState.ALL) + .recipeType(DUMMY_RECIPES) + .appearanceBlock(CASING_ALUMINIUM_FROSTPROOF) + .pattern((definition) -> FactoryBlockPattern.start() + .aisle("BCB", "BBB", "BBB", "BBB") + .where('C', Predicates.controller(Predicates.blocks(definition.get()))) + .where('B', CentralMonitorMachine.getMultiPredicate()) + .build()) + .modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE) + .model(createWorkableCasingMachineModel( + GTCEu.id("block/casings/solid/machine_casing_frost_proof"), + GTCEu.id("block/multiblock/central_monitor")) + .andThen(b -> b.addDynamicRenderer(DynamicRenderHelper::createCentralMonitorRender))) + .hasBER(true) + .register(); + public static void init() {} } diff --git a/src/main/java/com/gregtechceu/gtceu/data/machine/GTResearchMachines.java b/src/main/java/com/gregtechceu/gtceu/data/machine/GTResearchMachines.java index 012754e41b8..213fff524bf 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/machine/GTResearchMachines.java +++ b/src/main/java/com/gregtechceu/gtceu/data/machine/GTResearchMachines.java @@ -2,14 +2,13 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; -import com.gregtechceu.gtceu.api.capability.IHPCAComponentHatch; -import com.gregtechceu.gtceu.api.capability.IWorkable; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.MultiblockMachineDefinition; import com.gregtechceu.gtceu.api.machine.RotationState; import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.multiblock.FactoryBlockPattern; import com.gregtechceu.gtceu.api.multiblock.MultiblockShapeInfo; @@ -46,6 +45,7 @@ import javax.annotation.ParametersAreNonnullByDefault; import static com.gregtechceu.gtceu.api.GTValues.*; +import static com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties.IS_FORMED; import static com.gregtechceu.gtceu.api.multiblock.Predicates.*; import static com.gregtechceu.gtceu.common.registry.GTRegistration.REGISTRATE; import static com.gregtechceu.gtceu.data.block.GTBlocks.*; @@ -114,7 +114,8 @@ public class GTResearchMachines { .tier(ZPM) .rotationState(RotationState.ALL) .abilities(PartAbility.OBJECT_HOLDER) - .modelProperty(RecipeLogic.STATUS_PROPERTY, RecipeLogic.Status.IDLE) + .modelProperty(IS_FORMED, false) + .modelProperty(GTMachineModelProperties.RECIPE_LOGIC_STATUS, RecipeLogic.Status.IDLE) .model(createWorkableTieredHullMachineModel(GTCEu.id("block/machines/object_holder")) .andThen((ctx, prov, model) -> { model.addReplaceableTextures("bottom", "top", "side"); @@ -324,6 +325,18 @@ public class GTResearchMachines { .tooltips(Component.translatable("gtceu.part_sharing.disabled")) .register(); + public static final MachineDefinition BASIC_DATA_ACCESS_HATCH = REGISTRATE + .machine("basic_data_access_hatch", (holder) -> new DataAccessHatchMachine(holder, HV, false)) + .langValue("Basic Data Access Hatch") + .tier(HV) + .rotationState(RotationState.ALL) + .abilities(PartAbility.DATA_ACCESS) + .tooltips(Component.translatable("gtceu.machine.data_access_hatch.tooltip.0"), + Component.translatable("gtceu.machine.data_access_hatch.tooltip.1", 4), + Component.translatable("gtceu.part_sharing.disabled")) + .overlayTieredHullModel("data_access_hatch") + .register(); + public static final MachineDefinition DATA_ACCESS_HATCH = REGISTRATE .machine("data_access_hatch", (holder) -> new DataAccessHatchMachine(holder, EV, false)) .langValue("Data Access Hatch") @@ -354,6 +367,7 @@ public class GTResearchMachines { .tier(MAX) .rotationState(RotationState.ALL) .abilities(PartAbility.DATA_ACCESS) + .modelProperty(IS_FORMED, false) .tooltipBuilder((s, list) -> { list.add(Component.translatable("gtceu.machine.data_access_hatch.tooltip.0")); CREATIVE_TOOLTIPS.accept(s, list); @@ -441,8 +455,9 @@ private static MachineBuilder registerHPCAPart(String name, S .langValue(displayName) .rotationState(RotationState.ALL) .abilities(PartAbility.HPCA_COMPONENT) - .modelProperty(IHPCAComponentHatch.HPCA_PART_DAMAGED_PROPERTY, false) - .modelProperty(IWorkable.ACTIVE_PROPERTY, false) + .modelProperty(GTMachineModelProperties.IS_FORMED, false) + .modelProperty(GTMachineModelProperties.IS_HPCA_PART_DAMAGED, false) + .modelProperty(GTMachineModelProperties.IS_ACTIVE, false) .model(createHPCAPartModel(isAdvanced, GTCEu.id("block/overlay/machine/hpca/" + texture), GTCEu.id("block/overlay/machine/hpca/damaged" + (isAdvanced ? "_advanced" : "")))); diff --git a/src/main/java/com/gregtechceu/gtceu/data/material/ElementMaterials.java b/src/main/java/com/gregtechceu/gtceu/data/material/ElementMaterials.java index 36f895db4f4..bee030ba0a4 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/material/ElementMaterials.java +++ b/src/main/java/com/gregtechceu/gtceu/data/material/ElementMaterials.java @@ -256,8 +256,8 @@ public static void register() { .ingot() .liquid(new FluidBuilder().temperature(1099)) .color(0x20FFFF).secondaryColor(0x429393).iconSet(METALLIC) - .appendFlags(STD_METAL, GENERATE_LONG_ROD, GENERATE_FINE_WIRE, GENERATE_SPRING, GENERATE_FOIL, - GENERATE_FRAME) + .appendFlags(STD_METAL, GENERATE_LONG_ROD, GENERATE_FINE_WIRE, GENERATE_SPRING, GENERATE_SPRING_SMALL, + GENERATE_FOIL, GENERATE_FRAME) .element(GTElements.Eu) .cableProperties(V[UHV], 2, 32) .fluidPipeProperties(7750, 300, true) diff --git a/src/main/java/com/gregtechceu/gtceu/data/material/FirstDegreeMaterials.java b/src/main/java/com/gregtechceu/gtceu/data/material/FirstDegreeMaterials.java index 38cb9e325a3..af9e5d04dc6 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/material/FirstDegreeMaterials.java +++ b/src/main/java/com/gregtechceu/gtceu/data/material/FirstDegreeMaterials.java @@ -77,7 +77,7 @@ public static void register() { .gem(3).ore(2, 1) .color(0xdbfeff).secondaryColor(0xa0c4d7).iconSet(GEM_HORIZONTAL) .appendFlags(EXT_METAL, NO_SMASHING, NO_SMELTING, HIGH_SIFTER_OUTPUT) - .components(Aluminium, 2, Silicon, 1, Fluorine, 2, Hydrogen, 2, Oxygen, 6) + .components(Aluminium, 2, Silicon, 1, Oxygen, 4, Fluorine, 2) .buildAndRegister(); Bone = new Material.Builder(GTCEu.id("bone")) @@ -650,7 +650,7 @@ public static void register() { Tetrahedrite = new Material.Builder(GTCEu.id("tetrahedrite")) .dust().ore() .color(0xa3a09b).secondaryColor(0x143313) - .components(Copper, 3, Antimony, 1, Sulfur, 3, Iron, 1) + .components(Copper, 2, Iron, 1, Antimony, 1, Sulfur, 3) .buildAndRegister(); TinAlloy = new Material.Builder(GTCEu.id("tin_alloy")) @@ -666,7 +666,7 @@ public static void register() { .gem(3).ore() .color(0xe8d73a).secondaryColor(0xf4680f).iconSet(GEM_HORIZONTAL) .appendFlags(EXT_METAL, NO_SMASHING, NO_SMELTING, HIGH_SIFTER_OUTPUT) - .components(Aluminium, 2, Silicon, 1, Fluorine, 1, Hydrogen, 2) + .components(Aluminium, 2, Silicon, 1, Oxygen, 5, Fluorine, 1, Hydrogen, 1) .buildAndRegister(); Tungstate = new Material.Builder(GTCEu.id("tungstate")) @@ -1055,7 +1055,7 @@ public static void register() { GlauconiteSand = new Material.Builder(GTCEu.id("glauconite_sand")) .dust().ore(3, 1) .color(0x1da351).secondaryColor(0x1a6e8f).iconSet(SAND) - .components(Potassium, 1, Magnesium, 2, Aluminium, 4, Hydrogen, 2, Oxygen, 12) + .components(Potassium, 1, Magnesium, 2, Aluminium, 2, Silicon, 3, Oxygen, 12, Hydrogen, 2, Water, 1) .buildAndRegister(); Malachite = new Material.Builder(GTCEu.id("malachite")) @@ -1079,7 +1079,7 @@ public static void register() { Alunite = new Material.Builder(GTCEu.id("alunite")) .dust().ore(3, 1) .color(0xfbd677).secondaryColor(0xe11e0a).iconSet(METALLIC) - .components(Potassium, 1, Aluminium, 3, Silicon, 2, Hydrogen, 6, Oxygen, 14) + .components(Potassium, 1, Aluminium, 2, Silicon, 2, Hydrogen, 6, Oxygen, 14) .buildAndRegister(); Talc = new Material.Builder(GTCEu.id("talc")) @@ -1272,7 +1272,7 @@ public static void register() { PotassiumFeldspar = new Material.Builder(GTCEu.id("potassium_feldspar")) .dust(1) .color(0xffe3bc).secondaryColor(0xd4918a).iconSet(FINE) - .components(Potassium, 1, Aluminium, 1, Silicon, 1, Oxygen, 8) + .components(Potassium, 1, Aluminium, 1, Silicon, 3, Oxygen, 8) .buildAndRegister(); NeodymiumMagnetic = new Material.Builder(GTCEu.id("magnetic_neodymium")) @@ -1545,7 +1545,7 @@ public static void register() { Pyrochlore = new Material.Builder(GTCEu.id("pyrochlore")) .dust().ore() .color(0x5b4838).secondaryColor(0x331400).iconSet(METALLIC) - .components(Calcium, 2, Niobium, 2, Oxygen, 7) + .components(Calcium, 2, Niobium, 2, Oxygen, 6, Fluorine, 1) .buildAndRegister(); PotassiumHydroxide = new Material.Builder(GTCEu.id("potassium_hydroxide")) @@ -1592,7 +1592,7 @@ public static void register() { CalciumCarbonate = new Material.Builder(GTCEu.id("calcium_carbonate")) .dust() .color(0xd9ca9c).secondaryColor(0xad913b) - .components(Calcium, 2, Carbon, 1, Oxygen, 3) + .components(Calcium, 1, Carbon, 1, Oxygen, 3) .buildAndRegister(); PotassiumCyanide = new Material.Builder(GTCEu.id("potassium_cyanide")) @@ -1610,7 +1610,7 @@ public static void register() { .buildAndRegister(); FormicAcid = new Material.Builder(GTCEu.id("formic_acid")) - .gas() + .liquid(new FluidBuilder().attribute(FluidAttributes.ACID)) .color(0xa6a6a6) .components(Carbon, 1, Hydrogen, 2, Oxygen, 2) .hazard(HazardProperty.HazardTrigger.INHALATION, GTMedicalConditions.CHEMICAL_BURNS) diff --git a/src/main/java/com/gregtechceu/gtceu/data/material/GTMaterials.java b/src/main/java/com/gregtechceu/gtceu/data/material/GTMaterials.java index d5ece80dca1..83e3a451518 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/material/GTMaterials.java +++ b/src/main/java/com/gregtechceu/gtceu/data/material/GTMaterials.java @@ -185,7 +185,7 @@ public static void init() { for (TagPrefix prefix : ORES.keySet()) { TagPrefix.OreType oreType = ORES.get(prefix); - if (oreType.shouldDropAsItem() && oreType.material() != null) { + if (oreType.material() != null) { prefix.addSecondaryMaterial(new MaterialStack(oreType.material().get(), dust.materialAmount())); } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/material/HigherDegreeMaterials.java b/src/main/java/com/gregtechceu/gtceu/data/material/HigherDegreeMaterials.java index 46839a0def3..5539044b56a 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/material/HigherDegreeMaterials.java +++ b/src/main/java/com/gregtechceu/gtceu/data/material/HigherDegreeMaterials.java @@ -102,7 +102,8 @@ public static void register() { .ingot(0) .liquid(new FluidBuilder().temperature(1400)) .color(0xc55252).secondaryColor(0xC80000).iconSet(METALLIC) - .appendFlags(STD_METAL, GENERATE_FINE_WIRE, GENERATE_BOLT_SCREW, DISABLE_DECOMPOSITION) + .appendFlags(STD_METAL, GENERATE_FINE_WIRE, GENERATE_BOLT_SCREW, GENERATE_SPRING_SMALL, + DISABLE_DECOMPOSITION) .components(Copper, 1, Redstone, 4) .cableProperties(GTValues.V[0], 1, 0) .buildAndRegister(); diff --git a/src/main/java/com/gregtechceu/gtceu/data/material/SecondDegreeMaterials.java b/src/main/java/com/gregtechceu/gtceu/data/material/SecondDegreeMaterials.java index 9dc30c7366b..9183176de09 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/material/SecondDegreeMaterials.java +++ b/src/main/java/com/gregtechceu/gtceu/data/material/SecondDegreeMaterials.java @@ -61,7 +61,7 @@ public static void register() { .gem().ore(2, 1) .color(0xa7e404).secondaryColor(0x166439).iconSet(RUBY) .appendFlags(EXT_METAL, NO_SMASHING, NO_SMELTING, HIGH_SIFTER_OUTPUT) - .components(Magnesium, 2, Iron, 1, SiliconDioxide, 2) + .components(Magnesium, 1, Iron, 1, SiliconDioxide, 2) .buildAndRegister(); Opal = new Material.Builder(GTCEu.id("opal")) @@ -228,13 +228,13 @@ public static void register() { .dust().ore(3, 1) .color(0xede8a3).secondaryColor(0xcdb44c).iconSet(ROUGH) .flags(DISABLE_DECOMPOSITION) - .components(Sodium, 1, Magnesium, 6, Silicon, 12, Hydrogen, 4, Water, 5, Oxygen, 36) + .components(Sodium, 1, Magnesium, 6, Silicon, 12, Hydrogen, 6, Water, 5, Oxygen, 36) .buildAndRegister(); FullersEarth = new Material.Builder(GTCEu.id("fullers_earth")) .dust().ore(2, 1) .color(0xf3efbb).secondaryColor(0xb8d066).iconSet(FINE) - .components(Magnesium, 1, Silicon, 4, Hydrogen, 1, Water, 4, Oxygen, 11) + .components(Magnesium, 2, Silicon, 4, Oxygen, 14, Hydrogen, 4, Water, 1) .buildAndRegister(); Pitchblende = new Material.Builder(GTCEu.id("pitchblende")) @@ -274,8 +274,7 @@ public static void register() { Zeolite = new Material.Builder(GTCEu.id("zeolite")) .dust().ore(3, 1) .color(0xf2e3e0).secondaryColor(0xeabeb4) - .flags(DISABLE_DECOMPOSITION) - .components(Sodium, 1, Calcium, 4, Silicon, 27, Aluminium, 9, Water, 28, Oxygen, 72) + .components(Sodium, 2, Aluminium, 2, Silicon, 3, Oxygen, 10, Water, 2) .buildAndRegister(); Concrete = new Material.Builder(GTCEu.id("concrete")) diff --git a/src/main/java/com/gregtechceu/gtceu/data/material/UnknownCompositionMaterials.java b/src/main/java/com/gregtechceu/gtceu/data/material/UnknownCompositionMaterials.java index 4fb86fcca4a..a2f785f7c9f 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/material/UnknownCompositionMaterials.java +++ b/src/main/java/com/gregtechceu/gtceu/data/material/UnknownCompositionMaterials.java @@ -48,7 +48,7 @@ public static void register() { .buildAndRegister(); Creosote = new Material.Builder(GTCEu.id("creosote")) - .liquid(new FluidBuilder().customStill().burnTime(6400)).color(0x804000) + .liquid(new FluidBuilder().block().customStill().burnTime(6400)).color(0x804000) .flags(STICKY).buildAndRegister(); Diesel = new Material.Builder(GTCEu.id("diesel")) @@ -333,7 +333,7 @@ public static void register() { .dust(0) .color(0xa4a4a4).secondaryColor(0x767676).iconSet(ROUGH) .flags(FLAMMABLE, EXPLOSIVE, NO_SMELTING, NO_SMASHING) - .components(Saltpeter, 2, Sulfur, 1, Coal, 3) + .components(Saltpeter, 2, Sulfur, 1, Carbon, 3) .buildAndRegister(); Oilsands = new Material.Builder(GTCEu.id("oilsands")) @@ -443,7 +443,7 @@ public static void register() { Paper = new Material.Builder(GTCEu.id("paper")) .dust(0) - .color(0xFAFAFA).secondaryColor(0x878787).iconSet(FINE) + .color(0xF9F9F9).secondaryColor(0xECECEC).iconSet(DULL) .flags(GENERATE_PLATE, FLAMMABLE, NO_SMELTING, NO_SMASHING, MORTAR_GRINDABLE, EXCLUDE_PLATE_COMPRESSOR_RECIPE) .buildAndRegister(); diff --git a/src/main/java/com/gregtechceu/gtceu/data/misc/GTDimensionMarkers.java b/src/main/java/com/gregtechceu/gtceu/data/misc/GTDimensionMarkers.java index 02ed366fce1..6c23ecc7f2c 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/misc/GTDimensionMarkers.java +++ b/src/main/java/com/gregtechceu/gtceu/data/misc/GTDimensionMarkers.java @@ -20,7 +20,7 @@ public class GTDimensionMarkers { static { - REGISTRATE.creativeModeTab(null); + REGISTRATE.resetCreativeModeTab(); } public static final BlockEntry OVERWORLD_MARKER = createMarker("overworld"); diff --git a/src/main/java/com/gregtechceu/gtceu/data/model/GTMachineModels.java b/src/main/java/com/gregtechceu/gtceu/data/model/GTMachineModels.java index 89f728bfdf3..a8498fe5952 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/model/GTMachineModels.java +++ b/src/main/java/com/gregtechceu/gtceu/data/model/GTMachineModels.java @@ -3,13 +3,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.block.IMachineBlock; -import com.gregtechceu.gtceu.api.blockentity.IPaintable; -import com.gregtechceu.gtceu.api.capability.IHPCAComponentHatch; -import com.gregtechceu.gtceu.api.capability.IWorkable; import com.gregtechceu.gtceu.api.machine.MachineDefinition; -import com.gregtechceu.gtceu.api.machine.feature.IExhaustVentMachine; -import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMaintenanceMachine; -import com.gregtechceu.gtceu.api.machine.steam.SteamMachine; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.material.material.Material; import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; @@ -20,11 +14,7 @@ import com.gregtechceu.gtceu.client.model.machine.overlays.HPCAOverlay; import com.gregtechceu.gtceu.client.model.machine.overlays.WorkableOverlays; import com.gregtechceu.gtceu.common.machine.electric.ChargerMachine; -import com.gregtechceu.gtceu.common.machine.electric.ConverterMachine; -import com.gregtechceu.gtceu.common.machine.electric.TransformerMachine; -import com.gregtechceu.gtceu.common.machine.electric.WorldAcceleratorMachine; import com.gregtechceu.gtceu.common.machine.multiblock.part.DiodePartMachine; -import com.gregtechceu.gtceu.common.machine.storage.CrateMachine; import com.gregtechceu.gtceu.data.datagen.model.builder.MachineModelBuilder; import com.gregtechceu.gtceu.data.material.GTMaterials; @@ -44,8 +34,7 @@ import java.util.Locale; -import static com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController.IS_FORMED_PROPERTY; -import static com.gregtechceu.gtceu.api.machine.feature.multiblock.IRotorHolderMachine.*; +import static com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties.*; import static com.gregtechceu.gtceu.client.model.machine.overlays.EnergyIOOverlay.*; import static com.gregtechceu.gtceu.data.model.GTModels.*; @@ -114,6 +103,18 @@ public static MachineBuilder.ModelInitializer createOverlayTieredHullMachineMode }; } + public static MachineBuilder.ModelInitializer createOverlayCasingMachineModel(ResourceLocation baseCasingTexture, + ResourceLocation overlayModel) { + return (ctx, prov, builder) -> { + BlockModelBuilder model = prov.models().nested() + .parent(prov.models().getExistingFile(overlayModel)); + model.texture("all", baseCasingTexture); + + builder.forAllStatesModels(state -> model); + builder.addReplaceableTextures("all"); + }; + } + public static MachineBuilder.ModelInitializer createColorOverlayTieredHullMachineModel(ResourceLocation overlay, @Nullable ResourceLocation pipeOverlay, @Nullable ResourceLocation emissiveOverlay) { @@ -147,7 +148,7 @@ public static MachineBuilder.ModelInitializer createWorkableTieredHullMachineMod WorkableOverlays overlays = WorkableOverlays.get(overlayDir, prov.getExistingFileHelper()); builder.forAllStates(state -> { - RecipeLogic.Status status = state.getValue(RecipeLogic.STATUS_PROPERTY); + RecipeLogic.Status status = state.getValue(RECIPE_LOGIC_STATUS); BlockModelBuilder model = prov.models().nested().parent(tieredHullModel(prov.models(), builder)); return addWorkableOverlays(overlays, status, model); @@ -158,7 +159,7 @@ public static MachineBuilder.ModelInitializer createWorkableTieredHullMachineMod public static MachineBuilder.ModelInitializer createOverlaySteamHullMachineModel(ResourceLocation overlayModel) { return (ctx, prov, builder) -> { builder.forAllStatesModels(state -> { - boolean steel = state.getOptionalValue(SteamMachine.STEEL_PROPERTY).orElse(false); + boolean steel = state.getOptionalValue(IS_STEEL_MACHINE).orElse(false); BlockModelBuilder model = prov.models().nested() .parent(prov.models().getExistingFile(overlayModel)); @@ -177,7 +178,7 @@ public static MachineBuilder.ModelInitializer createColorOverlaySteamHullMachine builder.forAllStatesModels(state -> { BlockModelBuilder model = colorOverlayHullModel(overlay, pipeOverlay, emissiveOverlay, state, prov.models()); - steamCasingTextures(model, state.getOptionalValue(SteamMachine.STEEL_PROPERTY).orElse(false)); + steamCasingTextures(model, state.getOptionalValue(IS_STEEL_MACHINE).orElse(false)); return model; }); @@ -198,7 +199,7 @@ public static MachineBuilder.ModelInitializer createWorkableSteamHullMachineMode makeWorkableOverlayPart(prov.models(), builder, parent, overlays, RecipeLogic.Status.WAITING); makeWorkableOverlayPart(prov.models(), builder, parent, overlays, RecipeLogic.Status.SUSPEND); - if (!builder.getOwner().defaultRenderState().hasProperty(IExhaustVentMachine.VENT_DIRECTION_PROPERTY)) { + if (!builder.getOwner().defaultRenderState().hasProperty(VENT_DIRECTION)) { return; } @@ -208,7 +209,7 @@ public static MachineBuilder.ModelInitializer createWorkableSteamHullMachineMode .rotationX(dir == Direction.DOWN ? 90 : dir == Direction.UP ? 270 : 0) .rotationY(dir.getAxis().isVertical() ? 0 : ((int) dir.toYRot() + 180) % 360) .addModel() - .condition(IExhaustVentMachine.VENT_DIRECTION_PROPERTY, relative); + .condition(VENT_DIRECTION, relative); } }; } @@ -219,7 +220,7 @@ private static void makeWorkableOverlayPart(BlockModelProvider models, WorkableOverlays overlays, RecipeLogic.Status status) { BlockModelBuilder model = models.nested().parent(parentModel); addWorkableOverlays(overlays, status, model); - builder.part(model).condition(RecipeLogic.STATUS_PROPERTY, status); + builder.part(model).condition(RECIPE_LOGIC_STATUS, status); } public static MachineBuilder.ModelInitializer createWorkableCasingMachineModel(ResourceLocation baseCasingTexture, @@ -228,7 +229,7 @@ public static MachineBuilder.ModelInitializer createWorkableCasingMachineModel(R WorkableOverlays overlays = WorkableOverlays.get(overlayDir, prov.getExistingFileHelper()); builder.forAllStates(state -> { - RecipeLogic.Status status = state.getValue(RecipeLogic.STATUS_PROPERTY); + RecipeLogic.Status status = state.getValue(RECIPE_LOGIC_STATUS); BlockModelBuilder model = prov.models().nested() .parent(prov.models().getExistingFile(CUBE_ALL_SIDED_OVERLAY_MODEL)) @@ -258,7 +259,7 @@ public static MachineBuilder.ModelInitializer createSidedWorkableCasingMachineMo WorkableOverlays overlays = WorkableOverlays.get(overlayDir, prov.getExistingFileHelper()); builder.forAllStates(state -> { - RecipeLogic.Status status = state.getValue(RecipeLogic.STATUS_PROPERTY); + RecipeLogic.Status status = state.getValue(RECIPE_LOGIC_STATUS); BlockModelBuilder model = prov.models().nested() .parent(prov.models().getExistingFile(SIDED_SIDED_OVERLAY_MODEL)); @@ -280,11 +281,20 @@ public static MachineBuilder.ModelInitializer createSidedWorkableCasingMachineMo // region per-machine models - // spotless:off + public static final String OVERLAY_FLUID_HATCH_INPUT = "overlay_fluid_hatch_input"; + public static final String OVERLAY_FLUID_HATCH_OUTPUT = "overlay_fluid_hatch_output"; + public static final String OVERLAY_ITEM_HATCH_INPUT = "overlay_item_hatch_input"; + public static final String OVERLAY_ITEM_HATCH_OUTPUT = "overlay_item_hatch_output"; + + // @deprecated use {@link com.gregtechceu.gtceu.common.data.models.GTMachineModels.OVERLAY_FLUID_HATCH_INPUT} or {@link com.gregtechceu.gtceu.common.data.models.GTMachineModels.OVERLAY_FLUID_HATCH_OUTPUT} instead. + @Deprecated public static final String OVERLAY_FLUID_HATCH_TEX = "overlay_fluid_hatch"; + // @deprecated use {@link com.gregtechceu.gtceu.common.data.models.GTMachineModels.OVERLAY_FLUID_HATCH_INPUT} or {@link com.gregtechceu.gtceu.common.data.models.GTMachineModels.OVERLAY_FLUID_HATCH_OUTPUT} instead. + @Deprecated public static final String OVERLAY_FLUID_HATCH_HALF_PX_TEX = "overlay_fluid_hatch_half_px_out"; + // @deprecated use {@link com.gregtechceu.gtceu.common.data.models.GTMachineModels.OVERLAY_ITEM_HATCH_INPUT} or {@link com.gregtechceu.gtceu.common.data.models.GTMachineModels.OVERLAY_ITEM_HATCH_OUTPUT} instead. + @Deprecated public static final String OVERLAY_ITEM_HATCH = "overlay_item_hatch"; - // spotless:on public static final ResourceLocation GENERATOR_MODEL = GTCEu.id("block/machine/template/generator_machine"); @@ -293,7 +303,7 @@ public static MachineBuilder.ModelInitializer createSimpleGeneratorModel(Resourc WorkableOverlays overlays = WorkableOverlays.get(overlayDir, prov.getExistingFileHelper()); builder.forAllStatesModels(state -> { - RecipeLogic.Status status = state.getValue(RecipeLogic.STATUS_PROPERTY); + RecipeLogic.Status status = state.getValue(RECIPE_LOGIC_STATUS); BlockModelBuilder model = prov.models().nested().parent(prov.models().getExistingFile(GENERATOR_MODEL)); tieredHullTextures(model, builder.getOwner().getTier()); @@ -329,7 +339,7 @@ public static MachineBuilder.ModelInitializer createBatteryBufferModel(int inven public static MachineBuilder.ModelInitializer createChargerModel() { return (ctx, prov, builder) -> { builder.forAllStatesModels(renderState -> { - ChargerMachine.State state = renderState.getValue(ChargerMachine.STATE_PROPERTY); + ChargerMachine.State state = renderState.getValue(CHARGER_STATE); BlockModelBuilder model = prov.models().nested() .parent(prov.models().getExistingFile(SIDED_SIDED_OVERLAY_MODEL)); @@ -388,10 +398,10 @@ public static MachineBuilder.ModelInitializer createConverterModel(int amperage) tieredHullTextures(feToEuModel, builder.getOwner().getTier()); builder.partialState() - .with(ConverterMachine.FE_TO_EU_PROPERTY, false) + .with(IS_FE_TO_EU, false) .setModel(euToFeModel) .partialState() - .with(ConverterMachine.FE_TO_EU_PROPERTY, true) + .with(IS_FE_TO_EU, true) .setModel(feToEuModel) .end(); }; @@ -404,7 +414,7 @@ public static MachineBuilder.ModelInitializer createCrateModel(boolean wooden) { ModelFile tapedModel = prov.models().getExistingFile(GTCEu.id(modelPath + "_taped")); builder.forAllStatesModels(state -> { - if (state.getOptionalValue(CrateMachine.TAPED_PROPERTY).orElse(false)) { + if (state.getOptionalValue(IS_TAPED).orElse(false)) { return tapedModel; } else { return baseModel; @@ -416,7 +426,7 @@ public static MachineBuilder.ModelInitializer createCrateModel(boolean wooden) { public static MachineBuilder.ModelInitializer createDiodeModel() { return (ctx, prov, builder) -> { builder.forAllStatesModels(renderState -> { - DiodePartMachine.AmpMode mode = renderState.getValue(DiodePartMachine.AMP_MODE_PROPERTY); + DiodePartMachine.AmpMode mode = renderState.getValue(DIODE_AMP_MODE); final EnergyIOOverlay energyIn = IN_OVERLAYS_FOR_AMP.get(mode.getAmpValue()); final EnergyIOOverlay energyOut = OUT_OVERLAYS_FOR_AMP.get(mode.getAmpValue()); @@ -439,7 +449,7 @@ public static MachineBuilder.ModelInitializer createDiodeModel() { public static MachineBuilder.ModelInitializer createTransformerModel(int baseAmp) { return (ctx, prov, builder) -> { builder.forAllStatesModels(renderState -> { - boolean transformUp = renderState.getValue(TransformerMachine.TRANSFORM_UP_PROPERTY); + boolean transformUp = renderState.getValue(IS_TRANSFORM_UP); EnergyIOOverlay frontFace = (transformUp ? OUT_OVERLAYS_FOR_AMP : IN_OVERLAYS_FOR_AMP) .get(baseAmp); EnergyIOOverlay otherFace = (transformUp ? IN_OVERLAYS_FOR_AMP : OUT_OVERLAYS_FOR_AMP) @@ -473,7 +483,7 @@ public static MachineBuilder.ModelInitializer createRotorHolderModel() { tieredHullTextures(blockModel, builder.getOwner().getTier()); builder.part(blockModel).end(); - builder.part(ROTOR_HOLDER_OVERLAY).condition(IS_FORMED_PROPERTY, true).end(); + builder.part(ROTOR_HOLDER_OVERLAY).condition(IS_FORMED, true).end(); makeRotorHolderState(builder, models, ROTOR_HOLDER_ROTOR_IDLE, false, false); makeRotorHolderState(builder, models, ROTOR_HOLDER_ROTOR_IDLE.withSuffix(EMISSIVE_SUFFIX), false, true); @@ -488,10 +498,10 @@ private static void makeRotorHolderState(MachineModelBuilder BlockModelProvider provider, ResourceLocation model, boolean spinning, boolean emissive) { builder.partialState() - .with(IS_FORMED_PROPERTY, true) - .with(HAS_ROTOR_PROPERTY, true) - .with(ROTOR_SPINNING_PROPERTY, spinning) - .with(EMISSIVE_ROTOR_PROPERTY, emissive) + .with(IS_FORMED, true) + .with(HAS_ROTOR, true) + .with(IS_ROTOR_SPINNING, spinning) + .with(IS_EMISSIVE_ROTOR, emissive) .setModel(provider.getExistingFile(model)); } @@ -517,11 +527,11 @@ public static MachineBuilder.ModelInitializer createWorldAcceleratorModel(Resour WorkableOverlays beOverlays = WorkableOverlays.get(beModeModelPath, prov.getExistingFileHelper()); builder.forAllStates(state -> { - boolean rtMode = state.getValue(WorldAcceleratorMachine.RANDOM_TICK_PROPERTY); + boolean rtMode = state.getValue(IS_RANDOM_TICK_MODE); WorkableOverlays overlays = rtMode ? rtOverlays : beOverlays; - boolean active = state.getValue(IWorkable.ACTIVE_PROPERTY); - boolean workingEnabled = state.getValue(WorldAcceleratorMachine.WORKING_ENABLED_PROPERTY); + boolean active = state.getValue(IS_ACTIVE); + boolean workingEnabled = state.getValue(IS_WORKING_ENABLED); RecipeLogic.Status status = active ? workingEnabled ? RecipeLogic.Status.WORKING : @@ -547,7 +557,7 @@ public static MachineBuilder.ModelInitializer createMaintenanceModel(ResourceLoc .parent(prov.models().getExistingFile(overlayModel)); tieredHullTextures(baseModel, builder.getOwner().getTier()); - if (state.getValue(IMaintenanceMachine.MAINTENANCE_TAPED_PROPERTY)) { + if (state.getValue(IS_TAPED)) { baseModel.texture("overlay_2", MAINTENANCE_TAPED_OVERLAY); } return baseModel; @@ -577,8 +587,8 @@ public static MachineBuilder.ModelInitializer createHPCAPartModel(boolean advanc casingTexture(baseModel, "side", textures); builder.forAllStatesModels(state -> { - boolean damaged = state.getValue(IHPCAComponentHatch.HPCA_PART_DAMAGED_PROPERTY); - boolean active = state.getValue(IWorkable.ACTIVE_PROPERTY); + boolean damaged = state.getValue(IS_HPCA_PART_DAMAGED); + boolean active = state.getValue(IS_ACTIVE); return prov.models().nested().parent(baseModel) .texture("overlay", overlay.getTexture(active, damaged)) @@ -607,8 +617,8 @@ public static MachineBuilder.ModelInitializer createItemCollectorModel(ResourceL WorkableOverlays overlays = WorkableOverlays.get(overlayDir, prov.getExistingFileHelper()); builder.forAllStates(state -> { - boolean active = state.getValue(IWorkable.ACTIVE_PROPERTY); - boolean workingEnabled = state.getValue(WorldAcceleratorMachine.WORKING_ENABLED_PROPERTY); + boolean active = state.getValue(IS_ACTIVE); + boolean workingEnabled = state.getValue(IS_WORKING_ENABLED); RecipeLogic.Status status = active ? workingEnabled ? RecipeLogic.Status.WORKING : @@ -678,7 +688,7 @@ public static BlockModelBuilder colorOverlayHullModel(ResourceLocation overlay, @Nullable ResourceLocation emissiveOverlay, MachineRenderState state, BlockModelProvider models) { ResourceLocation parent; - if (state.getOptionalValue(IPaintable.IS_PAINTED_PROPERTY).orElse(false)) { + if (state.getOptionalValue(IS_PAINTED).orElse(false)) { parent = emissiveOverlay != null ? HATCH_PART_EMISSIVE_COLOR_RING_MODEL : HATCH_PART_COLOR_RING_MODEL; } else { parent = emissiveOverlay != null ? HATCH_PART_EMISSIVE_MODEL : HATCH_PART_MODEL; diff --git a/src/main/java/com/gregtechceu/gtceu/data/placeholder/GTPlaceholders.java b/src/main/java/com/gregtechceu/gtceu/data/placeholder/GTPlaceholders.java new file mode 100644 index 00000000000..72f41e149b8 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/data/placeholder/GTPlaceholders.java @@ -0,0 +1,882 @@ +package com.gregtechceu.gtceu.data.placeholder; + +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; +import com.gregtechceu.gtceu.api.capability.IEnergyContainer; +import com.gregtechceu.gtceu.api.capability.IEnergyInfoProvider; +import com.gregtechceu.gtceu.api.capability.IWorkable; +import com.gregtechceu.gtceu.api.cover.filter.ItemFilter; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMaintenanceMachine; +import com.gregtechceu.gtceu.api.misc.virtualregistry.EntryTypes; +import com.gregtechceu.gtceu.api.misc.virtualregistry.VirtualEnderRegistry; +import com.gregtechceu.gtceu.api.placeholder.*; +import com.gregtechceu.gtceu.api.placeholder.exceptions.*; +import com.gregtechceu.gtceu.common.blockentity.CableBlockEntity; +import com.gregtechceu.gtceu.common.item.datacomponents.BindingData; +import com.gregtechceu.gtceu.common.item.datacomponents.DataItem; +import com.gregtechceu.gtceu.common.item.datacomponents.FormatStringList; +import com.gregtechceu.gtceu.common.machine.multiblock.part.monitor.AdvancedMonitorPartMachine; +import com.gregtechceu.gtceu.data.item.GTDataComponents; +import com.gregtechceu.gtceu.utils.GTStringUtils; +import com.gregtechceu.gtceu.utils.GTTransferUtils; + +import net.minecraft.ChatFormatting; +import net.minecraft.commands.CommandSource; +import net.minecraft.commands.CommandSourceStack; +import net.minecraft.core.Direction; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.phys.Vec2; +import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.capability.IFluidHandler; +import net.neoforged.neoforge.items.IItemHandler; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class GTPlaceholders { + + public static int countItems(String id, @Nullable IItemHandler itemHandler) { + if (itemHandler == null) return 0; + int cnt = 0; + for (int i = 0; i < itemHandler.getSlots(); i++) { + ItemStack itemStack = itemHandler.getStackInSlot(i); + String itemId = "%s:%s".formatted(itemStack.getItem().getCreatorModId(itemStack), + itemStack.getItem().toString()); + if (itemId.equals(id)) cnt += itemStack.getCount(); + } + return cnt; + } + + public static int countFluids(@Nullable String id, @Nullable IFluidHandler fluidHandler) { + if (fluidHandler == null) return 0; + int count = 0; + for (int i = 0; i < fluidHandler.getTanks(); i++) { + FluidStack fluidStack = fluidHandler.getFluidInTank(i); + String fluidId = Objects.requireNonNull(BuiltInRegistries.FLUID.getKey(fluidStack.getFluid())).toString(); + + if (id == null || fluidId.equals(id)) { + count += fluidStack.getAmount(); + } + } + return count; + } + + public static int countItems(@Nullable ItemFilter filter, @Nullable IItemHandler itemHandler) { + if (itemHandler == null) + return -1; + int cnt = 0; + for (int i = 0; i < itemHandler.getSlots(); i++) { + if (filter == null || filter.test(itemHandler.getStackInSlot(i))) + cnt += itemHandler.getStackInSlot(i).getCount(); + } + return cnt; + } + + public static void initPlaceholders() { + PlaceholderHandler.addPlaceholder(new Placeholder("energy") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 0); + if (ctx.level().getBlockEntity(ctx.pos()) instanceof IMachineBlockEntity machineBE) { + if (machineBE.getMetaMachine() instanceof IEnergyInfoProvider energyInfoProvider) { + return MultiLineComponent.literal(energyInfoProvider.getEnergyInfo().stored().longValue()); + } + } + IEnergyContainer energy = GTCapabilityHelper.getEnergyContainer(ctx.level(), ctx.pos(), ctx.side()); + return MultiLineComponent.literal(energy != null ? energy.getEnergyStored() : 0); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("energyCapacity") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 0); + if (ctx.level().getBlockEntity(ctx.pos()) instanceof IMachineBlockEntity machineBE) { + if (machineBE.getMetaMachine() instanceof IEnergyInfoProvider energyInfoProvider) { + return MultiLineComponent.literal(energyInfoProvider.getEnergyInfo().capacity().longValue()); + } + } + IEnergyContainer energy = GTCapabilityHelper.getEnergyContainer(ctx.level(), ctx.pos(), ctx.side()); + return MultiLineComponent.literal(energy != null ? energy.getEnergyCapacity() : 0); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("calc") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, List args) { + List stringArgs = new ArrayList<>(); + args.forEach((components) -> stringArgs.add(GTStringUtils.componentsToString(components))); + return MultiLineComponent.literal(GTStringUtils.calc(stringArgs)); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("itemCount") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + IItemHandler itemHandler = GTCapabilityHelper.getItemHandler(ctx.level(), ctx.pos(), ctx.side()); + if (args.isEmpty()) { + return MultiLineComponent.literal(countItems((ItemFilter) null, itemHandler)); + } + if (args.size() == 1) { + return MultiLineComponent.literal(countItems( + GTStringUtils.componentsToString(args.getFirst()), itemHandler)); + } + if (GTStringUtils.equals(args.getFirst(), "filter")) { + int slot = PlaceholderUtils.toInt(args.get(1)); + PlaceholderUtils.checkRange("slot index", 1, 8, slot); + try { + if (ctx.itemStackHandler() == null) { + throw new NotSupportedException(); + } + return MultiLineComponent.literal(countItems( + ItemFilter.loadFilter(ctx.itemStackHandler().getStackInSlot(slot - 1)), itemHandler)); + } catch (NullPointerException e) { + throw new MissingItemException("filter", slot); + } + } + throw new InvalidArgsException(); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("fluidCount") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + IFluidHandler fluidHandler = GTCapabilityHelper.getFluidHandler(ctx.level(), ctx.pos(), ctx.side()); + if (args.isEmpty()) return MultiLineComponent.literal(countFluids(null, fluidHandler)); + if (args.size() == 1) + return MultiLineComponent + .literal(countFluids(GTStringUtils.componentsToString(args.getFirst()), fluidHandler)); + PlaceholderUtils.checkArgs(args, 1); + return MultiLineComponent.empty(); // unreachable + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("if") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 2, true); + try { + if (GTStringUtils.toDouble(args.get(0)) != 0) { + return new MultiLineComponent(args.get(1)).setIgnoreSpaces(true); + } else if (args.size() > 2) { + return new MultiLineComponent(args.get(2)).setIgnoreSpaces(true); + } else return MultiLineComponent.empty(); + } catch (NumberFormatException e) { + return args.get(1); + } + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("color") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 2); + ChatFormatting color = ChatFormatting.getByName(GTStringUtils.componentsToString(args.getFirst())); + if (color == null) throw new InvalidArgsException(); + return new MultiLineComponent(args.get(1).stream().map(c -> c.withStyle(color)).toList()); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("underline") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + return new MultiLineComponent( + args.getFirst().stream().map(c -> c.withStyle(ChatFormatting.UNDERLINE)).toList()); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("strike") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + return new MultiLineComponent( + args.getFirst().stream().map(c -> c.withStyle(ChatFormatting.STRIKETHROUGH)).toList()); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("obf") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + return new MultiLineComponent( + args.getFirst().stream().map(c -> c.withStyle(ChatFormatting.OBFUSCATED)).toList()); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("random") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 2); + return MultiLineComponent.literal(GTValues.RNG.nextIntBetweenInclusive( + PlaceholderUtils.toInt(args.getFirst()), PlaceholderUtils.toInt(args.get(1)))); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("repeat") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 2); + int count = PlaceholderUtils.toInt(args.get(0)); + PlaceholderUtils.checkRange("n", 0, 50000, count); + MultiLineComponent out = MultiLineComponent.empty(); + for (int i = 0; i < count; i++) out.append(args.get(1)); + return out.setIgnoreSpaces(true); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("block") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 0); + return MultiLineComponent.literal("█"); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("tick") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 0); + if (ctx.cover() instanceof IPlaceholderInfoProviderCover cover) + return MultiLineComponent.literal(cover.getTicksSincePlaced()); + throw new NotSupportedException(); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("select") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1, true); + int i = PlaceholderUtils.toInt(args.get(0)); + PlaceholderUtils.checkArgs(args, i + 1, true); + return new MultiLineComponent(args.get(i + 1)).setIgnoreSpaces(true); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("redstone") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 2, true); + if (GTStringUtils.equals(args.getFirst(), "get")) { + Direction direction = Direction.byName(GTStringUtils.componentsToString(args.get(1))); + if (direction == null) + throw new InvalidArgsException(); + return MultiLineComponent.literal(ctx.level() + .getSignal(ctx.pos().relative(direction), direction)); + } else if (GTStringUtils.equals(args.get(1), "set")) { + int power = PlaceholderUtils.toInt(args.get(1)); + PlaceholderUtils.checkRange("redstone power", 0, 15, power); + if (ctx.cover() == null) throw new NotSupportedException(); + ctx.cover().setRedstoneSignalOutput(power); + return MultiLineComponent.empty(); + } + throw new InvalidArgsException(); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("previousText") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + int i = PlaceholderUtils.toInt(args.getFirst()); + if (ctx.previousText() == null) throw new NotSupportedException(); + PlaceholderUtils.checkRange("line", 1, ctx.previousText().size(), i); + return MultiLineComponent.of(ctx.previousText().get(i - 1)).setIgnoreSpaces(true); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("progress") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 0); + IWorkable workable = GTCapabilityHelper.getWorkable(ctx.level(), + ctx.pos(), ctx.side()); + if (workable == null) throw new NotSupportedException(); + return MultiLineComponent.literal(workable.getProgress()); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("maxProgress") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 0); + IWorkable workable = GTCapabilityHelper.getWorkable(ctx.level(), + ctx.pos(), ctx.side()); + if (workable == null) throw new NotSupportedException(); + return MultiLineComponent.literal(workable.getMaxProgress()); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("maintenance") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 0); + IMaintenanceMachine maintenance = GTCapabilityHelper.getMaintenanceMachine(ctx.level(), + ctx.pos(), ctx.side()); + if (maintenance == null) throw new NotSupportedException(); + return MultiLineComponent.literal(maintenance.hasMaintenanceProblems() ? 1 : 0); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("active") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 0); + IWorkable workable = GTCapabilityHelper.getWorkable(ctx.level(), + ctx.pos(), ctx.side()); + if (workable == null) throw new NotSupportedException(); + return MultiLineComponent.literal(workable.isActive() ? 1 : 0); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("voltage") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 0); + if (ctx.level().getBlockEntity(ctx.pos()) instanceof CableBlockEntity cable) { + return MultiLineComponent.literal(cable.getAverageVoltage()); + } + throw new NotSupportedException(); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("amperage") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 0); + if (ctx.level().getBlockEntity(ctx.pos()) instanceof CableBlockEntity cable) { + return MultiLineComponent.literal(cable.getAverageAmperage()); + } + throw new NotSupportedException(); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("count") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1, true); + String arg1 = GTStringUtils.componentsToString(args.getFirst()); + int cnt = -1; + for (List arg : args) { + if (GTStringUtils.equals(arg, arg1)) cnt++; + } + return MultiLineComponent.literal(cnt); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("data") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 2, true); + try { + int slot = PlaceholderUtils.toInt(args.get(1)); + PlaceholderUtils.checkRange("slot index", 1, 8, slot); + if (ctx.itemStackHandler() == null) throw new NotSupportedException(); + + ItemStack stack = ctx.itemStackHandler().getStackInSlot(slot - 1); + DataItem component = stack.get(GTDataComponents.DATA_ITEM); + if (component == null) { + throw new MissingItemException("any data item", slot); + } + int capacity = component.capacity(); + + PlaceholderUtils.checkRange("index", 0, capacity - 1, PlaceholderUtils.toInt(args.get(2))); + // <<<<<<< HEAD:src/main/java/com/gregtechceu/gtceu/data/placeholder/GTPlaceholders.java + + FormatStringList immutableData = stack.get(GTDataComponents.COMPUTER_MONITOR_DATA); + if (immutableData == null) { + throw new MissingItemException("any data item", slot); + } + FormatStringList.Mutable monitorData = immutableData.mutable(); + while (monitorData.size() <= PlaceholderUtils.toInt(args.get(2))) { + monitorData.add(""); + } + + int p = stack.getOrDefault(GTDataComponents.COMPUTER_MONITOR_P, 0); + if (GTStringUtils.equals(args.get(2), "")) { + args.set(2, MultiLineComponent.literal(p)); + } + if (GTStringUtils.equals(args.getFirst(), "get")) { + return MultiLineComponent.literal( + monitorData.get(PlaceholderUtils.toInt(args.get(2)) % capacity)).setIgnoreSpaces(true); + } else if (args.getFirst().equalsString("set")) { + monitorData.set(PlaceholderUtils.toInt(args.get(2)) % capacity, args.get(3).toString()); + stack.set(GTDataComponents.COMPUTER_MONITOR_DATA, monitorData.toImmutable()); + return MultiLineComponent.empty(); + } else if (args.getFirst().equalsString("setp")) { + stack.set(GTDataComponents.COMPUTER_MONITOR_P, PlaceholderUtils.toInt(args.get(3)) % capacity); + return MultiLineComponent.empty(); + } else if (args.getFirst().equalsString("inc")) { + stack.set(GTDataComponents.COMPUTER_MONITOR_P, (p + 1) % capacity); + return MultiLineComponent.empty(); + } else if (args.getFirst().equalsString("dec")) { + stack.set(GTDataComponents.COMPUTER_MONITOR_P, p == 0 ? capacity - 1 : p - 1); + return MultiLineComponent.empty(); + } else { + throw new InvalidArgsException(); + } + } catch (IndexOutOfBoundsException e) { + throw new InvalidArgsException(); + } + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("combine") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, List args) { + MultiLineComponent out = MultiLineComponent.empty(); + for (int i = 0; i < args.size(); i++) { + out.append(args.get(i)); + if (i != args.size() - 1) out.append(" "); + } + return out.setIgnoreSpaces(true); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("nbt") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + int slot = GTStringUtils.toInt(args.getFirst()); + PlaceholderUtils.checkRange("slot index", 1, 8, slot); + if (ctx.itemStackHandler() == null) throw new NotSupportedException(); + return MultiLineComponent + .literal(ctx.itemStackHandler().getStackInSlot(slot - 1).getComponents().toString()); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("toChars") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + if (args.getFirst().isEmpty()) return MultiLineComponent.empty(); + StringBuilder out = new StringBuilder(); + for (char c : GTStringUtils.componentsToString(args.getFirst()).toCharArray()) + out.append(c).append(' '); + return MultiLineComponent.literal(out.substring(0, out.length() - 2)); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("toAscii") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + String arg = args.getFirst().toString(); + if (arg.length() != 1) throw new InvalidArgsException(); + return MultiLineComponent.literal((int) arg.toCharArray()[0]); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("fromAscii") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + return MultiLineComponent.literal((char) PlaceholderUtils.toInt(args.get(0))).setIgnoreSpaces(true); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("subList") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 2, true); + int l = PlaceholderUtils.toInt(args.getFirst()); + int r = PlaceholderUtils.toInt(args.get(1)); + PlaceholderUtils.checkRange("start index", 0, args.size(), l); + PlaceholderUtils.checkRange("end index", 0, args.size(), r); + MultiLineComponent out = MultiLineComponent.empty(); + for (int i = l; i < r - 1; i++) out.append(args.get(i)).append(' '); + out.append(args.get(r - 1)); + out.setIgnoreSpaces(true); + return out; + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("cmp") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 3); + double a = PlaceholderUtils.toDouble(args.getFirst()); + double b = PlaceholderUtils.toDouble(args.get(2)); + return switch (args.get(1).toString()) { + case ">" -> MultiLineComponent.literal(a > b ? 1 : 0); + case "<" -> MultiLineComponent.literal(a < b ? 1 : 0); + case ">=" -> MultiLineComponent.literal(a >= b ? 1 : 0); + case "<=" -> MultiLineComponent.literal(a <= b ? 1 : 0); + case "==" -> MultiLineComponent.literal(a == b ? 1 : 0); + case "!=" -> MultiLineComponent.literal(a != b ? 1 : 0); + default -> throw new InvalidArgsException(); + }; + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("bf") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 2); + int slot = PlaceholderUtils.toInt(args.getFirst()); + PlaceholderUtils.checkRange("slot index", 1, 8, slot); + if (ctx.itemStackHandler() == null) throw new NotSupportedException(); + + ItemStack stack = ctx.itemStackHandler().getStackInSlot(slot - 1); + FormatStringList immutableData = stack.get(GTDataComponents.COMPUTER_MONITOR_DATA); + if (immutableData == null) { + throw new MissingItemException("any data item", slot); + } + FormatStringList.Mutable monitorData = immutableData.mutable(); + + int operationsLeft = 5000; + int p = 0, start = 0, cnt = 0, num = 0; + String rawCode = args.get(1).toString().replaceAll("[^+\\-><\\[\\]]", ""); + StringBuilder codeBuilder = new StringBuilder(); + // optimize BF code ("[----[+++]-<<-]" -> "[4-[3+]1-2<1-]") + @Nullable + Character cur = null; + for (char i : rawCode.toCharArray()) { + if (cur != null) { + if (cur == i) cnt++; + else { + codeBuilder.append(cnt).append(cur); + cur = null; + cnt = 0; + } + } + if (cur == null) { + if (List.of('+', '-', '<', '>').contains(i)) { + cur = i; + cnt = 1; + } else codeBuilder.append(i); + } + } + if (cur != null) codeBuilder.append(cnt).append(cur); + String code = codeBuilder.toString(); + Stack loops = new Stack<>(); + if (!getData(ctx).getBoolean("completed")) { + p = getData(ctx).getInt("pointer"); + start = getData(ctx).getInt("index"); + num = getData(ctx).getInt("num"); + } + getData(ctx).putBoolean("completed", true); + for (int i = 0; i < code.length(); i++) { + if (operationsLeft <= 0) { + getData(ctx).putBoolean("completed", false); + getData(ctx).putInt("pointer", p); + getData(ctx).putInt("index", i); + getData(ctx).putInt("num", num); + break; + } + while (monitorData.size() <= p) { + monitorData.add("0"); + } + if (monitorData.get(p).isEmpty()) { + monitorData.set(i, "0"); + } + try { + switch (code.charAt(i)) { + case '+' -> monitorData.set(p, + String.valueOf((Integer.parseInt(monitorData.get(p)) + num) % 256)); + case '-' -> { + int tmp = Integer.parseInt(monitorData.get(p)) - num; + if (tmp < 0) tmp = (256 - ((-tmp) % 256)) % 256; + monitorData.set(p, String.valueOf(tmp)); + } + case '>' -> p += num; + case '<' -> p -= num; + case '[' -> loops.push(i); + case ']' -> { + if (Integer.parseInt(monitorData.get(p)) == 0) { + loops.pop(); + } else { + i = loops.peek(); + } + } + default -> throw new PlaceholderException(Component + .translatable("gtceu.computer_monitor_cover.error.bf_invalid", i).getString()); + } + } catch (Exception e) { + + } + if (Character.isDigit(code.charAt(i))) { + num = num * 10 + code.charAt(i) - '0'; + } else num = 0; + operationsLeft--; + } + return MultiLineComponent.empty(); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("cmd") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 2); + if (ctx.itemStackHandler() == null) throw new NotSupportedException(); + int slot = PlaceholderUtils.toInt(args.getFirst()); + PlaceholderUtils.checkRange("slot index", 1, 8, slot); + ItemStack stack = ctx.itemStackHandler().getStackInSlot(slot - 1); + + BindingData bindingData = stack.get(GTDataComponents.BINDING_DATA); + if (bindingData == null) { + throw new MissingItemException("any data item bound to player", slot); + } + + Component displayName = bindingData.getBoundPlayerName(ctx.level()); + if (displayName == null) { + displayName = Component.translatable("gtceu.tooltip.player_name.placeholder_processor"); + } + + if (!(ctx.level() instanceof ServerLevel serverLevel)) { + throw new NotSupportedException(); + } + MinecraftServer server = serverLevel.getServer(); + Player player = ctx.level().getPlayerByUUID(bindingData.uuid()); + + MultiLineComponent output = MultiLineComponent.empty(); + CommandSource customSource = new CommandSource() { + + @Override + public void sendSystemMessage(@NotNull Component message) { + output.append(List.of(message)).appendNewline(); + } + + @Override + public boolean acceptsSuccess() { + return true; + } + + @Override + public boolean acceptsFailure() { + return true; + } + + @Override + public boolean shouldInformAdmins() { + return false; + } + }; + + CommandSourceStack source = new CommandSourceStack( + customSource, + ctx.pos() == null ? Vec3.ZERO : ctx.pos().getCenter(), + Vec2.ZERO, + serverLevel, + bindingData.permissionLevel(), + displayName.getString(), + displayName, + server, + player); + server.getCommands().performPrefixedCommand(source, args.get(1).toString()); + return output; + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("tm") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, List args) { + return MultiLineComponent.literal("™"); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("formatInt") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + long n = PlaceholderUtils.toLong(args.getFirst()); + Map suffixes = Map.of( + 1L, "", + 1000L, "K", + 1000000L, "M", + 1000000000L, "B", + 1000000000000L, "T"); + long max = 1; + for (Long i : suffixes.keySet()) { + if (n >= i && max < i) max = i; + } + return MultiLineComponent.literal("%.2f%s".formatted(((double) n) / max, suffixes.get(max))); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("click") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + if (!(MetaMachine.getMachine(ctx.level(), ctx.pos()) instanceof AdvancedMonitorPartMachine monitor)) + throw new NotSupportedException(); + monitor.resetClicked(); + if (args.isEmpty()) return MultiLineComponent.literal(monitor.isClicked() ? 1 : 0); + PlaceholderUtils.checkArgs(args, 1); + if (args.get(0).equalsString("x")) return MultiLineComponent.literal(monitor.getClickPosX()); + if (args.get(0).equalsString("y")) return MultiLineComponent.literal(monitor.getClickPosY()); + throw new InvalidArgsException(); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("ender") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 2, true); + String type = args.get(0).toString(); + String channel = args.get(1).toString(); + UUID owner = null; + if (args.size() > 2 && !args.get(2).toString().isEmpty()) { + if (ctx.itemStackHandler() == null) throw new NotSupportedException(); + int slot = PlaceholderUtils.toInt(args.get(2)); + PlaceholderUtils.checkRange("slot index", 1, 8, slot); + ItemStack stack = ctx.itemStackHandler().getStackInSlot(slot - 1); + // if (stack.getOrCreateTag().contains("boundPlayerUUID")) + // owner = UUID.fromString(stack.getOrCreateTag().getString("boundPlayerUUID")); + if (stack.has(GTDataComponents.DATA_BOUND_PLAYER)) + owner = stack.get(GTDataComponents.DATA_BOUND_PLAYER).uuid(); + } + VirtualEnderRegistry ender = VirtualEnderRegistry.getInstance(); + switch (type) { + case "redstone" -> { + channel = "ERLink#" + channel; + if (!ender.hasEntry(owner, EntryTypes.ENDER_REDSTONE, channel)) + return MultiLineComponent.literal(0); + if (args.size() > 4) { + if (ctx.itemStackHandler() == null) throw new NotSupportedException(); + int slot = PlaceholderUtils.toInt(args.get(3)); + PlaceholderUtils.checkRange("slot index", 1, 8, slot); + ItemStack stack = ctx.itemStackHandler().getStackInSlot(slot - 1); + UUID uuid; + if (stack.has(GTDataComponents.ENDER_REDSTONE_LINK_TRANSMITTER_UUID)) { + uuid = stack.get(GTDataComponents.ENDER_REDSTONE_LINK_TRANSMITTER_UUID); + } else { + uuid = UUID.randomUUID(); + stack.set(GTDataComponents.ENDER_REDSTONE_LINK_TRANSMITTER_UUID, uuid); + } + int power = PlaceholderUtils.toInt(args.get(4)); + PlaceholderUtils.checkRange("redstone signal", 0, 15, power); + ender.getEntry(owner, EntryTypes.ENDER_REDSTONE, channel).setSignal(uuid, power); + return MultiLineComponent.empty(); + } + return MultiLineComponent + .literal(ender.getEntry(owner, EntryTypes.ENDER_REDSTONE, channel).getSignal()); + } + case "item" -> { + channel = "EILink#" + channel; + if (!ender.hasEntry(owner, EntryTypes.ENDER_ITEM, channel)) + return MultiLineComponent.literal(0); + IItemHandler items = ender.getEntry(owner, EntryTypes.ENDER_ITEM, channel).getHandler(); + int count = 0; + for (int i = 0; i < items.getSlots(); i++) count += items.getStackInSlot(i).getCount(); + return MultiLineComponent.literal(count); + } + case "itemId" -> { + channel = "EILink#" + channel; + if (!ender.hasEntry(owner, EntryTypes.ENDER_ITEM, channel)) + return MultiLineComponent.literal(ItemStack.EMPTY.toString()); + IItemHandler items = ender.getEntry(owner, EntryTypes.ENDER_ITEM, channel).getHandler(); + if (items.getSlots() == 0) return MultiLineComponent.literal(ItemStack.EMPTY.toString()); + return MultiLineComponent.literal(items.getStackInSlot(0).toString()); + } + case "itemPull" -> { + channel = "EILink#" + channel; + if (!ender.hasEntry(owner, EntryTypes.ENDER_ITEM, channel)) + return MultiLineComponent.empty(); + IItemHandler items = ender.getEntry(owner, EntryTypes.ENDER_ITEM, channel).getHandler(); + if (ctx.itemStackHandler() != null) + GTTransferUtils.transferItemsFiltered(items, ctx.itemStackHandler(), stack -> true, 1); + else throw new NotSupportedException(); + return MultiLineComponent.empty(); + } + case "itemPush" -> { + channel = "EILink#" + channel; + if (!ender.hasEntry(owner, EntryTypes.ENDER_ITEM, channel)) + return MultiLineComponent.empty(); + IItemHandler items = ender.getEntry(owner, EntryTypes.ENDER_ITEM, channel).getHandler(); + if (ctx.itemStackHandler() != null) + GTTransferUtils.transferItemsFiltered(ctx.itemStackHandler(), items, stack -> true, 1); + else throw new NotSupportedException(); + return MultiLineComponent.empty(); + } + case "fluid" -> { + channel = "EFLink#" + channel; + if (!ender.hasEntry(owner, EntryTypes.ENDER_FLUID, channel)) + return MultiLineComponent.literal(0); + return MultiLineComponent.literal( + ender.getEntry(owner, EntryTypes.ENDER_FLUID, channel).getFluidTank().getFluidAmount()); + } + default -> throw new InvalidArgsException(); + } + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("eval") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + return PlaceholderHandler.processPlaceholders(args.get(0).toString(), ctx); + } + }); + // PORT TODO: Replace with blockComponent + // PlaceholderHandler.addPlaceholder(new Placeholder("blockNbt") { + + // @Override + // public MultiLineComponent apply(PlaceholderContext ctx, List args) { + // BlockEntity blockEntity = ctx.level().getBlockEntity(ctx.pos()); + // if (blockEntity == null) return MultiLineComponent.empty(); + // Tag tag = blockEntity.saveWithFullMetadata(); + // if (tag instanceof CompoundTag compoundTag && compoundTag.contains("cover")) { + // CompoundTag coverTag = compoundTag.getCompound("cover"); + // if (coverTag.contains(ctx.side().getName())) { + // CompoundTag cover = coverTag.getCompound(ctx.side().getName()).getCompound("payload") + // .getCompound("d"); + // cover.putString("text", "[REMOVED]"); + // } + // } + // for (MultiLineComponent arg : args) { + // if (!(tag instanceof CompoundTag compoundTag)) return MultiLineComponent.empty(); + // tag = compoundTag.get(arg.toString()); + // } + // return tag == null ? MultiLineComponent.empty() : MultiLineComponent.literal(tag.toString()); + // } + // }); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/GCYMRecipeTypes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/GCYMRecipeTypes.java index 09e23d5c2fc..ab37da6f9f7 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/GCYMRecipeTypes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/GCYMRecipeTypes.java @@ -51,7 +51,6 @@ public class GCYMRecipeTypes { } return ""; }) - .setMaxTooltips(4) .setUiBuilder((recipe, widgetGroup) -> { int temp = recipe.data.getInt("ebf_temp"); List> items = new ArrayList<>(); diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeCategories.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeCategories.java index b3be4f32449..e87c6e15083 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeCategories.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeCategories.java @@ -10,6 +10,12 @@ public class GTRecipeCategories { + public static final GTRecipeCategory ORE_CRUSHING = register("ore_crushing", GTRecipeTypes.MACERATOR_RECIPES); + public static final GTRecipeCategory ORE_FORGING = register("ore_forging", GTRecipeTypes.FORGE_HAMMER_RECIPES); + public static final GTRecipeCategory ORE_BATHING = register("ore_bathing", GTRecipeTypes.CHEMICAL_BATH_RECIPES); + public static final GTRecipeCategory CHEM_DYES = register("chem_dyes", GTRecipeTypes.CHEMICAL_BATH_RECIPES); + public static final GTRecipeCategory INGOT_MOLDING = register("ingot_molding", GTRecipeTypes.ALLOY_SMELTER_RECIPES); + public static final GTRecipeCategory ARC_FURNACE_RECYCLING = register("arc_furnace_recycling", GTRecipeTypes.ARC_FURNACE_RECIPES) .setIcon(GuiTextures.ARC_FURNACE_RECYCLING_CATEGORY); @@ -22,12 +28,6 @@ public class GTRecipeCategories { GTRecipeTypes.EXTRACTOR_RECIPES) .setIcon(GuiTextures.EXTRACTOR_RECYCLING_CATEGORY); - public static final GTRecipeCategory ORE_CRUSHING = register("ore_crushing", GTRecipeTypes.MACERATOR_RECIPES); - public static final GTRecipeCategory ORE_FORGING = register("ore_forging", GTRecipeTypes.FORGE_HAMMER_RECIPES); - public static final GTRecipeCategory ORE_BATHING = register("ore_bathing", GTRecipeTypes.CHEMICAL_BATH_RECIPES); - public static final GTRecipeCategory CHEM_DYES = register("chem_dyes", GTRecipeTypes.CHEMICAL_BATH_RECIPES); - public static final GTRecipeCategory INGOT_MOLDING = register("ingot_molding", GTRecipeTypes.ALLOY_SMELTER_RECIPES); - public static GTRecipeCategory register(String categoryName, @NotNull GTRecipeType recipeType) { GTRecipeCategory category = new GTRecipeCategory(categoryName, recipeType); GTRegistries.register(GTRegistries.RECIPE_CATEGORIES, category.registryKey, category); diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeConditions.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeConditions.java index 85ff13f41f7..c4d82721e82 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeConditions.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeConditions.java @@ -18,8 +18,7 @@ private GTRecipeConditions() {} GTCEu.id("pos_y"), new RecipeConditionType<>(PositionYCondition::new, PositionYCondition.CODEC)); public static final RecipeConditionType RAINING = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, GTCEu.id("rain"), new RecipeConditionType<>(RainingCondition::new, RainingCondition.CODEC)); - public static final RecipeConditionType ROCK_BREAKER = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, - GTCEu.id("rock_breaker"), new RecipeConditionType<>(RockBreakerCondition::new, RockBreakerCondition.CODEC)); + public static final RecipeConditionType ADJACENT_FLUID = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, GTCEu.id("adjacent_fluid"), new RecipeConditionType<>(AdjacentFluidCondition::new, AdjacentFluidCondition.CODEC)); public static final RecipeConditionType ADJACENT_BLOCK = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, GTCEu.id("adjacent_block"), new RecipeConditionType<>(AdjacentBlockCondition::new, AdjacentBlockCondition.CODEC)); public static final RecipeConditionType THUNDER = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, @@ -36,23 +35,25 @@ private GTRecipeConditions() {} GTCEu.id("environmental_hazard"), new RecipeConditionType<>(EnvironmentalHazardCondition::new, EnvironmentalHazardCondition.CODEC)); public static final RecipeConditionType DAYTIME = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, GTCEu.id("daytime"), new RecipeConditionType<>(DaytimeCondition::new, DaytimeCondition.CODEC)); + public static final RecipeConditionType ROCK_BREAKER = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, + GTCEu.id("rock_breaker"), new RecipeConditionType<>(RockBreakerCondition::new, RockBreakerCondition.CODEC)); public static RecipeConditionType FTB_QUEST; - public static RecipeConditionType GAMESTAGE; - public static RecipeConditionType HERACLES_QUEST; +// public static RecipeConditionType GAMESTAGE; +// public static RecipeConditionType HERACLES_QUEST; public static void init() { if (GTCEu.Mods.isFTBQuestsLoaded()) { FTB_QUEST = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, GTCEu.id("ftb_quest"), new RecipeConditionType<>(FTBQuestCondition::new, FTBQuestCondition.CODEC)); } - if (GTCEu.Mods.isGameStagesLoaded()) { - GAMESTAGE = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, - GTCEu.id("game_stage"), new RecipeConditionType<>(GameStageCondition::new, GameStageCondition.CODEC)); - } - if (GTCEu.Mods.isHeraclesLoaded()) { - HERACLES_QUEST = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, - GTCEu.id("heracles_quest"), new RecipeConditionType<>(HeraclesQuestCondition::new, HeraclesQuestCondition.CODEC)); - } + // if (GTCEu.Mods.isGameStagesLoaded()) { + // GAMESTAGE = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, + // GTCEu.id("game_stage"), new RecipeConditionType<>(GameStageCondition::new, GameStageCondition.CODEC)); + // } + // if (GTCEu.Mods.isHeraclesLoaded()) { + // HERACLES_QUEST = GTRegistries.register(GTRegistries.RECIPE_CONDITIONS, + // GTCEu.id("heracles_quest"), new RecipeConditionType<>(HeraclesQuestCondition::new, HeraclesQuestCondition.CODEC)); + // } } // spotless:on } diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeTypes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeTypes.java index 87ed869c675..24dc49e1549 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeTypes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipeTypes.java @@ -11,18 +11,21 @@ import com.gregtechceu.gtceu.api.gui.widget.SlotWidget; import com.gregtechceu.gtceu.api.gui.widget.TankWidget; import com.gregtechceu.gtceu.api.recipe.*; +import com.gregtechceu.gtceu.api.recipe.condition.RecipeCondition; import com.gregtechceu.gtceu.api.recipe.content.Content; import com.gregtechceu.gtceu.api.recipe.ingredient.SizedIngredientExtensions; import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.api.sound.ExistingSoundEntry; -import com.gregtechceu.gtceu.api.transfer.fluid.CustomFluidTank; import com.gregtechceu.gtceu.common.machine.multiblock.electric.FusionReactorMachine; import com.gregtechceu.gtceu.common.machine.trait.customlogic.*; import com.gregtechceu.gtceu.common.recipe.builder.GTRecipeBuilder; -import com.gregtechceu.gtceu.common.recipe.condition.RockBreakerCondition; +import com.gregtechceu.gtceu.common.recipe.condition.AdjacentFluidCondition; import com.gregtechceu.gtceu.data.machine.GTMachines; import com.gregtechceu.gtceu.data.material.GTMaterials; import com.gregtechceu.gtceu.data.sound.GTSoundEntries; +import com.gregtechceu.gtceu.integration.xei.entry.fluid.FluidEntryList; +import com.gregtechceu.gtceu.integration.xei.entry.fluid.FluidHolderSetList; +import com.gregtechceu.gtceu.integration.xei.handlers.fluid.CycleFluidEntryHandler; import com.gregtechceu.gtceu.integration.xei.handlers.item.CycleItemEntryHandler; import com.gregtechceu.gtceu.utils.GTMath; import com.gregtechceu.gtceu.utils.ResearchManager; @@ -30,14 +33,13 @@ import com.lowdragmc.lowdraglib.utils.LocalizationUtils; import net.minecraft.client.resources.language.I18n; +import net.minecraft.core.HolderSet; import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceLocation; import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.RecipeType; -import net.minecraft.world.level.material.Fluids; -import net.neoforged.neoforge.fluids.FluidStack; +import net.minecraft.world.level.material.Fluid; import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient; import lombok.experimental.ExtensionMethod; @@ -66,7 +68,8 @@ public class GTRecipeTypes { .setProgressBar(GuiTextures.PROGRESS_BAR_BOILER_FUEL.get(true), DOWN_TO_UP) .setMaxTooltips(1) .onRecipeBuild((builder, provider) -> { - var duration = (builder.duration / 12 / 80); // copied for large boiler + // all LBB recipes' duration is 1/4 the small boiler recipe's duration + int duration = builder.duration / 4; if (duration > 0) { GTRecipeTypes.LARGE_BOILER_RECIPES.copyFrom(builder).duration(duration).save(provider); } @@ -143,7 +146,8 @@ public class GTRecipeTypes { .setIconSupplier(() -> GTMachines.MACERATOR[GTValues.LV].asStack()) .setSteamProgressBar(GuiTextures.PROGRESS_BAR_MACERATE_STEAM, LEFT_TO_RIGHT) .addCustomRecipeLogic(MaceratorLogic.INSTANCE) - .setSound(GTSoundEntries.MACERATOR); + .setSound(GTSoundEntries.MACERATOR) + .addDataInfo(data -> LocalizationUtils.format("gtceu.recipe.byproduct_tier", GTValues.VNF[GTValues.HV])); public final static GTRecipeType CANNER_RECIPES = register("canner", ELECTRIC).setMaxIOSize(2, 2, 1, 1) .setEUIO(IO.IN) @@ -185,7 +189,6 @@ public class GTRecipeTypes { .setSlotOverlay(true, true, GuiTextures.VIAL_OVERLAY_2) .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE, LEFT_TO_RIGHT) .setSound(GTValues.FOOLS.getAsBoolean() ? GTSoundEntries.SCIENCE : GTSoundEntries.CHEMICAL) - .setMaxTooltips(4) .onRecipeBuild((recipeBuilder, provider) -> GTRecipeTypes.LARGE_CHEMICAL_RECIPES.copyFrom(recipeBuilder) .save(provider)); @@ -205,7 +208,6 @@ public class GTRecipeTypes { .setSlotOverlay(true, false, true, GuiTextures.DUST_OVERLAY) .setProgressBar(GuiTextures.PROGRESS_BAR_SLICE, LEFT_TO_RIGHT) .setSound(GTSoundEntries.CUT) - .setMaxTooltips(4) .onRecipeBuild((recipeBuilder, provider) -> { if (recipeBuilder.input.getOrDefault(FluidRecipeCapability.CAP, Collections.emptyList()).isEmpty() && recipeBuilder.tickInput.getOrDefault(FluidRecipeCapability.CAP, Collections.emptyList()) @@ -344,7 +346,6 @@ public class GTRecipeTypes { .setMaxIOSize(2, 1, 0, 0).setEUIO(IO.IN) .setSlotOverlay(false, false, true, GuiTextures.LENS_OVERLAY) .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, LEFT_TO_RIGHT) - .setMaxTooltips(4) .setSound(GTSoundEntries.ELECTROLYZER); public final static GTRecipeType SIFTER_RECIPES = register("sifter", ELECTRIC).setMaxIOSize(1, 6, 0, 0) @@ -371,7 +372,6 @@ public class GTRecipeTypes { .setSlotOverlay(false, false, GuiTextures.CIRCUIT_OVERLAY) .setProgressBar(GuiTextures.PROGRESS_BAR_CIRCUIT_ASSEMBLER, LEFT_TO_RIGHT) .setSound(GTSoundEntries.ASSEMBLER) - .setMaxTooltips(4) .onRecipeBuild((recipeBuilder, provider) -> { if (recipeBuilder.input.getOrDefault(FluidRecipeCapability.CAP, Collections.emptyList()).isEmpty() && recipeBuilder.tickInput.getOrDefault(FluidRecipeCapability.CAP, Collections.emptyList()) @@ -394,14 +394,12 @@ public class GTRecipeTypes { .setSlotOverlay(false, false, GuiTextures.INT_CIRCUIT_OVERLAY) .setSlotOverlay(true, true, GuiTextures.CENTRIFUGE_OVERLAY) .setProgressBar(GuiTextures.PROGRESS_BAR_GAS_COLLECTOR, LEFT_TO_RIGHT) - .setMaxTooltips(4) .setOffsetVoltageText(true) .setSound(GTSoundEntries.COOLING); public final static GTRecipeType AIR_SCRUBBER_RECIPES = register("air_scrubber", ELECTRIC) .setMaxIOSize(1, 3, 1, 3).setEUIO(IO.IN) .setProgressBar(GuiTextures.PROGRESS_BAR_GAS_COLLECTOR, LEFT_TO_RIGHT) - .setMaxTooltips(4) .setSound(GTSoundEntries.COOLING); public static final GTRecipeType RESEARCH_STATION_RECIPES = register("research_station", ELECTRIC) @@ -420,22 +418,36 @@ public class GTRecipeTypes { .setProgressBar(GuiTextures.PROGRESS_BAR_MACERATE, LEFT_TO_RIGHT) .setIconSupplier(() -> GTMachines.ROCK_CRUSHER[GTValues.LV].asStack()) .setSteamProgressBar(GuiTextures.PROGRESS_BAR_MACERATE_STEAM, LEFT_TO_RIGHT) - .prepareBuilder(recipeBuilder -> recipeBuilder.addCondition(RockBreakerCondition.INSTANCE)) .setUiBuilder((recipe, widgetGroup) -> { - var fluidA = BuiltInRegistries.FLUID.get(ResourceLocation.parse(recipe.data.getString("fluidA"))); - var fluidB = BuiltInRegistries.FLUID.get(ResourceLocation.parse(recipe.data.getString("fluidB"))); - if (fluidA != Fluids.EMPTY) { - widgetGroup.addWidget(new TankWidget(new CustomFluidTank(new FluidStack(fluidA, 1000)), - widgetGroup.getSize().width - 30, widgetGroup.getSize().height - 30, false, false) - .setBackground(GuiTextures.FLUID_SLOT).setShowAmount(false)); + List> fluids = new ArrayList<>(); + for (RecipeCondition condition : recipe.conditions) { + if (condition instanceof AdjacentFluidCondition adjacentFluid) { + fluids.addAll(adjacentFluid.getOrInitFluids(recipe)); + } } - if (fluidB != Fluids.EMPTY) { - widgetGroup.addWidget(new TankWidget(new CustomFluidTank(new FluidStack(fluidB, 1000)), - widgetGroup.getSize().width - 30 - 20, widgetGroup.getSize().height - 30, false, false) - .setBackground(GuiTextures.FLUID_SLOT).setShowAmount(false)); + if (fluids.isEmpty()) { + return; + } + + int xOffset = 35; + int yOffset = 0; + int i = 0; + for (HolderSet set : fluids) { + if (set.size() == 0) { + continue; + } + List slots = Collections.singletonList(FluidHolderSetList.of(set, 1000)); + TankWidget tank = new TankWidget(new CycleFluidEntryHandler(slots), + widgetGroup.getSize().width - 30 - xOffset, widgetGroup.getSize().height - 30 + yOffset, + false, false) + .setBackground(GuiTextures.FLUID_SLOT).setShowAmount(false); + widgetGroup.addWidget(tank); + + i++; + xOffset = 20 * (2 - (i % 3)) - 5; + yOffset = 20 * (i / 3); } }) - .setMaxTooltips(4) .setSound(GTSoundEntries.FIRE); public static final GTRecipeType SCANNER_RECIPES = register("scanner", ELECTRIC) @@ -630,7 +642,6 @@ public class GTRecipeTypes { .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW, LEFT_TO_RIGHT) .setSound(GTSoundEntries.ASSEMBLER) .setHasResearchSlot(true) - .setMaxTooltips(4) .onRecipeBuild(ResearchManager::createDefaultResearchRecipe); public static final GTRecipeType LARGE_CHEMICAL_RECIPES = register("large_chemical_reactor", MULTIBLOCK) @@ -644,7 +655,6 @@ public class GTRecipeTypes { .setSlotOverlay(true, true, GuiTextures.VIAL_OVERLAY_2) .setSound(GTValues.FOOLS.getAsBoolean() ? GTSoundEntries.SCIENCE : GTSoundEntries.CHEMICAL) .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE, LEFT_TO_RIGHT) - .setMaxTooltips(4) .setSmallRecipeMap(CHEMICAL_RECIPES); public static final GTRecipeType FUSION_RECIPES = register("fusion_reactor", MULTIBLOCK).setMaxIOSize(0, 0, 2, 1) diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipes.java index 9313530c21d..b55156ae40c 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/GTRecipes.java @@ -19,7 +19,7 @@ import net.minecraft.world.item.crafting.Recipe; import net.neoforged.neoforge.common.conditions.ICondition; -import dev.latvian.mods.kubejs.bindings.event.ServerEvents; +import dev.latvian.mods.kubejs.plugin.builtin.event.ServerEvents; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -63,7 +63,8 @@ public void accept(@NotNull ResourceLocation id, @NotNull Recipe recipe, // com.gregtechceu.gtceu.data.recipe.generated.* for (Material material : GTCEuAPI.materialManager) { - if (material.hasFlag(MaterialFlags.DISABLE_MATERIAL_RECIPES)) { + if (material.hasFlag(MaterialFlags.NO_UNIFICATION) || + material.hasFlag(MaterialFlags.DISABLE_MATERIAL_RECIPES)) { continue; } diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java index 0f38b0d6f85..9dd048c7efb 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/VanillaRecipeHelper.java @@ -23,6 +23,7 @@ import net.minecraft.world.level.ItemLike; import net.neoforged.neoforge.common.crafting.ICustomIngredient; +import com.tterrag.registrate.util.entry.ItemProviderEntry; import it.unimi.dsi.fastutil.chars.*; import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; import org.jetbrains.annotations.NotNull; @@ -61,6 +62,43 @@ public static void addSmeltingRecipe(RecipeOutput provider, @NotNull ResourceLoc .save(provider); } + public static void addSmeltingRecipe(RecipeOutput provider, @NotNull String regName, ItemStack input, + ItemStack output) { + addSmeltingRecipe(provider, GTCEu.id(regName), input, output, 0.0f); + } + + public static void addSmeltingRecipe(RecipeOutput provider, @NotNull String regName, Item input, + Item output) { + addSmeltingRecipe(provider, GTCEu.id(regName), input.getDefaultInstance(), output.getDefaultInstance(), 0.0f); + } + + public static void addSmeltingRecipe(RecipeOutput provider, @NotNull String regName, Item input, + Item output, float experience) { + addSmeltingRecipe(provider, GTCEu.id(regName), input.getDefaultInstance(), output.getDefaultInstance(), + experience); + } + + public static void addSmeltingRecipe(RecipeOutput provider, @NotNull String regName, ItemStack input, + ItemStack output, float experience) { + addSmeltingRecipe(provider, GTCEu.id(regName), input, output, experience); + } + + public static void addSmeltingRecipe(RecipeOutput provider, @NotNull ResourceLocation regName, + ItemStack input, ItemStack output, float experience) { + SimpleCookingRecipeBuilder.smelting(regName).input(input).output(output).cookingTime(200).experience(experience) + .save(provider); + } + + public static void addBlastingRecipe(RecipeOutput provider, @NotNull String regName, TagKey input, + ItemStack output) { + addBlastingRecipe(provider, GTCEu.id(regName), input, output); + } + + public static void addBlastingRecipe(RecipeOutput provider, @NotNull ResourceLocation regName, + TagKey input, ItemStack output) { + addBlastingRecipe(provider, regName, input, output, 0.0f); + } + public static void addBlastingRecipe(RecipeOutput provider, @NotNull String regName, TagKey input, ItemStack output, float experience) { addBlastingRecipe(provider, GTCEu.id(regName), input, output, experience); @@ -73,45 +111,99 @@ public static void addBlastingRecipe(RecipeOutput provider, @NotNull String regN public static void addBlastingRecipe(RecipeOutput provider, @NotNull ResourceLocation regName, Ingredient input, ItemStack output, float experience) { - SimpleCookingRecipeBuilder.blasting(regName).input(input).output(output).cookingTime(100).experience(experience) + SimpleCookingRecipeBuilder.smelting(regName).input(input).output(output).cookingTime(200).experience(experience) .save(provider); } public static void addBlastingRecipe(RecipeOutput provider, @NotNull ResourceLocation regName, TagKey input, ItemStack output, float experience) { - SimpleCookingRecipeBuilder.blasting(regName).input(input).output(output).cookingTime(100).experience(experience) + SimpleCookingRecipeBuilder.smelting(regName).input(input).output(output).cookingTime(200).experience(experience) + .save(provider); + } + + public static void addBlastingRecipe(RecipeOutput provider, @NotNull String regName, ItemStack input, + ItemStack output) { + addBlastingRecipe(provider, GTCEu.id(regName), input, output, 0.0f); + } + + public static void addBlastingRecipe(RecipeOutput provider, @NotNull String regName, Item input, + Item output) { + addBlastingRecipe(provider, GTCEu.id(regName), input.getDefaultInstance(), output.getDefaultInstance(), 0.0f); + } + + public static void addBlastingRecipe(RecipeOutput provider, @NotNull String regName, Item input, + Item output, float experience) { + addBlastingRecipe(provider, GTCEu.id(regName), input.getDefaultInstance(), output.getDefaultInstance(), + experience); + } + + public static void addBlastingRecipe(RecipeOutput provider, @NotNull String regName, ItemStack input, + ItemStack output, float experience) { + addBlastingRecipe(provider, GTCEu.id(regName), input, output, experience); + } + + public static void addBlastingRecipe(RecipeOutput provider, @NotNull ResourceLocation regName, + ItemStack input, ItemStack output, float experience) { + SimpleCookingRecipeBuilder.blasting(regName).input(input).output(output).cookingTime(200).experience(experience) .save(provider); } + public static void addSmokingRecipe(RecipeOutput provider, @NotNull String regName, TagKey input, + ItemStack output) { + addSmokingRecipe(provider, GTCEu.id(regName), input, output); + } + + public static void addSmokingRecipe(RecipeOutput provider, @NotNull ResourceLocation regName, + TagKey input, ItemStack output) { + addSmokingRecipe(provider, regName, input, output, 0.0f); + } + public static void addSmokingRecipe(RecipeOutput provider, @NotNull String regName, TagKey input, ItemStack output, float experience) { addSmokingRecipe(provider, GTCEu.id(regName), input, output, experience); } - public static void addSmokingRecipe(RecipeOutput provider, @NotNull String regName, ItemStack input, + public static void addSmokingRecipe(RecipeOutput provider, @NotNull String regName, Ingredient input, ItemStack output, float experience) { addSmokingRecipe(provider, GTCEu.id(regName), input, output, experience); } - public static void addSmokingRecipe(RecipeOutput provider, @NotNull String regName, TagKey input, - ItemStack output) { - addSmokingRecipe(provider, GTCEu.id(regName), input, output, 0); + public static void addSmokingRecipe(RecipeOutput provider, @NotNull ResourceLocation regName, + Ingredient input, ItemStack output, float experience) { + SimpleCookingRecipeBuilder.smelting(regName).input(input).output(output).cookingTime(200).experience(experience) + .save(provider); + } + + public static void addSmokingRecipe(RecipeOutput provider, @NotNull ResourceLocation regName, + TagKey input, ItemStack output, float experience) { + SimpleCookingRecipeBuilder.smelting(regName).input(input).output(output).cookingTime(200).experience(experience) + .save(provider); } public static void addSmokingRecipe(RecipeOutput provider, @NotNull String regName, ItemStack input, ItemStack output) { - addSmokingRecipe(provider, GTCEu.id(regName), input, output, 0); + addSmokingRecipe(provider, GTCEu.id(regName), input, output, 0.0f); } - public static void addSmokingRecipe(RecipeOutput provider, @NotNull ResourceLocation regName, - TagKey input, ItemStack output, float experience) { - SimpleCookingRecipeBuilder.smoking(regName).input(input).output(output).cookingTime(100).experience(experience) - .save(provider); + public static void addSmokingRecipe(RecipeOutput provider, @NotNull String regName, Item input, + Item output) { + addSmokingRecipe(provider, GTCEu.id(regName), input.getDefaultInstance(), output.getDefaultInstance(), 0.0f); + } + + public static void addSmokingRecipe(RecipeOutput provider, @NotNull String regName, Item input, + Item output, float experience) { + addSmokingRecipe(provider, GTCEu.id(regName), input.getDefaultInstance(), output.getDefaultInstance(), + experience); + } + + public static void addSmokingRecipe(RecipeOutput provider, @NotNull String regName, ItemStack input, + ItemStack output, float experience) { + addSmokingRecipe(provider, GTCEu.id(regName), input, output, experience); } public static void addSmokingRecipe(RecipeOutput provider, @NotNull ResourceLocation regName, ItemStack input, ItemStack output, float experience) { - SimpleCookingRecipeBuilder.smoking(regName).input(input).output(output).cookingTime(100).experience(experience) + SimpleCookingRecipeBuilder.smoking(regName).input(input).output(output).cookingTime(200).experience(experience) .save(provider); } @@ -149,33 +241,6 @@ public static void addCampfireRecipe(RecipeOutput provider, @NotNull ResourceLoc .save(provider); } - public static void addSmeltingRecipe(RecipeOutput provider, @NotNull String regName, ItemStack input, - ItemStack output) { - addSmeltingRecipe(provider, GTCEu.id(regName), input, output, 0.0f); - } - - public static void addSmeltingRecipe(RecipeOutput provider, @NotNull String regName, Item input, - Item output) { - addSmeltingRecipe(provider, GTCEu.id(regName), input.getDefaultInstance(), output.getDefaultInstance(), 0.0f); - } - - public static void addSmeltingRecipe(RecipeOutput provider, @NotNull String regName, Item input, - Item output, float experience) { - addSmeltingRecipe(provider, GTCEu.id(regName), input.getDefaultInstance(), output.getDefaultInstance(), - experience); - } - - public static void addSmeltingRecipe(RecipeOutput provider, @NotNull String regName, ItemStack input, - ItemStack output, float experience) { - addSmeltingRecipe(provider, GTCEu.id(regName), input, output, experience); - } - - public static void addSmeltingRecipe(RecipeOutput provider, @NotNull ResourceLocation regName, - ItemStack input, ItemStack output, float experience) { - SimpleCookingRecipeBuilder.smelting(regName).input(input).output(output).cookingTime(200).experience(experience) - .save(provider); - } - /** * Adds a shaped recipe which clears the components of the outputs * @@ -297,7 +362,7 @@ case MaterialEntry(TagPrefix tagPrefix, Material material) -> { } for (var it = foundTools.iterator(); it.hasNext();) { char c = it.nextChar(); - builder.define(c, ToolHelper.getToolFromSymbol(c).itemTags.get(0)); + builder.define(c, ToolHelper.getToolFromSymbol(c).craftingTags.get(0)); } builder.save(provider); @@ -332,6 +397,15 @@ public static void addStrictShapedRecipe(RecipeOutput provider, boolean setMater addShapedRecipe(provider, setMaterialInfoData, true, regName, result, recipe); } + /** + * @see #addShapedRecipe(RecipeOutput, boolean, boolean, ResourceLocation, ItemStack, Object...) + */ + public static void addStrictShapedRecipe(RecipeOutput provider, boolean setMaterialInfoData, + @NotNull String regName, @NotNull ItemStack result, + @NotNull Object... recipe) { + addShapedRecipe(provider, setMaterialInfoData, true, GTCEu.id(regName), result, recipe); + } + public static void addShapelessRecipe(RecipeOutput provider, @NotNull String regName, @NotNull ItemStack result, @NotNull Object... recipe) { addShapelessRecipe(provider, GTCEu.id(regName), result, recipe); @@ -387,7 +461,7 @@ case MaterialEntry(TagPrefix tagPrefix, Material material) -> { } for (var it = foundTools.iterator(); it.hasNext();) { char c = it.nextChar(); - builder.define(c, ToolHelper.getToolFromSymbol(c).itemTags.get(0)); + builder.define(c, ToolHelper.getToolFromSymbol(c).craftingTags.get(0)); } builder.save(provider); @@ -458,7 +532,7 @@ case MaterialEntry(TagPrefix tagPrefix, Material material) -> { } for (var it = foundTools.iterator(); it.hasNext();) { char c = it.nextChar(); - builder.define(c, ToolHelper.getToolFromSymbol(c).itemTags.get(0)); + builder.define(c, ToolHelper.getToolFromSymbol(c).craftingTags.get(0)); } builder.save(provider); @@ -509,20 +583,23 @@ public static void addShapelessRecipe(RecipeOutput provider, @NotNull ResourceLo @NotNull ItemStack result, @NotNull Object... recipe) { var builder = new ShapelessRecipeBuilder(regName).output(result); for (Object content : recipe) { - switch (content) { - case Ingredient ingredient -> builder.requires(ingredient); - case ICustomIngredient ingredient -> builder.requires(ingredient.toVanilla()); - case ItemStack itemStack -> builder.requires(itemStack); - case TagKey key when key.isFor(Registries.ITEM) -> builder.requires((TagKey) key); - case ItemLike itemLike -> builder.requires(itemLike); - case MaterialEntry(TagPrefix tagPrefix, Material material) -> { - TagKey tag = ChemicalHelper.getTag(tagPrefix, material); - if (tag != null) { - builder.requires(tag); - } else builder.requires(ChemicalHelper.get(tagPrefix, material)); - } - case Character c -> builder.requires(ToolHelper.getToolFromSymbol(c).itemTags.getFirst()); - default -> {} + if (content instanceof Ingredient ingredient) { + builder.requires(ingredient); + } else if (content instanceof ItemStack itemStack) { + builder.requires(itemStack); + } else if (content instanceof TagKey key) { + builder.requires((TagKey) key); + } else if (content instanceof ItemLike itemLike) { + builder.requires(itemLike); + } else if (content instanceof MaterialEntry entry) { + TagKey tag = ChemicalHelper.getTag(entry.tagPrefix(), entry.material()); + if (tag != null) { + builder.requires(tag); + } else builder.requires(ChemicalHelper.get(entry.tagPrefix(), entry.material())); + } else if (content instanceof ItemProviderEntry entry) { + builder.requires(entry.asStack()); + } else if (content instanceof Character c) { + builder.requires(ToolHelper.getToolFromSymbol(c).craftingTags.get(0)); } } builder.save(provider); diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/configurable/RecipeAddition.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/configurable/RecipeAddition.java index 363500959e1..98ac101ed7c 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/configurable/RecipeAddition.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/configurable/RecipeAddition.java @@ -52,45 +52,89 @@ public static void init(RecipeOutput provider) { private static void steelSteamMultiblocks(RecipeOutput provider) { if (ConfigHolder.INSTANCE.machines.steelSteamMultiblocks) { - VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_oven", GTMultiMachines.STEAM_OVEN.asStack(), - "CGC", - "FMF", "CGC", 'F', GTBlocks.FIREBOX_STEEL.asStack(), 'C', GTBlocks.CASING_STEEL_SOLID.asStack(), - 'M', GTMachines.STEAM_FURNACE.right().asStack(), 'G', - new MaterialEntry(TagPrefix.gear, GTMaterials.Invar)); + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_oven", + GTMultiMachines.STEAM_OVEN.asStack(), + "CGC", "FMF", "CGC", + 'F', GTBlocks.FIREBOX_STEEL.asStack(), + 'C', GTBlocks.CASING_STEEL_SOLID.asStack(), + 'M', GTMachines.STEAM_FURNACE.right().asStack(), + 'G', new MaterialEntry(TagPrefix.gear, GTMaterials.Invar)); + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_grinder", GTMultiMachines.STEAM_GRINDER.asStack(), - "CGC", "CFC", "CGC", 'G', new MaterialEntry(TagPrefix.gear, GTMaterials.Potin), 'F', - GTMachines.STEAM_MACERATOR.right().asStack(), 'C', GTBlocks.CASING_STEEL_SOLID.asStack()); - VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_hatch", GTMachines.STEAM_HATCH.asStack(), "BPB", - "BTB", "BPB", 'B', new MaterialEntry(TagPrefix.plate, GTMaterials.Steel), 'P', - new MaterialEntry(TagPrefix.pipeNormalFluid, GTMaterials.Steel), 'T', - GTMachines.STEEL_DRUM.asStack()); + "CGC", "CFC", "CGC", + 'G', new MaterialEntry(TagPrefix.gear, GTMaterials.Potin), + 'F', GTMachines.STEAM_MACERATOR.right().asStack(), + 'C', GTBlocks.CASING_STEEL_SOLID.asStack()); + + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_hatch", + GTMachines.STEAM_HATCH.asStack(), + "BPB", "BTB", "BPB", + 'B', new MaterialEntry(TagPrefix.plate, GTMaterials.Steel), + 'P', new MaterialEntry(TagPrefix.pipeNormalFluid, GTMaterials.Steel), + 'T', GTMachines.STEEL_DRUM.asStack()); + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_input_bus", - GTMachines.STEAM_IMPORT_BUS.asStack(), "C", "H", 'H', GTBlocks.STEEL_HULL.asStack(), 'C', - Tags.Items.CHESTS_WOODEN); + GTMachines.STEAM_IMPORT_BUS.asStack(), + "C", "H", + 'H', GTBlocks.STEEL_HULL.asStack(), + 'C', Tags.Items.CHESTS_WOODEN); + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_output_bus", - GTMachines.STEAM_EXPORT_BUS.asStack(), "H", "C", 'H', GTBlocks.STEEL_HULL.asStack(), 'C', - Tags.Items.CHESTS_WOODEN); + GTMachines.STEAM_EXPORT_BUS.asStack(), + "H", "C", + 'H', GTBlocks.STEEL_HULL.asStack(), + 'C', Tags.Items.CHESTS_WOODEN); } else { - VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_oven", GTMultiMachines.STEAM_OVEN.asStack(), - "CGC", - "FMF", "CGC", 'F', GTBlocks.FIREBOX_BRONZE.asStack(), 'C', GTBlocks.CASING_BRONZE_BRICKS.asStack(), - 'M', GTMachines.STEAM_FURNACE.left().asStack(), 'G', - new MaterialEntry(TagPrefix.gear, GTMaterials.Invar)); - VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_grinder", + // Doubled-up recipes to allow for either Low or High Pressure singleblock + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_oven_from_lp", + GTMultiMachines.STEAM_OVEN.asStack(), + "CGC", "FMF", "CGC", + 'F', GTBlocks.FIREBOX_BRONZE.asStack(), + 'C', GTBlocks.CASING_BRONZE_BRICKS.asStack(), + 'M', GTMachines.STEAM_FURNACE.left().asStack(), + 'G', new MaterialEntry(TagPrefix.gear, GTMaterials.Invar)); + + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_oven_from_hp", + GTMultiMachines.STEAM_OVEN.asStack(), + "CGC", "FMF", "CGC", + 'F', GTBlocks.FIREBOX_BRONZE.asStack(), + 'C', GTBlocks.CASING_BRONZE_BRICKS.asStack(), + 'M', GTMachines.STEAM_FURNACE.right().asStack(), + 'G', new MaterialEntry(TagPrefix.gear, GTMaterials.Invar)); + + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_grinder_from_lp", GTMultiMachines.STEAM_GRINDER.asStack(), - "CGC", "CFC", "CGC", 'G', new MaterialEntry(TagPrefix.gear, GTMaterials.Potin), 'F', - GTMachines.STEAM_MACERATOR.left().asStack(), 'C', GTBlocks.CASING_BRONZE_BRICKS.asStack()); - VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_hatch", GTMachines.STEAM_HATCH.asStack(), "BPB", - "BTB", "BPB", 'B', new MaterialEntry(TagPrefix.plate, GTMaterials.Bronze), 'P', - new MaterialEntry(TagPrefix.pipeNormalFluid, GTMaterials.Bronze), 'T', - GTMachines.BRONZE_DRUM.asStack()); + "CGC", "CFC", "CGC", + 'G', new MaterialEntry(TagPrefix.gear, GTMaterials.Potin), + 'F', GTMachines.STEAM_MACERATOR.left().asStack(), + 'C', GTBlocks.CASING_BRONZE_BRICKS.asStack()); + + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_grinder_from_hp", + GTMultiMachines.STEAM_GRINDER.asStack(), + "CGC", "CFC", "CGC", + 'G', new MaterialEntry(TagPrefix.gear, GTMaterials.Potin), + 'F', GTMachines.STEAM_MACERATOR.right().asStack(), + 'C', GTBlocks.CASING_BRONZE_BRICKS.asStack()); + + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_hatch", + GTMachines.STEAM_HATCH.asStack(), + "BPB", "BTB", "BPB", + 'B', new MaterialEntry(TagPrefix.plate, GTMaterials.Bronze), + 'P', new MaterialEntry(TagPrefix.pipeNormalFluid, GTMaterials.Bronze), + 'T', GTMachines.BRONZE_DRUM.asStack()); + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_input_bus", - GTMachines.STEAM_IMPORT_BUS.asStack(), "C", "H", 'H', GTBlocks.BRONZE_HULL.asStack(), 'C', - Tags.Items.CHESTS_WOODEN); + GTMachines.STEAM_IMPORT_BUS.asStack(), + "C", "H", + 'H', GTBlocks.BRONZE_HULL.asStack(), + 'C', Tags.Items.CHESTS_WOODEN); + VanillaRecipeHelper.addShapedRecipe(provider, true, "steam_output_bus", - GTMachines.STEAM_EXPORT_BUS.asStack(), "H", "C", 'H', GTBlocks.BRONZE_HULL.asStack(), 'C', - Tags.Items.CHESTS_WOODEN); + GTMachines.STEAM_EXPORT_BUS.asStack(), + "H", "C", + 'H', GTBlocks.BRONZE_HULL.asStack(), + 'C', Tags.Items.CHESTS_WOODEN); } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/DecompositionRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/DecompositionRecipeHandler.java index 93c1fd8f830..43263502e8f 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/DecompositionRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/DecompositionRecipeHandler.java @@ -37,8 +37,7 @@ private static void processDecomposition(@NotNull RecipeOutput provider, @NotNul (!material.hasFlag(DECOMPOSITION_BY_ELECTROLYZING) && !material.hasFlag(DECOMPOSITION_BY_CENTRIFUGING)) || // disable decomposition if explicitly disabled for this material or for one of it's components - material.hasFlag(DISABLE_DECOMPOSITION) || - material.getMaterialComponents().size() > 6) + material.hasFlag(DISABLE_DECOMPOSITION)) return; List outputs = new ArrayList<>(); @@ -55,6 +54,8 @@ private static void processDecomposition(@NotNull RecipeOutput provider, @NotNul } } + if (outputs.size() > 6 || fluidOutputs.size() > 6) return; + // only reduce items boolean hasDust = material.hasProperty(PropertyKey.DUST); if (hasDust) { diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/MaterialRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/MaterialRecipeHandler.java index 12aca193a66..58a62ca25b2 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/MaterialRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/MaterialRecipeHandler.java @@ -258,7 +258,7 @@ private static void processSmallDust(@NotNull RecipeOutput provider, @NotNull Ma VanillaRecipeHelper.addStrictShapedRecipe(provider, String.format("small_dust_disassembling_%s", material.getName()), - smallDustStack.copyWithCount(4), " X ", " ", " ", 'X', new MaterialEntry(dust, material)); + smallDustStack.copyWithCount(4), " X", " ", 'X', new MaterialEntry(dust, material)); VanillaRecipeHelper.addShapedRecipe(provider, String.format("small_dust_assembling_%s", material.getName()), dustStack, "XX", "XX", 'X', new MaterialEntry(dustSmall, material)); @@ -286,7 +286,7 @@ private static void processTinyDust(@NotNull RecipeOutput provider, @NotNull Mat VanillaRecipeHelper.addStrictShapedRecipe(provider, String.format("tiny_dust_disassembling_%s", material.getName()), - tinyDustStack.copyWithCount(9), "X ", " ", " ", 'X', new MaterialEntry(dust, material)); + tinyDustStack.copyWithCount(9), "X ", " ", 'X', new MaterialEntry(dust, material)); VanillaRecipeHelper.addShapedRecipe(provider, String.format("tiny_dust_assembling_%s", material.getName()), dustStack, "XXX", "XXX", "XXX", 'X', new MaterialEntry(dustTiny, material)); diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/OreRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/OreRecipeHandler.java index 3e26b684e74..1c54aa17b10 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/OreRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/OreRecipeHandler.java @@ -16,9 +16,9 @@ import com.gregtechceu.gtceu.utils.GTUtil; import net.minecraft.data.recipes.RecipeOutput; +import net.minecraft.tags.TagKey; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.Ingredient; -import net.neoforged.neoforge.common.crafting.IntersectionIngredient; import it.unimi.dsi.fastutil.objects.ObjectIntPair; import org.jetbrains.annotations.NotNull; @@ -43,9 +43,7 @@ public static void run(@NotNull RecipeOutput provider, @NotNull Material materia } for (TagPrefix ore : ORES.keySet()) { - if (ConfigHolder.INSTANCE.worldgen.allUniqueStoneTypes || ORES.get(ore).shouldDropAsItem()) { - processOre(provider, ore, property, material); - } + processOre(provider, ore, property, material); } processRawOre(provider, property, material); @@ -63,9 +61,11 @@ private static void processMetalSmelting(@NotNull RecipeOutput provider, @NotNul ItemStack ingotStack = ChemicalHelper.get(ingot, smeltingResult); if (!ingotStack.isEmpty() && doesMaterialUseNormalFurnace(smeltingResult) && !prefix.isIgnored(material)) { - VanillaRecipeHelper.addSmeltingRecipe(provider, - "smelt_" + prefix.name + "_" + material.getName() + "_to_ingot", - ChemicalHelper.getTag(prefix, material), ingotStack, 0.5f); + String name = "smelt_" + prefix.name + "_" + material.getName() + "_to_ingot"; + TagKey tag = ChemicalHelper.getTag(prefix, material); + + VanillaRecipeHelper.addSmeltingRecipe(provider, name, tag, ingotStack, 0.5f); + VanillaRecipeHelper.addBlastingRecipe(provider, name, tag, ingotStack, 0.5f); } } } @@ -76,6 +76,8 @@ private static void processOre(@NotNull RecipeOutput provider, @NotNull TagPrefi return; } + var inputStack = ChemicalHelper.get(orePrefix, material); + Material byproductMaterial = property.getOreByProduct(0, material); ItemStack byproductStack = ChemicalHelper.get(gem, byproductMaterial); if (byproductStack.isEmpty()) { @@ -101,29 +103,28 @@ private static void processOre(@NotNull RecipeOutput provider, @NotNull TagPrefi String prefixString = orePrefix == ore ? "" : orePrefix.name + "_"; if (!crushedStack.isEmpty()) { + int crushedCount = property.getOreMultiplier() * oreTypeMultiplier; GTRecipeBuilder builder = FORGE_HAMMER_RECIPES .recipeBuilder("hammer_" + prefixString + material.getName() + "_ore_to_crushed_ore") - .inputItems(IntersectionIngredient.of(Ingredient.of(orePrefix.getItemTags(material).getFirst()), - Ingredient.of(orePrefix.getItemParentTags().getFirst()))) - .category(GTRecipeCategories.ORE_FORGING) - .duration(10).EUt(16); + .inputItems(inputStack) + .EUt(16) + .duration(10) + .category(GTRecipeCategories.ORE_FORGING); if (material.hasProperty(PropertyKey.GEM) && !ChemicalHelper.get(gem, material).isEmpty()) { - builder.outputItems(ChemicalHelper.get(gem, material) - .copyWithCount(property.getOreMultiplier() * oreTypeMultiplier)); + builder.outputItems(ChemicalHelper.get(gem, material).copyWithCount(crushedCount)); } else { - builder.outputItems(crushedStack.copyWithCount(property.getOreMultiplier() * oreTypeMultiplier)); + builder.outputItems(crushedStack.copyWithCount(crushedCount)); } builder.save(provider); builder = MACERATOR_RECIPES .recipeBuilder("macerate_" + prefixString + material.getName() + "_ore_to_crushed_ore") - .inputItems(IntersectionIngredient.of(Ingredient.of(orePrefix.getItemTags(material).getFirst()), - Ingredient.of(orePrefix.getItemParentTags().getFirst()))) - .outputItems(crushedStack.copyWithCount(property.getOreMultiplier() * 2 * oreTypeMultiplier)) + .inputItems(inputStack) + .outputItems(crushedStack.copyWithCount(crushedCount * 2)) .chancedOutput(byproductStack, 1400, 0) .EUt(2) - .category(GTRecipeCategories.ORE_CRUSHING) - .duration(400); + .duration(400) + .category(GTRecipeCategories.ORE_CRUSHING); for (MaterialStack secondaryMaterial : orePrefix.secondaryMaterials()) { if (secondaryMaterial.material().hasProperty(PropertyKey.DUST)) { @@ -139,14 +140,10 @@ private static void processOre(@NotNull RecipeOutput provider, @NotNull TagPrefi if (!ingotStack.isEmpty() && doesMaterialUseNormalFurnace(smeltingMaterial) && !orePrefix.isIgnored(material)) { float xp = Math.round(((1 + oreTypeMultiplier * 0.5f) * 0.5f - 0.05f) * 10f) / 10f; VanillaRecipeHelper.addSmeltingRecipe(provider, - "smelt_" + prefixString + material.getName() + "_ore_to_ingot", - IntersectionIngredient.of(Ingredient.of(orePrefix.getItemTags(material).getFirst()), - Ingredient.of(orePrefix.getItemParentTags().getFirst())), + "smelt_" + prefixString + material.getName() + "_ore_to_ingot", inputStack, ingotStack, xp); VanillaRecipeHelper.addBlastingRecipe(provider, - "smelt_" + prefixString + material.getName() + "_ore_to_ingot", - IntersectionIngredient.of(Ingredient.of(orePrefix.getItemTags(material).getFirst()), - Ingredient.of(orePrefix.getItemParentTags().getFirst())), + "smelt_" + prefixString + material.getName() + "_ore_to_ingot", inputStack, ingotStack, xp); } } @@ -202,13 +199,6 @@ private static void processRawOre(@NotNull RecipeOutput provider, @NotNull OrePr .category(GTRecipeCategories.ORE_CRUSHING) .duration(400); - for (MaterialStack secondaryMaterial : ore.secondaryMaterials()) { - if (secondaryMaterial.material().hasProperty(PropertyKey.DUST)) { - ItemStack dustStack = ChemicalHelper.getGem(secondaryMaterial); - builder.chancedOutput(dustStack, 6700, 0); - } - } - builder.save(provider); } diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PartsRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PartsRecipeHandler.java index e564bc182d9..8ebe557cf32 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PartsRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PartsRecipeHandler.java @@ -390,7 +390,7 @@ private static void processRing(@NotNull RecipeOutput provider, @NotNull Materia if (!material.hasFlag(NO_SMASHING)) { VanillaRecipeHelper.addShapedRecipe(provider, String.format("ring_%s", material.getName()), ChemicalHelper.get(ring, material), - "h ", " X", + "h ", "fX", 'X', new MaterialEntry(rod, material)); } else { EXTRUDER_RECIPES.recipeBuilder("extrude_" + material.getName() + "_dust_to_ring") diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PipeRecipeHandler.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PipeRecipeHandler.java index 8025c113e04..8bc6f3d7e1c 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PipeRecipeHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/generated/PipeRecipeHandler.java @@ -87,6 +87,15 @@ private static void processPipeTiny(@NotNull RecipeOutput provider, @NotNull Pro .EUt(6L * getVoltageMultiplier(material)) .save(provider); + if (material.hasFluid()) { + FLUID_SOLIDFICATION_RECIPES.recipeBuilder("solidify_" + material.getName() + "_to_tiny_pipe") + .notConsumable(GTItems.SHAPE_MOLD_PIPE_TINY) + .inputFluids(material.getFluid(L / 2)) + .outputItems(pipeStack) + .duration((int) (material.getMass()) / 2) + .EUt(6L * getVoltageMultiplier(material)) + .save(provider); + } if (material.hasFlag(NO_SMASHING)) { EXTRUDER_RECIPES.recipeBuilder("extrude_" + material.getName() + "_tiny_pipe_dust") .inputItems(dust, material, 1) @@ -95,7 +104,7 @@ private static void processPipeTiny(@NotNull RecipeOutput provider, @NotNull Pro .duration((int) (material.getMass())) .EUt(6L * getVoltageMultiplier(material)) .save(provider); - } else { + } else if (plate.doGenerateItem(material)) { VanillaRecipeHelper.addShapedRecipe(provider, String.format("tiny_%s_pipe", material.getName()), pipeStack.copyWithCount(2), " s ", "hXw", 'X', new MaterialEntry(plate, material)); @@ -119,6 +128,15 @@ private static void processPipeSmall(@NotNull RecipeOutput provider, .EUt(6L * getVoltageMultiplier(material)) .save(provider); + if (material.hasFluid()) { + FLUID_SOLIDFICATION_RECIPES.recipeBuilder("solidify_" + material.getName() + "_to_small_pipe") + .notConsumable(GTItems.SHAPE_MOLD_PIPE_SMALL) + .inputFluids(material.getFluid(L)) + .outputItems(pipeStack) + .duration((int) (material.getMass())) + .EUt(6L * getVoltageMultiplier(material)) + .save(provider); + } if (material.hasFlag(NO_SMASHING)) { EXTRUDER_RECIPES.recipeBuilder("extrude_" + material.getName() + "_small_pipe_dust") .inputItems(dust, material, 1) @@ -127,7 +145,7 @@ private static void processPipeSmall(@NotNull RecipeOutput provider, .duration((int) (material.getMass())) .EUt(6L * getVoltageMultiplier(material)) .save(provider); - } else { + } else if (plate.doGenerateItem(material)) { VanillaRecipeHelper.addShapedRecipe(provider, String.format("small_%s_pipe", material.getName()), pipeStack, "wXh", 'X', new MaterialEntry(plate, material)); @@ -151,6 +169,15 @@ private static void processPipeNormal(@NotNull RecipeOutput provider, .EUt(6L * getVoltageMultiplier(material)) .save(provider); + if (material.hasFluid()) { + FLUID_SOLIDFICATION_RECIPES.recipeBuilder("solidify_" + material.getName() + "_to_normal_pipe") + .notConsumable(GTItems.SHAPE_MOLD_PIPE_NORMAL) + .inputFluids(material.getFluid(L * 3)) + .outputItems(pipeStack) + .duration((int) (material.getMass()) * 3) + .EUt(6L * getVoltageMultiplier(material)) + .save(provider); + } if (material.hasFlag(NO_SMASHING)) { EXTRUDER_RECIPES.recipeBuilder("extrude_" + material.getName() + "_pipe_dust") .inputItems(dust, material, 3) @@ -159,7 +186,7 @@ private static void processPipeNormal(@NotNull RecipeOutput provider, .duration((int) material.getMass() * 3) .EUt(6L * getVoltageMultiplier(material)) .save(provider); - } else { + } else if (plate.doGenerateItem(material)) { VanillaRecipeHelper.addShapedRecipe(provider, String.format("medium_%s_pipe", material.getName()), pipeStack, "XXX", "w h", 'X', new MaterialEntry(plate, material)); @@ -183,6 +210,15 @@ private static void processPipeLarge(@NotNull RecipeOutput provider, .EUt(6L * getVoltageMultiplier(material)) .save(provider); + if (material.hasFluid()) { + FLUID_SOLIDFICATION_RECIPES.recipeBuilder("solidify_" + material.getName() + "_to_large_pipe") + .notConsumable(GTItems.SHAPE_MOLD_PIPE_LARGE) + .inputFluids(material.getFluid(L * 6)) + .outputItems(pipeStack) + .duration((int) (material.getMass()) * 6) + .EUt(6L * getVoltageMultiplier(material)) + .save(provider); + } if (material.hasFlag(NO_SMASHING)) { EXTRUDER_RECIPES.recipeBuilder("extrude_" + material.getName() + "_large_pipe_dust") .inputItems(dust, material, 6) @@ -191,7 +227,7 @@ private static void processPipeLarge(@NotNull RecipeOutput provider, .duration((int) material.getMass() * 6) .EUt(6L * getVoltageMultiplier(material)) .save(provider); - } else { + } else if (plate.doGenerateItem(material)) { VanillaRecipeHelper.addShapedRecipe(provider, String.format("large_%s_pipe", material.getName()), pipeStack, "XXX", "w h", "XXX", 'X', new MaterialEntry(plate, material)); @@ -214,6 +250,15 @@ private static void processPipeHuge(@NotNull RecipeOutput provider, @NotNull Pro .EUt(6L * getVoltageMultiplier(material)) .save(provider); + if (material.hasFluid()) { + FLUID_SOLIDFICATION_RECIPES.recipeBuilder("solidify_" + material.getName() + "_to_huge_pipe") + .notConsumable(GTItems.SHAPE_MOLD_PIPE_HUGE) + .inputFluids(material.getFluid(L * 12)) + .outputItems(pipeStack) + .duration((int) (material.getMass()) * 24) + .EUt(6L * getVoltageMultiplier(material)) + .save(provider); + } if (material.hasFlag(NO_SMASHING)) { EXTRUDER_RECIPES.recipeBuilder("extrude_" + material.getName() + "_huge_pipe_dust") .inputItems(dust, material, 12) @@ -276,18 +321,22 @@ private static void processPipeNonuple(@NotNull RecipeOutput provider, } private static void addDuctRecipes(RecipeOutput provider, Material material, int outputAmount) { - VanillaRecipeHelper.addShapedRecipe(provider, "small_duct_%s".formatted(material.getName()), - GTBlocks.DUCT_PIPES[DuctPipeType.SMALL.ordinal()].asStack(outputAmount * 2), "w", "X", "h", - 'X', new MaterialEntry(plate, material)); - VanillaRecipeHelper.addShapedRecipe(provider, "medium_duct_%s".formatted(material.getName()), - GTBlocks.DUCT_PIPES[DuctPipeType.NORMAL.ordinal()].asStack(outputAmount), " X ", "wXh", " X ", - 'X', new MaterialEntry(plate, material)); - VanillaRecipeHelper.addShapedRecipe(provider, "large_duct_%s".formatted(material.getName()), - GTBlocks.DUCT_PIPES[DuctPipeType.LARGE.ordinal()].asStack(outputAmount), "XwX", "X X", "XhX", - 'X', new MaterialEntry(plate, material)); - VanillaRecipeHelper.addShapedRecipe(provider, "huge_duct_%s".formatted(material.getName()), - GTBlocks.DUCT_PIPES[DuctPipeType.HUGE.ordinal()].asStack(outputAmount), "XwX", "X X", "XhX", - 'X', new MaterialEntry(plateDouble, material)); + if (plate.doGenerateItem(material)) { + VanillaRecipeHelper.addShapedRecipe(provider, "small_duct_%s".formatted(material.getName()), + GTBlocks.DUCT_PIPES[DuctPipeType.SMALL.ordinal()].asStack(outputAmount * 2), "w", "X", "h", + 'X', new MaterialEntry(plate, material)); + VanillaRecipeHelper.addShapedRecipe(provider, "medium_duct_%s".formatted(material.getName()), + GTBlocks.DUCT_PIPES[DuctPipeType.NORMAL.ordinal()].asStack(outputAmount), " X ", "wXh", " X ", + 'X', new MaterialEntry(plate, material)); + VanillaRecipeHelper.addShapedRecipe(provider, "large_duct_%s".formatted(material.getName()), + GTBlocks.DUCT_PIPES[DuctPipeType.LARGE.ordinal()].asStack(outputAmount), "XwX", "X X", "XhX", + 'X', new MaterialEntry(plate, material)); + } + if (plateDouble.doGenerateItem(material)) { + VanillaRecipeHelper.addShapedRecipe(provider, "huge_duct_%s".formatted(material.getName()), + GTBlocks.DUCT_PIPES[DuctPipeType.HUGE.ordinal()].asStack(outputAmount), "XwX", "X X", "XhX", + 'X', new MaterialEntry(plateDouble, material)); + } } private static int getVoltageMultiplier(Material material) { diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComputerRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComputerRecipes.java index c813801a1b1..f024142c637 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComputerRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/ComputerRecipes.java @@ -20,6 +20,16 @@ public class ComputerRecipes { public static void init(RecipeOutput provider) { + ASSEMBLER_RECIPES.recipeBuilder("basic_data_access_hatch") + .inputItems(ITEM_IMPORT_BUS[HV]) + .inputItems(TOOL_DATA_STICK, 4) + .inputItems(CustomTags.HV_CIRCUITS, 4) + .outputItems(BASIC_DATA_ACCESS_HATCH) + .inputFluids(Polyethylene, L * 2) + .cleanroom(CleanroomType.CLEANROOM) + .duration(200).EUt(VA[HV]) + .addMaterialInfo(true).save(provider); + ASSEMBLER_RECIPES.recipeBuilder("data_access_hatch") .inputItems(ITEM_IMPORT_BUS[EV]) .inputItems(TOOL_DATA_STICK, 4) @@ -41,6 +51,54 @@ public static void init(RecipeOutput provider) { .duration(400).EUt(6000) .addMaterialInfo(true, true).save(provider); + // ASSEMBLER_RECIPES.recipeBuilder("wireless_transmitter_cover") + // .inputItems(plate, EnderPearl) + // .inputItems(foil, AnnealedCopper) + // .inputItems(EMITTER_MV) + // .inputItems(wireFine, Platinum) + // .inputFluids(SolderingAlloy, L) + // .outputItems(COVER_WIRELESS_TRANSMITTER) + // .duration(1000).EUt(VA[MV]) + // .addMaterialInfo(true).save(provider); + + ASSEMBLER_RECIPES.recipeBuilder("text_module") + .inputItems(PLASTIC_CIRCUIT_BOARD) + .inputItems(foil, Steel, 4) + .inputItems(wireFine, RedAlloy, 4) + .inputItems(CustomTags.MV_CIRCUITS) + .inputFluids(SolderingAlloy, L) + .outputItems(TEXT_MODULE) + .duration(1000).EUt(VA[MV]) + .addMaterialInfo(true).save(provider); + + ASSEMBLER_RECIPES.recipeBuilder("image_module") + .inputItems(PLASTIC_CIRCUIT_BOARD) + .inputItems(foil, Electrum, 4) + .inputItems(wireFine, Silver, 4) + .inputItems(CustomTags.MV_CIRCUITS) + .inputFluids(SolderingAlloy, L) + .outputItems(IMAGE_MODULE) + .duration(1000).EUt(VA[MV]) + .addMaterialInfo(true).save(provider); + + ASSEMBLER_RECIPES.recipeBuilder("monitor_casing") + .inputItems(HULL[MV]) + .inputItems(COVER_SCREEN) + .inputItems(plate, Glass, 4) + .inputItems(wireFine, RedAlloy, 4) + .inputFluids(Glowstone, L) + .outputItems(MONITOR, ConfigHolder.INSTANCE.recipes.casingsPerCraft) + .duration(1000).EUt(VA[MV]) + .addMaterialInfo(true).save(provider); + ASSEMBLER_RECIPES.recipeBuilder("advanced_monitor_casing") + .inputItems(MONITOR) + .inputItems(CustomTags.HV_CIRCUITS) + .inputItems(plate, StainlessSteel, 4) + .inputFluids(SolderingAlloy, L) + .outputItems(ADVANCED_MONITOR, 1) + .duration(1000).EUt(VA[HV]) + .addMaterialInfo(true).save(provider); + ASSEMBLER_RECIPES.recipeBuilder("high_power_casing") .inputItems(frameGt, Iridium) .inputItems(plate, Iridium, 6) diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/FuelRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/FuelRecipes.java index 6daa053b3a2..57a5912e479 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/FuelRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/FuelRecipes.java @@ -1,10 +1,21 @@ package com.gregtechceu.gtceu.data.recipe.misc; +import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.fluid.store.FluidStorageKeys; +import com.gregtechceu.gtceu.utils.GTUtil; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.data.recipes.RecipeOutput; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.entity.FurnaceBlockEntity; import net.minecraft.world.level.material.Fluids; import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.FluidUtil; + +import java.util.HashSet; +import java.util.Optional; +import java.util.Set; import static com.gregtechceu.gtceu.api.GTValues.*; import static com.gregtechceu.gtceu.data.material.GTMaterials.*; @@ -12,51 +23,91 @@ public class FuelRecipes { + public static void addBoilerFuel(RecipeOutput provider, Set added, + Item item, int burnTime) { + if (added.contains(item) || burnTime <= 0) { + return; + } + added.add(item); + + Optional containedFluid = FluidUtil.getFluidContained(item.getDefaultInstance()); + if (containedFluid.isEmpty()) { + ResourceLocation id = BuiltInRegistries.ITEM.getKey(item); + STEAM_BOILER_RECIPES.recipeBuilder(GTCEu.id(id.getNamespace() + "_" + id.getPath())) + .inputItems(item) + .duration(burnTime) + .save(provider); + } else { + FluidStack fluid = containedFluid.get().copyWithAmount(250); + ResourceLocation id = BuiltInRegistries.FLUID.getKey(fluid.getFluid()); + + // the lava recipe's duration is 4/9 of the bucket's burn time + // the creosote recipe's duration is 7/32 of the bucket's burn time + // as such, the mean ratio is 191/576, or approximately 1/3. + STEAM_BOILER_RECIPES.recipeBuilder(id.getNamespace() + "_" + id.getPath()) + .inputFluids(fluid) + .duration(burnTime / 3) + .save(provider); + } + } + public static void init(RecipeOutput provider) { - STEAM_BOILER_RECIPES.recipeBuilder("lava") + // TODO this all needs to be cleaned up, but this will make it somewhat work for now + // do these first because for some reason vanilla fuels are not set up yet at this phase? + Set addedItems = new HashSet<>(); + for (var fuelEntry : FurnaceBlockEntity.getFuel().entrySet()) { + addBoilerFuel(provider, addedItems, fuelEntry.getKey(), fuelEntry.getValue()); + } + for (Item item : BuiltInRegistries.ITEM) { + int burnTime = GTUtil.getItemBurnTime(item); + addBoilerFuel(provider, addedItems, item, burnTime); + } + + // override the default fluid recipes for lava and creosote + STEAM_BOILER_RECIPES.recipeBuilder("minecraft_lava") .inputFluids(new FluidStack(Fluids.LAVA, 100)) - .duration(600 * 12) + .duration(900) // 60s -> 45s Might still be too good with drip stone farming. .save(provider); - STEAM_BOILER_RECIPES.recipeBuilder("creosote") + STEAM_BOILER_RECIPES.recipeBuilder("gtceu_creosote") .inputFluids(Creosote.getFluid(250)) - .duration(600 * 12) + .duration(350) // 150s -> 17.5s .save(provider); - // semi-fluid fuels, like creosote - LARGE_BOILER_RECIPES.recipeBuilder("creosote") - .inputFluids(Creosote.getFluid(160)) - .duration(10) + // semi-fluid fuels, like creosote - these are awful and need to be scrutinized heavily... + LARGE_BOILER_RECIPES.recipeBuilder("gtceu_creosote") + .inputFluids(Creosote.getFluid(250)) + .duration(35) .save(provider); - LARGE_BOILER_RECIPES.recipeBuilder("biomass") + LARGE_BOILER_RECIPES.recipeBuilder("gtceu_biomass") .inputFluids(Biomass.getFluid(40)) - .duration(10) + .duration(85) .save(provider); - LARGE_BOILER_RECIPES.recipeBuilder("oil") + LARGE_BOILER_RECIPES.recipeBuilder("gtceu_oil") .inputFluids(Oil.getFluid(200)) - .duration(10) + .duration(50) .save(provider); - LARGE_BOILER_RECIPES.recipeBuilder("heavy_oil") + LARGE_BOILER_RECIPES.recipeBuilder("gtceu_oil_heavy") .inputFluids(HeavyOil.getFluid(32)) - .duration(10) + .duration(50) .save(provider); - LARGE_BOILER_RECIPES.recipeBuilder("sulfuric_heavy_fuel") + LARGE_BOILER_RECIPES.recipeBuilder("gtceu_sulfuric_heavy_fuel") .inputFluids(SulfuricHeavyFuel.getFluid(32)) - .duration(10) + .duration(50) .save(provider); - LARGE_BOILER_RECIPES.recipeBuilder("heavy_fuel") + LARGE_BOILER_RECIPES.recipeBuilder("gtceu_heavy_fuel") .inputFluids(HeavyFuel.getFluid(16)) - .duration(30) + .duration(90) .save(provider); - LARGE_BOILER_RECIPES.recipeBuilder("fish_oil") + LARGE_BOILER_RECIPES.recipeBuilder("gtceu_fish_oil") .inputFluids(FishOil.getFluid(160)) - .duration(10) + .duration(50) .save(provider); // diesel generator fuels diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MachineRecipeLoader.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MachineRecipeLoader.java index e9ba5493192..b810615fb27 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MachineRecipeLoader.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MachineRecipeLoader.java @@ -624,6 +624,30 @@ private static void registerAssemblerRecipes(RecipeOutput provider) { .addMaterialInfo(true, true) .save(provider); + ASSEMBLER_RECIPES.recipeBuilder("cover_ender_item_link") + .inputItems(plate, EnderPearl, 9) + .inputItems(plateDouble, StainlessSteel) + .inputItems(SENSOR_HV) + .inputItems(EMITTER_HV) + .inputItems(CONVEYOR_MODULE_HV) + .inputFluids(Polytetrafluoroethylene, L * 2) + .outputItems(COVER_ENDER_ITEM_LINK) + .EUt(VA[HV]).duration(320) + .addMaterialInfo(true, true) + .save(provider); + + ASSEMBLER_RECIPES.recipeBuilder("cover_ender_redstone_link") + .inputItems(plate, EnderPearl, 4) + .inputItems(plateDouble, Aluminium) + .inputItems(SENSOR_MV) + .inputItems(EMITTER_MV) + .inputItems(CustomTags.MV_CIRCUITS) + .inputFluids(SolderingAlloy, L * 2) + .outputItems(COVER_ENDER_REDSTONE_LINK) + .EUt(VA[MV]).duration(320) + .addMaterialInfo(true, true) + .save(provider); + ASSEMBLER_RECIPES.recipeBuilder("cover_storage") .inputItems(Tags.Items.CHESTS_WOODEN) .inputItems(ELECTRIC_PISTON_LV) @@ -758,7 +782,8 @@ private static void registerAssemblerRecipes(RecipeOutput provider) { .inputItems(rod, Bronze, 3) .inputItems(frameGt, Bronze) .inputItems(plate, Bronze, 3) - .outputItems(GTBlocks.FIREBOX_BRONZE, 2) + .outputItems(GTBlocks.FIREBOX_BRONZE, ConfigHolder.INSTANCE.recipes.casingsPerCraft) + .addMaterialInfo(true, true) .duration(100) .EUt(VA[LV]) .save(provider); @@ -766,7 +791,8 @@ private static void registerAssemblerRecipes(RecipeOutput provider) { .inputItems(rod, Steel, 3) .inputItems(frameGt, Steel) .inputItems(plate, Steel, 3) - .outputItems(GTBlocks.FIREBOX_STEEL, 2) + .outputItems(GTBlocks.FIREBOX_STEEL, ConfigHolder.INSTANCE.recipes.casingsPerCraft) + .addMaterialInfo(true, true) .duration(200) .EUt(VA[LV]) .save(provider); @@ -774,7 +800,8 @@ private static void registerAssemblerRecipes(RecipeOutput provider) { .inputItems(rod, Titanium, 3) .inputItems(frameGt, Titanium) .inputItems(plate, Titanium, 3) - .outputItems(GTBlocks.FIREBOX_TITANIUM, 2) + .outputItems(GTBlocks.FIREBOX_TITANIUM, ConfigHolder.INSTANCE.recipes.casingsPerCraft) + .addMaterialInfo(true, true) .duration(300) .EUt(VA[HV]) .save(provider); @@ -782,7 +809,8 @@ private static void registerAssemblerRecipes(RecipeOutput provider) { .inputItems(rod, TungstenSteel, 3) .inputItems(frameGt, TungstenSteel) .inputItems(plate, TungstenSteel, 3) - .outputItems(GTBlocks.FIREBOX_TUNGSTENSTEEL, 2) + .outputItems(GTBlocks.FIREBOX_TUNGSTENSTEEL, ConfigHolder.INSTANCE.recipes.casingsPerCraft) + .addMaterialInfo(true, true) .duration(400) .EUt(VA[EV]) .save(provider); diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityLoader.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityLoader.java index bcae1303730..8d39e320e5d 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityLoader.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityLoader.java @@ -141,21 +141,26 @@ public static void init(RecipeOutput provider) { "PIP", "IFI", "PIP", 'P', new MaterialEntry(TagPrefix.plate, GTMaterials.Polytetrafluoroethylene), 'F', new MaterialEntry(TagPrefix.frameGt, GTMaterials.Polytetrafluoroethylene), 'I', new MaterialEntry(TagPrefix.pipeNormalFluid, GTMaterials.Polytetrafluoroethylene)); - VanillaRecipeHelper.addShapedRecipe(provider, true, "casing_bronze_firebox", GTBlocks.FIREBOX_BRONZE.asStack(2), + // Decomposition info handled by the assembler recipe + VanillaRecipeHelper.addShapedRecipe(provider, false, "casing_bronze_firebox", + GTBlocks.FIREBOX_BRONZE.asStack(ConfigHolder.INSTANCE.recipes.casingsPerCraft), "PSP", "SFS", "PSP", 'P', new MaterialEntry(TagPrefix.plate, GTMaterials.Bronze), 'F', new MaterialEntry(TagPrefix.frameGt, GTMaterials.Bronze), 'S', new MaterialEntry(TagPrefix.rod, GTMaterials.Bronze)); - VanillaRecipeHelper.addShapedRecipe(provider, true, "casing_steel_firebox", GTBlocks.FIREBOX_STEEL.asStack(2), + VanillaRecipeHelper.addShapedRecipe(provider, false, "casing_steel_firebox", + GTBlocks.FIREBOX_STEEL.asStack(ConfigHolder.INSTANCE.recipes.casingsPerCraft), "PSP", "SFS", "PSP", 'P', new MaterialEntry(TagPrefix.plate, GTMaterials.Steel), 'F', new MaterialEntry(TagPrefix.frameGt, GTMaterials.Steel), 'S', new MaterialEntry(TagPrefix.rod, GTMaterials.Steel)); - VanillaRecipeHelper.addShapedRecipe(provider, true, "casing_titanium_firebox", - GTBlocks.FIREBOX_TITANIUM.asStack(2), "PSP", "SFS", "PSP", 'P', + VanillaRecipeHelper.addShapedRecipe(provider, false, "casing_titanium_firebox", + GTBlocks.FIREBOX_TITANIUM.asStack(ConfigHolder.INSTANCE.recipes.casingsPerCraft), "PSP", "SFS", "PSP", + 'P', new MaterialEntry(TagPrefix.plate, GTMaterials.Titanium), 'F', new MaterialEntry(TagPrefix.frameGt, GTMaterials.Titanium), 'S', new MaterialEntry(TagPrefix.rod, GTMaterials.Titanium)); - VanillaRecipeHelper.addShapedRecipe(provider, true, "casing_tungstensteel_firebox", - GTBlocks.FIREBOX_TUNGSTENSTEEL.asStack(2), "PSP", "SFS", "PSP", 'P', + VanillaRecipeHelper.addShapedRecipe(provider, false, "casing_tungstensteel_firebox", + GTBlocks.FIREBOX_TUNGSTENSTEEL.asStack(ConfigHolder.INSTANCE.recipes.casingsPerCraft), "PSP", "SFS", + "PSP", 'P', new MaterialEntry(TagPrefix.plate, GTMaterials.TungstenSteel), 'F', new MaterialEntry(TagPrefix.frameGt, GTMaterials.TungstenSteel), 'S', new MaterialEntry(TagPrefix.rod, GTMaterials.TungstenSteel)); @@ -205,75 +210,75 @@ public static void init(RecipeOutput provider) { GTBlocks.YELLOW_STRIPES_BLOCK_A.asStack(), "Y ", " M ", " B", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_small_yellow_stripes", - GTBlocks.YELLOW_STRIPES_BLOCK_B.asStack(), " Y", " M ", "B ", 'M', + GTBlocks.YELLOW_STRIPES_BLOCK_B.asStack(), "B ", " M ", " Y", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_radioactive_hazard", GTBlocks.RADIOACTIVE_HAZARD_SIGN_BLOCK.asStack(), " YB", " M ", " ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_bio_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_bio_hazard", GTBlocks.BIO_HAZARD_SIGN_BLOCK.asStack(), " Y ", " MB", " ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_explosion_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_explosion_hazard", GTBlocks.EXPLOSION_HAZARD_SIGN_BLOCK.asStack(), " Y ", " M ", " B", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_fire_hazard", GTBlocks.FIRE_HAZARD_SIGN_BLOCK.asStack(), " Y ", " M ", " B ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_acid_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_acid_hazard", GTBlocks.ACID_HAZARD_SIGN_BLOCK.asStack(), " Y ", " M ", "B ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_magic_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_magic_hazard", GTBlocks.MAGIC_HAZARD_SIGN_BLOCK.asStack(), " Y ", "BM ", " ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_frost_hazard", GTBlocks.FROST_HAZARD_SIGN_BLOCK.asStack(), "BY ", " M ", " ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_noise_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_noise_hazard", GTBlocks.NOISE_HAZARD_SIGN_BLOCK.asStack(), " ", " M ", "BY ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_generic_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_generic_hazard", GTBlocks.GENERIC_HAZARD_SIGN_BLOCK.asStack(), " ", "BM ", " Y ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_high_voltage_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_high_voltage_hazard", GTBlocks.HIGH_VOLTAGE_HAZARD_SIGN_BLOCK.asStack(), "B ", " M ", " Y ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_magnetic_hazard", GTBlocks.MAGNETIC_HAZARD_SIGN_BLOCK.asStack(), " B ", " M ", " Y ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_antimatter_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_antimatter_hazard", GTBlocks.ANTIMATTER_HAZARD_SIGN_BLOCK.asStack(), " B", " M ", " Y ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_high_temperature_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_high_temperature_hazard", GTBlocks.HIGH_TEMPERATURE_HAZARD_SIGN_BLOCK.asStack(), " ", " MB", " Y ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_void_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_void_hazard", GTBlocks.VOID_HAZARD_SIGN_BLOCK.asStack(), " ", " M ", " YB", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_mob_spawner_hazard", + VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_mob_spawner_hazard", GTBlocks.MOB_SPAWNER_HAZARD_SIGN_BLOCK.asStack(), "B ", "YM ", " ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_spatial_storage_hazard", + VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_spatial_storage_hazard", GTBlocks.SPATIAL_STORAGE_HAZARD_SIGN_BLOCK.asStack(), " B ", "YM ", " ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_laser_hazard", + VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_laser_hazard", GTBlocks.LASER_HAZARD_SIGN_BLOCK.asStack(), " B", "YM ", " ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_mob_hazard", + VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_mob_hazard", GTBlocks.MOB_INFESTATION_HAZARD_SIGN_BLOCK.asStack(), " ", "YMB", " ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_boss_hazard", + VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_boss_hazard", GTBlocks.BOSS_HAZARD_SIGN_BLOCK.asStack(), " ", "YM ", " B", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_gregification_hazard", + VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_sign_gregification_hazard", GTBlocks.GREGIFICATION_HAZARD_SIGN_BLOCK.asStack(), " ", "YM ", " B ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_causality_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_causality_hazard", GTBlocks.CAUSALITY_HAZARD_SIGN_BLOCK.asStack(), " ", "YM ", "B ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_turret_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_turret_hazard", GTBlocks.TURRET_HAZARD_SIGN_BLOCK.asStack(), " ", " MY", " B", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); - VanillaRecipeHelper.addShapedRecipe(provider, true, "warning_high_pressure_hazard", + VanillaRecipeHelper.addStrictShapedRecipe(provider, true, "warning_sign_high_pressure_hazard", GTBlocks.HIGH_PRESSURE_HAZARD_SIGN_BLOCK.asStack(), " ", " MY", " B ", 'M', GTBlocks.CASING_STEEL_SOLID.asStack(), 'Y', Tags.Items.DYES_YELLOW, 'B', Tags.Items.DYES_BLACK); @@ -561,19 +566,25 @@ public static void init(RecipeOutput provider) { 'R', new MaterialEntry(TagPrefix.rotor, GTMaterials.Iron), 'H', GTBlocks.BRONZE_BRICKS_HULL, 'F', Items.FLINT_AND_STEEL); + if (!ConfigHolder.INSTANCE.recipes.hardMultiRecipes) { VanillaRecipeHelper.addShapedRecipe(provider, true, "electric_blast_furnace", - GTMultiMachines.ELECTRIC_BLAST_FURNACE.asStack(), "FFF", "CMC", "WCW", 'M', - GTBlocks.CASING_INVAR_HEATPROOF.asStack(), 'F', Blocks.FURNACE.asItem(), 'C', - CustomTags.LV_CIRCUITS, + GTMultiMachines.ELECTRIC_BLAST_FURNACE.asStack(), + "FFF", "CMC", "WCW", + 'M', GTBlocks.CASING_INVAR_HEATPROOF.asStack(), + 'F', Blocks.BLAST_FURNACE.asItem(), + 'C', CustomTags.LV_CIRCUITS, 'W', new MaterialEntry(TagPrefix.cableGtSingle, GTMaterials.Tin)); } else { VanillaRecipeHelper.addShapedRecipe(provider, true, "electric_blast_furnace", - GTMultiMachines.ELECTRIC_BLAST_FURNACE.asStack(), "FFF", "CMC", "WCW", 'M', - GTBlocks.CASING_INVAR_HEATPROOF.asStack(), 'F', GTMachines.ELECTRIC_FURNACE[LV].asStack(), 'C', - CustomTags.LV_CIRCUITS, + GTMultiMachines.ELECTRIC_BLAST_FURNACE.asStack(), + "FFF", "CMC", "WCW", + 'M', GTBlocks.CASING_INVAR_HEATPROOF.asStack(), + 'F', GTMachines.ELECTRIC_FURNACE[LV].asStack(), + 'C', CustomTags.LV_CIRCUITS, 'W', new MaterialEntry(TagPrefix.cableGtSingle, GTMaterials.Tin)); } + VanillaRecipeHelper.addShapedRecipe(provider, true, "vacuum_freezer", GTMultiMachines.VACUUM_FREEZER.asStack(), "PPP", "CMC", "WCW", 'M', GTBlocks.CASING_ALUMINIUM_FROSTPROOF.asStack(), 'P', GTItems.ELECTRIC_PUMP_HV, 'C', CustomTags.EV_CIRCUITS, 'W', new MaterialEntry(TagPrefix.cableGtSingle, GTMaterials.Gold)); @@ -638,6 +649,11 @@ public static void init(RecipeOutput provider) { new MaterialEntry(TagPrefix.gear, GTMaterials.TungstenSteel), 'P', CustomTags.LuV_CIRCUITS, 'A', GTMachines.HULL[GTValues.LuV].asStack(), 'C', new MaterialEntry(TagPrefix.pipeLargeFluid, GTMaterials.TungstenSteel)); + VanillaRecipeHelper.addShapedRecipe(provider, true, "central_monitor", + GTMultiMachines.CENTRAL_MONITOR.asStack(), "CMC", "SAE", "FFF", 'C', + CustomTags.MV_CIRCUITS, 'M', GTItems.COVER_SCREEN, 'S', GTItems.SENSOR_MV, + 'A', GTMachines.HULL[GTValues.MV].asStack(), 'E', GTItems.EMITTER_MV, + 'F', GTBlocks.CASING_ALUMINIUM_FROSTPROOF.asStack()); VanillaRecipeHelper.addShapedRecipe(provider, true, "large_bronze_boiler", GTMultiMachines.LARGE_BOILER_BRONZE.asStack(), "PSP", "SAS", "PSP", 'P', @@ -744,6 +760,9 @@ public static void init(RecipeOutput provider) { VanillaRecipeHelper.addShapedRecipe(provider, true, "wood_multiblock_tank", GTMultiMachines.WOODEN_MULTIBLOCK_TANK.asStack(), " R ", "rCs", " R ", 'R', new MaterialEntry(TagPrefix.ring, GTMaterials.Copper), 'C', GTBlocks.CASING_WOOD_WALL.asStack()); + VanillaRecipeHelper.addShapedRecipe(provider, true, "bronze_multiblock_tank", + GTMultiMachines.BRONZE_MULTIBLOCK_TANK.asStack(), " R ", "hCw", " R ", 'R', + new MaterialEntry(TagPrefix.ring, GTMaterials.Bronze), 'C', GTBlocks.CASING_BRONZE_BRICKS.asStack()); VanillaRecipeHelper.addShapedRecipe(provider, true, "steel_multiblock_tank", GTMultiMachines.STEEL_MULTIBLOCK_TANK.asStack(), " R ", "hCw", " R ", 'R', new MaterialEntry(TagPrefix.ring, GTMaterials.Steel), 'C', GTBlocks.CASING_STEEL_SOLID.asStack()); @@ -751,6 +770,10 @@ public static void init(RecipeOutput provider) { GTMultiMachines.WOODEN_TANK_VALVE.asStack(), " R ", "rCs", " O ", 'O', new MaterialEntry(TagPrefix.rotor, GTMaterials.Copper), 'R', new MaterialEntry(TagPrefix.ring, GTMaterials.Copper), 'C', GTBlocks.CASING_WOOD_WALL.asStack()); + VanillaRecipeHelper.addShapedRecipe(provider, true, "bronze_tank_valve", + GTMultiMachines.BRONZE_TANK_VALVE.asStack(), + " R ", "hCw", " O ", 'O', new MaterialEntry(TagPrefix.rotor, GTMaterials.Bronze), 'R', + new MaterialEntry(TagPrefix.ring, GTMaterials.Bronze), 'C', GTBlocks.CASING_BRONZE_BRICKS); VanillaRecipeHelper.addShapedRecipe(provider, true, "steel_tank_valve", GTMultiMachines.STEEL_TANK_VALVE.asStack(), " R ", "hCw", " O ", 'O', new MaterialEntry(TagPrefix.rotor, GTMaterials.Steel), 'R', @@ -867,26 +890,11 @@ public static void init(RecipeOutput provider) { registerMachineRecipe(provider, ArrayUtils.subarray(GTMachines.DIODE, GTValues.LuV, GTMachines.DIODE.length), "CDC", "DHD", "PDP", 'H', HULL, 'D', GTItems.ADVANCED_SMD_DIODE, 'P', PLATE, 'C', CABLE_QUAD); - registerMachineRecipe(provider, ArrayUtils.subarray(GTMachines.TRANSFORMER, GTValues.ULV, GTValues.MV), " CC", - "TH ", " CC", 'C', CABLE, 'T', CABLE_TIER_UP, 'H', HULL); - registerMachineRecipe(provider, ArrayUtils.subarray(GTMachines.TRANSFORMER, GTValues.MV, GTValues.UHV), "WCC", - "TH ", "WCC", 'W', POWER_COMPONENT, 'C', CABLE, 'T', CABLE_TIER_UP, 'H', HULL); - registerMachineRecipe(provider, - ArrayUtils.subarray(GTMachines.HI_AMP_TRANSFORMER_2A, GTValues.ULV, GTValues.MV), " CC", "TH ", " CC", - 'C', CABLE_DOUBLE, 'T', CABLE_TIER_UP_DOUBLE, 'H', HULL); - registerMachineRecipe(provider, - ArrayUtils.subarray(GTMachines.HI_AMP_TRANSFORMER_2A, GTValues.MV, GTValues.UHV), "WCC", "TH ", "WCC", - 'W', POWER_COMPONENT, 'C', CABLE_DOUBLE, 'T', CABLE_TIER_UP_DOUBLE, 'H', HULL); - registerMachineRecipe(provider, - ArrayUtils.subarray(GTMachines.HI_AMP_TRANSFORMER_4A, GTValues.ULV, GTValues.MV), " CC", "TH ", " CC", - 'C', CABLE_QUAD, 'T', CABLE_TIER_UP_QUAD, 'H', HULL); - registerMachineRecipe(provider, - ArrayUtils.subarray(GTMachines.HI_AMP_TRANSFORMER_4A, GTValues.MV, GTValues.UHV), "WCC", "TH ", "WCC", - 'W', POWER_COMPONENT, 'C', CABLE_QUAD, 'T', CABLE_TIER_UP_QUAD, 'H', HULL); - registerMachineRecipe(provider, ArrayUtils.subarray(GTMachines.POWER_TRANSFORMER, GTValues.ULV, GTValues.MV), - " CC", "TH ", " CC", 'C', CABLE_HEX, 'T', CABLE_TIER_UP_HEX, 'H', HULL); - registerMachineRecipe(provider, ArrayUtils.subarray(GTMachines.POWER_TRANSFORMER, GTValues.MV, GTValues.UHV), - "WCC", "TH ", "WCC", 'W', POWER_COMPONENT, 'C', CABLE_HEX, 'T', CABLE_TIER_UP_HEX, 'H', HULL); + // Decomposition info handled by the assembler recipe + registerMachineRecipe(provider, false, ArrayUtils.subarray(GTMachines.TRANSFORMER, GTValues.ULV, GTValues.MV), + " CC", "TH ", " CC", 'C', CABLE, 'T', CABLE_TIER_UP, 'H', HULL); + registerMachineRecipe(provider, false, ArrayUtils.subarray(GTMachines.TRANSFORMER, GTValues.MV, GTValues.IV), + "WCC", "TH ", "WCC", 'W', POWER_COMPONENT, 'C', CABLE, 'T', CABLE_TIER_UP, 'H', HULL); registerMachineRecipe(provider, GTMachines.BATTERY_BUFFER_4, "WTW", "WMW", 'M', HULL, 'W', WIRE_QUAD, 'T', Tags.Items.CHESTS_WOODEN); diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityMachineRecipeLoader.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityMachineRecipeLoader.java index c4da164bd67..0e4a6a63f18 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityMachineRecipeLoader.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MetaTileEntityMachineRecipeLoader.java @@ -5,6 +5,7 @@ import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.material.material.stack.MaterialEntry; +import com.gregtechceu.gtceu.common.recipe.builder.GTRecipeBuilder; import com.gregtechceu.gtceu.data.machine.GTAEMachines; import com.gregtechceu.gtceu.data.machine.GTMultiMachines; import com.gregtechceu.gtceu.data.recipe.GTCraftingComponents; @@ -310,6 +311,72 @@ public static void init(RecipeOutput provider) { .EUt(VA[UV])) .duration(1000).EUt(VA[UHV]).save(provider); + // Transformers + for (int tier = 0; tier < TRANSFORMER.length; tier++) { + var transformer = TRANSFORMER[tier]; + if (transformer == null) continue; + + GTRecipeBuilder b = ASSEMBLER_RECIPES.recipeBuilder(VN[tier].toLowerCase(Locale.ROOT) + "_transformer") + .inputItems(GTCraftingComponents.HULL.get(tier)) + .inputItems(GTCraftingComponents.CABLE_TIER_UP.get(tier)) + .inputItems(GTCraftingComponents.CABLE.get(tier), 4) + .outputItems(transformer) + // Lower-tier recipes faster because they have crafting table equivalents + .duration(tier < IV ? 20 : 100) + .EUt(tier < GTValues.IV ? VA[LV] : VA[tier]) + .addMaterialInfo(true); + + if (tier >= MV) { + b.inputItems(GTCraftingComponents.POWER_COMPONENT.get(tier), 2); + } + + b.save(provider); + } + + // Hi-Amp (2x) Transformers + for (int tier = 0; tier < TRANSFORMER.length; tier++) { + var hiAmp = HI_AMP_TRANSFORMER_2A[tier]; + var lowAmp = TRANSFORMER[tier]; + if (hiAmp == null || lowAmp == null) continue; + + GTRecipeBuilder b = ASSEMBLER_RECIPES + .recipeBuilder(VN[tier].toLowerCase(Locale.ROOT) + "_hi_amp_2a_transformer") + .inputItems(lowAmp) + .inputItems(GTCraftingComponents.CABLE_TIER_UP_DOUBLE.get(tier)) + .inputItems(GTCraftingComponents.CABLE_DOUBLE.get(tier), 4) + .outputItems(hiAmp) + .duration(100).EUt(VA[tier]) + .addMaterialInfo(true); + + if (tier >= MV) { + b.inputItems(GTCraftingComponents.POWER_COMPONENT.get(tier), 2); + } + + b.save(provider); + } + + // Hi-Amp (4x) Transformers + for (int tier = 0; tier < TRANSFORMER.length; tier++) { + var hiAmp = HI_AMP_TRANSFORMER_4A[tier]; + var lowAmp = TRANSFORMER[tier]; + if (hiAmp == null || lowAmp == null) continue; + + GTRecipeBuilder b = ASSEMBLER_RECIPES + .recipeBuilder(VN[tier].toLowerCase(Locale.ROOT) + "_hi_amp_4a_transformer") + .inputItems(lowAmp) + .inputItems(GTCraftingComponents.CABLE_TIER_UP_QUAD.get(tier)) + .inputItems(GTCraftingComponents.CABLE_QUAD.get(tier), 4) + .outputItems(hiAmp) + .duration(100).EUt(VA[tier]) + .addMaterialInfo(true); + + if (tier >= MV) { + b.inputItems(GTCraftingComponents.POWER_COMPONENT.get(tier), 2); + } + + b.save(provider); + } + // Power Transformers for (int tier = 0; tier < POWER_TRANSFORMER.length; tier++) { var hatch = POWER_TRANSFORMER[tier]; diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MiscRecipeLoader.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MiscRecipeLoader.java index 62b9c01d373..72cb679efc3 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MiscRecipeLoader.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/MiscRecipeLoader.java @@ -12,6 +12,7 @@ import com.gregtechceu.gtceu.data.tag.CustomTags; import net.minecraft.data.recipes.RecipeOutput; +import net.minecraft.tags.FluidTags; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @@ -86,109 +87,97 @@ public static void init(RecipeOutput provider) { ROCK_BREAKER_RECIPES.recipeBuilder("cobblestone") .notConsumable(Blocks.COBBLESTONE.asItem()) .outputItems(Blocks.COBBLESTONE.asItem()) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VA[ULV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); ROCK_BREAKER_RECIPES.recipeBuilder("stone") .notConsumable(Blocks.STONE.asItem()) .outputItems(Blocks.STONE.asItem()) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VA[ULV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); ROCK_BREAKER_RECIPES.recipeBuilder("andesite") .notConsumable(Blocks.ANDESITE.asItem()) .outputItems(Blocks.ANDESITE.asItem()) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VHA[MV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); ROCK_BREAKER_RECIPES.recipeBuilder("granite") .notConsumable(Blocks.GRANITE.asItem()) .outputItems(Blocks.GRANITE.asItem()) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VHA[MV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); ROCK_BREAKER_RECIPES.recipeBuilder("diorite") .notConsumable(Blocks.DIORITE.asItem()) .outputItems(Blocks.DIORITE.asItem()) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VHA[MV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); ROCK_BREAKER_RECIPES.recipeBuilder("obsidian") .notConsumable(dust, Redstone) .outputItems(Blocks.OBSIDIAN.asItem()) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VHA[HV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); ROCK_BREAKER_RECIPES.recipeBuilder("basalt") .notConsumable(Blocks.BASALT.asItem()) .outputItems(Blocks.BASALT.asItem()) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VHA[HV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); ROCK_BREAKER_RECIPES.recipeBuilder("blackstone") .notConsumable(Blocks.BLACKSTONE.asItem()) .outputItems(Blocks.BLACKSTONE.asItem()) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VHA[HV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); ROCK_BREAKER_RECIPES.recipeBuilder("deepslate") .notConsumable(Blocks.DEEPSLATE.asItem()) .outputItems(Blocks.DEEPSLATE.asItem()) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VHA[EV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); ROCK_BREAKER_RECIPES.recipeBuilder("marble") .notConsumable(rock, Marble) .outputItems(rock, Marble) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VHA[HV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); ROCK_BREAKER_RECIPES.recipeBuilder("basalt") .notConsumable(rock, Basalt) .outputItems(rock, Basalt) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VHA[HV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); ROCK_BREAKER_RECIPES.recipeBuilder("red_granite") .notConsumable(rock, RedGranite) .outputItems(rock, RedGranite) + .adjacentFluidTag(FluidTags.LAVA, FluidTags.WATER) .duration(16) .EUt(VHA[EV]) - .addData("fluidA", "minecraft:lava") - .addData("fluidB", "minecraft:water") .save(provider); // Jetpacks @@ -632,5 +621,11 @@ public static void init(RecipeOutput provider) { .inputItems(Blocks.CHISELED_BOOKSHELF.asItem()) .outputItems(dust, Wood, 6) .duration(100).EUt(2).save(provider); + + // Lazurite and Sodalite to dye + VanillaRecipeHelper.addShapelessRecipe(provider, "lazurite_to_dye", new ItemStack(Items.BLUE_DYE), + new MaterialEntry(gem, Lazurite)); + VanillaRecipeHelper.addShapelessRecipe(provider, "sodalite_to_dye", new ItemStack(Items.BLUE_DYE), + new MaterialEntry(gem, Sodalite)); } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/RecyclingRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/RecyclingRecipes.java index d826111bd1b..ebc7c7070b4 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/RecyclingRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/RecyclingRecipes.java @@ -11,6 +11,7 @@ import com.gregtechceu.gtceu.api.material.material.stack.MaterialStack; import com.gregtechceu.gtceu.api.tag.TagPrefix; import com.gregtechceu.gtceu.common.recipe.builder.GTRecipeBuilder; +import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.material.GTMaterials; import com.gregtechceu.gtceu.data.recipe.GTRecipeCategories; import com.gregtechceu.gtceu.data.recipe.GTRecipeTypes; @@ -19,10 +20,10 @@ import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; -import net.minecraft.util.Tuple; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import com.mojang.datafixers.util.Pair; import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -68,10 +69,10 @@ public static void registerRecyclingRecipes(RecipeOutput provider, ItemStack inp // Calculate the voltage multiplier based on if a Material has a Blast Property int voltageMultiplier = calculateVoltageMultiplier(components); - if (prefix != TagPrefix.dust) { + if (prefix != TagPrefix.dust && ConfigHolder.INSTANCE.recipes.enableMaceratorRecycling) { registerMaceratorRecycling(provider, input, components, voltageMultiplier); } - if (prefix != null) { + if (prefix != null && ConfigHolder.INSTANCE.recipes.enableExtractorRecycling) { registerExtractorRecycling(provider, input, components, voltageMultiplier, prefix); } if (ignoreArcSmelting) return; @@ -96,16 +97,19 @@ public static void registerRecyclingRecipes(RecipeOutput provider, ItemStack inp return; } } - registerArcRecycling(provider, input, components, prefix); + if (ConfigHolder.INSTANCE.recipes.enableArcRecycling) { + registerArcRecycling(provider, input, components, prefix); + } } private static void registerMaceratorRecycling(RecipeOutput provider, ItemStack input, List materials, int multiplier) { // Finalize the output list. + final float maceratorYield = ConfigHolder.INSTANCE.recipes.maceratorRecyclingYield; List outputs = finalizeOutputs( materials, GTRecipeTypes.MACERATOR_RECIPES.getMaxOutputs(ItemRecipeCapability.CAP), - ChemicalHelper::getDust); + ChemicalHelper::getDust, maceratorYield); MaterialEntry entry = ChemicalHelper.getMaterialEntry(input.getItem()); TagKey inputTag = null; @@ -163,10 +167,10 @@ private static void registerExtractorRecycling(RecipeOutput provider, ItemStack if (prefix == TagPrefix.dust && m.hasProperty(PropertyKey.BLAST)) { return; } - + final float yield = ConfigHolder.INSTANCE.recipes.extractorRecyclingYield; ResourceLocation itemPath = BuiltInRegistries.ITEM.getKey(input.getItem()); GTRecipeBuilder builder = GTRecipeTypes.EXTRACTOR_RECIPES.recipeBuilder("extract_" + itemPath.getPath()) - .outputFluids(m.getFluid((int) (ms.amount() * L / M))) + .outputFluids(m.getFluid((int) (ms.amount() * yield * L / M))) .duration((int) Math.max(1, ms.amount() * ms.material().getMass() / M)) .EUt((long) GTValues.VA[GTValues.LV] * multiplier) .category(GTRecipeCategories.EXTRACTOR_RECYCLING); @@ -271,10 +275,11 @@ private static void registerArcRecycling(RecipeOutput provider, ItemStack input, .collect(Collectors.toList())); // Finalize the output List + final float arcYield = ConfigHolder.INSTANCE.recipes.arcRecyclingYield; List outputs = finalizeOutputs( materials, GTRecipeTypes.ARC_FURNACE_RECIPES.getMaxOutputs(ItemRecipeCapability.CAP), - RecyclingRecipes::getArcIngotOrDust); + RecyclingRecipes::getArcIngotOrDust, arcYield); // Exit if no valid outputs exist for this recycling Recipe. if (outputs.isEmpty()) return; @@ -435,14 +440,14 @@ private static List combineStacks(List rawList) { } private static List finalizeOutputs(List materials, int maxOutputs, - Function toItemStackMapper) { + Function toItemStackMapper, float yield) { // Map of ItemStack, Long to properly sort by the true material amount for outputs - List> outputs = new ArrayList<>(); + List> outputs = new ArrayList<>(); for (MaterialStack ms : materials) { ms = new MaterialStack(ms.material().hasFlag(IS_MAGNETIC) ? ms.material().getProperty(PropertyKey.INGOT).getMacerateInto() : ms.material(), ms.amount()); - ItemStack stack = toItemStackMapper.apply(ms); + ItemStack stack = toItemStackMapper.apply(ms.multiply(yield)); if (stack == ItemStack.EMPTY) continue; if (stack.getCount() > 64) { MaterialEntry entry = ChemicalHelper.getMaterialEntry(stack.getItem()); @@ -456,21 +461,23 @@ private static List finalizeOutputs(List materials, in } else { // Attempt to split and to shrink the stack, and choose the option that creates the // "larger" single stack, in terms of raw material amount. - List> split = new ArrayList<>(); - List> shrink = new ArrayList<>(); + List> split = new ArrayList<>(); + List> shrink = new ArrayList<>(); splitStacks(split, stack, entry); shrinkStacks(shrink, stack, entry); - if (split.getFirst().getB().amount() > shrink.getFirst().getB().amount()) { + if (split.getFirst().getSecond().amount() > shrink.getFirst().getSecond().amount()) { outputs.addAll(split); } else outputs.addAll(shrink); } } - } else outputs.add(new Tuple<>(stack, ms)); + } else { + outputs.add(new Pair<>(stack, ms)); + } } // Sort the List by total material amount descending. - outputs.sort(Comparator.comparingLong(e -> -e.getB().amount())); + outputs.sort(Comparator.comparingLong(e -> -e.getSecond().amount())); // Sort "duplicate" outputs to the end. // For example, if there are blocks of Steel and nuggets of Steel, and the nuggets @@ -479,19 +486,19 @@ private static List finalizeOutputs(List materials, in // // There is probably a better way to do this. Map temp = new HashMap<>(); - for (Tuple t : outputs) { + for (Pair t : outputs) { boolean isInMap = false; for (MaterialStack ms : temp.keySet()) { - if (ms.material() == t.getB().material()) { + if (ms.material() == t.getSecond().material()) { isInMap = true; break; } } - if (!isInMap) temp.put(t.getB(), t.getA()); + if (!isInMap) temp.put(t.getSecond(), t.getFirst()); } temp.putAll(outputs.stream() - .filter(t -> !temp.containsKey(t.getB())) - .collect(Collectors.toMap(Tuple::getB, Tuple::getA))); + .filter(t -> !temp.containsKey(t.getSecond())) + .collect(Collectors.toMap(Pair::getSecond, Pair::getFirst))); // Filter Ash to the very end of the list, after all others List ashStacks = temp.entrySet().stream() @@ -513,15 +520,15 @@ private static List finalizeOutputs(List materials, in return returnValues; } - private static void splitStacks(List> list, ItemStack originalStack, + private static void splitStacks(List> list, ItemStack originalStack, MaterialEntry entry) { int amount = originalStack.getCount(); while (amount > 64) { - list.add(new Tuple<>(originalStack.copyWithCount(64), + list.add(new Pair<>(originalStack.copyWithCount(64), new MaterialStack(entry.material(), entry.tagPrefix().getMaterialAmount(entry.material()) * 64))); amount -= 64; } - list.add(new Tuple<>(originalStack.copyWithCount(amount), + list.add(new Pair<>(originalStack.copyWithCount(amount), new MaterialStack(entry.material(), entry.tagPrefix().getMaterialAmount(entry.material()) * amount))); } @@ -530,7 +537,7 @@ private static void splitStacks(List> list, Item private static final List INGOT_ORDER = List.of(TagPrefix.block, TagPrefix.ingot, TagPrefix.nugget); - private static void shrinkStacks(List> list, ItemStack originalStack, + private static void shrinkStacks(List> list, ItemStack originalStack, MaterialEntry entry) { Material material = entry.material(); long materialAmount = originalStack.getCount() * entry.tagPrefix().getMaterialAmount(material); @@ -570,7 +577,7 @@ private static void shrinkStacks(List> list, Ite if (mediumMS != null && smallestMS != null) { long singleStackAmount = mediumMS.amount() + smallestMS.amount(); if (singleStackAmount / smallestPrefix.getMaterialAmount(material) <= 64) { - list.add(new Tuple<>( + list.add(new Pair<>( ChemicalHelper.get(smallestPrefix, material, (int) (singleStackAmount / smallestPrefix.getMaterialAmount(material))), new MaterialStack(material, singleStackAmount))); @@ -579,12 +586,12 @@ private static void shrinkStacks(List> list, Ite } // Otherwise simply add the stacks to the List if they exist - if (mediumMS != null) list.add(new Tuple<>( + if (mediumMS != null) list.add(new Pair<>( ChemicalHelper.get(mediumPrefix, material, (int) (mediumMS.amount() / mediumPrefix.getMaterialAmount(material))), new MaterialStack(material, mediumMS.amount()))); - if (smallestMS != null) list.add(new Tuple<>( + if (smallestMS != null) list.add(new Pair<>( ChemicalHelper.get(smallestPrefix, material, (int) (smallestMS.amount() / smallestPrefix.getMaterialAmount(material))), new MaterialStack(material, smallestMS.amount()))); diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/StoneMachineRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/StoneMachineRecipes.java index 5f37c511b10..7134ab95200 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/StoneMachineRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/StoneMachineRecipes.java @@ -201,6 +201,7 @@ private static List getDefaultEntries() { .stair(Items.POLISHED_BLACKSTONE_STAIRS) .wall(Items.POLISHED_BLACKSTONE_WALL) .pressurePlate(Items.POLISHED_BLACKSTONE_PRESSURE_PLATE) + .button(Items.POLISHED_BLACKSTONE_BUTTON) .material(GTMaterials.Blackstone) .registerAllMaterialInfo() .build(), @@ -208,7 +209,6 @@ private static List getDefaultEntries() { .stone(Items.POLISHED_BLACKSTONE_BRICKS) .slab(Items.POLISHED_BLACKSTONE_BRICK_SLAB) .stair(Items.POLISHED_BLACKSTONE_BRICK_STAIRS) - .button(Items.POLISHED_BLACKSTONE_BUTTON) .wall(Items.POLISHED_BLACKSTONE_BRICK_WALL) .material(GTMaterials.Blackstone) .registerAllMaterialInfo() @@ -523,14 +523,14 @@ private static void registerStoneRecipes(RecipeOutput provider) { public static void registerStoneTypeRecipes(RecipeOutput provider, @NotNull StoneTypeEntry entry) { if (entry.stone == null) { - GTCEu.LOGGER.error("could not find stone form of StoneTypeEntry, id: {}", entry.stoneName); + GTCEu.LOGGER.error("Could not find stone form of StoneTypeEntry, id: {}", entry.stoneName); return; } if (entry.polishedStone != null) { if (ConfigHolder.INSTANCE.recipes.removeVanillaBlockRecipes) { VanillaRecipeHelper.addShapedRecipe(provider, entry.stoneName + "_polish_hammer", - new ItemStack(entry.polishedStone), + new ItemStack(entry.polishedStone, 4), "hSS", " SS", 'S', entry.stone); } @@ -582,7 +582,7 @@ public static void registerStoneTypeRecipes(RecipeOutput provider, @NotNull Ston if (ConfigHolder.INSTANCE.recipes.removeVanillaBlockRecipes) { VanillaRecipeHelper.addShapedRecipe(provider, entry.stoneName + "_polished_hammer", new ItemStack(entry.chiselStone), - "mSd", " S ", " S ", + "mSd", " S ", 'S', entry.slab); } GTRecipeTypes.FORMING_PRESS_RECIPES.recipeBuilder("form_" + entry.stoneName + "_slab_into_pillar") @@ -594,15 +594,36 @@ public static void registerStoneTypeRecipes(RecipeOutput provider, @NotNull Ston } } + if (entry.pressurePlate != null) { + + if (ConfigHolder.INSTANCE.recipes.hardRedstoneRecipes && entry.slab != null) { + VanillaRecipeHelper.addShapedRecipe(provider, entry.stoneName + "_pressure_plate", + new ItemStack(entry.pressurePlate, 2), "ShS", "LCL", "SdS", + 'S', new MaterialEntry(TagPrefix.screw, GTMaterials.Iron), + 'L', entry.slab, + 'C', new MaterialEntry(TagPrefix.spring, GTMaterials.Iron)); + + ASSEMBLER_RECIPES.recipeBuilder(entry.stoneName + "_pressure_plate") + .inputItems(TagPrefix.spring, GTMaterials.Iron) + .inputItems(entry.stone, 2) + .outputItems(entry.pressurePlate, 2) + .duration(100) + .EUt(VA[ULV]) + .save(provider); + } else if (ConfigHolder.INSTANCE.recipes.removeVanillaBlockRecipes) { + + } + } + if (entry.button != null) { if (ConfigHolder.INSTANCE.recipes.hardRedstoneRecipes && entry.pressurePlate != null) { VanillaRecipeHelper.addShapedRecipe(provider, "stone_button", new ItemStack(entry.button, 6), "sP", 'P', entry.pressurePlate); } - if (entry.slab != null) { + if (entry.pressurePlate != null) { GTRecipeTypes.CUTTER_RECIPES.recipeBuilder("cut_" + entry.stoneName + "slab_into_button") - .inputItems(entry.slab) + .inputItems(entry.pressurePlate) .outputItems(entry.button, 3) .duration(60) .EUt(8) @@ -618,27 +639,6 @@ public static void registerStoneTypeRecipes(RecipeOutput provider, @NotNull Ston } } - if (entry.pressurePlate != null) { - - if (ConfigHolder.INSTANCE.recipes.hardRedstoneRecipes && entry.slab != null) { - VanillaRecipeHelper.addShapedRecipe(provider, entry.stoneName + "_pressure_plate", - new ItemStack(entry.pressurePlate, 2), "ShS", "LCL", "SdS", - 'S', new MaterialEntry(TagPrefix.screw, GTMaterials.Iron), - 'L', entry.slab, - 'C', new MaterialEntry(TagPrefix.spring, GTMaterials.Iron)); - - ASSEMBLER_RECIPES.recipeBuilder(entry.stoneName + "_pressure_plate") - .inputItems(TagPrefix.spring, GTMaterials.Iron) - .inputItems(entry.stone, 2) - .outputItems(entry.pressurePlate, 2) - .duration(100) - .EUt(VA[ULV]) - .save(provider); - } else if (ConfigHolder.INSTANCE.recipes.removeVanillaBlockRecipes) { - - } - } - if (entry.stair != null) { if (ConfigHolder.INSTANCE.recipes.removeVanillaBlockRecipes) { VanillaRecipeHelper.addShapedRecipe(provider, entry.stoneName + "_stair_saw", diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/WoodMachineRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/WoodMachineRecipes.java index 630e4264f26..1698f463096 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/WoodMachineRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/misc/WoodMachineRecipes.java @@ -13,6 +13,8 @@ import com.gregtechceu.gtceu.data.material.GTMaterials; import com.gregtechceu.gtceu.data.recipe.VanillaRecipeHelper; import com.gregtechceu.gtceu.data.recipe.WoodTypeEntry; +import com.gregtechceu.gtceu.integration.kjs.GTCEuStartupEvents; +import com.gregtechceu.gtceu.integration.kjs.events.RegisterWoodsKubeEvent; import net.minecraft.data.recipes.RecipeOutput; import net.minecraft.resources.ResourceLocation; @@ -25,6 +27,7 @@ import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.Consumer; @@ -44,6 +47,7 @@ public static void init(RecipeOutput provider) { } private static List DEFAULT_ENTRIES; + private static List CUSTOM_ENTRIES; private static List getDefaultEntries() { if (DEFAULT_ENTRIES == null) { @@ -306,7 +310,21 @@ private static List getDefaultEntries() { .registerMaterialInfo(false, true, true, true, true, true, true, true, true, true) .build()); } - return DEFAULT_ENTRIES; + if (CUSTOM_ENTRIES == null) { + if (GTCEu.Mods.isKubeJSLoaded()) { + CUSTOM_ENTRIES = new ArrayList(); + var evt = new RegisterWoodsKubeEvent(); + GTCEuStartupEvents.REGISTER_WOODS.post(evt); + CUSTOM_ENTRIES = new ArrayList(evt.woods); + } else { + CUSTOM_ENTRIES = List.of(); + } + } + + List entries = new ArrayList(); + entries.addAll(DEFAULT_ENTRIES); + entries.addAll(CUSTOM_ENTRIES); + return entries; } public static void registerMaterialInfo() { diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/DistillationRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/DistillationRecipes.java index f5b445f36d3..1ab1e006957 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/DistillationRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/DistillationRecipes.java @@ -19,8 +19,8 @@ public static void init(RecipeOutput provider) { DISTILLATION_RECIPES.recipeBuilder("distill_dilute_hcl") .inputFluids(DilutedHydrochloricAcid.getFluid(2000)) - .outputFluids(Water.getFluid(1000)) .outputFluids(HydrochloricAcid.getFluid(1000)) + .outputFluids(Water.getFluid(1000)) .duration(600).EUt(64).save(provider); DISTILLATION_RECIPES.recipeBuilder("distill_dilute_sulfuric") diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/SeparationRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/SeparationRecipes.java index 5fe630f8ccb..77fedf62362 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/SeparationRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/SeparationRecipes.java @@ -48,7 +48,7 @@ public static void init(RecipeOutput provider) { CENTRIFUGE_RECIPES.recipeBuilder("oilsands_ore_separation") .inputItems(ore, Oilsands) .chancedOutput(new ItemStack(Blocks.SAND), 7500, 0) - .outputFluids(Oil.getFluid(2000)) + .outputFluids(HeavyOil.getFluid(2000)) .duration(200).EUt(30).save(provider); CENTRIFUGE_RECIPES.recipeBuilder("oilsands_dust_separation") @@ -107,7 +107,7 @@ public static void init(RecipeOutput provider) { .outputFluids(Glue.getFluid(100)) .save(provider); - CENTRIFUGE_RECIPES.recipeBuilder("rubber_log_separation").duration(200).EUt(20) + CENTRIFUGE_RECIPES.recipeBuilder("rubber_log_separation").duration(200).EUt(5) .inputItems(GTBlocks.RUBBER_LOG.asStack()) .chancedOutput(STICKY_RESIN.asStack(), 6400, 0) .chancedOutput(PLANT_BALL.asStack(), 4000, 0) @@ -424,14 +424,6 @@ public static void init(RecipeOutput provider) { .outputFluids(Oxygen.getFluid(9000)) .duration(270).EUt(VA[LV] * 2L).save(provider); - ELECTROLYZER_RECIPES.recipeBuilder("zeolite_electrolysis") - .inputItems(dust, Zeolite, 41) - .outputItems(dust, Sodium) - .outputItems(dust, Calcium, 4) - .outputItems(dust, Silicon, 27) - .outputItems(dust, Aluminium, 9) - .duration(656).EUt(VA[MV]).save(provider); - ELECTROLYZER_RECIPES.recipeBuilder("bentonite_electrolysis") .inputItems(dust, Bentonite, 30) .outputItems(dust, Sodium) diff --git a/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/TitaniumRecipes.java b/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/TitaniumRecipes.java index 59ba7fbb248..9e1d080344f 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/TitaniumRecipes.java +++ b/src/main/java/com/gregtechceu/gtceu/data/recipe/serialized/chemistry/TitaniumRecipes.java @@ -69,7 +69,7 @@ private static void solvayProcess(RecipeOutput provider) { // NaCl(H2O) + CO2 + NH3 -> NH4Cl + NaHCO3 CHEMICAL_RECIPES.recipeBuilder("sodium_bicarbonate_from_salt") - .inputItems(dust, Salt, 4) + .inputItems(dust, Salt, 2) .inputFluids(CarbonDioxide.getFluid(1000)) .inputFluids(Ammonia.getFluid(1000)) .inputFluids(Water.getFluid(1000)) @@ -136,8 +136,8 @@ private static void bauxiteProcess(RecipeOutput provider) { ELECTROMAGNETIC_SEPARATOR_RECIPES.recipeBuilder("bauxite_slag_separation") .inputItems(dust, BauxiteSlag) .outputItems(dust, Salt) - .chancedOutput(dust, Neodymium, 2000, 250) - .chancedOutput(dust, Chromium, 1000, 250) + .chancedOutput(dust, Neodymium, 2000, 0) + .chancedOutput(dust, Chromium, 1000, 0) .duration(50).EUt(VA[MV]).save(provider); // Bauxite Sludge -> Calcite (looped) + Decalcified Bauxite Sludge @@ -152,11 +152,11 @@ private static void bauxiteProcess(RecipeOutput provider) { CENTRIFUGE_RECIPES.recipeBuilder("bauxite_sludge_centrifuge") .inputFluids(DecalcifiedBauxiteSludge.getFluid(250)) .outputItems(dust, Rutile, 2) - .chancedOutput(dust, Gallium, 5000, 550) - .chancedOutput(dust, Gallium, 3000, 800) - .chancedOutput(dust, Gallium, 1000, 1000) - .chancedOutput(dust, SiliconDioxide, 9000, 250) - .chancedOutput(dust, Iron, 8000, 250) + .chancedOutput(dust, Gallium, 5000, 0) + .chancedOutput(dust, Gallium, 3000, 0) + .chancedOutput(dust, Gallium, 1000, 0) + .chancedOutput(dust, SiliconDioxide, 9000, 0) + .chancedOutput(dust, Iron, 8000, 0) .outputFluids(Water.getFluid(250)) .duration(100).EUt(VA[MV]).save(provider); } diff --git a/src/main/java/com/gregtechceu/gtceu/data/tag/CustomTags.java b/src/main/java/com/gregtechceu/gtceu/data/tag/CustomTags.java index 54c7c831e78..0b6cc856dc7 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/tag/CustomTags.java +++ b/src/main/java/com/gregtechceu/gtceu/data/tag/CustomTags.java @@ -3,6 +3,7 @@ import com.gregtechceu.gtceu.api.tag.TagUtil; import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.BlockTags; import net.minecraft.tags.TagKey; import net.minecraft.world.entity.EntityType; @@ -127,6 +128,8 @@ public class CustomTags { public static final TagKey CHEM_BATH_WASHABLE = TagUtil.createModItemTag("chemical_bath_washable"); + public static final TagKey SKIP_ITEM_DETECTOR = TagUtil.createModItemTag("skip_item_detector"); + // Mineability tags public static final TagKey MINEABLE_WITH_WRENCH = TagUtil.createBlockTag("mineable/wrench"); public static final TagKey MINEABLE_WITH_WIRE_CUTTER = TagUtil.createBlockTag("mineable/wire_cutter"); @@ -148,6 +151,7 @@ public class CustomTags { .createModBlockTag("incorrect_for_neutronium_tool"); // Tool tags + public static final TagKey TOOLS_IGNITER = TagUtil.createItemTag("tools/igniter"); public static final TagKey TOOLS_BUTCHERY_KNIFE = TagUtil.createItemTag("tools/butchery_knife"); public static final TagKey TOOLS_BUZZSAW = TagUtil.createItemTag("tools/buzzsaw"); public static final TagKey TOOLS_CHAINSAW = TagUtil.createItemTag("tools/chainsaw"); @@ -203,9 +207,18 @@ public class CustomTags { }; public static final TagKey ENDSTONE_ORE_REPLACEABLES = TagUtil.createBlockTag("end_stone_ore_replaceables"); + public static final TagKey CONCRETE_BLOCK = TagUtil.createBlockTag("concretes"); + public static final TagKey VERY_FAST_WALKABLE_BLOCKS = TagUtil.createBlockTag("very_fast_walkable_blocks"); + public static final TagKey FAST_WALKABLE_BLOCKS = TagUtil.createBlockTag("fast_walkable_blocks"); + public static final TagKey SLOW_WALKABLE_BLOCKS = TagUtil.createBlockTag("slow_walkable_blocks"); + public static final TagKey CONCRETE_POWDER_BLOCK = TagUtil.createBlockTag("concrete_powders"); public static final TagKey CLEANROOM_FLOORS = TagUtil.createModBlockTag("cleanroom_floors"); public static final TagKey CHARCOAL_PILE_IGNITER_WALLS = TagUtil.createModBlockTag( "charcoal_pile_igniter_walls"); + public static final TagKey CREATE_WRENCH_PICKUP = TagUtil.optionalTag(Registries.BLOCK, + ResourceLocation.fromNamespaceAndPath("create", "wrench_pickup")); + + public static final TagKey TALL_PLANTS = TagUtil.createModBlockTag("tall_plants"); public static final TagKey HAS_RUBBER_TREE = TagUtil.createModTag(Registries.BIOME, "has_rubber_tree"); @@ -222,4 +235,6 @@ public class CustomTags { public static final TagKey MOLTEN_FLUIDS = TagUtil.createFluidTag("molten"); public static final TagKey LIQUID_FLUIDS = TagUtil.createFluidTag("liquid"); public static final TagKey PLASMA_FLUIDS = TagUtil.createFluidTag("plasmatic"); + + public static final TagKey HPCA_COOLANTS = TagUtil.createModFluidTag("hpca_coolants"); } diff --git a/src/main/java/com/gregtechceu/gtceu/data/tools/GTToolBehaviors.java b/src/main/java/com/gregtechceu/gtceu/data/tools/GTToolBehaviors.java index 1bfcdf4d882..514b46d921e 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/tools/GTToolBehaviors.java +++ b/src/main/java/com/gregtechceu/gtceu/data/tools/GTToolBehaviors.java @@ -42,6 +42,8 @@ private GTToolBehaviors() {} GTCEu.id("wax_off"), new ToolBehaviorType<>(WaxOffBehavior.CODEC, WaxOffBehavior.STREAM_CODEC)); public static final ToolBehaviorType MODE_SWITCH = GTRegistries.register(GTRegistries.TOOL_BEHAVIORS, GTCEu.id("mode_switch"), new ToolBehaviorType<>(ToolModeSwitchBehavior.CODEC, ToolModeSwitchBehavior.STREAM_CODEC)); + public static final ToolBehaviorType PROSPECTING = GTRegistries.register(GTRegistries.TOOL_BEHAVIORS, + GTCEu.id("prospecting"), new ToolBehaviorType<>(ProspectingBehavior.CODEC, ProspectingBehavior.STREAM_CODEC)); // spotless:on public static void init() {} } diff --git a/src/main/java/com/gregtechceu/gtceu/data/tools/GTToolTiers.java b/src/main/java/com/gregtechceu/gtceu/data/tools/GTToolTiers.java index 17399776e8d..6ff75a39e73 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/tools/GTToolTiers.java +++ b/src/main/java/com/gregtechceu/gtceu/data/tools/GTToolTiers.java @@ -9,6 +9,8 @@ import net.minecraft.world.item.crafting.Ingredient; import net.neoforged.neoforge.common.SimpleTier; +import java.util.Objects; + @SuppressWarnings({ "unused", "FieldCanBeLocal" }) public class GTToolTiers { @@ -17,8 +19,10 @@ public class GTToolTiers { public static void init() { DURANIUM = new SimpleTier(CustomTags.INCORRECT_FOR_DURANIUM_TOOL, 8193, 14.0F, 12.0F, 33, - () -> Ingredient.of(ChemicalHelper.getTag(TagPrefix.ingot, GTMaterials.Duranium))); + () -> Ingredient + .of(Objects.requireNonNull(ChemicalHelper.getTag(TagPrefix.ingot, GTMaterials.Duranium)))); NEUTRONIUM = new SimpleTier(CustomTags.INCORRECT_FOR_NEUTRONIUM_TOOL, 65536, 180.0F, 100.0F, 33, - () -> Ingredient.of(ChemicalHelper.getTag(TagPrefix.ingot, GTMaterials.Neutronium))); + () -> Ingredient + .of(Objects.requireNonNull(ChemicalHelper.getTag(TagPrefix.ingot, GTMaterials.Neutronium)))); } } diff --git a/src/main/java/com/gregtechceu/gtceu/data/worldgen/GTOreVeins.java b/src/main/java/com/gregtechceu/gtceu/data/worldgen/GTOreVeins.java index ff55324c70a..d9861549bfb 100644 --- a/src/main/java/com/gregtechceu/gtceu/data/worldgen/GTOreVeins.java +++ b/src/main/java/com/gregtechceu/gtceu/data/worldgen/GTOreVeins.java @@ -457,7 +457,6 @@ public static void bootstrap(BootstrapContext context) { .biomes(BiomeTags.IS_OVERWORLD) .layeredVeinGenerator(generator -> generator .withLayerPattern(() -> GTLayerPattern.builder(stoneRules) - .layer(l -> l.weight(3).mat(Coal).size(2, 4)) .layer(l -> l.weight(3).mat(Coal).size(2, 4)) .build())) .surfaceIndicatorGenerator(indicator -> indicator diff --git a/src/main/java/com/gregtechceu/gtceu/forge/CommonEventListener.java b/src/main/java/com/gregtechceu/gtceu/forge/CommonEventListener.java index ac68d902dae..b458918e134 100644 --- a/src/main/java/com/gregtechceu/gtceu/forge/CommonEventListener.java +++ b/src/main/java/com/gregtechceu/gtceu/forge/CommonEventListener.java @@ -1,6 +1,7 @@ package com.gregtechceu.gtceu.forge; import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.block.BlockAttributes; import com.gregtechceu.gtceu.api.block.MetaMachineBlock; import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; import com.gregtechceu.gtceu.api.capability.IElectricItem; @@ -29,6 +30,7 @@ import com.gregtechceu.gtceu.common.item.armor.IStepAssist; import com.gregtechceu.gtceu.common.item.armor.QuarkTechSuite; import com.gregtechceu.gtceu.common.item.behavior.ToggleEnergyConsumerBehavior; +import com.gregtechceu.gtceu.common.item.datacomponents.FormatStringList; import com.gregtechceu.gtceu.common.machine.owner.MachineOwner; import com.gregtechceu.gtceu.common.network.packets.SPacketSendWorldID; import com.gregtechceu.gtceu.common.network.packets.hazard.SPacketAddHazardZone; @@ -44,8 +46,10 @@ import com.gregtechceu.gtceu.integration.map.ClientCacheManager; import com.gregtechceu.gtceu.integration.map.WaypointManager; import com.gregtechceu.gtceu.integration.map.cache.server.ServerCache; +import com.gregtechceu.gtceu.utils.GTStringUtils; import com.gregtechceu.gtceu.utils.TaskHandler; +import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.Difficulty; @@ -54,6 +58,7 @@ import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.ai.attributes.AttributeInstance; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.monster.Zombie; import net.minecraft.world.entity.player.Player; @@ -260,15 +265,14 @@ public static void onPlayerJoinServer(PlayerEvent.PlayerLoggedInEvent event) { if (player instanceof ServerPlayer serverPlayer) { PacketDistributor.sendToPlayer(serverPlayer, new SPacketSendWorldID()); - if (!ConfigHolder.INSTANCE.gameplay.environmentalHazards) - return; - - ServerLevel level = serverPlayer.serverLevel(); - var data = EnvironmentalHazardSavedData.getOrCreate(level); - PacketDistributor.sendToPlayer(serverPlayer, new SPacketSyncLevelHazards(data.getHazardZones())); + if (ConfigHolder.INSTANCE.gameplay.environmentalHazards) { + ServerLevel level = serverPlayer.serverLevel(); + var data = EnvironmentalHazardSavedData.getOrCreate(level); + PacketDistributor.sendToPlayer(serverPlayer, new SPacketSyncLevelHazards(data.getHazardZones())); + } + CapeRegistry.detectNewCapes(serverPlayer); + CapeRegistry.loadCurrentCapesOnLogin(serverPlayer); } - CapeRegistry.detectNewCapes(player); - CapeRegistry.loadCurrentCapesOnLogin(player); } @SubscribeEvent(priority = EventPriority.LOW) @@ -381,9 +385,72 @@ public static void onTooltipEvent(ItemTooltipEvent event) { public static void onAttributeTooltipEvent(AddAttributeTooltipsEvent event) { ItemStack stack = event.getStack(); + if (stack.has(GTDataComponents.BINDING_DATA)) { + stack.addToTooltip(GTDataComponents.BINDING_DATA, event.getContext(), + event::addTooltipLines, event.getContext().flag()); + } + if (stack.has(GTDataComponents.COMPUTER_MONITOR_CONFIG)) { + stack.addToTooltip(GTDataComponents.COMPUTER_MONITOR_CONFIG, event.getContext(), + event::addTooltipLines, event.getContext().flag()); + } + if (stack.has(GTDataComponents.COMPUTER_MONITOR_DATA)) { + FormatStringList list = stack.getOrDefault(GTDataComponents.COMPUTER_MONITOR_DATA, FormatStringList.EMPTY); + event.addTooltipLines(Component.translatable("gtceu.tooltip.computer_monitor_data", + GTStringUtils.toCompactedComponent(list.lines()))); + } if (!stack.has(GTDataComponents.DATA_COPY_POS)) { stack.addToTooltip(GTDataComponents.RESEARCH_ITEM, event.getContext(), event::addTooltipLines, event.getContext().flag()); } } + + @SubscribeEvent + public static void breakSpeed(PlayerEvent.BreakSpeed event) { + Player player = event.getEntity(); + for (ItemStack stack : player.getArmorSlots()) { + if (stack.getItem() instanceof ArmorComponentItem componentItem) { + if (componentItem.getArmorLogic() instanceof IJetpack jetpack && jetpack.removeMiningSpeedPenalty()) { + if (!player.onGround() || player.isUnderWater()) event.setNewSpeed(event.getOriginalSpeed() * 5); + } + } + } + } + + @SubscribeEvent + public static void playerTickEvent(PlayerTickEvent.Pre event) { + Player player = event.getEntity(); + if (!player.level().isClientSide) { + var speedAttrib = player.getAttribute(Attributes.MOVEMENT_SPEED); + if (speedAttrib == null) return; + var speedMod = speedAttrib.getModifier(BlockAttributes.BLOCK_SPEED_BOOST); + + float speedBoost = 0.0f; + if (!player.onGround() || player.isInWater() || player.isCrouching()) { + speedBoost = 0.0f; + } else { + var state = player.level().getBlockState(player.getOnPos()); + if (state.is(CustomTags.VERY_FAST_WALKABLE_BLOCKS)) { + speedBoost = 0.6f; // value that is added to the base MC speed + } else if (state.is(CustomTags.FAST_WALKABLE_BLOCKS)) { + speedBoost = 0.25f; // slower to walk on studs + } else if (state.is(CustomTags.SLOW_WALKABLE_BLOCKS)) { + speedBoost = -0.20f; // slower on frames + } + } + if (speedMod != null) { + if (speedBoost == speedMod.amount()) { + return; + } else { + speedAttrib.removeModifier(BlockAttributes.BLOCK_SPEED_BOOST); + } + } else { + if (speedBoost == 0.0f) return; + } + if (speedBoost != 0.0f) { + speedAttrib.addTransientModifier( + new AttributeModifier(BlockAttributes.BLOCK_SPEED_BOOST, + speedBoost, AttributeModifier.Operation.ADD_MULTIPLIED_BASE)); + } + } + } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/GTAEPlaceholders.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/GTAEPlaceholders.java new file mode 100644 index 00000000000..75784a5a998 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/GTAEPlaceholders.java @@ -0,0 +1,243 @@ +package com.gregtechceu.gtceu.integration.ae2; + +import com.gregtechceu.gtceu.api.cover.filter.ItemFilter; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.placeholder.*; +import com.gregtechceu.gtceu.api.placeholder.exceptions.*; +import com.gregtechceu.gtceu.utils.GTStringUtils; + +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.material.Fluid; +import net.neoforged.neoforge.fluids.FluidStack; + +import appeng.api.networking.GridHelper; +import appeng.api.networking.IGrid; +import appeng.api.networking.IGridNode; +import appeng.api.networking.IInWorldGridNodeHost; +import appeng.api.networking.crafting.CraftingJobStatus; +import appeng.api.networking.crafting.ICraftingCPU; +import appeng.api.networking.crafting.ICraftingService; +import appeng.api.stacks.AEFluidKey; +import appeng.api.stacks.AEItemKey; +import appeng.api.stacks.GenericStack; +import appeng.api.stacks.KeyCounter; +import appeng.me.helpers.IGridConnectedBlockEntity; +import org.jetbrains.annotations.Nullable; +import org.joml.Vector3i; + +import java.util.List; + +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class GTAEPlaceholders { + + private GTAEPlaceholders() {} + + private static IGrid getGrid(PlaceholderContext ctx) throws PlaceholderException { + if (ctx.pos() == null) throw new NotSupportedException(); + IInWorldGridNodeHost nodeHost = GridHelper.getNodeHost(ctx.level(), ctx.pos()); + if (nodeHost != null) { + IGridNode node = nodeHost.getGridNode(ctx.side()); + if (node != null) return node.getGrid(); + } ; + BlockEntity blockEntity = ctx.level().getBlockEntity(ctx.pos()); + if (blockEntity instanceof IMachineBlockEntity machineBlockEntity) { + if (machineBlockEntity.getMetaMachine() instanceof IGridConnectedBlockEntity gridMachine) { + IGrid nullable = gridMachine.getMainNode().getGrid(); + if (nullable == null) throw new NoMENetworkException(); + return nullable; + } + } + if (blockEntity instanceof IGridConnectedBlockEntity gridBlockEntity) { + IGridNode node = gridBlockEntity.getGridNode(); + if (node != null) return gridBlockEntity.getGridNode().getGrid(); + } + throw new NoMENetworkException(); + } + + private static long countItems(String id, IGrid grid) { + var key = ResourceLocation.parse(id); + if (key == null) return 0; + if (!BuiltInRegistries.ITEM.containsKey(key)) return 0; + Item item = BuiltInRegistries.ITEM.get(key); + GenericStack stack = GenericStack.fromItemStack(new ItemStack(item, 1)); + if (stack == null) return 0; + return grid.getStorageService().getInventory().getAvailableStacks().get(stack.what()); + } + + private static long countItems(@Nullable ItemFilter filter, IGrid grid) { + KeyCounter stacks = grid.getStorageService().getCachedInventory(); + long count = 0; + for (var stack : stacks) { + if (stack.getKey() instanceof AEItemKey && + (filter == null || filter.test(stack.getKey().wrapForDisplayOrFilter()))) + count += stack.getLongValue(); + } + return count; + } + + private static long countFluids(@Nullable String id, IGrid grid) { + if (id == null) { + KeyCounter stacks = grid.getStorageService().getCachedInventory(); + long count = 0; + for (var stack : stacks) { + if (stack.getKey() instanceof AEFluidKey) count += stack.getLongValue(); + } + return count; + } + var fluidId = ResourceLocation.parse(id); + if (!BuiltInRegistries.FLUID.containsKey(fluidId)) return 0; + Fluid fluid = BuiltInRegistries.FLUID.get(fluidId); + GenericStack stack = GenericStack.fromFluidStack(new FluidStack(fluid, 1)); + if (stack == null) return 0; + return grid.getStorageService().getInventory().getAvailableStacks().get(stack.what()); + } + + private static Vector3i getSpatialSize(IGrid grid) { + BlockPos start = grid.getSpatialService().getMin(); + BlockPos end = grid.getSpatialService().getMax(); + BlockPos tmp = end.subtract(start); + return new Vector3i(tmp.getX(), tmp.getY(), tmp.getZ()).absolute(); + } + + public static void init() { + PlaceholderHandler.addPlaceholder(new Placeholder("ae2itemCount") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + IGrid grid = getGrid(ctx); + if (args.isEmpty()) return MultiLineComponent.literal(countItems((ItemFilter) null, grid)); + if (args.size() == 1) + return MultiLineComponent.literal(countItems(GTStringUtils.componentsToString(args.get(0)), grid)); + if (GTStringUtils.equals(args.get(0), "filter")) { + int slot = PlaceholderUtils.toInt(args.get(1)); + try { + PlaceholderUtils.checkRange("slot index", 1, 8, slot); + if (ctx.itemStackHandler() == null) throw new NotSupportedException(); + return MultiLineComponent.literal(countItems( + ItemFilter.loadFilter(ctx.itemStackHandler().getStackInSlot(slot - 1)), grid)); + } catch (NullPointerException e) { + throw new MissingItemException("filter", slot); + } + } + throw new InvalidArgsException(); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("ae2fluidCount") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + IGrid grid = getGrid(ctx); + if (args.isEmpty()) return MultiLineComponent.literal(countFluids(null, grid)); + if (args.size() == 1) + return MultiLineComponent.literal(countFluids(GTStringUtils.componentsToString(args.get(0)), grid)); + throw new WrongNumberOfArgsException(1, args.size()); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("ae2power") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + IGrid grid = getGrid(ctx); + PlaceholderUtils.checkArgs(args, 0); + return MultiLineComponent.literal(grid.getEnergyService().getStoredPower()); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("ae2maxPower") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + IGrid grid = getGrid(ctx); + PlaceholderUtils.checkArgs(args, 0); + return MultiLineComponent.literal(grid.getEnergyService().getMaxStoredPower()); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("ae2powerUsage") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + IGrid grid = getGrid(ctx); + PlaceholderUtils.checkArgs(args, 0); + return MultiLineComponent.literal(grid.getEnergyService().getAvgPowerUsage()); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("ae2spatial") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + IGrid grid = getGrid(ctx); + PlaceholderUtils.checkArgs(args, 1); + if (GTStringUtils.equals(args.get(0), "power")) { + return MultiLineComponent.literal(grid.getSpatialService().requiredPower()); + } else if (GTStringUtils.equals(args.get(0), "efficiency")) { + return MultiLineComponent.literal(grid.getSpatialService().currentEfficiency()); + } else if (GTStringUtils.equals(args.get(0), "sizeX")) { + return MultiLineComponent.literal(getSpatialSize(grid).x); + } else if (GTStringUtils.equals(args.get(0), "sizeY")) { + return MultiLineComponent.literal(getSpatialSize(grid).y); + } else if (GTStringUtils.equals(args.get(0), "sizeZ")) { + return MultiLineComponent.literal(getSpatialSize(grid).z); + } else throw new InvalidArgsException(); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("ae2crafting") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + IGrid grid = getGrid(ctx); + PlaceholderUtils.checkArgs(args, 1, true); + ICraftingService crafting = grid.getCraftingService(); + if (GTStringUtils.equals(args.get(0), "get")) { + if (GTStringUtils.equals(args.get(1), "amount")) + return MultiLineComponent.literal(crafting.getCpus().size()); + int index = PlaceholderUtils.toInt(args.get(1)); + int i = 0; + for (ICraftingCPU cpu : crafting.getCpus()) { + if (index - 1 == i) { + CraftingJobStatus job = cpu.getJobStatus(); + if (GTStringUtils.equals(args.get(2), "storage")) + return MultiLineComponent.literal(cpu.getAvailableStorage()); + else if (GTStringUtils.equals(args.get(2), "threads")) + return MultiLineComponent.literal(cpu.getCoProcessors()); + else if (GTStringUtils.equals(args.get(2), "name")) + return MultiLineComponent + .of(cpu.getName() == null ? Component.literal("Crafting CPU " + i) : + cpu.getName().copy()); + else if (GTStringUtils.equals(args.get(2), "selectionMode")) + return MultiLineComponent.literal(cpu.getSelectionMode().name()); + else if (job == null) return MultiLineComponent.literal(0); + else if (GTStringUtils.equals(args.get(2), "amount")) + return MultiLineComponent.literal(job.crafting().amount()); + else if (GTStringUtils.equals(args.get(2), "item")) + return MultiLineComponent.of(job.crafting().what().getDisplayName().copy()); + else if (GTStringUtils.equals(args.get(2), "progress")) + return MultiLineComponent.literal(job.progress()); + else if (GTStringUtils.equals(args.get(2), "time")) + return MultiLineComponent.literal(job.elapsedTimeNanos()); + else throw new InvalidArgsException(); + } + i++; + } + throw new OutOfRangeException("cpu number", 1, crafting.getCpus().size(), index); + } // else if (GTStringUtils.equals(args.get(0), "request")) {} gonna implement that someday :) + throw new InvalidArgsException(); + } + }); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java index ca469b0a96d..9268274deb5 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEPatternBufferPartMachine.java @@ -496,9 +496,16 @@ public List getItems() { public List getFluids() { if (fluidStacks == null) { + // <<<<<<< HEAD fluidStacks = fluidInventory.object2LongEntrySet().stream() .map(e -> e.getKey().copyWithAmount(GTMath.saturatedCast(e.getLongValue()))) .toList(); + // ======= + // fluidStacks = new ArrayList<>(); + // fluidInventory.object2LongEntrySet().stream() + // .map(e -> GTMath.splitFluidStacks(e.getKey(), e.getLongValue())) + // .forEach(fluidStacks::addAll); + // >>>>>>> v7.1.3-1.20.1 } return fluidStacks; } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingBusPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingBusPartMachine.java index 16db4c7463b..59ada0134db 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingBusPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingBusPartMachine.java @@ -1,12 +1,15 @@ package com.gregtechceu.gtceu.integration.ae2.machine; import com.gregtechceu.gtceu.api.gui.fancy.ConfiguratorPanel; +import com.gregtechceu.gtceu.api.gui.fancy.TabsWidget; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.fancyconfigurator.AutoStockingFancyConfigurator; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; import com.gregtechceu.gtceu.common.item.behavior.IntCircuitBehaviour; +import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.integration.ae2.machine.feature.multiblock.IMEStockingPart; import com.gregtechceu.gtceu.integration.ae2.slot.ExportOnlyAEItemList; import com.gregtechceu.gtceu.integration.ae2.slot.ExportOnlyAEItemSlot; @@ -14,6 +17,7 @@ import com.gregtechceu.gtceu.integration.ae2.slot.IConfigurableSlotList; import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; +import com.lowdragmc.lowdraglib.syncdata.annotation.DropSaved; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; @@ -52,6 +56,17 @@ public class MEStockingBusPartMachine extends MEInputBusPartMachine implements I @Getter private boolean autoPull; + @Getter + @Setter + @Persisted + @DropSaved + private int minStackSize = 1; + @Getter + @Setter + @Persisted + @DropSaved + private int ticksPerCycle = 40; + @Setter private Predicate autoPullTest; @@ -94,8 +109,12 @@ public ManagedFieldHolder getFieldHolder() { @Override public void autoIO() { super.autoIO(); - if (autoPull && getOffsetTimer() % 100 == 0) { - refreshList(); + if (ticksPerCycle == 0) ticksPerCycle = ConfigHolder.INSTANCE.compat.ae2.updateIntervals; // Emergency Check to + // Avoid Crash loops. + if (getOffsetTimer() % ticksPerCycle == 0) { + if (autoPull) { + refreshList(); + } syncME(); } } @@ -111,7 +130,7 @@ protected void syncME() { // Try to fill the slot var key = config.what(); long extracted = networkInv.extract(key, Long.MAX_VALUE, Actionable.SIMULATE, actionSource); - if (extracted > 0) { + if (extracted >= minStackSize) { slot.setStock(new GenericStack(key, extracted)); continue; } @@ -120,6 +139,11 @@ protected void syncME() { } } + @Override + public void attachSideTabs(TabsWidget sideTabs) { + sideTabs.setMainTab(this); // removes the cover configurator, it's pointless and clashes with layout. + } + @Override protected void flushInventory() { // no-op, nothing to send back to the network @@ -196,7 +220,6 @@ private void refreshList() { for (Object2LongMap.Entry entry : counter) { long amount = entry.getLongValue(); - if (!topItems.isEmpty() && amount < topItems.peek().getLongValue()) continue; AEKey what = entry.getKey(); if (amount <= 0) continue; @@ -207,12 +230,13 @@ private void refreshList() { // Ensure that it is valid to configure with this stack if (autoPullTest != null && !autoPullTest.test(new GenericStack(itemKey, amount))) continue; - - if (topItems.size() < CONFIG_SIZE) { - topItems.offer(entry); - } else if (amount > topItems.peek().getLongValue()) { - topItems.poll(); - topItems.offer(entry); + if (amount >= minStackSize) { + if (topItems.size() < CONFIG_SIZE) { + topItems.offer(entry); + } else if (amount > topItems.peek().getLongValue()) { + topItems.poll(); + topItems.offer(entry); + } } } @@ -247,6 +271,7 @@ private void refreshList() { public void attachConfigurators(ConfiguratorPanel configuratorPanel) { IMEStockingPart.super.attachConfigurators(configuratorPanel); super.attachConfigurators(configuratorPanel); + configuratorPanel.attachConfigurators(new AutoStockingFancyConfigurator(this)); } @Override diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingHatchPartMachine.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingHatchPartMachine.java index def41b84d24..b534c59ae18 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingHatchPartMachine.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/MEStockingHatchPartMachine.java @@ -1,12 +1,15 @@ package com.gregtechceu.gtceu.integration.ae2.machine; import com.gregtechceu.gtceu.api.gui.fancy.ConfiguratorPanel; +import com.gregtechceu.gtceu.api.gui.fancy.TabsWidget; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.fancyconfigurator.AutoStockingFancyConfigurator; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiController; import com.gregtechceu.gtceu.api.machine.feature.multiblock.IMultiPart; import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; import com.gregtechceu.gtceu.common.item.behavior.IntCircuitBehaviour; +import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.integration.ae2.machine.feature.multiblock.IMEStockingPart; import com.gregtechceu.gtceu.integration.ae2.slot.ExportOnlyAEFluidList; import com.gregtechceu.gtceu.integration.ae2.slot.ExportOnlyAEFluidSlot; @@ -15,6 +18,7 @@ import com.gregtechceu.gtceu.integration.ae2.utils.AEUtil; import com.lowdragmc.lowdraglib.syncdata.annotation.DescSynced; +import com.lowdragmc.lowdraglib.syncdata.annotation.DropSaved; import com.lowdragmc.lowdraglib.syncdata.annotation.Persisted; import com.lowdragmc.lowdraglib.syncdata.field.ManagedFieldHolder; @@ -56,6 +60,18 @@ public class MEStockingHatchPartMachine extends MEInputHatchPartMachine implemen @Getter private boolean autoPull; + @Getter + @Setter + @Persisted + @DropSaved + private int minStackSize = 1; + + @Getter + @Setter + @Persisted + @DropSaved + private int ticksPerCycle = 40; + @Setter private Predicate autoPullTest; @@ -98,8 +114,12 @@ public ManagedFieldHolder getFieldHolder() { @Override public void autoIO() { super.autoIO(); - if (autoPull && getOffsetTimer() % 100 == 0) { - refreshList(); + if (ticksPerCycle == 0) ticksPerCycle = ConfigHolder.INSTANCE.compat.ae2.updateIntervals; // Emergency Check to + // Avoid Crash loops. + if (getOffsetTimer() % ticksPerCycle == 0) { + if (autoPull) { + refreshList(); + } syncME(); } } @@ -113,7 +133,7 @@ protected void syncME() { // Try to fill the slot var key = config.what(); long extracted = networkInv.extract(key, Long.MAX_VALUE, Actionable.SIMULATE, actionSource); - if (extracted > 0) { + if (extracted >= minStackSize) { slot.setStock(new GenericStack(key, extracted)); continue; } @@ -122,6 +142,11 @@ protected void syncME() { } } + @Override + public void attachSideTabs(TabsWidget sideTabs) { + sideTabs.setMainTab(this); // removes the cover configurator, it's pointless and clashes with layout. + } + @Override protected void flushInventory() { // no-op, nothing to send back to the network @@ -180,8 +205,6 @@ private void refreshList() { for (Object2LongMap.Entry entry : counter) { long amount = entry.getLongValue(); - if (!topFluids.isEmpty() && amount < topFluids.peek().getLongValue()) continue; - AEKey what = entry.getKey(); if (amount <= 0) continue; @@ -192,12 +215,13 @@ private void refreshList() { // Ensure that it is valid to configure with this stack if (autoPullTest != null && !autoPullTest.test(new GenericStack(fluidKey, amount))) continue; - - if (topFluids.size() < CONFIG_SIZE) { - topFluids.offer(entry); - } else if (amount > topFluids.peek().getLongValue()) { - topFluids.poll(); - topFluids.offer(entry); + if (amount >= minStackSize) { + if (topFluids.size() < CONFIG_SIZE) { + topFluids.offer(entry); + } else if (amount > topFluids.peek().getLongValue()) { + topFluids.poll(); + topFluids.offer(entry); + } } } @@ -231,6 +255,7 @@ private void refreshList() { public void attachConfigurators(ConfiguratorPanel configuratorPanel) { IMEStockingPart.super.attachConfigurators(configuratorPanel); super.attachConfigurators(configuratorPanel); + configuratorPanel.attachConfigurators(new AutoStockingFancyConfigurator(this)); } //////////////////////////////// diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/feature/multiblock/IMEStockingPart.java b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/feature/multiblock/IMEStockingPart.java index c54b79a102e..75515fcaaab 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/feature/multiblock/IMEStockingPart.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ae2/machine/feature/multiblock/IMEStockingPart.java @@ -56,4 +56,12 @@ default void validateConfig() { } } } + + int getMinStackSize(); + + void setMinStackSize(int newSize); + + int getTicksPerCycle(); + + void setTicksPerCycle(int newSize); } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/CCTweakedPlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/CCTweakedPlugin.java index 5cfca095c81..bd2aa58acfe 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/CCTweakedPlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/CCTweakedPlugin.java @@ -1,19 +1,42 @@ package com.gregtechceu.gtceu.integration.cctweaked; import com.gregtechceu.gtceu.api.capability.GTCapability; +import com.gregtechceu.gtceu.api.placeholder.*; +import com.gregtechceu.gtceu.api.placeholder.exceptions.NotSupportedException; +import com.gregtechceu.gtceu.api.placeholder.exceptions.PlaceholderException; import com.gregtechceu.gtceu.integration.cctweaked.peripherals.*; import dan200.computercraft.api.ComputerCraftAPI; import dan200.computercraft.api.ForgeComputerCraftAPI; +import java.util.List; + public class CCTweakedPlugin { public static void init() { ComputerCraftAPI.registerGenericSource(new ControllablePeripheral()); ComputerCraftAPI.registerGenericSource(new EnergyInfoPeripheral()); + ComputerCraftAPI.registerGenericSource(new TurbineMachinePeripheral()); ComputerCraftAPI.registerGenericSource(new WorkablePeripheral()); + ComputerCraftAPI.registerGenericSource(new CoverHolderPeripheral()); + ComputerCraftAPI.registerGenericSource(new CentralMonitorPeripheral()); ForgeComputerCraftAPI.registerGenericCapability(GTCapability.CAPABILITY_CONTROLLABLE); ForgeComputerCraftAPI.registerGenericCapability(GTCapability.CAPABILITY_ENERGY_INFO_PROVIDER); + ForgeComputerCraftAPI.registerGenericCapability(GTCapability.CAPABILITY_TURBINE_MACHINE); ForgeComputerCraftAPI.registerGenericCapability(GTCapability.CAPABILITY_WORKABLE); + ForgeComputerCraftAPI.registerGenericCapability(GTCapability.CAPABILITY_COVERABLE); + ForgeComputerCraftAPI.registerGenericCapability(GTCapability.CAPABILITY_CENTRAL_MONITOR); + PlaceholderHandler.addPlaceholder(new Placeholder("bufferText") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + if (!(ctx.cover() instanceof IPlaceholderInfoProviderCover cover)) throw new NotSupportedException(); + int i = PlaceholderUtils.toInt(args.get(0)); + PlaceholderUtils.checkRange("line number", 1, 100, i); + return MultiLineComponent.of(cover.getComputerCraftTextBuffer().get(i - 1)); + } + }); } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/peripherals/CentralMonitorPeripheral.java b/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/peripherals/CentralMonitorPeripheral.java new file mode 100644 index 00000000000..62105f05bb0 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/peripherals/CentralMonitorPeripheral.java @@ -0,0 +1,119 @@ +package com.gregtechceu.gtceu.integration.cctweaked.peripherals; + +import com.gregtechceu.gtceu.api.capability.ICentralMonitor; +import com.gregtechceu.gtceu.api.item.ComponentItem; +import com.gregtechceu.gtceu.api.item.component.IItemComponent; +import com.gregtechceu.gtceu.api.item.component.IMonitorModuleItem; +import com.gregtechceu.gtceu.common.item.modules.ImageModuleBehaviour; +import com.gregtechceu.gtceu.common.item.modules.TextModuleBehaviour; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; + +import net.minecraft.world.item.ItemStack; + +import dan200.computercraft.api.lua.*; +import dan200.computercraft.api.peripheral.GenericPeripheral; +import org.jetbrains.annotations.Nullable; + +public class CentralMonitorPeripheral implements GenericPeripheral { + + @Override + public String id() { + return "gtceu:central_monitor"; + } + + @LuaFunction + public static MethodResult getGroups(ICentralMonitor centralMonitor) { + return MethodResult.of(centralMonitor.getMonitorGroups().stream().map(LuaMonitorGroup::new).toList()); + } + + public static class LuaMonitorGroup { + + private final MonitorGroup group; + + public LuaMonitorGroup(MonitorGroup group) { + this.group = group; + } + + @LuaFunction + public String getName() { + return group.getName(); + } + + @LuaFunction + public LuaMonitorModule getModule() { + return new LuaMonitorModule(group.getItemStackHandler().getStackInSlot(0)); + } + + // TODO item transfer (setModule, etc.) + } + + public static class LuaMonitorModule { + + private final ItemStack stack; + + public LuaMonitorModule(ItemStack stack) { + this.stack = stack; + } + + private @Nullable IMonitorModuleItem getModuleItem() { + if (stack.getItem() instanceof ComponentItem componentItem) { + for (IItemComponent component : componentItem.getComponents()) { + if (component instanceof IMonitorModuleItem moduleItem) { + return moduleItem; + } + } + } + return null; + } + + @LuaFunction + public String getType() { + if (stack.isEmpty()) return "none"; + IMonitorModuleItem moduleItem = getModuleItem(); + if (moduleItem != null) return moduleItem.getType(); + return "invalid"; + } + + @LuaFunction + public MethodResult getCurrentText() { + if (getModuleItem() instanceof TextModuleBehaviour textModule) { + return MethodResult.of(textModule.getText(stack).toString()); + } else return MethodResult.of(); + } + + @LuaFunction + public void setPlaceholderText(String text) { + if (getModuleItem() instanceof TextModuleBehaviour textModule) { + textModule.setPlaceholderText(stack, text); + } + } + + @LuaFunction + public MethodResult getScale() { + if (getModuleItem() instanceof TextModuleBehaviour textModule) { + return MethodResult.of(textModule.getScale(stack)); + } else return MethodResult.of(); + } + + @LuaFunction + public void setScale(double scale) { + if (getModuleItem() instanceof TextModuleBehaviour textModule) { + textModule.setScale(stack, scale); + } + } + + @LuaFunction + public MethodResult getImageUrl() { + if (getModuleItem() instanceof ImageModuleBehaviour imageModule) { + return MethodResult.of(imageModule.getUrl(stack)); + } else return MethodResult.of(); + } + + @LuaFunction + public void setImageUrl(String url) { + if (getModuleItem() instanceof ImageModuleBehaviour imageModule) { + imageModule.setUrl(stack, url); + } + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/peripherals/CoverHolderPeripheral.java b/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/peripherals/CoverHolderPeripheral.java new file mode 100644 index 00000000000..dc6024d4214 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/peripherals/CoverHolderPeripheral.java @@ -0,0 +1,50 @@ +package com.gregtechceu.gtceu.integration.cctweaked.peripherals; + +import com.gregtechceu.gtceu.api.capability.ICoverable; +import com.gregtechceu.gtceu.api.placeholder.IPlaceholderInfoProviderCover; +import com.gregtechceu.gtceu.api.placeholder.MultiLineComponent; +import com.gregtechceu.gtceu.api.placeholder.PlaceholderContext; +import com.gregtechceu.gtceu.api.placeholder.PlaceholderHandler; +import com.gregtechceu.gtceu.common.cover.ComputerMonitorCover; + +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; + +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.lua.MethodResult; +import dan200.computercraft.api.peripheral.GenericPeripheral; + +public class CoverHolderPeripheral implements GenericPeripheral { + + @Override + public String id() { + return "gtceu:coverable"; + } + + @LuaFunction + public static MethodResult setBufferedText(ICoverable coverable, String face, int line, String text) { + Direction direction = Direction.byName(face); + if (direction == null) return MethodResult.of(false, "invalid face"); + if (line < 1 || line > 100) return MethodResult.of(false, "line must be from 1 to 100 (inclusive)"); + if (coverable.getCoverAtSide(direction) instanceof IPlaceholderInfoProviderCover cover) { + cover.setComputerCraftTextBufferLine(line - 1, Component.literal(text)); + return MethodResult.of(true, "success"); + } else return MethodResult.of(false, "invalid cover"); + } + + @LuaFunction + public static MethodResult parsePlaceholders(ICoverable coverable, String face, String text) { + Direction direction = Direction.byName(face); + if (direction == null) return MethodResult.of(false, "invalid face"); + if (coverable.getCoverAtSide(direction) instanceof ComputerMonitorCover cover) { + return MethodResult.of(true, PlaceholderHandler.processPlaceholders(text, new PlaceholderContext( + coverable.getLevel(), + coverable.getPos(), + direction, + cover.itemHandler, + cover, + new MultiLineComponent(cover.getText()), + cover.getPlaceholderUUID())).toString()); + } else return MethodResult.of(false, "invalid cover"); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/peripherals/TurbineMachinePeripheral.java b/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/peripherals/TurbineMachinePeripheral.java new file mode 100644 index 00000000000..555d17301a2 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/cctweaked/peripherals/TurbineMachinePeripheral.java @@ -0,0 +1,49 @@ +package com.gregtechceu.gtceu.integration.cctweaked.peripherals; + +import com.gregtechceu.gtceu.api.capability.ITurbineMachine; + +import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.lua.MethodResult; +import dan200.computercraft.api.peripheral.GenericPeripheral; + +public class TurbineMachinePeripheral implements GenericPeripheral { + + public String id() { + return "gtceu:large_turbine"; + } + + @LuaFunction + public static MethodResult hasRotor(ITurbineMachine turbine) { + return MethodResult.of(turbine.hasRotor()); + } + + @LuaFunction + public static MethodResult getRotorSpeed(ITurbineMachine turbine) { + return MethodResult.of(turbine.getRotorSpeed()); + } + + @LuaFunction + public static MethodResult getMaxRotorHolderSpeed(ITurbineMachine turbine) { + return MethodResult.of(turbine.getMaxRotorHolderSpeed()); + } + + @LuaFunction + public static MethodResult getTotalEfficiency(ITurbineMachine turbine) { + return MethodResult.of(turbine.getTotalEfficiency()); + } + + @LuaFunction + public static MethodResult getCurrentProduction(ITurbineMachine turbine) { + return MethodResult.of(turbine.getCurrentProduction()); + } + + @LuaFunction + public static MethodResult getOverclockVoltage(ITurbineMachine turbine) { + return MethodResult.of(turbine.getOverclockVoltage()); + } + + @LuaFunction + public static MethodResult getRotorDurabilityPercent(ITurbineMachine turbine) { + return MethodResult.of(turbine.getRotorDurabilityPercent()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/create/GTCreateDisplaySources.java b/src/main/java/com/gregtechceu/gtceu/integration/create/GTCreateDisplaySources.java new file mode 100644 index 00000000000..891dcf41910 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/create/GTCreateDisplaySources.java @@ -0,0 +1,34 @@ +package com.gregtechceu.gtceu.integration.create; + +import com.gregtechceu.gtceu.api.registry.GTRegistries; +import com.gregtechceu.gtceu.api.registry.registrate.GTRegistrate; +import com.gregtechceu.gtceu.common.registry.GTRegistration; +import com.gregtechceu.gtceu.integration.create.display.ComputerMonitorCoverDisplaySource; + +import net.minecraft.core.registries.Registries; + +import com.simibubi.create.api.behaviour.display.DisplaySource; +import com.simibubi.create.api.registry.registrate.SimpleBuilder; +import com.tterrag.registrate.util.entry.RegistryEntry; + +import java.util.function.Supplier; + +public class GTCreateDisplaySources { + + public static final RegistryEntry COMPUTER_MONITOR_COVER = registerToAllMachines( + "computer_monitor_cover", ComputerMonitorCoverDisplaySource::new); + + @SuppressWarnings("SameParameterValue") + private static < + T extends DisplaySource> RegistryEntry registerToAllMachines(String name, + Supplier supplier) { + SimpleBuilder builder = GTCreateIntegration + .displaySource(GTRegistration.REGISTRATE, name, supplier); + builder.onRegisterAfter(Registries.BLOCK_ENTITY_TYPE, + source -> GTRegistries.MACHINES.forEach( + (def) -> DisplaySource.BY_BLOCK_ENTITY.add(def.getBlockEntityType(), source))); + return builder.register(); + } + + public static void init() {} +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/create/GTCreateDisplayTargets.java b/src/main/java/com/gregtechceu/gtceu/integration/create/GTCreateDisplayTargets.java new file mode 100644 index 00000000000..b849922df91 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/create/GTCreateDisplayTargets.java @@ -0,0 +1,34 @@ +package com.gregtechceu.gtceu.integration.create; + +import com.gregtechceu.gtceu.api.registry.GTRegistries; +import com.gregtechceu.gtceu.api.registry.registrate.GTRegistrate; +import com.gregtechceu.gtceu.common.registry.GTRegistration; +import com.gregtechceu.gtceu.integration.create.display.ComputerMonitorCoverDisplayTarget; + +import net.minecraft.core.registries.Registries; + +import com.simibubi.create.api.behaviour.display.DisplayTarget; +import com.simibubi.create.api.registry.registrate.SimpleBuilder; +import com.tterrag.registrate.util.entry.RegistryEntry; + +import java.util.function.Supplier; + +public class GTCreateDisplayTargets { + + public static final RegistryEntry COMPUTER_MONITOR_COVER = registerToAllMachines( + "computer_monitor_cover", ComputerMonitorCoverDisplayTarget::new); + + @SuppressWarnings("SameParameterValue") + private static < + T extends DisplayTarget> RegistryEntry registerToAllMachines(String name, + Supplier supplier) { + SimpleBuilder builder = GTCreateIntegration + .displayTarget(GTRegistration.REGISTRATE, name, supplier); + builder.onRegisterAfter(Registries.BLOCK_ENTITY_TYPE, + target -> GTRegistries.MACHINES.forEach( + (def) -> DisplayTarget.BY_BLOCK_ENTITY.register(def.getBlockEntityType(), target))); + return builder.register(); + } + + public static void init() {} +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/create/GTCreateIntegration.java b/src/main/java/com/gregtechceu/gtceu/integration/create/GTCreateIntegration.java new file mode 100644 index 00000000000..cddad6d91f3 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/create/GTCreateIntegration.java @@ -0,0 +1,247 @@ +package com.gregtechceu.gtceu.integration.create; + +import com.gregtechceu.gtceu.api.placeholder.*; +import com.gregtechceu.gtceu.api.placeholder.exceptions.InvalidArgsException; +import com.gregtechceu.gtceu.api.placeholder.exceptions.MissingItemException; +import com.gregtechceu.gtceu.api.placeholder.exceptions.NotSupportedException; +import com.gregtechceu.gtceu.api.placeholder.exceptions.PlaceholderException; +import com.gregtechceu.gtceu.utils.GTStringUtils; + +import net.createmod.catnip.data.Couple; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; + +import com.simibubi.create.AllItems; +import com.simibubi.create.Create; +import com.simibubi.create.api.behaviour.display.DisplaySource; +import com.simibubi.create.api.behaviour.display.DisplayTarget; +import com.simibubi.create.api.registry.CreateRegistries; +import com.simibubi.create.api.registry.registrate.SimpleBuilder; +import com.simibubi.create.content.redstone.link.IRedstoneLinkable; +import com.simibubi.create.content.redstone.link.RedstoneLinkNetworkHandler; +import com.simibubi.create.content.redstone.link.controller.LinkedControllerItem; +import com.tterrag.registrate.AbstractRegistrate; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.Supplier; + +public class GTCreateIntegration { + + private GTCreateIntegration() {} + + public static void init() { + GTCreateDisplaySources.init(); + GTCreateDisplayTargets.init(); + + PlaceholderHandler.addPlaceholder(new Placeholder("redstone", 1) { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + return processRedstonePlaceholder(ctx, args); + } + }); + PlaceholderHandler.addPlaceholder(new Placeholder("displayTarget") { + + @Override + public MultiLineComponent apply(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1); + if (!(ctx.cover() instanceof IPlaceholderInfoProviderCover cover)) throw new NotSupportedException(); + int i = PlaceholderUtils.toInt(args.get(0)); + PlaceholderUtils.checkRange("line number", 1, 100, i); + return MultiLineComponent.of(cover.getCreateDisplayTargetBuffer().get(i - 1)); + } + }); + } + + private static int getRedstoneLinkPower(PlaceholderContext ctx, + Couple freq) { + IRedstoneLinkable linkable = new IRedstoneLinkable() { + + @Override + public int getTransmittedStrength() { + return 0; + } + + @Override + public void setReceivedStrength(int power) {} + + @Override + public boolean isListening() { + return true; + } + + @Override + public boolean isAlive() { + return true; + } + + @Override + public Couple getNetworkKey() { + return freq; + } + + @Override + public BlockPos getLocation() { + return ctx.pos(); + } + }; + Set network = Create.REDSTONE_LINK_NETWORK_HANDLER.getNetworkOf(ctx.level(), + linkable); + int power = 0; + for (IRedstoneLinkable i : network) { + if (!i.isAlive()) continue; + if (!RedstoneLinkNetworkHandler.withinRange(i, linkable)) continue; + power = Math.max(power, i.getTransmittedStrength()); + } + return power; + } + + private static void setRedstoneLinkPower(PlaceholderContext ctx, + Couple freq, int power) { + TemporaryRedstoneLinkTransmitter linkable = new TemporaryRedstoneLinkTransmitter(freq, power, + ctx.pos(), ctx.level()); + Create.REDSTONE_LINK_NETWORK_HANDLER.addToNetwork(ctx.level(), linkable); + } + + private static MultiLineComponent processRedstonePlaceholder(PlaceholderContext ctx, + List args) throws PlaceholderException { + PlaceholderUtils.checkArgs(args, 1, true); + if (GTStringUtils.equals(args.get(0), "get")) { + PlaceholderUtils.checkArgs(args, 2, true); + if (GTStringUtils.equals(args.get(1), "link")) { + PlaceholderUtils.checkArgs(args, 4); + int slot = PlaceholderUtils.toInt(args.get(2)); + int freq_slot = PlaceholderUtils.toInt(args.get(3)); + PlaceholderUtils.checkRange("slot index", 1, 8, slot); + if (ctx.itemStackHandler() == null) throw new NotSupportedException(); + + ItemStack item = ctx.itemStackHandler().getStackInSlot(slot - 1); + if (item.is(AllItems.LINKED_CONTROLLER.get())) { + Couple freq = LinkedControllerItem.toFrequency(item, + freq_slot); + return MultiLineComponent.literal(getRedstoneLinkPower(ctx, freq)); + } else { + throw new MissingItemException("redstone link", slot); + } + } else { + Direction direction = Direction.byName(args.get(1).toString()); + if (direction == null) + throw new InvalidArgsException(); + return MultiLineComponent.literal(ctx.level().getSignal(ctx.pos().relative(direction), direction)); + } + } else if (GTStringUtils.equals(args.get(0), "set")) { + PlaceholderUtils.checkArgs(args, 2, true); + if (GTStringUtils.equals(args.get(1), "link")) { + PlaceholderUtils.checkArgs(args, 5); + int slot = PlaceholderUtils.toInt(args.get(2)); + int freq_slot = PlaceholderUtils.toInt(args.get(3)); + int power = PlaceholderUtils.toInt(args.get(4)); + PlaceholderUtils.checkRange("redstone power", 0, 15, power); + PlaceholderUtils.checkRange("slot", 1, 8, slot); + if (ctx.itemStackHandler() == null) throw new NotSupportedException(); + + ItemStack item = ctx.itemStackHandler().getStackInSlot(slot - 1); + if (item.is(AllItems.LINKED_CONTROLLER.get())) { + Couple freq = LinkedControllerItem.toFrequency(item, + freq_slot); + setRedstoneLinkPower(ctx, freq, power); + return MultiLineComponent.empty(); + } else { + throw new MissingItemException("redstone link", slot); + } + } else { + int power = PlaceholderUtils.toInt(args.get(1)); + PlaceholderUtils.checkRange("redstone power", 0, 15, power); + if (ctx.cover() == null) throw new NotSupportedException(); + ctx.cover().setRedstoneSignalOutput(power); + return MultiLineComponent.empty(); + } + } else { + throw new InvalidArgsException(); + } + } + + public static > SimpleBuilder displaySource(P registrate, String name, + Supplier supplier) { + return registrate.entry(name, callback -> new SimpleBuilder<>( + registrate, registrate, name, callback, CreateRegistries.DISPLAY_SOURCE, supplier) + .byBlock(DisplaySource.BY_BLOCK) + .byBlockEntity(DisplaySource.BY_BLOCK_ENTITY)); + } + + public static > SimpleBuilder displayTarget(P registrate, String name, + Supplier supplier) { + return registrate.entry(name, callback -> new SimpleBuilder<>( + registrate, registrate, name, callback, CreateRegistries.DISPLAY_TARGET, supplier) + .byBlock(DisplayTarget.BY_BLOCK) + .byBlockEntity(DisplayTarget.BY_BLOCK_ENTITY)); + } + + public static class TemporaryRedstoneLinkTransmitter implements IRedstoneLinkable { + + private static final ArrayList transmitters = new ArrayList<>(); + private final int power; + private final Couple freq; + private final BlockPos pos; + private final Level level; + private boolean alive; + + public TemporaryRedstoneLinkTransmitter(Couple frequency, int power, + BlockPos pos, Level level) { + this.power = power; + this.freq = frequency; + this.alive = true; + this.pos = pos; + this.level = level; + transmitters.add(this); + } + + @Override + public int getTransmittedStrength() { + return power; + } + + @Override + public void setReceivedStrength(int power) {} + + @Override + public boolean isListening() { + return false; + } + + @Override + public boolean isAlive() { + return alive; + } + + @Override + public Couple getNetworkKey() { + return freq; + } + + @Override + public BlockPos getLocation() { + return pos; + } + + public void destroy() { + this.alive = false; + Create.REDSTONE_LINK_NETWORK_HANDLER.updateNetworkOf(level, this); + } + + public static void destroyAll() { + while (!transmitters.isEmpty()) { + transmitters.getLast().destroy(); + transmitters.removeLast(); + } + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/create/display/ComputerMonitorCoverDisplaySource.java b/src/main/java/com/gregtechceu/gtceu/integration/create/display/ComputerMonitorCoverDisplaySource.java new file mode 100644 index 00000000000..5853ef40337 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/create/display/ComputerMonitorCoverDisplaySource.java @@ -0,0 +1,38 @@ +package com.gregtechceu.gtceu.integration.create.display; + +import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; +import com.gregtechceu.gtceu.api.capability.ICoverable; +import com.gregtechceu.gtceu.common.cover.ComputerMonitorCover; +import com.gregtechceu.gtceu.utils.GTStringUtils; + +import net.minecraft.network.chat.MutableComponent; + +import com.simibubi.create.api.behaviour.display.DisplaySource; +import com.simibubi.create.content.redstone.displayLink.DisplayLinkContext; +import com.simibubi.create.content.redstone.displayLink.target.DisplayTargetStats; + +import java.util.List; + +public class ComputerMonitorCoverDisplaySource extends DisplaySource { + + private int refreshTicks = 100; + + @Override + public List provideText(DisplayLinkContext context, DisplayTargetStats stats) { + ICoverable coverable = GTCapabilityHelper.getCoverable(context.level(), context.getSourcePos(), + context.blockEntity().getDirection().getOpposite()); + if (coverable != null) { + if (coverable.getCoverAtSide( + context.blockEntity().getDirection().getOpposite()) instanceof ComputerMonitorCover cover) { + refreshTicks = cover.getUpdateInterval(); + return cover.getText(); + } + } + return GTStringUtils.literalLine("No cover!"); + } + + @Override + public int getPassiveRefreshTicks() { + return refreshTicks; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/create/display/ComputerMonitorCoverDisplayTarget.java b/src/main/java/com/gregtechceu/gtceu/integration/create/display/ComputerMonitorCoverDisplayTarget.java new file mode 100644 index 00000000000..2099bc524fd --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/create/display/ComputerMonitorCoverDisplayTarget.java @@ -0,0 +1,37 @@ +package com.gregtechceu.gtceu.integration.create.display; + +import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; +import com.gregtechceu.gtceu.api.capability.ICoverable; +import com.gregtechceu.gtceu.api.placeholder.IPlaceholderInfoProviderCover; + +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; + +import com.simibubi.create.api.behaviour.display.DisplayTarget; +import com.simibubi.create.content.redstone.displayLink.DisplayLinkContext; +import com.simibubi.create.content.redstone.displayLink.target.DisplayTargetStats; + +import java.util.List; + +public class ComputerMonitorCoverDisplayTarget extends DisplayTarget { + + @Override + public void acceptText(int line, List text, DisplayLinkContext context) { + ICoverable coverable = GTCapabilityHelper.getCoverable(context.level(), context.getTargetPos(), Direction.DOWN); + MutableComponent component = Component.empty(); + text.forEach(component::append); + if (coverable != null) { + for (Direction face : Direction.values()) { + if (coverable.getCoverAtSide(face) instanceof IPlaceholderInfoProviderCover cover) { + cover.setDisplayTargetBufferLine(line, component); + } + } + } + } + + @Override + public DisplayTargetStats provideStats(DisplayLinkContext context) { + return new DisplayTargetStats(100, 1000, this); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/emi/multipage/MultiblockInfoEmiRecipe.java b/src/main/java/com/gregtechceu/gtceu/integration/emi/multipage/MultiblockInfoEmiRecipe.java index b3dd867f0d8..fe705dea7f4 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/emi/multipage/MultiblockInfoEmiRecipe.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/emi/multipage/MultiblockInfoEmiRecipe.java @@ -9,17 +9,34 @@ import net.minecraft.resources.ResourceLocation; import dev.emi.emi.api.recipe.EmiRecipeCategory; +import dev.emi.emi.api.stack.EmiStack; +import dev.emi.emi.api.widget.SlotWidget; +import dev.emi.emi.api.widget.WidgetHolder; import org.jetbrains.annotations.Nullable; +import java.util.List; + public class MultiblockInfoEmiRecipe extends ModularEmiRecipe { - public final MultiblockMachineDefinition definition; + private final MultiblockMachineDefinition definition; + private SlotWidget slotWidget; public MultiblockInfoEmiRecipe(MultiblockMachineDefinition definition) { super(() -> PatternPreviewWidget.getPatternWidget(definition)); this.definition = definition; } + @Override + public void addWidgets(WidgetHolder widgets) { + super.addWidgets(widgets); + // numbers gotten from the size of the widget + slotWidget = new SlotWidget(EmiStack.of(definition.getItem().asItem()), 138, 12) + .recipeContext(this) + .drawBack(false); + + widgets.add(slotWidget); + } + @Override public EmiRecipeCategory getCategory() { return MultiblockInfoEmiCategory.CATEGORY; @@ -29,4 +46,9 @@ public EmiRecipeCategory getCategory() { public @Nullable ResourceLocation getId() { return definition.getId().withPrefix("/"); } + + @Override + public List getOutputs() { + return List.of(EmiStack.of(definition.getItem())); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/emi/oreprocessing/GTOreProcessingEmiCategory.java b/src/main/java/com/gregtechceu/gtceu/integration/emi/oreprocessing/GTOreProcessingEmiCategory.java index 49f842b5e3f..1828dc5a332 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/emi/oreprocessing/GTOreProcessingEmiCategory.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/emi/oreprocessing/GTOreProcessingEmiCategory.java @@ -20,6 +20,7 @@ import static com.gregtechceu.gtceu.api.material.material.properties.PropertyKey.ORE; import static com.gregtechceu.gtceu.data.recipe.GTRecipeTypes.*; +import static com.gregtechceu.gtceu.integration.emi.recipe.GTRecipeEMICategory.sortDefinition; public class GTOreProcessingEmiCategory extends EmiRecipeCategory { @@ -43,7 +44,10 @@ public static void registerWorkStations(EmiRegistry registry) { MACERATOR_RECIPES, ORE_WASHER_RECIPES, THERMAL_CENTRIFUGE_RECIPES, CENTRIFUGE_RECIPES, CHEMICAL_BATH_RECIPES, ELECTROMAGNETIC_SEPARATOR_RECIPES, SIFTER_RECIPES }; - for (MachineDefinition machine : GTRegistries.MACHINES) { + for (MachineDefinition machine : GTRegistries.MACHINES + .stream() + .sorted(sortDefinition) + .toList()) { for (GTRecipeType type : machine.getRecipeTypes()) { for (GTRecipeType validType : validTypes) { if (type == validType && !registeredMachines.contains(machine)) { diff --git a/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeEMICategory.java b/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeEMICategory.java index 25a44e7fc73..01e4493f320 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeEMICategory.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/emi/recipe/GTRecipeEMICategory.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.machine.MachineDefinition; +import com.gregtechceu.gtceu.api.machine.MultiblockMachineDefinition; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.registry.GTRegistries; @@ -17,6 +18,9 @@ import dev.emi.emi.api.recipe.VanillaEmiRecipeCategories; import dev.emi.emi.api.stack.EmiStack; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; import java.util.function.Function; public class GTRecipeEMICategory extends EmiRecipeCategory { @@ -31,19 +35,50 @@ private GTRecipeEMICategory(GTRecipeCategory category) { } public static void registerDisplays(EmiRegistry registry) { + List subCategories = new ArrayList<>(); + // run main categories first for (GTRecipeCategory category : GTRegistries.RECIPE_CATEGORIES) { if (!category.shouldRegisterDisplays()) continue; var type = category.getRecipeType(); - if (category == type.getCategory()) type.buildRepresentativeRecipes(); + if (category == type.getCategory()) { + type.buildRepresentativeRecipes(); + } else { + subCategories.add(category); + continue; + } EmiRecipeCategory emiCategory = CATEGORIES.apply(category); type.getRecipesInCategory(category).stream() .map(recipe -> new GTEmiRecipe(recipe, emiCategory)) .forEach(registry::addRecipe); } + // run subcategories + for (var subCategory : subCategories) { + if (!subCategory.shouldRegisterDisplays()) continue; + var type = subCategory.getRecipeType(); + EmiRecipeCategory emiCategory = CATEGORIES.apply(subCategory); + type.getRecipesInCategory(subCategory).stream() + .map(recipe -> new GTEmiRecipe(recipe, emiCategory)) + .forEach(registry::addRecipe); + } } + public static Comparator sortDefinition = (a, b) -> { + boolean isAMulti = a instanceof MultiblockMachineDefinition; + boolean isBMulti = b instanceof MultiblockMachineDefinition; + if (isAMulti && !isBMulti) { + return 1; + } else if (!isAMulti && isBMulti) { + return -1; + } else { + return a.getTier() - b.getTier(); + } + }; + public static void registerWorkStations(EmiRegistry registry) { - for (MachineDefinition machine : GTRegistries.MACHINES) { + for (MachineDefinition machine : GTRegistries.MACHINES + .stream() + .sorted(sortDefinition) + .toList()) { for (GTRecipeType type : machine.getRecipeTypes()) { for (GTRecipeCategory category : type.getCategories()) { if (!category.isXEIVisible() && !GTCEu.isDev()) continue; diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java index 3a779786789..8bcf8366cf7 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/GTJadePlugin.java @@ -43,6 +43,7 @@ public void register(IWailaCommonRegistration registration) { registration.registerBlockDataProvider(new HazardCleanerBlockProvider(), BlockEntity.class); registration.registerBlockDataProvider(new TransformerBlockProvider(), BlockEntity.class); registration.registerBlockDataProvider(new PrimitivePumpBlockProvider(), BlockEntity.class); + registration.registerBlockDataProvider(new DataBankBlockProvider(), BlockEntity.class); registration.registerBlockDataProvider(new EnergyConverterModeProvider(), BlockEntity.class); if (GTCEu.Mods.isAE2Loaded()) { registration.registerBlockDataProvider(new MEPatternBufferProvider(), BlockEntity.class); @@ -73,6 +74,7 @@ public void registerClient(IWailaClientRegistration registration) { registration.registerBlockComponent(new HazardCleanerBlockProvider(), Block.class); registration.registerBlockComponent(new TransformerBlockProvider(), Block.class); registration.registerBlockComponent(new PrimitivePumpBlockProvider(), Block.class); + registration.registerBlockComponent(new DataBankBlockProvider(), Block.class); registration.registerBlockComponent(new EnergyConverterModeProvider(), Block.class); if (GTCEu.Mods.isAE2Loaded()) { registration.registerBlockComponent(new MEPatternBufferProvider(), Block.class); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/ControllableBlockProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/ControllableBlockProvider.java index f933ffbef31..7ce7a50c389 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/ControllableBlockProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/ControllableBlockProvider.java @@ -33,13 +33,17 @@ protected IControllable getCapability(Level level, BlockPos pos, @Nullable Direc @Override protected void write(CompoundTag data, IControllable capability) { data.putBoolean("WorkingEnabled", capability.isWorkingEnabled()); + data.putBoolean("SuspendAfter", capability.isSuspendAfterFinish()); } @Override protected void addTooltip(CompoundTag capData, ITooltip tooltip, Player player, BlockAccessor block, BlockEntity blockEntity, IPluginConfig config) { - if (capData.contains("WorkingEnabled") && !capData.getBoolean("WorkingEnabled")) { - tooltip.add(Component.translatable("gtceu.top.working_disabled").withStyle(ChatFormatting.YELLOW)); + if (capData.contains("SuspendAfter") && capData.getBoolean("SuspendAfter")) { + tooltip.add( + Component.translatable("behaviour.soft_hammer.disabled_cycle").withStyle(ChatFormatting.YELLOW)); + } else if (capData.contains("WorkingEnabled") && !capData.getBoolean("WorkingEnabled")) { + tooltip.add(Component.translatable("behaviour.soft_hammer.disabled").withStyle(ChatFormatting.YELLOW)); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/DataBankBlockProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/DataBankBlockProvider.java new file mode 100644 index 00000000000..3e57198f181 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/DataBankBlockProvider.java @@ -0,0 +1,56 @@ +package com.gregtechceu.gtceu.integration.jade.provider; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.research.DataBankMachine; +import com.gregtechceu.gtceu.utils.FormattingUtil; +import com.gregtechceu.gtceu.utils.GTUtil; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; + +import snownee.jade.api.BlockAccessor; +import snownee.jade.api.IBlockComponentProvider; +import snownee.jade.api.IServerDataProvider; +import snownee.jade.api.ITooltip; +import snownee.jade.api.config.IPluginConfig; + +public class DataBankBlockProvider implements IBlockComponentProvider, IServerDataProvider { + + @Override + public ResourceLocation getUid() { + return GTCEu.id("data_bank"); + } + + @Override + public void appendTooltip(ITooltip iTooltip, BlockAccessor blockAccessor, IPluginConfig iPluginConfig) { + if (blockAccessor.getBlockEntity() instanceof IMachineBlockEntity blockEntity) { + MetaMachine machine = blockEntity.getMetaMachine(); + if (machine instanceof DataBankMachine) { + long energyUsage = blockAccessor.getServerData().getLong("energyUsage"); + String energyFormatted = FormattingUtil.formatNumbers(energyUsage); + // wrap in text component to keep it from being formatted + Component voltageName = Component.literal(GTValues.VNF[GTUtil.getTierByVoltage(energyUsage)]); + Component text = Component.translatable( + "gtceu.multiblock.energy_consumption", + energyFormatted, + voltageName); + + iTooltip.add(text); + } + } + } + + @Override + public void appendServerData(CompoundTag compoundTag, BlockAccessor blockAccessor) { + if (blockAccessor.getBlockEntity() instanceof IMachineBlockEntity blockEntity) { + MetaMachine machine = blockEntity.getMetaMachine(); + if (machine instanceof DataBankMachine dataBank) { + compoundTag.putLong("energyUsage", dataBank.getEnergyUsage()); + } + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java index 92c71d4bb21..7dea33c7017 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/MEPatternBufferProvider.java @@ -97,7 +97,8 @@ public static void readBufferTag(ITooltip iTooltip, CompoundTag serverData) { if (stack.isPresent() && !stack.get().isEmpty() && count > 0) { iTooltip.add(helper.smallItem(stack.get())); Component text = Component.literal(" ") - .append(Component.literal(String.valueOf(count)).withStyle(ChatFormatting.DARK_PURPLE)) + .append(Component.literal(FormattingUtil.formatNumbers(count)) + .withStyle(ChatFormatting.DARK_PURPLE)) .append(Component.literal("× ").withStyle(ChatFormatting.WHITE)) .append(stack.get().getHoverName().copy().withStyle(ChatFormatting.GOLD)); iTooltip.append(text); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/ParallelProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/ParallelProvider.java index a351b96d31f..c5c25a645e2 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/ParallelProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/ParallelProvider.java @@ -24,12 +24,39 @@ public class ParallelProvider implements IBlockComponentProvider, IServerDataPro public void appendTooltip(ITooltip iTooltip, BlockAccessor blockAccessor, IPluginConfig iPluginConfig) { if (blockAccessor.getServerData().contains("parallel")) { int parallel = blockAccessor.getServerData().getInt("parallel"); - if (parallel > 1) { + if (!blockAccessor.getServerData().getBoolean("exact") && parallel > 1) { Component parallels = Component.literal(FormattingUtil.formatNumbers(parallel)) .withStyle(ChatFormatting.DARK_PURPLE); String key = "gtceu.multiblock.parallel"; - if (blockAccessor.getServerData().getBoolean("exact")) key += ".exact"; iTooltip.add(Component.translatable(key, parallels)); + } else { + int batch = blockAccessor.getServerData().getInt("batch"); + int subtickParallel = blockAccessor.getServerData().getInt("subtickParallel"); + int totalRuns = parallel * batch * subtickParallel; + if (totalRuns == 1) return; + Component runs = Component.literal(FormattingUtil.formatNumbers(totalRuns)) + .withStyle(ChatFormatting.DARK_PURPLE); + String key = "gtceu.multiblock.total_runs"; + iTooltip.add(Component.translatable(key, runs)); + + if (parallel > 1) { + Component parallels = Component.literal(FormattingUtil.formatNumbers(parallel)) + .withStyle(ChatFormatting.DARK_PURPLE); + String keyParallel = "gtceu.multiblock.parallel.exact"; + iTooltip.add(Component.translatable(keyParallel, parallels)); + } + if (batch > 1) { + Component batches = Component.literal(FormattingUtil.formatNumbers(batch)) + .withStyle(ChatFormatting.DARK_PURPLE); + String keyBatch = "gtceu.multiblock.batch_enabled"; + iTooltip.add(Component.translatable(keyBatch, batches)); + } + if (subtickParallel > 1) { + Component subticks = Component.literal(FormattingUtil.formatNumbers(subtickParallel)) + .withStyle(ChatFormatting.DARK_PURPLE); + String keySubtick = "gtceu.multiblock.subtick_parallels"; + iTooltip.add(Component.translatable(keySubtick, subticks)); + } } } } @@ -44,6 +71,8 @@ public void appendServerData(CompoundTag compoundTag, BlockAccessor blockAccesso rlm.getRecipeLogic().isActive() && rlm.getRecipeLogic().getLastRecipe() != null) { compoundTag.putInt("parallel", rlm.getRecipeLogic().getLastRecipe().parallels); + compoundTag.putInt("batch", rlm.getRecipeLogic().getLastRecipe().batchParallels); + compoundTag.putInt("subtickParallel", rlm.getRecipeLogic().getLastRecipe().subtickParallels); compoundTag.putBoolean("exact", true); } else { controller.getParallelHatch() diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeLogicProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeLogicProvider.java index 0635b79277f..31f2324e24b 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeLogicProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeLogicProvider.java @@ -4,10 +4,14 @@ import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; +import com.gregtechceu.gtceu.api.machine.SimpleGeneratorMachine; +import com.gregtechceu.gtceu.api.machine.SimpleTieredMachine; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; import com.gregtechceu.gtceu.api.machine.steam.SimpleSteamMachine; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; import com.gregtechceu.gtceu.client.util.TooltipHelper; +import com.gregtechceu.gtceu.common.machine.multiblock.part.EnergyHatchPartMachine; import com.gregtechceu.gtceu.common.machine.multiblock.steam.SteamParallelMultiblockMachine; import com.gregtechceu.gtceu.utils.FormattingUtil; import com.gregtechceu.gtceu.utils.GTUtil; @@ -49,7 +53,7 @@ protected void write(CompoundTag data, RecipeLogic capability) { var EUt = RecipeHelper.getRealEUtWithIO(recipe); recipeInfo.putLong("EUt", EUt.getTotalEU()); - recipeInfo.putLong("amperage", EUt.amperage()); + recipeInfo.putLong("voltage", getVoltage(capability)); recipeInfo.putBoolean("isInput", EUt.isInput()); } @@ -58,6 +62,25 @@ protected void write(CompoundTag data, RecipeLogic capability) { } } + public static long getVoltage(RecipeLogic capability) { + long voltage = -1; + if (capability.machine instanceof SimpleTieredMachine machine) { + voltage = GTValues.V[machine.getTier()]; + } else if (capability.machine instanceof SimpleGeneratorMachine machine) { + voltage = GTValues.V[machine.getTier()]; + } else if (capability.machine instanceof WorkableElectricMultiblockMachine machine) { + voltage = machine.getParts().stream() + .filter(EnergyHatchPartMachine.class::isInstance) + .map(EnergyHatchPartMachine.class::cast) + .mapToLong(dynamo -> GTValues.V[dynamo.getTier()]) + .max() + .orElse(-1); + } + // default display as LV, this shouldn't happen because a machine is either electric or steam + if (voltage == -1) voltage = 32; + return voltage; + } + @Override protected void addTooltip(CompoundTag capData, ITooltip tooltip, Player player, BlockAccessor block, BlockEntity blockEntity, IPluginConfig config) { @@ -65,33 +88,36 @@ protected void addTooltip(CompoundTag capData, ITooltip tooltip, Player player, var recipeInfo = capData.getCompound("Recipe"); if (!recipeInfo.isEmpty()) { var EUt = recipeInfo.getLong("EUt"); - var amperage = recipeInfo.getLong("amperage"); var isInput = recipeInfo.getBoolean("isInput"); boolean isSteam = false; - if (blockEntity instanceof MetaMachineBlockEntity mbe) { - var machine = mbe.getMetaMachine(); - if (machine instanceof SimpleSteamMachine ssm) { - EUt = (long) (EUt * ssm.getConversionRate()); - isSteam = true; - } else if (machine instanceof SteamParallelMultiblockMachine smb) { - EUt = (long) (EUt * smb.getConversionRate()); - isSteam = true; + if (EUt > 0) { + if (blockEntity instanceof MetaMachineBlockEntity mbe) { + var machine = mbe.getMetaMachine(); + if (machine instanceof SimpleSteamMachine ssm) { + EUt = (long) Math.ceil(EUt * ssm.getConversionRate()); + isSteam = true; + } else if (machine instanceof SteamParallelMultiblockMachine smb) { + EUt = (long) Math.ceil(EUt * smb.getConversionRate()); + isSteam = true; + } } - } - if (EUt > 0) { - MutableComponent text = Component.literal(FormattingUtil.formatNumbers(EUt)); + MutableComponent text; if (isSteam) { - text = text.withStyle(ChatFormatting.GREEN) - .append(Component.literal(" mB/t").withStyle(ChatFormatting.RESET)); + text = Component.translatable("gtceu.jade.fluid_use", FormattingUtil.formatNumbers(EUt)) + .withStyle(ChatFormatting.GREEN); } else { - var tier = GTUtil.getOCTierByVoltage(EUt / amperage); - - text = text.withStyle(ChatFormatting.RED) - .append(Component.literal(" EU/t ").withStyle(ChatFormatting.RESET) - .append(Component.literal("(").withStyle(ChatFormatting.GREEN))); + var voltage = recipeInfo.getLong("voltage"); + var tier = GTUtil.getTierByVoltage(voltage); + float minAmperage = (float) EUt / voltage; + + text = Component + .translatable("gtceu.jade.amperage_use", + FormattingUtil.formatNumber2Places(minAmperage)) + .withStyle(ChatFormatting.RED) + .append(Component.translatable("gtceu.jade.at").withStyle(ChatFormatting.GREEN)); if (tier < GTValues.TIER_COUNT) { text = text.append(Component.literal(GTValues.VNF[tier]) .withStyle(style -> style.withColor(GTValues.VC[tier]))); @@ -104,7 +130,10 @@ protected void addTooltip(CompoundTag capData, ITooltip tooltip, Player player, .append(FormattingUtil.formatNumbers(speed)))); } - text = text.append(Component.literal(")").withStyle(ChatFormatting.GREEN)); + text.append(Component.translatable("gtceu.universal.padded_parentheses", + (Component.translatable("gtceu.recipe.eu.total", + FormattingUtil.formatNumbers(EUt)))) + .withStyle(ChatFormatting.WHITE)); } if (isInput) { diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeOutputProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeOutputProvider.java index 0a729fc8ee4..55aa4ac02a2 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeOutputProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/RecipeOutputProvider.java @@ -6,6 +6,7 @@ import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; +import com.gregtechceu.gtceu.api.recipe.content.ContentModifier; import com.gregtechceu.gtceu.api.recipe.ingredient.IntProviderFluidIngredient; import com.gregtechceu.gtceu.api.recipe.ingredient.IntProviderIngredient; import com.gregtechceu.gtceu.api.recipe.ingredient.SizedIngredientExtensions; @@ -66,31 +67,39 @@ protected void write(CompoundTag data, RecipeLogic recipeLogic) { var function = recipe.getType().getChanceFunction(); var itemContents = recipe.getOutputContents(ItemRecipeCapability.CAP); var fluidContents = recipe.getOutputContents(FluidRecipeCapability.CAP); + int runs = recipe.getTotalRuns(); var ops = recipeLogic.getMachine().getLevel() .registryAccess().createSerializationContext(NbtOps.INSTANCE); ListTag itemTags = new ListTag(); for (var item : itemContents) { - var itemTag = new CompoundTag(); + CompoundTag itemTag; if (item.content instanceof IntProviderIngredient provider) { - // don't bother rolling output - itemTag = IntProviderIngredient.CODEC.codec().encodeStart(ops, provider) - .map(tag -> (CompoundTag) tag) - .getOrThrow(); + + // don't roll for output but do copy for chance and batch + IntProviderIngredient chanced = provider; + if (item.chance < item.maxChance) { + double countD = (double) runs * + function.getBoostedChance(item, recipeTier, chanceTier) / item.maxChance; + chanced = (IntProviderIngredient) ItemRecipeCapability.CAP.copyWithModifier(provider, + ContentModifier.multiplier(countD)); + } + // itemTag = (CompoundTag) chanced.; + // PORT TODO: Fix this + itemTag = new CompoundTag(); } else { var stacks = ItemRecipeCapability.CAP.of(item.content).getItems(); if (stacks.length == 0 || stacks[0].isEmpty()) continue; var stack = stacks[0]; - itemTag = ItemStack.CODEC.encodeStart(ops, stack) .map(tag -> (CompoundTag) tag) .getOrThrow(); if (item.chance < item.maxChance) { int count = stack.getCount(); - double countD = (double) count * recipe.parallels * + double countD = (double) count * runs * function.getBoostedChance(item, recipeTier, chanceTier) / item.maxChance; - count = countD < 1 ? 1 : (int) Math.round(countD); + count = Math.max(1, (int) Math.round(countD)); itemTag.putInt("Count", count); } } @@ -110,6 +119,12 @@ protected void write(CompoundTag data, RecipeLogic recipeLogic) { fluidTag = IntProviderFluidIngredient.CODEC.codec().encodeStart(ops, provider) .map(tag -> (CompoundTag) tag) .getOrThrow(); + if (fluid.chance < fluid.maxChance) { + double countD = (double) runs * + function.getBoostedChance(fluid, recipeTier, chanceTier) / fluid.maxChance; + provider = (IntProviderFluidIngredient) FluidRecipeCapability.CAP.copyWithModifier(provider, + ContentModifier.multiplier(countD)); + } } else { FluidStack[] stacks = FluidRecipeCapability.CAP.of(fluid.content).getFluids(); if (stacks.length == 0) continue; @@ -120,10 +135,15 @@ protected void write(CompoundTag data, RecipeLogic recipeLogic) { .map(tag -> (CompoundTag) tag) .getOrThrow(); if (fluid.chance < fluid.maxChance) { + // <<<<<<< HEAD int amount = stack.getAmount(); - double amountD = (double) amount * recipe.parallels * + double amountD = (double) amount * runs * + // ======= + // int amount = stacks[0].getAmount(); + // double amountD = (double) amount * runs * + // >>>>>>> v.7.2.0-1.20.1 function.getBoostedChance(fluid, recipeTier, chanceTier) / fluid.maxChance; - amount = amountD < 1 ? 1 : (int) Math.round(amountD); + amount = Math.max(1, (int) Math.round(amountD)); fluidTag.putInt("Amount", amount); } } @@ -200,15 +220,19 @@ private void addItemTooltips(ITooltip iTooltip, List outputItem iTooltip.add(helper.smallItem(item)); MutableComponent text = CommonComponents.space(); if (itemOutput.getContainedCustom() instanceof IntProviderIngredient provider) { - text.append(String.valueOf(provider.getCountProvider().getMinValue())) - .append("-") - .append(String.valueOf(provider.getCountProvider().getMaxValue())); + text.append(Component.translatable("gtceu.gui.content.range", + String.valueOf(provider.getCountProvider().getMinValue()), + String.valueOf(provider.getCountProvider().getMaxValue()))); } else { - text.append(String.valueOf(count)); + item = itemOutput.getItems()[0]; + text.append(String.valueOf(item.getCount())); + item.setCount(1); } - text.append("× ") - .append(getItemName(item)) - .withStyle(ChatFormatting.WHITE); + text.append(Component.translatable("gtceu.gui.content.times_item", + getItemName(item)) + .withStyle(ChatFormatting.WHITE)); + + iTooltip.add(helper.smallItem(item)); iTooltip.append(text); } } @@ -222,24 +246,23 @@ private void addFluidTooltips(ITooltip iTooltip, List outp iTooltip.add(GTElementHelper.smallFluid(getFluid(fluid))); MutableComponent text = CommonComponents.space(); if (fluidOutput.ingredient() instanceof IntProviderFluidIngredient provider) { - text.append(FluidTextHelper.getUnicodeMillibuckets( - provider.getCountProvider().getMinValue(), true)) - .append("-") - .append(FluidTextHelper.getUnicodeMillibuckets( - provider.getCountProvider().getMaxValue(), true)); + text.append(Component.translatable("gtceu.gui.content.range", + FluidTextHelper.getUnicodeMillibuckets(provider.getCountProvider().getMinValue(), true), + FluidTextHelper.getUnicodeMillibuckets(provider.getCountProvider().getMaxValue(), true))); } else { text.append(FluidTextHelper.getUnicodeMillibuckets(fluidOutput.amount(), true)); } text.append(CommonComponents.space()) .append(getFluidName(fluid)) .withStyle(ChatFormatting.WHITE); + iTooltip.append(text); } } } private Component getItemName(ItemStack stack) { - return ComponentUtils.wrapInSquareBrackets(stack.getHoverName()).withStyle(ChatFormatting.WHITE); + return stack.getDisplayName().copy().withStyle(ChatFormatting.WHITE); } private Component getFluidName(FluidStack stack) { diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/SteamBoilerBlockProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/SteamBoilerBlockProvider.java index 7d57cd8cec8..23152ef2ec6 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/SteamBoilerBlockProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jade/provider/SteamBoilerBlockProvider.java @@ -3,10 +3,13 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.steam.SteamBoilerMachine; +import com.gregtechceu.gtceu.utils.FormattingUtil; +import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; @@ -33,21 +36,63 @@ protected SteamBoilerMachine getCapability(Level level, BlockPos blockPos) { @Override protected void write(CompoundTag data, SteamBoilerMachine capability, BlockAccessor block) { - data.putBoolean("heatingUp", capability.getRecipeLogic().isWorking()); - data.putBoolean("coolingDown", capability.getCurrentTemperature() > 0); - data.putBoolean("producingSteam", !capability.isHasNoWater() && capability.getCurrentTemperature() >= 100); + data.putBoolean("isBurning", capability.getRecipeLogic().isWorking()); + data.putBoolean("hasWater", !capability.isHasNoWater()); + data.putLong("steamProduction", capability.getTotalSteamOutput()); + data.putInt("currentTemperature", capability.getCurrentTemperature()); + data.putInt("maxTemperature", capability.getMaxTemperature()); } @Override protected void addTooltip(CompoundTag capData, ITooltip tooltip, Player player, BlockAccessor block, BlockEntity blockEntity, IPluginConfig config) { - var producing = capData.getBoolean("producingSteam"); - if (capData.getBoolean("heatingUp")) { - tooltip.add(Component.translatable("gtceu.machine.boiler.info.heating.up", - producing ? Component.translatable("gtceu.machine.boiler.info.producing.steam") : "")); - } else if (capData.getBoolean("coolingDown")) { - tooltip.add(Component.translatable("gtceu.machine.boiler.info.cooling.down", - producing ? Component.translatable("gtceu.machine.boiler.info.producing.steam") : "")); + boolean isBurning = capData.getBoolean("isBurning"); + boolean hasWater = capData.getBoolean("hasWater"); + long production = capData.getLong("steamProduction"); + int temperature = capData.getInt("currentTemperature"); + int maxTemperature = capData.getInt("maxTemperature"); + + boolean makingSteam = hasWater && temperature >= 100; + + // Determine the first section + MutableComponent root; + if (isBurning && temperature < maxTemperature) { + // Heating up + root = Component.translatable("gtceu.machine.boiler.info.heating.up"); + } else if (!isBurning && temperature > 0) { + // Cooling down + root = Component.translatable("gtceu.machine.boiler.info.cooling.down"); + } else { + root = null; // neither heating nor cooling, is either max temperature or temperature of zero + } + + // Determine the second section + MutableComponent extra; + if (makingSteam) { + // Producing some amount of steam + extra = Component.translatable("gtceu.machine.boiler.info.production.data", + Component.literal(FormattingUtil.formatNumbers(production / 10)) + .withStyle(ChatFormatting.GREEN)); + if (root != null) { + // append some nice separation here to the root + extra = Component.literal(" | ").append(extra); + } + } else if (temperature > 0 && temperature < 100) { + // Still warming up (or cooling down) + extra = Component.literal(String.format(" (%s%%)", temperature)) + // Either heating up or cooling down + .withStyle(isBurning ? ChatFormatting.RED : ChatFormatting.BLUE); + } else { + // Nothing to add + extra = null; + } + + if (root != null && extra != null) { + tooltip.add(root.append(extra)); + } else if (root != null) { + tooltip.add(root); + } else if (extra != null) { + tooltip.add(extra); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jei/multipage/MultiblockInfoCategory.java b/src/main/java/com/gregtechceu/gtceu/integration/jei/multipage/MultiblockInfoCategory.java index b026e75ad8d..30f7cf81820 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jei/multipage/MultiblockInfoCategory.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jei/multipage/MultiblockInfoCategory.java @@ -5,30 +5,48 @@ import com.gregtechceu.gtceu.api.registry.GTRegistries; import com.gregtechceu.gtceu.data.machine.GTMultiMachines; +import com.lowdragmc.lowdraglib.gui.widget.Widget; import com.lowdragmc.lowdraglib.jei.ModularUIRecipeCategory; +import net.minecraft.MethodsReturnNonnullByDefault; +import net.minecraft.client.gui.navigation.ScreenPosition; import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; import lombok.Getter; import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.gui.ingredient.IRecipeSlotDrawable; +import mezz.jei.api.gui.inputs.RecipeSlotUnderMouse; +import mezz.jei.api.gui.widgets.IRecipeExtrasBuilder; +import mezz.jei.api.gui.widgets.ISlottedRecipeWidget; import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.helpers.IJeiHelpers; +import mezz.jei.api.recipe.IFocusGroup; import mezz.jei.api.recipe.RecipeType; import mezz.jei.api.registration.IRecipeRegistration; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class MultiblockInfoCategory extends ModularUIRecipeCategory { +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; - public final static RecipeType RECIPE_TYPE = new RecipeType<>( +import javax.annotation.ParametersAreNonnullByDefault; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class MultiblockInfoCategory extends ModularUIRecipeCategory { + + public final static RecipeType RECIPE_TYPE = new RecipeType<>( GTCEu.id("multiblock_info"), - MultiblockMachineDefinition.class); + MultiblockInfoWrapper.class); @Getter private final IDrawable background; @Getter private final IDrawable icon; public MultiblockInfoCategory(IJeiHelpers helpers) { - super(MultiblockInfoWrapper::new); + super((def) -> new MultiblockInfoWrapper(def.definition)); IGuiHelper guiHelper = helpers.getGuiHelper(); this.background = guiHelper.createBlankDrawable(160, 160); this.icon = helpers.getGuiHelper().createDrawableItemStack(GTMultiMachines.ELECTRIC_BLAST_FURNACE.asStack()); @@ -39,12 +57,58 @@ public static void registerRecipes(IRecipeRegistration registry) { .filter(MultiblockMachineDefinition.class::isInstance) .map(MultiblockMachineDefinition.class::cast) .filter(MultiblockMachineDefinition::isRenderXEIPreview) + .map(MultiblockInfoWrapper::new) .toList()); } + @Override + public void createRecipeExtras(@NotNull IRecipeExtrasBuilder builder, @NotNull MultiblockInfoWrapper recipe, + @NotNull IFocusGroup focuses) { + super.createRecipeExtras(builder, recipe, focuses); + List slots = new ArrayList<>(builder.getRecipeSlots().getSlots()); + class ProxyRecipeWidget implements ISlottedRecipeWidget { + + private final ScreenPosition position = new ScreenPosition(0, 0); + + @Override + public Optional getSlotUnderMouse(double mouseX, double mouseY) { + var panel = recipe.getWidget(); + var pos = panel.getSelfPosition(); + var size = panel.getSize(); + boolean inParent = Widget.isMouseOver(pos.x, pos.y, size.width, size.height, mouseX, mouseY); + if (!inParent) return Optional.empty(); + List widgets = recipe.modularUI.getFlatWidgetCollection(); + return slots.stream() + .filter(slot -> { + Optional slotName = slot.getSlotName(); + if (slotName.isEmpty()) return false; + String name = slotName.get(); + int index = Integer.parseInt(name.substring(5)); + Widget widget = widgets.get(index); + slot.setPosition(widget.getPositionX(), widget.getPositionY()); + return slot.isMouseOver(mouseX, mouseY); + }) + .findFirst() + .map(slot -> new RecipeSlotUnderMouse(slot, 0, 0)); + } + + @Override + public ScreenPosition getPosition() { + return position; + } + } + + builder.addSlottedWidget(new ProxyRecipeWidget(), slots); + } + + @Override + public @Nullable ResourceLocation getRegistryName(@NotNull MultiblockInfoWrapper recipe) { + return recipe.definition.getId(); + } + @Override @NotNull - public RecipeType getRecipeType() { + public RecipeType getRecipeType() { return RECIPE_TYPE; } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeJEICategory.java b/src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeJEICategory.java index c68ad7f691c..838aa934cdc 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeJEICategory.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/jei/recipe/GTRecipeJEICategory.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; import java.util.function.Function; @@ -52,13 +53,27 @@ public GTRecipeJEICategory(IJeiHelpers helpers, } public static void registerRecipes(IRecipeRegistration registration) { + List subCategories = new ArrayList<>(); + // run main categories first for (GTRecipeCategory category : GTRegistries.RECIPE_CATEGORIES) { if (!category.shouldRegisterDisplays()) continue; var type = category.getRecipeType(); - if (category == type.getCategory()) type.buildRepresentativeRecipes(); + if (category == type.getCategory()) { + type.buildRepresentativeRecipes(); + } else { + subCategories.add(category); + continue; + } var wrapped = List.copyOf(type.getRecipesInCategory(category)); registration.addRecipes(TYPES.apply(category), wrapped); } + // run subcategories + for (GTRecipeCategory subCategory : subCategories) { + if (!subCategory.shouldRegisterDisplays()) continue; + var type = subCategory.getRecipeType(); + var wrapped = List.copyOf(type.getRecipesInCategory(subCategory)); + registration.addRecipes(TYPES.apply(subCategory), wrapped); + } } public static void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/GTCEuStartupEvents.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/GTCEuStartupEvents.java index ed9840e7226..c0a4f7273d5 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/GTCEuStartupEvents.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/GTCEuStartupEvents.java @@ -15,4 +15,6 @@ public interface GTCEuStartupEvents { EventHandler MATERIAL_MODIFICATION = GROUP.startup("materialModification", () -> MaterialModificationKubeEvent.class); EventHandler CRAFTING_COMPONENTS = GROUP.startup("craftingComponents", () -> CraftingComponentsKubeEvent.class); + + EventHandler REGISTER_WOODS = GROUP.startup("registerWoods", () -> RegisterWoodsKubeEvent.class); } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/GTKubeJSPlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/GTKubeJSPlugin.java index abbc9fe8cd3..7ff60805545 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/GTKubeJSPlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/GTKubeJSPlugin.java @@ -5,7 +5,6 @@ import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.cosmetics.CapeRegistry; -import com.gregtechceu.gtceu.api.fluid.FluidBuilder; import com.gregtechceu.gtceu.api.fluid.FluidState; import com.gregtechceu.gtceu.api.fluid.attribute.FluidAttributes; import com.gregtechceu.gtceu.api.fluid.store.FluidStorageKeys; @@ -17,6 +16,7 @@ import com.gregtechceu.gtceu.api.machine.SimpleTieredMachine; import com.gregtechceu.gtceu.api.machine.multiblock.CleanroomType; import com.gregtechceu.gtceu.api.machine.multiblock.PartAbility; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.material.ChemicalHelper; import com.gregtechceu.gtceu.api.material.Element; import com.gregtechceu.gtceu.api.material.material.Material; @@ -52,6 +52,7 @@ import com.gregtechceu.gtceu.api.worldgen.generator.indicators.SurfaceIndicatorGenerator.IndicatorPlacement; import com.gregtechceu.gtceu.api.worldgen.generator.veins.DikeVeinGenerator; import com.gregtechceu.gtceu.api.worldgen.generator.veins.NoopVeinGenerator; +import com.gregtechceu.gtceu.client.renderer.machine.DynamicRenderHelper; import com.gregtechceu.gtceu.common.cosmetics.GTCapes; import com.gregtechceu.gtceu.common.machine.multiblock.primitive.PrimitiveFancyUIWorkableMachine; import com.gregtechceu.gtceu.common.pack.GTDynamicResourcePack; @@ -115,7 +116,7 @@ import dev.latvian.mods.kubejs.event.EventGroupRegistry; import dev.latvian.mods.kubejs.plugin.ClassFilter; import dev.latvian.mods.kubejs.plugin.KubeJSPlugin; -import dev.latvian.mods.kubejs.recipe.schema.RecipeComponentFactoryRegistry; +import dev.latvian.mods.kubejs.recipe.component.RecipeComponentTypeRegistry; import dev.latvian.mods.kubejs.recipe.schema.RecipeFactoryRegistry; import dev.latvian.mods.kubejs.recipe.schema.RecipeSchemaRegistry; import dev.latvian.mods.kubejs.registry.BuilderTypeRegistry; @@ -162,7 +163,7 @@ public void registerBuilderTypes(BuilderTypeRegistry registry) { registry.addDefault(GTRegistries.MATERIAL_REGISTRY, MaterialBuilderWrapper.class, MaterialBuilderWrapper::new); registry.of(GTRegistries.TAG_PREFIX_REGISTRY, reg -> { reg.addDefault(TagPrefixBuilder.class, TagPrefixBuilder::new); - reg.add("ore", OreTagPrefixBuilder.class, OreTagPrefixBuilder::new); + reg.add(ResourceLocation.parse("ore"), OreTagPrefixBuilder.class, OreTagPrefixBuilder::new); }); registry.addDefault(GTRegistries.RECIPE_TYPE_REGISTRY, GTRecipeTypeBuilder.class, GTRecipeTypeBuilder::new); @@ -175,24 +176,25 @@ public void registerBuilderTypes(BuilderTypeRegistry registry) { new KJSTieredMachineBuilder(id, SimpleTieredMachine::new, SimpleTieredMachine.EDITABLE_UI_CREATOR, false))); - reg.add("custom", KJSWrappingMachineBuilder.class, + reg.add(ResourceLocation.parse("custom"), KJSWrappingMachineBuilder.class, (id) -> new KJSWrappingMachineBuilder(id, new KJSTieredMachineBuilder(id))); - reg.add("steam", KJSSteamMachineBuilder.class, KJSSteamMachineBuilder::new); - reg.add("generator", KJSWrappingMachineBuilder.class, + reg.add(ResourceLocation.parse("steam"), KJSSteamMachineBuilder.class, KJSSteamMachineBuilder::new); + reg.add(ResourceLocation.parse("generator"), KJSWrappingMachineBuilder.class, (id) -> new KJSWrappingMachineBuilder(id, new KJSTieredMachineBuilder(id, SimpleGeneratorMachine::new, SimpleGeneratorMachine.EDITABLE_UI_CREATOR, true))); - reg.add("multiblock", MultiblockMachineBuilderWrapper.class, + reg.add(ResourceLocation.parse("multiblock"), MultiblockMachineBuilderWrapper.class, MultiblockMachineBuilderWrapper::createKJSMulti); - reg.add("tiered_multiblock", KJSWrappingMultiblockBuilder.class, KJSWrappingMultiblockBuilder::new); - reg.add("primitive", MultiblockMachineBuilderWrapper.class, + reg.add(ResourceLocation.parse("tiered_multiblock"), KJSWrappingMultiblockBuilder.class, + KJSWrappingMultiblockBuilder::new); + reg.add(ResourceLocation.parse("primitive"), MultiblockMachineBuilderWrapper.class, (id) -> MultiblockMachineBuilderWrapper.createKJSMulti(id, PrimitiveFancyUIWorkableMachine::new)); }); registry.of(Registries.BLOCK, reg -> { - reg.add("gtceu:active", ActiveBlockBuilder.class, ActiveBlockBuilder::new); - reg.add("gtceu:coil", CoilBlockBuilder.class, CoilBlockBuilder::new); + reg.add(ResourceLocation.parse("gtceu:active"), ActiveBlockBuilder.class, ActiveBlockBuilder::new); + reg.add(ResourceLocation.parse("gtceu:coil"), CoilBlockBuilder.class, CoilBlockBuilder::new); }); registry.addDefault(GTRegistries.ORE_VEIN_REGISTRY, OreVeinDefinitionBuilder.class, @@ -262,17 +264,17 @@ public void registerRecipeFactories(RecipeFactoryRegistry registry) { } @Override - public void registerRecipeComponents(RecipeComponentFactoryRegistry registry) { - registry.register(GTRecipeComponents.TAG); - registry.register(GTRecipeComponents.RECIPE_CONDITION); - registry.register(GTRecipeComponents.RESOURCE_LOCATION); - registry.register(GTRecipeComponents.RECIPE_CAPABILITY); - registry.register(GTRecipeComponents.CHANCE_LOGIC); - registry.register(CapabilityMapComponent.INSTANCE); - - registry.register(GTRecipeComponents.ITEM); - registry.register(GTRecipeComponents.FLUID); - registry.register(GTRecipeComponents.EU); + public void registerRecipeComponents(RecipeComponentTypeRegistry registry) { + registry.register(GTRecipeComponents.TAG.type()); + registry.register(GTRecipeComponents.RECIPE_CONDITION.type()); + registry.register(GTRecipeComponents.RESOURCE_LOCATION.type()); + registry.register(GTRecipeComponents.RECIPE_CAPABILITY.type()); + registry.register(GTRecipeComponents.CHANCE_LOGIC.type()); + registry.register(CapabilityMapComponent.INSTANCE.type()); + + registry.register(GTRecipeComponents.ITEM.type()); + registry.register(GTRecipeComponents.FLUID.type()); + registry.register(GTRecipeComponents.EU.type()); } @Override @@ -291,7 +293,6 @@ public void registerBindings(BindingRegistry event) { event.add("MaterialEntry", MaterialEntry.class); event.add("GTMaterialFlags", MaterialFlags.class); event.add("GTFluidAttributes", FluidAttributes.class); - event.add("GTFluidBuilder", FluidBuilder.class); event.add("GTFluidStorageKeys", FluidStorageKeys.class); event.add("GTFluidState", FluidState.class); event.add("GTMaterialIconSet", MaterialIconSet.class); @@ -334,6 +335,7 @@ public void registerBindings(BindingRegistry event) { event.add("GTCraftingComponents", GTCraftingComponents.class); event.add("EnergyStack", EnergyStack.class); event.add("IOEnergyStack", EnergyStack.WithIO.class); + // event.add("NBTPredicates", NBTPredicates.class); // Sound related event.add("GTSoundEntries", GTSoundEntries.class); event.add("SoundType", SoundType.class); @@ -342,6 +344,8 @@ public void registerBindings(BindingRegistry event) { // Client/Server data related event.add("GTModels", GTModels.class); event.add("GTMachineModels", GTMachineModels.class); + event.add("GTModelProperties", GTMachineModelProperties.class); + event.add("GTDynamicRenders", DynamicRenderHelper.class); // Hazard Related event.add("HazardProperty", HazardProperty.class); @@ -459,7 +463,7 @@ public void registerTypeWrappers(TypeWrapperRegistry registry) { registry.register(IWorldGenLayer.RuleTestSupplier.class, (cx, o, t) -> { if (o instanceof IWorldGenLayer.RuleTestSupplier supplier) return supplier; - return () -> BlockStatePredicate.ruleTestOf(cx, o); + return () -> BlockStatePredicate.wrapRuleTest(cx, o); }); registry.register(CraftingComponent.class, o -> { if (o instanceof CraftingComponent comp) return comp; diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSSteamMachineBuilder.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSSteamMachineBuilder.java index f10c2ad274f..74a18413a56 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSSteamMachineBuilder.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/KJSSteamMachineBuilder.java @@ -4,6 +4,7 @@ import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.property.GTMachineModelProperties; import com.gregtechceu.gtceu.api.machine.steam.SimpleSteamMachine; import com.gregtechceu.gtceu.api.multiblock.util.RelativeDirection; import com.gregtechceu.gtceu.api.registry.registrate.MachineBuilder; @@ -52,7 +53,7 @@ public MachineDefinition createObject() { .langValue("Low Pressure " + FormattingUtil.toEnglishName(this.id.getPath())) .tier(0) .recipeModifier(SimpleSteamMachine::recipeModifier) - .modelProperty(SimpleSteamMachine.VENT_DIRECTION_PROPERTY, RelativeDirection.BACK) + .modelProperty(GTMachineModelProperties.VENT_DIRECTION, RelativeDirection.BACK) .workableSteamHullModel(false, id.withPrefix("block/machines/")); definition.apply(false, lowPressureBuilder); @@ -67,7 +68,7 @@ public MachineDefinition createObject() { .langValue("High Pressure " + FormattingUtil.toEnglishName(this.id.getPath())) .tier(1) .recipeModifier(SimpleSteamMachine::recipeModifier) - .modelProperty(SimpleSteamMachine.VENT_DIRECTION_PROPERTY, RelativeDirection.BACK) + .modelProperty(GTMachineModelProperties.VENT_DIRECTION, RelativeDirection.BACK) .workableSteamHullModel(true, id.withPrefix("block/machines/")); definition.apply(true, highPressureBuilder); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/MultiblockMachineBuilderWrapper.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/MultiblockMachineBuilderWrapper.java index 7cbf8b33059..638e9ce7fe6 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/MultiblockMachineBuilderWrapper.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/builders/machine/MultiblockMachineBuilderWrapper.java @@ -44,7 +44,7 @@ import dev.latvian.mods.kubejs.client.LangKubeEvent; import dev.latvian.mods.kubejs.generator.KubeAssetGenerator; import dev.latvian.mods.kubejs.registry.BuilderBase; -import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Reference2IntMap; import org.apache.commons.lang3.function.TriFunction; import org.jetbrains.annotations.Nullable; @@ -190,7 +190,7 @@ public MultiblockMachineBuilderWrapper tier(int tier) { return this; } - public MultiblockMachineBuilderWrapper recipeOutputLimits(Object2IntMap> map) { + public MultiblockMachineBuilderWrapper recipeOutputLimits(Reference2IntMap> map) { internal.recipeOutputLimits(map); return this; } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/events/CraftingComponentsKubeEvent.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/events/CraftingComponentsKubeEvent.java index 29e58e0c3fe..3982f62c425 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/events/CraftingComponentsKubeEvent.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/events/CraftingComponentsKubeEvent.java @@ -14,10 +14,8 @@ import net.minecraft.world.item.ItemStack; import dev.latvian.mods.kubejs.event.KubeStartupEvent; -import dev.latvian.mods.kubejs.item.ItemStackJS; import dev.latvian.mods.kubejs.script.ConsoleJS; import dev.latvian.mods.kubejs.util.ID; -import dev.latvian.mods.kubejs.util.RegistryAccessContainer; import dev.latvian.mods.rhino.Context; import lombok.NoArgsConstructor; import org.jetbrains.annotations.NotNull; @@ -135,9 +133,12 @@ public void removeTiers(CraftingComponent craftingComponent, int... tiers) { } private static ItemStack parseItemStack(Context cx, Object o) { - ItemStack stack = ItemStackJS.wrap(RegistryAccessContainer.of(cx), o); - if (stack == null || stack.isEmpty()) return null; - return stack; + if (o instanceof ItemStack) { + ItemStack stack = (ItemStack) o; + if (stack == null || stack.isEmpty()) return null; + return stack; + } + return null; } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/events/RegisterWoodsKubeEvent.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/events/RegisterWoodsKubeEvent.java new file mode 100644 index 00000000000..e1e1728dbd2 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/events/RegisterWoodsKubeEvent.java @@ -0,0 +1,280 @@ +package com.gregtechceu.gtceu.integration.kjs.events; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.data.recipe.WoodTypeEntry; + +import net.minecraft.world.item.Item; +import net.minecraft.world.item.Items; + +import dev.latvian.mods.kubejs.event.EventResult; +import dev.latvian.mods.kubejs.event.KubeEvent; +import dev.latvian.mods.rhino.util.HideFromJS; + +import java.util.ArrayList; + +public class RegisterWoodsKubeEvent implements KubeEvent { + + public RegisterWoodsKubeEvent() { + this.woods = new ArrayList<>(); + this.wrapped = new ArrayList<>(); + } + + @HideFromJS + public ArrayList woods; + @HideFromJS + public ArrayList wrapped; + + public class Wrapped { + + RegisterWoodsKubeEvent evt; + String modId; + String woodName; + + @HideFromJS + Wrapped(String modId, String woodName) { + this.modId = modId; + this.woodName = woodName; + } + + private String _recipeId; + private Item _plank; + private Item _strippedLog; + private Item _strippedWood; + private Item _wood; + private Item _log; + private Item _door; + private Item _trapdoor; + private Item _slab; + private Item _fence; + private Item _fenceGate; + private Item _stairs; + private Item _boat; + private Item _chestBoat; + private Item _sign; + private Item _hangingSign; + private Item _button; + private Item _pressurePlate; + + public Wrapped recipeId(String recipeId) { + this._recipeId = recipeId; + return this; + } + + public Wrapped plank(Item plank) { + this._plank = plank; + return this; + } + + public Wrapped strippedLog(Item strippedLog) { + this._strippedLog = strippedLog; + return this; + } + + public Wrapped strippedWood(Item strippedWood) { + this._strippedWood = strippedWood; + return this; + } + + public Wrapped wood(Item wood) { + this._wood = wood; + return this; + } + + public Wrapped log(Item log) { + this._log = log; + return this; + } + + public Wrapped door(Item door) { + this._door = door; + return this; + } + + public Wrapped trapdoor(Item trapdoor) { + this._trapdoor = trapdoor; + return this; + } + + public Wrapped slab(Item slab) { + this._slab = slab; + return this; + } + + public Wrapped fence(Item fence) { + this._fence = fence; + return this; + } + + public Wrapped fenceGate(Item fenceGate) { + this._fenceGate = fenceGate; + return this; + } + + public Wrapped stairs(Item stairs) { + this._stairs = stairs; + return this; + } + + public Wrapped boat(Item boat) { + this._boat = boat; + return this; + } + + public Wrapped chestBoat(Item chestBoat) { + this._chestBoat = chestBoat; + return this; + } + + public Wrapped sign(Item sign) { + this._sign = sign; + return this; + } + + public Wrapped hangingSign(Item hangingSign) { + this._hangingSign = hangingSign; + return this; + } + + public Wrapped button(Item button) { + this._button = button; + return this; + } + + public Wrapped pressurePlate(Item pressurePlate) { + this._pressurePlate = pressurePlate; + return this; + } + + @HideFromJS + public WoodTypeEntry toEntry() throws IllegalArgumentException { + if (this.modId == null) { + throw new IllegalArgumentException("Need a modId"); + } + if (this.woodName == null) { + throw new IllegalArgumentException("Need a woodName"); + } + if (this._recipeId == null) { + throw new IllegalArgumentException("Need a recipeId"); + } + + if (this._plank == null) { + throw new IllegalArgumentException("Need a plank"); + } + + if (this._strippedLog == null) { + throw new IllegalArgumentException("Need a strippedLog"); + } + + if (this._strippedWood == null) { + throw new IllegalArgumentException("Need a strippedWood"); + } + + if (this._wood == null) { + throw new IllegalArgumentException("Need a wood"); + } + + if (this._log == null) { + throw new IllegalArgumentException("Need a log"); + } + + if (this._door == null) { + throw new IllegalArgumentException("Need a door"); + } + + if (this._trapdoor == null) { + throw new IllegalArgumentException("Need a trapdoor"); + } + + if (this._slab == null) { + throw new IllegalArgumentException("Need a slab"); + } + + if (this._fence == null) { + throw new IllegalArgumentException("Need a fence"); + } + + if (this._fenceGate == null) { + throw new IllegalArgumentException("Need a fenceGate"); + } + + if (this._stairs == null) { + throw new IllegalArgumentException("Need a stairs"); + } + + if (this._boat == null) { + throw new IllegalArgumentException("Need a boat"); + } + + if (this._chestBoat == null) { + throw new IllegalArgumentException("Need a chestBoat"); + } + + if (this._sign == null) { + throw new IllegalArgumentException("Need a sign"); + } + + if (this._hangingSign == null) { + throw new IllegalArgumentException("Need a hangingSign"); + } + + if (this._button == null) { + throw new IllegalArgumentException("Need a button"); + } + + if (this._pressurePlate == null) { + throw new IllegalArgumentException("Need a pressurePlate"); + } + + return new WoodTypeEntry.Builder(this.modId, this.woodName) + .planks(this._plank, this._recipeId + "_planks") + .log(Items.OAK_LOG).removeCharcoalRecipe() + .strippedLog(this._strippedLog) + .wood(this._wood) + .strippedWood(this._strippedWood) + .door(this._door, this._recipeId + "_door") + .trapdoor(this._trapdoor, this._recipeId + "_trapdoor") + .slab(this._slab, this._recipeId + "_slab") + .fence(this._fence, this._recipeId + "_fence") + .fenceGate(this._fenceGate, this._recipeId + "_fence_gate") + .stairs(this._stairs, this._recipeId + "_stairs") + .boat(this._boat, this._recipeId + "_boat") + .chestBoat(this._chestBoat, this._recipeId + "_chest_boat") + .sign(this._sign, this._recipeId + "_sign") + .hangingSign(this._hangingSign, this._recipeId + "_hanging_sign") + .button(this._button, this._recipeId + "_button") + .pressurePlate(this._pressurePlate, this._recipeId + "_pressure_plate") + .registerAllMaterialInfo() + .build(); + } + + boolean wasRegistered = false; + + @HideFromJS + public void register() { + if (!this.wasRegistered) { + this.wasRegistered = true; + try { + woods.add(this.toEntry()); + } catch (Exception e) { + GTCEu.LOGGER.error(e); + + } + } else + GTCEu.LOGGER.warn("Tried registering a wood type twice!"); + } + } + + public Wrapped register(String modId, String woodName) { + var wrap = new Wrapped(modId, woodName); + this.wrapped.add(wrap); + return wrap; + } + + @Override + public void afterPosted(EventResult result) { + for (var wrapped : this.wrapped) { + wrapped.register(); + } + KubeEvent.super.afterPosted(result); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/helpers/MaterialStackWrapper.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/helpers/MaterialStackWrapper.java index c64b0c371ad..39ade00624a 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/helpers/MaterialStackWrapper.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/helpers/MaterialStackWrapper.java @@ -33,7 +33,8 @@ public static MaterialStackWrapper fromString(CharSequence str) { } final String copyFinal = copy; - cached = new MaterialStackWrapper(() -> GTMaterials.get(copyFinal), count); + Supplier mat = () -> GTMaterials.get(copyFinal); + cached = new MaterialStackWrapper(mat, count); PARSE_CACHE.put(trimmed, cached); return cached.copy(); } @@ -44,7 +45,7 @@ public MaterialStackWrapper copy() { } public boolean isEmpty() { - return this.amount < 1 || this.material.get().isNull(); + return this.amount < 1 || this.material == null; } public MaterialStack toMatStack() { diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java index b258eb04961..a3596aa4f41 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTRecipeSchema.java @@ -1,13 +1,21 @@ package com.gregtechceu.gtceu.integration.kjs.recipe; import com.gregtechceu.gtceu.GTCEu; -import com.gregtechceu.gtceu.api.capability.recipe.*; +import com.gregtechceu.gtceu.api.capability.recipe.CWURecipeCapability; +import com.gregtechceu.gtceu.api.capability.recipe.EURecipeCapability; +import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; +import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; +import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; +import com.gregtechceu.gtceu.api.machine.MachineDefinition; import com.gregtechceu.gtceu.api.machine.multiblock.CleanroomType; import com.gregtechceu.gtceu.api.material.ChemicalHelper; import com.gregtechceu.gtceu.api.material.material.Material; +import com.gregtechceu.gtceu.api.material.material.stack.MaterialEntry; import com.gregtechceu.gtceu.api.material.material.stack.MaterialStack; import com.gregtechceu.gtceu.api.medicalcondition.MedicalCondition; -import com.gregtechceu.gtceu.api.recipe.*; +import com.gregtechceu.gtceu.api.recipe.RecipeHelper; +import com.gregtechceu.gtceu.api.recipe.ResearchData; +import com.gregtechceu.gtceu.api.recipe.ResearchRecipeBuilder; import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; import com.gregtechceu.gtceu.api.recipe.chance.logic.ChanceLogic; import com.gregtechceu.gtceu.api.recipe.condition.RecipeCondition; @@ -24,18 +32,24 @@ import com.gregtechceu.gtceu.integration.kjs.recipe.components.GTRecipeComponents; import com.gregtechceu.gtceu.utils.ResearchManager; +import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; import net.minecraft.util.valueproviders.IntProvider; import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.Fluid; import net.neoforged.neoforge.common.crafting.SizedIngredient; +import net.neoforged.neoforge.fluids.FluidStack; import net.neoforged.neoforge.fluids.crafting.FluidIngredient; import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient; @@ -57,8 +71,14 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.function.Consumer; +import java.util.function.Supplier; import java.util.function.UnaryOperator; public interface GTRecipeSchema { @@ -83,8 +103,11 @@ class GTKubeRecipe extends KubeRecipe { private final Collection researchRecipeEntries = new ArrayList<>(); private boolean generatingRecipes = true; + // material stacks that are from already resolved inputs public List itemMaterialStacks = new ArrayList<>(); public List fluidMaterialStacks = new ArrayList<>(); + // temporary buffer for unresolved item stacks where decomp is found post recipe addition + public List tempItemStacks = new ArrayList<>(); public boolean itemMaterialInfo = false; public boolean fluidMaterialInfo = false; public boolean removeMaterialInfo = false; @@ -207,19 +230,147 @@ public GTKubeRecipe outputCWU(int cwu) { return output(CWURecipeCapability.CAP, cwu); } + public GTKubeRecipe itemInputs(SizedIngredient... inputs) { + return inputItems(inputs); + } + + public GTKubeRecipe itemInput(MaterialEntry input) { + return inputItems(input); + } + + public GTKubeRecipe itemInput(MaterialEntry input, int count) { + return inputItems(input, count); + } + public GTKubeRecipe inputItems(SizedIngredient... inputs) { + validateItems("input", inputs); + for (var stack : inputs) { - var matInfo = ChemicalHelper.getMaterialInfo(stack.ingredient()); - if (matInfo != null && chance == maxChance && chance != 0) { - for (var matStack : matInfo.getMaterials()) { + // test simple item that have pure singular material stack + var matStack = ChemicalHelper.getMaterialStack(stack.getItems()[0].getItem()); + // test item that has multiple material stacks + var matInfo = ChemicalHelper.getMaterialInfo(stack.getItems()[0].getItem()); + if (chance == maxChance && chance != 0) { + if (!matStack.isEmpty()) { itemMaterialStacks.add(matStack.multiply(stack.count())); } + if (matInfo != null) { + for (var ms : matInfo.getMaterials()) { + itemMaterialStacks.add(ms.multiply(stack.count())); + } + } else { + tempItemStacks.add(stack.getItems()[0].copyWithCount(stack.count())); + } } } return input(ItemRecipeCapability.CAP, (Object[]) inputs); } + public GTKubeRecipe inputItems(ItemStack... inputs) { + validateItems("input", inputs); + + for (ItemStack itemStack : inputs) { + if (itemStack.isEmpty()) { + throw new KubeRuntimeException(String.format("Input items is empty, id: %s", id)); + } + gatherMaterialInfoFromStacks(itemStack); + } + return input(ItemRecipeCapability.CAP, + Arrays.stream(inputs) + .map(stack -> new SizedIngredient( + Ingredient.of(stack), + stack.getCount())) + .toArray()); + } + + public GTKubeRecipe inputItems(TagKey tag, int amount) { + return inputItems(new SizedIngredient(Ingredient.of(tag), amount)); + } + + public GTKubeRecipe inputItems(Item input, int amount) { + return inputItems(new ItemStack(input, amount)); + } + + public GTKubeRecipe inputItems(Item input) { + return inputItems(new SizedIngredient(Ingredient.of(input), 1)); + } + + public GTKubeRecipe inputItems(Supplier input) { + return inputItems(input.get()); + } + + public GTKubeRecipe inputItems(Supplier input, int amount) { + return inputItems(new ItemStack(input.get(), amount)); + } + + public GTKubeRecipe inputItems(TagPrefix orePrefix, Material material) { + return inputItems(orePrefix, material, 1); + } + + public GTKubeRecipe inputItems(MaterialEntry input) { + return inputItems(input.tagPrefix(), input.material(), 1); + } + + public GTKubeRecipe inputItems(MaterialEntry input, int count) { + return inputItems(input.tagPrefix(), input.material(), count); + } + + public GTKubeRecipe inputItems(TagPrefix orePrefix, Material material, int count) { + itemMaterialStacks.add(new MaterialStack(material, orePrefix.getMaterialAmount(material) * count)); + return inputItems(ChemicalHelper.getTag(orePrefix, material), count); + } + + public GTKubeRecipe inputItems(MachineDefinition machine) { + return inputItems(machine, 1); + } + + public GTKubeRecipe inputItems(MachineDefinition machine, int count) { + return inputItems(machine.asStack(count)); + } + + public GTKubeRecipe itemInputsRanged(SizedIngredient ingredient, int min, int max) { + return inputItemsRanged(ingredient.ingredient(), min, max); + } + + public GTKubeRecipe inputItemsRanged(Ingredient ingredient, int min, int max) { + validateItems("ranged input", ingredient); + return input(ItemRecipeCapability.CAP, + new SizedIngredient(IntProviderIngredient.of(ingredient, UniformInt.of(min, max)).toVanilla(), 1)); + } + + public GTKubeRecipe inputItemsRanged(ItemStack stack, int min, int max) { + validateItems("ranged input", stack); + return input(ItemRecipeCapability.CAP, new SizedIngredient( + IntProviderIngredient.of(Ingredient.of(stack), UniformInt.of(min, max)).toVanilla(), 1)); + } + + public GTKubeRecipe itemInputsRanged(TagPrefix orePrefix, Material material, int min, int max) { + return inputItemsRanged(ChemicalHelper.get(orePrefix, material), min, max); + } + + // public GTKubeRecipe inputItemNbtPredicate(ItemStack itemStack, NBTPredicate predicate) { + // if (itemStack.isEmpty()) { + // throw new KubeRuntimeException(String.format("Input items is empty, id: %s", id)); + // } + // gatherMaterialInfoFromStacks(itemStack); + + // return itemInputs(InputItem.of(new NBTPredicateIngredient(itemStack, predicate), itemStack.getCount())); + // } + + public GTKubeRecipe itemOutputs(SizedIngredient... outputs) { + return outputItems(outputs); + } + + // public GTKubeRecipe itemOutput(MaterialEntry materialEntry) { + // return outputItems(materialEntry.tagPrefix(), materialEntry.material()); + // } + + // public GTKubeRecipe itemOutput(MaterialEntry materialEntry, int count) { + // return outputItems(materialEntry.tagPrefix(), materialEntry.material(), count); + // } + public GTKubeRecipe outputItems(SizedIngredient... outputs) { + validateItems("output", outputs); for (SizedIngredient itemStack : outputs) { if (itemStack.ingredient().isEmpty()) { throw new KubeRuntimeException(String.format("Output items is empty, id: %s", id)); @@ -233,12 +384,14 @@ public GTKubeRecipe inputFluids(SizedFluidIngredient... inputs) { } public GTKubeRecipe outputItemsRanged(Ingredient ingredient, int min, int max) { + validateItems("ranged output", ingredient); return output(ItemRecipeCapability.CAP, - new SizedIngredient(IntProviderIngredient.of(ingredient, UniformInt.of(min, max)), 1)); + new SizedIngredient(IntProviderIngredient.of(ingredient, UniformInt.of(min, max)).toVanilla(), 1)); } @HideFromJS public GTKubeRecipe outputItemsRanged(ItemStack stack, int min, int max) { + validateItems("ranged output", stack); return outputItemsRanged(RecipeHelper.makeItemIngredient(stack), min, max); } @@ -247,6 +400,8 @@ public GTKubeRecipe outputItemsRanged(TagPrefix orePrefix, Material material, in } public GTKubeRecipe notConsumableItem(SizedIngredient itemStack) { + validateItems("not consumable", itemStack); + int lastChance = this.chance; this.chance = 0; inputItems(itemStack); @@ -254,7 +409,8 @@ public GTKubeRecipe notConsumableItem(SizedIngredient itemStack) { return this; } - public GTKubeRecipe notConsumableItem(TagPrefix orePrefix, Material material) { + public GTKubeRecipe notConsumable(TagPrefix orePrefix, Material material) { + validateItems("not consumable", orePrefix); int lastChance = this.chance; this.chance = 0; inputItems(SizedIngredient.of(ChemicalHelper.get(orePrefix, material).getItem(), 1)); @@ -262,6 +418,16 @@ public GTKubeRecipe notConsumableItem(TagPrefix orePrefix, Material material) { return this; } + public GTKubeRecipe notConsumableFluid(SizedFluidIngredient fluid) { + validateFluids("not consumable", fluid); + + int lastChance = this.chance; + this.chance = 0; + inputFluids(fluid); + this.chance = lastChance; + return this; + } + public GTKubeRecipe circuit(int configuration) { if (configuration < 0 || configuration > IntCircuitBehaviour.CIRCUIT_MAX) { throw new KubeRuntimeException("Circuit configuration must be in the bounds 0 - 32"); @@ -270,6 +436,8 @@ public GTKubeRecipe circuit(int configuration) { } public GTKubeRecipe chancedInput(SizedIngredient stack, int chance, int tierChanceBoost) { + validateItems("chanced input", stack); + if (0 >= chance || chance > ChanceLogic.getMaxChancedValue()) { throw new KubeRuntimeException( String.format("Chance cannot be less or equal to 0 or more than %s, Actual: %s, id: %s", @@ -303,6 +471,8 @@ public GTKubeRecipe chancedFluidInput(SizedFluidIngredient stack, int chance, } public GTKubeRecipe chancedOutput(SizedIngredient stack, int chance, int tierChanceBoost) { + validateItems("chanced output", stack); + if (0 >= chance || chance > ChanceLogic.getMaxChancedValue()) { throw new KubeRuntimeException( String.format("Chance cannot be less or equal to 0 or more than %s, Actual: %s, id: %s", @@ -328,9 +498,7 @@ public GTKubeRecipe chancedOutput(TagPrefix tag, Material mat, int count, int ch } public GTKubeRecipe chancedOutput(SizedIngredient stack, String fraction, int tierChanceBoost) { - if (stack.count() == 0 || stack.ingredient().isEmpty()) { - return this; - } + validateItems("chanced output", stack); String[] split = fraction.split("/"); if (split.length > 2) { @@ -401,6 +569,8 @@ public GTKubeRecipe chancedOutput(TagPrefix prefix, Material material, String fr } public GTKubeRecipe chancedFluidOutput(SizedFluidIngredient stack, int chance, int tierChanceBoost) { + validateFluids("chanced output", stack); + if (0 >= chance || chance > ChanceLogic.getMaxChancedValue()) { throw new KubeRuntimeException( String.format("Chance cannot be less or equal to 0 or more than %s, Actual: %s, id: %s", @@ -417,6 +587,7 @@ public GTKubeRecipe chancedFluidOutput(SizedFluidIngredient stack, int chance, i } public GTKubeRecipe chancedFluidOutput(SizedFluidIngredient stack, String fraction, int tierChanceBoost) { + validateFluids("chanced output", stack); if (stack.amount() == 0) { return this; } @@ -524,7 +695,34 @@ public GTKubeRecipe chancedTickInputLogic(RecipeCapability cap, ChanceLogic l return this; } + // public GTKubeRecipe inputFluids(SizedFluidIngredient... inputs) { + // validateFluids("input", inputs); + + // for (var fluidIng : inputs) { + // for (var stack : fluidIng.ingredient().getStacks()) { + // var mat = ChemicalHelper.getMaterial(stack.getFluid()); + // if (!mat.isNull()) { + // fluidMaterialStacks.add(new MaterialStack(mat, + // ((long) stack.getAmount() * GTValues.M) / GTValues.L)); + // } + // } + // } + // return input(FluidRecipeCapability.CAP, (Object[]) inputs); + // } + + public GTKubeRecipe inputFluidsRanged(FluidStack input, int min, int max) { + return inputFluidsRanged(input, UniformInt.of(min, max)); + } + + public GTKubeRecipe inputFluidsRanged(FluidStack input, IntProvider range) { + validateFluids("ranged input", input); + FluidStack stack = input.copy(); + return input(FluidRecipeCapability.CAP, + IntProviderFluidIngredient.of(FluidIngredient.of(stack), range)); + } + public GTKubeRecipe outputFluids(SizedFluidIngredient... outputs) { + validateFluids("output", outputs); return output(FluidRecipeCapability.CAP, (Object[]) outputs); } @@ -533,10 +731,89 @@ public GTKubeRecipe outputFluidsRanged(FluidIngredient output, int min, int max) } public GTKubeRecipe outputFluidsRanged(FluidIngredient output, IntProvider range) { + validateFluids("ranged output", output); IntProviderFluidIngredient ing = IntProviderFluidIngredient.of(output, range); return output(FluidRecipeCapability.CAP, new SizedFluidIngredient(ing, 1)); } + ////////////////////////////////////// + // ********** VALIDATION ***********// + ////////////////////////////////////// + + private void validateItems(@NotNull String type, SizedIngredient... items) { + for (var stack : items) { + if (stack == null || stack.getItems().length == 0) { + throw new KubeRuntimeException(String.format("Invalid or empty %s item (recipe ID: %s)", type, id)); + } + } + } + + private void validateItems(@NotNull String type, ItemStack... stacks) { + for (var stack : stacks) { + if (stack == null || stack.isEmpty()) { + throw new KubeRuntimeException(String.format("Invalid or empty %s item (recipe ID: %s)", type, id)); + } + } + } + + private void validateItems(@NotNull String type, Ingredient... ingredients) { + for (var ingredient : ingredients) { + if (ingredient == null || ingredient.isEmpty()) { + throw new KubeRuntimeException(String.format("Invalid or empty %s item (recipe ID: %s)", type, id)); + } + } + } + + private void validateItems(@NotNull String type, IntProviderIngredient... items) { + for (var item : items) { + if (item == null || item.getItemStacks() == null || item.getItemStacks().length == 0) { + throw new KubeRuntimeException(String.format("Invalid or empty %s item (recipe ID: %s)", type, id)); + } + } + } + + private void validateItems(@NotNull String type, TagPrefix... items) { + for (var item : items) { + if (item == null || item.isEmpty()) { + throw new KubeRuntimeException(String.format("Invalid or empty %s item (recipe ID: %s)", type, id)); + } + } + } + + private void validateFluids(@NotNull String type, FluidStack... fluids) { + for (var fluid : fluids) { + if (fluid == null || fluid.getAmount() == 0) { + throw new KubeRuntimeException( + String.format("Invalid or empty %s fluid (recipe ID: %s)", type, id)); + } + } + } + + private void validateFluids(@NotNull String type, FluidIngredient... fluids) { + for (var fluid : fluids) { + if (fluid == null || fluid.getStacks() == null) { + throw new KubeRuntimeException( + String.format("Invalid or empty %s fluid (recipe ID: %s)", type, id)); + } + + for (var stack : fluid.getStacks()) { + if (stack == null || stack.isEmpty()) { + throw new KubeRuntimeException( + String.format("Invalid or empty %s fluid (recipe ID: %s)", type, id)); + } + } + } + } + + private void validateFluids(@NotNull String type, SizedFluidIngredient... stacks) { + for (var stack : stacks) { + if (stack == null || stack.getFluids() == null || stack.getFluids().length == 0) { + throw new KubeRuntimeException( + String.format("Invalid or empty %s fluid (recipe ID: %s)", type, id)); + } + } + } + ////////////////////////////////////// // ********** DATA ***********// ////////////////////////////////////// @@ -684,6 +961,82 @@ public GTKubeRecipe environmentalHazard(MedicalCondition condition) { return environmentalHazard(condition, false); } + public GTKubeRecipe adjacentFluids(Fluid... fluids) { + return adjacentFluids(false, fluids); + } + + public GTKubeRecipe adjacentFluids(boolean isReverse, Fluid... fluids) { + return addCondition(AdjacentFluidCondition.fromFluids(fluids).setReverse(isReverse)); + } + + public GTKubeRecipe adjacentFluid(Fluid... fluids) { + return adjacentFluid(false, fluids); + } + + public GTKubeRecipe adjacentFluid(boolean isReverse, Fluid... fluids) { + return addCondition(AdjacentFluidCondition.fromFluids(fluids).setReverse(isReverse)); + } + + public GTKubeRecipe adjacentFluid(ResourceLocation... tagNames) { + return adjacentFluid(false, tagNames); + } + + public GTKubeRecipe adjacentFluid(boolean isReverse, ResourceLocation... tagNames) { + List> tags = Arrays.stream(tagNames) + .map(id -> TagKey.create(Registries.FLUID, id)) + .toList(); + return addCondition(AdjacentFluidCondition.fromTags(tags).setReverse(isReverse)); + } + + public GTKubeRecipe adjacentFluidTag(ResourceLocation... tagNames) { + return adjacentFluidTag(false, tagNames); + } + + public GTKubeRecipe adjacentFluidTag(boolean isReverse, ResourceLocation... tagNames) { + List> tags = Arrays.stream(tagNames) + .map(id -> TagKey.create(Registries.FLUID, id)) + .toList(); + return addCondition(AdjacentFluidCondition.fromTags(tags).setReverse(isReverse)); + } + + public GTKubeRecipe adjacentBlocks(Block... blocks) { + return adjacentBlocks(false, blocks); + } + + public GTKubeRecipe adjacentBlocks(boolean isReverse, Block... blocks) { + return addCondition(AdjacentBlockCondition.fromBlocks(blocks).setReverse(isReverse)); + } + + public GTKubeRecipe adjacentBlock(Block... blocks) { + return adjacentBlock(false, blocks); + } + + public GTKubeRecipe adjacentBlock(boolean isReverse, Block... blocks) { + return addCondition(AdjacentBlockCondition.fromBlocks(blocks).setReverse(isReverse)); + } + + public GTKubeRecipe adjacentBlockTag(ResourceLocation... tagNames) { + return adjacentBlockTag(false, tagNames); + } + + public GTKubeRecipe adjacentBlockTag(boolean isReverse, ResourceLocation... tagNames) { + List> tags = Arrays.stream(tagNames) + .map(id -> TagKey.create(Registries.BLOCK, id)) + .toList(); + return addCondition(AdjacentBlockCondition.fromTags(tags).setReverse(isReverse)); + } + + public GTKubeRecipe adjacentBlock(ResourceLocation... tagNames) { + return adjacentBlock(false, tagNames); + } + + public GTKubeRecipe adjacentBlock(boolean isReverse, ResourceLocation... tagNames) { + List> tags = Arrays.stream(tagNames) + .map(id -> TagKey.create(Registries.BLOCK, id)) + .toList(); + return addCondition(AdjacentBlockCondition.fromTags(tags).setReverse(isReverse)); + } + public GTKubeRecipe daytime(boolean isNight) { return addCondition(new DaytimeCondition().setReverse(isNight)); } @@ -692,30 +1045,34 @@ public GTKubeRecipe daytime() { return daytime(false); } - public GTKubeRecipe heraclesQuest(String questId, boolean isReverse) { - if (!GTCEu.Mods.isHeraclesLoaded()) { - throw new KubeRuntimeException("Heracles not loaded!"); - } - if (questId.isEmpty()) { - throw new KubeRuntimeException(String.format("Quest ID cannot be empty for recipe %s", this.id)); - } - return addCondition(new HeraclesQuestCondition(isReverse, questId)); + public GTKubeRecipe nighttime() { + return daytime(true); } - public GTKubeRecipe heraclesQuest(String questId) { - return heraclesQuest(questId, false); - } + // public GTKubeRecipe heraclesQuest(String questId, boolean isReverse) { + // if (!GTCEu.Mods.isHeraclesLoaded()) { + // throw new KubeRuntimeException("Heracles not loaded!"); + // } + // if (questId.isEmpty()) { + // throw new KubeRuntimeException(String.format("Quest ID cannot be empty for recipe %s", this.id)); + // } + // return addCondition(new HeraclesQuestCondition(isReverse, questId)); + // } - public GTKubeRecipe gameStage(String stageName) { - return gameStage(stageName, false); - } + // public GTKubeRecipe heraclesQuest(String questId) { + // return heraclesQuest(questId, false); + // } - public GTKubeRecipe gameStage(String stageName, boolean isReverse) { - if (!GTCEu.Mods.isGameStagesLoaded()) { - throw new KubeRuntimeException("GameStages is not loaded, ignoring recipe condition"); - } - return addCondition(new GameStageCondition(isReverse, stageName)); - } + // public GTKubeRecipe gameStage(String stageName) { + // return gameStage(stageName, false); + // } + + // public GTKubeRecipe gameStage(String stageName, boolean isReverse) { + // if (!GTCEu.Mods.isGameStagesLoaded()) { + // throw new KubeRuntimeException("GameStages is not loaded, ignoring recipe condition"); + // } + // return addCondition(new GameStageCondition(isReverse, stageName)); + // } public GTKubeRecipe ftbQuest(String questId, boolean isReverse) { if (!GTCEu.Mods.isFTBQuestsLoaded()) { @@ -834,6 +1191,25 @@ public GTKubeRecipe removePreviousMaterialInfo() { return this; } + private void gatherMaterialInfoFromStacks(ItemStack itemStack) { + // test simple item that have pure singular material stack + var matStack = ChemicalHelper.getMaterialStack(itemStack); + // test item that has multiple material stacks + var matInfo = ChemicalHelper.getMaterialInfo(itemStack); + if (chance == maxChance && chance != 0) { + if (!matStack.isEmpty()) { + itemMaterialStacks.add(matStack.multiply(itemStack.getCount())); + } + if (matInfo != null) { + for (var ms : matInfo.getMaterials()) { + itemMaterialStacks.add(ms.multiply(itemStack.getCount())); + } + } else { + tempItemStacks.add(itemStack); + } + } + } + /* * KubeJS overrides */ diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTShapedRecipeSchema.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTShapedRecipeSchema.java index efdb6742a23..66babb6400f 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTShapedRecipeSchema.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/GTShapedRecipeSchema.java @@ -2,6 +2,7 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.item.tool.ToolHelper; +import com.gregtechceu.gtceu.integration.kjs.recipe.components.StringGridComponent; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.CraftingBookCategory; @@ -16,7 +17,8 @@ import dev.latvian.mods.kubejs.recipe.ingredientaction.IngredientActionHolder; import dev.latvian.mods.kubejs.recipe.schema.KubeRecipeFactory; import dev.latvian.mods.kubejs.recipe.schema.RecipeSchema; -import dev.latvian.mods.kubejs.recipe.schema.RecipeSchemaFunction; +import dev.latvian.mods.kubejs.recipe.schema.function.RecipeFunctionInstance; +import dev.latvian.mods.kubejs.recipe.schema.function.SetFunction; import dev.latvian.mods.kubejs.recipe.special.KubeJSCraftingRecipe; import dev.latvian.mods.kubejs.script.ConsoleJS; import dev.latvian.mods.kubejs.util.TinyMap; @@ -52,10 +54,10 @@ public List getIngredientActions() { // Adapted from KJS's ShapedRecipeSchema#ShapedKubeRecipe @Override - public void afterLoaded() { - super.afterLoaded(); - var pattern = new ArrayList<>(getValue(PATTERN)); - var key = getValue(KEY); + public void validate(RecipeValidationContext cx) { + // super.afterLoaded(stack); + var pattern = new ArrayList<>(cx.recipe().getValue(PATTERN)); + var key = cx.recipe().getValue(KEY); if (pattern.isEmpty()) { throw new KubeRuntimeException("Pattern is empty!"); @@ -90,7 +92,7 @@ public void afterLoaded() { for (char c : pattern.get(i).toCharArray()) { // Inject tool symbol mappings if (tools.contains(c) && !addedTools.contains(c)) { var tool = ToolHelper.getToolFromSymbol(c); - keyEntries.add(new TinyMap.Entry<>(c, Ingredient.of(tool.itemTags.getFirst()))); + keyEntries.add(new TinyMap.Entry<>(c, Ingredient.of(tool.craftingTags.get(0)))); addedTools.add(c); } } @@ -120,9 +122,9 @@ public RecipeTypeFunction getSerializationTypeFunction() { // spotless:off KubeRecipeFactory RECIPE_FACTORY = new KubeRecipeFactory(GTCEu.id("shaped"), ShapedKubeRecipe.class, ShapedKubeRecipe::new); - RecipeKey RESULT = ItemStackComponent.STRICT_ITEM_STACK.outputKey("result"); + RecipeKey RESULT = ItemStackComponent.ITEM_STACK.outputKey("result"); RecipeKey> PATTERN = StringGridComponent.STRING_GRID.otherKey("pattern"); - RecipeKey> KEY = IngredientComponent.INGREDIENT.asPatternKey().inputKey("key"); + RecipeKey> KEY = IngredientComponent.INGREDIENT.instance().asPatternKey().inputKey("key"); RecipeKey MIRROR = BooleanComponent.BOOLEAN.otherKey(KubeJSCraftingRecipe.MIRROR_KEY).optional(true).exclude() .functionNames(List.of("kjsMirror")); RecipeKey SHRINK = BooleanComponent.BOOLEAN.otherKey("kubejs:shrink").optional(true).exclude() @@ -137,6 +139,6 @@ public RecipeTypeFunction getSerializationTypeFunction() { .constructor(RESULT, PATTERN, KEY) .uniqueId(RESULT) .typeOverride(KubeJS.id("shaped")) - .function("noMirror", new RecipeSchemaFunction.SetFunction<>(MIRROR, false)) - .function("noShrink", new RecipeSchemaFunction.SetFunction<>(SHRINK, false)); + .function(new RecipeFunctionInstance("noMirror", new SetFunction.Resolved<>(MIRROR, false))) + .function(new RecipeFunctionInstance("noShrink", new SetFunction.Resolved<>(SHRINK, false))); } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/IDRecipeConstructor.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/IDRecipeConstructor.java index e0a335de30c..c2025713905 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/IDRecipeConstructor.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/IDRecipeConstructor.java @@ -2,6 +2,7 @@ import dev.latvian.mods.kubejs.recipe.KubeRecipe; import dev.latvian.mods.kubejs.recipe.RecipeKey; +import dev.latvian.mods.kubejs.recipe.RecipeScriptContext; import dev.latvian.mods.kubejs.recipe.RecipeTypeFunction; import dev.latvian.mods.kubejs.recipe.component.ComponentValueMap; import dev.latvian.mods.kubejs.recipe.schema.RecipeConstructor; @@ -26,14 +27,14 @@ public IDRecipeConstructor() { public KubeRecipe create(Context cx, SourceLine sourceLine, RecipeTypeFunction type, RecipeSchemaType schemaType, ComponentValueMap from) { var r = super.create(cx, sourceLine, type, schemaType, from); - r.id(KubeResourceLocation.wrap(from.getValue(cx, r, GTRecipeSchema.ID))); + r.id(KubeResourceLocation.wrap(from.getValue(new RecipeScriptContext.Impl(cx, r), GTRecipeSchema.ID))); return r; } @Override - public void setValues(Context cx, KubeRecipe recipe, RecipeSchemaType schemaType, ComponentValueMap from) { + public void setValues(RecipeScriptContext cx, RecipeSchemaType schemaType, ComponentValueMap from) { for (var entry : overrides.entrySet()) { - recipe.setValue(entry.getKey(), Cast.to(entry.getValue().getDefaultValue(schemaType))); + cx.recipe().setValue(entry.getKey(), Cast.to(entry.getValue().getDefaultValue(schemaType))); } } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/CapabilityMapComponent.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/CapabilityMapComponent.java index 1898e855b58..4b7db0f8237 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/CapabilityMapComponent.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/CapabilityMapComponent.java @@ -3,11 +3,13 @@ import com.gregtechceu.gtceu.api.capability.recipe.RecipeCapability; import com.gregtechceu.gtceu.api.recipe.content.Content; +import net.minecraft.resources.ResourceLocation; + import com.mojang.serialization.Codec; -import dev.latvian.mods.kubejs.recipe.KubeRecipe; +import dev.latvian.mods.kubejs.recipe.RecipeScriptContext; import dev.latvian.mods.kubejs.recipe.component.RecipeComponent; +import dev.latvian.mods.kubejs.recipe.component.RecipeComponentType; import dev.latvian.mods.kubejs.recipe.match.ReplacementMatchInfo; -import dev.latvian.mods.rhino.Context; import dev.latvian.mods.rhino.type.TypeInfo; import java.util.concurrent.atomic.AtomicBoolean; @@ -35,14 +37,14 @@ public String toString() { } @Override - public CapabilityMap replace(Context cx, KubeRecipe recipe, CapabilityMap original, + public CapabilityMap replace(RecipeScriptContext cx, CapabilityMap original, ReplacementMatchInfo match, Object with) { AtomicBoolean changed = new AtomicBoolean(false); original.forEach((key, values) -> { var content = GTRecipeComponents.VALID_CAPS.get(key); for (int i = 0; i < values.size(); ++i) { Content value = values.get(i); - Content result = content.replace(cx, recipe, value, match, with); + Content result = content.replace(cx, value, match, with); if (!result.equals(value)) { changed.set(true); values.set(i, result); @@ -51,4 +53,8 @@ public CapabilityMap replace(Context cx, KubeRecipe recipe, CapabilityMap origin }); return changed.get() ? new CapabilityMap(original) : original; } + + public @Override RecipeComponentType type() { + return RecipeComponentType.unit(ResourceLocation.parse("capability_map"), this); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/ContentJS.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/ContentJS.java index e1887b29dab..fcaa7f621aa 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/ContentJS.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/ContentJS.java @@ -4,16 +4,16 @@ import com.gregtechceu.gtceu.api.recipe.content.Content; import com.mojang.serialization.Codec; -import dev.latvian.mods.kubejs.recipe.KubeRecipe; +import dev.latvian.mods.kubejs.recipe.RecipeScriptContext; import dev.latvian.mods.kubejs.recipe.component.RecipeComponent; +import dev.latvian.mods.kubejs.recipe.component.RecipeComponentType; import dev.latvian.mods.kubejs.recipe.match.ReplacementMatchInfo; -import dev.latvian.mods.rhino.Context; import dev.latvian.mods.rhino.type.TypeInfo; -public record ContentJS(RecipeComponent baseComponent, RecipeCapability capability) +public record ContentJS(RecipeComponentType baseComponent, RecipeCapability capability) implements RecipeComponent { - public static ContentJS create(RecipeComponent baseComponent, RecipeCapability capability) { + public static ContentJS create(RecipeComponentType baseComponent, RecipeCapability capability) { return new ContentJS<>(baseComponent, capability); } @@ -28,9 +28,10 @@ public TypeInfo typeInfo() { } @Override - public Content replace(Context cx, KubeRecipe recipe, Content original, ReplacementMatchInfo match, Object with) { + public Content replace(RecipeScriptContext cx, Content original, ReplacementMatchInfo match, Object with) { return new Content( - baseComponent.replace(cx, recipe, baseComponent.wrap(cx, recipe, original.content), match, with), + baseComponent.instance().replace(cx, + baseComponent.instance().wrap(cx, original.content), match, with), original.chance, original.maxChance, original.tierChanceBoost); } @@ -38,4 +39,9 @@ public Content replace(Context cx, KubeRecipe recipe, Content original, Replacem public String toString() { return baseComponent.toString() + "_content"; } + + @Override + public RecipeComponentType type() { + return baseComponent; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/GTRecipeComponents.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/GTRecipeComponents.java index 31f614670e3..b073fdcd2f1 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/GTRecipeComponents.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/GTRecipeComponents.java @@ -16,14 +16,13 @@ import com.mojang.serialization.Codec; import dev.latvian.mods.kubejs.recipe.component.*; -import dev.latvian.mods.kubejs.recipe.component.RecipeComponent; import dev.latvian.mods.rhino.type.TypeInfo; import java.util.*; public class GTRecipeComponents { - public static final RecipeComponent TAG = new RecipeComponent<>() { + public static final RecipeComponent TAG = new RecipeComponent() { @Override public Codec codec() { @@ -39,8 +38,13 @@ public TypeInfo typeInfo() { public String toString() { return "tag"; } + + @Override + public RecipeComponentType type() { + return RecipeComponentType.unit(ResourceLocation.parse("tag"), this); + } }; - public static final RecipeComponent RESOURCE_LOCATION = new RecipeComponent<>() { + public static final RecipeComponent RESOURCE_LOCATION = new RecipeComponent() { @Override public Codec codec() { @@ -56,8 +60,13 @@ public TypeInfo typeInfo() { public String toString() { return "resource_location"; } + + @Override + public RecipeComponentType type() { + return RecipeComponentType.unit(ResourceLocation.parse("resource_location"), this); + } }; - public static final RecipeComponent> RECIPE_CAPABILITY = new RecipeComponent<>() { + public static final RecipeComponent> RECIPE_CAPABILITY = new RecipeComponent>() { @Override public Codec> codec() { @@ -73,8 +82,13 @@ public TypeInfo typeInfo() { public String toString() { return "recipe_capability"; } + + @Override + public RecipeComponentType> type() { + return RecipeComponentType.>unit(ResourceLocation.parse("recipe_capability"), this); + } }; - public static final RecipeComponent CHANCE_LOGIC = new RecipeComponent<>() { + public static final RecipeComponent CHANCE_LOGIC = new RecipeComponent() { @Override public Codec codec() { @@ -90,9 +104,14 @@ public TypeInfo typeInfo() { public String toString() { return "chance_logic"; } + + @Override + public RecipeComponentType type() { + return RecipeComponentType.unit(ResourceLocation.parse("chance_logic"), this); + } }; - public static final RecipeComponent> RECIPE_CONDITION = new RecipeComponent<>() { + public static final RecipeComponent> RECIPE_CONDITION = new RecipeComponent>() { @Override public Codec> codec() { @@ -108,9 +127,14 @@ public TypeInfo typeInfo() { public String toString() { return "recipe_condition"; } + + @Override + public RecipeComponentType> type() { + return RecipeComponentType.>unit(ResourceLocation.parse("recipe_condition"), this); + } }; - public static final RecipeComponent ENERGY_STACK = new RecipeComponent<>() { + public static final RecipeComponent ENERGY_STACK = new RecipeComponent() { @Override public Codec codec() { @@ -129,14 +153,21 @@ public TypeInfo typeInfo() { public String toString() { return "energy_stack"; } + + @Override + public RecipeComponentType type() { + return RecipeComponentType.unit(ResourceLocation.parse("energy_stack"), this); + } }; - public static final ContentJS ITEM = ContentJS.create(SizedIngredientComponent.NESTED, + public static final ContentJS ITEM = ContentJS.create(SizedIngredientComponent.SIZED_INGREDIENT, GTRecipeCapabilities.ITEM); public static final ContentJS FLUID = ContentJS.create(SizedFluidIngredientComponent.NESTED, GTRecipeCapabilities.FLUID); - public static final ContentJS EU = ContentJS.create(ENERGY_STACK, GTRecipeCapabilities.EU); - public static final ContentJS CWU = ContentJS.create(NumberComponent.INT, GTRecipeCapabilities.CWU); + public static final ContentJS EU = ContentJS + .create((RecipeComponentType) ENERGY_STACK.type(), GTRecipeCapabilities.EU); + public static final ContentJS CWU = ContentJS.create(NumberComponent.NON_NEGATIVE_INT, + GTRecipeCapabilities.CWU); public static final RecipeComponent, ChanceLogic>> CHANCE_LOGIC_MAP = new JavaMapRecipeComponent<>( RECIPE_CAPABILITY, CHANCE_LOGIC); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/JavaMapRecipeComponent.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/JavaMapRecipeComponent.java index 433ac1a1263..46b07ad0cbb 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/JavaMapRecipeComponent.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/JavaMapRecipeComponent.java @@ -1,10 +1,11 @@ package com.gregtechceu.gtceu.integration.kjs.recipe.components; +import net.minecraft.resources.ResourceLocation; + import com.mojang.serialization.Codec; -import dev.latvian.mods.kubejs.recipe.KubeRecipe; +import dev.latvian.mods.kubejs.recipe.RecipeScriptContext; import dev.latvian.mods.kubejs.recipe.component.*; import dev.latvian.mods.kubejs.recipe.match.ReplacementMatchInfo; -import dev.latvian.mods.rhino.Context; import dev.latvian.mods.rhino.type.TypeInfo; import java.util.HashMap; @@ -14,12 +15,12 @@ public record JavaMapRecipeComponent(RecipeComponent key, RecipeCompone implements RecipeComponent> { @Override - public Map replace(Context cx, KubeRecipe recipe, Map original, ReplacementMatchInfo match, + public Map replace(RecipeScriptContext cx, Map original, ReplacementMatchInfo match, Object with) { var map = original; for (Map.Entry entry : original.entrySet()) { - var r = value.replace(cx, recipe, entry.getValue(), match, with); + var r = value.replace(cx, entry.getValue(), match, with); if (r != entry.getValue()) { if (map == original) { map = new HashMap<>(original); @@ -45,4 +46,8 @@ public Codec> codec() { public TypeInfo typeInfo() { return TypeInfo.RAW_MAP.withParams(key.typeInfo(), value.typeInfo()); } + + public @Override RecipeComponentType> type() { + return RecipeComponentType.>unit(ResourceLocation.parse("java_map{" + key + ":" + value + "}"), this); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/StringGridComponent.java b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/StringGridComponent.java new file mode 100644 index 00000000000..57428bab4e6 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/kjs/recipe/components/StringGridComponent.java @@ -0,0 +1,31 @@ +package com.gregtechceu.gtceu.integration.kjs.recipe.components; + +import dev.latvian.mods.kubejs.KubeJS; +import dev.latvian.mods.kubejs.recipe.RecipeScriptContext; +import dev.latvian.mods.kubejs.recipe.component.RecipeComponent; +import dev.latvian.mods.kubejs.recipe.component.RecipeComponentType; +import dev.latvian.mods.kubejs.recipe.component.SimpleRecipeComponent; +import dev.latvian.mods.kubejs.recipe.component.StringComponent; + +import java.util.List; + +public class StringGridComponent extends SimpleRecipeComponent> { + + private static final RecipeComponent> PARENT = StringComponent.STRING.instance().asList(); + public static final RecipeComponentType> STRING_GRID = RecipeComponentType + .unit(KubeJS.id("string_grid"), StringGridComponent::new); + + private StringGridComponent(RecipeComponentType type) { + super(type, PARENT.codec(), PARENT.typeInfo()); + } + + @Override + public boolean isEmpty(List value) { + return value.isEmpty(); + } + + @Override + public List wrap(RecipeScriptContext cx, Object from) { + return PARENT.wrap(cx, from); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/ldlib/GTLDLibPlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/ldlib/GTLDLibPlugin.java index 90930c8c66a..2eba6118173 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/ldlib/GTLDLibPlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/ldlib/GTLDLibPlugin.java @@ -5,12 +5,15 @@ import com.lowdragmc.lowdraglib.plugin.ILDLibPlugin; import com.lowdragmc.lowdraglib.plugin.LDLibPlugin; +import org.apache.logging.log4j.LogManager; + @SuppressWarnings("unused") @LDLibPlugin public class GTLDLibPlugin implements ILDLibPlugin { @Override public void onLoad() { + LogManager.getLogger().warn("LDLib plugin is loading!"); GTSyncedFieldAccessors.init(); } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeREICategory.java b/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeREICategory.java index 293b453ffb0..771df3be65f 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeREICategory.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/rei/recipe/GTRecipeREICategory.java @@ -23,6 +23,8 @@ import me.shedaniel.rei.plugin.common.BuiltinPlugin; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; +import java.util.List; import java.util.function.Function; public class GTRecipeREICategory extends ModularUIDisplayCategory { @@ -45,15 +47,31 @@ public GTRecipeREICategory(@NotNull GTRecipeCategory category) { } public static void registerDisplays(DisplayRegistry registry) { + List subCategories = new ArrayList<>(); + // run main categories first for (GTRecipeCategory category : GTRegistries.RECIPE_CATEGORIES) { if (!category.shouldRegisterDisplays()) continue; var type = category.getRecipeType(); - if (category == type.getCategory()) type.buildRepresentativeRecipes(); + if (category == type.getCategory()) { + type.buildRepresentativeRecipes(); + } else { + subCategories.add(category); + continue; + } var identifier = CATEGORIES.apply(category); type.getRecipesInCategory(category).stream() .map(r -> new GTRecipeDisplay(r, identifier)) .forEach(registry::add); } + // run subcategories + for (GTRecipeCategory subCategory : subCategories) { + if (!subCategory.shouldRegisterDisplays()) continue; + var type = subCategory.getRecipeType(); + var identifier = CATEGORIES.apply(subCategory); + type.getRecipesInCategory(subCategory).stream() + .map(r -> new GTRecipeDisplay(r, identifier)) + .forEach(registry::add); + } } public static void registerWorkStations(CategoryRegistry registry) { diff --git a/src/main/java/com/gregtechceu/gtceu/integration/top/TheOneProbePlugin.java b/src/main/java/com/gregtechceu/gtceu/integration/top/TheOneProbePlugin.java index 5f0edb5807f..e221c396472 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/top/TheOneProbePlugin.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/top/TheOneProbePlugin.java @@ -50,6 +50,7 @@ public ResourceLocation getId() { probe.registerProvider(new MachineModeProvider()); probe.registerProvider(new StainedColorProvider()); probe.registerProvider(new PrimitivePumpProvider()); + probe.registerProvider(new DataBankInfoProvider()); probe.registerProvider(new CoverProvider()); probe.registerProvider(new HazardCleanerInfoProvider()); probe.registerProvider(new TransformerInfoProvider()); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/top/provider/ControllableInfoProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/ControllableInfoProvider.java index ed17135f364..eb9e751c3c7 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/top/provider/ControllableInfoProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/ControllableInfoProvider.java @@ -35,7 +35,9 @@ protected void addProbeInfo(IControllable capability, IProbeInfo probeInfo, Play IProbeHitData data) { IProbeInfo horizontalPane = probeInfo .horizontal(probeInfo.defaultLayoutStyle().alignment(ElementAlignment.ALIGN_CENTER)); - if (!capability.isWorkingEnabled()) - horizontalPane.text(CompoundText.create().warning("gtceu.top.working_disabled")); + if (capability.isSuspendAfterFinish()) + horizontalPane.text(CompoundText.create().warning("behaviour.soft_hammer.disabled_cycle")); + else if (!capability.isWorkingEnabled()) + horizontalPane.text(CompoundText.create().warning("behaviour.soft_hammer.disabled")); } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/top/provider/DataBankInfoProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/DataBankInfoProvider.java new file mode 100644 index 00000000000..5ecfa5bedbe --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/DataBankInfoProvider.java @@ -0,0 +1,44 @@ +package com.gregtechceu.gtceu.integration.top.provider; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.research.DataBankMachine; +import com.gregtechceu.gtceu.utils.FormattingUtil; +import com.gregtechceu.gtceu.utils.GTUtil; + +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; + +import mcjty.theoneprobe.api.IProbeHitData; +import mcjty.theoneprobe.api.IProbeInfo; +import mcjty.theoneprobe.api.IProbeInfoProvider; +import mcjty.theoneprobe.api.ProbeMode; + +public class DataBankInfoProvider implements IProbeInfoProvider { + + @Override + public ResourceLocation getID() { + return GTCEu.id("data_bank_provider"); + } + + @Override + public void addProbeInfo(ProbeMode probeMode, IProbeInfo iProbeInfo, Player player, Level level, + BlockState blockState, IProbeHitData iProbeHitData) { + if (MetaMachine.getMachine(level, iProbeHitData.getPos()) instanceof DataBankMachine dataBank) { + IProbeInfo verticalPane = iProbeInfo.vertical(iProbeInfo.defaultLayoutStyle().spacing(0)); + int energyUsage = dataBank.getEnergyUsage(); + String energyFormatted = FormattingUtil.formatNumbers(energyUsage); + // wrap in text component to keep it from being formatted + Component voltageName = Component.literal(GTValues.VNF[GTUtil.getTierByVoltage(energyUsage)]); + Component text = Component.translatable( + "gtceu.multiblock.energy_consumption", + energyFormatted, + voltageName); + verticalPane.text(text); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/top/provider/ParallelProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/ParallelProvider.java index 220baaa76a6..a7eb257361d 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/top/provider/ParallelProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/ParallelProvider.java @@ -33,6 +33,9 @@ public void addProbeInfo(ProbeMode probeMode, IProbeInfo iProbeInfo, Player play BlockEntity blockEntity = level.getBlockEntity(iProbeHitData.getPos()); if (blockEntity instanceof MetaMachineBlockEntity machineBlockEntity) { int parallel = 0; + int batch = 0; + int subtickParallel = 0; + int totalRuns = 0; boolean exact = false; if (machineBlockEntity.getMetaMachine() instanceof IParallelHatch parallelHatch) { parallel = parallelHatch.getCurrentParallel(); @@ -41,6 +44,9 @@ public void addProbeInfo(ProbeMode probeMode, IProbeInfo iProbeInfo, Player play rlm.getRecipeLogic().isActive() && rlm.getRecipeLogic().getLastRecipe() != null) { parallel = rlm.getRecipeLogic().getLastRecipe().parallels; + batch = rlm.getRecipeLogic().getLastRecipe().batchParallels; + subtickParallel = rlm.getRecipeLogic().getLastRecipe().subtickParallels; + totalRuns = rlm.getRecipeLogic().getLastRecipe().getTotalRuns(); exact = true; } else { parallel = controller.getParallelHatch() @@ -48,12 +54,36 @@ public void addProbeInfo(ProbeMode probeMode, IProbeInfo iProbeInfo, Player play .orElse(0); } } - if (parallel > 1) { + + if (!exact && parallel > 1) { Component parallels = Component.literal(FormattingUtil.formatNumbers(parallel)) .withStyle(ChatFormatting.DARK_PURPLE); String key = "gtceu.multiblock.parallel"; - if (exact) key += ".exact"; iProbeInfo.text(Component.translatable(key, parallels)); + } else if (totalRuns > 1) { + Component runs = Component.literal(FormattingUtil.formatNumbers(totalRuns)) + .withStyle(ChatFormatting.DARK_PURPLE); + String key = "gtceu.multiblock.total_runs"; + iProbeInfo.text(Component.translatable(key, runs)); + + if (parallel > 1) { + Component parallels = Component.literal(FormattingUtil.formatNumbers(parallel)) + .withStyle(ChatFormatting.DARK_PURPLE); + String keyParallel = "gtceu.multiblock.parallel.exact"; + iProbeInfo.text(Component.translatable(keyParallel, parallels)); + } + if (batch > 1) { + Component batches = Component.literal(FormattingUtil.formatNumbers(batch)) + .withStyle(ChatFormatting.DARK_PURPLE); + String keyBatch = "gtceu.multiblock.batch_enabled"; + iProbeInfo.text(Component.translatable(keyBatch, batches)); + } + if (subtickParallel > 1) { + Component subticks = Component.literal(FormattingUtil.formatNumbers(subtickParallel)) + .withStyle(ChatFormatting.DARK_PURPLE); + String keySubtick = "gtceu.multiblock.subtick_parallels"; + iProbeInfo.text(Component.translatable(keySubtick, subticks)); + } } } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/top/provider/RecipeLogicInfoProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/RecipeLogicInfoProvider.java index 0f01adf4d54..7ff00ff3db1 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/top/provider/RecipeLogicInfoProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/RecipeLogicInfoProvider.java @@ -4,9 +4,12 @@ import com.gregtechceu.gtceu.api.GTValues; import com.gregtechceu.gtceu.api.capability.GTCapabilityHelper; import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.steam.SimpleSteamMachine; import com.gregtechceu.gtceu.api.machine.steam.SteamMachine; import com.gregtechceu.gtceu.api.machine.trait.RecipeLogic; import com.gregtechceu.gtceu.api.recipe.RecipeHelper; +import com.gregtechceu.gtceu.common.machine.multiblock.steam.SteamParallelMultiblockMachine; +import com.gregtechceu.gtceu.integration.jade.provider.RecipeLogicProvider; import com.gregtechceu.gtceu.utils.FormattingUtil; import com.gregtechceu.gtceu.utils.GTUtil; @@ -49,21 +52,35 @@ protected void addProbeInfo(RecipeLogic capability, IProbeInfo probeInfo, Player // do not show energy usage on machines that do not use energy return; } - String formatted = FormattingUtil.formatNumbers(EUt.getTotalEU()) + TextStyleClass.INFO; Component text = null; if (blockEntity instanceof IMachineBlockEntity machineBlockEntity) { var machine = machineBlockEntity.getMetaMachine(); + long MBt = 0; + if (machine instanceof SimpleSteamMachine ssm) { + MBt = (long) Math.ceil(EUt.getTotalEU() * ssm.getConversionRate()); + } else if (machine instanceof SteamParallelMultiblockMachine smb) { + MBt = (long) Math.ceil(EUt.getTotalEU() * smb.getConversionRate()); + } if (machine instanceof SteamMachine) { - text = Component.literal(formatted + " mB/t").withStyle(ChatFormatting.GREEN); + text = Component.translatable("gtceu.jade.fluid_use", + FormattingUtil.formatNumbers(MBt) + TextStyleClass.INFO) + .withStyle(ChatFormatting.GREEN); } } if (text == null) { - text = Component.literal(formatted + " EU/t ").withStyle(ChatFormatting.RED) - .append(Component.literal("(").withStyle(ChatFormatting.GREEN)) - .append(GTValues.VNF[GTUtil.getTierByVoltage(EUt.voltage())]) - .append(Component.literal(")").withStyle(ChatFormatting.GREEN)); + var tier = GTUtil.getTierByVoltage(RecipeLogicProvider.getVoltage(capability)); + String minAmperage = FormattingUtil + .formatNumber2Places((float) (EUt.getTotalEU()) / GTValues.V[tier]) + TextStyleClass.INFO; + + text = Component.translatable("gtceu.jade.amperage_use", minAmperage).withStyle(ChatFormatting.RED) + .append(Component.translatable("gtceu.jade.at").withStyle(ChatFormatting.GREEN)) + .append(GTValues.VNF[tier]) + .append(Component.translatable("gtceu.universal.padded_parentheses", + (Component.translatable("gtceu.recipe.eu.total", + FormattingUtil.formatNumbers(EUt.getTotalEU()) + TextStyleClass.INFO))) + .withStyle(ChatFormatting.WHITE)); } if (EUt.isInput()) { diff --git a/src/main/java/com/gregtechceu/gtceu/integration/top/provider/RecipeOutputProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/RecipeOutputProvider.java index 5a816cda93a..296d2edae5c 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/top/provider/RecipeOutputProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/RecipeOutputProvider.java @@ -63,7 +63,13 @@ protected void addProbeInfo(RecipeLogic recipeLogic, IProbeInfo iProbeInfo, Play List itemOutputs = new ArrayList<>(); for (var item : itemContents) { - var stacks = ItemRecipeCapability.CAP.of(item.content).getItems(); + ItemStack[] stacks; + SizedIngredient content = ItemRecipeCapability.CAP.of(item.content); + // if (content instanceof IntProviderIngredient provider) { + // stacks = provider.getInner().getItems(); + // } else { + stacks = content.getItems(); + // } if (stacks.length == 0) continue; if (stacks[0].isEmpty()) continue; var stack = stacks[0].copy(); @@ -72,7 +78,7 @@ protected void addProbeInfo(RecipeLogic recipeLogic, IProbeInfo iProbeInfo, Play int count = stack.getCount(); double countD = (double) count * recipe.parallels * function.getBoostedChance(item, recipeTier, chanceTier) / item.maxChance; - count = countD < 1 ? 1 : (int) Math.round(countD); + count = Math.max(1, (int) Math.round(countD)); stack.setCount(count); } itemOutputs.add(RecipeHelper.makeSizedIngredient(stack)); @@ -89,7 +95,7 @@ protected void addProbeInfo(RecipeLogic recipeLogic, IProbeInfo iProbeInfo, Play int amount = stack.getAmount(); double amountD = (double) amount * recipe.parallels * function.getBoostedChance(fluid, recipeTier, chanceTier) / fluid.maxChance; - amount = amountD < 1 ? 1 : (int) Math.round(amountD); + amount = Math.max(1, (int) Math.round(amountD)); stack.setAmount(amount); } fluidOutputs.add(RecipeHelper.makeSizedFluidIngredient(stack)); @@ -116,8 +122,9 @@ private void addItemInfo(IProbeInfo verticalPane, List outputIt String spacer = " "; if (itemOutput.getContainedCustom() instanceof IntProviderIngredient provider) { - spacer += provider.getCountProvider().getMinValue() + "-" + - provider.getCountProvider().getMaxValue() + " "; + spacer += (Component.translatable("gtceu.gui.content.range", + String.valueOf(provider.getCountProvider().getMinValue()), + String.valueOf(provider.getCountProvider().getMaxValue()))) + " "; provider.setItemStacks(null); // no roll provider.setSampledCount(1); } @@ -137,10 +144,10 @@ private void addFluidInfo(IProbeInfo verticalPane, List ou IProbeInfo horizontalPane = verticalPane .horizontal(verticalPane.defaultLayoutStyle().alignment(ElementAlignment.ALIGN_CENTER)); String spacer = " "; - if (fluidOutput.ingredient() instanceof IntProviderFluidIngredient provider) { - spacer += provider.getCountProvider().getMinValue() + "-" + - provider.getCountProvider().getMaxValue() + " "; + spacer += (Component.translatable("gtceu.gui.content.range", + String.valueOf(provider.getCountProvider().getMinValue()), + String.valueOf(provider.getCountProvider().getMaxValue()))) + " "; provider.setFluidStacks(null); // no roll provider.setSampledCount(1); stack.setAmount(provider.getCountProvider().getMaxValue()); // no roll diff --git a/src/main/java/com/gregtechceu/gtceu/integration/top/provider/SteamBoilerInfoProvider.java b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/SteamBoilerInfoProvider.java index 59e113a66a7..1ad3a5517f0 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/top/provider/SteamBoilerInfoProvider.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/top/provider/SteamBoilerInfoProvider.java @@ -3,10 +3,13 @@ import com.gregtechceu.gtceu.GTCEu; import com.gregtechceu.gtceu.api.machine.MetaMachine; import com.gregtechceu.gtceu.api.machine.steam.SteamBoilerMachine; +import com.gregtechceu.gtceu.utils.FormattingUtil; +import net.minecraft.ChatFormatting; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; @@ -33,13 +36,54 @@ protected void addProbeInfo(SteamBoilerMachine capability, IProbeInfo probeInfo, IProbeInfo horizontalPane = probeInfo .horizontal(probeInfo.defaultLayoutStyle().alignment(ElementAlignment.ALIGN_CENTER)); - var producingSteam = !capability.isHasNoWater() && capability.getCurrentTemperature() >= 100; - if (capability.getRecipeLogic().isWorking()) { - horizontalPane.text("gtceu.machine.boiler.info.heating.up", - producingSteam ? Component.translatable("gtceu.machine.boiler.info.producing.steam") : ""); - } else if (capability.getCurrentTemperature() > 0) { - horizontalPane.text("gtceu.machine.boiler.info.cooling.down", - producingSteam ? Component.translatable("gtceu.machine.boiler.info.producing.steam") : ""); + boolean isBurning = capability.getRecipeLogic().isWorking(); + boolean hasWater = !capability.isHasNoWater(); + long production = capability.getTotalSteamOutput(); + int temperature = capability.getCurrentTemperature(); + int maxTemperature = capability.getMaxTemperature(); + + boolean makingSteam = hasWater && temperature >= 100; + + // Determine the first section + MutableComponent root; + if (isBurning && temperature < maxTemperature) { + // Heating up + root = Component.translatable("gtceu.machine.boiler.info.heating.up"); + } else if (!isBurning && temperature > 0) { + // Cooling down + root = Component.translatable("gtceu.machine.boiler.info.cooling.down"); + } else { + root = null; // neither heating nor cooling, is either max temperature or temperature of zero + } + + // Determine the second section + MutableComponent extra; + if (makingSteam) { + // Producing some amount of steam + extra = Component.translatable("gtceu.machine.boiler.info.production.data", + Component.literal(FormattingUtil.formatNumbers(production / 10)) + .withStyle(ChatFormatting.GREEN)); + if (root != null) { + // append some nice separation here to the root + extra = Component.literal(" | ").append(extra); + } + } else if (temperature > 0 && temperature < 100) { + // Still warming up (or cooling down) + extra = Component.literal(String.format(" %s(%s%%)", + // Either heating up or cooling down + isBurning ? ChatFormatting.RED : ChatFormatting.BLUE, + temperature)); + } else { + // Nothing to add + extra = null; + } + + if (root != null && extra != null) { + horizontalPane.text(root.append(extra)); + } else if (root != null) { + horizontalPane.text(root); + } else if (extra != null) { + horizontalPane.text(extra); } } diff --git a/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/fluid/FluidEntryList.java b/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/fluid/FluidEntryList.java index ff5e1c8633c..0d1ec57a5ab 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/fluid/FluidEntryList.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/fluid/FluidEntryList.java @@ -4,7 +4,7 @@ import java.util.List; -public sealed interface FluidEntryList permits FluidStackList, FluidTagList { +public sealed interface FluidEntryList permits FluidStackList, FluidTagList, FluidHolderSetList { List getStacks(); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/fluid/FluidHolderSetList.java b/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/fluid/FluidHolderSetList.java new file mode 100644 index 00000000000..a90bca0deaa --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/fluid/FluidHolderSetList.java @@ -0,0 +1,51 @@ +package com.gregtechceu.gtceu.integration.xei.entry.fluid; + +import net.minecraft.core.HolderSet; +import net.minecraft.world.level.material.Fluid; +import net.neoforged.neoforge.fluids.FluidStack; + +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +public final class FluidHolderSetList implements FluidEntryList { + + @Getter + private final List entries = new ArrayList<>(); + + public static FluidHolderSetList of(@NotNull HolderSet set, int amount) { + var list = new FluidHolderSetList(); + list.add(set, amount); + return list; + } + + public void add(FluidHolderSetEntry entry) { + entries.add(entry); + } + + public void add(@NotNull HolderSet set, int amount) { + add(new FluidHolderSetEntry(set, amount)); + } + + @Override + public boolean isEmpty() { + return entries.isEmpty(); + } + + @Override + public List getStacks() { + return entries.stream() + .flatMap(FluidHolderSetEntry::stacks) + .toList(); + } + + public record FluidHolderSetEntry(@NotNull HolderSet set, int amount) { + + public Stream stacks() { + return set.stream().map(holder -> new FluidStack(holder, amount)); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/item/ItemEntryList.java b/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/item/ItemEntryList.java index 7b4f8f98832..6d4947fbf5c 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/item/ItemEntryList.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/item/ItemEntryList.java @@ -4,7 +4,7 @@ import java.util.List; -public sealed interface ItemEntryList permits ItemStackList, ItemTagList { +public sealed interface ItemEntryList permits ItemStackList, ItemTagList, ItemHolderSetList { List getStacks(); diff --git a/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/item/ItemHolderSetList.java b/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/item/ItemHolderSetList.java new file mode 100644 index 00000000000..b60738e3292 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/integration/xei/entry/item/ItemHolderSetList.java @@ -0,0 +1,53 @@ +package com.gregtechceu.gtceu.integration.xei.entry.item; + +import net.minecraft.core.Holder; +import net.minecraft.core.component.DataComponentPatch; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import lombok.Getter; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +public final class ItemHolderSetList implements ItemEntryList { + + @Getter + private final List entries = new ArrayList<>(); + + public static ItemHolderSetList of(@NotNull Holder set, int amount, @NotNull DataComponentPatch patch) { + var list = new ItemHolderSetList(); + list.add(set, amount, patch); + return list; + } + + public void add(ItemHolderSetEntry entry) { + entries.add(entry); + } + + public void add(@NotNull Holder set, int amount, @NotNull DataComponentPatch patch) { + add(new ItemHolderSetEntry(set, amount, patch)); + } + + @Override + public boolean isEmpty() { + return entries.isEmpty(); + } + + @Override + public List getStacks() { + return entries.stream() + .flatMap(ItemHolderSetEntry::stacks) + .toList(); + } + + public record ItemHolderSetEntry(@NotNull Holder set, int amount, @NotNull DataComponentPatch patch) { + + public Stream stacks() { + // return set.map(holder -> ); + return Stream.of(new ItemStack(set, amount, patch)); + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/integration/xei/widgets/GTRecipeWidget.java b/src/main/java/com/gregtechceu/gtceu/integration/xei/widgets/GTRecipeWidget.java index c9d202f08dc..6534f5473a5 100644 --- a/src/main/java/com/gregtechceu/gtceu/integration/xei/widgets/GTRecipeWidget.java +++ b/src/main/java/com/gregtechceu/gtceu/integration/xei/widgets/GTRecipeWidget.java @@ -354,50 +354,72 @@ private void setTierToMin() { public void collectStorage(Table, Object> extraTable, Table, List> extraContents, GTRecipe recipe) { - Map, List> inputCapabilities = new Object2ObjectLinkedOpenHashMap<>(); for (var entry : recipe.inputs.entrySet()) { RecipeCapability cap = entry.getKey(); List contents = entry.getValue(); extraContents.put(IO.IN, cap, contents); - inputCapabilities.put(cap, cap.createXEIContainerContents(contents, recipe, IO.IN)); } for (var entry : recipe.tickInputs.entrySet()) { RecipeCapability cap = entry.getKey(); List contents = entry.getValue(); - extraContents.put(IO.IN, cap, contents); - inputCapabilities.put(cap, cap.createXEIContainerContents(contents, recipe, IO.IN)); + if (extraContents.get(IO.IN, cap) == null) { + extraContents.put(IO.IN, cap, contents); + } else { + ArrayList fullContents = new ArrayList<>(extraContents.get(IO.IN, cap)); + fullContents.addAll(contents); + extraContents.put(IO.IN, cap, fullContents); + } } - for (var entry : inputCapabilities.entrySet()) { - while (entry.getValue().size() < recipe.recipeType.getMaxInputs(entry.getKey())) entry.getValue().add(null); - var container = entry.getKey().createXEIContainer(entry.getValue()); - if (container != null) { - extraTable.put(IO.IN, entry.getKey(), container); + if (extraContents.containsRow(IO.IN)) { + Map, List> inputCapabilities = new Object2ObjectLinkedOpenHashMap<>(); + for (var entry : extraContents.row(IO.IN).entrySet()) { + RecipeCapability cap = entry.getKey(); + inputCapabilities.put(cap, cap.createXEIContainerContents(entry.getValue(), recipe, IO.IN)); + } + + for (var entry : inputCapabilities.entrySet()) { + while (entry.getValue().size() < recipe.recipeType.getMaxInputs(entry.getKey())) + entry.getValue().add(null); + var container = entry.getKey().createXEIContainer(entry.getValue()); + if (container != null) { + extraTable.put(IO.IN, entry.getKey(), container); + } } } - Map, List> outputCapabilities = new Object2ObjectLinkedOpenHashMap<>(); for (var entry : recipe.outputs.entrySet()) { RecipeCapability cap = entry.getKey(); List contents = entry.getValue(); extraContents.put(IO.OUT, cap, contents); - outputCapabilities.put(cap, cap.createXEIContainerContents(contents, recipe, IO.OUT)); } for (var entry : recipe.tickOutputs.entrySet()) { RecipeCapability cap = entry.getKey(); List contents = entry.getValue(); - extraContents.put(IO.OUT, cap, contents); - outputCapabilities.put(cap, cap.createXEIContainerContents(contents, recipe, IO.OUT)); + if (extraContents.get(IO.OUT, cap) == null) { + extraContents.put(IO.OUT, cap, contents); + } else { + ArrayList fullContents = new ArrayList<>(extraContents.get(IO.IN, cap)); + fullContents.addAll(contents); + extraContents.put(IO.OUT, cap, fullContents); + } } - for (var entry : outputCapabilities.entrySet()) { - while (entry.getValue().size() < recipe.recipeType.getMaxOutputs(entry.getKey())) - entry.getValue().add(null); - var container = entry.getKey().createXEIContainer(entry.getValue()); - if (container != null) { - extraTable.put(IO.OUT, entry.getKey(), container); + if (extraContents.containsRow(IO.OUT)) { + Map, List> outputCapabilities = new Object2ObjectLinkedOpenHashMap<>(); + for (var entry : extraContents.row(IO.OUT).entrySet()) { + RecipeCapability cap = entry.getKey(); + outputCapabilities.put(cap, cap.createXEIContainerContents(entry.getValue(), recipe, IO.OUT)); + } + for (var entry : outputCapabilities.entrySet()) { + while (entry.getValue().size() < recipe.recipeType.getMaxOutputs(entry.getKey())) + entry.getValue().add(null); + var container = entry.getKey().createXEIContainer(entry.getValue()); + if (container != null) { + extraTable.put(IO.OUT, entry.getKey(), container); + } } } } diff --git a/src/main/java/com/gregtechceu/gtceu/syncdata/MonitorGroupPayload.java b/src/main/java/com/gregtechceu/gtceu/syncdata/MonitorGroupPayload.java new file mode 100644 index 00000000000..8e131ed8345 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/syncdata/MonitorGroupPayload.java @@ -0,0 +1,66 @@ +package com.gregtechceu.gtceu.syncdata; + +import com.gregtechceu.gtceu.api.transfer.item.CustomItemStackHandler; +import com.gregtechceu.gtceu.common.machine.multiblock.electric.monitor.MonitorGroup; + +import com.lowdragmc.lowdraglib.syncdata.payload.ObjectTypedPayload; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; + +import org.jetbrains.annotations.Nullable; + +public class MonitorGroupPayload extends ObjectTypedPayload { + + @Override + public @Nullable Tag serializeNBT(HolderLookup.Provider provider) { + CompoundTag tag = new CompoundTag(); + tag.putString("name", payload.getName()); + ListTag list = new ListTag(); + payload.getRelativePositions().forEach(pos -> { + CompoundTag subtag = new CompoundTag(); + subtag.put("pos", NbtUtils.writeBlockPos(pos)); + list.add(subtag); + }); + if (payload.getTargetRaw() != null) { + tag.put("targetPos", NbtUtils.writeBlockPos(payload.getTargetRaw())); + if (payload.getTargetCoverSide() != null) { + tag.putString("targetSide", payload.getTargetCoverSide().getSerializedName()); + } + } + tag.put("positions", list); + tag.putInt("dataSlot", payload.getDataSlot()); + tag.put("items", payload.getItemStackHandler().serializeNBT(provider)); + tag.put("placeholderSlots", payload.getPlaceholderSlotsHandler().serializeNBT(provider)); + return tag; + } + + @Override + public void deserializeNBT(Tag tag, HolderLookup.Provider provider) { + if (tag instanceof CompoundTag compoundTag) { + CustomItemStackHandler handler = new CustomItemStackHandler(), + placeholderSlotsHandler = new CustomItemStackHandler(); + handler.deserializeNBT(provider, compoundTag.getCompound("items")); + placeholderSlotsHandler.deserializeNBT(provider, compoundTag.getCompound("placeholderSlots")); + payload = new MonitorGroup(compoundTag.getString("name"), handler, placeholderSlotsHandler); + ListTag list = compoundTag.getList("positions", Tag.TAG_COMPOUND); + for (int i = 0; i < list.size(); i++) { + payload.add(NbtUtils.readBlockPos(list.getCompound(i), "pos").orElse(BlockPos.ZERO)); + } + if (compoundTag.contains("targetPos", Tag.TAG_COMPOUND)) { + payload.setTarget(NbtUtils.readBlockPos(compoundTag, "targetPos").orElse(BlockPos.ZERO)); + if (compoundTag.contains("targetSide", Tag.TAG_STRING)) { + payload.setTargetCoverSide(Direction.byName(compoundTag.getString("targetSide"))); + } + if (compoundTag.contains("dataSlot", Tag.TAG_INT)) { + payload.setDataSlot(compoundTag.getInt("dataSlot")); + } + } + } + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/syncdata/VirtualItemStorageAccessor.java b/src/main/java/com/gregtechceu/gtceu/syncdata/VirtualItemStorageAccessor.java new file mode 100644 index 00000000000..147f5eea1a6 --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/syncdata/VirtualItemStorageAccessor.java @@ -0,0 +1,32 @@ +package com.gregtechceu.gtceu.syncdata; + +import com.gregtechceu.gtceu.api.misc.virtualregistry.entries.VirtualItemStorage; + +import com.lowdragmc.lowdraglib.syncdata.AccessorOp; +import com.lowdragmc.lowdraglib.syncdata.accessor.CustomObjectAccessor; +import com.lowdragmc.lowdraglib.syncdata.payload.ITypedPayload; +import com.lowdragmc.lowdraglib.syncdata.payload.NbtTagPayload; + +import net.minecraft.core.HolderLookup.Provider; +import net.minecraft.nbt.CompoundTag; + +public class VirtualItemStorageAccessor extends CustomObjectAccessor { + + public static final VirtualItemStorageAccessor INSTANCE = new VirtualItemStorageAccessor(); + + protected VirtualItemStorageAccessor() { + super(VirtualItemStorage.class, true); + } + + @Override + public ITypedPayload serialize(AccessorOp op, VirtualItemStorage value, Provider provider) { + return NbtTagPayload.of(value.serializeNBT(provider)); + } + + @Override + public VirtualItemStorage deserialize(AccessorOp op, ITypedPayload payload, Provider provider) { + var tank = new VirtualItemStorage(); + tank.deserializeNBT(provider, (CompoundTag) payload.getPayload()); + return tank; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/syncdata/VirtualRedstoneAccessor.java b/src/main/java/com/gregtechceu/gtceu/syncdata/VirtualRedstoneAccessor.java new file mode 100644 index 00000000000..936fbbe763c --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/syncdata/VirtualRedstoneAccessor.java @@ -0,0 +1,32 @@ +package com.gregtechceu.gtceu.syncdata; + +import com.gregtechceu.gtceu.api.misc.virtualregistry.entries.VirtualRedstone; + +import com.lowdragmc.lowdraglib.syncdata.AccessorOp; +import com.lowdragmc.lowdraglib.syncdata.accessor.CustomObjectAccessor; +import com.lowdragmc.lowdraglib.syncdata.payload.ITypedPayload; +import com.lowdragmc.lowdraglib.syncdata.payload.NbtTagPayload; + +import net.minecraft.core.HolderLookup.Provider; +import net.minecraft.nbt.CompoundTag; + +public class VirtualRedstoneAccessor extends CustomObjectAccessor { + + public static final VirtualRedstoneAccessor INSTANCE = new VirtualRedstoneAccessor(); + + protected VirtualRedstoneAccessor() { + super(VirtualRedstone.class, true); + } + + @Override + public ITypedPayload serialize(AccessorOp op, VirtualRedstone value, Provider provider) { + return NbtTagPayload.of(value.serializeNBT(provider)); + } + + @Override + public VirtualRedstone deserialize(AccessorOp op, ITypedPayload payload, Provider provider) { + var tank = new VirtualRedstone(); + tank.deserializeNBT(provider, (CompoundTag) payload.getPayload()); + return tank; + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java b/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java index 0accfdd7941..f5871c10b24 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/GTMath.java @@ -1,6 +1,8 @@ package com.gregtechceu.gtceu.utils; +import net.minecraft.util.Mth; import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.fluids.FluidStack; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList; @@ -18,16 +20,36 @@ public static long clamp(long value, long min, long max) { return Math.max(min, Math.min(max, value)); } + public static int lerpInt(double delta, int start, int end) { + return start + Mth.floor(delta * (end - start)); + } + public static List splitStacks(ItemStack stack, long amount) { - int count = saturatedCast(amount); - int fullStacks = count / 64; - int rem = count % 64; + int fullStacks = (int) (amount / Integer.MAX_VALUE); + int rem = (int) (amount % Integer.MAX_VALUE); List stacks = new ObjectArrayList<>(fullStacks + 1); - if (fullStacks > 0) stacks.addAll(Collections.nCopies(fullStacks, stack.copyWithCount(64))); + if (fullStacks > 0) stacks.addAll(Collections.nCopies(fullStacks, stack.copyWithCount(Integer.MAX_VALUE))); if (rem > 0) stacks.add(stack.copyWithCount(rem)); return stacks; } + public static List splitFluidStacks(net.neoforged.neoforge.fluids.FluidStack stack, long amount) { + int fullStacks = (int) (amount / Integer.MAX_VALUE); + int rem = (int) (amount % Integer.MAX_VALUE); + List stacks = new ObjectArrayList<>(fullStacks + 1); + if (fullStacks > 0) { + var copy = stack.copy(); + copy.setAmount(Integer.MAX_VALUE); + stacks.addAll(Collections.nCopies(fullStacks, copy)); + } + if (rem > 0) { + var copy = stack.copy(); + copy.setAmount(rem); + stacks.add(copy); + } + return stacks; + } + public static int[] split(long value) { IntArrayList result = new IntArrayList(); while (value > 0) { @@ -57,4 +79,13 @@ public static int hashLongs(long... vals) { public static float ratio(BigInteger a, BigInteger b) { return new BigDecimal(a).divide(new BigDecimal(b), MathContext.DECIMAL32).floatValue(); } + + public static int ceilDiv(int x, int y) { + final int q = x / y; + // if the signs are the same and modulo not zero, round up + if ((x ^ y) >= 0 && (q * y != x)) { + return q + 1; + } + return q; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/utils/GTMatrixUtils.java b/src/main/java/com/gregtechceu/gtceu/utils/GTMatrixUtils.java index f0d50c759c5..8a09d65ff55 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/GTMatrixUtils.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/GTMatrixUtils.java @@ -9,11 +9,9 @@ import com.google.common.collect.Table; import com.google.common.collect.Tables; import org.jetbrains.annotations.Contract; -import org.joml.Matrix4f; -import org.joml.Matrix4fc; -import org.joml.Vector3f; -import org.joml.Vector3fc; +import org.joml.*; +import java.lang.Math; import java.security.InvalidParameterException; import java.util.Objects; @@ -56,10 +54,30 @@ public static Vector3f getRotationAxis(Vector3f from, final Vector3fc to) { * @param dest the vector to save the result to * @return {@code dest} */ - public static Vector3f getRotationAxis(Vector3fc from, Vector3fc to, Vector3f dest) { + public static Vector3f getRotationAxis(final Vector3fc from, final Vector3fc to, Vector3f dest) { return from.cross(to, dest).normalize(); } + /** + * @param from the original vector + * @param to the wanted vector + * @return the quaternion to make {@code from} point in the direction of {@code to} + */ + @Contract(pure = true) + public static Quaternionf getRotation(final Vector3fc from, final Vector3fc to) { + return from.rotationTo(to, new Quaternionf()); + } + + /** + * @param from the original direction + * @param to the wanted direction + * @return the quaternion to make a vector based on {@code from} point towards {@code to} + */ + @Contract(pure = true) + public static Quaternionf getRotation(final Direction from, final Direction to) { + return getRotation(getDirectionAxis(from), getDirectionAxis(to)); + } + /** * Transforms the {@code matrix} and all {@code additional} vectors such that the {@code from} vector will be on the * {@code to} vector's axis diff --git a/src/main/java/com/gregtechceu/gtceu/utils/GTStringUtils.java b/src/main/java/com/gregtechceu/gtceu/utils/GTStringUtils.java index ee2aa78d512..07cee466125 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/GTStringUtils.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/GTStringUtils.java @@ -1,11 +1,23 @@ package com.gregtechceu.gtceu.utils; +import net.minecraft.ChatFormatting; import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.nbt.ListTag; +import net.minecraft.network.chat.CommonComponents; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentUtils; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.contents.PlainTextContents; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; import net.neoforged.neoforge.fluids.FluidStack; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; public class GTStringUtils { @@ -27,4 +39,219 @@ public static String fluidStackToString(@NotNull FluidStack stack) { ResourceLocation fluidId = BuiltInRegistries.FLUID.getKey(stack.getFluid()); return stack.getAmount() + "x_" + fluidId.getNamespace() + "_" + fluidId.getPath(); } + + /** + * This function does this: + *
    + *
  • {@code 1} -> {@code "1st"}
  • + *
  • {@code 2} -> {@code "2nd"}
  • + *
  • {@code 3} -> {@code "3rd"}
  • + *
  • {@code 4} -> {@code "4th"}
  • + *
  • ...
  • + *
+ */ + @NotNull + public static String getIntOrderingSuffix(int x) { + if ((x % 100) / 10 == 1) return x + "th"; + if (x % 10 == 1) return x + "st"; + if (x % 10 == 2) return x + "nd"; + if (x % 10 == 3) return x + "rd"; + return x + "th"; + } + + /** + * Returns a string with the result of the provided expression. + * This function is intended for use with user input. + * For example: + *
    + *
  • {@code {"12", "+", "34"}} -> {@code "46"}
  • + *
  • {@code {"sqrt", "16"}} -> {@code "4"}
  • + *
  • {@code {"round", "4.5"}} -> {@code "5"}
  • + *
  • {@code {"literally any string"}} -> {@code "literally any string"}
  • + *
  • {@code {"~", "0"}} -> {@code "-1"} // signed bitwise inversion
  • + *
+ * Currently the operations are: {@code {"+", "-", "*", "/", "%", ">>", "<<", "~", "round", "ceil", "floor", + * "sqrt"}} + * + * @param args the arguments, including operands and operation to calculate + * @return the result of the calculation, {@code "Invalid number!"} or {@code "Invalid expression!"} + */ + @NotNull + public static String calc(@NotNull List args) { + // yes I know this is terrible code, but I want to be able to do math in placeholders + // not going to do anything crazy like including lua or python here + if (args.size() == 3) { + try { + long a = Long.parseLong(args.get(0)); + long b = Long.parseLong(args.get(2)); + return switch (args.get(1)) { + case "+" -> String.valueOf(a + b); + case "-" -> String.valueOf(a - b); + case "*" -> String.valueOf(a * b); + case "/" -> String.valueOf(a / b); + case "%" -> String.valueOf(a % b); + case "<<" -> String.valueOf(a << b); + case ">>" -> String.valueOf(a >> b); + default -> "No such operation: '%s'".formatted(args.get(1)); + }; + } catch (NumberFormatException e) { + try { + double a = Double.parseDouble(args.get(0)); + double b = Double.parseDouble(args.get(2)); + return switch (args.get(1)) { + case "/" -> String.valueOf(a / b); + case "+" -> String.valueOf(a + b); + case "-" -> String.valueOf(a - b); + case "*" -> String.valueOf(a * b); + default -> "Invalid number: '%s' or operation '%s'".formatted(e.getMessage(), args.get(1)); + }; + } catch (NumberFormatException ex) { + return "Invalid number '%s'!".formatted(ex.getMessage()); + } + } + } else if (args.size() == 2) { + try { + long a = Long.parseLong(args.get(1)); + return switch (args.get(0)) { + case "~" -> String.valueOf(~a); + case "sqrt" -> String.valueOf(Math.sqrt(a)); + default -> "No such operation: '%s'".formatted(args.get(0)); + }; + } catch (NumberFormatException e) { + try { + double a = Double.parseDouble(args.get(1)); + return switch (args.get(0)) { + case "round" -> String.valueOf(Math.round(a)); + case "ceil" -> String.valueOf(Math.ceil(a)); + case "floor" -> String.valueOf(Math.floor(a)); + case "sqrt" -> String.valueOf(Math.sqrt(a)); + default -> "Invalid number '%s' or operation '%s'!".formatted(e.getMessage(), args.get(0)); + }; + } catch (NumberFormatException e2) { + return "Invalid number '%s'!".formatted(e2.getMessage()); + } + } + } else if (args.size() == 1) return args.get(0); + return "Invalid expression!"; + } + + public static List literalLine(String s) { + return new ArrayList<>(List.of(Component.literal(s))); + } + + public static List literalLine(long n) { + return literalLine(String.valueOf(n)); + } + + public static boolean equals(List components, String s) { + return Objects.equals(componentsToString(components), s); + } + + public static double toDouble(List components) throws NumberFormatException { + if (components.isEmpty()) return 0; + if (components.size() > 1) throw new NumberFormatException(componentsToString(components)); + return Double.parseDouble(components.get(0).getString()); + } + + public static int toInt(List components) throws NumberFormatException { + if (components.isEmpty()) return 0; + if (components.size() > 1) throw new NumberFormatException(componentsToString(components)); + return Integer.parseInt(components.get(0).getString()); + } + + public static String componentsToString(List components) { + StringBuilder out = new StringBuilder(); + if (components.isEmpty()) return out.toString(); + for (Component component : components) { + out.append(component.getString()); + out.append('\n'); + } + return out.substring(0, out.length() - 1); + } + + public static void append(List components, @Nullable String s) { + if (s != null) + GTUtil.getLast(components).append(s); + } + + public static void append(List components, char c) { + append(components, String.valueOf(c)); + } + + public static void append(List components, @Nullable List lines) { + if (lines == null) return; + if (lines.isEmpty()) return; + for (Component line : lines) { + GTUtil.getLast(components).append(line); + components.add(MutableComponent.create(PlainTextContents.EMPTY)); + } + components.remove(components.size() - 1); + } + + public static List toImmutable(List singleOrMultiLang) { + return singleOrMultiLang.stream().map((c) -> (Component) c).toList(); + } + + public static List literalLine(double d) { + return literalLine(String.valueOf(d)); + } + + public static String replace(String s, String regex, List replacements) { + List out = new ArrayList<>(); + out.add(s); + replacements.forEach(replacement -> out.set(0, out.get(0).replaceFirst(regex, replacement))); + return out.get(0); + } + + public static Component toComponent(ListTag arr) { + return toComponent(List.of(arr.toArray(new String[0]))); + } + + public static Component toComponent(List arr) { + MutableComponent component = Component.literal("["); + if (arr.size() <= 5) { + for (int i = 0; i < arr.size(); i++) { + component.append(Component.literal('"' + arr.get(i) + '"').withStyle(ChatFormatting.DARK_AQUA)); + if (i != arr.size() - 1) component.append(", "); + } + } else { + for (int i = 0; i < 2; i++) { + component.append(Component.literal('"' + arr.get(i) + '"').withStyle(ChatFormatting.DARK_AQUA)); + component.append(", "); + } + component.append("..., "); + for (int i = arr.size() - 2; i < arr.size(); i++) { + component.append(Component.literal('"' + arr.get(i) + '"').withStyle(ChatFormatting.DARK_AQUA)); + if (i != arr.size() - 1) component.append(", "); + } + } + component.append("]"); + return component; + } + + public static Component toCompactedComponent(List list) { + MutableComponent component = Component.literal("["); + if (list.size() <= 5) { + for (int i = 0; i < list.size(); i++) { + component.append(Component.literal('"' + list.get(i) + '"').withStyle(ChatFormatting.DARK_AQUA)); + if (i != list.size() - 1) { + component.append(ComponentUtils.DEFAULT_NO_STYLE_SEPARATOR); + } + } + } else { + for (int i = 0; i < 2; i++) { + component.append(Component.literal('"' + list.get(i) + '"').withStyle(ChatFormatting.DARK_AQUA)); + component.append(ComponentUtils.DEFAULT_NO_STYLE_SEPARATOR); + } + component.append(CommonComponents.ELLIPSIS).append(ComponentUtils.DEFAULT_NO_STYLE_SEPARATOR); + for (int i = list.size() - 2; i < list.size(); i++) { + component.append(Component.literal('"' + list.get(i) + '"').withStyle(ChatFormatting.DARK_AQUA)); + if (i != list.size() - 1) { + component.append(ComponentUtils.DEFAULT_NO_STYLE_SEPARATOR); + } + } + } + component.append("]"); + return component; + } } diff --git a/src/main/java/com/gregtechceu/gtceu/utils/GTUtil.java b/src/main/java/com/gregtechceu/gtceu/utils/GTUtil.java index 0276ba75457..05f11c8c078 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/GTUtil.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/GTUtil.java @@ -19,6 +19,8 @@ import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.Style; import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; import net.minecraft.tags.BiomeTags; import net.minecraft.util.RandomSource; import net.minecraft.util.Tuple; @@ -30,7 +32,12 @@ import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.level.Level; import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.SnowLayerBlock; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Fluid; +import net.minecraft.world.level.material.MapColor; import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; import net.neoforged.neoforge.common.Tags; import net.neoforged.neoforge.fluids.FluidStack; @@ -47,6 +54,7 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.*; +import java.util.function.Function; import static com.gregtechceu.gtceu.api.material.material.properties.PropertyKey.HAZARD; @@ -66,6 +74,17 @@ public class GTUtil { private static final Object2IntMap RVN = new Object2IntArrayMap<>(GTValues.VN, GTValues.ALL_TIERS); + private static final MapColor[] MAP_COLORS; + + static { + int maxId = MapColor.GLOW_LICHEN.id; + MAP_COLORS = new MapColor[maxId]; + for (int i = 0; i < maxId; i++) { + // Skip MapColor.NONE + MAP_COLORS[i] = MapColor.byId(i + 1); + } + } + /** * Convenience method to get from VN -> Tier * @@ -377,19 +396,30 @@ public static int getPumpBiomeModifier(Holder biome) { /** * Determines dye color nearest to specified RGB color */ - public static @Nullable DyeColor determineDyeColor(int rgbColor) { + public static DyeColor determineDyeColor(int rgbColor) { + return closestColor(rgbColor, DyeColor.values(), DyeColor::getTextColor); + } + + /** + * Determines map color nearest to specified RGB color + */ + public static MapColor determineMapColor(int rgbColor) { + return closestColor(rgbColor, MAP_COLORS, c -> c.calculateRGBColor(MapColor.Brightness.NORMAL)); + } + + private static T closestColor(int rgbColor, T[] colors, Function extractRgbColor) { float[] c = GradientUtil.getRGB(rgbColor); double min = Double.MAX_VALUE; - DyeColor minColor = null; - for (DyeColor dyeColor : DyeColor.values()) { - float[] c2 = GradientUtil.getRGB(dyeColor.getTextColor()); + T minColor = null; + for (T color : colors) { + float[] c2 = GradientUtil.getRGB(extractRgbColor.apply(color)); double distance = (c[0] - c2[0]) * (c[0] - c2[0]) + (c[1] - c2[1]) * (c[1] - c2[1]) + (c[2] - c2[2]) * (c[2] - c2[2]); - if (min > distance) { - minColor = dyeColor; + if (Double.compare(min, distance) > 0) { + minColor = color; min = distance; } } @@ -445,6 +475,45 @@ public static boolean canSeeSunClearly(Level world, BlockPos blockPos) { } else return world.isDay(); } + /** + * @param state the blockstate to check + * @return if the block is a snow layer or snow block + */ + public static boolean isBlockSnow(@NotNull BlockState state) { + return state.is(Blocks.SNOW) || state.is(Blocks.SNOW_BLOCK); + } + + /** + * Attempt to break a (single) snow layer at the given BlockPos. + * Will also turn snow blocks into snow layers at height 7. + * + * @return true if the passed IBlockState was valid snow block + */ + public static boolean tryBreakSnow(@NotNull Level level, @NotNull BlockPos pos, @NotNull BlockState state, + boolean playSound) { + boolean success = false; + if (state.is(Blocks.SNOW_BLOCK)) { + level.setBlock(pos, Blocks.SNOW.defaultBlockState().setValue(SnowLayerBlock.LAYERS, 7), + Block.UPDATE_ALL_IMMEDIATE); + success = true; + } else if (state.getBlock() == Blocks.SNOW) { + int layers = state.getValue(SnowLayerBlock.LAYERS); + if (layers == 1) { + level.destroyBlock(pos, false); + } else { + level.setBlock(pos, Blocks.SNOW.defaultBlockState().setValue(SnowLayerBlock.LAYERS, layers - 1), + Block.UPDATE_ALL_IMMEDIATE); + } + success = true; + } + + if (success && playSound) { + level.playSound(null, pos, SoundEvents.LAVA_EXTINGUISH, SoundSource.BLOCKS, 1.0f, 1.0f); + } + + return success; + } + public static void appendHazardTooltips(Material material, List tooltipComponents) { if (!ConfigHolder.INSTANCE.gameplay.hazardsEnabled || !material.hasProperty(HAZARD)) return; @@ -508,4 +577,16 @@ public static EquipmentSlot equipmentSlotByTypeAndIndex(EquipmentSlot.Type slotT throw new IllegalArgumentException("Invalid slot '" + slotType + "': " + slotIndex); } + + public static boolean isSameItemSameTags(ItemStack s1, ItemStack s2) { + return ItemStack.isSameItemSameComponents(s1, s2); + } + + public static T getLast(List list) { + return list.get(list.size() - 1); + } + + public static ArrayList list(T obj) { + return new ArrayList<>(List.of(obj)); + } } diff --git a/src/main/java/com/gregtechceu/gtceu/utils/OverlayedItemHandler.java b/src/main/java/com/gregtechceu/gtceu/utils/OverlayedItemHandler.java index 1b0107fd289..4ca9ad81bb6 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/OverlayedItemHandler.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/OverlayedItemHandler.java @@ -56,7 +56,7 @@ public int insertStackedItemStack(@NotNull ItemStack stack, int amountToInsert) initSlot(i); // if it's the same item or there is no item in the slot ItemStack slotKey = this.slots[i].getItemStack(); - if (slotKey.isEmpty() || ItemStack.isSameItemSameComponents(slotKey, stack)) { + if (slotKey.isEmpty() || GTUtil.isSameItemSameTags(slotKey, stack)) { // if the slot is not full int canInsertUpTo = Math.min(this.slots[i].getSlotLimit() - this.slots[i].getCount(), stack.getMaxStackSize()); @@ -140,7 +140,7 @@ public ItemStack getItemStack() { } public void setItemStack(@NotNull ItemStack itemStack) { - if (!ItemStack.isSameItemSameComponents(this.itemStack, itemStack)) { + if (!GTUtil.isSameItemSameTags(this.itemStack, itemStack)) { this.itemStack = itemStack; this.slotLimit = Math.min(itemStack.getMaxStackSize(), slotLimit); } diff --git a/src/main/java/com/gregtechceu/gtceu/utils/ResearchManager.java b/src/main/java/com/gregtechceu/gtceu/utils/ResearchManager.java index 9090fc05357..490e6d6400c 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/ResearchManager.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/ResearchManager.java @@ -5,7 +5,9 @@ import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; import com.gregtechceu.gtceu.api.recipe.GTRecipeSerializer; import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.ingredient.EnergyStack; import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; +import com.gregtechceu.gtceu.common.item.datacomponents.DataItem; import com.gregtechceu.gtceu.common.recipe.builder.GTRecipeBuilder; import com.gregtechceu.gtceu.config.ConfigHolder; import com.gregtechceu.gtceu.data.item.GTDataComponents; @@ -59,8 +61,8 @@ private ResearchManager() {} */ public static boolean isStackDataItem(@NotNull ItemStack stack, boolean isDataBank) { @Nullable - Boolean dataItem = stack.get(GTDataComponents.DATA_ITEM); - return dataItem != null && !dataItem || isDataBank; + DataItem dataItem = stack.get(GTDataComponents.DATA_ITEM); + return dataItem != null && dataItem.requireDataBank() || isDataBank; } /** @@ -85,7 +87,8 @@ public static void createDefaultResearchRecipe(@NotNull GTRecipeBuilder builder, public static void createDefaultResearchRecipe(@NotNull GTRecipeType recipeType, @NotNull String researchId, @NotNull ItemStack researchItem, @NotNull FluidStack researchFluid, @NotNull ItemStack dataItem, - int duration, int EUt, int CWUt, RecipeOutput provider) { + int duration, EnergyStack eut, int CWUt, + RecipeOutput provider) { if (!ConfigHolder.INSTANCE.machines.enableResearch) return; dataItem.set(GTDataComponents.RESEARCH_ITEM, new ResearchItem(researchId, recipeType)); @@ -99,7 +102,7 @@ public static void createDefaultResearchRecipe(@NotNull GTRecipeType recipeType, if (!researchFluid.isEmpty()) builder.inputFluids(researchFluid); builder.outputItems(dataItem) - .EUt(EUt) + .EUt(eut.voltage(), eut.amperage()) .CWUt(CWUt) .totalCWU(duration) .save(provider); @@ -112,7 +115,7 @@ public static void createDefaultResearchRecipe(@NotNull GTRecipeType recipeType, builder.outputItems(dataItem) .duration(duration) - .EUt(EUt) + .EUt(eut.voltage(), eut.amperage()) .researchScan(true) .save(provider); } diff --git a/src/main/java/com/gregtechceu/gtceu/utils/input/IKeyPressedListener.java b/src/main/java/com/gregtechceu/gtceu/utils/input/IKeyPressedListener.java new file mode 100644 index 00000000000..c7857530e9b --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/utils/input/IKeyPressedListener.java @@ -0,0 +1,15 @@ +package com.gregtechceu.gtceu.utils.input; + +import net.minecraft.server.level.ServerPlayer; + +@FunctionalInterface +public interface IKeyPressedListener { + + /** + * Called server-side only when a player presses a specified keybinding. + * + * @param player The player who pressed the key. + * @param keyPressed The key the player pressed. + */ + void onKeyPressed(ServerPlayer player, SyncedKeyMapping keyPressed, boolean isDown); +} diff --git a/src/main/java/com/gregtechceu/gtceu/utils/input/KeyBind.java b/src/main/java/com/gregtechceu/gtceu/utils/input/KeyBind.java index bb8768c5737..2682a8cca71 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/input/KeyBind.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/input/KeyBind.java @@ -24,6 +24,10 @@ import java.util.*; import java.util.function.Supplier; +/** + * @deprecated Use {@link SyncedKeyMappings} instead + */ +@Deprecated @EventBusSubscriber(modid = GTCEu.MOD_ID, value = Dist.CLIENT, bus = EventBusSubscriber.Bus.GAME) public enum KeyBind { diff --git a/src/main/java/com/gregtechceu/gtceu/utils/input/SyncedKeyMapping.java b/src/main/java/com/gregtechceu/gtceu/utils/input/SyncedKeyMapping.java new file mode 100644 index 00000000000..cd5ad3c616f --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/utils/input/SyncedKeyMapping.java @@ -0,0 +1,252 @@ +package com.gregtechceu.gtceu.utils.input; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.common.network.packets.CPacketKeyDown; + +import net.minecraft.client.KeyMapping; +import net.minecraft.client.Minecraft; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.player.Player; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.neoforge.client.event.ClientTickEvent; +import net.neoforged.neoforge.client.event.RegisterKeyMappingsEvent; +import net.neoforged.neoforge.client.settings.IKeyConflictContext; +import net.neoforged.neoforge.network.PacketDistributor; + +import com.mojang.blaze3d.platform.InputConstants; +import it.unimi.dsi.fastutil.ints.Int2BooleanMap; +import it.unimi.dsi.fastutil.ints.Int2BooleanOpenHashMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectMap; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import org.jetbrains.annotations.ApiStatus; + +import java.util.Collections; +import java.util.Set; +import java.util.WeakHashMap; +import java.util.function.Supplier; + +public final class SyncedKeyMapping { + + private static final Int2ObjectMap KEYMAPPINGS = new Int2ObjectOpenHashMap<>(); + private static int syncIndex = 0; + + @OnlyIn(Dist.CLIENT) + private KeyMapping keyMapping; + @OnlyIn(Dist.CLIENT) + private Supplier> keyMappingGetter; + private final boolean needsRegister; + @OnlyIn(Dist.CLIENT) + private int keyCode; + @OnlyIn(Dist.CLIENT) + private boolean isKeyDown; + + private static final Int2BooleanMap updatingKeyDown = new Int2BooleanOpenHashMap(); + + private final WeakHashMap serverMapping = new WeakHashMap<>(); + private final WeakHashMap> playerListeners = new WeakHashMap<>(); + private final Set globalListeners = Collections.newSetFromMap(new WeakHashMap<>()); + + private SyncedKeyMapping(Supplier> mcKeyMapping) { + if (GTCEu.isClientSide()) { + this.keyMappingGetter = mcKeyMapping; + } + // Does not need to be registered, will be registered by MC + this.needsRegister = false; + + KEYMAPPINGS.put(syncIndex++, this); + } + + private SyncedKeyMapping(int keyCode) { + if (GTCEu.isClientSide() && !GTCEu.isDataGen()) { + this.keyCode = keyCode; + } + // Does not need to be registered, is not a configurable key mapping + this.needsRegister = false; + + KEYMAPPINGS.put(syncIndex++, this); + } + + private SyncedKeyMapping(String nameKey, IKeyConflictContext ctx, int keyCode, String category) { + if (GTCEu.isClientSide() && !GTCEu.isDataGen()) { + this.keyMapping = (KeyMapping) createKeyMapping(nameKey, ctx, keyCode, category); + } + this.needsRegister = true; + KEYMAPPINGS.put(syncIndex++, this); + } + + /** + * Create a SyncedKeyMapping wrapper around a Minecraft {@link KeyMapping}. + * + * @param mcKeyMapping Doubly-wrapped supplier around a keymapping from + * {@link net.minecraft.client.Options Minecraft.getInstance().options}. + */ + public static SyncedKeyMapping createFromMC(Supplier> mcKeyMapping) { + return new SyncedKeyMapping(mcKeyMapping); + } + + /** + * Create a new SyncedKeyMapping for a specified key code. + * + * @param keyCode The key code. + */ + public static SyncedKeyMapping create(int keyCode) { + return new SyncedKeyMapping(keyCode); + } + + /** + * Create a new SyncedKeyMapping with server held and pressed syncing to server.
+ * Will automatically create a keymapping entry in the MC options page under the GregTechCEu category. + * + * @param nameKey Translation key for the keymapping name. + * @param ctx Conflict context for the keymapping options category. + * @param keyCode The key code, from {@link InputConstants}. + */ + public static SyncedKeyMapping createConfigurable(String nameKey, IKeyConflictContext ctx, int keyCode) { + return createConfigurable(nameKey, ctx, keyCode, GTCEu.NAME); + } + + /** + * Create a new SyncedKeyMapping with server held and pressed syncing to server.
+ * Will automatically create a keymapping entry in the MC options page under the specified category. + * + * @param nameKey Translation key for the keymapping name. + * @param ctx Conflict context for the keymapping options category. + * @param keyCode The key code, from {@link InputConstants}. + * @param category The category in the MC options page. + */ + public static SyncedKeyMapping createConfigurable(String nameKey, IKeyConflictContext ctx, int keyCode, + String category) { + return new SyncedKeyMapping(nameKey, ctx, keyCode, category); + } + + @OnlyIn(Dist.CLIENT) + private Object createKeyMapping(String nameKey, IKeyConflictContext ctx, int keyCode, String category) { + return new KeyMapping(nameKey, ctx, InputConstants.Type.KEYSYM, keyCode, category); + } + + /** + * Check if a player is currently holding down this key. + * + * @param player The player to check. + * + * @return If the key is held. + */ + public boolean isKeyDown(Player player) { + if (player.level().isClientSide) { + if (keyMapping != null) { + return keyMapping.isDown(); + } + long id = Minecraft.getInstance().getWindow().getWindow(); + return InputConstants.isKeyDown(id, keyCode); + } + Boolean isKeyDown = serverMapping.get((ServerPlayer) player); + return isKeyDown != null ? isKeyDown : false; + } + + /** + * Registers an {@link IKeyPressedListener} to this key, which will have its {@link IKeyPressedListener#onKeyPressed + * onKeyPressed} method called when the provided player presses this key. + * + * @param player The player who owns this listener. + * @param listener The handler for the key clicked event. + */ + public SyncedKeyMapping registerPlayerListener(ServerPlayer player, IKeyPressedListener listener) { + Set listenerSet = playerListeners + .computeIfAbsent(player, $ -> Collections.newSetFromMap(new WeakHashMap<>())); + listenerSet.add(listener); + return this; + } + + public static void onRegisterKeyBinds(RegisterKeyMappingsEvent event) { + for (SyncedKeyMapping value : KEYMAPPINGS.values()) { + if (value.keyMappingGetter != null) { + value.keyMapping = value.keyMappingGetter.get().get(); + value.keyMappingGetter = null; + } + if (value.keyMapping != null && value.needsRegister) { + event.register(value.keyMapping); + } + } + } + + /** + * Remove a player's listener on this keymapping for a provided player. + * + * @param player The player who owns this listener. + * @param listener The handler for the key clicked event. + */ + public void removePlayerListener(ServerPlayer player, IKeyPressedListener listener) { + Set listenerSet = playerListeners.get(player); + if (listenerSet != null) { + listenerSet.remove(listener); + } + } + + /** + * Registers an {@link IKeyPressedListener} to this key, which will have its {@link IKeyPressedListener#onKeyPressed + * onKeyPressed} method called when any player presses this key. + * + * @param listener The handler for the key clicked event. + */ + public SyncedKeyMapping registerGlobalListener(IKeyPressedListener listener) { + globalListeners.add(listener); + return this; + } + + /** + * Remove a global listener on this keybinding. + * + * @param listener The handler for the key clicked event. + */ + public void removeGlobalListener(IKeyPressedListener listener) { + globalListeners.remove(listener); + } + + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void onClientTick(ClientTickEvent.Pre event) { + updatingKeyDown.clear(); + for (var entry : KEYMAPPINGS.int2ObjectEntrySet()) { + SyncedKeyMapping keyMapping = entry.getValue(); + boolean previousKeyDown = keyMapping.isKeyDown; + + if (keyMapping.keyMapping != null) { + keyMapping.isKeyDown = keyMapping.keyMapping.isDown(); + } else { + long id = Minecraft.getInstance().getWindow().getWindow(); + keyMapping.isKeyDown = InputConstants.isKeyDown(id, keyMapping.keyCode); + } + + if (previousKeyDown != keyMapping.isKeyDown) { + updatingKeyDown.put(entry.getIntKey(), keyMapping.isKeyDown); + } + } + if (!updatingKeyDown.isEmpty()) { + PacketDistributor.sendToServer(new CPacketKeyDown(updatingKeyDown)); + } + } + + @ApiStatus.Internal + public void serverActivate(boolean keyDown, ServerPlayer player) { + this.serverMapping.put(player, keyDown); + + // Player listeners + Set listenerSet = playerListeners.get(player); + if (listenerSet != null && !listenerSet.isEmpty()) { + for (IKeyPressedListener listener : listenerSet) { + listener.onKeyPressed(player, this, keyDown); + } + } + // Global listeners + for (IKeyPressedListener listener : globalListeners) { + listener.onKeyPressed(player, this, keyDown); + } + } + + @ApiStatus.Internal + public static SyncedKeyMapping getFromSyncId(int id) { + return KEYMAPPINGS.get(id); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/utils/input/SyncedKeyMappingEvent.java b/src/main/java/com/gregtechceu/gtceu/utils/input/SyncedKeyMappingEvent.java new file mode 100644 index 00000000000..bfd8d25622a --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/utils/input/SyncedKeyMappingEvent.java @@ -0,0 +1,16 @@ +package com.gregtechceu.gtceu.utils.input; + +import net.neoforged.bus.api.Event; +import net.neoforged.fml.event.IModBusEvent; + +/** + * Event to register {@link SyncedKeyMapping}s in. + *
+ * Event is fired on the mod bus. + */ +public class SyncedKeyMappingEvent extends Event implements IModBusEvent { + + public SyncedKeyMappingEvent() { + super(); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/utils/input/SyncedKeyMappings.java b/src/main/java/com/gregtechceu/gtceu/utils/input/SyncedKeyMappings.java new file mode 100644 index 00000000000..945d6feefef --- /dev/null +++ b/src/main/java/com/gregtechceu/gtceu/utils/input/SyncedKeyMappings.java @@ -0,0 +1,30 @@ +package com.gregtechceu.gtceu.utils.input; + +import com.gregtechceu.gtceu.GTCEu; + +import net.minecraft.client.Minecraft; +import net.neoforged.fml.ModLoader; +import net.neoforged.neoforge.common.NeoForge; + +public class SyncedKeyMappings { + + public static final SyncedKeyMapping VANILLA_JUMP = SyncedKeyMapping + .createFromMC(() -> () -> Minecraft.getInstance().options.keyJump); + public static final SyncedKeyMapping VANILLA_SNEAK = SyncedKeyMapping + .createFromMC(() -> () -> Minecraft.getInstance().options.keyShift); + public static final SyncedKeyMapping VANILLA_FORWARD = SyncedKeyMapping + .createFromMC(() -> () -> Minecraft.getInstance().options.keyUp); + public static final SyncedKeyMapping VANILLA_BACKWARD = SyncedKeyMapping + .createFromMC(() -> () -> Minecraft.getInstance().options.keyDown); + public static final SyncedKeyMapping VANILLA_LEFT = SyncedKeyMapping + .createFromMC(() -> () -> Minecraft.getInstance().options.keyLeft); + public static final SyncedKeyMapping VANILLA_RIGHT = SyncedKeyMapping + .createFromMC(() -> () -> Minecraft.getInstance().options.keyRight); + + public static void init() { + if (GTCEu.isClientSide()) { + NeoForge.EVENT_BUS.register(SyncedKeyMapping.class); + } + ModLoader.postEvent(new SyncedKeyMappingEvent()); + } +} diff --git a/src/main/java/com/gregtechceu/gtceu/utils/memoization/GTMemoizer.java b/src/main/java/com/gregtechceu/gtceu/utils/memoization/GTMemoizer.java index 2fd12f106df..be27b6cb231 100644 --- a/src/main/java/com/gregtechceu/gtceu/utils/memoization/GTMemoizer.java +++ b/src/main/java/com/gregtechceu/gtceu/utils/memoization/GTMemoizer.java @@ -2,7 +2,11 @@ import net.minecraft.world.level.block.Block; +import org.apache.commons.lang3.function.TriFunction; +import org.apache.commons.lang3.tuple.Triple; + import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.function.Supplier; @@ -37,4 +41,21 @@ public String toString() { } }; } + + public static TriFunction memoize(final TriFunction memoTriFunction) { + return new TriFunction<>() { + + private final Map, R> cache = new ConcurrentHashMap<>(); + + public R apply(T key1, U key2, V key3) { + return this.cache.computeIfAbsent(Triple.of(key1, key2, key3), (cacheKey) -> { + return memoTriFunction.apply(cacheKey.getLeft(), cacheKey.getMiddle(), cacheKey.getRight()); + }); + } + + public String toString() { + return "memoize/3[function=" + memoTriFunction + ", size=" + this.cache.size() + "]"; + } + }; + } } diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 41410f44464..4daf465e69a 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -14,6 +14,7 @@ public net.minecraft.data.models.BlockModelGenerators createFacingDispatch()Lnet public net.minecraft.data.models.BlockModelGenerators createSimpleBlock(Lnet/minecraft/world/level/block/Block;Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/data/models/blockstates/MultiVariantGenerator; public net.minecraft.world.item.alchemy.PotionBrewing$Mix +public net.minecraft.world.item.alchemy.PotionBrewing$Mix (Lnet/minecraft/core/Holder;Lnet/minecraft/world/item/crafting/Ingredient;Lnet/minecraft/core/Holder;)V public net.minecraft.client.resources.model.ModelBakery ITEM_MODEL_GENERATOR diff --git a/src/main/resources/assets/gtceu/lang/ja_jp.json b/src/main/resources/assets/gtceu/lang/ja_jp.json index a818219d5a1..2704dc4ad25 100644 --- a/src/main/resources/assets/gtceu/lang/ja_jp.json +++ b/src/main/resources/assets/gtceu/lang/ja_jp.json @@ -1,8 +1,8 @@ { - "behavior.data_item.assemblyline.data": "- §a%s", - "behavior.data_item.assemblyline.title": "§nアセンブリライン構築データ:", - "behavior.item_magnet.disabled": "§cアイテムを引き寄せない", - "behavior.item_magnet.enabled": "§aアイテムを引き寄せる", + "behavior.data_item.data": "- §a%s", + "behavior.data_item.title": "§n%s 設計図:", + "behavior.item_magnet.disabled": "アイテムを引き寄せない", + "behavior.item_magnet.enabled": "アイテムを引き寄せる", "behavior.portable_scanner.amp_per_sec": "平均(直近1秒): %s A", "behavior.portable_scanner.bedrock_fluid.amount": "チャンク内の液体: %s %s - %s%%", "behavior.portable_scanner.bedrock_fluid.amount_unknown": "チャンク内の液体: 不明 - %s%%", @@ -30,8 +30,8 @@ "behavior.portable_scanner.machine_front_facing": "正面向き: %s", "behavior.portable_scanner.machine_ownership": "§2マシン所有者のタイプ: %s§r", "behavior.portable_scanner.machine_power_loss": "エネルギー不足で停止", - "behavior.portable_scanner.machine_upwards_facing": "上向き: %s", "behavior.portable_scanner.machine_progress": "進捗/最大: %s / %s", + "behavior.portable_scanner.machine_upwards_facing": "上向き: %s", "behavior.portable_scanner.mode.caption": "ディスプレイモード: %s", "behavior.portable_scanner.mode.show_all_info": "すべての情報を表示", "behavior.portable_scanner.mode.show_block_info": "ブロック情報を表示", @@ -54,7 +54,7 @@ "behavior.portable_scanner.workable_production": "予想生産量: %s EU/t at %s A", "behavior.portable_scanner.workable_progress": "進捗: %s s / %s s", "behavior.portable_scanner.workable_stored_energy": "エネルギー貯蓄量: %s EU / %s EU", - "behavior.prospector.added_waypoint": "%s ウェイポイントを追加!", + "behavior.prospector.added_waypoint": "ウェイポイントを追加しました!", "behavior.prospector.not_enough_energy": "エネルギー不足!", "behavior.toggle_energy_consumer.tooltip": "使うことでモード切替", "behaviour.boor.by": "by %s", @@ -89,16 +89,17 @@ "behaviour.setting.item_auto_output.tooltip": "%s の自動出力は %s です", "behaviour.setting.muffled.tooltip": "%s の消音", "behaviour.setting.output.direction.tooltip": "%s の出力方向: %s", - "behaviour.soft_hammer": "機械の稼働/停止を切り替える", + "behaviour.soft_hammer": "機械のON/OFFを切り替える", "behaviour.soft_hammer.disabled": "作業停止", + "behaviour.soft_hammer.disabled_cycle": "現在のサイクル終了後に作業を無効化", "behaviour.soft_hammer.enabled": "作業開始", - "behaviour.soft_hammer.idle_after_cycle": "現在のサイクルが終了したら機械を一時停止", "behaviour.wrench": "右クリックでブロックを回転", "block.filter_casing.tooltip": "§a無塵§7環境を構築する", "block.gtceu.acid_hazard_sign_block": "酸危害警告ブロック", "block.gtceu.active_transformer": "大型変圧器", "block.gtceu.advanced_computer_casing": "発展型コンピュータ外装", "block.gtceu.advanced_data_access_hatch": "発展型データアクセスハッチ", + "block.gtceu.advanced_monitor": "発展型モニター", "block.gtceu.alloy_blast_smelter": "合金高炉", "block.gtceu.aluminium_crate": "アルミニウム製クレート", "block.gtceu.aluminium_drum": "アルミニウム製ドラム", @@ -109,14 +110,18 @@ "block.gtceu.assembly_line_unit": "組立機制御外装", "block.gtceu.atomic_casing": "原子マシン外装", "block.gtceu.auto_maintenance_hatch": "自動メンテナンスハッチ", + "block.gtceu.basic_data_access_hatch": "基本データアクセスハッチ", "block.gtceu.bio_hazard_sign_block": "生物学的危害警告ブロック", "block.gtceu.black_borderless_lamp": "黒のボーダーレスランプ", "block.gtceu.black_lamp": "黒のランプ", - "block.gtceu.blue_borderless_lamp": "青のボーダーレスランプ", - "block.gtceu.black_large_metal_sheet": "黒色大型金属板", - "block.gtceu.black_metal_sheet": "黒色金属板", + "block.gtceu.black_large_metal_sheet": "黒色の大きな板金ブロック", + "block.gtceu.black_metal_sheet": "黒色の板金ブロック", "block.gtceu.black_studs": "黒鋲", + "block.gtceu.blue_borderless_lamp": "青のボーダーレスランプ", "block.gtceu.blue_lamp": "青のランプ", + "block.gtceu.blue_large_metal_sheet": "青色の大きな板金ブロック", + "block.gtceu.blue_metal_sheet": "青色の板金ブロック", + "block.gtceu.blue_studs": "青鋲", "block.gtceu.boss_hazard_sign_block": "ボス危害警告ブロック", "block.gtceu.brittle_charcoal": "脆い木炭", "block.gtceu.bronze_brick_casing": "ブロンズレンガ筐体", @@ -126,12 +131,18 @@ "block.gtceu.bronze_gearbox": "ブロンズ製ギアボックス外装", "block.gtceu.bronze_large_boiler": "ブロンズ製大型ボイラー", "block.gtceu.bronze_machine_casing": "ブロンズ製マシン外装", + "block.gtceu.bronze_multiblock_tank": "ブロンズ製マルチブロックタンク", "block.gtceu.bronze_pipe_casing": "ブロンズ製パイプ外装", + "block.gtceu.bronze_tank_valve": "ブロンズ製タンクバルブ", "block.gtceu.brown_borderless_lamp": "茶色のボーダーレスランプ", "block.gtceu.brown_lamp": "茶色のランプ", + "block.gtceu.brown_large_metal_sheet": "茶色の大きな板金ブロック", + "block.gtceu.brown_metal_sheet": "茶色の板金ブロック", + "block.gtceu.brown_studs": "茶鋲", "block.gtceu.casing_coke_bricks": "コークス炉用レンガブロック", "block.gtceu.casing_grate": "格子マシン外装", "block.gtceu.causality_hazard_sign_block": "因果関係的危険警告ブロック", + "block.gtceu.central_monitor": "セントラルモニター", "block.gtceu.charcoal_pile_igniter": "炭窯", "block.gtceu.chiseled_dark_concrete": "模様入りの暗色コンクリート", "block.gtceu.chiseled_light_concrete": "模様入りの明色コンクリート", @@ -160,10 +171,14 @@ "block.gtceu.creative_data_access_hatch": "クリエイティブデータアクセスハッチ", "block.gtceu.creative_energy": "クリエイティブエネルギー", "block.gtceu.creative_tank": "クリエイティブタンク", + "block.gtceu.creosote": "クレオソート油", "block.gtceu.crushing_wheels": "破砕歯車", "block.gtceu.cupronickel_coil_block": "キュプロニッケルコイルブロック", "block.gtceu.cyan_borderless_lamp": "青緑色のボーダーレスランプ", "block.gtceu.cyan_lamp": "青緑色のランプ", + "block.gtceu.cyan_large_metal_sheet": "青緑色の大きな板金ブロック", + "block.gtceu.cyan_metal_sheet": "青緑色の板金ブロック", + "block.gtceu.cyan_studs": "青緑鋲", "block.gtceu.dark_concrete": "暗色コンクリート", "block.gtceu.dark_concrete_bricks": "暗色コンクリートのレンガ", "block.gtceu.dark_concrete_cobblestone": "暗色コンクリートの丸石", @@ -195,7 +210,7 @@ "block.gtceu.ev_battery_buffer_4x": "§5EV§r4スロット蓄電器", "block.gtceu.ev_battery_buffer_8x": "§5EV§r8スロット蓄電器", "block.gtceu.ev_bedrock_ore_miner": "§5発展型岩盤鉱石採掘機 III§r", - "block.gtceu.ev_bender": "§5A発展型金属加工機 III§r", + "block.gtceu.ev_bender": "§5発展型金属加工機 III§r", "block.gtceu.ev_block_breaker": "§5発展型ブロック破壊機 III§r", "block.gtceu.ev_brewery": "§5発展型醸造機 III§r", "block.gtceu.ev_canner": "§5発展型缶詰装置 III§r", @@ -267,7 +282,6 @@ "block.gtceu.ev_transformer_4a": "4A対応§5EV§r変圧器", "block.gtceu.ev_wiremill": "§5発展型ワイヤー作製機 III§r", "block.gtceu.ev_world_accelerator": "§5発展型世界加速機 III§r", - "block.gtceu.evaporation_plant": "蒸発塔", "block.gtceu.explosion_hazard_sign_block": "爆発危害警告ブロック", "block.gtceu.explosive.breaking_tooltip": "採掘すると爆発する、スニークして採掘する", "block.gtceu.explosive.lighting_tooltip": "レッドストーンでは点火できない", @@ -289,8 +303,14 @@ "block.gtceu.gold_drum": "金製ドラム", "block.gtceu.gray_borderless_lamp": "灰色のボーダーレスランプ", "block.gtceu.gray_lamp": "灰色のランプ", + "block.gtceu.gray_large_metal_sheet": "灰色の大きな板金ブロック", + "block.gtceu.gray_metal_sheet": "灰色の板金ブロック", + "block.gtceu.gray_studs": "灰鋲", "block.gtceu.green_borderless_lamp": "緑色のボーダーレスランプ", "block.gtceu.green_lamp": "緑色のランプ", + "block.gtceu.green_large_metal_sheet": "緑色の大きな板金ブロック", + "block.gtceu.green_metal_sheet": "緑色の板金ブロック", + "block.gtceu.green_studs": "緑鋲", "block.gtceu.gregification_hazard_sign_block": "Greg化危害警告ブロック", "block.gtceu.heat_vent": "排熱口", "block.gtceu.heatproof_machine_casing": "インバー製耐熱マシン外装", @@ -335,6 +355,7 @@ "block.gtceu.hv_bender": "§6発展型金属加工機 II§r", "block.gtceu.hv_block_breaker": "§6発展型ブロック破壊機 II§r", "block.gtceu.hv_brewery": "§6発展型醸造機 II§r", + "block.gtceu.hv_buffer": "§6発展型バッファ II§r", "block.gtceu.hv_canner": "§6発展型缶詰装置 II§r", "block.gtceu.hv_centrifuge": "§6発展型遠心分離機 II§r", "block.gtceu.hv_charger_4x": "4x§6HV§r高速充電器", @@ -345,7 +366,6 @@ "block.gtceu.hv_compressor": "§6発展型圧縮機 II§r", "block.gtceu.hv_cutter": "§6発展型裁断機 II§r", "block.gtceu.hv_diode": "§6HVダイオード", - "block.gtceu.hv_buffer": "§6発展型バッファ II§r", "block.gtceu.hv_distillery": "§6発展型蒸留機 II§r", "block.gtceu.hv_electric_furnace": "§6発展型電気かまど II§r", "block.gtceu.hv_electrolyzer": "§6発展型電解槽 II§r", @@ -522,6 +542,9 @@ "block.gtceu.laser_safe_engraving_casing": "耐レーザー刻印マシン外装", "block.gtceu.light_blue_borderless_lamp": "空色のボーダーレスランプ", "block.gtceu.light_blue_lamp": "空色のランプ", + "block.gtceu.light_blue_large_metal_sheet": "空色の大きな板金ブロック", + "block.gtceu.light_blue_metal_sheet": "空色の板金ブロック", + "block.gtceu.light_blue_studs": "空色鋲", "block.gtceu.light_concrete": "明色コンクリート", "block.gtceu.light_concrete_bricks": "明色コンクリートのレンガ", "block.gtceu.light_concrete_cobblestone": "明色コンクリートの丸石", @@ -531,8 +554,14 @@ "block.gtceu.light_concrete_windmill_b": "明色コンクリート風車B", "block.gtceu.light_gray_borderless_lamp": "薄灰色のボーダーレスランプ", "block.gtceu.light_gray_lamp": "薄灰色のランプ", + "block.gtceu.light_gray_large_metal_sheet": "薄灰色の大きな板金ブロック", + "block.gtceu.light_gray_metal_sheet": "薄灰色の板金ブロック", + "block.gtceu.light_gray_studs": "薄灰鋲", "block.gtceu.lime_borderless_lamp": "黄緑色のボーダーレスランプ", "block.gtceu.lime_lamp": "黄緑色のランプ", + "block.gtceu.lime_large_metal_sheet": "黄緑色の大きな板金ブロック", + "block.gtceu.lime_metal_sheet": "黄緑色の板金ブロック", + "block.gtceu.lime_studs": "黄緑鋲", "block.gtceu.long_distance_fluid_pipeline": "長距離液体パイプライン", "block.gtceu.long_distance_fluid_pipeline_endpoint": "長距離液体パイプ接続口", "block.gtceu.long_distance_item_pipeline": "長距離アイテムパイプライン", @@ -721,6 +750,9 @@ "block.gtceu.lv_world_accelerator": "基本型世界加速機 §r", "block.gtceu.magenta_borderless_lamp": "赤紫色のボーダーレスランプ", "block.gtceu.magenta_lamp": "赤紫色のランプ", + "block.gtceu.magenta_large_metal_sheet": "赤紫色の大きな板金ブロック", + "block.gtceu.magenta_metal_sheet": "赤紫色の板金ブロック", + "block.gtceu.magenta_studs": "赤紫鋲", "block.gtceu.magic_hazard_sign_block": "魔術的危害警告ブロック", "block.gtceu.magnetic_hazard_sign_block": "磁力危害警告ブロック", "block.gtceu.maintenance_hatch": "メンテナンスハッチ", @@ -773,6 +805,7 @@ "block.gtceu.mob_infestation_hazard_sign_block": "モブ侵入危害警告ブロック", "block.gtceu.mob_spawner_hazard_sign_block": "スポナー危害警告ブロック", "block.gtceu.molybdenum_disilicide_coil_block": "二ケイ化モリブデン製コイルブロック", + "block.gtceu.monitor": "モニター", "block.gtceu.mossy_dark_concrete_bricks": "苔むした暗色コンクリートのレンガ", "block.gtceu.mossy_dark_concrete_cobblestone": "苔むした暗色コンクリートの丸石", "block.gtceu.mossy_light_concrete_bricks": "苔むした明色コンクリートのレンガ", @@ -870,6 +903,7 @@ "block.gtceu.normal_optical_pipe": "光ファイバーケーブル", "block.gtceu.normal_optical_pipe.tooltip": "§f計算§7 または§f研究データ§7 の送信に", "block.gtceu.object_holder": "オブジェクトホルダー", + "block.gtceu.oil": "原油", "block.gtceu.oil_heavy": "重油", "block.gtceu.oil_light": "軽油", "block.gtceu.oil_medium": "原料油", @@ -957,6 +991,9 @@ "block.gtceu.opv_wiremill": "§9§l伝説のワイヤー作製機 §r", "block.gtceu.orange_borderless_lamp": "橙色のボーダーレスランプ", "block.gtceu.orange_lamp": "橙色のランプ", + "block.gtceu.orange_large_metal_sheet": "橙色の大きな板金ブロック", + "block.gtceu.orange_metal_sheet": "橙色の板金ブロック", + "block.gtceu.orange_studs": "橙鋲", "block.gtceu.overworld_marker": "オーバーワールド", "block.gtceu.palladium_substation": "パラジウム製大型蓄電器用外装", "block.gtceu.pattern_buffer.desc.0": "§fマルチブロックのために §6AE2 パターンを直接保存できる。", @@ -968,6 +1005,9 @@ "block.gtceu.petrified_foam": "石化したフォーム", "block.gtceu.pink_borderless_lamp": "桃色のボーダーレスランプ", "block.gtceu.pink_lamp": "桃色のランプ", + "block.gtceu.pink_large_metal_sheet": "桃色の大きな板金ブロック", + "block.gtceu.pink_metal_sheet": "桃色の板金ブロック", + "block.gtceu.pink_studs": "桃鋲", "block.gtceu.plascrete": "プラスクリート", "block.gtceu.plasma_large_turbine": "大型プラズマタービン", "block.gtceu.polished_dark_concrete": "磨かれた暗色コンクリート", @@ -984,6 +1024,9 @@ "block.gtceu.pump_hatch": "ポンプハッチ", "block.gtceu.purple_borderless_lamp": "紫色のボーダーレスランプ", "block.gtceu.purple_lamp": "紫色のランプ", + "block.gtceu.purple_large_metal_sheet": "紫色の大きな板金ブロック", + "block.gtceu.purple_metal_sheet": "紫色の板金ブロック", + "block.gtceu.purple_studs": "紫鋲", "block.gtceu.pyrolyse_oven": "熱分解炉", "block.gtceu.radioactive_hazard_sign_block": "放射性危害警告ブロック", "block.gtceu.reaction_safe_mixing_casing": "不活性混合用マシン外装", @@ -996,6 +1039,10 @@ "block.gtceu.red_granite_windmill_a": "赤色花崗岩の風車A", "block.gtceu.red_granite_windmill_b": "赤色花崗岩の風車B", "block.gtceu.red_lamp": "赤のランプ", + "block.gtceu.red_large_metal_sheet": "赤色の大きな板金ブロック", + "block.gtceu.red_metal_sheet": "赤色の板金ブロック", + "block.gtceu.red_studs": "赤鋲", + "block.gtceu.reinforced_foam": "強化フォーム", "block.gtceu.reinforced_stone": "強化石材", "block.gtceu.research_station": "研究ステーション", "block.gtceu.reservoir_hatch": "リザーバーハッチ", @@ -1031,7 +1078,6 @@ "block.gtceu.square_marble_bricks": "大理石の大レンガ", "block.gtceu.square_red_granite_bricks": "赤色花崗岩の大レンガ", "block.gtceu.stable_machine_casing": "堅牢なチタン製マシン外装", - "block.gtceu.stainless_evaporation_casing": "蒸発塔用ステンレス製ケーシング", "block.gtceu.stainless_steel_crate": "ステンレススチール製クレート", "block.gtceu.stainless_steel_drum": "ステンレススチール製ドラム", "block.gtceu.stainless_steel_gearbox": "ステンレススチール製ギアボックス外装", @@ -1063,7 +1109,7 @@ "block.gtceu.steel_multiblock_tank": "スチール製マルチブロックタンク", "block.gtceu.steel_pipe_casing": "スチール製パイプ外装", "block.gtceu.steel_tank_valve": "スチール製タンクバルブ", - "block.gtceu.steel_turbine_casing": "スチール製タービン外装", + "block.gtceu.steel_turbine_casing": "マグナリウム製タービン外装", "block.gtceu.sterilizing_filter_casing": "滅菌フィルター外装", "block.gtceu.stress_proof_casing": "耐応力マシン外装", "block.gtceu.stripped_rubber_log": "ゴムの原木", @@ -1305,7 +1351,7 @@ "block.gtceu.uiv_electromagnetic_separator": "§2史上最高の電磁分離機 III§r", "block.gtceu.uiv_energy_input_hatch": "§2UIVエネルギーハッチ", "block.gtceu.uiv_energy_input_hatch_16a": "§2UIV 16A エネルギーハッチ", -"block.gtceu.uiv_energy_input_hatch_4a": "§2UIV 4A エネルギーハッチ", + "block.gtceu.uiv_energy_input_hatch_4a": "§2UIV 4A エネルギーハッチ", "block.gtceu.uiv_energy_output_hatch": "§2UIVダイナモハッチ", "block.gtceu.uiv_energy_output_hatch_16a": "§2UIV 16A ダイナモハッチ", "block.gtceu.uiv_energy_output_hatch_4a": "§2UIV 4A ダイナモハッチ", @@ -1546,9 +1592,12 @@ "block.gtceu.watertight_casing": "防水マシン外装", "block.gtceu.white_borderless_lamp": "白のボーダーレスランプ", "block.gtceu.white_lamp": "白のランプ", + "block.gtceu.white_large_metal_sheet": "白色の大きな板金ブロック", + "block.gtceu.white_metal_sheet": "白色の板金ブロック", + "block.gtceu.white_studs": "白鋲", "block.gtceu.wire_coil.tooltip_cracking": "§8接触分解装置:", "block.gtceu.wire_coil.tooltip_energy_cracking": " §aエネルギー使用量: §f%s%%", - "block.gtceu.wire_coil.tooltip_energy_smelter": " §aエネルギー使用量: §f%s EU/t §8毎レシピ", + "block.gtceu.wire_coil.tooltip_energy_smelter": " §aエネルギー使用量: §f%s EU/t", "block.gtceu.wire_coil.tooltip_extended_info": "§7SHIFTでコイルのボーナス情報を表示", "block.gtceu.wire_coil.tooltip_heat": "§c基本最大温度: §f%d K", "block.gtceu.wire_coil.tooltip_parallel_smelter": " §5最大並列処理数: §f%s", @@ -1562,12 +1611,15 @@ "block.gtceu.wooden_tank_valve": "木製タンクバルブ", "block.gtceu.yellow_borderless_lamp": "黄色のボーダーレスランプ", "block.gtceu.yellow_lamp": "黄色のランプ", + "block.gtceu.yellow_large_metal_sheet": "黄色の大きな板金ブロック", + "block.gtceu.yellow_metal_sheet": "黄色の板金ブロック", "block.gtceu.yellow_stripes_block.a": "黄色斜線ブロック", "block.gtceu.yellow_stripes_block.b": "黄色斜線ブロック", "block.gtceu.yellow_stripes_block.c": "黄色斜線ブロック", "block.gtceu.yellow_stripes_block.d": "黄色斜線ブロック", "block.gtceu.yellow_stripes_block_a": "黄色斜線ブロック A", "block.gtceu.yellow_stripes_block_b": "黄色斜線ブロック B", + "block.gtceu.yellow_studs": "黄鋲", "block.gtceu.zpm_1024a_laser_source_hatch": "§cZPM§r 1024§eA§r対応レーザー照射ハッチ", "block.gtceu.zpm_1024a_laser_target_hatch": "§cZPM§r 1024§eA§r対応レーザー照準ハッチ", "block.gtceu.zpm_16a_energy_converter": "§cZPM§r 16§eA§rエネルギー変換機", @@ -1659,10 +1711,20 @@ "block.surface_rock": "%sの小石", "button.gtceu.mark_as_depleted.name": "枯渇済みとしてマーク", "button.gtceu.toggle_waypoint.name": "ウェイポイントを切り替え", + "command.gtceu.cape.failure.does_not_exist": "マント %s は存在しません", + "command.gtceu.cape.give.failed": "新しいマントはアンロックされませんでした", + "command.gtceu.cape.give.success.multiple": "%s 人のプレイヤーに %s 個のマントをアンロックしました", + "command.gtceu.cape.give.success.single": "%s に %s 個のマントをアンロックしました", + "command.gtceu.cape.take.failed": "マントを削除できませんでした", + "command.gtceu.cape.take.success.multiple": "%s 人のプレイヤーから %s 個のマントを削除しました", + "command.gtceu.cape.take.success.single": "%s から %s 個のマントを削除しました", + "command.gtceu.cape.use.failed": "%s はマント %s を所持していない(または存在しない)ため、使用できません!", + "command.gtceu.cape.use.success": "%s はマント %s を使用しています", + "command.gtceu.cape.use.success.none": "%s はマントを使用していません", "command.gtceu.dump_data.success": "レジストリ %2$s から %1$s リソースを %3$s にダンプしました。", "command.gtceu.medical_condition.get": "プレイヤー%sは以下のような健康状態にです。:", - "command.gtceu.medical_condition.get.element": "コンディション %s§r: %s 分 %s 秒", - "command.gtceu.medical_condition.get.element.permanent": "コンディション %s§r: %s 分 %s 秒(永続的)", + "command.gtceu.medical_condition.get.element": "Condition %s§r: %s minutes %s seconds", + "command.gtceu.medical_condition.get.element.permanent": "Condition %s§r: %s minutes %s seconds (permanent)", "command.gtceu.medical_condition.get.empty": "プレイヤー%sは全て健康です。", "command.gtceu.place_vein.failure": "鉱脈 %1$s を位置 %2$s に配置できませんでした。", "command.gtceu.place_vein.success": "鉱脈 %s を位置 %s に配置しました。", @@ -1670,8 +1732,11 @@ "config.gtceu.option.addLoot": "戦利品の追加", "config.gtceu.option.ae2": "AE2", "config.gtceu.option.allUniqueStoneTypes": "すべてのユニークな石の種類", + "config.gtceu.option.allowDrumsInputFluidsFromOutputSide": "ドラム缶の出力側からの液体入力を許可する", "config.gtceu.option.animationTime": "アニメーション時間", + "config.gtceu.option.arcRecyclingYield": "アーク炉リサイクル収率", "config.gtceu.option.armorHud": "防具HUD", + "config.gtceu.option.batchDuration": "バッチ処理時間", "config.gtceu.option.bedrockOreDistance": "岩盤鉱石間隔", "config.gtceu.option.bedrockOreDropTagPrefix": "岩盤鉱石ドロップタグ接頭辞", "config.gtceu.option.borderColor": "境界線の色", @@ -1681,7 +1746,10 @@ "config.gtceu.option.casingsPerCraft": "筐体パークラフト", "config.gtceu.option.cleanMultiblocks": "クリーンマルチブロック", "config.gtceu.option.client": "クライアント", + "config.gtceu.option.coloredTieredMachineOutline": "機械のTierごとの色付きアウトライン", + "config.gtceu.option.coloredWireOutline": "ワイヤーの色付きアウトライン", "config.gtceu.option.compat": "互換性", + "config.gtceu.option.createCompat": "Createとの互換性", "config.gtceu.option.debug": "デバック", "config.gtceu.option.debugWorldgen": "デバッグワールド生成", "config.gtceu.option.defaultPaintingColor": "デフォルトペインティングカラー", @@ -1692,10 +1760,14 @@ "config.gtceu.option.doBedrockOres": "岩盤鉱石を使う", "config.gtceu.option.doSuperflatOres": "スーパーフラット鉱石を有効にする", "config.gtceu.option.doesExplosionDamagesTerrain": "爆発は地形を破壊する", + "config.gtceu.option.drum": "ドラム缶", "config.gtceu.option.dumpAssets": "ダンプアセット", "config.gtceu.option.dumpRecipes": "ダンプレシピ", + "config.gtceu.option.enableArcRecycling": "アーク炉リサイクルを有効化", "config.gtceu.option.enableCleanroom": "クリーンルームの有効化", + "config.gtceu.option.enableExtractorRecycling": "抽出機リサイクルを有効化", "config.gtceu.option.enableFEConverters": "エネルギー変換機の有効化", + "config.gtceu.option.enableMaceratorRecycling": "粉砕機リサイクルを有効化", "config.gtceu.option.enableMaintenance": "メンテナンスの有効化", "config.gtceu.option.enableResearch": "研究の有効化", "config.gtceu.option.enableTieredCasings": "階層筐体の有効化", @@ -1707,9 +1779,10 @@ "config.gtceu.option.environmentalHazardDecayRate": "環境汚染減衰率", "config.gtceu.option.environmentalHazards": "環境汚染", "config.gtceu.option.euToFeRatio": "EUからFEへの変換比率", + "config.gtceu.option.extractorRecyclingYield": "抽出機リサイクル収率", "config.gtceu.option.feToEuRatio": "FEからEUへの変換比率", "config.gtceu.option.flintAndSteelRequireSteel": "火打石と打ち金にスチールを要求する", - "config.gtceu.option.ftbChunksIntegration": "FTBChunks連携", + "config.gtceu.option.ftbChunksIntegration": "FTB Chunksとの連携", "config.gtceu.option.gameplay": "ゲームプレイ", "config.gtceu.option.generateLowQualityGems": "低品質宝石の生成を行う", "config.gtceu.option.ghostCircuit": "ゴーストサーキット", @@ -1742,16 +1815,19 @@ "config.gtceu.option.inWorldPreviewDuration": "ワールドプレビュー時間", "config.gtceu.option.increaseDungeonLoot": "ダンジョンの戦利品を増やす", "config.gtceu.option.infiniteBedrockOresFluids": "無限に岩盤鉱石、液体を出すか", - "config.gtceu.option.journeyMapIntegration": "JourneyMap連携", + "config.gtceu.option.journeyMapIntegration": "JourneyMapとの連携", "config.gtceu.option.largeBoilers": "大型ボイラー", "config.gtceu.option.ldFluidPipeMinDistance": "長距離液体パイプ 最短距離", "config.gtceu.option.ldItemPipeMinDistance": "長距離アイテムパイプ 最短距離", "config.gtceu.option.liquidBoilerBaseOutput": "液体ボイラー基本出力", + "config.gtceu.option.maceratorRecyclingYield": "粉砕機リサイクル収率", "config.gtceu.option.machineSounds": "マシンサウンド", "config.gtceu.option.machines": "機械", "config.gtceu.option.machinesEmissiveTextures": "マシンエミッシブテクスチャー", + "config.gtceu.option.machinesHaveBERsByDefault": "機械がデフォルトでBERを持つ", + "config.gtceu.option.maintenanceCheckRate": "メンテナンスチェック頻度", "config.gtceu.option.meHatchEnergyUsage": "ハッチのエネルギー使用量", - "config.gtceu.option.minerSpeed": "採掘速度", + "config.gtceu.option.minerSpeed": "採掘機速度", "config.gtceu.option.minimap": "ミニマップ", "config.gtceu.option.nanoSaber": "ナノセイバー", "config.gtceu.option.nanoSaberBaseDamage": "ナノセイバーのベースダメージ", @@ -1775,7 +1851,7 @@ "config.gtceu.option.oreVeins": "鉱脈", "config.gtceu.option.ownerOPBypass": "所有者のOPバイパス", "config.gtceu.option.prospectorEnergyUseMultiplier": "プロスペクター エネルギー使用乗数", - "config.gtceu.option.recipeProgressLowEnergy": "レシピ プログレス 低エネルギー", + "config.gtceu.option.quantumTank": "クァンタムタンク", "config.gtceu.option.recipes": "レシピ", "config.gtceu.option.removeSmeltingForEBFMetals": "EBF金属の製錬削除", "config.gtceu.option.removeVanillaBlockRecipes": "バニラブロックのレシピを削除する", @@ -1783,6 +1859,7 @@ "config.gtceu.option.removeVanillaOreGen": "バニラの鉱石生成を削除", "config.gtceu.option.removeVanillaTNTRecipe": "バニラTNTのレシピを削除", "config.gtceu.option.renderFluids": "流体をレンダリング", + "config.gtceu.option.renderGrowingPlants": "成長中の植物をレンダリング", "config.gtceu.option.renderer": "レンダラー", "config.gtceu.option.replaceMinedBlocksWith": "採掘されたブロックを置き換える", "config.gtceu.option.requireGTToolsForBlocks": "ブロック用GTツールが必要", @@ -1801,9 +1878,10 @@ "config.gtceu.option.steelBoilerMaxTemperature": "スチールボイラー最大温度", "config.gtceu.option.steelSteamMultiblocks": "スチール製マルチブロック", "config.gtceu.option.surfaceRockProspectRange": "地表の岩探査範囲", + "config.gtceu.option.tankItemFluidPreview": "タンクアイテムの液体プレビュー", "config.gtceu.option.titaniumBoilerHeatSpeed": "チタン製大型ボイラー加熱速度", "config.gtceu.option.titaniumBoilerMaxTemperature": "チタン製大型ボイラー最大温度", - "config.gtceu.option.toggle": "トグル", + "config.gtceu.option.toggle": "切り替え", "config.gtceu.option.toolCraftingSounds": "ツールをクラフトに使用したときの音", "config.gtceu.option.toolUseSounds": "ツールを使ったときの音", "config.gtceu.option.tools": "ツール", @@ -1823,13 +1901,15 @@ "config.gtceu.option.worldAcceleratorBlacklist": "世界加速機のブラックリスト", "config.gtceu.option.worldgen": "ワールド生成", "config.gtceu.option.xOffset": "Xオフセット", - "config.gtceu.option.xaerosMapIntegration": "XaerosMap連携", + "config.gtceu.option.xaerosMapIntegration": "Xaero's Mapとの連携", "config.gtceu.option.yOffset": "Yオフセット", "config.gtceu.option.zombieSpawnWithSabers": "ゾンビがナノセイバーを持ってスポーンするか", "config.jade.plugin_gtceu.auto_output_info": "[GTCEu] 自動出力情報", "config.jade.plugin_gtceu.cable_info": "[GTCEu] ケーブル情報", "config.jade.plugin_gtceu.controllable_provider": "[GTCEu] 制御可能", + "config.jade.plugin_gtceu.data_bank": "[GTCEu] データバンク情報", "config.jade.plugin_gtceu.electric_container_provider": "[GTCEu] 電気コンテナ", + "config.jade.plugin_gtceu.energy_converter_provider": "[GTCEu] エネルギー変換機モード", "config.jade.plugin_gtceu.exhaust_vent_info": "[GTCEu] 排気ガス情報", "config.jade.plugin_gtceu.hazard_cleaner_provider": "[GTCEu] 汚染洗浄", "config.jade.plugin_gtceu.machine_mode": "[GTCEu] マシンモード", @@ -1845,6 +1925,16 @@ "config.jade.plugin_gtceu.steam_boiler_info": "[GTCEu] 蒸気ボイラー情報", "config.jade.plugin_gtceu.transformer": "[GTCEu] 変圧器情報", "config.jade.plugin_gtceu.workable_provider": "[GTCEu] 実行可能", + "cover.advanced_detector.latch.disabled.0": "挙動: 連続", + "cover.advanced_detector.latch.disabled.1": "", + "cover.advanced_detector.latch.disabled.2": "このカバーのレッドストーン挙動を変更する。", + "cover.advanced_detector.latch.disabled.3": "§e連続§7 - デフォルト。最小値未満で出力0、最大値以上で出力15、最小と最大の間では0から15の間で出力する。", + "cover.advanced_detector.latch.disabled.4": "§eラッチ§7 - 最大値を超えるまで出力15を維持し、その後最小値を下回るまで出力0を維持する。", + "cover.advanced_detector.latch.enabled.0": "挙動: ラッチ", + "cover.advanced_detector.latch.enabled.1": "", + "cover.advanced_detector.latch.enabled.2": "このカバーのレッドストーン挙動を変更する。", + "cover.advanced_detector.latch.enabled.3": "§e連続§7 - デフォルト。最小値未満で出力0、最大値以上で出力15、最小と最大の間では0から15の間で出力する。", + "cover.advanced_detector.latch.enabled.4": "§eラッチ§7 - 最大値を超えるまで出力15を維持し、その後最小値を下回るまで出力0を維持する。", "cover.advanced_energy_detector.invert.disabled.0": "アウトプット: ノーマル", "cover.advanced_energy_detector.invert.disabled.1": "", "cover.advanced_energy_detector.invert.disabled.2": "赤石ロジックの反転の切替", @@ -1871,8 +1961,8 @@ "cover.advanced_fluid_detector.invert.enabled.2": "赤石ロジックの反転の切替", "cover.advanced_fluid_detector.invert.enabled.3": "デフォルトでは、レッドストーンは、液体が最小mB未満になると信号を停止し、最小mBを超えると、設定された最大値まで信号を開始する。", "cover.advanced_fluid_detector.label": "発展型液体検出器", - "cover.advanced_fluid_detector.max": "最大液体 (mB)", - "cover.advanced_fluid_detector.min": "最小液体 (mB)", + "cover.advanced_fluid_detector.max": "最大液体量:", + "cover.advanced_fluid_detector.min": "最小液体量:", "cover.advanced_item_detector.invert.disabled.0": "アウトプット: ノーマル", "cover.advanced_item_detector.invert.disabled.1": "", "cover.advanced_item_detector.invert.disabled.2": "赤石ロジックの反転の切替", @@ -1882,22 +1972,22 @@ "cover.advanced_item_detector.invert.enabled.2": "赤石ロジックの反転の切替", "cover.advanced_item_detector.invert.enabled.3": "デフォルトでは、レッドストーンはアイテムの最小量より少ない場合は信号を停止し、最小量より多い場合は設定された最大量まで信号を出力する。", "cover.advanced_item_detector.label": "発展型アイテム検出器", - "cover.advanced_item_detector.max": "最大アイテム", - "cover.advanced_item_detector.min": "最小アイテム", - "cover.bucket.mode.bucket": "B", - "cover.bucket.mode.milli_bucket": "mB", + "cover.advanced_item_detector.max": "最大アイテム量:", + "cover.advanced_item_detector.min": "最小アイテム量:", + "cover.bucket.mode.bucket": "バケツモード: kL", + "cover.bucket.mode.milli_bucket": "バケツモード: L", "cover.conveyor.blocks_input.disabled.0": "有効にすると、カバーがインベントリからパイプにアイテムを引き込むように設定されている場合、アイテムは挿入されない。", "cover.conveyor.blocks_input.disabled.1": "§c無効", "cover.conveyor.blocks_input.enabled.0": "有効にすると、カバーがインベントリからパイプにアイテムを引き込むように設定されている場合、アイテムは挿入されない。", "cover.conveyor.blocks_input.enabled.1": "§a有効", - "cover.conveyor.distribution.insert_first.0": "分配モード: §b優先順位", - "cover.conveyor.distribution.insert_first.1": "§7最も優先順位の高い最初のインベントリに挿入される。", - "cover.conveyor.distribution.insert_first.2": "§7制限項目パイプはパスの優先順位を下げる。", + "cover.conveyor.distribution.insert_first.0": "分配モード: §b優先度", + "cover.conveyor.distribution.insert_first.1": "§7最も優先度の高い最初のインベントリに挿入される。", + "cover.conveyor.distribution.insert_first.2": "§7制限項目パイプはパスの優先度を下げる。", "cover.conveyor.distribution.round_robin_global.0": "分配モード: §bラウンドロビン", "cover.conveyor.distribution.round_robin_global.1": "§7接続されたインベントリ間でアイテムを均等に分割", - "cover.conveyor.distribution.round_robin_prio.0": "分配モード: §b優先順位付きラウンドロビン", - "cover.conveyor.distribution.round_robin_prio.1": "§7連結された在庫にアイテムを分割しようとし、優先順位の高いものから先に考える。", - "cover.conveyor.distribution.round_robin_prio.2": "§7制限項目パイプはパスの優先順位を下げる。", + "cover.conveyor.distribution.round_robin_prio.0": "分配モード: §b制限付きラウンドロビン", + "cover.conveyor.distribution.round_robin_prio.1": "§7接続されたインベントリ間でアイテムを均等に分割しようとします。", + "cover.conveyor.distribution.round_robin_prio.2": "§7他の経路がない限り、制限付きアイテムパイプにはアイテムを送りません。", "cover.conveyor.item_filter.title": "アイテムフィルター", "cover.conveyor.mode": "モード: %s", "cover.conveyor.mode.export": "モード: 搬出", @@ -1905,7 +1995,7 @@ "cover.conveyor.tag.title.0": "鉱石辞書フィルター", "cover.conveyor.tag.title.1": "( * でワイルドカード指定)", "cover.conveyor.title": "%s コンベアーカバー設定", - "cover.conveyor.transfer_rate": "§7アイテム/秒", + "cover.conveyor.transfer_rate": "個/秒", "cover.detector_base.message_inverted_state": "反転", "cover.detector_base.message_normal_state": "通常", "cover.ender_fluid_link.incomplete_hex.0": "入力された色が不完全である!", @@ -1917,6 +2007,12 @@ "cover.ender_fluid_link.private.tooltip.disabled.1": "プライベートモードでは、最初にカバーをかけたプレイヤーが使用できます。", "cover.ender_fluid_link.private.tooltip.enabled": "公開タンクモードに切り替え", "cover.ender_fluid_link.title": "液体エンダーリンク", + "cover.ender_fluid_link.tooltip.channel_description": "テキスト入力でチャンネルの説明を設定する", + "cover.ender_fluid_link.tooltip.channel_name": "テキスト入力でチャンネル名を設定する", + "cover.ender_fluid_link.tooltip.clear_button": "チャンネルの説明をクリアする", + "cover.ender_fluid_link.tooltip.list_button": "チャンネルリストを表示する", + "cover.ender_item_link.title": "アイテムエンダーリンク", + "cover.ender_redstone_link.title": "レッドストーンエンダーリンク", "cover.filter.blacklist.disabled": "ホワイトリスト", "cover.filter.blacklist.enabled": "ブラックリスト", "cover.filter.mode.filter_both": "搬入/搬出フィルター", @@ -1953,19 +2049,20 @@ "cover.item_smart_filter.filtering_mode.electrolyzer": "電解槽", "cover.item_smart_filter.filtering_mode.sifter": "選別機", "cover.item_smart_filter.title": "スマートアイテムフィルター", - "cover.machine_controller.invert.disabled.0": "§eNormal§r - このモードでは、カバーは設定されたレッドストーンレベルより弱い信号を必要とします。", - "cover.machine_controller.invert.enabled.0": "§eInverted§r - このモードでは、カバーが動作するために設定されたレッドストーンレベルより強い信号を必要とします。", + "cover.machine_controller.invert.disabled.0": "§e通常§r - このモードでは、カバーが動作するために設定されたレッドストーンレベルより弱い信号を必要とします。", + "cover.machine_controller.invert.enabled.0": "§e反転§r - このモードでは、カバーが動作するために設定されたレッドストーンレベルより強い信号を必要とします。", "cover.machine_controller.inverted": "反転", - "cover.machine_controller.mode.cover_down": "下面カバー制御", - "cover.machine_controller.mode.cover_east": "東面カバー制御", - "cover.machine_controller.mode.cover_north": "北面カバー制御", - "cover.machine_controller.mode.cover_south": "南面カバー制御", - "cover.machine_controller.mode.cover_up": "上面カバー制御", - "cover.machine_controller.mode.cover_west": "西面カバー制御", + "cover.machine_controller.mode.cover_down": "カバー制御 (下面)", + "cover.machine_controller.mode.cover_east": "カバー制御 (東面)", + "cover.machine_controller.mode.cover_north": "カバー制御 (北面)", + "cover.machine_controller.mode.cover_south": "カバー制御 (南面)", + "cover.machine_controller.mode.cover_up": "カバー制御 (上面)", + "cover.machine_controller.mode.cover_west": "カバー制御 (西面)", "cover.machine_controller.mode.machine": "機械制御", - "cover.machine_controller.mode.null": "制御しない", + "cover.machine_controller.mode.null": "何も制御しない", "cover.machine_controller.normal": "通常", "cover.machine_controller.redstone": "最小レッドストーン強度: %d", + "cover.machine_controller.suspend_powerfail": "電力不足による停止を防止:", "cover.machine_controller.title": "マシンコントローラーの設定", "cover.pump.fluid_filter.title": "液体フィルター", "cover.pump.mode.export": "モード: 搬出", @@ -1980,21 +2077,21 @@ "cover.robotic_arm.transfer_mode.keep_exact": "保持モード", "cover.robotic_arm.transfer_mode.transfer_any": "すべて移動", "cover.robotic_arm.transfer_mode.transfer_exact": "供給モード", - "cover.shutter.message.disabled": "シャッターを開く", - "cover.shutter.message.enabled": "シャッターを閉じる", - "cover.storage.title": "倉庫カバー", + "cover.shutter.message.disabled": "シャッターを無効化", + "cover.shutter.message.enabled": "シャッターを有効化", + "cover.storage.title": "収納カバー", "cover.tag_filter.info.0": "§b複雑な表現も受け入れる", - "cover.tag_filter.info.1": "a & b§r = AND", + "cover.tag_filter.info.1": "§6a & b§r = AND", + "cover.tag_filter.info.10": "§b例: §6*dusts/gold | (gtceu:circuits & !*lv)", + "cover.tag_filter.info.11": "これは全ての金の粉、またはLVを除く全ての回路に一致します。", "cover.tag_filter.info.2": "§6a | b§r = OR", "cover.tag_filter.info.3": "§6a ^ b§r = XOR", "cover.tag_filter.info.4": "§6!a§r = NOT", - "cover.tag_filter.info.5": "§6(a)§r 優先度", - "cover.tag_filter.info.6": "§6*§r ワイルドカード", - "cover.tag_filter.info.7": "§6$§r タグ無し", - "cover.tag_filter.info.8": "§bタグは'名前空間:タグ/サブタイプ'の形式で書かれます。", - "cover.tag_filter.info.9": "指定されていない場合は、'forge:'名前空間になります。", - "cover.tag_filter.info.10": "§b例: §6*dusts/gold | (gtceu:circuits & !*lv)", - "cover.tag_filter.info.11": "これはすべての金の粉かLV以外の電子回路にマッチします。", + "cover.tag_filter.info.5": "§6(a)§r for grouping", + "cover.tag_filter.info.6": "§6*§r for wildcard", + "cover.tag_filter.info.7": "§6$§r for untagged", + "cover.tag_filter.info.8": "§bタグは次のような形式で提供されます 'namespace:tag/subtype'.", + "cover.tag_filter.info.9": "指定されていない場合は、\"forge:\"名前空間が想定されます。", "cover.tag_filter.matches": "アイテムが一致", "cover.tag_filter.matches_not": "アイテムが一致しません", "cover.tag_filter.test_slot.info": "フィルター式に一致するかテストするためにアイテムを挿入してください", @@ -2002,14 +2099,14 @@ "cover.universal.manual_import_export.mode.description.0": "§e無効§r - アイテム/液体は、カバーとそのフィルターによって指定された通りにしか動きません。 ", "cover.universal.manual_import_export.mode.description.1": "§eフィルター付き§r - フィルターがあれば、カバーモードに関係なく、アイテム/液体を抽出し、挿入することができます。 ", "cover.universal.manual_import_export.mode.description.2": "§eフィルターなしを許可§r - アイテム/液体はカバーモードとは無関係に移動できる。フィルターは、このカバーによって挿入または抽出されたアイテムに適用されます。", - "cover.universal.manual_import_export.mode.disabled": "手動入出力: §b無効\n§7アイテム/液体は、カバーとそのフィルターによって指定された通りにしか動きません。", - "cover.universal.manual_import_export.mode.filtered": "手動入出力: §bフィルタ\n§7アイテム/液体は、フィルターがあれば、カバーモードとは無関係に抽出/挿入できる。", - "cover.universal.manual_import_export.mode.unfiltered": "マニュアルI/O: §bアイテム/液体は、カバーモードとは無関係に移動できる。フィルターは、このカバー自体によって挿入または抽出されるものにのみ適用される。", + "cover.universal.manual_import_export.mode.disabled": "マニュアル I/O: 無効", + "cover.universal.manual_import_export.mode.filtered": "マニュアル I/O: フィルタ済み", + "cover.universal.manual_import_export.mode.unfiltered": "マニュアル I/O: フィルタされていない", "cover.voiding.label.disabled": "無効", "cover.voiding.label.enabled": "有効", "cover.voiding.message.disabled": "消去カバーを無効化", "cover.voiding.message.enabled": "消去カバーを有効化", - "cover.voiding.tooltip": "§c警告!§7 この設定を \"有効 \"にすると、液体やアイテムが無効になります。", + "cover.voiding.tooltip": "警告! これを\"有効\"にすると搬入された液体やアイテムが全て消去されます。", "cover.voiding.voiding_mode.description.0": "§e虚無マッチング§r は、フィルタにマッチするものを無効にする。 ", "cover.voiding.voiding_mode.description.1": "§e虚無オーバーフロー§rは、フィルターにマッチするものを、指定された量まで無効にする。", "cover.voiding.voiding_mode.void_any": "適合消去モード", @@ -2088,7 +2185,7 @@ "gtceu.arc_furnace": "アーク炉", "gtceu.assembler": "組立機", "gtceu.assembly_line": "アセンブリライン", - "gtceu.auto_decomp.rotor": "タービンロータ", + "gtceu.auto_decomp.rotor": "タービンローター", "gtceu.auto_decomp.tool": "非電動ツール", "gtceu.autoclave": "オートクレーブ", "gtceu.battery_buffer.average_input": "入力平均: %s EU/t", @@ -2098,53 +2195,57 @@ "gtceu.bus.collapse.error": "バスは最初にマルチブロックに接続されなければならない", "gtceu.bus.collapse_false": "バス内でアイテムを整頓を行わない", "gtceu.bus.collapse_true": "バス内でアイテムを整頓を行う", - "gtceu.button.bedrock_fluids": "岩盤流体鉱脈を表示", - "gtceu.button.hide_depleted": "枯渇した鉱脈を隠す", + "gtceu.button.bedrock_fluids": "岩盤流体鉱床を表示", + "gtceu.button.hide_depleted": "枯渇した鉱床を隠す", "gtceu.button.ore_veins": "GT鉱石鉱脈を表示", - "gtceu.button.show_depleted": "枯渇した鉱脈を表示", - "gtceu.cable.amperage": "§e最大アンペア数:§r §e%d", - "gtceu.cable.loss_per_block": "§c損失/メートル/アンペア§r §c%d§7 EU ボルト", - "gtceu.cable.superconductor": "%s §d超伝導体", - "gtceu.cable.voltage": "§a最大電圧:§r §a%d §a(%s§a)", + "gtceu.button.show_depleted": "枯渇した鉱床を表示", + "gtceu.cable.amperage": "§eMax Amperage:§r §e%d", + "gtceu.cable.loss_per_block": "§cLoss/Meter/Ampere:§r §c%d§7 EU-Volt", + "gtceu.cable.superconductor": "%s §dSuperconductor", + "gtceu.cable.voltage": "§aMax Voltage:§r §a%d §a(%s§a)", "gtceu.canner": "缶詰機", + "gtceu.central_monitor.gui.create_group": "グループを作成", + "gtceu.central_monitor.gui.currently_editing": "現在編集中: %s", + "gtceu.central_monitor.gui.remove_from_group": "グループから削除", + "gtceu.central_monitor.gui.set_target": "ターゲットを設定", + "gtceu.central_monitor.info_tooltip.0": "モニターを使用するには、まずグループに分割する必要があります。1つのグループには1つのモジュールしか含めることはできません。", + "gtceu.central_monitor.info_tooltip.1": "左クリックで選択し、「グループを作成」をクリックします。", + "gtceu.central_monitor.info_tooltip.2": "次に、グループの設定ページでモジュールを挿入し、同じページで設定できます。", + "gtceu.central_monitor.info_tooltip.3": "グループを削除するには、そのすべてのコンポーネントを選択し、「グループから削除」をクリックします。", + "gtceu.central_monitor.info_tooltip.4": "グループ名をクリックすると、そのグループのすべてのコンポーネントを素早く選択できます。もう一度クリックすると選択解除されます。", + "gtceu.central_monitor.info_tooltip.5": "一部のモジュールはターゲットとするブロックに応じて情報を表示します。グループのターゲットを設定するには、そのグループの任意のコンポーネントを選択し、目的のコンポーネントを右クリックします。", + "gtceu.central_monitor.info_tooltip.6": "マルチブロック外のターゲットを選択したい場合は、ワイヤレス送信機カバーを使用する必要があります。", + "gtceu.central_monitor.info_tooltip.7": "目的のブロックにカバーを設置し、データスティックで右クリックして、そのデータスティックをマルチブロックのデータアクセスハッチに入れます。", + "gtceu.central_monitor.info_tooltip.8": "次に、データアクセスハッチをターゲットとして選択し、表示された数値フィールドにデータスティックのスロットインデックスを設定します。", + "gtceu.central_monitor.size": "サイズ: (%d+1+%d)x(%d+1+%d)", "gtceu.centrifuge": "遠心分離機", "gtceu.chance_logic.and": "AND", + "gtceu.chance_logic.first": "FIRST", "gtceu.chance_logic.none": "NONE", "gtceu.chance_logic.or": "OR", "gtceu.chance_logic.xor": "XOR", - "gtceu.chat.cape": "§おめでとうございます!使うにはケープセレクターターミナルアプリを参照してください§r", + "gtceu.chat.cape": "§おめでとうございます!使うにはターミナルのマントセレクタのアプリを参照してください§r", "gtceu.chemical_bath": "化学槽", "gtceu.chemical_reactor": "化学反応器", "gtceu.circuit_assembler": "回路組立機", "gtceu.coke_oven": "コークス炉", "gtceu.combustion_generator": "燃焼発電機", - "gtceu.command.copy.click_to_copy": "クリックでコピー", - "gtceu.command.copy.copied_and_click": "をクリップボードにコピーします。クリックで再びコピーします", - "gtceu.command.copy.copied_end": "] をコピーしました", - "gtceu.command.copy.copied_start": "クリップボードに [", - "gtceu.command.hand.electric": "蓄電量: %d / %d EU - Tier: %d; バッテリー?: %s", - "gtceu.command.hand.fluid": "液体情報: %d / %d mB; Can Fill: %s; Can Drain: %s", - "gtceu.command.hand.fluid2": "液体ID:", - "gtceu.command.hand.groovy": "§6/gs hand§7を検討してください。", - "gtceu.command.hand.item_id": "アイテムID: %s (メタデータ: %d)", - "gtceu.command.hand.material": "マテリアルID:", - "gtceu.command.hand.meta_item": "メタアイテムID:", - "gtceu.command.hand.no_item": "コマンドを実行するためには何かを手にもっておく必要があります。", - "gtceu.command.hand.not_a_player": "このコマンドはプレイヤーのみ使用できます。", - "gtceu.command.hand.ore_prefix": "鉱石接頭辞:", - "gtceu.command.hand.tag_entries": "§3タグエントリ:", - "gtceu.command.hand.tool_stats": "ツール統計クラス: %s", - "gtceu.command.hand.usage": "使用方法: /gtceu hand", - "gtceu.command.recipecheck.begin": "レシピの競合チェック開始...", - "gtceu.command.recipecheck.end": "競合チェックにより、競合の可能性が%d個見つかりました。サーバーログで詳細を確認してください。", - "gtceu.command.recipecheck.end_no_conflicts": "レシピ競合は見つかりませんでした!", - "gtceu.command.recipecheck.usage": "使用方法: /gtceu recipecheck", - "gtceu.command.usage": "使用方法: /gtceu ", - "gtceu.command.worldgen.reload.failed": "Worldgenの読み込みに失敗しました。エラーを確認してください。", - "gtceu.command.worldgen.reload.success": "configからWorldgenが正常に読み込まれました。", - "gtceu.command.worldgen.reload.usage": "使用方法: /gtceu worldgen reload", - "gtceu.command.worldgen.usage": "使用方法: /gtceu worldgen ", "gtceu.compressor": "圧縮機", + "gtceu.computer_monitor_cover.error.bf_invalid": "位置%dに無効な文字があります", + "gtceu.computer_monitor_cover.error.bf_invalid_num": "%d番目のシンボル処理中、インデックス%dに無効な数値があります", + "gtceu.computer_monitor_cover.error.exception": "予期せぬ例外が発生しました: %s", + "gtceu.computer_monitor_cover.error.invalid_args": "無効な引数です!", + "gtceu.computer_monitor_cover.error.invalid_number": "無効な数値 '%s' です!", + "gtceu.computer_monitor_cover.error.missing_item": "スロット%dに%sがありません!", + "gtceu.computer_monitor_cover.error.no_ae": "カバーホルダーにAE2ネットワークがありません!", + "gtceu.computer_monitor_cover.error.no_cover": "カバーがありません!", + "gtceu.computer_monitor_cover.error.no_placeholder": "そのようなプレースホルダーはありません: '%s'!", + "gtceu.computer_monitor_cover.error.not_enough_args": "少なくとも%d個の引数が必要ですが、%d個しかありません!", + "gtceu.computer_monitor_cover.error.not_in_range": "%sは%dから%dの間(両端を含む)である必要がありますが、%dです", + "gtceu.computer_monitor_cover.error.not_supported": "この機能はこのブロック/カバーではサポートされていません!", + "gtceu.computer_monitor_cover.error.unclosed_bracket": "閉じられていない括弧があります!", + "gtceu.computer_monitor_cover.error.unexpected_bracket": "予期せぬ閉じ括弧です!", + "gtceu.computer_monitor_cover.error.wrong_number_of_args": "引数が%d個必要ですが、%d個です!", "gtceu.cover.activity_detector.message_activity_inverted": "反転アクティビティ状態のモニタリング", "gtceu.cover.activity_detector.message_activity_normal": "通常活動状況のモニタリング", "gtceu.cover.activity_detector_advanced.message_activity_inverted": "反転進行ステータスのモニタリング", @@ -2180,6 +2281,8 @@ "gtceu.direction.tooltip.left": "左", "gtceu.direction.tooltip.right": "右", "gtceu.direction.tooltip.up": "上", + "gtceu.display_source.computer_monitor_cover": "コンピュータモニターカバー", + "gtceu.display_target.computer_monitor_cover": "コンピュータモニターカバー", "gtceu.distillation_tower": "蒸留塔", "gtceu.distillery": "蒸留機", "gtceu.duct_pipe.transfer_rate": "§b空気搬送速度: %s", @@ -2188,7 +2291,9 @@ "gtceu.electric_furnace": "電気かまど", "gtceu.electrolyzer": "電解槽", "gtceu.electromagnetic_separator": "電磁分離機", - "gtceu.evaporation": "蒸発塔", + "gtceu.ender_item_link_cover.title": "アイテムエンダーリンク", + "gtceu.ender_redstone_link_cover.label": "レッドストーンパワー: %d", + "gtceu.ender_redstone_link_cover.title": "レッドストーンエンダーリンク", "gtceu.extractor": "抽出機", "gtceu.extruder": "押出機", "gtceu.fermenter": "発酵槽", @@ -2227,7 +2332,15 @@ "gtceu.fusion_reactor": "核融合炉", "gtceu.gas_collector": "ガス収集機", "gtceu.gas_turbine": "ガスタービン", + "gtceu.gui.adv_stocking_config.min_fluid_count": "自動引き出しのための最小液体スタックサイズ", + "gtceu.gui.adv_stocking_config.min_item_count": "自動引き出しのための最小アイテムスタックサイズ", + "gtceu.gui.adv_stocking_config.ticks_per_cycle": "アイテムリスト更新間の遅延", + "gtceu.gui.adv_stocking_config.title": "自動在庫設定", "gtceu.gui.auto_output.name": "自動", + "gtceu.gui.central_monitor.group": "グループ: %s", + "gtceu.gui.central_monitor.group_default_name": "グループ #%d", + "gtceu.gui.central_monitor.none": "なし", + "gtceu.gui.central_monitor.text_scale": "テキストスケール", "gtceu.gui.charger_slot.tooltip.0": "§fチャージャースロット§r", "gtceu.gui.charger_slot.tooltip.1": "§7%sバッテリーから電力を供給§r", "gtceu.gui.charger_slot.tooltip.2": "§7%sツールとバッテリーを充電します。", @@ -2236,6 +2349,18 @@ "gtceu.gui.chunkmode.enabled.0": "チャンクモード有効: クリックすると無効になります。", "gtceu.gui.chunkmode.enabled.1": "§7スイッチングにはアイドルマシンが必要。", "gtceu.gui.circuit.title": "回路設定", + "gtceu.gui.computer_monitor_cover.edit_blank_placeholders": "空のプレースホルダーを編集", + "gtceu.gui.computer_monitor_cover.edit_displayed_text": "表示テキストを編集", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.0": "ここに%d行目に表示する文字列を入力します。", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.1": "プレースホルダーを含めることができます。例: 'エネルギー: {energy}/{energyCapacity} EU'", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.2": "プレースホルダーは他のプレースホルダーの中にも記述できます。", + "gtceu.gui.computer_monitor_cover.placeholder_reference.0": "すべてのプレースホルダー:", + "gtceu.gui.computer_monitor_cover.placeholder_reference.1": "(ホバーで詳細情報を表示)", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.0": "ここに%s '{}' の代わりに使用するプレースホルダーを入力します。", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.1": "例えば、'エネルギー: {}/{} EU' という文字列と、これらのテキストボックスに 'energy' と 'energyCapacity' を入力できます。", + "gtceu.gui.computer_monitor_cover.slot_tooltip.0": "一部のプレースホルダーが参照できるアイテム用のスロット", + "gtceu.gui.computer_monitor_cover.slot_tooltip.1": "スロット番号: %d", + "gtceu.gui.computer_monitor_cover.update_interval": "更新間隔 (tick単位)", "gtceu.gui.config_slot": "§fコンフィグスロット§r", "gtceu.gui.config_slot.auto_pull_managed": "§4無効:§7オートプルによる管理", "gtceu.gui.config_slot.remove": "§7右クリックで§4クリア§7コンフィグスロット§r", @@ -2253,10 +2378,15 @@ "gtceu.gui.content.chance_boosted_logic": "電圧確率: %s%% (%s)", "gtceu.gui.content.chance_nc": "§c消費されない§r", "gtceu.gui.content.chance_nc_short": "§cNC§r", - "gtceu.gui.content.chance_tier_boost_plus": "ティアチャンス: +%s%%/tier", + "gtceu.gui.content.chance_no_boost": "確率: %s%%", + "gtceu.gui.content.chance_no_boost_logic": "確率: %s%% (%s)", "gtceu.gui.content.chance_tier_boost_minus": "ティアチャンス: -%s%%/tier", + "gtceu.gui.content.chance_tier_boost_plus": "ティアチャンス: +%s%%/tier", "gtceu.gui.content.count_range": "%s-%sx", + "gtceu.gui.content.fluid_range": "%s-%smB", "gtceu.gui.content.per_tick": "§a1Tickあたりの消費量/生産量 §r", + "gtceu.gui.content.range": "%s-%s", + "gtceu.gui.content.times_item": "x %s", "gtceu.gui.content.tips.per_second_short": "§a/秒§r", "gtceu.gui.content.tips.per_tick_short": "§a/tick§r", "gtceu.gui.content.units.per_second": "/s", @@ -2289,6 +2419,7 @@ "gtceu.gui.item_voiding_partial.tooltip.disabled": "アイテム消滅無効", "gtceu.gui.item_voiding_partial.tooltip.enabled": "アイテム消滅有効", "gtceu.gui.machinemode": "アクティブマシンモード: %s", + "gtceu.gui.machinemode.tab_tooltip": "アクティブなマシンモードを変更する", "gtceu.gui.machinemode.title": "アクティブマシンモード", "gtceu.gui.me_bus.auto_pull_button": "クリックすると、MEからのアイテムの自動取り出しが切り替わります。", "gtceu.gui.me_network.offline": "ネットワーク状況: §4オフライン§r", @@ -2318,6 +2449,9 @@ "gtceu.gui.silktouch.enabled.0": "シルクタッチ有効: クリックすると無効になります。", "gtceu.gui.silktouch.enabled.1": "§7スイッチングにはアイドルマシンが必要。", "gtceu.gui.sort": "ソート", + "gtceu.gui.title.adv_stocking_config.min_fluid_count": "最小液体量", + "gtceu.gui.title.adv_stocking_config.min_item_count": "最小アイテム数", + "gtceu.gui.title.adv_stocking_config.ticks_per_cycle": "サイクル毎Tick", "gtceu.gui.title_bar.back": "戻る", "gtceu.gui.title_bar.page_switcher": "ページ", "gtceu.gui.toggle_view.disabled": "液体スロット切り替え", @@ -2337,9 +2471,12 @@ "gtceu.item_filter.empty_item": "指定なし", "gtceu.item_filter.footer": "§e 書き換える項目でクリックする。", "gtceu.item_list.item_stored": "§7格納: %d", - "gtceu.item_pipe.priority": "§9優先順位: §f%d", + "gtceu.item_pipe.priority": "§9優先度: §f%d", + "gtceu.jade.amperage_use": "%s A", + "gtceu.jade.at": " @ ", "gtceu.jade.cleaned_this_second": "汚染の洗浄度: %s/s", "gtceu.jade.energy_stored": "%d / %d EU", + "gtceu.jade.fluid_use": "%s mB/t", "gtceu.jade.progress_computation": "%s / %s CWU", "gtceu.jade.progress_sec": "%s / %s s", "gtceu.jade.progress_tick": "%s / %s t", @@ -2432,8 +2569,8 @@ "gtceu.jei.ore_vein_diagram.weight": "割合: %s", "gtceu.jei.programmed_circuit": "プログラム回路ページ", "gtceu.journeymap.options.layers": "探査層", - "gtceu.journeymap.options.layers.bedrock_fluids": "岩盤液体鉱脈を表示", - "gtceu.journeymap.options.layers.hide_depleted": "枯渇した鉱脈を非表示", + "gtceu.journeymap.options.layers.bedrock_fluids": "岩盤液体鉱床を表示", + "gtceu.journeymap.options.layers.hide_depleted": "枯渇した鉱床を隠す", "gtceu.journeymap.options.layers.ore_veins": "鉱石鉱脈を表示", "gtceu.key.armor_charging": "装備のインベントリ充電機能の切替", "gtceu.key.armor_hover": "装備のホバーモードの切替", @@ -2458,14 +2595,16 @@ "gtceu.machine.available_recipe_map_4.tooltip": "使用可能なレシピの種類: %s, %s, %s, %s", "gtceu.machine.basic.input_from_output_side.allow": "出力側からの入力を許可する: ", "gtceu.machine.basic.input_from_output_side.disallow": "出力側からの入力を許可しない: ", + "gtceu.machine.batch_disabled": "バッチ処理無効", + "gtceu.machine.batch_enabled": "バッチ処理有効", "gtceu.machine.bedrock_ore_miner.depletion": "§b枯渇速度: §f%s%%", "gtceu.machine.bedrock_ore_miner.description": "§7岩盤下の鉱脈から鉱石を掘り出す。", "gtceu.machine.bedrock_ore_miner.production": "§e生産倍率: §f%dx、オーバークロックで%f倍", "gtceu.machine.block_breaker.speed_bonus": "速度ボーナス: §f%d%%", "gtceu.machine.block_breaker.tooltip": "§7正面のブロックを破壊しドロップアイテムを集める", - "gtceu.machine.boiler.info.cooling.down": "§9冷却中§r%s", - "gtceu.machine.boiler.info.heating.up": "§c加熱中§r%s", - "gtceu.machine.boiler.info.producing.steam": " §a(沸騰する水)", + "gtceu.machine.boiler.info.cooling.down": "§9冷却中§r", + "gtceu.machine.boiler.info.heating.up": "§c加熱中§r", + "gtceu.machine.boiler.info.production.data": "§a%s§a mB/t 生産中", "gtceu.machine.buffer.tooltip": "アイテムと液体を補完する小さなバッファー", "gtceu.machine.canner.jei_description": "この機械を使うことで、バケツや液体セルなどあらゆる液体容器から液体を出し入れできる。", "gtceu.machine.central_monitor.tooltip": "これでDoomってプレイできる?", @@ -2595,7 +2734,7 @@ "gtceu.machine.hp_steam_forge_hammer.tooltip": "§7鍛造機", "gtceu.machine.hp_steam_furnace.tooltip": "§7圧縮蒸気の力で製錬", "gtceu.machine.hp_steam_liquid_boiler.tooltip": "§7液体燃料用小型ボイラーより早い", - "gtceu.machine.hp_steam_macerator.tooltip": "§7鉱石を細かく刻む", + "gtceu.machine.hp_steam_macerator.tooltip": "§7Macerating your Ores without Byproducts", "gtceu.machine.hp_steam_rock_crusher.tooltip": "§7水と溶岩を水平に隣接させる", "gtceu.machine.hp_steam_solar_boiler.tooltip": "§7太陽の力で蒸気を", "gtceu.machine.hp_steam_solid_boiler.tooltip": "§7固形燃料用小型ボイラーよりも早い", @@ -2733,7 +2872,7 @@ "gtceu.machine.lp_steam_forge_hammer.tooltip": "§7鍛造機", "gtceu.machine.lp_steam_furnace.tooltip": "§7圧縮蒸気の力で製錬", "gtceu.machine.lp_steam_liquid_boiler.tooltip": "§7液体燃料で動くボイラー", - "gtceu.machine.lp_steam_macerator.tooltip": "§7鉱石を細かく刻む", + "gtceu.machine.lp_steam_macerator.tooltip": "§7副産物なしで鉱石を粉砕する", "gtceu.machine.lp_steam_rock_crusher.tooltip": "§7水と溶岩を水平に隣接させる", "gtceu.machine.lp_steam_solar_boiler.tooltip": "§7太陽の力で蒸気を", "gtceu.machine.lp_steam_solid_boiler.tooltip": "§7蒸気の力を得るための最初の手段", @@ -2826,7 +2965,7 @@ "gtceu.machine.maintenance_hatch_full_auto.tooltip": "マルチブロックの自動メンテナンスに", "gtceu.machine.maintenance_hatch_tape_slot.tooltip": "故障を解決するためにテープを挿入", "gtceu.machine.maintenance_hatch_tool_slot.tooltip": "故障解決のためのツールがインベントリ内にある場合、素手でここをクリックすると故障箇所を解決できる。", - "gtceu.machine.me.copy_paste.tooltip": "データスティックをシフト右クリックして設定をコピーし、右クリックして適用する", + "gtceu.machine.me.copy_paste.tooltip": "データスティックでスニーク右クリックして設定をコピー、右クリックして適用", "gtceu.machine.me.export.tooltip": "MEネットワークに接続する前の容量は無限。", "gtceu.machine.me.fluid_export.tooltip": "液体を直接MEネットワークに保存する。", "gtceu.machine.me.fluid_import.data_stick.name": "§oME搬入ハッチ構成データ", @@ -2924,7 +3063,7 @@ "gtceu.machine.power_substation.tooltip.1": "§f蓄電ブロック§7のTierを揃える必要はない。", "gtceu.machine.power_substation.tooltip.2": "§f蓄電ブロック§7は§f%d層§7まで増築できる。", "gtceu.machine.power_substation.tooltip.3": "§f24時間毎に§7最大蓄電量の§f1%%§7を損失する。", - "gtceu.machine.power_substation.tooltip.4": "蓄電ブロック当たり§f%,d EU/t§7の受動損失。", + "gtceu.machine.power_substation.tooltip.4": "蓄電ブロック当たり§f%d EU/t§7の受動損失。", "gtceu.machine.power_substation.tooltip.5": "", "gtceu.machine.power_substation.tooltip.6": "レーザーハッチ§7も利用可能。", "gtceu.machine.primitive_blast_furnace.bronze.tooltip": "初めてのスチールづくりに", @@ -3100,6 +3239,7 @@ "gtceu.multiblock.active_transformer.max_input": "§a最大入力: §f%s EU/t", "gtceu.multiblock.active_transformer.max_output": "§c最大出力: §f%s EU/t", "gtceu.multiblock.assembly_line.description": "アセンブリラインは5から16の\"スライス\"から成る大型マルチブロック機械です。理屈の上では高度な電子部品を作成するために使用される大型の組み立て機です。", + "gtceu.multiblock.batch_enabled": "- バッチ処理による%dx", "gtceu.multiblock.blast_furnace.max_temperature": "最大温度: %s", "gtceu.multiblock.central_monitor.height": "スクリーンの高さ:", "gtceu.multiblock.central_monitor.height_modify": "高さ変更: %d", @@ -3127,6 +3267,9 @@ "gtceu.multiblock.cracking_unit.energy": "エネルギー使用量: %s%%", "gtceu.multiblock.data_bank.description": "データバンクは複数のアセンブリラインで研究データを共有するマルチブロックで、アセンブリラインにより複雑な研究データの読み取りを可能にさせます。", "gtceu.multiblock.data_bank.providing": "研究データを供給中", + "gtceu.multiblock.dimension": "§eDimensions: §r%sx%sx%s", + "gtceu.multiblock.dimensions.0": "Dimensions: ", + "gtceu.multiblock.dimensions.1": " §c§lWidth§r: %s, §a§lHeight§r: %s, §9§lDepth§r: %s ", "gtceu.multiblock.distillation_tower.description": "蒸留塔は石油を様々なものに蒸留し、副産物を得ることができるマルチブロック機械です。", "gtceu.multiblock.distillation_tower.distilling_fluid": "%sを蒸留中", "gtceu.multiblock.electric_blast_furnace.description": "工業用電気炉(EBF)は合金や金属の精錬、鉱石の精製を行うマルチブロック機械です。これはアルミニウムやステンレススチール、チタン、ナクアダ合金のような上位素材に要求されます。", @@ -3227,7 +3370,7 @@ "gtceu.multiblock.page_switcher.io.export": "§4出力", "gtceu.multiblock.page_switcher.io.import": "§2入力", "gtceu.multiblock.parallel": "最大 %d レシピを並列実行します。", - "gtceu.multiblock.parallel.exact": "%d 個のレシピを並列実行しています", + "gtceu.multiblock.parallel.exact": "- 並列処理による%dx", "gtceu.multiblock.parallelizable.tooltip": "パラレルコントロールハッチで並列化可能。", "gtceu.multiblock.pattern.clear_amount_1": "§6前方に1x1x1のスペースが必要§r", "gtceu.multiblock.pattern.clear_amount_3": "§6前方に3x3x1のスペースが必要§r", @@ -3244,13 +3387,13 @@ "gtceu.multiblock.pattern.location_end": "§c最後尾§r", "gtceu.multiblock.pattern.replaceable_air": "空気で置換可能", "gtceu.multiblock.pattern.single": "§6このブロックのみ使用可§r", - "gtceu.multiblock.power_substation.average_in": "§7平均値 入力: §c%s §7EU/t", + "gtceu.multiblock.power_substation.average_in": "§7平均値 入力: %s §7EU/t", "gtceu.multiblock.power_substation.average_in_hover": "大型蓄電器の内部蓄電器に充電されるEUの平均値", - "gtceu.multiblock.power_substation.average_out": "§7平均値 出力: §a%s §7EU/t", + "gtceu.multiblock.power_substation.average_out": "§7平均値 出力: %s §7EU/t", "gtceu.multiblock.power_substation.average_out_hover": "大型蓄電器の内部蓄電器から出力されたEUの平均値", - "gtceu.multiblock.power_substation.capacity": "§7最大蓄電量: §6%s §7EU", - "gtceu.multiblock.power_substation.passive_drain": "§7損失量: $4%s §7EU/t", - "gtceu.multiblock.power_substation.stored": "§7蓄電量: §6%s §7EU", + "gtceu.multiblock.power_substation.capacity": "§7最大蓄電量: %s §7EU", + "gtceu.multiblock.power_substation.passive_drain": "§7損失量: %s §7EU/t", + "gtceu.multiblock.power_substation.stored": "§7蓄電量: %s §7EU", "gtceu.multiblock.power_substation.time_days": "%s 日", "gtceu.multiblock.power_substation.time_forever": "永遠", "gtceu.multiblock.power_substation.time_hours": "%s 時間", @@ -3293,7 +3436,9 @@ "gtceu.multiblock.steam.steam_stored": "蒸気: %s / %s mb", "gtceu.multiblock.steam_grinder.description": "蒸気時代のマルチブロック式粉砕機。ブロンズ製外装が最低14個必要。/n通常のハッチ/バスは使えず、専用の蒸気用のものが必要。", "gtceu.multiblock.steam_oven.description": "蒸気時代のマルチスメルター。ブロンズ製外装が最低6個必要。通常のハッチ/バスは使えず、専用の蒸気用のものが必要。蒸気ハッチは最下段に一つだけ置ける。", + "gtceu.multiblock.subtick_parallels": "- オーバークロックによる%dx", "gtceu.multiblock.title": "マルチブロックの構造", + "gtceu.multiblock.total_runs": "一度に%d個のレシピを実行中", "gtceu.multiblock.turbine.efficiency": "タービン効率: %s%%", "gtceu.multiblock.turbine.efficiency_tooltip": "%s 以上のローターホルダーごとに§f10%%§7の効率化とEUを2倍にします§7。", "gtceu.multiblock.turbine.energy_per_tick": "エネルギー出力: %s/%s EU/t", @@ -3312,12 +3457,12 @@ "gtceu.multiblock.universal.muffler_obstructed": "マフラーハッチがふさがれている!", "gtceu.multiblock.universal.muffler_obstructed.tooltip": "マフラーハッチの正面は何も置いてはいけません。", "gtceu.multiblock.universal.no_problems": "問題ナシ!", - "gtceu.multiblock.universal.problem.crowbar": "§7部品がずれている。 (§aバール§7)", - "gtceu.multiblock.universal.problem.hard_hammer": "§7メッキがへこんでいる。 (§aハンマー§7)", - "gtceu.multiblock.universal.problem.screwdriver": "§7ネジが緩い。 (§aスクリュードライバー§7)", - "gtceu.multiblock.universal.problem.soft_mallet": "§7何かが詰まっている。 (§aソフトマレット§7)", - "gtceu.multiblock.universal.problem.wire_cutter": "§7ワイヤーが焼き切れている。 (§aワイヤーカッター§7)", - "gtceu.multiblock.universal.problem.wrench": "%s§7パイプが緩い。 (§aレンチ§7)", + "gtceu.multiblock.universal.problem.crowbar": "§7これはここにあるべきではない。(§aバール§7)", + "gtceu.multiblock.universal.problem.hard_hammer": "§7メッキがへこんでいる。(§a硬質ハンマー§7)", + "gtceu.multiblock.universal.problem.screwdriver": "§7ネジが緩んでいる。(§aスクリュードライバー§7)", + "gtceu.multiblock.universal.problem.soft_mallet": "§7何かが詰まっている。(§aソフトマレット§7)", + "gtceu.multiblock.universal.problem.wire_cutter": "§7ワイヤーが焼き切れている。(§aワイヤーカッター§7)", + "gtceu.multiblock.universal.problem.wrench": "§7パイプが緩んでいる。(§aレンチ§7)", "gtceu.multiblock.universal.rotor_obstructed": "ローターの近くに邪魔になるブロックがあります。", "gtceu.multiblock.uv_fusion_reactor.description": "核融合炉MK 3は、元素をより重いものに融合させるための大型マルチブロック。UVエネルギーハッチのみを使用することができる。ハッチ1つにつきバッファーは40000000 EU増加し、最大640000000EUまで増加する。", "gtceu.multiblock.vacuum_freezer.description": "真空フリーザーは主に熱いインゴットを通常のインゴットにするために用いるマルチブロック機械ですが、水のような他の物も冷却できます。", @@ -3331,15 +3476,205 @@ "gtceu.oc.tooltip.3": "ミドルクリックでオーバークロックをリセット", "gtceu.oc.tooltip.4": "シフトを押したまま完璧なオーバークロックに変更", "gtceu.ore_washer": "鉱石洗浄機", + "gtceu.ownership.name.argonauts": "アルゴノーツギルド", + "gtceu.ownership.name.ftb": "FTBチーム", + "gtceu.ownership.name.player": "プレイヤー", "gtceu.packer": "梱包機", - "gtceu.part_sharing.disabled": "マルチブロック間での共有: §4不可能", - "gtceu.part_sharing.enabled": "マルチブロック間での共有: §a可能", + "gtceu.part_sharing.disabled": "マルチブロック共有 §4無効", + "gtceu.part_sharing.enabled": "マルチブロック共有 §a有効", + "gtceu.placeholder_info.active.0": "カバーが取り付けられているブロックが現在レシピを実行している場合は1を、それ以外の場合は0を返します。", + "gtceu.placeholder_info.active.1": "使用法:", + "gtceu.placeholder_info.active.2": " {active} -> 現在実行中のレシピがあるかどうか", + "gtceu.placeholder_info.ae2crafting.0": "このカバーが取り付けられているブロックのMEネットワークでの自動クラフトに関する情報を返します。", + "gtceu.placeholder_info.ae2crafting.1": "使用法:", + "gtceu.placeholder_info.ae2crafting.10": " {ae2crafting get time} -> クラフト開始からの経過時間(ナノ秒単位)、CPUがアイドル状態の場合は0", + "gtceu.placeholder_info.ae2crafting.2": " {ae2crafting get amount} -> MEネットワーク内のクラフトCPUの数", + "gtceu.placeholder_info.ae2crafting.3": " {ae2crafting get storage} -> 指定されたCPUが持つクラフトストレージの量", + "gtceu.placeholder_info.ae2crafting.4": " {ae2crafting get threads} -> 指定されたCPUが持つコプロセッサの数", + "gtceu.placeholder_info.ae2crafting.5": " {ae2crafting get name} -> 指定されたクラフトCPUの名前", + "gtceu.placeholder_info.ae2crafting.6": " {ae2crafting get selectionMode} -> 指定されたクラフトCPUの選択モード(手動、自動、または両方のリクエストに使用)", + "gtceu.placeholder_info.ae2crafting.7": " {ae2crafting get amount} -> リクエストされたアイテムの量、CPUがアイドル状態の場合は0", + "gtceu.placeholder_info.ae2crafting.8": " {ae2crafting get item} -> リクエストされたアイテムの表示名、CPUがアイドル状態の場合は0", + "gtceu.placeholder_info.ae2crafting.9": " {ae2crafting get progress} -> クラフトジョブの進捗、CPUがアイドル状態の場合は0", + "gtceu.placeholder_info.ae2energy.0": "このカバーが取り付けられているブロックのMEネットワークに現在保存されているエネルギーを返します。", + "gtceu.placeholder_info.ae2energy.1": "使用法:", + "gtceu.placeholder_info.ae2energy.2": " {ae2energy} -> MEネットワーク内のエネルギー(AE単位)", + "gtceu.placeholder_info.ae2fluidCount.0": "fluidCountと同じですが、このカバーが取り付けられているブロックのMEネットワーク内のアイテムをカウントします。", + "gtceu.placeholder_info.ae2fluidCount.1": "すべての液体をカウントするとラグが発生する可能性があることに注意してください!", + "gtceu.placeholder_info.ae2fluidCount.2": "使用法:", + "gtceu.placeholder_info.ae2fluidCount.3": " {fluidCount [fluidId]} -> すべての液体の量、または指定された場合はfluidIdを持つ液体の量", + "gtceu.placeholder_info.ae2itemCount.0": "itemCountと同じですが、このカバーが取り付けられているブロックのMEネットワーク内のアイテムをカウントします。", + "gtceu.placeholder_info.ae2itemCount.1": "フィルターまたはすべてのアイテムをカウントするとラグが発生する可能性があることに注意してください!", + "gtceu.placeholder_info.ae2itemCount.2": "使用法:", + "gtceu.placeholder_info.ae2itemCount.3": " {itemCount} -> 合計アイテム数", + "gtceu.placeholder_info.ae2itemCount.4": " {itemCount } -> item_idと等しいIDを持つアイテムの数", + "gtceu.placeholder_info.ae2itemCount.5": " {itemCount filter } -> このカバーの指定されたスロットのフィルターに一致するアイテムの数", + "gtceu.placeholder_info.ae2maxPower.0": "このカバーが取り付けられているブロックのMEネットワークのエネルギー容量を返します。", + "gtceu.placeholder_info.ae2maxPower.1": "使用法:", + "gtceu.placeholder_info.ae2maxPower.2": " {ae2maxPower} -> MEネットワークのエネルギー容量", + "gtceu.placeholder_info.ae2powerUsage.0": "このカバーが取り付けられているブロックのMEネットワークのエネルギー消費量を返します。", + "gtceu.placeholder_info.ae2powerUsage.1": "使用法:", + "gtceu.placeholder_info.ae2powerUsage.2": " {ae2powerUsage} -> MEネットワークのエネルギー消費量", + "gtceu.placeholder_info.ae2spatial.0": "このカバーが取り付けられているブロックのMEネットワーク内の空間I/Oに関する情報を返す。", + "gtceu.placeholder_info.ae2spatial.1": "使用法:", + "gtceu.placeholder_info.ae2spatial.2": " {ae2spatial power} -> 空間I/Oを開始するために必要な電力", + "gtceu.placeholder_info.ae2spatial.3": " {ae2spatial efficiency} -> 立方空間ストレージ (SPS) の効率", + "gtceu.placeholder_info.ae2spatial.4": " {ae2spatial size} -> 指定された軸に沿ったSPSのサイズ (例: 'サイズ: {sizeX}x{sizeY}x{sizeZ}')", + "gtceu.placeholder_info.amperage.0": "カバーが取り付けられているワイヤー/ケーブル内の電流を返す。", + "gtceu.placeholder_info.amperage.1": "使用法:", + "gtceu.placeholder_info.amperage.2": " {amperage} -> ワイヤー/ケーブル内の電流", + "gtceu.placeholder_info.bf.0": "使用法:", + "gtceu.placeholder_info.bf.1": " {bf } -> 空の文字列", + "gtceu.placeholder_info.block.0": "ブロック記号 (█) を返す。", + "gtceu.placeholder_info.block.1": "使用法:", + "gtceu.placeholder_info.block.2": " {block} -> '█'", + "gtceu.placeholder_info.calc.0": "数学関数または演算の結果を返す。", + "gtceu.placeholder_info.calc.1": "使用法:", + "gtceu.placeholder_info.calc.2": " {calc } -> any_string", + "gtceu.placeholder_info.calc.3": " {calc } -> 指定された演算の結果", + "gtceu.placeholder_info.calc.4": " {calc <+|-|*|/|//|>>|<<|%> } -> 指定された演算の結果", + "gtceu.placeholder_info.click.0": "ターゲットの発展型モニターが現在のtickより前にクリックされたかどうかを返す。", + "gtceu.placeholder_info.click.1": "使用法:", + "gtceu.placeholder_info.click.2": " {click} -> ターゲットの発展型モニターがクリックされた場合は \"1\"、それ以外の場合は \"0\"", + "gtceu.placeholder_info.click.3": " {click x} -> 最後のクリックのx座標 (0から1の間)", + "gtceu.placeholder_info.click.4": " {click y} -> 最後のクリックのy座標 (0から1の間)", + "gtceu.placeholder_info.cmd.0": "Minecraftコマンドを実行し、その出力を返す。", + "gtceu.placeholder_info.cmd.1": "プレイヤーにバインドされたデータアイテムが必要です。データアイテムを右クリックして自分にバインドしてください。", + "gtceu.placeholder_info.cmd.2": "使用法:", + "gtceu.placeholder_info.cmd.3": " {cmd } -> コマンド出力", + "gtceu.placeholder_info.cmp.0": "引数の式に基づいて1または0を返す。", + "gtceu.placeholder_info.cmp.1": "使用法:", + "gtceu.placeholder_info.cmp.2": " {cmp } -> 1または0、演算子は >, <, >=, <=, ==, != のいずれか", + "gtceu.placeholder_info.color.0": "2番目の引数のテキストを、1番目の引数の色で色付けして返す。すべてのデフォルトのMinecraftチャットカラーが使用可能。", + "gtceu.placeholder_info.color.1": "使用法:", + "gtceu.placeholder_info.color.2": " {color } -> 色付きテキスト", + "gtceu.placeholder_info.combine.0": "すべての引数を単一の文字列に結合する(引数間のすべてのスペースをエスケープすることによって)。", + "gtceu.placeholder_info.combine.1": "例: {combine abc def ghi jkl mno} -> \"abc\\ def\\ ghi\\ jkl\\ mno\"", + "gtceu.placeholder_info.combine.2": "使用法:", + "gtceu.placeholder_info.combine.3": " {combine [arg1] [arg2] [arg3] ...} -> 以降のプレースホルダーで単一の引数として扱われる文字列", + "gtceu.placeholder_info.count.0": "提供された引数のうち、最初の引数と等しいものの数を返す(文字列として比較されるため、\"0\" != \"0.0\")。", + "gtceu.placeholder_info.count.1": "使用法:", + "gtceu.placeholder_info.count.2": " {count [arg2] [arg3] [arg4] ...} -> 最初の引数と等しい引数の数", + "gtceu.placeholder_info.data.0": "スロットのいずれかにあるデータアイテム(データスティック/オーブ/モジュール)からデータを保存または取得する。", + "gtceu.placeholder_info.data.1": " 引数を空のままにすると、値pに置き換えられる(pはデータアイテムのNBTに保存される0から(容量-1)までの整数)。", + "gtceu.placeholder_info.data.2": "使用法:", + "gtceu.placeholder_info.data.3": " {data get } -> 指定されたスロットのアイテムに保存されているデータ", + "gtceu.placeholder_info.data.4": " {data set } -> 指定されたスロットのアイテムに保存されているデータを設定し、空の文字列を返す", + "gtceu.placeholder_info.data.5": " {data getp } -> p", + "gtceu.placeholder_info.data.6": " {data setp } -> pを設定し、空の文字列を返す", + "gtceu.placeholder_info.data.7": " {data inc } -> pを1増やし、pが容量以上になった場合はpを0に設定する", + "gtceu.placeholder_info.data.8": " {data dec } -> pを1減らし、pが0未満になった場合はpを(容量-1)に設定する", + "gtceu.placeholder_info.displayTarget.0": "ディスプレイリンクを使用してこのカバーに送信された指定された行を返す。", + "gtceu.placeholder_info.displayTarget.1": "使用法:", + "gtceu.placeholder_info.displayTarget.2": " {displayTarget } -> 指定された行のテキスト(行番号は1-100)", + "gtceu.placeholder_info.ender.0": "エンダーリンクカバーと対話する", + "gtceu.placeholder_info.ender.1": "プレイヤーにバインドされたデータアイテムを提供された場合、プライベートチャンネルと対話できる", + "gtceu.placeholder_info.ender.10": "player_data_item_slot引数は空(0ではなく、空文字列)にすることができる", + "gtceu.placeholder_info.ender.2": "使用法:", + "gtceu.placeholder_info.ender.3": " {ender item [player_data_item_slot]} -> アイテム数", + "gtceu.placeholder_info.ender.4": " {ender itemPull [player_data_item_slot]} -> エンダーリンクのバッファからアイテムを1つ取り出す", + "gtceu.placeholder_info.ender.5": " {ender itemPush [player_data_item_slot]} -> エンダーリンクのバッファにアイテムを1つ入れる", + "gtceu.placeholder_info.ender.6": " {ender itemId [player_data_item_slot]} -> エンダーリンクのバッファ内のアイテムのID(例: \"26 minecraft:dirt\")", + "gtceu.placeholder_info.ender.7": " {ender fluid [player_data_item_slot]} -> 液体量", + "gtceu.placeholder_info.ender.8": " {ender redstone [player_data_item_slot] -> レッドストーン信号レベル", + "gtceu.placeholder_info.ender.9": " {ender redstone -> エンダーレッドストーンリンクに出力されるレッドストーン信号を設定し、空の文字列を返す", + "gtceu.placeholder_info.energy.0": "保存されているエネルギー量を返す。", + "gtceu.placeholder_info.energy.1": "使用法:", + "gtceu.placeholder_info.energy.2": " {energy} -> 保存されているエネルギー量", + "gtceu.placeholder_info.energyCapacity.0": "保存できる最大エネルギー量を返す。", + "gtceu.placeholder_info.energyCapacity.1": "使用法:", + "gtceu.placeholder_info.energyCapacity.2": "{energyCapacity} -> エネルギー容量", + "gtceu.placeholder_info.eval.0": "プレースホルダーを含む可能性のある指定された文字列を評価した結果を返す。", + "gtceu.placeholder_info.eval.1": "使用法:", + "gtceu.placeholder_info.eval.2": " {eval abcdefg} -> abcdefg", + "gtceu.placeholder_info.eval.3": " {eval \"repeating a: {repeat 5 \\\"a \\\"}\" -> repeating a: a a a a a ", + "gtceu.placeholder_info.eval.4": " {eval \\\"\"{some random text}\"\\\" -> {some random text}", + "gtceu.placeholder_info.eval.5": " {eval \"text \"\\\"\"{something with spaces}\"\\\"\" more text\" -> text {something with spaces} more text", + "gtceu.placeholder_info.fluidCount.0": "液体の量(フィルター可能)を返す。", + "gtceu.placeholder_info.fluidCount.1": "使用法:", + "gtceu.placeholder_info.fluidCount.2": " {fluidCount [fluidId]} -> すべての液体の量、または指定された場合はfluidIdを持つ液体の量", + "gtceu.placeholder_info.formatInt.0": "提供された整数の文字列表現を返す。", + "gtceu.placeholder_info.formatInt.1": "例: {formatInt 1236457} -> 1.24M", + "gtceu.placeholder_info.formatInt.2": "使用法:", + "gtceu.placeholder_info.formatInt.3": " {formatInt } -> 整数の文字列表現", + "gtceu.placeholder_info.fromAscii.0": "提供されたASCIIコードで表される文字を返す。", + "gtceu.placeholder_info.fromAscii.1": "使用法:", + "gtceu.placeholder_info.fromAscii.2": " {fromAscii } -> 文字", + "gtceu.placeholder_info.if.0": "条件に応じて引数のいずれかを返す。条件は空文字列でなく、0と等しくない場合に真と見なされる。", + "gtceu.placeholder_info.if.1": "使用法:", + "gtceu.placeholder_info.if.2": " {if [returned_if_false]}", + "gtceu.placeholder_info.itemCount.0": "アイテムの量(フィルター可能)を返す。", + "gtceu.placeholder_info.itemCount.1": "使用法:", + "gtceu.placeholder_info.itemCount.2": " {itemCount} -> 合計アイテム数", + "gtceu.placeholder_info.itemCount.3": " {itemCount } -> item_idと等しいIDを持つアイテムの数", + "gtceu.placeholder_info.itemCount.4": " {itemCount filter } -> このカバーの指定されたスロットのフィルターに一致するアイテムの数", + "gtceu.placeholder_info.maintenance.0": "カバーが取り付けられているブロックにメンテナンス上の問題がある場合は1を、それ以外の場合は0を返す。", + "gtceu.placeholder_info.maintenance.1": "例: 'メンテナンス状況: {if {maintenance} 修理が必要 正常}'", + "gtceu.placeholder_info.maintenance.2": "使用法:", + "gtceu.placeholder_info.maintenance.3": " {maintenance} -> メンテナンス上の問題があるかどうか", + "gtceu.placeholder_info.maxProgress.0": "このカバーが取り付けられているブロックで現在実行中のレシピの最大進捗を返す。", + "gtceu.placeholder_info.maxProgress.1": "例: '進捗: {calc {calc {progress} / {maxProgress}} * 100}%'", + "gtceu.placeholder_info.maxProgress.2": "使用法:", + "gtceu.placeholder_info.maxProgress.3": " {maxProgress} -> 現在実行中のレシピの最大進捗", + "gtceu.placeholder_info.nbt.0": "指定されたスロットのアイテムのNBTデータを返す。", + "gtceu.placeholder_info.nbt.1": "使用法:", + "gtceu.placeholder_info.nbt.2": " {nbt [key1] [key2] [key3] ...} -> item_nbt[key1][key2][key3][...]", + "gtceu.placeholder_info.obf.0": "最初の引数のテキストを、難読化して返す。", + "gtceu.placeholder_info.obf.1": "使用法:", + "gtceu.placeholder_info.obf.2": " {obf } -> 難読化されたテキスト", + "gtceu.placeholder_info.previousText.0": "このカバーが指定された行で以前に表示していたテキスト(行折り返し前)を返す。", + "gtceu.placeholder_info.previousText.1": "使用法:", + "gtceu.placeholder_info.previousText.2": " {previousText } -> 指定された行で以前に表示されたテキスト(インデックスは1から)", + "gtceu.placeholder_info.progress.0": "このカバーが取り付けられているブロックで現在実行中のレシピの進捗を返す。", + "gtceu.placeholder_info.progress.1": "進捗は0から{maxProgress}までの整数であることに注意。", + "gtceu.placeholder_info.progress.2": "使用法:", + "gtceu.placeholder_info.progress.3": " {progress} -> 現在実行中のレシピの進捗", + "gtceu.placeholder_info.random.0": "指定された間隔(両端を含む)で乱数を返す。", + "gtceu.placeholder_info.random.1": "使用法:", + "gtceu.placeholder_info.random.2": " {random } -> minとmaxの間(両端を含む)の乱数", + "gtceu.placeholder_info.redstone.0": "レッドストーン信号の強度を返すか、レッドストーン出力強度を設定する。", + "gtceu.placeholder_info.redstone.1": "使用法:", + "gtceu.placeholder_info.redstone.2": " {redstone get } -> 指定された側のレッドストーン信号強度(0-15)", + "gtceu.placeholder_info.redstone.3": " {redstone get link } -> スロット#slot_indexのリンクされたコントローラで指定されたCreateレッドストーンリンク周波数のレッドストーン信号強度。freq_slot_indexはコントローラ内の周波数のインデックス(左から右へ、0-6)", + "gtceu.placeholder_info.redstone.4": " {redstone set } -> 空の文字列、このカバーの側からのレッドストーン出力強度を設定する", + "gtceu.placeholder_info.redstone.5": " {redstone set link } -> 空の文字列、指定されたCreateレッドストーンリンク周波数で指定されたレッドストーンパワーをブロードキャストする", + "gtceu.placeholder_info.repeat.0": "2番目の引数のテキストを、1番目の引数で指定された回数繰り返したものを返す。", + "gtceu.placeholder_info.repeat.1": "使用法:", + "gtceu.placeholder_info.repeat.2": " {repeat } -> 指定された回数繰り返されたテキスト", + "gtceu.placeholder_info.select.0": "指定されたインデックス(0から始まる)の引数を返す。", + "gtceu.placeholder_info.select.1": "使用法:", + "gtceu.placeholder_info.select.2": " {select [arg1] [arg2] [arg3] ... -> 指定されたインデックスの引数", + "gtceu.placeholder_info.strike.0": "最初の引数のテキストを、取り消し線付きで表示して返す。", + "gtceu.placeholder_info.strike.1": "使用法:", + "gtceu.placeholder_info.strike.2": " {strike } -> 取り消し線付きのテキスト", + "gtceu.placeholder_info.subList.0": "インデックスがl(含む)からr(含まない)までの引数を返す(0から始まる)。", + "gtceu.placeholder_info.subList.1": "使用法:", + "gtceu.placeholder_info.subList.2": " {subList [arg0] [arg1] ...} -> lからrまでのインデックスを持つすべての引数をスペースで区切って返す", + "gtceu.placeholder_info.tick.0": "このカバーが設置されてからの経過tick数を返す。", + "gtceu.placeholder_info.tick.1": "使用法:", + "gtceu.placeholder_info.tick.2": " {tick} -> tick数", + "gtceu.placeholder_info.tm.0": "™記号を返す。", + "gtceu.placeholder_info.tm.1": "使用法:", + "gtceu.placeholder_info.tm.2": " {tm} -> ™記号", + "gtceu.placeholder_info.toAscii.0": "指定された文字のASCIIコードを返す。", + "gtceu.placeholder_info.toAscii.1": "使用法:", + "gtceu.placeholder_info.toAscii.2": " {toAscii } -> 文字のASCIIコード", + "gtceu.placeholder_info.toChars.0": "指定された文字列の文字をスペースで区切って返す。", + "gtceu.placeholder_info.toChars.1": "例: {toChars example} -> 'e x a m p l e'", + "gtceu.placeholder_info.toChars.2": "使用法:", + "gtceu.placeholder_info.toChars.3": " {toChars } -> 文字", + "gtceu.placeholder_info.underline.0": "最初の引数のテキストに下線を引いて返す。", + "gtceu.placeholder_info.underline.1": "使用法:", + "gtceu.placeholder_info.underline.2": " {underline } -> 下線付きのテキスト", + "gtceu.placeholder_info.voltage.0": "カバーが取り付けられているワイヤー/ケーブルの電圧を返す。", + "gtceu.placeholder_info.voltage.1": "使用法:", + "gtceu.placeholder_info.voltage.2": " {voltage} -> ワイヤー/ケーブルの電圧", "gtceu.plasma_generator": "プラズマ発生機", "gtceu.polarizer": "磁化装置", "gtceu.primitive_blast_furnace": "初歩的な溶鉱炉", "gtceu.pyrolyse_oven": "熱分解炉", - "gtceu.recipe.amperage": "電流: %s", - "gtceu.recipe.category.arc_furnace_recycling": "プラズマスクラッピング", + "gtceu.recipe.byproduct_tier": "%s§r+ からの副産物", + "gtceu.recipe.category.arc_furnace_recycling": "アーク炉スクラップ処理", "gtceu.recipe.category.chem_dyes": "化学染色", "gtceu.recipe.category.extractor_recycling": "スクラップ再溶解", "gtceu.recipe.category.ingot_molding": "金属成形", @@ -3357,8 +3692,9 @@ "gtceu.recipe.duration": "処理時間: %s 秒", "gtceu.recipe.environmental_hazard": "§cエリアには必ず %s", "gtceu.recipe.environmental_hazard.reverse": "§cこのエリアには、以下のものがないこと %s", - "gtceu.recipe.eu": "消費: %s EU/t", - "gtceu.recipe.eu_inverted": "発電: %s EU/t", + "gtceu.recipe.eu": "使用量: %s A @ %s", + "gtceu.recipe.eu.total": "%s EU/t", + "gtceu.recipe.eu_inverted": "生成量: %s A @ %s", "gtceu.recipe.eu_to_start": "開始EU: %sEU", "gtceu.recipe.explosive": "爆薬: %s", "gtceu.recipe.max_eu": "最大EU: %s EU", @@ -3368,10 +3704,14 @@ "gtceu.recipe.temperature": "温度: %sK", "gtceu.recipe.total": "合計: %s EU", "gtceu.recipe.total_computation": "総計算力: %s CWU", - "gtceu.recipe_logic.condition_fails": "コンディション不良", + "gtceu.recipe.total_eu": "総使用量: %s EU/t", + "gtceu.recipe.voltage": "使用量: %s A @ %s", + "gtceu.recipe_logic.condition_fails": "条件を満たしていない", "gtceu.recipe_logic.insufficient_fuel": "燃料不足", "gtceu.recipe_logic.insufficient_in": "入力不足", "gtceu.recipe_logic.insufficient_out": "出力不足", + "gtceu.recipe_logic.no_capabilities": "機械に機能がありません", + "gtceu.recipe_logic.no_contents": "レシピに内容物がありません", "gtceu.recipe_memory_widget.tooltip.0": "§7左クリックするとこのレシピがクラフトグリッドに自動的に搬入されます。", "gtceu.recipe_memory_widget.tooltip.1": "§7シフトでレシピの固定化を設定", "gtceu.recipe_type.show_recipes": "レシピを表示", @@ -3405,7 +3745,7 @@ "gtceu.subtitle.furnace": "かまどの温まる音", "gtceu.subtitle.jet_engine": "ジェット轟音", "gtceu.subtitle.macerator": "粉砕機の粉砕の音", - "gtceu.subtitle.metal_pipe": "破壊_金属_極_L_波_2_0_0.wav", + "gtceu.subtitle.metal_pipe": "金属パイプの音", "gtceu.subtitle.miner": "鉱夫の掘削", "gtceu.subtitle.mixer": "ミキサーの泡立ち", "gtceu.subtitle.mortar": "モーター破砕", @@ -3463,16 +3803,24 @@ "gtceu.tool_action.wire_cutter.connect": "§8ワイヤーカッターで接続を設定できます。", "gtceu.tool_action.wrench.connect": "§8レンチを使用して接続を設定し、スニークを使用して接続をブロックする。", "gtceu.tool_action.wrench.set_facing": "§8レンチを使うと向きを変更できます。", + "gtceu.tooltip.computer_monitor_config": "コンピュータモニターカバーの設定データを保存中", + "gtceu.tooltip.computer_monitor_data": "保存データ: %s", "gtceu.tooltip.fluid_pipe_hold_shift": "§7SHIFTで耐液体性能を表示", "gtceu.tooltip.hold_ctrl": "§7CTRLを押して詳細を表示", "gtceu.tooltip.hold_shift": "§7SHIFTを押して詳細を表示", + "gtceu.tooltip.player_bind": "バインド先プレイヤー: %s", "gtceu.tooltip.potion.each": " %s %s §7で§r %s §7刻み、§r %s%% §7の確率で起こる。§r", - "gtceu.tooltip.potion.header": "§6エフェクトを含む:", - "gtceu.tooltip.proxy_bind": "§f %s %s %s でパターン・バッファにバインドされます。", + "gtceu.tooltip.potion.header": "§6エフェクトを含む:", + "gtceu.tooltip.proxy_bind": "§f %s %s %s でパターン・バッファにバインドされます。", + "gtceu.tooltip.status.trinary.false": "False", + "gtceu.tooltip.status.trinary.true": "True", + "gtceu.tooltip.status.trinary.unknown": "不明", "gtceu.tooltip.tool_fluid_hold_shift": "§7SHIFTで耐液体性能とツール情報を表示", + "gtceu.tooltip.wireless_transmitter_bind": "%s %s %s にある%s向きの送信機カバーにバインド中 (%s)", "gtceu.top.allow_output_input": "全てのインプット", "gtceu.top.auto_output": "自動アウトプット", "gtceu.top.buffer_bound_pos": "バウンド先 - X: %s, Y: %s, Z: %s", + "gtceu.top.buffer_not_bound": "バッファは現在バインドされていません", "gtceu.top.cable_amperage": "電流: ", "gtceu.top.cable_voltage": "電圧: ", "gtceu.top.convert_eu": "変換 §eEU§r -> §cFE§r", @@ -3480,7 +3828,7 @@ "gtceu.top.energy_consumption": "使用量:", "gtceu.top.energy_production": "発電量:", "gtceu.top.energy_stored": " / %d EU", - "gtceu.top.exhaust_vent_blocked": "ロック中", + "gtceu.top.exhaust_vent_blocked": "ブロック中", "gtceu.top.exhaust_vent_direction": "排気口: %s", "gtceu.top.filter.label": "フィルター:", "gtceu.top.fluid_auto_output": "液体アウトプット: %s", @@ -3520,6 +3868,10 @@ "gtceu.universal.clear_nbt_recipe.tooltip": "§cこれによりすべてのコンテンツが破棄されます!", "gtceu.universal.kiloliters": "%s B", "gtceu.universal.liters": "%s mB", + "gtceu.universal.padded_parentheses": " (%s) ", + "gtceu.universal.padded_spaced_parentheses": " ( %s ) ", + "gtceu.universal.parentheses": "(%s)", + "gtceu.universal.spaced_parentheses": "( %s )", "gtceu.universal.tooltip.amperage_in": "§e入力電流: §f%dA", "gtceu.universal.tooltip.amperage_in_out": "§e入出力電流: §f%dA", "gtceu.universal.tooltip.amperage_in_out_till": "§e最大入出力電流: §f%dA", @@ -3587,12 +3939,13 @@ "item.gtceu.advanced_fluid_voiding_cover.tooltip.1": "配置後、§fソフトマレット§7でアクティ ブにする。", "item.gtceu.advanced_integrated_circuit": "発展型集積回路", "item.gtceu.advanced_integrated_circuit.tooltip.0": "§7より小さく、よりパワフルに", - "item.gtceu.advanced_integrated_circuit.tooltip.1": "§6HV-ティアの回路", + "item.gtceu.advanced_integrated_circuit.tooltip.1": "§6HV時代の回路", "item.gtceu.advanced_item_detector_cover": "発展型アイテム検出器", "item.gtceu.advanced_item_detector_cover.tooltip": "§fRS-ラッチ§7がコントロールする§fアイテムの保管状態§7のレッドストーン信号を§fカバー§7に伝える。", "item.gtceu.advanced_item_voiding_cover": "発展型アイテム消去カバー", "item.gtceu.advanced_item_voiding_cover.tooltip.0": "§7消滅される§fアイテム§7を§fカバー§7で量をコントロールする", "item.gtceu.advanced_item_voiding_cover.tooltip.1": "配置後§fソフトマレット§7でアクティベートする。", + "item.gtceu.advanced_nanomuscle_chestplate": "発展型NanoMuscle™スーツ チェストプレート", "item.gtceu.advanced_power_thruster": "発展型パワースラスター", "item.gtceu.advanced_quarktech_chestplate": "発展型QuarkTech™ スーツ - チェストプレート", "item.gtceu.advanced_smd_capacitor": "発展型SMDキャパシター", @@ -3612,8 +3965,11 @@ "item.gtceu.aluminium_fluid_cell": "%sのアルミニウムセル", "item.gtceu.anvil_casting_mold": "金型 (金床)", "item.gtceu.anvil_casting_mold.tooltip": "§7金床を作る為の金型", + "item.gtceu.armor.boots": "%s ブーツ", + "item.gtceu.armor.chestplate": "%s チェストプレート", + "item.gtceu.armor.helmet": "%s ヘルメット", + "item.gtceu.armor.leggings": "%s レギンス", "item.gtceu.ash_dust": "灰の粉", - "item.gtceu.advanced_nanomuscle_chestplate": "発展型NanoMuscle™ スーツ - チェストプレート", "item.gtceu.axe_extruder_mold.tooltip": "§7斧刃を作る為の押出形成用金型", "item.gtceu.ball_casting_mold": "金型 (Ball)", "item.gtceu.ball_casting_mold.tooltip": "§7ボールを作る為の金型", @@ -3626,7 +3982,7 @@ "item.gtceu.basic_integrated_circuit.tooltip.1": "§cLV時代の回路", "item.gtceu.basic_tape": "テープ", "item.gtceu.basic_tape.tooltip": "§7機械的な問題に対する強度が不十分\nアイテムを落とさずに木箱を入手することができる。", - "item.gtceu.battery.charge_detailed": "%s/%s EU§7 - Tier %s §7(%s/%s %s 放出可能§7)", + "item.gtceu.battery.charge_detailed": "%s/%s EU§7 - Tier %s §7(%s/%s %s remaining§7)", "item.gtceu.battery.charge_time": "§a %s %s 放出可能(%s)", "item.gtceu.battery.charge_unit.hour": "時間", "item.gtceu.battery.charge_unit.minute": "分", @@ -3707,13 +4063,13 @@ "item.gtceu.crystal_processor.tooltip.1": "§9IV時代の回路", "item.gtceu.crystal_processor_assembly": "クリスタル演算処理装置", "item.gtceu.crystal_processor_assembly.tooltip.0": "§7クリスタルの彫刻を活用", - "item.gtceu.crystal_processor_assembly.tooltip.1": "§9LuV時代の回路", + "item.gtceu.crystal_processor_assembly.tooltip.1": "§dLuV時代の回路", "item.gtceu.crystal_processor_computer": "クリスタルスーパーコンピュータ", "item.gtceu.crystal_processor_computer.tooltip.0": "§7クリスタルの彫刻を活用", - "item.gtceu.crystal_processor_computer.tooltip.1": "§9ZPM時代の回路", + "item.gtceu.crystal_processor_computer.tooltip.1": "§cZPM時代の回路", "item.gtceu.crystal_processor_mainframe": "クリスタル処理メインフレーム", "item.gtceu.crystal_processor_mainframe.tooltip.0": "§7クリスタルの彫刻を活用", - "item.gtceu.crystal_processor_mainframe.tooltip.1": "§9UV時代の回路", + "item.gtceu.crystal_processor_mainframe.tooltip.1": "§3UV時代の回路", "item.gtceu.crystal_soc": "クリスタルSoC", "item.gtceu.crystal_soc.tooltip": "§7クリスタルシステムオンチップ", "item.gtceu.cyan_dye_spray_can": "青緑色のスプレー缶", @@ -3723,9 +4079,9 @@ "item.gtceu.dark_ash_dust": "黒色灰の粉", "item.gtceu.data_module": "データモジュール", "item.gtceu.data_orb": "データオーブ", - "item.gtceu.data_orb.tooltip": "§7A 大容量データストレージ", + "item.gtceu.data_orb.tooltip": "§7大容量データストレージ", "item.gtceu.data_stick": "データスティック", - "item.gtceu.data_stick.tooltip": "§7A 小容量データストレージ", + "item.gtceu.data_stick.tooltip": "§7小容量データストレージ", "item.gtceu.diamond_grinding_head": "ダイヤモンド製研削ヘッド", "item.gtceu.diode": "ダイオード", "item.gtceu.diode.tooltip": "§7基本的な電子部品", @@ -3742,6 +4098,8 @@ "item.gtceu.empty_wooden_form": "木枠", "item.gtceu.ender_fluid_link_cover": "液体エンダーリンク", "item.gtceu.ender_fluid_link_cover.tooltip": "§7§f液体§7を§f無線§dエンダー§f空間§7に転送する§fカバー§7。", + "item.gtceu.ender_item_link_cover": "アイテムエンダーリンク", + "item.gtceu.ender_redstone_link_cover": "レッドストーンエンダーリンク", "item.gtceu.energium_dust": "エナジウムの粉", "item.gtceu.energy_cluster": "エネルギークラスター", "item.gtceu.energy_cluster.tooltip": "§7充電式", @@ -3778,7 +4136,7 @@ "item.gtceu.exquisite_glass_gem": "精巧なガラス結晶", "item.gtceu.facade_cover": "%sの外装", "item.gtceu.facade_cover.tooltip.0": "§7ケーブルを装飾する§fカバー§7", - "item.gtceu.facade_cover.tooltip.1": "§7鉄板3枚と任意のブロックを使って作成", + "item.gtceu.facade_cover.tooltip.1": "§7鉄板と任意のブロックでクラフト", "item.gtceu.face_mask": "フェイスマスク", "item.gtceu.fertilizer": "肥料", "item.gtceu.fiber_reinforced_circuit_board": "繊維強化回路基板", @@ -3827,10 +4185,10 @@ "item.gtceu.glauconite_sand_dust": "砂状海緑石", "item.gtceu.good_electronic_circuit": "改良型電子回路", "item.gtceu.good_electronic_circuit.tooltip.0": "§72番目の回路", - "item.gtceu.good_electronic_circuit.tooltip.1": "§cMV時代の回路", + "item.gtceu.good_electronic_circuit.tooltip.1": "§bMV時代の回路", "item.gtceu.good_integrated_circuit": "改良型集積回路", "item.gtceu.good_integrated_circuit.tooltip.0": "§7より小さく、よりパワフルに", - "item.gtceu.good_integrated_circuit.tooltip.1": "§6MV時代の回路", + "item.gtceu.good_integrated_circuit.tooltip.1": "§bMV時代の回路", "item.gtceu.granitic_mineral_sand_dust": "花崗岩質含鉱砂", "item.gtceu.gravi_star": "グラビスター", "item.gtceu.gravi_star.tooltip": "§7究極のネザースター", @@ -3853,6 +4211,7 @@ "item.gtceu.hpic_chip.tooltip": "§7高出力電源IC", "item.gtceu.hpic_wafer": "HPICウェハー", "item.gtceu.hpic_wafer.tooltip": "§7高出力電源回路の原料", + "item.gtceu.huge_pipe_casting_mold": "金型 (極太パイプ)", "item.gtceu.huge_pipe_extruder_mold": "押出形成用金型 (極太パイプ)", "item.gtceu.hv_battery_hull": "大型バッテリー筐体", "item.gtceu.hv_battery_hull.tooltip": "§7空の§6HV用§7バッテリー筐体", @@ -3881,6 +4240,7 @@ "item.gtceu.ilc_chip.tooltip": "§7六人寄れば文殊の知恵", "item.gtceu.ilc_wafer": "ILCウェハー", "item.gtceu.ilc_wafer.tooltip": "§7論理回路の原料", + "item.gtceu.image_module": "画像モジュール", "item.gtceu.impure_bentonite_dust": "汚れたベントナイト", "item.gtceu.impure_cassiterite_sand_dust": "汚れた錫砂", "item.gtceu.impure_pitchblende_dust": "汚れた瀝青ウラン鉱", @@ -3914,7 +4274,7 @@ "item.gtceu.item_voiding_cover.tooltip.0": "§fアイテム§7を消去する§fカバー§7。", "item.gtceu.item_voiding_cover.tooltip.1": "設置後に§fソフトマレット§7で有効化する必要がある。", "item.gtceu.iv_battery_hull": "中型バナジウム製バッテリー筐体", - "item.gtceu.iv_battery_hull.tooltip": "§7空の§1IV用§7バッテリー筐体", + "item.gtceu.iv_battery_hull.tooltip": "§7空の§9IV用§7バッテリー筐体", "item.gtceu.iv_conveyor_module": "IVコンベアーモジュール", "item.gtceu.iv_electric_motor": "IV電動モーター", "item.gtceu.iv_electric_piston": "IV電動ピストン", @@ -3936,6 +4296,7 @@ "item.gtceu.lapotronic_energy_orb.tooltip": "§7充電式", "item.gtceu.lapotronic_energy_orb_cluster": "ラポトロニックエネルギーオーブクラスター", "item.gtceu.lapotronic_energy_orb_cluster.tooltip": "§7充電式", + "item.gtceu.large_pipe_casting_mold": "金型 (太いパイプ)", "item.gtceu.large_pipe_extruder_mold": "押出形成用金型 (太いパイプ)", "item.gtceu.light_blue_dye_spray_can": "空色のスプレー缶", "item.gtceu.light_blue_glass_lens": "空色のガラスレンズ", @@ -3944,7 +4305,6 @@ "item.gtceu.lime_dye_spray_can": "黄緑色のスプレー缶", "item.gtceu.lime_glass_lens": "黄緑色のガラスレンズ", "item.gtceu.liquid_fuel_jetpack": "液体燃料ジェットパック", - "item.gtceu.long_rod_extruder_mold": "押出形成用金型 (長い棒)", "item.gtceu.long_treated_wood_rod": "長い防腐木材の棒", "item.gtceu.long_wood_rod": "長い木の棒", "item.gtceu.lpic_chip": "LPICチップ", @@ -4004,19 +4364,19 @@ "item.gtceu.meat_dust": "ひき肉", "item.gtceu.micro_processor": "マイクロプロセッサー", "item.gtceu.micro_processor.tooltip.0": "§7驚異的な計算速度!", - "item.gtceu.micro_processor.tooltip.1": "§eMV時代の回路", + "item.gtceu.micro_processor.tooltip.1": "§bMV時代の回路", "item.gtceu.micro_processor_assembly": "マイクロ処理演算装置", "item.gtceu.micro_processor_assembly.tooltip.0": "§7驚異的な計算速度!", - "item.gtceu.micro_processor_assembly.tooltip.1": "§eHV時代の回路", + "item.gtceu.micro_processor_assembly.tooltip.1": "§6HV時代の回路", "item.gtceu.micro_processor_computer": "マイクロプロセッサーコンピューター", "item.gtceu.micro_processor_computer.tooltip.0": "§7驚異的な計算速度!", - "item.gtceu.micro_processor_computer.tooltip.1": "§eEV時代の回路", + "item.gtceu.micro_processor_computer.tooltip.1": "§5EV時代の回路", "item.gtceu.micro_processor_mainframe": "マイクロプロセッサーメインフレーム", "item.gtceu.micro_processor_mainframe.tooltip.0": "§7驚異的な計算速度!", - "item.gtceu.micro_processor_mainframe.tooltip.1": "§eIV時代の回路", + "item.gtceu.micro_processor_mainframe.tooltip.1": "§9IV時代の回路", "item.gtceu.microchip_processor": "マイクロチッププロセッサー", - "item.gtceu.microchip_processor.tooltip.0": "§7A より良いLV時代の回路", - "item.gtceu.microchip_processor.tooltip.1": "§eLV時代の回路", + "item.gtceu.microchip_processor.tooltip.0": "§7より良いLV時代の回路", + "item.gtceu.microchip_processor.tooltip.1": "§7LV時代の回路", "item.gtceu.mpic_chip": "MPICチップ", "item.gtceu.mpic_chip.tooltip": "§7電源IC", "item.gtceu.mpic_wafer": "MPICウェハー", @@ -4051,8 +4411,8 @@ "item.gtceu.nan_certificate": "もう初心者ではないという証明", "item.gtceu.nan_certificate.tooltip": "挑戦を受けました!", "item.gtceu.nand_chip": "NANDチップ", - "item.gtceu.nand_chip.tooltip.0": "§7A 優れたシンプルな回路", - "item.gtceu.nand_chip.tooltip.1": "§6ULV時代の回路", + "item.gtceu.nand_chip.tooltip.0": "§7優れたシンプルな回路", + "item.gtceu.nand_chip.tooltip.1": "§8ULV時代の回路", "item.gtceu.nand_memory_chip": "NANDメモリーチップ", "item.gtceu.nand_memory_chip.tooltip": "§7NAND論理ゲート", "item.gtceu.nand_memory_wafer": "NANDメモリーウェハー", @@ -4063,16 +4423,16 @@ "item.gtceu.nano_cpu_wafer.tooltip": "§7ナノ回路の原料", "item.gtceu.nano_processor": "ナノプロセッサー", "item.gtceu.nano_processor.tooltip.0": "§7これまで以上に小型化", - "item.gtceu.nano_processor.tooltip.1": "§bHV時代の回路", + "item.gtceu.nano_processor.tooltip.1": "§6HV時代の回路", "item.gtceu.nano_processor_assembly": "ナノ演算処理装置", "item.gtceu.nano_processor_assembly.tooltip.0": "§7これまで以上に小型化", - "item.gtceu.nano_processor_assembly.tooltip.1": "§bEV時代の回路", + "item.gtceu.nano_processor_assembly.tooltip.1": "§5EV時代の回路", "item.gtceu.nano_processor_computer": "ナノスーパーコンピュータ", "item.gtceu.nano_processor_computer.tooltip.0": "§7これまで以上に小型化", - "item.gtceu.nano_processor_computer.tooltip.1": "§bIV時代の回路", + "item.gtceu.nano_processor_computer.tooltip.1": "§9IV時代の回路", "item.gtceu.nano_processor_mainframe": "ナノプロセッサーメインフレーム", "item.gtceu.nano_processor_mainframe.tooltip.0": "§7これまで以上に小型化", - "item.gtceu.nano_processor_mainframe.tooltip.1": "§bLuV時代の回路", + "item.gtceu.nano_processor_mainframe.tooltip.1": "§dLuV時代の回路", "item.gtceu.nano_saber": "ナノセイバー", "item.gtceu.nano_saber.tooltip": "§7竜神の剣を喰らえ!", "item.gtceu.nanomuscle_boots": "NanoMuscle™ スーツ - ブーツ", @@ -4096,9 +4456,10 @@ "item.gtceu.nor_memory_chip.tooltip": "§7NOR論理ゲート", "item.gtceu.nor_memory_wafer": "NORメモリーウェハー", "item.gtceu.nor_memory_wafer.tooltip": "§7論理ゲートの原料", + "item.gtceu.normal_pipe_casting_mold": "金型 (通常パイプ)", "item.gtceu.normal_pipe_extruder_mold": "押出形成用金型 (通常パイプ)", - "item.gtceu.nugget_casting_mold": "金型 (ナゲット)", - "item.gtceu.nugget_casting_mold.tooltip": "§7ナゲットを作る為の金型", + "item.gtceu.nugget_casting_mold": "金型 (塊)", + "item.gtceu.nugget_casting_mold.tooltip": "§7塊を作る為の金型", "item.gtceu.opv_conveyor_module": "OpVコンベアーモジュール", "item.gtceu.opv_electric_motor": "OpV電動モーター", "item.gtceu.opv_electric_piston": "OpV電動ピストン", @@ -4128,10 +4489,15 @@ "item.gtceu.pill_casting_mold": "金型 (錠剤)", "item.gtceu.pink_dye_spray_can": "桃色のスプレー缶", "item.gtceu.pink_glass_lens": "桃色のガラスレンズ", + "item.gtceu.pipe.huge_casting_mold.tooltip": "§7極太パイプを作るための金型", "item.gtceu.pipe.huge_extruder_mold.tooltip": "§7極太パイプを作る為の押出形成用金型", + "item.gtceu.pipe.large_casting_mold.tooltip": "§7太いパイプを作るための金型", "item.gtceu.pipe.large_extruder_mold.tooltip": "§7太いパイプを作る為の押出形成用金型", + "item.gtceu.pipe.normal_casting_mold.tooltip": "§7パイプを作るための金型", "item.gtceu.pipe.normal_extruder_mold.tooltip": "§7パイプを作る為の押出形成用金型", + "item.gtceu.pipe.small_casting_mold.tooltip": "§7細いパイプを作るための金型", "item.gtceu.pipe.small_extruder_mold.tooltip": "§7細いパイプを作る為の押出形成用金型", + "item.gtceu.pipe.tiny_casting_mold.tooltip": "§7極細パイプを作るための金型", "item.gtceu.pipe.tiny_extruder_mold.tooltip": "§7極細パイプを作る為の押出形成用金型", "item.gtceu.pitchblende_dust": "瀝青ウラン鉱", "item.gtceu.plant_ball": "プラントボール", @@ -4179,16 +4545,16 @@ "item.gtceu.quantum_eye.tooltip": "§7改善したエンダーアイ", "item.gtceu.quantum_processor": "量子処理装置", "item.gtceu.quantum_processor.tooltip.0": "§7量子コンピュータが現実に!", - "item.gtceu.quantum_processor.tooltip.1": "§aEV時代の回路", + "item.gtceu.quantum_processor.tooltip.1": "§5EV時代の回路", "item.gtceu.quantum_processor_assembly": "量子演算処理装置", "item.gtceu.quantum_processor_assembly.tooltip.0": "§7量子コンピュータが現実に", - "item.gtceu.quantum_processor_assembly.tooltip.1": "§aIV時代の回路", + "item.gtceu.quantum_processor_assembly.tooltip.1": "§9IV時代の回路", "item.gtceu.quantum_processor_computer": "量子スーパーコンピュータ", "item.gtceu.quantum_processor_computer.tooltip.0": "§7量子コンピュータが現実に", - "item.gtceu.quantum_processor_computer.tooltip.1": "§aLuV時代の回路", + "item.gtceu.quantum_processor_computer.tooltip.1": "§dLuV時代の回路", "item.gtceu.quantum_processor_mainframe": "量子処理メインフレーム", "item.gtceu.quantum_processor_mainframe.tooltip.0": "§7量子コンピュータが現実に", - "item.gtceu.quantum_processor_mainframe.tooltip.1": "§aZPM時代の回路", + "item.gtceu.quantum_processor_mainframe.tooltip.1": "§cZPM時代の回路", "item.gtceu.quantum_star": "クアンタムスター", "item.gtceu.quantum_star.tooltip": "§7改善したネザースター", "item.gtceu.quarktech_boots": "QuarkTech™ スーツ - ブーツ", @@ -4266,6 +4632,7 @@ "item.gtceu.small_meat_dust": "小さなひき肉", "item.gtceu.small_palladium_raw_dust": "小さな粗パラジウムパウダー", "item.gtceu.small_paper_dust": "小さな紙くず", + "item.gtceu.small_pipe_casting_mold": "金型 (細いパイプ)", "item.gtceu.small_pipe_extruder_mold": "押出形成用金型 (細いパイプ)", "item.gtceu.small_pitchblende_dust": "小さな瀝青ウラン鉱", "item.gtceu.small_platinum_group_sludge_dust": "小さな白金族泥の塊の粉", @@ -4316,6 +4683,7 @@ "item.gtceu.tantalum_capacitor": "タンタル製キャパシター", "item.gtceu.terminal": "ターミナル", "item.gtceu.terminal.tooltip": "コントローラーをシフト+右クリックして、マルチブロックを自動的に構築", + "item.gtceu.text_module": "テキストモジュール", "item.gtceu.tiny_ash_dust": "極小の灰の粉", "item.gtceu.tiny_basaltic_mineral_sand_dust": "極小の玄武岩質含鉱砂", "item.gtceu.tiny_bentonite_dust": "極小のベントナイト", @@ -4334,6 +4702,7 @@ "item.gtceu.tiny_meat_dust": "極小のひき肉", "item.gtceu.tiny_palladium_raw_dust": "極小の粗パラジウムパウダー", "item.gtceu.tiny_paper_dust": "極小の紙くず", + "item.gtceu.tiny_pipe_casting_mold": "金型 (極細パイプ)", "item.gtceu.tiny_pipe_extruder_mold": "押出形成用金型 (極細パイプ)", "item.gtceu.tiny_pitchblende_dust": "極小の瀝青ウラン鉱", "item.gtceu.tiny_platinum_group_sludge_dust": "極小の白金族泥の塊の粉", @@ -4358,9 +4727,15 @@ "item.gtceu.tool.behavior.block_rotation": "§2メカニック: §fブロックを回転", "item.gtceu.tool.behavior.crop_harvesting": "§a収穫家: §f作物を収穫", "item.gtceu.tool.behavior.damage_boost": "§4ダメージブースト: §f%sに対してダメージ増加", + "item.gtceu.tool.behavior.dowse_campfire": "§消防士: §f焚き火を消す", "item.gtceu.tool.behavior.grass_path": "§e造園家: §f草の道を作成", "item.gtceu.tool.behavior.ground_tilling": "§e農家: §f地面を耕す", "item.gtceu.tool.behavior.plunger": "§9排水業者: §f液体を回収", + "item.gtceu.tool.behavior.prospecting.air": "空洞を発見", + "item.gtceu.tool.behavior.prospecting.changing": "物質の変化を検出", + "item.gtceu.tool.behavior.prospecting.lava": "溶岩を発見", + "item.gtceu.tool.behavior.prospecting.ore": "鉱石を発見: %s", + "item.gtceu.tool.behavior.prospecting.water": "水を発見", "item.gtceu.tool.behavior.rail_rotation": "§e鉄道技師: §fレールを回転", "item.gtceu.tool.behavior.relocate_mining": "§2磁力: §f採掘ブロックとモブドロップを直接回収", "item.gtceu.tool.behavior.remove_wax": "§6クリーナー: §fワックス除去", @@ -4403,6 +4778,7 @@ "item.gtceu.tool.lv_drill": "LVの%s製ドリル", "item.gtceu.tool.lv_screwdriver": "LVの%s製スクリュードライバー", "item.gtceu.tool.lv_screwdriver.tooltip": "§8カバーと機械の設定に", + "item.gtceu.tool.lv_wirecutter": "%s ワイヤーカッター (LV)", "item.gtceu.tool.lv_wrench": "LVの%s製レンチ", "item.gtceu.tool.lv_wrench.tooltip": "§8左クリック長押しで機械を撤去", "item.gtceu.tool.mallet": "%s製ソフトマレット", @@ -4432,6 +4808,7 @@ "item.gtceu.tool.tooltip.attack_damage": "§c攻撃力 %s", "item.gtceu.tool.tooltip.attack_speed": "§9攻撃速度 %s", "item.gtceu.tool.tooltip.crafting_uses": "§aあと§l%s§r§a回クラフトに利用できる", + "item.gtceu.tool.tooltip.default_enchantments": "§5デフォルトエンチャント:", "item.gtceu.tool.tooltip.general_uses": "§bあと§l%s§b回使用可能", "item.gtceu.tool.tooltip.harvest_level": "§e採掘レベル %s", "item.gtceu.tool.tooltip.harvest_level_extra": "§e採掘レベル %s §f(%s§f)", @@ -4452,7 +4829,7 @@ "item.gtceu.treated_wood_plate": "防腐木材の板", "item.gtceu.treated_wood_rod": "防腐木材の棒", "item.gtceu.tungsten_grinding_head": "タングステン製研削ヘッド", - "item.gtceu.tungsten_steel_fluid_cell": "%sのタングステンスチール製セル", + "item.gtceu.tungsten_steel_fluid_cell": "%sのタングステンスチールセル", "item.gtceu.turbine_rotor": "%s製タービンローター", "item.gtceu.turbine_rotor.tooltip": "発電施設用のタービンローター", "item.gtceu.uev_conveyor_module": "UEVコンベアーモジュール", @@ -4526,20 +4903,20 @@ "item.gtceu.uxv_voltage_coil.tooltip": "エピックコイル", "item.gtceu.vacuum_tube": "真空管", "item.gtceu.vacuum_tube.tooltip.0": "§7技術的にはダイオード", - "item.gtceu.vacuum_tube.tooltip.1": "§cULV-Tier", + "item.gtceu.vacuum_tube.tooltip.1": "§8ULV時代の回路", "item.gtceu.wetware_circuit_board": "ウェットウェア回路基板", "item.gtceu.wetware_circuit_board.tooltip": "§7生命を維持する基板", "item.gtceu.wetware_printed_circuit_board": "ウェットウェアプリント回路基板", "item.gtceu.wetware_printed_circuit_board.tooltip": "§7生命を維持する基板", "item.gtceu.wetware_processor": "ウェットウェア処理装置", "item.gtceu.wetware_processor.tooltip.0": "§7何かの視線を感じる", - "item.gtceu.wetware_processor.tooltip.1": "§4LuV時代の回路", + "item.gtceu.wetware_processor.tooltip.1": "§dLuV時代の回路", "item.gtceu.wetware_processor_assembly": "ウェットウェア演算装置", "item.gtceu.wetware_processor_assembly.tooltip.0": "§7マインクラフトが動く", - "item.gtceu.wetware_processor_assembly.tooltip.1": "§4ZPM時代の回路", + "item.gtceu.wetware_processor_assembly.tooltip.1": "§cZPM時代の回路", "item.gtceu.wetware_processor_computer": "ウェットウェアスーパーコンピュータ", "item.gtceu.wetware_processor_computer.tooltip.0": "§7肉体と機械の究極の融合", - "item.gtceu.wetware_processor_computer.tooltip.1": "§4UV時代の回路", + "item.gtceu.wetware_processor_computer.tooltip.1": "§3UV時代の回路", "item.gtceu.wetware_processor_mainframe": "ウェットウェアメインフレーム", "item.gtceu.wetware_processor_mainframe.tooltip.0": "§7今まで見た中での最高傑作", "item.gtceu.wetware_processor_mainframe.tooltip.1": "§4UHV時代の回路", @@ -4547,6 +4924,7 @@ "item.gtceu.white_dye_spray_can": "白色のスプレー缶", "item.gtceu.wire_extruder_mold": "押出形成用金型 (ワイヤー)", "item.gtceu.wire_extruder_mold.tooltip": "§7ワイヤーを作る為の押出形成用金型", + "item.gtceu.wireless_transmitter_cover": "ワイヤレス送信機", "item.gtceu.wood_bolt": "木のボルト", "item.gtceu.wood_dust": "木のパルプ", "item.gtceu.wood_plate": "木板", @@ -4554,7 +4932,7 @@ "item.gtceu.yellow_glass_lens": "黄色いガラスレンズ", "item.gtceu.zero_point_module": "ZPM (Zero Point Module) 時代", "item.gtceu.zpm_battery_hull": "中型ナクアドリア製バッテリー筐体", - "item.gtceu.zpm_battery_hull.tooltip": "§7空の§fZPM用§7バッテリー筐体", + "item.gtceu.zpm_battery_hull.tooltip": "§7空の§cZPM用§7バッテリー筐体", "item.gtceu.zpm_conveyor_module": "ZPMコンベアーモジュール", "item.gtceu.zpm_electric_motor": "ZPM電動モーター", "item.gtceu.zpm_electric_piston": "ZPM電動ピストン", @@ -4580,15 +4958,18 @@ "itemGroup.gtceu.material_item": "GregTechCEu金属アイテム", "itemGroup.gtceu.material_pipe": "GregTechCEu金属パイプ", "itemGroup.gtceu.tool": "GregTechCEuツール", + "ldlib.gui.editor.group.widget.gtm_container": "GTM コンテナウィジェット", "ldlib.gui.editor.register.editor.gtceu.mui": "機械UIプロジェクト", "ldlib.gui.editor.register.editor.gtceu.rtui": "レシピタイプUIプロジェクト", "ldlib.gui.editor.register.editor.gtceu.template_tab": "テンプレート", + "ldlib.gui.editor.register.widget.container.gtm_fluid_slot": "GTM 液体スロット", + "ldlib.gui.editor.register.widget.container.gtm_item_slot": "GTM アイテムスロット", + "ldlib.gui.editor.register.widget.container.gtm_phantom_fluid_slot": "GTM ファントム液体スロット", + "ldlib.gui.editor.register.widget.container.gtm_phantom_item_slot": "GTM ファントムアイテムスロット", "mataarmor.hud.supply_mode": "電力供給: %s", "material.gtceu.acetic_acid": "酢酸", "material.gtceu.acetic_anhydride": "無水酢酸", "material.gtceu.acetone": "アセトン", - "material.gtceu.acidic_bromine_exhaust": "酸性臭素排気", - "material.gtceu.acidic_bromine_solution": "酸性臭素溶液", "material.gtceu.acidic_enriched_naquadah_solution": "酸性濃縮ナクアダ溶液", "material.gtceu.acidic_naquadria_solution": "酸性ナクアドリア溶液", "material.gtceu.acidic_osmium_solution": "酸性オスミウム溶液", @@ -4631,6 +5012,9 @@ "material.gtceu.bastnasite": "バストネス石", "material.gtceu.battery_alloy": "バッテリー用合金", "material.gtceu.bauxite": "ボーキサイト", + "material.gtceu.bauxite_slag": "ボーキサイトスラグ", + "material.gtceu.bauxite_sludge": "ボーキサイトスラッジ", + "material.gtceu.bauxite_slurry": "ボーキサイトスラリー", "material.gtceu.bentonite": "ベントナイト", "material.gtceu.benzene": "ベンゼン", "material.gtceu.berkelium": "バークリウム", @@ -4659,7 +5043,6 @@ "material.gtceu.borosilicate_glass": "ホウ素ケイ酸ガラス", "material.gtceu.brass": "真鍮", "material.gtceu.brick": "レンガ", - "material.gtceu.brominated_chlorine_vapor": "臭素化塩素蒸気", "material.gtceu.bromine": "臭素", "material.gtceu.bronze": "ブロンズ", "material.gtceu.brown_dye": "茶色の染料", @@ -4709,12 +5092,12 @@ "material.gtceu.cocoa": "カカオ", "material.gtceu.coke": "コークス", "material.gtceu.collagen": "コラーゲン", - "material.gtceu.concentrated_bromine_solution": "濃縮臭素溶液", "material.gtceu.concrete": "コンクリート", "material.gtceu.construction_foam": "建築用フォーム", "material.gtceu.cooperite": "シェルドナイト", "material.gtceu.copernicium": "コペルニシウム", "material.gtceu.copper": "銅", + "material.gtceu.cracked_bauxite_slurry": "分解ボーキサイトスラリー", "material.gtceu.creosote": "クレオソート油", "material.gtceu.cumene": "クメン", "material.gtceu.cupric_oxide": "酸化銅 (II)", @@ -4726,7 +5109,7 @@ "material.gtceu.damascus_steel": "ダマスカススチール", "material.gtceu.dark_ash": "濃い灰", "material.gtceu.darmstadtium": "ダームスタチウム", - "material.gtceu.debrominated_brine": "脱臭塩水", + "material.gtceu.decalcified_bauxite_sludge": "脱灰ボーキサイトスラッジ", "material.gtceu.deepslate": "ディープスレート", "material.gtceu.depleted_uranium_hexafluoride": "劣化六フッ化ウラン", "material.gtceu.deuterium": "重水素", @@ -4755,7 +5138,7 @@ "material.gtceu.dubnium": "ドブニウム", "material.gtceu.duranium": "デュラニウム", "material.gtceu.dysprosium": "ジスプロシウム", - "material.gtceu.echo_shard": "エコーの欠片", + "material.gtceu.echo_shard": "残響の欠片", "material.gtceu.einsteinium": "アインスタイニウム", "material.gtceu.electrotine": "エレクトロチン", "material.gtceu.electrum": "エレクトラム", @@ -4838,10 +5221,6 @@ "material.gtceu.hematite": "赤鉄鉱", "material.gtceu.high_octane_gasoline": "高オクタン価ガソリン", "material.gtceu.holmium": "ホルミウム", - "material.gtceu.hot_alkaline_debrominated_brine": "高温アルカリ脱臭塩水", - "material.gtceu.hot_brine": "高温塩水", - "material.gtceu.hot_chlorinated_brominated_brine": "高温塩素化臭素化塩水", - "material.gtceu.hot_debrominated_brine": "高温脱臭塩水", "material.gtceu.hsla_steel": "高張力鋼", "material.gtceu.hsse": "HSS-E", "material.gtceu.hssg": "HSS-G", @@ -4857,11 +5236,12 @@ "material.gtceu.hydrofluoric_acid": "フッ化水素酸", "material.gtceu.hydrogen": "水素", "material.gtceu.hydrogen_cyanide": "シアン化水素", - "material.gtceu.hydrogen_iodide": "ヨウ化水素", + "material.gtceu.hydrogen_peroxide": "過酸化水素", "material.gtceu.hydrogen_sulfide": "硫化水素", "material.gtceu.hypochlorous_acid": "次亜塩素酸", "material.gtceu.ice": "氷", "material.gtceu.ilmenite": "チタン鉄鉱", + "material.gtceu.ilmenite_slag": "チタン鉄鉱スラグ", "material.gtceu.impure_enriched_naquadah_solution": "不純な濃縮ナクアダ溶液", "material.gtceu.impure_naquadria_solution": "不純なナクアドリア溶液", "material.gtceu.incoloy_ma_956": "インコロイ合金MA956", @@ -5065,7 +5445,6 @@ "material.gtceu.radon": "ラドン", "material.gtceu.rare_earth": "レアアースの粉", "material.gtceu.rarest_metal_mixture": "希少金属混合物の粉", - "material.gtceu.raw_brine": "生塩水", "material.gtceu.raw_gasoline": "直留ガソリン", "material.gtceu.raw_growth_medium": "粗培養地", "material.gtceu.raw_rubber": "粗ゴム", @@ -5231,7 +5610,7 @@ "material.gtceu.xenon": "キセノン", "material.gtceu.yellow_dye": "黄色の染料", "material.gtceu.yellow_garnet": "イエローガーネット", - "material.gtceu.yellow_limonite": "黄色褐鉄鉱", + "material.gtceu.yellow_limonite": "褐鉄鉱", "material.gtceu.ytterbium": "イッテルビウム", "material.gtceu.yttrium": "イットリウム", "material.gtceu.yttrium_barium_cuprate": "イットリウムバリウムキュプライト", @@ -5241,10 +5620,11 @@ "material.gtceu.zinc_sulfide": "硫化亜鉛", "material.gtceu.zincite": "紅亜鉛鉱", "material.gtceu.zirconium": "ジルコニウム", - "message.gtceu.new_veins": "新しい鉱脈を%d個探査しました!", + "message.gtceu.new_veins.amount": "%d個の新しい鉱床を探査しました!", + "message.gtceu.new_veins.name": "%sを探査しました!", "metaarmor.energy_share.disable": "電力供給: 装備への電力供給を無効化", "metaarmor.energy_share.enable": "電力供給: 装備への電力供給を有効化", - "metaarmor.energy_share.error": "電力供給: §c電力不足!", + "metaarmor.energy_share.error": "電力供給: 電力不足!", "metaarmor.energy_share.tooltip": "供給モード: %s", "metaarmor.energy_share.tooltip.guide": "手に持ちながらShift+右クリックでモードを変更", "metaarmor.hud.energy_lvl": "エネルギー残量: %s", @@ -5252,41 +5632,41 @@ "metaarmor.hud.fuel_lvl": "燃料残量: %s", "metaarmor.hud.gravi_engine": "重力エンジン: %s", "metaarmor.hud.hover_mode": "ホバー: %s", - "metaarmor.hud.status.disabled": "§cOFF", - "metaarmor.hud.status.enabled": "§aON", + "metaarmor.hud.status.disabled": "OFF", + "metaarmor.hud.status.enabled": "ON", "metaarmor.jetpack.emergency_hover_mode": "緊急ホバーモードを有効化!", - "metaarmor.jetpack.flight.disable": "Jetpack: 飛行を無効化", - "metaarmor.jetpack.flight.enable": "Jetpack: 飛行を有効化", - "metaarmor.jetpack.hover.disable": "Jetpack: ホバーモードを無効化", - "metaarmor.jetpack.hover.enable": "Jetpack: ホバーモードを有効化", - "metaarmor.message.nightvision.disabled": "§b暗視: §cOff", - "metaarmor.message.nightvision.enabled": "§b暗視: §aOn", - "metaarmor.message.nightvision.error": "§cパワーが足りない!", - "metaarmor.nms.boosted_jump.disabled": "NanoMuscle™ Suite: ジャンプブースト無効化", - "metaarmor.nms.boosted_jump.enabled": "NanoMuscle™ Suite: ジャンプブースト有効化", - "metaarmor.nms.nightvision.disabled": "NanoMuscle™ Suite: 暗視を無効化", - "metaarmor.nms.nightvision.enabled": "NanoMuscle™ Suite: 暗視を有効化", - "metaarmor.nms.nightvision.error": "NanoMuscle™ Suite: §cエネルギー不足!", - "metaarmor.nms.share.disable": "NanoMuscle™ Suite: 電力供給を無効化", - "metaarmor.nms.share.enable": "NanoMuscle™ Suite: 電力供給を有効化", - "metaarmor.nms.share.error": "NanoMuscle™ Suite: §cエネルギー不足!", - "metaarmor.qts.nightvision.disabled": "QuarkTech™ Suite: 暗視を無効化", - "metaarmor.qts.nightvision.enabled": "QuarkTech™ Suite: 暗視を有効化", - "metaarmor.qts.nightvision.error": "QuarkTech™ Suite: §cエネルギー不足!", - "metaarmor.qts.share.disable": "QuarkTech™ Suite: 電力供給を無効化", - "metaarmor.qts.share.enable": "QuarkTech™ Suite: 電力供給を有効化", - "metaarmor.qts.share.error": "QuarkTech™ Suite: §cエネルギー不足!", + "metaarmor.jetpack.flight.disable": "ジェットパック: 飛行を無効化", + "metaarmor.jetpack.flight.enable": "ジェットパック: 飛行を有効化", + "metaarmor.jetpack.hover.disable": "ジェットパック: ホバーモードを無効化", + "metaarmor.jetpack.hover.enable": "ジェットパック: ホバーモードを有効化", + "metaarmor.message.nightvision.disabled": "暗視: Off", + "metaarmor.message.nightvision.enabled": "暗視: On", + "metaarmor.message.nightvision.error": "エネルギー不足!", + "metaarmor.nms.boosted_jump.disabled": "NanoMuscle™ スーツ: ジャンプブースト無効化", + "metaarmor.nms.boosted_jump.enabled": "NanoMuscle™ スーツ: ジャンプブースト有効化", + "metaarmor.nms.nightvision.disabled": "NanoMuscle™ スーツ: 暗視を無効化", + "metaarmor.nms.nightvision.enabled": "NanoMuscle™ スーツ: 暗視を有効化", + "metaarmor.nms.nightvision.error": "NanoMuscle™ スーツ: エネルギー不足!", + "metaarmor.nms.share.disable": "NanoMuscle™ スーツ: 電力供給を無効化", + "metaarmor.nms.share.enable": "NanoMuscle™ スーツ: 電力供給を有効化", + "metaarmor.nms.share.error": "NanoMuscle™ スーツ: エネルギー不足!", + "metaarmor.qts.nightvision.disabled": "QuarkTech™ スーツ: 暗視を無効化", + "metaarmor.qts.nightvision.enabled": "QuarkTech™ スーツ: 暗視を有効化", + "metaarmor.qts.nightvision.error": "QuarkTech™ スーツ: エネルギー不足!", + "metaarmor.qts.share.disable": "QuarkTech™ スーツ: 電力供給を無効化", + "metaarmor.qts.share.enable": "QuarkTech™ スーツ: 電力供給を有効化", + "metaarmor.qts.share.error": "QuarkTech™ スーツ: エネルギー不足!", "metaarmor.tooltip.autoeat": "インベントリの食料で満腹度回復", "metaarmor.tooltip.breath": "水中呼吸", "metaarmor.tooltip.burning": "炎上無効", "metaarmor.tooltip.falldamage": "落下ダメージ無効", - "metaarmor.tooltip.freezing": "凍結防止", + "metaarmor.tooltip.freezing": "凍結を防止", "metaarmor.tooltip.jump": "ジャンプ力とジャンプ距離が上昇", "metaarmor.tooltip.potions": "デバフ無効", "metaarmor.tooltip.speed": "走る速度が上昇", "metaarmor.tooltip.stepassist": "ステップアシストを提供", "metaitem.behavior.mode_switch.current_mode": "モード: %s", - "metaitem.behavior.mode_switch.mode_switched": "§eモードが設定されました: %s", + "metaitem.behavior.mode_switch.mode_switched": "モード設定: %s", "metaitem.behavior.mode_switch.tooltip": "スニーク中に使うことでモード変更", "metaitem.clipboard.tooltip": "筆記具なしで書くことができます。壁に右クリックして配置、Shiftキーを押しながら右クリックして撤去。", "metaitem.cover.digital.mode.energy.disabled": "クリックでエネルギーモードを有効化", @@ -5299,38 +5679,38 @@ "metaitem.cover.digital.mode.machine.enabled": "マシンモードが有効", "metaitem.cover.digital.mode.proxy.disabled": "クリックでプロキシモードを有効化", "metaitem.cover.digital.mode.proxy.enabled": "プロキシモードが有効", - "metaitem.cover.digital.tooltip": "§fケーブル§7を介して機械と§fセントラルモニター§7を繋げる§fカバー§7。", + "metaitem.cover.digital.tooltip": "ケーブルを介して機械とセントラルモニターを繋げるカバー。", "metaitem.cover.digital.wireless.tooltip.0": "§fセントラルモニター§7に機械を§f無線で§7接続できる§fカバー§7。", - "metaitem.cover.digital.wireless.tooltip.1": "§fセントラルモニター§7を§f右クリック§7することで無線でリンクできます。", - "metaitem.cover.digital.wireless.tooltip.2": "§fシフト右クリック§7でリンクを除去します。", - "metaitem.cover.digital.wireless.tooltip.3": "§aリンク先: §f%s", - "metaitem.crushed.tooltip.purify": "大釜を右クリックすることで洗浄された鉱石を得られる。", + "metaitem.cover.digital.wireless.tooltip.1": "セントラルモニターに機械を無線で接続できるカバー。", + "metaitem.cover.digital.wireless.tooltip.2": "セントラルモニターを右クリックすることで無線でリンクできます。", + "metaitem.cover.digital.wireless.tooltip.3": "シフト右クリックでリンクを除去します。", + "metaitem.crushed.tooltip.purify": "大釜に投げ入れることで洗浄された鉱石を得られる。", "metaitem.debug_scanner.tooltip": "トライコーダー", - "metaitem.dust.tooltip.purify": "大釜を右クリックすることで綺麗な粉を得られる。", - "metaitem.electric.discharge_mode.disabled": "§e放電無効", - "metaitem.electric.discharge_mode.enabled": "§e放電有効", + "metaitem.dust.tooltip.purify": "大釜に投げ入れることで綺麗な粉を得られる。", + "metaitem.electric.discharge_mode.disabled": "放電:無効", + "metaitem.electric.discharge_mode.enabled": "放電:有効", "metaitem.electric.discharge_mode.tooltip": "スニーク中に使うことで放電を切り替えできます。", "metaitem.generic.electric_item.stored": "%d/%d EU (%s)", "metaitem.generic.electric_item.tooltip": "%d/%d EU - Tier %s", - "metaitem.generic.fluid_container.tooltip": "%d/%dL %s", + "metaitem.generic.fluid_container.tooltip": "%3$s %1$,d/%2$,dL", "metaitem.int_circuit.configuration": "設定値: %d", "metaitem.liquid_fuel_jetpack.tooltip": "推力に燃焼発電機の燃料を使用", "metaitem.machine_configuration.mode": "§a設定モード:§r %s", "metaitem.plugin.proxy.tooltips.1": "(スクリーンでプロキシモードに設定してください)", "metaitem.plugin.tooltips.1": "プラグインはスクリーンに挿入することで機能を追加します", "metaitem.prospector.mode.bedrock_ore": "§b岩盤鉱石探査モード§r", - "metaitem.prospector.mode.fluid": "§b液体探知モード§r", - "metaitem.prospector.mode.ores": "§a鉱石探知モード§r", + "metaitem.prospector.mode.fluid": "液体探知モード", + "metaitem.prospector.mode.ores": "鉱石探知モード", "metaitem.prospector.tooltip.modes": "利用可能なモード:", "metaitem.prospector.tooltip.radius": "半径%sチャンクの液体と鉱石をスキャン", - "metaitem.record.sus.tooltip": "§7Leonz - Among Us Drip", + "metaitem.record.sus.tooltip": "Leonz - Among Us Drip", "metaitem.terminal.tooltip": "良い仕事をする賢い道具", - "metaitem.terminal.tooltip.creative": "§bクリエイティブモード", - "metaitem.terminal.tooltip.hardware": "§aハードウェア: %d", - "metaitem.tool.tooltip.durability": "§f耐久値: §a%d/%d", - "metaitem.tool.tooltip.primary_material": "§f素材: §e%s", - "metaitem.tool.tooltip.rotor.efficiency": "タービン効率: §9%d%%", - "metaitem.tool.tooltip.rotor.power": "タービンパワー: §9%d%%", + "metaitem.terminal.tooltip.creative": "クリエイティブモード", + "metaitem.terminal.tooltip.hardware": "ハードウェア: %d", + "metaitem.tool.tooltip.durability": "耐久値: %d/%d", + "metaitem.tool.tooltip.primary_material": "素材: %s", + "metaitem.tool.tooltip.rotor.efficiency": "タービン効率: %d%%", + "metaitem.tool.tooltip.rotor.power": "タービンパワー: %d%%", "metaitem.tricorder_scanner.tooltip": "トライコーダー", "monitor.gui.title.argb": "ARGB:", "monitor.gui.title.back": "戻る", @@ -5343,15 +5723,19 @@ "recipe.capability.fluid.name": "液体", "recipe.capability.item.name": "アイテム", "recipe.condition.adjacent_block.tooltip": "周辺のブロック", + "recipe.condition.adjacent_fluid.tooltip": "周囲の液体ブロック", "recipe.condition.biome.tooltip": "バイオーム: %s", - "recipe.condition.daytime.day.tooltip": "動作するには昼間でないといけません", - "recipe.condition.daytime.night.tooltip": "動作するには夜間でないといけません", + "recipe.condition.daytime.day.tooltip": "動作には昼間が必要", + "recipe.condition.daytime.night.tooltip": "動作には夜間が必要", "recipe.condition.dimension.tooltip": "ディメンション: %s", "recipe.condition.dimension_marker.tooltip": "ディメンション:", "recipe.condition.eu_to_start.tooltip": "開始エネルギー: %d%s", + "recipe.condition.gamestage.locked_stage": "ステージでロック: %s", + "recipe.condition.gamestage.unlocked_stage": "ステージでアンロック: %s", "recipe.condition.pos_y.tooltip": "Y座標レベル: %d <= Y <= %d", + "recipe.condition.quest.completed.tooltip": "%s の完了が必要", + "recipe.condition.quest.not_completed.tooltip": "%s が未完了である必要がある", "recipe.condition.rain.tooltip": "雨レベル: %d", - "recipe.condition.rock_breaker.tooltip": "周囲の液体ブロック", "recipe.condition.steam_vent.tooltip": "蒸気排出口の清掃", "recipe.condition.thunder.tooltip": "雷レベル: %d", "tagprefix.andesite": "%s鉱石 (安山岩)", @@ -5397,7 +5781,8 @@ "tagprefix.long_rod": "長い%sの棒", "tagprefix.marble": "大理石%s鉱石", "tagprefix.netherrack": "ネザー%s鉱石", - "tagprefix.nugget": "%sナゲット", + "tagprefix.nugget": "%s塊", + "tagprefix.null": "%s Null", "tagprefix.pipe_huge_fluid": "極太の%s製液体パイプ", "tagprefix.pipe_huge_item": "極太の%s製アイテムパイプ", "tagprefix.pipe_huge_restrictive": "極太の%s製制限アイテムパイプ", @@ -5427,7 +5812,7 @@ "tagprefix.pure_dust": "ほぼ綺麗な%sの粉", "tagprefix.purified_ore": "洗浄した%s鉱石", "tagprefix.raw": "%sの原石", - "tagprefix.raw_ore_block": "生の%sブロック", + "tagprefix.raw_ore_block": "%sの原石ブロック", "tagprefix.red_granite": "赤色花崗岩%s鉱石", "tagprefix.red_sand": "%sの赤砂鉱石", "tagprefix.refined_ore": "精製%s鉱石", @@ -5446,6 +5831,7 @@ "tagprefix.spring": "%sのバネ", "tagprefix.stairs": "%sの階段", "tagprefix.stone": "%s鉱石", + "tagprefix.surface_rock": "%sの地表の岩", "tagprefix.tiny_dust": "極小の%sの粉", "tagprefix.tuff": "凝灰岩%s鉱石", "tagprefix.turbine_blade": "%s製タービンブレード", @@ -5462,6 +5848,6 @@ "tile.gtceu.foam.name": "フォーム", "tile.gtceu.petrified_foam.name": "石化したフォーム", "tile.gtceu.reinforced_foam.name": "強化フォーム", - "tile.gtceu.reinforced_stone.name": "強化石材", + "tile.gtceu.reinforced_stone.name": "強化石材", "tile.gtceu.seal.name": "密封されたブロック" } diff --git a/src/main/resources/assets/gtceu/lang/ru_ru.json b/src/main/resources/assets/gtceu/lang/ru_ru.json index 2f45089eb52..c1e322573a1 100644 --- a/src/main/resources/assets/gtceu/lang/ru_ru.json +++ b/src/main/resources/assets/gtceu/lang/ru_ru.json @@ -145,7 +145,7 @@ "block.gtceu.ev_macerator": "§5Улучшенный измельчитель III§r", "block.gtceu.ev_machine_casing": "Корпус машины (EV)", "block.gtceu.ev_machine_hull": "Оболочка машины (§5EV§r)", - "block.gtceu.ev_mixer": "§5Улучшенный смеситель III§r", + "block.gtceu.ev_mixer": "§5Улучшенный миксер III§r", "block.gtceu.ev_muffler_hatch": "Люк глушителя (§5EV§r)", "block.gtceu.ev_ore_washer": "§5Улучшенная рудопромывочная машина III§r", "block.gtceu.ev_output_bus": "§5Предметный выходной люк (EV)§r", @@ -245,7 +245,7 @@ "block.gtceu.hv_machine_casing": "Корпус машины (§6HV§r)", "block.gtceu.hv_machine_hull": "Оболочка машины (§6HV§r)", "block.gtceu.hv_miner": "§6Улучшенный шахтер II§r", - "block.gtceu.hv_mixer": "§6Улучшенный смеситель II§r", + "block.gtceu.hv_mixer": "§6Улучшенный миксер II§r", "block.gtceu.hv_muffler_hatch": "Люк глушителя (§6HV§r)", "block.gtceu.hv_ore_washer": "§6Улучшенная рудопромывочная машина II§r", "block.gtceu.hv_output_bus": "§6Предметный выходной люк (HV)§r", @@ -322,7 +322,7 @@ "block.gtceu.iv_macerator": "§9Превосходный измельчитель §r", "block.gtceu.iv_machine_casing": "Корпус машины (§9IV§r)", "block.gtceu.iv_machine_hull": "Оболочка машины (§9IV§r)", - "block.gtceu.iv_mixer": "§9Превосходный смеситель §r", + "block.gtceu.iv_mixer": "§9Превосходный миксер §r", "block.gtceu.iv_muffler_hatch": "Люк глушителя §9(IV)§r", "block.gtceu.iv_ore_washer": "§5Превосходная рудопромывочная машина §r", "block.gtceu.iv_output_bus": "§9Предметный выходной люк (IV)§r", @@ -440,7 +440,7 @@ "block.gtceu.luv_macerator": "§dПревосходный измельчитель II§r", "block.gtceu.luv_machine_casing": "Корпус машины (§dLuV§r)", "block.gtceu.luv_machine_hull": "Оболочка машины (§dLuV§r)", - "block.gtceu.luv_mixer": "§dПревосходный смеситель II§r", + "block.gtceu.luv_mixer": "§dПревосходный миксер II§r", "block.gtceu.luv_muffler_hatch": "Люк глушителя (§dLuV§r)", "block.gtceu.luv_ore_washer": "§dПревосходная рудопромывочная машина II§r", "block.gtceu.luv_output_bus": "§dПредметный выходной люк (LuV)§r", @@ -512,7 +512,7 @@ "block.gtceu.lv_machine_casing": "Корпус машины (§7LV§r)", "block.gtceu.lv_machine_hull": "Оболочка машины (§7LV§r)", "block.gtceu.lv_miner": "Обычный шахтер §r", - "block.gtceu.lv_mixer": "Обычный смеситель §r", + "block.gtceu.lv_mixer": "Обычный миксер §r", "block.gtceu.lv_muffler_hatch": "Люк глушителя (§7LV§r)", "block.gtceu.lv_ore_washer": "Обычная рудопромывочная машина §r", "block.gtceu.lv_output_bus": "§7Предметный выходной люк (LV)§r", @@ -609,7 +609,7 @@ "block.gtceu.mv_machine_casing": "Корпус машины (§bMV§r)", "block.gtceu.mv_machine_hull": "Оболочка машины (§bMV§r)", "block.gtceu.mv_miner": "§bУлучшенный шахтер §r", - "block.gtceu.mv_mixer": "§bУлучшенный смеситель §r", + "block.gtceu.mv_mixer": "§bУлучшенный миксер §r", "block.gtceu.mv_muffler_hatch": "Люк глушителя (§bMV§r)", "block.gtceu.mv_ore_washer": "§bУлучшенная рудопромывочная машина §r", "block.gtceu.mv_output_bus": "§bПредметный выходной люк (MV)§r", @@ -683,7 +683,7 @@ "block.gtceu.opv_macerator": "§9§lСовершенный измельчитель §r", "block.gtceu.opv_machine_casing": "Корпус машины (§9§lOpV§r)", "block.gtceu.opv_machine_hull": "Оболочка машины (§9§lOpV§r)", - "block.gtceu.opv_mixer": "§9§lСовершенный смеситель §r", + "block.gtceu.opv_mixer": "§9§lСовершенный миксер §r", "block.gtceu.opv_muffler_hatch": "Люк глушителя (§9§lOpV§r)", "block.gtceu.opv_ore_washer": "§9§lСовершенная рудопромывочная машина §r", "block.gtceu.opv_output_bus": "Предметный выходной люк (§9§lOpV§r)", @@ -819,7 +819,7 @@ "block.gtceu.uev_macerator": "§aИдеальный измельчитель II§r", "block.gtceu.uev_machine_casing": "Корпус машины (§aUEV§r)", "block.gtceu.uev_machine_hull": "Оболочка машины (§aUEV§r)", - "block.gtceu.uev_mixer": "§aИдеальный смеситель II§r", + "block.gtceu.uev_mixer": "§aИдеальный миксер II§r", "block.gtceu.uev_muffler_hatch": "Люк глушителя (§aUEV§r)", "block.gtceu.uev_ore_washer": "§aИдеальная рудопромывочная машина II§r", "block.gtceu.uev_output_bus": "Предметный выходной люк (§aUEV§r)", @@ -888,7 +888,7 @@ "block.gtceu.uhv_macerator": "§4Идеальный измельчитель §r", "block.gtceu.uhv_machine_casing": "Корпус машины (§4UHV§r)", "block.gtceu.uhv_machine_hull": "Оболочка машины (§4UHV§r)", - "block.gtceu.uhv_mixer": "§4Идеальный смеситель§r", + "block.gtceu.uhv_mixer": "§4Идеальный миксер§r", "block.gtceu.uhv_muffler_hatch": "Люк глушителя (§4UHV§r)", "block.gtceu.uhv_ore_washer": "§4Идеальная рудопромывочная машина§r", "block.gtceu.uhv_output_bus": "§4Предметный выходной люк (UHV)§r", @@ -955,7 +955,7 @@ "block.gtceu.uiv_macerator": "§2Идеальный измельчитель III§r", "block.gtceu.uiv_machine_casing": "Корпус машины (§2UIV§r)", "block.gtceu.uiv_machine_hull": "Оболочка машины (§2UIV§r)", - "block.gtceu.uiv_mixer": "§2Идеальный смеситель III§r", + "block.gtceu.uiv_mixer": "§2Идеальный миксер III§r", "block.gtceu.uiv_muffler_hatch": "Люк глушителя §2UIV§r)", "block.gtceu.uiv_ore_washer": "§2Идеальная рудопромывочная машина III§r", "block.gtceu.uiv_output_bus": "Предметный выходной люк (§2UIV§r)", @@ -1030,7 +1030,7 @@ "block.gtceu.uv_extruder": "§3Безупречный экструдер §r", "block.gtceu.uv_fermenter": "§3Безупречный ферментатор §r", "block.gtceu.uv_fluid_heater": "§3Безупречный жидкостный нагреватель §r", - "block.gtceu.uv_fluid_passthrough_hatch": "§3Жидкостный сквозной люк (UV)§r", + "block.gtceu.uv_fluid_passthrough_hatch": "Жидкостный сквозной люк (§3UV§r)", "block.gtceu.uv_fluid_solidifier": "§3Безупречный жидкостный отвердитель §r", "block.gtceu.uv_forge_hammer": "§3Безупречный кузнечный молот §r", "block.gtceu.uv_forming_press": "§3Безупречный формовочный пресс §r", @@ -1039,14 +1039,14 @@ "block.gtceu.uv_hermetic_casing": "Герметичный корпус VIII", "block.gtceu.uv_input_bus": "§3Предметный входной люк (UV)§r", "block.gtceu.uv_input_hatch": "§3Жидкостный входной люк (UV)§r", - "block.gtceu.uv_item_passthrough_hatch": "§3Предметный сквозной люк (UV)§r", + "block.gtceu.uv_item_passthrough_hatch": "Предметный сквозной люк (§3UV§r)", "block.gtceu.uv_lapotronic_battery": "Лапотронный накопитель (§3UV§r)", "block.gtceu.uv_laser_engraver": "§3Безупречный лазерный гравировщик §r", "block.gtceu.uv_lathe": "§3Безупречный токарный станок §r", "block.gtceu.uv_macerator": "§3Безупречный измельчитель §r", "block.gtceu.uv_machine_casing": "Корпус машины (§3UV§r)", "block.gtceu.uv_machine_hull": "Оболочка машины (§3UV§r)", - "block.gtceu.uv_mixer": "§3Безупречный смеситель §r", + "block.gtceu.uv_mixer": "§3Безупречный миксер §r", "block.gtceu.uv_muffler_hatch": "Люк глушителя (§3UV§r)", "block.gtceu.uv_ore_washer": "§3Безупречная рудопромывочная машина §r", "block.gtceu.uv_output_bus": "§3Предметный выходной люк (UV)§r", @@ -1118,7 +1118,7 @@ "block.gtceu.uxv_macerator": "§eИдеальный измельчитель IV§r", "block.gtceu.uxv_machine_casing": "Корпус машины (§eUXV§r)", "block.gtceu.uxv_machine_hull": "Оболочка машины (§eUXV§r)", - "block.gtceu.uxv_mixer": "§eИдеальный смеситель IV§r", + "block.gtceu.uxv_mixer": "§eИдеальный миксер IV§r", "block.gtceu.uxv_muffler_hatch": "Люк глушителя (§eUXV§r)", "block.gtceu.uxv_ore_washer": "§eИдеальная рудопромывочная машина IV§r", "block.gtceu.uxv_output_bus": "Предметный выходной люк (§eUXV§r)", @@ -1136,7 +1136,7 @@ "block.gtceu.watertight_casing": "Водостойкий корпус", "block.gtceu.wire_coil.tooltip_cracking": "§8Крекинг:", "block.gtceu.wire_coil.tooltip_energy_cracking": " §§aЭнергопотребление: §f%s%%", - "block.gtceu.wire_coil.tooltip_energy_smelter": " §aЭнергопотребление: §f%s EU/t §8на рецепт", + "block.gtceu.wire_coil.tooltip_energy_smelter": " §aЭнергопотребление: §f%s EU/t", "block.gtceu.wire_coil.tooltip_extended_info": "§7Зажмите SHIFT для просмотра Бонуса Катушек", "block.gtceu.wire_coil.tooltip_heat": "§cТеплоемкость: §f%d K", "block.gtceu.wire_coil.tooltip_parallel_smelter": " §5Параллелей: §f%s", @@ -1187,7 +1187,7 @@ "block.gtceu.zpm_extruder": "§cПревосходный экструдер III§r", "block.gtceu.zpm_fermenter": "§cПревосходный ферментатор III§r", "block.gtceu.zpm_fluid_heater": "§cПревосходный жидкостный нагреватель III§r", - "block.gtceu.zpm_fluid_passthrough_hatch": "§cЖидкостный сквозной люк (ZPM)§r", + "block.gtceu.zpm_fluid_passthrough_hatch": "Жидкостный сквозной люк (§cZPM§r)", "block.gtceu.zpm_fluid_solidifier": "§cПревосходный жидкостный отвердитель III§r", "block.gtceu.zpm_forge_hammer": "§cПревосходный кузнечный молот III§r", "block.gtceu.zpm_forming_press": "§cПревосходный формовочный пресс III§r", @@ -1196,14 +1196,14 @@ "block.gtceu.zpm_hermetic_casing": "Герметичный корпус VII", "block.gtceu.zpm_input_bus": "§cПредметный входной люк (ZPM)§r", "block.gtceu.zpm_input_hatch": "§cЖидкостный входной люк (ZPM)§r", - "block.gtceu.zpm_item_passthrough_hatch": "§cПредметный сквозной люк (ZPM)§r", + "block.gtceu.zpm_item_passthrough_hatch": "Предметный сквозной люк (§cZPM§r)", "block.gtceu.zpm_lapotronic_battery": "Лапотронный накопитель (§fZPM§r)", "block.gtceu.zpm_laser_engraver": "§cПревосходный лазерный гравировщик III§r", "block.gtceu.zpm_lathe": "§cПревосходный токарный станок III§r", "block.gtceu.zpm_macerator": "§cПревосходный измельчитель III§r", "block.gtceu.zpm_machine_casing": "Корпус машины (§fZPM§r)", "block.gtceu.zpm_machine_hull": "Оболочка машины (§fZPM§r)", - "block.gtceu.zpm_mixer": "§cПревосходный смеситель III§r", + "block.gtceu.zpm_mixer": "§cПревосходный миксер III§r", "block.gtceu.zpm_muffler_hatch": "Люк глушителя (§cZPM§r)", "block.gtceu.zpm_ore_washer": "§cПревосходная рудопромывочная машина III§r", "block.gtceu.zpm_output_bus": "§cПредметный выходной люк (ZPM)§r", @@ -1330,9 +1330,9 @@ "cover.conveyor.distribution.insert_first.2": "§7Ограниченная предметная труба снижает приоритет пути.", "cover.conveyor.distribution.round_robin_global.0": "Режим распределения: §bКруговой алгоритм", "cover.conveyor.distribution.round_robin_global.1": "§7Равномерно распределяет предметы по подключенным инвентарям", - "cover.conveyor.distribution.round_robin_prio.0": "Режим распределения: §bКруговой алгоритм с приоритетом", - "cover.conveyor.distribution.round_robin_prio.1": "§7Пытается равномерно распределять предметы по подключенным инвентарям и предпочтитает наивысший приоритет.", - "cover.conveyor.distribution.round_robin_prio.2": "§7Ограниченная предметная труба снижает приоритет пути.", + "cover.conveyor.distribution.round_robin_prio.0": "Режим распределения: §bКруговой алгоритм с ограничением", + "cover.conveyor.distribution.round_robin_prio.1": "§7Пытается равномерно распределить предметы по подключенным инвентарям.", + "cover.conveyor.distribution.round_robin_prio.2": "§7Не будет передавать через Ограниченную предметную трубу, если доступны другие пути.", "cover.conveyor.item_filter.title": "Фильтр предметов", "cover.conveyor.mode": "Режим: %s", "cover.conveyor.tag.title.0": "Название по словарю руд", @@ -1706,7 +1706,7 @@ "gtceu.machine.drum.disable_output": "Не сливает жидкость", "gtceu.machine.drum.enable_output": "Сливает жидкость в вертикально соединённые резервуары", "gtceu.machine.electric_blast_furnace.tooltip": "Где электрокоптильня?", - "gtceu.machine.electric_blast_furnace.tooltip.1": "На каждые §f900K§7, превышающих температуру рецепта, ускорение становится эффективным на §f100%%§7 (Идеальный Разгон).", + "gtceu.machine.electric_blast_furnace.tooltip.1": "На каждые §f1800K§7, превышающих температуру рецепта, ускорение становится эффективным на §f100%%§7 (Идеальный Разгон).", "gtceu.machine.electric_blast_furnace.tooltip.2": "На каждые уровень напряжения выше §bMV§7, разгон становится эффективным на §f100K§7.", "gtceu.machine.endpoint.tooltip.0": "Соединяется с блоком §fТрубопровода§7 для создания трубопровода.", "gtceu.machine.endpoint.tooltip.1": "Трубопровод обязан иметь §f1 Входную§7 и §f1 Выходную§7 конечную точку.", @@ -1853,6 +1853,7 @@ "gtceu.maintenance.configurable_time": "Время: %fx", "gtceu.maintenance.configurable_time.changed_description": "Проблемы с обслуживанием будут возникать в %f раз чаще.", "gtceu.maintenance.configurable_time.unchanged_description": "Проблемы с обслуживанием будут возникать с обычной частотой. Измените конфигурацию для обновления.", + "gtceu.mixer": "Миксер", "gtceu.muffler.recovery_tooltip": "§bШанс восстановления предмета: §f%d%%", "gtceu.multiblock.assembly_line.description": "Сборочная линия представляет собой большую многоблочную конструкцию, состоящую из 5-16 «кусочков». Теоретически это большая сборочная машина, используемая для создания продвинутых компонентов для крафта.", "gtceu.multiblock.blast_furnace.max_temperature": "Максимальная температура: %s", @@ -1929,7 +1930,7 @@ "gtceu.multiblock.multiple_recipemaps_recipes.tooltip": "Режим машин: §e%s§r", "gtceu.multiblock.not_enough_energy": "ВНИМАНИЕ: Машине нужно больше энергии.", "gtceu.multiblock.parallel": "Выполняет до %d рецептов одновременно", - "gtceu.multiblock.parallel.exact": "Выполняет %d рецептов одновременно", + "gtceu.multiblock.parallel.exact": "- %dx от Параллелей", "gtceu.multiblock.parallelizable.tooltip": "Можно распараллелить с Люком контроля Парралелей.", "gtceu.multiblock.pattern.clear_amount_1": "§6Спереди должно быть свободное пространство 1x1x1§r", "gtceu.multiblock.pattern.clear_amount_3": "§6Спереди должно быть свободное пространство 3x3x1§r", @@ -2106,7 +2107,7 @@ "gtceu.universal.tooltip.item_storage_total": "§6Вместимость: §f%d предметов", "gtceu.universal.tooltip.item_stored": "§6Вместимость: §f%s, %d предметов", "gtceu.universal.tooltip.item_transfer_rate": "§bСкорость передачи: §f%d предметов/сек", - "gtceu.universal.tooltip.item_transfer_rate_stacks": "§bСкорость передачи: §f%d предметов/сек", + "gtceu.universal.tooltip.item_transfer_rate_stacks": "§bСкорость передачи: §f%d стеков/сек", "gtceu.universal.tooltip.max_voltage_in": "§аМаксимальное потребляемое напряжение: §f%d (%s§f)", "gtceu.universal.tooltip.max_voltage_in_out": "§aМаксимальное напряжение: §f%d EU/t (%s§f)", "gtceu.universal.tooltip.max_voltage_out": "§aМаксимальное выдаваемое напряжение: §f%d (%s§f)", @@ -2260,7 +2261,7 @@ "item.gtceu.foam_sprayer.tooltip.2": "Пена может быть цветной", "item.gtceu.foil_extruder_mold": "Форма экструдера (Фольга)", "item.gtceu.gear_casting_mold": "Отливная форма (Шестерня)", - "item.gtceu.gear_extruder_mold": "Форма экструдера (Щестерня)", + "item.gtceu.gear_extruder_mold": "Форма экструдера (Шестерня)", "item.gtceu.gelled_toluene": "Гелеобразный толуол", "item.gtceu.gelled_toluene.tooltip": "§7Сырое взрывчатое вещество", "item.gtceu.glass_tube": "Стеклянная трубка", @@ -2746,7 +2747,7 @@ "recipe.condition.eu_to_start.tooltip": "Запуск: %d EU", "recipe.condition.pos_y.tooltip": "Высота Y: %d <= Y <= %d", "recipe.condition.rain.tooltip": "Уровень дождя: %d", - "recipe.condition.rock_breaker.tooltip": "Блоки жидкости вокруг", + "recipe.condition.adjacent_fluid.tooltip": "Блоки жидкости вокруг", "recipe.condition.steam_vent.tooltip": "Очистите пароотвод", "recipe.condition.thunder.tooltip": "Уровень грозы: %d", "tagprefix.andesite": "%s (Андезитовая руда)", @@ -2884,7 +2885,7 @@ "gtceu.machine.hp_steam_extractor.tooltip": "§7Извлечение вашей первой резины", "gtceu.machine.hp_steam_furnace.tooltip": "§7Плавка с паром под давлением", "gtceu.machine.hp_steam_liquid_boiler.tooltip": "§7Быстрее, чем маленький жидкостный паровой котел", - "gtceu.machine.hp_steam_macerator.tooltip": "§7Дробит ваши руды", + "gtceu.machine.hp_steam_macerator.tooltip": "§7Дробит ваши руды без побочных продуктов", "gtceu.machine.iv_arc_furnace.tooltip": "§7Нагнетательный нагреватель", "gtceu.machine.iv_autoclave.tooltip": "§7Скороварка", "gtceu.machine.iv_bender.tooltip": "§7Искажатель формы", @@ -2990,7 +2991,7 @@ "gtceu.machine.lp_steam_extractor.tooltip": "§7Извлечение вашей первой резины", "gtceu.machine.lp_steam_forge_hammer.tooltip": "§7Кузнечный молот", "gtceu.machine.lp_steam_furnace.tooltip": "§7Плавка с паром под давлением", - "gtceu.machine.lp_steam_macerator.tooltip": "§7Дробит ваши руды", + "gtceu.machine.lp_steam_macerator.tooltip": "§7Дробит ваши руды без побочных продуктов", "gtceu.machine.lp_steam_rock_crusher.tooltip": "§7Поместите Воду и Лаву горизонтально рядом", "gtceu.machine.lp_steam_solar_boiler.tooltip": "§7Пар от энергии солнца", "gtceu.machine.luv_alloy_smelter.tooltip": "§7Сплавный интегратор", @@ -3877,7 +3878,7 @@ "material.gtceu.xenon": "Ксенон", "material.gtceu.yellow_dye": "Желтый краситель", "material.gtceu.yellow_garnet": "Желтый гранат", - "material.gtceu.yellow_limonite": "Желтый лимонит", + "material.gtceu.yellow_limonite": "Лимонит", "material.gtceu.ytterbium": "Иттербий", "material.gtceu.yttrium": "Иттрий", "material.gtceu.yttrium_barium_cuprate": "Оксид иттрия-бария-меди", @@ -4193,7 +4194,7 @@ "material.gtceu.hydrofluoric_acid": "Плавиковая кислота", "material.gtceu.hydrogen": "Водород", "material.gtceu.hydrogen_sulfide": "Сероводород", - "material.gtceu.hypochlorous_acid": "Соляная кислота", + "material.gtceu.hypochlorous_acid": "Хлорноватистая кислота", "material.gtceu.ice": "Лед", "material.gtceu.ilmenite": "Ильменит", "material.gtceu.impure_naquadria_solution": "Загрязненный раствор наквадрии", @@ -4917,7 +4918,7 @@ "gtceu.subtitle.furnace": "Печь нагревается", "gtceu.subtitle.jet_engine": "Двигатель ревет", "gtceu.subtitle.miner": "Шахтер добывает", - "gtceu.subtitle.mixer": "Смеситель плещет", + "gtceu.subtitle.mixer": "Миксер смешивает", "gtceu.subtitle.mortar": "Ступа измельчает", "gtceu.subtitle.motor": "Мотор шумит", "gtceu.subtitle.plunger": "Вантуз чпокнул", @@ -5145,31 +5146,31 @@ "metaarmor.jetpack.flight.disable": "Джетпак: Полет выкл", "metaarmor.jetpack.flight.enable": "Джетпак: Полет вкл", "config.jade.plugin_gtceu.primitive_pump": "[GTCEu] Примитивная помпа", - "block.gtceu.uiv_dual_input_hatch": "Двойной входной люк (§2UIV§r)", - "block.gtceu.uv_dual_input_hatch": "Двойной входной люк (§3UV§r)", - "block.gtceu.zpm_dual_input_hatch": "Двойной входной люк (§cZPM§r)", - "block.gtceu.uhv_dual_input_hatch": "Двойной входной люк (§4UHV§r)", - "block.gtceu.uxv_dual_input_hatch": "Двойной входной люк (§eUXV§r)", - "gtceu.gui.me_bus.auto_pull_button": "Нажмите для переключения авто. вытягивания предметов из МЕ сети", + "block.gtceu.uiv_dual_input_hatch": "Совмещенный входной люк (§2UIV§r)", + "block.gtceu.uv_dual_input_hatch": "Совмещенный входной люк (§3UV§r)", + "block.gtceu.zpm_dual_input_hatch": "Совмещенный входной люк (§cZPM§r)", + "block.gtceu.uhv_dual_input_hatch": "Совмещенный входной люк (§4UHV§r)", + "block.gtceu.uxv_dual_input_hatch": "Совмещенный входной люк (§eUXV§r)", + "gtceu.gui.me_bus.auto_pull_button": "Нажмите для переключения авто. вытягивания предметов из МЭ сети", "gtceu.gui.waiting_list": "Очередь на отправку:", "gtceu.key.enable_boots": "Включить Прыгучесть", - "block.gtceu.luv_dual_input_hatch": "Двойной входной люк (§dLuV§r)", - "block.gtceu.luv_dual_output_hatch": "Двойной выходной люк (§dLuV§r)", - "block.gtceu.max_dual_input_hatch": "Двойной входной люк (§c§lMAX§r)", - "block.gtceu.max_dual_output_hatch": "Двойной выходной люк (§c§lMAX§r)", + "block.gtceu.luv_dual_input_hatch": "Совмещенный входной люк (§dLuV§r)", + "block.gtceu.luv_dual_output_hatch": "Совмещенный выходной люк (§dLuV§r)", + "block.gtceu.max_dual_input_hatch": "Совмещенный входной люк (§c§lMAX§r)", + "block.gtceu.max_dual_output_hatch": "Совмещенный выходной люк (§c§lMAX§r)", "block.gtceu.me_stocking_input_bus": "ME Накопительный предметный люк", "block.gtceu.me_pattern_buffer": "Буфер ME Шаблонов", - "block.gtceu.me_pattern_buffer_proxy": "Прокси-буфер МЕ Шаблонов", + "block.gtceu.me_pattern_buffer_proxy": "Прокси-буфер МЭ Шаблонов", "block.gtceu.me_stocking_input_hatch": "ME Накопительный жидкостный люк", - "block.gtceu.opv_dual_input_hatch": "Двойной входной люк (§9§lOpV§r)", - "block.gtceu.opv_dual_output_hatch": "Двойной выходной люк (§9§lOpV§r)", - "block.gtceu.uev_dual_input_hatch": "Двойной входной люк (§aUEV§r)", - "block.gtceu.uev_dual_output_hatch": "Двойной выходной люк (§aUEV§r)", - "block.gtceu.uhv_dual_output_hatch": "Двойной выходной люк (§4UHV§r)", - "block.gtceu.uiv_dual_output_hatch": "Двойной выходной люк (§2UIV§r)", - "block.gtceu.uv_dual_output_hatch": "Двойной выходной люк (§3UV§r)", - "block.gtceu.uxv_dual_output_hatch": "Двойной выходной люк (§eUXV§r)", - "block.gtceu.zpm_dual_output_hatch": "Двойной выходной люк (§cZPM§r)", + "block.gtceu.opv_dual_input_hatch": "Совмещенный входной люк (§9§lOpV§r)", + "block.gtceu.opv_dual_output_hatch": "Совмещенный выходной люк (§9§lOpV§r)", + "block.gtceu.uev_dual_input_hatch": "Совмещенный входной люк (§aUEV§r)", + "block.gtceu.uev_dual_output_hatch": "Совмещенный выходной люк (§aUEV§r)", + "block.gtceu.uhv_dual_output_hatch": "Совмещенный выходной люк (§4UHV§r)", + "block.gtceu.uiv_dual_output_hatch": "Совмещенный выходной люк (§2UIV§r)", + "block.gtceu.uv_dual_output_hatch": "Совмещенный выходной люк (§3UV§r)", + "block.gtceu.uxv_dual_output_hatch": "Совмещенный выходной люк (§eUXV§r)", + "block.gtceu.zpm_dual_output_hatch": "Совмещенный выходной люк (§cZPM§r)", "config.jade.plugin_gtceu.me_pattern_buffer": "[GTCEu] Буфер шаблонов", "config.jade.plugin_gtceu.me_pattern_buffer_proxy": "[GTCEu] Прокси буфер шаблонов", "gtceu.gui.config_slot.auto_pull_managed": "§4Отключено:§7 Управляется Авто-вытягиванием", @@ -5185,16 +5186,16 @@ "gtceu.machine.me.stocking_auto_pull_disabled": "Авто-вытягивание выкл", "gtceu.machine.me.stocking_auto_pull_enabled": "Авто-вытягивание вкл", "gtceu.machine.me.stocking_fluid.tooltip.0": "Извлекает жидкости непосредственно из сети ME", - "gtceu.machine.me.stocking_fluid.tooltip.1": "Авто-вытягивание из МЕ сети будет автоматически пополнять первые 16 слотов жидкости в МЕ сети, обновляясь раз в 5 сек.", + "gtceu.machine.me.stocking_fluid.tooltip.1": "Авто-вытягивание из МЭ сети будет автоматически пополнять первые 16 слотов жидкости в МЭ сети, обновляясь раз в 5 сек.", "gtceu.machine.me.stocking_item.tooltip.0": "Извлекает предметы непосредственно из сети ME", - "gtceu.machine.me.stocking_item.tooltip.1": "Авто-вытягивание из МЕ сети будет автоматически пополнять первые 16 предметов в МЕ сети, обновляясь раз в 5 сек.", + "gtceu.machine.me.stocking_item.tooltip.1": "Авто-вытягивание из МЭ сети будет автоматически пополнять первые 16 предметов в МЭ сети, обновляясь раз в 5 сек.", "gtceu.machine.me_import_fluid_hatch.configs.tooltip": "Держит 16 жидкостей в наличии", "gtceu.machine.me_import_item_hatch.configs.tooltip": "Держит 16 предметов в наличии", "block.gtceu.pattern_buffer.desc.0": "§fПозволяет прямое использование §66AE2 хранилища шаблонов§f в Gregtech структурах.", "block.gtceu.pattern_buffer_proxy.desc.2": "§fПусть фабрика растет!", "gtceu.jei.bedrock_ore_diagram": "Схема руды коренной породы", "block.gtceu.pattern_buffer.desc.1": "§6Шаблоны AE2 могут использовать все что хранится в §6общих инвентарях§f.", - "block.gtceu.pattern_buffer.desc.2": "§fСоедини §6Прокси-буфер МЕ Шаблонов§f с помощью §bФлешки§f с другими машинами!", + "block.gtceu.pattern_buffer.desc.2": "§fСоедини §6Прокси-буфер МЭ Шаблонов§f с помощью §bФлешки§f с другими машинами!", "command.gtceu.dump_data.success": "Ресурсы %s скопированы из реестра %s в %s", "command.gtceu.place_vein.failure": "Не удалось разместить жилу %s в позиции %s", "block.gtceu.pattern_buffer_proxy.desc.0": "§fПозволяет соединить множество машин с одним §6Буфером ME Шаблонов§f.", @@ -5253,7 +5254,7 @@ "config.gtceu.option.onlyOwnerGUI": "onlyOwnerGUI", "gtceu.multiblock.progress_percent": "Прогресс: %s%%", "item.gtceu.facade_cover.tooltip.0": "§7Декоративное§f улучшение§7.", - "item.gtceu.facade_cover.tooltip.1": "§7Создается из 3 Железных пластин и любого блока", + "item.gtceu.facade_cover.tooltip.1": "§7Создается из Железной пластины и любого блока", "gtceu.multiblock.research_station.researching": "§6Исследование.", "item.gtceu.programmed_circuit.tooltip.0": "Используйте для открытия интерфейса настроек", "item.gtceu.programmed_circuit.tooltip.2": "c Инт. схемой в руке", @@ -5286,17 +5287,18 @@ "gtceu.gui.content.chance_boosted_logic": "Шанс за уровень: %s%% (%s)", "gtceu.gui.fisher_mode.tooltip.0": "Включить режим Мусора", "gtceu.gui.fisher_mode.tooltip.1": "Ценой двух Ниток за операцию", - "gtceu.machine.boiler.info.cooling.down": "§9Охлаждение§r%s", - "gtceu.machine.boiler.info.heating.up": "§cНагрев§r%s", + "gtceu.machine.boiler.info.cooling.down": "§9Охлаждение§r", + "gtceu.machine.boiler.info.heating.up": "§cНагрев§r", "gtceu.machine.boiler.info.producing.steam": " §a(кипящей воды)", - "recipe_category.gtceu.arc_furnace_recycling": "Утилизация плазмой", - "recipe_category.gtceu.chem_dyes": "Хим. покраска", - "recipe_category.gtceu.extractor_recycling": "Утилизация экстрактором", - "recipe_category.gtceu.ingot_molding": "Отливка металлов", - "recipe_category.gtceu.macerator_recycling": "Утилизация измельчителем", - "recipe_category.gtceu.ore_bathing": "Обработка руды", - "recipe_category.gtceu.ore_crushing": "Измельчение руды", - "recipe_category.gtceu.ore_forging": "Дробление руды", + "gtceu.recipe.category.arc_furnace_recycling": "Дуговая утилизация", + "gtceu.recipe.category.chem_dyes": "Хим. покраска", + "gtceu.recipe.category.extractor_recycling": "Утилизация экстрактором", + "gtceu.recipe.category.ingot_molding": "Отливка металлов", + "gtceu.recipe.category.macerator_recycling": "Утилизация измельчителем", + "gtceu.recipe.category.ore_bathing": "Обработка руды", + "gtceu.recipe.category.ore_crushing": "Измельчение руды", + "gtceu.recipe.category.ore_forging": "Дробление руды", + "item.gtceu.item_smart_filter": "Умный предметный фильтр", "item.gtceu.tool.mallet.tooltip.1": "§8Останавливает/Запускает механизм", "item.gtceu.tool.tooltip.max_uses": "%s §eОбщая прочность", "behaviour.soft_hammer.idle_after_cycle": "Остановить машину после текущего цикла", @@ -5581,5 +5583,320 @@ "gtceu.multiblock.batch_enabled": "Группирование: включено (%sx)", "gtceu.recipe.eu.total": "%s EU/т", "gtceu.recipe.total_eu": "Общее исп.: %s EU/т", - "gtceu.recipe.voltage": "Исп.: %s A @ %s" + "gtceu.recipe.voltage": "Исп.: %s A @ %s", + "command.gtceu.cape.failure.does_not_exist": "Плащ %s не существует", + "block.gtceu.basic_data_access_hatch": "Обычный люк доступа к данным", + "behaviour.soft_hammer.disabled_cycle": "Работа остановится после текущего цикла", + "block.gtceu.central_monitor": "Центральный монитор", + "gtceu.central_monitor.gui.currently_editing": "Редактируется: %s", + "gtceu.central_monitor.gui.remove_from_group": "Удалить из группы", + "gtceu.central_monitor.gui.set_target": "Цель", + "config.gtceu.option.machinesHaveBERsByDefault": "machinesHaveBERsByDefault", + "gtceu.central_monitor.gui.create_group": "Создать группу", + "block.gtceu.monitor": "Монитор", + "config.gtceu.option.maintenanceTime": "maintenanceTime", + "gtceu.central_monitor.info_tooltip.0": "Чтобы использовать мониторы, сначала необходимо разделить их на группы. В каждой группе допустим только один модуль.", + "gtceu.central_monitor.info_tooltip.1": "Выделите нужные элементы ЛКМ и нажмите 'Создать группу'.", + "gtceu.central_monitor.info_tooltip.2": "Затем в настройках группы можно установить модуль и настроить его на той же странице.", + "gtceu.central_monitor.info_tooltip.3": "Чтобы удалить группу, выделите все её компоненты и нажмите 'Удалить из группы'.", + "gtceu.central_monitor.info_tooltip.4": "Для быстрого выделения всех компонентов группы щёлкните по её названию. Повторный щелчок отменит выбор.", + "gtceu.central_monitor.info_tooltip.6": "Если требуется выбрать цель вне мультиблока, используйте Беспроводной передатчик.", + "gtceu.central_monitor.size": "Размер: (%d+1+%d)x(%d+1+%d)", + "gtceu.computer_monitor_cover.error.bf_invalid": "Неверный символ в %d", + "gtceu.computer_monitor_cover.error.bf_invalid_num": "Некорректное число по индексу %d при обработке символа номер %d", + "gtceu.computer_monitor_cover.error.exception": "Произошло неожиданное исключение: %s", + "gtceu.computer_monitor_cover.error.invalid_args": "Неверные аргументы!", + "gtceu.computer_monitor_cover.error.invalid_number": "Неверное число '%s'!", + "gtceu.computer_monitor_cover.error.missing_item": "Нету %s в слоте %d!", + "gtceu.computer_monitor_cover.error.no_cover": "Нет улучшения!", + "gtceu.computer_monitor_cover.error.no_placeholder": "Нет такого заполнителя: '%s'!", + "gtceu.computer_monitor_cover.error.not_enough_args": "Ожидалось не менее %d аргументов, получено %d!", + "gtceu.computer_monitor_cover.error.not_supported": "Эта функция не поддерживается данным блоком/улучшением!", + "gtceu.computer_monitor_cover.error.unclosed_bracket": "Не закрытая скобка!", + "gtceu.computer_monitor_cover.error.unexpected_bracket": "Неожиданная закрывающая скобка!", + "gtceu.computer_monitor_cover.error.wrong_number_of_args": "Ожидалось %d аргументов, получено %d!", + "gtceu.display_source.computer_monitor_cover": "Компьютерный монитор (Улучшение)", + "gtceu.display_target.computer_monitor_cover": "Компьютерный монитор (Улучшение)", + "gtceu.central_monitor.info_tooltip.5": "Некоторые модули могут отображать данные в зависимости от целевого блока. Чтобы задать цель для группы, выделите любой её компонент и кликните ПКМ по целевому блоку.", + "gtceu.computer_monitor_cover.error.not_in_range": "Ожидалось, что %s будет в диапазоне от %d до %d (включительно), но получено %d", + "gtceu.central_monitor.info_tooltip.7": "Установите улучшение на целевой блок, кликните по ней ПКМ с Флешкой и поместите этот чип в Люк доступа к данным мультиблока.", + "gtceu.central_monitor.info_tooltip.8": "Затем выберите Люк доступа к данным как цель и укажите номер слота вашего чипа в появившемся поле.", + "gtceu.computer_monitor_cover.error.no_ae": "Улучшение не имеет AE2 сети!", + "gtceu.gui.adv_stocking_config.min_item_count": "Мин. размер стека пред. для авто. забора", + "gtceu.gui.adv_stocking_config.ticks_per_cycle": "Задержка между обновлением списка предметов", + "gtceu.gui.adv_stocking_config.title": "Настроить авт. пополнение", + "gtceu.gui.central_monitor.group": "Группа: %s", + "gtceu.gui.central_monitor.group_default_name": "Группа #%d", + "gtceu.gui.central_monitor.none": "пусто", + "gtceu.gui.central_monitor.text_scale": "Масштаб текста", + "gtceu.gui.computer_monitor_cover.edit_displayed_text": "Редактировать текст", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.0": "Строка для вывода на строку %d.", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.2": "Запонители также могут быть внутри других заполнителей.", + "gtceu.gui.computer_monitor_cover.placeholder_reference.0": "Все заполнители:", + "gtceu.gui.computer_monitor_cover.placeholder_reference.1": "(наведите для подробностей)", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.0": "Заполнитель для ввода, используемый вместо %s '{}' здесь.", + "gtceu.gui.computer_monitor_cover.slot_tooltip.1": "Слот: %d", + "gtceu.gui.computer_monitor_cover.slot_tooltip.0": "Слот для предметов на который могут ссылаться некоторые заполнители", + "gtceu.gui.computer_monitor_cover.update_interval": "Период обновления (в тиках)", + "gtceu.gui.content.range": "%s-%s", + "gtceu.gui.content.times_item": "x %s", + "gtceu.gui.title.adv_stocking_config.min_fluid_count": "Мик. кол-во жид", + "gtceu.gui.title.adv_stocking_config.min_item_count": "Мик. кол-во пред", + "gtceu.gui.title.adv_stocking_config.ticks_per_cycle": "Тиков в цикле", + "gtceu.jade.amperage_use": "%s A", + "gtceu.jade.at": " @ ", + "gtceu.jade.fluid_use": "%s мВ/т", + "gtceu.machine.boiler.info.production.data": "§aПроизводит %s§a мВ/т", + "gtceu.placeholder_info.active.1": "Используется:", + "gtceu.gui.computer_monitor_cover.edit_blank_placeholders": "Редактировать заглушку", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.1": "Это может содержать заполнители, например: «Энергия: {energy}/{energyCapacity} EU»", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.1": "Например, можно использовать строку 'Энергия: {}/{} EU' и ввести 'energy' и 'energyCapacity' в эти текстовые поля.", + "gtceu.gui.adv_stocking_config.min_fluid_count": "Мин. размер стека жид-ти для авто. забора", + "gtceu.placeholder_info.active.0": "Возвращает 1, если блок, к которому прикреплено улучшение, в данный момент выполняет рецепт, иначе 0.", + "gtceu.placeholder_info.active.2": " {active} -> возвращает информацию существует ли запущенный в данный момент рецепт", + "gtceu.placeholder_info.ae2crafting.1": "Используется:", + "gtceu.placeholder_info.ae2crafting.0": "Возвращает информацию об авто. создании в сети МЭ, в которой находится это улучшение.", + "gtceu.placeholder_info.ae2crafting.4": " {ae2crafting get threads} -> возвращает количество сопроцессоров, имеющихся у указанного процессора", + "gtceu.placeholder_info.ae2crafting.3": " {ae2crafting get storage} -> возвращает объём хранилища создания, имеющиеся у указанного CPU", + "gtceu.placeholder_info.ae2crafting.2": " {ae2crafting get amount} -> возвращает количество процессоров создания в МЭ сети", + "gtceu.placeholder_info.ae2crafting.5": " {ae2crafting get name} -> возвращает Имя указанного процессора", + "gtceu.placeholder_info.ae2crafting.9": " {ae2crafting get progress} -> возвращает прогресс работы или 0, если процессор простаивает", + "gtceu.placeholder_info.ae2crafting.7": " {ae2crafting get amount} -> возвращает количество запрошенных предметов или 0, если процессор простаивает", + "gtceu.placeholder_info.ae2energy.2": " {ae2energy} -> Возвращает количество Энергия в МЭ сети (в единицах AE)", + "gtceu.placeholder_info.ae2fluidCount.0": "Аналогично fluidCount, но производит подсчёт предметов в сети МЭ, к которой подключен блок на котором установлено это улучшение.", + "gtceu.placeholder_info.ae2fluidCount.1": "Обратите внимание, что подсчёт всех жидкостей может привести к лагам!", + "gtceu.placeholder_info.ae2fluidCount.2": "Используется:", + "gtceu.placeholder_info.ae2crafting.8": " {ae2crafting get item} -> возвращает отображаемое имя запрошенного предмета или 0, если процессор простаивает", + "gtceu.placeholder_info.ae2crafting.10": " {ae2crafting get time} -> возвращает время, прошедшее с начала крафта (в наносекундах), или 0, если процессор бездействует", + "gtceu.placeholder_info.ae2crafting.6": " {ae2crafting get selectionMode} -> возвращает режим выбора указанного процессора создания (предназначенный для ручных, автоматических или обоих типов запросов)", + "gtceu.placeholder_info.ae2energy.0": "Возвращает объем энергии запасённый в МЭ сети, в которой находится это улучшение.", + "gtceu.placeholder_info.ae2energy.1": "Используется:", + "config.gtceu.option.arcRecyclingYield": "arcRecyclingYield", + "behavior.data_item.data": "- §a%s", + "config.gtceu.option.enableArcRecycling": "enableArcRecycling", + "config.gtceu.option.maceratorRecyclingYield": "maceratorRecyclingYield", + "config.gtceu.option.enableExtractorRecycling": "enableExtractorRecycling", + "config.gtceu.option.enableMaceratorRecycling": "enableMaceratorRecycling", + "config.gtceu.option.extractorRecyclingYield": "extractorRecyclingYield", + "config.gtceu.option.drum": "drum", + "gtceu.ender_item_link_cover.title": "Предметное Эндер соединение", + "gtceu.ender_redstone_link_cover.label": "Сила редстоуна: %d", + "gtceu.ender_redstone_link_cover.title": "Редстоуновое Эндер соединение", + "gtceu.gui.machinemode.tab_tooltip": "Переключить активный режим машины", + "gtceu.placeholder_info.ae2itemCount.2": "Используется:", + "gtceu.placeholder_info.ae2itemCount.3": " {itemCount} -> возвращает общее количество предметов", + "gtceu.placeholder_info.ae2itemCount.5": " {itemCount фильтр } -> возвращает количество предметов, соответствующих фильтру в указанном слоте этого улучшения", + "gtceu.placeholder_info.ae2maxPower.1": "Используется:", + "gtceu.placeholder_info.ae2maxPower.2": " {ae2maxPower} -> возвращает энергоёмкость МЭ сети", + "gtceu.placeholder_info.ae2powerUsage.0": "Возвращает энергопотребления МЭ сети, в которой находится это улучшение.", + "gtceu.placeholder_info.ae2powerUsage.1": "Используется:", + "config.gtceu.option.quantumTank": "quantumTank", + "gtceu.placeholder_info.ae2itemCount.4": " {itemCount } -> возвращает количество предметов, чьи идентификаторы равны item_id", + "gtceu.placeholder_info.ae2maxPower.0": "Возвращает энергоёмкость МЭ сети, в которой находится это улучшение.", + "config.gtceu.option.tankItemFluidPreview": "tankItemFluidPreview", + "gtceu.placeholder_info.ae2fluidCount.3": " {fluidCount [fluidId]} -> возвращает общее количество всех жидкостей или количество жидкости с указанным fluidId, если оно задано", + "gtceu.placeholder_info.ae2itemCount.0": "Так же, как и itemCount, но подсчитывает предметы в сети МЭ, к которой подключен блок на котором установлено это улучшение.", + "gtceu.placeholder_info.ae2itemCount.1": "Обратите внимание, что подсчёт по фильтру или всех предметов может привести к лагам!", + "behavior.data_item.title": "§nДанные о строительстве %s:", + "cover.machine_controller.suspend_powerfail": "Предотвращение отключения питания:", + "gtceu.placeholder_info.ae2powerUsage.2": " {ae2powerUsage} -> возвращает энергопотребление МЭ сети", + "block.gtceu.bronze_tank_valve": "Клапан бронзового резервуара", + "cover.ender_item_link.title": "Предметное Эндер соединение", + "cover.ender_redstone_link.title": "Редстоуновое Эндер соединение", + "block.gtceu.advanced_monitor": "Улучшенный монитор", + "block.gtceu.bronze_multiblock_tank": "Бронзовый многоблочный резервуар", + "gtceu.placeholder_info.ae2spatial.0": "Возвращает информацию о Пространственном порте ввода\\вывода в сети МЭ, в которой находится это улучшение.", + "gtceu.placeholder_info.ae2spatial.1": "Используется:", + "gtceu.placeholder_info.ae2spatial.2": " {ae2spatial power} -> возвращает количество энергии требуемой для запуска Пространственного порта ввода\\вывода", + "gtceu.placeholder_info.ae2spatial.3": " {ae2spatial efficiency} -> возвращает эффективность Пространственный структуры", + "gtceu.placeholder_info.ae2spatial.4": " {ae2spatial size} -> возвращает размер структуры по указаным осям (например: 'Размер: {sizeX}x{sizeY}x{sizeZ}')", + "gtceu.placeholder_info.amperage.0": "Возвращает значение силы тока в проводе/кабеле, на котором находится это улучшение.", + "gtceu.placeholder_info.amperage.1": "Используется:", + "gtceu.placeholder_info.amperage.2": " {amperage} -> Возвращает значение силы тока в проводе/кабеле", + "gtceu.placeholder_info.bf.0": "Используется:", + "gtceu.placeholder_info.bf.1": " {bf } -> пустая строка", + "gtceu.placeholder_info.block.0": "Возвращает блочный элемент (█).", + "gtceu.placeholder_info.block.1": "Используется:", + "gtceu.placeholder_info.calc.1": "Используется:", + "gtceu.placeholder_info.calc.2": " {calc } -> any_string", + "gtceu.placeholder_info.calc.4": " {calc <+|-|*|/|//|>>|<<|%> } -> возвращает результат указанной операции", + "gtceu.placeholder_info.block.2": " {block} -> '█'", + "gtceu.placeholder_info.calc.0": "Возвращает результат математической функции или операции.", + "gtceu.placeholder_info.calc.3": " {calc } -> возвращает результат указанной операции", + "gtceu.placeholder_info.click.0": "Возвращает значение, указывающее, была ли нажат целевой улучшенный монитор до текущего тика", + "gtceu.placeholder_info.click.1": "Используется:", + "gtceu.placeholder_info.click.2": " {click} -> \"1\" если целевой улучшенный монитор был нажат, в противном случае \"0\"", + "gtceu.placeholder_info.click.3": " {click x} -> возвращает координату X для последнего клика (в диапазоне от 0 до 1)", + "gtceu.placeholder_info.click.4": " {click x} -> возвращает координату Y для последнего клика (в диапазоне от 0 до 1)", + "gtceu.placeholder_info.cmd.0": "Выполняет Minecraft команду и возвращает её вывод.", + "gtceu.placeholder_info.cmd.1": "Требуется предмет данных, привязанный к игроку. Для этого возьмите любой предмет данных в руку и щёлкните ПКМ, чтобы привязать его к себе.", + "gtceu.placeholder_info.combine.1": "Example: {одьединяет абв где жзи} -> \"абв\\ где\\ жзи\"", + "gtceu.placeholder_info.cmd.3": " {cmd <номер_слота> <комманда>} -> вывод команды", + "gtceu.placeholder_info.cmp.0": "Возвращает значение 1 или 0 в зависимости от выражения, содержащегося в его аргументах", + "gtceu.placeholder_info.cmp.1": "Используется:", + "gtceu.placeholder_info.cmp.2": " {cmp <оператор> } -> возвращает 1 или 0, оператором является один из >, <, >=, <=, ==, !=", + "gtceu.placeholder_info.color.1": "Используется:", + "gtceu.placeholder_info.color.2": " {color <цвет> <текст>} -> цветной текст", + "gtceu.placeholder_info.combine.2": "Используется:", + "gtceu.placeholder_info.combine.3": " {combine [арг1] арг2] [арг3] ...} → строку, которая в последующих заполнителях будет обрабатываться как единый аргумент", + "gtceu.placeholder_info.color.0": "Возвращает текст из второго аргумента, раскрашенный в цвет, указанный в первом аргументе. Могут быть использованы все стандартные цвета чата Minecraft.", + "gtceu.placeholder_info.combine.0": "Объединяет все свои аргументы в единую строку (экранируя все пробелы между аргументами)", + "gtceu.placeholder_info.count.0": "Возвращает количество указанных аргументов, которые равны первому (сравниваются как строки, поэтому \"0\" != \"0.0\")", + "gtceu.placeholder_info.count.1": "Используется:", + "gtceu.placeholder_info.count.2": " {count <арг1> [арг2] [арг3] [арг4] ...} -> возвращает количество аргументов, равных первому", + "gtceu.placeholder_info.cmd.2": "Используется:", + "gtceu.placeholder_info.data.0": "Производит запись или считывание данных на устройство хранения данных(Флешка/Сфера данных/Модуль данных) в одном из слотов.", + "gtceu.placeholder_info.data.1": "Если оставить аргумент пустым, он будет заменён на значение p (где p — целое число от 0 до (вместимость - 1), которое хранится в NBT-данных элемента).", + "gtceu.placeholder_info.data.2": "Используется:", + "block.gtceu.creosote": "Креозот", + "config.gtceu.option.maintenanceCheckRate": "maintenanceCheckRate", + "config.gtceu.option.allowDrumsInputFluidsFromOutputSide": "allowDrumsInputFluidsFromOutputSide", + "config.gtceu.option.renderGrowingPlants": "renderGrowingPlants", + "block.gtceu.oil": "Нефть", + "gtceu.placeholder_info.data.3": " {data get <слот> <индекс>} -> возвращает данные, хранящиеся в предмете в указанном слоте", + "gtceu.placeholder_info.data.4": " {data set <слот> <индекс> <значение>} — задаёт данные, хранящиеся в элементе указанного слота, возвращает пустую строку.", + "gtceu.placeholder_info.data.7": " {data inc <слот>} -> увеличивает p на 1, если p становится больше или равно вместимости, устанавливает p равным 0", + "gtceu.placeholder_info.data.5": " {data getp <слот>} -> p", + "gtceu.placeholder_info.data.6": " {data setp <слот> <значение>} -> задаёт р, возвращает пустую строку", + "gtceu.placeholder_info.data.8": " {data dec <слот>} -> уменьшает p на 1, если p становится меньше 0, устанавливает p равным (вместимость - 1)", + "gtceu.placeholder_info.ender.1": "Может взаимодействовать с приватными каналами при наличии элемента данных, привязанного к игроку", + "gtceu.placeholder_info.displayTarget.0": "Возвращает указанную строку, переданную на это улучшение помощью Передатчика информации.", + "gtceu.placeholder_info.displayTarget.1": "Используется:", + "gtceu.placeholder_info.displayTarget.2": " {displayTarget <номер_строки>} -> отобразить текст на указанной строке (номер строки от 1 до 100)", + "gtceu.placeholder_info.ender.0": "Взаимодействует с Улучшениями эндер соединения", + "gtceu.placeholder_info.ender.2": "Используется:", + "gtceu.placeholder_info.ender.10": "Аргумент player_data_item_slot может быть оставлен пустым (не 0, а пустая строка)", + "gtceu.placeholder_info.ender.3": " {ender item <канал> [player_data_item_slot]} -> возвращает количество предметов", + "gtceu.placeholder_info.ender.4": " {ender itemPull <канал> [player_data_item_slot]} -> вытащить 1 предмет из буфера Эндер соединения", + "gtceu.placeholder_info.ender.5": " {ender itemPush <канал> [player_data_item_slot]} -> положить 1 предмет из буфера Эндер соединения", + "gtceu.placeholder_info.ender.6": " {ender itemId <канал> [player_data_item_slot]} -> ID предмета лежащего в буфере Эндер соединения (прм. \"26 minecraft:dirt\")", + "gtceu.placeholder_info.ender.7": " {ender fluid <канал> [player_data_item_slot]} -> возвращает количество жидкости", + "gtceu.placeholder_info.ender.8": " {ender redstone <канал> [player_data_item_slot]} -> возвращает силу редстоун сигнала", + "gtceu.placeholder_info.eval.4": " {eval \\\"\"{ваш текст}\"\\\" -> {ваш текст}", + "gtceu.placeholder_info.eval.5": " {eval \"текст\"\\\"\"{что то с пробелом}\"\\\"\" ещё текст\" -> текст {что то с пробелом} ещё текст", + "gtceu.placeholder_info.ender.9": " {ender redstone <канал> <сигнал> -> устанавливает уровень сигнала редстоуна, выдаваемый на Редстоуновое Эндер соединение, и возвращает пустую строку", + "gtceu.placeholder_info.energy.0": "Возвращает накопленное количество энергии.", + "gtceu.placeholder_info.energy.1": "Используется:", + "gtceu.placeholder_info.energy.2": " {energy} -> возвращает количество накопленной энергии", + "gtceu.placeholder_info.energyCapacity.0": "Возвращает максимальный объём энергии, который может быть накоплен", + "gtceu.placeholder_info.energyCapacity.1": "Используется:", + "gtceu.placeholder_info.energyCapacity.2": "{energyCapacity} -> энергоемкость", + "gtceu.placeholder_info.eval.0": "Возвращает результат вычисления заданной строки, которая может содержать заполнители", + "gtceu.placeholder_info.eval.1": "Используется:", + "gtceu.placeholder_info.eval.2": " {eval абвгде} -> абвгде", + "gtceu.placeholder_info.eval.3": " {eval \"Повторить a: {repeat 5 \\\"a \\\"}\" -> Повторить a: a a a a a ", + "gtceu.placeholder_info.fluidCount.0": "Возвращает количество жидкости (может быть отфильтровано).", + "gtceu.placeholder_info.fluidCount.1": "Используется:", + "config.jade.plugin_gtceu.data_bank": "[GTCEu] Хранилище Данных", + "gtceu.placeholder_info.formatInt.0": "Возвращает строковое представление указанного целого числа", + "gtceu.placeholder_info.formatInt.1": "Например: {formatInt 1236457} -> 1.24М", + "gtceu.placeholder_info.fromAscii.0": "Возвращает символ, представленный предоставленным ASCII-кодом", + "gtceu.placeholder_info.fromAscii.1": "Используется:", + "gtceu.placeholder_info.fromAscii.2": " {fromAscii } -> Возвращает символ", + "gtceu.placeholder_info.if.2": " {if [returned_if_false]}", + "gtceu.placeholder_info.itemCount.0": "Возвращает количество предметов (может быть отфильтровано).", + "gtceu.placeholder_info.itemCount.1": "Используется:", + "gtceu.placeholder_info.itemCount.2": " {itemCount} -> возвращает общее количество предметов", + "gtceu.placeholder_info.formatInt.2": "Используется:", + "gtceu.placeholder_info.formatInt.3": " {formatInt } -> Возвращает строковое представление int", + "gtceu.placeholder_info.if.0": "Возвращает один из аргументов, зависящих от условия. Условие считается истинным, если оно не является пустой строкой и не равно 0.", + "gtceu.placeholder_info.if.1": "Используется:", + "gtceu.placeholder_info.fluidCount.2": " {fluidCount [fluidId]} -> возвращает общее количество всех жидкостей или количество жидкости с указанным fluidId, если оно задано", + "gtceu.placeholder_info.itemCount.3": " {itemCount } -> возвращает количество предметов, чьи идентификаторы равны item_id", + "gtceu.placeholder_info.itemCount.4": " {itemCount фильтр } -> возвращает количество предметов, соответствующих фильтру в указанном слоте этого улучшения", + "gtceu.placeholder_info.maintenance.0": "Возвращает значение 1, если в блоке, к которому прикреплено улучшение, возникли проблемы с обслуживанием, и 0 в противном случае.", + "gtceu.placeholder_info.maintenance.2": "Используется:", + "gtceu.placeholder_info.maintenance.3": " {maintenance} -> возвращает имеются ли проблемы с обслуживанием", + "gtceu.placeholder_info.maxProgress.0": "Возвращает максимальный прогресс текущего выполняемого рецепта для блока, к которому присоединено это улучшение.", + "gtceu.placeholder_info.maxProgress.1": "Например: 'Прогресс: {calc {calc {progress} / {maxProgress}} * 100}%'", + "gtceu.placeholder_info.maxProgress.2": "Используется:", + "gtceu.placeholder_info.maxProgress.3": " {maxProgress} -> возвращает максимальный прогресс выполняемого в данный момента рецепта", + "gtceu.placeholder_info.nbt.0": "Возвращает NBT-данные предмета в указанном слоте", + "gtceu.placeholder_info.nbt.1": "Используется:", + "gtceu.placeholder_info.nbt.2": " {nbt [key1] [key2] [key3] ...} -> item_nbt[key1][key2][key3][...]", + "gtceu.placeholder_info.obf.0": "Возвращает текст первого аргумента в обфусцированном виде.", + "gtceu.placeholder_info.obf.1": "Используется:", + "gtceu.placeholder_info.obf.2": " {obf } -> обфусцированный текст", + "gtceu.placeholder_info.previousText.0": "Возвращает текст, который ранее отображался данным улучшением в указанной строке (до переноса текста).", + "gtceu.placeholder_info.previousText.1": "Используется:", + "gtceu.placeholder_info.previousText.2": " {previousText } -> текст, отображавшийся ранее на указанной строке (индексация начинается с 1)", + "gtceu.placeholder_info.maintenance.1": "Статус обслуживания: '{if {maintenance} ТРЕБУЕТСЯ\\ РЕМОНТ ИСПРАВНО}'", + "gtceu.placeholder_info.progress.0": "Возвращает ход выполнения текущего рецепта, запущенного в блоке, к которому присоединено это улучшение.", + "gtceu.placeholder_info.progress.1": "Учтите, что прогресс является целым числом в диапазоне от 0 до {maxProgress}", + "gtceu.placeholder_info.progress.2": "Используется:", + "gtceu.placeholder_info.progress.3": " {progress} -> возвращает ход выполнения текущего рецепта", + "gtceu.placeholder_info.random.0": "Возвращает случайное число в заданном диапазоне, включая его границы.", + "gtceu.placeholder_info.random.1": "Используется:", + "gtceu.placeholder_info.random.2": " {random } -> возвращает случайное число в диапазоне от min до max включительно", + "gtceu.multiblock.subtick_parallels": "- %dx от Ускорения", + "gtceu.multiblock.total_runs": "Выполняет %d рецептов за раз", + "gtceu.placeholder_info.redstone.0": "Возвращает силу редстоун сигнала или задаёт выходную мощность силу сигнала", + "gtceu.placeholder_info.redstone.1": "Используется:", + "gtceu.placeholder_info.redstone.2": " {redstone get } -> задаёт силу редстоун сигнала (0-15) на указанной стороне", + "gtceu.placeholder_info.redstone.3": " {redstone get link } -> возвращает силу редстоун сигнала для частоты из мода Create, заданной связанным контроллером в слоте #slot_index. Параметр freq_slot_index представляет индекс частоты внутри контроллера (отсчёт ведётся слева направо, от 0 до 6)", + "gtceu.placeholder_info.redstone.4": " {redstone set } -> пустая строка, задаёт силу сигнала редстоуна, исходящего с этой стороны улучшения", + "gtceu.placeholder_info.redstone.5": " {redstone set link } -> возвращает пустую строку и транслирует заданную силу сигнала редстоуна на указанной частоте Редстоунового передатчика из Create", + "gtceu.placeholder_info.repeat.0": "Возвращает текст из вторых аргументов, повторенный столько раз, сколько указано в первом аргументе.", + "gtceu.placeholder_info.repeat.1": "Используется:", + "gtceu.placeholder_info.repeat.2": " {repeat <количество> <текст>} -> текст, повторённый указанное количество раз", + "gtceu.placeholder_info.select.0": "Возвращает аргумент по указанному индексу (отсчёт начинается с 0)", + "gtceu.placeholder_info.select.1": "Используется:", + "config.gtceu.option.createCompat": "createCompat", + "gtceu.placeholder_info.select.2": " {select [arg1] [arg2] [arg3] ... -> аргумент по указанному индексу", + "gtceu.placeholder_info.strike.0": "Возвращает текст из первого текстового блока, отображая его перечёркнутым", + "gtceu.placeholder_info.strike.1": "Используется:", + "gtceu.placeholder_info.strike.2": " {strike <текст>} -> перечёркнутый текст", + "gtceu.placeholder_info.subList.0": "Возвращает аргументы с индексами от l (включительно) до r (исключительно) (начиная с 0)", + "gtceu.placeholder_info.subList.1": "Используется:", + "gtceu.placeholder_info.subList.2": " {subList <слева> <справа> [arg0] [arg1] ...} -> все аргументы с индексами от l до r, разделённые пробелами", + "gtceu.placeholder_info.tick.0": "Возвращает количество тиков, прошедших с момента установки этого улучшения.", + "gtceu.placeholder_info.tick.1": "Используется:", + "gtceu.placeholder_info.tick.2": " {tick} -> возвращает количество тиков", + "gtceu.placeholder_info.tm.0": "Возвращает символ ™", + "gtceu.placeholder_info.tm.1": "Используется:", + "gtceu.placeholder_info.tm.2": " {tm} -> возвращает символ ™", + "gtceu.placeholder_info.toAscii.0": "Возвращает ASCII-код указанного символа", + "gtceu.placeholder_info.toAscii.1": "Используется:", + "gtceu.placeholder_info.toAscii.2": " {toAscii } -> возвращает ASCII-код символа", + "gtceu.placeholder_info.toChars.0": "Возвращает символы указанной строки, разделённые пробелами", + "gtceu.placeholder_info.toChars.1": "Например: {toChars пример} -> 'п р и м е р'", + "gtceu.placeholder_info.toChars.2": "Используется:", + "gtceu.placeholder_info.toChars.3": " {toChars } -> символы", + "gtceu.placeholder_info.underline.0": "Возвращает текст из первого аргумента, подчёркнутым", + "gtceu.placeholder_info.underline.1": "Используется:", + "gtceu.placeholder_info.underline.2": " {underline } -> подчёркнутый текст", + "gtceu.placeholder_info.voltage.0": "Возвращает значение напряжения в проводе/кабеле, на котором установлен данное улучшение.", + "gtceu.placeholder_info.voltage.1": "Используется:", + "gtceu.placeholder_info.voltage.2": " {voltage} -> напряжение в проводе/кабеле", + "gtceu.recipe.byproduct_tier": "Побочные продукты от %s§r+", + "gtceu.tooltip.computer_monitor_config": "Хранение настроек улучшения Компьютерный монитор", + "gtceu.tooltip.computer_monitor_data": "Хранимые данные: %s", + "gtceu.tooltip.player_bind": "Привязано к игроку: %s", + "gtceu.tooltip.wireless_transmitter_bind": "Привязка улучшения Передатчик в %s %s %s на стороне %s в %s", + "gtceu.universal.padded_parentheses": " (%s) ", + "gtceu.universal.padded_spaced_parentheses": " ( %s ) ", + "gtceu.universal.parentheses": "(%s)", + "gtceu.universal.spaced_parentheses": "( %s )", + "item.gtceu.ender_item_link_cover": "Предметное Эндер соединение", + "item.gtceu.ender_redstone_link_cover": "Редстоуновое Эндер соединение", + "item.gtceu.huge_pipe_casting_mold": "Отливная форма (Огромная труба)", + "item.gtceu.image_module": "Модуль изображения", + "item.gtceu.large_pipe_casting_mold": "Отливная форма (Большая труба)", + "item.gtceu.normal_pipe_casting_mold": "Отливная форма (Обычная труба)", + "item.gtceu.pipe.huge_casting_mold.tooltip": "§7Форма для отливки огромных труб", + "item.gtceu.pipe.large_casting_mold.tooltip": "§7Форма для отливки больших труб", + "item.gtceu.pipe.normal_casting_mold.tooltip": "§7Форма для отливки труб", + "item.gtceu.pipe.small_casting_mold.tooltip": "§7Форма для отливки небольших труб", + "item.gtceu.pipe.tiny_casting_mold.tooltip": "§7Форма для отливки очень маленьких труб", + "item.gtceu.small_pipe_casting_mold": "Отливная форма (Малая труба)", + "item.gtceu.text_module": "Текстовый модуль", + "item.gtceu.tiny_pipe_casting_mold": "Отливная форма (Очень малая труба)", + "item.gtceu.tool.behavior.dowse_campfire": "§Пожаротушение: §fГасит костры", + "item.gtceu.tool.behavior.prospecting.air": "Обнаружен воздушный карман", + "item.gtceu.tool.behavior.prospecting.changing": "Обнаружено изменение материала", + "item.gtceu.tool.behavior.prospecting.lava": "Обнаружена лава", + "item.gtceu.tool.behavior.prospecting.ore": "Обнаружена руда: %s", + "item.gtceu.tool.behavior.prospecting.water": "Обнаружена вода", + "item.gtceu.tool.tooltip.default_enchantments": "§5Стандартные чары:", + "item.gtceu.wireless_transmitter_cover": "Беспроводной передатчик" } diff --git a/src/main/resources/assets/gtceu/lang/uk_ua.json b/src/main/resources/assets/gtceu/lang/uk_ua.json index f5b39bd658c..1c4b5b49d2c 100644 --- a/src/main/resources/assets/gtceu/lang/uk_ua.json +++ b/src/main/resources/assets/gtceu/lang/uk_ua.json @@ -1,5572 +1,5854 @@ { - "death.attack.gtceu.medical_condition.arsenicosis": "%s отруївся миш'яком", - "death.attack.gtceu.medical_condition.asbestosis": "%s програв мезотеліомі", - "death.attack.gtceu.medical_condition.berylliosis": "%s надто жадав добувати смарагди", - "death.attack.gtceu.medical_condition.carbon_monoxide_poisoning": "%s залишив плиту увімкненою", - "death.attack.gtceu.medical_condition.carcinogen": "%s не витримав лейкемії", - "death.attack.gtceu.medical_condition.chemical_burns": "%s став учасником хімічної аварії", - "death.attack.gtceu.medical_condition.irritant": "%s отримав§n§l дУЖЕ§r сильний висип", - "death.attack.gtceu.medical_condition.methanol_poisoning": "%s наважився випити самогону в час сухого закону", - "death.attack.gtceu.medical_condition.nausea": "%s помер від нудоти", - "death.attack.gtceu.medical_condition.none": "%s помер від... нічого?", - "death.attack.gtceu.medical_condition.poison": "%s забув, що отруйні матеріали дійсно є отруйними", - "death.attack.gtceu.medical_condition.silicosis": "%s помер не від туберкульозу. Його життя обірвав силікоз.", - "death.attack.gtceu.medical_condition.weak_poison": "%s скуштував свинцю (або меркурію!)", - "death.attack.gtceu.explosion": "%s вибухнув", - "death.attack.gtceu.explosion.player": "%s вибухнув за допомогою %s", - "death.attack.gtceu.frost": "%s пізнав кріогеніку", - "death.attack.gtceu.wrench": "%s забив %s гайковим ключем!", - "death.attack.gtceu.radiation": "%s тепер світиться від рАДості", - "death.attack.gtceu.buzzsaw": "%s був розпилений %s", - "death.attack.gtceu.shovel": "%s був відритий %s", - "death.attack.gtceu.spade": "%s був розкопаний %s", - "death.attack.gtceu.mallet": "%s був забитий насмерть молотом %s", - "death.attack.gtceu.pickaxe": "%s був добутий %s", - "death.attack.gtceu.chemical": "%s став учасником хімічної аварії", - "death.attack.gtceu.wrench_iv": "%s зловив розвідного ключа від %s", - "death.attack.gtceu.hoe": "Голова %s була відсічена %s", - "death.attack.gtceu.screwdriver_lv": "Гвинти %s були відкручені %s", - "death.attack.gtceu.scythe": "%s віддав свою душу %s", - "death.attack.gtceu.axe": "%s був зарублений %s", - "death.attack.gtceu.file": "На тілі %s була викарбувана 'Смерть' за допомогою %s", - "death.attack.gtceu.wire_cutter": "%s перерізав кабель до апарату життєзабезпечення %s", - "death.attack.gtceu.screwdriver": "%s був викручений %s востаннє!", - "death.attack.gtceu.crowbar": "%s напіврозпався через %s", - "death.attack.gtceu.turbine": "%s занурив голову в турбіну", - "death.attack.gtceu.heat": "%s був зварений живцем", - "death.attack.gtceu.heat.player": "%s був зварений живцем через %s", - "death.attack.gtceu.butchery_knife": "%s був зарубаний %s", - "death.attack.gtceu.drill_mv": "%s забурився від 128V %s", - "death.attack.gtceu.drill_ev": "%s забурився від 2048V %s", - "death.attack.gtceu.drill_lv": "%s забурився від 32V %s", - "death.attack.gtceu.drill_hv": "%s забурився від 512V %s", - "death.attack.gtceu.drill_iv": "%s забурився від 8192V %s", - "death.attack.gtceu.electric": "%s вбило струмом", - "death.attack.gtceu.knife": "%s був ніжно проштрикнутий %s", - "death.attack.gtceu.mortar": "%s був стертий у пил %s", - "death.attack.gtceu.chainsaw_lv": "%s був замордований %s", - "death.attack.gtceu.mining_hammer": "%s був переплутаний з рудою %s", - "death.attack.gtceu.hammer": "%s був розчавлений %s", - "death.attack.gtceu.wrench_hv": "Труби %s розхиталися через %s", - "death.attack.gtceu.wrench_lv": "Труби %s розхиталися через %s", - - "tagprefix.planks": "Дошки (%s)", - "tagprefix.door": "Двері (%s)", - "tagprefix.fence": "Паркан (%s)", - "tagprefix.fence_gate": "Хвіртка (%s)", - "tagprefix.block": "Блок (%s)", - "tagprefix.slab": "Плита (%s)", - "tagprefix.stairs": "Сходи (%s)", - "tagprefix.rock": "%s", - "tagprefix.polymer.ingot": "%s (злиток)", - "tagprefix.ingot": "%s (злиток)", - "tagprefix.polymer.nugget": "%s (шматок)", - "tagprefix.nugget": "Самородок (%s)", - "tagprefix.polymer.dust": "%s (целюлоза)", - "tagprefix.dust": "Пил (%s)", - "tagprefix.impure_dust": "%s (неочищений пил)", - "tagprefix.pure_dust": "%s (очищений пил)", - "tagprefix.small_dust": "Дрібний пил (%s)", - "tagprefix.tiny_dust": "Крихта пилу (%s)", - "tagprefix.polymer.small_dust": "%s (дрібна целюлоза)", - "tagprefix.polymer.tiny_dust": "%s (крихта целюлози)", - "tagprefix.plate": "%s (лист)", - "tagprefix.polymer.plate": "%s (пластина)", - "tagprefix.dense_plate": "Міцний лист (%s)", - "tagprefix.polymer.dense_plate": "%s (міцна пластина)", - "tagprefix.double_plate": "Подвійний лист (%s)", - "tagprefix.polymer.double_plate": "%s (подвійна пластина)", - "tagprefix.hot_ingot": "%s (розпечений злиток)", - "tagprefix.raw": "%s (необроблена копалина)", - "tagprefix.stone": "%s (руда)", - "tagprefix.andesite": "%s (андезитова руда)", - "tagprefix.basalt": "%s (базальтова руда)", - "tagprefix.blackstone": "%s (чорнокам'яна руда)", - "tagprefix.raw_ore_block": "%s (блок необробленої руди)", - "tagprefix.crushed_ore": "%s (подрібнена руда)", - "tagprefix.deepslate": "%s (глибосланцева руда)", - "tagprefix.diorite": "%s (діоритова руда)", - "tagprefix.endstone": "%s (руда енду)", - "tagprefix.granite": "%s (гранітова руда)", - "tagprefix.gravel": "%s (гравієва руда)", - "tagprefix.marble": "%s (мармурова руда)", - "tagprefix.netherrack": "%s (незерська руда)", - "tagprefix.purified_ore": "%s (очищена руда)", - "tagprefix.red_granite": "%s (червоногранітна руда)", - "tagprefix.red_sand": "%s (червонопіщана руда)", - "tagprefix.refined_ore": "%s (рафінована руда)", - "tagprefix.sand": "%s (піщана руда)", - "tagprefix.tuff": "%s (туфова руда)", - - "item.gtceu.crushed_bentonite_ore": "Дроблений бентоніт", - "item.gtceu.crushed_cassiterite_sand_ore": "Дроблений каситеритовий пісок", - "item.gtceu.crushed_pitchblende_ore": "Дроблений настуран", - "item.gtceu.crushed_talc_ore_ore": "Дроблений тальк", - "item.gtceu.refined_bentonite_ore": "Рафінований бентоніт", - "item.gtceu.refined_cassiterite_sand_ore": "Рафінований каситеритовий пісок", - "item.gtceu.refined_pitchblende_ore": "Рафінований настуран", - "item.gtceu.refined_talc_ore": "Рафінований тальк", - "item.gtceu.bentonite_dust": "Бентоніт", - "item.gtceu.cassiterite_sand_dust": "Каситеритовий пісок", - "item.gtceu.pitchblende_dust": "Настуран", - "item.gtceu.talc_dust": "Тальк", - "item.gtceu.black_glass_lens": "Скляна лінза (Чорна)", - "item.gtceu.blue_glass_lens": "Скляна лінза (Синя)", - "item.gtceu.brown_glass_lens": "Скляна лінза (Коричнева)", - "item.gtceu.cyan_glass_lens": "Скляна лінза (Бірюзова)", - "item.gtceu.gray_glass_lens": "Скляна лінза (Сіра)", - "item.gtceu.green_glass_lens": "Скляна лінза (Зелена)", - "item.gtceu.light_blue_glass_lens": "Скляна лінза (Блакитна)", - "item.gtceu.light_gray_glass_lens": "Скляна лінза (Світло-сіра)", - "item.gtceu.lime_glass_lens": "Скляна лінза (Лаймова)", - "item.gtceu.magenta_glass_lens": "Скляна лінза (Пурпурова)", - "item.gtceu.orange_glass_lens": "Скляна лінза (Помаранчева)", - "item.gtceu.pink_glass_lens": "Скляна лінза (Рожева)", - "item.gtceu.purple_glass_lens": "Скляна лінза (Фіолетова)", - "item.gtceu.red_glass_lens": "Скляна лінза (Червона)", - "item.glass_lens": "Скляна лінза (Біла)", - "item.gtceu.yellow_glass_lens": "Скляна лінза (Жовта)", - "tagprefix.bolt": "Болт (%s)", - "tagprefix.dye": "Бравник (%s)", - "tagprefix.foil": "Фольга (%s)", - "tagprefix.polymer.foil": "Тонка пластина (%s)", - "tagprefix.frame": "Каркас (%s)", - "tagprefix.gear": "Шестерня (%s)", - "tagprefix.small_gear": "Мала шестерня (%s)", - "tagprefix.lens": "Лінза (%s)", - "tagprefix.log": "Колода (%s)", - "tagprefix.ring": "Кільце (%s)", - "tagprefix.rod": "Стрижень (%s)", - "tagprefix.long_rod": "Довгий стрижень (%s)", - "tagprefix.rotor": "Ротор (%s)", - "tagprefix.round": "Кулька (%s)", - "tagprefix.screw": "Гвинт (%s)", - "tagprefix.spring": "Пружина (%s)", - "tagprefix.small_spring": "Мала пружина (%s)", - "tagprefix.fine_wire": "Тонкий дріт (%s)", - "tagprefix.chainsaw_head": "Голівка ланцюгової пили (%s)", - "tagprefix.drill_head": "Голівка бура (%s)", - "tagprefix.screwdriver_tip": "Наконечник викрутки (%s)", - "tagprefix.wire_cutter_head": "Голівка кусачок (%s)", - "tagprefix.wrench_tip": "Голівка гайкового ключа (%s)", - "tagprefix.buzz_saw_blade": "Лезо електропили (%s)", - "tagprefix.turbine_blade": "Лезо турбіни (%s)", - "item.gtceu.turbine_rotor": "Ротор турбіни (%s)", - "tagprefix.gem": "%s", - "tagprefix.chipped_gem": "Надщерблений кристал (%s)", - "tagprefix.flawed_gem": "Огранований кристал (%s)", - "tagprefix.flawless_gem": "Вишуканий кристал (%s)", - "tagprefix.exquisite_gem": "Бездоганний кристал (%s)", - "item.gtceu.glass_gem": "Скляний кристал", - "item.gtceu.chipped_glass_gem": "Надщерблений скляний кристал", - "item.gtceu.flawed_glass_gem": "Огранований скляний кристал", - "item.gtceu.flawless_glass_gem": "Вишуканий скляний кристал", - "item.gtceu.exquisite_glass_gem": "Бездоганний скляний кристал", - "item.gtceu.bucket": "%s (у відрі)", - "item.gtceu.facade_cover": "Накладний фасад (%s)", - "item.gtceu.facade_cover.tooltip.0": "§7Декоративне§f покриття§7.", - "item.gtceu.facade_cover.tooltip.1": "§7Створюється з 3 залізних листів та будь-якого блоку", - "item.gtceu.aluminium_fluid_cell": "Алюмінієва комірка (%s)", - "item.gtceu.fluid_cell": "Рідинна комірка (%s)", - "item.gtceu.stainless_steel_fluid_cell": "Нержавіюча сталева комірка (%s)", - "item.gtceu.steel_fluid_cell": "Сталева комірка (%s)", - "item.gtceu.titanium_fluid_cell": "Титанова комірка (%s)", - "item.gtceu.tungstensteel_fluid_cell": "Вольфрамова сталева комірка (%s)", - "item.gtceu.universal_fluid_cell": "Універсальна комірка (%s)", - "item.gtceu.glass_vial": "Скляна пробірка (%s)", - - "tagprefix.cable_gt_hex": "16x кабель (%s)", - "tagprefix.wire_gt_hex": "16x дріт (%s)", - "tagprefix.cable_gt_single": "1x кабель (%s)", - "tagprefix.wire_gt_single": "1x дріт (%s)", - "tagprefix.cable_gt_double": "2x кабель (%s)", - "tagprefix.wire_gt_double": "2x дріт (%s)", - "tagprefix.cable_gt_quadruple": "4x кабель (%s)", - "tagprefix.wire_gt_quadruple": "4x дріт (%s)", - "tagprefix.cable_gt_octal": "8x кабель (%s)", - "tagprefix.wire_gt_octal": "8x дріт (%s)", - "tagprefix.pipe_tiny_fluid": "Крихітна рідинна труба (%s)", - "tagprefix.pipe_small_fluid": "Мала рідинна труба (%s)", - "tagprefix.pipe_normal_fluid": "Рідинна труба (%s)", - "tagprefix.pipe_large_fluid": "Велика рідинна труба (%s)", - "tagprefix.pipe_huge_fluid": "Величезна рідинна труба (%s)", - "tagprefix.pipe_quadruple_fluid": "Чотирикамерна рідинна труба (%s)", - "tagprefix.pipe_nonuple_fluid": "Дев'ятикамерна рідинна труба (%s)", - "tagprefix.pipe_small_item": "Мала предметна труба (%s)", - "tagprefix.pipe_small_restrictive": "Мала обмежувальна предметна труба (%s)", - "tagprefix.pipe_normal_item": "Предметна труба (%s)", - "tagprefix.pipe_normal_restrictive": "Обмежувальна предметна труба (%s)", - "tagprefix.pipe_large_item": "Велика предметна труба (%s)", - "tagprefix.pipe_large_restrictive": "Велика обмежувальна предметна труба (%s)", - "tagprefix.pipe_huge_item": "Величезна предметна труба (%s)", - "tagprefix.pipe_huge_restrictive": "Величезна обмежувальна предметна труба (%s)", - - "block.gtceu.surface_rock": "%s (поверхневий поклад)", - "block.gtceu.small_duct_pipe": "Мала вентиляційна труба", - "block.gtceu.normal_duct_pipe": "Вентиляційна труба", - "block.gtceu.large_duct_pipe": "Велика вентиляційна труба", - "block.gtceu.huge_duct_pipe": "Величезна вентиляційна труба", - "block.gtceu.normal_laser_pipe": "Лазерна труба", - "block.gtceu.normal_optical_pipe": "Оптоволоконний кабель", - "block.gtceu.long_distance_fluid_pipeline": "Великодистанційний рідинний трубопровід", - "block.gtceu.long_distance_fluid_pipeline_endpoint": "Пункт призначення великодистанційного рідинного трубопроводу", - "block.gtceu.long_distance_item_pipeline": "Великодистанційний предметний трубопровід", - "block.gtceu.long_distance_item_pipeline_endpoint": "Пункт призначення великодистанційного предметного трубопроводу", - "item.gtceu.tiny_ash_dust": "Крихта пилу попелу", - "item.gtceu.small_ash_dust": "Дрібний пил попелу", - "item.gtceu.tiny_basaltic_mineral_sand_dust": "Крихта пилу базальтового мінерального піску", - "item.gtceu.small_basaltic_mineral_sand_dust": "Дрібний пил базальтового мінерального піску", - "item.gtceu.tiny_bentonite_dust": "Крихта пилу бентоніту", - "item.gtceu.impure_bentonite_dust": "Забруднений пил бентоніту", - "item.gtceu.pure_bentonite_dust": "Очищений пил бентоніту", - "item.gtceu.small_bentonite_dust": "Дрібний пил бентоніту", - "item.gtceu.purified_bentonite_ore": "Очищений бентоніт", - "item.gtceu.tiny_blaze_dust": "Крихта пороху пломеня", - "item.gtceu.small_blaze_dust": "Дрібний порох пломеня", - "item.gtceu.tiny_bone_dust": "Крихта кісткового борошна", - "item.gtceu.small_bone_dust": "Дрібне кісткове борошно", - "item.gtceu.impure_cassiterite_sand_dust": "Забруднений пил каситеритового піску", - "item.gtceu.pure_cassiterite_sand_dust": "Очищений пил каситеритового піску", - "item.gtceu.small_cassiterite_sand_dust": "Дрібний пил каситеритового піску", - "item.gtceu.tiny_cassiterite_sand_dust": "Крихта пилу каситеритового піску", - "item.gtceu.purified_cassiterite_sand_ore": "Очищений каситеритовий пісок", - "item.gtceu.tiny_paper_dust": "Крихітна паперова стружка", - "item.gtceu.small_paper_dust": "Дрібна паперова стружка", - "item.gtceu.tiny_ice_dust": "Крихта подрібненого льоду", - "item.gtceu.small_ice_dust": "Колотий лід", - "item.gtceu.tiny_dark_ash_dust": "Крихта темного попелу", - "item.gtceu.small_dark_ash_dust": "Дрібний темний попіл", - "item.gtceu.tiny_wheat_dust": "Крихта борошна", - "item.gtceu.small_wheat_dust": "Дрібне борошно", - "item.gtceu.tiny_fullers_earth_dust": "Крихта пилу відбілювальних глин", - "item.gtceu.small_fullers_earth_dust": "Дрібний пил відбілювальних глин", - "item.gtceu.tiny_garnet_sand_dust": "Крихта пилу гранатового піску", - "item.gtceu.small_garnet_sand_dust": "Дрібний пил гранатового піску", - "item.gtceu.tiny_glauconite_sand_dust": "Крихта пилу глауконітового піску", - "item.gtceu.small_glauconite_sand_dust": "Дрібний пил глауконітового піску", - "item.gtceu.tiny_granitic_mineral_sand_dust": "Крихта пилу гранітового мінерального піску", - "item.gtceu.small_granitic_mineral_sand_dust": "Дрібний пил гранітового мінерального піску", - "item.gtceu.tiny_gunpowder_dust": "Крихта пороху", - "item.gtceu.small_gunpowder_dust": "Дрібний порох", - "item.gtceu.tiny_inert_metal_mixture_dust": "Крихта пилу суміші інертних металів", - "item.gtceu.small_inert_metal_mixture_dust": "Дрібний пил суміші інертних металів", - "item.gtceu.tiny_iridium_metal_residue_dust": "Крихта пилу металевого залишку іридію", - "item.gtceu.small_iridium_metal_residue_dust": "Дрібний пил металевого залишку іридію", - "item.gtceu.tiny_meat_dust": "Крихта фаршу", - "item.gtceu.small_meat_dust": "Дрібний фарш", - "item.gtceu.tiny_pitchblende_dust": "Крихта пилу настурану", - "item.gtceu.impure_pitchblende_dust": "Забруднений пил настурану", - "item.gtceu.pure_pitchblende_dust": "Очищений пил настурану", - "item.gtceu.small_pitchblende_dust": "Дрібний пил настурану", - "item.gtceu.purified_pitchblende_ore": "Очищений настуран", - "item.gtceu.tiny_platinum_group_sludge_dust": "Крихта пилу шламу платинової групи", - "item.gtceu.small_platinum_group_sludge_dust": "Дрібний пил шламу платинової групи", - "item.gtceu.tiny_platinum_sludge_residue_dust": "Крихта пилу залишку платинового шламу", - "item.gtceu.small_platinum_sludge_residue_dust": "Дрібний пил залишку платинового шламу", - "item.gtceu.tiny_quartz_sand_dust": "Крихта пилу кварцового піску", - "item.gtceu.small_quartz_sand_dust": "Дрібний пил кварцового піску", - "item.gtceu.tiny_rare_earth_dust": "Крихта рідкісноземельного пилу", - "item.gtceu.small_rare_earth_dust": "Дрібний рідкісноземельний пил", - "item.gtceu.tiny_rarest_metal_mixture_dust": "Крихта пилу суміші найрідкісніших металів", - "item.gtceu.small_rarest_metal_mixture_dust": "Дрібний пил суміші найрідкісніших металів", - "item.gtceu.tiny_palladium_raw_dust": "Крихта необробленого паладієвого пилу", - "item.gtceu.small_palladium_raw_dust": "Дрібний необроблений паладієвий пил", - "item.gtceu.tiny_platinum_raw_dust": "Крихта необробленого платинового пилу", - "item.gtceu.small_platinum_raw_dust": "Дрібний необроблений платиновий пил", - "item.gtceu.tiny_rock_salt_dust": "Крихта пилу кам'яної солі", - "item.gtceu.impure_rock_salt_dust": "Забруднений пил кам'яної солі", - "item.gtceu.pure_rock_salt_dust": "Очищений пил кам'яної солі", - "item.gtceu.small_rock_salt_dust": "Дрібний пил кам'яної солі", - "item.gtceu.tiny_salt_dust": "Крихта солі", - "item.gtceu.impure_salt_dust": "Забруднена сіль", - "item.gtceu.pure_salt_dust": "Очищена сіль", - "item.gtceu.small_salt_dust": "Дрібна сіль", - "item.gtceu.tiny_sugar_dust": "Крихта цукру", - "item.gtceu.small_sugar_dust": "Дрібний цукор", - "item.gtceu.tiny_talc_dust": "Крихта пилу тальку", - "item.gtceu.impure_talc_dust": "Забруднений пил тальку", - "item.gtceu.pure_talc_dust": "Очищений пил тальку", - "item.gtceu.small_talc_dust": "Дрібний пил тальку", - "item.gtceu.purified_talc_ore": "Очищений тальк", - "item.gtceu.tiny_treated_wood_dust": "Крихта обробленої деревної целюлози", - "item.gtceu.small_treated_wood_dust": "Дрібна оброблена деревна целюлоза", - "item.gtceu.tiny_wood_dust": "Крихта деревної целюлози", - "item.gtceu.small_wood_dust": "Дрібна деревна целюлоза", - "item.gtceu.platinum_group_sludge_dust": "Шлам платинової групи", - "item.gtceu.portable_scanner": "Портативний сканер", - - "behavior.portable_scanner.amp_per_sec": "В середньому (за останню секунду): %s A", - "behavior.portable_scanner.eu_per_sec": "В середньому (за останню секунду): %s EU/т", - "behavior.portable_scanner.bedrock_fluid.amount": "Розміщена рідина: %s %s - %s%%", - "behavior.portable_scanner.bedrock_fluid.amount_unknown": "Розміщена рідина: %s%%", - "behavior.portable_scanner.bedrock_fluid.nothing": "Розміщена рідина:§6 Нічого§r", - "behavior.portable_scanner.block_hardness": "Твердість: %s захист від вибухів: %s", - "behavior.portable_scanner.block_name": "Назва: %s Метадані: %s", - "behavior.portable_scanner.debug_cpu_load": "Середнє завантаження процесора ~%sнс протягом %s тактів з найгіршим часом %sнс.", - "behavior.portable_scanner.debug_cpu_load_seconds": "Це %s секунд.", - "behavior.portable_scanner.debug_lag_count": "Попередження про затримку %s (все, що триває довше, ніж %sмс) на сервері.", - "behavior.portable_scanner.debug_machine": "Мета-ID: %s", - "behavior.portable_scanner.debug_machine_invalid": " недійсний!", - "behavior.portable_scanner.debug_machine_invalid_null=invalid! MetaTileEntity =": " null!", - "behavior.portable_scanner.debug_machine_valid": " дійсний", - "behavior.portable_scanner.divider": "=========================", - "behavior.portable_scanner.energy_container_in": "Макс. Вхід: %s (%s) EU з %s A", - "behavior.portable_scanner.energy_container_out": "Макс. Вихід: %s (%s) EU з %s A", - "behavior.portable_scanner.energy_container_storage": "Енергія: %s EU / %s EU", - "behavior.portable_scanner.environmental_hazard": "Екологічна небезпека у чанку: %s§r - %s ppm", - "behavior.portable_scanner.environmental_hazard.nothing": "Екологічна небезпека у чанку:§6 відсутня§r", - "behavior.portable_scanner.local_hazard": "Місцева небезпека в регіоні: %s§r - %s ppm", - "behavior.portable_scanner.local_hazard.nothing": "Місцева небезпека в регіоні:§6 відсутня§r", - "behavior.portable_scanner.guild_name": "§2Ім'я гільдії: %s§r", - "behavior.portable_scanner.machine_disabled": "Вимкнено.", - "behavior.portable_scanner.machine_front_facing": "Лицьовий бік: %s", - "behavior.portable_scanner.machine_ownership": "§2Тип власника машини: %s§r", - "behavior.portable_scanner.machine_power_loss": "Вимкнено через втрату живлення.", - "behavior.portable_scanner.machine_progress": "Обробка/завантаження: %s / %s", - "behavior.portable_scanner.machine_upwards_facing": "Верхній бік: %s", - "behavior.portable_scanner.mode.caption": "Режим відображення: %s", - "behavior.portable_scanner.mode.show_all_info": "Показувати всю інформацію", - "behavior.portable_scanner.mode.show_block_info": "Показувати інформацію про блок", - "behavior.portable_scanner.mode.show_electrical_info": "Показувати інженерну інформацію", - "behavior.portable_scanner.mode.show_environmental_info": "Показувати інформацію про довкілля", - "behavior.portable_scanner.mode.show_machine_info": "Показувати інформацію про машину", - "behavior.portable_scanner.mode.show_recipe_info": "Показувати інформацію про рецепт", - "behavior.portable_scanner.muffled": "Заглушено.", - "behavior.portable_scanner.multiblock_energy_input": "Макс. подача енергії: %s EU/т рівень: %s", - "behavior.portable_scanner.multiblock_energy_output": "Макс. Вихід енергії: %s EU/т рівень: %s", - "behavior.portable_scanner.multiblock_maintenance": "Проблеми: %s", - "behavior.portable_scanner.multiblock_parallel": "Паралельна обробка: %s", - "behavior.portable_scanner.player_name": "§2Ім'я гравця: %s§r,§7 гравець у мережі: %s§r", - "behavior.portable_scanner.position": "----- X: %s Y: %s Z: %s в: %s -----", - "behavior.portable_scanner.state": "%s: %s", - "behavior.portable_scanner.tank": "Резервуар %s: %s мВ / %s мВ %s", - "behavior.portable_scanner.tanks_empty": "Усі резервуари порожні", - "behavior.portable_scanner.team_name": "§2Назва команди: %s§r", - "behavior.portable_scanner.workable_consumption": "Ймовірно споживає: %s EU/т з %s A", - "behavior.portable_scanner.workable_production": "Ймовірно виробляє: %s EU/т з %s A", - "behavior.portable_scanner.workable_progress": "Прогрес: %s s / %s s", - "behavior.portable_scanner.workable_stored_energy": "Збережена енергія: %s EU / %s EU", - - "item.gtceu.terminal": "Термінал", - "item.gtceu.terminal.tooltip": "Shift+ПКМ по контролеру для автоматичної побудови конструкції", - "item.gtceu.programmed_circuit": "Програмна плата", - "item.gtceu.programmed_circuit.tooltip.0": "Використайте, щоб відкрити інтерфейс конфігурації", - "item.gtceu.programmed_circuit.tooltip.1": "Shift+ПКМ по машині з гніздом", - "item.gtceu.programmed_circuit.tooltip.2": "плати, щоб встановити її", - "item.gtceu.programmed_circuit.tooltip.3": "на значення цієї плати.", - "item.gtceu.sus_record": "Платівка", - "item.gtceu.sus_record.desc": "§7підозріло!", - "metaitem.record.sus.tooltip": "§7Leonz - Among Us Drip", - - "item.gtceu.tool.tooltip.attack_speed": "%s§9 швидкости атаки", - "item.gtceu.tool.tooltip.crafting_uses": "%s§a використань у майструванні", - "item.gtceu.tool.tooltip.general_uses": "%s§b міцности", - "item.gtceu.tool.tooltip.attack_damage": "%s§c шкоди від атаки", - "item.gtceu.tool.tooltip.mining_speed": "%s§d швидкости добування", - "item.gtceu.tool.tooltip.max_uses": "%s§e загальної міцности", - "item.gtceu.tool.tooltip.repair_material": "§8Придатне для ремонту:§f§a %s", - "item.gtceu.tool.tooltip.harvest_level": "§eРівень добування %s", - "item.gtceu.tool.tooltip.harvest_level_extra": "§eРівень добування %s§f (%s§f)", - "item.gtceu.tool.harvest_level.0": "§8Дерево", - "item.gtceu.tool.harvest_level.1": "§7Камінь", - "item.gtceu.tool.harvest_level.2": "§aЗалізо", - "item.gtceu.tool.harvest_level.3": "§bДіамант", - "item.gtceu.tool.harvest_level.4": "§dНезерит", - "item.gtceu.tool.harvest_level.5": "§9Дюран", - "item.gtceu.tool.harvest_level.6": "§cНейтроній", - "item.gtceu.tool.behavior.relocate_mining": "§2Магнетизм:§f телепортує добуті блоки та дроп мобів", - "item.gtceu.tool.behavior.block_rotation": "§2Механіка:§f Обертає блоки", - "item.gtceu.tool.behavior.damage_boost": "§4Збільшення шкоди:§f додаткова шкода проти %s", - "item.gtceu.tool.behavior.tree_felling": "§4Лісоруб:§f повал дерев", - "item.gtceu.tool.behavior.aoe_mining": "§5Ефект по площі:§f %sx%sx%s", - "item.gtceu.tool.behavior.strip_log": "§5Ремісник:§f Обсічує колоди", - "item.gtceu.tool.behavior.remove_wax": "§6Очисник:§f знімає віск", - "item.gtceu.tool.behavior.plunger": "§9Вантуз:§f викачує рідини", - "item.gtceu.tool.behavior.crop_harvesting": "§aЖнивар:§f збирає дозрілі культури", - "item.gtceu.tool.behavior.silk_ice": "§bЛьодоріз:§f Шовково добуває лід", - "item.gtceu.tool.behavior.scrape": "§bПолірувальник:§f видаляє окиснення", - "item.gtceu.tool.behavior.shield_disable": "§cБрутал:§f знешкоджує щити", - "item.gtceu.tool.behavior.ground_tilling": "§eФермер:§f Оре ґрунт", - "item.gtceu.tool.behavior.grass_path": "§eКаток:§f створює трав'яні доріжки", - "item.gtceu.tool.behavior.rail_rotation": "§eЗалізничний інженер:§f повертає рейки", - "item.gtceu.tool.behavior.torch_place": "§eСпелеолог:§f розміщує смолоскипи на ПКМ", - "item.gtceu.tool.usable_as": "§8Використовується як:§f %s", - "item.gtceu.tool.plunger.tooltip": "§8Видаляє рідини з машин", - "item.gtceu.tool.lighter.platinum.tooltip": "§7На ній викарбуваний відомий майстер пранків", - "item.gtceu.tool.matchbox.tooltip": "§7Це не авто", - "item.gtceu.tool.lv_screwdriver.tooltip": "§8Налаштовує кришки та машини", - "item.gtceu.tool.screwdriver.tooltip": "§8Налаштовує кришки та машини", - "item.gtceu.tool.scythe.tooltip": "§8Тому що коса не має сенсу", - "item.gtceu.tool.hammer.tooltip": "§8Подрібнює блоки при добуванні", - "item.gtceu.tool.crowbar.tooltip": "§8Знімає кришки", - "item.gtceu.tool.butchery_knife.tooltip": "§8Має низьку швидкість атаки", - "item.gtceu.tool.hv_wrench.tooltip": "§8Утримуйте лКМ, щоб демонтовувати машини", - "item.gtceu.tool.iv_wrench.tooltip": "§8Утримуйте лКМ, щоб демонтовувати машини", - "item.gtceu.tool.lv_wrench.tooltip": "§8Утримуйте лКМ, щоб демонтовувати машини", - "item.gtceu.tool.wrench.tooltip": "§8Утримуйте лКМ, щоб демонтовувати машини", - "item.gtceu.tool.mining_hammer.tooltip": "§8Добуває більшою площею (поки ви не крадетесь)", - "item.gtceu.tool.spade.tooltip": "§8Риє більшою площею (поки ви не крадетесь)", - "item.gtceu.tool.buzzsaw.tooltip": "§8Не підходить для збору блоків", - "item.gtceu.tool.mallet.tooltip.0": "§8Клацніть по машині крадькома, щоб зупинити її по завершенню поточної операції.", - "item.gtceu.tool.mallet.tooltip.1": "§8Зупиняє/запускає машини", - "item.gtceu.tool.aoe.columns": "Колони", - "item.gtceu.tool.aoe.layers": " Шари", - "item.gtceu.tool.aoe.rows": "Рядки", - "item.gtceu.tool.replace_tool_head": "Об'єднайте з іншою головкою інструмента, щоб замінити її", - - "item.gtceu.tool.axe": "Сокира (%s)", - "item.gtceu.tool.butchery_knife": "М'ясний ніж (%s)", - "item.gtceu.tool.buzzsaw": "LV електропила (%s)", - "item.gtceu.tool.hv_chainsaw": "HV ланцюгова пила (%s)", - "item.gtceu.tool.lv_chainsaw": "LV ланцюгова пила (%s)", - "item.gtceu.tool.mv_chainsaw": "MV ланцюгова пила (%s)", - "item.gtceu.tool.crowbar": "Лом (%s)", - "item.gtceu.tool.ev_drill": "EV Бур (%s)", - "item.gtceu.tool.hv_drill": "HV Бур (%s)", - "item.gtceu.tool.iv_drill": "IV Бур (%s)", - "item.gtceu.tool.lv_drill": "LV Бур (%s)", - "item.gtceu.tool.mv_drill": "MV Бур (%s)", - "item.gtceu.tool.file": "Напилок (%s)", - "item.gtceu.tool.hammer": "Молот (%s)", - "item.gtceu.tool.hoe": "Мотика (%s)", - "item.gtceu.tool.knife": "Ніж (%s)", - "item.gtceu.tool.mining_hammer": "Шахтарський молот (%s)", - "item.gtceu.tool.mortar": "Ступка (%s)", - "item.gtceu.tool.pickaxe": "Кайло (%s)", - "item.gtceu.tool.plunger": "Вантуз (%s)", - "item.gtceu.tool.rolling_pin": "Качалка (%s)", - "item.gtceu.tool.saw": "Пила (%s)", - "item.gtceu.tool.screwdriver": "Викрутка (%s)", - "item.gtceu.tool.lv_screwdriver": "LV викрутка (%s)", - "item.gtceu.tool.scythe": "Коса (%s)", - "item.gtceu.tool.shears": "Ножиці (%s)", - "item.gtceu.tool.shovel": "Лопата (%s)", - "item.gtceu.tool.mallet": "М'який молоток (%s)", - "item.gtceu.tool.spade": "Заступ (%s)", - "item.gtceu.tool.sword": "Меч (%s)", - "item.gtceu.tool.wire_cutter": "Кусачки (%s)", - "item.gtceu.tool.hv_wirecutter": "HV кусачки (%s)", - "item.gtceu.tool.iv_wirecutter": "IV кусачки (%s)", - "item.gtceu.tool.lv_wirecutter": "LV кусачки (%s)", - "item.gtceu.tool.wrench": "Гайковий ключ (%s)", - "item.gtceu.tool.hv_wrench": "HV гайковерт (%s)", - "item.gtceu.tool.iv_wrench": "IV гайковерт (%s)", - "item.gtceu.tool.lv_wrench": "LV гайковерт (%s)", - "entity.gtceu.dynamite": "Динамітна шашка", - "item.gtceu.dynamite": "Динамітна шашка", - "item.gtceu.invar_lighter": "Інварова запальничка", - "item.gtceu.platinum_lighter": "Платинова запальничка", - - "gtceu.tool.class.axe": "Сокира", - "gtceu.tool.class.butchery_knife": "М'ясний ніж", - "gtceu.tool.class.crowbar": "Лом", - "gtceu.tool.class.drill": "Бур", - "gtceu.tool.class.file": "Напилок", - "gtceu.tool.class.hammer": "Молот", - "gtceu.tool.class.hoe": "Мотика", - "gtceu.tool.class.knife": "Ніж", - "gtceu.tool.class.mining_hammer": "Шахтарський молот", - "gtceu.tool.class.mortar": "Ступка", - "gtceu.tool.class.pickaxe": "Кайло", - "gtceu.tool.class.plunger": "Вантуз", - "gtceu.tool.class.rolling_pin": "Качалка", - "gtceu.tool.class.saw": "Пила", - "gtceu.tool.class.screwdriver": "Викрутка", - "gtceu.tool.class.scythe": "Коса", - "gtceu.tool.class.shears": "Ножиці", - "gtceu.tool.class.shovel": "Лопата", - "gtceu.tool.class.mallet": "М'який молоток", - "gtceu.tool.class.spade": "Заступ", - "gtceu.tool.class.sword": "Меч", - "gtceu.tool.class.wire_cutter": "Кусачки", - "gtceu.tool.class.wrench": "Гайковий ключ", - - "gtceu.multiblock.assembly_line.description": "Конвеєрна лінія - це велика багатоблочна конструкція, що складається з 5 до 16 \"скибок\". теоретично, це великий збиральний апарат, який використовується для створення просунутих крафтових компонентів.", - "gtceu.multiblock.charcoal_pile.description.0": "Перетворює колоди на крихке деревне вугілля в зоні 9х4х9 під собою.", - "gtceu.multiblock.charcoal_pile.description.2": "Підлога ями повинна бути викладена з цегли, а для стін і даху можна використовувати будь-який грунтовий блок. Усередині ями не повинно бути повітря.", - "gtceu.multiblock.charcoal_pile.description.4": "Більші ями займають більше часу для обробки колод, але є більш ефективними.", - "gtceu.multiblock.primitive_blast_furnace.bronze.description": "Примітивна доменна піч (ПДП) - це багатоблочна конструкція, яка використовується для виплавки сталі на початку гри. хоч і не дуже швидко, але вона забезпечить вас сталлю для перших установок.", - "gtceu.multiblock.electric_blast_furnace.description": "Електрична доменна піч (ЕДП) - це багатоблочна конструкція, яка використовується для виплавки сплавів, варіння металів і збагачення руд. Вона необхідна для отримання високоякісних сплавів і металів, таких як алюміній, нержавіюча сталь, титан і сплав наквада.", - "gtceu.multiblock.multi_furnace.description": "Мультиплавильна піч - це багатоблочна конструкція, яка використовується для виплавки великої кількості предметів одночасно. різні рівні котушок забезпечують підвищення швидкості та енергоефективності. 32 - це базове значення кількості предметів, що виплавляються за одну операцію, і може бути збільшене шляхом використання котушок вищого рівня.", - "gtceu.multiblock.steam_oven.description": "Мультиплавильна піч парової епохи. для формування потрібно щонайменше 6 бронзових корпусів. Не можна використовувати звичайні вхідні/вихідні шини, а також рідинні люки, окрім парового. паровий люк повинен бути на нижньому шарі, не більше одного.", - "gtceu.multiblock.coke_oven.description": "Коксова піч - це багатоблочна конструкція, яка використовується для отримання коксу та креозоту на початку гри. Вона не потребує палива і має внутрішній резервуар на 32 відра для креозоту. доступ до її інвентарю можна отримати через люк коксової печі.", - "gtceu.multiblock.steam_grinder.description": "Мультиблочний подрібнювач парової епохи. для формування потребує щонайменше 14 бронзових корпусів. Не може використовувати звичайні вхідні/вихідні шини, а також рідинні люки, окрім парового.", - "gtceu.multiblock.cracker.description": "Нафтова крекінгова установка - це багатоблочна конструкція, яка використовується для перетворення легкого та важкого палива на їх крекінгові варіанти.", - "gtceu.multiblock.data_bank.description": "База даних - це багатоблочна конструкція, яка використовується для спільного використання дослідницьких даних конвеєрної лінії між кількома конвеєрними лініями. крім того, це дозволяє конвеєрним лініям зчитувати складніші дослідницькі дані з модулів даних.", - "gtceu.multiblock.distillation_tower.description": "Дистиляційна вежа - це багатоблочна конструкція, яка використовується для перегонки різних типів нафти та деяких побічних продуктів. кожен шар повинен мати рівно один вихідний люк, починаючи з другого. Нижній шар може виводити предмети і вводити рідини в будь-якому положенні.", - "gtceu.multiblock.extreme_combustion_engine.description": "Екстремальний двигун внутрішнього згоряння - це багатоблочна конструкція, яка діє як генератор згоряння для IV живлення.", - "gtceu.multiblock.hpca.description": "Високопродуктивний обчислювальний масив (ВОМ) - це багатоблочна конструкція, яка використовується для створення Обчислювальних робочих одиниць (ОРО/т) для складніших дослідницьких даних конвеєра. структура має гнучку область 3x3, яку можна заповнити компонентами вОМ у будь-який спосіб. різні компоненти можуть забезпечувати різні обсяги обчислень, охолодження, а також витрати енергії, охолоджувальної рідини та виробництва тепла. при використанні з мостовим компонентом вОМ може підключатися до мережевих комутаторів для об'єднання і маршрутизації обчислень від декількох джерел до одного або декількох пунктів призначення.", - "gtceu.multiblock.implosion_compressor.description": "Імплозійний компресор - це багатоблочна конструкція, яка використовує вибухівку для перетворення кристалічного пилу на відповідні кристали.", - "gtceu.multiblock.luv_fusion_reactor.description": "Термоядерний реактор MK 1 - це велика багатоблочна конструкція, яка використовується для злиття елементів у більш важкі. Він може використовувати лише LuV, ZPM та UV енергетичні люки. з кожним встановленим люком його буфер збільшується на 10 млн EU і може досягати 160 млн.", - "gtceu.multiblock.uv_fusion_reactor.description": "Термоядерний реактор MK 3 - це велика багатоблочна конструкція, яка використовується для злиття елементів у більш важкі. Він може використовувати лише UV енергетичні люки. з кожним встановленим люком його буфер збільшується на 40 млн EU і може досягати 640 млн.", - "gtceu.multiblock.zpm_fusion_reactor.description": "Термоядерний реактор MK 2 - це велика багатоблочна конструкція, яка використовується для злиття елементів у більш важкі. Він може використовувати лише ZPM та UV енергетичні люки. з кожним встановленим люком його буфер збільшується на 20 млн EU і може досягати 320 млн.", - "gtceu.multiblock.large_boiler.description": "Великі котли - це конструкції, які виробляють пару з джерела енергії та води. зазначеним джерелом енергії є будь-яке тверде паливо з певним часом горіння або дизельне/напіврідке паливо. Можна регулювати з кроком 5%% для зменшення виходу пари та споживання палива.", - "gtceu.multiblock.large_chemical_reactor.description": "Великий хімічний реактор виконує хімічні реакції зі 100% енергоефективністю. розгін збільшує швидкість і енергію в 4 рази. конструкція вимагає рівно 1 блок мельхіорової котушки, який повинен бути розміщений поруч з корпусом пТФЕ-труби, розташованим в центрі.", - "gtceu.multiblock.large_combustion_engine.description": "Великий двигун внутрішнього згоряння - це багатоблочна конструкція, яка працює як генератор внутрішнього згоряння для EV живлення.", - "gtceu.multiblock.large_turbine.description": "Великі турбіни - це конструкції, які генерують енергію з пари, газів і плазми шляхом обертання ротора турбіни. Вихід енергії залежить від ефективності ротора та поточної швидкості турбіни. У центрі конструкції використовуються корпуси редукторів.", - "gtceu.multiblock.network_switch.description": "Мережевий комутатор - це багатоблочна конструкція, яка використовується для розподілу обчислень від багатьох джерел до багатьох пунктів призначення. Він може приймати будь-яку кількість люків прийому або передачі обчислювальних даних. Це необхідно для дослідницьких даних, які вимагають набагато більшого обсягу обчислень, оскільки дослідницька станція може прийняти лише один люк прийому обчислювальних даних. ВОМ повинні мати мостовий компонент, щоб мережевий комутатор міг отримати доступ до їхніх обчислень.", - "gtceu.multiblock.primitive_water_pump.description": "Примітивна водяна помпа - це конструкція до-парової епохи, яка збирає воду раз на секунду, залежно від біома, в якому він знаходиться. Вона може використовувати вихідний люк помпи, ULV або LV, збільшуючи кількість води за рівень. розраховується за формулою: коефіцієнт біома * Множник люка.", - "gtceu.multiblock.pyrolyse_oven.description": "Піролізна піч - це багатоблочна конструкція, яка використовується для перетворення колод на деревне вугілля та креозотову олію, або попіл та важку нафту.", - "gtceu.multiblock.research_station.description": "Дослідницька станція - це багатоблочна конструкція, яка використовується для дослідження набагато складніших дослідницьких даних конвеєрної лінії. Будь-яке дослідження, що вимагає сфери даних або модуля даних, має бути відскановане в дослідницькій станції. для дослідження рецептів потрібні обчислювальні робочі одиниці (ОРО/т), які надаються високопродуктивними обчислювальними масивами (ВОМ).", - "gtceu.multiblock.vacuum_freezer.description": "Вакуумна морозильна камера - це багатоблочна конструкція, яка в основному використовується для охолодження розпечених злитків у звичайні. Однак вона також може заморожувати інші речовини, такі як вода.", - "gtceu.multiblock.active_transformer.average_in": "§bСеред. Вхід:§f %s EU/т", - "gtceu.multiblock.active_transformer.average_out": "§bСеред. Вихід:§f %s EU/т", - "gtceu.multiblock.active_transformer.danger_enabled": "§c§bНЕБЕЗПЕКА: вибухонебезпечно", - "gtceu.multiblock.active_transformer.max_input": "§aМакс. Вхід:§f %s EU/т", - "gtceu.multiblock.active_transformer.max_output": "§cМакс. Вихід:§f %s EU/т", - "gtceu.multiblock.blast_furnace.max_temperature": "Теплоємність: %s", - "gtceu.multiblock.central_monitor.height": "Висота екрану:", - "gtceu.multiblock.central_monitor.height_modify": "Зміна висоти: %d", - "gtceu.multiblock.central_monitor.low_power": "Низька потужність", - "gtceu.multiblock.central_monitor.tooltip.0": "Це машина, яка контролює машини, проксі яких знаходяться під кришкою цифрового інтерфейсу. Ви можете легко контролювати рідини, предмети, енергію та стани машин, проксі яких підключено до енергетичної мережі.", - "gtceu.multiblock.central_monitor.tooltip.1": "Ви можете побудувати екран центрального контролера від 3x2 да %dx%d (ширина x висота).", - "gtceu.multiblock.central_monitor.tooltip.2": "Висота за замовчуванням - 3. Ви можете налаштувати висоту екрану в графічному інтерфейсі до того, як структура буде сформована.", - "gtceu.multiblock.central_monitor.tooltip.3": "Споживання енергії: %d EU/c за кожний екран.", - "gtceu.multiblock.central_monitor.width": "Ширина екрану: %d", - "gtceu.multiblock.cleanroom.clean_amount": "Чистота:§a %s%%", - "gtceu.multiblock.cleanroom.clean_state": "Стан:§a ЧИСТО", - "gtceu.multiblock.cleanroom.dirty_state": "Стан:§4 ЗАБРУДНЕНО", - "gtceu.multiblock.computation.max": "Макс. ОРО/т: %s", - "gtceu.multiblock.computation.non_bridging": "Знайдено немостове з'єднання", - "gtceu.multiblock.computation.non_bridging.detailed": "Приймальний люк пов'язаний з машиною без мостування", - "gtceu.multiblock.computation.not_enough_computation": "Машина вимагає більше обчислень!", - "gtceu.multiblock.computation.usage": "Використовується: %s", - "gtceu.multiblock.cracking_unit.energy": "Вик. енергії: %s%%", - "gtceu.multiblock.data_bank.providing": "Надання даних.", - "gtceu.multiblock.distillation_tower.distilling_fluid": "Дистиляція %s", - "gtceu.multiblock.energy_consumption": "Вик. енергії: %s EU/т (%s)", - "gtceu.multiblock.exact_hatch_1.tooltip": "§fПриймає рівно§6 один§f енергетичний люк.", - "gtceu.multiblock.fluid_rig.drilled_fluid": "Рідина: %s", - "gtceu.multiblock.fluid_rig.fluid_amount": "Швидкість перекачування: %s", - "gtceu.multiblock.fluid_rig.no_fluid_in_area": "Немає поблизу.", - "gtceu.multiblock.fluid_rig.vein_depleted": "Поклада виснажена.", - "gtceu.multiblock.fluid_rig.vein_depletion": "Розмір поклади: %s", - "gtceu.multiblock.fusion_reactor.energy": "EU: %d / %d", - "gtceu.multiblock.fusion_reactor.heat": "Тепло: %d", - "gtceu.multiblock.generation_eu": "Виведення:§a %s EU/т", - "gtceu.multiblock.hpca.computation": "Надання: %s", - "gtceu.multiblock.hpca.energy": "Живлення: %s / %s EU/т (%s)", - "gtceu.multiblock.hpca.error_damaged": "Пошкоджений компонент в структурі!", - "gtceu.multiblock.hpca.error_temperature": "Температура вище 100C, компоненти можуть бути пошкоджені!", - "gtceu.multiblock.hpca.hover_for_info": "Наведіть для подробиць", - "gtceu.multiblock.hpca.info_bridging_disabled": "Мостування вимкнено", - "gtceu.multiblock.hpca.info_bridging_enabled": "Мостування увімкнено", - "gtceu.multiblock.hpca.info_coolant_name": "ДП-охолоджуюча рідина", - "gtceu.multiblock.hpca.info_max_computation": "Макс. ОРО/т: %s", - "gtceu.multiblock.hpca.info_max_coolant_required": "Необхідна охолоджуюча рідина: %s", - "gtceu.multiblock.hpca.info_max_cooling_available": "Наявне охолодження: %s", - "gtceu.multiblock.hpca.info_max_cooling_demand": "Потреба в охолодженні: %s", - "gtceu.multiblock.hpca.temperature": "Температура: %s", - "gtceu.multiblock.hpca.warning_low_cooling": "- Недостатньо охолодження", - "gtceu.multiblock.hpca.warning_multiple_bridges": "- Багато мостів у структурі (не надає додаткових переваг)", - "gtceu.multiblock.hpca.warning_no_computation": "- Немає постачальників обчислень", - "gtceu.multiblock.hpca.warning_structure_header": "Попередження структури:", - "gtceu.multiblock.hpca.warning_temperature": "Температура вище 50C, компоненти можуть бути пошкоджені при 100C!", - "gtceu.multiblock.hpca.warning_temperature_active_cool": "Повне використання активних охолоджувачів", - "gtceu.multiblock.idling": "§6Очікування.", - "gtceu.multiblock.invalid_structure": "Неприпустима структура.", - "gtceu.multiblock.invalid_structure.tooltip": "Цей блок є контролером багатоблокової структури. для отримання допомоги у створенні дивіться шаблон структури в JEI.", - "gtceu.multiblock.large_boiler.efficiency": "Ефективність: %s", - "gtceu.multiblock.large_boiler.explosion_tooltip": "Вибухне, якщо подати паливо без води", - "gtceu.multiblock.large_boiler.heat_time_tooltip": "§7Закипає за§f %d секунд", - "gtceu.multiblock.large_boiler.max_temperature": "Макс. температура: %dK, виробництво пари: %dмВ/т", - "gtceu.multiblock.large_boiler.rate_tooltip": "§7Виробляє§f %d л§7 пари за§f 1 вугілля", - "gtceu.multiblock.large_boiler.steam_output": "Вихід пари: %s мВ/т", - "gtceu.multiblock.large_boiler.temperature": "Температура: %sK / %sK", - "gtceu.multiblock.large_boiler.throttle": "Дросель: %d", - "gtceu.multiblock.large_boiler.throttle.tooltip": "Котел може виробляти менше пари й споживати менше палива (ефективність не втрачається, не впливає на час нагрівання)", - "gtceu.multiblock.large_boiler.throttle_modify": "Зміна дроселю:", - "gtceu.multiblock.large_combustion_engine.boost_disallowed": "§bОновіть динамо-люк, щоб увімкнути кисневе пришвидшення.", - "gtceu.multiblock.large_combustion_engine.liquid_oxygen_amount": "Кількість рідкого кисню: %sL", - "gtceu.multiblock.large_combustion_engine.liquid_oxygen_boosted": "§bПришвидшено рідким киснем.", - "gtceu.multiblock.large_combustion_engine.lubricant_amount": "Кількість мастила: %sL", - "gtceu.multiblock.large_combustion_engine.obstructed": "Повітрозабірники двигуна заблоковані.", - "gtceu.multiblock.large_combustion_engine.oxygen_amount": "Кількість кисню: %sL", - "gtceu.multiblock.large_combustion_engine.oxygen_boosted": "§bПришвидшено киснем.", - "gtceu.multiblock.large_combustion_engine.supply_liquid_oxygen_to_boost": "Подайте рідкий кисень для пришвидшення.", - "gtceu.multiblock.large_combustion_engine.supply_oxygen_to_boost": "Подайте кисень для пришвидшення.", - "gtceu.multiblock.large_miner.done": "Завершено!", - "gtceu.multiblock.large_miner.errorradius": "§cНеможливо змінити радіус під час роботи!", - "gtceu.multiblock.large_miner.invfull": "Вмістилище заповнено!", - "gtceu.multiblock.large_miner.needsfluid": "Потрібна бурильна рідина", - "gtceu.multiblock.large_miner.needspower": "Потрібне живлення!", - "gtceu.multiblock.large_miner.radius": "Радіус:§a %d§r блоків", - "gtceu.multiblock.large_miner.steam": "Потрібна пара!", - "gtceu.multiblock.large_miner.vent": "Вентиляція заблокована!", - "gtceu.multiblock.large_miner.working": "Опрацювання...", - "gtceu.multiblock.max_energy_per_tick": "Макс. EU/т:§a %s (%s§r)", - "gtceu.multiblock.max_energy_per_tick_amps": "Макс. EU/т: %s (%sA %s)", - "gtceu.multiblock.max_energy_per_tick_hover": "Максимальна кількість EU/т, доступна для запуску обробки або розгону", - "gtceu.multiblock.max_recipe_tier": "Макс. рівень обробки: %s", - "gtceu.multiblock.max_recipe_tier_hover": "Максимальний рівень обробки, який можна запускати", - "gtceu.multiblock.monitor_screen.tooltip.0": "Графічний інтерфейс можна відкрити клацанням ПКМ із викруткою.", - "gtceu.multiblock.monitor_screen.tooltip.1": "Проксі-режим цифрового інтерфейсу кришок може розподіляти можливості машини та графічного інтерфейсу. (Так, ви можете з'єднувати труби безпосередньо на екрані.)", - "gtceu.multiblock.monitor_screen.tooltip.2": "Екран також підтримує плагіни.", - "gtceu.multiblock.multi_furnace.heating_coil_discount": "Прискорення EU нагрівальною котушкою: %sx", - "gtceu.multiblock.multi_furnace.heating_coil_level": "Рівень нагрівальної котушки: %s", - "gtceu.multiblock.multiple_recipemaps.header": "Режим машини:", - "gtceu.multiblock.multiple_recipemaps.switch_message": "Для перемикання режимів машина повинна бути вимкнена!", - "gtceu.multiblock.multiple_recipemaps.tooltip": "Використовуйте викрутку на контролері, щоб змінити режим роботи машини.", - "gtceu.multiblock.multiple_recipemaps_recipes.tooltip": "Режими машини:§e %s§r", - "gtceu.multiblock.not_enough_energy": "ПОПЕРЕДЖЕННЯ: Машині потрібно більше енергії.", - "gtceu.multiblock.not_enough_energy_output": "ПОПЕРЕДЖЕННЯ: рівень енергетичного динамо занадто низький!", - "gtceu.multiblock.ore_rig.drilled_ore_entry": " - %s", - "gtceu.multiblock.ore_rig.drilled_ores_list": "Руди:", - "gtceu.multiblock.ore_rig.ore_amount": "Швидкість буріння: %s", - "gtceu.multiblock.output_line.0": "%s x§e %s§r (%sс/од)", - "gtceu.multiblock.output_line.1": "%s x§e %s§r (%s/с)", - "gtceu.multiblock.output_line.2": "%s ≈§e %s§r (%sс/од)", - "gtceu.multiblock.output_line.3": "%s ≈§e %s§r (%s/с)", - "gtceu.multiblock.page_switcher.io.both": "§5Комбіновані входи/виходи", - "gtceu.multiblock.page_switcher.io.export": "§4Виходи", - "gtceu.multiblock.page_switcher.io.import": "§2Входи", - "gtceu.multiblock.parallel": "Паралельне виконання до %d рецептів", - "gtceu.multiblock.parallel.exact": "Паралельне виконання %d рецептів", - "gtceu.multiblock.parallelizable.tooltip": "Може працювати паралельно між люками паралельного контролю.", - "gtceu.multiblock.pattern.clear_amount_1": "§6Спереду має бути вільний простір 1х1х1§r", - "gtceu.multiblock.pattern.clear_amount_3": "§6Спереду має бути вільний простір 3x3x1§r", - "gtceu.multiblock.pattern.error": "Очікувалися компоненти (%s) у (%s).", - "gtceu.multiblock.pattern.error.batteries": "§cВсі батареї повинні бути однаковими§r", - "gtceu.multiblock.pattern.error.coils": "§cВсі нагрівальні котушки повинні бути однаковими§r", - "gtceu.multiblock.pattern.error.filters": "§cВсі фільтри повинні бути однаковими§r", - "gtceu.multiblock.pattern.error.limited.0": "§cМаксимум: %d§r", - "gtceu.multiblock.pattern.error.limited.1": "§cМаксимум: %d§r", - "gtceu.multiblock.pattern.error.limited.2": "§cМаксимум: %d за шар§r", - "gtceu.multiblock.pattern.error.limited.3": "§cМаксимум: %d за шар§r", - "gtceu.multiblock.pattern.error.limited_exact": "§cРівно: %d§r", - "gtceu.multiblock.pattern.error.limited_within": "§cМіж %d та %d§r", - "gtceu.multiblock.pattern.location_end": "§cТочно енд§r", - "gtceu.multiblock.pattern.replaceable_air": "Замінюється повітрям", - "gtceu.multiblock.pattern.single": "§6Можна використовувати тільки цей блок§r", - "gtceu.multiblock.power_substation.average_in": "§7Серед. Вхід: %s§7 EU/т", - "gtceu.multiblock.power_substation.average_in_hover": "Середній обсяг EU, вкладеної у внутрішній резерв енергії електропідстанції", - "gtceu.multiblock.power_substation.average_out": "§7Серед. Вихід: %s§7 EU/т", - "gtceu.multiblock.power_substation.average_out_hover": "Середній обсяг EU, виведеної з внутрішнього резерву енергії електропідстанції", - "gtceu.multiblock.power_substation.capacity": "§7Ємність: %s§7 EU", - "gtceu.multiblock.power_substation.passive_drain": "§7Пасивне розряджання: %s§7 EU/т", - "gtceu.multiblock.power_substation.stored": "§7Збережено: %s§7 EU", - "gtceu.multiblock.power_substation.time_days": "%s днів", - "gtceu.multiblock.power_substation.time_forever": "Вічно", - "gtceu.multiblock.power_substation.time_hours": "%s годин", - "gtceu.multiblock.power_substation.time_minutes": "%s хвилин", - "gtceu.multiblock.power_substation.time_seconds": "%s секунд", - "gtceu.multiblock.power_substation.time_to_drain": "§7Часу до розрядження: %s", - "gtceu.multiblock.power_substation.time_to_fill": "§7Часу до заповнення: %s", - "gtceu.multiblock.power_substation.time_years": "%s років", - "gtceu.multiblock.power_substation.under_one_hour_left": "Менше 1 години до повного розрядження!", - "gtceu.multiblock.preview.rotate": "Клацніть та перемістіть для обертання", - "gtceu.multiblock.preview.select": "Клацніть ПКМ, щоб перевірити кандидатів", - "gtceu.multiblock.preview.zoom": "Обертайте коліщатко або переміщуйте із затиснутою ПКМ, щоб масштабувати", - "gtceu.multiblock.primitive_water_pump.extra1.0": "Коефіцієнт біома:", - "gtceu.multiblock.primitive_water_pump.extra1.1": " Океан, річка: 1000 мВ/с", - "gtceu.multiblock.primitive_water_pump.extra1.2": " Болото: 800 мВ/с", - "gtceu.multiblock.primitive_water_pump.extra1.3": " джунглі: 350 мВ/с", - "gtceu.multiblock.primitive_water_pump.extra1.4": " сніга: 300 мВ/с", - "gtceu.multiblock.primitive_water_pump.extra1.5": " рівнини, ліс: 250 мВ/с", - "gtceu.multiblock.primitive_water_pump.extra1.6": " тайга: 175 мВ/с", - "gtceu.multiblock.primitive_water_pump.extra1.7": " пляж: 170 мВ/с", - "gtceu.multiblock.primitive_water_pump.extra1.8": " Інші: 100 мВ/с", - "gtceu.multiblock.primitive_water_pump.extra2.0": "Множники люків:", - "gtceu.multiblock.primitive_water_pump.extra2.1": " Люк помпи: 1x", - "gtceu.multiblock.primitive_water_pump.extra2.2": " ULV вихідний люк: 2x", - "gtceu.multiblock.primitive_water_pump.extra2.3": " LV вихідний люк: 4x", - "gtceu.multiblock.primitive_water_pump.extra2.5": "Під час дощу в біомі викачування загальне виробництво води збільшиться на 50%%.", - "gtceu.multiblock.progress": "Прогрес: %ss / %ss (%s%%)", - "gtceu.multiblock.progress_percent": "Прогрес: %s%%", - "gtceu.multiblock.pyrolyse_oven.speed": "Швидкість обробки: %s%%", - "gtceu.multiblock.require_steam_parts": "Потрібні парові люки та шини!", - "gtceu.multiblock.research_station.researching": "§6Дослідження.", - "gtceu.multiblock.running": "Працює бездоганно.", - "gtceu.multiblock.steam.duration_modifier": "Забирає§f 1.5x§7 базової тривалості обробки, не залежить від кількості предметів.", - "gtceu.multiblock.steam.low_steam": "Недостатньо пари для роботи!", - "gtceu.multiblock.steam.steam_stored": "Пара: %s / %s mb", - "gtceu.multiblock.title": "Шаблон конструкції", - "gtceu.multiblock.turbine.efficiency": "Ефективність турбіни: %s%%", - "gtceu.multiblock.turbine.efficiency_tooltip": "Кожен тримач ротора вище %s§7 додає§f 10%% ефективності і множить EU/т на 2§7.", - "gtceu.multiblock.turbine.energy_per_tick": "Вихід енергії: %s/%s EU/т", - "gtceu.multiblock.turbine.energy_per_tick_maxed": "Вихід енергії: %s EU/т", - "gtceu.multiblock.turbine.fuel_amount": "Кількість палива: %sL (%s)", - "gtceu.multiblock.turbine.fuel_needed": "Споживає %s за %s тактів", - "gtceu.multiblock.turbine.obstructed": "Перешкода на шляху турбіни", - "gtceu.multiblock.turbine.rotor_durability": "Міцність ротора: %s%%", - "gtceu.multiblock.turbine.rotor_speed": "Швидкість ротора: %s/%s RPM", - "gtceu.multiblock.universal.distinct": "Відокремленні шини:", - "gtceu.multiblock.universal.distinct.info": "Якщо увімкнено, кожна вхідна предметна шина буде розглядатися як повністю відмінна одна від одної для пошуку рецептів. корисно для таких речей, як програмні плати, формові відтиски тощо.", - "gtceu.multiblock.universal.distinct.no": "Ні", - "gtceu.multiblock.universal.distinct.yes": "Так", - "gtceu.multiblock.universal.has_problems": "Наявні проблеми з технічним обслуговуванням!", - "gtceu.multiblock.universal.has_problems_header": "Виправте наведені нижче проблеми в люку технічного обслуговування:", - "gtceu.multiblock.universal.muffler_obstructed": "Люк вихлопа перекрито!", - "gtceu.multiblock.universal.muffler_obstructed.tooltip": "Люк вихлопа повинен мати блок повітряного простору перед собою.", - "gtceu.multiblock.universal.no_problems": "Немає проблем з технічним обслуговуванням!", - "gtceu.multiblock.universal.problem.crowbar": "%s§7Цьому тут не місце. (§aЛом§7)", - "gtceu.multiblock.universal.problem.hard_hammer": "%s§7Покриття має вм'ятини. (§aВажкий молот§7)", - "gtceu.multiblock.universal.problem.screwdriver": "%s§7Гвинти розхитані. (§aВикрутка§7)", - "gtceu.multiblock.universal.problem.soft_mallet": "%s§7Щось заклинило. (§aМ'який молоток§7)", - "gtceu.multiblock.universal.problem.wire_cutter": "%s§7Дроти перегоріли. (§aКусачки§7)", - "gtceu.multiblock.universal.problem.wrench": "%s§7Труба відійшла. (§aКлюч§7)", - "gtceu.multiblock.universal.rotor_obstructed": "Ротор заблоковано!", - "gtceu.multiblock.validation_failed": "Неправильна кількість входів/виходів.", - "gtceu.multiblock.waiting": "ПОПЕРЕДЖЕННЯ: Машина очікує.", - "gtceu.multiblock.work_paused": "Робота зупинена.", - - "material.gtceu.acetic_acid": "Оцтова кислота", - "material.gtceu.acetic_anhydride": "Оцтовий ангідрид", - "material.gtceu.acetone": "Ацетон", - "material.gtceu.acidic_bromine_exhaust": "Залишок броматної кислоти", - "material.gtceu.acidic_bromine_solution": "Розчин броматної кислоти", - "material.gtceu.bromine": "Бром", - "material.gtceu.concentrated_bromine_solution": "Концентрований розчин брому", - "material.gtceu.acidic_enriched_naquadah_solution": "Кислотний збагачений розчин наквуади", - "material.gtceu.impure_enriched_naquadah_solution": "Нечистий збагачений розчин наквуади", - "material.gtceu.enriched_naquadah": "Збагачена наквуада", - "material.gtceu.enriched_naquadah_solution": "Збагачений розчин наквуади", - "material.gtceu.enriched_naquadah_sulfate": "Сульфат збагаченої наквуади", - "material.gtceu.enriched_naquadah_trinium_europium_duranide": "Збагачений наквуада триній європій дуранід", - "material.gtceu.ruthenium_trinium_americium_neutronate": "Рутеній триній америцій нейтронат", - "material.gtceu.americium": "Америцій", - "material.gtceu.trinium": "Триній", - "material.gtceu.trinium_sulfide": "Сульфід тринію", - "material.gtceu.enriched_naquadah_waste": "Відпрацьована збагачена наквуада", - "material.gtceu.naquadah": "Наквуада", - "material.gtceu.naquadah_alloy": "Наквуадовий сплав", - "material.gtceu.acidic_naquadria_solution": "Кислотний розчин наквуадрії", - "material.gtceu.impure_naquadria_solution": "Нечистий розчин наквуадрії", - "material.gtceu.naquadria": "Наквуадрія", - "material.gtceu.naquadria_solution": "Розчин наквуадрії", - "material.gtceu.naquadria_sulfate": "Сульфат наквуадрії", - "material.gtceu.naquadria_waste": "Відпрацьована наквуадрія", - "material.gtceu.acidic_osmium_solution": "Розчин осмієвої кислоти", - "material.gtceu.actinium": "Актиній", - "material.gtceu.activated_carbon": "Активоване вугілля", - "material.gtceu.agar": "Агар", - "material.gtceu.air": "Повітря", - "material.gtceu.allyl_chloride": "Алілхлорид", - "material.gtceu.almandine": "Альмандин", - "material.gtceu.aluminium": "Алюміній", - "material.gtceu.aluminium_sulfite": "Сульфіт алюмінію", - "material.gtceu.alunite": "Алуніт", - "material.gtceu.amethyst": "Аметискт", - "material.gtceu.aminophenol": "Амінофенол", - "material.gtceu.ammonia": "Аміак", - "material.gtceu.ammonium_chloride": "Хлорид амонію", - "material.gtceu.ammonium_formate": "Форміат амонію", - "material.gtceu.andesite": "Андезит", - "material.gtceu.andradite": "Андрадит", - "material.gtceu.annealed_copper": "Відпалена мідь", - "material.gtceu.antimony": "Стибій", - "material.gtceu.antimony_trifluoride": "Фторид стибію", - "material.gtceu.antimony_trioxide": "Оксид стибію", - "material.gtceu.apatite": "Апатит", - "material.gtceu.aqua_regia": "Гетьманська горілка", - "material.gtceu.argon": "Аргон", - "material.gtceu.arsenic": "Арсен", - "material.gtceu.arsenic_trioxide": "Оксид арсену", - "material.gtceu.asbestos": "Азбест", - "material.gtceu.ash": "Попіл", - "material.gtceu.astatine": "Астат", - "material.gtceu.bacteria": "Бактерії", - "material.gtceu.bacterial_sludge": "Бактерієвий шлам", - "material.gtceu.enriched_bacterial_sludge": "Збагачений бактерієвий шлам", - "material.gtceu.barite": "Барит", - "material.gtceu.barium": "Барій", - "material.gtceu.barium_sulfide": "Сульфід барію", - "material.gtceu.basalt": "Базальт", - "material.gtceu.basaltic_mineral_sand": "Базальтовий мінеральний пісок", - "material.gtceu.bastnasite": "Бастнезит", - "material.gtceu.battery_alloy": "Батарейний сплав", - "material.gtceu.blue_alloy": "Синій сплав", - "material.gtceu.red_alloy": "Червоний сплав", - "material.gtceu.rtm_alloy": "RTM-сплав", - "material.gtceu.soldering_alloy": "Припій", - "material.gtceu.tin_alloy": "Станід заліза", - "material.gtceu.bauxite": "Боксит", - "material.gtceu.bentonite": "Бентоніт", - "material.gtceu.benzene": "Бензен", - "material.gtceu.berkelium": "Берклій", - "material.gtceu.beryllium": "Берилій", - "material.gtceu.bio_diesel": "Біодизель", - "material.gtceu.biomass": "Біомаса", - "material.gtceu.biotite": "Біотит", - "material.gtceu.biphenyl": "Діфеніл", - "material.gtceu.bismuth": "Бісмут", - "material.gtceu.bismuth_bronze": "Бісмутова бронза", - "material.gtceu.bisphenol_a": "Бісфенол A", - "material.gtceu.black_dye": "Чорний барвник", - "material.gtceu.blue_dye": "Синій барвник", - "material.gtceu.brown_dye": "Коричневий барвник", - "material.gtceu.cyan_dye": "Бірюзовий барвник", - "material.gtceu.gray_dye": "Сірий барвник", - "material.gtceu.green_dye": "Зелений барвник", - "material.gtceu.light_blue_dye": "Блакитний барвник", - "material.gtceu.light_gray_dye": "Світло-сірий барвник", - "material.gtceu.lime_dye": "Лаймовий барвник", - "material.gtceu.magenta_dye": "Пурпуровий барвник", - "material.gtceu.orange_dye": "Помаранчевий барвник", - "material.gtceu.pink_dye": "Рожевий барвник", - "material.gtceu.purple_dye": "Фіолетовий барвник", - "material.gtceu.red_dye": "Червоний барвник", - "material.gtceu.white_dye": "Білий барвник", - "material.gtceu.yellow_dye": "Жовтий барвник", - "material.gtceu.black_bronze": "Чорна бронза", - "material.gtceu.blackstone": "Чорнокамінь", - "material.gtceu.blaze": "Пломінь", - "material.gtceu.blue_topaz": "Синій топаз", - "material.gtceu.bohrium": "Борій", - "material.gtceu.bone": "Кістка", - "material.gtceu.borax": "Бура", - "material.gtceu.bornite": "Борніт", - "material.gtceu.boron": "Бор", - "material.gtceu.borosilicate_glass": "Боросілікатне скло", - "material.gtceu.brass": "Латунь", - "material.gtceu.brick": "Цеглина", - "material.gtceu.brominated_chlorine_vapor": "Пара бромованого хлору", - "material.gtceu.bronze": "Бронза", - "material.gtceu.butadiene": "Бутадієн", - "material.gtceu.butane": "Бутан", - "material.gtceu.butene": "Бутен", - "material.gtceu.butyraldehyde": "Бутаналь", - "material.gtceu.cadmium": "Кадмій", - "material.gtceu.caesium": "Цезій", - "material.gtceu.calcite": "Кальцит", - "material.gtceu.calcium": "Кальцій", - "material.gtceu.calcium_carbonate": "Карбонат кальцію", - "material.gtceu.calcium_chloride": "Хлорид кальцію", - "material.gtceu.calcium_ferrocyanide": "Фероцианід кальцію", - "material.gtceu.calcium_hydroxide": "Гідроксид кальцію", - "material.gtceu.calcium_phosphide": "Фосфід кальцію", - "material.gtceu.californium": "Каліфорній", - "material.gtceu.caprolactam": "Капролактам", - "material.gtceu.carbon": "Вуглець", - "material.gtceu.carbon_dioxide": "Діоксид вуглецю", - "material.gtceu.carbon_monoxide": "Монооксид вуглецю", - "material.gtceu.cassiterite": "Каситерит", - "material.gtceu.cassiterite_sand": "Каситеритовий пісок", - "material.gtceu.cerium": "Церій", - "material.gtceu.certus_quartz": "Істинний кварц", - "material.gtceu.cetane_boosted_diesel": "Високоцитанове дизельне паливо", - "material.gtceu.chalcocite": "Халькозин", - "material.gtceu.chalcopyrite": "Халькопірит", - "material.gtceu.charcoal": "Деревне вугілля", - "material.gtceu.charcoal_byproducts": "Побічні продукти з деревного вугілля", - "material.gtceu.chlorine": "Хлор", - "material.gtceu.chlorobenzene": "Хлорбензен", - "material.gtceu.chloroform": "Хлороформ", - "material.gtceu.chloromethane": "Хлорометан", - "material.gtceu.chromite": "Хроміт", - "material.gtceu.chromium": "Хром", - "material.gtceu.chromium_trioxide": "Оксид хрому", - "material.gtceu.cinnabar": "Кіновар", - "material.gtceu.clay": "Глина", - "material.gtceu.coal": "Вугілля", - "material.gtceu.coal_gas": "Вугільний газ", - "material.gtceu.coal_tar": "Вугільна смола", - "material.gtceu.cobalt": "Кобальт", - "material.gtceu.cobalt_brass": "Кобальтова латунь", - "material.gtceu.cobalt_oxide": "Оксид кобальта", - "material.gtceu.cobaltite": "Кобальтит", - "material.gtceu.cocoa": "Какао", - "material.gtceu.coke": "Кокс", - "material.gtceu.collagen": "Колаген", - "material.gtceu.concrete": "Бетон", - "material.gtceu.construction_foam": "Будівельна піна", - "material.gtceu.copernicium": "Коперницій", - "material.gtceu.copper": "Мідь", - "material.gtceu.creosote": "Креозот", - "material.gtceu.cumene": "Кумен", - "material.gtceu.cupric_oxide": "Оксид міді", - "material.gtceu.cupronickel": "Мельхіор", - "material.gtceu.curium": "Кюрій", - "material.gtceu.cyclohexane": "Циклогексан", - "material.gtceu.cyclohexanone_oxime": "Циклогексанон оксім", - "material.gtceu.dark_ash": "Темний попіл", - "material.gtceu.darmstadtium": "Дармштадтій", - "material.gtceu.debrominated_brine": "Дебромована ропа", - "material.gtceu.hot_alkaline_debrominated_brine": "Гаряча лужна дебромована ропа", - "material.gtceu.hot_brine": "Гаряча ропа", - "material.gtceu.hot_chlorinated_brominated_brine": "Гаряча хлорована бромована ропа", - "material.gtceu.hot_debrominated_brine": "Гаряча дебромована ропа", - "material.gtceu.raw_brine": "Неочищена ропа", - "material.gtceu.deepslate": "Глибосланець", - "material.gtceu.depleted_uranium_hexafluoride": "Збіднений гексафторид урану", - "material.gtceu.enriched_uranium_hexafluoride": "Збагачений гексафторид урану", - "material.gtceu.uraninite": "Настуран", - "material.gtceu.uranium": "Уран", - "material.gtceu.uranium_235": "Уран 235", - "material.gtceu.uranium_hexafluoride": "Гексафторид урану", - "material.gtceu.uranium_rhodium_dinaquadide": "Уран родій динаквуадид", - "material.gtceu.uranium_triplatinum": "Уран триплатинум", - "material.gtceu.deuterium": "Дейтерій", - "material.gtceu.diaminobenzidine": "Діамінобензидин", - "material.gtceu.diamond": "Діамант", - "material.gtceu.diatomite": "Діатоміт", - "material.gtceu.dichlorobenzene": "Діхлорбензен", - "material.gtceu.dichlorobenzidine": "Діхлорбензідін", - "material.gtceu.dichloroethane": "Діхлоретан", - "material.gtceu.diesel": "Дизель", - "material.gtceu.diethylenetriamine": "Діетілентріамін", - "material.gtceu.diethylenetriamine_pentaacetonitrile": "Діетілентріамін пентаоцтонітріл", - "material.gtceu.diethylenetriaminepentaacetic_acid": "Діетілентріамінопентаоцтова кислота", - "material.gtceu.diluted_hydrochloric_acid": "Розбавлена соляна кислота", - "material.gtceu.hydrochloric_acid": "Соляна кислота", - "material.gtceu.diluted_sulfuric_acid": "Розбавлена cульфатна кислота", - "material.gtceu.sulfuric_acid": "Сульфатна кислота", - "material.gtceu.sulfuric_copper_solution": "Сульфатний розчин міді", - "material.gtceu.sulfuric_gas": "Сірчаний газ", - "material.gtceu.sulfuric_heavy_fuel": "Сірчане важке паливо", - "material.gtceu.sulfuric_light_fuel": "Сірчане легке паливо", - "material.gtceu.sulfuric_naphtha": "Сірчаний лігроїн", - "material.gtceu.sulfuric_nickel_solution": "Сульфатний розчин нікелю", - "material.gtceu.dimethylamine": "Диметиламін", - "material.gtceu.dimethylbenzene": "Диметилбензен", - "material.gtceu.dimethyldichlorosilane": "Диметилдихлорсилан", - "material.gtceu.dimethylhydrazine": "Диметилгідразин", - "material.gtceu.dinitrogen_tetroxide": "Азотний тетраоксид", - "material.gtceu.diorite": "Діорит", - "material.gtceu.diphenyl_isophthalate": "Діфеніл ізофталат", - "material.gtceu.dissolved_calcium_acetate": "Розчинений ацетат кальцію", - "material.gtceu.distilled_water": "Дистильована вода", - "material.gtceu.drilling_fluid": "Бурильна рідина", - "material.gtceu.dubnium": "Дубній", - "material.gtceu.duranium": "Дюраній", - "material.gtceu.dysprosium": "Диспрозій", - "material.gtceu.echo_shard": "Уламок відлуння", - "material.gtceu.einsteinium": "Ейнштейній", - "material.gtceu.electrotine": "Електротин", - "material.gtceu.electrum": "Електрум", - "material.gtceu.emerald": "Смарагд", - "material.gtceu.ender_air": "Повітря енду", - "material.gtceu.ender_eye": "Око енду", - "material.gtceu.ender_pearl": "Перлина енду", - "material.gtceu.endstone": "Камінь енду", - "material.gtceu.epichlorohydrin": "Епіхлоргідрин", - "material.gtceu.epoxy": "Епоксидна суміш", - "material.gtceu.erbium": "Ербій", - "material.gtceu.ethane": "Етан", - "material.gtceu.ethanol": "Етанол", - "material.gtceu.ethenone": "Етенон", - "material.gtceu.ethyl_tertbutyl_ether": "Метилтретинний бутиловий етер", - "material.gtceu.ethylbenzene": "Етилбензен", - "material.gtceu.ethylene": "Етилен", - "material.gtceu.europium": "Європій", - "material.gtceu.fermented_biomass": "Ферментована біомаса", - "material.gtceu.fermium": "Фермій", - "material.gtceu.ferrosilite": "Феросиліт", - "material.gtceu.fireclay": "Шамот", - "material.gtceu.fish_oil": "Риб'ячий жир", - "material.gtceu.flerovium": "Флеровій", - "material.gtceu.flint": "Кремінь", - "material.gtceu.fluorine": "Фтор", - "material.gtceu.fluoroantimonic_acid": "Фторантимонова кислота", - "material.gtceu.formaldehyde": "Формальдегід", - "material.gtceu.formamide": "Формамід", - "material.gtceu.formic_acid": "Мурашина кислота", - "material.gtceu.francium": "Францій", - "material.gtceu.fullers_earth": "Відбілювальні глини", - "material.gtceu.gadolinium": "Гадоліній", - "material.gtceu.galena": "Галеніт", - "material.gtceu.gallium": "Галій", - "material.gtceu.gallium_arsenide": "Арсенід галію", - "material.gtceu.gallium_sulfide": "Сульфід галію", - "material.gtceu.garnet_sand": "Гранатовий пісок", - "material.gtceu.garnierite": "Гранетит", - "material.gtceu.gasoline": "Бензин", - "material.gtceu.high_octane_gasoline": "Високооктановий безин", - "material.gtceu.raw_gasoline": "Сирий бензин", - "material.gtceu.gelatin": "Желатин", - "material.gtceu.germanium": "Германій", - "material.gtceu.glass": "Скло", - "material.gtceu.glauconite_sand": "Глауконітове скло", - "material.gtceu.glowstone": "Світлокамінь", - "material.gtceu.glue": "Клей", - "material.gtceu.glycerol": "Гліцерол", - "material.gtceu.glyceryl_trinitrate": "Гліцерил тринітрат", - "material.gtceu.glycolonitrile": "Гліконітрил", - "material.gtceu.goethite": "Ґетит", - "material.gtceu.gold": "Золото", - "material.gtceu.granite": "Граніт", - "material.gtceu.granite_red": "Червоний граніт", - "material.gtceu.granitic_mineral_sand": "Гранітний мінеральний пісок", - "material.gtceu.graphene": "Графен", - "material.gtceu.graphite": "Графіт", - "material.gtceu.green_sapphire": "Зелений сапфір", - "material.gtceu.green_sapphire_slurry": "Зелено-сапфірова суспензія", - "material.gtceu.grossular": "Гросуляр", - "material.gtceu.gunpowder": "Порох", - "material.gtceu.gypsum": "Гіпс", - "material.gtceu.hafnium": "Гафній", - "material.gtceu.hassium": "Гасій", - "material.gtceu.hastelloy_c_276": "Хастелой C-276", - "material.gtceu.hastelloy_x": "Хастелой X", - "material.gtceu.heavy_fuel": "Важке паливо", - "material.gtceu.oil_heavy": "Важка нафта", - "material.gtceu.helium": "Гелій", - "material.gtceu.helium_3": "Гелій 3", - "material.gtceu.hematite": "Гематит", - "material.gtceu.holmium": "Holmium", - "material.gtceu.hsse": "HSS-E", - "material.gtceu.hssg": "HSS-G", - "material.gtceu.hsss": "HSS-S", - "material.gtceu.hydrofluoric_acid": "Флуоридна кислота", - "material.gtceu.hydrogen": "Водень", - "material.gtceu.hydrogen_cyanide": "Синильна кислота", - "material.gtceu.hydrogen_iodide": "Йодоводень", - "material.gtceu.hydrogen_sulfide": "Сірководень", - "material.gtceu.hypochlorous_acid": "Гіпохлоритна кислота", - "material.gtceu.ice": "Лід", - "material.gtceu.ilmenite": "Ільменіт", - "material.gtceu.incoloy_ma_956": "Incoloy MA-956", - "material.gtceu.indium": "Індій", - "material.gtceu.indium_concentrate": "Концентрат індію", - "material.gtceu.indium_gallium_phosphide": "Фосфід індію-галію", - "material.gtceu.indium_phosphide": "Фосфід індію", - "material.gtceu.indium_tin_barium_titanium_cuprate": "Індій олово барій титановий купорос", - "material.gtceu.invar": "Інвар", - "material.gtceu.iodine": "Йод", - "material.gtceu.iridium": "Іридій", - "material.gtceu.iridium_chloride": "Хлорид іридію", - "material.gtceu.iridium_metal_residue": "Залишок ірідієвого металу", - "material.gtceu.iron": "Залізо", - "material.gtceu.iron_ii_chloride": "Хлорид заліза (II)", - "material.gtceu.iron_iii_chloride": "Хлорид заліза (III)", - "material.gtceu.isoprene": "Ізопрен", - "material.gtceu.kanthal": "Канталь", - "material.gtceu.krypton": "Криптон", - "material.gtceu.kyanite": "Кіаніт", - "material.gtceu.lanthanum": "Лантан", - "material.gtceu.lapis": "Лазурит", - "material.gtceu.lapotron": "Лапотрон", - "material.gtceu.lava": "Лава", - "material.gtceu.lawrencium": "Лоуренсій", - "material.gtceu.lazurite": "Лазурит", - "material.gtceu.lead": "Свинець", - "material.gtceu.lead_zinc_solution": "Свинцево-цинкова суміш", - "material.gtceu.lepidolite": "Лепідоліт", - "material.gtceu.light_fuel": "Легке паливо", - "material.gtceu.oil_light": "Легка нафта", - "material.gtceu.hydro_cracked_butadiene": "Водневокрекінговий бутадієн", - "material.gtceu.hydro_cracked_butane": "Водневокрекінговий бутан", - "material.gtceu.hydro_cracked_butene": "Водневокрекінговий бутен", - "material.gtceu.hydro_cracked_ethane": "Водневокрекінговий етан", - "material.gtceu.hydro_cracked_ethylene": "Водневокрекінговий етилен", - "material.gtceu.hydro_cracked_propane": "Водневокрекінговий пропан", - "material.gtceu.hydro_cracked_propene": "Водневокрекінговий пропен", - "material.gtceu.lightly_hydro_cracked_gas": "Легко-водневокрекінговий газ", - "material.gtceu.lightly_hydro_cracked_heavy_fuel": "Легко-водневокрекінговий важке паливо", - "material.gtceu.lightly_hydro_cracked_light_fuel": "Легко-водневокрекінговий легке паливо", - "material.gtceu.lightly_hydro_cracked_naphtha": "Легко-водневокрекінговий лігроїн", - "material.gtceu.lightly_steam_cracked_gas": "Легко-парокрекінговий газ", - "material.gtceu.lightly_steam_cracked_heavy_fuel": "Легко-парокрекінговий важке паливо", - "material.gtceu.lightly_steam_cracked_light_fuel": "Легко-парокрекінговий легке паливо", - "material.gtceu.lightly_steam_cracked_naphtha": "Легко-парокрекінговий лігроїн", - "material.gtceu.severely_hydro_cracked_gas": "Сильно-водневокрекінговий газ", - "material.gtceu.severely_hydro_cracked_heavy_fuel": "Сильно-водневокрекінговий важке паливо", - "material.gtceu.severely_hydro_cracked_light_fuel": "Сильно-водневокрекінговий легке паливо", - "material.gtceu.severely_hydro_cracked_naphtha": "Сильно-водневокрекінговий лігроїн", - "material.gtceu.severely_steam_cracked_gas": "Сильно-парокрекінговий газ", - "material.gtceu.severely_steam_cracked_heavy_fuel": "Сильно-парокрекінговий важке паливо", - "material.gtceu.severely_steam_cracked_light_fuel": "Сильно-парокрекінговий легке паливо", - "material.gtceu.severely_steam_cracked_naphtha": "Сильно-парокрекінговий лігроїн", - "material.gtceu.steam_cracked_butadiene": "Парокрекінговий бутадієн", - "material.gtceu.steam_cracked_butane": "Парокрекінговий бутан", - "material.gtceu.steam_cracked_butene": "Парокрекінговий бутен", - "material.gtceu.steam_cracked_ethane": "Парокрекінговий етан", - "material.gtceu.steam_cracked_ethylene": "Парокрекінговий етилен", - "material.gtceu.steam_cracked_propane": "Парокрекінговий пропан", - "material.gtceu.steam_cracked_propene": "Парокрекінговий пропен", - "material.gtceu.liquid_air": "Рідке повітря", - "material.gtceu.liquid_ender_air": "Рідке повітря енду", - "material.gtceu.liquid_nether_air": "Рідке повітря Незеру", - "material.gtceu.lithium": "Літій", - "material.gtceu.lithium_chloride": "Хлорид літію", - "material.gtceu.livermorium": "Ліверморій", - "material.gtceu.lpg": "ЗНГ", - "material.gtceu.lubricant": "Мастило", - "material.gtceu.lutetium": "Лютецій", - "material.gtceu.magnalium": "Магналій", - "material.gtceu.magnesia": "Периклаз", - "material.gtceu.magnesite": "Магнезит", - "material.gtceu.magnesium": "Магнезій", - "material.gtceu.magnesium_chloride": "Хлорид магнезію", - "material.gtceu.magnesium_diboride": "Диборид магнію", - "material.gtceu.magnetic_iron": "Магнітне залізо", - "material.gtceu.magnetic_neodymium": "Магнітний неодим", - "material.gtceu.magnetic_samarium": "Магнітний самарій", - "material.gtceu.black_steel": "Чорна сталь", - "material.gtceu.blue_steel": "Синя сталь", - "material.gtceu.red_steel": "Червона сталь", - "material.gtceu.damascus_steel": "Дамаск", - "material.gtceu.hsla_steel": "HSLA-сталь", - "material.gtceu.magnetic_steel": "Магнітна сталь", - "material.gtceu.maraging_steel_300": "Марагенова сталь 300", - "material.gtceu.stainless_steel": "Нержавіюча сталь", - "material.gtceu.steel": "Сталь", - "material.gtceu.vanadium_steel": "Ванадієва сталь", - "material.gtceu.watertight_steel": "Водонепроникна сталь", - "material.gtceu.magnetite": "Магнетит", - "material.gtceu.malachite": "Малахіт", - "material.gtceu.manganese": "Манган", - "material.gtceu.manganese_phosphide": "Фосфід мангану", - "material.gtceu.marble": "Мармур", - "material.gtceu.massicot": "Масикот", - "material.gtceu.mc_guffium_239": "МакГаффін 239", - "material.gtceu.meat": "М'ясо", - "material.gtceu.meitnerium": "Майтнерій", - "material.gtceu.mendelevium": "Менделевій", - "material.gtceu.mercury": "Ртуть", - "material.gtceu.mercury_barium_calcium_cuprate": "Ртуть барій кальцієвий купорос", - "material.gtceu.ferrite_mixture": "Суміш феритів", - "material.gtceu.gelatin_mixture": "Желатинова суміш", - "material.gtceu.inert_metal_mixture": "Суміш інертних металів", - "material.gtceu.metal_mixture": "Суміш металів", - "material.gtceu.nitration_mixture": "Нітратна суміш", - "material.gtceu.rarest_metal_mixture": "Суміш найрідкісніших металів", - "material.gtceu.methane": "Метан", - "material.gtceu.methanol": "Метанол", - "material.gtceu.methyl_acetate": "Метилацетат", - "material.gtceu.mica": "Слюда", - "material.gtceu.milk": "Молоко", - "material.gtceu.mirabilite": "Мірабіліт", - "material.gtceu.molybdenite": "Молібденіт", - "material.gtceu.molybdenum": "Молібден", - "material.gtceu.molybdenum_disilicide": "Дисиліцид молібдену", - "material.gtceu.monazite": "Монацит", - "material.gtceu.monochloramine": "Хлорамін", - "material.gtceu.moscovium": "Московій", - "material.gtceu.mutagen": "Мутаген", - "material.gtceu.naphtha": "Лігроїн", - "material.gtceu.naphthalene": "Нафтален", - "material.gtceu.natural_gas": "Природній газ", - "material.gtceu.neodymium": "Неодим", - "material.gtceu.neon": "Неон", - "material.gtceu.neptunium": "Нептуній", - "material.gtceu.nether_air": "Незерське повітря", - "material.gtceu.nether_quartz": "Незерський кварц", - "material.gtceu.nether_star": "Зірка Незеру", - "material.gtceu.netherite": "Незерит", - "material.gtceu.netherrack": "Незерак", - "material.gtceu.neutronium": "Нейтроній", - "material.gtceu.nichrome": "Ніхром", - "material.gtceu.nickel": "Нікель", - "material.gtceu.nickel_zinc_ferrite": "Ферит нікелю-цинку", - "material.gtceu.nihonium": "Ніхоній", - "material.gtceu.niobium": "Ніобій", - "material.gtceu.niobium_nitride": "Нітрит ніобію", - "material.gtceu.niobium_titanium": "Ніобій-титан", - "material.gtceu.nitric_acid": "Нітратна кислота", - "material.gtceu.nitric_oxide": "Монооксид азоту", - "material.gtceu.nitrobenzene": "Нітробензен", - "material.gtceu.nitrochlorobenzene": "Нітрохлоробензен", - "material.gtceu.nitrogen": "Азот", - "material.gtceu.nitrogen_dioxide": "Діоксид азоту", - "material.gtceu.nitrosyl_chloride": "Хлорид нітрозила", - "material.gtceu.nitrous_oxide": "Оксид азоту (I)", - "material.gtceu.nobelium": "Нобелій", - "material.gtceu.obsidian": "Обсидіан", - "material.gtceu.octane": "Октан", - "material.gtceu.oganesson": "Оґанесон", - "material.gtceu.oil": "Нафта", - "material.gtceu.oilsands": "Нафтоносні піски", - "material.gtceu.olivine": "Олівін", - "material.gtceu.opal": "Опал", - "material.gtceu.osmiridium": "Осмиридій", - "material.gtceu.osmium": "Осмій", - "material.gtceu.osmium_tetroxide": "Оксид осмію", - "material.gtceu.oxygen": "Кисень", - "material.gtceu.palladium": "Паладій", - "material.gtceu.palladium_raw": "Необроблений паладій", - "material.gtceu.paper": "Папір", - "material.gtceu.paracetamol": "Парацетамол", - "material.gtceu.pcb_coolant": "ДП-охолоджуюча рідина", - "material.gtceu.pentlandite": "Пентландит", - "material.gtceu.perlite": "Перліт", - "material.gtceu.phenol": "Фенол", - "material.gtceu.phosphate": "Фосфат", - "material.gtceu.phosphoric_acid": "Ортофосфатна кислота", - "material.gtceu.phosphorus": "Фосфор", - "material.gtceu.phosphorus_pentoxide": "Оксид фосфору (V)", - "material.gtceu.phthalic_acid": "Фталева кислота", - "material.gtceu.pitchblende": "Настуран", - "material.gtceu.platinum": "Платина", - "material.gtceu.platinum_group_sludge": "Шлам платинової групи", - "material.gtceu.platinum_raw": "Необроблена платина", - "material.gtceu.platinum_sludge_residue": "Залишок платинового шламу", - "material.gtceu.plutonium": "Плутоній", - "material.gtceu.plutonium_241": "Плутоній 241", - "material.gtceu.pollucite": "Поллуцит", - "material.gtceu.polonium": "Полоній", - "material.gtceu.polybenzimidazole": "Полібензимідазол", - "material.gtceu.polycaprolactam": "Полікапролактам", - "material.gtceu.polychlorinated_biphenyl": "Поліхлорований дифеніл", - "material.gtceu.polydimethylsiloxane": "Полідиметилсилоксан", - "material.gtceu.polyethylene": "Поліетилен", - "material.gtceu.polyphenylene_sulfide": "Сульфід поліфенілену", - "material.gtceu.polytetrafluoroethylene": "Політетрафторетилен", - "material.gtceu.polyvinyl_acetate": "Полівінілацетат", - "material.gtceu.polyvinyl_butyral": "Полівінілбутирал", - "material.gtceu.polyvinyl_chloride": "Полівінілхлорид", - "material.gtceu.potash": "Карбонат калію", - "material.gtceu.potassium": "Калій", - "material.gtceu.potassium_carbonate": "Карбонат калію", - "material.gtceu.potassium_cyanide": "Ціанід калію", - "material.gtceu.potassium_dichromate": "Дихромат калію", - "material.gtceu.potassium_feldspar": "Пертит", - "material.gtceu.potassium_ferrocyanide": "Гексаціаноферат(II) калію", - "material.gtceu.potassium_hydroxide": "Гідроксид калію", - "material.gtceu.potassium_iodide": "Йодид калію", - "material.gtceu.potassium_sulfate": "Сульфат калію", - "material.gtceu.potin": "Потін", - "material.gtceu.powellite": "Повеліт", - "material.gtceu.praseodymium": "Празеодим", - "material.gtceu.promethium": "Прометій", - "material.gtceu.propane": "Пропан", - "material.gtceu.propene": "Пропен", - "material.gtceu.protactinium": "Протактиній", - "material.gtceu.prussian_blue": "Берлінська лазур", - "material.gtceu.pyrite": "Пірит", - "material.gtceu.pyrochlore": "Пірохлорид", - "material.gtceu.pyrolusite": "Піролюзит", - "material.gtceu.pyrope": "Піроп", - "material.gtceu.quartz_sand": "Кварцовий пісок", - "material.gtceu.quartzite": "Кварцит", - "material.gtceu.quicklime": "Оксид кальцію", - "material.gtceu.rad_away": "Антирадин", - "material.gtceu.radium": "Радій", - "material.gtceu.radon": "Радон", - "material.gtceu.rare_earth": "Рідкісноземельний пил", - "material.gtceu.raw_growth_medium": "Сире живильне середовище", - "material.gtceu.sterilized_growth_medium": "Стерилізоване живильне середовище", - "material.gtceu.oil_medium": "Сира нафта", - "material.gtceu.raw_rubber": "Сира гума", - "material.gtceu.raw_styrene_butadiene_rubber": "Сира бутаден-стирольна гума", - "material.gtceu.rubber": "Гума", - "material.gtceu.silicone_rubber": "Силіконова гума", - "material.gtceu.styrene_butadiene_rubber": "Бутаден-стирольна гума", - "material.gtceu.realgar": "Реальгар", - "material.gtceu.red_garnet": "Червоний гранат", - "material.gtceu.redrock": "Червоний камінь", - "material.gtceu.redstone": "Редстоун", - "material.gtceu.refinery_gas": "Нафтопереробний газ", - "material.gtceu.reinforced_epoxy_resin": "Посилена епоксидна смола", - "material.gtceu.rhenium": "Реній", - "material.gtceu.rhodium": "Родій", - "material.gtceu.rhodium_plated_palladium": "Паладій з родієвим покриттям", - "material.gtceu.rhodium_sulfate": "Сульфат родію", - "material.gtceu.rock_salt": "Кам'яна сіль", - "material.gtceu.rocket_fuel": "Ракетне паливо", - "material.gtceu.roentgenium": "Рентгеній", - "material.gtceu.rose_gold": "Рожеве золото", - "material.gtceu.rubidium": "Рубідій", - "material.gtceu.ruby": "Рубін", - "material.gtceu.ruby_slurry": "Рубінова суспензія", - "material.gtceu.ruridit": "Рурідіт", - "material.gtceu.ruthenium": "Рутеній", - "material.gtceu.ruthenium_tetroxide": "Оксид рутенію(VIII)", - "material.gtceu.rutherfordium": "Резерфордій", - "material.gtceu.rutile": "Рутил", - "material.gtceu.salt": "Сіль", - "material.gtceu.salt_water": "Солона вода", - "material.gtceu.saltpeter": "Селітра", - "material.gtceu.samarium": "Самарій", - "material.gtceu.samarium_iron_arsenic_oxide": "Самарій залізо арсеновий оксід", - "material.gtceu.sapphire": "Сапфір", - "material.gtceu.sapphire_slurry": "Сапфірова суспензія", - "material.gtceu.scandium": "Скандій", - "material.gtceu.scheelite": "Шеєліт", - "material.gtceu.sculk": "Скалк", - "material.gtceu.seaborgium": "Мореродень", - "material.gtceu.seed_oil": "Рослинна олія", - "material.gtceu.selenium": "Селен", - "material.gtceu.cooperite": "Шелдоніт", - "material.gtceu.silicon": "Кремній", - "material.gtceu.silicon_dioxide": "Діоксид кремнію", - "material.gtceu.silver": "Срібло", - "material.gtceu.soapstone": "Стеатит", - "material.gtceu.soda_ash": "Кальцинована сода", - "material.gtceu.sodalite": "Содаліт", - "material.gtceu.sodium": "Натрій", - "material.gtceu.sodium_bicarbonate": "Гідрокарбонат натрію", - "material.gtceu.sodium_bisulfate": "Гідросульфат натрію", - "material.gtceu.sodium_hydroxide": "Гідроксид натрію", - "material.gtceu.sodium_nitrite": "Нітрит натрію", - "material.gtceu.sodium_persulfate": "Пероксодисульфат натрію", - "material.gtceu.sodium_potassium": "Натрій-калій", - "material.gtceu.sodium_sulfide": "Сульфід натрію", - "material.gtceu.spessartine": "Спесартин", - "material.gtceu.sphalerite": "Сфалерит", - "material.gtceu.spodumene": "Сподумен", - "material.gtceu.steam": "Пара", - "material.gtceu.stellite_100": "Стелліт-100", - "material.gtceu.sterling_silver": "Стерлінгове срібло", - "material.gtceu.stibnite": "Антимоніт", - "material.gtceu.stone": "Камінь", - "material.gtceu.strontium": "Стронцій", - "material.gtceu.styrene": "Стирол", - "material.gtceu.sugar": "Цукор", - "material.gtceu.sulfur": "Сірка", - "material.gtceu.sulfur_dioxide": "Діоксид сірки", - "material.gtceu.sulfur_trioxide": "Триоксид сірки", - "material.gtceu.talc": "Тальк", - "material.gtceu.tantalite": "Танталіт", - "material.gtceu.tantalum": "Тантал", - "material.gtceu.tantalum_carbide": "Карбід танталу", - "material.gtceu.technetium": "Технецій", - "material.gtceu.tellurium": "Телур", - "material.gtceu.tennessine": "Теннессин", - "material.gtceu.terbium": "Тербій", - "material.gtceu.tetrafluoroethylene": "Тетрафторетилен", - "material.gtceu.tetrahedrite": "Тетраедрит", - "material.gtceu.tetranitromethane": "Тетранітрометан", - "material.gtceu.thallium": "Талій", - "material.gtceu.thorium": "Торій", - "material.gtceu.thulium": "Тулій", - "material.gtceu.tin": "Олово", - "material.gtceu.titanium": "Титан", - "material.gtceu.titanium_carbide": "Карбід титану", - "material.gtceu.titanium_tetrachloride": "Хлорид титану(IV)", - "material.gtceu.titanium_trifluoride": "Фторид титану(III)", - "material.gtceu.titanium_tungsten_carbide": "Карбід вольфрам-титану", - "material.gtceu.toluene": "Толуен", - "material.gtceu.topaz": "Топаз", - "material.gtceu.treated_wood": "Оброблена деревина", - "material.gtceu.tricalcium_phosphate": "Ортофосфат кальцію", - "material.gtceu.tritanium": "Тританій", - "material.gtceu.tritium": "Тритій", - "material.gtceu.trona": "Трона", - "material.gtceu.tungstate": "Вольфрамат", - "material.gtceu.tungsten": "Вольфрам", - "material.gtceu.tungsten_carbide": "Карбід вольфраму", - "material.gtceu.tungsten_steel": "Вольфрамова сталь", - "material.gtceu.tungstic_acid": "Вольфрамова кислота", - "material.gtceu.ultimet": "Ультимет", - "material.gtceu.uu_matter": "UU-матерія", - "material.gtceu.uvarovite": "Уваровіт", - "material.gtceu.vanadium": "Ванадій", - "material.gtceu.vanadium_gallium": "Галід ванадію", - "material.gtceu.vanadium_magnetite": "Ванадієвий магнетит", - "material.gtceu.vinyl_acetate": "Вінілацетат", - "material.gtceu.vinyl_chloride": "Вінілхлорид", - "material.gtceu.water": "Вода", - "material.gtceu.wax": "Віск", - "material.gtceu.wheat": "Пшениця", - "material.gtceu.wood": "Деревина", - "material.gtceu.wood_gas": "Деревний газ", - "material.gtceu.wood_tar": "Деревна смола", - "material.gtceu.wood_vinegar": "Деревний оцет", - "material.gtceu.wrought_iron": "Коване залізо", - "material.gtceu.wulfenite": "Вульфеніт", - "material.gtceu.xenon": "Ксенон", - "material.gtceu.yellow_garnet": "Жовтий гранат", - "material.gtceu.yellow_limonite": "Жовтий лимоніт", - "material.gtceu.ytterbium": "Ітербій", - "material.gtceu.yttrium": "Ітрій", - "material.gtceu.yttrium_barium_cuprate": "Ітрій-барієвий купорос", - "material.gtceu.zeolite": "Цеоліт", - "material.gtceu.zeron_100": "Zeron-100", - "material.gtceu.zinc": "Цинк", - "material.gtceu.zinc_sulfide": "Сульфід цинку", - "material.gtceu.zincite": "Цинкіт", - "material.gtceu.zirconium": "Цирконій", - - "gtceu.jei.bedrock_fluid.heavy_oil_deposit": "Поклад важкої нафти", - "gtceu.jei.bedrock_fluid.lava_deposit": "Поклад лави", - "gtceu.jei.bedrock_fluid.light_oil_deposit": "Поклад легкої нафти", - "gtceu.jei.bedrock_fluid.natural_gas_deposit": "Поклад природього газу", - "gtceu.jei.bedrock_fluid.nether_natural_gas_deposit": "Незерський поклад природього газу", - "gtceu.jei.bedrock_fluid.oil_deposit": "Поклад нафти", - "gtceu.jei.bedrock_fluid.raw_oil_deposit": "Поклад сирої нафти", - "gtceu.jei.bedrock_fluid.salt_water_deposit": "Поклад солоної води", - "gtceu.jei.bedrock_fluid_diagram": "Діаграма глибокореневих рідин", - "gtceu.jei.bedrock_ore_diagram": "Діаграма глибокореневих руд", - "gtceu.jei.fluid.dep_amount_hover": "На який обсяг буде виснажено поклад", - "gtceu.jei.fluid.dep_chance_hover": "Відсоткова ймовірність того, що поклад буде виснажено під час збору", - "gtceu.jei.fluid.dep_yield_hover": "Максимальний видобуток з поклади при її повному виснаженні", - "gtceu.jei.fluid.depleted_rate": "Максимальний видобуток: %d", - "gtceu.jei.fluid.depletion_amount": "Обсяг покладу: %d", - "gtceu.jei.fluid.depletion_chance": "Шанс видобутку: %d%%", - "gtceu.jei.fluid.dimension": "Виміри:", - "gtceu.jei.fluid.max_hover": "Максимальний видобуток, який може мати будь-який поклад цієї рідини", - "gtceu.jei.fluid.min_hover": "Мінімальний видобуток, який може мати будь-який поклад цієї рідини", - "gtceu.jei.fluid.max_yield": "Максимальний видобуток: %d", - "gtceu.jei.fluid.min_yield": "Мінімальний видобуток: %d", - "gtceu.jei.fluid.vein_weight": "Вага жили: %d", - "gtceu.jei.fluid.weight_hover": "Вага жили. Наведіться на рідину, щоб побачити всі можливі модифікації біома", - "gtceu.jei.materials.average_mass": "Середня маса: %d", - "gtceu.jei.materials.average_neutrons": "В серед. нейтронів: %d", - "gtceu.jei.materials.average_protons": "В серед. протонів: %d", - "gtceu.jei.multiblock_info": "Інфо про конструкцію", - "gtceu.jei.ore.between.0": "Внутрішня руда", - "gtceu.jei.ore.between.1": "Генерується у середині %d шарів поклади разом з іншими рудами", - "gtceu.jei.ore.biome_weighting": "Вага§d %s:§3 %d", - "gtceu.jei.ore.biome_weighting_no_spawn": "Вага§d %s:§c Не може зненеруватися", - "gtceu.jei.ore.biome_weighting_title": "§dЗагальна вага модифікованого біома:", - "gtceu.jei.ore.ore_weight": "Вага у жилі: %d%%", - "gtceu.jei.ore.primary.0": "Верхня руда", - "gtceu.jei.ore.primary.1": "Генерується зверху %d шарів жили", - "gtceu.jei.ore.secondary.0": "Нижня руда", - "gtceu.jei.ore.secondary.1": "Генерується знизу %d шарів жили", - "gtceu.jei.ore.sporadic.0": "Спорадична руда", - "gtceu.jei.ore.sporadic.1": "Генерується по всій жилі", - "gtceu.jei.ore.surface_rock.0": "Поверхневі утворення з цим матеріалом позначають місця генерації жил.", - "gtceu.jei.ore.surface_rock.1": "Їх можна розбити, щоб отримати 3-5 крихт пилу, та ще більше із удачею.", - "gtceu.jei.ore_processing_diagram": "Послідовна рудообробка", - "gtceu.jei.ore_vein.apatite_vein": "Апатитова жила", - "gtceu.jei.ore_vein.banded_iron_vein": "Стрічкова залізна жила", - "gtceu.jei.ore_vein.bauxite_vein_end": "Бокситова жила енду", - "gtceu.jei.ore_vein.beryllium_vein": "Берилієва жила", - "gtceu.jei.ore_vein.cassiterite_vein": "Каситеритова жила", - "gtceu.jei.ore_vein.certus_quartz": "Істинний кварц", - "gtceu.jei.ore_vein.coal_vein": "Вугільна жила", - "gtceu.jei.ore_vein.copper_tin_vein": "Мідно-олов'яна жила", - "gtceu.jei.ore_vein.copper_vein": "Мідна жила", - "gtceu.jei.ore_vein.diamond_vein": "Діамантова жила", - "gtceu.jei.ore_vein.galena_vein": "Галенова жила", - "gtceu.jei.ore_vein.garnet_tin_vein": "Гранатово-олов'яна жила", - "gtceu.jei.ore_vein.garnet_vein": "Гранатова жила", - "gtceu.jei.ore_vein.iron_vein": "Залізна жила", - "gtceu.jei.ore_vein.lapis_vein": "Лазуритова жила", - "gtceu.jei.ore_vein.lubricant_vein": "Мастильна жила", - "gtceu.jei.ore_vein.magnetite_vein_end": "Магнетитова жила енду", - "gtceu.jei.ore_vein.magnetite_vein_ow": "Магнетитова жила вС", - "gtceu.jei.ore_vein.manganese_vein": "Марганцева жила", - "gtceu.jei.ore_vein.manganese_vein_ow": "Марганцева жила вС", - "gtceu.jei.ore_vein.mica_vein": "Слюдяна жила", - "gtceu.jei.ore_vein.mineral_sand_vein": "Жила мінерального піску", - "gtceu.jei.ore_vein.molybdenum_vein": "Молібденова жила", - "gtceu.jei.ore_vein.monazite_vein": "Монацитова жила", - "gtceu.jei.ore_vein.naquadah_vein": "Наквадова жила", - "gtceu.jei.ore_vein.nether_quartz_vein": "Нижня кварцова жила", - "gtceu.jei.ore_vein.nickel_vein": "Нікелева жила", - "gtceu.jei.ore_vein.oilsands_vein": "Жила нафтоносних пісків", - "gtceu.jei.ore_vein.olivine_vein": "Олівінова жила", - "gtceu.jei.ore_vein.pitchblende_vein_end": "Настуранова жила енду", - "gtceu.jei.ore_vein.redstone_vein": "Редстоунова жила", - "gtceu.jei.ore_vein.redstone_vein_ow": "Редстоунова жила вС", - "gtceu.jei.ore_vein.saltpeter_vein": "Селітрова жила", - "gtceu.jei.ore_vein.salts_vein": "Соляна жила", - "gtceu.jei.ore_vein.sapphire_vein": "Сапфірова жила", - "gtceu.jei.ore_vein.scheelite_vein": "Шеєлітова жила", - "gtceu.jei.ore_vein.sheldonite_vein": "Шелдонітова жила", - "gtceu.jei.ore_vein.sulfur_vein": "Сірчана жила", - "gtceu.jei.ore_vein.tetrahedrite_vein": "Тетраедритна жила", - "gtceu.jei.ore_vein.topaz_vein": "Топазова жила", - "gtceu.jei.ore_vein_diagram": "Залягання руди", - "gtceu.jei.ore_vein_diagram.chance": "§eШанс: %s§r", - "gtceu.jei.ore_vein_diagram.dimensions": "Виміри:", - "gtceu.jei.ore_vein_diagram.spawn_range": "Висота залягання:", - "gtceu.jei.ore_vein_diagram.weight": "Вага: %s", - "gtceu.jei.programmed_circuit": "Сторінка програмної плати", - - "command.gtceu.medical_condition.get": "Гравець %s має такі медичні показання:", - "command.gtceu.medical_condition.get.element": "Ураження - %s§r: %s хвилин %s секунд", - "command.gtceu.medical_condition.get.element.permanent": "Ураження - %s§r: %s хвилин %s секунд (постійне)", - "command.gtceu.medical_condition.get.empty": "Гравець %s не має медичних показань.", - "gtceu.medical_condition.antidote.description": "§aПротиотрута§7 Утримуйте Shift для подробиць", - "gtceu.medical_condition.antidote.description.effect_removed": "Знешкоджує %s%% наявних ефектів уражень", - "gtceu.medical_condition.antidote.description.effect_removed.all": "Знешкоджує усі ураження", - "gtceu.medical_condition.antidote.description_shift": "§aВиліковує ці ураження:", - "gtceu.medical_condition.description": "§l§cНЕБЕЗПЕЧНО§7 Утримуйте Shift для подробиць", - "gtceu.medical_condition.description_shift": "§l§cНЕБЕЗПЕКА:", - "gtceu.medical_condition.arsenicosis": "§bОтруєння миш'яком", - "gtceu.medical_condition.asbestosis": "§dАзбестоз", - "gtceu.medical_condition.berylliosis": "§5Бериліоз", - "gtceu.medical_condition.carbon_monoxide_poisoning": "§7Отруєння монооксидом вуглецю", - "gtceu.medical_condition.carcinogen": "§eРадіоактивне опромінення", - "gtceu.medical_condition.chemical_burns": "§5Хімічні опіки", - "gtceu.medical_condition.irritant": "§6Подразення", - "gtceu.medical_condition.methanol_poisoning": "§6Отруєння метанолом", - "gtceu.medical_condition.nausea": "§3Нудота", - "gtceu.medical_condition.none": "§2(Не²)Безпечно", - "gtceu.medical_condition.poison": "§2Отрута", - "gtceu.medical_condition.silicosis": "§1Силікоз", - "gtceu.medical_condition.weak_poison": "§aСлабка отрута", - "gtceu.hazard_trigger.description": "Спричиняється:", - "gtceu.hazard_trigger.protection.description": "Захищає:", - "gtceu.hazard_trigger.any": "При будь-якому контакті", - "gtceu.hazard_trigger.inhalation": "При вдиханні", - "gtceu.hazard_trigger.skin_contact": "При контакті зі шкірою", - "gtceu.hazard_trigger.none": "Ніяк", - - "gtceu.oc.tooltip.0": "Мінімум: %s", - "gtceu.oc.tooltip.1": "ЛКМ, щоб збільшити розгін", - "gtceu.oc.tooltip.2": "ПКМ, щоб зменьшити розгін", - "gtceu.oc.tooltip.3": "СКМ, щоб скинути розгін", - "gtceu.oc.tooltip.4": "Утримуйте Shift, щоб змінювати ідеальний розгін", - "gtceu.tool_action.show_tooltips": "Утримуйте Shift, щоб показати інформацію інструмента", - "gtceu.tooltip.fluid_pipe_hold_shift": "§7Утримуйте Shift, щоб показати інформацію про наявну рідину", - "gtceu.tooltip.hold_shift": "§7Утримуйте Shift для більшої інформації", - "gtceu.tooltip.hold_ctrl": "§7Утримуйте Ctrl для більшої інформації", - "gtceu.tooltip.tool_fluid_hold_shift": "§7Утримуйте Shift, щоб показати інформацію інструмента та про наявну рідину", - "gui.widget.incrementButton.default_tooltip": "Утримуйте Shift, Ctrl чи обидва, щоб змінити кількість", - "gtceu.machine.cleanroom.tooltip.hold_ctrl": "Утримуйте CTRL, щоб показати додаткову інформацію конструкції", - "behaviour.lighter.tooltip.usage": "Shift+ПКМ, щоб відкрити/закрити", - "item.gtceu.tool.tooltip.repair_info": "§8Утримуйте Shift, щоб показати інформацію з ремонтування", - "block.gtceu.wire_coil.tooltip_extended_info": "§7Утримуйте Shift, щоб показати інформацію з бонусу котушки", - "metaitem.behavior.mode_switch.current_mode": "Режим: %s", - "metaitem.behavior.mode_switch.mode_switched": "§eРежим встановлено на: %s", - "metaitem.behavior.mode_switch.tooltip": "Використайте крадькома, щоб змінити режим", - "metaitem.clipboard.tooltip": "Можна записувати (без жодного інструменту для письма). клацніть ПКМ на стіні, щоб розмістити, і Shift+ПКМ, щоб видалити", - "metaitem.cover.digital.mode.energy.disabled": "Клацніть, щоб увімкнути режим енергії", - "metaitem.cover.digital.mode.energy.enabled": "Увімкнено режим енергії", - "metaitem.cover.digital.mode.fluid.disabled": "Клацніть, щоб увімкнути режим рідини", - "metaitem.cover.digital.mode.fluid.enabled": "Увімкнено режим рідини", - "metaitem.cover.digital.mode.item.disabled": "Клацніть, щоб увімкнути режим предметів", - "metaitem.cover.digital.mode.item.enabled": "Увімкнено режим предметів", - "metaitem.cover.digital.mode.machine.disabled": "Клацніть, щоб увімкнути режим машин", - "metaitem.cover.digital.mode.machine.enabled": "Увімкнено режим машин", - "metaitem.cover.digital.mode.proxy.disabled": "Клацніть, щоб увімкнути режим проксі", - "metaitem.cover.digital.mode.proxy.enabled": "Увімкнено режим проксі", - "metaitem.cover.digital.tooltip": "Під'єднує машини за допомогою§f кабелів живлення§7 до§f центрального монітора§7 у вигляді§f кришки§7.", - "metaitem.cover.digital.wireless.tooltip.0": "§fБездротово§7 під'єднує машини до§f центрального монітора§7 у вигляді§f кришки§7.", - "metaitem.cover.digital.wireless.tooltip.1": "§fПКМ§7 по§f центральному монітору§7 для віддаленої прив'язки до нього.", - "metaitem.cover.digital.wireless.tooltip.2": "§fПКМ крадькома§7 для видалення поточної прив'язки.", - "metaitem.cover.digital.wireless.tooltip.3": "§aПрив'язка:§f %s", - "metaitem.crushed.tooltip.purify": "Клацніть ПКМ по казану із водою, щоб отримати очищену руду", - "metaitem.debug_scanner.tooltip": "Трикодер", - "metaitem.tricorder_scanner.tooltip": "Трикодер", - "metaitem.dust.tooltip.purify": "ПКМ по казану, щоб отримати очищений пил", - "metaitem.electric.discharge_mode.disabled": "§eРежим розряджання вимкнено", - "metaitem.electric.discharge_mode.enabled": "§eРежим розряджання увімкнено", - "metaitem.electric.discharge_mode.tooltip": "Використовуйте крадькома, щоб змінити режим розряджання", - "metaitem.generic.electric_item.stored": "%d/%d EU (%s)", - "metaitem.generic.electric_item.tooltip": "%d/%d EU - рівень %s", - "item.gtceu.battery.charge_detailed": "%s/%s EU§7 - рівень %s§7 (залишилось %s/%s %s§7)", - "item.gtceu.battery.charge_time": "§aHolds %s %s of Power (%s)", - "item.gtceu.battery.charge_unit.hour": "годин", - "item.gtceu.battery.charge_unit.minute": "хвилин", - "item.gtceu.battery.charge_unit.second": "секунд", - "metaitem.generic.fluid_container.tooltip": "%d/%dЛ %s", - "metaitem.int_circuit.configuration": "Конфігурація: %d", - "metaitem.liquid_fuel_jetpack.tooltip": "Використовує паливо внутрішнього згоряння для створення тяги", - "metaitem.machine_configuration.mode": "§aНалаштований режим:§r %s", - "gtceu.mode.item": "§6Предмети§r", - "gtceu.mode.fluid": "§9Рідини§r", - "gtceu.mode.both": "§dСпільний (Рідини та предмети)§r", - "metaitem.plugin.proxy.tooltips.1": "(Будь ласка, налаштуйтеся на режим проксі на екрані)", - "metaitem.plugin.tooltips.1": "На екран можна додати плагіни для більшої функціональності.", - "metaitem.prospector.mode.bedrock_ore": "§bРежим розвідки глибокорінних руд§r", - "metaitem.prospector.mode.fluid": "§bРежим розвідки рідини§r", - "metaitem.prospector.mode.ores": "§aРежим розвідки руд§r", - "metaitem.prospector.tooltip.modes": "Доступні режими:", - "metaitem.prospector.tooltip.radius": "Діапазон сканування в радіусі %s чанків", - "metaitem.terminal.tooltip": "Гострі інструменти роблять гарну роботу", - "metaitem.terminal.tooltip.creative": "§bТворчий режим", - "metaitem.terminal.tooltip.hardware": "§aОбладнання: %d", - "metaitem.tool.tooltip.durability": "§fМіцність:§a %d / %d", - "metaitem.tool.tooltip.primary_material": "§fМатеріал:§e %s", - "metaitem.tool.tooltip.rotor.efficiency": "Ефективність турбіни:§9 %d%%", - "metaitem.tool.tooltip.rotor.power": "Потужність турбіни:§9 %d%%", - - "gtceu.fluid.gas_vapor": "%s (пара)", - "gtceu.fluid.plasma": "%s (плазма)", - "gtceu.fluid.gas_generic": "%s (газ)", - "gtceu.fluid.liquid_generic": "%s (рідина)", - "gtceu.fluid.molten": "%s (розплавлений)", - "gtceu.fluid.state_gas": "§aСтан: газоподібний", - "gtceu.fluid.state_liquid": "§aСтан: рідкий", - "gtceu.fluid.state_plasma": "§aСтан: плазма", - "gtceu.fluid.temperature": "§cТемпература: %d K", - "gtceu.fluid.temperature.cryogenic": "§bКріогенна небезпека! тримайте обережно!", - "gtceu.fluid.type_acid.tooltip": "§6Кислотна небезпека! тримайте обережно!", - "gtceu.fluid_pipe.not_gas_proof": "§4Можливий витік газів!", - "gtceu.fluid_pipe.acid_proof": "§6Може працювати з кислотами", - "gtceu.fluid_pipe.plasma_proof": "§6Може працювати з усіма видами плазми", - "gtceu.fluid_pipe.cryo_proof": "§6Може працювати з кріогенними речовинами", - "gtceu.fluid_pipe.gas_proof": "§6Може працювати з газами", - "gtceu.fluid.click_to_fill": "§7Клацніть контейнером з рідиною, щоб§b заповнити§7 бак (Shift-клік для повного стосу).", - "gtceu.fluid.click_combined": "§7Клацніть контейнером з рідиною, щоб§b спустошити§7 або§b заповнити§7 бак (Shift-клік для повного стосу).", - "gtceu.fluid.click_to_empty": "§7Клацніть контейнером з рідиною, щоб§b спустошити§7 бак (Shift-клік для повного стосу).", - "gtceu.fluid.amount": "§9Ємність: %d/%d мВ", - "gtceu.fluid_pipe.capacity": "§9Місткість:§f %d мВ", - "gtceu.fluid_pipe.max_temperature": "§cМежа температури:§f %d K", - "gtceu.fluid_pipe.channels": "§eКанали:§f %d", - "gtceu.fluid.empty": "Порожньо", - "gtceu.fluid.generic": "%s", - - "block.gtceu.long_distance_item_pipeline_input_pos": " - вхід: %s", - "block.gtceu.long_distance_item_pipeline_output_pos": " - вихід: %s", - "block.gtceu.long_distance_item_pipeline_pipe_count": " - труби: %s", - "block.gtceu.wire_coil.tooltip_energy_cracking": "§a використання енергії:§f %s%%", - "block.gtceu.wire_coil.tooltip_energy_smelter": "§a використання енергії:§f %s EU/т§8 за рецепт", - "block.gtceu.wire_coil.tooltip_parallel_smelter": "§5 Макс. паралелей:§f %s", - "block.gtceu.wire_coil.tooltip_speed_pyro": "§b Швидкість обробки:§f %s%%", - "gtceu.machine.world_accelerator.working_area_random": " режим випадкового такту:§f %dx%d", - "gtceu.machine.world_accelerator.working_area_tile": " режим блокової сутності:§f суміжних блоків", - "gtceu.top.energy_stored": " / %d EU", - "gtceu.top.progress_computation": " / %s ОРО", - "gtceu.top.progress_sec": " / %s с", - "gtceu.top.progress_tick": " / %s т", - "gtceu.machine.boiler.info.producing.steam": "§a (кип'яток)", - "gtceu.machine.boiler.info.cooling.down": "§9Оходження§r%s", - "gtceu.machine.boiler.info.heating.up": "§cНагрівання§r%s", - "gtceu.creative_tooltip.1": "§7Вам потрібен", - "gtceu.creative_tooltip.2": " творчий режим", - "gtceu.creative_tooltip.3": "§7, щоб використовувати це", - "gtceu.machine.hull.tooltip": "§7Просто проявіть§c у§eя§aв§9у§7, щоб використовувати це", - "block.gtceu.creative_chest": "Творча скриня", - "block.gtceu.creative_computation_provider": "Творчий постачальник обчислень", - "block.gtceu.creative_data_access_hatch": "Творчий люк доступу до даних", - "block.gtceu.creative_energy": "Творче джерело енергії", - "block.gtceu.creative_tank": "Творчий резервуар", - "gtceu.machine.power_substation.tooltip.0": "Серце централізованої енергосистеми", - "gtceu.machine.power_substation.tooltip.1": "§fАкумулятори§7 не обов'язково повинні бути одного рівня.", - "gtceu.machine.power_substation.tooltip.2": "Допускає до§f %d шарів акумуляторів§7.", - "gtceu.machine.power_substation.tooltip.3": "Втрачає енергію, що дорівнює§f 1%%§7 від загальної ємності кожні§f 24 години§7.", - "gtceu.machine.power_substation.tooltip.4": "Обмежено на рівні§f %d kEU/т§7 пасивних втрат на блок акумулятора.", - "gtceu.machine.power_substation.tooltip.5": "Може використовувати", - "gtceu.machine.power_substation.tooltip.6": " лазерні люки§7.", - "gtceu.machine.active_transformer.tooltip.0": "§7Трансформатори: замасковані лазери", - "gtceu.machine.active_transformer.tooltip.1": "§7Може об'єднати будь-яку кількість енергетичних§f входів§7 у будь-яку кількість енергетичних§f виходів§7.", - "gtceu.machine.active_transformer.tooltip.2": "§7Може передавати енергію на неймовірні відстані за допомогою", - "gtceu.machine.active_transformer.tooltip.3": " лазерів§7.", - "gtceu.jade.energy_stored": "%d / %d EU", - "gtceu.jade.progress_computation": "%s / %s ОРО", - "gtceu.jade.progress_sec": "%s / %s s", - "gtceu.jade.progress_tick": "%s / %s t", - "gtceu.jade.cleaned_this_second": "Очищена небезпека: %s/s", - "gtceu.tooltip.potion.each": "%s %s§7 на§r %s§7 тактів, який застосується із§r %s%%§7 ймовірністю§r", - "gtceu.tooltip.potion.header": "§6Містить ефекти:", - - "behaviour.setting.item_auto_output.tooltip": "%s автовиведення is %s", - "behaviour.setting.allow.input.from.output.tooltip": "%s вхід з вихідної сторони %s", - "behaviour.setting.output.direction.tooltip": "%s напрям виведення: %s", - "behaviour.meta.machine.config.paste.tooltip": "§7ПКМ щоб вставити конфігурацію машини", - "behaviour.meta.machine.config.copy.tooltip": "§7ПКМ щоб скопіювати конфігурацію машини", - "behaviour.soft_hammer": "Запускає та зупиняє магини", - "behaviour.boor.by": " %s", - "behaviour.lighter.tooltip.description": "Може підпалювати речі", - "behaviour.lighter.fluid.tooltip": "Може підпалювати речі за допомогою бутану або пропану", - "behaviour.paintspray.black.tooltip": "Фарбує речі в чорний", - "behaviour.paintspray.blue.tooltip": "Фарбує речі в синій", - "behaviour.paintspray.brown.tooltip": "Фарбує речі в коричневий", - "behaviour.paintspray.cyan.tooltip": "Фарбує речі в бірюзовий", - "behaviour.paintspray.gray.tooltip": "Фарбує речі в сірий", - "behaviour.paintspray.green.tooltip": "Фарбує речі в зелений", - "behaviour.paintspray.light_blue.tooltip": "Фарбує речі в блакитний", - "behaviour.paintspray.light_gray.tooltip": "Фарбує речі в світло-сірий", - "behaviour.paintspray.lime.tooltip": "Фарбує речі в лаймовий", - "behaviour.paintspray.magenta.tooltip": "Фарбує речі в пурпурний", - "behaviour.paintspray.orange.tooltip": "Фарбує речі в помаранчевий", - "behaviour.paintspray.pink.tooltip": "Фарбує речі в рожевий", - "behaviour.paintspray.purple.tooltip": "Фарбує речі в фіолетовий", - "behaviour.paintspray.red.tooltip": "Фарбує речі в червоний", - "behaviour.paintspray.white.tooltip": "Фарбує речі в білий", - "behaviour.paintspray.yellow.tooltip": "Фарбує речі в жовтий", - "behaviour.paintspray.solvent.tooltip": "Вибілює речі", - "behaviour.hoe": "Може орати ґрунт", - "behaviour.setting.muffled.tooltip": "Глушить %s", - "behaviour.soft_hammer.idle_after_cycle": "Зупинити машину після завершення циклу роботи", - "behaviour.lighter.uses": "Використань: %d", - "behaviour.paintspray.uses": "Використань: %d", - "behaviour.wrench": "Повертає блоки клацанням ПКМ", - "behaviour.hammer": "Перемикає заглушення машин (тицянням по ним)", - "behaviour.prospecting": "Використовується для геологорозвідки", - "behaviour.soft_hammer.disabled": "Робота зупинена", - "behaviour.soft_hammer.enabled": "Робота відновлена", - - "gtceu.machine.iv_alloy_smelter.tooltip": "§7Інтегратор сплавів", - "gtceu.machine.luv_alloy_smelter.tooltip": "§7Інтегратор сплавів", - "gtceu.machine.zpm_alloy_smelter.tooltip": "§7Інтегратор сплавів", - "gtceu.machine.hp_steam_alloy_smelter.tooltip": "§7Комбінувальний плавильник", - "gtceu.machine.lp_steam_alloy_smelter.tooltip": "§7Комбінувальний плавильник", - "gtceu.machine.ev_alloy_smelter.tooltip": "§7Високотехнологічний комбінувальний плавильник", - "gtceu.machine.hv_alloy_smelter.tooltip": "§7Високотехнологічний комбінувальний плавильник", - "gtceu.machine.lv_alloy_smelter.tooltip": "§7Високотехнологічний комбінувальний плавильник", - "gtceu.machine.mv_alloy_smelter.tooltip": "§7Високотехнологічний комбінувальний плавильник", - "gtceu.machine.uv_packer.tooltip": "§7Склад Нової пошти", - "gtceu.machine.iv_packer.tooltip": "§7Коробкар", - "gtceu.machine.luv_packer.tooltip": "§7Коробкар", - "gtceu.machine.zpm_packer.tooltip": "§7Коробкар", - "gtceu.machine.ev_packer.tooltip": "§7Запаковує та розпаковує речі", - "gtceu.machine.hv_packer.tooltip": "§7Запаковує та розпаковує речі", - "gtceu.machine.lv_packer.tooltip": "§7Запаковує та розпаковує речі", - "gtceu.machine.mv_packer.tooltip": "§7Запаковує та розпаковує речі", - "gtceu.machine.uv_assembler.tooltip": "§7Збиральний конструктор", - "gtceu.machine.ev_assembler.tooltip": "§7Месники, збираємось!", - "gtceu.machine.hv_assembler.tooltip": "§7Месники, збираємось!", - "gtceu.machine.lv_assembler.tooltip": "§7Месники, збираємось!", - "gtceu.machine.mv_assembler.tooltip": "§7Месники, збираємось!", - "gtceu.machine.iv_assembler.tooltip": "§7НЕ верстак", - "gtceu.machine.luv_assembler.tooltip": "§7НЕ верстак", - "gtceu.machine.zpm_assembler.tooltip": "§7НЕ верстак", - "gtceu.machine.uv_circuit_assembler.tooltip": "§7Фабрика обчислень", - "gtceu.machine.iv_circuit_assembler.tooltip": "§7Виробник електроніки", - "gtceu.machine.luv_circuit_assembler.tooltip": "§7Виробник електроніки", - "gtceu.machine.zpm_circuit_assembler.tooltip": "§7Виробник електроніки", - "gtceu.machine.ev_circuit_assembler.tooltip": "§7Всюдисущий віьзми-поклади", - "gtceu.machine.hv_circuit_assembler.tooltip": "§7Всюдисущий віьзми-поклади", - "gtceu.machine.lv_circuit_assembler.tooltip": "§7Всюдисущий віьзми-поклади", - "gtceu.machine.mv_circuit_assembler.tooltip": "§7Всюдисущий віьзми-поклади", - "gtceu.machine.uv_electric_furnace.tooltip": "§7Атомний стимулятор", - "gtceu.machine.iv_arc_furnace.tooltip": "§7Розрядний нагрівач", - "gtceu.machine.luv_arc_furnace.tooltip": "§7Розрядний нагрівач", - "gtceu.machine.zpm_arc_furnace.tooltip": "§7Розрядний нагрівач", - "gtceu.machine.uv_arc_furnace.tooltip": "§7Нагрівач короткого замикання", - "gtceu.machine.ev_arc_furnace.tooltip": "§7Кому взагалі потрібна плавильна піч?", - "gtceu.machine.hv_arc_furnace.tooltip": "§7Кому взагалі потрібна плавильна піч?", - "gtceu.machine.lv_arc_furnace.tooltip": "§7Кому взагалі потрібна плавильна піч?", - "gtceu.machine.mv_arc_furnace.tooltip": "§7Кому взагалі потрібна плавильна піч?", - "gtceu.machine.iv_electric_furnace.tooltip": "§7Механізм електронного збудження", - "gtceu.machine.luv_electric_furnace.tooltip": "§7Механізм електронного збудження", - "gtceu.machine.zpm_electric_furnace.tooltip": "§7Механізм електронного збудження", - "gtceu.machine.ev_electric_furnace.tooltip": "§7Не схоже на користування Commodore 64", - "gtceu.machine.hv_electric_furnace.tooltip": "§7Не схоже на користування Commodore 64", - "gtceu.machine.lv_electric_furnace.tooltip": "§7Не схоже на користування Commodore 64", - "gtceu.machine.mv_electric_furnace.tooltip": "§7Не схоже на користування Commodore 64", - "gtceu.machine.uv_electrolyzer.tooltip": "§7Атомний іонізатор", - "gtceu.machine.ev_electrolyzer.tooltip": "§7Молекулярний електроліз", - "gtceu.machine.hv_electrolyzer.tooltip": "§7Молекулярний електроліз", - "gtceu.machine.lv_electrolyzer.tooltip": "§7Молекулярний електроліз", - "gtceu.machine.mv_electrolyzer.tooltip": "§7Молекулярний електроліз", - "gtceu.machine.iv_electrolyzer.tooltip": "§7Молекулярний дезінтегратор E-4906", - "gtceu.machine.luv_electrolyzer.tooltip": "§7Молекулярний дезінтегратор E-4907", - "gtceu.machine.zpm_electrolyzer.tooltip": "§7Молекулярний дезінтегратор E-4908", - "gtceu.machine.ev_chemical_bath.tooltip": "§7Розщеплює руди шляхом їх вимочування у хімікатах", - "gtceu.machine.hv_chemical_bath.tooltip": "§7Розщеплює руди шляхом їх вимочування у хімікатах", - "gtceu.machine.lv_chemical_bath.tooltip": "§7Розщеплює руди шляхом їх вимочування у хімікатах", - "gtceu.machine.mv_chemical_bath.tooltip": "§7Розщеплює руди шляхом їх вимочування у хімікатах", - "gtceu.machine.uv_chemical_bath.tooltip": "§7Хімічний занурятор 2222", - "gtceu.machine.iv_chemical_bath.tooltip": "§7Хімічний розчинник", - "gtceu.machine.luv_chemical_bath.tooltip": "§7Хімічний розчинник", - "gtceu.machine.zpm_chemical_bath.tooltip": "§7Хімічний розчинник", - "gtceu.machine.quantum_chest.tooltip": "§7Краще ніж Storage Drawers", - "gtceu.machine.ev_polarizer.tooltip": "§7Біполяризовує магніти", - "gtceu.machine.hv_polarizer.tooltip": "§7Біполяризовує магніти", - "gtceu.machine.lv_polarizer.tooltip": "§7Біполяризовує магніти", - "gtceu.machine.mv_polarizer.tooltip": "§7Біполяризовує магніти", - "gtceu.machine.uv_polarizer.tooltip": "§7Реорганізатор магнітного поля", - "gtceu.machine.iv_polarizer.tooltip": "§7Індуктор магнітного поля", - "gtceu.machine.luv_polarizer.tooltip": "§7Індуктор магнітного поля", - "gtceu.machine.zpm_polarizer.tooltip": "§7Індуктор магнітного поля", - "gtceu.machine.iv_macerator.tooltip": "§7Блендоматор 9001", - "gtceu.machine.luv_macerator.tooltip": "§7Блендоматор 9002", - "gtceu.machine.zpm_macerator.tooltip": "§7Блендоматор 9003", - "gtceu.machine.hp_steam_macerator.tooltip": "§7Подрібнює руди", - "gtceu.machine.lp_steam_macerator.tooltip": "§7Подрібнює руди", - "gtceu.machine.uv_macerator.tooltip": "§7Деформувальник", - "gtceu.machine.ev_macerator.tooltip": "§7Подрібнює руди з побічними продуктами", - "gtceu.machine.hv_macerator.tooltip": "§7Подрібнює руди з побічними продуктами", - "gtceu.machine.lv_macerator.tooltip": "§7Подрібнює руди без побічних продуктів", - "gtceu.machine.mv_macerator.tooltip": "§7Подрібнює руди без побічних продуктів", - "gtceu.machine.lv_bender.tooltip": "§7Бендера", - "gtceu.machine.mv_bender.tooltip": "§7Бендера", - "gtceu.machine.hv_bender.tooltip": "§7Біндера", - "gtceu.machine.ev_bender.tooltip": "§7Біндера", - "gtceu.machine.uv_bender.tooltip": "§7Деформатор матерії", - "gtceu.machine.iv_bender.tooltip": "§7Викривлювач", - "gtceu.machine.luv_bender.tooltip": "§7Викривлювач", - "gtceu.machine.zpm_bender.tooltip": "§7Викривлювач", - "gtceu.machine.uv_brewery.tooltip": "§7Перша броварня", - "gtceu.machine.iv_brewery.tooltip": "§7Більше ніж варильня", - "gtceu.machine.luv_brewery.tooltip": "§7Більше ніж варильня", - "gtceu.machine.zpm_brewery.tooltip": "§7Більше ніж варильня", - "gtceu.machine.ev_brewery.tooltip": "§7Компактне та ефективне зіллєваріння", - "gtceu.machine.hv_brewery.tooltip": "§7Компактне та ефективне зіллєваріння", - "gtceu.machine.lv_brewery.tooltip": "§7Компактне та ефективне зіллєваріння", - "gtceu.machine.mv_brewery.tooltip": "§7Компактне та ефективне зіллєваріння", - "gtceu.machine.iv_scanner.tooltip": "§7Детектор аномалій", - "gtceu.machine.luv_scanner.tooltip": "§7Детектор аномалій", - "gtceu.machine.zpm_scanner.tooltip": "§7Детектор аномалій", - "gtceu.machine.uv_scanner.tooltip": "§7Електронний мікроскоп", - "gtceu.machine.ev_scanner.tooltip": "§7Сканує матеріали та інші речі", - "gtceu.machine.hv_scanner.tooltip": "§7Сканує матеріали та інші речі", - "gtceu.machine.lv_scanner.tooltip": "§7Сканує матеріали та інші речі", - "gtceu.machine.mv_scanner.tooltip": "§7Сканує матеріали та інші речі", - "gtceu.machine.uv_canner.tooltip": "§7Консервний актуатор", - "gtceu.machine.iv_canner.tooltip": "§7Консервний оператор", - "gtceu.machine.luv_canner.tooltip": "§7Консервний оператор", - "gtceu.machine.zpm_canner.tooltip": "§7Консервний оператор", - "gtceu.machine.ev_canner.tooltip": "§7Поміщає речі в контейнери та виймає їх з них", - "gtceu.machine.hv_canner.tooltip": "§7Поміщає речі в контейнери та виймає їх з них", - "gtceu.machine.lv_canner.tooltip": "§7Поміщає речі в контейнери та виймає їх з них", - "gtceu.machine.mv_canner.tooltip": "§7Поміщає речі в контейнери та виймає їх з них", - "gtceu.machine.iv_chemical_reactor.tooltip": "§7Хімічний перетворювач", - "gtceu.machine.luv_chemical_reactor.tooltip": "§7Хімічний перетворювач", - "gtceu.machine.zpm_chemical_reactor.tooltip": "§7Хімічний перетворювач", - "gtceu.machine.ev_chemical_reactor.tooltip": "§7Дає хімічним речовинам вступати в реакцію між собою", - "gtceu.machine.hv_chemical_reactor.tooltip": "§7Дає хімічним речовинам вступати в реакцію між собою", - "gtceu.machine.lv_chemical_reactor.tooltip": "§7Дає хімічним речовинам вступати в реакцію між собою", - "gtceu.machine.mv_chemical_reactor.tooltip": "§7Дає хімічним речовинам вступати в реакцію між собою", - "gtceu.machine.uv_chemical_reactor.tooltip": "§7Каталізатор реакцій", - "gtceu.machine.ev_gas_collector.tooltip": "§7Збирає газ з повітря залежно від виміру", - "gtceu.machine.hv_gas_collector.tooltip": "§7Збирає газ з повітря залежно від виміру", - "gtceu.machine.lv_gas_collector.tooltip": "§7Збирає газ з повітря залежно від виміру", - "gtceu.machine.mv_gas_collector.tooltip": "§7Збирає газ з повітря залежно від виміру", - "gtceu.machine.iv_gas_collector.tooltip": "§7Збирає газ з атмосфери залежно від виміру", - "gtceu.machine.luv_gas_collector.tooltip": "§7Збирає газ з атмосфери залежно від виміру", - "gtceu.machine.zpm_gas_collector.tooltip": "§7Збирає газ з атмосфери залежно від виміру", - "gtceu.machine.uev_gas_collector.tooltip": "§7Збирає газ з сонячної системи залежно від виміру", - "gtceu.machine.uhv_gas_collector.tooltip": "§7Збирає газ з сонячної системи залежно від виміру", - "gtceu.machine.uiv_gas_collector.tooltip": "§7Збирає газ з сонячної системи залежно від виміру", - "gtceu.machine.uv_gas_collector.tooltip": "§7Збирає газ з сонячної системи залежно від виміру", - "gtceu.machine.uxv_gas_collector.tooltip": "§7Збирає газ з сонячної системи залежно від виміру", - "gtceu.machine.opv_gas_collector.tooltip": "§7Збирає газ із всесвіту залежно від виміру", - "gtceu.machine.iv_distillery.tooltip": "§7Сепаратор конденсату", - "gtceu.machine.luv_distillery.tooltip": "§7Сепаратор конденсату", - "gtceu.machine.zpm_distillery.tooltip": "§7Сепаратор конденсату", - "gtceu.machine.ev_distillery.tooltip": "§7Вилучає найбільш важливі частини рідин", - "gtceu.machine.hv_distillery.tooltip": "§7Вилучає найбільш важливі частини рідин", - "gtceu.machine.lv_distillery.tooltip": "§7Вилучає найбільш важливі частини рідин", - "gtceu.machine.mv_distillery.tooltip": "§7Вилучає найбільш важливі частини рідин", - "gtceu.machine.uv_distillery.tooltip": "§7Дільник фракцій", - "gtceu.machine.ev_fluid_solidifier.tooltip": "§7Охолоджує рідини до твердого стану", - "gtceu.machine.hv_fluid_solidifier.tooltip": "§7Охолоджує рідини до твердого стану", - "gtceu.machine.lv_fluid_solidifier.tooltip": "§7Охолоджує рідини до твердого стану", - "gtceu.machine.mv_fluid_solidifier.tooltip": "§7Охолоджує рідини до твердого стану", - "gtceu.machine.uv_fluid_solidifier.tooltip": "§7Рідинний окаменювач", - "gtceu.machine.iv_fluid_solidifier.tooltip": "§7Не льодогенератор", - "gtceu.machine.luv_fluid_solidifier.tooltip": "§7Не льодогенератор", - "gtceu.machine.zpm_fluid_solidifier.tooltip": "§7Не льодогенератор", - "gtceu.machine.zpm_rock_crusher.tooltip": "§7Кріогенний затверджувач магми R-10200", - "gtceu.machine.iv_rock_crusher.tooltip": "§7Кріогенний затверджувач магми R-8200", - "gtceu.machine.luv_rock_crusher.tooltip": "§7Кріогенний затверджувач магми R-9200", - "gtceu.machine.hp_steam_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", - "gtceu.machine.lp_steam_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", - "gtceu.machine.ev_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", - "gtceu.machine.hv_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", - "gtceu.machine.lv_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", - "gtceu.machine.mv_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", - "gtceu.machine.opv_rock_crusher.tooltip": "§7Камера вулканічних утворень", - "gtceu.machine.uev_rock_crusher.tooltip": "§7Камера вулканічних утворень", - "gtceu.machine.uhv_rock_crusher.tooltip": "§7Камера вулканічних утворень", - "gtceu.machine.uiv_rock_crusher.tooltip": "§7Камера вулканічних утворень", - "gtceu.machine.uv_rock_crusher.tooltip": "§7Камера вулканічних утворень", - "gtceu.machine.uxv_rock_crusher.tooltip": "§7Камера вулканічних утворень", - "gtceu.machine.ev_autoclave.tooltip": "§7Кристалізує пил", - "gtceu.machine.hv_autoclave.tooltip": "§7Кристалізує пил", - "gtceu.machine.lv_autoclave.tooltip": "§7Кристалізує пил", - "gtceu.machine.mv_autoclave.tooltip": "§7Кристалізує пил", - "gtceu.machine.uv_autoclave.tooltip": "§7Блок обтяження", - "gtceu.machine.iv_autoclave.tooltip": "§7Скороварка", - "gtceu.machine.luv_autoclave.tooltip": "§7Скороварка", - "gtceu.machine.zpm_autoclave.tooltip": "§7Скороварка", - "gtceu.machine.ev_extractor.tooltip": "§7Соковичавлюючий пристрій приречення - D123", - "gtceu.machine.hv_extractor.tooltip": "§7Соковичавлюючий пристрій приречення - D123", - "gtceu.machine.lv_extractor.tooltip": "§7Соковичавлюючий пристрій приречення - D123", - "gtceu.machine.mv_extractor.tooltip": "§7Соковичавлюючий пристрій приречення - D123", - "gtceu.machine.hp_steam_extractor.tooltip": "§7Добувач першої глини", - "gtceu.machine.lp_steam_extractor.tooltip": "§7Добувач першої глини", - "gtceu.machine.uv_extractor.tooltip": "§7Відсмоктувач зрідження", - "gtceu.machine.iv_extractor.tooltip": "§7Вакуумний екстрактор", - "gtceu.machine.luv_extractor.tooltip": "§7Вакуумний екстрактор", - "gtceu.machine.zpm_extractor.tooltip": "§7Вакуумний екстрактор", - "gtceu.machine.ev_laser_engraver.tooltip": "§7Не дивіться прямо на лазер", - "gtceu.machine.hv_laser_engraver.tooltip": "§7Не дивіться прямо на лазер", - "gtceu.machine.lv_laser_engraver.tooltip": "§7Не дивіться прямо на лазер", - "gtceu.machine.mv_laser_engraver.tooltip": "§7Не дивіться прямо на лазер", - "gtceu.machine.luv_laser_engraver.tooltip": "§7Із силою 8.16 MW", - "gtceu.machine.iv_laser_engraver.tooltip": "§7Із силою 2.04 MW", - "gtceu.machine.zpm_laser_engraver.tooltip": "§7Із силою 32.64 MW", - "gtceu.machine.uv_laser_engraver.tooltip": "§7Точна фотонна гармата", - "gtceu.machine.fluid_drilling_rig.description": "§7Видобуває рідини з поклад під бедроком.", - "gtceu.machine.bedrock_ore_miner.description": "§7Видобуває руди з поклад під бедроком.", - "gtceu.machine.uv_replicator.tooltip": "§7Елементарний композитор", - "gtceu.machine.iv_replicator.tooltip": "§7Матеріальний Ctrl+V", - "gtceu.machine.luv_replicator.tooltip": "§7Матеріальний Ctrl+V", - "gtceu.machine.zpm_replicator.tooltip": "§7Матеріальний Ctrl+V", - "gtceu.machine.ev_replicator.tooltip": "§7Виробляє найчистіші елементи", - "gtceu.machine.hv_replicator.tooltip": "§7Виробляє найчистіші елементи", - "gtceu.machine.lv_replicator.tooltip": "§7Виробляє найчистіші елементи", - "gtceu.machine.mv_replicator.tooltip": "§7Виробляє найчистіші елементи", - "gtceu.machine.iv_electromagnetic_separator.tooltip": "§7Електромагнітний категоризатор", - "gtceu.machine.luv_electromagnetic_separator.tooltip": "§7Електромагнітний категоризатор", - "gtceu.machine.zpm_electromagnetic_separator.tooltip": "§7Електромагнітний категоризатор", - "gtceu.machine.uv_electromagnetic_separator.tooltip": "§7Ровіювач електромагнітної сили", - "gtceu.machine.ev_electromagnetic_separator.tooltip": "§7Відокремлює магнітні руди від решти", - "gtceu.machine.hv_electromagnetic_separator.tooltip": "§7Відокремлює магнітні руди від решти", - "gtceu.machine.lv_electromagnetic_separator.tooltip": "§7Відокремлює магнітні руди від решти", - "gtceu.machine.mv_electromagnetic_separator.tooltip": "§7Відокремлює магнітні руди від решти", - "gtceu.machine.uv_mass_fabricator.tooltip": "§7Ініціатор існування", - "gtceu.machine.iv_mass_fabricator.tooltip": "§7Фабрика буття", - "gtceu.machine.luv_mass_fabricator.tooltip": "§7Фабрика буття", - "gtceu.machine.zpm_mass_fabricator.tooltip": "§7Фабрика буття", - "gtceu.machine.ev_mass_fabricator.tooltip": "§7UUM матерія * виробництво в квадраті", - "gtceu.machine.hv_mass_fabricator.tooltip": "§7UUM матерія * виробництво в квадраті", - "gtceu.machine.lv_mass_fabricator.tooltip": "§7UUM матерія * виробництво в квадраті", - "gtceu.machine.mv_mass_fabricator.tooltip": "§7UUM матерія * виробництво в квадраті", - "gtceu.machine.hp_steam_liquid_boiler.tooltip": "§7Швидше ніж малий паровий рідинний котел", - "gtceu.machine.hp_steam_solid_boiler.tooltip": "§7Швидше ніж малий паровий твердопаливний котел", - "gtceu.machine.hp_steam_solar_boiler.tooltip": "§7Парова енергія від сонця", - "gtceu.machine.lp_steam_solar_boiler.tooltip": "§7Парова енергія від сонця", - "gtceu.machine.iv_fermenter.tooltip": "§7Прискорювач ферментації", - "gtceu.machine.luv_fermenter.tooltip": "§7Прискорювач ферментації", - "gtceu.machine.zpm_fermenter.tooltip": "§7Прискорювач ферментації", - "gtceu.machine.ev_fermenter.tooltip": "§7Ферментує рідини", - "gtceu.machine.hv_fermenter.tooltip": "§7Ферментує рідини", - "gtceu.machine.lv_fermenter.tooltip": "§7Ферментує рідини", - "gtceu.machine.mv_fermenter.tooltip": "§7Ферментує рідини", - "gtceu.machine.uv_fermenter.tooltip": "§7Дихальний контролер", - "gtceu.machine.hp_steam_forge_hammer.tooltip": "§7Ковальський молот", - "gtceu.machine.lp_steam_forge_hammer.tooltip": "§7Ковальський молот", - "gtceu.machine.uv_forge_hammer.tooltip": "§7Модулятор удару", - "gtceu.machine.iv_forge_hammer.tooltip": "§7Плитопідроблювач", - "gtceu.machine.luv_forge_hammer.tooltip": "§7Плитопідроблювач", - "gtceu.machine.zpm_forge_hammer.tooltip": "§7Плитопідроблювач", - "gtceu.machine.ev_forge_hammer.tooltip": "§7Стоп, час молота!", - "gtceu.machine.hv_forge_hammer.tooltip": "§7Стоп, час молота!", - "gtceu.machine.lv_forge_hammer.tooltip": "§7Стоп, час молота!", - "gtceu.machine.mv_forge_hammer.tooltip": "§7Стоп, час молота!", - "gtceu.machine.ev_ore_washer.tooltip": "§7Отримує більше побічних продуктів з руд", - "gtceu.machine.hv_ore_washer.tooltip": "§7Отримує більше побічних продуктів з руд", - "gtceu.machine.lv_ore_washer.tooltip": "§7Отримує більше побічних продуктів з руд", - "gtceu.machine.mv_ore_washer.tooltip": "§7Отримує більше побічних продуктів з руд", - "gtceu.machine.iv_ore_washer.tooltip": "§7Переобладнана пральна машина I-360", - "gtceu.machine.luv_ore_washer.tooltip": "§7Переобладнана пральна машина I-361", - "gtceu.machine.zpm_ore_washer.tooltip": "§7Переобладнана пральна машина I-362", - "gtceu.machine.iv_fluid_heater.tooltip": "§7Тепловий інфузор", - "gtceu.machine.luv_fluid_heater.tooltip": "§7Тепловий інфузор", - "gtceu.machine.zpm_fluid_heater.tooltip": "§7Тепловий інфузор", - "gtceu.machine.ev_fluid_heater.tooltip": "§7Нагріває рідини", - "gtceu.machine.hv_fluid_heater.tooltip": "§7Нагріває рідини", - "gtceu.machine.lv_fluid_heater.tooltip": "§7Нагріває рідини", - "gtceu.machine.mv_fluid_heater.tooltip": "§7Нагріває рідини", - "gtceu.machine.hp_steam_furnace.tooltip": "§7Плавить речі за допомогою стисненої пари", - "gtceu.machine.lp_steam_furnace.tooltip": "§7Плавить речі за допомогою стисненої пари", - "gtceu.machine.hp_steam_compressor.tooltip": "§7Стискає предмети", - "gtceu.machine.lp_steam_compressor.tooltip": "§7Стискає предмети", - "gtceu.machine.ev_compressor.tooltip": "§7Компресорно-механічна система C77", - "gtceu.machine.hv_compressor.tooltip": "§7Компресорно-механічна система C77", - "gtceu.machine.lv_compressor.tooltip": "§7Компресорно-механічна система C77", - "gtceu.machine.mv_compressor.tooltip": "§7Компресорно-механічна система C77", - "gtceu.machine.uv_compressor.tooltip": "§7Стискач матерії", - "gtceu.machine.iv_compressor.tooltip": "§7Конденсатор сингулярності", - "gtceu.machine.luv_compressor.tooltip": "§7Конденсатор сингулярності", - "gtceu.machine.zpm_compressor.tooltip": "§7Конденсатор сингулярності", - "gtceu.machine.ev_forming_press.tooltip": "§7Витискає речам нову форму", - "gtceu.machine.hv_forming_press.tooltip": "§7Витискає речам нову форму", - "gtceu.machine.lv_forming_press.tooltip": "§7Витискає речам нову форму", - "gtceu.machine.mv_forming_press.tooltip": "§7Витискає речам нову форму", - "gtceu.machine.iv_forming_press.tooltip": "§7Предметний нашаровувач", - "gtceu.machine.luv_forming_press.tooltip": "§7Предметний нашаровувач", - "gtceu.machine.zpm_forming_press.tooltip": "§7Предметний нашаровувач", - "gtceu.machine.uv_forming_press.tooltip": "§7Змінювач поверхней", - "gtceu.machine.iv_wiremill.tooltip": "§7Подовжувач злитків", - "gtceu.machine.luv_wiremill.tooltip": "§7Подовжувач злитків", - "gtceu.machine.zpm_wiremill.tooltip": "§7Подовжувач злитків", - "gtceu.machine.ev_wiremill.tooltip": "§7Ефективніше виробляє дроти", - "gtceu.machine.hv_wiremill.tooltip": "§7Ефективніше виробляє дроти", - "gtceu.machine.lv_wiremill.tooltip": "§7Ефективніше виробляє дроти", - "gtceu.machine.mv_wiremill.tooltip": "§7Ефективніше виробляє дроти", - "gtceu.machine.uv_wiremill.tooltip": "§7Трансформатор дротів", - "gtceu.machine.iv_extruder.tooltip": "§7Витіснювач матеріалів", - "gtceu.machine.luv_extruder.tooltip": "§7Витіснювач матеріалів", - "gtceu.machine.zpm_extruder.tooltip": "§7Витіснювач матеріалів", - "gtceu.machine.uv_extruder.tooltip": "§7Формоутворювач", - "gtceu.machine.ev_extruder.tooltip": "§7Універсальна металообробна машина", - "gtceu.machine.hv_extruder.tooltip": "§7Універсальна металообробна машина", - "gtceu.machine.lv_extruder.tooltip": "§7Універсальна металообробна машина", - "gtceu.machine.mv_extruder.tooltip": "§7Універсальна металообробна машина", - "gtceu.machine.uv_mixer.tooltip": "§7Гомогенізатор матеріалу", - "gtceu.machine.iv_mixer.tooltip": "§7Органайзер матерії", - "gtceu.machine.luv_mixer.tooltip": "§7Органайзер матерії", - "gtceu.machine.zpm_mixer.tooltip": "§7Органайзер матерії", - "gtceu.machine.ev_mixer.tooltip": "§7Чи змішається?", - "gtceu.machine.hv_mixer.tooltip": "§7Чи змішається?", - "gtceu.machine.lv_mixer.tooltip": "§7Чи змішається?", - "gtceu.machine.mv_mixer.tooltip": "§7Чи змішається?", - "gtceu.machine.iv_cutter.tooltip": "§7Розсікач предметів", - "gtceu.machine.luv_cutter.tooltip": "§7Розсікач предметів", - "gtceu.machine.zpm_cutter.tooltip": "§7Розсікач предметів", - "gtceu.machine.uv_cutter.tooltip": "§7Розділювач матерії", - "gtceu.machine.ev_cutter.tooltip": "§7Ріж-крій", - "gtceu.machine.hv_cutter.tooltip": "§7Ріж-крій", - "gtceu.machine.lv_cutter.tooltip": "§7Криворіж", - "gtceu.machine.mv_cutter.tooltip": "§7Ріж-крій", - "gtceu.machine.iv_thermal_centrifuge.tooltip": "§7Потогонник пломенів T-6350", - "gtceu.machine.luv_thermal_centrifuge.tooltip": "§7Потогонник пломенів T-6351", - "gtceu.machine.zpm_thermal_centrifuge.tooltip": "§7Потогонник пломенів T-6352", - "gtceu.machine.uv_thermal_centrifuge.tooltip": "§7Вогняний циклон", - "gtceu.machine.ev_thermal_centrifuge.tooltip": "§7Точніше розділяє руди", - "gtceu.machine.hv_thermal_centrifuge.tooltip": "§7Точніше розділяє руди", - "gtceu.machine.lv_thermal_centrifuge.tooltip": "§7Точніше розділяє руди", - "gtceu.machine.mv_thermal_centrifuge.tooltip": "§7Точніше розділяє руди", - "gtceu.machine.iv_centrifuge.tooltip": "§7Молекулярний циклон", - "gtceu.machine.luv_centrifuge.tooltip": "§7Молекулярний циклон", - "gtceu.machine.zpm_centrifuge.tooltip": "§7Молекулярний циклон", - "gtceu.machine.ev_centrifuge.tooltip": "§7Молекулярний сепаратор", - "gtceu.machine.uv_centrifuge.tooltip": "§7Молекулярне торнадо", - "gtceu.machine.hv_centrifuge.tooltip": "§7Розподіл молекул", - "gtceu.machine.lv_centrifuge.tooltip": "§7Розподіл молекул", - "gtceu.machine.mv_centrifuge.tooltip": "§7Розподіл молекул", - "gtceu.machine.ev_lathe.tooltip": "§7Ефективніше виробляє стрижні", - "gtceu.machine.hv_lathe.tooltip": "§7Ефективніше виробляє стрижні", - "gtceu.machine.lv_lathe.tooltip": "§7Ефективніше виробляє стрижні", - "gtceu.machine.mv_lathe.tooltip": "§7Ефективніше виробляє стрижні", - "gtceu.machine.uv_lathe.tooltip": "§7Ротаційна шліфувальна машина", - "gtceu.machine.iv_lathe.tooltip": "§7Поворотно-відкидна машина L-5906", - "gtceu.machine.luv_lathe.tooltip": "§7Поворотно-відкидна машина L-5907", - "gtceu.machine.zpm_lathe.tooltip": "§7Поворотно-відкидна машина L-5908", - "gtceu.machine.uv_sifter.tooltip": "§7Пульсаційний фільтр", - "gtceu.machine.iv_sifter.tooltip": "§7За підтримки TFC", - "gtceu.machine.luv_sifter.tooltip": "§7За підтримки TFC", - "gtceu.machine.zpm_sifter.tooltip": "§7За підтримки TFC", - "gtceu.machine.ev_sifter.tooltip": "§7Зберігайте спокій і продовжуйте просіювати", - "gtceu.machine.hv_sifter.tooltip": "§7Зберігайте спокій і продовжуйте просіювати", - "gtceu.machine.lv_sifter.tooltip": "§7Зберігайте спокій і продовжуйте просіювати", - "gtceu.machine.mv_sifter.tooltip": "§7Зберігайте спокій і продовжуйте просіювати", - "gtceu.machine.lp_steam_liquid_boiler.tooltip": "§7Котел, що працює на рідині", - "gtceu.machine.lp_steam_solid_boiler.tooltip": "§7Ранній спосіб отримати парову енергію", - "gtceu.machine.coke_oven_hatch.tooltip": "§7Дозволяє автоматизувати доступ до коксової печі.", - "gtceu.machine.steam_turbine.tooltip": "§7Перетворює пару на EU", - "gtceu.machine.quantum_tank.tooltip": "§7Компактне місце для зберігання всіх рідин", - "gtceu.machine.combustion_generator.tooltip": "§7Потребує легкозаймистих рідин", - "gtceu.machine.gas_turbine.tooltip": "§7Потребує горючих газів", - "gtceu.machine.laser_hatch.target.tooltip": "§7Отримує енергію на відстані", - "gtceu.machine.laser_hatch.source.tooltip": "§7Передає енергію на відстані", - "gtceu.machine.pump.tooltip": "§7Найкращий спосіб спустошувати океани!", - "gtceu.machine.locked_safe.requirements": "§7Необхідні замінники:", - "gtceu.machine.fusion_reactor.capacity": "§7Максимальний запас енергії:§e %sM EU", - "gtceu.machine.uv_alloy_smelter.tooltip": "§7Амальгаматор металу", - "gtceu.machine.uv_ore_washer.tooltip": "§7Мініатюрна автомийка", - "gtceu.machine.block_breaker.tooltip": "§7Добуває блок на лицьовій стороні та збирає його дроп", - "gtceu.machine.steam_miner.tooltip": "§7Добуває руди під шахтами!", - "gtceu.machine.miner.tooltip": "§7Добуває руди під шахтами! починає з зони§f %sx%s§7 ", - "gtceu.machine.transformer.description": "§7Трансформує енергію між рівнями напруги", - "gtceu.machine.uv_fluid_heater.tooltip": "§7Тепловий просякач", - "gtceu.machine.ev_fluid_drilling_rig.tooltip": "Свердловинний дренажер", - - "gtceu.machine.me.item_import.data_stick.name": "§oКонфігураційні дані ME-вхідної шини", - "gtceu.machine.me.fluid_import.data_stick.name": "§oКонфігураційні дані ME-вхідного люка", - "gtceu.machine.me.import_paste_settings": "Застосовані налаштування з картки даних", - "gtceu.machine.me.stocking_auto_pull_disabled": "Автовитягання вимкнено", - "gtceu.machine.me.stocking_auto_pull_enabled": "Автовитягання увімкнено", - "gtceu.machine.me.stocking_fluid.tooltip.1": "Режим автовитягання з МЕ автоматично заповнить перші 16 рідин у ME-системі, оновлюючись кожні 5 секунд.", - "gtceu.machine.me.stocking_item.tooltip.1": "Режим автовитягання з МЕ автоматично заповнить перші 16 предметів у ME-системі, оновлюючись кожні 5 секунд.", - "gtceu.machine.me.fluid_import.tooltip": "Автоматично забирає рідини з МЕ-мережі.", - "gtceu.machine.me.item_import.tooltip": "Автоматично забирає предмети з МЕ-мережі.", - "gtceu.machine.me.export.tooltip": "Має необмежену ємність до підключення до МЕ-мережі.", - "gtceu.machine.me_import_fluid_hatch.configs.tooltip": "Зберігає в наявності 16 типів рідин", - "gtceu.machine.me_import_item_hatch.configs.tooltip": "Зберігає в наявності 16 типів предметів", - "gtceu.machine.me.copy_paste.tooltip": "ЛКМ із карткою даних, щоб скопіювати налаштування, ПКМ, щоб застосувати", - "gtceu.machine.me.stocking_fluid.tooltip.0": "Отримує рідини безпосередньо з МЕ-мережі", - "gtceu.machine.me.stocking_item.tooltip.0": "Отримує предмети безпосередньо з МЕ-мережі", - "gtceu.machine.me.import_copy_settings": "Налаштування збережені у картці даних", - "gtceu.machine.me.fluid_export.tooltip": "Зберігає рідини безпосередньо в МЕ-мережу.", - "gtceu.machine.me.item_export.tooltip": "Зберігає предмети безпосередньо в МЕ-мережу.", - "gtceu.machine.advanced_processing_array.tooltip": "Паралелізуйте світ", - "gtceu.machine.assembly_line.tooltip": "Не багатоблочна складальна машина!", - "gtceu.machine.available_recipe_map_1.tooltip": "Доступні типи рецептів: %s", - "gtceu.machine.available_recipe_map_2.tooltip": "Доступні типи рецептів: %s, %s", - "gtceu.machine.available_recipe_map_3.tooltip": "Доступні типи рецептів: %s, %s, %s", - "gtceu.machine.available_recipe_map_4.tooltip": "Доступні типи рецептів: %s, %s, %s, %s", - "gtceu.machine.basic.input_from_output_side.allow": "Дозволити введення з боку виходу: ", - "gtceu.machine.basic.input_from_output_side.disallow": "Заборонити введення з боку виходу: ", - "gtceu.machine.bedrock_ore_miner.depletion": "§bШвидкість виснаження:§f %s%%", - "gtceu.machine.bedrock_ore_miner.production": "§eМножник виробництва:§f %dx, %fx розгін", - "gtceu.machine.block_breaker.speed_bonus": "§eДодаткова швидкість:§f %d%%", - "gtceu.machine.buffer.tooltip": "Невеликий буфер для зберігання предметів і рідин", - "gtceu.machine.canner.jei_description": "За допомогою консерватора можна наповнювати та спорожняти будь-які ємності для рідини (наприклад, відра або рідинні комірки)", - "gtceu.machine.central_monitor.tooltip": "На ньому можна запустити Doom?", - "gtceu.machine.charcoal_pile.tooltip": "Підземна паливна піч", - "gtceu.machine.charcoal_pile.tooltip.0": "Перетворює колоди на§a деревне вугілля§7 when§c ignited§7.", - "gtceu.machine.charcoal_pile.tooltip.1": "ПКМ із запалюючим предметом, щоб запустити.", - "gtceu.machine.charcoal_pile.tooltip.2": "Піроліз відбувається під машиною в просторі до§b 9x4x9§7.", - "gtceu.machine.charcoal_pile.tooltip.3": "Колоди не повинні контактувати з§e повітрям§7!", - "gtceu.machine.cleanroom.tooltip": "Закривайте двері, мухи летять!", - "gtceu.machine.cleanroom.tooltip.0": "Розмістіть машини всередині, щоб виконувати рецепти чистої кімнати.", - "gtceu.machine.cleanroom.tooltip.1": "Використовує§f 30 EU/т§7 коли брудно,§f 4 EU/т§7 коли чисто.", - "gtceu.machine.cleanroom.tooltip.2": "Розгін збільшує обсяг очищення за цикл.", - "gtceu.machine.cleanroom.tooltip.3": "§bРозмір:§f від 5x5x5 до 15x15x15", - "gtceu.machine.cleanroom.tooltip.4": "Потребує§f фільтруючі кришки§7 на стелі, за винятком країв.", - "gtceu.machine.cleanroom.tooltip.5": "Дозволяє встановити до§f 4 дверей§7! залишається чистим, коли двері відчинені.", - "gtceu.machine.cleanroom.tooltip.6": "Генератори, вихлопи, бури, гірники, та примітивні машини занадто брудні для чистої кімнати!", - "gtceu.machine.cleanroom.tooltip.7": "Передавайте енергію через§f корпуси§7 або§f діоди§7 у стінах.", - "gtceu.machine.cleanroom.tooltip.ae2.channels": "Проводьте до§f 8 AE2 каналів§7 через§f корпуси§7 у стінах.", - "gtceu.machine.cleanroom.tooltip.ae2.no_channels": "Проводьте§a мережу AE2§7 через§f корпуси§7 у стінах.", - "gtceu.machine.coke_oven.tooltip": "Створює краще палива для металургії та енергетики", - "gtceu.machine.computation_receiver_hatch.tooltip": "Вхід для обчислювальних даних конструкцій", - "gtceu.machine.computation_transmitter_hatch.tooltip": "Вихід для обчислювальних даних конструкцій", - "gtceu.machine.cracker.tooltip": "Робить нафту корисною", - "gtceu.machine.cracker.tooltip.1": "§7Кожна котушка після§6 мельхіорової§7 зменьшує споживання еннергії на§f 10%%§7.", - "gtceu.machine.data_access_hatch.tooltip.0": "Доступ до даних для конструкцій", - "gtceu.machine.data_receiver_hatch.tooltip": "Вхід дослідницьких даних для конструкцій", - "gtceu.machine.data_transmitter_hatch.tooltip": "Вихід дослідницьких даних для конструкцій", - "gtceu.machine.dual_hatch.export.tooltip": "Рідиний і предметний вихід для конструкцій", - "gtceu.machine.dual_hatch.import.tooltip": "Рідиний і предметний вхід для конструкцій", - "gtceu.machine.energy_hatch.input.tooltip": "Енергетичний вхід для конструкцій", - "gtceu.machine.energy_hatch.input_hi_amp.tooltip": "Багатоамперний енергетичний вхід для конструкцій", - "gtceu.machine.energy_hatch.output.tooltip": "Енергетичний вхід для конструкцій", - "gtceu.machine.energy_hatch.output_hi_amp.tooltip": "Багатоамперний енергетичний вхід для конструкцій", - "gtceu.machine.fluid_hatch.export.tooltip": "Рідинний вихід для конструкцій", - "gtceu.machine.fluid_hatch.import.tooltip": "Рідинний вхід для конструкцій", - "gtceu.machine.item_bus.export.tooltip": "Предметний вихід для конструкцій", - "gtceu.machine.item_bus.import.tooltip": "Предметний вхід для конструкцій", - "gtceu.machine.rotor_holder.tooltip.0": "Тримач ротора для конструкцій", - "gtceu.machine.data_access_hatch.tooltip.1": "Додає§a %s§7 слотів для предметів даних", - "gtceu.machine.data_bank.tooltip.0": "Ваша персональна NAS", - "gtceu.machine.data_bank.tooltip.1": "Масове сховище даних. передає через оптичні кабелі.", - "gtceu.machine.data_bank.tooltip.2": "Бази даних можуть бути об'єднані в ланцюжок.", - "gtceu.machine.data_bank.tooltip.3": "Споживає§f %s EU/т§7 за звичайний люк даних/оптичний люк.", - "gtceu.machine.data_bank.tooltip.4": "Uses§f %s EU/т§7 за люк даних/оптичний люк у ланцюжку.", - "gtceu.machine.diode.message": "Максимальний пропускний струм: %s", - "gtceu.machine.diode.tooltip_general": "Дозволяє потік енергії в одному напрямку та обмежує силу струму", - "gtceu.machine.diode.tooltip_starts_at": "Починає з§f 1A§7, використовуйте м'який молоток для зміни", - "gtceu.machine.diode.tooltip_tool_usage": "Вдаряйте м'яким молотком, щоб змінити силу струму.", - "gtceu.machine.distillation_tower.tooltip": "Рідинопереробний завод", - "gtceu.machine.drum.disable_output": "Не витягує рідину", - "gtceu.machine.drum.enable_output": "Витягує рідину у розміщений нижче резервуар", - "gtceu.machine.electric_blast_furnace.tooltip": "А де електрокоптильня?", - "gtceu.machine.electric_blast_furnace.tooltip.0": "§7За кожні§f 900K§7 над необхідною температурою рецепта застосовується мультиплікативний§f 95%%§7 мультиплікатор енергії.", - "gtceu.machine.electric_blast_furnace.tooltip.1": "§7За кожні§f 1800K§7 над необхідною температурою рецепта один розгін стає на§f 100%% ефективним§7 (ідеальний розгін).", - "gtceu.machine.electric_blast_furnace.tooltip.2": "§7За кожний рівень напруги вище§b MV§7 температура збільшується на§f 100K§7.", - "gtceu.machine.endpoint.tooltip.0": "§7З'єднайте з блоком§f великодистанційного трубопроводу§7, щоб створити трубопровід.", - "gtceu.machine.endpoint.tooltip.1": "§7Тробопроводи повинні мати точно§f 1 вхід§7 та§f 1 вихід§7 у якості пункту призначення.", - "gtceu.machine.endpoint.tooltip.2": "§7Тільки пункти призначення трубопроводу потребують бути у§f завантаженому чанку§7.", - "gtceu.machine.endpoint.tooltip.min_length": "§bМінімальна дистанція до пункту призначекння:§f %d блоків", - "gtceu.machine.energy_converter.description": "Конвертує енергію між EU та FE", - "gtceu.machine.energy_converter.message_conversion_eu": "Конвертація EU, вхід: %dA %d EU, вихід: %d первинної енергії", - "gtceu.machine.energy_converter.message_conversion_native": "Конвертація первинної енергії, вхід: %d FE, вихід: %dA %d EU", - "gtceu.machine.energy_converter.tooltip_conversion_eu": "§aEU-конвертація:§f %dA %d EU (%s§f) -> %d первинної енергії", - "gtceu.machine.energy_converter.tooltip_conversion_native": "§cПервинна конвертація:§f %d FE -> %dA %d EU (%s§f)", - "gtceu.machine.energy_converter.tooltip_tool_usage": "Починає як§f FE-конвертер§7, використовуйте м'який молоток для зміни", - "gtceu.machine.extreme_combustion_engine.tooltip": "Екстремальний хімічний вивільнювач енергії", - "gtceu.machine.fisher.requirement": "Потребує %dx%d квадрат води прямо під собою.", - "gtceu.machine.fisher.speed": "Виловлює щось кожні %d тактів", - "gtceu.machine.fisher.tooltip": "Витрачає нитку на кожу ловлю.", - "gtceu.machine.fluid_drilling_rig.depletion": "§bШвидкість виснаження:§f %s%%", - "gtceu.machine.fluid_drilling_rig.production": "§eМультиплікатор виробництва:§f %dx, %fx розгін", - "gtceu.machine.fluid_tank.fluid": "Містить %s л %s", - "gtceu.machine.fluid_tank.max_multiblock": "Макс. розмір конструкції: %dx%dx%d", - "gtceu.machine.fusion_reactor.luv.tooltip": "Плавильник атомних сплавів", - "gtceu.machine.fusion_reactor.overclocking": "Розгін подвоює енергію та вдвічі скорочує тривалість.", - "gtceu.machine.fusion_reactor.uv.tooltip": "БІЛИЙ кАРЛИК зІЙШОВ НА тВОЮ БАЗУ", - "gtceu.machine.fusion_reactor.zpm.tooltip": "СОНЦЕ зІЙШЛО НА зЕМЛЮ", - "gtceu.machine.high_performance_computation_array.tooltip.0": "Просто звичайний суперкомп'ютер", - "gtceu.machine.high_performance_computation_array.tooltip.1": "Використовується для генерації§f обчислень§7 (та тепла).", - "gtceu.machine.high_performance_computation_array.tooltip.2": "Потребує компоненти вОМ для генерації§f ОРО/т§7 (обчислювальних робочих одиниць).", - "gtceu.machine.hpca.active_cooler_component.tooltip": "Менше витрат, ефективніше охолодження", - "gtceu.machine.hpca.advanced_computation_component.damaged.name": "Пошкоджений вОМ-удосконалений обчислювальний компонент", - "gtceu.machine.hpca.advanced_computation_component.damaged.tooltip": "Це коштувало лише руки та ноги", - "gtceu.machine.hpca.advanced_computation_component.tooltip": "Вища ліга обчислень", - "gtceu.machine.hpca.bridge_component.tooltip": "Так ось звідки з'явився «масив» У вОМ", - "gtceu.machine.hpca.component_general.max_eut": "§6Макс. енергії:§f %d EU/т", - "gtceu.machine.hpca.component_general.upkeep_eut": "§eУтримання енергії:§f %d EU/т", - "gtceu.machine.hpca.component_type.bridge": "Дає§f вОМ§7 можливість під'єднюватися до§f мережевих комутаторів§7", - "gtceu.machine.hpca.component_type.computation_cooling": "§cВимагає до:§f %d охолодження", - "gtceu.machine.hpca.component_type.computation_cwut": "§9Обчислення:§f %d ОРО/т", - "gtceu.machine.hpca.component_type.cooler_active": "§bТип охолоджувача:§f активний", - "gtceu.machine.hpca.component_type.cooler_active_coolant": "§cВимагає до:§f %d мВ/т %s", - "gtceu.machine.hpca.component_type.cooler_cooling": "§aЗабезпечує:§f %d охолодження", - "gtceu.machine.hpca.component_type.cooler_passive": "§bТип охолоджувача:§f пасивний", - "gtceu.machine.hpca.component_type.damaged": "Може бути пошкоджений через перегрівання вОМ!", - "gtceu.machine.hpca.computation_component.damaged.name": "Пошкоджений вОМ-обчислювальний компонент", - "gtceu.machine.hpca.computation_component.damaged.tooltip": "Безкоштовні переробні матеріали", - "gtceu.machine.hpca.computation_component.tooltip": "Перші обчислення малюка", - "gtceu.machine.hpca.empty_component.tooltip": "Просто для заповнення простору", - "gtceu.machine.hpca.heat_sink_component.tooltip": "Безкоштовне охолодження! хіба щось буває безкоштовним?", - "gtceu.machine.hv_fluid_drilling_rig.tooltip": "Не проводить гідророзрив пласта", - "gtceu.machine.implosion_compressor.tooltip": "Єдина машина, з якою хочеться робити бум!", - "gtceu.machine.item_collector.gui.collect_range": "Підбір в області %sx%s блоків", - "gtceu.machine.item_collector.tooltip": "Збирає предмети навколо себе", - "gtceu.machine.large_boiler.bronze.tooltip": "Нам потрібно більше пари!", - "gtceu.machine.large_boiler.steel.tooltip": "Вуглезбагачувальна піч", - "gtceu.machine.large_boiler.titanium.tooltip": "Де чарівне суперпаливо?", - "gtceu.machine.large_boiler.tungstensteel.tooltip": "Як ви взагалі заправляєте цю штуку?", - "gtceu.machine.large_chemical_reactor.tooltip": "Реактор «Чорний ящик»", - "gtceu.machine.large_combustion_engine.tooltip": "Камера запалювання палива", - "gtceu.machine.large_combustion_engine.tooltip.boost_extreme": "§7Подавайте§f 80 мВ/с§7 рідкого кисню для виробництва до§f %s EU/т§7 при витраті§f 2x§7 палива.", - "gtceu.machine.large_combustion_engine.tooltip.boost_regular": "§7Подавайте§f 20 мВ/с§7 кисню для виробництва до§f %s EU/т§7 при витраті§f 2x§7 палива.", - "gtceu.machine.large_miner.ev.tooltip": "Копає руду замість вас", - "gtceu.machine.large_miner.iv.tooltip": "Біомний екскаватор", - "gtceu.machine.large_miner.luv.tooltip": "Земний комбайн", - "gtceu.machine.large_turbine.gas.tooltip": "Не реактивний двигун", - "gtceu.machine.large_turbine.plasma.tooltip": "Сифон плазмової енергії", - "gtceu.machine.large_turbine.steam.tooltip": "Не пхайте туди голову", - "gtceu.machine.laser_hatch.both.tooltip": "§cЛазерні кабелі повинні бути розміщені по прямій лінії!§7", - "gtceu.machine.laser_source_hatch.tooltip.0": "Передача живлення на відстані", - "gtceu.machine.laser_source_hatch.tooltip.1": "§cЛазерні кабелі повинні бути розміщені по прямій лінії!§7", - "gtceu.machine.laser_target_hatch.tooltip.0": "Отримання живлення на відстані", - "gtceu.machine.laser_target_hatch.tooltip.1": "§cЛазерні кабелі повинні бути розміщені по прямій лінії!§7", - "gtceu.machine.locked_safe.malfunctioning": "§cНесправність!", - "gtceu.machine.machine_hatch.locked": "Інтерфейс машини заблоковано", - "gtceu.machine.machine_hatch.processing_array": "Коли в§e конвеєрній лінії§7, утримує тільки машини, які працюють в§e обробчій лінії", - "gtceu.machine.machine_hatch.tooltip": "Спеціалізована шина доступу, яка утримує тільки дійсні предмети", - "gtceu.machine.maintenance_hatch.tooltip": "Для обслуговування конструкцій", - "gtceu.machine.maintenance_hatch_cleanroom_auto.tooltip.0": "Для автоматичного догляду за конструкціями з очищенням!", - "gtceu.machine.maintenance_hatch_cleanroom_auto.tooltip.1": "Очищає як:", - "gtceu.machine.maintenance_hatch_configurable.tooltip.0": "Для кращого контролю над конструкціями", - "gtceu.machine.maintenance_hatch_configurable.tooltip.1": "Починає роботу без проблем з обслуговуванням!", - "gtceu.machine.maintenance_hatch_full_auto.tooltip": "Для автоматичного догляду за конструкціями", - "gtceu.machine.maintenance_hatch_tape_slot.tooltip": "Вставте клейку стрічку, щоб запобігти проблемам", - "gtceu.machine.maintenance_hatch_tool_slot.tooltip": "Клацніть гніздо порожньою рукою, коли потрібні інструменти є в інвентарі, щоб вирішити проблему", - "gtceu.machine.miner.chunkradius": "Радіус чанків: %d", - "gtceu.machine.miner.fluid_usage": "Використовує§f %d мВ/т§7 §f %s§7, подвоюється при розгоні.", - "gtceu.machine.miner.minex": "mX: %d", - "gtceu.machine.miner.miney": "mY: %d", - "gtceu.machine.miner.minez": "mZ: %d", - "gtceu.machine.miner.multi.description": "Багатоблочний видобувний комбайн, який охоплює велику площу і видобуває величезну кількість руди.", - "gtceu.machine.miner.multi.modes": "Має режими вирівнювання по чанку та шовкового дотику.", - "gtceu.machine.miner.multi.production": "Виробляє в§f 3§7 рази більше руди, ніж§f дробарка§7.", - "gtceu.machine.miner.per_block": "§7забирає§f %ds§7 за блок", - "gtceu.machine.miner.radius": "Радіус: %d", - "gtceu.machine.miner.startx": "sX: %d", - "gtceu.machine.miner.starty": "sY: %d", - "gtceu.machine.miner.startz": "sZ: %d", - "gtceu.machine.muffle.off": "Приглушення звуку: вимкнено", - "gtceu.machine.muffle.on": "Приглушення звуку: Увімкнено", - "gtceu.machine.muffler_hatch.tooltip.0": "Утилізує відходи з машин", - "gtceu.machine.muffler_hatch.tooltip.1": "НЕ ПЕРЕКРИВАЙТЕ ВИХІД!", - "gtceu.machine.multi_furnace.tooltip": "Як у домашній духовці", - "gtceu.machine.multiblock.tank.tooltip": "Заправляйте та зливайте через контролер або клапани бака.", - "gtceu.machine.mv_fluid_drilling_rig.tooltip": "Нафтоперекачувальна помпа", - "gtceu.machine.network_switch.tooltip.0": "Ethernet-концентратор", - "gtceu.machine.network_switch.tooltip.1": "Використовується для маршрутизації та розподілу§f обчислень§7.", - "gtceu.machine.network_switch.tooltip.2": "Може об'єднати будь-яку кількість обчислювальних§f приймачів§7 у будь-яку кількість обчислювальних§f передавачів§7.", - "gtceu.machine.network_switch.tooltip.3": "Використовує§f %s EU/т§7 для кожного люка обчислювальних даних.", - "gtceu.machine.object_holder.tooltip": "Просунутий механізм утримання для дослідницької станції", - "gtceu.machine.parallel_hatch.display": "Регулюйте максимум паралелей конструкції", - "gtceu.machine.parallel_hatch_mk5.tooltip": "Дозволяє запускати до 4 рецептів паралельно.", - "gtceu.machine.parallel_hatch_mk6.tooltip": "Дозволяє запускати до 16 рецептів паралельно.", - "gtceu.machine.parallel_hatch_mk7.tooltip": "Дозволяє запускати до 64 рецептів паралельно.", - "gtceu.machine.parallel_hatch_mk8.tooltip": "Дозволяє запускати до 256 рецептів паралельно.", - "gtceu.machine.parallel_limit": "Дозволяє виконувати до§b %d§r§7 рецептів одночасно.", - "gtceu.machine.passthrough_hatch_fluid.tooltip": "Перекачує рідини з однієї сторони на іншу", - "gtceu.machine.passthrough_hatch_item.tooltip": "Переміщує предмети з однієї сторони на іншу", - "gtceu.machine.perfect_oc": "Не втрачає енергоефективність при розгоні.", - "gtceu.machine.primitive_blast_furnace.bronze.tooltip": "Створення першої сталі", - "gtceu.machine.primitive_water_pump.tooltip": "Ендервуар в домашніх умовах", - "gtceu.machine.processing_array.tooltip": "Коли кількох машин недостатньо", - "gtceu.machine.pump.tooltip_buckets": "§f%d§7 тактів за відро", - "gtceu.machine.pump_hatch.tooltip": "Примітивний вихід рідини для водяної помпи", - "gtceu.machine.pyrolyse_oven.tooltip": "Електрична коксувальна піч", - "gtceu.machine.pyrolyse_oven.tooltip.1": "§6Мельхіорові§7 котушки на§f 25%%§7 повільніші. кожна котушка після§b канталової§7 збільшує швидкість на§f 50%%§7.", - "gtceu.machine.quantum_chest.items_stored": "Кількість:", - "gtceu.machine.research_station.researching": "Дослідження.", - "gtceu.machine.research_station.tooltip.0": "Більше, ніж просто багатоблочний сканер", - "gtceu.machine.research_station.tooltip.1": "Використовується для сканування на§f сферах даних§7 та§f модулях даних§7.", - "gtceu.machine.research_station.tooltip.2": "Для роботи потрібні§f обчислення§7.", - "gtceu.machine.research_station.tooltip.3": "Забезпечення більшої кількості обчислень дозволяє рецепту працювати швидше.", - "gtceu.machine.rotor_holder.tooltip.1": "Утримує ротор на місці, щоб він не відлетів", - "gtceu.machine.steam.steam_hatch.tooltip": "§eПриймає рідину:§f пара", - "gtceu.machine.steam_boiler.heat_amount": "Теплоємність: %s %%", - "gtceu.machine.steam_bus.tooltip": "Не працює з непаровими конструкціями", - "gtceu.machine.steam_grinder.tooltip": "Багатоблочний подрібнювач без побічних продуктів", - "gtceu.machine.steam_oven.tooltip": "Не плутати з мультиплавильнею", - "gtceu.machine.substation_hatch.input.tooltip": "Вхід енергії для електропідстанції", - "gtceu.machine.substation_hatch.output.tooltip": "Вихід енергії для електропідстанції", - "gtceu.machine.tank_valve.tooltip": "Використовується для наповнення та спорожнення резервуарів конструкцій. Виводить автоматично, якщо розміщений лицьовою стороною донизу.", - "gtceu.machine.transformer.message_transform_down": "Трансформація вниз, вхід: %s EU %dA, вихід: %s EU %dA", - "gtceu.machine.transformer.message_transform_up": "Трансформація вгору, вхід: %s EU %dA, вихід: %s EU %dA", - "gtceu.machine.transformer.tooltip_tool_usage": "Починає з§f трансформації вниз§7, використовуйте викрутку для зміни", - "gtceu.machine.transformer.tooltip_transform_down": "§aТрансформування вниз:§f %dA %s EU (%s§f) -> %dA %s EU (%s§f)", - "gtceu.machine.transformer.tooltip_transform_up": "§cТрансформування вгору:§f %dA %s EU (%s§f) -> %dA %s EU (%s§f)", - "gtceu.machine.vacuum_freezer.tooltip": "Алюмінієвий контейнер для льоду", - "gtceu.machine.workbench.storage_note.0": "(Доступні предмети з під'єднаних", - "gtceu.machine.workbench.storage_note.1": "контейнерів доступні для майстрування)", - "gtceu.machine.workbench.tab.container": "Контейнер", - "gtceu.machine.workbench.tab.crafting": "Майстрування", - "gtceu.machine.workbench.tab.item_list": "Сховище", - "gtceu.machine.workbench.tab.workbench": "Майстрування", - "gtceu.machine.workbench.tooltip.0": "Краще Forestry", - "gtceu.machine.workbench.tooltip.1": "Має сховище предметів, сховище інструментів, витягує з сусідніх контейнерів і зберігає рецепти.", - "gtceu.machine.world_accelerator.description": "Тактово прискорює сусідні блоки в одному з 2 режимів:§f Блок-сутність§7 або§f випадковий такт§7. Використовуйте викрутку, щоб змінити режим.", - "gtceu.machine.world_accelerator.mode_entity": "Режим випадкового такту", - "gtceu.machine.world_accelerator.mode_tile": "Режим блока-сутності", - "gtceu.machine.world_accelerator.working_area": "§bРобоча зона:", - - "gtceu.universal.kiloliters": "%s B", - "gtceu.universal.liters": "%s мВ", - "gtceu.universal.tooltip.fluid_stored": "§2Збережена рідина:§f %s, %d мВ", - "gtceu.universal.tooltip.deprecated": "§4§l ПОПЕРЕДЖЕННЯ:§r§4 ЗАСТАРІЛО. БУДЕ ВИДАЛЕНО В МАЙБУТНІХ ВЕРСІЯХ.§r", - "gtceu.universal.tooltip.requires_redstone": "§4Потребує заживлення редстоуном", - "gtceu.universal.tooltip.item_storage_total": "§6Предметна місткість:§f %d предметів", - "gtceu.universal.tooltip.item_storage_capacity": "§6Предметних слотів:§f %d", - "gtceu.universal.tooltip.fluid_storage_capacity_mult": "§9Рідинна ємність:§f %d§7 резервуарів,§f %d мВ§7 кожний", - "gtceu.universal.tooltip.fluid_storage_capacity": "§9Рідинна ємність:§f %d мВ", - "gtceu.universal.tooltip.energy_tier_range": "§aДопустимі рівні напруги:§f %s§f - %s", - "gtceu.universal.tooltip.max_voltage_in_out": "§aМакс. напруга на вході/виході:§f %d EU/т (%s§f)", - "gtceu.universal.tooltip.max_voltage_in": "§aМакс. напруга на вході:§f %d (%s§f)", - "gtceu.universal.tooltip.max_voltage_out": "§aМакс. напруга на виході:§f %d (%s§f)", - "gtceu.universal.tooltip.voltage_in_out": "§aНапруга на вході/виході:§f %d EU/т (%s§f)", - "gtceu.universal.tooltip.voltage_in": "§aНапруга на вході:§f %d EU/т (%s§f)", - "gtceu.universal.tooltip.voltage_out": "§аНапруга на виході:§f %d EU/т (%s§f)", - "gtceu.universal.tooltip.working_area_max": "§bМакс. робоча зона:§f %dx%d", - "gtceu.universal.tooltip.working_area_chunks_max": "§bМакс. робоча зона:§f %dx%d чанків", - "gtceu.universal.tooltip.item_transfer_rate": "§bШвидкість передачі:§f %d предметів/с", - "gtceu.universal.tooltip.fluid_transfer_rate": "§bШвидкість передачі:§f %d мВ/т", - "gtceu.universal.tooltip.item_transfer_rate_stacks": "§bШвидкість передачі:§f %d стосів/с", - "gtceu.universal.tooltip.working_area": "§bРобоча зона:§f %dx%d", - "gtceu.universal.tooltip.working_area_chunks": "§bРобоча зона:§f %dx%d чанків", - "gtceu.universal.tooltip.energy_storage_capacity": "§cЕнергетична ємність:§r %d EU", - "gtceu.universal.clear_nbt_recipe.tooltip": "§cЦе знищить увесь вміст!", - "gtceu.universal.tooltip.item_stored": "§dПредметний вміст:§f %s, %d предметів", - "gtceu.universal.tooltip.parallel": "§dМакс. паралелей:§f %d", - "gtceu.universal.tooltip.amperage_in_till": "§eСила струму на вході до:§f %dA", - "gtceu.universal.tooltip.amperage_in_out_till": "§eСила струму на вході/виході до:§f %dA", - "gtceu.universal.tooltip.amperage_in_out": "§eСила струму на вході/виході:§f %dA", - "gtceu.universal.tooltip.amperage_in": "§eСила струму на вході:§f %dA", - "gtceu.universal.tooltip.amperage_out_till": "§eСила струму на виході до: §f%dA", - "gtceu.universal.tooltip.amperage_out": "§eСила струму на виході:§f %dA", - "gtceu.universal.tooltip.base_production_eut": "§eБазове виробництво:§f %d EU/т", - "gtceu.universal.tooltip.base_production_fluid": "§eБазове виробництво:§f %d мВ/т", - "gtceu.universal.tooltip.produces_fluid": "§eВиробляє:§f %d мВ/т", - "gtceu.universal.tooltip.chunk_mode": "Режим чанків: ", - "gtceu.universal.tooltip.silk_touch": "Шовковий дотик: ", - "gtceu.universal.tooltip.terrain_resist": "Ця машина не вибухне під час контакту з хім. елементами", - "gtceu.universal.tooltip.uses_per_op": "Використовує§f %d EU на операцію", - "gtceu.universal.tooltip.uses_per_second": "Використовує§f %d EU/c§7 під час роботи", - "gtceu.universal.tooltip.uses_per_tick": "Використовує§f %d EU/т§7 під час роботи", - "gtceu.universal.tooltip.uses_per_hour_lubricant": "Використовує§f %d мВ/год§7§6 мастила§7 під час роботи", - "gtceu.universal.tooltip.uses_per_tick_steam": "Використовує§f %d мВ/т§7§f пари§7 під час роботи", - - "command.gtceu.share_prospection_data.notification": "%s ділиться з вами розвідницькими даними!", - "command.gtceu.dump_data.success": "Перекинуто %s ресурсів з реєстру %s до %s", - "command.gtceu.place_vein.failure": "Не вдалося розмістити жилу %s на позиції %s", - "command.gtceu.place_vein.success": "Розміщено жилу %s на позиції %s", - - "gtceu.gui.auto_output.name": "авто", - "gtceu.gui.charger_slot.tooltip.0": "§fГніздо для зарядного пристрою§r", - "gtceu.gui.charger_slot.tooltip.1": "§7Живиться від %s акумуляторів§r", - "gtceu.gui.charger_slot.tooltip.2": "§7Заряджає %s інструментів та акумуляторів", - "gtceu.gui.chunkmode.disabled.0": "Режим чанків вимкнено: клацніть, щоб увімкнути.", - "gtceu.gui.chunkmode.disabled.1": "§7Перемикання вимагає зупинки машини.", - "gtceu.gui.chunkmode.enabled.0": "Режим чанків увімкнено: клацніть, щоб вимкнути.", - "gtceu.gui.chunkmode.enabled.1": "§7Перемикання вимагає зупинки машини.", - "gtceu.gui.circuit.title": "Налаштування схеми", - "gtceu.gui.config_slot": "§fКонфігураційний слот§r", - "gtceu.gui.config_slot.auto_pull_managed": "§4Вимкнено:§7 керується автоматичним витягуванням", - "gtceu.gui.config_slot.remove": "§7Клацніть ПКМ, щоб§4 очистити§7 конфігураційний слот.§r", - "gtceu.gui.config_slot.scroll": "§7Прокрутіть коліщатко, щоб§a змінити§7 число конфігурації.§r", - "gtceu.gui.config_slot.set": "§7Натисніть, щоб§b встановити/обрати§7 конфігураційний слот.§r", - "gtceu.gui.config_slot.set_only": "§7Натисніть, щоб§bвстановити§7 конфігураційний слот.§r", - "gtceu.gui.configurator_slot.tooltip.0": "§fСлот конфігуратора§r", - "gtceu.gui.configurator_slot.tooltip.1": "§7Помістіть§6 програмну плату§7 у це гніздо, щоб", - "gtceu.gui.configurator_slot.tooltip.2": "§7змінити його конфігурацію.", - "gtceu.gui.configurator_slot.tooltip.3": "§7Утримуйте§6 Shift§7 при натисканні кнопок, щоб змінювати на§6 5.", - "gtceu.gui.configurator_slot.tooltip.4": "§aПрограмна плата у цьому гнізді також дійсна для входів рецептів.§r", - "gtceu.gui.content.chance_base": "Базовий шанс: %s%%", - "gtceu.gui.content.chance_base_logic": "Базовий шанс: %s%% (%s)", - "gtceu.gui.content.chance_boosted": "Шанс на рівні: %s%%", - "gtceu.gui.content.chance_boosted_logic": "Шанс на рівні: %s%% (%s)", - "gtceu.gui.content.chance_nc": "§cНе витрачається§r", - "gtceu.gui.content.chance_nc_short": "§cНВ§r", - "gtceu.gui.content.chance_tier_boost_minus": "Додатковий шанс: -%s%%/рівень", - "gtceu.gui.content.chance_tier_boost_plus": "Додатковий шанс: +%s%%/рівень", - "gtceu.gui.content.count_range": "%s-%sx", - "gtceu.gui.content.per_tick": "§aСпожито/Вироблено за такт§r", - "gtceu.gui.content.tips.per_second_short": "§a/секунда§r", - "gtceu.gui.content.tips.per_tick_short": "§a/такт§r", - "gtceu.gui.content.units.per_second": "/s", - "gtceu.gui.content.units.per_tick": "/t", - "gtceu.gui.cover_setting.title": "Налаштування кришки", - "gtceu.gui.editor.group.recipe_type": "межа", - "gtceu.gui.editor.tips.citation": "Кількість цитувань", - "gtceu.gui.fisher_mode.tooltip.0": "Вимкнути видалення предметів", - "gtceu.gui.fisher_mode.tooltip.1": "Вимкнення коштує 2 нитки за операцію", - "gtceu.gui.fluid_amount": "Кількість рідини:", - "gtceu.gui.fluid_auto_input.tooltip.disabled": "Автовведення рідин вимкнено", - "gtceu.gui.fluid_auto_input.tooltip.enabled": "Автовведення рідин увімкнено", - "gtceu.gui.fluid_auto_output.allow_input.disabled": "вимкнути подачу рідин з боку виходу", - "gtceu.gui.fluid_auto_output.allow_input.enabled": "дозволити подачу рідин з боку виходу", - "gtceu.gui.fluid_auto_output.tooltip.disabled": "Автовиведення рідин вимкнено", - "gtceu.gui.fluid_auto_output.tooltip.enabled": "Автовиведення рідин увімкнено", - "gtceu.gui.fluid_lock.tooltip.disabled": "Блокування рідин вимкнено", - "gtceu.gui.fluid_lock.tooltip.enabled": "Блокування рідин увімкнено", - "gtceu.gui.fluid_voiding_partial.tooltip.disabled": "Видалення рідин вимкнено", - "gtceu.gui.fluid_voiding_partial.tooltip.enabled": "Видалення рідин увімкнено", - "gtceu.gui.fuel_amount": "Кількість пального:", - "gtceu.gui.item_auto_input.tooltip.disabled": "Автовведення предметів вимкнено", - "gtceu.gui.item_auto_input.tooltip.enabled": "Автовведення предметів увімкнено", - "gtceu.gui.item_auto_output.allow_input.disabled": "заборонити введення предметів з боку виходу", - "gtceu.gui.item_auto_output.allow_input.enabled": "дозволити введення предметів з боку виходу", - "gtceu.gui.item_auto_output.tooltip.disabled": "Автовиведення предметів вимкнено", - "gtceu.gui.item_auto_output.tooltip.enabled": "Автовиведення предметів увімкнено", - "gtceu.gui.item_lock.tooltip.disabled": "Блокування предметів вимкнено", - "gtceu.gui.item_lock.tooltip.enabled": "Блокування предметів увімкнено", - "gtceu.gui.item_voiding_partial.tooltip.disabled": "Видалення вимкнено", - "gtceu.gui.item_voiding_partial.tooltip.enabled": "Видалення увімкнено", - "gtceu.gui.machinemode": "Активний режим машини: %s", - "gtceu.gui.machinemode.title": "Активний режим машини", - "gtceu.gui.me_bus.auto_pull_button": "Натисніть, щоб увімкнути автоматичне витягування предметів з ME", - "gtceu.gui.me_network.offline": "Стан мережі:§4 Офлайн§r", - "gtceu.gui.me_network.online": "Стан мережі:§2 Онлайн§r", - "gtceu.gui.multiblock_fluid_voiding.0": "Режим видалення", - "gtceu.gui.multiblock_fluid_voiding.1": "§7Видалення§9 рідин", - "gtceu.gui.multiblock_item_fluid_voiding.0": "Режим видалення", - "gtceu.gui.multiblock_item_fluid_voiding.1": "§7Видалення§6 предметів§7 та§9 рідин", - "gtceu.gui.multiblock_item_voiding.0": "Режим видалення", - "gtceu.gui.multiblock_item_voiding.1": "§7Видалення§6 предметів", - "gtceu.gui.multiblock_no_voiding.0": "Режим анулювання", - "gtceu.gui.multiblock_no_voiding.1": "§7Видалення нічого", - "gtceu.gui.output_setting.title": "Налаштування виводу", - "gtceu.gui.output_setting.tooltips.0": "ЛКМ, щоб налаштувати автоматичне виведення предметів", - "gtceu.gui.output_setting.tooltips.1": "ПКМ, щоб налаштувати автоматичне виведення рідин.", - "gtceu.gui.overclock.description.0": "Кнопка розгону", - "gtceu.gui.overclock.description.1": "§7Рецепти можуть розганятися до встановленого рівня", - "gtceu.gui.overclock.disabled.0": "Розгін вимкнено.", - "gtceu.gui.overclock.disabled.1": "Натисніть, щоб увімкнути", - "gtceu.gui.overclock.enabled.0": "Розгін увімкнено.", - "gtceu.gui.overclock.enabled.1": "Натисніть, щоб вимкнути", - "gtceu.gui.overclock.off": "X", - "gtceu.gui.overclock.range": "Доступні рівні [%s, %s]", - "gtceu.gui.overclock.title": "Рівень розгону", - "gtceu.gui.silktouch.disabled.0": "Шовковий дотик вимкнено: Натисніть, щоб увімкнути.", - "gtceu.gui.silktouch.disabled.1": "§7Перемикання вимагає зупинки машини.", - "gtceu.gui.silktouch.enabled.0": "Шовковий дотик увімкнено: Натисніть, щоб вимкнути.", - "gtceu.gui.silktouch.enabled.1": "§7Перемикання вимагає зупинки машини.", - "gtceu.gui.sort": "Сортувати", - "gtceu.gui.title_bar.back": "Назад", - "gtceu.gui.title_bar.page_switcher": "Сторінки", - "gtceu.gui.toggle_view.disabled": "Перемкнути вид (Рідини)", - "gtceu.gui.toggle_view.enabled": "Перемкнути вид (Предмети)", - "gtceu.gui.waiting_list": "Черга на відправлення:", - "gtceu.part_sharing.disabled": "Спільний доступ конструкції§4 вимкнено", - "gtceu.part_sharing.enabled": "Спільний доступ конструкції§a увімкнено", - "item.gtceu.ash_dust": "Попіл", - "item.gtceu.basaltic_mineral_sand_dust": "Базальтовий мінеральний пісок", - "item.gtceu.bone_dust": "Кісткове борошно", - "item.gtceu.dark_ash_dust": "Темний попіл", - "item.gtceu.energium_dust": "Енергієвий пил", - "item.gtceu.fullers_earth_dust": "Відбілювальні глини", - "item.gtceu.garnet_sand_dust": "Гранатовий пісок", - "item.gtceu.glauconite_sand_dust": "Глауконітове скло", - "item.gtceu.granitic_mineral_sand_dust": "Гранітний мінеральний пісок", - "item.gtceu.ice_dust": "Подрібнений лід", - "item.gtceu.meat_dust": "Фарш", - "item.gtceu.palladium_raw_dust": "Сирий паладієвий пил", - "item.gtceu.paper_dust": "Паперова стружка", - "item.gtceu.platinum_raw_dust": "Пил необробленої платини", - "item.gtceu.platinum_sludge_residue_dust": "Залишок платинового шламу", - "item.gtceu.quartz_sand_dust": "Кварцовий пісок", - "item.gtceu.rare_earth_dust": "Рідкісноземельний пил", - "item.gtceu.rarest_metal_mixture_dust": "Суміш найрідкісніших металів", - "item.gtceu.rock_salt_dust": "Кам'яна сіль", - "item.gtceu.salt_dust": "Сіль", - "item.gtceu.wheat_dust": "Борошно", - "item.gtceu.wood_dust": "Дерев'яна стружка", - "item.invalid.name": "Неприпустимий предмет", - "item.gtceu.advanced_integrated_circuit.tooltip.0": "§7Менша та потужніша", - "item.gtceu.advanced_power_thruster": "Просунутий силовий рушій", - "item.gtceu.basic_integrated_circuit.tooltip.0": "§7Менша та потужніша", - "item.gtceu.basic_tape": "Клейка стрічка", - "item.gtceu.bio_chaff": "Біо полова", - "item.gtceu.borosilicate_glass_ingot": "Злиток боросилікатного скла", - "item.gtceu.brick_wooden_form": "Дерев'яна форма цеглини", - "item.gtceu.chipped_sugar_gem": "Маленький кубик цукру", - "item.gtceu.coke_oven_brick": "Цеглина коксової печі", - "item.gtceu.compressed_clay": "Пресована глина", - "item.gtceu.compressed_coke_clay": "Пресована коксова глина", - "item.gtceu.compressed_fireclay": "Пресована шамотна глина", - "item.gtceu.dough": "Тісто", - "item.gtceu.electric_jetpack": "Електричний реактивний ранець", - "item.gtceu.empty_wooden_form": "Порожня дерев'яна форма", - "item.gtceu.fertilizer": "Добриво", - "item.gtceu.fine_borosilicate_glass_wire": "Боросилікатне скловолокно", - "item.gtceu.flawed_sugar_gem": "Крихітний кубик цукру", - "item.gtceu.glass_plate": "Шибка", - "item.gtceu.glass_tube": "Скляна трубка", - "item.gtceu.good_integrated_circuit.tooltip.0": "§7Менша та потужніша", - "item.gtceu.long_wood_rod": "Довга палиця", - "item.gtceu.plant_ball": "Рослинна кулька", - "item.gtceu.sugar_gem": "Кубик цукру", - "item.gtceu.wood_bolt": "Коротка палиця", - "item.gtceu.wood_plate": "Дерев'яна дошка", - "item.netherrack_nether_quartz": "Незерська кварцова руда", - "item.gtceu.advanced_electric_jetpack": "Просунутий електричний реактивний ранець", - "item.gtceu.basic_tape.tooltip": "§7Не достатньо міцний для механічних проблем\nМожна використовувати для підняття ящиків, не скидаючи предмети з них", - "item.gtceu.black_dye_spray_can": "Аерозольний балончик (чорний)", - "item.gtceu.blue_dye_spray_can": "Аерозольний балончик (синій)", - "item.gtceu.brown_dye_spray_can": "Аерозольний балончик (коричневий)", - "item.gtceu.cyan_dye_spray_can": "Аерозольний балончик (бірюзовий)", - "item.gtceu.empty_spray_can": "Аерозольний балончик (порожній)", - "item.gtceu.empty_spray_can.tooltip": "§7Можна наповнити аерозолем різних кольорів", - "item.gtceu.gray_dye_spray_can": "Аерозольний балончик (сірий)", - "item.gtceu.green_dye_spray_can": "Аерозольний балончик (зелений)", - "item.gtceu.light_blue_dye_spray_can": "Аерозольний балончик (блакитний)", - "item.gtceu.light_gray_dye_spray_can": "Аерозольний балончик (світло-сірий)", - "item.gtceu.lime_dye_spray_can": "Аерозольний балончик (лаймовий)", - "item.gtceu.magenta_dye_spray_can": "Аерозольний балончик (пурпурний)", - "item.gtceu.orange_dye_spray_can": "Аерозольний балончик (помаранчевий)", - "item.gtceu.pink_dye_spray_can": "Аерозольний балончик (рожевий)", - "item.gtceu.purple_dye_spray_can": "Аерозольний балончик (фіолетовий)", - "item.gtceu.red_dye_spray_can": "Аерозольний балончик (червоний)", - "item.gtceu.solvent_spray_can": "Аерозольний балончик (Розчинник)", - "item.gtceu.white_dye_spray_can": "Аерозольний балончик (білий)", - "item.gtceu.yellow_dye_spray_can": "Аерозольний балончик (жовтий)", - "item.gtceu.blacklight": "Чорне світло", - "item.gtceu.blacklight.tooltip": "Довгохвильове§d ультрафіолетове§7 джерело світла", - "item.gtceu.capacitor": "Конденсатор", - "item.gtceu.capacitor.tooltip": "§7Базовий електронний компонент", - "item.gtceu.carbon_fiber_mesh": "Сітка з вуглецевого волокна", - "item.gtceu.carbon_fiber_plate": "Плита з вуглецевого волокна", - "item.gtceu.carbon_fibers": "Сире вуглецеве волокно", - "item.gtceu.chemical_black_dye": "Хімічний чорний барвник", - "item.gtceu.chemical_blue_dye": "Хімічний синій барвник", - "item.gtceu.chemical_brown_dye": "Хімічний коричневий барвник", - "item.gtceu.chemical_cyan_dye": "Хімічний бірюзовий барвник", - "item.gtceu.chemical_gray_dye": "Хімічний сірий барвник", - "item.gtceu.chemical_green_dye": "Хімічний зелений барвник", - "item.gtceu.chemical_light_blue_dye": "Хімічний блакитний барвник", - "item.gtceu.chemical_light_gray_dye": "Хімічний світло-сірий барвник", - "item.gtceu.chemical_lime_dye": "Хімічний лаймовий барвник", - "item.gtceu.chemical_magenta_dye": "Хімічний пурпурний барвник", - "item.gtceu.chemical_orange_dye": "Хімічний помаранчевий барвник", - "item.gtceu.chemical_pink_dye": "Хімічний рожевий барвник", - "item.gtceu.chemical_purple_dye": "Хімічний фіолетовий барвник", - "item.gtceu.chemical_red_dye": "Хімічний червоний барвник", - "item.gtceu.chemical_white_dye": "Хімічний білий барвник", - "item.gtceu.chemical_yellow_dye": "Хімічний жовтий барвник", - "item.gtceu.conveyor.module.tooltip": "§7Переміщує§f предмети§7 із певною кількістю як§f кришка§7.", - "item.gtceu.crystal_cpu": "Кришталевий CPU", - "item.gtceu.crystal_cpu.tooltip": "§7Кришталевий процесорний блок", - "item.gtceu.crystal_processor": "Кришталевий процесор", - "item.gtceu.crystal_processor.tooltip.0": "§7Використання переваг кришталевого гравіювання", - "item.gtceu.crystal_processor_assembly": "Кришталевий процесорний вузол", - "item.gtceu.crystal_processor_assembly.tooltip.0": "§7Використання переваг кришталевого гравіювання", - "item.gtceu.crystal_processor_computer": "Кришталевий процесорний суперкомп'ютер", - "item.gtceu.crystal_processor_computer.tooltip.0": "§7Використання переваг кришталевого гравіювання", - "item.gtceu.crystal_processor_mainframe": "Кришталевий процесорний мейнфрейм", - "item.gtceu.crystal_processor_mainframe.tooltip.0": "§7Використання переваг кришталевого гравіювання", - "item.gtceu.data_module": "Модуль даних", - "item.gtceu.data_orb": "Сфера даних", - "item.gtceu.data_stick": "Картка даних", - "item.gtceu.diamond_grinding_head": "Діамантова шліфувальна головка", - "item.gtceu.tungsten_grinding_head": "Вольфрамова шліфувальна головка", - "item.gtceu.diode.tooltip": "§7Базовий електронний компонент", - "item.gtceu.duct_tape": "BrainTech аерокосмічна вдосконалена армована клейка стрічка FAL-84", - "item.gtceu.duct_tape.tooltip": "§7Якщо ви не можете виправити це за допомогою цього, використовуйте більше!", - "item.gtceu.electric.pump.tooltip": "§7Переміщує§f рідини§7 із певною кількістю як§f кришка§7.", - "item.gtceu.energy_cluster": "Енергетичний кластер", - "item.gtceu.energy_cluster.tooltip": "§7Багаторазова батарея", - "item.gtceu.energy_crystal": "Енергієвий кристал", - "item.gtceu.energy_crystal.tooltip": "§7Багаторазова батарея", - "item.gtceu.energy_module": "Енергетичний модуль", - "item.gtceu.energy_module.tooltip": "§7Багаторазова батарея", - "item.gtceu.ev_battery_hull.tooltip": "§7Порожній корпус§5 EV§7 батареї", - "item.gtceu.hv_battery_hull.tooltip": "§7Порожній корпус§6 HV§7 батареї", - "item.gtceu.iv_battery_hull.tooltip": "§7Порожній корпус§1 IV§7 батареї", - "item.gtceu.luv_battery_hull.tooltip": "§7Порожній корпус§d LuV§7 батареї", - "item.gtceu.lv_battery_hull.tooltip": "§7Порожній корпус LV батареї", - "item.gtceu.mv_battery_hull.tooltip": "§7Порожній корпус§b MV§7 батареї", - "item.gtceu.uv_battery_hull.tooltip": "§7Порожній корпус§3 UV§7 батареї", - "item.gtceu.zpm_battery_hull.tooltip": "§7Порожній корпус§f ZPM§7 батареї", - "item.gtceu.ev_battery_hull": "Малий корпус ванадієвої батареї", - "item.gtceu.hv_battery_hull": "Великий корпус батареї", - "item.gtceu.iv_battery_hull": "Середній корпус ванадієвої батареї", - "item.gtceu.luv_battery_hull": "Великий корпус ванадієвої батареї", - "item.gtceu.lv_battery_hull": "Малий корпус батареї", - "item.gtceu.mv_battery_hull": "Середній корпус батареї", - "item.gtceu.uv_battery_hull": "Великий корпус наквуадрієвої батареї", - "item.gtceu.zpm_battery_hull": "Середній корпус наквуадрієвої батареї", - "item.gtceu.ev_vanadium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.hv_cadmium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.hv_lithium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.hv_sodium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.iv_vanadium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.luv_vanadium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.lv_cadmium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.lv_lithium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.lv_sodium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.mv_cadmium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.mv_lithium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.mv_sodium_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.ulv_tantalum_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.uv_naquadria_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.zpm_naquadria_battery.tooltip": "§7Багаторазова батарея", - "item.gtceu.max_battery.tooltip": "§7Зарядіть це щоб перемогти Minecraft", - "item.gtceu.ev_vanadium_battery": "Мала ванадієва батарея", - "item.gtceu.lv_cadmium_battery": "Мала кадмієва батарея", - "item.gtceu.lv_lithium_battery": "Мала літієва батарея", - "item.gtceu.lv_sodium_battery": "Мала натрієва батарея", - "item.gtceu.iv_vanadium_battery": "Середня ванадієва батарея", - "item.gtceu.mv_cadmium_battery": "Середня кадмієва батарея", - "item.gtceu.mv_lithium_battery": "Середня літієва батарея", - "item.gtceu.mv_sodium_battery": "Середня натрієва батарея", - "item.gtceu.zpm_naquadria_battery": "Середня наквуадрієва батарея", - "item.gtceu.hv_cadmium_battery": "Велика кадмієва батарея", - "item.gtceu.hv_lithium_battery": "Велика літієва батарея", - "item.gtceu.hv_sodium_battery": "Велика натрієва батарея", - "item.gtceu.luv_vanadium_battery": "Велика ванадієва батарея", - "item.gtceu.uv_naquadria_battery": "Велика наквуадрієва батарея", - "item.gtceu.max_battery": "Ультимативна батарея", - "block.gtceu.empty_tier_i_battery": "Порожній акумулятор I рівня", - "block.gtceu.empty_tier_ii_battery": "Порожній акумулятор II рівня", - "block.gtceu.empty_tier_iii_battery": "Порожній акумулятор III рівня", - "block.gtceu.ev_lapotronic_battery": "EV лапотронний акумулятор", - "block.gtceu.iv_lapotronic_battery": "IV лапотронний акумулятор", - "block.gtceu.luv_lapotronic_battery": "LuV лапотронний акумулятор", - "block.gtceu.zpm_lapotronic_battery": "ZPM лапотронний акумулятор", - "block.gtceu.uv_lapotronic_battery": "UV лапотронний акумулятор", - "block.gtceu.uhv_ultimate_battery": "UHV ультимативний акумулятор", - "item.gtceu.ev_conveyor_module": "EV конвеєрний модуль", - "item.gtceu.hv_conveyor_module": "HV конвеєрний модуль", - "item.gtceu.iv_conveyor_module": "IV конвеєрний модуль", - "item.gtceu.luv_conveyor_module": "LuV конвеєрний модуль", - "item.gtceu.lv_conveyor_module": "LV конвеєрний модуль", - "item.gtceu.mv_conveyor_module": "MV конвеєрний модуль", - "item.gtceu.opv_conveyor_module": "OpV конвеєрний модуль", - "item.gtceu.uev_conveyor_module": "UEV конвеєрний модуль", - "item.gtceu.uhv_conveyor_module": "UHV конвеєрний модуль", - "item.gtceu.uiv_conveyor_module": "UIV конвеєрний модуль", - "item.gtceu.uv_conveyor_module": "UV конвеєрний модуль", - "item.gtceu.uxv_conveyor_module": "UXV конвеєрний модуль", - "item.gtceu.zpm_conveyor_module": "ZPM конвеєрний модуль", - "item.gtceu.ev_electric_motor": "EV електричний мотор", - "item.gtceu.hv_electric_motor": "HV електричний мотор", - "item.gtceu.iv_electric_motor": "IV електричний мотор", - "item.gtceu.luv_electric_motor": "LuV електричний мотор", - "item.gtceu.lv_electric_motor": "LV електричний мотор", - "item.gtceu.mv_electric_motor": "MV електричний мотор", - "item.gtceu.opv_electric_motor": "OpV електричний мотор", - "item.gtceu.uev_electric_motor": "UEV електричний мотор", - "item.gtceu.uhv_electric_motor": "UHV електричний мотор", - "item.gtceu.uiv_electric_motor": "UIV електричний мотор", - "item.gtceu.uv_electric_motor": "UV електричний мотор", - "item.gtceu.uxv_electric_motor": "UXV електричний мотор", - "item.gtceu.zpm_electric_motor": "ZPM електричний мотор", - "item.gtceu.ev_emitter": "EV випромінювач", - "item.gtceu.hv_emitter": "HV випромінювач", - "item.gtceu.iv_emitter": "IV випромінювач", - "item.gtceu.luv_emitter": "LuV випромінювач", - "item.gtceu.lv_emitter": "LV випромінювач", - "item.gtceu.mv_emitter": "MV випромінювач", - "item.gtceu.opv_emitter": "OpV випромінювач", - "item.gtceu.uev_emitter": "UEV випромінювач", - "item.gtceu.uhv_emitter": "UHV випромінювач", - "item.gtceu.uiv_emitter": "UIV випромінювач", - "item.gtceu.uv_emitter": "UV випромінювач", - "item.gtceu.uxv_emitter": "UXV випромінювач", - "item.gtceu.zpm_emitter": "ZPM випромінювач", - "item.gtceu.ev_field_generator": "EV генератор поля", - "item.gtceu.hv_field_generator": "HV генератор поля", - "item.gtceu.iv_field_generator": "IV генератор поля", - "item.gtceu.luv_field_generator": "LuV генератор поля", - "item.gtceu.lv_field_generator": "LV генератор поля", - "item.gtceu.mv_field_generator": "MV генератор поля", - "item.gtceu.opv_field_generator": "OpV генератор поля", - "item.gtceu.uev_field_generator": "UEV генератор поля", - "item.gtceu.uhv_field_generator": "UHV генератор поля", - "item.gtceu.uiv_field_generator": "UIV генератор поля", - "item.gtceu.uv_field_generator": "UV генератор поля", - "item.gtceu.uxv_field_generator": "UXV генератор поля", - "item.gtceu.zpm_field_generator": "ZPM генератор поля", - "item.gtceu.ev_fluid_regulator": "EV регулятор рідини", - "item.gtceu.hv_fluid_regulator": "HV регулятор рідини", - "item.gtceu.iv_fluid_regulator": "IV регулятор рідини", - "item.gtceu.luv_fluid_regulator": "LuV регулятор рідини", - "item.gtceu.lv_fluid_regulator": "LV регулятор рідини", - "item.gtceu.mv_fluid_regulator": "MV регулятор рідини", - "item.gtceu.opv_fluid_regulator": "OpV регулятор рідини", - "item.gtceu.uev_fluid_regulator": "UEV регулятор рідини", - "item.gtceu.uhv_fluid_regulator": "UHV регулятор рідини", - "item.gtceu.uiv_fluid_regulator": "UIV регулятор рідини", - "item.gtceu.uv_fluid_regulator": "UV регулятор рідини", - "item.gtceu.uxv_fluid_regulator": "UXV регулятор рідини", - "item.gtceu.zpm_fluid_regulator": "ZPM регулятор рідини", - "item.gtceu.ev_power_unit": "EV блок живлення", - "item.gtceu.hv_power_unit": "HV блок живлення", - "item.gtceu.iv_power_unit": "IV блок живлення", - "item.gtceu.lv_power_unit": "LV блок живлення", - "item.gtceu.mv_power_unit": "MV блок живлення", - "item.gtceu.ev_robot_arm": "EV маніпулятор", - "item.gtceu.hv_robot_arm": "HV маніпулятор", - "item.gtceu.iv_robot_arm": "IV маніпулятор", - "item.gtceu.luv_robot_arm": "LuV маніпулятор", - "item.gtceu.lv_robot_arm": "LV маніпулятор", - "item.gtceu.mv_robot_arm": "MV маніпулятор", - "item.gtceu.opv_robot_arm": "OpV маніпулятор", - "item.gtceu.uev_robot_arm": "UEV маніпулятор", - "item.gtceu.uhv_robot_arm": "UHV маніпулятор", - "item.gtceu.uiv_robot_arm": "UIV маніпулятор", - "item.gtceu.uv_robot_arm": "UV маніпулятор", - "item.gtceu.uxv_robot_arm": "UXV маніпулятор", - "item.gtceu.zpm_robot_arm": "ZPM маніпулятор", - "item.gtceu.ev_sensor": "EV сенсор", - "item.gtceu.hv_sensor": "HV сенсор", - "item.gtceu.iv_sensor": "IV сенсор", - "item.gtceu.luv_sensor": "LuV сенсор", - "item.gtceu.lv_sensor": "LV сенсор", - "item.gtceu.mv_sensor": "MV сенсор", - "item.gtceu.opv_sensor": "OpV сенсор", - "item.gtceu.uev_sensor": "UEV сенсор", - "item.gtceu.uhv_sensor": "UHV сенсор", - "item.gtceu.uiv_sensor": "UIV сенсор", - "item.gtceu.uv_sensor": "UV сенсор", - "item.gtceu.uxv_sensor": "UXV сенсор", - "item.gtceu.zpm_sensor": "ZPM сенсор", - "item.gtceu.ev_solar_panel": "Сонячна панель екстремальної напруги", - "item.gtceu.hv_solar_panel": "Сонячна панель високої напруги", - "item.gtceu.iv_solar_panel": "Сонячна панель неможливої напруги", - "item.gtceu.luv_solar_panel": "Сонячна панель сміхотворної напруги", - "item.gtceu.lv_solar_panel": "Сонячна панель низької напруги", - "item.gtceu.mv_solar_panel": "Сонячна панель середньої напруги", - "item.gtceu.solar_panel": "Сонячна панель", - "item.gtceu.ulv_solar_panel": "Сонячна панель ультранизької напруги", - "item.gtceu.uv_solar_panel": "Сонячна панель ультимативної напруги", - "item.gtceu.zpm_solar_panel": "Сонячна панель модуля нульової точки", - "item.gtceu.ev_voltage_coil": "Котушка екстремальної напруги", - "item.gtceu.hv_voltage_coil": "Котушка високої напруги", - "item.gtceu.iv_voltage_coil": "Котушка божевільної напруги", - "item.gtceu.luv_voltage_coil": "Котушка сміхотворної напруги", - "item.gtceu.lv_voltage_coil": "Котушка низької напруги", - "item.gtceu.mv_voltage_coil": "Котушка середньої напруги", - "item.gtceu.ulv_voltage_coil": "Котушка надмірно низької напруги", - "item.gtceu.uv_voltage_coil": "Котушка ультимативної напруги", - "item.gtceu.zpm_voltage_coil": "Котушки напруги модуля нульової точки", - "item.gtceu.ev_voltage_coil.tooltip": "Екстремальна котушка", - "item.gtceu.hv_voltage_coil.tooltip": "Просунута котушка", - "item.gtceu.iv_voltage_coil.tooltip": "Елітна котушка", - "item.gtceu.luv_voltage_coil.tooltip": "Майстерська котушка", - "item.gtceu.lv_voltage_coil.tooltip": "Базова котушка", - "item.gtceu.max_voltage_coil.tooltip": "Максимальна котушка", - "item.gtceu.mv_voltage_coil.tooltip": "Хороша котушка", - "item.gtceu.opv_voltage_coil.tooltip": "Легендарна котушка", - "item.gtceu.uev_voltage_coil.tooltip": "Нереальна котушка", - "item.gtceu.uhv_voltage_coil.tooltip": "Ультракотушка", - "item.gtceu.uiv_voltage_coil.tooltip": "Божевільна котушка", - "item.gtceu.ulv_voltage_coil.tooltip": "Примітивна котушка", - "item.gtceu.uv_voltage_coil.tooltip": "Ультимативна котушка", - "item.gtceu.uxv_voltage_coil.tooltip": "Епічна котушка", - "item.gtceu.zpm_voltage_coil.tooltip": "Суперкотушка", - "block.gtceu.cupronickel_coil_block": "Блок мельхіорової котушки", - "block.gtceu.molybdenum_disilicide_coil_block": "Блок дисиліцид молібденової котушки", - "block.gtceu.kanthal_coil_block": "Блок канталової котушки", - "block.gtceu.nichrome_coil_block": "Блок ніхромової котушки", - "block.gtceu.rtm_alloy_coil_block": "Блок котушки з RTM-сплаву", - "block.gtceu.hssg_coil_block": "Блок HSS-G котушки", - "block.gtceu.naquadah_coil_block": "Блок наквуадової котушки", - "block.gtceu.trinium_coil_block": "Блок тринієвої котушки", - "block.gtceu.tritanium_coil_block": "Блок тританієвої котушки", - "block.gtceu.superconducting_coil": "Блок надпровідної котушки", - "block.gtceu.fusion_coil": "Блок термоядерної котушки", - "item.gtceu.face_mask": "Лицьова маска", - "item.gtceu.firebrick": "Шамотна цеглина", - "item.gtceu.firebrick.tooltip": "§7Термостійка", - "item.gtceu.fluid_filter": "Рідинний фільтр", - "item.gtceu.fluid_tag_filter": "Рідинний теговий фільтр", - "item.gtceu.item_filter": "Предметний фільтр", - "item.gtceu.item_smart_filter": "Розумний предметний фільтр", - "item.gtceu.item_tag_filter": "Предметний теговий фільтр", - "item.gtceu.fluid.regulator.tooltip": "§7Обмежує§f рідини§7 до певної кількості як§f кришка§7.", - "item.gtceu.fluid_filter.tooltip.0": "§7Фільтрує§f рідинний§7 вхід/вихід як§f кришка§7.", - "item.gtceu.fluid_tag_filter.tooltip.0": "§7Фільтрує§f рідинний§7 вхід/вихід із§f рідинними тегами§7 як§f кришка§7.", - "item.gtceu.item_filter.tooltip.0": "§7Фільтрує§f предметний§7 вхід/вихід як§f кришка§7.", - "item.gtceu.item_smart_filter.tooltip.0": "§7Фільтрує§f предметний§7 вхід/вихід із§f рецептами машини§7 як§f кришка§7.", - "item.gtceu.item_tag_filter.tooltip.0": "§7Фільтрує§f предметний§7 вхід/вихід із§f предметними тегами§7 як§f кришка§7.", - "item.gtceu.tag_filter.tooltip.0": "§7Фільтрує§f предметний§7 вхід/вихід із§f тегами§7 як§f кришка§7.", - "item.gtceu.fluid_filter.tooltip.1": "Може використовуватися як§f електрична помпа§7 та покращення§f рідинного регулятора§7.", - "item.gtceu.fluid_tag_filter.tooltip.1": "Може використовуватися як§f електрична помпа§7 та покращення§f рідинного регулятора§7.", - "item.gtceu.item_filter.tooltip.1": "Може використовуватися як§f конвеєрний модуль§7 та покращення§f маніпулятора§7.", - "item.gtceu.item_smart_filter.tooltip.1": "Може використовуватися як§f конвеєрний модуль§7 та покращення§f маніпулятора§7.", - "item.gtceu.item_tag_filter.tooltip.1": "Може використовуватися як§f конвеєрний модуль§7 та покращення§f маніпулятора§7.", - "item.gtceu.tag_filter.tooltip.1": "Може використовуватися як§f конвеєрний модуль§7 та покращення§f маніпулятора§7.", - "item.gtceu.gelled_toluene": "Гелевий толуол", - "item.gtceu.gelled_toluene.tooltip": "§7Сира вибухівка", - "item.gtceu.gravi_star": "Граві-зірка", - "item.gtceu.gravi_star.tooltip": "§7Ультимативна зірка Незеру", - "item.gtceu.gravitation_engine_unit": "Блок гравітаційного двигуна", - "item.gtceu.hazmat_boots": "Чоботи костюма для роботи з небезпечними матеріалами", - "item.gtceu.hazmat_chestpiece": "Куртка костюма для роботи з небезпечними матеріалами", - "item.gtceu.hazmat_headpiece": "Головний убір костюма для роботи з небезпечними матеріалами", - "item.gtceu.hazmat_leggings": "Штани костюма для роботи з небезпечними матеріалами", - "item.gtceu.advanced_soc_wafer": "Підкладка ASoC", - "item.gtceu.highly_advanced_soc_wafer": "Підкладка HASoC", - "item.gtceu.simple_soc_wafer": "Підкладка базової SoC", - "item.gtceu.soc_wafer": "Підкладка SoC", - "item.gtceu.cpu_wafer": "Підкладка CPU", - "item.gtceu.hpic_wafer": "Підкладка HPIC", - "item.gtceu.ilc_wafer": "Підкладка ILC", - "item.gtceu.lpic_wafer": "Підкладка LPIC", - "item.gtceu.mpic_wafer": "Підкладка MPIC", - "item.gtceu.nand_memory_wafer": "Підкладка пам'яті NAND", - "item.gtceu.nor_memory_wafer": "Підкладка пам'яті NOR", - "item.gtceu.nano_cpu_wafer": "Підкладка нано CPU", - "item.gtceu.naquadah_wafer": "Легована наквуадою підкладка", - "item.gtceu.neutronium_wafer": "Легована нейтронієм підкладка", - "item.gtceu.phosphorus_wafer": "Легована фосфором підкладка", - "item.gtceu.qbit_cpu_wafer": "Підкладка кубітного CPU", - "item.gtceu.ram_wafer": "Підкладка RAM", - "item.gtceu.silicon_wafer": "Силіконова підкладка", - "item.gtceu.uhpic_wafer": "Підкладка UHPIC", - "item.gtceu.ulpic_wafer": "Підкладка ULPIC", - "item.gtceu.cpu_chip": "Чіп CPU", - "item.gtceu.engraved_crystal_chip": "Гравірований кришталевий чіп", - "item.gtceu.engraved_lapotron_crystal_chip": "Гравірований лапотронний кришталевий чіп", - "item.gtceu.hpic_chip": "Чіп HPIC", - "item.gtceu.ilc_chip": "Чіп IC", - "item.gtceu.lpic_chip": "Чіп LPIC", - "item.gtceu.mpic_chip": "Чіп MPIC", - "item.gtceu.nand_chip": "Чіп NAND", - "item.gtceu.nand_memory_chip": "Чіп пам'яті NAND", - "item.gtceu.nano_cpu_chip": "Чіп нано CPU", - "item.gtceu.nor_memory_chip": "Чіп пам'яті NOR", - "item.gtceu.qbit_cpu_chip": "Чіп кубітного CPU", - "item.gtceu.ram_chip": "Чіп RAM", - "item.gtceu.raw_crystal_chip": "Сирий кришталевий чіп", - "item.gtceu.uhpic_chip": "Чіп UHPIC", - "item.gtceu.ulpic_chip": "Чіп ULPIC", - "item.gtceu.cpu_chip.tooltip": "§7Центральний процесорний блок", - "item.gtceu.engraved_crystal_chip.tooltip": "§7Потрібно для схем", - "item.gtceu.hpic_chip.tooltip": "§7IC високої напруги", - "item.gtceu.ilc_chip.tooltip": "§7Інтегральна логічна схема", - "item.gtceu.lpic_chip.tooltip": "§7IC низької напруги", - "item.gtceu.mpic_chip.tooltip": "§7IC напруги", - "item.gtceu.nand_chip.tooltip.0": "§7Надзвичайно простий електронний компонент", - "item.gtceu.nand_memory_chip.tooltip": "§7Логічний вентиль NAND", - "item.gtceu.nano_cpu_chip.tooltip": "§7Нано центральний процесорний блок", - "item.gtceu.nor_memory_chip.tooltip": "§7Логічний вентиль NOR", - "item.gtceu.qbit_cpu_chip.tooltip": "§7Кубітний центральний процесорний блок", - "item.gtceu.ram_chip.tooltip": "§7Оперативна пам'ять", - "item.gtceu.raw_crystal_chip.tooltip": "§7Сирий кришталевий чіп", - "item.gtceu.uhpic_chip.tooltip": "§7IC надмірно високої напруги", - "item.gtceu.ulpic_chip.tooltip": "§7IC надмірно низької напруги", - "item.gtceu.smd_capacitor.tooltip": "§7Електронний компонент", - "item.gtceu.smd_diode.tooltip": "§7Електронний компонент", - "item.gtceu.smd_inductor.tooltip": "§7Електронний компонент", - "item.gtceu.smd_resistor.tooltip": "§7Електронний компонент", - "item.gtceu.smd_transistor.tooltip": "§7Електронний компонент", - "item.gtceu.advanced_smd_capacitor.tooltip": "§7Просунутий електронний компонент", - "item.gtceu.advanced_smd_diode.tooltip": "§7Просунутий електронний компонент", - "item.gtceu.advanced_smd_inductor.tooltip": "§7Просунутий електронний компонент", - "item.gtceu.advanced_smd_resistor.tooltip": "§7Просунутий електронний компонент", - "item.gtceu.advanced_smd_transistor.tooltip": "§7Просунутий електронний компонент", - "item.gtceu.smd_capacitor": "SMD конденсатор", - "item.gtceu.smd_inductor": "SMD індуктор", - "item.gtceu.smd_resistor": "SMD резистор", - "item.gtceu.smd_transistor": "SMD транзистор", - "item.gtceu.advanced_smd_capacitor": "Просунутий SMD конденсатор", - "item.gtceu.advanced_smd_inductor": "Просунутий SMD індуктор", - "item.gtceu.advanced_smd_resistor": "Просунутий SMD резистор", - "item.gtceu.advanced_smd_transistor": "Просунутий SMD транзистор", - "item.gtceu.advanced_soc": "ASoC", - "item.gtceu.crystal_soc": "Кришталева SoC", - "item.gtceu.highly_advanced_soc": "HASoC", - "item.gtceu.simple_soc": "Базова SoC", - "item.gtceu.soc": "SoC", - "item.gtceu.advanced_soc.tooltip": "§7Просунута система на чіпі", - "item.gtceu.crystal_soc.tooltip": "§7Кришталева система на чіпі", - "item.gtceu.highly_advanced_soc.tooltip": "§7Високорозвинена система на чіпі", - "item.gtceu.simple_soc.tooltip": "§7Базова система на чіпі", - "item.gtceu.soc.tooltip": "§7Система на чіпі", - "item.gtceu.advanced_soc_wafer.tooltip": "§7Сира просунута схема", - "item.gtceu.highly_advanced_soc_wafer.tooltip": "§7Сира високорозвинена схема", - "item.gtceu.simple_soc_wafer.tooltip": "§7Сира проста схема", - "item.gtceu.soc_wafer.tooltip": "§7Сира базова схема", - "item.gtceu.cpu_wafer.tooltip": "§7Сирий процесорний блок", - "item.gtceu.nand_memory_wafer.tooltip": "§7Сирий логічний вентиль", - "item.gtceu.nor_memory_wafer.tooltip": "§7Сирий логічний вентиль", - "item.gtceu.ram_wafer.tooltip": "§7Сира пам'ять", - "item.gtceu.ev_electric_piston": "EV електричний поршень", - "item.gtceu.hv_electric_piston": "HV електричний поршень", - "item.gtceu.iv_electric_piston": "IV електричний поршень", - "item.gtceu.luv_electric_piston": "LuV електричний поршень", - "item.gtceu.lv_electric_piston": "LV електричний поршень", - "item.gtceu.mv_electric_piston": "MV електричний поршень", - "item.gtceu.opv_electric_piston": "OpV електричний поршень", - "item.gtceu.uev_electric_piston": "UEV електричний поршень", - "item.gtceu.uhv_electric_piston": "UHV електричний поршень", - "item.gtceu.uiv_electric_piston": "UIV електричний поршень", - "item.gtceu.uv_electric_piston": "UV електричний поршень", - "item.gtceu.uxv_electric_piston": "UXV електричний поршень", - "item.gtceu.zpm_electric_piston": "ZPM електричний поршень", - "item.gtceu.hv_item_magnet": "HV предметний магніт", - "item.gtceu.lv_item_magnet": "LV предметний магніт", - "item.gtceu.inductor": "Індуктор", - "item.gtceu.inductor.tooltip": "§7Мала котушка", - "item.gtceu.inert_metal_mixture_dust": "Інертна металева суміш", - "item.gtceu.iridium_metal_residue_dust": "Металевий залишок іридію", - "item.gtceu.lapotron_crystal": "Лапотронний кристал", - "item.gtceu.lapotron_crystal.tooltip": "§7Багаторазова батарея", - "item.gtceu.lapotronic_energy_orb": "Лапотронна енергетична сфера", - "item.gtceu.lapotronic_energy_orb.tooltip": "§7Багаторазова батарея", - "item.gtceu.lapotronic_energy_orb_cluster": "Кластер лапотронної енергетичної сфери", - "item.gtceu.lapotronic_energy_orb_cluster.tooltip": "§7Багаторазова батарея", - "item.gtceu.liquid_fuel_jetpack": "Рідкопаливний реактивний ранець", - "item.gtceu.machine_controller.tooltip": "§7Перемикає стан§f машини§7 як§f кришка§7.", - "item.gtceu.machine_memory_card": "Карта пам'яті машини", - "item.gtceu.mask_filter": "Фільтр газової маски", - "item.gtceu.matchbox": "Упаковка сірників", - "item.gtceu.matches": "Сірник", - "item.gtceu.micro_processor": "Мікропроцессор", - "item.gtceu.micro_processor.tooltip.0": "§7Вражаюча швидкість обчислень!", - "item.gtceu.micro_processor_assembly": "Мікропроцесорний вузол", - "item.gtceu.micro_processor_assembly.tooltip.0": "§7Вражаюча швидкість обчислень!", - "item.gtceu.micro_processor_computer": "Мікропроцесорний суперкомп'ютер", - "item.gtceu.micro_processor_computer.tooltip.0": "§7Вражаюча швидкість обчислень!", - "item.gtceu.micro_processor_mainframe": "Мікропроцесорний мейнфрейм", - "item.gtceu.micro_processor_mainframe.tooltip.0": "§7Вражаюча швидкість обчислень!", - "item.gtceu.microchip_processor": "Мікрочіповий процесор", - "item.gtceu.nan_certificate": "Сертифікат шо ти вже не нубік", - "item.gtceu.nan_certificate.tooltip": "Виклик прийнято!", - "item.gtceu.nano_processor": "Нанопроцесор", - "item.gtceu.nano_processor.tooltip.0": "§7Менше, ніж будь-коли", - "item.gtceu.nano_processor_assembly": "Нанопроцесорний вузол", - "item.gtceu.nano_processor_assembly.tooltip.0": "§7Менше, ніж будь-коли", - "item.gtceu.nano_processor_computer": "Нанопроцесорний суперкомп'ютер", - "item.gtceu.nano_processor_computer.tooltip.0": "§7Менше, ніж будь-коли", - "item.gtceu.nano_processor_mainframe": "Нанопроцесорний мейнфрейм", - "item.gtceu.nano_processor_mainframe.tooltip.0": "§7Менше, ніж будь-коли", - "item.gtceu.nano_saber": "Наношабля", - "item.gtceu.nano_saber.tooltip": "§7Ryujin no ken wo kurae!", - "item.gtceu.avanced_nanomuscle_chestplate": "Просунутий NanoMuscle™ люксовий нагрудник", - "item.gtceu.nanomuscle_boots": "NanoMuscle™ люксові чоботи", - "item.gtceu.nanomuscle_chestplate": "NanoMuscle™ люксовий нагрудник", - "item.gtceu.nanomuscle_helmet": "NanoMuscle™ люксовий шолом", - "item.gtceu.nanomuscle_leggings": "NanoMuscle™ люксові наголінники", - "item.gtceu.naquadah_boule": "Легована наквуадою монокристалічна силіконова маса", - "item.gtceu.neutronium_boule": "Легована нейтронієм монокристалічна силіконова маса", - "item.gtceu.phosphorus_boule": "Легована фосфором монокристалічна силіконова маса", - "item.gtceu.silicon_boule": "Монокристалічна силіконова маса", - "item.gtceu.neuro_processing_unit": "Нейропроцесорний блок", - "item.gtceu.neuro_processing_unit.tooltip": "§7Нейро CPU", - "item.gtceu.neutron_reflector": "Іридієвий відбивач нейтронів", - "item.gtceu.neutron_reflector.tooltip": "§7Незнищенний", - "item.gtceu.nightvision_goggles": "Окуляри нічного бачення", - "item.gtceu.paracetamol_pill": "Пігулка парацетамолу", - "item.gtceu.rad_away_pill": "Пігулка антирадину™", - "item.gtceu.petri_dish": "Чашка петри", - "item.gtceu.petri_dish.tooltip": "§7Для вирощування клітин", - "item.gtceu.power_thruster": "Силовий рушій", - "item.gtceu.prospector.hv": "Просунутий розвідник (HV)", - "item.gtceu.prospector.luv": "Супер розвідник (LuV)", - "item.gtceu.prospector.lv": "Рудошукач (LV)", - "item.gtceu.purple_drink": "Фіолетовий напій", - "item.gtceu.bottle.purple.drink.tooltip": "§Як щодо лимонаду? або чаю з льодом? У мене є фіолетовий напій!", - "item.gtceu.quantum_eye": "Квантове око", - "item.gtceu.quantum_eye.tooltip": "§7Поліпшене око енду", - "item.gtceu.quantum_processor": "Квантовий процесор", - "item.gtceu.quantum_processor.tooltip.0": "§7Квантові обчислення оживають!", - "item.gtceu.quantum_processor_assembly": "Квантовий процесорний вузол", - "item.gtceu.quantum_processor_assembly.tooltip.0": "§7Квантові обчислення оживають!", - "item.gtceu.quantum_processor_computer": "Квантовий процесорний суперкомп'ютер", - "item.gtceu.quantum_processor_computer.tooltip.0": "§7Квантові обчислення оживають!", - "item.gtceu.quantum_processor_mainframe": "Квантовий процесорний мейнфрейм", - "item.gtceu.quantum_processor_mainframe.tooltip.0": "§7Квантові обчислення оживають!", - "item.gtceu.quantum_star": "Квантова зірка", - "item.gtceu.quantum_star.tooltip": "§7Поліпшена зірка Незеру", - "item.gtceu.advanced_quarktech_chestplate": "Просунутий QuarkTech™ люксовий нагрудник", - "item.gtceu.quarktech_boots": "QuarkTech™ люксові чоботи", - "item.gtceu.quarktech_chestplate": "QuarkTech™ люксовий нагрудник", - "item.gtceu.quarktech_helmet": "QuarkTech™ люксовий шолом", - "item.gtceu.quarktech_leggings": "QuarkTech™ люксові наголінники", - "item.gtceu.raw_crystal_chip_parts": "Частинки сирого кристалічного чіпу", - "item.gtceu.raw_crystal_chip_parts.tooltip": "§7Частинки сирого кристалічного процесора", - "item.gtceu.resistor": "Резистор", - "item.gtceu.resistor.tooltip": "§7Базовий електронний компонент", - "item.gtceu.robot.arm.tooltip": "§7Обмежує§f предмети§7 до певної кількості як§f кришка§7.", - "item.gtceu.rubber_boat": "Каучуковий човен", - "item.gtceu.rubber_chest_boat": "Каучуковий човен зі скринею", - "item.gtceu.rubber_gloves": "Гумові рукавиці", - "item.gtceu.activity_detector_cover.tooltip": "§7Видає§f статус активності§7 як редстоун та§f кришка§7.", - "item.gtceu.advanced_activity_detector_cover.tooltip": "§7Видає§f прогрес машини§7 як редстоун та§f кришка§7.", - "item.gtceu.advanced_energy_detector_cover.tooltip": "§7Видає§f RS-засув§7 контрольований§f статус енергії§7 як редстоун та§f кришка§7.", - "item.gtceu.advanced_fluid_detector_cover.tooltip": "§7Видає§f RS-засув§7 контрольований§f статус наявної рідини§7 як редстоун та§f кришка§7.", - "item.gtceu.advanced_fluid_voiding_cover.tooltip.0": "§7Видаляє§f рідини§7 з контролем кількості, як§f кришка§7.", - "item.gtceu.advanced_fluid_voiding_cover.tooltip.1": "Активуйте§f м'яким молотком§7 після розміщення.", - "item.gtceu.advanced_item_detector_cover.tooltip": "§7Видає§f RS-засув§7 контрольований§f статус наявних предметів§7 як редстоун та§f кришка§7.", - "item.gtceu.advanced_item_voiding_cover.tooltip.0": "§7Видаляє§f предмети§7 з контролем кількості, як§f кришка§7.", - "item.gtceu.advanced_item_voiding_cover.tooltip.1": "Активуйте§f м'яким молотком§7 після розміщення.", - "item.gtceu.computer_monitor_cover.tooltip": "§7Відображає§f дані§7 як§f кришка§7.", - "item.gtceu.ender_fluid_link_cover.tooltip": "§7Переміщує§f рідини§7 за допомогою§f безпровідого з'єднання§d енду§f§7 як§f кришка§7.", - "item.gtceu.energy_detector_cover.tooltip": "§7Видає§f кількість енергії§7 як редстоун та§f кришка§7.", - "item.gtceu.fluid_detector_cover.tooltip": "§7Видає§f кількість рідини§7 як редстоун та§f кришка§7.", - "item.gtceu.fluid_voiding_cover.tooltip.0": "§7Видаляє§f рідини§7 як§f кришка§7.", - "item.gtceu.fluid_voiding_cover.tooltip.1": "Активуйте§f м'яким молотком§7 після розміщення.", - "item.gtceu.infinite_water_cover.tooltip": "§7Заповнює приєднані контейнери §9 водою§7 як§f кришка§7.", - "item.gtceu.item_detector_cover.tooltip": "§7Видає§f Item Amount§7 як редстоун та§f кришка§7.", - "item.gtceu.item_voiding_cover.tooltip.0": "§7Видаляє§f предмети§7 як§f кришка§7.", - "item.gtceu.item_voiding_cover.tooltip.1": "Активуйте§f м'яким молотком§7 після розміщення.", - "item.gtceu.shutter_module_cover.tooltip": "§fПереміщує блоки§7 через приєднаний бік як§f кришка§7.", - "item.gtceu.activity_detector_cover": "Детектор активності", - "item.gtceu.advanced_activity_detector_cover": "Просунутий детектор активності", - "item.gtceu.advanced_energy_detector_cover": "Просунутий детектор енергії", - "item.gtceu.energy_detector_cover": "Energy Detector", - "item.gtceu.advanced_fluid_detector_cover": "Просунутий детектор рідин", - "item.gtceu.fluid_detector_cover": "Детектор рідин", - "item.gtceu.advanced_fluid_voiding_cover": "Просунута кришка видалення рідини", - "item.gtceu.fluid_voiding_cover": "Кришка видалення рідини", - "item.gtceu.advanced_item_detector_cover": "Просунутий детектор предметів", - "item.gtceu.item_detector_cover": "Детектор предметів", - "item.gtceu.advanced_item_voiding_cover": "Просунута кришка видалення предметів", - "item.gtceu.item_voiding_cover": "Кришка видалення предметів", - "item.gtceu.computer_monitor_cover": "Комп'ютерний монітор", - "item.gtceu.ender_fluid_link_cover": "Рідинний зв'язок енду", - "item.gtceu.infinite_water_cover": "Кришка джерела води", - "item.gtceu.machine_controller_cover": "Контролер машини", - "item.gtceu.maintenance_detector_cover": "Детектор технічного обслуговування", - "item.gtceu.shutter_module_cover": "Модуль затвору", - "item.gtceu.storage_cover": "Кришка сховища", - "item.gtceu.solar_panel.tooltip.0": "§7Нехай сонце буде з вами.", - "item.gtceu.solar_panel.tooltip.1": "Виробляє§f енергію§7 з§e сонця§7 як§f кришка§7.", - "item.gtceu.iron_minecart_wheels": "Залізні колеса вагонетки", - "item.gtceu.steel_minecart_wheels": "Сталеві колеса вагонетки", - "item.gtceu.stem_cells": "Стовбурові клітини", - "item.gtceu.stem_cells.tooltip": "§7Сирий розум", - "item.gtceu.sticky_resin": "Липка смола", - "item.gtceu.tantalum_capacitor": "Танталовий конденсатор", - "item.gtceu.transistor": "Транзистор", - "item.gtceu.transistor.tooltip": "§7Базовий електронний компонент", - "item.gtceu.turbine_rotor.tooltip": "Ротор турбін для вашої електростанції", - "item.gtceu.vacuum_tube": "Вакуумна трубка", - "item.gtceu.vacuum_tube.tooltip.0": "§7Технічно це діод", - "item.gtceu.vacuum_tube.tooltip.1": "§cULV-рівень", - "item.gtceu.wetware_processor": "Животехнічний процесор", - "item.gtceu.wetware_processor.tooltip.0": "§7Він ніби спостерігає за вами", - "item.gtceu.wetware_processor_assembly": "Животехнічний процесорний вузол", - "item.gtceu.wetware_processor_assembly.tooltip.0": "§7Може запустити Minecraft", - "item.gtceu.wetware_processor_computer": "Животехнічний процесорний суперкомп'ютер", - "item.gtceu.wetware_processor_computer.tooltip.0": "§7Остаточне злиття плоті та машини", - "item.gtceu.wetware_processor_mainframe": "Животехнічний процесорний мейнфрейм", - "item.gtceu.wetware_processor_mainframe.tooltip.0": "§7Краще, що коли-небудь хтось бачив", - - "item.gtceu.zero_point_module": "Модуль нульової точки", - "block.gtceu.uiv_alloy_smelter": "§2Епічний плавильник сплавів III§r", - "block.gtceu.uv_alloy_smelter": "§3Ультимативний плавильник сплавів§r ", - "block.gtceu.uhv_alloy_smelter": "§4Епічний плавильник сплавів§r ", - "block.gtceu.ev_alloy_smelter": "§5Просунутий плавильник сплавів III§r", - "block.gtceu.hv_alloy_smelter": "§6Просунутий плавильник сплавів II§r", - "block.gtceu.opv_alloy_smelter": "§9§lЛегендарний плавильник сплавів§r ", - "block.gtceu.iv_alloy_smelter": "§9Елітний плавильник сплавів§r ", - "block.gtceu.uev_alloy_smelter": "§aЕпічний плавильник сплавів II§r", - "block.gtceu.mv_alloy_smelter": "§bПросунутий плавильник сплавів§r ", - "block.gtceu.zpm_alloy_smelter": "§cЕлітний плавильник сплавів III§r", - "block.gtceu.luv_alloy_smelter": "§dЕлітний плавильник сплавів II§r", - "block.gtceu.uxv_alloy_smelter": "§eЕпічний плавильник сплавів IV§r", - "gtceu.alloy_smelter": "Плавильник сплавів", - "block.gtceu.lv_alloy_smelter": "Базовий плавильник сплавів§r ", - "block.gtceu.hp_steam_alloy_smelter": "Паровий плавильник сплавів під високим тиском", - "block.gtceu.lp_steam_alloy_smelter": "Паровий плавильник сплавів під низьким тиском", - "block.gtceu.uiv_arc_furnace": "§2Епічна дугова піч III§r", - "block.gtceu.uv_arc_furnace": "§3Ультимативна дугова піч§r ", - "block.gtceu.uhv_arc_furnace": "§4Епічна дугова піч§r ", - "block.gtceu.ev_arc_furnace": "§5Просунута дугова піч III§r", - "block.gtceu.hv_arc_furnace": "§6Просунута дугова піч II§r", - "block.gtceu.opv_arc_furnace": "§9§lЛегендарна дугова піч§r ", - "block.gtceu.iv_arc_furnace": "§9Елітна дугова піч§r ", - "block.gtceu.uev_arc_furnace": "§aЕпічна дугова піч II§r", - "block.gtceu.mv_arc_furnace": "§bПросунута дугова піч§r ", - "block.gtceu.zpm_arc_furnace": "§cЕлітна дугова піч III§r", - "block.gtceu.luv_arc_furnace": "§dЕлітна дугова піч II§r", - "block.gtceu.uxv_arc_furnace": "§eЕпічна дугова піч IV§r", - "gtceu.arc_furnace": "Дугова піч", - "block.gtceu.lv_arc_furnace": "Базова дугова піч§r ", - "block.gtceu.uiv_assembler": "§2Епічний збирач III§r", - "block.gtceu.uv_assembler": "§3Ультимативний збирач§r ", - "block.gtceu.uhv_assembler": "§4Епічний збирач§r ", - "block.gtceu.ev_assembler": "§5Просунутий збирач III§r", - "block.gtceu.hv_assembler": "§6Просунутий збирач II§r", - "block.gtceu.opv_assembler": "§9§lЛегендарний збирач§r ", - "block.gtceu.iv_assembler": "§9Елітний збирач§r ", - "block.gtceu.uev_assembler": "§aЕпічний збирач II§r", - "block.gtceu.mv_assembler": "§bПросунутий збирач§r ", - "block.gtceu.zpm_assembler": "§cЕлітний збирач III§r", - "block.gtceu.luv_assembler": "§dЕлітний збирач II§r", - "block.gtceu.uxv_assembler": "§eЕпічний збирач IV§r", - "gtceu.assembler": "Збирач", - "block.gtceu.lv_assembler": "Базовий збирач§r ", - "block.gtceu.uiv_circuit_assembler": "§2Епічний схемотехнічний асемблер III§r", - "block.gtceu.uv_circuit_assembler": "§3Ультимативний схемотехнічний асемблер§r ", - "block.gtceu.uhv_circuit_assembler": "§4Епічний схемотехнічний асемблер§r ", - "block.gtceu.ev_circuit_assembler": "§5Просунутий схемотехнічний асемблер III§r", - "block.gtceu.hv_circuit_assembler": "§6Просунутий схемотехнічний асемблер II§r", - "block.gtceu.opv_circuit_assembler": "§9§lЛегендарний схемотехнічний асемблер§r ", - "block.gtceu.iv_circuit_assembler": "§9Елітний схемотехнічний асемблер§r ", - "block.gtceu.uev_circuit_assembler": "§aЕпічний схемотехнічний асемблер II§r", - "block.gtceu.mv_circuit_assembler": "§bПросунутий схемотехнічний асемблер§r ", - "block.gtceu.zpm_circuit_assembler": "§cЕлітний схемотехнічний асемблер III§r", - "block.gtceu.luv_circuit_assembler": "§dЕлітний схемотехнічний асемблер II§r", - "block.gtceu.uxv_circuit_assembler": "§eЕпічний схемотехнічний асемблер IV§r", - "block.gtceu.lv_circuit_assembler": "Базовий схемотехнічний асемблер§r ", - "gtceu.circuit_assembler": "Схемотехнічний асемблер", - "block.gtceu.uiv_autoclave": "§2Епічний автоклав III§r", - "block.gtceu.uv_autoclave": "§3Ультимативний автоклав§r ", - "block.gtceu.uhv_autoclave": "§4Епічний автоклав§r ", - "block.gtceu.ev_autoclave": "§5Просунутий автоклав III§r", - "block.gtceu.hv_autoclave": "§6Просунутий автоклав II§r", - "block.gtceu.opv_autoclave": "§9§lЛегендарний автоклав§r ", - "block.gtceu.iv_autoclave": "§9Елітний автоклав§r ", - "block.gtceu.uev_autoclave": "§aЕпічний автоклав II§r", - "block.gtceu.mv_autoclave": "§bПросунутий автоклав§r ", - "block.gtceu.zpm_autoclave": "§cЕлітний автоклав III§r", - "block.gtceu.luv_autoclave": "§dЕлітний автоклав II§r", - "block.gtceu.uxv_autoclave": "§eЕпічний автоклав IV§r", - "gtceu.autoclave": "Автоклав", - "block.gtceu.lv_autoclave": "Базовий автоклав§r ", - "block.gtceu.uiv_bender": "§2Епічний прокатний стан III§r", - "block.gtceu.uv_bender": "§3Ультимативний прокатний стан§r ", - "block.gtceu.uhv_bender": "§4Епічний прокатний стан§r ", - "block.gtceu.ev_bender": "§5Просунутий прокатний стан III§r", - "block.gtceu.hv_bender": "§6Просунутий прокатний стан II§r", - "block.gtceu.opv_bender": "§9§lЛегендарний прокатний стан§r ", - "block.gtceu.iv_bender": "§9Елітний прокатний стан§r ", - "block.gtceu.uev_bender": "§aЕпічний прокатний стан II§r", - "block.gtceu.mv_bender": "§bПросунутий прокатний стан§r ", - "block.gtceu.zpm_bender": "§cЕлітний прокатний стан III§r", - "block.gtceu.luv_bender": "§dЕлітний прокатний стан II§r", - "block.gtceu.uxv_bender": "§eЕпічний прокатний стан IV§r", - "block.gtceu.lv_bender": "Базовий прокатний стан§r ", - "gtceu.bender": "Прокатний стан", - "block.gtceu.uiv_brewery": "§2Епічний варильник III§r", - "block.gtceu.uv_brewery": "§3Ультимативний варильник§r ", - "block.gtceu.uhv_brewery": "§4Епічний варильник§r ", - "block.gtceu.ev_brewery": "§5Просунутий варильник III§r", - "block.gtceu.hv_brewery": "§6Просунутий варильник II§r", - "block.gtceu.opv_brewery": "§9§lЛегендарний варильник§r ", - "block.gtceu.iv_brewery": "§9Елітний варильник§r ", - "block.gtceu.uev_brewery": "§aЕпічний варильник II§r", - "block.gtceu.mv_brewery": "§bПросунутий варильник§r ", - "block.gtceu.zpm_brewery": "§cЕлітний варильник III§r", - "block.gtceu.luv_brewery": "§dЕлітний варильник II§r", - "block.gtceu.uxv_brewery": "§eЕпічний варильник IV§r", - "block.gtceu.lv_brewery": "Базовий варильник§r ", - "gtceu.brewery": "Варильник", - "block.gtceu.uiv_canner": "§2Епічний консерваторний стан III§r", - "block.gtceu.uv_canner": "§3Ультимативний консерваторний стан§r ", - "block.gtceu.uhv_canner": "§4Епічний консерваторний стан§r ", - "block.gtceu.ev_canner": "§5Просунутий консерваторний стан III§r", - "block.gtceu.hv_canner": "§6Просунутий консерваторний стан II§r", - "block.gtceu.opv_canner": "§9§lЛегендарний консерваторний стан§r ", - "block.gtceu.iv_canner": "§9Елітний консерваторний стан§r ", - "block.gtceu.uev_canner": "§aЕпічний консерваторний стан II§r", - "block.gtceu.mv_canner": "§bПросунутий консерваторний стан§r ", - "block.gtceu.zpm_canner": "§cЕлітний консерваторний стан III§r", - "block.gtceu.luv_canner": "§dЕлітний консерваторний стан II§r", - "block.gtceu.uxv_canner": "§eЕпічний консерваторний стан IV§r", - "block.gtceu.lv_canner": "Базовий консерваторний стан§r ", - "gtceu.canner": "Консерваторний стан", - "block.gtceu.uiv_centrifuge": "§2Епічна центрифуга III§r", - "block.gtceu.uv_centrifuge": "§3Ультимативна центрифуга§r ", - "block.gtceu.uhv_centrifuge": "§4Епічна центрифуга§r ", - "block.gtceu.ev_centrifuge": "§5Просунута центрифуга III§r", - "block.gtceu.hv_centrifuge": "§6Просунута центрифуга II§r", - "block.gtceu.opv_centrifuge": "§9§lЛегендарна центрифуга§r ", - "block.gtceu.iv_centrifuge": "§9Елітна центрифуга§r ", - "block.gtceu.uev_centrifuge": "§aЕпічна центрифуга II§r", - "block.gtceu.mv_centrifuge": "§bПросунута центрифуга§r ", - "block.gtceu.zpm_centrifuge": "§cЕлітна центрифуга III§r", - "block.gtceu.luv_centrifuge": "§dЕлітна центрифуга II§r", - "block.gtceu.uxv_centrifuge": "§eЕпічна центрифуга IV§r", - "block.gtceu.lv_centrifuge": "Базова центрифуга§r ", - "gtceu.centrifuge": "Центрифуга", - "cover.item_smart_filter.filtering_mode.centrifuge": "Центрифуга", - "block.gtceu.uiv_thermal_centrifuge": "§2Епічна термічна центрифуга III§r", - "block.gtceu.uv_thermal_centrifuge": "§3Ультимативна термічна центрифуга§r ", - "block.gtceu.uhv_thermal_centrifuge": "§4Епічна термічна центрифуга§r ", - "block.gtceu.ev_thermal_centrifuge": "§5Просунута термічна центрифуга III§r", - "block.gtceu.hv_thermal_centrifuge": "§6Просунута термічна центрифуга II§r", - "block.gtceu.opv_thermal_centrifuge": "§9§lЛегендарна термічна центрифуга§r ", - "block.gtceu.iv_thermal_centrifuge": "§9Елітна термічна центрифуга§r ", - "block.gtceu.uev_thermal_centrifuge": "§aЕпічна термічна центрифуга II§r", - "block.gtceu.mv_thermal_centrifuge": "§bПросунута термічна центрифуга§r ", - "block.gtceu.zpm_thermal_centrifuge": "§cЕлітна термічна центрифуга III§r", - "block.gtceu.luv_thermal_centrifuge": "§dЕлітна термічна центрифуга II§r", - "block.gtceu.uxv_thermal_centrifuge": "§eЕпічна термічна центрифуга IV§r", - "block.gtceu.lv_thermal_centrifuge": "Базова термічна центрифуга§r ", - "gtceu.thermal_centrifuge": "Термічна центрифуга", - "block.gtceu.uiv_chemical_bath": "§2Епічна хімічна ванна III§r", - "block.gtceu.uv_chemical_bath": "§3Ультимативна хімічна ванна§r ", - "block.gtceu.uhv_chemical_bath": "§4Епічна хімічна ванна§r ", - "block.gtceu.ev_chemical_bath": "§5Просунута хімічна ванна III§r", - "block.gtceu.hv_chemical_bath": "§6Просунута хімічна ванна II§r", - "block.gtceu.opv_chemical_bath": "§9§lЛегендарна хімічна ванна§r ", - "block.gtceu.iv_chemical_bath": "§9Елітна хімічна ванна§r ", - "block.gtceu.uev_chemical_bath": "§aЕпічна хімічна ванна II§r", - "block.gtceu.mv_chemical_bath": "§bПросунута хімічна ванна§r ", - "block.gtceu.zpm_chemical_bath": "§cЕлітна хімічна ванна III§r", - "block.gtceu.luv_chemical_bath": "§dЕлітна хімічна ванна II§r", - "block.gtceu.uxv_chemical_bath": "§eЕпічна хімічна ванна IV§r", - "block.gtceu.lv_chemical_bath": "Базова хімічна ванна§r ", - "gtceu.chemical_bath": "Хімічна ванна", - "block.gtceu.large_chemical_bath": "Велика хімічна ванна", - "block.gtceu.uiv_chemical_reactor": "§2Епічний хімічний реактор III§r", - "block.gtceu.uv_chemical_reactor": "§3Ультимативний хімічний реактор§r ", - "block.gtceu.uhv_chemical_reactor": "§4Епічний хімічний реактор§r ", - "block.gtceu.ev_chemical_reactor": "§5Просунутий хімічний реактор III§r", - "block.gtceu.hv_chemical_reactor": "§6Просунутий хімічний реактор II§r", - "block.gtceu.opv_chemical_reactor": "§9§lЛегендарний хімічний реактор§r ", - "block.gtceu.iv_chemical_reactor": "§9Елітний хімічний реактор§r ", - "block.gtceu.uev_chemical_reactor": "§aЕпічний хімічний реактор II§r", - "block.gtceu.mv_chemical_reactor": "§bПросунутий хімічний реактор§r ", - "block.gtceu.zpm_chemical_reactor": "§cЕлітний хімічний реактор III§r", - "block.gtceu.luv_chemical_reactor": "§dЕлітний хімічний реактор II§r", - "block.gtceu.uxv_chemical_reactor": "§eЕпічний хімічний реактор IV§r", - "block.gtceu.lv_chemical_reactor": "Базовий хімічний реактор§r ", - "gtceu.chemical_reactor": "Хімічний реактор", - "block.gtceu.large_chemical_reactor": "Великий хімічний реактор", - "gtceu.large_chemical_reactor": "Великий хімічний реактор", - "block.gtceu.uiv_compressor": "§2Епічний компресор III§r", - "block.gtceu.uv_compressor": "§3Ультимативний компресор§r ", - "block.gtceu.uhv_compressor": "§4Епічний компресор§r ", - "block.gtceu.ev_compressor": "§5Просунутий компресор III§r", - "block.gtceu.hv_compressor": "§6Просунутий компресор II§r", - "block.gtceu.opv_compressor": "§9§lЛегендарний компресор§r ", - "block.gtceu.iv_compressor": "§9Елітний компресор§r ", - "block.gtceu.uev_compressor": "§aЕпічний компресор II§r", - "block.gtceu.mv_compressor": "§bПросунутий компресор§r ", - "block.gtceu.zpm_compressor": "§cЕлітний компресор III§r", - "block.gtceu.luv_compressor": "§dЕлітний компресор II§r", - "block.gtceu.uxv_compressor": "§eЕпічний компресор IV§r", - "block.gtceu.lv_compressor": "Базовий компресор§r ", - "gtceu.compressor": "Компресор", - "block.gtceu.hp_steam_compressor": "Паровий компресор під високим тиском", - "block.gtceu.lp_steam_compressor": "Паровий компресор під низьким тиском", - "block.gtceu.implosion_compressor": "Компресор надмірного тиску", - "gtceu.implosion_compressor": "Компресор надмірного тиску", - "block.gtceu.uiv_cutter": "§2Епічний різак III§r", - "block.gtceu.uv_cutter": "§3Ультимативний різак§r ", - "block.gtceu.uhv_cutter": "§4Епічний різак§r ", - "block.gtceu.ev_cutter": "§5Просунутий різак III§r", - "block.gtceu.hv_cutter": "§6Просунутий різак II§r", - "gtceu.tool_action.wire_cutter.connect": "§8Використовуйте кусачки для встановлення з'єднань", - "block.gtceu.opv_cutter": "§9§lЛегендарний різак§r ", - "block.gtceu.iv_cutter": "§9Елітний різак§r ", - "block.gtceu.uev_cutter": "§aЕпічний різак II§r", - "block.gtceu.mv_cutter": "§bПросунутий різак§r ", - "block.gtceu.zpm_cutter": "§cЕлітний різак III§r", - "block.gtceu.luv_cutter": "§dЕлітний різак II§r", - "block.gtceu.uxv_cutter": "§eЕпічний різак IV§r", - "block.gtceu.lv_cutter": "Базовий різак§r ", - "gtceu.cutter": "Різак", - "block.gtceu.uiv_distillery": "§2Епічний дистилятор III§r", - "block.gtceu.uv_distillery": "§3Ультимативний дистилятор§r ", - "block.gtceu.uhv_distillery": "§4Епічний дистилятор§r ", - "block.gtceu.ev_distillery": "§5Просунутий дистилятор III§r", - "block.gtceu.hv_distillery": "§6Просунутий дистилятор II§r", - "block.gtceu.opv_distillery": "§9§lЛегендарний дистилятор§r ", - "block.gtceu.iv_distillery": "§9Елітний дистилятор§r ", - "block.gtceu.uev_distillery": "§aЕпічний дистилятор II§r", - "block.gtceu.mv_distillery": "§bПросунутий дистилятор§r ", - "block.gtceu.zpm_distillery": "§cЕлітний дистилятор III§r", - "block.gtceu.luv_distillery": "§dЕлітний дистилятор II§r", - "block.gtceu.uxv_distillery": "§eЕпічний дистилятор IV§r", - "block.gtceu.lv_distillery": "Базовий дистилятор§r ", - "gtceu.distillery": "Дистилятор", - "block.gtceu.large_distillery": "Великий фракційний дистилятор", - "block.gtceu.uiv_electric_furnace": "§2Епічна електрична піч III§r", - "block.gtceu.uv_electric_furnace": "§3Ультимативна електрична піч§r ", - "block.gtceu.uhv_electric_furnace": "§4Епічна електрична піч§r ", - "block.gtceu.ev_electric_furnace": "§5Просунута електрична піч III§r", - "block.gtceu.hv_electric_furnace": "§6Просунута електрична піч II§r", - "block.gtceu.opv_electric_furnace": "§9§lЛегендарна електрична піч§r ", - "block.gtceu.iv_electric_furnace": "§9Елітна електрична піч§r ", - "block.gtceu.uev_electric_furnace": "§aЕпічна електрична піч II§r", - "block.gtceu.mv_electric_furnace": "§bПросунута електрична піч§r ", - "block.gtceu.zpm_electric_furnace": "§cЕлітна електрична піч III§r", - "block.gtceu.luv_electric_furnace": "§dЕлітна електрична піч II§r", - "block.gtceu.uxv_electric_furnace": "§eЕпічна електрична піч IV§r", - "block.gtceu.lv_electric_furnace": "Базова електрична піч§r ", - "gtceu.electric_furnace": "Електрична піч", - "block.gtceu.uiv_electrolyzer": "§2Епічний електролізер III§r", - "block.gtceu.uv_electrolyzer": "§3Ультимативний електролізер§r ", - "block.gtceu.uhv_electrolyzer": "§4Епічний електролізер§r ", - "block.gtceu.ev_electrolyzer": "§5Просунутий електролізер III§r", - "block.gtceu.hv_electrolyzer": "§6Просунутий електролізер II§r", - "block.gtceu.opv_electrolyzer": "§9§lЛегендарний електролізер§r ", - "block.gtceu.iv_electrolyzer": "§9Елітний електролізер§r ", - "block.gtceu.uev_electrolyzer": "§aЕпічний електролізер II§r", - "block.gtceu.mv_electrolyzer": "§bПросунутий електролізер§r ", - "block.gtceu.zpm_electrolyzer": "§cЕлітний електролізер III§r", - "block.gtceu.luv_electrolyzer": "§dЕлітний електролізер II§r", - "block.gtceu.uxv_electrolyzer": "§eЕпічний електролізер IV§r", - "block.gtceu.lv_electrolyzer": "Базовий електролізер§r ", - "gtceu.electrolyzer": "Електролізер", - "cover.item_smart_filter.filtering_mode.electrolyzer": "Електролізер", - "block.gtceu.uiv_electromagnetic_separator": "§2Епічний електромагнітний сепаратор III§r", - "block.gtceu.uv_electromagnetic_separator": "§3Ультимативний електромагнітний сепаратор§r ", - "block.gtceu.uhv_electromagnetic_separator": "§4Епічний електромагнітний сепаратор§r ", - "block.gtceu.ev_electromagnetic_separator": "§5Просунутий електромагнітний сепаратор III§r", - "block.gtceu.hv_electromagnetic_separator": "§6Просунутий електромагнітний сепаратор II§r", - "block.gtceu.opv_electromagnetic_separator": "§9§lЛегендарний електромагнітний сепаратор§r ", - "block.gtceu.iv_electromagnetic_separator": "§9Елітний електромагнітний сепаратор§r ", - "block.gtceu.uev_electromagnetic_separator": "§aЕпічний електромагнітний сепаратор II§r", - "block.gtceu.mv_electromagnetic_separator": "§bПросунутий електромагнітний сепаратор§r ", - "block.gtceu.zpm_electromagnetic_separator": "§cЕлітний електромагнітний сепаратор III§r", - "block.gtceu.luv_electromagnetic_separator": "§dЕлітний електромагнітний сепаратор II§r", - "block.gtceu.uxv_electromagnetic_separator": "§eЕпічний електромагнітний сепаратор IV§r", - "block.gtceu.lv_electromagnetic_separator": "Базовий електромагнітний сепаратор§r ", - "gtceu.electromagnetic_separator": "Електромагнітний сепаратор", - "block.gtceu.uiv_extractor": "§2Епічний екстрактор III§r", - "block.gtceu.uv_extractor": "§3Ультимативний екстрактор§r ", - "block.gtceu.uhv_extractor": "§4Епічний екстрактор§r ", - "block.gtceu.ev_extractor": "§5Просунутий екстрактор III§r", - "block.gtceu.hv_extractor": "§6Просунутий екстрактор II§r", - "block.gtceu.opv_extractor": "§9§lЛегендарний екстрактор§r ", - "block.gtceu.iv_extractor": "§9Елітний екстрактор§r ", - "block.gtceu.uev_extractor": "§aЕпічний екстрактор II§r", - "block.gtceu.mv_extractor": "§bПросунутий екстрактор§r ", - "block.gtceu.zpm_extractor": "§cЕлітний екстрактор III§r", - "block.gtceu.luv_extractor": "§dЕлітний екстрактор II§r", - "block.gtceu.uxv_extractor": "§eЕпічний екстрактор IV§r", - "block.gtceu.lv_extractor": "Базовий екстрактор§r ", - "gtceu.extractor": "Екстрактор", - "block.gtceu.hp_steam_extractor": "Паровий екстрактор під високим тиском", - "block.gtceu.lp_steam_extractor": "Паровий екстрактор під низьким тиском", - "block.gtceu.uiv_extruder": "§2Епічний екструдер III§r", - "block.gtceu.uv_extruder": "§3Ультимативний екструдер§r ", - "block.gtceu.uhv_extruder": "§4Епічний екструдер§r ", - "block.gtceu.ev_extruder": "§5Просунутий екструдер III§r", - "block.gtceu.hv_extruder": "§6Просунутий екструдер II§r", - "block.gtceu.opv_extruder": "§9§lЛегендарний екструдер§r ", - "block.gtceu.iv_extruder": "§9Елітний екструдер§r ", - "block.gtceu.uev_extruder": "§aЕпічний екструдер II§r", - "block.gtceu.mv_extruder": "§bПросунутий екструдер§r ", - "block.gtceu.zpm_extruder": "§cЕлітний екструдер III§r", - "block.gtceu.luv_extruder": "§dЕлітний екструдер II§r", - "block.gtceu.uxv_extruder": "§eЕпічний екструдер IV§r", - "block.gtceu.lv_extruder": "Базовий екструдер§r ", - "gtceu.extruder": "Екструдер", - "item.gtceu.axe_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення сокир", - "item.gtceu.block_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення блоків", - "item.gtceu.bolt_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення болтів", - "item.gtceu.bottle_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення пляшок", - "item.gtceu.cell_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення комірок", - "item.gtceu.file_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення напилків", - "item.gtceu.foil_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення тонких пластин", - "item.gtceu.pipe.huge_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення повноблочних труб", - "item.gtceu.pipe.large_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення великих труб", - "item.gtceu.pipe.normal_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення труб", - "item.gtceu.pipe.small_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення малих труб", - "item.gtceu.pipe.tiny_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення крихітних труб", - "item.gtceu.gear_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення шестерень", - "item.gtceu.gear_small_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення малих шестерень", - "item.gtceu.hammer_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення малотків", - "item.gtceu.hoe_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення мотик", - "item.gtceu.casing_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення предметних корпусів", - "item.gtceu.rod_long_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення довгих стрижнів", - "item.gtceu.pickaxe_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення кайл", - "item.gtceu.plate_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення листів", - "item.gtceu.ring_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення кілець", - "item.gtceu.rod_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення стрижнів", - "item.gtceu.rotor_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення роторів", - "item.gtceu.saw_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення Saws", - "item.gtceu.shovel_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення Shovels", - "item.gtceu.sword_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення Swords", - "item.gtceu.wire_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення Wires", - "item.gtceu.ingot_extruder_mold.tooltip": "§7Формовий відтиск для... зачекайте, чи не можна просто використати піч?", - "item.gtceu.name_casting_mold.tooltip": "§7Форма для іменування предметів у формовому пресі (перейменуйте форму у ковадлі)", - "item.gtceu.credit_casting_mold.tooltip": "§7Безпечна форма для карбування монет (Не загубіть її!)", - "item.gtceu.ball_casting_mold.tooltip": "§7Форма для виготовлення куль", - "item.gtceu.block_casting_mold.tooltip": "§7Форма для виготовлення блоків", - "item.gtceu.bottle_casting_mold.tooltip": "§7Форма для виготовлення пляшок", - "item.gtceu.gear_casting_mold.tooltip": "§7Форма для виготовлення шестерень", - "item.gtceu.ingot_casting_mold.tooltip": "§7Форма для виготовлення злитків", - "item.gtceu.casing_casting_mold.tooltip": "§7Форма для виготовлення предметних каркасів", - "item.gtceu.nugget_casting_mold.tooltip": "§7Форма для виготовлення самородків", - "item.gtceu.plate_casting_mold.tooltip": "§7Форма для виготовлення листів", - "item.gtceu.rotor_casting_mold.tooltip": "§7Форма для виготовлення роторів", - "item.gtceu.gear_casting_mold.small.tooltip": "§7Форма для виготовлення малих шестерень", - "item.gtceu.anvil_casting_mold.tooltip": "§7Форма для формування ковадл", - "item.gtceu.cylinder_casting_mold.tooltip": "§7Форма для формування циліндрів", - "item.gtceu.block_extruder_mold": "Відтискна форма (блок)", - "item.gtceu.bolt_extruder_mold": "Відтискна форма (болт)", - "item.gtceu.bottle_extruder_mold": "Відтискна форма (пляшка)", - "item.gtceu.cell_extruder_mold": "Відтискна форма (комірка)", - "item.gtceu.foil_extruder_mold": "Відтискна форма (тонка пластина)", - "item.gtceu.gear_extruder_mold": "Відтискна форма (шестерня)", - "item.gtceu.huge_pipe_extruder_mold": "Відтискна форма (величезна труба)", - "item.gtceu.large_pipe_extruder_mold": "Відтискна форма (велика труба)", - "item.gtceu.normal_pipe_extruder_mold": "Відтискна форма (труба)", - "item.gtceu.small_gear_extruder_mold": "Відтискна форма (мала шестерня)", - "item.gtceu.small_pipe_extruder_mold": "Відтискна форма (мала труба)", - "item.gtceu.tiny_pipe_extruder_mold": "Відтискна форма (крихітна труба)", - "item.gtceu.ingot_extruder_mold": "Відтискна форма (злиток)", - "item.gtceu.long_rod_extruder_mold": "Відтискна форма (довгий стрижень)", - "item.gtceu.plate_extruder_mold": "Відтискна форма (лист)", - "item.gtceu.ring_extruder_mold": "Відтискна форма (кільце)", - "item.gtceu.rod_extruder_mold": "Відтискна форма (стрижень)", - "item.gtceu.rotor_extruder_mold": "Відтискна форма (Rotor)", - "item.gtceu.wire_extruder_mold": "Відтискна форма (дріт)", - "item.gtceu.credit_casting_mold": "Монетний карб", - "item.gtceu.anvil_casting_mold": "Відливна форма (ковадло)", - "item.gtceu.ball_casting_mold": "Відливна форма (куля)", - "item.gtceu.block_casting_mold": "Відливна форма (блок)", - "item.gtceu.bottle_casting_mold": "Відливна форма (пляшка)", - "item.gtceu.cylinder_casting_mold": "Відливна форма (циліндр)", - "item.gtceu.gear_casting_mold": "Відливна форма (шестерня)", - "item.gtceu.ingot_casting_mold": "Відливна форма (злиток)", - "item.gtceu.name_casting_mold": "Відливна форма (Ім'я)", - "item.gtceu.nugget_casting_mold": "Відливна форма (самородок)", - "item.gtceu.pill_casting_mold": "Відливна форма (пігулка)", - "item.gtceu.plate_casting_mold": "Відливна форма (лист)", - "item.gtceu.rotor_casting_mold": "Відливна форма (ротор)", - "item.gtceu.small_gear_casting_mold": "Відливна форма (мала шестерня)", - "block.gtceu.uiv_fermenter": "§2Епічний ферментатор III§r", - "block.gtceu.uv_fermenter": "§3Ультимативний ферментатор§r ", - "block.gtceu.uhv_fermenter": "§4Епічний ферментатор§r ", - "block.gtceu.ev_fermenter": "§5Просунутий ферментатор III§r", - "block.gtceu.hv_fermenter": "§6Просунутий ферментатор II§r", - "block.gtceu.opv_fermenter": "§9§lЛегендарний ферментатор§r ", - "block.gtceu.iv_fermenter": "§9Елітний ферментатор§r ", - "block.gtceu.uev_fermenter": "§aЕпічний ферментатор II§r", - "block.gtceu.mv_fermenter": "§bПросунутий ферментатор§r ", - "block.gtceu.zpm_fermenter": "§cЕлітний ферментатор III§r", - "block.gtceu.luv_fermenter": "§dЕлітний ферментатор II§r", - "block.gtceu.uxv_fermenter": "§eЕпічний ферментатор IV§r", - "block.gtceu.lv_fermenter": "Базовий ферментатор§r ", - "gtceu.fermenter": "Ферментатор", - "block.gtceu.uiv_fluid_heater": "§2Епічний рідинний нагрівач III§r", - "block.gtceu.uv_fluid_heater": "§3Ультимативний рідинний нагрівач§r ", - "block.gtceu.uhv_fluid_heater": "§4Епічний рідинний нагрівач§r ", - "block.gtceu.ev_fluid_heater": "§5Просунутий рідинний нагрівач III§r", - "block.gtceu.hv_fluid_heater": "§6Просунутий рідинний нагрівач II§r", - "block.gtceu.opv_fluid_heater": "§9§lЛегендарний рідинний нагрівач§r ", - "block.gtceu.iv_fluid_heater": "§9Елітний рідинний нагрівач§r ", - "block.gtceu.uev_fluid_heater": "§aЕпічний рідинний нагрівач II§r", - "block.gtceu.mv_fluid_heater": "§bПросунутий рідинний нагрівач§r ", - "block.gtceu.zpm_fluid_heater": "§cЕлітний рідинний нагрівач III§r", - "block.gtceu.luv_fluid_heater": "§dЕлітний рідинний нагрівач II§r", - "block.gtceu.uxv_fluid_heater": "§eЕпічний рідинний нагрівач IV§r", - "block.gtceu.lv_fluid_heater": "Базовий рідинний нагрівач§r ", - "block.gtceu.uiv_fluid_solidifier": "§2Епічний рідинний затверджувач III§r", - "block.gtceu.uv_fluid_solidifier": "§3Ультимативний рідинний затверджувач§r ", - "block.gtceu.uhv_fluid_solidifier": "§4Епічний рідинний затверджувач§r ", - "block.gtceu.ev_fluid_solidifier": "§5Просунутий рідинний затверджувач III§r", - "block.gtceu.hv_fluid_solidifier": "§6Просунутий рідинний затверджувач II§r", - "block.gtceu.opv_fluid_solidifier": "§9§lЛегендарний рідинний затверджувач§r ", - "block.gtceu.iv_fluid_solidifier": "§9Елітний рідинний затверджувач§r ", - "block.gtceu.uev_fluid_solidifier": "§aЕпічний рідинний затверджувач II§r", - "block.gtceu.mv_fluid_solidifier": "§bПросунутий рідинний затверджувач§r ", - "block.gtceu.zpm_fluid_solidifier": "§cЕлітний рідинний затверджувач III§r", - "block.gtceu.luv_fluid_solidifier": "§dЕлітний рідинний затверджувач II§r", - "block.gtceu.uxv_fluid_solidifier": "§eЕпічний рідинний затверджувач IV§r", - "block.gtceu.lv_fluid_solidifier": "Базовий рідинний затверджувач§r ", - "block.gtceu.uiv_forge_hammer": "§2Епічний ковальський молот III§r", - "block.gtceu.uv_forge_hammer": "§3Ультимативний ковальський молот§r ", - "block.gtceu.uhv_forge_hammer": "§4Епічний ковальський молот§r ", - "block.gtceu.ev_forge_hammer": "§5Просунутий ковальський молот III§r", - "block.gtceu.hv_forge_hammer": "§6Просунутий ковальський молот II§r", - "block.gtceu.opv_forge_hammer": "§9§lЛегендарний ковальський молот§r ", - "block.gtceu.iv_forge_hammer": "§9Елітний ковальський молот§r ", - "block.gtceu.uev_forge_hammer": "§aЕпічний ковальський молот II§r", - "block.gtceu.mv_forge_hammer": "§bПросунутий ковальський молот§r ", - "block.gtceu.zpm_forge_hammer": "§cЕлітний ковальський молот III§r", - "block.gtceu.luv_forge_hammer": "§dЕлітний ковальський молот II§r", - "block.gtceu.uxv_forge_hammer": "§eЕпічний ковальський молот IV§r", - "block.gtceu.lv_forge_hammer": "Базовий ковальський молот§r ", - "gtceu.forge_hammer": "Ковальський молот", - "block.gtceu.hp_steam_forge_hammer": "Паровий ковальський молот під високим тиском", - "block.gtceu.lp_steam_forge_hammer": "Паровий ковальський молот під низьким тиском", - "block.gtceu.uiv_forming_press": "§2Епічний формовий прес III§r", - "block.gtceu.uv_forming_press": "§3Ультимативний формовий прес§r ", - "block.gtceu.uhv_forming_press": "§4Епічний формовий прес§r ", - "block.gtceu.ev_forming_press": "§5Просунутий формовий прес III§r", - "block.gtceu.hv_forming_press": "§6Просунутий формовий прес II§r", - "block.gtceu.opv_forming_press": "§9§lЛегендарний формовий прес§r ", - "block.gtceu.iv_forming_press": "§9Елітний формовий прес§r ", - "block.gtceu.uev_forming_press": "§aЕпічний формовий прес II§r", - "block.gtceu.mv_forming_press": "§bПросунутий формовий прес§r ", - "block.gtceu.zpm_forming_press": "§cЕлітний формовий прес III§r", - "block.gtceu.luv_forming_press": "§dЕлітний формовий прес II§r", - "block.gtceu.uxv_forming_press": "§eЕпічний формовий прес IV§r", - "block.gtceu.lv_forming_press": "Базовий формовий прес§r ", - "gtceu.forming_press": "Формовий прес", - "block.gtceu.uiv_gas_collector": "§2Епічний газозбірник III§r", - "block.gtceu.uv_gas_collector": "§3Ультимативний газозбірник§r ", - "block.gtceu.uhv_gas_collector": "§4Епічний газозбірник§r ", - "block.gtceu.ev_gas_collector": "§5Просунутий газозбірник III§r", - "block.gtceu.hv_gas_collector": "§6Просунутий газозбірник II§r", - "block.gtceu.opv_gas_collector": "§9§lЛегендарний газозбірник§r ", - "block.gtceu.iv_gas_collector": "§9Елітний газозбірник§r ", - "block.gtceu.uev_gas_collector": "§aЕпічний газозбірник II§r", - "block.gtceu.mv_gas_collector": "§bПросунутий газозбірник§r ", - "block.gtceu.zpm_gas_collector": "§cЕлітний газозбірник III§r", - "block.gtceu.luv_gas_collector": "§dЕлітний газозбірник II§r", - "block.gtceu.uxv_gas_collector": "§eЕпічний газозбірник IV§r", - "block.gtceu.lv_gas_collector": "Базовий газозбірник§r ", - "gtceu.gas_collector": "Газозбірник", - "block.gtceu.uiv_laser_engraver": "§2Епічний літограф III§r", - "block.gtceu.uv_laser_engraver": "§3Ультимативний літограф§r ", - "block.gtceu.uhv_laser_engraver": "§4Епічний літограф§r ", - "block.gtceu.ev_laser_engraver": "§5Просунутий літограф III§r", - "block.gtceu.hv_laser_engraver": "§6Просунутий літограф II§r", - "block.gtceu.opv_laser_engraver": "§9§lЛегендарний літограф§r ", - "block.gtceu.iv_laser_engraver": "§9Елітний літограф§r ", - "block.gtceu.uev_laser_engraver": "§aЕпічний літограф II§r", - "block.gtceu.mv_laser_engraver": "§bПросунутий літограф§r ", - "block.gtceu.zpm_laser_engraver": "§cЕлітний літограф III§r", - "block.gtceu.luv_laser_engraver": "§dЕлітний літограф II§r", - "block.gtceu.uxv_laser_engraver": "§eЕпічний літограф IV§r", - "block.gtceu.lv_laser_engraver": "Базовий літограф§r ", - "gtceu.laser_engraver": "Літограф", - "block.gtceu.uiv_lathe": "§2Епічний токарний стан III§r", - "block.gtceu.uv_lathe": "§3Ультимативний токарний стан§r ", - "block.gtceu.uhv_lathe": "§4Епічний токарний стан§r ", - "block.gtceu.ev_lathe": "§5Просунутий токарний стан III§r", - "block.gtceu.hv_lathe": "§6Просунутий токарний стан II§r", - "block.gtceu.opv_lathe": "§9§lЛегендарний токарний стан§r ", - "block.gtceu.iv_lathe": "§9Елітний токарний стан§r ", - "block.gtceu.uev_lathe": "§aЕпічний токарний стан II§r", - "block.gtceu.mv_lathe": "§bПросунутий токарний стан§r ", - "block.gtceu.zpm_lathe": "§cЕлітний токарний стан III§r", - "block.gtceu.luv_lathe": "§dЕлітний токарний стан II§r", - "block.gtceu.uxv_lathe": "§eЕпічний токарний стан IV§r", - "block.gtceu.lv_lathe": "Базовий токарний стан§r ", - "gtceu.lathe": "Токарний стан", - "block.gtceu.uiv_macerator": "§2Епічний подрібнювач III§r", - "block.gtceu.uv_macerator": "§3Ультимативний подрібнювач§r ", - "block.gtceu.uhv_macerator": "§4Епічний подрібнювач§r ", - "block.gtceu.ev_macerator": "§5Просунутий подрібнювач III§r", - "block.gtceu.hv_macerator": "§6Просунутий подрібнювач II§r", - "block.gtceu.opv_macerator": "§9§lЛегендарний подрібнювач§r ", - "block.gtceu.iv_macerator": "§9Елітний подрібнювач§r ", - "block.gtceu.uev_macerator": "§aЕпічний подрібнювач II§r", - "block.gtceu.mv_macerator": "§bПросунутий подрібнювач§r ", - "block.gtceu.zpm_macerator": "§cЕлітний подрібнювач III§r", - "block.gtceu.luv_macerator": "§dЕлітний подрібнювач II§r", - "block.gtceu.uxv_macerator": "§eЕпічний подрібнювач IV§r", - "block.gtceu.lv_macerator": "Базовий подрібнювач§r ", - "block.gtceu.hp_steam_macerator": "Паровий подрібнювач під високим тиском", - "block.gtceu.lp_steam_macerator": "Паровий подрібнювач під низьким тиском", - "gtceu.macerator": "Подрібнювач", - "block.gtceu.uiv_mixer": "§2Епічний змішувач III§r", - "block.gtceu.uv_mixer": "§3Ультимативний змішувач§r ", - "block.gtceu.uhv_mixer": "§4Епічний змішувач§r ", - "block.gtceu.ev_mixer": "§5Просунутий змішувач III§r", - "block.gtceu.hv_mixer": "§6Просунутий змішувач II§r", - "block.gtceu.opv_mixer": "§9§lЛегендарний змішувач§r ", - "block.gtceu.iv_mixer": "§9Елітний змішувач§r ", - "block.gtceu.uev_mixer": "§aЕпічний змішувач II§r", - "block.gtceu.mv_mixer": "§bПросунутий змішувач§r ", - "block.gtceu.zpm_mixer": "§cЕлітний змішувач III§r", - "block.gtceu.luv_mixer": "§dЕлітний змішувач II§r", - "block.gtceu.uxv_mixer": "§eЕпічний змішувач IV§r", - "block.gtceu.lv_mixer": "Базовий змішувач§r ", - "gtceu.mixer": "Змішувач", - "block.gtceu.uiv_ore_washer": "§2Епічний рудопромивач III§r", - "block.gtceu.uv_ore_washer": "§3Ультимативний рудопромивач§r ", - "block.gtceu.uhv_ore_washer": "§4Епічний рудопромивач§r ", - "block.gtceu.ev_ore_washer": "§5Просунутий рудопромивач III§r", - "block.gtceu.hv_ore_washer": "§6Просунутий рудопромивач II§r", - "block.gtceu.opv_ore_washer": "§9§lЛегендарний рудопромивач§r ", - "block.gtceu.iv_ore_washer": "§9Елітний рудопромивач§r ", - "block.gtceu.uev_ore_washer": "§aЕпічний рудопромивач II§r", - "block.gtceu.mv_ore_washer": "§bПросунутий рудопромивач§r ", - "block.gtceu.zpm_ore_washer": "§cЕлітний рудопромивач III§r", - "block.gtceu.luv_ore_washer": "§dЕлітний рудопромивач II§r", - "block.gtceu.uxv_ore_washer": "§eЕпічний рудопромивач IV§r", - "block.gtceu.lv_ore_washer": "Базовий рудопромивач§r ", - "gtceu.ore_washer": "Рудопромивач", - "block.gtceu.uiv_packer": "§2Епічний пакувальник III§r", - "block.gtceu.uv_packer": "§3Ультимативний пакувальник§r ", - "block.gtceu.uhv_packer": "§4Епічний пакувальник§r ", - "block.gtceu.ev_packer": "§5Просунутий пакувальник III§r", - "block.gtceu.hv_packer": "§6Просунутий пакувальник II§r", - "block.gtceu.opv_packer": "§9§lЛегендарний пакувальник§r ", - "block.gtceu.iv_packer": "§9Елітний пакувальник§r ", - "block.gtceu.uev_packer": "§aЕпічний пакувальник II§r", - "block.gtceu.mv_packer": "§bПросунутий пакувальник§r ", - "block.gtceu.zpm_packer": "§cЕлітний пакувальник III§r", - "block.gtceu.luv_packer": "§dЕлітний пакувальник II§r", - "block.gtceu.uxv_packer": "§eЕпічний пакувальник IV§r", - "block.gtceu.lv_packer": "Базовий пакувальник§r ", - "gtceu.packer": "Пакувальник", - "block.gtceu.uiv_polarizer": "§2Епічний поляризатор III§r", - "block.gtceu.uv_polarizer": "§3Ультимативний поляризатор§r ", - "block.gtceu.uhv_polarizer": "§4Епічний поляризатор§r ", - "block.gtceu.ev_polarizer": "§5Просунутий поляризатор III§r", - "block.gtceu.hv_polarizer": "§6Просунутий поляризатор II§r", - "block.gtceu.opv_polarizer": "§9§lЛегендарний поляризатор§r ", - "block.gtceu.iv_polarizer": "§9Елітний поляризатор§r ", - "block.gtceu.uev_polarizer": "§aЕпічний поляризатор II§r", - "block.gtceu.mv_polarizer": "§bПросунутий поляризатор§r ", - "block.gtceu.zpm_polarizer": "§cЕлітний поляризатор III§r", - "block.gtceu.luv_polarizer": "§dЕлітний поляризатор II§r", - "block.gtceu.uxv_polarizer": "§eЕпічний поляризатор IV§r", - "block.gtceu.lv_polarizer": "Базовий поляризатор§r ", - "gtceu.polarizer": "Поляризатор", - "block.gtceu.uiv_rock_crusher": "§2Епічна кам'яна дробарка III§r", - "block.gtceu.uv_rock_crusher": "§3Ультимативна кам'яна дробарка§r ", - "block.gtceu.uhv_rock_crusher": "§4Епічна кам'яна дробарка§r ", - "block.gtceu.ev_rock_crusher": "§5Просунута кам'яна дробарка III§r", - "block.gtceu.hv_rock_crusher": "§6Просунута кам'яна дробарка II§r", - "block.gtceu.opv_rock_crusher": "§9§lЛегендарна кам'яна дробарка§r ", - "block.gtceu.iv_rock_crusher": "§9Елітна кам'яна дробарка§r ", - "block.gtceu.uev_rock_crusher": "§aЕпічна кам'яна дробарка II§r", - "block.gtceu.mv_rock_crusher": "§bПросунута кам'яна дробарка§r ", - "block.gtceu.zpm_rock_crusher": "§cЕлітна кам'яна дробарка III§r", - "block.gtceu.luv_rock_crusher": "§dЕлітна кам'яна дробарка II§r", - "block.gtceu.uxv_rock_crusher": "§eЕпічна кам'яна дробарка IV§r", - "block.gtceu.lv_rock_crusher": "Базова кам'яна дробарка§r ", - "block.gtceu.hp_steam_rock_crusher": "Парова кам'яна дробарка під високим тиском", - "block.gtceu.lp_steam_rock_crusher": "Парова кам'яна дробарка під низьким тиском", - "block.gtceu.uiv_scanner": "§2Епічний сканер III§r", - "block.gtceu.uv_scanner": "§3Ультимативний сканер§r ", - "block.gtceu.uhv_scanner": "§4Епічний сканер§r ", - "block.gtceu.ev_scanner": "§5Просунутий сканер III§r", - "block.gtceu.hv_scanner": "§6Просунутий сканер II§r", - "block.gtceu.opv_scanner": "§9§lЛегендарний сканер§r ", - "block.gtceu.iv_scanner": "§9Елітний сканер§r ", - "block.gtceu.uev_scanner": "§aЕпічний сканер II§r", - "block.gtceu.mv_scanner": "§bПросунутий сканер§r ", - "block.gtceu.zpm_scanner": "§cЕлітний сканер III§r", - "block.gtceu.luv_scanner": "§dЕлітний сканер II§r", - "block.gtceu.uxv_scanner": "§eЕпічний сканер IV§r", - "block.gtceu.lv_scanner": "Базовий сканер§r ", - "item.gtceu.portable_debug_scanner": "Портативний налагоджувальний сканер", - "gtceu.scanner": "Сканер", - "block.gtceu.uiv_sifter": "§2Епічний просіювач III§r", - "block.gtceu.uv_sifter": "§3Ультимативний просіювач§r ", - "block.gtceu.uhv_sifter": "§4Епічний просіювач§r ", - "block.gtceu.ev_sifter": "§5Просунутий просіювач III§r", - "block.gtceu.hv_sifter": "§6Просунутий просіювач II§r", - "block.gtceu.opv_sifter": "§9§lЛегендарний просіювач§r ", - "block.gtceu.iv_sifter": "§9Елітний просіювач§r ", - "block.gtceu.uev_sifter": "§aЕпічний просіювач II§r", - "block.gtceu.mv_sifter": "§bПросунутий просіювач§r ", - "block.gtceu.zpm_sifter": "§cЕлітний просіювач III§r", - "block.gtceu.luv_sifter": "§dЕлітний просіювач II§r", - "block.gtceu.uxv_sifter": "§eЕпічний просіювач IV§r", - "block.gtceu.lv_sifter": "Базовий просіювач§r ", - "gtceu.sifter": "Просіювач", - "cover.item_smart_filter.filtering_mode.sifter": "Просіювач", - "block.gtceu.uiv_wiremill": "§2Епічний дротяний стан III§r", - "block.gtceu.uv_wiremill": "§3Ультимативний дротяний стан§r ", - "block.gtceu.uhv_wiremill": "§4Епічний дротяний стан§r ", - "block.gtceu.ev_wiremill": "§5Просунутий дротяний стан III§r", - "block.gtceu.hv_wiremill": "§6Просунутий дротяний стан II§r", - "block.gtceu.opv_wiremill": "§9§lЛегендарний дротяний стан§r ", - "block.gtceu.iv_wiremill": "§9Елітний дротяний стан§r ", - "block.gtceu.uev_wiremill": "§aЕпічний дротяний стан II§r", - "block.gtceu.mv_wiremill": "§bПросунутий дротяний стан§r ", - "block.gtceu.zpm_wiremill": "§cЕлітний дротяний стан III§r", - "block.gtceu.luv_wiremill": "§dЕлітний дротяний стан II§r", - "block.gtceu.uxv_wiremill": "§eЕпічний дротяний стан IV§r", - "block.gtceu.lv_wiremill": "Базовий дротяний стан§r ", - "gtceu.wiremill": "Дротяний стан", - "block.gtceu.uiv_machine_hull": "§2UIV§f корпус машини", - "block.gtceu.uv_machine_hull": "§3UV§f корпус машини", - "block.gtceu.uhv_machine_hull": "§4UHV§f корпус машини", - "block.gtceu.ev_machine_hull": "§5EV§f корпус машини", - "block.gtceu.hv_machine_hull": "§6HV§f корпус машини", - "block.gtceu.lv_machine_hull": "§7LV§f корпус машини", - "block.gtceu.ulv_machine_hull": "§8ULV§f корпус машини", - "block.gtceu.opv_machine_hull": "§9§lOpV§f корпус машини", - "block.gtceu.iv_machine_hull": "§9IV§f корпус машини", - "block.gtceu.uev_machine_hull": "§aUEV§f корпус машини", - "block.gtceu.mv_machine_hull": "§bMV§f корпус машини", - "block.gtceu.max_machine_hull": "§c§lMAX§f корпус машини", - "block.gtceu.zpm_machine_hull": "§cZPM§f корпус машини", - "block.gtceu.luv_machine_hull": "§dLuV§f корпус машини", - "block.gtceu.uxv_machine_hull": "§eUXV§f корпус машини", - "block.gtceu.ev_substation_output_hatch_64a": "§5EV 64A динамо-люк підстанції", - "block.gtceu.iv_substation_output_hatch_64a": "§9IV 64A динамо-люк підстанції", - "block.gtceu.luv_substation_output_hatch_64a": "§dLuV 64A динамо-люк підстанції", - "block.gtceu.max_substation_output_hatch_64a": "§c§lMAX 64A динамо-люк підстанції", - "block.gtceu.opv_substation_output_hatch_64a": "§9§lOpV 64A динамо-люк підстанції", - "block.gtceu.uev_substation_output_hatch_64a": "§aUEV 64A динамо-люк підстанції", - "block.gtceu.uhv_substation_output_hatch_64a": "§4UHV 64A динамо-люк підстанції", - "block.gtceu.uiv_substation_output_hatch_64a": "§2UIV 64A динамо-люк підстанції", - "block.gtceu.uv_substation_output_hatch_64a": "§3UV 64A динамо-люк підстанції", - "block.gtceu.uxv_substation_output_hatch_64a": "§eUXV 64A динамо-люк підстанції", - "block.gtceu.zpm_substation_output_hatch_64a": "§cZPM 64A динамо-люк підстанції", - "block.gtceu.ev_energy_output_hatch_16a": "§5EV 16A динамо-люк", - "block.gtceu.iv_energy_output_hatch_16a": "§9IV 16A динамо-люк", - "block.gtceu.luv_energy_output_hatch_16a": "§dLuV 16A динамо-люк", - "block.gtceu.max_energy_output_hatch_16a": "§c§lMAX 16A динамо-люк", - "block.gtceu.opv_energy_output_hatch_16a": "§9§lOpV 16A динамо-люк", - "block.gtceu.uev_energy_output_hatch_16a": "§aUEV 16A динамо-люк", - "block.gtceu.uhv_energy_output_hatch_16a": "§4UHV 16A динамо-люк", - "block.gtceu.uiv_energy_output_hatch_16a": "§2UIV 16A динамо-люк", - "block.gtceu.uv_energy_output_hatch_16a": "§3UV 16A динамо-люк", - "block.gtceu.uxv_energy_output_hatch_16a": "§eUXV 16A динамо-люк", - "block.gtceu.zpm_energy_output_hatch_16a": "§cZPM 16A динамо-люк", - "block.gtceu.ev_energy_output_hatch_4a": "§5EV 4A динамо-люк", - "block.gtceu.iv_energy_output_hatch_4a": "§9IV 4A динамо-люк", - "block.gtceu.luv_energy_output_hatch_4a": "§dLuV 4A динамо-люк", - "block.gtceu.max_energy_output_hatch_4a": "§c§lMAX 4A динамо-люк", - "block.gtceu.opv_energy_output_hatch_4a": "§9§lOpV 4A динамо-люк", - "block.gtceu.uev_energy_output_hatch_4a": "§aUEV 4A динамо-люк", - "block.gtceu.uhv_energy_output_hatch_4a": "§4UHV 4A динамо-люк", - "block.gtceu.uiv_energy_output_hatch_4a": "§2UIV 4A динамо-люк", - "block.gtceu.uv_energy_output_hatch_4a": "§3UV 4A динамо-люк", - "block.gtceu.uxv_energy_output_hatch_4a": "§eUXV 4A динамо-люк", - "block.gtceu.zpm_energy_output_hatch_4a": "§cZPM 4A динамо-люк", - "block.gtceu.ev_energy_output_hatch": "§5EV динамо-люк", - "block.gtceu.hv_energy_output_hatch": "§6HV динамо-люк", - "block.gtceu.iv_energy_output_hatch": "§9IV динамо-люк", - "block.gtceu.luv_energy_output_hatch": "§dLuV динамо-люк", - "block.gtceu.lv_energy_output_hatch": "§7LV динамо-люк", - "block.gtceu.max_energy_output_hatch": "§c§lMAX динамо-люк", - "block.gtceu.mv_energy_output_hatch": "§bMV динамо-люк", - "block.gtceu.opv_energy_output_hatch": "§9§lOpV динамо-люк", - "block.gtceu.uev_energy_output_hatch": "§aUEV динамо-люк", - "block.gtceu.uhv_energy_output_hatch": "§4UHV динамо-люк", - "block.gtceu.uiv_energy_output_hatch": "§2UIV динамо-люк", - "block.gtceu.ulv_energy_output_hatch": "§8ULV динамо-люк", - "block.gtceu.uv_energy_output_hatch": "§3UV динамо-люк", - "block.gtceu.uxv_energy_output_hatch": "§eUXV динамо-люк", - "block.gtceu.zpm_energy_output_hatch": "§cZPM динамо-люк", - "block.gtceu.ev_substation_input_hatch_64a": "§5EV 64A енергетичний люк підстанції", - "block.gtceu.iv_substation_input_hatch_64a": "§9IV 64A енергетичний люк підстанції", - "block.gtceu.luv_substation_input_hatch_64a": "§dLuV 64A енергетичний люк підстанції", - "block.gtceu.max_substation_input_hatch_64a": "§c§lMAX 64A енергетичний люк підстанції", - "block.gtceu.opv_substation_input_hatch_64a": "§9§lOpV 64A енергетичний люк підстанції", - "block.gtceu.uev_substation_input_hatch_64a": "§aUEV 64A енергетичний люк підстанції", - "block.gtceu.uhv_substation_input_hatch_64a": "§4UHV 64A енергетичний люк підстанції", - "block.gtceu.uiv_substation_input_hatch_64a": "§2UIV 64A енергетичний люк підстанції", - "block.gtceu.uv_substation_input_hatch_64a": "§3UV 64A енергетичний люк підстанції", - "block.gtceu.uxv_substation_input_hatch_64a": "§eUXV 64A енергетичний люк підстанції", - "block.gtceu.zpm_substation_input_hatch_64a": "§cZPM 64A енергетичний люк підстанції", - "block.gtceu.ev_energy_input_hatch_16a": "§5EV 16A енергетичний люк", - "block.gtceu.iv_energy_input_hatch_16a": "§9IV 16A енергетичний люк", - "block.gtceu.luv_energy_input_hatch_16a": "§dLuV 16A енергетичний люк", - "block.gtceu.max_energy_input_hatch_16a": "§c§lMAX 16A енергетичний люк", - "block.gtceu.opv_energy_input_hatch_16a": "§9§lOpV 16A енергетичний люк", - "block.gtceu.uev_energy_input_hatch_16a": "§aUEV 16A енергетичний люк", - "block.gtceu.uhv_energy_input_hatch_16a": "§4UHV 16A енергетичний люк", - "block.gtceu.uiv_energy_input_hatch_16a": "§2UIV 16A енергетичний люк", - "block.gtceu.uv_energy_input_hatch_16a": "§3UV 16A енергетичний люк", - "block.gtceu.uxv_energy_input_hatch_16a": "§eUXV 16A енергетичний люк", - "block.gtceu.zpm_energy_input_hatch_16a": "§cZPM 16A енергетичний люк", - "block.gtceu.ev_energy_input_hatch_4a": "§5EV 4A енергетичний люк", - "block.gtceu.iv_energy_input_hatch_4a": "§9IV 4A енергетичний люк", - "block.gtceu.luv_energy_input_hatch_4a": "§dLuV 4A енергетичний люк", - "block.gtceu.max_energy_input_hatch_4a": "§c§lMAX 4A енергетичний люк", - "block.gtceu.opv_energy_input_hatch_4a": "§9§lOpV 4A енергетичний люк", - "block.gtceu.uev_energy_input_hatch_4a": "§aUEV 4A енергетичний люк", - "block.gtceu.uhv_energy_input_hatch_4a": "§4UHV 4A енергетичний люк", - "block.gtceu.uiv_energy_input_hatch_4a": "§2UIV 4A енергетичний люк", - "block.gtceu.uv_energy_input_hatch_4a": "§3UV 4A енергетичний люк", - "block.gtceu.uxv_energy_input_hatch_4a": "§eUXV 4A енергетичний люк", - "block.gtceu.zpm_energy_input_hatch_4a": "§cZPM 4A енергетичний люк", - "block.gtceu.ev_energy_input_hatch": "§5EV енергетичний люк", - "block.gtceu.hv_energy_input_hatch": "§6HV енергетичний люк", - "block.gtceu.iv_energy_input_hatch": "§9IV енергетичний люк", - "block.gtceu.luv_energy_input_hatch": "§dLuV енергетичний люк", - "block.gtceu.lv_energy_input_hatch": "§7LV енергетичний люк", - "block.gtceu.max_energy_input_hatch": "§c§lMAX енергетичний люк", - "block.gtceu.mv_energy_input_hatch": "§bMV енергетичний люк", - "block.gtceu.opv_energy_input_hatch": "§9§lOpV енергетичний люк", - "block.gtceu.uev_energy_input_hatch": "§aUEV енергетичний люк", - "block.gtceu.uhv_energy_input_hatch": "§4UHV енергетичний люк", - "block.gtceu.uiv_energy_input_hatch": "§2UIV енергетичний люк", - "block.gtceu.ulv_energy_input_hatch": "§8ULV енергетичний люк", - "block.gtceu.uv_energy_input_hatch": "§3UV енергетичний люк", - "block.gtceu.uxv_energy_input_hatch": "§eUXV енергетичний люк", - "block.gtceu.zpm_energy_input_hatch": "§cZPM енергетичний люк", - "block.gtceu.uiv_diode": "§2UIV діод", - "block.gtceu.uv_diode": "§3UV діод", - "block.gtceu.uhv_diode": "§4UHV діод", - "block.gtceu.ev_diode": "§5EV діод", - "block.gtceu.hv_diode": "§6HV діод", - "block.gtceu.lv_diode": "§7LV діод", - "block.gtceu.opv_diode": "§9§lOpV діод", - "block.gtceu.iv_diode": "§9IV діод", - "block.gtceu.uev_diode": "§aUEV діод", - "block.gtceu.mv_diode": "§bMV діод", - "block.gtceu.zpm_diode": "§cZPM діод", - "block.gtceu.luv_diode": "§dLuV діод", - "block.gtceu.uxv_diode": "§eUXV діод", - "item.gtceu.advanced_smd_diode": "Просунутий SMD діод", - "item.gtceu.diode": "Діод", - "item.gtceu.smd_diode": "SMD діод", - "block.gtceu.uiv_dual_input_hatch": "§2UIV подвійний вхідний люк", - "block.gtceu.uv_dual_input_hatch": "§3UV подвійний вхідний люк", - "block.gtceu.uhv_dual_input_hatch": "§4UHV подвійний вхідний люк", - "block.gtceu.opv_dual_input_hatch": "§9§lOpV подвійний вхідний люк", - "block.gtceu.uev_dual_input_hatch": "§aUEV подвійний вхідний люк", - "block.gtceu.max_dual_input_hatch": "§c§lMAX подвійний вхідний люк", - "block.gtceu.zpm_dual_input_hatch": "§cZPM подвійний вхідний люк", - "block.gtceu.luv_dual_input_hatch": "§dLuV подвійний вхідний люк", - "block.gtceu.uxv_dual_input_hatch": "§eUXV подвійний вхідний люк", - "block.gtceu.uiv_dual_output_hatch": "§2UIV подвійний вихідний люк", - "block.gtceu.uv_dual_output_hatch": "§3UV подвійний вихідний люк", - "block.gtceu.uhv_dual_output_hatch": "§4UHV подвійний вихідний люк", - "block.gtceu.opv_dual_output_hatch": "§9§lOpV подвійний вихідний люк", - "block.gtceu.uev_dual_output_hatch": "§aUEV подвійний вихідний люк", - "block.gtceu.max_dual_output_hatch": "§c§lMAX подвійний вихідний люк", - "block.gtceu.zpm_dual_output_hatch": "§cZPM подвійний вихідний люк", - "block.gtceu.luv_dual_output_hatch": "§dLuV подвійний вихідний люк", - "block.gtceu.uxv_dual_output_hatch": "§eUXV подвійний вихідний люк", - "block.gtceu.uiv_fluid_passthrough_hatch": "§2UIV прохідний рідинний люк", - "block.gtceu.uv_fluid_passthrough_hatch": "§3UV прохідний рідинний люк", - "block.gtceu.uhv_fluid_passthrough_hatch": "§4UHV прохідний рідинний люк", - "block.gtceu.ev_fluid_passthrough_hatch": "§5EV прохідний рідинний люк", - "block.gtceu.hv_fluid_passthrough_hatch": "§6HV прохідний рідинний люк", - "block.gtceu.lv_fluid_passthrough_hatch": "§7LV прохідний рідинний люк", - "block.gtceu.opv_fluid_passthrough_hatch": "§9§lOpV прохідний рідинний люк", - "block.gtceu.iv_fluid_passthrough_hatch": "§9IV прохідний рідинний люк", - "block.gtceu.uev_fluid_passthrough_hatch": "§aUEV прохідний рідинний люк", - "block.gtceu.mv_fluid_passthrough_hatch": "§bMV прохідний рідинний люк", - "block.gtceu.zpm_fluid_passthrough_hatch": "§cZPM прохідний рідинний люк", - "block.gtceu.luv_fluid_passthrough_hatch": "§dLuV прохідний рідинний люк", - "block.gtceu.uxv_fluid_passthrough_hatch": "§eUXV прохідний рідинний люк", - "block.gtceu.uiv_input_hatch_9x": "§2UIV дев'ятикамерний вхідний люк", - "block.gtceu.uv_input_hatch_9x": "§3UV дев'ятикамерний вхідний люк", - "block.gtceu.uhv_input_hatch_9x": "§4UHV дев'ятикамерний вхідний люк", - "block.gtceu.ev_input_hatch_9x": "§5EV дев'ятикамерний вхідний люк", - "block.gtceu.opv_input_hatch_9x": "§9§lOpV дев'ятикамерний вхідний люк", - "block.gtceu.iv_input_hatch_9x": "§9IV дев'ятикамерний вхідний люк", - "block.gtceu.uev_input_hatch_9x": "§aUEV дев'ятикамерний вхідний люк", - "block.gtceu.max_input_hatch_9x": "§c§lMAX дев'ятикамерний вхідний люк", - "block.gtceu.zpm_input_hatch_9x": "§cZPM дев'ятикамерний вхідний люк", - "block.gtceu.luv_input_hatch_9x": "§dLuV дев'ятикамерний вхідний люк", - "block.gtceu.uxv_input_hatch_9x": "§eUXV дев'ятикамерний вхідний люк", - "block.gtceu.uiv_input_hatch_4x": "§2UIV чотирикамерний вхідний люк", - "block.gtceu.uv_input_hatch_4x": "§3UV чотирикамерний вхідний люк", - "block.gtceu.uhv_input_hatch_4x": "§4UHV чотирикамерний вхідний люк", - "block.gtceu.ev_input_hatch_4x": "§5EV чотирикамерний вхідний люк", - "block.gtceu.opv_input_hatch_4x": "§9§lOpV чотирикамерний вхідний люк", - "block.gtceu.iv_input_hatch_4x": "§9IV чотирикамерний вхідний люк", - "block.gtceu.uev_input_hatch_4x": "§aUEV чотирикамерний вхідний люк", - "block.gtceu.max_input_hatch_4x": "§c§lMAX чотирикамерний вхідний люк", - "block.gtceu.zpm_input_hatch_4x": "§cZPM чотирикамерний вхідний люк", - "block.gtceu.luv_input_hatch_4x": "§dLuV чотирикамерний вхідний люк", - "block.gtceu.uxv_input_hatch_4x": "§eUXV чотирикамерний вхідний люк", - "block.gtceu.uiv_input_hatch": "§2UIV вхідний люк", - "block.gtceu.uv_input_hatch": "§3UV вхідний люк", - "block.gtceu.uhv_input_hatch": "§4UHV вхідний люк", - "block.gtceu.ev_input_hatch": "§5EV вхідний люк", - "block.gtceu.hv_input_hatch": "§6HV вхідний люк", - "block.gtceu.lv_input_hatch": "§7LV вхідний люк", - "block.gtceu.ulv_input_hatch": "§8ULV вхідний люк", - "block.gtceu.opv_input_hatch": "§9§lOpV вхідний люк", - "block.gtceu.iv_input_hatch": "§9IV вхідний люк", - "block.gtceu.uev_input_hatch": "§aUEV вхідний люк", - "block.gtceu.mv_input_hatch": "§bMV вхідний люк", - "block.gtceu.max_input_hatch": "§c§lMAX вхідний люк", - "block.gtceu.zpm_input_hatch": "§cZPM вхідний люк", - "block.gtceu.luv_input_hatch": "§dLuV вхідний люк", - "block.gtceu.uxv_input_hatch": "§eUXV вхідний люк", - "block.gtceu.uiv_output_hatch_9x": "§2UIV дев'ятикамерний вихідний люк", - "block.gtceu.uv_output_hatch_9x": "§3UV дев'ятикамерний вихідний люк", - "block.gtceu.uhv_output_hatch_9x": "§4UHV дев'ятикамерний вихідний люк", - "block.gtceu.ev_output_hatch_9x": "§5EV дев'ятикамерний вихідний люк", - "block.gtceu.opv_output_hatch_9x": "§9§lOpV дев'ятикамерний вихідний люк", - "block.gtceu.iv_output_hatch_9x": "§9IV дев'ятикамерний вихідний люк", - "block.gtceu.uev_output_hatch_9x": "§aUEV дев'ятикамерний вихідний люк", - "block.gtceu.max_output_hatch_9x": "§c§lMAX дев'ятикамерний вихідний люк", - "block.gtceu.zpm_output_hatch_9x": "§cZPM дев'ятикамерний вихідний люк", - "block.gtceu.luv_output_hatch_9x": "§dLuV дев'ятикамерний вихідний люк", - "block.gtceu.uxv_output_hatch_9x": "§eUXV дев'ятикамерний вихідний люк", - "block.gtceu.uiv_output_hatch_4x": "§2UIV чотирикамерний вихідний люк", - "block.gtceu.uv_output_hatch_4x": "§3UV чотирикамерний вихідний люк", - "block.gtceu.uhv_output_hatch_4x": "§4UHV чотирикамерний вихідний люк", - "block.gtceu.ev_output_hatch_4x": "§5EV чотирикамерний вихідний люк", - "block.gtceu.opv_output_hatch_4x": "§9§lOpV чотирикамерний вихідний люк", - "block.gtceu.iv_output_hatch_4x": "§9IV чотирикамерний вихідний люк", - "block.gtceu.uev_output_hatch_4x": "§aUEV чотирикамерний вихідний люк", - "block.gtceu.max_output_hatch_4x": "§c§lMAX чотирикамерний вихідний люк", - "block.gtceu.zpm_output_hatch_4x": "§cZPM чотирикамерний вихідний люк", - "block.gtceu.luv_output_hatch_4x": "§dLuV чотирикамерний вихідний люк", - "block.gtceu.uxv_output_hatch_4x": "§eUXV чотирикамерний вихідний люк", - "block.gtceu.uiv_output_hatch": "§2UIV вихідний люк", - "block.gtceu.uv_output_hatch": "§3UV вихідний люк", - "block.gtceu.uhv_output_hatch": "§4UHV вихідний люк", - "block.gtceu.ev_output_hatch": "§5EV вихідний люк", - "block.gtceu.hv_output_hatch": "§6HV вихідний люк", - "block.gtceu.lv_output_hatch": "§7LV вихідний люк", - "block.gtceu.ulv_output_hatch": "§8ULV вихідний люк", - "block.gtceu.opv_output_hatch": "§9§lOpV вихідний люк", - "block.gtceu.iv_output_hatch": "§9IV вихідний люк", - "block.gtceu.uev_output_hatch": "§aUEV вихідний люк", - "block.gtceu.mv_output_hatch": "§bMV вихідний люк", - "block.gtceu.max_output_hatch": "§c§lMAX вихідний люк", - "block.gtceu.zpm_output_hatch": "§cZPM вихідний люк", - "block.gtceu.luv_output_hatch": "§dLuV вихідний люк", - "block.gtceu.uxv_output_hatch": "§eUXV вихідний люк", - "block.gtceu.me_output_hatch": "ME вихідний люк", - "block.gtceu.uiv_item_passthrough_hatch": "§2UIV прохідний предметний люк", - "block.gtceu.uv_item_passthrough_hatch": "§3UV прохідний предметний люк", - "block.gtceu.uhv_item_passthrough_hatch": "§4UHV прохідний предметний люк", - "block.gtceu.ev_item_passthrough_hatch": "§5EV прохідний предметний люк", - "block.gtceu.hv_item_passthrough_hatch": "§6HV прохідний предметний люк", - "block.gtceu.lv_item_passthrough_hatch": "§7LV прохідний предметний люк", - "block.gtceu.opv_item_passthrough_hatch": "§9§lOpV прохідний предметний люк", - "block.gtceu.iv_item_passthrough_hatch": "§9IV прохідний предметний люк", - "block.gtceu.uev_item_passthrough_hatch": "§aUEV прохідний предметний люк", - "block.gtceu.mv_item_passthrough_hatch": "§bMV прохідний предметний люк", - "block.gtceu.zpm_item_passthrough_hatch": "§cZPM прохідний предметний люк", - "block.gtceu.luv_item_passthrough_hatch": "§dLuV прохідний предметний люк", - "block.gtceu.uxv_item_passthrough_hatch": "§eUXV прохідний предметний люк", - "block.gtceu.me_input_hatch": "ME-вхідний люк", - "block.gtceu.me_stocking_input_hatch": "ME-складальний вхідний люк", - "block.gtceu.steam_input_hatch": "Паровий вхідний люк", - "block.gtceu.uiv_4096a_laser_source_hatch": "§2UIV§r 4,096§eA§r люк джерела лазера", - "block.gtceu.uv_4096a_laser_source_hatch": "§3UV§r 4,096§eA§r люк джерела лазера", - "block.gtceu.uhv_4096a_laser_source_hatch": "§4UHV§r 4,096§eA§r люк джерела лазера", - "block.gtceu.opv_4096a_laser_source_hatch": "§9§lOpV§r 4,096§eA§r люк джерела лазера", - "block.gtceu.iv_4096a_laser_source_hatch": "§9IV§r 4,096§eA§r люк джерела лазера", - "block.gtceu.uev_4096a_laser_source_hatch": "§aUEV§r 4,096§eA§r люк джерела лазера", - "block.gtceu.zpm_4096a_laser_source_hatch": "§cZPM§r 4,096§eA§r люк джерела лазера", - "block.gtceu.luv_4096a_laser_source_hatch": "§dLuV§r 4,096§eA§r люк джерела лазера", - "block.gtceu.uxv_4096a_laser_source_hatch": "§eUXV§r 4,096§eA§r люк джерела лазера", - "block.gtceu.uiv_1024a_laser_source_hatch": "§2UIV§r 1,024§eA§r люк джерела лазера", - "block.gtceu.uv_1024a_laser_source_hatch": "§3UV§r 1,024§eA§r люк джерела лазера", - "block.gtceu.uhv_1024a_laser_source_hatch": "§4UHV§r 1,024§eA§r люк джерела лазера", - "block.gtceu.opv_1024a_laser_source_hatch": "§9§lOpV§r 1,024§eA§r люк джерела лазера", - "block.gtceu.iv_1024a_laser_source_hatch": "§9IV§r 1,024§eA§r люк джерела лазера", - "block.gtceu.uev_1024a_laser_source_hatch": "§aUEV§r 1,024§eA§r люк джерела лазера", - "block.gtceu.zpm_1024a_laser_source_hatch": "§cZPM§r 1,024§eA§r люк джерела лазера", - "block.gtceu.luv_1024a_laser_source_hatch": "§dLuV§r 1,024§eA§r люк джерела лазера", - "block.gtceu.uxv_1024a_laser_source_hatch": "§eUXV§r 1,024§eA§r люк джерела лазера", - "block.gtceu.uiv_256a_laser_source_hatch": "§2UIV§r 256§eA§r люк джерела лазера", - "block.gtceu.uv_256a_laser_source_hatch": "§3UV§r 256§eA§r люк джерела лазера", - "block.gtceu.uhv_256a_laser_source_hatch": "§4UHV§r 256§eA§r люк джерела лазера", - "block.gtceu.opv_256a_laser_source_hatch": "§9§lOpV§r 256§eA§r люк джерела лазера", - "block.gtceu.iv_256a_laser_source_hatch": "§9IV§r 256§eA§r люк джерела лазера", - "block.gtceu.uev_256a_laser_source_hatch": "§aUEV§r 256§eA§r люк джерела лазера", - "block.gtceu.zpm_256a_laser_source_hatch": "§cZPM§r 256§eA§r люк джерела лазера", - "block.gtceu.luv_256a_laser_source_hatch": "§dLuV§r 256§eA§r люк джерела лазера", - "block.gtceu.uxv_256a_laser_source_hatch": "§eUXV§r 256§eA§r люк джерела лазера", - "block.gtceu.opv_4096a_laser_target_hatch": "§9§lOpV§r 4,096§eA§r люк цілі лазера", - "block.gtceu.uiv_4096a_laser_target_hatch": "§2UIV§r 4,096§eA§r люк цілі лазера", - "block.gtceu.uhv_4096a_laser_target_hatch": "§4UHV§r 4,096§eA§r люк цілі лазера", - "block.gtceu.uev_4096a_laser_target_hatch": "§aUEV§r 4,096§eA§r люк цілі лазера", - "block.gtceu.zpm_4096a_laser_target_hatch": "§cZPM§r 4,096§eA§r люк цілі лазера", - "block.gtceu.luv_4096a_laser_target_hatch": "§dLuV§r 4,096§eA§r люк цілі лазера", - "block.gtceu.uxv_4096a_laser_target_hatch": "§eUXV§r 4,096§eA§r люк цілі лазера", - "block.gtceu.uv_4096a_laser_target_hatch": "§3UV§r 4,096§eA§r люк цілі лазера", - "block.gtceu.iv_4096a_laser_target_hatch": "§9IV§r 4,096§eA§r люк цілі лазера", - "block.gtceu.uiv_1024a_laser_target_hatch": "§2UIV§r 1,024§eA§r люк цілі лазера", - "block.gtceu.opv_1024a_laser_target_hatch": "§9§lOpV§r 1,024§eA§r люк цілі лазера", - "block.gtceu.uhv_1024a_laser_target_hatch": "§4UHV§r 1,024§eA§r люк цілі лазера", - "block.gtceu.uev_1024a_laser_target_hatch": "§aUEV§r 1,024§eA§r люк цілі лазера", - "block.gtceu.zpm_1024a_laser_target_hatch": "§cZPM§r 1,024§eA§r люк цілі лазера", - "block.gtceu.luv_1024a_laser_target_hatch": "§dLuV§r 1,024§eA§r люк цілі лазера", - "block.gtceu.uxv_1024a_laser_target_hatch": "§eUXV§r 1,024§eA§r люк цілі лазера", - "block.gtceu.uv_1024a_laser_target_hatch": "§3UV§r 1,024§eA§r люк цілі лазера", - "block.gtceu.iv_1024a_laser_target_hatch": "§9IV§r 1,024§eA§r люк цілі лазера", - "block.gtceu.opv_256a_laser_target_hatch": "§9§lOpV§r 256§eA§r люк цілі лазера", - "block.gtceu.uiv_256a_laser_target_hatch": "§2UIV§r 256§eA§r люк цілі лазера", - "block.gtceu.uhv_256a_laser_target_hatch": "§4UHV§r 256§eA§r люк цілі лазера", - "block.gtceu.uev_256a_laser_target_hatch": "§aUEV§r 256§eA§r люк цілі лазера", - "block.gtceu.zpm_256a_laser_target_hatch": "§cZPM§r 256§eA§r люк цілі лазера", - "block.gtceu.luv_256a_laser_target_hatch": "§dLuV§r 256§eA§r люк цілі лазера", - "block.gtceu.uxv_256a_laser_target_hatch": "§eUXV§r 256§eA§r люк цілі лазера", - "block.gtceu.uv_256a_laser_target_hatch": "§3UV§r 256§eA§r люк цілі лазера", - "block.gtceu.iv_256a_laser_target_hatch": "§9IV§r 256§eA§r люк цілі лазера", - "block.gtceu.maintenance_hatch": "Люк техобслуговування", - "block.gtceu.auto_maintenance_hatch": "Автоматичний люк техобслуговування", - "block.gtceu.cleaning_maintenance_hatch": "Очищуючий люк техобслуговування", - "block.gtceu.configurable_maintenance_hatch": "Налаштовний люк техобслуговування", - "block.gtceu.data_receiver_hatch": "Оптичний люк прийому даних", - "block.gtceu.computation_receiver_hatch": "Оптичний люк прийому обчислень", - "block.gtceu.data_transmitter_hatch": "Оптичний люк трансмісії даних", - "block.gtceu.computation_transmitter_hatch": "Оптичний люк трансмісії обчислень", - "block.gtceu.iv_parallel_hatch": "Елітний люк паралельного контролю", - "block.gtceu.luv_parallel_hatch": "Майстерський люк паралельного контролю", - "block.gtceu.uv_parallel_hatch": "Супер люк паралельного контролю", - "block.gtceu.zpm_parallel_hatch": "Ультимативний люк паралельного контролю", - "block.gtceu.uiv_muffler_hatch": "Люк вихлопа§2 UIV", - "block.gtceu.uv_muffler_hatch": "Люк вихлопа§3 UV", - "block.gtceu.uhv_muffler_hatch": "Люк вихлопа§4 UHV", - "block.gtceu.ev_muffler_hatch": "Люк вихлопа§5 EV", - "block.gtceu.hv_muffler_hatch": "Люк вихлопа§6 HV", - "block.gtceu.lv_muffler_hatch": "Люк вихлопа§7 LV", - "block.gtceu.opv_muffler_hatch": "Люк вихлопа§9§l OpV", - "block.gtceu.iv_muffler_hatch": "Люк вихлопа§9 IV", - "block.gtceu.uev_muffler_hatch": "Люк вихлопа§a UEV", - "block.gtceu.mv_muffler_hatch": "Люк вихлопа§b MV", - "block.gtceu.zpm_muffler_hatch": "Люк вихлопа§c ZPM", - "block.gtceu.luv_muffler_hatch": "Люк вихлопа§d LuV", - "block.gtceu.uxv_muffler_hatch": "Люк вихлопа§e UXV", - "block.gtceu.coke_oven_hatch": "Люк коксової печі", - "block.gtceu.pump_hatch": "Люк помпи", - "block.gtceu.reservoir_hatch": "Люк резервуара", - "block.gtceu.uiv_input_bus": "§2UIV вхідна шина", - "block.gtceu.uv_input_bus": "§3UV вхідна шина", - "block.gtceu.uhv_input_bus": "§4UHV вхідна шина", - "block.gtceu.ev_input_bus": "§5EV вхідна шина", - "block.gtceu.hv_input_bus": "§6HV вхідна шина", - "block.gtceu.lv_input_bus": "§7LV вхідна шина", - "block.gtceu.ulv_input_bus": "§8ULV вхідна шина", - "block.gtceu.opv_input_bus": "§9§lOpV вхідна шина", - "block.gtceu.iv_input_bus": "§9IV вхідна шина", - "block.gtceu.uev_input_bus": "§aUEV вхідна шина", - "block.gtceu.mv_input_bus": "§bMV вхідна шина", - "block.gtceu.max_input_bus": "§c§lMAX вхідна шина", - "block.gtceu.zpm_input_bus": "§cZPM вхідна шина", - "block.gtceu.luv_input_bus": "§dLuV вхідна шина", - "block.gtceu.uxv_input_bus": "§eUXV вхідна шина", - "block.gtceu.me_input_bus": "ME-вхідна шина", - "block.gtceu.me_stocking_input_bus": "ME-складальний вхідна шина", - "block.gtceu.steam_input_bus": "Парова вхідна шина", - "block.gtceu.uiv_output_bus": "§2UIV вихідна шина", - "block.gtceu.uv_output_bus": "§3UV вихідна шина", - "block.gtceu.uhv_output_bus": "§4UHV вихідна шина", - "block.gtceu.ev_output_bus": "§5EV вихідна шина", - "block.gtceu.hv_output_bus": "§6HV вихідна шина", - "block.gtceu.lv_output_bus": "§7LV вихідна шина", - "block.gtceu.ulv_output_bus": "§8ULV вихідна шина", - "block.gtceu.opv_output_bus": "§9§lOpV вихідна шина", - "block.gtceu.iv_output_bus": "§9IV вихідна шина", - "block.gtceu.uev_output_bus": "§aUEV вихідна шина", - "block.gtceu.mv_output_bus": "§bMV вихідна шина", - "block.gtceu.max_output_bus": "§c§lMAX вихідна шина", - "block.gtceu.zpm_output_bus": "§cZPM вихідна шина", - "block.gtceu.luv_output_bus": "§dLuV вихідна шина", - "block.gtceu.uxv_output_bus": "§eUXV вихідна шина", - "block.gtceu.me_output_bus": "ME-вихідна шина", - "gtceu.bus.collapse.error": "Спочатку шина повинна бути приєднана до конструкції", - "gtceu.bus.collapse_true": "Шина руйнуватиме предмети", - "gtceu.bus.collapse_false": "Шина не руйнуватиме предмети", - "block.gtceu.steam_output_bus": "Парова вихідна шина", - "block.gtceu.uiv_rotor_holder": "§2UIV тримач ротора", - "block.gtceu.uv_rotor_holder": "§3UV тримач ротора", - "block.gtceu.uhv_rotor_holder": "§4UHV тримач ротора", - "block.gtceu.ev_rotor_holder": "§5EV тримач ротора", - "block.gtceu.hv_rotor_holder": "§6HV тримач ротора", - "block.gtceu.opv_rotor_holder": "§9§lOpV тримач ротора", - "block.gtceu.iv_rotor_holder": "§9IV тримач ротора", - "block.gtceu.uev_rotor_holder": "§aUEV тримач ротора", - "block.gtceu.zpm_rotor_holder": "§cZPM тримач ротора", - "block.gtceu.luv_rotor_holder": "§dLuV тримач ротора", - "block.gtceu.uxv_rotor_holder": "§eUXV тримач ротора", - "block.gtceu.zpm_16a_energy_converter": "§cZPM§r 16§eA§r енергетичний конвертер", - "block.gtceu.uxv_16a_energy_converter": "§eUXV§r 16§eA§r енергетичний конвертер", - "block.gtceu.uv_16a_energy_converter": "§3UV§r 16§eA§r енергетичний конвертер", - "block.gtceu.ulv_16a_energy_converter": "§8ULV§r 16§eA§r енергетичний конвертер", - "block.gtceu.uiv_16a_energy_converter": "§2UIV§r 16§eA§r енергетичний конвертер", - "block.gtceu.uhv_16a_energy_converter": "§4UHV§r 16§eA§r енергетичний конвертер", - "block.gtceu.uev_16a_energy_converter": "§aUEV§r 16§eA§r енергетичний конвертер", - "block.gtceu.opv_16a_energy_converter": "§9§lOpV§r 16§eA§r енергетичний конвертер", - "block.gtceu.mv_16a_energy_converter": "§bMV§r 16§eA§r енергетичний конвертер", - "block.gtceu.max_16a_energy_converter": "§c§lMAX§r 16§eA§r енергетичний конвертер", - "block.gtceu.lv_16a_energy_converter": "§7LV§r 16§eA§r енергетичний конвертер", - "block.gtceu.luv_16a_energy_converter": "§dLuV§r 16§eA§r енергетичний конвертер", - "block.gtceu.iv_16a_energy_converter": "§9IV§r 16§eA§r енергетичний конвертер", - "block.gtceu.hv_16a_energy_converter": "§6HV§r 16§eA§r енергетичний конвертер", - "block.gtceu.ev_16a_energy_converter": "§5EV§r 16§eA§r енергетичний конвертер", - "block.gtceu.zpm_8a_energy_converter": "§cZPM§r 8§eA§r енергетичний конвертер", - "block.gtceu.uxv_8a_energy_converter": "§eUXV§r 8§eA§r енергетичний конвертер", - "block.gtceu.uv_8a_energy_converter": "§3UV§r 8§eA§r енергетичний конвертер", - "block.gtceu.ulv_8a_energy_converter": "§8ULV§r 8§eA§r енергетичний конвертер", - "block.gtceu.uiv_8a_energy_converter": "§2UIV§r 8§eA§r енергетичний конвертер", - "block.gtceu.uhv_8a_energy_converter": "§4UHV§r 8§eA§r енергетичний конвертер", - "block.gtceu.uev_8a_energy_converter": "§aUEV§r 8§eA§r енергетичний конвертер", - "block.gtceu.opv_8a_energy_converter": "§9§lOpV§r 8§eA§r енергетичний конвертер", - "block.gtceu.mv_8a_energy_converter": "§bMV§r 8§eA§r енергетичний конвертер", - "block.gtceu.max_8a_energy_converter": "§c§lMAX§r 8§eA§r енергетичний конвертер", - "block.gtceu.lv_8a_energy_converter": "§7LV§r 8§eA§r енергетичний конвертер", - "block.gtceu.luv_8a_energy_converter": "§dLuV§r 8§eA§r енергетичний конвертер", - "block.gtceu.iv_8a_energy_converter": "§9IV§r 8§eA§r енергетичний конвертер", - "block.gtceu.hv_8a_energy_converter": "§6HV§r 8§eA§r енергетичний конвертер", - "block.gtceu.ev_8a_energy_converter": "§5EV§r 8§eA§r енергетичний конвертер", - "block.gtceu.zpm_4a_energy_converter": "§cZPM§r 4§eA§r енергетичний конвертер", - "block.gtceu.uxv_4a_energy_converter": "§eUXV§r 4§eA§r енергетичний конвертер", - "block.gtceu.uv_4a_energy_converter": "§3UV§r 4§eA§r енергетичний конвертер", - "block.gtceu.ulv_4a_energy_converter": "§8ULV§r 4§eA§r енергетичний конвертер", - "block.gtceu.uiv_4a_energy_converter": "§2UIV§r 4§eA§r енергетичний конвертер", - "block.gtceu.uhv_4a_energy_converter": "§4UHV§r 4§eA§r енергетичний конвертер", - "block.gtceu.uev_4a_energy_converter": "§aUEV§r 4§eA§r енергетичний конвертер", - "block.gtceu.opv_4a_energy_converter": "§9§lOpV§r 4§eA§r енергетичний конвертер", - "block.gtceu.mv_4a_energy_converter": "§bMV§r 4§eA§r енергетичний конвертер", - "block.gtceu.max_4a_energy_converter": "§c§lMAX§r 4§eA§r енергетичний конвертер", - "block.gtceu.lv_4a_energy_converter": "§7LV§r 4§eA§r енергетичний конвертер", - "block.gtceu.luv_4a_energy_converter": "§dLuV§r 4§eA§r енергетичний конвертер", - "block.gtceu.iv_4a_energy_converter": "§9IV§r 4§eA§r енергетичний конвертер", - "block.gtceu.hv_4a_energy_converter": "§6HV§r 4§eA§r енергетичний конвертер", - "block.gtceu.ev_4a_energy_converter": "§5EV§r 4§eA§r енергетичний конвертер", - "block.gtceu.zpm_1a_energy_converter": "§cZPM§r 1§eA§r енергетичний конвертер", - "block.gtceu.uxv_1a_energy_converter": "§eUXV§r 1§eA§r енергетичний конвертер", - "block.gtceu.uv_1a_energy_converter": "§3UV§r 1§eA§r енергетичний конвертер", - "block.gtceu.ulv_1a_energy_converter": "§8ULV§r 1§eA§r енергетичний конвертер", - "block.gtceu.uiv_1a_energy_converter": "§2UIV§r 1§eA§r енергетичний конвертер", - "block.gtceu.uhv_1a_energy_converter": "§4UHV§r 1§eA§r енергетичний конвертер", - "block.gtceu.uev_1a_energy_converter": "§aUEV§r 1§eA§r енергетичний конвертер", - "block.gtceu.opv_1a_energy_converter": "§9§lOpV§r 1§eA§r енергетичний конвертер", - "block.gtceu.mv_1a_energy_converter": "§bMV§r 1§eA§r енергетичний конвертер", - "block.gtceu.max_1a_energy_converter": "§c§lMAX§r 1§eA§r енергетичний конвертер", - "block.gtceu.lv_1a_energy_converter": "§7LV§r 1§eA§r енергетичний конвертер", - "block.gtceu.luv_1a_energy_converter": "§dLuV§r 1§eA§r енергетичний конвертер", - "block.gtceu.iv_1a_energy_converter": "§9IV§r 1§eA§r енергетичний конвертер", - "block.gtceu.hv_1a_energy_converter": "§6HV§r 1§eA§r енергетичний конвертер", - "block.gtceu.ev_1a_energy_converter": "§5EV§r 1§eA§r енергетичний конвертер", - "block.gtceu.zpm_battery_buffer_16x": "§cZPM-напружений§r 16x акумуляторний буфер", - "block.gtceu.zpm_battery_buffer_8x": "§cZPM-напружений§r 8x акумуляторний буфер", - "block.gtceu.zpm_battery_buffer_4x": "§cZPM-напружений§r 4x акумуляторний буфер", - "block.gtceu.uxv_battery_buffer_16x": "§eНадмірно екстремально напружений§r 16x акумуляторний буфер", - "block.gtceu.uxv_battery_buffer_8x": "§eНадмірно екстремально напружений§r 8x акумуляторний буфер", - "block.gtceu.uxv_battery_buffer_4x": "§eНадмірно екстремально напружений§r 4x акумуляторний буфер", - "block.gtceu.uv_battery_buffer_16x": "§3Ультимативно напружений§r 16x акумуляторний буфер", - "block.gtceu.uv_battery_buffer_8x": "§3Ультимативно напружений§r 8x акумуляторний буфер", - "block.gtceu.uv_battery_buffer_4x": "§3Ультимативно напружений§r 4x акумуляторний буфер", - "block.gtceu.ulv_battery_buffer_16x": "§8Надмірно низько напружений§r 16x акумуляторний буфер", - "block.gtceu.ulv_battery_buffer_8x": "§8Надмірно низько напружений§r 8x акумуляторний буфер", - "block.gtceu.ulv_battery_buffer_4x": "§8Надмірно низько напружений§r 4x акумуляторний буфер", - "block.gtceu.uiv_battery_buffer_16x": "§2Надмірно неосяжно напружений§r 16x акумуляторний буфер", - "block.gtceu.uiv_battery_buffer_8x": "§2Надмірно неосяжно напружений§r 8x акумуляторний буфер", - "block.gtceu.uiv_battery_buffer_4x": "§2Надмірно неосяжно напружений§r 4x акумуляторний буфер", - "block.gtceu.uhv_battery_buffer_16x": "§4Надмірно високо напружений§r 16x акумуляторний буфер", - "block.gtceu.uhv_battery_buffer_8x": "§4Надмірно високо напружений§r 8x акумуляторний буфер", - "block.gtceu.uhv_battery_buffer_4x": "§4Надмірно високо напружений§r 4x акумуляторний буфер", - "block.gtceu.uev_battery_buffer_16x": "§aНадмірно екстремально напружений§r 16x акумуляторний буфер", - "block.gtceu.uev_battery_buffer_8x": "§aНадмірно екстремально напружений§r 8x акумуляторний буфер", - "block.gtceu.uev_battery_buffer_4x": "§aНадмірно екстремально напружений§r 4x акумуляторний буфер", - "block.gtceu.opv_battery_buffer_16x": "§9§lБезмірно напружений§r 16x акумуляторний буфер", - "block.gtceu.opv_battery_buffer_8x": "§9§lБезмірно напружений§r 8x акумуляторний буфер", - "block.gtceu.opv_battery_buffer_4x": "§9§lБезмірно напружений§r 4x акумуляторний буфер", - "block.gtceu.mv_battery_buffer_16x": "§bСередньо напружений§r 16x акумуляторний буфер", - "block.gtceu.mv_battery_buffer_8x": "§bСередньо напружений§r 8x акумуляторний буфер", - "block.gtceu.mv_battery_buffer_4x": "§bСередньо напружений§r 4x акумуляторний буфер", - "block.gtceu.max_battery_buffer_16x": "§c§lМаксимально напружений§r 16x акумуляторний буфер", - "block.gtceu.max_battery_buffer_8x": "§c§lМаксимально напружений§r 8x акумуляторний буфер", - "block.gtceu.max_battery_buffer_4x": "§c§lМаксимально напружений§r 4x акумуляторний буфер", - "block.gtceu.lv_battery_buffer_16x": "§7Низько напружений§r 16x акумуляторний буфер", - "block.gtceu.lv_battery_buffer_8x": "§7Низько напружений§r 8x акумуляторний буфер", - "block.gtceu.lv_battery_buffer_4x": "§7Низько напружений§r 4x акумуляторний буфер", - "block.gtceu.luv_battery_buffer_16x": "§dСміхотворно напружений§r 16x акумуляторний буфер", - "block.gtceu.luv_battery_buffer_8x": "§dСміхотворно напружений§r 8x акумуляторний буфер", - "block.gtceu.luv_battery_buffer_4x": "§dСміхотворно напружений§r 4x акумуляторний буфер", - "block.gtceu.iv_battery_buffer_16x": "§9Божевільно напружений§r 16x акумуляторний буфер", - "block.gtceu.iv_battery_buffer_8x": "§9Божевільно напружений§r 8x акумуляторний буфер", - "block.gtceu.iv_battery_buffer_4x": "§9Божевільно напружений§r 4x акумуляторний буфер", - "block.gtceu.hv_battery_buffer_16x": "§6Високо напружений§r 16x акумуляторний буфер", - "block.gtceu.hv_battery_buffer_8x": "§6Високо напружений§r 8x акумуляторний буфер", - "block.gtceu.hv_battery_buffer_4x": "§6Високо напружений§r 4x акумуляторний буфер", - "block.gtceu.ev_battery_buffer_16x": "§5Екстремально напружений§r 16x акумуляторний буфер", - "block.gtceu.ev_battery_buffer_8x": "§5Екстремально напружений§r 8x акумуляторний буфер", - "block.gtceu.ev_battery_buffer_4x": "§5Екстремально напружений§r 4x акумуляторний буфер", - "block.gtceu.zpm_charger_4x": "§cZPM-напружений§r 4x турбозарядник", - "block.gtceu.uxv_charger_4x": "§eНадмірно екстремально напружений§r 4x турбозарядник", - "block.gtceu.uv_charger_4x": "§3Ультимативно напружений§r 4x турбозарядник", - "block.gtceu.ulv_charger_4x": "§8Надмірно низько напружений§r 4x турбозарядник", - "block.gtceu.uiv_charger_4x": "§2Надмірно неосяжно напружений§r 4x турбозарядник", - "block.gtceu.uhv_charger_4x": "§4Надмірно високо напружений§r 4x турбозарядник", - "block.gtceu.uev_charger_4x": "§aНадмірно екстремально напружений§r 4x турбозарядник", - "block.gtceu.opv_charger_4x": "§9§lБезмірно напружений§r 4x турбозарядник", - "block.gtceu.mv_charger_4x": "§bСередньо напружений§r 4x турбозарядник", - "block.gtceu.max_charger_4x": "§c§lМаксимально напружений§r 4x турбозарядник", - "block.gtceu.lv_charger_4x": "§7Низько напружений§r 4x турбозарядник", - "block.gtceu.luv_charger_4x": "§dСміхотворно напружений§r 4x турбозарядник", - "block.gtceu.iv_charger_4x": "§9Божевільно напружений§r 4x турбозарядник", - "block.gtceu.hv_charger_4x": "§6Високо напружений§r 4x турбозарядник", - "block.gtceu.ev_charger_4x": "§5Екстремально напружений§r 4x турбозарядник", - "block.gtceu.zpm_transformer_16a": "§cZPM-напружений§r силовий трансформатор", - "block.gtceu.zpm_transformer_4a": "§cZPM-напружений§r трансформатор високого струму (4x)", - "block.gtceu.zpm_transformer_2a": "§cZPM-напружений§r трансформатор високого струму (2x)", - "block.gtceu.zpm_transformer_1a": "§cZPM-напружений§r трансформатор", - "block.gtceu.uxv_transformer_16a": "§eНадмірно екстремально напружений§r силовий трансформатор", - "block.gtceu.uxv_transformer_4a": "§eНадмірно екстремально напружений§r трансформатор високого струму (4x)", - "block.gtceu.uxv_transformer_2a": "§eНадмірно екстремально напружений§r трансформатор високого струму (2x)", - "block.gtceu.uxv_transformer_1a": "§eНадмірно екстремально напружений§r трансформатор", - "block.gtceu.uv_transformer_16a": "§3Ультимативно напружений§r силовий трансформатор", - "block.gtceu.uv_transformer_4a": "§3Ультимативно напружений§r трансформатор високого струму (4x)", - "block.gtceu.uv_transformer_2a": "§3Ультимативно напружений§r трансформатор високого струму (2x)", - "block.gtceu.uv_transformer_1a": "§3Ультимативно напружений§r трансформатор", - "block.gtceu.ulv_transformer_16a": "§8Надмірно низько напружений§r силовий трансформатор", - "block.gtceu.ulv_transformer_4a": "§8Надмірно низько напружений§r трансформатор високого струму (4x)", - "block.gtceu.ulv_transformer_2a": "§8Надмірно низько напружений§r трансформатор високого струму (2x)", - "block.gtceu.ulv_transformer_1a": "§8Надмірно низько напружений§r трансформатор", - "block.gtceu.uiv_transformer_16a": "§2Надмірно неосяжно напружений§r силовий трансформатор", - "block.gtceu.uiv_transformer_4a": "§2Надмірно неосяжно напружений§r трансформатор високого струму (4x)", - "block.gtceu.uiv_transformer_2a": "§2Надмірно неосяжно напружений§r трансформатор високого струму (2x)", - "block.gtceu.uiv_transformer_1a": "§2Надмірно неосяжно напружений§r трансформатор", - "block.gtceu.uhv_transformer_16a": "§4Надмірно високо напружений§r силовий трансформатор", - "block.gtceu.uhv_transformer_4a": "§4Надмірно високо напружений§r трансформатор високого струму (4x)", - "block.gtceu.uhv_transformer_2a": "§4Надмірно високо напружений§r трансформатор високого струму (2x)", - "block.gtceu.uhv_transformer_1a": "§4Надмірно високо напружений§r трансформатор", - "block.gtceu.uev_transformer_16a": "§aНадмірно екстремально напружений§r силовий трансформатор", - "block.gtceu.uev_transformer_4a": "§aНадмірно екстремально напружений§r трансформатор високого струму (4x)", - "block.gtceu.uev_transformer_2a": "§aНадмірно екстремально напружений§r трансформатор високого струму (2x)", - "block.gtceu.uev_transformer_1a": "§aНадмірно екстремально напружений§r трансформатор", - "block.gtceu.opv_transformer_16a": "§9§lБезмірно напружений§r силовий трансформатор", - "block.gtceu.opv_transformer_4a": "§9§lБезмірно напружений§r трансформатор високого струму (4x)", - "block.gtceu.opv_transformer_2a": "§9§lБезмірно напружений§r трансформатор високого струму (2x)", - "block.gtceu.opv_transformer_1a": "§9§lБезмірно напружений§r трансформатор", - "block.gtceu.mv_transformer_16a": "§bСередньо напружений§r силовий трансформатор", - "block.gtceu.mv_transformer_4a": "§bСередньо напружений§r трансформатор високого струму (4x)", - "block.gtceu.mv_transformer_2a": "§bСередньо напружений§r трансформатор високого струму (2x)", - "block.gtceu.mv_transformer_1a": "§bСередньо напружений§r трансформатор", - "block.gtceu.lv_transformer_16a": "§7Низько напружений§r силовий трансформатор", - "block.gtceu.lv_transformer_4a": "§7Низько напружений§r трансформатор високого струму (4x)", - "block.gtceu.lv_transformer_2a": "§7Низько напружений§r трансформатор високого струму (2x)", - "block.gtceu.lv_transformer_1a": "§7Низько напружений§r трансформатор", - "block.gtceu.luv_transformer_16a": "§dСміхотворно напружений§r силовий трансформатор", - "block.gtceu.luv_transformer_4a": "§dСміхотворно напружений§r трансформатор високого струму (4x)", - "block.gtceu.luv_transformer_2a": "§dСміхотворно напружений§r трансформатор високого струму (2x)", - "block.gtceu.luv_transformer_1a": "§dСміхотворно напружений§r трансформатор", - "block.gtceu.iv_transformer_16a": "§9Божевільно напружений§r силовий трансформатор", - "block.gtceu.iv_transformer_4a": "§9Божевільно напружений§r трансформатор високого струму (4x)", - "block.gtceu.iv_transformer_2a": "§9Божевільно напружений§r трансформатор високого струму (2x)", - "block.gtceu.iv_transformer_1a": "§9Божевільно напружений§r трансформатор", - "block.gtceu.hv_transformer_16a": "§6Високо напружений§r силовий трансформатор", - "block.gtceu.hv_transformer_4a": "§6Високо напружений§r трансформатор високого струму (4x)", - "block.gtceu.hv_transformer_2a": "§6Високо напружений§r трансформатор високого струму (2x)", - "block.gtceu.hv_transformer_1a": "§6Високо напружений§r трансформатор", - "block.gtceu.ev_transformer_16a": "§5Екстремально напружений§r силовий трансформатор", - "block.gtceu.ev_transformer_4a": "§5Екстремально напружений§r трансформатор високого струму (4x)", - "block.gtceu.ev_transformer_2a": "§5Екстремально напружений§r трансформатор високого струму (2x)", - "block.gtceu.ev_transformer_1a": "§5Екстремально напружений§r трансформатор", - "block.gtceu.active_transformer": "Активний трансформатор", - "block.gtceu.uv_world_accelerator": "§3Ультимативний світовий прискорювач§r ", - "block.gtceu.ev_world_accelerator": "§5Просунутий світовий прискорювач III§r", - "block.gtceu.hv_world_accelerator": "§6Просунутий світовий прискорювач II§r", - "block.gtceu.iv_world_accelerator": "§9Елітний світовий прискорювач§r ", - "block.gtceu.mv_world_accelerator": "§bПросунутий світовий прискорювач§r ", - "block.gtceu.zpm_world_accelerator": "§cЕлітний світовий прискорювач III§r", - "block.gtceu.luv_world_accelerator": "§dЕлітний світовий прискорювач II§r", - "block.gtceu.lv_world_accelerator": "Базовий світовий прискорювач§r ", - "block.gtceu.large_circuit_assembler": "Великий схемотехнічний складальний комплекс", - "item.gtceu.advanced_integrated_circuit": "Просунута інтегральна схема", - "item.gtceu.basic_integrated_circuit": "Базова інтегральна схема", - "item.gtceu.good_integrated_circuit": "Хороша інтегральна схема", - "item.gtceu.ilc_wafer.tooltip": "§7Сира інтегральна схема", - "item.gtceu.advanced_integrated_circuit.tooltip.1": "§6Схема HV рівня", - "item.gtceu.basic_electronic_circuit.tooltip.1": "§cСхема LV рівня", - "item.gtceu.basic_integrated_circuit.tooltip.1": "§6Схема LV рівня", - "item.gtceu.crystal_processor.tooltip.1": "§9Схема IV рівня", - "item.gtceu.crystal_processor_assembly.tooltip.1": "§9Схема LuV рівня", - "item.gtceu.crystal_processor_computer.tooltip.1": "§9Схема ZPM рівня", - "item.gtceu.crystal_processor_mainframe.tooltip.1": "§9Схема UV рівня", - "item.gtceu.good_electronic_circuit.tooltip.1": "§cСхема MV рівня", - "item.gtceu.good_integrated_circuit.tooltip.1": "§6Схема MV рівня", - "item.gtceu.micro_processor.tooltip.1": "§eСхема MV рівня", - "item.gtceu.micro_processor_assembly.tooltip.1": "§eСхема HV рівня", - "item.gtceu.micro_processor_computer.tooltip.1": "§eСхема EV рівня", - "item.gtceu.micro_processor_mainframe.tooltip.1": "§eСхема IV рівня", - "item.gtceu.microchip_processor.tooltip.1": "§eСхема LV рівня", - "item.gtceu.nand_chip.tooltip.1": "§6Електросхема ULV-рівня", - "item.gtceu.nano_processor.tooltip.1": "§bСхема HV рівня", - "item.gtceu.nano_processor_assembly.tooltip.1": "§bСхема EV рівня", - "item.gtceu.nano_processor_computer.tooltip.1": "§bСхема IV рівня", - "item.gtceu.nano_processor_mainframe.tooltip.1": "§bСхема LuV рівня", - "item.gtceu.quantum_processor.tooltip.1": "§aСхема EV рівня", - "item.gtceu.quantum_processor_assembly.tooltip.1": "§aСхема IV рівня", - "item.gtceu.quantum_processor_computer.tooltip.1": "§aСхема LuV рівня", - "item.gtceu.quantum_processor_mainframe.tooltip.1": "§aСхема ZPM рівня", - "item.gtceu.wetware_processor.tooltip.1": "§4Схема LuV рівня", - "item.gtceu.wetware_processor_assembly.tooltip.1": "§4Схема ZPM рівня", - "item.gtceu.wetware_processor_computer.tooltip.1": "§4Схема UV рівня", - "item.gtceu.wetware_processor_mainframe.tooltip.1": "§4Схема UHV рівня", - "item.gtceu.basic_electronic_circuit": "Базова електросхема", - "item.gtceu.good_electronic_circuit": "Хороша електросхема", - "item.gtceu.basic_electronic_circuit.tooltip.0": "§7Ваша перша схема", - "item.gtceu.good_electronic_circuit.tooltip.0": "§7Ваша друга схема", - "item.gtceu.circuit.integrated.gui": "§7Конфігурація програмної плати", - "item.gtceu.fiber_reinforced_printed_circuit_board": "Армована волокном друкована плата", - "item.gtceu.multilayer_fiber_reinforced_printed_circuit_board": "Багатошарова армована волокном друкована плата", - "item.gtceu.fiber_reinforced_circuit_board": "Армована волокном плата", - "item.gtceu.multilayer_fiber_reinforced_circuit_board": "Багатошарова армована волокном плата", - "item.gtceu.epoxy_circuit_board": "Епоксидна плата", - "item.gtceu.epoxy_printed_circuit_board": "Епоксидна друкована плата", - "item.gtceu.phenolic_printed_circuit_board": "Фенольна друкована плата", - "item.gtceu.phenolic_circuit_board": "Фенольна плата", - "item.gtceu.plastic_printed_circuit_board": "Пластикова друкована плата", - "item.gtceu.plastic_circuit_board": "Пластикова плата", - "item.gtceu.resin_printed_circuit_board": "Резинова друкована плата", - "item.gtceu.resin_circuit_board": "Резинова плата", - "item.gtceu.wetware_printed_circuit_board": "Животехічна друкована плата", - "item.gtceu.wetware_circuit_board": "Животехічна плата", - "item.gtceu.epoxy_printed_circuit_board.tooltip": "§7Просунута плата", - "item.gtceu.fiber_reinforced_printed_circuit_board.tooltip": "§7Просунутіша плата", - "item.gtceu.multilayer_fiber_reinforced_printed_circuit_board.tooltip": "§7Елітна плата", - "item.gtceu.phenolic_printed_circuit_board.tooltip": "§7Хороша плата", - "item.gtceu.plastic_printed_circuit_board.tooltip": "§7Хороша плата", - "item.gtceu.resin_printed_circuit_board.tooltip": "§7Базова плата", - "item.gtceu.microchip_processor.tooltip.0": "§7Відмінна базова схема", - "item.gtceu.hpic_wafer.tooltip": "§7Сира високопотужна схема", - "item.gtceu.lpic_wafer.tooltip": "§7Сира низькопотужна схема", - "item.gtceu.uhpic_wafer.tooltip": "§7Сира надвисокопотужна схема", - "item.gtceu.ulpic_wafer.tooltip": "§7Сира наднизькопотужна схема", - "item.gtceu.mpic_wafer.tooltip": "§7Сира потужна схема", - "item.gtceu.nano_cpu_wafer.tooltip": "§7Сира нанотехнічна схема", - "item.gtceu.qbit_cpu_wafer.tooltip": "§7Сира кубітна схема", - "item.gtceu.naquadah_boule.tooltip": "§7Сира схема", - "item.gtceu.naquadah_wafer.tooltip": "§7Сира схема", - "item.gtceu.neutronium_boule.tooltip": "§7Сира схема", - "item.gtceu.neutronium_wafer.tooltip": "§7Сира схема", - "item.gtceu.phosphorus_boule.tooltip": "§7Сира схема", - "item.gtceu.phosphorus_wafer.tooltip": "§7Сира схема", - "item.gtceu.silicon_boule.tooltip": "§7Сира схема", - "item.gtceu.silicon_wafer.tooltip": "§7Сира схема", - "block.gtceu.ev_air_scrubber": "§5Просунутий очисник повітря III§r", - "block.gtceu.hv_air_scrubber": "§6Просунутий очисник повітря II§r", - "block.gtceu.mv_air_scrubber": "§bПросунутий очисник повітря§r ", - "gtceu.air_scrubber": "Очисник повітря", - "block.gtceu.lv_air_scrubber": "Базовий очисник повітря§r ", - "block.gtceu.ev_bedrock_ore_miner": "§5Просунутий гірник бедрокової руди III§r", - "block.gtceu.hv_bedrock_ore_miner": "§6Просунутий гірник бедрокової руди II§r", - "block.gtceu.mv_bedrock_ore_miner": "§bПросунутий гірник бедрокової руди§r ", - "block.gtceu.ev_large_miner": "§5Просунутий великий гірник III§r", - "block.gtceu.iv_large_miner": "§9Елітний великий гірник§r ", - "block.gtceu.luv_large_miner": "§dЕлітний великий гірник II§r", - "block.gtceu.hv_miner": "§6Просунутий гірник II§r", - "block.gtceu.mv_miner": "§bПросунутий гірник§r ", - "block.gtceu.lv_miner": "Базовий гірник§r ", - "block.gtceu.hp_steam_miner": "Паровий гірник під високим тиском", - "block.gtceu.lp_steam_miner": "Паровий гірник під низьким тиском", - "block.gtceu.miner_pipe": "Гірнична труба", - "block.gtceu.ev_block_breaker": "§5Просунутий руйнівник блоків III§r", - "block.gtceu.hv_block_breaker": "§6Просунутий руйнівник блоків II§r", - "block.gtceu.mv_block_breaker": "§bПросунутий руйнівник блоків§r ", - "block.gtceu.lv_block_breaker": "Базовий руйнівник блоків§r ", - "block.gtceu.ev_fluid_drilling_rig": "§5Просунута рідинна бурова установка III§r", - "block.gtceu.hv_fluid_drilling_rig": "§6Просунута рідинна бурова установка II§r", - "block.gtceu.mv_fluid_drilling_rig": "§bПросунута рідинна бурова установка§r ", - "block.gtceu.ev_fisher": "§5Просунутий рибалка III§r", - "block.gtceu.hv_fisher": "§6Просунутий рибалка II§r", - "block.gtceu.iv_fisher": "§9Елітний рибалка§r ", - "block.gtceu.mv_fisher": "§bПросунутий рибалка§r ", - "block.gtceu.luv_fisher": "§dЕлітний рибалка II§r", - "block.gtceu.lv_fisher": "Базовий рибалка§r ", - "block.gtceu.ev_item_collector": "§5Просунутий предметний збирач III§r", - "block.gtceu.hv_item_collector": "§6Просунутий предметний збирач II§r", - "block.gtceu.mv_item_collector": "§bПросунутий предметний збирач§r ", - "block.gtceu.lv_item_collector": "Базовий предметний збирач§r ", - "block.gtceu.primitive_pump": "Примітивна помпа", - "block.gtceu.ev_pump": "§5Просунута помпа III§r", - "block.gtceu.hv_pump": "§6Просунута помпа II§r", - "block.gtceu.mv_pump": "§bПросунута помпа§r ", - "block.gtceu.lv_pump": "Базова помпа§r ", - "item.gtceu.ev_electric_pump": "EV електрична помпа", - "item.gtceu.hv_electric_pump": "HV електрична помпа", - "item.gtceu.iv_electric_pump": "IV електрична помпа", - "item.gtceu.luv_electric_pump": "LuV електрична помпа", - "item.gtceu.lv_electric_pump": "LV електрична помпа", - "item.gtceu.mv_electric_pump": "MV електрична помпа", - "item.gtceu.opv_electric_pump": "OpV електрична помпа", - "item.gtceu.uev_electric_pump": "UEV електрична помпа", - "item.gtceu.uhv_electric_pump": "UHV електрична помпа", - "item.gtceu.uiv_electric_pump": "UIV електрична помпа", - "item.gtceu.uv_electric_pump": "UV електрична помпа", - "item.gtceu.uxv_electric_pump": "UXV електрична помпа", - "item.gtceu.zpm_electric_pump": "ZPM електрична помпа", - "item.gtceu.copper_credit": "Мідна монета", - "item.gtceu.copper_credit.tooltip": "§70.125 монети", - "item.gtceu.cupronickel_credit": "Мельхіорова монета", - "item.gtceu.cupronickel_credit.tooltip": "§71 монета", - "item.gtceu.gold_credit": "Золота монета", - "item.gtceu.gold_credit.tooltip": "§764 монети", - "item.gtceu.naquadah_credit": "Наквуадова монета", - "item.gtceu.naquadah_credit.tooltip": "§732768 монет", - "item.gtceu.neutronium_credit": "Нейтронієва монета", - "item.gtceu.neutronium_credit.tooltip": "§7262144 монети", - "item.gtceu.osmium_credit": "Осмієва монета", - "item.gtceu.osmium_credit.tooltip": "§74096 монет", - "item.gtceu.platinum_credit": "Платинова монета", - "item.gtceu.platinum_credit.tooltip": "§7512 монети", - "item.gtceu.silver_credit": "Срібна монета", - "item.gtceu.silver_credit.tooltip": "§78 монет", - "item.gtceu.ancient_gold_coin": "Стародавня золота монета", - "item.gtceu.ancient_gold_coin.tooltip": "§7Можна знайти в стародавніх руїнах", - "item.gtceu.chocolate_coin": "Шоколадна монета", - "item.gtceu.chocolate_coin.tooltip": "§7Загорнута у золото", - "item.gtceu.doge_coin": "Доге коін", - "item.gtceu.doge_coin.tooltip": "§7тиба кіко монет які багаті гроші такі крипто буласька мені дуже коштовні ого", - "item.gtceu.empty_mold.tooltip": "§7Сира плита для виготовлення прес-форм та формових відтисків", - "item.gtceu.empty_mold": "Порожня форма", - "recipe_category.gtceu.ingot_molding": "Лиття металів", - "item.gtceu.resin_circuit_board.tooltip": "§7Покрита плата", - "item.gtceu.phenolic_circuit_board.tooltip": "§7Хороша плата", - "item.gtceu.plastic_circuit_board.tooltip": "§7Хороша плата", - "item.gtceu.epoxy_circuit_board.tooltip": "§7Просунута плата", - "item.gtceu.multilayer_fiber_reinforced_circuit_board.tooltip": "§7Елітна плата", - "item.gtceu.fiber_reinforced_circuit_board.tooltip": "§7Екстремальна плата", - "item.gtceu.wetware_circuit_board.tooltip": "§7Плата, що містить життя", - "item.gtceu.wetware_printed_circuit_board.tooltip": "§7Плата, що містить життя", - "item.gtceu.data_orb.tooltip": "§7Сховище даних великої місткості", - "item.gtceu.data_stick.tooltip": "§7Сховище даних малої місткості", - - "block.gtceu.advanced_data_access_hatch": "Просунутий люк доступу до даних", - "block.gtceu.data_access_hatch": "Люк доступу до даних", - "block.gtceu.alloy_blast_smelter": "Плавильник сплавів", - "block.gtceu.aluminium_crate": "Алюмінієвий ящик", - "block.gtceu.bronze_crate": "Бронзовий ящик", - "block.gtceu.stainless_steel_crate": "Нержавіючий сталевий ящик", - "block.gtceu.steel_crate": "Сталевий ящик", - "block.gtceu.titanium_crate": "Титановий ящик", - "block.gtceu.tungsten_steel_crate": "Вольфрамовий ящик", - "block.gtceu.wood_crate": "Дерев'яний ящик", - "block.gtceu.aluminium_drum": "Алюмінієва діжка", - "block.gtceu.bronze_drum": "Бронзова діжка", - "block.gtceu.gold_drum": "Золота діжка", - "block.gtceu.stainless_steel_drum": "Нержавіюча сталева діжка", - "block.gtceu.steel_drum": "Сталева діжка", - "block.gtceu.titanium_drum": "Титанова діжка", - "block.gtceu.tungsten_steel_drum": "Вольфрамова діжка", - "block.gtceu.assembly_line": "Конвеєрна лінія", - "block.gtceu.bronze_large_boiler": "Великий бронзовий котел", - "block.gtceu.hp_steam_liquid_boiler": "Паровий рідинний котел під високим тиском", - "block.gtceu.hp_steam_solar_boiler": "Паровий сонячний котел під високим тиском", - "block.gtceu.hp_steam_solid_boiler": "Паровий твердопаливний котел під високим тиском", - "block.gtceu.lp_steam_liquid_boiler": "Паровий рідинний котел під низьким тиском", - "block.gtceu.lp_steam_solar_boiler": "Паровий сонячний котел під низьким тиском", - "block.gtceu.lp_steam_solid_boiler": "Паровий твердопаливний котел під низьким тиском", - "block.gtceu.steam_liquid_boiler.bronze": "Малий паровий рідинний котел", - "block.gtceu.steam_solid_boiler.bronze": "Малий паровий твердопаливний котел", - "block.gtceu.steel_large_boiler": "Великий сталевий котел", - "block.gtceu.titanium_large_boiler": "Великий титановий котел", - "block.gtceu.tungstensteel_large_boiler": "Великий вольфрамовий котел", - "block.gtceu.charcoal_pile_igniter": "Запалювач вугільної купи", - "block.gtceu.cleanroom": "Чиста кімната", - "block.gtceu.coke_oven": "Коксова піч", - "block.gtceu.cracker": "Крекер", - "block.gtceu.data_bank": "База даних", - "block.gtceu.distillation_tower": "Дистиляційна вежа", - "block.gtceu.electric_blast_furnace": "Електроплавильня", - "block.gtceu.hp_steam_furnace": "Паровий піч під високим тиском", - "block.gtceu.lp_steam_furnace": "Паровий піч під низьким тиском", - "block.gtceu.mega_blast_furnace": "Ротаційна мартенівська піч", - "block.gtceu.primitive_blast_furnace": "Примітивна сталеварня", - "block.gtceu.ev_super_chest": "Суперскриня IV", - "block.gtceu.hv_super_chest": "Суперскриня III", - "block.gtceu.lv_super_chest": "Суперскриня I", - "block.gtceu.mv_super_chest": "Суперскриня II", - "block.gtceu.iv_quantum_chest": "Квантова скриня V", - "block.gtceu.luv_quantum_chest": "Квантова скриня VI", - "block.gtceu.opv_quantum_chest": "Квантова скриня XIII", - "block.gtceu.uev_quantum_chest": "Квантова скриня X", - "block.gtceu.uhv_quantum_chest": "Квантова скриня IX", - "block.gtceu.uiv_quantum_chest": "Квантова скриня XI", - "block.gtceu.uv_quantum_chest": "Квантова скриня VIII", - "block.gtceu.uxv_quantum_chest": "Квантова скриня XII", - "block.gtceu.zpm_quantum_chest": "Квантова скриня VII", - "block.gtceu.ev_super_tank": "Суперрезервуар IV", - "block.gtceu.hv_super_tank": "Суперрезервуар III", - "block.gtceu.lv_super_tank": "Суперрезервуар I", - "block.gtceu.mv_super_tank": "Суперрезервуар II", - "block.gtceu.iv_quantum_tank": "Квантовий резервуар V", - "block.gtceu.luv_quantum_tank": "Квантовий резервуар VI", - "block.gtceu.opv_quantum_tank": "Квантовий резервуар XIII", - "block.gtceu.uev_quantum_tank": "Квантовий резервуар X", - "block.gtceu.uhv_quantum_tank": "Квантовий резервуар IX", - "block.gtceu.uiv_quantum_tank": "Квантовий резервуар XI", - "block.gtceu.uv_quantum_tank": "Квантовий резервуар VIII", - "block.gtceu.uxv_quantum_tank": "Квантовий резервуар XII", - "block.gtceu.zpm_quantum_tank": "Квантовий резервуар VII", - "block.gtceu.steel_multiblock_tank": "Сталевий багатоблочний резервуар", - "block.gtceu.steel_tank_valve": "Сталевий вентиль резервуара", - "block.gtceu.wooden_multiblock_tank": "Дерев'яний багатоблочний резервуар", - "block.gtceu.wooden_tank_valve": "Дерев'яний вентиль резервуара", - "block.gtceu.evaporation_plant": "Випарна вежа", - "block.gtceu.explosive.breaking_tooltip": "Вибухає від зламу, ламайте крадькома, щоб добути", - "block.gtceu.explosive.lighting_tooltip": "Не можна запалити редстоуном", - "block.gtceu.extreme_combustion_engine": "Екстремальний двигун внутрішнього згоряння", - "block.gtceu.high_performance_computation_array": "Високопродуктивний обчислювальний масив (ВОМ)", - "block.gtceu.hpca_active_cooler_component": "ВОМ-активний охолоджувальний компонент", - "block.gtceu.hpca_advanced_computation_component": "ВОМ-просунутий обчислювальний компонент", - "block.gtceu.hpca_bridge_component": "ВОМ-мостовий компонент", - "block.gtceu.hpca_computation_component": "ВОМ-обчислювальний компонент", - "block.gtceu.hpca_empty_component": "Порожній ВОМ компонент", - "block.gtceu.hpca_heat_sink_component": "ВОМ-радіаторний компонент", - "block.gtceu.hv_buffer": "§6Просунутий буфер II§r", - "block.gtceu.lv_buffer": "Базовий буфер§r ", - "block.gtceu.me_pattern_buffer": "ME-шаблонний буфер", - "block.gtceu.me_pattern_buffer_proxy": "Проксі ME-шаблонного буфера", - "block.gtceu.mv_buffer": "§bПросунутий буфер§r ", - "block.gtceu.pattern_buffer.desc.0": "§fДозволяє безпосередньо§6 зберігати шаблони AE2§f для конструкцій GregTech.", - "block.gtceu.pattern_buffer.desc.1": "§fШаблони AE2 можуть використовувати все, що зберігається у віджеті§6 спільного інвентарю§f.", - "block.gtceu.pattern_buffer.desc.2": "§fЗ'єднайте§6 проксі шаблонних буферів§f з§b карткою даних§f, щоб зв'язати машини між собою!", - "block.gtceu.pattern_buffer_proxy.desc.0": "§fДозволяє зв'язати багато машин з єдиним§6 ME-шаблонним буфером§f.", - "block.gtceu.pattern_buffer_proxy.desc.1": "§fВсі підключені проксі будуть використовувати шаблони, що містяться в§6 оригінальному буфері§f.", - "block.gtceu.pattern_buffer_proxy.desc.2": "§fНехай фабрика росте!", - "block.gtceu.hv_combustion": "§6Просунутий генератор внутрішнього згоряння II§r", - "block.gtceu.lv_combustion": "Базовий генератор внутрішнього згоряння§r ", - "block.gtceu.mv_combustion": "§bПросунутий генератор внутрішнього згоряння§r ", - "block.gtceu.hv_gas_turbine": "§6Просунутий газотурбінний генератор II§r", - "block.gtceu.lv_gas_turbine": "Базовий газотурбінний генератор§r ", - "block.gtceu.mv_gas_turbine": "§bПросунутий газотурбінний генератор§r ", - "block.gtceu.hv_steam_turbine": "§6Просунутий паротурбінний генератор II§r", - "block.gtceu.lv_steam_turbine": "Базовий паротурбінний генератор§r ", - "block.gtceu.mv_steam_turbine": "§bПросунутий паротурбінний генератор§r ", - "block.gtceu.itnt.drops_tooltip": "Добуває усі знищені блоки так само, як динаміт, але з набагато більшим радіусом", - "block.gtceu.powderbarrel.drops_tooltip": "Добуває усі знищені блоки так само, як динаміт, але з трохи більшим радіусом", - "block.gtceu.gas_large_turbine": "Велика газова турбіна", - "block.gtceu.large_arc_smelter": "Велика дугова плавильна піч", - "block.gtceu.large_assembler": "Велика складальна фабрика", - "block.gtceu.large_autoclave": "Велика кристалізаційна камера", - "block.gtceu.large_brewer": "Великий варильний чан", - "block.gtceu.large_centrifuge": "Велика відцентрова установка", - "block.gtceu.large_combustion_engine": "Великий двигун внутрішнього згоряння", - "block.gtceu.large_cutter": "Велика відрізна пила", - "block.gtceu.large_electrolyzer": "Велика електролізна камера", - "block.gtceu.large_electromagnet": "Великий електромагніт", - "block.gtceu.large_engraving_laser": "Великий літограф", - "block.gtceu.large_extractor": "Велика екстракційна машина", - "block.gtceu.large_extruder": "Велика екструзійна машина", - "block.gtceu.large_maceration_tower": "Велика подрібнювальна вежа", - "block.gtceu.large_material_press": "Великий матеріальний прес", - "block.gtceu.large_mixer": "Великий змішувальний бак", - "block.gtceu.large_packer": "Велика пакувальна машина", - "block.gtceu.large_sifting_funnel": "Велика просіювальна лійка", - "block.gtceu.large_solidifier": "Великий масив затвердіння", - "block.gtceu.large_wiremill": "Велика дротова фабрика", - "block.gtceu.long_distance_item_pipeline_input_endpoint": "Вхід кінцевої точки", - "block.gtceu.long_distance_item_pipeline_network_header": "Мережа:", - "block.gtceu.long_distance_item_pipeline_no_network": "Мережу не знайдено", - "block.gtceu.long_distance_item_pipeline_output_endpoint": "Вихід кінцевої точки", - "block.gtceu.luv_fusion_reactor": "Комп'ютер термоядерного реактора MK I", - "block.gtceu.uv_fusion_reactor": "Комп'ютер термоядерного реактора MK III", - "block.gtceu.zpm_fusion_reactor": "Комп'ютер термоядерного реактора MK II", - "block.gtceu.mega_vacuum_freezer": "Масовий шоковий охолоджувач", - "block.gtceu.multi_smelter": "Мультиплавильня", - "block.gtceu.network_switch": "Мережевий комутатор", - "block.gtceu.normal_laser_pipe.tooltip": "§7Транспортує енергію§f без витрат§7 на прямих лініях", - "block.gtceu.normal_optical_pipe.tooltip": "§7Транспортує§f обчислення§7 або§f дослідницькі дані§7", - "block.gtceu.object_holder": "Тримач об'єктів", - "block.gtceu.oil_heavy": "Важка нафта", - "block.gtceu.oil_light": "Легка нафта", - "block.gtceu.oil_medium": "Сира нафта", - "block.gtceu.plasma_large_turbine": "Велика плазмова турбіна", - "block.gtceu.steam_large_turbine": "Велика парова турбіна", - "block.gtceu.power_substation": "Електропідстанція", - "block.gtceu.pyrolyse_oven": "Піролізна піч", - "block.gtceu.reinforced_stone": "Зміцнений камінь", - "block.gtceu.research_station": "Дослідницька станція", - "block.gtceu.steam_casing_bricked_bronze.tooltip": "§7Для ваших перших парових машин", - "block.gtceu.steam_casing_bricked_steel.tooltip": "§7Для покращених парових машин", - "block.gtceu.steam_casing_bronze": "Бронзовий корпус", - "block.gtceu.steam_casing_steel": "Сталевий корпус", - "block.gtceu.steam_casing_bronze.tooltip": "§7Для ваших перших парових машин", - "block.gtceu.steam_casing_steel.tooltip": "§7Для покращених парових машин", - "block.gtceu.steam_grinder": "Парова дробарка", - "block.gtceu.steam_oven": "Парова піч", - "block.gtceu.substation_capacitor.tooltip_empty": "§7Для заповнення простору на вашій електропідстанції", - "block.gtceu.substation_capacitor.tooltip_filled": "§cЄмність енергії:§f %d EU", - "block.gtceu.overworld_marker": "Верхній світ", - "block.gtceu.the_end_marker": "Енд", - "block.gtceu.the_nether_marker": "Незер", - "block.gtceu.vacuum_freezer": "Вакуумна морозильна камера", - "block.gtceu.wire_coil.tooltip_cracking": "§8Крекінг-установка:", - "block.gtceu.wire_coil.tooltip_heat": "§cБазова теплоємність:§f %d K", - "block.gtceu.wire_coil.tooltip_pyro": "§8Піролізна піч:", - "block.gtceu.wire_coil.tooltip_smelter": "§8Мультиплавильня:", - "block.gtceu.wood_drum": "Дерев'яна діжка", - - "block.gtceu.wood_wall": "Дерев'яна стіна", - "block.gtceu.casing_coke_bricks": "Цегла коксової печі", - "block.gtceu.coke_oven_bricks": "Цегла коксової печі", - "block.gtceu.firebricks": "Шамотна цегла", - "block.gtceu.steam_machine_casing": "Паровий машинний корпус", - "block.gtceu.heatproof_machine_casing": "Термостійкий інваровий машинний корпус", - "block.gtceu.frostproof_machine_casing": "Морозостійкий алюмінієвий машинний корпус", - "block.gtceu.solid_machine_casing": "Міцний машинний корпус", - "block.gtceu.clean_machine_casing": "Чистий нержавіючий сталевий корпус", - "block.gtceu.stable_machine_casing": "Стійкий титановий машинний корпус", - "block.gtceu.robust_machine_casing": "Надійний вольфрамовий сталевий машинний корпус", - "block.gtceu.inert_machine_casing": "Хімічно інертний ПТФЕ машинний корпус", - "block.gtceu.sturdy_machine_casing": "Витривалий HSS-E машинний корпус", - "block.gtceu.palladium_substation": "Паладієвий корпус підстанції", - "block.gtceu.tempered_glass": "Загартоване скло", - "block.gtceu.stainless_evaporation_casing": "Нержавіючий випарний корпус", - "block.gtceu.nonconducting_casing": "Непровідний корпус", - "block.gtceu.vibration_safe_casing": "Вібростійкий корпус", - "block.gtceu.watertight_casing": "Водонепроникний корпус", - "block.gtceu.secure_maceration_casing": "Захисний подрібнювальний корпус", - "block.gtceu.high_temperature_smelting_casing": "Корпус для високотемпературного плавлення", - "block.gtceu.laser_safe_engraving_casing": "Захисний корпус для лазерного гравіювання", - "block.gtceu.large_scale_assembler_casing": "Корпус для великомасштабного збирання", - "block.gtceu.shock_proof_cutting_casing": "Ударостійкий різальний корпус", - "block.gtceu.stress_proof_casing": "Стресостійкий корпус", - "block.gtceu.corrosion_proof_casing": "Антикорозійний корпус", - "block.gtceu.reaction_safe_mixing_casing": "Реактивно-захисний змішувальний корпус", - "block.gtceu.atomic_casing": "Атомний корпус", - "block.gtceu.industrial_steam_casing": "Промисловий паровий корпус", - "block.gtceu.slicing_blades": "Ріжучі леза", - "block.gtceu.electrolytic_cell": "Електролітична комірка", - "block.gtceu.crushing_wheels": "Подрібнювальні колеса", - "block.gtceu.heat_vent": "Тепловідвід", - "block.gtceu.assembly_line_grating": "Решітка конвеєрної лінії", - "block.gtceu.assembly_line_casing": "Корпус конвеєрної лінії", - "block.gtceu.laminated_glass": "Багатошарове скло", - "block.gtceu.assembly_line_unit": "Конвеєрний контролюючий корпус", - "block.gtceu.bronze_gearbox": "Бронзовий редукторний корпус", - "block.gtceu.steel_gearbox": "Сталевий редукторний корпус", - "block.gtceu.stainless_steel_gearbox": "Нержавіючий сталевий редукторний корпус", - "block.gtceu.titanium_gearbox": "Титановий редукторний корпус", - "block.gtceu.tungstensteel_gearbox": "Вольфрамовий сталевий редукторний корпус", - "block.gtceu.steel_turbine_casing": "Сталевий турбінний корпус", - "block.gtceu.titanium_turbine_casing": "Титановий турбінний корпус", - "block.gtceu.stainless_steel_turbine_casing": "Нержавіючий турбінний корпус", - "block.gtceu.tungstensteel_turbine_casing": "Вольфрамовий сталевий турбінний корпус", - "block.gtceu.bronze_pipe_casing": "Бронзовий трубний корпус", - "block.gtceu.steel_pipe_casing": "Сталевий трубний корпус", - "block.gtceu.titanium_pipe_casing": "Титановий трубний корпус", - "block.gtceu.tungstensteel_pipe_casing": "Вольфрамовий сталевий трубний корпус", - "block.gtceu.ptfe_pipe_casing": "ПТФЕ трубний корпус", - "block.gtceu.pump_deck": "Палуба помпи", - "block.gtceu.ulv_machine_casing": "ULV машинний корпус", - "block.gtceu.lv_machine_casing": "LV машинний корпус", - "block.gtceu.mv_machine_casing": "MV машинний корпус", - "block.gtceu.hv_machine_casing": "HV машинний корпус", - "block.gtceu.ev_machine_casing": "EV машинний корпус", - "block.gtceu.iv_machine_casing": "IV машинний корпус", - "block.gtceu.luv_machine_casing": "LuV машинний корпус", - "block.gtceu.zpm_machine_casing": "ZPM машинний корпус", - "block.gtceu.uv_machine_casing": "UV машинний корпус", - "block.gtceu.uxv_machine_casing": "UXV машинний корпус", - "block.gtceu.uhv_machine_casing": "UHV машинний корпус", - "block.gtceu.uiv_machine_casing": "UIV машинний корпус", - "block.gtceu.uev_machine_casing": "UEV машинний корпус", - "block.gtceu.opv_machine_casing": "OpV машинний корпус", - "block.gtceu.max_machine_casing": "MAX машинний корпус", - "block.gtceu.lv_hermetic_casing": "Герметичний корпус I", - "block.gtceu.mv_hermetic_casing": "Герметичний корпус II", - "block.gtceu.hv_hermetic_casing": "Герметичний корпус III", - "block.gtceu.ev_hermetic_casing": "Герметичний корпус IV", - "block.gtceu.iv_hermetic_casing": "Герметичний корпус V", - "block.gtceu.luv_hermetic_casing": "Герметичний корпус VI", - "block.gtceu.zpm_hermetic_casing": "Герметичний корпус VII", - "block.gtceu.uv_hermetic_casing": "Герметичний корпус VIII", - "block.gtceu.uhv_hermetic_casing": "Герметичний корпус IX", - "block.gtceu.bronze_machine_casing": "Бронзовий машинний корпус", - "block.gtceu.bronze_brick_casing": "Мурований бронзовий корпус", - "block.gtceu.steam_casing_bricked_bronze": "Мурований бронзовий корпус", - "block.gtceu.steel_machine_casing": "Міцний сталевий машинний корпус", - "block.gtceu.steel_brick_casing": "Мурований кованозалізний корпус", - "block.gtceu.steam_casing_bricked_steel": "Мурований кованозалізний корпус", - "block.gtceu.engine_intake_casing": "Впускний корпус двигуна", - "block.gtceu.extreme_engine_intake_casing": "Екстремальний впускний корпус двигуна", - "block.gtceu.fusion_casing": "Реакторний машинний корпус", - "block.gtceu.fusion_casing_mk2": "Реакторний машинний корпус MK II", - "block.gtceu.fusion_casing_mk3": "Реакторний машинний корпус MK III", - "block.gtceu.casing_grate": "Заґратований машинний корпус", - "block.gtceu.fusion_glass": "Скло реактора", - "block.gtceu.plascrete": "Гіпсобетон", - "block.gtceu.filter_casing": "Фільтрувальний корпус", - "block.gtceu.sterilizing_filter_casing": "Стерилізуючий фільтрувальний корпус", - "block.gtceu.cleanroom_glass": "Скло чистої кімнати", - "block.gtceu.bronze_firebox_casing": "Бронзова топка", - "block.gtceu.steel_firebox_casing": "Сталева топка", - "block.gtceu.titanium_firebox_casing": "Титанова топка", - "block.gtceu.tungstensteel_firebox_casing": "Вольфрамова сталева топка", - "block.gtceu.computer_casing": "Комп'ютерний корпус", - "block.gtceu.advanced_computer_casing": "Просунутий комп'ютерний корпус", - "block.gtceu.computer_heat_vent": "Комп'ютерний тепловідвід", - "block.gtceu.high_power_casing": "Високопотужний корпус", - "block.gtceu.powderbarrel": "Порохова діжка", - "block.gtceu.industrial_tnt": "Промисловий динаміт", - "block.gtceu.rubber_sapling": "Каучуковий паросток", - "block.gtceu.rubber_log": "Каучукова колода", - "block.gtceu.rubber_leaves": "Каучукове листя", - "block.gtceu.stripped_rubber_log": "Обтесана каучуковий колода", - "block.gtceu.rubber_wood": "Каучукова деревина", - "block.gtceu.stripped_rubber_wood": "Обтесана каучукова деревина", - "block.gtceu.rubber_planks": "Каучукові дошки", - "block.gtceu.rubber_slab": "Каучукова плита", - "block.gtceu.rubber_fence": "Каучуковий паркан", - "block.gtceu.rubber_sign": "Каучукова табличка", - "block.gtceu.rubber_hanging_sign": "Каучукова вивіска", - "block.gtceu.rubber_pressure_plate": "Каучукова натискна плита", - "block.gtceu.rubber_trapdoor": "Каучуковий люк", - "block.gtceu.rubber_stairs": "Каучукові сходи", - "block.gtceu.rubber_button": "Каучукова кнопка", - "block.gtceu.rubber_fence_gate": "Каучукова хвіртка", - "block.gtceu.rubber_door": "Каучукові двері", - "item.gtceu.long_treated_wood_rod": "Довга оброблена дерев'яна палиця", - "item.gtceu.treated_wood_boat": "Оброблений дерев'яний човен", - "item.gtceu.treated_wood_bolt": "Коротка оброблена дерев'яна палиця", - "item.gtceu.treated_wood_chest_boat": "Оброблений дерев'яний човен зі скринею", - "item.gtceu.treated_wood_dust": "Оброблена дерев'яна стружка", - "item.gtceu.treated_wood_plate": "Оброблена дерев'яна дошка", - "item.gtceu.treated_wood_rod": "Оброблена дерев'яна палиця", - "block.gtceu.treated_wood_planks": "Оброблені дерев'яні дошки", - "block.gtceu.treated_wood_slab": "Оброблена дерев'яна плита", - "block.gtceu.treated_wood_fence": "Оброблений дерев'яний паркан", - "block.gtceu.treated_wood_sign": "Оброблена дерев'яна табличка", - "block.gtceu.treated_wood_hanging_sign": "Оброблена дерев'яна вивіска", - "block.gtceu.treated_wood_pressure_plate": "Оброблена дерев'яна натискна плита", - "block.gtceu.treated_wood_trapdoor": "Оброблений дерев'яний люк", - "block.gtceu.treated_wood_stairs": "Оброблені дерев'яні сходи", - "block.gtceu.treated_wood_button": "Оброблена дерев'яна кнопка", - "block.gtceu.treated_wood_fence_gate": "Оброблена дерев'яна хвіртка", - "block.gtceu.treated_wood_door": "Оброблені дерев'яні двері", - "block.gtceu.acid_hazard_sign_block": "Блок зі знаком кислотної небезпеки", - "block.gtceu.antimatter_hazard_sign_block": "Блок зі знаком антиматеріальної небезпеки", - "block.gtceu.bio_hazard_sign_block": "Блок зі знаком біонебезпеки", - "block.gtceu.boss_hazard_sign_block": "Блок зі знаком босової небезпеки", - "block.gtceu.causality_hazard_sign_block": "Блок зі знаком причинно-наслідкової небезпеки", - "block.gtceu.explosion_hazard_sign_block": "Блок зі знаком вибухової небезпеки", - "block.gtceu.fire_hazard_sign_block": "Блок зі знаком вогневої небезпеки", - "block.gtceu.frost_hazard_sign_block": "Блок зі знаком морозної небезпеки", - "block.gtceu.generic_hazard_sign_block": "Блок зі знаком попередження", - "block.gtceu.gregification_hazard_sign_block": "Блок зі знаком грегіфікаційної небезпеки", - "block.gtceu.high_pressure_hazard_sign_block": "Блок зі знаком небезпеки високого тиску", - "block.gtceu.high_temperature_hazard_sign_block": "Блок зі знаком небезпеки високої температури", - "block.gtceu.high_voltage_hazard_sign_block": "Блок зі знаком небезпеки високої напруги", - "block.gtceu.laser_hazard_sign_block": "Блок зі знаком лазерної небезпеки", - "block.gtceu.magic_hazard_sign_block": "Блок зі знаком містичної небезпеки", - "block.gtceu.magnetic_hazard_sign_block": "Блок зі знаком магнітної небезпеки", - "block.gtceu.mob_infestation_hazard_sign_block": "Блок зі знаком небезпеки зараження мобів", - "block.gtceu.mob_spawner_hazard_sign_block": "Блок зі знаком спавнерової небезпеки", - "block.gtceu.noise_hazard_sign_block": "Блок зі знаком шумової небезпеки", - "block.gtceu.radioactive_hazard_sign_block": "Блок зі знаком радіоактивної небезпеки", - "block.gtceu.spatial_storage_hazard_sign_block": "Блок зі знаком небезпеки просторового сховища", - "block.gtceu.turret_hazard_sign_block": "Блок зі знаком турельної небезпеки", - "block.gtceu.void_hazard_sign_block": "Блок зі знаком небезпеки порожнечі", - "block.gtceu.yellow_stripes_block.a": "Блок жовтих стрічок", - "block.gtceu.yellow_stripes_block.b": "Блок жовтих стрічок", - "block.gtceu.yellow_stripes_block.c": "Блок жовтих стрічок", - "block.gtceu.yellow_stripes_block.d": "Блок жовтих стрічок", - "block.gtceu.yellow_stripes_block_a": "Блок жовтих стрічок A", - "block.gtceu.yellow_stripes_block_b": "Блок жовтих стрічок B", - "block.gtceu.brittle_charcoal": "Крихке деревне вугілля", - "block.gtceu.foam": "Піна", - "block.gtceu.reinforced_foam": "Посилена піна", - "block.gtceu.petrified_foam": "Скам'яніла піна", - "item.gtceu.foam_sprayer.tooltip.0": "§7Розпилює будівельну піні", - "item.gtceu.foam_sprayer.tooltip.1": "Використовуйте на боці, щоб вкрити піною прилеглі сторони", - "item.gtceu.foam_sprayer.tooltip.2": "Піну можна пофарбувати", - "block.gtceu.black_lamp": "Чорна лампа", - "block.gtceu.blue_lamp": "Синя лампа", - "block.gtceu.brown_lamp": "Коричнева лампа", - "block.gtceu.cyan_lamp": "Бірюзова лампа", - "block.gtceu.gray_lamp": "Сіра лампа", - "block.gtceu.green_lamp": "Зелена лампа", - "block.gtceu.light_blue_lamp": "Блакитна лампа", - "block.gtceu.light_gray_lamp": "Світло-сіра лампа", - "block.gtceu.lime_lamp": "Лаймова лампа", - "block.gtceu.magenta_lamp": "Пурпурова лампа", - "block.gtceu.orange_lamp": "Помаранчева лампа", - "block.gtceu.pink_lamp": "Рожева лампа", - "block.gtceu.purple_lamp": "Фіолетова лампа", - "block.gtceu.red_lamp": "Червона лампа", - "block.gtceu.white_lamp": "Біла лампа", - "block.gtceu.yellow_lamp": "Жовта лампа", - "block.gtceu.black_borderless_lamp": "Чорна необлямована лампа", - "block.gtceu.blue_borderless_lamp": "Синя необлямована лампа", - "block.gtceu.brown_borderless_lamp": "Коричнева необлямована лампа", - "block.gtceu.cyan_borderless_lamp": "Бірюзова необлямована лампа", - "block.gtceu.gray_borderless_lamp": "Сіра необлямована лампа", - "block.gtceu.green_borderless_lamp": "Зелена необлямована лампа", - "block.gtceu.light_blue_borderless_lamp": "Блакитна необлямована лампа", - "block.gtceu.light_gray_borderless_lamp": "Світло-сіра необлямована лампа", - "block.gtceu.lime_borderless_lamp": "Лаймова необлямована лампа", - "block.gtceu.magenta_borderless_lamp": "Пурпурова необлямована лампа", - "block.gtceu.orange_borderless_lamp": "Помаранчева необлямована лампа", - "block.gtceu.pink_borderless_lamp": "Рожева необлямована лампа", - "block.gtceu.purple_borderless_lamp": "Фіолетова необлямована лампа", - "block.gtceu.red_borderless_lamp": "Червона необлямована лампа", - "block.gtceu.white_borderless_lamp": "Біла необлямована лампа", - "block.gtceu.yellow_borderless_lamp": "Жовта необлямована лампа", - "block.gtceu.lamp.tooltip.inverted": "Інвертована", - "block.gtceu.lamp.tooltip.no_bloom": "Не мерехтить", - "block.gtceu.lamp.tooltip.no_light": "Не світить", - "block.gtceu.black_metal_sheet": "Чорне металеве покриття", - "block.gtceu.blue_metal_sheet": "Синє металеве покриття", - "block.gtceu.brown_metal_sheet": "Коричневе металеве покриття", - "block.gtceu.cyan_metal_sheet": "Бірюзове металеве покриття", - "block.gtceu.gray_metal_sheet": "Сіре металеве покриття", - "block.gtceu.green_metal_sheet": "Зелене металеве покриття", - "block.gtceu.light_blue_metal_sheet": "Блакитне металеве покриття", - "block.gtceu.light_gray_metal_sheet": "Світло-сіре металеве покриття", - "block.gtceu.lime_metal_sheet": "Лаймове металеве покриття", - "block.gtceu.magenta_metal_sheet": "Пурпурове металеве покриття", - "block.gtceu.orange_metal_sheet": "Помаранчеве металеве покриття", - "block.gtceu.pink_metal_sheet": "Рожеве металеве покриття", - "block.gtceu.purple_metal_sheet": "Фіолетове металеве покриття", - "block.gtceu.red_metal_sheet": "Червоне металеве покриття", - "block.gtceu.white_metal_sheet": "Біле металеве покриття", - "block.gtceu.yellow_metal_sheet": "Жовте металеве покриття", - "block.gtceu.black_large_metal_sheet": "Чорне велике металеве покриття", - "block.gtceu.blue_large_metal_sheet": "Синє велике металеве покриття", - "block.gtceu.brown_large_metal_sheet": "Коричневе велике металеве покриття", - "block.gtceu.cyan_large_metal_sheet": "Бірюзове велике металеве покриття", - "block.gtceu.gray_large_metal_sheet": "Сіре велике металеве покриття", - "block.gtceu.green_large_metal_sheet": "Зелене велике металеве покриття", - "block.gtceu.light_blue_large_metal_sheet": "Блакитне велике металеве покриття", - "block.gtceu.light_gray_large_metal_sheet": "Світло-сіре велике металеве покриття", - "block.gtceu.lime_large_metal_sheet": "Лаймове велике металеве покриття", - "block.gtceu.magenta_large_metal_sheet": "Пурпурове велике металеве покриття", - "block.gtceu.orange_large_metal_sheet": "Помаранчеве велике металеве покриття", - "block.gtceu.pink_large_metal_sheet": "Рожеве велике металеве покриття", - "block.gtceu.purple_large_metal_sheet": "Фіолетове велике металеве покриття", - "block.gtceu.red_large_metal_sheet": "Червоне велике металеве покриття", - "block.gtceu.white_large_metal_sheet": "Біле велике металеве покриття", - "block.gtceu.yellow_large_metal_sheet": "Жовте велике металеве покриття", - "block.gtceu.black_studs": "Чорні деталькі", - "block.gtceu.blue_studs": "Сині деталькі", - "block.gtceu.brown_studs": "Коричневі деталькі", - "block.gtceu.cyan_studs": "Бірюзові деталькі", - "block.gtceu.gray_studs": "Сірі деталькі", - "block.gtceu.green_studs": "Зелені деталькі", - "block.gtceu.light_blue_studs": "Блакитні деталькі", - "block.gtceu.light_gray_studs": "Світло-сірі деталькі", - "block.gtceu.lime_studs": "Лаймові деталькі", - "block.gtceu.magenta_studs": "Пурпурові деталькі", - "block.gtceu.orange_studs": "Помаранчеві деталькі", - "block.gtceu.pink_studs": "Рожеві деталькі", - "block.gtceu.purple_studs": "Фіолетові деталькі", - "block.gtceu.red_studs": "Червоні деталькі", - "block.gtceu.white_studs": "Білі деталькі", - "block.gtceu.yellow_studs": "Жовті деталькі", - "block.gtceu.chiseled_red_granite": "Різблений червоний граніт", - "block.gtceu.cracked_red_granite_bricks": "Тріснута червоногранітна цегла", - "block.gtceu.mossy_red_granite_bricks": "Моховита червоногранітна цегла", - "block.gtceu.mossy_red_granite_cobblestone": "Моховитий червоногранітний кругляк", - "block.gtceu.polished_red_granite": "Полірований червоний граніт", - "block.gtceu.red_granite": "Червоний граніт", - "block.gtceu.red_granite_bricks": "Червоногранітна цегла", - "block.gtceu.red_granite_cobblestone": "Червоногранітний кругляк", - "block.gtceu.red_granite_small_tile": "Червоногранітні дрібні кахлі", - "block.gtceu.red_granite_tile": "Червоногранітні кахлі", - "block.gtceu.red_granite_windmill_a": "Червоногранітний вітряк A", - "block.gtceu.red_granite_windmill_b": "Червоногранітний вітряк B", - "block.gtceu.small_red_granite_bricks": "Дрібна червоногранітна цегла", - "block.gtceu.square_red_granite_bricks": "Квадратна червоногранітна цегла", - "block.gtceu.chiseled_marble": "Різблений мармур", - "block.gtceu.cracked_marble_bricks": "Тріснута мармурова цегла", - "block.gtceu.marble": "Мармур", - "block.gtceu.marble_bricks": "Мармурова цегла", - "block.gtceu.marble_cobblestone": "Мармуровий кругляк", - "block.gtceu.marble_small_tile": "Мармурові дрібні кахлі", - "block.gtceu.marble_tile": "Мармурові кахлі", - "block.gtceu.marble_windmill_a": "Мармуровий вітряк A", - "block.gtceu.marble_windmill_b": "Мармуровий вітряк B", - "block.gtceu.mossy_marble_bricks": "Моховита мармурова цегла", - "block.gtceu.mossy_marble_cobblestone": "Моховитий мармуровий кругляк", - "block.gtceu.polished_marble": "Полірований мармур", - "block.gtceu.small_marble_bricks": "Дрібна мармурова цегла", - "block.gtceu.square_marble_bricks": "Квадратна мармурова цегла", - "block.gtceu.chiseled_light_concrete": "Різблений світлий бетон", - "block.gtceu.cracked_light_concrete_bricks": "Тріснута світла бетонна цегла", - "block.gtceu.light_concrete": "Світлий бетон", - "block.gtceu.light_concrete_bricks": "Світла бетонна цегла", - "block.gtceu.light_concrete_cobblestone": "Світлий бетонний кругляк", - "block.gtceu.light_concrete_small_tile": "Світлі бетонні дрібні кахлі", - "block.gtceu.light_concrete_tile": "Світлі бетонні кахлі", - "block.gtceu.light_concrete_windmill_a": "Світлий бетонний вітряк A", - "block.gtceu.light_concrete_windmill_b": "Світлий бетонний вітряк B", - "block.gtceu.mossy_light_concrete_bricks": "Моховита світла бетонна цегла", - "block.gtceu.mossy_light_concrete_cobblestone": "Моховитий світлий бетонний кругляк", - "block.gtceu.polished_light_concrete": "Полірований світлий бетон", - "block.gtceu.small_light_concrete_bricks": "Дрібна світла бетонна цегла", - "block.gtceu.square_light_concrete_bricks": "Квадратна світла бетонна цегла", - "block.gtceu.chiseled_dark_concrete": "Різблений темний бетон", - "block.gtceu.cracked_dark_concrete_bricks": "Тріснута темна бетонна цегла", - "block.gtceu.dark_concrete": "Темний бетон", - "block.gtceu.dark_concrete_bricks": "Темна бетонна цегла", - "block.gtceu.dark_concrete_cobblestone": "Темний бетонний кругляк", - "block.gtceu.dark_concrete_small_tile": "Темні бетонні дрібні кахлі", - "block.gtceu.dark_concrete_tile": "Темні бетонні кахлі", - "block.gtceu.dark_concrete_windmill_a": "Темний бетонний вітряк A", - "block.gtceu.dark_concrete_windmill_b": "Темний бетонний вітряк B", - "block.gtceu.mossy_dark_concrete_bricks": "Моховита темна бетонна цегла", - "block.gtceu.mossy_dark_concrete_cobblestone": "Моховитий темний бетонний кругляк", - "block.gtceu.polished_dark_concrete": "Полірований темний бетон", - "block.gtceu.small_dark_concrete_bricks": "Дрібна темна бетонна цегла", - "block.gtceu.square_dark_concrete_bricks": "Квадратна темна бетонна цегла", - - "fluid.empty": "Порожньо", - "fluid_cell.empty": "Порожньо", - "fluid.spawnlocation.name": "Інфо про рідинну жилу", - "fluid.gtceu.potion": "Зілля", - "fluid.tile.lava": "Лава", - "fluid.tile.water": "Вода", - - "gtceu.top.allow_output_input": "Відкритий вхід", - "gtceu.top.auto_output": "Автовиведення", - "gtceu.top.buffer_bound_pos": "Прив'язано до - X: %s, Y: %s, Z: %s", - "gtceu.top.cable_amperage": "Сила струму: ", - "gtceu.top.cable_voltage": "Напруга: ", - "gtceu.top.convert_eu": "Конвертація§e EU§r ->§c FE§r", - "gtceu.top.convert_fe": "Конвертація§c FE§r ->§e EU§r", - "gtceu.top.energy_consumption": "Використання", - "gtceu.top.energy_production": "Вироблення", - "gtceu.top.exhaust_vent_blocked": "Заблоковано", - "gtceu.top.exhaust_vent_direction": "Витяжна вентиляція: %s", - "gtceu.top.filter.label": "Фільтр:", - "gtceu.top.fluid_auto_output": "Вихід рідини: %s", - "gtceu.top.fuel_min_consume": "Потребує", - "gtceu.top.fuel_none": "Нема палива", - "gtceu.top.invalid_structure": "Конструкція незавершена", - "gtceu.top.item_auto_output": "Вихід предметів: %s", - "gtceu.top.link_cover.color": "Колір:", - "gtceu.top.machine_mode": "Режим машини: ", - "gtceu.top.maintenance.crowbar": "Цьому тут не місце", - "gtceu.top.maintenance.hard_hammer": "Покриття має вм'ятини", - "gtceu.top.maintenance.screwdriver": "Гвинти розхитані", - "gtceu.top.maintenance.soft_mallet": "Щось заклинило", - "gtceu.top.maintenance.wire_cutter": "Дроти перегоріли", - "gtceu.top.maintenance.wrench": "Труба відійшла", - "gtceu.top.maintenance_broken": "Потребує технічного обслуговування", - "gtceu.top.maintenance_fixed": "Обслуговування завершено", - "gtceu.top.mode.export": "Експортування", - "gtceu.top.mode.import": "Імпортування", - "gtceu.top.obstructed_structure": "Щось заважає формуванню конструкції", - "gtceu.top.primitive_pump_production": "Вироблення: %s мВ/с", - "gtceu.top.proxies_bound": "Прив'язані буферні проксі: %s", - "gtceu.top.recipe_output": "Виходи рецептів:", - "gtceu.top.stained": "Фарбування: %s", - "gtceu.top.transform_down": "§aКрок вниз§r %s", - "gtceu.top.transform_input": "§6Вхід:§r %s", - "gtceu.top.transform_output": "§9Вихід:§r %s", - "gtceu.top.transform_up": "§cКрок вгору§r %s", - "gtceu.top.unit.fluid_buckets": "кЛ", - "gtceu.top.unit.fluid_milibuckets": "Л", - "gtceu.top.unit.items": "Предмети", - "gtceu.top.valid_structure": "Конструкцію сформовано", - "gtceu.top.working_disabled": "Роботу зупинено", - - "gtceu.tool_action.crowbar": "§8Використовуйте лом, щоб зняти кришки", - "gtceu.tool_action.hammer": "§8Використовуйте молот, щоб приглушити звуки", - "gtceu.tool_action.screwdriver.access_covers": "§8Використовуйте викрутку для доступу до кришок", - "gtceu.tool_action.screwdriver.auto_output_covers": "§8Використовуйте викрутку, щоб увімкнути вхід з боку виходу або для доступу до кришок", - "gtceu.tool_action.screwdriver.auto_output": "§8Використовуйте викрутку, щоб увімкнути автоматичний вихід", - "gtceu.tool_action.screwdriver.auto_collapse": "§8Використовуйте викрутку, щоб увімкнути руйнування предметів", - "gtceu.tool_action.screwdriver.toggle_mode": "§8Використовуйте викрутку для перемикання режимів", - "gtceu.tool_action.screwdriver.toggle_mode_covers": "§8Використовуйте викрутку для перемикання режимів або доступу до кришок", - "gtceu.tool_action.soft_mallet.toggle_mode": "§8Використовуйте м'який молоток для перемикання режимів", - "gtceu.tool_action.soft_mallet.reset": "§8Використовуйте м'який молоток для перемикання робочого стану", - "gtceu.tool_action.tape": "§8Використовуйте стрічку для усунення проблем з технічним обслуговуванням", - "gtceu.tool_action.wrench.connect": "§8Використовуйте гайковий ключ для встановлення з'єднань, крадькома, щоб заблокувати з'єднання", - "gtceu.tool_action.wrench.set_facing": "§8Використовуйте ключ, щоб встановити напрямок", - - "gtceu.recipe.environmental_hazard.reverse": "§cОбласть повинна бути захищена від %s", - "gtceu.recipe.environmental_hazard": "§cВ області повинно бути %s", - "gtceu.recipe.amperage": "Сила струму: %s", - "gtceu.recipe.chance": "Шанс: %s +%s/tier", - "recipe_category.gtceu.chem_dyes": "Хімічне розфарбовування", - "gtceu.recipe.cleanroom.display_name": "Чиста кімната", - "gtceu.recipe.coil.tier": "Котушка: %s", - "gtceu.recipe.total_computation": "Обчислення: %s ОРО", - "gtceu.recipe_logic.condition_fails": "Умова не виконана", - "gtceu.recipe.dimensions": "Виміри: %s", - "gtceu.recipe.not_consumed": "Не витрачається в процесі роботи", - "gtceu.recipe.duration": "Тривалість: %s secs", - "gtceu.recipe.eu_to_start": "Стартове EU: %sEU%s", - "gtceu.recipe.explosive": "Вибухова речовина: %s", - "gtceu.recipe.eu_inverted": "Генерування: %s EU/т", - "gtceu.recipe_logic.insufficient_fuel": "Недостатньо палива", - "gtceu.recipe_logic.insufficient_in": "Недостатньо входів", - "gtceu.recipe_logic.insufficient_out": "Недостатньо виходів", - "gtceu.recipe.max_eu": "Макс. EU: %s EU", - "gtceu.recipe.computation_per_tick": "Мін. обчислень: %s ОРО/т", - "recipe_category.gtceu.ore_forging": "Дроблення руд", - "recipe_category.gtceu.ore_crushing": "Подрібнення руд", - "recipe_category.gtceu.ore_bathing": "Рудообробка", - "recipe_category.gtceu.macerator_recycling": "Переробка", - "recipe_category.gtceu.arc_furnace_recycling": "Плазмова переробка", - "gtceu.recipe.cleanroom": "Потребує %s", - "gtceu.recipe.research": "Потребує дослідження", - "gtceu.recipe.scan_for_research": "Сканування для конвеєрної лінії", - "recipe_category.gtceu.extractor_recycling": "Переливання металолому", - "gtceu.recipe_type.show_recipes": "Показати рецепти", - "gtceu.recipe.cleanroom_sterile.display_name": "Стерильна чиста кімната", - "gtceu.recipe.temperature": "Температура: %sK", - "gtceu.recipe.total": "Загалом: %s EU", - "gtceu.recipe.eu": "Використання: %s EU/т", - "gtceu.recipe_memory_widget.tooltip.0": "§7Клацніть ЛКМ, щоб автоматично внести цей рецепт до сітки виготовлення", - "gtceu.recipe_memory_widget.tooltip.1": "§7Клацайте із затиснутим Shift, щоб заблокувати/розблокувати цей рецепт", - - "effect.gtceu.weak_poison": "Слабке отруєння", - "enchantment.damage.disjunction": "Розщеплення", - "enchantment.disjunction": "Розщеплення", - "enchantment.gtceu.disjunction.description": "Застосовує Слабкість і Повільність до пов'язаних з Ендом мобів.", - "enchantment.gtceu.hard_hammer.description": "Розбиває блоки так, ніби вони були видобуті за допомогою молота GregTech.", - "enchantment.hard_hammer": "Забивання", - "entity.gtceu.boat": "Човен", - "entity.gtceu.chest_boat": "Човен зі скринею", - "entity.gtceu.industrial_tnt": "Промисловий динаміт", - "entity.gtceu.powderbarrel": "Порохова діжка", - "gtceu.alloy_blast_smelter": "Плавильник сплавів", - "gtceu.assembly_line": "Конвеєрна лінія", - "gtceu.auto_decomp.rotor": "Ротор турбіни", - "gtceu.coke_oven": "Коксова піч", - "gtceu.combustion_generator": "Генератор внутрішнього згоряння", - "gtceu.cracker": "Крекер", - "gtceu.distillation_tower": "Дистиляційня вежа", - "gtceu.dummy": "Манекен", - "gtceu.electric_blast_furnace": "Електрична доменна піч", - "gtceu.fluid_heater": "Рідинний нагрівач", - "gtceu.fluid_solidifier": "Рідинний затверджувач", - "gtceu.fusion_reactor": "Термоядерний реактор", - "gtceu.gas_turbine": "Газова турбіна", - "gtceu.large_boiler": "Великий котел", - "gtceu.plasma_generator": "Плазмовий генератор", - "gtceu.primitive_blast_furnace": "Примітивна плавильня", - "gtceu.pyrolyse_oven": "Піролізна піч", - "gtceu.rei.group.potion_fluids": "Рідини зіллів", - "gtceu.research_station": "Дослідницька станція", - "gtceu.rock_breaker": "Кам'яна дробарка", - "gtceu.steam_boiler": "Паровий котел", - "gtceu.steam_turbine": "Парова турбіна", - - "block.filter_casing.tooltip": "Створює§a вільне від частинок§7 середовище", - "block.sterilizing_filter_casing.tooltip": "Створює§a стерильне§7 середовище", - "button.gtceu.mark_as_depleted.name": "Позначити як виснажений", - "button.gtceu.toggle_waypoint.name": "Перемикнути маршрутну точку", - "curios.identifier.gtceu_magnet": "GTCEu магніт", - "gtceu.auto_decomp.tool": "Неелектричний інструмент", - "gtceu.battery_buffer.average_input": "Середній вхід: %s EU/т", - "gtceu.battery_buffer.average_output": "Середній вихід: %s EU/т", - "gtceu.button.bedrock_fluids": "Показати рідинні глибокорінні жили", - "gtceu.button.hide_depleted": "Приховати виснажені жили", - "gtceu.button.ore_veins": "Показати рудні жили GT", - "gtceu.button.show_depleted": "Показати виснажені жили", - "gtceu.cable.amperage": "Макс. сила струму:§e %d", - "gtceu.cable.loss_per_block": "Втрати/Метр/Ампер:§c %d§7 EU-Вольт", - "gtceu.cable.superconductor": "§d%s Надпровідник", - "gtceu.cable.voltage": "Макс. напруга:§a %d§a (%s§a)", - "gtceu.chance_logic.and": "AND", - "gtceu.chance_logic.none": "NONE", - "gtceu.chance_logic.or": "OR", - "gtceu.chance_logic.xor": "XOR", - "gtceu.chat.cape": "§5Вітаємо: ви щойно розблокували новий плащ! Дивіться в термінальному додатку обирач плащів, щоб скористатися ним.§r", - "message.gtceu.new_veins": "Виявлено %d нових жил!", - "gtceu.debug.f3_h.enabled": "GregTech змінив інформацію про налагодження! Для розробників: увімкніть опцію misc:debug config у конфігураційному файлі GregTech, щоб побачити більше", - "gtceu.duct_pipe.transfer_rate": "§bШвидкість передачі повітря: %s", - "gtceu.evaporation": "Випаровування", - "gtceu.item_filter.empty_item": "Порожньо (немає предметів)", - "gtceu.item_filter.footer": "§eКлацніть з предметом, щоб замінити", - "gtceu.item_list.item_stored": "§7Вміст: %d", - "gtceu.item_pipe.priority": "§9Пріорітет:§f %d", - "gtceu.minimap.ore_vein.depleted": "Виснажено", - "gtceu.muffler.recovery_tooltip": "§bШанс відновлення:§f %d%%", - "gtceu.tooltip.proxy_bind": "§fПрив'язати до буфера шаблонів у %s %s %s", - "gtceu.vacuum_freezer": "Вакуумна морозильна камера", - "item.toggle.advanced.info.tooltip": "§8<Крадіться, щоб відобразити конфігурацію зберігання>", - "ore.spawnlocation.name": "Інформація про генерацію руд", - - "gtceu.cover.activity_detector.message_activity_inverted": "Моніторинг інвертованого стану активності", - "gtceu.cover.activity_detector.message_activity_normal": "Моніторинг нормального стану активності", - "gtceu.cover.activity_detector_advanced.message_activity_inverted": "Моніторинг інвертованого стану обробки", - "gtceu.cover.activity_detector_advanced.message_activity_normal": "Моніторинг нормального стану обробки", - "gtceu.cover.energy_detector.message_electricity_storage_inverted": "Моніторинг інвертованого зберігання електроенергії", - "gtceu.cover.energy_detector.message_electricity_storage_normal": "Моніторинг нормального зберігання електроенергії", - "gtceu.cover.fluid_detector.message_fluid_storage_inverted": "Моніторинг інвертованого зберігання рідини", - "gtceu.cover.fluid_detector.message_fluid_storage_normal": "Моніторинг нормального зберігання рідин", - "gtceu.cover.item_detector.message_item_storage_inverted": "Моніторинг інвертованого зберігання предметів", - "gtceu.cover.item_detector.message_item_storage_normal": "Моніторинг нормального зберігання предметів", - "gtceu.creative.activity.off": "Неактивний", - "gtceu.creative.activity.on": "Активний", - "gtceu.creative.chest.ipc": "Предмети за цикл", - "gtceu.creative.chest.item": "Предмет", - "gtceu.creative.chest.tpc": "Такти за цикл", - "gtceu.creative.computation.average": "Середні запитувані ОРОт", - "gtceu.creative.energy.amperage": "Сила струму", - "gtceu.creative.energy.sink": "Поглинання", - "gtceu.creative.energy.source": "Джерело", - "gtceu.creative.energy.voltage": "Напруга", - "gtceu.creative.tank.fluid": "Рідина", - "gtceu.creative.tank.mbpc": "мВ за цикл", - "gtceu.creative.tank.tpc": "Тактів за цикл", - "gtceu.io.both": "Обидва", - "gtceu.io.export": "Експорт", - "gtceu.io.import": "Імпорт", - "gtceu.io.none": "Ніяк", - "gtceu.forming_press.naming.named": "§oПерейменований предмет", - "gtceu.forming_press.naming.press": "§oІменувальний прес", - "gtceu.forming_press.naming.to_name": "§oПредмет до перейменування", - "gtceu.journeymap.options.layers": "Шари до розвідування", - "gtceu.journeymap.options.layers.bedrock_fluids": "Показати рідинні жили в корінних породах", - "gtceu.journeymap.options.layers.hide_depleted": "Приховати виснажені жили", - "gtceu.journeymap.options.layers.ore_veins": "Показати рудні жили", - "gtceu.maintenance.configurable_duration": "Тривалість: %fx", - "gtceu.maintenance.configurable_duration.changed_description": "Рецепти запускатимуться з тривалістю %fx, застосованою перед розгоном.", - "gtceu.maintenance.configurable_duration.modify": "Змінити тривалість:", - "gtceu.maintenance.configurable_duration.unchanged_description": "Рецепти виконуватимуться зі звичайною швидкістю. Змініть конфігурацію для оновлення.", - "gtceu.maintenance.configurable_time": "Час: %fx", - "gtceu.maintenance.configurable_time.changed_description": "Проблеми з обслуговуванням виникатимуть у %f разів частіше.", - "gtceu.maintenance.configurable_time.unchanged_description": "Проблеми з обслуговуванням виникатимуть зі звичайною швидкістю. Змініть конфігурацію для оновлення.", - "gtceu.scanner.copy_stick_empty": "§oПорожня картка", - "gtceu.scanner.copy_stick_from": "§oКопіювання до картки", - "gtceu.scanner.copy_stick_to": "§oВставка з картки", - "gui.gtceu.share_inventory.title": "Інвентар спільних предметів", - "gui.gtceu.share_inventory.desc.0": "Ділиться вставленими предметами з усіма шаблонами в буфері!", - "gui.gtceu.share_inventory.desc.1": "Дозволяє значно автоматизувати роботу, зберігаючи каталізатори", - "gui.gtceu.rename.desc": "Перейменувати буфер деталей", - "gui.gtceu.refund_all.desc": "Повернути збережений вміст до AE2", - "gui.gtceu.share_tank.title": "Інвентар спільного резервуара", - "gui.gtceu.share_tank.desc.0": "Ділиться вставленими рідинами/газами/тощо з усіма шаблонами в буфері!", - "itemGroup.gtceu.decoration": "GregTechCEu: Декоративні блоки", - "itemGroup.gtceu.item": "GregTechCEu: Предмети", - "itemGroup.gtceu.machine": "GregTechCEU: Машини", - "itemGroup.gtceu.material_block": "GregTechCEu: Блоки матеріалів", - "itemGroup.gtceu.material_fluid": "GregTechCEu: Рідинні ємності матеріалів", - "itemGroup.gtceu.material_item": "GregTechCEu: Предмети матеріалів", - "itemGroup.gtceu.material_pipe": "GregTechCEu: Труби", - "itemGroup.gtceu.tool": "GregTechCEu: Предмети", - "ldlib.gui.editor.register.editor.gtceu.mui": "Проєкт машинного інтерфейсу", - "ldlib.gui.editor.register.editor.gtceu.rtui": "Проєкт інтерфейсу типу рецепта", - "ldlib.gui.editor.register.editor.gtceu.template_tab": "шаблони", - "monitor.gui.title.argb": "ARGB:", - "monitor.gui.title.back": "Назад", - "monitor.gui.title.config": "Конфігурація", - "monitor.gui.title.plugin": "Плагін:", - "monitor.gui.title.scale": "Масштаб:", - "monitor.gui.title.slot": "Слот:", - "recipe.capability.eu.name": "GTCEu Енергія", - "recipe.capability.fluid.name": "Рідина", - "recipe.capability.item.name": "Предмет", - "tile.gtceu.brittle_charcoal.name": "Крихке вугілля", - "tile.gtceu.brittle_charcoal.tooltip.0": "Виробляється запалювачем вугільної купи.", - "tile.gtceu.brittle_charcoal.tooltip.1": "Зламайте його, щоб отримати деревне вугілля.", - "tile.gtceu.foam.name": "Піна", - "tile.gtceu.petrified_foam.name": "Скам'яніла піна", - "tile.gtceu.reinforced_foam.name": "Посилена піна", - "tile.gtceu.reinforced_stone.name": "Посилений камінь", - "tile.gtceu.seal.name": "Герметичний блок", - "gtceu.direction.tooltip.back": "Тил", - "gtceu.direction.tooltip.down": "Низ", - "gtceu.direction.tooltip.front": "Перед", - "gtceu.direction.tooltip.left": "Лівий бік", - "gtceu.direction.tooltip.right": "Правий бік", - "gtceu.direction.tooltip.up": "Верх", - "behavior.data_item.assemblyline.data": "-§a %s", - "behavior.data_item.assemblyline.title": "§nДані про конструкцію конвеєрної лінії:", - "behavior.toggle_energy_consumer.tooltip": "Використовуйте крадькома для перемикання режиму", - "behavior.item_magnet.enabled": "§aМагнітне поле увімкнено", - "behavior.item_magnet.disabled": "§cМагнітне поле вимкнено", - "behavior.prospector.added_waypoint": "Створено маршрутну точку з іменем %s!", - "behavior.prospector.not_enough_energy": "Недостатньо енергії!", - "gui.widget.recipeProgressWidget.default_tooltip": "Показати рецепти", - "recipe.condition.biome.tooltip": "Біом: %s", - "recipe.condition.adjacent_block.tooltip": "Блоки навколо", - "recipe.condition.steam_vent.tooltip": "Чистий вентиляційний отвір", - "recipe.condition.dimension_marker.tooltip": "Вимір:", - "recipe.condition.dimension.tooltip": "Вимір: %s", - "recipe.condition.eu_to_start.tooltip": "EU до запуску: %d%s", - "recipe.condition.rock_breaker.tooltip": "Прилеглі розміщені рідини", - "recipe.condition.rain.tooltip": "Рівень дощу: %d", - "recipe.condition.thunder.tooltip": "Рівень грози: %d", - "recipe.condition.pos_y.tooltip": "Рівень Y: %d <= Y <= %d", - - "mataarmor.hud.supply_mode": "Режим живлення: %s", - "metaarmor.energy_share.disable": "Енергопостачання: Заряджання приладів вимкнена", - "metaarmor.energy_share.enable": "Енергопостачання: Заряджання приладів увімкнено", - "metaarmor.energy_share.error": "Енергопостачання:§c Недостатньо енергії для заряджання приладів!", - "metaarmor.energy_share.tooltip": "Режим живлення: %s", - "metaarmor.energy_share.tooltip.guide": "Щоб змінити режим, клацніть ПКМ крадькома, утримуючи предмет", - "metaarmor.hud.energy_lvl": "Рівень енергії: %s", - "metaarmor.hud.engine_enabled": "Двигун увімкнено: %s", - "metaarmor.hud.fuel_lvl": "Рівень палива: %s", - "metaarmor.hud.gravi_engine": "Гравітаційний двигун: %s", - "metaarmor.hud.hover_mode": "Режим ширяння: %s", - "metaarmor.hud.status.disabled": "§cВИМК", - "metaarmor.hud.status.enabled": "§aУВІМК", - "metaarmor.jetpack.emergency_hover_mode": "Аварійний режим польоту увімкнено!", - "metaarmor.jetpack.flight.disable": "Реактивний ранець: Політ вимкнено.", - "metaarmor.jetpack.flight.enable": "Реактивний ранець: Політ увімкнено", - "metaarmor.jetpack.hover.disable": "Реактивний ранець: Режим ширяння вимкнено", - "metaarmor.jetpack.hover.enable": "Реактивний ранець: Режим ширяння увімкнено", - "metaarmor.message.nightvision.disabled": "§bНічне бачення:§c Вимкнено", - "metaarmor.message.nightvision.enabled": "§bНічне бачення:§a Увімкнено", - "metaarmor.message.nightvision.error": "§cНедостатньо енергії!", - "metaarmor.nms.boosted_jump.disabled": "Комплект NanoMuscle™: Посилення стрибків вимкнено", - "metaarmor.nms.boosted_jump.enabled": "Комплект NanoMuscle™: Прискорення стрибків увімкнено", - "metaarmor.nms.nightvision.disabled": "Комплект NanoMuscle™: Нічне бачення вимкнено", - "metaarmor.nms.nightvision.enabled": "Комплект NanoMuscle™: Нічне бачення увімкнено", - "metaarmor.nms.nightvision.error": "Комплект NanoMuscle™:§c Недостатньо енергії!", - "metaarmor.nms.share.disable": "Комплект NanoMuscle™: Заряджання вимкнено", - "metaarmor.nms.share.enable": "Комплект NanoMuscle™: Заряджання увімкнено", - "metaarmor.nms.share.error": "Комплект NanoMuscle™:§c Недостатньо енергії для заряджання!", - "metaarmor.qts.nightvision.disabled": "Комплект QuarkTech™: Нічне бачення вимкнено", - "metaarmor.qts.nightvision.enabled": "Комплект QuarkTech™: Нічне бачення увімкнено", - "metaarmor.qts.nightvision.error": "Комплект QuarkTech™:§c Недостатньо енергії!", - "metaarmor.qts.share.disable": "Комплект QuarkTech™: Заряджання вимкнено", - "metaarmor.qts.share.enable": "Комплект QuarkTech™: Заряджання увімкнено", - "metaarmor.qts.share.error": "Комплект QuarkTech™:§c Недостатньо енергії для заряджання!", - "metaarmor.tooltip.autoeat": "Поповнює очки голоду з інвентарю", - "metaarmor.tooltip.breath": "Поповнює очки запасу повітря", - "metaarmor.tooltip.burning": "Знешкоджує горіння", - "metaarmor.tooltip.falldamage": "Знешкоджує кінетичну шкоду", - "metaarmor.tooltip.freezing": "Запобігає замерзанню", - "metaarmor.tooltip.jump": "Збільшує висоту та відстань стрибка", - "metaarmor.tooltip.potions": "Знешкоджує шкідливі ефекти", - "metaarmor.tooltip.speed": "Збільшує швидкість бігу", - "metaarmor.tooltip.stepassist": "Збільшує висоту кроку", - - "gtceu.subtitle.portable_scanner": "Сканування", - "gtceu.subtitle.assembler": "Збирач конструює", - "gtceu.subtitle.centrifuge": "Центрифуга обертається", - "gtceu.subtitle.compressor": "Компресор віджимає", - "gtceu.subtitle.cut": "Різак дзижчить", - "gtceu.subtitle.electrolyzer": "Електролізер іскрить", - "gtceu.subtitle.forge_hammer": "Ковальський молот стукає", - "gtceu.subtitle.macerator": "Подрібнювач дробить", - "gtceu.subtitle.mixer": "Змішувач міксує", - "gtceu.subtitle.miner": "Шахтар видобуває", - "gtceu.subtitle.arc": "Дуги дзижчать", - "gtceu.subtitle.bath": "Ванна шипить", - "gtceu.subtitle.boiler": "Котел гріється", - "gtceu.subtitle.chainsaw": "Пила гуде", - "gtceu.subtitle.chemical": "Хімікати булькають", - "gtceu.subtitle.combustion": "Горіння", - "gtceu.subtitle.computation": "Комп'ютер тугодумає", - "gtceu.subtitle.metal_pipe": "Руйнування_металевого_стовпа_L_Хвилею_2_0_0.wav", - "gtceu.subtitle.drill": "Свердління", - "gtceu.subtitle.file": "Скрегіт напилка", - "gtceu.subtitle.fire": "Потріскування вогню", - "gtceu.subtitle.cooling": "Морозильник гуде", - "gtceu.subtitle.furnace": "Піч гріється", - "gtceu.subtitle.jet_engine": "Реактивне ревіння", - "gtceu.subtitle.mortar": "Ступка подрібнює", - "gtceu.subtitle.motor": "Двигун гуде", - "gtceu.subtitle.plunger": "Вантуз хлопає", - "gtceu.subtitle.portal_closing": "Портал закривається", - "gtceu.subtitle.portal_opening": "Портал відкривається", - "gtceu.subtitle.replicator": "Реплікатор копіює", - "gtceu.subtitle.science": "н а у к а", - "gtceu.subtitle.saw": "Пиляння", - "gtceu.subtitle.screwdriver": "Закручування", - "gtceu.subtitle.soft_hammer": "М'який тик", - "gtceu.subtitle.spray_can": "Обприскування", - "gtceu.subtitle.sus": "Підозріло...", - "gtceu.subtitle.turbine": "Свист турбіни", - "gtceu.subtitle.wirecutter": "Дріт рветься", - "gtceu.subtitle.wrench": "Ключ брязкає", - - "config.jade.plugin_gtceu.auto_output_info": "[GTCEu] Інфо автовиведення", - "config.jade.plugin_gtceu.cable_info": "[GTCEu] Інфо кабелів", - "config.jade.plugin_gtceu.controllable_provider": "[GTCEu] Контролювання", - "config.jade.plugin_gtceu.electric_container_provider": "[GTCEu] Електричний контейнер", - "config.jade.plugin_gtceu.exhaust_vent_info": "[GTCEu] Інфо витяжної вентиляції", - "config.jade.plugin_gtceu.hazard_cleaner_provider": "[GTCEu] Очисник загроз", - "config.jade.plugin_gtceu.machine_mode": "[GTCEu] Режим машини", - "config.jade.plugin_gtceu.maintenance_info": "[GTCEu] Інфо з обслуговування", - "config.jade.plugin_gtceu.me_pattern_buffer": "[GTCEu] Інфо буфера шаблонів", - "config.jade.plugin_gtceu.me_pattern_buffer_proxy": "[GTCEu] Інфо проксі буфера шаблонів", - "config.jade.plugin_gtceu.multiblock_structure": "[GTCEu] Мультиблочна конструкція", - "config.jade.plugin_gtceu.parallel_info": "[GTCEu] Інфо паралелізації", - "config.jade.plugin_gtceu.primitive_pump": "[GTCEu] Інфо примітивної помпи", - "config.jade.plugin_gtceu.recipe_logic_provider": "[GTCEu] Логіка рецептів", - "config.jade.plugin_gtceu.recipe_output_info": "[GTCEu] Інфо виводу рецептів", - "config.jade.plugin_gtceu.stained_color": "[GTCEu] Інфо заплямованого блоку", - "config.jade.plugin_gtceu.steam_boiler_info": "[GTCEu] Інфо парового котла", - "config.jade.plugin_gtceu.transformer": "[GTCEu] Інфо трансформатора", - "config.jade.plugin_gtceu.workable_provider": "[GTCEu] Обробка", - "config.gtceu.option.addLoot": "addLoot", - "config.gtceu.option.ae2": "ae2", - "config.gtceu.option.allUniqueStoneTypes": "allUniqueStoneTypes", - "config.gtceu.option.animationTime": "animationTime", - "config.gtceu.option.armorHud": "armorHud", - "config.gtceu.option.bedrockOreDistance": "bedrockOreDistance", - "config.gtceu.option.bedrockOreDropTagPrefix": "bedrockOreDropTagPrefix", - "config.gtceu.option.borderColor": "borderColor", - "config.gtceu.option.bronzeBoilerHeatSpeed": "bronzeBoilerHeatSpeed", - "config.gtceu.option.bronzeBoilerMaxTemperature": "bronzeBoilerMaxTemperature", - "config.gtceu.option.buttonAnchor": "buttonAnchor", - "config.gtceu.option.casingsPerCraft": "casingsPerCraft", - "config.gtceu.option.cleanMultiblocks": "cleanMultiblocks", - "config.gtceu.option.client": "client", - "config.gtceu.option.compat": "compat", - "config.gtceu.option.debug": "debug", - "config.gtceu.option.debugWorldgen": "debugWorldgen", - "config.gtceu.option.defaultPaintingColor": "defaultPaintingColor", - "config.gtceu.option.defaultUIColor": "defaultUIColor", - "config.gtceu.option.dev": "dev", - "config.gtceu.option.direction": "direction", - "config.gtceu.option.disableManualCompression": "disableManualCompression", - "config.gtceu.option.doBedrockOres": "doBedrockOres", - "config.gtceu.option.doSuperflatOres": "doSuperflatOres", - "config.gtceu.option.doesExplosionDamagesTerrain": "doesExplosionDamagesTerrain", - "config.gtceu.option.dumpAssets": "dumpAssets", - "config.gtceu.option.dumpRecipes": "dumpRecipes", - "config.gtceu.option.enableCleanroom": "enableCleanroom", - "config.gtceu.option.enableFEConverters": "enableFEConverters", - "config.gtceu.option.enableMaintenance": "enableMaintenance", - "config.gtceu.option.enableResearch": "enableResearch", - "config.gtceu.option.enableTieredCasings": "enableTieredCasings", - "config.gtceu.option.enableWorldAccelerators": "enableWorldAccelerators", - "config.gtceu.option.enchantedTools": "enchantedTools", - "config.gtceu.option.energy": "energy", - "config.gtceu.option.energyConsumption": "energyConsumption", - "config.gtceu.option.energyUsageMultiplier": "energyUsageMultiplier", - "config.gtceu.option.environmentalHazardDecayRate": "environmentalHazardDecayRate", - "config.gtceu.option.environmentalHazards": "environmentalHazards", - "config.gtceu.option.euToFeRatio": "euToFeRatio", - "config.gtceu.option.feToEuRatio": "feToEuRatio", - "config.gtceu.option.flintAndSteelRequireSteel": "flintAndSteelRequireSteel", - "config.gtceu.option.ftbChunksIntegration": "ftbChunksIntegration", - "config.gtceu.option.gameplay": "gameplay", - "config.gtceu.option.generateLowQualityGems": "generateLowQualityGems", - "config.gtceu.option.ghostCircuit": "ghostCircuit", - "config.gtceu.option.gt6StylePipesCables": "gt6StylePipesCables", - "config.gtceu.option.hardAdvancedIronRecipes": "hardAdvancedIronRecipes", - "config.gtceu.option.hardDyeRecipes": "hardDyeRecipes", - "config.gtceu.option.hardGlassRecipes": "hardGlassRecipes", - "config.gtceu.option.hardIronRecipes": "hardIronRecipes", - "config.gtceu.option.hardMiscRecipes": "hardMiscRecipes", - "config.gtceu.option.hardMultiRecipes": "hardMultiRecipes", - "config.gtceu.option.hardRedstoneRecipes": "hardRedstoneRecipes", - "config.gtceu.option.hardToolArmorRecipes": "hardToolArmorRecipes", - "config.gtceu.option.hardWoodRecipes": "hardWoodRecipes", - "config.gtceu.option.harderBrickRecipes": "harderBrickRecipes", - "config.gtceu.option.harderCharcoalRecipe": "harderCharcoalRecipe", - "config.gtceu.option.harderCircuitRecipes": "harderCircuitRecipes", - "config.gtceu.option.harderRods": "harderRods", - "config.gtceu.option.harmlessActiveTransformers": "harmlessActiveTransformers", - "config.gtceu.option.hazardsEnabled": "hazardsEnabled", - "config.gtceu.option.hideFacadesInRecipeViewer": "hideFacadesInRecipeViewer", - "config.gtceu.option.hideFilledCellsInRecipeViewer": "hideFilledCellsInRecipeViewer", - "config.gtceu.option.hideOreProcessingDiagrams": "hideOreProcessingDiagrams", - "config.gtceu.option.highTierContent": "highTierContent", - "config.gtceu.option.hpLiquidBoilerBaseOutput": "hpLiquidBoilerBaseOutput", - "config.gtceu.option.hpSolarBoilerBaseOutput": "hpSolarBoilerBaseOutput", - "config.gtceu.option.hpSolidBoilerBaseOutput": "hpSolidBoilerBaseOutput", - "config.gtceu.option.hudLocation": "hudLocation", - "config.gtceu.option.hudOffsetX": "hudOffsetX", - "config.gtceu.option.hudOffsetY": "hudOffsetY", - "config.gtceu.option.inWorldPreviewDuration": "inWorldPreviewDuration", - "config.gtceu.option.increaseDungeonLoot": "increaseDungeonLoot", - "config.gtceu.option.infiniteBedrockOresFluids": "infiniteBedrockOresFluids", - "config.gtceu.option.journeyMapIntegration": "journeyMapIntegration", - "config.gtceu.option.largeBoilers": "largeBoilers", - "config.gtceu.option.ldFluidPipeMinDistance": "ldFluidPipeMinDistance", - "config.gtceu.option.ldItemPipeMinDistance": "ldItemPipeMinDistance", - "config.gtceu.option.liquidBoilerBaseOutput": "liquidBoilerBaseOutput", - "config.gtceu.option.machineSounds": "machineSounds", - "config.gtceu.option.machines": "machines", - "config.gtceu.option.machinesEmissiveTextures": "machinesEmissiveTextures", - "config.gtceu.option.meHatchEnergyUsage": "meHatchEnergyUsage", - "config.gtceu.option.minimap": "minimap", - "config.gtceu.option.nanoSaber": "nanoSaber", - "config.gtceu.option.nanoSaberBaseDamage": "nanoSaberBaseDamage", - "config.gtceu.option.nanoSaberDamageBoost": "nanoSaberDamageBoost", - "config.gtceu.option.nativeEUToFE": "nativeEUToFE", - "config.gtceu.option.nerfPaperCrafting": "nerfPaperCrafting", - "config.gtceu.option.nerfWoodCrafting": "nerfWoodCrafting", - "config.gtceu.option.onlyOwnerBreak": "onlyOwnerBreak", - "config.gtceu.option.onlyOwnerGUI": "onlyOwnerGUI", - "config.gtceu.option.orderedAssemblyLineFluids": "orderedAssemblyLineFluids", - "config.gtceu.option.orderedAssemblyLineItems": "orderedAssemblyLineItems", - "config.gtceu.option.oreBlockProspectRange": "oreBlockProspectRange", - "config.gtceu.option.oreGenerationChunkCacheSize": "oreGenerationChunkCacheSize", - "config.gtceu.option.oreIconSize": "oreIconSize", - "config.gtceu.option.oreIndicatorChunkCacheSize": "oreIndicatorChunkCacheSize", - "config.gtceu.option.oreNamePrefix": "oreNamePrefix", - "config.gtceu.option.oreScaleStop": "oreScaleStop", - "config.gtceu.option.oreVeinGridSize": "oreVeinGridSize", - "config.gtceu.option.oreVeinRandomOffset": "oreVeinRandomOffset", - "config.gtceu.option.oreVeins": "oreVeins", - "config.gtceu.option.ownerOPBypass": "ownerOPBypass", - "config.gtceu.option.prospectorEnergyUseMultiplier": "prospectorEnergyUseMultiplier", - "config.gtceu.option.recipeProgressLowEnergy": "recipeProgressLowEnergy", - "config.gtceu.option.recipes": "recipes", - "config.gtceu.option.removeSmeltingForEBFMetals": "removeSmeltingForEBFMetals", - "config.gtceu.option.removeVanillaBlockRecipes": "removeVanillaBlockRecipes", - "config.gtceu.option.removeVanillaLargeOreVeins": "removeVanillaLargeOreVeins", - "config.gtceu.option.removeVanillaOreGen": "removeVanillaOreGen", - "config.gtceu.option.removeVanillaTNTRecipe": "removeVanillaTNTRecipe", - "config.gtceu.option.renderFluids": "renderFluids", - "config.gtceu.option.renderer": "renderer", - "config.gtceu.option.replaceMinedBlocksWith": "replaceMinedBlocksWith", - "config.gtceu.option.requireGTToolsForBlocks": "requireGTToolsForBlocks", - "config.gtceu.option.rightToolbar": "rightToolbar", - "config.gtceu.option.rngDamageElectricTools": "rngDamageElectricTools", - "config.gtceu.option.rubberTreeSpawnChance": "rubberTreeSpawnChance", - "config.gtceu.option.sandOresFall": "sandOresFall", - "config.gtceu.option.shouldWeatherOrTerrainExplosion": "shouldWeatherOrTerrainExplosion", - "config.gtceu.option.showDimensionTier": "showDimensionTier", - "config.gtceu.option.smallBoilers": "smallBoilers", - "config.gtceu.option.solarBoilerBaseOutput": "solarBoilerBaseOutput", - "config.gtceu.option.solidBoilerBaseOutput": "solidBoilerBaseOutput", - "config.gtceu.option.sprayCanChainLength": "sprayCanChainLength", - "config.gtceu.option.steamMultiParallelAmount": "steamMultiParallelAmount", - "config.gtceu.option.steamPerWater": "steamPerWater", - "config.gtceu.option.steelBoilerHeatSpeed": "steelBoilerHeatSpeed", - "config.gtceu.option.steelBoilerMaxTemperature": "steelBoilerMaxTemperature", - "config.gtceu.option.steelSteamMultiblocks": "steelSteamMultiblocks", - "config.gtceu.option.surfaceRockProspectRange": "surfaceRockProspectRange", - "config.gtceu.option.titaniumBoilerHeatSpeed": "titaniumBoilerHeatSpeed", - "config.gtceu.option.titaniumBoilerMaxTemperature": "titaniumBoilerMaxTemperature", - "config.gtceu.option.toggle": "toggle", - "config.gtceu.option.toolCraftingSounds": "toolCraftingSounds", - "config.gtceu.option.toolUseSounds": "toolUseSounds", - "config.gtceu.option.tools": "tools", - "config.gtceu.option.treeFellingDelay": "treeFellingDelay", - "config.gtceu.option.tungstensteelBoilerHeatSpeed": "tungstensteelBoilerHeatSpeed", - "config.gtceu.option.tungstensteelBoilerMaxTemperature": "tungstensteelBoilerMaxTemperature", - "config.gtceu.option.universalHazards": "universalHazards", - "config.gtceu.option.updateIntervals": "updateIntervals", - "config.gtceu.option.useVBO": "useVBO", - "config.gtceu.option.voltageTierAdvImpeller": "voltageTierAdvImpeller", - "config.gtceu.option.voltageTierAdvNanoSuit": "voltageTierAdvNanoSuit", - "config.gtceu.option.voltageTierAdvQuarkTech": "voltageTierAdvQuarkTech", - "config.gtceu.option.voltageTierImpeller": "voltageTierImpeller", - "config.gtceu.option.voltageTierNanoSuit": "voltageTierNanoSuit", - "config.gtceu.option.voltageTierNightVision": "voltageTierNightVision", - "config.gtceu.option.voltageTierQuarkTech": "voltageTierQuarkTech", - "config.gtceu.option.worldAcceleratorBlacklist": "worldAcceleratorBlacklist", - "config.gtceu.option.worldgen": "worldgen", - "config.gtceu.option.xOffset": "xOffset", - "config.gtceu.option.xaerosMapIntegration": "xaerosMapIntegration", - "config.gtceu.option.yOffset": "yOffset", - "config.gtceu.option.zombieSpawnWithSabers": "zombieSpawnWithSabers", - "gtceu.command.copy.click_to_copy": "Клацніть, щоб скопіювати", - "gtceu.command.copy.copied_and_click": "скопійовано в буфер обміну. Натисніть, щоб скопіювати ще раз", - "gtceu.command.copy.copied_end": "] до буфера обміну", - "gtceu.command.copy.copied_start": "Скопійовано [", - "gtceu.command.hand.electric": "Інформація про електрику: %d / %d EU - Tier: %d; Is Battery: %s", - "gtceu.command.hand.fluid": "Інформація про рідину: %d / %d мВ; Can Fill: %s; Can Drain: %s", - "gtceu.command.hand.fluid2": "Id рідини:", - "gtceu.command.hand.groovy": "Можливість використання§6 /gs hand", - "gtceu.command.hand.item_id": "Предмет: %s (метадані: %d)", - "gtceu.command.hand.material": "Id матеріалу:", - "gtceu.command.hand.meta_item": "Id метапредмету:", - "gtceu.command.hand.no_item": "Перед виконанням цієї команди ви повинні тримати щось в основній або іншій руці.", - "gtceu.command.hand.not_a_player": "Ця команда може бути виконана лише гравцем.", - "gtceu.command.hand.ore_prefix": "Префікс руди:", - "gtceu.command.hand.tag_entries": "§3Записи тегів:", - "gtceu.command.hand.tool_stats": "Класс характеристик інструмента: %s", - "gtceu.command.hand.usage": "Використання: /gtceu hand", - "gtceu.command.recipecheck.begin": "Починаємо перевірку конфлікту рецептів...", - "gtceu.command.recipecheck.end": "Перевірка конфліктів рецептів знайшла %d можливих конфліктів. Перевірте журнал сервера для отримання додаткової інформації", - "gtceu.command.recipecheck.end_no_conflicts": "Конфліктних рецептів не виявлено!", - "gtceu.command.recipecheck.usage": "Використання: /gtceu recipecheck", - "gtceu.command.usage": "Використання: /gtceu ", - "gtceu.command.worldgen.reload.failed": "Не вдалося перезавантажити генерацію світу. Перевірте консоль на наявність помилок.", - "gtceu.command.worldgen.reload.success": "Генерацію світу успішно перезавантажено з конфігурації.", - "gtceu.command.worldgen.reload.usage": "Використання: /gtceu worldgen reload", - "gtceu.command.worldgen.usage": "Використання: /gtceu worldgen ", - - "gtceu.key.armor_charging": "Перемикач заряджання інвентаря від броні", - "gtceu.key.armor_hover": "Перемикач наведення броні", - "gtceu.key.armor_mode_switch": "Перемикач режиму броні", - "gtceu.key.enable_boots": "Увімкнути посилений стрибок", - "gtceu.key.enable_jetpack": "Реактивний ранець", - "gtceu.key.tool_aoe_change": "Перемикач роботи по області інструменту", - - "cover.advanced_energy_detector.invert.disabled.0": "Вихід: Нормальний", - "cover.advanced_energy_detector.invert.disabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", - "cover.advanced_energy_detector.invert.disabled.3": "За замовчуванням, редстоун випромінюється, коли мінімальне значення EU менше, і припиняє випромінювання, коли максимальне значення EU перевищує мінімальне.", - "cover.advanced_energy_detector.invert.enabled.0": "Вихід: Інвертований", - "cover.advanced_energy_detector.invert.enabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", - "cover.advanced_energy_detector.invert.enabled.3": "За замовчуванням, редстоун випромінюється, коли мінімальне значення EU менше, і припиняє випромінювання, коли максимальне значення EU перевищує мінімальне.", - "cover.advanced_energy_detector.label": "Просунутий детектор енергії", - "cover.advanced_energy_detector.max": "Максимум", - "cover.advanced_energy_detector.min": "Мінімум", - "cover.advanced_energy_detector.use_percent.disabled.0": "Режим: Дискретний EU", - "cover.advanced_energy_detector.use_percent.disabled.2": "Change between using discrete EU values or percentages for comparing min/max against an attached energy storage.", - "cover.advanced_energy_detector.use_percent.enabled.0": "Режим: Percentage", - "cover.advanced_energy_detector.use_percent.enabled.2": "Change between using discrete EU values or percentages for comparing min/max against an attached energy storage.", - "cover.advanced_fluid_detector.invert.disabled.0": "Вихід: Нормальний", - "cover.advanced_fluid_detector.invert.disabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", - "cover.advanced_fluid_detector.invert.disabled.3": "За замовчуванням редстоун припиняє випромінювання, коли рівень рідини менший за мінімальний мВ, і починає випромінювати, коли рівень рідини більший за мінімальний мВ до встановленого максимуму.", - "cover.advanced_fluid_detector.invert.enabled.0": "Вихід: Інвертований", - "cover.advanced_fluid_detector.invert.enabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", - "cover.advanced_fluid_detector.invert.enabled.3": "За замовчуванням редстоун припиняє випромінювання, коли рівень рідини менший за мінімальний мВ, і починає випромінювати, коли рівень рідини більший за мінімальний мВ до встановленого максимуму.", - "cover.advanced_fluid_detector.label": "Просунутий детектор рідин", - "cover.advanced_fluid_detector.max": "Максимум рідини (мВ)", - "cover.advanced_fluid_detector.min": "Мінімум рідина (мВ)", - "cover.advanced_item_detector.invert.disabled.0": "Вихід: Нормальний", - "cover.advanced_item_detector.invert.disabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", - "cover.advanced_item_detector.invert.disabled.3": "За замовчуванням, редстоун припиняє випромінювання, коли кількість предметів менша за мінімальну, і починає випромінювати, коли кількість предметів більша за мінімальну, але не перевищує встановленого максимуму", - "cover.advanced_item_detector.invert.enabled.0": "Вихід: Інвертований", - "cover.advanced_item_detector.invert.enabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", - "cover.advanced_item_detector.invert.enabled.3": "За замовчуванням, редстоун припиняє випромінювання, коли кількість предметів менша за мінімальну, і починає випромінювати, коли кількість предметів більша за мінімальну, але не перевищує встановленого максимуму", - "cover.advanced_item_detector.label": "Просунутий дектектор предметів", - "cover.advanced_item_detector.max": "Максимум предметів", - "cover.advanced_item_detector.min": "Мінімум Items", - "cover.bucket.mode.bucket": "B", - "cover.bucket.mode.milli_bucket": "мВ", - "cover.conveyor.blocks_input.disabled.0": "Якщо увімкнено, предмети не вставлятимуться, коли кришку встановлено так, щоб втягувати предмети з інвентарю в трубу.", - "cover.conveyor.blocks_input.disabled.1": "§cВимкнено", - "cover.conveyor.blocks_input.enabled.0": "Якщо увімкнено, предмети не вставлятимуться, коли кришку встановлено так, щоб втягувати предмети з інвентарю в трубу.", - "cover.conveyor.blocks_input.enabled.1": "§aУвімкнено", - "cover.conveyor.distribution.insert_first.0": "Режим розповсюдження:§b Пріоритетний", - "cover.conveyor.distribution.insert_first.1": "§7Вставить до першого знайденого інвентарю з найвищим пріоритетом.", - "cover.conveyor.distribution.insert_first.2": "§7Обмежувальні предметні труби знижують пріоритет шляху.", - "cover.conveyor.distribution.round_robin_global.0": "Режим розповсюдження:§b Розділення", - "cover.conveyor.distribution.round_robin_global.1": "§7Розподіляє предмети порівну між під'єднаними інвентарями", - "cover.conveyor.distribution.round_robin_prio.0": "Режим розповсюдження:§b Пріорітетне розділення", - "cover.conveyor.distribution.round_robin_prio.1": "§7Намагається розділити предмети між пов'язаними інвентарями і спочатку розглядає шляхи з вищим пріоритетом.", - "cover.conveyor.distribution.round_robin_prio.2": "§7Обмежувальні предметні труби знижують пріоритет шляху.", - "cover.conveyor.item_filter.title": "Предметний фільтр", - "cover.conveyor.mode": "Режим: %s", - "cover.conveyor.mode.export": "Режим: Експорт", - "cover.conveyor.mode.import": "Режим: Імпорт", - "cover.conveyor.tag.title.0": "Тегове ім'я", - "cover.conveyor.tag.title.1": "(використовуйте * для підстановочного символу)", - "cover.conveyor.title": "Налаштування кришки конвеєра (%s)", - "cover.conveyor.transfer_rate": "§7предметів/с", - "cover.detector_base.message_inverted_state": "Статус моніторингу: Перевернутий", - "cover.detector_base.message_normal_state": "Статус моніторингу: Нормальний", - "cover.ender_fluid_link.incomplete_hex.0": "Введено неповний колір!", - "cover.ender_fluid_link.incomplete_hex.1": "Буде застосовано після завершення (всі 8 шістнадцяткових чисел)", - "cover.ender_fluid_link.incomplete_hex.2": "Закриття інтерфейсу скасує усі зміни!", - "cover.ender_fluid_link.iomode.disabled": "Ввід/вивід вимкнено", - "cover.ender_fluid_link.iomode.enabled": "Ввід/вивід увімкнено", - "cover.ender_fluid_link.private.tooltip.disabled.0": "Перехід у приватний режим резервуара", - "cover.ender_fluid_link.private.tooltip.disabled.1": "Приватний режим використовує гравець, який першим встановив кришку", - "cover.ender_fluid_link.private.tooltip.enabled": "Перехід у публічний режим резервуара", - "cover.ender_fluid_link.title": "Рідинний зв'язок Енду", - "cover.filter.blacklist.disabled": "Білий список", - "cover.filter.blacklist.enabled": "Чорний список", - "cover.filter.mode.filter_both": "Вставка/витягання фільтра", - "cover.filter.mode.filter_extract": "Витягнути фільтр", - "cover.filter.mode.filter_insert": "Вставка фільтра", - "cover.fluid.voiding.advanced.title": "Просунуте налаштування видалення рідини", - "cover.fluid.voiding.title": "Налаштування видалення рідини", - "cover.fluid_filter.config_amount.0": "Коліщатко вгору збільшує кількість, вниз - зменшує.", - "cover.fluid_filter.config_amount.1": "Shift[§6x10§r],Ctrl[§ex100§r],Shift+Ctrl[§ax1000§r]", - "cover.fluid_filter.config_amount.2": "ПКМ збільшує кількість, ЛКМ - зменшує.", - "cover.fluid_filter.config_amount.3": "Утримуйте Shift, щоб подвоїти/розділити.", - "cover.fluid_filter.config_amount.4": "Клацніть СКМ, щоб очистити", - "cover.fluid_filter.mode.filter_both": "Фільтр заповнення та спорожнення", - "cover.fluid_filter.mode.filter_drain": "Фільтр спорожнення", - "cover.fluid_filter.mode.filter_fill": "Фільтр заповнення", - "cover.fluid_filter.title": "Фільтр рідин", - "cover.fluid_regulator.keep_exact": "Зберігати точно: %s", - "cover.fluid_regulator.supply_exact": "Подавати точно: %s", - "cover.fluid_regulator.title": "Налаштування регулятора подачі рідини (%s)", - "cover.fluid_regulator.transfer_mode.description.0": "§eПодавати будь-як§r - у цьому режимі кришка подаватиме якомога більше рідин, що відповідають її фільтру.", - "cover.fluid_regulator.transfer_mode.description.1": "§eПодавати точно§r - у цьому режимі кришка подаватиме рідини порціями, вказаними у вікні під цією кнопкою. Блокує подачу меньшої кількості рідини, ніж зазначено порцією.", - "cover.fluid_regulator.transfer_mode.description.2": "§eУтримувати точно§r - у цьому режимі кришка буде зберігати вказану кількість рідин в призначеному інвентарі, доливаючи рідину, якщо це необхідно.", - "cover.fluid_regulator.transfer_mode.description.3": "§7Порада: Клацання із затиснутим Shift помножить крок зміни на 10, а клацання із Ctrl помножить крок на 100.", - "cover.item.voiding.advanced.title": "Просунуті налаштування знищення предметів", - "cover.item.voiding.title": "Налаштування знищення предметів", - "cover.item_filter.ignore_damage.disabled": "Враховувати шкоду", - "cover.item_filter.ignore_damage.enabled": "Ігнорувати шкоду", - "cover.item_filter.ignore_nbt.disabled": "Враховувати NBT", - "cover.item_filter.ignore_nbt.enabled": "Ігнорувати NBT", - "cover.item_filter.title": "Фільтр предметів", - "cover.item_smart_filter.filtering_mode.description.0": "Виберіть машину, яку буде використовувати розумний фільтр для фільтрації.", - "cover.item_smart_filter.filtering_mode.description.1": "Він автоматично вибере потрібні обсяги предметів для маніпулятора.", - "cover.item_smart_filter.title": "Розумний фільтр предметів", - "cover.machine_controller.invert.disabled.0": "§eНормальний§r - у цьому режимі для запуску кришка потребує слабшого сигналу редстоуна, ніж встановлений рівень", - "cover.machine_controller.invert.enabled.0": "§eІнвертований§r - у цьому режимі для запуску кришки потребує сильнішого сигналу редстоуна, ніж встановлений рівень", - "cover.machine_controller.inverted": "Інвертований", - "cover.machine_controller.mode.cover_down": "Кришка управління (низ)", - "cover.machine_controller.mode.cover_east": "Контрольна кришка (схід)", - "cover.machine_controller.mode.cover_north": "Контрольна кришка (північ)", - "cover.machine_controller.mode.cover_south": "Контрольна кришка (південь)", - "cover.machine_controller.mode.cover_up": "Кришка (верх)", - "cover.machine_controller.mode.cover_west": "Кришка управління (захід)", - "cover.machine_controller.mode.machine": "Контрольна машина", - "cover.machine_controller.normal": "Нормальний", - "cover.machine_controller.redstone": "Мінімальний рівень редстоунового живлення: %d", - "cover.machine_controller.title": "Налаштування контролера машини", - "cover.pump.fluid_filter.title": "Фільтр рідин", - "cover.pump.mode.export": "Режим: витягування", - "cover.pump.mode.import": "Режим: вставка", - "cover.pump.title": "Налаштування кришки помпи (%s)", - "cover.pump.transfer_rate": "%s", - "cover.robotic_arm.title": "Налаштування маніпулятора (%s)", - "cover.robotic_arm.transfer_mode.description.0": "§eПодавати будь-як§r - у цьому режимі кришка буде переносити якомога більше предметів, що відповідають її фільтру.", - "cover.robotic_arm.transfer_mode.description.1": "§eПодавати точно§r - у цьому режимі кришка постачатиме предмети порціями, зазначеними у слотах фільтра предметів (або змінною під цією кнопкою для фільтра міток). Блокує подачу меньшої кількості предметів, ніж зазначено порцією.", - "cover.robotic_arm.transfer_mode.description.2": "§eУтримувати точно§r - у цьому режимі кришка буде зберігати вказану кількість предметів в інвентарі призначення, постачаючи додаткову кількість предметів, якщо це необхідно.", - "cover.robotic_arm.transfer_mode.description.3": "§7Порада: клацайте ЛКМ/ПКМ на слотах фільтра, щоб змінити кількість предметів, клацайте крадькома, щоб змінювати кількість швидше.", - "cover.robotic_arm.transfer_mode.keep_exact": "Утримувати точно", - "cover.robotic_arm.transfer_mode.transfer_any": "Подавати будь-як", - "cover.robotic_arm.transfer_mode.transfer_exact": "Подавати точно", - "cover.shutter.message.disabled": "Затвор відкрито", - "cover.shutter.message.enabled": "Затвор закрито", - "cover.storage.title": "Кришка сховища", - "cover.tag_filter.info.0": "§bПриймає складні вирази", - "cover.tag_filter.info.1": "§6a & b§r = AND", - "cover.tag_filter.info.10": "§bПриклад:§6 *dusts/gold | (gtceu:circuits & !*lv)", - "cover.tag_filter.info.11": "Перебирає увесь золотий пил або всі схеми, окрім lv", - "cover.tag_filter.info.2": "§6a | b§r = OR", - "cover.tag_filter.info.3": "§6a ^ b§r = XOR", - "cover.tag_filter.info.4": "§6!a§r = NOT", - "cover.tag_filter.info.5": "§6(a)§r для групування", - "cover.tag_filter.info.6": "§6*§r для підстановки", - "cover.tag_filter.info.7": "§6$§r без тегів", - "cover.tag_filter.info.8": "§bТеги мають вигляд 'namespace:tag/subtype'.", - "cover.tag_filter.info.9": "Простір назв 'forge:' передбачається, якщо його не вказано.", - "cover.tag_filter.matches": "Предмет збігається", - "cover.tag_filter.matches_not": "Предмет не збігається", - "cover.tag_filter.test_slot.info": "Вставте предмет, щоб перевірити, чи відповідає він виразу фільтра", - "cover.tag_filter.title": "Фільтр тегів", - "cover.universal.manual_import_export.mode.description.0": "§eВимкнено§r - Предмети/рідини переміщуватимуться лише так, як визначено кришкою та її фільтром. ", - "cover.universal.manual_import_export.mode.description.1": "§eДозволити фільтрований§r - поки відповідає фільтру кришки, предмети/рідини можна витягувати та вставляти незалежно від її режиму (якщо такий є). ", - "cover.universal.manual_import_export.mode.description.2": "§eДозволити нефільтрований§r - предмети/рідини можна переміщувати незалежно від режиму кришки. Фільтр застосовується до предметів, вставлених або витягнутих за допомогою цієї кришки", - "cover.universal.manual_import_export.mode.disabled": "Ручний ввід/вивід:§b Вимкнено\n§7Предмети/рідини переміщуватимуться лише так, як визначено кришкою та її фільтром.", - "cover.universal.manual_import_export.mode.filtered": "Ручний ввід/вивід:§b Фільтрований\n§7поки відповідає фільтру кришки, предмети/рідини можна витягувати та вставляти незалежно від її режиму (якщо такий є)", - "cover.universal.manual_import_export.mode.unfiltered": "Ручний ввід/вивід:§b Нефільтрований\n§7Предмети/рідини можна переміщувати незалежно від режиму кришки. Фільтр застосовується лише до того, що вставляється або витягується самою кришкою.", - "cover.voiding.label.disabled": "Вимкнено", - "cover.voiding.label.enabled": "Увімкнено", - "cover.voiding.message.disabled": "Кришку знищення вимкнено", - "cover.voiding.message.enabled": "Кришку знищення увімкнено", - "cover.voiding.tooltip": "§УВАГА! §7 Встановлення цього параметра на «Увімкнено» означає, що рідини або предмети БУДУТЬ знищені.", - "cover.voiding.voiding_mode.description.0": "§eЗнищувати відповідне§r знищує все, що відповідає фільтру. ", - "cover.voiding.voiding_mode.description.1": "§eЗнищувати до межі§r знищує все, що відповідає фільтру, до вказаної кількості.", - "cover.voiding.voiding_mode.void_any": "Знищувати відповідне", - "cover.voiding.voiding_mode.void_overflow": "Знищувати до межі", - - "gtceu.multiblock.charcoal_pile.description.1": "", - "gtceu.multiblock.charcoal_pile.description.3": "", - "gtceu.multiblock.primitive_water_pump.extra2.4": "", - "cover.advanced_energy_detector.invert.disabled.1": "", - "cover.advanced_energy_detector.invert.enabled.1": "", - "cover.advanced_energy_detector.use_percent.disabled.1": "", - "cover.advanced_energy_detector.use_percent.enabled.1": "", - "cover.advanced_fluid_detector.invert.disabled.1": "", - "cover.advanced_fluid_detector.invert.enabled.1": "", - "cover.advanced_item_detector.invert.disabled.1": "", - "cover.advanced_item_detector.invert.enabled.1": "" + "translators": "discord: tenwoc, roll_54, metenbouldry1749. for minestar.com.ua", + "behavior.data_item.data": "-§a %s", + "behavior.data_item.title": "§nДані про конструкцію «%s»:", + "behavior.item_magnet.disabled": "§cМагнітне поле вимкнено", + "behavior.item_magnet.enabled": "§aМагнітне поле увімкнено", + "behavior.portable_scanner.amp_per_sec": "В середньому (за останню секунду): %s A", + "behavior.portable_scanner.bedrock_fluid.amount": "Розміщена рідина: %s %s - %s%%", + "behavior.portable_scanner.bedrock_fluid.amount_unknown": "Розміщена рідина: %s%%", + "behavior.portable_scanner.bedrock_fluid.nothing": "Розміщена рідина:§6 Нічого§r", + "behavior.portable_scanner.block_hardness": "Твердість: %s захист від вибухів: %s", + "behavior.portable_scanner.block_name": "Назва: %s Метадані: %s", + "behavior.portable_scanner.debug_cpu_load": "Середнє завантаження процесора ~%sнс протягом %s тактів з найгіршим часом %sнс.", + "behavior.portable_scanner.debug_cpu_load_seconds": "Це %s секунд.", + "behavior.portable_scanner.debug_lag_count": "Попередження про затримку %s (все, що триває довше, ніж %sмс) на сервері.", + "behavior.portable_scanner.debug_machine": "Мета-ID: %s", + "behavior.portable_scanner.debug_machine_invalid": " недійсний!", + "behavior.portable_scanner.debug_machine_invalid_null=invalid! MetaTileEntity =": " null!", + "behavior.portable_scanner.debug_machine_valid": " дійсний", + "behavior.portable_scanner.divider": "=========================", + "behavior.portable_scanner.energy_container_in": "Макс. Вхід: %s (%s) EU з %s A", + "behavior.portable_scanner.energy_container_out": "Макс. Вихід: %s (%s) EU з %s A", + "behavior.portable_scanner.energy_container_storage": "Енергія: %s EU / %s EU", + "behavior.portable_scanner.environmental_hazard": "Екологічна небезпека у чанку: %s§r - %s ppm", + "behavior.portable_scanner.environmental_hazard.nothing": "Екологічна небезпека у чанку:§6 відсутня§r", + "behavior.portable_scanner.eu_per_sec": "В середньому (за останню секунду): %s EU/т", + "behavior.portable_scanner.guild_name": "§2Ім'я гільдії: %s§r", + "behavior.portable_scanner.local_hazard": "Місцева небезпека в регіоні: %s§r - %s ppm", + "behavior.portable_scanner.local_hazard.nothing": "Місцева небезпека в регіоні:§6 відсутня§r", + "behavior.portable_scanner.machine_disabled": "Вимкнено.", + "behavior.portable_scanner.machine_front_facing": "Лицьовий бік: %s", + "behavior.portable_scanner.machine_ownership": "§2Тип власника машини: %s§r", + "behavior.portable_scanner.machine_power_loss": "Вимкнено через втрату живлення.", + "behavior.portable_scanner.machine_progress": "Обробка/завантаження: %s / %s", + "behavior.portable_scanner.machine_upwards_facing": "Верхній бік: %s", + "behavior.portable_scanner.mode.caption": "Режим відображення: %s", + "behavior.portable_scanner.mode.show_all_info": "Показувати всю інформацію", + "behavior.portable_scanner.mode.show_block_info": "Показувати інформацію про блок", + "behavior.portable_scanner.mode.show_electrical_info": "Показувати інженерну інформацію", + "behavior.portable_scanner.mode.show_environmental_info": "Показувати інформацію про довкілля", + "behavior.portable_scanner.mode.show_machine_info": "Показувати інформацію про машину", + "behavior.portable_scanner.mode.show_recipe_info": "Показувати інформацію про рецепт", + "behavior.portable_scanner.muffled": "Заглушено.", + "behavior.portable_scanner.multiblock_energy_input": "Макс. подача енергії: %s EU/т рівень: %s", + "behavior.portable_scanner.multiblock_energy_output": "Макс. Вихід енергії: %s EU/т рівень: %s", + "behavior.portable_scanner.multiblock_maintenance": "Проблеми: %s", + "behavior.portable_scanner.multiblock_parallel": "Паралельна обробка: %s", + "behavior.portable_scanner.player_name": "§2Ім'я гравця: %s§r,§7 гравець у мережі: %s§r", + "behavior.portable_scanner.position": "----- X: %s Y: %s Z: %s в: %s -----", + "behavior.portable_scanner.state": "%s: %s", + "behavior.portable_scanner.tank": "Резервуар %s: %s мВ / %s мВ %s", + "behavior.portable_scanner.tanks_empty": "Усі резервуари порожні", + "behavior.portable_scanner.team_name": "§2Назва команди: %s§r", + "behavior.portable_scanner.workable_consumption": "Ймовірно споживає: %s EU/т з %s A", + "behavior.portable_scanner.workable_production": "Ймовірно виробляє: %s EU/т з %s A", + "behavior.portable_scanner.workable_progress": "Прогрес: %s s / %s s", + "behavior.portable_scanner.workable_stored_energy": "Збережена енергія: %s EU / %s EU", + "behavior.prospector.added_waypoint": "Створено маршрутну точку з іменем %s!", + "behavior.prospector.not_enough_energy": "Недостатньо енергії!", + "behavior.toggle_energy_consumer.tooltip": "Використовуйте крадькома для перемикання режиму", + "behaviour.boor.by": " %s", + "behaviour.hammer": "Перемикає заглушення машин (тицянням по ним)", + "behaviour.hoe": "Може орати ґрунт", + "behaviour.lighter.fluid.tooltip": "Може підпалювати речі за допомогою бутану або пропану", + "behaviour.lighter.tooltip.description": "Може підпалювати речі", + "behaviour.lighter.tooltip.usage": "Shift+ПКМ, щоб відкрити/закрити", + "behaviour.lighter.uses": "Використань: %d", + "behaviour.meta.machine.config.copy.tooltip": "§7ПКМ, щоб скопіювати конфігурацію машини", + "behaviour.meta.machine.config.paste.tooltip": "§7ПКМ, щоб вставити конфігурацію машини", + "behaviour.paintspray.black.tooltip": "Фарбує речі в чорний", + "behaviour.paintspray.blue.tooltip": "Фарбує речі в синій", + "behaviour.paintspray.brown.tooltip": "Фарбує речі в коричневий", + "behaviour.paintspray.cyan.tooltip": "Фарбує речі в бірюзовий", + "behaviour.paintspray.gray.tooltip": "Фарбує речі в сірий", + "behaviour.paintspray.green.tooltip": "Фарбує речі в зелений", + "behaviour.paintspray.light_blue.tooltip": "Фарбує речі в блакитний", + "behaviour.paintspray.light_gray.tooltip": "Фарбує речі в світло-сірий", + "behaviour.paintspray.lime.tooltip": "Фарбує речі в лаймовий", + "behaviour.paintspray.magenta.tooltip": "Фарбує речі в пурпурний", + "behaviour.paintspray.orange.tooltip": "Фарбує речі в помаранчевий", + "behaviour.paintspray.pink.tooltip": "Фарбує речі в рожевий", + "behaviour.paintspray.purple.tooltip": "Фарбує речі в фіолетовий", + "behaviour.paintspray.red.tooltip": "Фарбує речі в червоний", + "behaviour.paintspray.solvent.tooltip": "Вибілює речі", + "behaviour.paintspray.uses": "Використань: %d", + "behaviour.paintspray.white.tooltip": "Фарбує речі в білий", + "behaviour.paintspray.yellow.tooltip": "Фарбує речі в жовтий", + "behaviour.prospecting": "Використовується для геологорозвідки", + "behaviour.setting.allow.input.from.output.tooltip": "%s вхід з вихідної сторони %s", + "behaviour.setting.item_auto_output.tooltip": "%s автовиведення is %s", + "behaviour.setting.muffled.tooltip": "Глушить %s", + "behaviour.setting.output.direction.tooltip": "%s напрям виведення: %s", + "behaviour.soft_hammer": "Запускає та зупиняє машини", + "behaviour.soft_hammer.disabled": "Робота зупинена", + "behaviour.soft_hammer.disabled_cycle": "Робота зупиниться по завершенню поточного циклу", + "behaviour.soft_hammer.enabled": "Робота відновлена", + "behaviour.wrench": "Повертає блоки клацанням ПКМ", + "block.filter_casing.tooltip": "Створює§a вільне від частинок§7 середовище", + "block.gtceu.acid_hazard_sign_block": "Блок зі знаком кислотної небезпеки", + "block.gtceu.active_transformer": "Активний трансформатор", + "block.gtceu.advanced_computer_casing": "Вдосконалений комп'ютерний корпус", + "block.gtceu.advanced_data_access_hatch": "Вдосконалений люк доступу до даних", + "block.gtceu.advanced_monitor": "Вдосконалений монітор", + "block.gtceu.alloy_blast_smelter": "Доменна плавильня сплавів", + "block.gtceu.aluminium_crate": "Алюмінієвий ящик", + "block.gtceu.aluminium_drum": "Алюмінієва бочка", + "block.gtceu.antimatter_hazard_sign_block": "Блок зі знаком антиматеріальної небезпеки", + "block.gtceu.assembly_line": "Конвеєрна лінія", + "block.gtceu.assembly_line_casing": "Корпус конвеєрної лінії", + "block.gtceu.assembly_line_grating": "Решітка конвеєрної лінії", + "block.gtceu.assembly_line_unit": "Конвеєрний контролювальний корпус", + "block.gtceu.atomic_casing": "Атомний корпус", + "block.gtceu.auto_maintenance_hatch": "Автоматичний люк техобслуговування", + "block.gtceu.basic_data_access_hatch": "Базовий люк доступу до даних", + "block.gtceu.bio_hazard_sign_block": "Блок зі знаком біонебезпеки", + "block.gtceu.black_borderless_lamp": "Чорна необлямована лампа", + "block.gtceu.black_lamp": "Чорна лампа", + "block.gtceu.black_large_metal_sheet": "Чорне велике металеве покриття", + "block.gtceu.black_metal_sheet": "Чорне металеве покриття", + "block.gtceu.black_studs": "Чорні кубики", + "block.gtceu.blue_borderless_lamp": "Синя необлямована лампа", + "block.gtceu.blue_lamp": "Синя лампа", + "block.gtceu.blue_large_metal_sheet": "Синє велике металеве покриття", + "block.gtceu.blue_metal_sheet": "Синє металеве покриття", + "block.gtceu.blue_studs": "Сині кубики", + "block.gtceu.boss_hazard_sign_block": "Блок зі знаком босової небезпеки", + "block.gtceu.brittle_charcoal": "Крихке деревне вугілля", + "block.gtceu.bronze_brick_casing": "Мурований бронзовий корпус", + "block.gtceu.bronze_crate": "Бронзовий ящик", + "block.gtceu.bronze_drum": "Бронзова бочка", + "block.gtceu.bronze_firebox_casing": "Бронзова топка", + "block.gtceu.bronze_gearbox": "Бронзовий редукторний корпус", + "block.gtceu.bronze_large_boiler": "Великий бронзовий котел", + "block.gtceu.bronze_machine_casing": "Бронзовий корпус машини", + "block.gtceu.bronze_multiblock_tank": "Бронзовий багатоблочний резервуар", + "block.gtceu.bronze_pipe_casing": "Бронзовий трубний корпус", + "block.gtceu.bronze_tank_valve": "Бронзовий рідинний вентиль", + "block.gtceu.brown_borderless_lamp": "Коричнева необлямована лампа", + "block.gtceu.brown_lamp": "Коричнева лампа", + "block.gtceu.brown_large_metal_sheet": "Коричневе велике металеве покриття", + "block.gtceu.brown_metal_sheet": "Коричневе металеве покриття", + "block.gtceu.brown_studs": "Коричневі кубики", + "block.gtceu.casing_coke_bricks": "Цегла коксової печі", + "block.gtceu.casing_grate": "Заґратований корпус машини", + "block.gtceu.causality_hazard_sign_block": "Блок зі знаком причинно-наслідкової небезпеки", + "block.gtceu.central_monitor": "Центральний монітор", + "block.gtceu.charcoal_pile_igniter": "Запалювач вугільної купи", + "block.gtceu.chiseled_dark_concrete": "Різьблений темний бетон", + "block.gtceu.chiseled_light_concrete": "Різьблений світлий бетон", + "block.gtceu.chiseled_marble": "Різьблений мармур", + "block.gtceu.chiseled_red_granite": "Різьблений червоний граніт", + "block.gtceu.clean_machine_casing": "Чистий нержавіючий сталевий корпус", + "block.gtceu.cleaning_maintenance_hatch": "Очищальний люк техобслуговування", + "block.gtceu.cleanroom": "Чиста кімната", + "block.gtceu.cleanroom_glass": "Скло чистої кімнати", + "block.gtceu.coke_oven": "Коксова піч", + "block.gtceu.coke_oven_bricks": "Цегла коксової печі", + "block.gtceu.coke_oven_hatch": "Люк коксової печі", + "block.gtceu.computation_receiver_hatch": "Оптичний люк приймання обчислень", + "block.gtceu.computation_transmitter_hatch": "Оптичний люк трансмісії обчислень", + "block.gtceu.computer_casing": "Комп'ютерний корпус", + "block.gtceu.computer_heat_vent": "Комп'ютерний тепловідвід", + "block.gtceu.configurable_maintenance_hatch": "Налаштовний люк техобслуговування", + "block.gtceu.corrosion_proof_casing": "Антикорозійний корпус", + "block.gtceu.cracked_dark_concrete_bricks": "Тріснута темна бетонна цегла", + "block.gtceu.cracked_light_concrete_bricks": "Тріснута світла бетонна цегла", + "block.gtceu.cracked_marble_bricks": "Тріснута мармурова цегла", + "block.gtceu.cracked_red_granite_bricks": "Тріснута червоногранітна цегла", + "block.gtceu.cracker": "Крекер", + "block.gtceu.creative_chest": "Творча скриня", + "block.gtceu.creative_computation_provider": "Творчий постачальник обчислень", + "block.gtceu.creative_data_access_hatch": "Творчий люк доступу до даних", + "block.gtceu.creative_energy": "Творче джерело енергії", + "block.gtceu.creative_tank": "Творчий резервуар", + "block.gtceu.creosote": "Креозот", + "block.gtceu.crushing_wheels": "Подрібнювальні колеса", + "block.gtceu.cupronickel_coil_block": "Блок мельхіорової котушки", + "block.gtceu.cyan_borderless_lamp": "Бірюзова необлямована лампа", + "block.gtceu.cyan_lamp": "Бірюзова лампа", + "block.gtceu.cyan_large_metal_sheet": "Бірюзове велике металеве покриття", + "block.gtceu.cyan_metal_sheet": "Бірюзове металеве покриття", + "block.gtceu.cyan_studs": "Бірюзові кубики", + "block.gtceu.dark_concrete": "Темний бетон", + "block.gtceu.dark_concrete_bricks": "Темна бетонна цегла", + "block.gtceu.dark_concrete_cobblestone": "Темний бетонний кругляк", + "block.gtceu.dark_concrete_small_tile": "Темні бетонні дрібні кахлі", + "block.gtceu.dark_concrete_tile": "Темні бетонні кахлі", + "block.gtceu.dark_concrete_windmill_a": "Темний бетонний вітряк A", + "block.gtceu.dark_concrete_windmill_b": "Темний бетонний вітряк B", + "block.gtceu.data_access_hatch": "Люк доступу до даних", + "block.gtceu.data_bank": "База даних", + "block.gtceu.data_receiver_hatch": "Оптичний люк приймання даних", + "block.gtceu.data_transmitter_hatch": "Оптичний люк трансмісії даних", + "block.gtceu.distillation_tower": "Дистиляційна вежа", + "block.gtceu.electric_blast_furnace": "Електрична доменна піч", + "block.gtceu.electrolytic_cell": "Електролітична комірка", + "block.gtceu.empty_tier_i_battery": "Порожній акумулятор I рівня", + "block.gtceu.empty_tier_ii_battery": "Порожній акумулятор II рівня", + "block.gtceu.empty_tier_iii_battery": "Порожній акумулятор III рівня", + "block.gtceu.engine_intake_casing": "Впускний корпус двигуна", + "block.gtceu.ev_16a_energy_converter": "§5EV§r 16§eA§r енергетичний конвертер", + "block.gtceu.ev_1a_energy_converter": "§5EV§r 1§eA§r енергетичний конвертер", + "block.gtceu.ev_4a_energy_converter": "§5EV§r 4§eA§r енергетичний конвертер", + "block.gtceu.ev_8a_energy_converter": "§5EV§r 8§eA§r енергетичний конвертер", + "block.gtceu.ev_air_scrubber": "§5Вдосконалений очисник повітря III§r", + "block.gtceu.ev_alloy_smelter": "§5Вдосконалена плавильня сплавів III§r", + "block.gtceu.ev_arc_furnace": "§5Вдосконалена дугова піч III§r", + "block.gtceu.ev_assembler": "§5Вдосконалений збирач III§r", + "block.gtceu.ev_autoclave": "§5Вдосконалений автоклав III§r", + "block.gtceu.ev_battery_buffer_16x": "§5Екстремальна напруга§r 16x акумуляторний буфер", + "block.gtceu.ev_battery_buffer_4x": "§5Екстремальна напруга§r 4x акумуляторний буфер", + "block.gtceu.ev_battery_buffer_8x": "§5Екстремальна напруга§r 8x акумуляторний буфер", + "block.gtceu.ev_bedrock_ore_miner": "§5Вдосконалений глибокореневий бур III§r", + "block.gtceu.ev_bender": "§5Вдосконалений згинач III§r", + "block.gtceu.ev_block_breaker": "§5Вдосконалений руйнівник блоків III§r", + "block.gtceu.ev_brewery": "§5Вдосконалений варильник III§r", + "block.gtceu.ev_canner": "§5Вдосконалений пакувальник III§r", + "block.gtceu.ev_centrifuge": "§5Вдосконалена центрифуга III§r", + "block.gtceu.ev_charger_4x": "§5Екстремальна напруга§r 4x турбозарядник", + "block.gtceu.ev_chemical_bath": "§5Вдосконалена хімічна ванна III§r", + "block.gtceu.ev_chemical_reactor": "§5Вдосконалений хімічний реактор III§r", + "block.gtceu.ev_circuit_assembler": "§5Вдосконалений схемотехнічний збирач III§r", + "block.gtceu.ev_compressor": "§5Вдосконалений компресор III§r", + "block.gtceu.ev_cutter": "§5Вдосконалений різак III§r", + "block.gtceu.ev_diode": "§5EV діод", + "block.gtceu.ev_distillery": "§5Вдосконалений дистилятор III§r", + "block.gtceu.ev_electric_furnace": "§5Вдосконалена електрична піч III§r", + "block.gtceu.ev_electrolyzer": "§5Вдосконалений електролізер III§r", + "block.gtceu.ev_electromagnetic_separator": "§5Вдосконалений електромагнітний сепаратор III§r", + "block.gtceu.ev_energy_input_hatch": "§5EV енергетичний люк", + "block.gtceu.ev_energy_input_hatch_16a": "§5EV 16A енергетичний люк", + "block.gtceu.ev_energy_input_hatch_4a": "§5EV 4A енергетичний люк", + "block.gtceu.ev_energy_output_hatch": "§5EV динамо-люк", + "block.gtceu.ev_energy_output_hatch_16a": "§5EV 16A динамо-люк", + "block.gtceu.ev_energy_output_hatch_4a": "§5EV 4A динамо-люк", + "block.gtceu.ev_extractor": "§5Вдосконалений екстрактор III§r", + "block.gtceu.ev_extruder": "§5Вдосконалений екструдер III§r", + "block.gtceu.ev_fermenter": "§5Вдосконалений ферментатор III§r", + "block.gtceu.ev_fisher": "§5Вдосконалений рибалка III§r", + "block.gtceu.ev_fluid_drilling_rig": "§5Вдосконалена рідинна бурова установка III§r", + "block.gtceu.ev_fluid_heater": "§5Вдосконалений рідинний нагрівач III§r", + "block.gtceu.ev_fluid_passthrough_hatch": "§5EV прохідний рідинний люк", + "block.gtceu.ev_fluid_solidifier": "§5Вдосконалений рідинний затверджувач III§r", + "block.gtceu.ev_forge_hammer": "§5Вдосконалений ковальський молот III§r", + "block.gtceu.ev_forming_press": "§5Вдосконалений формовий прес III§r", + "block.gtceu.ev_gas_collector": "§5Вдосконалений газозбірник III§r", + "block.gtceu.ev_hermetic_casing": "Герметичний корпус IV", + "block.gtceu.ev_input_bus": "§5EV вхідна шина", + "block.gtceu.ev_input_hatch": "§5EV ввідний люк", + "block.gtceu.ev_input_hatch_4x": "§5EV чотирикамерний ввідний люк", + "block.gtceu.ev_input_hatch_9x": "§5EV дев'ятикамерний ввідний люк", + "block.gtceu.ev_item_collector": "§5Вдосконалений предметний збирач III§r", + "block.gtceu.ev_item_passthrough_hatch": "§5EV прохідний предметний люк", + "block.gtceu.ev_lapotronic_battery": "EV лапотронний акумулятор", + "block.gtceu.ev_large_miner": "§5Вдосконалений великий бур III§r", + "block.gtceu.ev_laser_engraver": "§5Вдосконалений літограф III§r", + "block.gtceu.ev_lathe": "§5Вдосконалений токар III§r", + "block.gtceu.ev_macerator": "§5Вдосконалений подрібнювач III§r", + "block.gtceu.ev_machine_casing": "EV корпус машини", + "block.gtceu.ev_machine_hull": "§5EV§f машинна основа", + "block.gtceu.ev_mixer": "§5Вдосконалений змішувач III§r", + "block.gtceu.ev_muffler_hatch": "Люк вихлопу§5 EV", + "block.gtceu.ev_ore_washer": "§5Вдосконалений рудопромивач III§r", + "block.gtceu.ev_output_bus": "§5EV вихідна шина", + "block.gtceu.ev_output_hatch": "§5EV вивідний люк", + "block.gtceu.ev_output_hatch_4x": "§5EV чотирикамерний вивідний люк", + "block.gtceu.ev_output_hatch_9x": "§5EV дев'ятикамерний вивідний люк", + "block.gtceu.ev_packer": "§5Вдосконалений пакувальник III§r", + "block.gtceu.ev_polarizer": "§5Вдосконалений намагнічувач III§r", + "block.gtceu.ev_pump": "§5Вдосконалена помпа III§r", + "block.gtceu.ev_rock_crusher": "§5Вдосконалена кам'яна дробарка III§r", + "block.gtceu.ev_rotor_holder": "§5EV тримач ротора", + "block.gtceu.ev_scanner": "§5Вдосконалений сканер III§r", + "block.gtceu.ev_sifter": "§5Вдосконалений просіювач III§r", + "block.gtceu.ev_substation_input_hatch_64a": "§5EV 64A енергетичний люк підстанції", + "block.gtceu.ev_substation_output_hatch_64a": "§5EV 64A динамо-люк підстанції", + "block.gtceu.ev_super_chest": "Суперскриня IV", + "block.gtceu.ev_super_tank": "Суперрезервуар IV", + "block.gtceu.ev_thermal_centrifuge": "§5Вдосконалена термічна центрифуга III§r", + "block.gtceu.ev_transformer_16a": "§5Екстремальна напруга§r Силовий трансформатор", + "block.gtceu.ev_transformer_1a": "§5Екстремальна напруга§r Трансформатор", + "block.gtceu.ev_transformer_2a": "§5Екстремальна напруга§r Трансформатор високого струму (2x)", + "block.gtceu.ev_transformer_4a": "§5Екстремальна напруга§r Трансформатор високого струму (4x)", + "block.gtceu.ev_wiremill": "§5Вдосконалений волок III§r", + "block.gtceu.ev_world_accelerator": "§5Вдосконалений світовий прискорювач III§r", + "block.gtceu.explosion_hazard_sign_block": "Блок зі знаком вибухової небезпеки", + "block.gtceu.explosive.breaking_tooltip": "Вибухає від зламу, ламайте крадькома, щоб добути", + "block.gtceu.explosive.lighting_tooltip": "Не можна запалити редстоуном", + "block.gtceu.extreme_combustion_engine": "Екстремальний двигун внутрішнього згоряння", + "block.gtceu.extreme_engine_intake_casing": "Екстремальний впускний корпус двигуна", + "block.gtceu.filter_casing": "Фільтрувальний корпус", + "block.gtceu.fire_hazard_sign_block": "Блок зі знаком вогневої небезпеки", + "block.gtceu.firebricks": "Шамотна цегла", + "block.gtceu.foam": "Піна", + "block.gtceu.frost_hazard_sign_block": "Блок зі знаком морозної небезпеки", + "block.gtceu.frostproof_machine_casing": "Морозостійкий алюмінієвий корпус машини", + "block.gtceu.fusion_casing": "Реакторний корпус машини", + "block.gtceu.fusion_casing_mk2": "Реакторний корпус машини MK II", + "block.gtceu.fusion_casing_mk3": "Реакторний корпус машини MK III", + "block.gtceu.fusion_coil": "Блок термоядерної котушки", + "block.gtceu.fusion_glass": "Скло реактора", + "block.gtceu.gas_large_turbine": "Велика газова турбіна", + "block.gtceu.generic_hazard_sign_block": "Блок зі знаком попередження", + "block.gtceu.gold_drum": "Золота бочка", + "block.gtceu.gray_borderless_lamp": "Сіра необлямована лампа", + "block.gtceu.gray_lamp": "Сіра лампа", + "block.gtceu.gray_large_metal_sheet": "Сіре велике металеве покриття", + "block.gtceu.gray_metal_sheet": "Сіре металеве покриття", + "block.gtceu.gray_studs": "Сірі кубики", + "block.gtceu.green_borderless_lamp": "Зелена необлямована лампа", + "block.gtceu.green_lamp": "Зелена лампа", + "block.gtceu.green_large_metal_sheet": "Зелене велике металеве покриття", + "block.gtceu.green_metal_sheet": "Зелене металеве покриття", + "block.gtceu.green_studs": "Зелені кубики", + "block.gtceu.gregification_hazard_sign_block": "Блок зі знаком грегіфікаційної небезпеки", + "block.gtceu.heat_vent": "Тепловідвід", + "block.gtceu.heatproof_machine_casing": "Термостійкий інваровий корпус машини", + "block.gtceu.high_performance_computation_array": "Високопродуктивний обчислювальний масив (ВОМ)", + "block.gtceu.high_power_casing": "Високопотужний корпус", + "block.gtceu.high_pressure_hazard_sign_block": "Блок зі знаком небезпеки високого тиску", + "block.gtceu.high_temperature_hazard_sign_block": "Блок зі знаком небезпеки високої температури", + "block.gtceu.high_temperature_smelting_casing": "Корпус для високотемпературного плавлення", + "block.gtceu.high_voltage_hazard_sign_block": "Блок зі знаком небезпеки високої напруги", + "block.gtceu.hp_steam_alloy_smelter": "Парова плавильня сплавів під високим тиском", + "block.gtceu.hp_steam_compressor": "Паровий компресор під високим тиском", + "block.gtceu.hp_steam_extractor": "Паровий екстрактор під високим тиском", + "block.gtceu.hp_steam_forge_hammer": "Паровий ковальський молот під високим тиском", + "block.gtceu.hp_steam_furnace": "Парова піч під високим тиском", + "block.gtceu.hp_steam_liquid_boiler": "Паровий рідинний котел під високим тиском", + "block.gtceu.hp_steam_macerator": "Паровий подрібнювач під високим тиском", + "block.gtceu.hp_steam_miner": "Паровий бур під високим тиском", + "block.gtceu.hp_steam_rock_crusher": "Парова кам'яна дробарка під високим тиском", + "block.gtceu.hp_steam_solar_boiler": "Паровий сонячний котел під високим тиском", + "block.gtceu.hp_steam_solid_boiler": "Паровий твердопаливний котел під високим тиском", + "block.gtceu.hpca_active_cooler_component": "ВОМ-активний охолоджувальний компонент", + "block.gtceu.hpca_advanced_computation_component": "ВОМ-вдосконалений обчислювальний компонент", + "block.gtceu.hpca_bridge_component": "ВОМ-мостовий компонент", + "block.gtceu.hpca_computation_component": "ВОМ-обчислювальний компонент", + "block.gtceu.hpca_empty_component": "Порожній ВОМ-компонент", + "block.gtceu.hpca_heat_sink_component": "ВОМ-радіаторний компонент", + "block.gtceu.hssg_coil_block": "Блок HSS-G котушки", + "block.gtceu.huge_duct_pipe": "Величезна вентиляційна труба", + "block.gtceu.hv_16a_energy_converter": "§6HV§r 16§eA§r енергетичний конвертер", + "block.gtceu.hv_1a_energy_converter": "§6HV§r 1§eA§r енергетичний конвертер", + "block.gtceu.hv_4a_energy_converter": "§6HV§r 4§eA§r енергетичний конвертер", + "block.gtceu.hv_8a_energy_converter": "§6HV§r 8§eA§r енергетичний конвертер", + "block.gtceu.hv_air_scrubber": "§6Вдосконалений очисник повітря II§r", + "block.gtceu.hv_alloy_smelter": "§6Вдосконалена плавильня сплавів II§r", + "block.gtceu.hv_arc_furnace": "§6Вдосконалена дугова піч II§r", + "block.gtceu.hv_assembler": "§6Вдосконалений збирач II§r", + "block.gtceu.hv_autoclave": "§6Вдосконалений автоклав II§r", + "block.gtceu.hv_battery_buffer_16x": "§6Висока напруга§r 16x акумуляторний буфер", + "block.gtceu.hv_battery_buffer_4x": "§6Висока напруга§r 4x акумуляторний буфер", + "block.gtceu.hv_battery_buffer_8x": "§6Висока напруга§r 8x акумуляторний буфер", + "block.gtceu.hv_bedrock_ore_miner": "§6Вдосконалений глибокореневий бур II§r", + "block.gtceu.hv_bender": "§6Вдосконалений згинач II§r", + "block.gtceu.hv_block_breaker": "§6Вдосконалений руйнівник блоків II§r", + "block.gtceu.hv_brewery": "§6Вдосконалений варильник II§r", + "block.gtceu.hv_buffer": "§6Вдосконалений буфер II§r", + "block.gtceu.hv_canner": "§6Вдосконалений пакувальник II§r", + "block.gtceu.hv_centrifuge": "§6Вдосконалена центрифуга II§r", + "block.gtceu.hv_charger_4x": "§6Висока напруга§r 4x турбозарядник", + "block.gtceu.hv_chemical_bath": "§6Вдосконалена хімічна ванна II§r", + "block.gtceu.hv_chemical_reactor": "§6Вдосконалений хімічний реактор II§r", + "block.gtceu.hv_circuit_assembler": "§6Вдосконалений схемотехнічний збирач II§r", + "block.gtceu.hv_combustion": "§6Вдосконалений генератор внутрішнього згоряння II§r", + "block.gtceu.hv_compressor": "§6Вдосконалений компресор II§r", + "block.gtceu.hv_cutter": "§6Вдосконалений різак II§r", + "block.gtceu.hv_diode": "§6HV діод", + "block.gtceu.hv_distillery": "§6Вдосконалений дистилятор II§r", + "block.gtceu.hv_electric_furnace": "§6Вдосконалена електрична піч II§r", + "block.gtceu.hv_electrolyzer": "§6Вдосконалений електролізер II§r", + "block.gtceu.hv_electromagnetic_separator": "§6Вдосконалений електромагнітний сепаратор II§r", + "block.gtceu.hv_energy_input_hatch": "§6HV енергетичний люк", + "block.gtceu.hv_energy_output_hatch": "§6HV динамо-люк", + "block.gtceu.hv_extractor": "§6Вдосконалений екстрактор II§r", + "block.gtceu.hv_extruder": "§6Вдосконалений екструдер II§r", + "block.gtceu.hv_fermenter": "§6Вдосконалений ферментатор II§r", + "block.gtceu.hv_fisher": "§6Вдосконалений рибалка II§r", + "block.gtceu.hv_fluid_drilling_rig": "§6Вдосконалена рідинна бурова установка II§r", + "block.gtceu.hv_fluid_heater": "§6Вдосконалений рідинний нагрівач II§r", + "block.gtceu.hv_fluid_passthrough_hatch": "§6HV прохідний рідинний люк", + "block.gtceu.hv_fluid_solidifier": "§6Вдосконалений рідинний затверджувач II§r", + "block.gtceu.hv_forge_hammer": "§6Вдосконалений ковальський молот II§r", + "block.gtceu.hv_forming_press": "§6Вдосконалений формовий прес II§r", + "block.gtceu.hv_gas_collector": "§6Вдосконалений газозбірник II§r", + "block.gtceu.hv_gas_turbine": "§6Вдосконалений газотурбінний генератор II§r", + "block.gtceu.hv_hermetic_casing": "Герметичний корпус III", + "block.gtceu.hv_input_bus": "§6HV вхідна шина", + "block.gtceu.hv_input_hatch": "§6HV ввідний люк", + "block.gtceu.hv_item_collector": "§6Вдосконалений предметний збирач II§r", + "block.gtceu.hv_item_passthrough_hatch": "§6HV прохідний предметний люк", + "block.gtceu.hv_laser_engraver": "§6Вдосконалений літограф II§r", + "block.gtceu.hv_lathe": "§6Вдосконалений токар II§r", + "block.gtceu.hv_macerator": "§6Вдосконалений подрібнювач II§r", + "block.gtceu.hv_machine_casing": "HV корпус машини", + "block.gtceu.hv_machine_hull": "§6HV§f машинна основа", + "block.gtceu.hv_miner": "§6Вдосконалений бур II§r", + "block.gtceu.hv_mixer": "§6Вдосконалений змішувач II§r", + "block.gtceu.hv_muffler_hatch": "Люк вихлопу§6 HV", + "block.gtceu.hv_ore_washer": "§6Вдосконалений рудопромивач II§r", + "block.gtceu.hv_output_bus": "§6HV вихідна шина", + "block.gtceu.hv_output_hatch": "§6HV вивідний люк", + "block.gtceu.hv_packer": "§6Вдосконалений пакувальник II§r", + "block.gtceu.hv_polarizer": "§6Вдосконалений намагнічувач II§r", + "block.gtceu.hv_pump": "§6Вдосконалена помпа II§r", + "block.gtceu.hv_rock_crusher": "§6Вдосконалена кам'яна дробарка II§r", + "block.gtceu.hv_rotor_holder": "§6HV тримач ротора", + "block.gtceu.hv_scanner": "§6Вдосконалений сканер II§r", + "block.gtceu.hv_sifter": "§6Вдосконалений просіювач II§r", + "block.gtceu.hv_steam_turbine": "§6Вдосконалений паротурбінний генератор II§r", + "block.gtceu.hv_super_chest": "Суперскриня III", + "block.gtceu.hv_super_tank": "Суперрезервуар III", + "block.gtceu.hv_thermal_centrifuge": "§6Вдосконалена термічна центрифуга II§r", + "block.gtceu.hv_transformer_16a": "§6Висока напруга§r Силовий трансформатор", + "block.gtceu.hv_transformer_1a": "§6Висока напруга§r Трансформатор", + "block.gtceu.hv_transformer_2a": "§6Висока напруга§r Трансформатор високого струму (2x)", + "block.gtceu.hv_transformer_4a": "§6Висока напруга§r Трансформатор високого струму (4x)", + "block.gtceu.hv_wiremill": "§6Вдосконалений волок II§r", + "block.gtceu.hv_world_accelerator": "§6Вдосконалений світовий прискорювач II§r", + "block.gtceu.implosion_compressor": "Компресор надмірного тиску", + "block.gtceu.industrial_steam_casing": "Промисловий паровий корпус", + "block.gtceu.industrial_tnt": "Промисловий динаміт", + "block.gtceu.inert_machine_casing": "Хімічно інертний ПТФЕ корпус машини", + "block.gtceu.itnt.drops_tooltip": "Добуває усі знищені блоки так само, як динаміт, але з набагато більшим радіусом", + "block.gtceu.iv_1024a_laser_source_hatch": "§9IV§r 1,024§eA§r люк джерела лазера", + "block.gtceu.iv_1024a_laser_target_hatch": "§9IV§r 1,024§eA§r люк цілі лазера", + "block.gtceu.iv_16a_energy_converter": "§9IV§r 16§eA§r енергетичний конвертер", + "block.gtceu.iv_1a_energy_converter": "§9IV§r 1§eA§r енергетичний конвертер", + "block.gtceu.iv_256a_laser_source_hatch": "§9IV§r 256§eA§r люк джерела лазера", + "block.gtceu.iv_256a_laser_target_hatch": "§9IV§r 256§eA§r люк цілі лазера", + "block.gtceu.iv_4096a_laser_source_hatch": "§9IV§r 4,096§eA§r люк джерела лазера", + "block.gtceu.iv_4096a_laser_target_hatch": "§9IV§r 4,096§eA§r люк цілі лазера", + "block.gtceu.iv_4a_energy_converter": "§9IV§r 4§eA§r енергетичний конвертер", + "block.gtceu.iv_8a_energy_converter": "§9IV§r 8§eA§r енергетичний конвертер", + "block.gtceu.iv_alloy_smelter": "§9Елітна плавильня сплавів §r ", + "block.gtceu.iv_arc_furnace": "§9Елітна дугова піч§r ", + "block.gtceu.iv_assembler": "§9Елітний збирач§r ", + "block.gtceu.iv_autoclave": "§9Елітний автоклав§r ", + "block.gtceu.iv_battery_buffer_16x": "§9Божевільна напруга§r 16x акумуляторний буфер", + "block.gtceu.iv_battery_buffer_4x": "§9Божевільна напруга§r 4x акумуляторний буфер", + "block.gtceu.iv_battery_buffer_8x": "§9Божевільна напруга§r 8x акумуляторний буфер", + "block.gtceu.iv_bender": "§9Елітний згинач§r ", + "block.gtceu.iv_brewery": "§9Елітний варильник§r ", + "block.gtceu.iv_canner": "§9Елітний пакувальник§r ", + "block.gtceu.iv_centrifuge": "§9Елітна центрифуга§r ", + "block.gtceu.iv_charger_4x": "§9Божевільна напруга§r 4x турбозарядник", + "block.gtceu.iv_chemical_bath": "§9Елітна хімічна ванна§r ", + "block.gtceu.iv_chemical_reactor": "§9Елітний хімічний реактор§r ", + "block.gtceu.iv_circuit_assembler": "§9Елітний схемотехнічний збирач§r ", + "block.gtceu.iv_compressor": "§9Елітний компресор§r ", + "block.gtceu.iv_cutter": "§9Елітний різак§r ", + "block.gtceu.iv_diode": "§9IV діод", + "block.gtceu.iv_distillery": "§9Елітний дистилятор§r ", + "block.gtceu.iv_electric_furnace": "§9Елітна електрична піч§r ", + "block.gtceu.iv_electrolyzer": "§9Елітний електролізер§r ", + "block.gtceu.iv_electromagnetic_separator": "§9Елітний електромагнітний сепаратор§r ", + "block.gtceu.iv_energy_input_hatch": "§9IV енергетичний люк", + "block.gtceu.iv_energy_input_hatch_16a": "§9IV 16A енергетичний люк", + "block.gtceu.iv_energy_input_hatch_4a": "§9IV 4A енергетичний люк", + "block.gtceu.iv_energy_output_hatch": "§9IV динамо-люк", + "block.gtceu.iv_energy_output_hatch_16a": "§9IV 16A динамо-люк", + "block.gtceu.iv_energy_output_hatch_4a": "§9IV 4A динамо-люк", + "block.gtceu.iv_extractor": "§9Елітний екстрактор§r ", + "block.gtceu.iv_extruder": "§9Елітний екструдер§r ", + "block.gtceu.iv_fermenter": "§9Елітний ферментатор§r ", + "block.gtceu.iv_fisher": "§9Елітний рибалка§r ", + "block.gtceu.iv_fluid_heater": "§9Елітний рідинний нагрівач§r ", + "block.gtceu.iv_fluid_passthrough_hatch": "§9IV прохідний рідинний люк", + "block.gtceu.iv_fluid_solidifier": "§9Елітний рідинний затверджувач§r ", + "block.gtceu.iv_forge_hammer": "§9Елітний ковальський молот§r ", + "block.gtceu.iv_forming_press": "§9Елітний формовий прес§r ", + "block.gtceu.iv_gas_collector": "§9Елітний газозбірник§r ", + "block.gtceu.iv_hermetic_casing": "Герметичний корпус V", + "block.gtceu.iv_input_bus": "§9IV вхідна шина", + "block.gtceu.iv_input_hatch": "§9IV ввідний люк", + "block.gtceu.iv_input_hatch_4x": "§9IV чотирикамерний ввідний люк", + "block.gtceu.iv_input_hatch_9x": "§9IV дев'ятикамерний ввідний люк", + "block.gtceu.iv_item_passthrough_hatch": "§9IV прохідний предметний люк", + "block.gtceu.iv_lapotronic_battery": "IV лапотронний акумулятор", + "block.gtceu.iv_large_miner": "§9Елітний великий бур §r ", + "block.gtceu.iv_laser_engraver": "§9Елітний літограф§r ", + "block.gtceu.iv_lathe": "§9Елітний токар§r ", + "block.gtceu.iv_macerator": "§9Елітний подрібнювач§r ", + "block.gtceu.iv_machine_casing": "IV корпус машини", + "block.gtceu.iv_machine_hull": "§9IV§f машинна основа", + "block.gtceu.iv_mixer": "§9Елітний змішувач§r ", + "block.gtceu.iv_muffler_hatch": "Люк вихлопу§9 IV", + "block.gtceu.iv_ore_washer": "§9Елітний рудопромивач§r ", + "block.gtceu.iv_output_bus": "§9IV вихідна шина", + "block.gtceu.iv_output_hatch": "§9IV вивідний люк", + "block.gtceu.iv_output_hatch_4x": "§9IV чотирикамерний вивідний люк", + "block.gtceu.iv_output_hatch_9x": "§9IV дев'ятикамерний вивідний люк", + "block.gtceu.iv_packer": "§9Елітний пакувальник§r ", + "block.gtceu.iv_parallel_hatch": "Елітний люк паралельного контролю", + "block.gtceu.iv_polarizer": "§9Елітний намагнічувач§r ", + "block.gtceu.iv_quantum_chest": "Квантова скриня V", + "block.gtceu.iv_quantum_tank": "Квантовий резервуар V", + "block.gtceu.iv_rock_crusher": "§9Елітна кам'яна дробарка§r ", + "block.gtceu.iv_rotor_holder": "§9IV тримач ротора", + "block.gtceu.iv_scanner": "§9Елітний сканер§r ", + "block.gtceu.iv_sifter": "§9Елітний просіювач§r ", + "block.gtceu.iv_substation_input_hatch_64a": "§9IV 64A енергетичний люк підстанції", + "block.gtceu.iv_substation_output_hatch_64a": "§9IV 64A динамо-люк підстанції", + "block.gtceu.iv_thermal_centrifuge": "§9Елітна термічна центрифуга§r ", + "block.gtceu.iv_transformer_16a": "§9Божевільна напруга§r Силовий трансформатор", + "block.gtceu.iv_transformer_1a": "§9Божевільна напруга§r Трансформатор", + "block.gtceu.iv_transformer_2a": "§9Божевільна напруга§r Трансформатор високого струму (2x)", + "block.gtceu.iv_transformer_4a": "§9Божевільна напруга§r Трансформатор високого струму (4x)", + "block.gtceu.iv_wiremill": "§9Елітний волок§r ", + "block.gtceu.iv_world_accelerator": "§9Елітний світовий прискорювач§r ", + "block.gtceu.kanthal_coil_block": "Блок канталової котушки", + "block.gtceu.laminated_glass": "Багатошарове скло", + "block.gtceu.lamp.tooltip.inverted": "Інвертована", + "block.gtceu.lamp.tooltip.no_bloom": "Не мерехтить", + "block.gtceu.lamp.tooltip.no_light": "Не світить", + "block.gtceu.large_arc_smelter": "Велика дугова плавильна піч", + "block.gtceu.large_assembler": "Велика складальна фабрика", + "block.gtceu.large_autoclave": "Велика кристалізаційна камера", + "block.gtceu.large_brewer": "Великий варильний чан", + "block.gtceu.large_centrifuge": "Велика відцентрова установка", + "block.gtceu.large_chemical_bath": "Велика хімічна ванна", + "block.gtceu.large_chemical_reactor": "Великий хімічний реактор", + "block.gtceu.large_circuit_assembler": "Великий схемотехнічний складальний комплекс", + "block.gtceu.large_combustion_engine": "Великий двигун внутрішнього згоряння", + "block.gtceu.large_cutter": "Велика відрізна пила", + "block.gtceu.large_distillery": "Великий фракційний дистилятор", + "block.gtceu.large_duct_pipe": "Велика вентиляційна труба", + "block.gtceu.large_electrolyzer": "Велика електролізна камера", + "block.gtceu.large_electromagnet": "Великий електромагніт", + "block.gtceu.large_engraving_laser": "Великий літограф", + "block.gtceu.large_extractor": "Велика екстракційна машина", + "block.gtceu.large_extruder": "Велика екструзійна машина", + "block.gtceu.large_maceration_tower": "Велика подрібнювальна вежа", + "block.gtceu.large_material_press": "Великий матеріальний прес", + "block.gtceu.large_mixer": "Великий змішувальний бак", + "block.gtceu.large_packer": "Велика пакувальна машина", + "block.gtceu.large_scale_assembler_casing": "Корпус для великомасштабного збирання", + "block.gtceu.large_sifting_funnel": "Велика просіювальна лійка", + "block.gtceu.large_solidifier": "Великий масив затвердіння", + "block.gtceu.large_wiremill": "Велика дротова фабрика", + "block.gtceu.laser_hazard_sign_block": "Блок зі знаком лазерної небезпеки", + "block.gtceu.laser_safe_engraving_casing": "Захисний корпус для лазерного гравіювання", + "block.gtceu.light_blue_borderless_lamp": "Блакитна необлямована лампа", + "block.gtceu.light_blue_lamp": "Блакитна лампа", + "block.gtceu.light_blue_large_metal_sheet": "Блакитне велике металеве покриття", + "block.gtceu.light_blue_metal_sheet": "Блакитне металеве покриття", + "block.gtceu.light_blue_studs": "Блакитні кубики", + "block.gtceu.light_concrete": "Світлий бетон", + "block.gtceu.light_concrete_bricks": "Світла бетонна цегла", + "block.gtceu.light_concrete_cobblestone": "Світлий бетонний кругляк", + "block.gtceu.light_concrete_small_tile": "Світлі бетонні дрібні кахлі", + "block.gtceu.light_concrete_tile": "Світлі бетонні кахлі", + "block.gtceu.light_concrete_windmill_a": "Світлий бетонний вітряк A", + "block.gtceu.light_concrete_windmill_b": "Світлий бетонний вітряк B", + "block.gtceu.light_gray_borderless_lamp": "Світло-сіра необлямована лампа", + "block.gtceu.light_gray_lamp": "Світло-сіра лампа", + "block.gtceu.light_gray_large_metal_sheet": "Світло-сіре велике металеве покриття", + "block.gtceu.light_gray_metal_sheet": "Світло-сіре металеве покриття", + "block.gtceu.light_gray_studs": "Світло-сірі кубики", + "block.gtceu.lime_borderless_lamp": "Лаймова необлямована лампа", + "block.gtceu.lime_lamp": "Лаймова лампа", + "block.gtceu.lime_large_metal_sheet": "Лаймове велике металеве покриття", + "block.gtceu.lime_metal_sheet": "Лаймове металеве покриття", + "block.gtceu.lime_studs": "Лаймові кубики", + "block.gtceu.long_distance_fluid_pipeline": "Великодистанційний рідинний трубопровід", + "block.gtceu.long_distance_fluid_pipeline_endpoint": "Пункт призначення великодистанційного рідинного трубопроводу", + "block.gtceu.long_distance_item_pipeline": "Великодистанційний предметний трубопровід", + "block.gtceu.long_distance_item_pipeline_endpoint": "Пункт призначення великодистанційного предметного трубопроводу", + "block.gtceu.long_distance_item_pipeline_input_endpoint": "Вхід кінцевої точки", + "block.gtceu.long_distance_item_pipeline_input_pos": " - вхід: %s", + "block.gtceu.long_distance_item_pipeline_network_header": "Мережа:", + "block.gtceu.long_distance_item_pipeline_no_network": "Мережу не знайдено", + "block.gtceu.long_distance_item_pipeline_output_endpoint": "Вихід кінцевої точки", + "block.gtceu.long_distance_item_pipeline_output_pos": " - вихід: %s", + "block.gtceu.long_distance_item_pipeline_pipe_count": " - труби: %s", + "block.gtceu.lp_steam_alloy_smelter": "Парова плавильня сплавів під низьким тиском", + "block.gtceu.lp_steam_compressor": "Паровий компресор під низьким тиском", + "block.gtceu.lp_steam_extractor": "Паровий екстрактор під низьким тиском", + "block.gtceu.lp_steam_forge_hammer": "Паровий ковальський молот під низьким тиском", + "block.gtceu.lp_steam_furnace": "Парова піч під низьким тиском", + "block.gtceu.lp_steam_liquid_boiler": "Паровий рідинний котел під низьким тиском", + "block.gtceu.lp_steam_macerator": "Паровий подрібнювач під низьким тиском", + "block.gtceu.lp_steam_miner": "Паровий бур під низьким тиском", + "block.gtceu.lp_steam_rock_crusher": "Парова кам'яна дробарка під низьким тиском", + "block.gtceu.lp_steam_solar_boiler": "Паровий сонячний котел під низьким тиском", + "block.gtceu.lp_steam_solid_boiler": "Паровий твердопаливний котел під низьким тиском", + "block.gtceu.luv_1024a_laser_source_hatch": "§dLuV§r 1,024§eA§r люк джерела лазера", + "block.gtceu.luv_1024a_laser_target_hatch": "§dLuV§r 1,024§eA§r люк цілі лазера", + "block.gtceu.luv_16a_energy_converter": "§dLuV§r 16§eA§r енергетичний конвертер", + "block.gtceu.luv_1a_energy_converter": "§dLuV§r 1§eA§r енергетичний конвертер", + "block.gtceu.luv_256a_laser_source_hatch": "§dLuV§r 256§eA§r люк джерела лазера", + "block.gtceu.luv_256a_laser_target_hatch": "§dLuV§r 256§eA§r люк цілі лазера", + "block.gtceu.luv_4096a_laser_source_hatch": "§dLuV§r 4,096§eA§r люк джерела лазера", + "block.gtceu.luv_4096a_laser_target_hatch": "§dLuV§r 4,096§eA§r люк цілі лазера", + "block.gtceu.luv_4a_energy_converter": "§dLuV§r 4§eA§r енергетичний конвертер", + "block.gtceu.luv_8a_energy_converter": "§dLuV§r 8§eA§r енергетичний конвертер", + "block.gtceu.luv_alloy_smelter": "§dЕлітна плавильня сплавів II§r", + "block.gtceu.luv_arc_furnace": "§dЕлітна дугова піч II§r", + "block.gtceu.luv_assembler": "§dЕлітний збирач II§r", + "block.gtceu.luv_autoclave": "§dЕлітний автоклав II§r", + "block.gtceu.luv_battery_buffer_16x": "§dАбсурдна напруга§r 16x акумуляторний буфер", + "block.gtceu.luv_battery_buffer_4x": "§dАбсурдна напруга§r 4x акумуляторний буфер", + "block.gtceu.luv_battery_buffer_8x": "§dАбсурдна напруга§r 8x акумуляторний буфер", + "block.gtceu.luv_bender": "§dЕлітний згинач II§r", + "block.gtceu.luv_brewery": "§dЕлітний варильник II§r", + "block.gtceu.luv_canner": "§dЕлітний пакувальник II§r", + "block.gtceu.luv_centrifuge": "§dЕлітна центрифуга II§r", + "block.gtceu.luv_charger_4x": "§dАбсурдна напруга§r 4x турбозарядник", + "block.gtceu.luv_chemical_bath": "§dЕлітна хімічна ванна II§r", + "block.gtceu.luv_chemical_reactor": "§dЕлітний хімічний реактор II§r", + "block.gtceu.luv_circuit_assembler": "§dЕлітний схемотехнічний збирач II§r", + "block.gtceu.luv_compressor": "§dЕлітний компресор II§r", + "block.gtceu.luv_cutter": "§dЕлітний різак II§r", + "block.gtceu.luv_diode": "§dLuV діод", + "block.gtceu.luv_distillery": "§dЕлітний дистилятор II§r", + "block.gtceu.luv_dual_input_hatch": "§dLuV подвійний ввідний люк", + "block.gtceu.luv_dual_output_hatch": "§dLuV подвійний вивідний люк", + "block.gtceu.luv_electric_furnace": "§dЕлітна електрична піч II§r", + "block.gtceu.luv_electrolyzer": "§dЕлітний електролізер II§r", + "block.gtceu.luv_electromagnetic_separator": "§dЕлітний електромагнітний сепаратор II§r", + "block.gtceu.luv_energy_input_hatch": "§dLuV енергетичний люк", + "block.gtceu.luv_energy_input_hatch_16a": "§dLuV 16A енергетичний люк", + "block.gtceu.luv_energy_input_hatch_4a": "§dLuV 4A енергетичний люк", + "block.gtceu.luv_energy_output_hatch": "§dLuV динамо-люк", + "block.gtceu.luv_energy_output_hatch_16a": "§dLuV 16A динамо-люк", + "block.gtceu.luv_energy_output_hatch_4a": "§dLuV 4A динамо-люк", + "block.gtceu.luv_extractor": "§dЕлітний екстрактор II§r", + "block.gtceu.luv_extruder": "§dЕлітний екструдер II§r", + "block.gtceu.luv_fermenter": "§dЕлітний ферментатор II§r", + "block.gtceu.luv_fisher": "§dЕлітний рибалка II§r", + "block.gtceu.luv_fluid_heater": "§dЕлітний рідинний нагрівач II§r", + "block.gtceu.luv_fluid_passthrough_hatch": "§dLuV прохідний рідинний люк", + "block.gtceu.luv_fluid_solidifier": "§dЕлітний рідинний затверджувач II§r", + "block.gtceu.luv_forge_hammer": "§dЕлітний ковальський молот II§r", + "block.gtceu.luv_forming_press": "§dЕлітний формовий прес II§r", + "block.gtceu.luv_fusion_reactor": "Комп'ютер термоядерного реактора MK I", + "block.gtceu.luv_gas_collector": "§dЕлітний газозбірник II§r", + "block.gtceu.luv_hermetic_casing": "Герметичний корпус VI", + "block.gtceu.luv_input_bus": "§dLuV вхідна шина", + "block.gtceu.luv_input_hatch": "§dLuV ввідний люк", + "block.gtceu.luv_input_hatch_4x": "§dLuV чотирикамерний ввідний люк", + "block.gtceu.luv_input_hatch_9x": "§dLuV дев'ятикамерний ввідний люк", + "block.gtceu.luv_item_passthrough_hatch": "§dLuV прохідний предметний люк", + "block.gtceu.luv_lapotronic_battery": "LuV лапотронний акумулятор", + "block.gtceu.luv_large_miner": "§dЕлітний великий бур II§r", + "block.gtceu.luv_laser_engraver": "§dЕлітний літограф II§r", + "block.gtceu.luv_lathe": "§dЕлітний токар II§r", + "block.gtceu.luv_macerator": "§dЕлітний подрібнювач II§r", + "block.gtceu.luv_machine_casing": "LuV корпус машини", + "block.gtceu.luv_machine_hull": "§dLuV§f машинна основа", + "block.gtceu.luv_mixer": "§dЕлітний змішувач II§r", + "block.gtceu.luv_muffler_hatch": "Люк вихлопу§d LuV", + "block.gtceu.luv_ore_washer": "§dЕлітний рудопромивач II§r", + "block.gtceu.luv_output_bus": "§dLuV вихідна шина", + "block.gtceu.luv_output_hatch": "§dLuV вивідний люк", + "block.gtceu.luv_output_hatch_4x": "§dLuV чотирикамерний вивідний люк", + "block.gtceu.luv_output_hatch_9x": "§dLuV дев'ятикамерний вивідний люк", + "block.gtceu.luv_packer": "§dЕлітний пакувальник II§r", + "block.gtceu.luv_parallel_hatch": "Майстерський люк паралельного контролю", + "block.gtceu.luv_polarizer": "§dЕлітний намагнічувач II§r", + "block.gtceu.luv_quantum_chest": "Квантова скриня VI", + "block.gtceu.luv_quantum_tank": "Квантовий резервуар VI", + "block.gtceu.luv_rock_crusher": "§dЕлітна кам'яна дробарка II§r", + "block.gtceu.luv_rotor_holder": "§dLuV тримач ротора", + "block.gtceu.luv_scanner": "§dЕлітний сканер II§r", + "block.gtceu.luv_sifter": "§dЕлітний просіювач II§r", + "block.gtceu.luv_substation_input_hatch_64a": "§dLuV 64A енергетичний люк підстанції", + "block.gtceu.luv_substation_output_hatch_64a": "§dLuV 64A динамо-люк підстанції", + "block.gtceu.luv_thermal_centrifuge": "§dЕлітна термічна центрифуга II§r", + "block.gtceu.luv_transformer_16a": "§dАбсурдна напруга§r Силовий трансформатор", + "block.gtceu.luv_transformer_1a": "§dАбсурдна напруга§r Трансформатор", + "block.gtceu.luv_transformer_2a": "§dАбсурдна напруга§r Трансформатор високого струму (2x)", + "block.gtceu.luv_transformer_4a": "§dАбсурдна напруга§r Трансформатор високого струму (4x)", + "block.gtceu.luv_wiremill": "§dЕлітний волок II§r", + "block.gtceu.luv_world_accelerator": "§dЕлітний світовий прискорювач II§r", + "block.gtceu.lv_16a_energy_converter": "§7LV§r 16§eA§r енергетичний конвертер", + "block.gtceu.lv_1a_energy_converter": "§7LV§r 1§eA§r енергетичний конвертер", + "block.gtceu.lv_4a_energy_converter": "§7LV§r 4§eA§r енергетичний конвертер", + "block.gtceu.lv_8a_energy_converter": "§7LV§r 8§eA§r енергетичний конвертер", + "block.gtceu.lv_air_scrubber": "Базовий очисник повітря§r ", + "block.gtceu.lv_alloy_smelter": "Базова плавильня сплавів §r ", + "block.gtceu.lv_arc_furnace": "Базова дугова піч§r ", + "block.gtceu.lv_assembler": "Базовий збирач§r ", + "block.gtceu.lv_autoclave": "Базовий автоклав§r ", + "block.gtceu.lv_battery_buffer_16x": "§7Низька напруга§r 16x акумуляторний буфер", + "block.gtceu.lv_battery_buffer_4x": "§7Низька напруга§r 4x акумуляторний буфер", + "block.gtceu.lv_battery_buffer_8x": "§7Низька напруга§r 8x акумуляторний буфер", + "block.gtceu.lv_bender": "Базовий згинач§r ", + "block.gtceu.lv_block_breaker": "Базовий руйнівник блоків§r ", + "block.gtceu.lv_brewery": "Базовий варильник§r ", + "block.gtceu.lv_buffer": "Базовий буфер§r ", + "block.gtceu.lv_canner": "Базовий пакувальник§r ", + "block.gtceu.lv_centrifuge": "Базова центрифуга§r ", + "block.gtceu.lv_charger_4x": "§7Низька напруга§r 4x турбозарядник", + "block.gtceu.lv_chemical_bath": "Базова хімічна ванна§r ", + "block.gtceu.lv_chemical_reactor": "Базовий хімічний реактор§r ", + "block.gtceu.lv_circuit_assembler": "Базовий схемотехнічний збирач§r ", + "block.gtceu.lv_combustion": "Базовий генератор внутрішнього згоряння§r ", + "block.gtceu.lv_compressor": "Базовий компресор§r ", + "block.gtceu.lv_cutter": "Базовий різак§r ", + "block.gtceu.lv_diode": "§7LV діод", + "block.gtceu.lv_distillery": "Базовий дистилятор§r ", + "block.gtceu.lv_electric_furnace": "Базова електрична піч§r ", + "block.gtceu.lv_electrolyzer": "Базовий електролізер§r ", + "block.gtceu.lv_electromagnetic_separator": "Базовий електромагнітний сепаратор§r ", + "block.gtceu.lv_energy_input_hatch": "§7LV енергетичний люк", + "block.gtceu.lv_energy_output_hatch": "§7LV динамо-люк", + "block.gtceu.lv_extractor": "Базовий екстрактор§r ", + "block.gtceu.lv_extruder": "Базовий екструдер§r ", + "block.gtceu.lv_fermenter": "Базовий ферментатор§r ", + "block.gtceu.lv_fisher": "Базовий рибалка§r ", + "block.gtceu.lv_fluid_heater": "Базовий рідинний нагрівач§r ", + "block.gtceu.lv_fluid_passthrough_hatch": "§7LV прохідний рідинний люк", + "block.gtceu.lv_fluid_solidifier": "Базовий рідинний затверджувач§r ", + "block.gtceu.lv_forge_hammer": "Базовий ковальський молот§r ", + "block.gtceu.lv_forming_press": "Базовий формовий прес§r ", + "block.gtceu.lv_gas_collector": "Базовий газозбірник§r ", + "block.gtceu.lv_gas_turbine": "Базовий газотурбінний генератор§r ", + "block.gtceu.lv_hermetic_casing": "Герметичний корпус I", + "block.gtceu.lv_input_bus": "§7LV вхідна шина", + "block.gtceu.lv_input_hatch": "§7LV ввідний люк", + "block.gtceu.lv_item_collector": "Базовий предметний збирач§r ", + "block.gtceu.lv_item_passthrough_hatch": "§7LV прохідний предметний люк", + "block.gtceu.lv_laser_engraver": "Базовий літограф§r ", + "block.gtceu.lv_lathe": "Базовий токар§r ", + "block.gtceu.lv_macerator": "Базовий подрібнювач§r ", + "block.gtceu.lv_machine_casing": "LV корпус машини", + "block.gtceu.lv_machine_hull": "§7LV§f машинна основа", + "block.gtceu.lv_miner": "Базовий бур §r ", + "block.gtceu.lv_mixer": "Базовий змішувач§r ", + "block.gtceu.lv_muffler_hatch": "Люк вихлопу§7 LV", + "block.gtceu.lv_ore_washer": "Базовий рудопромивач§r ", + "block.gtceu.lv_output_bus": "§7LV вихідна шина", + "block.gtceu.lv_output_hatch": "§7LV вивідний люк", + "block.gtceu.lv_packer": "Базовий пакувальник§r ", + "block.gtceu.lv_polarizer": "Базовий намагнічувач§r ", + "block.gtceu.lv_pump": "Базова помпа§r ", + "block.gtceu.lv_rock_crusher": "Базова кам'яна дробарка§r ", + "block.gtceu.lv_scanner": "Базовий сканер§r ", + "block.gtceu.lv_sifter": "Базовий просіювач§r ", + "block.gtceu.lv_steam_turbine": "Базовий паротурбінний генератор§r ", + "block.gtceu.lv_super_chest": "Суперскриня I", + "block.gtceu.lv_super_tank": "Суперрезервуар I", + "block.gtceu.lv_thermal_centrifuge": "Базова термічна центрифуга§r ", + "block.gtceu.lv_transformer_16a": "§7Низька напруга§r Силовий трансформатор", + "block.gtceu.lv_transformer_1a": "§7Низька напруга§r Трансформатор", + "block.gtceu.lv_transformer_2a": "§7Низька напруга§r Трансформатор високого струму (2x)", + "block.gtceu.lv_transformer_4a": "§7Низька напруга§r Трансформатор високого струму (4x)", + "block.gtceu.lv_wiremill": "Базовий волок§r ", + "block.gtceu.lv_world_accelerator": "Базовий світовий прискорювач§r ", + "block.gtceu.magenta_borderless_lamp": "Пурпурова необлямована лампа", + "block.gtceu.magenta_lamp": "Пурпурова лампа", + "block.gtceu.magenta_large_metal_sheet": "Пурпурове велике металеве покриття", + "block.gtceu.magenta_metal_sheet": "Пурпурове металеве покриття", + "block.gtceu.magenta_studs": "Пурпурові кубики", + "block.gtceu.magic_hazard_sign_block": "Блок зі знаком містичної небезпеки", + "block.gtceu.magnetic_hazard_sign_block": "Блок зі знаком магнітної небезпеки", + "block.gtceu.maintenance_hatch": "Люк техобслуговування", + "block.gtceu.marble": "Мармур", + "block.gtceu.marble_bricks": "Мармурова цегла", + "block.gtceu.marble_cobblestone": "Мармуровий кругляк", + "block.gtceu.marble_small_tile": "Мармурові дрібні кахлі", + "block.gtceu.marble_tile": "Мармурові кахлі", + "block.gtceu.marble_windmill_a": "Мармуровий вітряк A", + "block.gtceu.marble_windmill_b": "Мармуровий вітряк B", + "block.gtceu.max_16a_energy_converter": "§c§lMAX§r 16§eA§r енергетичний конвертер", + "block.gtceu.max_1a_energy_converter": "§c§lMAX§r 1§eA§r енергетичний конвертер", + "block.gtceu.max_4a_energy_converter": "§c§lMAX§r 4§eA§r енергетичний конвертер", + "block.gtceu.max_8a_energy_converter": "§c§lMAX§r 8§eA§r енергетичний конвертер", + "block.gtceu.max_battery_buffer_16x": "§c§lМаксимально напружений§r 16x акумуляторний буфер", + "block.gtceu.max_battery_buffer_4x": "§c§lМаксимально напружений§r 4x акумуляторний буфер", + "block.gtceu.max_battery_buffer_8x": "§c§lМаксимально напружений§r 8x акумуляторний буфер", + "block.gtceu.max_charger_4x": "§c§lМаксимально напружений§r 4x турбозарядник", + "block.gtceu.max_dual_input_hatch": "§c§lMAX подвійний ввідний люк", + "block.gtceu.max_dual_output_hatch": "§c§lMAX подвійний вивідний люк", + "block.gtceu.max_energy_input_hatch": "§c§lMAX енергетичний люк", + "block.gtceu.max_energy_input_hatch_16a": "§c§lMAX 16A енергетичний люк", + "block.gtceu.max_energy_input_hatch_4a": "§c§lMAX 4A енергетичний люк", + "block.gtceu.max_energy_output_hatch": "§c§lMAX динамо-люк", + "block.gtceu.max_energy_output_hatch_16a": "§c§lMAX 16A динамо-люк", + "block.gtceu.max_energy_output_hatch_4a": "§c§lMAX 4A динамо-люк", + "block.gtceu.max_input_bus": "§c§lMAX вхідна шина", + "block.gtceu.max_input_hatch": "§c§lMAX ввідний люк", + "block.gtceu.max_input_hatch_4x": "§c§lMAX чотирикамерний ввідний люк", + "block.gtceu.max_input_hatch_9x": "§c§lMAX дев'ятикамерний ввідний люк", + "block.gtceu.max_machine_casing": "MAX корпус машини", + "block.gtceu.max_machine_hull": "§c§lMAX§f машинна основа", + "block.gtceu.max_output_bus": "§c§lMAX вихідна шина", + "block.gtceu.max_output_hatch": "§c§lMAX вивідний люк", + "block.gtceu.max_output_hatch_4x": "§c§lMAX чотирикамерний вивідний люк", + "block.gtceu.max_output_hatch_9x": "§c§lMAX дев'ятикамерний вивідний люк", + "block.gtceu.max_substation_input_hatch_64a": "§c§lMAX 64A енергетичний люк підстанції", + "block.gtceu.max_substation_output_hatch_64a": "§c§lMAX 64A динамо-люк підстанції", + "block.gtceu.me_input_bus": "ME-вхідна шина", + "block.gtceu.me_input_hatch": "ME-ввідний люк", + "block.gtceu.me_output_bus": "ME-вихідна шина", + "block.gtceu.me_output_hatch": "ME вивідний люк", + "block.gtceu.me_pattern_buffer": "ME-шаблонний буфер", + "block.gtceu.me_pattern_buffer_proxy": "Проксі ME-шаблонного буфера", + "block.gtceu.me_stocking_input_bus": "ME-складальний вхідна шина", + "block.gtceu.me_stocking_input_hatch": "ME-складальний ввідний люк", + "block.gtceu.mega_blast_furnace": "Ротаційна мартенівська піч", + "block.gtceu.mega_vacuum_freezer": "Масовий шоковий охолоджувач", + "block.gtceu.miner_pipe": "Бурова труба", + "block.gtceu.mob_infestation_hazard_sign_block": "Блок зі знаком небезпеки зараження мобів", + "block.gtceu.mob_spawner_hazard_sign_block": "Блок зі знаком породжувачової небезпеки", + "block.gtceu.molybdenum_disilicide_coil_block": "Блок дисиліцид молібденової котушки", + "block.gtceu.monitor": "Монітор", + "block.gtceu.mossy_dark_concrete_bricks": "Моховита темна бетонна цегла", + "block.gtceu.mossy_dark_concrete_cobblestone": "Моховитий темний бетонний кругляк", + "block.gtceu.mossy_light_concrete_bricks": "Моховита світла бетонна цегла", + "block.gtceu.mossy_light_concrete_cobblestone": "Моховитий світлий бетонний кругляк", + "block.gtceu.mossy_marble_bricks": "Моховита мармурова цегла", + "block.gtceu.mossy_marble_cobblestone": "Моховитий мармуровий кругляк", + "block.gtceu.mossy_red_granite_bricks": "Моховита червоногранітна цегла", + "block.gtceu.mossy_red_granite_cobblestone": "Моховитий червоногранітний кругляк", + "block.gtceu.multi_smelter": "Мультиплавильня", + "block.gtceu.mv_16a_energy_converter": "§bMV§r 16§eA§r енергетичний конвертер", + "block.gtceu.mv_1a_energy_converter": "§bMV§r 1§eA§r енергетичний конвертер", + "block.gtceu.mv_4a_energy_converter": "§bMV§r 4§eA§r енергетичний конвертер", + "block.gtceu.mv_8a_energy_converter": "§bMV§r 8§eA§r енергетичний конвертер", + "block.gtceu.mv_air_scrubber": "§bВдосконалений очисник повітря§r ", + "block.gtceu.mv_alloy_smelter": "§bВдосконалена плавильня сплавів §r ", + "block.gtceu.mv_arc_furnace": "§bВдосконалена дугова піч§r ", + "block.gtceu.mv_assembler": "§bВдосконалений збирач§r ", + "block.gtceu.mv_autoclave": "§bВдосконалений автоклав§r ", + "block.gtceu.mv_battery_buffer_16x": "§bСередня напруга§r 16x акумуляторний буфер", + "block.gtceu.mv_battery_buffer_4x": "§bСередня напруга§r 4x акумуляторний буфер", + "block.gtceu.mv_battery_buffer_8x": "§bСередня напруга§r 8x акумуляторний буфер", + "block.gtceu.mv_bedrock_ore_miner": "§bВдосконалений глибокореневий бур §r ", + "block.gtceu.mv_bender": "§bВдосконалений згинач§r ", + "block.gtceu.mv_block_breaker": "§bВдосконалений руйнівник блоків§r ", + "block.gtceu.mv_brewery": "§bВдосконалений варильник§r ", + "block.gtceu.mv_buffer": "§bВдосконалений буфер§r ", + "block.gtceu.mv_canner": "§bВдосконалений пакувальник§r ", + "block.gtceu.mv_centrifuge": "§bВдосконалена центрифуга§r ", + "block.gtceu.mv_charger_4x": "§bСередня напруга§r 4x турбозарядник", + "block.gtceu.mv_chemical_bath": "§bВдосконалена хімічна ванна§r ", + "block.gtceu.mv_chemical_reactor": "§bВдосконалений хімічний реактор§r ", + "block.gtceu.mv_circuit_assembler": "§bВдосконалений схемотехнічний збирач§r ", + "block.gtceu.mv_combustion": "§bВдосконалений генератор внутрішнього згоряння§r ", + "block.gtceu.mv_compressor": "§bВдосконалений компресор§r ", + "block.gtceu.mv_cutter": "§bВдосконалений різак§r ", + "block.gtceu.mv_diode": "§bMV діод", + "block.gtceu.mv_distillery": "§bВдосконалений дистилятор§r ", + "block.gtceu.mv_electric_furnace": "§bВдосконалена електрична піч§r ", + "block.gtceu.mv_electrolyzer": "§bВдосконалений електролізер§r ", + "block.gtceu.mv_electromagnetic_separator": "§bВдосконалений електромагнітний сепаратор§r ", + "block.gtceu.mv_energy_input_hatch": "§bMV енергетичний люк", + "block.gtceu.mv_energy_output_hatch": "§bMV динамо-люк", + "block.gtceu.mv_extractor": "§bВдосконалений екстрактор§r ", + "block.gtceu.mv_extruder": "§bВдосконалений екструдер§r ", + "block.gtceu.mv_fermenter": "§bВдосконалений ферментатор§r ", + "block.gtceu.mv_fisher": "§bВдосконалений рибалка§r ", + "block.gtceu.mv_fluid_drilling_rig": "§bВдосконалена рідинна бурова установка§r ", + "block.gtceu.mv_fluid_heater": "§bВдосконалений рідинний нагрівач§r ", + "block.gtceu.mv_fluid_passthrough_hatch": "§bMV прохідний рідинний люк", + "block.gtceu.mv_fluid_solidifier": "§bВдосконалений рідинний затверджувач§r ", + "block.gtceu.mv_forge_hammer": "§bВдосконалений ковальський молот§r ", + "block.gtceu.mv_forming_press": "§bВдосконалений формовий прес§r ", + "block.gtceu.mv_gas_collector": "§bВдосконалений газозбірник§r ", + "block.gtceu.mv_gas_turbine": "§bВдосконалений газотурбінний генератор§r ", + "block.gtceu.mv_hermetic_casing": "Герметичний корпус II", + "block.gtceu.mv_input_bus": "§bMV вхідна шина", + "block.gtceu.mv_input_hatch": "§bMV ввідний люк", + "block.gtceu.mv_item_collector": "§bВдосконалений предметний збирач§r ", + "block.gtceu.mv_item_passthrough_hatch": "§bMV прохідний предметний люк", + "block.gtceu.mv_laser_engraver": "§bВдосконалений літограф§r ", + "block.gtceu.mv_lathe": "§bВдосконалений токар§r ", + "block.gtceu.mv_macerator": "§bВдосконалений подрібнювач§r ", + "block.gtceu.mv_machine_casing": "MV корпус машини", + "block.gtceu.mv_machine_hull": "§bMV§f машинна основа", + "block.gtceu.mv_miner": "§bВдосконалений бур §r ", + "block.gtceu.mv_mixer": "§bВдосконалений змішувач§r ", + "block.gtceu.mv_muffler_hatch": "Люк вихлопу§b MV", + "block.gtceu.mv_ore_washer": "§bВдосконалений рудопромивач§r ", + "block.gtceu.mv_output_bus": "§bMV вихідна шина", + "block.gtceu.mv_output_hatch": "§bMV вивідний люк", + "block.gtceu.mv_packer": "§bВдосконалений пакувальник§r ", + "block.gtceu.mv_polarizer": "§bВдосконалений намагнічувач§r ", + "block.gtceu.mv_pump": "§bВдосконалена помпа§r ", + "block.gtceu.mv_rock_crusher": "§bВдосконалена кам'яна дробарка§r ", + "block.gtceu.mv_scanner": "§bВдосконалений сканер§r ", + "block.gtceu.mv_sifter": "§bВдосконалений просіювач§r ", + "block.gtceu.mv_steam_turbine": "§bВдосконалений паротурбінний генератор§r ", + "block.gtceu.mv_super_chest": "Суперскриня II", + "block.gtceu.mv_super_tank": "Суперрезервуар II", + "block.gtceu.mv_thermal_centrifuge": "§bВдосконалена термічна центрифуга§r ", + "block.gtceu.mv_transformer_16a": "§bСередня напруга§r Силовий трансформатор", + "block.gtceu.mv_transformer_1a": "§bСередня напруга§r Трансформатор", + "block.gtceu.mv_transformer_2a": "§bСередня напруга§r Трансформатор високого струму (2x)", + "block.gtceu.mv_transformer_4a": "§bСередня напруга§r Трансформатор високого струму (4x)", + "block.gtceu.mv_wiremill": "§bВдосконалений волок§r ", + "block.gtceu.mv_world_accelerator": "§bВдосконалений світовий прискорювач§r ", + "block.gtceu.naquadah_coil_block": "Блок наквадової котушки", + "block.gtceu.network_switch": "Мережевий комутатор", + "block.gtceu.nichrome_coil_block": "Блок ніхромової котушки", + "block.gtceu.noise_hazard_sign_block": "Блок зі знаком шумової небезпеки", + "block.gtceu.nonconducting_casing": "Непровідний корпус", + "block.gtceu.normal_duct_pipe": "Вентиляційна труба", + "block.gtceu.normal_laser_pipe": "Лазерна труба", + "block.gtceu.normal_laser_pipe.tooltip": "§7Транспортує енергію§f без витрат§7 на прямих лініях", + "block.gtceu.normal_optical_pipe": "Оптоволоконний кабель", + "block.gtceu.normal_optical_pipe.tooltip": "§7Транспортує§f обчислення§7 або§f дослідницькі дані§7", + "block.gtceu.object_holder": "Тримач об'єктів", + "block.gtceu.oil": "Нафта", + "block.gtceu.oil_heavy": "Важка нафта", + "block.gtceu.oil_light": "Легка нафта", + "block.gtceu.oil_medium": "Сира нафта", + "block.gtceu.opv_1024a_laser_source_hatch": "§9§lOpV§r 1,024§eA§r люк джерела лазера", + "block.gtceu.opv_1024a_laser_target_hatch": "§9§lOpV§r 1,024§eA§r люк цілі лазера", + "block.gtceu.opv_16a_energy_converter": "§9§lOpV§r 16§eA§r енергетичний конвертер", + "block.gtceu.opv_1a_energy_converter": "§9§lOpV§r 1§eA§r енергетичний конвертер", + "block.gtceu.opv_256a_laser_source_hatch": "§9§lOpV§r 256§eA§r люк джерела лазера", + "block.gtceu.opv_256a_laser_target_hatch": "§9§lOpV§r 256§eA§r люк цілі лазера", + "block.gtceu.opv_4096a_laser_source_hatch": "§9§lOpV§r 4,096§eA§r люк джерела лазера", + "block.gtceu.opv_4096a_laser_target_hatch": "§9§lOpV§r 4,096§eA§r люк цілі лазера", + "block.gtceu.opv_4a_energy_converter": "§9§lOpV§r 4§eA§r енергетичний конвертер", + "block.gtceu.opv_8a_energy_converter": "§9§lOpV§r 8§eA§r енергетичний конвертер", + "block.gtceu.opv_alloy_smelter": "§9§lЛегендарна плавильня сплавів §r ", + "block.gtceu.opv_arc_furnace": "§9§lЛегендарна дугова піч§r ", + "block.gtceu.opv_assembler": "§9§lЛегендарний збирач§r ", + "block.gtceu.opv_autoclave": "§9§lЛегендарний автоклав§r ", + "block.gtceu.opv_battery_buffer_16x": "§9§lБезмірна напруга§r 16x акумуляторний буфер", + "block.gtceu.opv_battery_buffer_4x": "§9§lБезмірна напруга§r 4x акумуляторний буфер", + "block.gtceu.opv_battery_buffer_8x": "§9§lБезмірна напруга§r 8x акумуляторний буфер", + "block.gtceu.opv_bender": "§9§lЛегендарний згинач§r ", + "block.gtceu.opv_brewery": "§9§lЛегендарний варильник§r ", + "block.gtceu.opv_canner": "§9§lЛегендарний пакувальник§r ", + "block.gtceu.opv_centrifuge": "§9§lЛегендарна центрифуга§r ", + "block.gtceu.opv_charger_4x": "§9§lБезмірна напруга§r 4x турбозарядник", + "block.gtceu.opv_chemical_bath": "§9§lЛегендарна хімічна ванна§r ", + "block.gtceu.opv_chemical_reactor": "§9§lЛегендарний хімічний реактор§r ", + "block.gtceu.opv_circuit_assembler": "§9§lЛегендарний схемотехнічний збирач§r ", + "block.gtceu.opv_compressor": "§9§lЛегендарний компресор§r ", + "block.gtceu.opv_cutter": "§9§lЛегендарний різак§r ", + "block.gtceu.opv_diode": "§9§lOpV діод", + "block.gtceu.opv_distillery": "§9§lЛегендарний дистилятор§r ", + "block.gtceu.opv_dual_input_hatch": "§9§lOpV подвійний ввідний люк", + "block.gtceu.opv_dual_output_hatch": "§9§lOpV подвійний вивідний люк", + "block.gtceu.opv_electric_furnace": "§9§lЛегендарна електрична піч§r ", + "block.gtceu.opv_electrolyzer": "§9§lЛегендарний електролізер§r ", + "block.gtceu.opv_electromagnetic_separator": "§9§lЛегендарний електромагнітний сепаратор§r ", + "block.gtceu.opv_energy_input_hatch": "§9§lOpV енергетичний люк", + "block.gtceu.opv_energy_input_hatch_16a": "§9§lOpV 16A енергетичний люк", + "block.gtceu.opv_energy_input_hatch_4a": "§9§lOpV 4A енергетичний люк", + "block.gtceu.opv_energy_output_hatch": "§9§lOpV динамо-люк", + "block.gtceu.opv_energy_output_hatch_16a": "§9§lOpV 16A динамо-люк", + "block.gtceu.opv_energy_output_hatch_4a": "§9§lOpV 4A динамо-люк", + "block.gtceu.opv_extractor": "§9§lЛегендарний екстрактор§r ", + "block.gtceu.opv_extruder": "§9§lЛегендарний екструдер§r ", + "block.gtceu.opv_fermenter": "§9§lЛегендарний ферментатор§r ", + "block.gtceu.opv_fluid_heater": "§9§lЛегендарний рідинний нагрівач§r ", + "block.gtceu.opv_fluid_passthrough_hatch": "§9§lOpV прохідний рідинний люк", + "block.gtceu.opv_fluid_solidifier": "§9§lЛегендарний рідинний затверджувач§r ", + "block.gtceu.opv_forge_hammer": "§9§lЛегендарний ковальський молот§r ", + "block.gtceu.opv_forming_press": "§9§lЛегендарний формовий прес§r ", + "block.gtceu.opv_gas_collector": "§9§lЛегендарний газозбірник§r ", + "block.gtceu.opv_input_bus": "§9§lOpV вхідна шина", + "block.gtceu.opv_input_hatch": "§9§lOpV ввідний люк", + "block.gtceu.opv_input_hatch_4x": "§9§lOpV чотирикамерний ввідний люк", + "block.gtceu.opv_input_hatch_9x": "§9§lOpV дев'ятикамерний ввідний люк", + "block.gtceu.opv_item_passthrough_hatch": "§9§lOpV прохідний предметний люк", + "block.gtceu.opv_laser_engraver": "§9§lЛегендарний літограф§r ", + "block.gtceu.opv_lathe": "§9§lЛегендарний токар§r ", + "block.gtceu.opv_macerator": "§9§lЛегендарний подрібнювач§r ", + "block.gtceu.opv_machine_casing": "OpV корпус машини", + "block.gtceu.opv_machine_hull": "§9§lOpV§f машинна основа", + "block.gtceu.opv_mixer": "§9§lЛегендарний змішувач§r ", + "block.gtceu.opv_muffler_hatch": "Люк вихлопу§9§l OpV", + "block.gtceu.opv_ore_washer": "§9§lЛегендарний рудопромивач§r ", + "block.gtceu.opv_output_bus": "§9§lOpV вихідна шина", + "block.gtceu.opv_output_hatch": "§9§lOpV вивідний люк", + "block.gtceu.opv_output_hatch_4x": "§9§lOpV чотирикамерний вивідний люк", + "block.gtceu.opv_output_hatch_9x": "§9§lOpV дев'ятикамерний вивідний люк", + "block.gtceu.opv_packer": "§9§lЛегендарний пакувальник§r ", + "block.gtceu.opv_polarizer": "§9§lЛегендарний намагнічувач§r ", + "block.gtceu.opv_quantum_chest": "Квантова скриня XIII", + "block.gtceu.opv_quantum_tank": "Квантовий резервуар XIII", + "block.gtceu.opv_rock_crusher": "§9§lЛегендарна кам'яна дробарка§r ", + "block.gtceu.opv_rotor_holder": "§9§lOpV тримач ротора", + "block.gtceu.opv_scanner": "§9§lЛегендарний сканер§r ", + "block.gtceu.opv_sifter": "§9§lЛегендарний просіювач§r ", + "block.gtceu.opv_substation_input_hatch_64a": "§9§lOpV 64A енергетичний люк підстанції", + "block.gtceu.opv_substation_output_hatch_64a": "§9§lOpV 64A динамо-люк підстанції", + "block.gtceu.opv_thermal_centrifuge": "§9§lЛегендарна термічна центрифуга§r ", + "block.gtceu.opv_transformer_16a": "§9§lБезмірна напруга§r Силовий трансформатор", + "block.gtceu.opv_transformer_1a": "§9§lБезмірна напруга§r Трансформатор", + "block.gtceu.opv_transformer_2a": "§9§lБезмірна напруга§r Трансформатор високого струму (2x)", + "block.gtceu.opv_transformer_4a": "§9§lБезмірна напруга§r Трансформатор високого струму (4x)", + "block.gtceu.opv_wiremill": "§9§lЛегендарний волок§r ", + "block.gtceu.orange_borderless_lamp": "Помаранчева необлямована лампа", + "block.gtceu.orange_lamp": "Помаранчева лампа", + "block.gtceu.orange_large_metal_sheet": "Помаранчеве велике металеве покриття", + "block.gtceu.orange_metal_sheet": "Помаранчеве металеве покриття", + "block.gtceu.orange_studs": "Помаранчеві кубики", + "block.gtceu.overworld_marker": "Верхній світ", + "block.gtceu.palladium_substation": "Паладієвий корпус підстанції", + "block.gtceu.pattern_buffer.desc.0": "§fДозволяє безпосередньо§6 зберігати шаблони AE2§f для конструкцій GregTech.", + "block.gtceu.pattern_buffer.desc.1": "§fШаблони AE2 можуть використовувати все, що зберігається у віджеті§6 спільного містила§f.", + "block.gtceu.pattern_buffer.desc.2": "§fЗ'єднайте§6 проксі шаблонних буферів§f з§b карткою даних§f, щоб зв'язати машини між собою!", + "block.gtceu.pattern_buffer_proxy.desc.0": "§fДозволяє зв'язати багато машин з єдиним§6 ME-шаблонним буфером§f.", + "block.gtceu.pattern_buffer_proxy.desc.1": "§fВсі підключені проксі будуть використовувати шаблони, що містяться в§6 оригінальному буфері§f.", + "block.gtceu.pattern_buffer_proxy.desc.2": "§fНехай фабрика росте!", + "block.gtceu.petrified_foam": "Скам'яніла піна", + "block.gtceu.pink_borderless_lamp": "Рожева необлямована лампа", + "block.gtceu.pink_lamp": "Рожева лампа", + "block.gtceu.pink_large_metal_sheet": "Рожеве велике металеве покриття", + "block.gtceu.pink_metal_sheet": "Рожеве металеве покриття", + "block.gtceu.pink_studs": "Рожеві кубики", + "block.gtceu.plascrete": "Гіпсобетон", + "block.gtceu.plasma_large_turbine": "Велика плазмова турбіна", + "block.gtceu.polished_dark_concrete": "Полірований темний бетон", + "block.gtceu.polished_light_concrete": "Полірований світлий бетон", + "block.gtceu.polished_marble": "Полірований мармур", + "block.gtceu.polished_red_granite": "Полірований червоний граніт", + "block.gtceu.powderbarrel": "Порохова бочка", + "block.gtceu.powderbarrel.drops_tooltip": "Добуває усі знищені блоки так само, як динаміт, але з трохи більшим радіусом", + "block.gtceu.power_substation": "Електропідстанція", + "block.gtceu.primitive_blast_furnace": "Примітивна сталеливарня", + "block.gtceu.primitive_pump": "Примітивна помпа", + "block.gtceu.ptfe_pipe_casing": "ПТФЕ трубний корпус", + "block.gtceu.pump_deck": "Палуба помпи", + "block.gtceu.pump_hatch": "Люк помпи", + "block.gtceu.purple_borderless_lamp": "Фіолетова необлямована лампа", + "block.gtceu.purple_lamp": "Фіолетова лампа", + "block.gtceu.purple_large_metal_sheet": "Фіолетове велике металеве покриття", + "block.gtceu.purple_metal_sheet": "Фіолетове металеве покриття", + "block.gtceu.purple_studs": "Фіолетові кубики", + "block.gtceu.pyrolyse_oven": "Піролізна піч", + "block.gtceu.radioactive_hazard_sign_block": "Блок зі знаком радіоактивної небезпеки", + "block.gtceu.reaction_safe_mixing_casing": "Реактивно-захисний змішувальний корпус", + "block.gtceu.red_borderless_lamp": "Червона необлямована лампа", + "block.gtceu.red_granite": "Червоний граніт", + "block.gtceu.red_granite_bricks": "Червоногранітна цегла", + "block.gtceu.red_granite_cobblestone": "Червоногранітний кругляк", + "block.gtceu.red_granite_small_tile": "Червоногранітні дрібні кахлі", + "block.gtceu.red_granite_tile": "Червоногранітні кахлі", + "block.gtceu.red_granite_windmill_a": "Червоногранітний вітряк A", + "block.gtceu.red_granite_windmill_b": "Червоногранітний вітряк B", + "block.gtceu.red_lamp": "Червона лампа", + "block.gtceu.red_large_metal_sheet": "Червоне велике металеве покриття", + "block.gtceu.red_metal_sheet": "Червоне металеве покриття", + "block.gtceu.red_studs": "Червоні кубики", + "block.gtceu.reinforced_foam": "Посилена піна", + "block.gtceu.reinforced_stone": "Зміцнений камінь", + "block.gtceu.research_station": "Дослідницька станція", + "block.gtceu.reservoir_hatch": "Люк резервуара", + "block.gtceu.robust_machine_casing": "Надійний вольфрамовий сталевий корпус машини", + "block.gtceu.rtm_alloy_coil_block": "Блок котушки з RTM-сплаву", + "block.gtceu.rubber_button": "Каучукова кнопка", + "block.gtceu.rubber_door": "Каучукові двері", + "block.gtceu.rubber_fence": "Каучуковий паркан", + "block.gtceu.rubber_fence_gate": "Каучукова хвіртка", + "block.gtceu.rubber_hanging_sign": "Каучукова вивіска", + "block.gtceu.rubber_leaves": "Каучукове листя", + "block.gtceu.rubber_log": "Каучукова колода", + "block.gtceu.rubber_planks": "Каучукові дошки", + "block.gtceu.rubber_pressure_plate": "Каучукова натискна плита", + "block.gtceu.rubber_sapling": "Каучуковий паросток", + "block.gtceu.rubber_sign": "Каучукова табличка", + "block.gtceu.rubber_slab": "Каучукова плита", + "block.gtceu.rubber_stairs": "Каучукові сходи", + "block.gtceu.rubber_trapdoor": "Каучуковий люк", + "block.gtceu.rubber_wood": "Каучукова деревина", + "block.gtceu.secure_maceration_casing": "Захисний подрібнювальний корпус", + "block.gtceu.shock_proof_cutting_casing": "Ударостійкий різальний корпус", + "block.gtceu.slicing_blades": "Різальні леза", + "block.gtceu.small_dark_concrete_bricks": "Дрібна темна бетонна цегла", + "block.gtceu.small_duct_pipe": "Мала вентиляційна труба", + "block.gtceu.small_light_concrete_bricks": "Дрібна світла бетонна цегла", + "block.gtceu.small_marble_bricks": "Дрібна мармурова цегла", + "block.gtceu.small_red_granite_bricks": "Дрібна червоногранітна цегла", + "block.gtceu.solid_machine_casing": "Міцний корпус машини", + "block.gtceu.spatial_storage_hazard_sign_block": "Блок зі знаком небезпеки просторового сховища", + "block.gtceu.square_dark_concrete_bricks": "Квадратна темна бетонна цегла", + "block.gtceu.square_light_concrete_bricks": "Квадратна світла бетонна цегла", + "block.gtceu.square_marble_bricks": "Квадратна мармурова цегла", + "block.gtceu.square_red_granite_bricks": "Квадратна червоногранітна цегла", + "block.gtceu.stable_machine_casing": "Стійкий титановий корпус машини", + "block.gtceu.stainless_steel_crate": "Нержавіючий сталевий ящик", + "block.gtceu.stainless_steel_drum": "Нержавіюча сталева бочка", + "block.gtceu.stainless_steel_gearbox": "Нержавіючий сталевий редукторний корпус", + "block.gtceu.stainless_steel_turbine_casing": "Нержавіючий турбінний корпус", + "block.gtceu.steam_casing_bricked_bronze": "Мурований бронзовий корпус", + "block.gtceu.steam_casing_bricked_bronze.tooltip": "§7Для ваших перших парових машин", + "block.gtceu.steam_casing_bricked_steel": "Мурований кованозалізний корпус", + "block.gtceu.steam_casing_bricked_steel.tooltip": "§7Для покращених парових машин", + "block.gtceu.steam_casing_bronze": "Бронзовий корпус", + "block.gtceu.steam_casing_bronze.tooltip": "§7Для ваших перших парових машин", + "block.gtceu.steam_casing_steel": "Сталевий корпус", + "block.gtceu.steam_casing_steel.tooltip": "§7Для покращених парових машин", + "block.gtceu.steam_grinder": "Парова дробарка", + "block.gtceu.steam_input_bus": "Парова вхідна шина", + "block.gtceu.steam_input_hatch": "Паровий ввідний люк", + "block.gtceu.steam_large_turbine": "Велика парова турбіна", + "block.gtceu.steam_liquid_boiler.bronze": "Малий паровий рідинний котел", + "block.gtceu.steam_machine_casing": "Паровий корпус машини", + "block.gtceu.steam_output_bus": "Парова вихідна шина", + "block.gtceu.steam_oven": "Парова піч", + "block.gtceu.steam_solid_boiler.bronze": "Малий паровий твердопаливний котел", + "block.gtceu.steel_brick_casing": "Мурований кованозалізний корпус", + "block.gtceu.steel_crate": "Сталевий ящик", + "block.gtceu.steel_drum": "Сталева бочка", + "block.gtceu.steel_firebox_casing": "Сталева топка", + "block.gtceu.steel_gearbox": "Сталевий редукторний корпус", + "block.gtceu.steel_large_boiler": "Великий сталевий котел", + "block.gtceu.steel_machine_casing": "Міцний сталевий корпус машини", + "block.gtceu.steel_multiblock_tank": "Сталевий багатоблочний резервуар", + "block.gtceu.steel_pipe_casing": "Сталевий трубний корпус", + "block.gtceu.steel_tank_valve": "Сталевий вентиль резервуара", + "block.gtceu.steel_turbine_casing": "Сталевий турбінний корпус", + "block.gtceu.sterilizing_filter_casing": "Стерилізуючий фільтрувальний корпус", + "block.gtceu.stress_proof_casing": "Стресостійкий корпус", + "block.gtceu.stripped_rubber_log": "Обтесана каучукова колода", + "block.gtceu.stripped_rubber_wood": "Обтесана каучукова деревина", + "block.gtceu.sturdy_machine_casing": "Витривалий HSS-E корпус машини", + "block.gtceu.substation_capacitor.tooltip_empty": "§7Для заповнення простору на вашій електропідстанції", + "block.gtceu.substation_capacitor.tooltip_filled": "§cЄмність енергії:§f %d EU", + "block.gtceu.superconducting_coil": "Блок надпровідної котушки", + "block.gtceu.tempered_glass": "Загартоване скло", + "block.gtceu.the_end_marker": "Енд", + "block.gtceu.the_nether_marker": "Незер", + "block.gtceu.titanium_crate": "Титановий ящик", + "block.gtceu.titanium_drum": "Титанова бочка", + "block.gtceu.titanium_firebox_casing": "Титанова топка", + "block.gtceu.titanium_gearbox": "Титановий редукторний корпус", + "block.gtceu.titanium_large_boiler": "Великий титановий котел", + "block.gtceu.titanium_pipe_casing": "Титановий трубний корпус", + "block.gtceu.titanium_turbine_casing": "Титановий турбінний корпус", + "block.gtceu.treated_wood_button": "Оброблена дерев'яна кнопка", + "block.gtceu.treated_wood_door": "Оброблені дерев'яні двері", + "block.gtceu.treated_wood_fence": "Оброблений дерев'яний паркан", + "block.gtceu.treated_wood_fence_gate": "Оброблена дерев'яна хвіртка", + "block.gtceu.treated_wood_hanging_sign": "Оброблена дерев'яна вивіска", + "block.gtceu.treated_wood_planks": "Оброблені дерев'яні дошки", + "block.gtceu.treated_wood_pressure_plate": "Оброблена дерев'яна натискна плита", + "block.gtceu.treated_wood_sign": "Оброблена дерев'яна табличка", + "block.gtceu.treated_wood_slab": "Оброблена дерев'яна плита", + "block.gtceu.treated_wood_stairs": "Оброблені дерев'яні сходи", + "block.gtceu.treated_wood_trapdoor": "Оброблений дерев'яний люк", + "block.gtceu.trinium_coil_block": "Блок тринієвої котушки", + "block.gtceu.tritanium_coil_block": "Блок тританієвої котушки", + "block.gtceu.tungsten_steel_crate": "Вольфрамовий ящик", + "block.gtceu.tungsten_steel_drum": "Вольфрамова бочка", + "block.gtceu.tungstensteel_firebox_casing": "Вольфрамова сталева топка", + "block.gtceu.tungstensteel_gearbox": "Вольфрамовий сталевий редукторний корпус", + "block.gtceu.tungstensteel_large_boiler": "Великий вольфрамовий котел", + "block.gtceu.tungstensteel_pipe_casing": "Вольфрамовий сталевий трубний корпус", + "block.gtceu.tungstensteel_turbine_casing": "Вольфрамовий сталевий турбінний корпус", + "block.gtceu.turret_hazard_sign_block": "Блок зі знаком турельної небезпеки", + "block.gtceu.uev_1024a_laser_source_hatch": "§aUEV§r 1,024§eA§r люк джерела лазера", + "block.gtceu.uev_1024a_laser_target_hatch": "§aUEV§r 1,024§eA§r люк цілі лазера", + "block.gtceu.uev_16a_energy_converter": "§aUEV§r 16§eA§r енергетичний конвертер", + "block.gtceu.uev_1a_energy_converter": "§aUEV§r 1§eA§r енергетичний конвертер", + "block.gtceu.uev_256a_laser_source_hatch": "§aUEV§r 256§eA§r люк джерела лазера", + "block.gtceu.uev_256a_laser_target_hatch": "§aUEV§r 256§eA§r люк цілі лазера", + "block.gtceu.uev_4096a_laser_source_hatch": "§aUEV§r 4,096§eA§r люк джерела лазера", + "block.gtceu.uev_4096a_laser_target_hatch": "§aUEV§r 4,096§eA§r люк цілі лазера", + "block.gtceu.uev_4a_energy_converter": "§aUEV§r 4§eA§r енергетичний конвертер", + "block.gtceu.uev_8a_energy_converter": "§aUEV§r 8§eA§r енергетичний конвертер", + "block.gtceu.uev_alloy_smelter": "§aЕпічна плавильня сплавів II§r", + "block.gtceu.uev_arc_furnace": "§aЕпічна дугова піч II§r", + "block.gtceu.uev_assembler": "§aЕпічний збирач II§r", + "block.gtceu.uev_autoclave": "§aЕпічний автоклав II§r", + "block.gtceu.uev_battery_buffer_16x": "§aНадмірно екстремальна напруга§r 16x акумуляторний буфер", + "block.gtceu.uev_battery_buffer_4x": "§aНадмірно екстремальна напруга§r 4x акумуляторний буфер", + "block.gtceu.uev_battery_buffer_8x": "§aНадмірно екстремальна напруга§r 8x акумуляторний буфер", + "block.gtceu.uev_bender": "§aЕпічний згинач II§r", + "block.gtceu.uev_brewery": "§aЕпічний варильник II§r", + "block.gtceu.uev_canner": "§aЕпічний пакувальник II§r", + "block.gtceu.uev_centrifuge": "§aЕпічна центрифуга II§r", + "block.gtceu.uev_charger_4x": "§aНадмірно екстремальна напруга§r 4x турбозарядник", + "block.gtceu.uev_chemical_bath": "§aЕпічна хімічна ванна II§r", + "block.gtceu.uev_chemical_reactor": "§aЕпічний хімічний реактор II§r", + "block.gtceu.uev_circuit_assembler": "§aЕпічний схемотехнічний збирач II§r", + "block.gtceu.uev_compressor": "§aЕпічний компресор II§r", + "block.gtceu.uev_cutter": "§aЕпічний різак II§r", + "block.gtceu.uev_diode": "§aUEV діод", + "block.gtceu.uev_distillery": "§aЕпічний дистилятор II§r", + "block.gtceu.uev_dual_input_hatch": "§aUEV подвійний ввідний люк", + "block.gtceu.uev_dual_output_hatch": "§aUEV подвійний вивідний люк", + "block.gtceu.uev_electric_furnace": "§aЕпічна електрична піч II§r", + "block.gtceu.uev_electrolyzer": "§aЕпічний електролізер II§r", + "block.gtceu.uev_electromagnetic_separator": "§aЕпічний електромагнітний сепаратор II§r", + "block.gtceu.uev_energy_input_hatch": "§aUEV енергетичний люк", + "block.gtceu.uev_energy_input_hatch_16a": "§aUEV 16A енергетичний люк", + "block.gtceu.uev_energy_input_hatch_4a": "§aUEV 4A енергетичний люк", + "block.gtceu.uev_energy_output_hatch": "§aUEV динамо-люк", + "block.gtceu.uev_energy_output_hatch_16a": "§aUEV 16A динамо-люк", + "block.gtceu.uev_energy_output_hatch_4a": "§aUEV 4A динамо-люк", + "block.gtceu.uev_extractor": "§aЕпічний екстрактор II§r", + "block.gtceu.uev_extruder": "§aЕпічний екструдер II§r", + "block.gtceu.uev_fermenter": "§aЕпічний ферментатор II§r", + "block.gtceu.uev_fluid_heater": "§aЕпічний рідинний нагрівач II§r", + "block.gtceu.uev_fluid_passthrough_hatch": "§aUEV прохідний рідинний люк", + "block.gtceu.uev_fluid_solidifier": "§aЕпічний рідинний затверджувач II§r", + "block.gtceu.uev_forge_hammer": "§aЕпічний ковальський молот II§r", + "block.gtceu.uev_forming_press": "§aЕпічний формовий прес II§r", + "block.gtceu.uev_gas_collector": "§aЕпічний газозбірник II§r", + "block.gtceu.uev_input_bus": "§aUEV вхідна шина", + "block.gtceu.uev_input_hatch": "§aUEV ввідний люк", + "block.gtceu.uev_input_hatch_4x": "§aUEV чотирикамерний ввідний люк", + "block.gtceu.uev_input_hatch_9x": "§aUEV дев'ятикамерний ввідний люк", + "block.gtceu.uev_item_passthrough_hatch": "§aUEV прохідний предметний люк", + "block.gtceu.uev_laser_engraver": "§aЕпічний літограф II§r", + "block.gtceu.uev_lathe": "§aЕпічний токар II§r", + "block.gtceu.uev_macerator": "§aЕпічний подрібнювач II§r", + "block.gtceu.uev_machine_casing": "UEV корпус машини", + "block.gtceu.uev_machine_hull": "§aUEV§f машинна основа", + "block.gtceu.uev_mixer": "§aЕпічний змішувач II§r", + "block.gtceu.uev_muffler_hatch": "Люк вихлопу§a UEV", + "block.gtceu.uev_ore_washer": "§aЕпічний рудопромивач II§r", + "block.gtceu.uev_output_bus": "§aUEV вихідна шина", + "block.gtceu.uev_output_hatch": "§aUEV вивідний люк", + "block.gtceu.uev_output_hatch_4x": "§aUEV чотирикамерний вивідний люк", + "block.gtceu.uev_output_hatch_9x": "§aUEV дев'ятикамерний вивідний люк", + "block.gtceu.uev_packer": "§aЕпічний пакувальник II§r", + "block.gtceu.uev_polarizer": "§aЕпічний намагнічувач II§r", + "block.gtceu.uev_quantum_chest": "Квантова скриня X", + "block.gtceu.uev_quantum_tank": "Квантовий резервуар X", + "block.gtceu.uev_rock_crusher": "§aЕпічна кам'яна дробарка II§r", + "block.gtceu.uev_rotor_holder": "§aUEV тримач ротора", + "block.gtceu.uev_scanner": "§aЕпічний сканер II§r", + "block.gtceu.uev_sifter": "§aЕпічний просіювач II§r", + "block.gtceu.uev_substation_input_hatch_64a": "§aUEV 64A енергетичний люк підстанції", + "block.gtceu.uev_substation_output_hatch_64a": "§aUEV 64A динамо-люк підстанції", + "block.gtceu.uev_thermal_centrifuge": "§aЕпічна термічна центрифуга II§r", + "block.gtceu.uev_transformer_16a": "§aНадмірно екстремальна напруга§r Силовий трансформатор", + "block.gtceu.uev_transformer_1a": "§aНадмірно екстремальна напруга§r Трансформатор", + "block.gtceu.uev_transformer_2a": "§aНадмірно екстремальна напруга§r Трансформатор високого струму (2x)", + "block.gtceu.uev_transformer_4a": "§aНадмірно екстремальна напруга§r Трансформатор високого струму (4x)", + "block.gtceu.uev_wiremill": "§aЕпічний волок II§r", + "block.gtceu.uhv_1024a_laser_source_hatch": "§4UHV§r 1,024§eA§r люк джерела лазера", + "block.gtceu.uhv_1024a_laser_target_hatch": "§4UHV§r 1,024§eA§r люк цілі лазера", + "block.gtceu.uhv_16a_energy_converter": "§4UHV§r 16§eA§r енергетичний конвертер", + "block.gtceu.uhv_1a_energy_converter": "§4UHV§r 1§eA§r енергетичний конвертер", + "block.gtceu.uhv_256a_laser_source_hatch": "§4UHV§r 256§eA§r люк джерела лазера", + "block.gtceu.uhv_256a_laser_target_hatch": "§4UHV§r 256§eA§r люк цілі лазера", + "block.gtceu.uhv_4096a_laser_source_hatch": "§4UHV§r 4,096§eA§r люк джерела лазера", + "block.gtceu.uhv_4096a_laser_target_hatch": "§4UHV§r 4,096§eA§r люк цілі лазера", + "block.gtceu.uhv_4a_energy_converter": "§4UHV§r 4§eA§r енергетичний конвертер", + "block.gtceu.uhv_8a_energy_converter": "§4UHV§r 8§eA§r енергетичний конвертер", + "block.gtceu.uhv_alloy_smelter": "§4Епічна плавильня сплавів §r ", + "block.gtceu.uhv_arc_furnace": "§4Епічна дугова піч§r ", + "block.gtceu.uhv_assembler": "§4Епічний збирач§r ", + "block.gtceu.uhv_autoclave": "§4Епічний автоклав§r ", + "block.gtceu.uhv_battery_buffer_16x": "§4Надмірно висока напруга§r 16x акумуляторний буфер", + "block.gtceu.uhv_battery_buffer_4x": "§4Надмірно висока напруга§r 4x акумуляторний буфер", + "block.gtceu.uhv_battery_buffer_8x": "§4Надмірно висока напруга§r 8x акумуляторний буфер", + "block.gtceu.uhv_bender": "§4Епічний згинач§r ", + "block.gtceu.uhv_brewery": "§4Епічний варильник§r ", + "block.gtceu.uhv_canner": "§4Епічний пакувальник§r ", + "block.gtceu.uhv_centrifuge": "§4Епічна центрифуга§r ", + "block.gtceu.uhv_charger_4x": "§4Надмірно висока напруга§r 4x турбозарядник", + "block.gtceu.uhv_chemical_bath": "§4Епічна хімічна ванна§r ", + "block.gtceu.uhv_chemical_reactor": "§4Епічний хімічний реактор§r ", + "block.gtceu.uhv_circuit_assembler": "§4Епічний схемотехнічний збирач§r ", + "block.gtceu.uhv_compressor": "§4Епічний компресор§r ", + "block.gtceu.uhv_cutter": "§4Епічний різак§r ", + "block.gtceu.uhv_diode": "§4UHV діод", + "block.gtceu.uhv_distillery": "§4Епічний дистилятор§r ", + "block.gtceu.uhv_dual_input_hatch": "§4UHV подвійний ввідний люк", + "block.gtceu.uhv_dual_output_hatch": "§4UHV подвійний вивідний люк", + "block.gtceu.uhv_electric_furnace": "§4Епічна електрична піч§r ", + "block.gtceu.uhv_electrolyzer": "§4Епічний електролізер§r ", + "block.gtceu.uhv_electromagnetic_separator": "§4Епічний електромагнітний сепаратор§r ", + "block.gtceu.uhv_energy_input_hatch": "§4UHV енергетичний люк", + "block.gtceu.uhv_energy_input_hatch_16a": "§4UHV 16A енергетичний люк", + "block.gtceu.uhv_energy_input_hatch_4a": "§4UHV 4A енергетичний люк", + "block.gtceu.uhv_energy_output_hatch": "§4UHV динамо-люк", + "block.gtceu.uhv_energy_output_hatch_16a": "§4UHV 16A динамо-люк", + "block.gtceu.uhv_energy_output_hatch_4a": "§4UHV 4A динамо-люк", + "block.gtceu.uhv_extractor": "§4Епічний екстрактор§r ", + "block.gtceu.uhv_extruder": "§4Епічний екструдер§r ", + "block.gtceu.uhv_fermenter": "§4Епічний ферментатор§r ", + "block.gtceu.uhv_fluid_heater": "§4Епічний рідинний нагрівач§r ", + "block.gtceu.uhv_fluid_passthrough_hatch": "§4UHV прохідний рідинний люк", + "block.gtceu.uhv_fluid_solidifier": "§4Епічний рідинний затверджувач§r ", + "block.gtceu.uhv_forge_hammer": "§4Епічний ковальський молот§r ", + "block.gtceu.uhv_forming_press": "§4Епічний формовий прес§r ", + "block.gtceu.uhv_gas_collector": "§4Епічний газозбірник§r ", + "block.gtceu.uhv_hermetic_casing": "Герметичний корпус IX", + "block.gtceu.uhv_input_bus": "§4UHV вхідна шина", + "block.gtceu.uhv_input_hatch": "§4UHV ввідний люк", + "block.gtceu.uhv_input_hatch_4x": "§4UHV чотирикамерний ввідний люк", + "block.gtceu.uhv_input_hatch_9x": "§4UHV дев'ятикамерний ввідний люк", + "block.gtceu.uhv_item_passthrough_hatch": "§4UHV прохідний предметний люк", + "block.gtceu.uhv_laser_engraver": "§4Епічний літограф§r ", + "block.gtceu.uhv_lathe": "§4Епічний токар§r ", + "block.gtceu.uhv_macerator": "§4Епічний подрібнювач§r ", + "block.gtceu.uhv_machine_casing": "UHV корпус машини", + "block.gtceu.uhv_machine_hull": "§4UHV§f машинна основа", + "block.gtceu.uhv_mixer": "§4Епічний змішувач§r ", + "block.gtceu.uhv_muffler_hatch": "Люк вихлопу§4 UHV", + "block.gtceu.uhv_ore_washer": "§4Епічний рудопромивач§r ", + "block.gtceu.uhv_output_bus": "§4UHV вихідна шина", + "block.gtceu.uhv_output_hatch": "§4UHV вивідний люк", + "block.gtceu.uhv_output_hatch_4x": "§4UHV чотирикамерний вивідний люк", + "block.gtceu.uhv_output_hatch_9x": "§4UHV дев'ятикамерний вивідний люк", + "block.gtceu.uhv_packer": "§4Епічний пакувальник§r ", + "block.gtceu.uhv_polarizer": "§4Епічний намагнічувач§r ", + "block.gtceu.uhv_quantum_chest": "Квантова скриня IX", + "block.gtceu.uhv_quantum_tank": "Квантовий резервуар IX", + "block.gtceu.uhv_rock_crusher": "§4Епічна кам'яна дробарка§r ", + "block.gtceu.uhv_rotor_holder": "§4UHV тримач ротора", + "block.gtceu.uhv_scanner": "§4Епічний сканер§r ", + "block.gtceu.uhv_sifter": "§4Епічний просіювач§r ", + "block.gtceu.uhv_substation_input_hatch_64a": "§4UHV 64A енергетичний люк підстанції", + "block.gtceu.uhv_substation_output_hatch_64a": "§4UHV 64A динамо-люк підстанції", + "block.gtceu.uhv_thermal_centrifuge": "§4Епічна термічна центрифуга§r ", + "block.gtceu.uhv_transformer_16a": "§4Надмірно висока напруга§r Силовий трансформатор", + "block.gtceu.uhv_transformer_1a": "§4Надмірно висока напруга§r Трансформатор", + "block.gtceu.uhv_transformer_2a": "§4Надмірно висока напруга§r Трансформатор високого струму (2x)", + "block.gtceu.uhv_transformer_4a": "§4Надмірно висока напруга§r Трансформатор високого струму (4x)", + "block.gtceu.uhv_ultimate_battery": "UHV ультимативний акумулятор", + "block.gtceu.uhv_wiremill": "§4Епічний волок§r ", + "block.gtceu.uiv_1024a_laser_source_hatch": "§2UIV§r 1,024§eA§r люк джерела лазера", + "block.gtceu.uiv_1024a_laser_target_hatch": "§2UIV§r 1,024§eA§r люк цілі лазера", + "block.gtceu.uiv_16a_energy_converter": "§2UIV§r 16§eA§r енергетичний конвертер", + "block.gtceu.uiv_1a_energy_converter": "§2UIV§r 1§eA§r енергетичний конвертер", + "block.gtceu.uiv_256a_laser_source_hatch": "§2UIV§r 256§eA§r люк джерела лазера", + "block.gtceu.uiv_256a_laser_target_hatch": "§2UIV§r 256§eA§r люк цілі лазера", + "block.gtceu.uiv_4096a_laser_source_hatch": "§2UIV§r 4,096§eA§r люк джерела лазера", + "block.gtceu.uiv_4096a_laser_target_hatch": "§2UIV§r 4,096§eA§r люк цілі лазера", + "block.gtceu.uiv_4a_energy_converter": "§2UIV§r 4§eA§r енергетичний конвертер", + "block.gtceu.uiv_8a_energy_converter": "§2UIV§r 8§eA§r енергетичний конвертер", + "block.gtceu.uiv_alloy_smelter": "§2Епічна плавильня сплавів III§r", + "block.gtceu.uiv_arc_furnace": "§2Епічна дугова піч III§r", + "block.gtceu.uiv_assembler": "§2Епічний збирач III§r", + "block.gtceu.uiv_autoclave": "§2Епічний автоклав III§r", + "block.gtceu.uiv_battery_buffer_16x": "§2Надмірно неосяжна напруга§r 16x акумуляторний буфер", + "block.gtceu.uiv_battery_buffer_4x": "§2Надмірно неосяжна напруга§r 4x акумуляторний буфер", + "block.gtceu.uiv_battery_buffer_8x": "§2Надмірно неосяжна напруга§r 8x акумуляторний буфер", + "block.gtceu.uiv_bender": "§2Епічний згинач III§r", + "block.gtceu.uiv_brewery": "§2Епічний варильник III§r", + "block.gtceu.uiv_canner": "§2Епічний пакувальник III§r", + "block.gtceu.uiv_centrifuge": "§2Епічна центрифуга III§r", + "block.gtceu.uiv_charger_4x": "§2Надмірно неосяжна напруга§r 4x турбозарядник", + "block.gtceu.uiv_chemical_bath": "§2Епічна хімічна ванна III§r", + "block.gtceu.uiv_chemical_reactor": "§2Епічний хімічний реактор III§r", + "block.gtceu.uiv_circuit_assembler": "§2Епічний схемотехнічний збирач III§r", + "block.gtceu.uiv_compressor": "§2Епічний компресор III§r", + "block.gtceu.uiv_cutter": "§2Епічний різак III§r", + "block.gtceu.uiv_diode": "§2UIV діод", + "block.gtceu.uiv_distillery": "§2Епічний дистилятор III§r", + "block.gtceu.uiv_dual_input_hatch": "§2UIV подвійний ввідний люк", + "block.gtceu.uiv_dual_output_hatch": "§2UIV подвійний вивідний люк", + "block.gtceu.uiv_electric_furnace": "§2Епічна електрична піч III§r", + "block.gtceu.uiv_electrolyzer": "§2Епічний електролізер III§r", + "block.gtceu.uiv_electromagnetic_separator": "§2Епічний електромагнітний сепаратор III§r", + "block.gtceu.uiv_energy_input_hatch": "§2UIV енергетичний люк", + "block.gtceu.uiv_energy_input_hatch_16a": "§2UIV 16A енергетичний люк", + "block.gtceu.uiv_energy_input_hatch_4a": "§2UIV 4A енергетичний люк", + "block.gtceu.uiv_energy_output_hatch": "§2UIV динамо-люк", + "block.gtceu.uiv_energy_output_hatch_16a": "§2UIV 16A динамо-люк", + "block.gtceu.uiv_energy_output_hatch_4a": "§2UIV 4A динамо-люк", + "block.gtceu.uiv_extractor": "§2Епічний екстрактор III§r", + "block.gtceu.uiv_extruder": "§2Епічний екструдер III§r", + "block.gtceu.uiv_fermenter": "§2Епічний ферментатор III§r", + "block.gtceu.uiv_fluid_heater": "§2Епічний рідинний нагрівач III§r", + "block.gtceu.uiv_fluid_passthrough_hatch": "§2UIV прохідний рідинний люк", + "block.gtceu.uiv_fluid_solidifier": "§2Епічний рідинний затверджувач III§r", + "block.gtceu.uiv_forge_hammer": "§2Епічний ковальський молот III§r", + "block.gtceu.uiv_forming_press": "§2Епічний формовий прес III§r", + "block.gtceu.uiv_gas_collector": "§2Епічний газозбірник III§r", + "block.gtceu.uiv_input_bus": "§2UIV вхідна шина", + "block.gtceu.uiv_input_hatch": "§2UIV ввідний люк", + "block.gtceu.uiv_input_hatch_4x": "§2UIV чотирикамерний ввідний люк", + "block.gtceu.uiv_input_hatch_9x": "§2UIV дев'ятикамерний ввідний люк", + "block.gtceu.uiv_item_passthrough_hatch": "§2UIV прохідний предметний люк", + "block.gtceu.uiv_laser_engraver": "§2Епічний літограф III§r", + "block.gtceu.uiv_lathe": "§2Епічний токар III§r", + "block.gtceu.uiv_macerator": "§2Епічний подрібнювач III§r", + "block.gtceu.uiv_machine_casing": "UIV корпус машини", + "block.gtceu.uiv_machine_hull": "§2UIV§f машинна основа", + "block.gtceu.uiv_mixer": "§2Епічний змішувач III§r", + "block.gtceu.uiv_muffler_hatch": "Люк вихлопу§2 UIV", + "block.gtceu.uiv_ore_washer": "§2Епічний рудопромивач III§r", + "block.gtceu.uiv_output_bus": "§2UIV вихідна шина", + "block.gtceu.uiv_output_hatch": "§2UIV вивідний люк", + "block.gtceu.uiv_output_hatch_4x": "§2UIV чотирикамерний вивідний люк", + "block.gtceu.uiv_output_hatch_9x": "§2UIV дев'ятикамерний вивідний люк", + "block.gtceu.uiv_packer": "§2Епічний пакувальник III§r", + "block.gtceu.uiv_polarizer": "§2Епічний намагнічувач III§r", + "block.gtceu.uiv_quantum_chest": "Квантова скриня XI", + "block.gtceu.uiv_quantum_tank": "Квантовий резервуар XI", + "block.gtceu.uiv_rock_crusher": "§2Епічна кам'яна дробарка III§r", + "block.gtceu.uiv_rotor_holder": "§2UIV тримач ротора", + "block.gtceu.uiv_scanner": "§2Епічний сканер III§r", + "block.gtceu.uiv_sifter": "§2Епічний просіювач III§r", + "block.gtceu.uiv_substation_input_hatch_64a": "§2UIV 64A енергетичний люк підстанції", + "block.gtceu.uiv_substation_output_hatch_64a": "§2UIV 64A динамо-люк підстанції", + "block.gtceu.uiv_thermal_centrifuge": "§2Епічна термічна центрифуга III§r", + "block.gtceu.uiv_transformer_16a": "§2Надмірно неосяжна напруга§r Силовий трансформатор", + "block.gtceu.uiv_transformer_1a": "§2Надмірно неосяжна напруга§r Трансформатор", + "block.gtceu.uiv_transformer_2a": "§2Надмірно неосяжна напруга§r Трансформатор високого струму (2x)", + "block.gtceu.uiv_transformer_4a": "§2Надмірно неосяжна напруга§r Трансформатор високого струму (4x)", + "block.gtceu.uiv_wiremill": "§2Епічний волок III§r", + "block.gtceu.ulv_16a_energy_converter": "§8ULV§r 16§eA§r енергетичний конвертер", + "block.gtceu.ulv_1a_energy_converter": "§8ULV§r 1§eA§r енергетичний конвертер", + "block.gtceu.ulv_4a_energy_converter": "§8ULV§r 4§eA§r енергетичний конвертер", + "block.gtceu.ulv_8a_energy_converter": "§8ULV§r 8§eA§r енергетичний конвертер", + "block.gtceu.ulv_battery_buffer_16x": "§8Надмірно низька напруга§r 16x акумуляторний буфер", + "block.gtceu.ulv_battery_buffer_4x": "§8Надмірно низька напруга§r 4x акумуляторний буфер", + "block.gtceu.ulv_battery_buffer_8x": "§8Надмірно низька напруга§r 8x акумуляторний буфер", + "block.gtceu.ulv_charger_4x": "§8Надмірно низька напруга§r 4x турбозарядник", + "block.gtceu.ulv_energy_input_hatch": "§8ULV енергетичний люк", + "block.gtceu.ulv_energy_output_hatch": "§8ULV динамо-люк", + "block.gtceu.ulv_input_bus": "§8ULV вхідна шина", + "block.gtceu.ulv_input_hatch": "§8ULV ввідний люк", + "block.gtceu.ulv_machine_casing": "ULV корпус машини", + "block.gtceu.ulv_machine_hull": "§8ULV§f машинна основа", + "block.gtceu.ulv_output_bus": "§8ULV вихідна шина", + "block.gtceu.ulv_output_hatch": "§8ULV вивідний люк", + "block.gtceu.ulv_transformer_16a": "§8Надмірно низька напруга§r Силовий трансформатор", + "block.gtceu.ulv_transformer_1a": "§8Надмірно низька напруга§r Трансформатор", + "block.gtceu.ulv_transformer_2a": "§8Надмірно низька напруга§r Трансформатор високого струму (2x)", + "block.gtceu.ulv_transformer_4a": "§8Надмірно низька напруга§r Трансформатор високого струму (4x)", + "block.gtceu.uv_1024a_laser_source_hatch": "§3UV§r 1,024§eA§r люк джерела лазера", + "block.gtceu.uv_1024a_laser_target_hatch": "§3UV§r 1,024§eA§r люк цілі лазера", + "block.gtceu.uv_16a_energy_converter": "§3UV§r 16§eA§r енергетичний конвертер", + "block.gtceu.uv_1a_energy_converter": "§3UV§r 1§eA§r енергетичний конвертер", + "block.gtceu.uv_256a_laser_source_hatch": "§3UV§r 256§eA§r люк джерела лазера", + "block.gtceu.uv_256a_laser_target_hatch": "§3UV§r 256§eA§r люк цілі лазера", + "block.gtceu.uv_4096a_laser_source_hatch": "§3UV§r 4,096§eA§r люк джерела лазера", + "block.gtceu.uv_4096a_laser_target_hatch": "§3UV§r 4,096§eA§r люк цілі лазера", + "block.gtceu.uv_4a_energy_converter": "§3UV§r 4§eA§r енергетичний конвертер", + "block.gtceu.uv_8a_energy_converter": "§3UV§r 8§eA§r енергетичний конвертер", + "block.gtceu.uv_alloy_smelter": "§3Ультимативна плавильня сплавів §r ", + "block.gtceu.uv_arc_furnace": "§3Ультимативна дугова піч§r ", + "block.gtceu.uv_assembler": "§3Ультимативний збирач§r ", + "block.gtceu.uv_autoclave": "§3Ультимативний автоклав§r ", + "block.gtceu.uv_battery_buffer_16x": "§3Ультимативна напруга§r 16x акумуляторний буфер", + "block.gtceu.uv_battery_buffer_4x": "§3Ультимативна напруга§r 4x акумуляторний буфер", + "block.gtceu.uv_battery_buffer_8x": "§3Ультимативна напруга§r 8x акумуляторний буфер", + "block.gtceu.uv_bender": "§3Ультимативний згинач§r ", + "block.gtceu.uv_brewery": "§3Ультимативний варильник§r ", + "block.gtceu.uv_canner": "§3Ультимативний пакувальник§r ", + "block.gtceu.uv_centrifuge": "§3Ультимативна центрифуга§r ", + "block.gtceu.uv_charger_4x": "§3Ультимативна напруга§r 4x турбозарядник", + "block.gtceu.uv_chemical_bath": "§3Ультимативна хімічна ванна§r ", + "block.gtceu.uv_chemical_reactor": "§3Ультимативний хімічний реактор§r ", + "block.gtceu.uv_circuit_assembler": "§3Ультимативний схемотехнічний збирач§r ", + "block.gtceu.uv_compressor": "§3Ультимативний компресор§r ", + "block.gtceu.uv_cutter": "§3Ультимативний різак§r ", + "block.gtceu.uv_diode": "§3UV діод", + "block.gtceu.uv_distillery": "§3Ультимативний дистилятор§r ", + "block.gtceu.uv_dual_input_hatch": "§3UV подвійний ввідний люк", + "block.gtceu.uv_dual_output_hatch": "§3UV подвійний вивідний люк", + "block.gtceu.uv_electric_furnace": "§3Ультимативна електрична піч§r ", + "block.gtceu.uv_electrolyzer": "§3Ультимативний електролізер§r ", + "block.gtceu.uv_electromagnetic_separator": "§3Ультимативний електромагнітний сепаратор§r ", + "block.gtceu.uv_energy_input_hatch": "§3UV енергетичний люк", + "block.gtceu.uv_energy_input_hatch_16a": "§3UV 16A енергетичний люк", + "block.gtceu.uv_energy_input_hatch_4a": "§3UV 4A енергетичний люк", + "block.gtceu.uv_energy_output_hatch": "§3UV динамо-люк", + "block.gtceu.uv_energy_output_hatch_16a": "§3UV 16A динамо-люк", + "block.gtceu.uv_energy_output_hatch_4a": "§3UV 4A динамо-люк", + "block.gtceu.uv_extractor": "§3Ультимативний екстрактор§r ", + "block.gtceu.uv_extruder": "§3Ультимативний екструдер§r ", + "block.gtceu.uv_fermenter": "§3Ультимативний ферментатор§r ", + "block.gtceu.uv_fluid_heater": "§3Ультимативний рідинний нагрівач§r ", + "block.gtceu.uv_fluid_passthrough_hatch": "§3UV прохідний рідинний люк", + "block.gtceu.uv_fluid_solidifier": "§3Ультимативний рідинний затверджувач§r ", + "block.gtceu.uv_forge_hammer": "§3Ультимативний ковальський молот§r ", + "block.gtceu.uv_forming_press": "§3Ультимативний формовий прес§r ", + "block.gtceu.uv_fusion_reactor": "Комп'ютер термоядерного реактора MK III", + "block.gtceu.uv_gas_collector": "§3Ультимативний газозбірник§r ", + "block.gtceu.uv_hermetic_casing": "Герметичний корпус VIII", + "block.gtceu.uv_input_bus": "§3UV вхідна шина", + "block.gtceu.uv_input_hatch": "§3UV ввідний люк", + "block.gtceu.uv_input_hatch_4x": "§3UV чотирикамерний ввідний люк", + "block.gtceu.uv_input_hatch_9x": "§3UV дев'ятикамерний ввідний люк", + "block.gtceu.uv_item_passthrough_hatch": "§3UV прохідний предметний люк", + "block.gtceu.uv_lapotronic_battery": "UV лапотронний акумулятор", + "block.gtceu.uv_laser_engraver": "§3Ультимативний літограф§r ", + "block.gtceu.uv_lathe": "§3Ультимативний токар§r ", + "block.gtceu.uv_macerator": "§3Ультимативний подрібнювач§r ", + "block.gtceu.uv_machine_casing": "UV корпус машини", + "block.gtceu.uv_machine_hull": "§3UV§f машинна основа", + "block.gtceu.uv_mixer": "§3Ультимативний змішувач§r ", + "block.gtceu.uv_muffler_hatch": "Люк вихлопу§3 UV", + "block.gtceu.uv_ore_washer": "§3Ультимативний рудопромивач§r ", + "block.gtceu.uv_output_bus": "§3UV вихідна шина", + "block.gtceu.uv_output_hatch": "§3UV вивідний люк", + "block.gtceu.uv_output_hatch_4x": "§3UV чотирикамерний вивідний люк", + "block.gtceu.uv_output_hatch_9x": "§3UV дев'ятикамерний вивідний люк", + "block.gtceu.uv_packer": "§3Ультимативний пакувальник§r ", + "block.gtceu.uv_parallel_hatch": "Супер люк паралельного контролю", + "block.gtceu.uv_polarizer": "§3Ультимативний намагнічувач§r ", + "block.gtceu.uv_quantum_chest": "Квантова скриня VIII", + "block.gtceu.uv_quantum_tank": "Квантовий резервуар VIII", + "block.gtceu.uv_rock_crusher": "§3Ультимативна кам'яна дробарка§r ", + "block.gtceu.uv_rotor_holder": "§3UV тримач ротора", + "block.gtceu.uv_scanner": "§3Ультимативний сканер§r ", + "block.gtceu.uv_sifter": "§3Ультимативний просіювач§r ", + "block.gtceu.uv_substation_input_hatch_64a": "§3UV 64A енергетичний люк підстанції", + "block.gtceu.uv_substation_output_hatch_64a": "§3UV 64A динамо-люк підстанції", + "block.gtceu.uv_thermal_centrifuge": "§3Ультимативна термічна центрифуга§r ", + "block.gtceu.uv_transformer_16a": "§3Ультимативна напруга§r Силовий трансформатор", + "block.gtceu.uv_transformer_1a": "§3Ультимативна напруга§r Трансформатор", + "block.gtceu.uv_transformer_2a": "§3Ультимативна напруга§r Трансформатор високого струму (2x)", + "block.gtceu.uv_transformer_4a": "§3Ультимативна напруга§r Трансформатор високого струму (4x)", + "block.gtceu.uv_wiremill": "§3Ультимативний волок§r ", + "block.gtceu.uv_world_accelerator": "§3Ультимативний світовий прискорювач§r ", + "block.gtceu.uxv_1024a_laser_source_hatch": "§eUXV§r 1,024§eA§r люк джерела лазера", + "block.gtceu.uxv_1024a_laser_target_hatch": "§eUXV§r 1,024§eA§r люк цілі лазера", + "block.gtceu.uxv_16a_energy_converter": "§eUXV§r 16§eA§r енергетичний конвертер", + "block.gtceu.uxv_1a_energy_converter": "§eUXV§r 1§eA§r енергетичний конвертер", + "block.gtceu.uxv_256a_laser_source_hatch": "§eUXV§r 256§eA§r люк джерела лазера", + "block.gtceu.uxv_256a_laser_target_hatch": "§eUXV§r 256§eA§r люк цілі лазера", + "block.gtceu.uxv_4096a_laser_source_hatch": "§eUXV§r 4,096§eA§r люк джерела лазера", + "block.gtceu.uxv_4096a_laser_target_hatch": "§eUXV§r 4,096§eA§r люк цілі лазера", + "block.gtceu.uxv_4a_energy_converter": "§eUXV§r 4§eA§r енергетичний конвертер", + "block.gtceu.uxv_8a_energy_converter": "§eUXV§r 8§eA§r енергетичний конвертер", + "block.gtceu.uxv_alloy_smelter": "§eЕпічна плавильня сплавів IV§r", + "block.gtceu.uxv_arc_furnace": "§eЕпічна дугова піч IV§r", + "block.gtceu.uxv_assembler": "§eЕпічний збирач IV§r", + "block.gtceu.uxv_autoclave": "§eЕпічний автоклав IV§r", + "block.gtceu.uxv_battery_buffer_16x": "§eНадмірно екстремальна напруга§r 16x акумуляторний буфер", + "block.gtceu.uxv_battery_buffer_4x": "§eНадмірно екстремальна напруга§r 4x акумуляторний буфер", + "block.gtceu.uxv_battery_buffer_8x": "§eНадмірно екстремальна напруга§r 8x акумуляторний буфер", + "block.gtceu.uxv_bender": "§eЕпічний згинач IV§r", + "block.gtceu.uxv_brewery": "§eЕпічний варильник IV§r", + "block.gtceu.uxv_canner": "§eЕпічний пакувальник IV§r", + "block.gtceu.uxv_centrifuge": "§eЕпічна центрифуга IV§r", + "block.gtceu.uxv_charger_4x": "§eНадмірно екстремальна напруга§r 4x турбозарядник", + "block.gtceu.uxv_chemical_bath": "§eЕпічна хімічна ванна IV§r", + "block.gtceu.uxv_chemical_reactor": "§eЕпічний хімічний реактор IV§r", + "block.gtceu.uxv_circuit_assembler": "§eЕпічний схемотехнічний збирач IV§r", + "block.gtceu.uxv_compressor": "§eЕпічний компресор IV§r", + "block.gtceu.uxv_cutter": "§eЕпічний різак IV§r", + "block.gtceu.uxv_diode": "§eUXV діод", + "block.gtceu.uxv_distillery": "§eЕпічний дистилятор IV§r", + "block.gtceu.uxv_dual_input_hatch": "§eUXV подвійний ввідний люк", + "block.gtceu.uxv_dual_output_hatch": "§eUXV подвійний вивідний люк", + "block.gtceu.uxv_electric_furnace": "§eЕпічна електрична піч IV§r", + "block.gtceu.uxv_electrolyzer": "§eЕпічний електролізер IV§r", + "block.gtceu.uxv_electromagnetic_separator": "§eЕпічний електромагнітний сепаратор IV§r", + "block.gtceu.uxv_energy_input_hatch": "§eUXV енергетичний люк", + "block.gtceu.uxv_energy_input_hatch_16a": "§eUXV 16A енергетичний люк", + "block.gtceu.uxv_energy_input_hatch_4a": "§eUXV 4A енергетичний люк", + "block.gtceu.uxv_energy_output_hatch": "§eUXV динамо-люк", + "block.gtceu.uxv_energy_output_hatch_16a": "§eUXV 16A динамо-люк", + "block.gtceu.uxv_energy_output_hatch_4a": "§eUXV 4A динамо-люк", + "block.gtceu.uxv_extractor": "§eЕпічний екстрактор IV§r", + "block.gtceu.uxv_extruder": "§eЕпічний екструдер IV§r", + "block.gtceu.uxv_fermenter": "§eЕпічний ферментатор IV§r", + "block.gtceu.uxv_fluid_heater": "§eЕпічний рідинний нагрівач IV§r", + "block.gtceu.uxv_fluid_passthrough_hatch": "§eUXV прохідний рідинний люк", + "block.gtceu.uxv_fluid_solidifier": "§eЕпічний рідинний затверджувач IV§r", + "block.gtceu.uxv_forge_hammer": "§eЕпічний ковальський молот IV§r", + "block.gtceu.uxv_forming_press": "§eЕпічний формовий прес IV§r", + "block.gtceu.uxv_gas_collector": "§eЕпічний газозбірник IV§r", + "block.gtceu.uxv_input_bus": "§eUXV вхідна шина", + "block.gtceu.uxv_input_hatch": "§eUXV ввідний люк", + "block.gtceu.uxv_input_hatch_4x": "§eUXV чотирикамерний ввідний люк", + "block.gtceu.uxv_input_hatch_9x": "§eUXV дев'ятикамерний ввідний люк", + "block.gtceu.uxv_item_passthrough_hatch": "§eUXV прохідний предметний люк", + "block.gtceu.uxv_laser_engraver": "§eЕпічний літограф IV§r", + "block.gtceu.uxv_lathe": "§eЕпічний токар IV§r", + "block.gtceu.uxv_macerator": "§eЕпічний подрібнювач IV§r", + "block.gtceu.uxv_machine_casing": "UXV корпус машини", + "block.gtceu.uxv_machine_hull": "§eUXV§f машинна основа", + "block.gtceu.uxv_mixer": "§eЕпічний змішувач IV§r", + "block.gtceu.uxv_muffler_hatch": "Люк вихлопу§e UXV", + "block.gtceu.uxv_ore_washer": "§eЕпічний рудопромивач IV§r", + "block.gtceu.uxv_output_bus": "§eUXV вихідна шина", + "block.gtceu.uxv_output_hatch": "§eUXV вивідний люк", + "block.gtceu.uxv_output_hatch_4x": "§eUXV чотирикамерний вивідний люк", + "block.gtceu.uxv_output_hatch_9x": "§eUXV дев'ятикамерний вивідний люк", + "block.gtceu.uxv_packer": "§eЕпічний пакувальник IV§r", + "block.gtceu.uxv_polarizer": "§eЕпічний намагнічувач IV§r", + "block.gtceu.uxv_quantum_chest": "Квантова скриня XII", + "block.gtceu.uxv_quantum_tank": "Квантовий резервуар XII", + "block.gtceu.uxv_rock_crusher": "§eЕпічна кам'яна дробарка IV§r", + "block.gtceu.uxv_rotor_holder": "§eUXV тримач ротора", + "block.gtceu.uxv_scanner": "§eЕпічний сканер IV§r", + "block.gtceu.uxv_sifter": "§eЕпічний просіювач IV§r", + "block.gtceu.uxv_substation_input_hatch_64a": "§eUXV 64A енергетичний люк підстанції", + "block.gtceu.uxv_substation_output_hatch_64a": "§eUXV 64A динамо-люк підстанції", + "block.gtceu.uxv_thermal_centrifuge": "§eЕпічна термічна центрифуга IV§r", + "block.gtceu.uxv_transformer_16a": "§eНадмірно екстремальна напруга§r Силовий трансформатор", + "block.gtceu.uxv_transformer_1a": "§eНадмірно екстремальна напруга§r Трансформатор", + "block.gtceu.uxv_transformer_2a": "§eНадмірно екстремальна напруга§r Трансформатор високого струму (2x)", + "block.gtceu.uxv_transformer_4a": "§eНадмірно екстремальна напруга§r Трансформатор високого струму (4x)", + "block.gtceu.uxv_wiremill": "§eЕпічний волок IV§r", + "block.gtceu.vacuum_freezer": "Вакуумна морозильна камера", + "block.gtceu.vibration_safe_casing": "Вібростійкий корпус", + "block.gtceu.void_hazard_sign_block": "Блок зі знаком небезпеки порожнечі", + "block.gtceu.watertight_casing": "Водонепроникний корпус", + "block.gtceu.white_borderless_lamp": "Біла необлямована лампа", + "block.gtceu.white_lamp": "Біла лампа", + "block.gtceu.white_large_metal_sheet": "Біле велике металеве покриття", + "block.gtceu.white_metal_sheet": "Біле металеве покриття", + "block.gtceu.white_studs": "Білі кубики", + "block.gtceu.wire_coil.tooltip_cracking": "§8Крекінг-установка:", + "block.gtceu.wire_coil.tooltip_energy_cracking": " §aВикористання енергії:§f %s%%", + "block.gtceu.wire_coil.tooltip_energy_smelter": "§a використання енергії:§f %s EU/т", + "block.gtceu.wire_coil.tooltip_extended_info": "§7Утримуйте Shift, щоб показати інформацію з бонусу котушки", + "block.gtceu.wire_coil.tooltip_heat": "§cБазова теплоємність:§f %d K", + "block.gtceu.wire_coil.tooltip_parallel_smelter": "§5 Макс. паралелей:§f %s", + "block.gtceu.wire_coil.tooltip_pyro": "§8Піролізна піч:", + "block.gtceu.wire_coil.tooltip_smelter": "§8Мультиплавильня:", + "block.gtceu.wire_coil.tooltip_speed_pyro": "§b Швидкість обробки:§f %s%%", + "block.gtceu.wood_crate": "Дерев'яний ящик", + "block.gtceu.wood_drum": "Дерев'яна бочка", + "block.gtceu.wood_wall": "Дерев'яна стіна", + "block.gtceu.wooden_multiblock_tank": "Дерев'яний багатоблочний резервуар", + "block.gtceu.wooden_tank_valve": "Дерев'яний вентиль резервуара", + "block.gtceu.yellow_borderless_lamp": "Жовта необлямована лампа", + "block.gtceu.yellow_lamp": "Жовта лампа", + "block.gtceu.yellow_large_metal_sheet": "Жовте велике металеве покриття", + "block.gtceu.yellow_metal_sheet": "Жовте металеве покриття", + "block.gtceu.yellow_stripes_block.a": "Блок жовтих стрічок", + "block.gtceu.yellow_stripes_block.b": "Блок жовтих стрічок", + "block.gtceu.yellow_stripes_block.c": "Блок жовтих стрічок", + "block.gtceu.yellow_stripes_block.d": "Блок жовтих стрічок", + "block.gtceu.yellow_stripes_block_a": "Блок жовтих стрічок A", + "block.gtceu.yellow_stripes_block_b": "Блок жовтих стрічок B", + "block.gtceu.yellow_studs": "Жовті кубики", + "block.gtceu.zpm_1024a_laser_source_hatch": "§cZPM§r 1,024§eA§r люк джерела лазера", + "block.gtceu.zpm_1024a_laser_target_hatch": "§cZPM§r 1,024§eA§r люк цілі лазера", + "block.gtceu.zpm_16a_energy_converter": "§cZPM§r 16§eA§r енергетичний конвертер", + "block.gtceu.zpm_1a_energy_converter": "§cZPM§r 1§eA§r енергетичний конвертер", + "block.gtceu.zpm_256a_laser_source_hatch": "§cZPM§r 256§eA§r люк джерела лазера", + "block.gtceu.zpm_256a_laser_target_hatch": "§cZPM§r 256§eA§r люк цілі лазера", + "block.gtceu.zpm_4096a_laser_source_hatch": "§cZPM§r 4,096§eA§r люк джерела лазера", + "block.gtceu.zpm_4096a_laser_target_hatch": "§cZPM§r 4,096§eA§r люк цілі лазера", + "block.gtceu.zpm_4a_energy_converter": "§cZPM§r 4§eA§r енергетичний конвертер", + "block.gtceu.zpm_8a_energy_converter": "§cZPM§r 8§eA§r енергетичний конвертер", + "block.gtceu.zpm_alloy_smelter": "§cЕлітна плавильня сплавів III§r", + "block.gtceu.zpm_arc_furnace": "§cЕлітна дугова піч III§r", + "block.gtceu.zpm_assembler": "§cЕлітний збирач III§r", + "block.gtceu.zpm_autoclave": "§cЕлітний автоклав III§r", + "block.gtceu.zpm_battery_buffer_16x": "§cZPM-напруга§r 16x акумуляторний буфер", + "block.gtceu.zpm_battery_buffer_4x": "§cZPM-напруга§r 4x акумуляторний буфер", + "block.gtceu.zpm_battery_buffer_8x": "§cZPM-напруга§r 8x акумуляторний буфер", + "block.gtceu.zpm_bender": "§cЕлітний згинач III§r", + "block.gtceu.zpm_brewery": "§cЕлітний варильник III§r", + "block.gtceu.zpm_canner": "§cЕлітний пакувальник III§r", + "block.gtceu.zpm_centrifuge": "§cЕлітна центрифуга III§r", + "block.gtceu.zpm_charger_4x": "§cZPM-напруга§r 4x турбозарядник", + "block.gtceu.zpm_chemical_bath": "§cЕлітна хімічна ванна III§r", + "block.gtceu.zpm_chemical_reactor": "§cЕлітний хімічний реактор III§r", + "block.gtceu.zpm_circuit_assembler": "§cЕлітний схемотехнічний збирач III§r", + "block.gtceu.zpm_compressor": "§cЕлітний компресор III§r", + "block.gtceu.zpm_cutter": "§cЕлітний різак III§r", + "block.gtceu.zpm_diode": "§cZPM діод", + "block.gtceu.zpm_distillery": "§cЕлітний дистилятор III§r", + "block.gtceu.zpm_dual_input_hatch": "§cZPM подвійний ввідний люк", + "block.gtceu.zpm_dual_output_hatch": "§cZPM подвійний вивідний люк", + "block.gtceu.zpm_electric_furnace": "§cЕлітна електрична піч III§r", + "block.gtceu.zpm_electrolyzer": "§cЕлітний електролізер III§r", + "block.gtceu.zpm_electromagnetic_separator": "§cЕлітний електромагнітний сепаратор III§r", + "block.gtceu.zpm_energy_input_hatch": "§cZPM енергетичний люк", + "block.gtceu.zpm_energy_input_hatch_16a": "§cZPM 16A енергетичний люк", + "block.gtceu.zpm_energy_input_hatch_4a": "§cZPM 4A енергетичний люк", + "block.gtceu.zpm_energy_output_hatch": "§cZPM динамо-люк", + "block.gtceu.zpm_energy_output_hatch_16a": "§cZPM 16A динамо-люк", + "block.gtceu.zpm_energy_output_hatch_4a": "§cZPM 4A динамо-люк", + "block.gtceu.zpm_extractor": "§cЕлітний екстрактор III§r", + "block.gtceu.zpm_extruder": "§cЕлітний екструдер III§r", + "block.gtceu.zpm_fermenter": "§cЕлітний ферментатор III§r", + "block.gtceu.zpm_fluid_heater": "§cЕлітний рідинний нагрівач III§r", + "block.gtceu.zpm_fluid_passthrough_hatch": "§cZPM прохідний рідинний люк", + "block.gtceu.zpm_fluid_solidifier": "§cЕлітний рідинний затверджувач III§r", + "block.gtceu.zpm_forge_hammer": "§cЕлітний ковальський молот III§r", + "block.gtceu.zpm_forming_press": "§cЕлітний формовий прес III§r", + "block.gtceu.zpm_fusion_reactor": "Комп'ютер термоядерного реактора MK II", + "block.gtceu.zpm_gas_collector": "§cЕлітний газозбірник III§r", + "block.gtceu.zpm_hermetic_casing": "Герметичний корпус VII", + "block.gtceu.zpm_input_bus": "§cZPM вхідна шина", + "block.gtceu.zpm_input_hatch": "§cZPM ввідний люк", + "block.gtceu.zpm_input_hatch_4x": "§cZPM чотирикамерний ввідний люк", + "block.gtceu.zpm_input_hatch_9x": "§cZPM дев'ятикамерний ввідний люк", + "block.gtceu.zpm_item_passthrough_hatch": "§cZPM прохідний предметний люк", + "block.gtceu.zpm_lapotronic_battery": "ZPM лапотронний акумулятор", + "block.gtceu.zpm_laser_engraver": "§cЕлітний літограф III§r", + "block.gtceu.zpm_lathe": "§cЕлітний токар III§r", + "block.gtceu.zpm_macerator": "§cЕлітний подрібнювач III§r", + "block.gtceu.zpm_machine_casing": "ZPM корпус машини", + "block.gtceu.zpm_machine_hull": "§cZPM§f машинна основа", + "block.gtceu.zpm_mixer": "§cЕлітний змішувач III§r", + "block.gtceu.zpm_muffler_hatch": "Люк вихлопу§c ZPM", + "block.gtceu.zpm_ore_washer": "§cЕлітний рудопромивач III§r", + "block.gtceu.zpm_output_bus": "§cZPM вихідна шина", + "block.gtceu.zpm_output_hatch": "§cZPM вивідний люк", + "block.gtceu.zpm_output_hatch_4x": "§cZPM чотирикамерний вивідний люк", + "block.gtceu.zpm_output_hatch_9x": "§cZPM дев'ятикамерний вивідний люк", + "block.gtceu.zpm_packer": "§cЕлітний пакувальник III§r", + "block.gtceu.zpm_parallel_hatch": "Ультимативний люк паралельного контролю", + "block.gtceu.zpm_polarizer": "§cЕлітний намагнічувач III§r", + "block.gtceu.zpm_quantum_chest": "Квантова скриня VII", + "block.gtceu.zpm_quantum_tank": "Квантовий резервуар VII", + "block.gtceu.zpm_rock_crusher": "§cЕлітна кам'яна дробарка III§r", + "block.gtceu.zpm_rotor_holder": "§cZPM тримач ротора", + "block.gtceu.zpm_scanner": "§cЕлітний сканер III§r", + "block.gtceu.zpm_sifter": "§cЕлітний просіювач III§r", + "block.gtceu.zpm_substation_input_hatch_64a": "§cZPM 64A енергетичний люк підстанції", + "block.gtceu.zpm_substation_output_hatch_64a": "§cZPM 64A динамо-люк підстанції", + "block.gtceu.zpm_thermal_centrifuge": "§cЕлітна термічна центрифуга III§r", + "block.gtceu.zpm_transformer_16a": "§cZPM-напруга§r Силовий трансформатор", + "block.gtceu.zpm_transformer_1a": "§cZPM-напруга§r Трансформатор", + "block.gtceu.zpm_transformer_2a": "§cZPM-напруга§r Трансформатор високого струму (2x)", + "block.gtceu.zpm_transformer_4a": "§cZPM-напруга§r Трансформатор високого струму (4x)", + "block.gtceu.zpm_wiremill": "§cЕлітний волок III§r", + "block.gtceu.zpm_world_accelerator": "§cЕлітний світовий прискорювач III§r", + "block.sterilizing_filter_casing.tooltip": "Створює§a стерильне§7 середовище", + "block.surface_rock": "%s (поверхневий поклад)", + "button.gtceu.mark_as_depleted.name": "Позначити як виснажений", + "button.gtceu.toggle_waypoint.name": "Перемикнути маршрутну точку", + "command.gtceu.cape.failure.does_not_exist": "Плаща «%s» не існує", + "command.gtceu.cape.give.failed": "Нових плащів не відкрито", + "command.gtceu.cape.give.success.multiple": "Відкрито %s плащів для %s гравців", + "command.gtceu.cape.give.success.single": "Відкрито %s плащів для %s", + "command.gtceu.cape.take.failed": "Нічого забирати", + "command.gtceu.cape.take.success.multiple": "Забрано %s плащів у %s гравців", + "command.gtceu.cape.take.success.single": "Забрано %s плащів у %s", + "command.gtceu.cape.use.failed": "%s не може користуватися плащем %s, тому що не має його (або його не існує)!", + "command.gtceu.cape.use.success": "%s тепер користується плащем %s", + "command.gtceu.cape.use.success.none": "%s більше не користується плащем", + "command.gtceu.dump_data.success": "Перекинуто %s ресурсів з реєстру %s до %s", + "command.gtceu.medical_condition.get": "Гравець %s має такі медичні показання:", + "command.gtceu.medical_condition.get.element": "Ураження - %s§r: %s хвилин %s секунд", + "command.gtceu.medical_condition.get.element.permanent": "Ураження - %s§r: %s хвилин %s секунд (постійне)", + "command.gtceu.medical_condition.get.empty": "Гравець %s не має медичних показань.", + "command.gtceu.place_vein.failure": "Не вдалося розмістити жилу %s на позиції %s", + "command.gtceu.place_vein.success": "Розміщено жилу %s на позиції %s", + "command.gtceu.share_prospection_data.notification": "%s ділиться з вами розвідницькими даними!", + "config.gtceu.option.addLoot": "addLoot", + "config.gtceu.option.ae2": "ae2", + "config.gtceu.option.allUniqueStoneTypes": "allUniqueStoneTypes", + "config.gtceu.option.allowDrumsInputFluidsFromOutputSide": "allowDrumsInputFluidsFromOutputSide", + "config.gtceu.option.animationTime": "animationTime", + "config.gtceu.option.arcRecyclingYield": "arcRecyclingYield", + "config.gtceu.option.armorHud": "armorHud", + "config.gtceu.option.batchDuration": "batchDuration", + "config.gtceu.option.bedrockOreDistance": "bedrockOreDistance", + "config.gtceu.option.bedrockOreDropTagPrefix": "bedrockOreDropTagPrefix", + "config.gtceu.option.borderColor": "borderColor", + "config.gtceu.option.bronzeBoilerHeatSpeed": "bronzeBoilerHeatSpeed", + "config.gtceu.option.bronzeBoilerMaxTemperature": "bronzeBoilerMaxTemperature", + "config.gtceu.option.buttonAnchor": "buttonAnchor", + "config.gtceu.option.casingsPerCraft": "casingsPerCraft", + "config.gtceu.option.cleanMultiblocks": "cleanMultiblocks", + "config.gtceu.option.client": "client", + "config.gtceu.option.coloredTieredMachineOutline": "coloredTieredMachineOutline", + "config.gtceu.option.coloredWireOutline": "coloredWireOutline", + "config.gtceu.option.compat": "compat", + "config.gtceu.option.createCompat": "createCompat", + "config.gtceu.option.debug": "debug", + "config.gtceu.option.debugWorldgen": "debugWorldgen", + "config.gtceu.option.defaultPaintingColor": "defaultPaintingColor", + "config.gtceu.option.defaultUIColor": "defaultUIColor", + "config.gtceu.option.dev": "dev", + "config.gtceu.option.direction": "direction", + "config.gtceu.option.disableManualCompression": "disableManualCompression", + "config.gtceu.option.doBedrockOres": "doBedrockOres", + "config.gtceu.option.doSuperflatOres": "doSuperflatOres", + "config.gtceu.option.doesExplosionDamagesTerrain": "doesExplosionDamagesTerrain", + "config.gtceu.option.drum": "drum", + "config.gtceu.option.dumpAssets": "dumpAssets", + "config.gtceu.option.dumpRecipes": "dumpRecipes", + "config.gtceu.option.enableArcRecycling": "enableArcRecycling", + "config.gtceu.option.enableCleanroom": "enableCleanroom", + "config.gtceu.option.enableExtractorRecycling": "enableExtractorRecycling", + "config.gtceu.option.enableFEConverters": "enableFEConverters", + "config.gtceu.option.enableMaceratorRecycling": "enableMaceratorRecycling", + "config.gtceu.option.enableMaintenance": "enableMaintenance", + "config.gtceu.option.enableResearch": "enableResearch", + "config.gtceu.option.enableTieredCasings": "enableTieredCasings", + "config.gtceu.option.enableWorldAccelerators": "enableWorldAccelerators", + "config.gtceu.option.enchantedTools": "enchantedTools", + "config.gtceu.option.energy": "energy", + "config.gtceu.option.energyConsumption": "energyConsumption", + "config.gtceu.option.energyUsageMultiplier": "energyUsageMultiplier", + "config.gtceu.option.environmentalHazardDecayRate": "environmentalHazardDecayRate", + "config.gtceu.option.environmentalHazards": "environmentalHazards", + "config.gtceu.option.euToFeRatio": "euToFeRatio", + "config.gtceu.option.extractorRecyclingYield": "extractorRecyclingYield", + "config.gtceu.option.feToEuRatio": "feToEuRatio", + "config.gtceu.option.flintAndSteelRequireSteel": "flintAndSteelRequireSteel", + "config.gtceu.option.ftbChunksIntegration": "ftbChunksIntegration", + "config.gtceu.option.gameplay": "gameplay", + "config.gtceu.option.generateLowQualityGems": "generateLowQualityGems", + "config.gtceu.option.ghostCircuit": "ghostCircuit", + "config.gtceu.option.gt6StylePipesCables": "gt6StylePipesCables", + "config.gtceu.option.hardAdvancedIronRecipes": "hardAdvancedIronRecipes", + "config.gtceu.option.hardDyeRecipes": "hardDyeRecipes", + "config.gtceu.option.hardGlassRecipes": "hardGlassRecipes", + "config.gtceu.option.hardIronRecipes": "hardIronRecipes", + "config.gtceu.option.hardMiscRecipes": "hardMiscRecipes", + "config.gtceu.option.hardMultiRecipes": "hardMultiRecipes", + "config.gtceu.option.hardRedstoneRecipes": "hardRedstoneRecipes", + "config.gtceu.option.hardToolArmorRecipes": "hardToolArmorRecipes", + "config.gtceu.option.hardWoodRecipes": "hardWoodRecipes", + "config.gtceu.option.harderBrickRecipes": "harderBrickRecipes", + "config.gtceu.option.harderCharcoalRecipe": "harderCharcoalRecipe", + "config.gtceu.option.harderCircuitRecipes": "harderCircuitRecipes", + "config.gtceu.option.harderRods": "harderRods", + "config.gtceu.option.harmlessActiveTransformers": "harmlessActiveTransformers", + "config.gtceu.option.hazardsEnabled": "hazardsEnabled", + "config.gtceu.option.hideFacadesInRecipeViewer": "hideFacadesInRecipeViewer", + "config.gtceu.option.hideFilledCellsInRecipeViewer": "hideFilledCellsInRecipeViewer", + "config.gtceu.option.hideOreProcessingDiagrams": "hideOreProcessingDiagrams", + "config.gtceu.option.highTierContent": "highTierContent", + "config.gtceu.option.hpLiquidBoilerBaseOutput": "hpLiquidBoilerBaseOutput", + "config.gtceu.option.hpSolarBoilerBaseOutput": "hpSolarBoilerBaseOutput", + "config.gtceu.option.hpSolidBoilerBaseOutput": "hpSolidBoilerBaseOutput", + "config.gtceu.option.hudLocation": "hudLocation", + "config.gtceu.option.hudOffsetX": "hudOffsetX", + "config.gtceu.option.hudOffsetY": "hudOffsetY", + "config.gtceu.option.inWorldPreviewDuration": "inWorldPreviewDuration", + "config.gtceu.option.increaseDungeonLoot": "increaseDungeonLoot", + "config.gtceu.option.infiniteBedrockOresFluids": "infiniteBedrockOresFluids", + "config.gtceu.option.journeyMapIntegration": "journeyMapIntegration", + "config.gtceu.option.largeBoilers": "largeBoilers", + "config.gtceu.option.ldFluidPipeMinDistance": "ldFluidPipeMinDistance", + "config.gtceu.option.ldItemPipeMinDistance": "ldItemPipeMinDistance", + "config.gtceu.option.liquidBoilerBaseOutput": "liquidBoilerBaseOutput", + "config.gtceu.option.maceratorRecyclingYield": "maceratorRecyclingYield", + "config.gtceu.option.machineSounds": "machineSounds", + "config.gtceu.option.machines": "machines", + "config.gtceu.option.machinesEmissiveTextures": "machinesEmissiveTextures", + "config.gtceu.option.machinesHaveBERsByDefault": "machinesHaveBERsByDefault", + "config.gtceu.option.maintenanceCheckRate": "maintenanceCheckRate", + "config.gtceu.option.meHatchEnergyUsage": "meHatchEnergyUsage", + "config.gtceu.option.minerSpeed": "minerSpeed", + "config.gtceu.option.minimap": "minimap", + "config.gtceu.option.nanoSaber": "nanoSaber", + "config.gtceu.option.nanoSaberBaseDamage": "nanoSaberBaseDamage", + "config.gtceu.option.nanoSaberDamageBoost": "nanoSaberDamageBoost", + "config.gtceu.option.nativeEUToFE": "nativeEUToFE", + "config.gtceu.option.nerfPaperCrafting": "nerfPaperCrafting", + "config.gtceu.option.nerfWoodCrafting": "nerfWoodCrafting", + "config.gtceu.option.onlyOwnerBreak": "onlyOwnerBreak", + "config.gtceu.option.onlyOwnerGUI": "onlyOwnerGUI", + "config.gtceu.option.orderedAssemblyLineFluids": "orderedAssemblyLineFluids", + "config.gtceu.option.orderedAssemblyLineItems": "orderedAssemblyLineItems", + "config.gtceu.option.oreBlockProspectRange": "oreBlockProspectRange", + "config.gtceu.option.oreGenerationChunkCacheSize": "oreGenerationChunkCacheSize", + "config.gtceu.option.oreIconSize": "oreIconSize", + "config.gtceu.option.oreIndicatorChunkCacheSize": "oreIndicatorChunkCacheSize", + "config.gtceu.option.oreIndicators": "oreIndicators", + "config.gtceu.option.oreNamePrefix": "oreNamePrefix", + "config.gtceu.option.oreScaleStop": "oreScaleStop", + "config.gtceu.option.oreVeinGridSize": "oreVeinGridSize", + "config.gtceu.option.oreVeinRandomOffset": "oreVeinRandomOffset", + "config.gtceu.option.oreVeins": "oreVeins", + "config.gtceu.option.ownerOPBypass": "ownerOPBypass", + "config.gtceu.option.prospectorEnergyUseMultiplier": "prospectorEnergyUseMultiplier", + "config.gtceu.option.quantumTank": "quantumTank", + "config.gtceu.option.recipes": "recipes", + "config.gtceu.option.removeSmeltingForEBFMetals": "removeSmeltingForEBFMetals", + "config.gtceu.option.removeVanillaBlockRecipes": "removeVanillaBlockRecipes", + "config.gtceu.option.removeVanillaLargeOreVeins": "removeVanillaLargeOreVeins", + "config.gtceu.option.removeVanillaOreGen": "removeVanillaOreGen", + "config.gtceu.option.removeVanillaTNTRecipe": "removeVanillaTNTRecipe", + "config.gtceu.option.renderFluids": "renderFluids", + "config.gtceu.option.renderGrowingPlants": "renderGrowingPlants", + "config.gtceu.option.renderer": "renderer", + "config.gtceu.option.replaceMinedBlocksWith": "replaceMinedBlocksWith", + "config.gtceu.option.requireGTToolsForBlocks": "requireGTToolsForBlocks", + "config.gtceu.option.rngDamageElectricTools": "rngDamageElectricTools", + "config.gtceu.option.rubberTreeSpawnChance": "rubberTreeSpawnChance", + "config.gtceu.option.sandOresFall": "sandOresFall", + "config.gtceu.option.shouldWeatherOrTerrainExplosion": "shouldWeatherOrTerrainExplosion", + "config.gtceu.option.showDimensionTier": "showDimensionTier", + "config.gtceu.option.smallBoilers": "smallBoilers", + "config.gtceu.option.solarBoilerBaseOutput": "solarBoilerBaseOutput", + "config.gtceu.option.solidBoilerBaseOutput": "solidBoilerBaseOutput", + "config.gtceu.option.sprayCanChainLength": "sprayCanChainLength", + "config.gtceu.option.steamMultiParallelAmount": "steamMultiParallelAmount", + "config.gtceu.option.steamPerWater": "steamPerWater", + "config.gtceu.option.steelBoilerHeatSpeed": "steelBoilerHeatSpeed", + "config.gtceu.option.steelBoilerMaxTemperature": "steelBoilerMaxTemperature", + "config.gtceu.option.steelSteamMultiblocks": "steelSteamMultiblocks", + "config.gtceu.option.surfaceRockProspectRange": "surfaceRockProspectRange", + "config.gtceu.option.tankItemFluidPreview": "tankItemFluidPreview", + "config.gtceu.option.titaniumBoilerHeatSpeed": "titaniumBoilerHeatSpeed", + "config.gtceu.option.titaniumBoilerMaxTemperature": "titaniumBoilerMaxTemperature", + "config.gtceu.option.toggle": "toggle", + "config.gtceu.option.toolCraftingSounds": "toolCraftingSounds", + "config.gtceu.option.toolUseSounds": "toolUseSounds", + "config.gtceu.option.tools": "tools", + "config.gtceu.option.treeFellingDelay": "treeFellingDelay", + "config.gtceu.option.tungstensteelBoilerHeatSpeed": "tungstensteelBoilerHeatSpeed", + "config.gtceu.option.tungstensteelBoilerMaxTemperature": "tungstensteelBoilerMaxTemperature", + "config.gtceu.option.universalHazards": "universalHazards", + "config.gtceu.option.updateIntervals": "updateIntervals", + "config.gtceu.option.useVBO": "useVBO", + "config.gtceu.option.voltageTierAdvImpeller": "voltageTierAdvImpeller", + "config.gtceu.option.voltageTierAdvNanoSuit": "voltageTierAdvNanoSuit", + "config.gtceu.option.voltageTierAdvQuarkTech": "voltageTierAdvQuarkTech", + "config.gtceu.option.voltageTierImpeller": "voltageTierImpeller", + "config.gtceu.option.voltageTierNanoSuit": "voltageTierNanoSuit", + "config.gtceu.option.voltageTierNightVision": "voltageTierNightVision", + "config.gtceu.option.voltageTierQuarkTech": "voltageTierQuarkTech", + "config.gtceu.option.worldAcceleratorBlacklist": "worldAcceleratorBlacklist", + "config.gtceu.option.worldgen": "worldgen", + "config.gtceu.option.xOffset": "xOffset", + "config.gtceu.option.xaerosMapIntegration": "xaerosMapIntegration", + "config.gtceu.option.yOffset": "yOffset", + "config.gtceu.option.zombieSpawnWithSabers": "zombieSpawnWithSabers", + "config.jade.plugin_gtceu.auto_output_info": "[GTCEu] Інфо автовиведення", + "config.jade.plugin_gtceu.cable_info": "[GTCEu] Інфо кабелів", + "config.jade.plugin_gtceu.controllable_provider": "[GTCEu] Контролювання", + "config.jade.plugin_gtceu.data_bank": "[GTCEu] Інфо зберігача даних", + "config.jade.plugin_gtceu.electric_container_provider": "[GTCEu] Електричний контейнер", + "config.jade.plugin_gtceu.energy_converter_provider": "[GTCEu] Режим енергетичного конвертера", + "config.jade.plugin_gtceu.exhaust_vent_info": "[GTCEu] Інфо витяжної вентиляції", + "config.jade.plugin_gtceu.hazard_cleaner_provider": "[GTCEu] Очисник загроз", + "config.jade.plugin_gtceu.machine_mode": "[GTCEu] Режим машини", + "config.jade.plugin_gtceu.maintenance_info": "[GTCEu] Інфо з обслуговування", + "config.jade.plugin_gtceu.me_pattern_buffer": "[GTCEu] Інфо буфера шаблонів", + "config.jade.plugin_gtceu.me_pattern_buffer_proxy": "[GTCEu] Інфо проксі буфера шаблонів", + "config.jade.plugin_gtceu.multiblock_structure": "[GTCEu] Багатоблочна конструкція", + "config.jade.plugin_gtceu.parallel_info": "[GTCEu] Інфо паралелізації", + "config.jade.plugin_gtceu.primitive_pump": "[GTCEu] Інфо примітивної помпи", + "config.jade.plugin_gtceu.recipe_logic_provider": "[GTCEu] Логіка рецептів", + "config.jade.plugin_gtceu.recipe_output_info": "[GTCEu] Інфо виводу рецептів", + "config.jade.plugin_gtceu.stained_color": "[GTCEu] Інфо заплямованого блоку", + "config.jade.plugin_gtceu.steam_boiler_info": "[GTCEu] Інфо парового котла", + "config.jade.plugin_gtceu.transformer": "[GTCEu] Інфо трансформатора", + "config.jade.plugin_gtceu.workable_provider": "[GTCEu] Обробка", + "cover.advanced_detector.latch.disabled.0": "Поведінка: Безперервна", + "cover.advanced_detector.latch.disabled.1": "", + "cover.advanced_detector.latch.disabled.2": "Змінити поведінку цієї кришки при редстоуновому заживленні.", + "cover.advanced_detector.latch.disabled.3": "§eБезперервна§7 - Усталено; значення менше мінімального виходу 0; значення більше максимального виходу 15; значення між мінімальним і максимальним виходом від 0 до 15", + "cover.advanced_detector.latch.disabled.4": "§eЗамкнена§7 - виводити 15, поки не перевищить максимум, потім виводити 0, поки не стане менше мінімуму", + "cover.advanced_detector.latch.enabled.0": "Поведінка: Замкнена", + "cover.advanced_detector.latch.enabled.1": "", + "cover.advanced_detector.latch.enabled.2": "Змінити поведінку цієї кришки при редстоуновому заживленні.", + "cover.advanced_detector.latch.enabled.3": "§eБезперервна§7 - Усталено; значення менше мінімального виходу 0; значення більше максимального виходу 15; значення між мінімальним і максимальним виходом від 0 до 15", + "cover.advanced_detector.latch.enabled.4": "§eЗамкнена§7 - виводити 15, поки не перевищить максимум, потім виводити 0, поки не стане менше мінімуму", + "cover.advanced_energy_detector.invert.disabled.0": "Вихід: Нормальний", + "cover.advanced_energy_detector.invert.disabled.1": "", + "cover.advanced_energy_detector.invert.disabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", + "cover.advanced_energy_detector.invert.disabled.3": "Усталено, редстоун випромінюється, коли мінімальне значення EU менше, і припиняє випромінювання, коли максимальне значення EU перевищує мінімальне.", + "cover.advanced_energy_detector.invert.enabled.0": "Вихід: Інвертований", + "cover.advanced_energy_detector.invert.enabled.1": "", + "cover.advanced_energy_detector.invert.enabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", + "cover.advanced_energy_detector.invert.enabled.3": "Усталено, редстоун випромінюється, коли мінімальне значення EU менше, і припиняє випромінювання, коли максимальне значення EU перевищує мінімальне.", + "cover.advanced_energy_detector.label": "Вдосконалений детектор енергії", + "cover.advanced_energy_detector.max": "Максимум", + "cover.advanced_energy_detector.min": "Мінімум", + "cover.advanced_energy_detector.use_percent.disabled.0": "Режим: Дискретна EU", + "cover.advanced_energy_detector.use_percent.disabled.1": "", + "cover.advanced_energy_detector.use_percent.disabled.2": "Перемикайтеся між використанням дискретних значень або відсотків EU для порівняння мінімуму/максимуму з підключеним накопичувачем енергії.", + "cover.advanced_energy_detector.use_percent.enabled.0": "Режим: Процентна", + "cover.advanced_energy_detector.use_percent.enabled.1": "", + "cover.advanced_energy_detector.use_percent.enabled.2": "Перемикайтеся між використанням дискретних значень або відсотків EU для порівняння мінімуму/максимуму з підключеним накопичувачем енергії.", + "cover.advanced_fluid_detector.invert.disabled.0": "Вихід: Нормальний", + "cover.advanced_fluid_detector.invert.disabled.1": "", + "cover.advanced_fluid_detector.invert.disabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", + "cover.advanced_fluid_detector.invert.disabled.3": "Усталено редстоун припиняє випромінювання, коли рівень рідини менший за мінімальний мВ, і починає випромінювати, коли рівень рідини більший за мінімальний мВ до встановленого максимуму.", + "cover.advanced_fluid_detector.invert.enabled.0": "Вихід: Інвертований", + "cover.advanced_fluid_detector.invert.enabled.1": "", + "cover.advanced_fluid_detector.invert.enabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", + "cover.advanced_fluid_detector.invert.enabled.3": "Усталено редстоун припиняє випромінювання, коли рівень рідини менший за мінімальний мВ, і починає випромінювати, коли рівень рідини більший за мінімальний мВ до встановленого максимуму.", + "cover.advanced_fluid_detector.label": "Вдосконалений детектор рідин", + "cover.advanced_fluid_detector.max": "Максимум рідини (мВ)", + "cover.advanced_fluid_detector.min": "Мінімум рідина (мВ)", + "cover.advanced_item_detector.invert.disabled.0": "Вихід: Нормальний", + "cover.advanced_item_detector.invert.disabled.1": "", + "cover.advanced_item_detector.invert.disabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", + "cover.advanced_item_detector.invert.disabled.3": "Усталено, редстоун припиняє випромінювання, коли кількість предметів менша за мінімальну, і починає випромінювати, коли кількість предметів більша за мінімальну, але не перевищує встановленого максимуму", + "cover.advanced_item_detector.invert.enabled.0": "Вихід: Інвертований", + "cover.advanced_item_detector.invert.enabled.1": "", + "cover.advanced_item_detector.invert.enabled.2": "Перемкніть, щоб інвертувати логіку редстоуна", + "cover.advanced_item_detector.invert.enabled.3": "Усталено, редстоун припиняє випромінювання, коли кількість предметів менша за мінімальну, і починає випромінювати, коли кількість предметів більша за мінімальну, але не перевищує встановленого максимуму", + "cover.advanced_item_detector.label": "Вдосконалений детектор предметів", + "cover.advanced_item_detector.max": "Максимум предметів", + "cover.advanced_item_detector.min": "Мінімум предметів", + "cover.bucket.mode.bucket": "B", + "cover.bucket.mode.milli_bucket": "мВ", + "cover.conveyor.blocks_input.disabled.0": "Якщо увімкнено, предмети не вставлятимуться, коли кришку встановлено так, щоб втягувати предмети з містила в трубу.", + "cover.conveyor.blocks_input.disabled.1": "§cВимкнено", + "cover.conveyor.blocks_input.enabled.0": "Якщо увімкнено, предмети не вставлятимуться, коли кришку встановлено так, щоб втягувати предмети з містила в трубу.", + "cover.conveyor.blocks_input.enabled.1": "§aУвімкнено", + "cover.conveyor.distribution.insert_first.0": "Режим розповсюдження: §bПріоритетний", + "cover.conveyor.distribution.insert_first.1": "§7Вставить до першого знайденого містила з найвищим пріоритетом.", + "cover.conveyor.distribution.insert_first.2": "§7Обмежувальні предметні труби знижують пріоритет шляху.", + "cover.conveyor.distribution.round_robin_global.0": "Режим розповсюдження: §bРозподілення", + "cover.conveyor.distribution.round_robin_global.1": "§7Рівномірно розподіляє предмети між під'єднаними містилами", + "cover.conveyor.distribution.round_robin_prio.0": "Режим розповсюдження: §bЦиклічний із пріоритетом", + "cover.conveyor.distribution.round_robin_prio.1": "§7Намагається рівномірно розподілити предмети між пов'язаними містилами.", + "cover.conveyor.distribution.round_robin_prio.2": "§7Не передаватиме предмети через обмежені предметні труби, поки наявні інші шляхи.", + "cover.conveyor.item_filter.title": "Фільтр предметів", + "cover.conveyor.mode": "Режим: %s", + "cover.conveyor.mode.export": "Режим: Експорт", + "cover.conveyor.mode.import": "Режим: Імпорт", + "cover.conveyor.tag.title.0": "Тегове ім'я", + "cover.conveyor.tag.title.1": "(використовуйте * для підстановочного символу)", + "cover.conveyor.title": "Налаштування кришки конвеєра (%s)", + "cover.conveyor.transfer_rate": "§7предметів/с", + "cover.detector_base.message_inverted_state": "Статус моніторингу: Перевернутий", + "cover.detector_base.message_normal_state": "Статус моніторингу: Нормальний", + "cover.ender_fluid_link.incomplete_hex.0": "Введено неповний колір!", + "cover.ender_fluid_link.incomplete_hex.1": "Буде застосовано після завершення (всі 8 шістнадцяткових чисел)", + "cover.ender_fluid_link.incomplete_hex.2": "Закриття інтерфейсу скасує усі зміни!", + "cover.ender_fluid_link.iomode.disabled": "Ввід/вивід вимкнено", + "cover.ender_fluid_link.iomode.enabled": "Ввід/вивід увімкнено", + "cover.ender_fluid_link.private.tooltip.disabled.0": "Перехід у приватний режим резервуара", + "cover.ender_fluid_link.private.tooltip.disabled.1": "Приватний режим використовує гравець, який першим встановив кришку", + "cover.ender_fluid_link.private.tooltip.enabled": "Перехід у публічний режим резервуара", + "cover.ender_fluid_link.title": "Рідинний зв'язок Енду", + "cover.ender_fluid_link.tooltip.channel_description": "Встановити опис каналу за допомогою введеного тексту", + "cover.ender_fluid_link.tooltip.channel_name": "Встановити назву каналу за допомогою введеного тексту", + "cover.ender_fluid_link.tooltip.clear_button": "Очистити опис каналу", + "cover.ender_fluid_link.tooltip.list_button": "Показати список каналів", + "cover.ender_item_link.title": "Предметний зв'язок Енду", + "cover.ender_redstone_link.title": "Редстоуновий зв'язок Енду", + "cover.filter.blacklist.disabled": "Білий список", + "cover.filter.blacklist.enabled": "Чорний список", + "cover.filter.mode.filter_both": "Вставка/витягання фільтра", + "cover.filter.mode.filter_extract": "Витягнути фільтр", + "cover.filter.mode.filter_insert": "Вставка фільтра", + "cover.fluid.voiding.advanced.title": "Вдосконалене налаштування видалення рідини", + "cover.fluid.voiding.title": "Налаштування видалення рідини", + "cover.fluid_filter.config_amount.0": "Коліщатко вгору збільшує кількість, вниз - зменшує.", + "cover.fluid_filter.config_amount.1": "Shift[§6x10§r],Ctrl[§ex100§r],Shift+Ctrl[§ax1000§r]", + "cover.fluid_filter.config_amount.2": "ПКМ збільшує кількість, ЛКМ - зменшує.", + "cover.fluid_filter.config_amount.3": "Утримуйте Shift, щоб подвоїти/розділити.", + "cover.fluid_filter.config_amount.4": "Клацніть СКМ, щоб очистити", + "cover.fluid_filter.mode.filter_both": "Фільтр заповнення та спорожнення", + "cover.fluid_filter.mode.filter_drain": "Фільтр спорожнення", + "cover.fluid_filter.mode.filter_fill": "Фільтр заповнення", + "cover.fluid_filter.title": "Фільтр рідин", + "cover.fluid_regulator.keep_exact": "Зберігати точно: %s", + "cover.fluid_regulator.supply_exact": "Подавати точно: %s", + "cover.fluid_regulator.title": "Налаштування регулятора подачі рідини (%s)", + "cover.fluid_regulator.transfer_mode.description.0": "§eПодавати будь-як§r - у цьому режимі кришка подаватиме якомога більше рідин, що відповідають її фільтру.", + "cover.fluid_regulator.transfer_mode.description.1": "§eПодавати точно§r - у цьому режимі кришка подаватиме рідини порціями, вказаними у вікні під цією кнопкою. Блокує подачу меншої кількості рідини, ніж зазначено порцією.", + "cover.fluid_regulator.transfer_mode.description.2": "§eУтримувати точно§r - у цьому режимі кришка буде зберігати вказану кількість рідин в призначеному інвентарі, доливаючи рідину, якщо це необхідно.", + "cover.fluid_regulator.transfer_mode.description.3": "§7Порада: Клацання із затиснутим Shift помножить крок зміни на 10, а клацання із Ctrl помножить крок на 100.", + "cover.item.voiding.advanced.title": "Вдосконалені налаштування знищення предметів", + "cover.item.voiding.title": "Налаштування знищення предметів", + "cover.item_filter.ignore_damage.disabled": "Враховувати шкоду", + "cover.item_filter.ignore_damage.enabled": "Ігнорувати шкоду", + "cover.item_filter.ignore_nbt.disabled": "Враховувати NBT", + "cover.item_filter.ignore_nbt.enabled": "Ігнорувати NBT", + "cover.item_filter.title": "Фільтр предметів", + "cover.item_smart_filter.filtering_mode.centrifuge": "Центрифуга", + "cover.item_smart_filter.filtering_mode.description.0": "Виберіть машину, яку буде використовувати розумний фільтр для фільтрації.", + "cover.item_smart_filter.filtering_mode.description.1": "Він автоматично вибере потрібні обсяги предметів для маніпулятора.", + "cover.item_smart_filter.filtering_mode.electrolyzer": "Електролізер", + "cover.item_smart_filter.filtering_mode.sifter": "Просіювач", + "cover.item_smart_filter.title": "Розумний фільтр предметів", + "cover.machine_controller.invert.disabled.0": "§eНормальний§r - у цьому режимі для запуску кришка потребує слабшого сигналу редстоуна, ніж встановлений рівень", + "cover.machine_controller.invert.enabled.0": "§eІнвертований§r - у цьому режимі для запуску кришки потребує сильнішого сигналу редстоуна, ніж встановлений рівень", + "cover.machine_controller.inverted": "Інвертована", + "cover.machine_controller.mode.cover_down": "Контроль кришки (низ)", + "cover.machine_controller.mode.cover_east": "Контроль кришки (схід)", + "cover.machine_controller.mode.cover_north": "Контроль кришки (північ)", + "cover.machine_controller.mode.cover_south": "Контроль кришки (південь)", + "cover.machine_controller.mode.cover_up": "Контроль кришки (верх)", + "cover.machine_controller.mode.cover_west": "Контроль кришки (захід)", + "cover.machine_controller.mode.machine": "Контроль машини", + "cover.machine_controller.mode.null": "Контроль нічого", + "cover.machine_controller.normal": "Нормальний", + "cover.machine_controller.redstone": "Мін. рівень редстоунового живлення: %d", + "cover.machine_controller.suspend_powerfail": "Запобігання збою живлення:", + "cover.machine_controller.title": "Налаштування контролера машини", + "cover.pump.fluid_filter.title": "Фільтр рідин", + "cover.pump.mode.export": "Режим: Експорт", + "cover.pump.mode.import": "Режим: Імпорт", + "cover.pump.title": "Налаштування кришки помпи (%s)", + "cover.pump.transfer_rate": "%s", + "cover.robotic_arm.title": "Налаштування маніпулятора (%s)", + "cover.robotic_arm.transfer_mode.description.0": "§eПодавати будь-як§r - у цьому режимі кришка буде переносити якомога більше предметів, що відповідають її фільтру.", + "cover.robotic_arm.transfer_mode.description.1": "§eПодавати точно§r - у цьому режимі кришка постачатиме предмети порціями, зазначеними у слотах фільтра предметів (або змінною під цією кнопкою для фільтра міток). Блокує подачу меншої кількості предметів, ніж зазначено порцією.", + "cover.robotic_arm.transfer_mode.description.2": "§eУтримувати точно§r - у цьому режимі кришка буде зберігати вказану кількість предметів в інвентарі призначення, постачаючи додаткову кількість предметів, якщо це необхідно.", + "cover.robotic_arm.transfer_mode.description.3": "§7Порада: клацайте ЛКМ/ПКМ на слотах фільтра, щоб змінити кількість предметів, клацайте крадькома, щоб змінювати кількість швидше.", + "cover.robotic_arm.transfer_mode.keep_exact": "Утримувати точно", + "cover.robotic_arm.transfer_mode.transfer_any": "Подавати будь-як", + "cover.robotic_arm.transfer_mode.transfer_exact": "Подавати точно", + "cover.shutter.message.disabled": "Затвор відкрито", + "cover.shutter.message.enabled": "Затвор закрито", + "cover.storage.title": "Кришка сховища", + "cover.tag_filter.info.0": "§bПриймає складні вирази", + "cover.tag_filter.info.1": "§6a & b§r = AND", + "cover.tag_filter.info.10": "§bПриклад:§6 *dusts/gold | (gtceu:circuits & !*lv)", + "cover.tag_filter.info.11": "Перебирає увесь золотий пил або всі схеми, окрім lv", + "cover.tag_filter.info.2": "§6a | b§r = OR", + "cover.tag_filter.info.3": "§6a ^ b§r = XOR", + "cover.tag_filter.info.4": "§6!a§r = NOT", + "cover.tag_filter.info.5": "§6(a)§r для групування", + "cover.tag_filter.info.6": "§6*§r для підставляння", + "cover.tag_filter.info.7": "§6$§r без тегів", + "cover.tag_filter.info.8": "§bТеги мають вигляд 'namespace:tag/subtype'.", + "cover.tag_filter.info.9": "Простір назв 'forge:' передбачається, якщо його не вказано.", + "cover.tag_filter.matches": "Предмет збігається", + "cover.tag_filter.matches_not": "Предмет не збігається", + "cover.tag_filter.test_slot.info": "Вставте предмет, щоб перевірити, чи відповідає він виразу фільтра", + "cover.tag_filter.title": "Фільтр тегів", + "cover.universal.manual_import_export.mode.description.0": "§eВимкнено§r - Предмети/рідини переміщуватимуться лише так, як визначено кришкою та її фільтром. ", + "cover.universal.manual_import_export.mode.description.1": "§eДозволити фільтрований§r - поки відповідає фільтру кришки, предмети/рідини можна витягувати та вставляти незалежно від її режиму (якщо такий є). ", + "cover.universal.manual_import_export.mode.description.2": "§eДозволити нефільтрований§r - предмети/рідини можна переміщувати незалежно від режиму кришки. Фільтр застосовується до предметів, вставлених або витягнутих за допомогою цієї кришки", + "cover.universal.manual_import_export.mode.disabled": "Ручний ввід/вивід:§b Вимкнено\n§7Предмети/рідини переміщуватимуться лише так, як визначено кришкою та її фільтром.", + "cover.universal.manual_import_export.mode.filtered": "Ручний ввід/вивід:§b Фільтрований\n§7поки відповідає фільтру кришки, предмети/рідини можна витягувати та вставляти незалежно від її режиму (якщо такий є)", + "cover.universal.manual_import_export.mode.unfiltered": "Ручний ввід/вивід:§b Нефільтрований\n§7Предмети/рідини можна переміщувати незалежно від режиму кришки. Фільтр застосовується лише до того, що вставляється або витягується самою кришкою.", + "cover.voiding.label.disabled": "Вимкнено", + "cover.voiding.label.enabled": "Увімкнено", + "cover.voiding.message.disabled": "Кришку знищення вимкнено", + "cover.voiding.message.enabled": "Кришку знищення увімкнено", + "cover.voiding.tooltip": "§cУВАГА!§7 Встановлення цього параметра на «Увімкнено» означає, що рідини або предмети БУДУТЬ знищені.", + "cover.voiding.voiding_mode.description.0": "§eЗнищувати відповідне§r знищує все, що відповідає фільтру. ", + "cover.voiding.voiding_mode.description.1": "§eЗнищувати до межі§r знищує все, що відповідає фільтру, до вказаної кількості.", + "cover.voiding.voiding_mode.void_any": "Знищувати відповідне", + "cover.voiding.voiding_mode.void_overflow": "Знищувати до межі", + "curios.identifier.gtceu_magnet": "GTCEu магніт", + "death.attack.gtceu.axe": "%s був зарубаний %s", + "death.attack.gtceu.butchery_knife": "%s був нашинкований %s", + "death.attack.gtceu.buzzsaw": "%s був розпилений %s", + "death.attack.gtceu.chainsaw_lv": "%s був замордований %s", + "death.attack.gtceu.chemical": "%s став учасником хімічної аварії", + "death.attack.gtceu.crowbar": "%s напіврозпався через %s", + "death.attack.gtceu.drill_ev": "%s забурився від 2048V %s", + "death.attack.gtceu.drill_hv": "%s забурився від 512V %s", + "death.attack.gtceu.drill_iv": "%s забурився від 8192V %s", + "death.attack.gtceu.drill_lv": "%s забурився від 32V %s", + "death.attack.gtceu.drill_mv": "%s забурився від 128V %s", + "death.attack.gtceu.electric": "%s вбило струмом", + "death.attack.gtceu.explosion": "%s вибухнув", + "death.attack.gtceu.explosion.player": "%s вибухнув за допомогою %s", + "death.attack.gtceu.file": "На тілі %s була викарбувана 'Смерть' за допомогою %s", + "death.attack.gtceu.frost": "%s пізнав кріогеніку", + "death.attack.gtceu.hammer": "%s був розчавлений %s", + "death.attack.gtceu.heat": "%s зварився живцем", + "death.attack.gtceu.heat.player": "%s був зварений живцем через %s", + "death.attack.gtceu.hoe": "Голова %s була відсічена %s", + "death.attack.gtceu.knife": "%s був ніжно проштрикнутий %s", + "death.attack.gtceu.mallet": "%s здався для %s бігучим цвяхом", + "death.attack.gtceu.medical_condition/arsenicosis": "%s отруївся миш'яком", + "death.attack.gtceu.medical_condition/asbestosis": "%s програв мезотеліомі", + "death.attack.gtceu.medical_condition/berylliosis": "%s надто жадав добувати смарагди", + "death.attack.gtceu.medical_condition/carbon_monoxide_poisoning": "%s залишив плиту увімкненою", + "death.attack.gtceu.medical_condition/carcinogen": "%s не витримав лейкемії", + "death.attack.gtceu.medical_condition/chemical_burns": "%s став учасником хімічної аварії", + "death.attack.gtceu.medical_condition/irritant": "%s отримав§n§l ДУЖЕ§r сильний висип", + "death.attack.gtceu.medical_condition/methanol_poisoning": "%s наважився випити самогону в час сухого закону", + "death.attack.gtceu.medical_condition/nausea": "%s помер від нудоти", + "death.attack.gtceu.medical_condition/none": "%s помер від... нічого?", + "death.attack.gtceu.medical_condition/poison": "%s забув, що отруйні матеріали дійсно є отруйними", + "death.attack.gtceu.medical_condition/silicosis": "%s помер не від туберкульозу. Його життя обірвав силікоз.", + "death.attack.gtceu.medical_condition/weak_poison": "%s скуштував свинцю (або меркурію!)", + "death.attack.gtceu.mining_hammer": "%s був переплутаний з рудою %s", + "death.attack.gtceu.mortar": "%s був стертий у пил %s", + "death.attack.gtceu.pickaxe": "%s був добутий %s", + "death.attack.gtceu.radiation": "%s тепер світиться від РАДості", + "death.attack.gtceu.screwdriver": "%s був викручений %s востаннє!", + "death.attack.gtceu.screwdriver_lv": "Гвинти %s були відкручені %s", + "death.attack.gtceu.scythe": "%s віддав свою душу %s", + "death.attack.gtceu.shovel": "%s був відритий %s", + "death.attack.gtceu.spade": "%s був розкопаний %s", + "death.attack.gtceu.turbine": "%s занурив голову в турбіну", + "death.attack.gtceu.wire_cutter": "%s перерізав кабель до апарату життєзабезпечення %s", + "death.attack.gtceu.wrench": "%s забив %s гайковим ключем!", + "death.attack.gtceu.wrench_hv": "Труби %s розхиталися через %s", + "death.attack.gtceu.wrench_iv": "%s зловив розвідного ключа від %s", + "death.attack.gtceu.wrench_lv": "Труби %s розхиталися через %s", + "effect.gtceu.weak_poison": "Слабке отруєння", + "enchantment.damage.disjunction": "Розщеплення", + "enchantment.disjunction": "Розщеплення", + "enchantment.gtceu.disjunction.description": "Застосовує Слабкість і Повільність до пов'язаних з Ендом мобів.", + "enchantment.gtceu.hard_hammer.description": "Розбиває блоки так, ніби вони були видобуті за допомогою молота GregTech.", + "enchantment.hard_hammer": "Забивання", + "entity.gtceu.boat": "Човен", + "entity.gtceu.chest_boat": "Човен зі скринею", + "entity.gtceu.dynamite": "Динамітна шашка", + "entity.gtceu.industrial_tnt": "Промисловий динаміт", + "entity.gtceu.powderbarrel": "Порохова бочка", + "fluid.empty": "Порожньо", + "fluid.gtceu.potion": "Зілля", + "fluid.spawnlocation.name": "Інфо про рідинну жилу", + "fluid.tile.lava": "Лава", + "fluid.tile.water": "Вода", + "fluid_cell.empty": "Порожньо", + "gtceu.air_scrubber": "Очисник повітря", + "gtceu.alloy_blast_smelter": "Доменна плавильня сплавів", + "gtceu.alloy_smelter": "Плавильня сплавів", + "gtceu.arc_furnace": "Дугова піч", + "gtceu.assembler": "Збирач", + "gtceu.assembly_line": "Конвеєрна лінія", + "gtceu.auto_decomp.rotor": "Ротор турбіни", + "gtceu.auto_decomp.tool": "Неелектричний інструмент", + "gtceu.autoclave": "Автоклав", + "gtceu.battery_buffer.average_input": "Середній вхід: %s EU/т", + "gtceu.battery_buffer.average_output": "Середній вихід: %s EU/т", + "gtceu.bender": "Згинач", + "gtceu.brewery": "Варильник", + "gtceu.bus.collapse.error": "Спочатку шина повинна бути приєднана до конструкції", + "gtceu.bus.collapse_false": "Шина не руйнуватиме предмети", + "gtceu.bus.collapse_true": "Шина руйнуватиме предмети", + "gtceu.button.bedrock_fluids": "Показати рідинні глибокорінні жили", + "gtceu.button.hide_depleted": "Приховати виснажені жили", + "gtceu.button.ore_veins": "Показати рудні жили GT", + "gtceu.button.show_depleted": "Показати виснажені жили", + "gtceu.cable.amperage": "Макс. сила струму:§e %d", + "gtceu.cable.loss_per_block": "Втрати/Метр/Ампер:§c %d§7 EU-Вольт", + "gtceu.cable.superconductor": "§d%s Надпровідник", + "gtceu.cable.voltage": "Макс. напруга:§a %d§a (%s§a)", + "gtceu.canner": "Пакувальник", + "gtceu.central_monitor.gui.create_group": "Створити групу", + "gtceu.central_monitor.gui.currently_editing": "Наразі редагується: %s", + "gtceu.central_monitor.gui.remove_from_group": "Видалити з групи", + "gtceu.central_monitor.gui.set_target": "Встановити ціль", + "gtceu.central_monitor.info_tooltip.0": "Щоб використовувати монітори, спочатку потрібно розділити їх на групи. У групі може бути тільки 1 модуль.", + "gtceu.central_monitor.info_tooltip.1": "Виберіть їх, клацнувши ЛКМ, а потім натисніть «Створити групу».", + "gtceu.central_monitor.info_tooltip.2": "Потім на сторінці налаштувань групи ви можете вставити модуль і налаштувати його на тій самій сторінці.", + "gtceu.central_monitor.info_tooltip.3": "Щоб видалити групу, виберіть усі її компоненти та натисніть «Видалити з групи».", + "gtceu.central_monitor.info_tooltip.4": "Ви можете швидко вибрати всі компоненти групи, натиснувши на її назву. Натисніть ще раз, щоб скасувати вибір.", + "gtceu.central_monitor.info_tooltip.5": "Деякі модулі можуть відображати інформацію залежно від блоку, на який вони націлені. Щоб встановити ціль для групи, виберіть будь-який компонент цієї групи та клацніть ПКМ на компоненті-цілі.", + "gtceu.central_monitor.info_tooltip.6": "Ви можете вибрати ціль, яка не знаходиться в конструкції, для цього вам потрібно використовувати кришку бездротового передавача.", + "gtceu.central_monitor.info_tooltip.7": "Помістіть кришку на цільовий блок, клацніть на ній ПКМ з флешкою і вставте цю флешку в люк доступу до даних в конструкції.", + "gtceu.central_monitor.info_tooltip.8": "Потім виберіть люк доступу до даних як ціль і встановіть індекс слота вашої флешки в полі для введення цифр, яке з'явилося.", + "gtceu.central_monitor.size": "Розмір: (%d+1+%d)x(%d+1+%d)", + "gtceu.centrifuge": "Центрифуга", + "gtceu.chance_logic.and": "AND", + "gtceu.chance_logic.first": "FIRST", + "gtceu.chance_logic.none": "NONE", + "gtceu.chance_logic.or": "OR", + "gtceu.chance_logic.xor": "XOR", + "gtceu.chat.cape": "§5Вітаємо: ви щойно розблокували новий плащ! Дивіться в термінальному додатку обирач плащів, щоб скористатися ним.§r", + "gtceu.chemical_bath": "Хімічна ванна", + "gtceu.chemical_reactor": "Хімічний реактор", + "gtceu.circuit_assembler": "Схемотехнічний збирач", + "gtceu.coke_oven": "Коксова піч", + "gtceu.combustion_generator": "Генератор внутрішнього згоряння", + "gtceu.compressor": "Компресор", + "gtceu.computer_monitor_cover.error.bf_invalid": "Недійсний символ у %d", + "gtceu.computer_monitor_cover.error.bf_invalid_num": "Недійсне число в індексі %d під час обробки символу № %d", + "gtceu.computer_monitor_cover.error.exception": "Сталася несподівана виняткова ситуація: %s", + "gtceu.computer_monitor_cover.error.invalid_args": "Недійсні аргументи!", + "gtceu.computer_monitor_cover.error.invalid_number": "Недійсне число «%s»!", + "gtceu.computer_monitor_cover.error.missing_item": "Відсутньо %s у слоті %d!", + "gtceu.computer_monitor_cover.error.no_ae": "Тримач кришки не має мережі AE2!", + "gtceu.computer_monitor_cover.error.no_cover": "Немає кришки!", + "gtceu.computer_monitor_cover.error.no_placeholder": "Немає такого заповнювача: «%s»!", + "gtceu.computer_monitor_cover.error.not_enough_args": "Очікувалося щонайменше %d аргументів, отримано %d!", + "gtceu.computer_monitor_cover.error.not_in_range": "Очікувалося, що %s буде між %d і %d (включно), отримано %d", + "gtceu.computer_monitor_cover.error.not_supported": "Ця функція не підтримується цим блоком/кришкою!", + "gtceu.computer_monitor_cover.error.unclosed_bracket": "Незакрита дужка!", + "gtceu.computer_monitor_cover.error.unexpected_bracket": "Несподівана закриваюча дужка!", + "gtceu.computer_monitor_cover.error.wrong_number_of_args": "Очікувалося %d аргументів, отримано %d!", + "gtceu.cover.activity_detector.message_activity_inverted": "Моніторинг інвертованого стану активності", + "gtceu.cover.activity_detector.message_activity_normal": "Моніторинг нормального стану активності", + "gtceu.cover.activity_detector_advanced.message_activity_inverted": "Моніторинг інвертованого стану обробки", + "gtceu.cover.activity_detector_advanced.message_activity_normal": "Моніторинг нормального стану обробки", + "gtceu.cover.energy_detector.message_electricity_storage_inverted": "Моніторинг інвертованого зберігання електроенергії", + "gtceu.cover.energy_detector.message_electricity_storage_normal": "Моніторинг нормального зберігання електроенергії", + "gtceu.cover.fluid_detector.message_fluid_storage_inverted": "Моніторинг інвертованого зберігання рідини", + "gtceu.cover.fluid_detector.message_fluid_storage_normal": "Моніторинг нормального зберігання рідин", + "gtceu.cover.item_detector.message_item_storage_inverted": "Моніторинг інвертованого зберігання предметів", + "gtceu.cover.item_detector.message_item_storage_normal": "Моніторинг нормального зберігання предметів", + "gtceu.cracker": "Крекер", + "gtceu.creative.activity.off": "Неактивний", + "gtceu.creative.activity.on": "Активний", + "gtceu.creative.chest.ipc": "Предмети за цикл", + "gtceu.creative.chest.item": "Предмет", + "gtceu.creative.chest.tpc": "Такти за цикл", + "gtceu.creative.computation.average": "Середні запитувані ОРОт", + "gtceu.creative.energy.amperage": "Сила струму", + "gtceu.creative.energy.sink": "Поглинання", + "gtceu.creative.energy.source": "Джерело", + "gtceu.creative.energy.voltage": "Напруга", + "gtceu.creative.tank.fluid": "Рідина", + "gtceu.creative.tank.mbpc": "мВ за цикл", + "gtceu.creative.tank.tpc": "Такти за цикл", + "gtceu.creative_tooltip.1": "§7Вам потрібен", + "gtceu.creative_tooltip.2": " творчий режим", + "gtceu.creative_tooltip.3": "§7, щоб використовувати це", + "gtceu.cutter": "Різак", + "gtceu.debug.f3_h.enabled": "GregTech змінив інформацію про налагодження! Для розробників: увімкніть опцію misc:debug config у конфігураційному файлі GregTech, щоб побачити більше", + "gtceu.direction.tooltip.back": "Тил", + "gtceu.direction.tooltip.down": "Низ", + "gtceu.direction.tooltip.front": "Перед", + "gtceu.direction.tooltip.left": "Лівий бік", + "gtceu.direction.tooltip.right": "Правий бік", + "gtceu.direction.tooltip.up": "Верх", + "gtceu.display_source.computer_monitor_cover": "Кришка монітору комп'ютера", + "gtceu.display_target.computer_monitor_cover": "Кришка монітору комп'ютера", + "gtceu.distillation_tower": "Дистиляційна вежа", + "gtceu.distillery": "Дистилятор", + "gtceu.duct_pipe.transfer_rate": "§bШвидкість передачі повітря: %s", + "gtceu.dummy": "Манекен", + "gtceu.electric_blast_furnace": "Електрична доменна піч", + "gtceu.electric_furnace": "Електрична піч", + "gtceu.electrolyzer": "Електролізер", + "gtceu.electromagnetic_separator": "Електромагнітний сепаратор", + "gtceu.ender_item_link_cover.title": "Предметний зв'язок Енду", + "gtceu.ender_redstone_link_cover.label": "Редстоунове живлення: %d", + "gtceu.ender_redstone_link_cover.title": "Редстоуновий зв'язок Енду", + "gtceu.extractor": "Екстрактор", + "gtceu.extruder": "Екструдер", + "gtceu.fermenter": "Ферментатор", + "gtceu.fluid.amount": "§9Ємність: %d/%d мВ", + "gtceu.fluid.click_combined": "§7Клацніть контейнером з рідиною, щоб§b спустошити§7 або§b заповнити§7 бак (Shift-клік для повного стосу).", + "gtceu.fluid.click_to_empty": "§7Клацніть контейнером з рідиною, щоб§b спустошити§7 бак (Shift-клік для повного стосу).", + "gtceu.fluid.click_to_fill": "§7Клацніть контейнером з рідиною, щоб§b заповнити§7 бак (Shift-клік для повного стосу).", + "gtceu.fluid.empty": "Порожньо", + "gtceu.fluid.gas_generic": "%s (газ)", + "gtceu.fluid.gas_vapor": "%s (пара)", + "gtceu.fluid.generic": "%s", + "gtceu.fluid.liquid_generic": "%s (рідина)", + "gtceu.fluid.molten": "%s (розплавлений)", + "gtceu.fluid.plasma": "%s (плазма)", + "gtceu.fluid.state_gas": "§aСтан: газоподібний", + "gtceu.fluid.state_liquid": "§aСтан: рідкий", + "gtceu.fluid.state_plasma": "§aСтан: плазма", + "gtceu.fluid.temperature": "§cТемпература: %d K", + "gtceu.fluid.temperature.cryogenic": "§bКріогенна небезпека! тримайте обережно!", + "gtceu.fluid.type_acid.tooltip": "§6Кислотна небезпека! тримайте обережно!", + "gtceu.fluid_heater": "Рідинний нагрівач", + "gtceu.fluid_pipe.acid_proof": "§6Може працювати з кислотами", + "gtceu.fluid_pipe.capacity": "§9Місткість:§f %d мВ", + "gtceu.fluid_pipe.channels": "§eКанали:§f %d", + "gtceu.fluid_pipe.cryo_proof": "§6Може працювати з кріогенними речовинами", + "gtceu.fluid_pipe.gas_proof": "§6Може працювати з газами", + "gtceu.fluid_pipe.max_temperature": "§cМежа температури:§f %d K", + "gtceu.fluid_pipe.not_gas_proof": "§4Можливий витік газів!", + "gtceu.fluid_pipe.plasma_proof": "§6Може працювати з усіма видами плазми", + "gtceu.fluid_solidifier": "Рідинний затверджувач", + "gtceu.forge_hammer": "Ковальський молот", + "gtceu.forming_press": "Формовий прес", + "gtceu.forming_press.naming.named": "§oПерейменований предмет", + "gtceu.forming_press.naming.press": "§oІменувальний прес", + "gtceu.forming_press.naming.to_name": "§oПредмет до перейменування", + "gtceu.fusion_reactor": "Термоядерний реактор", + "gtceu.gas_collector": "Газозбірник", + "gtceu.gas_turbine": "Газова турбіна", + "gtceu.gui.adv_stocking_config.min_fluid_count": "Мінімальний розмір стосу рідини для автоматичного витягування", + "gtceu.gui.adv_stocking_config.min_item_count": "Мінімальний розмір стосу предметів для автоматичного витягування", + "gtceu.gui.adv_stocking_config.ticks_per_cycle": "Затримка між оновленнями списку предметів", + "gtceu.gui.adv_stocking_config.title": "Налаштування автоматичного поповнення запасів", + "gtceu.gui.auto_output.name": "авто", + "gtceu.gui.central_monitor.group": "Група: %s", + "gtceu.gui.central_monitor.group_default_name": "Група #%d", + "gtceu.gui.central_monitor.none": "нічого", + "gtceu.gui.central_monitor.text_scale": "Масштаб тексту", + "gtceu.gui.charger_slot.tooltip.0": "§fГніздо для зарядного пристрою§r", + "gtceu.gui.charger_slot.tooltip.1": "§7Живиться від %s акумуляторів§r", + "gtceu.gui.charger_slot.tooltip.2": "§7Заряджає %s інструменти та акумулятори", + "gtceu.gui.chunkmode.disabled.0": "Режим чанків вимкнено: клацніть, щоб увімкнути.", + "gtceu.gui.chunkmode.disabled.1": "§7Перемикання вимагає зупинки машини.", + "gtceu.gui.chunkmode.enabled.0": "Режим чанків увімкнено: клацніть, щоб вимкнути.", + "gtceu.gui.chunkmode.enabled.1": "§7Перемикання вимагає зупинки машини.", + "gtceu.gui.circuit.title": "Налаштування схеми", + "gtceu.gui.computer_monitor_cover.edit_blank_placeholders": "Редагувати порожні заповнювачі", + "gtceu.gui.computer_monitor_cover.edit_displayed_text": "Редагувати відображуваний текст", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.0": "Введіть рядок, який буде відображатися в рядку %d тут.", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.1": "Він може містити заповнювачі, наприклад: «Енергія: {energy}/{energyCapacity} EU»", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.2": "Заповнювачі також можуть бути всередині інших заповнювачів.", + "gtceu.gui.computer_monitor_cover.placeholder_reference.0": "Усі заповнювачі:", + "gtceu.gui.computer_monitor_cover.placeholder_reference.1": "(наведіть курсор для деталей)", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.0": "Введіть заповнювач, який буде використовуватися замість %s «{}» тут.", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.1": "Наприклад, ви можете мати рядок «Енергія: {}/{} EU» та «energy» та «energyCapacity» у цих текстових полях.", + "gtceu.gui.computer_monitor_cover.slot_tooltip.0": "Слот для предметів, на які можуть посилатися деякі заповнювачі", + "gtceu.gui.computer_monitor_cover.slot_tooltip.1": "Номер слота: %d", + "gtceu.gui.computer_monitor_cover.update_interval": "Інтервал оновлення (у тактах)", + "gtceu.gui.config_slot": "§fКонфігураційний слот§r", + "gtceu.gui.config_slot.auto_pull_managed": "§4Вимкнено:§7 керується автоматичним витягуванням", + "gtceu.gui.config_slot.remove": "§7Клацніть ПКМ, щоб§4 очистити§7 конфігураційний слот.§r", + "gtceu.gui.config_slot.scroll": "§7Прокрутіть коліщатко, щоб§a змінити§7 число конфігурації.§r", + "gtceu.gui.config_slot.set": "§7Натисніть, щоб§b встановити/обрати§7 конфігураційний слот.§r", + "gtceu.gui.config_slot.set_only": "§7Натисніть, щоб§bвстановити§7 конфігураційний слот.§r", + "gtceu.gui.configurator_slot.tooltip.0": "§fСлот конфігуратора§r", + "gtceu.gui.configurator_slot.tooltip.1": "§7Помістіть§6 програмну плату§7 у це гніздо, щоб", + "gtceu.gui.configurator_slot.tooltip.2": "§7змінити його конфігурацію.", + "gtceu.gui.configurator_slot.tooltip.3": "§7Утримуйте§6 Shift§7 при натисканні кнопок, щоб змінювати на§6 5.", + "gtceu.gui.configurator_slot.tooltip.4": "§aПрограмна плата у цьому гнізді також дійсна для входів рецептів.§r", + "gtceu.gui.content.chance_base": "Базовий шанс: %s%%", + "gtceu.gui.content.chance_base_logic": "Базовий шанс: %s%% (%s)", + "gtceu.gui.content.chance_boosted": "Шанс на рівні: %s%%", + "gtceu.gui.content.chance_boosted_logic": "Шанс на рівні: %s%% (%s)", + "gtceu.gui.content.chance_nc": "§cНе витрачається§r", + "gtceu.gui.content.chance_nc_short": "§cНВ§r", + "gtceu.gui.content.chance_no_boost": "Ймовірність: %s%%", + "gtceu.gui.content.chance_no_boost_logic": "Ймовірність: %s%% (%s)", + "gtceu.gui.content.chance_tier_boost_minus": "Додатковий шанс: -%s%%/рівень", + "gtceu.gui.content.chance_tier_boost_plus": "Додатковий шанс: +%s%%/рівень", + "gtceu.gui.content.count_range": "%s-%sx", + "gtceu.gui.content.fluid_range": "%s-%sмВ", + "gtceu.gui.content.per_tick": "§aСпожито/Вироблено за такт§r", + "gtceu.gui.content.range": "%s-%s", + "gtceu.gui.content.times_item": "x %s", + "gtceu.gui.content.tips.per_second_short": "§a/секунда§r", + "gtceu.gui.content.tips.per_tick_short": "§a/такт§r", + "gtceu.gui.content.units.per_second": "/с", + "gtceu.gui.content.units.per_tick": "/т", + "gtceu.gui.cover_setting.title": "Налаштування кришки", + "gtceu.gui.editor.group.recipe_type": "межа", + "gtceu.gui.editor.tips.citation": "Кількість цитувань", + "gtceu.gui.fisher_mode.tooltip.0": "Вимкнути видалення предметів", + "gtceu.gui.fisher_mode.tooltip.1": "Вимкнення коштує 2 нитки за операцію", + "gtceu.gui.fluid_amount": "Кількість рідини:", + "gtceu.gui.fluid_auto_input.tooltip.disabled": "Автовведення рідин вимкнено", + "gtceu.gui.fluid_auto_input.tooltip.enabled": "Автовведення рідин увімкнено", + "gtceu.gui.fluid_auto_output.allow_input.disabled": "вимкнути подачу рідин з боку виходу", + "gtceu.gui.fluid_auto_output.allow_input.enabled": "дозволити подачу рідин з боку виходу", + "gtceu.gui.fluid_auto_output.tooltip.disabled": "Автовиведення рідин вимкнено", + "gtceu.gui.fluid_auto_output.tooltip.enabled": "Автовиведення рідин увімкнено", + "gtceu.gui.fluid_lock.tooltip.disabled": "Блокування рідин вимкнено", + "gtceu.gui.fluid_lock.tooltip.enabled": "Блокування рідин увімкнено", + "gtceu.gui.fluid_voiding_partial.tooltip.disabled": "Видалення рідин вимкнено", + "gtceu.gui.fluid_voiding_partial.tooltip.enabled": "Видалення рідин увімкнено", + "gtceu.gui.fuel_amount": "Кількість пального:", + "gtceu.gui.item_auto_input.tooltip.disabled": "Автовведення предметів вимкнено", + "gtceu.gui.item_auto_input.tooltip.enabled": "Автовведення предметів увімкнено", + "gtceu.gui.item_auto_output.allow_input.disabled": "заборонити введення предметів з боку виходу", + "gtceu.gui.item_auto_output.allow_input.enabled": "дозволити введення предметів з боку виходу", + "gtceu.gui.item_auto_output.tooltip.disabled": "Автовиведення предметів вимкнено", + "gtceu.gui.item_auto_output.tooltip.enabled": "Автовиведення предметів увімкнено", + "gtceu.gui.item_lock.tooltip.disabled": "Блокування предметів вимкнено", + "gtceu.gui.item_lock.tooltip.enabled": "Блокування предметів увімкнено", + "gtceu.gui.item_voiding_partial.tooltip.disabled": "Видалення вимкнено", + "gtceu.gui.item_voiding_partial.tooltip.enabled": "Видалення увімкнено", + "gtceu.gui.machinemode": "Активний режим машини: %s", + "gtceu.gui.machinemode.tab_tooltip": "Змінити активний режим машини", + "gtceu.gui.machinemode.title": "Активний режим машини", + "gtceu.gui.me_bus.auto_pull_button": "Натисніть, щоб увімкнути автоматичне витягування предметів з ME", + "gtceu.gui.me_network.offline": "Стан мережі:§4 Офлайн§r", + "gtceu.gui.me_network.online": "Стан мережі:§2 Онлайн§r", + "gtceu.gui.multiblock_fluid_voiding.0": "Режим видалення", + "gtceu.gui.multiblock_fluid_voiding.1": "§7Видалення§9 рідин", + "gtceu.gui.multiblock_item_fluid_voiding.0": "Режим видалення", + "gtceu.gui.multiblock_item_fluid_voiding.1": "§7Видалення§6 предметів§7 та§9 рідин", + "gtceu.gui.multiblock_item_voiding.0": "Режим видалення", + "gtceu.gui.multiblock_item_voiding.1": "§7Видалення§6 предметів", + "gtceu.gui.multiblock_no_voiding.0": "Режим видалення", + "gtceu.gui.multiblock_no_voiding.1": "§7Видалення нічого", + "gtceu.gui.output_setting.title": "Налаштування виводу", + "gtceu.gui.output_setting.tooltips.0": "ЛКМ, щоб налаштувати автоматичне виведення предметів", + "gtceu.gui.output_setting.tooltips.1": "ПКМ, щоб налаштувати автоматичне виведення рідин.", + "gtceu.gui.overclock.description.0": "Кнопка розгону", + "gtceu.gui.overclock.description.1": "§7Рецепти можуть розганятися до встановленого рівня", + "gtceu.gui.overclock.disabled.0": "Розгін вимкнено.", + "gtceu.gui.overclock.disabled.1": "Натисніть, щоб увімкнути", + "gtceu.gui.overclock.enabled.0": "Розгін увімкнено.", + "gtceu.gui.overclock.enabled.1": "Натисніть, щоб вимкнути", + "gtceu.gui.overclock.off": "X", + "gtceu.gui.overclock.range": "Доступні рівні [%s, %s]", + "gtceu.gui.overclock.title": "Рівень розгону", + "gtceu.gui.silktouch.disabled.0": "Шовковий дотик вимкнено: Натисніть, щоб увімкнути.", + "gtceu.gui.silktouch.disabled.1": "§7Перемикання вимагає зупинки машини.", + "gtceu.gui.silktouch.enabled.0": "Шовковий дотик увімкнено: Натисніть, щоб вимкнути.", + "gtceu.gui.silktouch.enabled.1": "§7Перемикання вимагає зупинки машини.", + "gtceu.gui.sort": "Сортувати", + "gtceu.gui.title.adv_stocking_config.min_fluid_count": "Мін. кількість рідини", + "gtceu.gui.title.adv_stocking_config.min_item_count": "Мін. кількість предметів", + "gtceu.gui.title.adv_stocking_config.ticks_per_cycle": "Тактів за цикл", + "gtceu.gui.title_bar.back": "Назад", + "gtceu.gui.title_bar.page_switcher": "Сторінки", + "gtceu.gui.toggle_view.disabled": "Перемкнути вид (Рідини)", + "gtceu.gui.toggle_view.enabled": "Перемкнути вид (Предмети)", + "gtceu.gui.waiting_list": "Черга на відправлення:", + "gtceu.hazard_trigger.any": "При будь-якому контакті", + "gtceu.hazard_trigger.description": "Спричиняється:", + "gtceu.hazard_trigger.inhalation": "При вдиханні", + "gtceu.hazard_trigger.none": "Ніяк", + "gtceu.hazard_trigger.protection.description": "Захищає:", + "gtceu.hazard_trigger.skin_contact": "При контакті зі шкірою", + "gtceu.implosion_compressor": "Компресор надмірного тиску", + "gtceu.io.both": "Обидва", + "gtceu.io.export": "Експорт", + "gtceu.io.import": "Імпорт", + "gtceu.io.none": "Ніяк", + "gtceu.item_filter.empty_item": "Порожньо (немає предметів)", + "gtceu.item_filter.footer": "§eКлацніть з предметом, щоб замінити", + "gtceu.item_list.item_stored": "§7Вміст: %d", + "gtceu.item_pipe.priority": "§9Пріоритет:§f %d", + "gtceu.jade.amperage_use": "%s A", + "gtceu.jade.at": " @ ", + "gtceu.jade.cleaned_this_second": "Очищена небезпека: %s/s", + "gtceu.jade.energy_stored": "%d / %d EU", + "gtceu.jade.fluid_use": "%s mB/т", + "gtceu.jade.progress_computation": "%s / %s ОРО", + "gtceu.jade.progress_sec": "%s / %s с", + "gtceu.jade.progress_tick": "%s / %s т", + "gtceu.jei.bedrock_fluid.heavy_oil_deposit": "Поклад важкої нафти", + "gtceu.jei.bedrock_fluid.lava_deposit": "Поклад лави", + "gtceu.jei.bedrock_fluid.light_oil_deposit": "Поклад легкої нафти", + "gtceu.jei.bedrock_fluid.natural_gas_deposit": "Поклад природього газу", + "gtceu.jei.bedrock_fluid.nether_natural_gas_deposit": "Незерський поклад природього газу", + "gtceu.jei.bedrock_fluid.oil_deposit": "Поклад нафти", + "gtceu.jei.bedrock_fluid.raw_oil_deposit": "Поклад сирої нафти", + "gtceu.jei.bedrock_fluid.salt_water_deposit": "Поклад солоної води", + "gtceu.jei.bedrock_fluid_diagram": "Діаграма глибокореневих рідин", + "gtceu.jei.bedrock_ore_diagram": "Діаграма глибокореневих руд", + "gtceu.jei.fluid.dep_amount_hover": "На який обсяг буде виснажено поклад", + "gtceu.jei.fluid.dep_chance_hover": "Відсоткова ймовірність того, що поклад буде виснажено під час збору", + "gtceu.jei.fluid.dep_yield_hover": "Максимальний видобуток з поклади при її повному виснаженні", + "gtceu.jei.fluid.depleted_rate": "Максимальний видобуток: %d", + "gtceu.jei.fluid.depletion_amount": "Обсяг покладу: %d", + "gtceu.jei.fluid.depletion_chance": "Шанс видобутку: %d%%", + "gtceu.jei.fluid.dimension": "Виміри:", + "gtceu.jei.fluid.max_hover": "Максимальний видобуток, який може мати будь-який поклад цієї рідини", + "gtceu.jei.fluid.max_yield": "Максимальний видобуток: %d", + "gtceu.jei.fluid.min_hover": "Мінімальний видобуток, який може мати будь-який поклад цієї рідини", + "gtceu.jei.fluid.min_yield": "Мінімальний видобуток: %d", + "gtceu.jei.fluid.vein_weight": "Вага жили: %d", + "gtceu.jei.fluid.weight_hover": "Вага жили. Наведіться на рідину, щоб побачити всі можливі модифікації біома", + "gtceu.jei.materials.average_mass": "Середня маса: %d", + "gtceu.jei.materials.average_neutrons": "В серед. нейтронів: %d", + "gtceu.jei.materials.average_protons": "В серед. протонів: %d", + "gtceu.jei.multiblock_info": "Інфо про конструкцію", + "gtceu.jei.ore.between.0": "Внутрішня руда", + "gtceu.jei.ore.between.1": "Генерується у середині %d шарів поклади разом з іншими рудами", + "gtceu.jei.ore.biome_weighting": "Вага§d %s:§3 %d", + "gtceu.jei.ore.biome_weighting_no_spawn": "Вага§d %s:§c Не може згенеруватися", + "gtceu.jei.ore.biome_weighting_title": "§dЗагальна вага модифікованого біома:", + "gtceu.jei.ore.ore_weight": "Вага у жилі: %d%%", + "gtceu.jei.ore.primary.0": "Верхня руда", + "gtceu.jei.ore.primary.1": "Генерується зверху %d шарів жили", + "gtceu.jei.ore.secondary.0": "Нижня руда", + "gtceu.jei.ore.secondary.1": "Генерується знизу %d шарів жили", + "gtceu.jei.ore.sporadic.0": "Спорадична руда", + "gtceu.jei.ore.sporadic.1": "Генерується по всій жилі", + "gtceu.jei.ore.surface_rock.0": "Поверхневі утворення з цим матеріалом позначають місця генерації жил.", + "gtceu.jei.ore.surface_rock.1": "Їх можна розбити, щоб отримати 3-5 крихт пилу, та ще більше із удачею.", + "gtceu.jei.ore_processing_diagram": "Послідовна рудообробка", + "gtceu.jei.ore_vein.apatite_vein": "Апатитова жила", + "gtceu.jei.ore_vein.banded_iron_vein": "Стрічкова залізна жила", + "gtceu.jei.ore_vein.bauxite_vein_end": "Бокситова жила Енду", + "gtceu.jei.ore_vein.beryllium_vein": "Берилієва жила", + "gtceu.jei.ore_vein.cassiterite_vein": "Каситеритова жила", + "gtceu.jei.ore_vein.certus_quartz": "Істинний кварц", + "gtceu.jei.ore_vein.coal_vein": "Вугільна жила", + "gtceu.jei.ore_vein.copper_tin_vein": "Мідно-олов'яна жила", + "gtceu.jei.ore_vein.copper_vein": "Мідна жила", + "gtceu.jei.ore_vein.diamond_vein": "Діамантова жила", + "gtceu.jei.ore_vein.galena_vein": "Галенова жила", + "gtceu.jei.ore_vein.garnet_tin_vein": "Гранатово-олов'яна жила", + "gtceu.jei.ore_vein.garnet_vein": "Гранатова жила", + "gtceu.jei.ore_vein.iron_vein": "Залізна жила", + "gtceu.jei.ore_vein.lapis_vein": "Лазуритова жила", + "gtceu.jei.ore_vein.lubricant_vein": "Мастильна жила", + "gtceu.jei.ore_vein.magnetite_vein_end": "Магнетитова жила Енду", + "gtceu.jei.ore_vein.magnetite_vein_ow": "Магнетитова жила вС", + "gtceu.jei.ore_vein.manganese_vein": "Марганцева жила", + "gtceu.jei.ore_vein.manganese_vein_ow": "Марганцева жила вС", + "gtceu.jei.ore_vein.mica_vein": "Слюдяна жила", + "gtceu.jei.ore_vein.mineral_sand_vein": "Жила мінерального піску", + "gtceu.jei.ore_vein.molybdenum_vein": "Молібденова жила", + "gtceu.jei.ore_vein.monazite_vein": "Монацитова жила", + "gtceu.jei.ore_vein.naquadah_vein": "Наквадова жила", + "gtceu.jei.ore_vein.nether_quartz_vein": "Нижня кварцова жила", + "gtceu.jei.ore_vein.nickel_vein": "Нікелева жила", + "gtceu.jei.ore_vein.oilsands_vein": "Жила нафтоносних пісків", + "gtceu.jei.ore_vein.olivine_vein": "Олівінова жила", + "gtceu.jei.ore_vein.pitchblende_vein_end": "Настуранова жила Енду", + "gtceu.jei.ore_vein.redstone_vein": "Редстоунова жила", + "gtceu.jei.ore_vein.redstone_vein_ow": "Редстоунова жила вС", + "gtceu.jei.ore_vein.saltpeter_vein": "Селітрова жила", + "gtceu.jei.ore_vein.salts_vein": "Соляна жила", + "gtceu.jei.ore_vein.sapphire_vein": "Сапфірова жила", + "gtceu.jei.ore_vein.scheelite_vein": "Шеєлітова жила", + "gtceu.jei.ore_vein.sheldonite_vein": "Шелдонітова жила", + "gtceu.jei.ore_vein.sulfur_vein": "Сірчана жила", + "gtceu.jei.ore_vein.tetrahedrite_vein": "Тетраедритова жила", + "gtceu.jei.ore_vein.topaz_vein": "Топазова жила", + "gtceu.jei.ore_vein_diagram": "Залягання руди", + "gtceu.jei.ore_vein_diagram.chance": "§eШанс: %s§r", + "gtceu.jei.ore_vein_diagram.dimensions": "Виміри:", + "gtceu.jei.ore_vein_diagram.spawn_range": "Висота залягання:", + "gtceu.jei.ore_vein_diagram.weight": "Вага: %s", + "gtceu.jei.programmed_circuit": "Сторінка програмної плати", + "gtceu.journeymap.options.layers": "Шари до розвідування", + "gtceu.journeymap.options.layers.bedrock_fluids": "Показати рідинні глибокорінні жили", + "gtceu.journeymap.options.layers.hide_depleted": "Приховати виснажені жили", + "gtceu.journeymap.options.layers.ore_veins": "Показати рудні жили", + "gtceu.key.armor_charging": "Перемикач заряджання інвентарю від броні", + "gtceu.key.armor_hover": "Перемикач наведення броні", + "gtceu.key.armor_mode_switch": "Перемикач режиму броні", + "gtceu.key.enable_boots": "Увімкнути посилений стрибок", + "gtceu.key.enable_jetpack": "Реактивний ранець", + "gtceu.key.tool_aoe_change": "Перемикач роботи по області інструменту", + "gtceu.large_boiler": "Великий котел", + "gtceu.large_chemical_reactor": "Великий хімічний реактор", + "gtceu.laser_engraver": "Літограф", + "gtceu.lathe": "Токар", + "gtceu.macerator": "Подрібнювач", + "gtceu.machine.active_transformer.tooltip.0": "§7Трансформатори: замасковані лазери", + "gtceu.machine.active_transformer.tooltip.1": "§7Може об'єднати будь-яку кількість енергетичних§f входів§7 у будь-яку кількість енергетичних§f виходів§7.", + "gtceu.machine.active_transformer.tooltip.2": "§7Може передавати енергію на неймовірні відстані за допомогою", + "gtceu.machine.active_transformer.tooltip.3": " лазерів§7.", + "gtceu.machine.advanced_processing_array.tooltip": "Паралелізуйте світ", + "gtceu.machine.assembly_line.tooltip": "Не багатоблочна складальна машина!", + "gtceu.machine.available_recipe_map_1.tooltip": "Доступні типи рецептів: %s", + "gtceu.machine.available_recipe_map_2.tooltip": "Доступні типи рецептів: %s, %s", + "gtceu.machine.available_recipe_map_3.tooltip": "Доступні типи рецептів: %s, %s, %s", + "gtceu.machine.available_recipe_map_4.tooltip": "Доступні типи рецептів: %s, %s, %s, %s", + "gtceu.machine.basic.input_from_output_side.allow": "Дозволити введення з боку виходу: ", + "gtceu.machine.basic.input_from_output_side.disallow": "Заборонити введення з боку виходу: ", + "gtceu.machine.batch_disabled": "Групування вимкнено", + "gtceu.machine.batch_enabled": "Групування увімкнено", + "gtceu.machine.bedrock_ore_miner.depletion": "§bШвидкість виснаження:§f %s%%", + "gtceu.machine.bedrock_ore_miner.description": "§7Видобуває руди з поклад під бедроком.", + "gtceu.machine.bedrock_ore_miner.production": "§eМножник виробництва:§f %dx, %fx розгін", + "gtceu.machine.block_breaker.speed_bonus": "§eДодаткова швидкість:§f %d%%", + "gtceu.machine.block_breaker.tooltip": "§7Добуває блок на лицьовій стороні та збирає його дроп", + "gtceu.machine.boiler.info.cooling.down": "§9Оходження§r", + "gtceu.machine.boiler.info.heating.up": "§cНагрівання§r", + "gtceu.machine.boiler.info.production.data": "§aВироблення %s§a мВ/т", + "gtceu.machine.buffer.tooltip": "Невеликий буфер для зберігання предметів і рідин", + "gtceu.machine.canner.jei_description": "За допомогою пакувальника можна наповнювати та спорожняти будь-які ємності для рідини (наприклад, відра або рідинні комірки)", + "gtceu.machine.central_monitor.tooltip": "На ньому можна запустити Doom?", + "gtceu.machine.charcoal_pile.tooltip": "Підземна паливна піч", + "gtceu.machine.charcoal_pile.tooltip.0": "Перетворює колоди на§a деревне вугілля§7 при§c запалюванні§7.", + "gtceu.machine.charcoal_pile.tooltip.1": "ПКМ із запалювальним предметом, щоб запустити.", + "gtceu.machine.charcoal_pile.tooltip.2": "Піроліз відбувається під машиною в просторі до§b 9x4x9§7.", + "gtceu.machine.charcoal_pile.tooltip.3": "Колоди не повинні контактувати з§e повітрям§7!", + "gtceu.machine.cleanroom.tooltip": "Закривайте двері, мухи летять!", + "gtceu.machine.cleanroom.tooltip.0": "Розмістіть машини всередині, щоб виконувати рецепти чистої кімнати.", + "gtceu.machine.cleanroom.tooltip.1": "Використовує§f 30 EU/т§7 коли брудно,§f 4 EU/т§7 коли чисто.", + "gtceu.machine.cleanroom.tooltip.2": "Розгін збільшує обсяг очищення за цикл.", + "gtceu.machine.cleanroom.tooltip.3": "§bРозмір:§f від 5x5x5 до 15x15x15", + "gtceu.machine.cleanroom.tooltip.4": "Потребує§f фільтрувальні кришки§7 на стелі, за винятком країв.", + "gtceu.machine.cleanroom.tooltip.5": "Дозволяє встановити до§f 4 дверей§7! залишається чистим, коли двері відчинені.", + "gtceu.machine.cleanroom.tooltip.6": "Генератори, вихлопи, бури, гірники, та примітивні машини занадто брудні для чистої кімнати!", + "gtceu.machine.cleanroom.tooltip.7": "Передавайте енергію через§f корпуси§7 або§f діоди§7 у стінах.", + "gtceu.machine.cleanroom.tooltip.ae2.channels": "Проводьте до§f 8 AE2 каналів§7 через§f корпуси§7 у стінах.", + "gtceu.machine.cleanroom.tooltip.ae2.no_channels": "Проводьте§a мережу AE2§7 через§f корпуси§7 у стінах.", + "gtceu.machine.cleanroom.tooltip.hold_ctrl": "Утримуйте CTRL, щоб показати додаткову інформацію конструкції", + "gtceu.machine.coke_oven.tooltip": "Створює кращі палива для металургії та енергетики", + "gtceu.machine.coke_oven_hatch.tooltip": "§7Дозволяє автоматизувати доступ до коксової печі.", + "gtceu.machine.combustion_generator.tooltip": "§7Потребує легкозаймистих рідин", + "gtceu.machine.computation_receiver_hatch.tooltip": "Вхід для обчислювальних даних конструкцій", + "gtceu.machine.computation_transmitter_hatch.tooltip": "Вихід для обчислювальних даних конструкцій", + "gtceu.machine.cracker.tooltip": "Робить нафту корисною", + "gtceu.machine.cracker.tooltip.1": "§7Кожна котушка після§6 мельхіорової§7 зменшує споживання енергії на§f 10%%§7.", + "gtceu.machine.data_access_hatch.tooltip.0": "Доступ до даних для конструкцій", + "gtceu.machine.data_access_hatch.tooltip.1": "Додає§a %s§7 слотів для предметів даних", + "gtceu.machine.data_bank.tooltip.0": "Ваша персональна NAS", + "gtceu.machine.data_bank.tooltip.1": "Масове сховище даних. передає через оптичні кабелі.", + "gtceu.machine.data_bank.tooltip.2": "Бази даних можуть бути об'єднані в ланцюжок.", + "gtceu.machine.data_bank.tooltip.3": "Споживає§f %s EU/т§7 за звичайний люк даних/оптичний люк.", + "gtceu.machine.data_bank.tooltip.4": "Uses§f %s EU/т§7 за люк даних/оптичний люк у ланцюжку.", + "gtceu.machine.data_receiver_hatch.tooltip": "Вхід дослідницьких даних для конструкцій", + "gtceu.machine.data_transmitter_hatch.tooltip": "Вихід дослідницьких даних для конструкцій", + "gtceu.machine.diode.message": "Максимальний пропускний струм: %s", + "gtceu.machine.diode.tooltip_general": "Дозволяє потік енергії в одному напрямку та обмежує силу струму", + "gtceu.machine.diode.tooltip_starts_at": "Починає з§f 1A§7, використовуйте киянку для зміни", + "gtceu.machine.diode.tooltip_tool_usage": "Вдаряйте киянкою, щоб змінити силу струму.", + "gtceu.machine.distillation_tower.tooltip": "Рідинопереробний завод", + "gtceu.machine.drum.disable_output": "Не витягує рідину", + "gtceu.machine.drum.enable_output": "Витягує рідину у розміщений нижче резервуар", + "gtceu.machine.dual_hatch.export.tooltip": "Рідинний і предметний вихід для конструкцій", + "gtceu.machine.dual_hatch.import.tooltip": "Рідинний і предметний вхід для конструкцій", + "gtceu.machine.electric_blast_furnace.tooltip": "А електрична коптильня?", + "gtceu.machine.electric_blast_furnace.tooltip.0": "§7За кожні§f 900K§7 над необхідною температурою рецепта застосовується мультиплікативний§f 95%%§7 мультиплікатор енергії.", + "gtceu.machine.electric_blast_furnace.tooltip.1": "§7За кожні§f 1800K§7 над необхідною температурою рецепта один розгін стає на§f 100%% ефективним§7 (ідеальний розгін).", + "gtceu.machine.electric_blast_furnace.tooltip.2": "§7За кожний рівень напруги вище§b MV§7 температура збільшується на§f 100K§7.", + "gtceu.machine.endpoint.tooltip.0": "§7З'єднайте з блоком§f великодистанційного трубопроводу§7, щоб створити трубопровід.", + "gtceu.machine.endpoint.tooltip.1": "§7Тробопроводи повинні мати точно§f 1 вхід§7 та§f 1 вихід§7 як пункт призначення.", + "gtceu.machine.endpoint.tooltip.2": "§7Тільки пункти призначення трубопроводу потребують бути у§f завантаженому чанку§7.", + "gtceu.machine.endpoint.tooltip.min_length": "§bМінімальна дистанція до пункту призначення:§f %d блоків", + "gtceu.machine.energy_converter.description": "Конвертує енергію між EU та FE", + "gtceu.machine.energy_converter.message_conversion_eu": "Конвертація EU, вхід: %dA %d EU, вихід: %d первинної енергії", + "gtceu.machine.energy_converter.message_conversion_native": "Конвертація первинної енергії, вхід: %d FE, вихід: %dA %d EU", + "gtceu.machine.energy_converter.tooltip_conversion_eu": "§aEU-конвертація:§f %dA %d EU (%s§f) -> %d первинної енергії", + "gtceu.machine.energy_converter.tooltip_conversion_native": "§cПервинна конвертація:§f %d FE -> %dA %d EU (%s§f)", + "gtceu.machine.energy_converter.tooltip_tool_usage": "Починає як§f FE-конвертер§7, використовуйте киянку для зміни", + "gtceu.machine.energy_hatch.input.tooltip": "Енергетичний вхід для конструкцій", + "gtceu.machine.energy_hatch.input_hi_amp.tooltip": "Багатоамперний енергетичний вхід для конструкцій", + "gtceu.machine.energy_hatch.output.tooltip": "Енергетичний вхід для конструкцій", + "gtceu.machine.energy_hatch.output_hi_amp.tooltip": "Багатоамперний енергетичний вхід для конструкцій", + "gtceu.machine.ev_alloy_smelter.tooltip": "§7Високотехнологічна комбінувальна плавильня сплавів", + "gtceu.machine.ev_arc_furnace.tooltip": "§7Кому взагалі потрібна плавильна піч?", + "gtceu.machine.ev_assembler.tooltip": "§7Месники, збираємось!", + "gtceu.machine.ev_autoclave.tooltip": "§7Кристалізує пил", + "gtceu.machine.ev_bender.tooltip": "§7Фууу, він поганий! Нам потрібен БЕНДЕР!!!", + "gtceu.machine.ev_brewery.tooltip": "§7Компактне та ефективне зіллєваріння", + "gtceu.machine.ev_canner.tooltip": "§7Поміщає речі в контейнери та виймає їх з них", + "gtceu.machine.ev_centrifuge.tooltip": "§7Молекулярний сепаратор", + "gtceu.machine.ev_chemical_bath.tooltip": "§7Розщеплює руди шляхом їх вимочування у хімікатах", + "gtceu.machine.ev_chemical_reactor.tooltip": "§7Дає хімічним речовинам вступати в реакцію між собою", + "gtceu.machine.ev_circuit_assembler.tooltip": "§7Всюдисущий віьзми-поклади", + "gtceu.machine.ev_compressor.tooltip": "§7Компресорно-механічна система C77", + "gtceu.machine.ev_cutter.tooltip": "§7Ріж-крій", + "gtceu.machine.ev_distillery.tooltip": "§7Вилучає найбільш важливі частини рідин", + "gtceu.machine.ev_electric_furnace.tooltip": "§7Не схоже на користування Commodore 64", + "gtceu.machine.ev_electrolyzer.tooltip": "§7Молекулярний електроліз", + "gtceu.machine.ev_electromagnetic_separator.tooltip": "§7Відокремлює магнітні руди від решти", + "gtceu.machine.ev_extractor.tooltip": "§7Соковичавлюючий пристрій приречення - D123", + "gtceu.machine.ev_extruder.tooltip": "§7Універсальна металообробна машина", + "gtceu.machine.ev_fermenter.tooltip": "§7Ферментує рідини", + "gtceu.machine.ev_fluid_drilling_rig.tooltip": "Свердловинний дренажер", + "gtceu.machine.ev_fluid_heater.tooltip": "§7Нагріває рідини", + "gtceu.machine.ev_fluid_solidifier.tooltip": "§7Охолоджує рідини до твердого стану", + "gtceu.machine.ev_forge_hammer.tooltip": "§7Стоп, час молота!", + "gtceu.machine.ev_forming_press.tooltip": "§7Витискає речам нову форму", + "gtceu.machine.ev_gas_collector.tooltip": "§7Збирає газ з повітря залежно від виміру", + "gtceu.machine.ev_laser_engraver.tooltip": "§7Не дивіться прямо на лазер", + "gtceu.machine.ev_lathe.tooltip": "§7Ефективніше виробляє стрижні", + "gtceu.machine.ev_macerator.tooltip": "§7Подрібнює руди з побічними продуктами", + "gtceu.machine.ev_mass_fabricator.tooltip": "§7UUM матерія * виробництво в квадраті", + "gtceu.machine.ev_mixer.tooltip": "§7Чи змішається?", + "gtceu.machine.ev_ore_washer.tooltip": "§7Отримує більше побічних продуктів з руд", + "gtceu.machine.ev_packer.tooltip": "§7Запаковує та розпаковує речі", + "gtceu.machine.ev_polarizer.tooltip": "§7Біполяризовує магніти", + "gtceu.machine.ev_replicator.tooltip": "§7Виробляє найчистіші елементи", + "gtceu.machine.ev_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", + "gtceu.machine.ev_scanner.tooltip": "§7Сканує матеріали та інші речі", + "gtceu.machine.ev_sifter.tooltip": "§7Зберігайте спокій і продовжуйте просіювати", + "gtceu.machine.ev_thermal_centrifuge.tooltip": "§7Точніше розділяє руди", + "gtceu.machine.ev_wiremill.tooltip": "§7Ефективніше виробляє дроти", + "gtceu.machine.extreme_combustion_engine.tooltip": "Екстремальний хімічний вивільнювач енергії", + "gtceu.machine.fisher.requirement": "Потребує %dx%d квадрат води прямо під собою.", + "gtceu.machine.fisher.speed": "Виловлює щось кожні %d тактів", + "gtceu.machine.fisher.tooltip": "Витрачає нитку на кожу ловлю.", + "gtceu.machine.fluid_drilling_rig.depletion": "§bШвидкість виснаження:§f %s%%", + "gtceu.machine.fluid_drilling_rig.description": "§7Видобуває рідини з покладів під бедроком.", + "gtceu.machine.fluid_drilling_rig.production": "§eМножник виробництва:§f %dx, %fx розгін", + "gtceu.machine.fluid_hatch.export.tooltip": "Рідинний вихід для конструкцій", + "gtceu.machine.fluid_hatch.import.tooltip": "Рідинний вхід для конструкцій", + "gtceu.machine.fluid_tank.fluid": "Містить %s л %s", + "gtceu.machine.fluid_tank.max_multiblock": "Макс. розмір конструкції: %dx%dx%d", + "gtceu.machine.fusion_reactor.capacity": "§7Максимальний запас енергії:§e %sM EU", + "gtceu.machine.fusion_reactor.luv.tooltip": "Атомний стоплювач", + "gtceu.machine.fusion_reactor.overclocking": "Розгін подвоює енергію та вдвічі скорочує тривалість.", + "gtceu.machine.fusion_reactor.uv.tooltip": "БІЛИЙ КАРЛИК ЗІЙШОВ НА ТВОЮ БАЗУ", + "gtceu.machine.fusion_reactor.zpm.tooltip": "СОНЦЕ ЗІЙШЛО НА ЗЕМЛЮ", + "gtceu.machine.gas_turbine.tooltip": "§7Потребує горючих газів", + "gtceu.machine.high_performance_computation_array.tooltip.0": "Просто звичайний суперкомп'ютер", + "gtceu.machine.high_performance_computation_array.tooltip.1": "Використовується для генерації§f обчислень§7 (та тепла).", + "gtceu.machine.high_performance_computation_array.tooltip.2": "Потребує компоненти ВОМ для генерації§f ОРО/т§7 (обчислювальних робочих одиниць).", + "gtceu.machine.hp_steam_alloy_smelter.tooltip": "§7Комбінувальна плавильня сплавів", + "gtceu.machine.hp_steam_compressor.tooltip": "§7Стискає предмети", + "gtceu.machine.hp_steam_extractor.tooltip": "§7Добувач першої глини", + "gtceu.machine.hp_steam_forge_hammer.tooltip": "§7Ковальський молот", + "gtceu.machine.hp_steam_furnace.tooltip": "§7Плавить речі за допомогою стисненої пари", + "gtceu.machine.hp_steam_liquid_boiler.tooltip": "§7Швидше ніж малий паровий рідинний котел", + "gtceu.machine.hp_steam_macerator.tooltip": "§7Подрібнює руди без побічних продуктів", + "gtceu.machine.hp_steam_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", + "gtceu.machine.hp_steam_solar_boiler.tooltip": "§7Парова енергія від сонця", + "gtceu.machine.hp_steam_solid_boiler.tooltip": "§7Швидше ніж малий паровий твердопаливний котел", + "gtceu.machine.hpca.active_cooler_component.tooltip": "Менше витрат, ефективніше охолодження", + "gtceu.machine.hpca.advanced_computation_component.damaged.name": "Пошкоджений ВОМ-удосконалений обчислювальний компонент", + "gtceu.machine.hpca.advanced_computation_component.damaged.tooltip": "Це коштувало лише руки та ноги", + "gtceu.machine.hpca.advanced_computation_component.tooltip": "Вища ліга обчислень", + "gtceu.machine.hpca.bridge_component.tooltip": "Так ось звідки з'явився «масив» У ВОМ", + "gtceu.machine.hpca.component_general.max_eut": "§6Макс. енергії:§f %d EU/т", + "gtceu.machine.hpca.component_general.upkeep_eut": "§eУтримання енергії:§f %d EU/т", + "gtceu.machine.hpca.component_type.bridge": "Дає§f ВОМ§7 можливість під'єднюватися до§f мережевих комутаторів§7", + "gtceu.machine.hpca.component_type.computation_cooling": "§cВимагає до:§f %d охолодження", + "gtceu.machine.hpca.component_type.computation_cwut": "§9Обчислення:§f %d ОРО/т", + "gtceu.machine.hpca.component_type.cooler_active": "§bТип охолоджувача:§f активний", + "gtceu.machine.hpca.component_type.cooler_active_coolant": "§cВимагає до:§f %d мВ/т %s", + "gtceu.machine.hpca.component_type.cooler_cooling": "§aЗабезпечує:§f %d охолодження", + "gtceu.machine.hpca.component_type.cooler_passive": "§bТип охолоджувача:§f пасивний", + "gtceu.machine.hpca.component_type.damaged": "Може бути пошкоджений через перегрівання ВОМ!", + "gtceu.machine.hpca.computation_component.damaged.name": "Пошкоджений ВОМ-обчислювальний компонент", + "gtceu.machine.hpca.computation_component.damaged.tooltip": "Безкоштовні переробні матеріали", + "gtceu.machine.hpca.computation_component.tooltip": "Перші обчислення малюка", + "gtceu.machine.hpca.empty_component.tooltip": "Просто для заповнення простору", + "gtceu.machine.hpca.heat_sink_component.tooltip": "Безкоштовне охолодження! хіба щось буває безкоштовним?", + "gtceu.machine.hull.tooltip": "§7Просто проявіть §cу§eя§aв§9у§7, щоб використовувати це", + "gtceu.machine.hv_alloy_smelter.tooltip": "§7Високотехнологічна комбінувальна плавильня сплавів", + "gtceu.machine.hv_arc_furnace.tooltip": "§7Кому взагалі потрібна плавильна піч?", + "gtceu.machine.hv_assembler.tooltip": "§7Месники, збираємось!", + "gtceu.machine.hv_autoclave.tooltip": "§7Кристалізує пил", + "gtceu.machine.hv_bender.tooltip": "§7Фууу, він поганий! Нам потрібен БЕНДЕР!!!", + "gtceu.machine.hv_brewery.tooltip": "§7Компактне та ефективне зіллєваріння", + "gtceu.machine.hv_canner.tooltip": "§7Поміщає речі в контейнери та виймає їх з них", + "gtceu.machine.hv_centrifuge.tooltip": "§7Розподіл молекул", + "gtceu.machine.hv_chemical_bath.tooltip": "§7Розщеплює руди шляхом їх вимочування у хімікатах", + "gtceu.machine.hv_chemical_reactor.tooltip": "§7Дає хімічним речовинам вступати в реакцію між собою", + "gtceu.machine.hv_circuit_assembler.tooltip": "§7Всюдисущий віьзми-поклади", + "gtceu.machine.hv_compressor.tooltip": "§7Компресорно-механічна система C77", + "gtceu.machine.hv_cutter.tooltip": "§7Ріж-крій", + "gtceu.machine.hv_distillery.tooltip": "§7Вилучає найбільш важливі частини рідин", + "gtceu.machine.hv_electric_furnace.tooltip": "§7Не схоже на користування Commodore 64", + "gtceu.machine.hv_electrolyzer.tooltip": "§7Молекулярний електроліз", + "gtceu.machine.hv_electromagnetic_separator.tooltip": "§7Відокремлює магнітні руди від решти", + "gtceu.machine.hv_extractor.tooltip": "§7Соковичавлюючий пристрій приречення - D123", + "gtceu.machine.hv_extruder.tooltip": "§7Універсальна металообробна машина", + "gtceu.machine.hv_fermenter.tooltip": "§7Ферментує рідини", + "gtceu.machine.hv_fluid_drilling_rig.tooltip": "Не проводить гідророзрив пласта", + "gtceu.machine.hv_fluid_heater.tooltip": "§7Нагріває рідини", + "gtceu.machine.hv_fluid_solidifier.tooltip": "§7Охолоджує рідини до твердого стану", + "gtceu.machine.hv_forge_hammer.tooltip": "§7Стоп, час молота!", + "gtceu.machine.hv_forming_press.tooltip": "§7Витискає речам нову форму", + "gtceu.machine.hv_gas_collector.tooltip": "§7Збирає газ з повітря залежно від виміру", + "gtceu.machine.hv_laser_engraver.tooltip": "§7Не дивіться прямо на лазер", + "gtceu.machine.hv_lathe.tooltip": "§7Ефективніше виробляє стрижні", + "gtceu.machine.hv_macerator.tooltip": "§7Подрібнює руди з побічними продуктами", + "gtceu.machine.hv_mass_fabricator.tooltip": "§7UUM матерія * виробництво в квадраті", + "gtceu.machine.hv_mixer.tooltip": "§7Чи змішається?", + "gtceu.machine.hv_ore_washer.tooltip": "§7Отримує більше побічних продуктів з руд", + "gtceu.machine.hv_packer.tooltip": "§7Запаковує та розпаковує речі", + "gtceu.machine.hv_polarizer.tooltip": "§7Біполяризовує магніти", + "gtceu.machine.hv_replicator.tooltip": "§7Виробляє найчистіші елементи", + "gtceu.machine.hv_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", + "gtceu.machine.hv_scanner.tooltip": "§7Сканує матеріали та інші речі", + "gtceu.machine.hv_sifter.tooltip": "§7Зберігайте спокій і продовжуйте просіювати", + "gtceu.machine.hv_thermal_centrifuge.tooltip": "§7Точніше розділяє руди", + "gtceu.machine.hv_wiremill.tooltip": "§7Ефективніше виробляє дроти", + "gtceu.machine.implosion_compressor.tooltip": "Єдина машина, з якою хочеться робити бум!", + "gtceu.machine.item_bus.export.tooltip": "Предметний вихід для конструкцій", + "gtceu.machine.item_bus.import.tooltip": "Предметний вхід для конструкцій", + "gtceu.machine.item_collector.gui.collect_range": "Підбір в області %sx%s блоків", + "gtceu.machine.item_collector.tooltip": "Збирає предмети навколо себе", + "gtceu.machine.iv_alloy_smelter.tooltip": "§7Інтегратор сплавів", + "gtceu.machine.iv_arc_furnace.tooltip": "§7Розрядний нагрівач", + "gtceu.machine.iv_assembler.tooltip": "§7НЕ верстак", + "gtceu.machine.iv_autoclave.tooltip": "§7Скороварка", + "gtceu.machine.iv_bender.tooltip": "§7Викривлювач", + "gtceu.machine.iv_brewery.tooltip": "§7Більше ніж варильня", + "gtceu.machine.iv_canner.tooltip": "§7Консервний оператор", + "gtceu.machine.iv_centrifuge.tooltip": "§7Молекулярний циклон", + "gtceu.machine.iv_chemical_bath.tooltip": "§7Хімічний розчинник", + "gtceu.machine.iv_chemical_reactor.tooltip": "§7Хімічний перетворювач", + "gtceu.machine.iv_circuit_assembler.tooltip": "§7Виробник електроніки", + "gtceu.machine.iv_compressor.tooltip": "§7Конденсатор сингулярності", + "gtceu.machine.iv_cutter.tooltip": "§7Розсікач предметів", + "gtceu.machine.iv_distillery.tooltip": "§7Сепаратор конденсату", + "gtceu.machine.iv_electric_furnace.tooltip": "§7Механізм електронного збудження", + "gtceu.machine.iv_electrolyzer.tooltip": "§7Молекулярний дезінтегратор E-4906", + "gtceu.machine.iv_electromagnetic_separator.tooltip": "§7Електромагнітний категоризатор", + "gtceu.machine.iv_extractor.tooltip": "§7Вакуумний екстрактор", + "gtceu.machine.iv_extruder.tooltip": "§7Витіснювач матеріалів", + "gtceu.machine.iv_fermenter.tooltip": "§7Прискорювач ферментації", + "gtceu.machine.iv_fluid_heater.tooltip": "§7Тепловий інфузор", + "gtceu.machine.iv_fluid_solidifier.tooltip": "§7Не льодогенератор", + "gtceu.machine.iv_forge_hammer.tooltip": "§7Плитопідроблювач", + "gtceu.machine.iv_forming_press.tooltip": "§7Предметний нашаровувач", + "gtceu.machine.iv_gas_collector.tooltip": "§7Збирає газ з атмосфери залежно від виміру", + "gtceu.machine.iv_laser_engraver.tooltip": "§7Із силою 2.04 MW", + "gtceu.machine.iv_lathe.tooltip": "§7Поворотно-відкидна машина L-5906", + "gtceu.machine.iv_macerator.tooltip": "§7Блендоматор 9001", + "gtceu.machine.iv_mass_fabricator.tooltip": "§7Фабрика буття", + "gtceu.machine.iv_mixer.tooltip": "§7Органайзер матерії", + "gtceu.machine.iv_ore_washer.tooltip": "§7Переобладнана пральна машина I-360", + "gtceu.machine.iv_packer.tooltip": "§7Коробкар", + "gtceu.machine.iv_polarizer.tooltip": "§7Індуктор магнітного поля", + "gtceu.machine.iv_replicator.tooltip": "§7Матеріальний Ctrl+V", + "gtceu.machine.iv_rock_crusher.tooltip": "§7Кріогенний затверджувач магми R-8200", + "gtceu.machine.iv_scanner.tooltip": "§7Детектор аномалій", + "gtceu.machine.iv_sifter.tooltip": "§7За підтримки TFC", + "gtceu.machine.iv_thermal_centrifuge.tooltip": "§7Потогонник пломенів T-6350", + "gtceu.machine.iv_wiremill.tooltip": "§7Подовжувач злитків", + "gtceu.machine.large_boiler.bronze.tooltip": "Нам потрібно більше пари!", + "gtceu.machine.large_boiler.steel.tooltip": "Вуглезбагачувальна піч", + "gtceu.machine.large_boiler.titanium.tooltip": "Де чарівне суперпаливо?", + "gtceu.machine.large_boiler.tungstensteel.tooltip": "Як ви взагалі заправляєте цю штуку?", + "gtceu.machine.large_chemical_reactor.tooltip": "Реактор «Чорний ящик»", + "gtceu.machine.large_combustion_engine.tooltip": "Камера запалювання палива", + "gtceu.machine.large_combustion_engine.tooltip.boost_extreme": "§7Подавайте§f 80 мВ/с§7 рідкого кисню для виробництва до§f %s EU/т§7 при витраті§f 2x§7 палива.", + "gtceu.machine.large_combustion_engine.tooltip.boost_regular": "§7Подавайте§f 20 мВ/с§7 кисню для виробництва до§f %s EU/т§7 при витраті§f 2x§7 палива.", + "gtceu.machine.large_miner.ev.tooltip": "Копає руду замість вас", + "gtceu.machine.large_miner.iv.tooltip": "Біомний екскаватор", + "gtceu.machine.large_miner.luv.tooltip": "Земний комбайн", + "gtceu.machine.large_turbine.gas.tooltip": "Не реактивний двигун", + "gtceu.machine.large_turbine.plasma.tooltip": "Сифон плазмової енергії", + "gtceu.machine.large_turbine.steam.tooltip": "Не пхайте туди голову", + "gtceu.machine.laser_hatch.both.tooltip": "§cЛазерні кабелі повинні бути розміщені по прямій лінії!§7", + "gtceu.machine.laser_hatch.source.tooltip": "§7Передає енергію на відстані", + "gtceu.machine.laser_hatch.target.tooltip": "§7Отримує енергію на відстані", + "gtceu.machine.laser_source_hatch.tooltip.0": "Передача живлення на відстані", + "gtceu.machine.laser_source_hatch.tooltip.1": "§cЛазерні кабелі повинні бути розміщені по прямій лінії!§7", + "gtceu.machine.laser_target_hatch.tooltip.0": "Отримання живлення на відстані", + "gtceu.machine.laser_target_hatch.tooltip.1": "§cЛазерні кабелі повинні бути розміщені по прямій лінії!§7", + "gtceu.machine.locked_safe.malfunctioning": "§cНесправність!", + "gtceu.machine.locked_safe.requirements": "§7Необхідні замінники:", + "gtceu.machine.lp_steam_alloy_smelter.tooltip": "§7Комбінувальна плавильня сплавів", + "gtceu.machine.lp_steam_compressor.tooltip": "§7Стискає предмети", + "gtceu.machine.lp_steam_extractor.tooltip": "§7Добувач першої глини", + "gtceu.machine.lp_steam_forge_hammer.tooltip": "§7Ковальський молот", + "gtceu.machine.lp_steam_furnace.tooltip": "§7Плавить речі за допомогою стисненої пари", + "gtceu.machine.lp_steam_liquid_boiler.tooltip": "§7Котел, що працює на рідині", + "gtceu.machine.lp_steam_macerator.tooltip": "§7Подрібнює руди без побічних продуктів", + "gtceu.machine.lp_steam_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", + "gtceu.machine.lp_steam_solar_boiler.tooltip": "§7Парова енергія від сонця", + "gtceu.machine.lp_steam_solid_boiler.tooltip": "§7Ранній спосіб отримати парову енергію", + "gtceu.machine.luv_alloy_smelter.tooltip": "§7Інтегратор сплавів", + "gtceu.machine.luv_arc_furnace.tooltip": "§7Розрядний нагрівач", + "gtceu.machine.luv_assembler.tooltip": "§7НЕ верстак", + "gtceu.machine.luv_autoclave.tooltip": "§7Скороварка", + "gtceu.machine.luv_bender.tooltip": "§7Викривлювач", + "gtceu.machine.luv_brewery.tooltip": "§7Більше ніж варильня", + "gtceu.machine.luv_canner.tooltip": "§7Консервний оператор", + "gtceu.machine.luv_centrifuge.tooltip": "§7Молекулярний циклон", + "gtceu.machine.luv_chemical_bath.tooltip": "§7Хімічний розчинник", + "gtceu.machine.luv_chemical_reactor.tooltip": "§7Хімічний перетворювач", + "gtceu.machine.luv_circuit_assembler.tooltip": "§7Виробник електроніки", + "gtceu.machine.luv_compressor.tooltip": "§7Конденсатор сингулярності", + "gtceu.machine.luv_cutter.tooltip": "§7Розсікач предметів", + "gtceu.machine.luv_distillery.tooltip": "§7Сепаратор конденсату", + "gtceu.machine.luv_electric_furnace.tooltip": "§7Механізм електронного збудження", + "gtceu.machine.luv_electrolyzer.tooltip": "§7Молекулярний дезінтегратор E-4907", + "gtceu.machine.luv_electromagnetic_separator.tooltip": "§7Електромагнітний категоризатор", + "gtceu.machine.luv_extractor.tooltip": "§7Вакуумний екстрактор", + "gtceu.machine.luv_extruder.tooltip": "§7Витіснювач матеріалів", + "gtceu.machine.luv_fermenter.tooltip": "§7Прискорювач ферментації", + "gtceu.machine.luv_fluid_heater.tooltip": "§7Тепловий інфузор", + "gtceu.machine.luv_fluid_solidifier.tooltip": "§7Не льодогенератор", + "gtceu.machine.luv_forge_hammer.tooltip": "§7Плитопідроблювач", + "gtceu.machine.luv_forming_press.tooltip": "§7Предметний нашаровувач", + "gtceu.machine.luv_gas_collector.tooltip": "§7Збирає газ з атмосфери залежно від виміру", + "gtceu.machine.luv_laser_engraver.tooltip": "§7Із силою 8.16 MW", + "gtceu.machine.luv_lathe.tooltip": "§7Поворотно-відкидна машина L-5907", + "gtceu.machine.luv_macerator.tooltip": "§7Блендоматор 9002", + "gtceu.machine.luv_mass_fabricator.tooltip": "§7Фабрика буття", + "gtceu.machine.luv_mixer.tooltip": "§7Органайзер матерії", + "gtceu.machine.luv_ore_washer.tooltip": "§7Переобладнана пральна машина I-361", + "gtceu.machine.luv_packer.tooltip": "§7Коробкар", + "gtceu.machine.luv_polarizer.tooltip": "§7Індуктор магнітного поля", + "gtceu.machine.luv_replicator.tooltip": "§7Матеріальний Ctrl+V", + "gtceu.machine.luv_rock_crusher.tooltip": "§7Кріогенний затверджувач магми R-9200", + "gtceu.machine.luv_scanner.tooltip": "§7Детектор аномалій", + "gtceu.machine.luv_sifter.tooltip": "§7За підтримки TFC", + "gtceu.machine.luv_thermal_centrifuge.tooltip": "§7Потогонник пломенів T-6351", + "gtceu.machine.luv_wiremill.tooltip": "§7Подовжувач злитків", + "gtceu.machine.lv_alloy_smelter.tooltip": "§7Високотехнологічна комбінувальна плавильня сплавів", + "gtceu.machine.lv_arc_furnace.tooltip": "§7Кому взагалі потрібна плавильна піч?", + "gtceu.machine.lv_assembler.tooltip": "§7Месники, збираємось!", + "gtceu.machine.lv_autoclave.tooltip": "§7Кристалізує пил", + "gtceu.machine.lv_bender.tooltip": "§7Фууу, він поганий! Нам потрібен БЕНДЕР!!!", + "gtceu.machine.lv_brewery.tooltip": "§7Компактне та ефективне зіллєваріння", + "gtceu.machine.lv_canner.tooltip": "§7Поміщає речі в контейнери та виймає їх з них", + "gtceu.machine.lv_centrifuge.tooltip": "§7Розподіл молекул", + "gtceu.machine.lv_chemical_bath.tooltip": "§7Розщеплює руди шляхом їх вимочування у хімікатах", + "gtceu.machine.lv_chemical_reactor.tooltip": "§7Дає хімічним речовинам вступати в реакцію між собою", + "gtceu.machine.lv_circuit_assembler.tooltip": "§7Всюдисущий віьзми-поклади", + "gtceu.machine.lv_compressor.tooltip": "§7Компресорно-механічна система C77", + "gtceu.machine.lv_cutter.tooltip": "§7Криворіж", + "gtceu.machine.lv_distillery.tooltip": "§7Вилучає найбільш важливі частини рідин", + "gtceu.machine.lv_electric_furnace.tooltip": "§7Не схоже на користування Commodore 64", + "gtceu.machine.lv_electrolyzer.tooltip": "§7Молекулярний електроліз", + "gtceu.machine.lv_electromagnetic_separator.tooltip": "§7Відокремлює магнітні руди від решти", + "gtceu.machine.lv_extractor.tooltip": "§7Соковичавлюючий пристрій приречення - D123", + "gtceu.machine.lv_extruder.tooltip": "§7Універсальна металообробна машина", + "gtceu.machine.lv_fermenter.tooltip": "§7Ферментує рідини", + "gtceu.machine.lv_fluid_heater.tooltip": "§7Нагріває рідини", + "gtceu.machine.lv_fluid_solidifier.tooltip": "§7Охолоджує рідини до твердого стану", + "gtceu.machine.lv_forge_hammer.tooltip": "§7Стоп, час молота!", + "gtceu.machine.lv_forming_press.tooltip": "§7Витискає речам нову форму", + "gtceu.machine.lv_gas_collector.tooltip": "§7Збирає газ з повітря залежно від виміру", + "gtceu.machine.lv_laser_engraver.tooltip": "§7Не дивіться прямо на лазер", + "gtceu.machine.lv_lathe.tooltip": "§7Ефективніше виробляє стрижні", + "gtceu.machine.lv_macerator.tooltip": "§7Подрібнює руди без побічних продуктів", + "gtceu.machine.lv_mass_fabricator.tooltip": "§7UUM матерія * виробництво в квадраті", + "gtceu.machine.lv_mixer.tooltip": "§7Чи змішається?", + "gtceu.machine.lv_ore_washer.tooltip": "§7Отримує більше побічних продуктів з руд", + "gtceu.machine.lv_packer.tooltip": "§7Запаковує та розпаковує речі", + "gtceu.machine.lv_polarizer.tooltip": "§7Біполяризовує магніти", + "gtceu.machine.lv_replicator.tooltip": "§7Виробляє найчистіші елементи", + "gtceu.machine.lv_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", + "gtceu.machine.lv_scanner.tooltip": "§7Сканує матеріали та інші речі", + "gtceu.machine.lv_sifter.tooltip": "§7Зберігайте спокій і продовжуйте просіювати", + "gtceu.machine.lv_thermal_centrifuge.tooltip": "§7Точніше розділяє руди", + "gtceu.machine.lv_wiremill.tooltip": "§7Ефективніше виробляє дроти", + "gtceu.machine.machine_hatch.locked": "Інтерфейс машини заблоковано", + "gtceu.machine.machine_hatch.processing_array": "Коли в§e конвеєрній лінії§7, утримує тільки машини, які працюють в§e обробчій лінії", + "gtceu.machine.machine_hatch.tooltip": "Спеціалізована шина доступу, яка утримує тільки дійсні предмети", + "gtceu.machine.maintenance_hatch.tooltip": "Для обслуговування конструкцій", + "gtceu.machine.maintenance_hatch_cleanroom_auto.tooltip.0": "Для автоматичного догляду за конструкціями з очищенням!", + "gtceu.machine.maintenance_hatch_cleanroom_auto.tooltip.1": "Очищає як:", + "gtceu.machine.maintenance_hatch_configurable.tooltip.0": "Для кращого контролю над конструкціями", + "gtceu.machine.maintenance_hatch_configurable.tooltip.1": "Починає роботу без проблем з обслуговуванням!", + "gtceu.machine.maintenance_hatch_full_auto.tooltip": "Для автоматичного догляду за конструкціями", + "gtceu.machine.maintenance_hatch_tape_slot.tooltip": "Вставте клейку стрічку, щоб запобігти проблемам", + "gtceu.machine.maintenance_hatch_tool_slot.tooltip": "Клацніть гніздо порожньою рукою, коли потрібні інструменти є в інвентарі, щоб вирішити проблему", + "gtceu.machine.me.copy_paste.tooltip": "ЛКМ із карткою даних, щоб скопіювати налаштування, ПКМ, щоб застосувати", + "gtceu.machine.me.export.tooltip": "Має необмежену ємність до підключення до МЕ-мережі.", + "gtceu.machine.me.fluid_export.tooltip": "Зберігає рідини безпосередньо в МЕ-мережу.", + "gtceu.machine.me.fluid_import.data_stick.name": "§oКонфігураційні дані ME-вхідного люка", + "gtceu.machine.me.fluid_import.tooltip": "Автоматично забирає рідини з МЕ-мережі.", + "gtceu.machine.me.import_copy_settings": "Налаштування збережені у картці даних", + "gtceu.machine.me.import_paste_settings": "Застосовані налаштування з картки даних", + "gtceu.machine.me.item_export.tooltip": "Зберігає предмети безпосередньо в МЕ-мережу.", + "gtceu.machine.me.item_import.data_stick.name": "§oКонфігураційні дані ME-вхідної шини", + "gtceu.machine.me.item_import.tooltip": "Автоматично забирає предмети з МЕ-мережі.", + "gtceu.machine.me.stocking_auto_pull_disabled": "Автовитягання вимкнено", + "gtceu.machine.me.stocking_auto_pull_enabled": "Автовитягання увімкнено", + "gtceu.machine.me.stocking_fluid.tooltip.0": "Отримує рідини безпосередньо з МЕ-мережі", + "gtceu.machine.me.stocking_fluid.tooltip.1": "Режим автовитягання з МЕ автоматично заповнить перші 16 рідин у ME-системі, оновлюючись кожні 5 секунд.", + "gtceu.machine.me.stocking_item.tooltip.0": "Отримує предмети безпосередньо з МЕ-мережі", + "gtceu.machine.me.stocking_item.tooltip.1": "Режим автовитягання з МЕ автоматично заповнить перші 16 предметів у ME-системі, оновлюючись кожні 5 секунд.", + "gtceu.machine.me_import_fluid_hatch.configs.tooltip": "Зберігає в наявності 16 типів рідин", + "gtceu.machine.me_import_item_hatch.configs.tooltip": "Зберігає в наявності 16 типів предметів", + "gtceu.machine.miner.chunkradius": "Радіус чанків: %d", + "gtceu.machine.miner.fluid_usage": "Використовує§f %d мВ/т§7 §f %s§7, подвоюється при розгоні.", + "gtceu.machine.miner.minex": "mX: %d", + "gtceu.machine.miner.miney": "mY: %d", + "gtceu.machine.miner.minez": "mZ: %d", + "gtceu.machine.miner.multi.description": "Багатоблочний видобувний комбайн, який охоплює велику площу і видобуває величезну кількість руди.", + "gtceu.machine.miner.multi.modes": "Має режими вирівнювання по чанку та шовкового дотику.", + "gtceu.machine.miner.multi.production": "Виробляє в§f 3§7 рази більше руди, ніж§f дробарка§7.", + "gtceu.machine.miner.per_block": "§7забирає§f %ds§7 за блок", + "gtceu.machine.miner.radius": "Радіус: %d", + "gtceu.machine.miner.startx": "sX: %d", + "gtceu.machine.miner.starty": "sY: %d", + "gtceu.machine.miner.startz": "sZ: %d", + "gtceu.machine.miner.tooltip": "§7Добуває руди під шахтами! починає з зони§f %sx%s§7 ", + "gtceu.machine.muffle.off": "Приглушення звуку: вимкнено", + "gtceu.machine.muffle.on": "Приглушення звуку: Увімкнено", + "gtceu.machine.muffler_hatch.tooltip.0": "Утилізує відходи з машин", + "gtceu.machine.muffler_hatch.tooltip.1": "НЕ ПЕРЕКРИВАЙТЕ ВИХІД!", + "gtceu.machine.multi_furnace.tooltip": "Як у домашній духовці", + "gtceu.machine.multiblock.tank.tooltip": "Заправляйте та зливайте через контролер або клапани бака.", + "gtceu.machine.mv_alloy_smelter.tooltip": "§7Високотехнологічна комбінувальна плавильня сплавів", + "gtceu.machine.mv_arc_furnace.tooltip": "§7Кому взагалі потрібна плавильна піч?", + "gtceu.machine.mv_assembler.tooltip": "§7Месники, збираємось!", + "gtceu.machine.mv_autoclave.tooltip": "§7Кристалізує пил", + "gtceu.machine.mv_bender.tooltip": "§7Фууу, він поганий! Нам потрібен БЕНДЕР!!!", + "gtceu.machine.mv_brewery.tooltip": "§7Компактне та ефективне зіллєваріння", + "gtceu.machine.mv_canner.tooltip": "§7Поміщає речі в контейнери та виймає їх з них", + "gtceu.machine.mv_centrifuge.tooltip": "§7Розподіл молекул", + "gtceu.machine.mv_chemical_bath.tooltip": "§7Розщеплює руди шляхом їх вимочування у хімікатах", + "gtceu.machine.mv_chemical_reactor.tooltip": "§7Дає хімічним речовинам вступати в реакцію між собою", + "gtceu.machine.mv_circuit_assembler.tooltip": "§7Всюдисущий віьзми-поклади", + "gtceu.machine.mv_compressor.tooltip": "§7Компресорно-механічна система C77", + "gtceu.machine.mv_cutter.tooltip": "§7Ріж-крій", + "gtceu.machine.mv_distillery.tooltip": "§7Вилучає найбільш важливі частини рідин", + "gtceu.machine.mv_electric_furnace.tooltip": "§7Не схоже на користування Commodore 64", + "gtceu.machine.mv_electrolyzer.tooltip": "§7Молекулярний електроліз", + "gtceu.machine.mv_electromagnetic_separator.tooltip": "§7Відокремлює магнітні руди від решти", + "gtceu.machine.mv_extractor.tooltip": "§7Соковичавлюючий пристрій приречення - D123", + "gtceu.machine.mv_extruder.tooltip": "§7Універсальна металообробна машина", + "gtceu.machine.mv_fermenter.tooltip": "§7Ферментує рідини", + "gtceu.machine.mv_fluid_drilling_rig.tooltip": "Нафтоперекачувальна помпа", + "gtceu.machine.mv_fluid_heater.tooltip": "§7Нагріває рідини", + "gtceu.machine.mv_fluid_solidifier.tooltip": "§7Охолоджує рідини до твердого стану", + "gtceu.machine.mv_forge_hammer.tooltip": "§7Стоп, час молота!", + "gtceu.machine.mv_forming_press.tooltip": "§7Витискає речам нову форму", + "gtceu.machine.mv_gas_collector.tooltip": "§7Збирає газ з повітря залежно від виміру", + "gtceu.machine.mv_laser_engraver.tooltip": "§7Не дивіться прямо на лазер", + "gtceu.machine.mv_lathe.tooltip": "§7Ефективніше виробляє стрижні", + "gtceu.machine.mv_macerator.tooltip": "§7Подрібнює руди без побічних продуктів", + "gtceu.machine.mv_mass_fabricator.tooltip": "§7UUM матерія * виробництво в квадраті", + "gtceu.machine.mv_mixer.tooltip": "§7Чи змішається?", + "gtceu.machine.mv_ore_washer.tooltip": "§7Отримує більше побічних продуктів з руд", + "gtceu.machine.mv_packer.tooltip": "§7Запаковує та розпаковує речі", + "gtceu.machine.mv_polarizer.tooltip": "§7Біполяризовує магніти", + "gtceu.machine.mv_replicator.tooltip": "§7Виробляє найчистіші елементи", + "gtceu.machine.mv_rock_crusher.tooltip": "§7Розмістіть поруч горизонтально воду і лаву", + "gtceu.machine.mv_scanner.tooltip": "§7Сканує матеріали та інші речі", + "gtceu.machine.mv_sifter.tooltip": "§7Зберігайте спокій і продовжуйте просіювати", + "gtceu.machine.mv_thermal_centrifuge.tooltip": "§7Точніше розділяє руди", + "gtceu.machine.mv_wiremill.tooltip": "§7Ефективніше виробляє дроти", + "gtceu.machine.network_switch.tooltip.0": "Ethernet-концентратор", + "gtceu.machine.network_switch.tooltip.1": "Використовується для маршрутизації та розподілу§f обчислень§7.", + "gtceu.machine.network_switch.tooltip.2": "Може об'єднати будь-яку кількість обчислювальних§f приймачів§7 у будь-яку кількість обчислювальних§f передавачів§7.", + "gtceu.machine.network_switch.tooltip.3": "Використовує§f %s EU/т§7 для кожного люка обчислювальних даних.", + "gtceu.machine.object_holder.tooltip": "Вдосконалений механізм утримання для дослідницької станції", + "gtceu.machine.opv_gas_collector.tooltip": "§7Збирає газ із всесвіту залежно від виміру", + "gtceu.machine.opv_rock_crusher.tooltip": "§7Камера вулканічних утворень", + "gtceu.machine.parallel_hatch.display": "Регулюйте максимум паралелей конструкції", + "gtceu.machine.parallel_hatch_mk5.tooltip": "Дозволяє запускати до 4 рецептів паралельно.", + "gtceu.machine.parallel_hatch_mk6.tooltip": "Дозволяє запускати до 16 рецептів паралельно.", + "gtceu.machine.parallel_hatch_mk7.tooltip": "Дозволяє запускати до 64 рецептів паралельно.", + "gtceu.machine.parallel_hatch_mk8.tooltip": "Дозволяє запускати до 256 рецептів паралельно.", + "gtceu.machine.parallel_limit": "Дозволяє виконувати до§b %d§r§7 рецептів одночасно.", + "gtceu.machine.passthrough_hatch_fluid.tooltip": "Перекачує рідини з однієї сторони на іншу", + "gtceu.machine.passthrough_hatch_item.tooltip": "Переміщує предмети з однієї сторони на іншу", + "gtceu.machine.perfect_oc": "Не втрачає енергоефективність при розгоні.", + "gtceu.machine.power_substation.tooltip.0": "Серце централізованої енергосистеми", + "gtceu.machine.power_substation.tooltip.1": "§fАкумулятори§7 не обов'язково повинні бути одного рівня.", + "gtceu.machine.power_substation.tooltip.2": "Допускає до§f %d шарів акумуляторів§7.", + "gtceu.machine.power_substation.tooltip.3": "Втрачає енергію, що дорівнює§f 1%%§7 від загальної ємності кожні§f 24 години§7.", + "gtceu.machine.power_substation.tooltip.4": "Обмежено на рівні§f %d kEU/т§7 пасивних втрат на блок акумулятора.", + "gtceu.machine.power_substation.tooltip.5": "Може використовувати", + "gtceu.machine.power_substation.tooltip.6": " лазерні люки§7.", + "gtceu.machine.primitive_blast_furnace.bronze.tooltip": "Створення першої сталі", + "gtceu.machine.primitive_water_pump.tooltip": "Ендервуар в домашніх умовах", + "gtceu.machine.processing_array.tooltip": "Коли кількох машин недостатньо", + "gtceu.machine.pump.tooltip": "§7Найкращий спосіб спустошувати океани!", + "gtceu.machine.pump.tooltip_buckets": "§f%d§7 тактів за відро", + "gtceu.machine.pump_hatch.tooltip": "Примітивний вихід рідини для водяної помпи", + "gtceu.machine.pyrolyse_oven.tooltip": "Електрична коксувальна піч", + "gtceu.machine.pyrolyse_oven.tooltip.1": "§6Мельхіорові§7 котушки на§f 25%%§7 повільніші. кожна котушка після§b канталової§7 збільшує швидкість на§f 50%%§7.", + "gtceu.machine.quantum_chest.items_stored": "Кількість:", + "gtceu.machine.quantum_chest.tooltip": "§7Краще ніж Storage Drawers", + "gtceu.machine.quantum_tank.tooltip": "§7Компактне місце для зберігання всіх рідин", + "gtceu.machine.research_station.researching": "Дослідження.", + "gtceu.machine.research_station.tooltip.0": "Більше, ніж просто багатоблочний сканер", + "gtceu.machine.research_station.tooltip.1": "Використовується для сканування на§f сферах даних§7 та§f модулях даних§7.", + "gtceu.machine.research_station.tooltip.2": "Для роботи потрібні§f обчислення§7.", + "gtceu.machine.research_station.tooltip.3": "Забезпечення більшої кількості обчислень дозволяє рецепту працювати швидше.", + "gtceu.machine.rotor_holder.tooltip.0": "Тримач ротора для конструкцій", + "gtceu.machine.rotor_holder.tooltip.1": "Утримує ротор на місці, щоб він не відлетів", + "gtceu.machine.steam.steam_hatch.tooltip": "§eПриймає рідину:§f пара", + "gtceu.machine.steam_boiler.heat_amount": "Тепломісткість: %s %%", + "gtceu.machine.steam_bus.tooltip": "Не працює з непаровими конструкціями", + "gtceu.machine.steam_grinder.tooltip": "Багатоблочний подрібнювач без побічних продуктів", + "gtceu.machine.steam_miner.tooltip": "§7Добуває руди під шахтами!", + "gtceu.machine.steam_oven.tooltip": "Не плутати з мультиплавильнею", + "gtceu.machine.steam_turbine.tooltip": "§7Перетворює пару на EU", + "gtceu.machine.substation_hatch.input.tooltip": "Вхід енергії для електропідстанції", + "gtceu.machine.substation_hatch.output.tooltip": "Вихід енергії для електропідстанції", + "gtceu.machine.tank_valve.tooltip": "Використовується для наповнення та спорожнення резервуарів конструкцій. Виводить автоматично, якщо розміщений лицьовою стороною донизу.", + "gtceu.machine.transformer.description": "§7Трансформує енергію між рівнями напруги", + "gtceu.machine.transformer.message_transform_down": "Трансформація вниз, вхід: %s EU %dA, вихід: %s EU %dA", + "gtceu.machine.transformer.message_transform_up": "Трансформація вгору, вхід: %s EU %dA, вихід: %s EU %dA", + "gtceu.machine.transformer.tooltip_tool_usage": "Починає з§f трансформації вниз§7, використовуйте викрутку для зміни", + "gtceu.machine.transformer.tooltip_transform_down": "§aТрансформування вниз:§f %dA %s EU (%s§f) -> %dA %s EU (%s§f)", + "gtceu.machine.transformer.tooltip_transform_up": "§cТрансформування вгору:§f %dA %s EU (%s§f) -> %dA %s EU (%s§f)", + "gtceu.machine.uev_gas_collector.tooltip": "§7Збирає газ з сонячної системи залежно від виміру", + "gtceu.machine.uev_rock_crusher.tooltip": "§7Камера вулканічних утворень", + "gtceu.machine.uhv_gas_collector.tooltip": "§7Збирає газ з сонячної системи залежно від виміру", + "gtceu.machine.uhv_rock_crusher.tooltip": "§7Камера вулканічних утворень", + "gtceu.machine.uiv_gas_collector.tooltip": "§7Збирає газ з сонячної системи залежно від виміру", + "gtceu.machine.uiv_rock_crusher.tooltip": "§7Камера вулканічних утворень", + "gtceu.machine.uv_alloy_smelter.tooltip": "§7Амальгаматор металу", + "gtceu.machine.uv_arc_furnace.tooltip": "§7Нагрівач короткого замикання", + "gtceu.machine.uv_assembler.tooltip": "§7Збиральний конструктор", + "gtceu.machine.uv_autoclave.tooltip": "§7Блок обтяження", + "gtceu.machine.uv_bender.tooltip": "§7Деформатор матерії", + "gtceu.machine.uv_brewery.tooltip": "§7Перша броварня", + "gtceu.machine.uv_canner.tooltip": "§7Консервний актуатор", + "gtceu.machine.uv_centrifuge.tooltip": "§7Молекулярне торнадо", + "gtceu.machine.uv_chemical_bath.tooltip": "§7Хімічний занурятор 2222", + "gtceu.machine.uv_chemical_reactor.tooltip": "§7Каталізатор реакцій", + "gtceu.machine.uv_circuit_assembler.tooltip": "§7Фабрика обчислень", + "gtceu.machine.uv_compressor.tooltip": "§7Стискач матерії", + "gtceu.machine.uv_cutter.tooltip": "§7Розділювач матерії", + "gtceu.machine.uv_distillery.tooltip": "§7Дільник фракцій", + "gtceu.machine.uv_electric_furnace.tooltip": "§7Атомний стимулятор", + "gtceu.machine.uv_electrolyzer.tooltip": "§7Атомний іонізатор", + "gtceu.machine.uv_electromagnetic_separator.tooltip": "§7Ровіювач електромагнітної сили", + "gtceu.machine.uv_extractor.tooltip": "§7Відсмоктувач зрідження", + "gtceu.machine.uv_extruder.tooltip": "§7Формоутворювач", + "gtceu.machine.uv_fermenter.tooltip": "§7Дихальний контролер", + "gtceu.machine.uv_fluid_heater.tooltip": "§7Тепловий просякач", + "gtceu.machine.uv_fluid_solidifier.tooltip": "§7Рідинний окаменювач", + "gtceu.machine.uv_forge_hammer.tooltip": "§7Модулятор удару", + "gtceu.machine.uv_forming_press.tooltip": "§7Змінювач поверхней", + "gtceu.machine.uv_gas_collector.tooltip": "§7Збирає газ з сонячної системи залежно від виміру", + "gtceu.machine.uv_laser_engraver.tooltip": "§7Точна фотонна гармата", + "gtceu.machine.uv_lathe.tooltip": "§7Ротаційна шліфувальна машина", + "gtceu.machine.uv_macerator.tooltip": "§7Деформувальник", + "gtceu.machine.uv_mass_fabricator.tooltip": "§7Ініціатор існування", + "gtceu.machine.uv_mixer.tooltip": "§7Гомогенізатор матеріалу", + "gtceu.machine.uv_ore_washer.tooltip": "§7Мініатюрна автомийка", + "gtceu.machine.uv_packer.tooltip": "§7Склад Нової пошти", + "gtceu.machine.uv_polarizer.tooltip": "§7Реорганізатор магнітного поля", + "gtceu.machine.uv_replicator.tooltip": "§7Елементарний композитор", + "gtceu.machine.uv_rock_crusher.tooltip": "§7Камера вулканічних утворень", + "gtceu.machine.uv_scanner.tooltip": "§7Електронний мікроскоп", + "gtceu.machine.uv_sifter.tooltip": "§7Пульсаційний фільтр", + "gtceu.machine.uv_thermal_centrifuge.tooltip": "§7Вогняний циклон", + "gtceu.machine.uv_wiremill.tooltip": "§7Трансформатор дротів", + "gtceu.machine.uxv_gas_collector.tooltip": "§7Збирає газ з сонячної системи залежно від виміру", + "gtceu.machine.uxv_rock_crusher.tooltip": "§7Камера вулканічних утворень", + "gtceu.machine.vacuum_freezer.tooltip": "Алюмінієвий контейнер для льоду", + "gtceu.machine.workbench.storage_note.0": "(Доступні предмети з під'єднаних", + "gtceu.machine.workbench.storage_note.1": "контейнерів доступні для майстрування)", + "gtceu.machine.workbench.tab.container": "Контейнер", + "gtceu.machine.workbench.tab.crafting": "Майстрування", + "gtceu.machine.workbench.tab.item_list": "Сховище", + "gtceu.machine.workbench.tab.workbench": "Майстрування", + "gtceu.machine.workbench.tooltip.0": "Краще Forestry", + "gtceu.machine.workbench.tooltip.1": "Має сховище предметів, сховище інструментів, витягує з сусідніх контейнерів і зберігає рецепти.", + "gtceu.machine.world_accelerator.description": "Тактово прискорює сусідні блоки в одному з 2 режимів:§f Блок-сутність§7 або§f випадковий такт§7. Використовуйте викрутку, щоб змінити режим.", + "gtceu.machine.world_accelerator.mode_entity": "Режим випадкового такту", + "gtceu.machine.world_accelerator.mode_tile": "Режим блока-сутності", + "gtceu.machine.world_accelerator.working_area": "§bРобоча зона:", + "gtceu.machine.world_accelerator.working_area_random": " режим випадкового такту:§f %dx%d", + "gtceu.machine.world_accelerator.working_area_tile": " режим блокової сутності:§f суміжних блоків", + "gtceu.machine.zpm_alloy_smelter.tooltip": "§7Інтегратор сплавів", + "gtceu.machine.zpm_arc_furnace.tooltip": "§7Розрядний нагрівач", + "gtceu.machine.zpm_assembler.tooltip": "§7НЕ верстак", + "gtceu.machine.zpm_autoclave.tooltip": "§7Скороварка", + "gtceu.machine.zpm_bender.tooltip": "§7Викривлювач", + "gtceu.machine.zpm_brewery.tooltip": "§7Більше ніж варильня", + "gtceu.machine.zpm_canner.tooltip": "§7Консервний оператор", + "gtceu.machine.zpm_centrifuge.tooltip": "§7Молекулярний циклон", + "gtceu.machine.zpm_chemical_bath.tooltip": "§7Хімічний розчинник", + "gtceu.machine.zpm_chemical_reactor.tooltip": "§7Хімічний перетворювач", + "gtceu.machine.zpm_circuit_assembler.tooltip": "§7Виробник електроніки", + "gtceu.machine.zpm_compressor.tooltip": "§7Конденсатор сингулярності", + "gtceu.machine.zpm_cutter.tooltip": "§7Розсікач предметів", + "gtceu.machine.zpm_distillery.tooltip": "§7Сепаратор конденсату", + "gtceu.machine.zpm_electric_furnace.tooltip": "§7Механізм електронного збудження", + "gtceu.machine.zpm_electrolyzer.tooltip": "§7Молекулярний дезінтегратор E-4908", + "gtceu.machine.zpm_electromagnetic_separator.tooltip": "§7Електромагнітний категоризатор", + "gtceu.machine.zpm_extractor.tooltip": "§7Вакуумний екстрактор", + "gtceu.machine.zpm_extruder.tooltip": "§7Витіснювач матеріалів", + "gtceu.machine.zpm_fermenter.tooltip": "§7Прискорювач ферментації", + "gtceu.machine.zpm_fluid_heater.tooltip": "§7Тепловий інфузор", + "gtceu.machine.zpm_fluid_solidifier.tooltip": "§7Не льодогенератор", + "gtceu.machine.zpm_forge_hammer.tooltip": "§7Плитопідроблювач", + "gtceu.machine.zpm_forming_press.tooltip": "§7Предметний нашаровувач", + "gtceu.machine.zpm_gas_collector.tooltip": "§7Збирає газ з атмосфери залежно від виміру", + "gtceu.machine.zpm_laser_engraver.tooltip": "§7Із силою 32.64 MW", + "gtceu.machine.zpm_lathe.tooltip": "§7Поворотно-відкидна машина L-5908", + "gtceu.machine.zpm_macerator.tooltip": "§7Блендоматор 9003", + "gtceu.machine.zpm_mass_fabricator.tooltip": "§7Фабрика буття", + "gtceu.machine.zpm_mixer.tooltip": "§7Органайзер матерії", + "gtceu.machine.zpm_ore_washer.tooltip": "§7Переобладнана пральна машина I-362", + "gtceu.machine.zpm_packer.tooltip": "§7Коробкар", + "gtceu.machine.zpm_polarizer.tooltip": "§7Індуктор магнітного поля", + "gtceu.machine.zpm_replicator.tooltip": "§7Матеріальний Ctrl+V", + "gtceu.machine.zpm_rock_crusher.tooltip": "§7Кріогенний затверджувач магми R-10200", + "gtceu.machine.zpm_scanner.tooltip": "§7Детектор аномалій", + "gtceu.machine.zpm_sifter.tooltip": "§7За підтримки TFC", + "gtceu.machine.zpm_thermal_centrifuge.tooltip": "§7Потогонник пломенів T-6352", + "gtceu.machine.zpm_wiremill.tooltip": "§7Подовжувач злитків", + "gtceu.maintenance.configurable_duration": "Тривалість: %fx", + "gtceu.maintenance.configurable_duration.changed_description": "Рецепти запускатимуться з тривалістю %fx, застосованою перед розгоном.", + "gtceu.maintenance.configurable_duration.modify": "Змінити тривалість:", + "gtceu.maintenance.configurable_duration.unchanged_description": "Рецепти виконуватимуться зі звичайною швидкістю. Змініть конфігурацію для оновлення.", + "gtceu.maintenance.configurable_time": "Час: %fx", + "gtceu.maintenance.configurable_time.changed_description": "Проблеми з обслуговуванням виникатимуть у %f разів частіше.", + "gtceu.maintenance.configurable_time.unchanged_description": "Проблеми з обслуговуванням виникатимуть зі звичайною швидкістю. Змініть конфігурацію для оновлення.", + "gtceu.medical_condition.antidote.description": "§aПротиотрута§7 Утримуйте Shift для подробиць", + "gtceu.medical_condition.antidote.description.effect_removed": "Знешкоджує %s%% наявних ефектів уражень", + "gtceu.medical_condition.antidote.description.effect_removed.all": "Знешкоджує усі ураження", + "gtceu.medical_condition.antidote.description_shift": "§aВиліковує ці ураження:", + "gtceu.medical_condition.arsenicosis": "§bОтруєння миш'яком", + "gtceu.medical_condition.asbestosis": "§dАзбестоз", + "gtceu.medical_condition.berylliosis": "§5Бериліоз", + "gtceu.medical_condition.carbon_monoxide_poisoning": "§7Отруєння монооксидом вуглецю", + "gtceu.medical_condition.carcinogen": "§eРадіоактивне опромінення", + "gtceu.medical_condition.chemical_burns": "§5Хімічні опіки", + "gtceu.medical_condition.description": "§l§cНЕБЕЗПЕЧНО§7 Утримуйте Shift для подробиць", + "gtceu.medical_condition.description_shift": "§l§cНЕБЕЗПЕКА:", + "gtceu.medical_condition.irritant": "§6Подразення", + "gtceu.medical_condition.methanol_poisoning": "§6Отруєння метанолом", + "gtceu.medical_condition.nausea": "§3Нудота", + "gtceu.medical_condition.none": "§2(Не²)Безпечно", + "gtceu.medical_condition.poison": "§2Отрута", + "gtceu.medical_condition.silicosis": "§1Силікоз", + "gtceu.medical_condition.weak_poison": "§aСлабка отрута", + "gtceu.minimap.ore_vein.depleted": "Виснажено", + "gtceu.mixer": "Змішувач", + "gtceu.mode.both": "§dСпільний (Рідини та предмети)§r", + "gtceu.mode.fluid": "§9Рідини§r", + "gtceu.mode.item": "§6Предмети§r", + "gtceu.muffler.recovery_tooltip": "§bШанс відновлення:§f %d%%", + "gtceu.multiblock.active_transformer.average_in": "§bСеред. Вхід:§f %s EU/т", + "gtceu.multiblock.active_transformer.average_out": "§bСеред. Вихід:§f %s EU/т", + "gtceu.multiblock.active_transformer.danger_enabled": "§c§bНЕБЕЗПЕКА: вибухонебезпечно", + "gtceu.multiblock.active_transformer.max_input": "§aМакс. Вхід:§f %s EU/т", + "gtceu.multiblock.active_transformer.max_output": "§cМакс. Вихід:§f %s EU/т", + "gtceu.multiblock.assembly_line.description": "Конвеєрна лінія - це велика багатоблочна конструкція, що складається з 5 до 16 \"скибок\". теоретично, це великий збиральний апарат, який використовується для створення вдосконалених крафтових компонентів.", + "gtceu.multiblock.batch_enabled": "Режим групування: Увімкнено (%sx)", + "gtceu.multiblock.blast_furnace.max_temperature": "Теплоємність: %s", + "gtceu.multiblock.central_monitor.height": "Висота екрану:", + "gtceu.multiblock.central_monitor.height_modify": "Зміна висоти: %d", + "gtceu.multiblock.central_monitor.low_power": "Низька потужність", + "gtceu.multiblock.central_monitor.tooltip.0": "Це машина, яка контролює машини, проксі яких знаходяться під кришкою цифрового інтерфейсу. Ви можете легко контролювати рідини, предмети, енергію та стани машин, проксі яких підключено до енергетичної мережі.", + "gtceu.multiblock.central_monitor.tooltip.1": "Ви можете побудувати екран центрального контролера від 3x2 до %dx%d (ширина x висота).", + "gtceu.multiblock.central_monitor.tooltip.2": "Усталена висота - 3. Ви можете налаштувати висоту екрану в графічному інтерфейсі до того, як структура буде сформована.", + "gtceu.multiblock.central_monitor.tooltip.3": "Споживання енергії: %d EU/c за кожний екран.", + "gtceu.multiblock.central_monitor.width": "Ширина екрану: %d", + "gtceu.multiblock.charcoal_pile.description.0": "Перетворює колоди на крихке деревне вугілля в зоні 9х4х9 під собою.", + "gtceu.multiblock.charcoal_pile.description.1": "", + "gtceu.multiblock.charcoal_pile.description.2": "Підлога ями повинна бути викладена з цегли, а для стін і даху можна використовувати будь-який грунтовий блок. Усередині ями не повинно бути повітря.", + "gtceu.multiblock.charcoal_pile.description.3": "", + "gtceu.multiblock.charcoal_pile.description.4": "Більші ями займають більше часу для обробки колод, але є більш ефективними.", + "gtceu.multiblock.cleanroom.clean_amount": "Чистота:§a %s%%", + "gtceu.multiblock.cleanroom.clean_state": "Стан:§a ЧИСТО", + "gtceu.multiblock.cleanroom.dirty_state": "Стан:§4 ЗАБРУДНЕНО", + "gtceu.multiblock.coke_oven.description": "Коксова піч - це багатоблочна конструкція, яка використовується для отримання коксу та креозоту на початку гри. Вона не потребує палива і має внутрішній резервуар на 32 відра для креозоту. Доступ до її інвентарю можна отримати через люк коксової печі.", + "gtceu.multiblock.computation.max": "Макс. ОРО/т: %s", + "gtceu.multiblock.computation.non_bridging": "Знайдено немостове з'єднання", + "gtceu.multiblock.computation.non_bridging.detailed": "Приймальний люк пов'язаний з машиною без мостування", + "gtceu.multiblock.computation.not_enough_computation": "Машина вимагає більше обчислень!", + "gtceu.multiblock.computation.usage": "Використовується: %s", + "gtceu.multiblock.cracker.description": "Нафтова крекінгова установка - це багатоблочна конструкція, яка використовується для перетворення легкого та важкого палива на їх крекінгові варіанти.", + "gtceu.multiblock.cracking_unit.energy": "Вик. енергії: %s%%", + "gtceu.multiblock.data_bank.description": "База даних - це багатоблочна конструкція, яка використовується для спільного використання дослідницьких даних конвеєрної лінії між кількома конвеєрними лініями. крім того, це дозволяє конвеєрним лініям зчитувати складніші дослідницькі дані з модулів даних.", + "gtceu.multiblock.data_bank.providing": "Надання даних.", + "gtceu.multiblock.dimension": "§eРозміри: §r%sx%sx%s", + "gtceu.multiblock.dimensions.0": "Розміри: ", + "gtceu.multiblock.dimensions.1": " §c§lШирина§r: %s, §a§lВисота§r: %s, §9§lГлибина§r: %s ", + "gtceu.multiblock.distillation_tower.description": "Дистиляційна вежа - це багатоблочна конструкція, яка використовується для перегонки різних типів нафти та деяких побічних продуктів. кожен шар повинен мати рівно один вивідний люк, починаючи з другого. Нижній шар може виводити предмети і вводити рідини в будь-якому положенні.", + "gtceu.multiblock.distillation_tower.distilling_fluid": "Дистиляція %s", + "gtceu.multiblock.electric_blast_furnace.description": "Електрична доменна піч (ЕДП) - це багатоблочна конструкція, яка використовується для витоплення сплавів, варіння металів і збагачення руд. Вона необхідна для отримання високоякісних сплавів і металів, таких як алюміній, нержавіюча сталь, титан і сплав наквади.", + "gtceu.multiblock.energy_consumption": "Вик. енергії: %s EU/т (%s)", + "gtceu.multiblock.exact_hatch_1.tooltip": "§fПриймає рівно§6 один§f енергетичний люк.", + "gtceu.multiblock.extreme_combustion_engine.description": "Екстремальний двигун внутрішнього згоряння - це багатоблочна конструкція, яка діє як генератор згоряння для IV живлення.", + "gtceu.multiblock.fluid_rig.drilled_fluid": "Рідина: %s", + "gtceu.multiblock.fluid_rig.fluid_amount": "Швидкість перекачування: %s", + "gtceu.multiblock.fluid_rig.no_fluid_in_area": "Немає поблизу.", + "gtceu.multiblock.fluid_rig.vein_depleted": "Поклада виснажена.", + "gtceu.multiblock.fluid_rig.vein_depletion": "Розмір поклади: %s", + "gtceu.multiblock.fusion_reactor.energy": "EU: %d / %d", + "gtceu.multiblock.fusion_reactor.heat": "Тепло: %d", + "gtceu.multiblock.generation_eu": "Виведення:§a %s EU/т", + "gtceu.multiblock.hpca.computation": "Надання: %s", + "gtceu.multiblock.hpca.description": "Високопродуктивний обчислювальний масив (ВОМ) - це багатоблочна конструкція, яка використовується для створення Обчислювальних робочих одиниць (ОРО/т) для складніших дослідницьких даних конвеєра. структура має гнучку область 3x3, яку можна заповнити компонентами ВОМ у будь-який спосіб. різні компоненти можуть забезпечувати різні обсяги обчислень, охолодження, а також витрати енергії, охолоджувальної рідини та виробництва тепла. при використанні з мостовим компонентом ВОМ може підключатися до мережевих комутаторів для об'єднання і маршрутизації обчислень від декількох джерел до одного або декількох пунктів призначення.", + "gtceu.multiblock.hpca.energy": "Живлення: %s / %s EU/т (%s)", + "gtceu.multiblock.hpca.error_damaged": "Пошкоджений компонент в структурі!", + "gtceu.multiblock.hpca.error_temperature": "Температура вище 100C, компоненти можуть бути пошкоджені!", + "gtceu.multiblock.hpca.hover_for_info": "Наведіть для подробиць", + "gtceu.multiblock.hpca.info_bridging_disabled": "Мостування вимкнено", + "gtceu.multiblock.hpca.info_bridging_enabled": "Мостування увімкнено", + "gtceu.multiblock.hpca.info_coolant_name": "ДП-охолоджуюча рідина", + "gtceu.multiblock.hpca.info_max_computation": "Макс. ОРО/т: %s", + "gtceu.multiblock.hpca.info_max_coolant_required": "Необхідна охолоджуюча рідина: %s", + "gtceu.multiblock.hpca.info_max_cooling_available": "Наявне охолодження: %s", + "gtceu.multiblock.hpca.info_max_cooling_demand": "Потреба в охолодженні: %s", + "gtceu.multiblock.hpca.temperature": "Температура: %s", + "gtceu.multiblock.hpca.warning_low_cooling": "- Недостатньо охолодження", + "gtceu.multiblock.hpca.warning_multiple_bridges": "- Багато мостів у структурі (не надає додаткових переваг)", + "gtceu.multiblock.hpca.warning_no_computation": "- Немає постачальників обчислень", + "gtceu.multiblock.hpca.warning_structure_header": "Попередження структури:", + "gtceu.multiblock.hpca.warning_temperature": "Температура вище 50C, компоненти можуть бути пошкоджені при 100C!", + "gtceu.multiblock.hpca.warning_temperature_active_cool": "Повне використання активних охолоджувачів", + "gtceu.multiblock.idling": "§6Очікування.", + "gtceu.multiblock.implosion_compressor.description": "Імплозійний компресор - це багатоблочна конструкція, яка використовує вибухівку для перетворення кристалічного пилу на відповідні кристали.", + "gtceu.multiblock.invalid_structure": "Неприпустима структура.", + "gtceu.multiblock.invalid_structure.tooltip": "Цей блок є контролером багатоблочної конструкції. Для отримання допомоги у створенні дивіться шаблон структури в JEI.", + "gtceu.multiblock.large_boiler.description": "Великі котли - це конструкції, які виробляють пару з джерела енергії та води. зазначеним джерелом енергії є будь-яке тверде паливо з певним часом горіння або дизельне/напіврідке паливо. Можна регулювати з кроком 5%% для зменшення виходу пари та споживання палива.", + "gtceu.multiblock.large_boiler.efficiency": "Ефективність: %s", + "gtceu.multiblock.large_boiler.explosion_tooltip": "Вибухне, якщо подати паливо без води", + "gtceu.multiblock.large_boiler.heat_time_tooltip": "§7Закипає за§f %d секунд", + "gtceu.multiblock.large_boiler.max_temperature": "Макс. температура: %dK, виробництво пари: %dмВ/т", + "gtceu.multiblock.large_boiler.rate_tooltip": "§7Виробляє§f %d л§7 пари за§f 1 вугілля", + "gtceu.multiblock.large_boiler.steam_output": "Вихід пари: %s мВ/т", + "gtceu.multiblock.large_boiler.temperature": "Температура: %sK / %sK", + "gtceu.multiblock.large_boiler.throttle": "Дросель: %d", + "gtceu.multiblock.large_boiler.throttle.tooltip": "Котел може виробляти менше пари й споживати менше палива (ефективність не втрачається, не впливає на час нагрівання)", + "gtceu.multiblock.large_boiler.throttle_modify": "Зміна дроселю:", + "gtceu.multiblock.large_chemical_reactor.description": "Великий хімічний реактор виконує хімічні реакції зі 100% енергоефективністю. розгін збільшує швидкість і енергію в 4 рази. конструкція вимагає рівно 1 блок мельхіорової котушки, який повинен бути розміщений поруч з корпусом ПТФЕ-труби, розташованим в центрі.", + "gtceu.multiblock.large_combustion_engine.boost_disallowed": "§bОновіть динамо-люк, щоб увімкнути кисневе пришвидшення.", + "gtceu.multiblock.large_combustion_engine.description": "Великий двигун внутрішнього згоряння - це багатоблочна конструкція, яка працює як генератор внутрішнього згоряння для EV живлення.", + "gtceu.multiblock.large_combustion_engine.liquid_oxygen_amount": "Кількість рідкого кисню: %sL", + "gtceu.multiblock.large_combustion_engine.liquid_oxygen_boosted": "§bПришвидшено рідким киснем.", + "gtceu.multiblock.large_combustion_engine.lubricant_amount": "Кількість мастила: %sL", + "gtceu.multiblock.large_combustion_engine.obstructed": "Повітрозабірники двигуна заблоковані.", + "gtceu.multiblock.large_combustion_engine.oxygen_amount": "Кількість кисню: %sL", + "gtceu.multiblock.large_combustion_engine.oxygen_boosted": "§bПришвидшено киснем.", + "gtceu.multiblock.large_combustion_engine.supply_liquid_oxygen_to_boost": "Подайте рідкий кисень для пришвидшення.", + "gtceu.multiblock.large_combustion_engine.supply_oxygen_to_boost": "Подайте кисень для пришвидшення.", + "gtceu.multiblock.large_miner.done": "Завершено!", + "gtceu.multiblock.large_miner.errorradius": "§cНеможливо змінити радіус під час роботи!", + "gtceu.multiblock.large_miner.invfull": "Вмістилище заповнено!", + "gtceu.multiblock.large_miner.needsfluid": "Потрібна бурильна рідина", + "gtceu.multiblock.large_miner.needspower": "Потрібне живлення!", + "gtceu.multiblock.large_miner.radius": "Радіус:§a %d§r блоків", + "gtceu.multiblock.large_miner.steam": "Потрібна пара!", + "gtceu.multiblock.large_miner.vent": "Вентиляція заблокована!", + "gtceu.multiblock.large_miner.working": "Опрацювання...", + "gtceu.multiblock.large_turbine.description": "Великі турбіни - це конструкції, які генерують енергію з пари, газів і плазми шляхом обертання ротора турбіни. Вихід енергії залежить від ефективності ротора та поточної швидкості турбіни. У центрі конструкції використовуються корпуси редукторів.", + "gtceu.multiblock.luv_fusion_reactor.description": "Термоядерний реактор MK 1 - це велика багатоблочна конструкція, яка використовується для злиття елементів у більш важкі. Він може використовувати лише LuV, ZPM та UV енергетичні люки. з кожним встановленим люком його буфер збільшується на 10 млн EU і може досягати 160 млн.", + "gtceu.multiblock.max_energy_per_tick": "Макс. EU/т:§a %s (%s§r)", + "gtceu.multiblock.max_energy_per_tick_amps": "Макс. EU/т: %s (%sA %s)", + "gtceu.multiblock.max_energy_per_tick_hover": "Максимальна кількість EU/т, доступна для запуску обробки або розгону", + "gtceu.multiblock.max_recipe_tier": "Макс. рівень обробки: %s", + "gtceu.multiblock.max_recipe_tier_hover": "Максимальний рівень обробки, який можна запускати", + "gtceu.multiblock.monitor_screen.tooltip.0": "Графічний інтерфейс можна відкрити клацанням ПКМ із викруткою.", + "gtceu.multiblock.monitor_screen.tooltip.1": "Проксі-режим цифрового інтерфейсу кришок може розподіляти можливості машини та графічного інтерфейсу. (Так, ви можете з'єднувати труби безпосередньо на екрані.)", + "gtceu.multiblock.monitor_screen.tooltip.2": "Екран також підтримує плагіни.", + "gtceu.multiblock.multi_furnace.description": "Мультиплавильна піч - це багатоблочна конструкція, яка використовується для витоплення великої кількості предметів одночасно. різні рівні котушок забезпечують підвищення швидкості та енергоефективності. 32 - це базове значення кількості предметів, що перетоплюються за одну операцію, і може бути збільшене шляхом використання котушок вищого рівня.", + "gtceu.multiblock.multi_furnace.heating_coil_discount": "Прискорення EU нагрівальною котушкою: %sx", + "gtceu.multiblock.multi_furnace.heating_coil_level": "Рівень нагрівальної котушки: %s", + "gtceu.multiblock.multiple_recipemaps.header": "Режим машини:", + "gtceu.multiblock.multiple_recipemaps.switch_message": "Для перемикання режимів машина повинна бути вимкнена!", + "gtceu.multiblock.multiple_recipemaps.tooltip": "Використовуйте викрутку на контролері, щоб змінити режим роботи машини.", + "gtceu.multiblock.multiple_recipemaps_recipes.tooltip": "Режими машини:§e %s§r", + "gtceu.multiblock.network_switch.description": "Мережевий комутатор - це багатоблочна конструкція, яка використовується для розподілу обчислень від багатьох джерел до багатьох пунктів призначення. Він може приймати будь-яку кількість люків приймання або передачі обчислювальних даних. Це необхідно для дослідницьких даних, які вимагають набагато більшого обсягу обчислень, оскільки дослідницька станція може прийняти лише один люк приймання обчислювальних даних. ВОМ повинні мати мостовий компонент, щоб мережевий комутатор міг отримати доступ до їхніх обчислень.", + "gtceu.multiblock.not_enough_energy": "ПОПЕРЕДЖЕННЯ: Машині потрібно більше енергії.", + "gtceu.multiblock.not_enough_energy_output": "ПОПЕРЕДЖЕННЯ: рівень енергетичного динамо занадто низький!", + "gtceu.multiblock.ore_rig.drilled_ore_entry": " - %s", + "gtceu.multiblock.ore_rig.drilled_ores_list": "Руди:", + "gtceu.multiblock.ore_rig.ore_amount": "Швидкість буріння: %s", + "gtceu.multiblock.output_line.0": "%s x§e %s§r (%sс/од)", + "gtceu.multiblock.output_line.1": "%s x§e %s§r (%s/с)", + "gtceu.multiblock.output_line.2": "%s ≈§e %s§r (%sс/од)", + "gtceu.multiblock.output_line.3": "%s ≈§e %s§r (%s/с)", + "gtceu.multiblock.page_switcher.io.both": "§5Комбіновані входи/виходи", + "gtceu.multiblock.page_switcher.io.export": "§4Виходи", + "gtceu.multiblock.page_switcher.io.import": "§2Входи", + "gtceu.multiblock.parallel": "Паралельне виконання до %d рецептів", + "gtceu.multiblock.parallel.exact": "Паралельне виконання %d рецептів", + "gtceu.multiblock.parallelizable.tooltip": "Може працювати паралельно за допомогою паралельних керуючих люків.", + "gtceu.multiblock.pattern.clear_amount_1": "§6Спереду має бути вільний простір 1х1х1§r", + "gtceu.multiblock.pattern.clear_amount_3": "§6Спереду має бути вільний простір 3x3x1§r", + "gtceu.multiblock.pattern.error": "Очікувалися компоненти (%s) у (%s).", + "gtceu.multiblock.pattern.error.batteries": "§cВсі батареї повинні бути однаковими§r", + "gtceu.multiblock.pattern.error.coils": "§cВсі нагрівальні котушки повинні бути однаковими§r", + "gtceu.multiblock.pattern.error.filters": "§cВсі фільтри повинні бути однаковими§r", + "gtceu.multiblock.pattern.error.limited.0": "§cМаксимум: %d§r", + "gtceu.multiblock.pattern.error.limited.1": "§cМаксимум: %d§r", + "gtceu.multiblock.pattern.error.limited.2": "§cМаксимум: %d за шар§r", + "gtceu.multiblock.pattern.error.limited.3": "§cМаксимум: %d за шар§r", + "gtceu.multiblock.pattern.error.limited_exact": "§cРівно: %d§r", + "gtceu.multiblock.pattern.error.limited_within": "§cМіж %d та %d§r", + "gtceu.multiblock.pattern.location_end": "§cТочно енд§r", + "gtceu.multiblock.pattern.replaceable_air": "Замінюється повітрям", + "gtceu.multiblock.pattern.single": "§6Можна використовувати тільки цей блок§r", + "gtceu.multiblock.power_substation.average_in": "§7Серед. Вхід: %s§7 EU/т", + "gtceu.multiblock.power_substation.average_in_hover": "Середній обсяг EU, вкладеної у внутрішній резерв енергії електропідстанції", + "gtceu.multiblock.power_substation.average_out": "§7Серед. Вихід: %s§7 EU/т", + "gtceu.multiblock.power_substation.average_out_hover": "Середній обсяг EU, виведеної з внутрішнього резерву енергії електропідстанції", + "gtceu.multiblock.power_substation.capacity": "§7Ємність: %s§7 EU", + "gtceu.multiblock.power_substation.passive_drain": "§7Пасивне розряджання: %s§7 EU/т", + "gtceu.multiblock.power_substation.stored": "§7Збережено: %s§7 EU", + "gtceu.multiblock.power_substation.time_days": "%s днів", + "gtceu.multiblock.power_substation.time_forever": "Вічно", + "gtceu.multiblock.power_substation.time_hours": "%s годин", + "gtceu.multiblock.power_substation.time_minutes": "%s хвилин", + "gtceu.multiblock.power_substation.time_seconds": "%s секунд", + "gtceu.multiblock.power_substation.time_to_drain": "§7Часу до розрядження: %s", + "gtceu.multiblock.power_substation.time_to_fill": "§7Часу до заповнення: %s", + "gtceu.multiblock.power_substation.time_years": "%s років", + "gtceu.multiblock.power_substation.under_one_hour_left": "Менше 1 години до повного розрядження!", + "gtceu.multiblock.preview.rotate": "Клацніть та перемістіть для обертання", + "gtceu.multiblock.preview.select": "Клацніть ПКМ, щоб перевірити кандидатів", + "gtceu.multiblock.preview.zoom": "Обертайте коліщатко або переміщуйте із затиснутою ПКМ, щоб масштабувати", + "gtceu.multiblock.primitive_blast_furnace.bronze.description": "Примітивна сталеливарня (ПС) - це багатоблочна конструкція, яка використовується для витоплення сталі на початку гри. Хоч і не дуже швидко, але вона забезпечить вас сталлю для перших установок.", + "gtceu.multiblock.primitive_water_pump.description": "Примітивна водяна помпа - це конструкція до-парової епохи, яка збирає воду раз на секунду, залежно від біома, в якому він знаходиться. Вона може використовувати вивідний люк помпи, ULV або LV, збільшуючи кількість води за рівень. розраховується за формулою: коефіцієнт біома * Множник люка.", + "gtceu.multiblock.primitive_water_pump.extra1.0": "Коефіцієнт біома:", + "gtceu.multiblock.primitive_water_pump.extra1.1": " Океан, річка: 1000 мВ/с", + "gtceu.multiblock.primitive_water_pump.extra1.2": " Болото: 800 мВ/с", + "gtceu.multiblock.primitive_water_pump.extra1.3": " джунглі: 350 мВ/с", + "gtceu.multiblock.primitive_water_pump.extra1.4": " сніга: 300 мВ/с", + "gtceu.multiblock.primitive_water_pump.extra1.5": " рівнини, ліс: 250 мВ/с", + "gtceu.multiblock.primitive_water_pump.extra1.6": " тайга: 175 мВ/с", + "gtceu.multiblock.primitive_water_pump.extra1.7": " пляж: 170 мВ/с", + "gtceu.multiblock.primitive_water_pump.extra1.8": " Інші: 100 мВ/с", + "gtceu.multiblock.primitive_water_pump.extra2.0": "Множники люків:", + "gtceu.multiblock.primitive_water_pump.extra2.1": " Люк помпи: 1x", + "gtceu.multiblock.primitive_water_pump.extra2.2": " ULV вивідний люк: 2x", + "gtceu.multiblock.primitive_water_pump.extra2.3": " LV вивідний люк: 4x", + "gtceu.multiblock.primitive_water_pump.extra2.4": "", + "gtceu.multiblock.primitive_water_pump.extra2.5": "Під час дощу в біомі викачування загальне виробництво води збільшиться на 50%%.", + "gtceu.multiblock.progress": "Прогрес: %ss / %ss (%s%%)", + "gtceu.multiblock.progress_percent": "Прогрес: %s%%", + "gtceu.multiblock.pyrolyse_oven.description": "Піролізна піч - це багатоблочна конструкція, яка використовується для перетворення колод на деревне вугілля та креозотову олію, або попіл та важку нафту.", + "gtceu.multiblock.pyrolyse_oven.speed": "Швидкість обробки: %s%%", + "gtceu.multiblock.require_steam_parts": "Потрібні парові люки та шини!", + "gtceu.multiblock.research_station.description": "Дослідницька станція - це багатоблочна конструкція, яка використовується для дослідження набагато складніших дослідницьких даних конвеєрної лінії. Будь-яке дослідження, що вимагає сфери даних або модуля даних, має бути відскановане в дослідницькій станції. Для дослідження рецептів потрібні обчислювальні робочі одиниці (ОРО/т), які надаються високопродуктивними обчислювальними масивами (ВОМ).", + "gtceu.multiblock.research_station.researching": "§6Дослідження.", + "gtceu.multiblock.running": "Працює бездоганно.", + "gtceu.multiblock.steam.duration_modifier": "Забирає§f 1.5x§7 базової тривалості обробки, не залежить від кількості предметів.", + "gtceu.multiblock.steam.low_steam": "Недостатньо пари для роботи!", + "gtceu.multiblock.steam.steam_stored": "Пара: %s / %s mb", + "gtceu.multiblock.steam_grinder.description": "Багатоблочний подрібнювач парової епохи. Для формування потребує щонайменше 14 бронзових корпусів. Не може використовувати звичайні вхідні/вихідні шини, а також рідинні люки, окрім парового.", + "gtceu.multiblock.steam_oven.description": "Мультиплавильна піч парової епохи. Для формування потрібно щонайменше 6 бронзових корпусів. Не можна використовувати звичайні вхідні/вихідні шини, а також рідинні люки, окрім парового. паровий люк повинен бути на нижньому шарі, не більше одного.", + "gtceu.multiblock.subtick_parallels": "- %dx для розгону", + "gtceu.multiblock.title": "Шаблон конструкції", + "gtceu.multiblock.total_runs": "Виконання %d рецептів одночасно", + "gtceu.multiblock.turbine.efficiency": "Ефективність турбіни: %s%%", + "gtceu.multiblock.turbine.efficiency_tooltip": "Кожен тримач ротора вище %s§7 додає§f 10%% ефективності і множить EU/т на 2§7.", + "gtceu.multiblock.turbine.energy_per_tick": "Вихід енергії: %s/%s EU/т", + "gtceu.multiblock.turbine.energy_per_tick_maxed": "Вихід енергії: %s EU/т", + "gtceu.multiblock.turbine.fuel_amount": "Кількість палива: %sL (%s)", + "gtceu.multiblock.turbine.fuel_needed": "Споживає %s за %s тактів", + "gtceu.multiblock.turbine.obstructed": "Перешкода на шляху турбіни", + "gtceu.multiblock.turbine.rotor_durability": "Міцність ротора: %s%%", + "gtceu.multiblock.turbine.rotor_speed": "Швидкість ротора: %s/%s RPM", + "gtceu.multiblock.universal.distinct": "Відокремленні шини:", + "gtceu.multiblock.universal.distinct.info": "Якщо увімкнено, кожна вхідна предметна шина буде розглядатися як повністю відмінна одна від одної для пошуку рецептів. корисно для таких речей, як програмні плати, формові відтиски тощо.", + "gtceu.multiblock.universal.distinct.no": "Ні", + "gtceu.multiblock.universal.distinct.yes": "Так", + "gtceu.multiblock.universal.has_problems": "Наявні проблеми з технічним обслуговуванням!", + "gtceu.multiblock.universal.has_problems_header": "Виправте наведені нижче проблеми в люку технічного обслуговування:", + "gtceu.multiblock.universal.muffler_obstructed": "Люк вихлопу перекрито!", + "gtceu.multiblock.universal.muffler_obstructed.tooltip": "Люк вихлопу повинен мати блок повітряного простору перед собою.", + "gtceu.multiblock.universal.no_problems": "Немає проблем з технічним обслуговуванням!", + "gtceu.multiblock.universal.problem.crowbar": "%s§7Цьому тут не місце. (§aЛом§7)", + "gtceu.multiblock.universal.problem.hard_hammer": "%s§7Покриття має вм'ятини. (§aМолот§7)", + "gtceu.multiblock.universal.problem.screwdriver": "%s§7Гвинти розхитані. (§aВикрутка§7)", + "gtceu.multiblock.universal.problem.soft_mallet": "%s§7Щось заклинило. (§aКиянка§7)", + "gtceu.multiblock.universal.problem.wire_cutter": "%s§7Дроти перегоріли. (§aКусачки§7)", + "gtceu.multiblock.universal.problem.wrench": "%s§7Труба відійшла. (§aКлюч§7)", + "gtceu.multiblock.universal.rotor_obstructed": "Ротор заблоковано!", + "gtceu.multiblock.uv_fusion_reactor.description": "Термоядерний реактор MK 3 - це велика багатоблочна конструкція, яка використовується для злиття елементів у більш важкі. Він може використовувати лише UV енергетичні люки. з кожним встановленим люком його буфер збільшується на 40 млн EU і може досягати 640 млн.", + "gtceu.multiblock.vacuum_freezer.description": "Вакуумна морозильна камера - це багатоблочна конструкція, яка в основному використовується для охолодження розпечених злитків у звичайні. Однак вона також може заморожувати інші речовини, такі як вода.", + "gtceu.multiblock.validation_failed": "Неправильна кількість входів/виходів.", + "gtceu.multiblock.waiting": "ПОПЕРЕДЖЕННЯ: Машина очікує.", + "gtceu.multiblock.work_paused": "Робота зупинена.", + "gtceu.multiblock.zpm_fusion_reactor.description": "Термоядерний реактор MK 2 - це велика багатоблочна конструкція, яка використовується для злиття елементів у більш важкі. Він може використовувати лише ZPM та UV енергетичні люки. з кожним встановленим люком його буфер збільшується на 20 млн EU і може досягати 320 млн.", + "gtceu.oc.tooltip.0": "Мінімум: %s", + "gtceu.oc.tooltip.1": "ЛКМ, щоб збільшити розгін", + "gtceu.oc.tooltip.2": "ПКМ, щоб зменшити розгін", + "gtceu.oc.tooltip.3": "СКМ, щоб скинути розгін", + "gtceu.oc.tooltip.4": "Утримуйте Shift, щоб змінювати ідеальний розгін", + "gtceu.ore_washer": "Рудопромивач", + "gtceu.ownership.name.argonauts": "Гільдія Аргонавтів", + "gtceu.ownership.name.ftb": "FTB Teams", + "gtceu.ownership.name.player": "Гравець", + "gtceu.packer": "Пакувальник", + "gtceu.part_sharing.disabled": "Спільний доступ конструкції§4 вимкнено", + "gtceu.part_sharing.enabled": "Спільний доступ конструкції§a увімкнено", + "gtceu.placeholder_info.active.0": "Повертає 1, якщо блок, до якого прикріплена кришка, в даний момент виконує рецепт, інакше повертає 0.", + "gtceu.placeholder_info.active.1": "Використання:", + "gtceu.placeholder_info.active.2": " {active} -> чи є рецепт, який зараз виконується", + "gtceu.placeholder_info.ae2crafting.0": "Повертає інформацію про автоматичне створення в мережі ME блоку, на якому знаходиться ця кришка.", + "gtceu.placeholder_info.ae2crafting.1": "Використання:", + "gtceu.placeholder_info.ae2crafting.10": " {ae2crafting get time} -> кількість часу, що минула з моменту запуску програми (в наносекундах), або 0, якщо процесор не працює", + "gtceu.placeholder_info.ae2crafting.2": " {ae2crafting get amount} -> кількість процесорів створення у мережі ME", + "gtceu.placeholder_info.ae2crafting.3": " {ae2crafting get storage} -> обсяг пам'яті створення, що має вказаний процесор", + "gtceu.placeholder_info.ae2crafting.4": " {ae2crafting get threads} -> співпроцесорів, що має вказаний процесор", + "gtceu.placeholder_info.ae2crafting.5": " {ae2crafting get name} -> назва вказаного процесора створення", + "gtceu.placeholder_info.ae2crafting.6": " {ae2crafting get selectionMode} -> режим вибору зазначеного процесора для виготовлення (використовується для ручних, автоматичних або обох типів запитів)", + "gtceu.placeholder_info.ae2crafting.7": " {ae2crafting get amount} -> кількість запитуваного предмета або 0, якщо процесор не виконує задач", + "gtceu.placeholder_info.ae2crafting.8": " {ae2crafting get item} -> відображуване ім'я запитуваного предмета або 0, якщо процесор не виконує задач", + "gtceu.placeholder_info.ae2crafting.9": " {ae2crafting get progress} -> прогрес виконання створення або 0, якщо процесор не виконує задач", + "gtceu.placeholder_info.ae2energy.0": "Повертає енергію, яка наразі зберігається в мережі ME блоку, на якому знаходиться ця кришка.", + "gtceu.placeholder_info.ae2energy.1": "Використання:", + "gtceu.placeholder_info.ae2energy.2": " {ae2energy} -> енергія в мережі ME (в одиницях AE)", + "gtceu.placeholder_info.ae2fluidCount.0": "Те саме, що fluidCount, але підраховує предмети в мережі ME блоку, до якого приєднано цю кришку.", + "gtceu.placeholder_info.ae2fluidCount.1": "Зверніть увагу, що підрахунок усіх рідин може спричинити затримку!", + "gtceu.placeholder_info.ae2fluidCount.2": "Використання:", + "gtceu.placeholder_info.ae2fluidCount.3": " {fluidCount [fluidId]} -> кількість усіх рідин або рідини з fluidId, якщо зазначено", + "gtceu.placeholder_info.ae2itemCount.0": "Те саме, що itemCount, але підраховує предмети в мережі ME блоку, до якого приєднано цю кришку.", + "gtceu.placeholder_info.ae2itemCount.1": "Зауважте, що підрахунок за фільтром або всіма предметами може спричинити затримку!", + "gtceu.placeholder_info.ae2itemCount.2": "Використання:", + "gtceu.placeholder_info.ae2itemCount.3": " {itemCount} -> загальна кількість предметів", + "gtceu.placeholder_info.ae2itemCount.4": " {itemCount } -> кількість предметів з ідентифікаторами, що дорівнюють item_id", + "gtceu.placeholder_info.ae2itemCount.5": " {itemCount filter } -> кількість предметів, що відповідають фільтру, у вказаному слоті цієї кришки", + "gtceu.placeholder_info.ae2maxPower.0": "Повертає енергетичну ємність мережі МЕ блоку, на якому ця кришка включена.", + "gtceu.placeholder_info.ae2maxPower.1": "Використання:", + "gtceu.placeholder_info.ae2maxPower.2": " {ae2maxPower} -> енергетична потужність мережі МЕ", + "gtceu.placeholder_info.ae2powerUsage.0": "Повертає енергоспоживання мережі МЕ блоку, на якому ця кришка включена.", + "gtceu.placeholder_info.ae2powerUsage.1": "Використання:", + "gtceu.placeholder_info.ae2powerUsage.2": " {ae2powerUsage} -> енергоспоживання мережі МЕ", + "gtceu.placeholder_info.ae2spatial.0": "Повертає інформацію про просторовий ввід/вивід у мережі МЕ блоку, до якого приєднано цю кришку.", + "gtceu.placeholder_info.ae2spatial.1": "Використання:", + "gtceu.placeholder_info.ae2spatial.2": " {ae2spatial power} -> обсяг потужності, необхідний для ініціювання просторового вводу/виводу", + "gtceu.placeholder_info.ae2spatial.3": " {ae2spatial efficiency} -> ефективність структури просторового утримання (SPS)", + "gtceu.placeholder_info.ae2spatial.4": " {ae2spatial size} -> розмір СПС по вказаній осі (приклад: 'Розмір: {sizeX}x{sizeY}x{sizeZ}')", + "gtceu.placeholder_info.amperage.0": "Повертає силу струму в дроті/кабелі, на якому ввімкнена кришка.", + "gtceu.placeholder_info.amperage.1": "Використання:", + "gtceu.placeholder_info.amperage.2": " {amperage} -> ампераж у дроті/кабелі", + "gtceu.placeholder_info.bf.0": "Використання:", + "gtceu.placeholder_info.bf.1": " {bf } -> порожній рядок", + "gtceu.placeholder_info.block.0": "Повертає символ блоку (█).", + "gtceu.placeholder_info.block.1": "Використання:", + "gtceu.placeholder_info.block.2": " {block} -> '█'", + "gtceu.placeholder_info.calc.0": "Повертає результат математичної функції або операції.", + "gtceu.placeholder_info.calc.1": "Використання:", + "gtceu.placeholder_info.calc.2": " {calc } -> any_string", + "gtceu.placeholder_info.calc.3": " {calc } -> результат зазначеної операції", + "gtceu.placeholder_info.calc.4": " {calc <+|-|*|/|//|>>|<<|%> } -> результат зазначеної операції", + "gtceu.placeholder_info.click.0": "Повертає значення, коли вибраний вдосконалений монітор було клацнуто перед поточним тактом", + "gtceu.placeholder_info.click.1": "Використання:", + "gtceu.placeholder_info.click.2": " {click} -> \"1\" якщо вибраний вдосконалений монітор клацнуто, в іншому випадку \"0\"", + "gtceu.placeholder_info.click.3": " {click x} -> позиція x останнього клацання (між 0 та 1)", + "gtceu.placeholder_info.click.4": " {click y} -> позиція y останнього клацання (між 0 та 1)", + "gtceu.placeholder_info.cmd.0": "Виконує команди Minecraft і повертає їх резульатат.", + "gtceu.placeholder_info.cmd.1": "Потрібен предмет даних, прив’язаний до гравця, прив’яжіть будь-який предмет даних до себе, клацнувши ним ПКМ.", + "gtceu.placeholder_info.cmd.2": "Використання:", + "gtceu.placeholder_info.cmd.3": " {cmd } -> командний вивід", + "gtceu.placeholder_info.cmp.0": "Повертає 1 або 0 на основі виразу в його аргументах", + "gtceu.placeholder_info.cmp.1": "Використання:", + "gtceu.placeholder_info.cmp.2": " {cmp } -> 1 або 0, оператор є одним із >, <, >=, <=, ==, !=", + "gtceu.placeholder_info.color.0": "Повертає текст з другого аргументу, розфарбований кольором з першого аргументу. Можна використовувати всі типові кольори чату minecraft.", + "gtceu.placeholder_info.color.1": "Використання:", + "gtceu.placeholder_info.color.2": " {color } -> кольоровий текст", + "gtceu.placeholder_info.combine.0": "Об’єднує всі свої аргументи в один рядок (шляхом екранування всіх пробілів між аргументами)", + "gtceu.placeholder_info.combine.1": "Приклад: {combine abc def ghi jkl mno} -> \"abc\\ def\\ ghi\\ jkl\\ mno\"", + "gtceu.placeholder_info.combine.2": "Використання:", + "gtceu.placeholder_info.combine.3": " {combine [arg1] [arg2] [arg3] ...} -> рядок, який розглядатиметься як єдиний аргумент у додаткових заповнювачах", + "gtceu.placeholder_info.count.0": "Повертає, скільки з наданих аргументів дорівнюють першому (порівняно як рядки, отже \"0\" != \"0, 0\")", + "gtceu.placeholder_info.count.1": "Використання:", + "gtceu.placeholder_info.count.2": " {count [arg2] [arg3] [arg4] ...} -> кількість аргументів, які дорівнюють першим", + "gtceu.placeholder_info.data.0": "Зберігає або отримує деякі дані з предмета даних (паличка даних/орб/модуль) в одному з слотів.", + "gtceu.placeholder_info.data.1": "Якщо залишити аргумент порожнім, його буде замінено значенням p (p - ціле число від 0 до (ємність - 1), яке зберігається в предметі даних nbt).", + "gtceu.placeholder_info.data.2": "Використання:", + "gtceu.placeholder_info.data.3": " {data get } -> дані, що зберігаються в предметі у вказаному слоті", + "gtceu.placeholder_info.data.4": " {data set } -> встановлює дані, що зберігаються в предметі у вказаному слоті, повертає порожній рядок", + "gtceu.placeholder_info.data.5": " {data getп } -> p", + "gtceu.placeholder_info.data.6": " {data setp } -> встановлює p, повертає порожній рядок", + "gtceu.placeholder_info.data.7": " {data inc } -> збільшує p на 1, якщо p стає більше або дорівнює ємності, встановлює p на 0", + "gtceu.placeholder_info.data.8": " {data dec } -> декрементує p на 1, якщо p стає менше 0, встановлює p на (ємність - 1)", + "gtceu.placeholder_info.displayTarget.0": "Повертає вказаний рядок, який було передано на цю кришку за допомогою посилання відображення.", + "gtceu.placeholder_info.displayTarget.1": "Використання:", + "gtceu.placeholder_info.displayTarget.2": " {displayTarget } -> текст на вказаному рядку (номер рядка 1-100)", + "gtceu.placeholder_info.ender.0": "Взаємодіє з кришками зв'язку Енду", + "gtceu.placeholder_info.ender.1": "Може взаємодіяти з приватними каналами, якщо йому надано предмет даних, прив’язаний до гравця", + "gtceu.placeholder_info.ender.10": "Аргумент player_data_item_slot може залишатися порожнім (не 0, а порожній рядок)", + "gtceu.placeholder_info.ender.2": "Використання:", + "gtceu.placeholder_info.ender.3": " {ender item [player_data_item_slot]} -> кількість предметів", + "gtceu.placeholder_info.ender.4": " {ender itemPull [player_data_item_slot]} -> витягнути 1 предмет з буфера зв'язку Енду", + "gtceu.placeholder_info.ender.5": " {ender itemPush [player_data_item_slot]} -> надіслати 1 предмет до буфера зв'язку Енду", + "gtceu.placeholder_info.ender.6": " {ender itemId [player_data_item_slot]} -> ID предмета у буфері зв'язку Ендузв'язку Енду (у вигляді \"26 minecraft:dirt\")", + "gtceu.placeholder_info.ender.7": " {ender fluid [player_data_item_slot]} -> обсяг рідини", + "gtceu.placeholder_info.ender.8": " {ender redstone [player_data_item_slot] -> рівень редстоунового сигналу", + "gtceu.placeholder_info.ender.9": " {ender redstone -> надсилає визначений рівень редстоунового сигналу до редстоунового зв'язку Енду, повертає порожній рядок", + "gtceu.placeholder_info.energy.0": "Повертає кількість накопиченої енергії.", + "gtceu.placeholder_info.energy.1": "Використання:", + "gtceu.placeholder_info.energy.2": " {energy} -> кількість енергії, що зберігається", + "gtceu.placeholder_info.energyCapacity.0": "Повертає максимальну кількість енергії, яку можна зберегти", + "gtceu.placeholder_info.energyCapacity.1": "Використання:", + "gtceu.placeholder_info.energyCapacity.2": "{energyCapacity} -> енергетична ємність", + "gtceu.placeholder_info.eval.0": "Повертає результат оцінки наданого рядка, який може містити заповнювачі", + "gtceu.placeholder_info.eval.1": "Використання:", + "gtceu.placeholder_info.eval.2": " {eval abcdefg} -> abcdefg", + "gtceu.placeholder_info.eval.3": " {eval \"повторювання a: {repeat 5 \\\"a \\\"}\" -> повторювання a: a a a a a ", + "gtceu.placeholder_info.eval.4": " {eval \\\"\"{вставте текст}\"\\\" -> {вставте текст}", + "gtceu.placeholder_info.eval.5": " {eval \"текст \"\\\"\"{щось із пробілами}\"\\\"\" додатковий текст\" -> текст {щось із пробілами} додатковий текст", + "gtceu.placeholder_info.fluidCount.0": "Повертає кількість рідин (можна відфільтрувати).", + "gtceu.placeholder_info.fluidCount.1": "Використання:", + "gtceu.placeholder_info.fluidCount.2": " {fluidCount [fluidId]} -> кількість усіх рідин або рідини з fluidId, якщо зазначено", + "gtceu.placeholder_info.formatInt.0": "Повертає рядкове представлення наданого цілого числа", + "gtceu.placeholder_info.formatInt.1": "Приклад: {formatInt 1236457} -> 1, 24 М", + "gtceu.placeholder_info.formatInt.2": "Використання:", + "gtceu.placeholder_info.formatInt.3": " {formatInt } -> рядкове представлення int", + "gtceu.placeholder_info.fromAscii.0": "Повертає символ, представлений наданим кодом ASCII", + "gtceu.placeholder_info.fromAscii.1": "Використання:", + "gtceu.placeholder_info.fromAscii.2": " {fromAscii } -> символ", + "gtceu.placeholder_info.if.0": "Повертає один з аргументів залежно від умови. Умова вважається істинною, якщо вона не є порожнім рядком і не дорівнює 0.", + "gtceu.placeholder_info.if.1": "Використання:", + "gtceu.placeholder_info.if.2": " {if [returned_if_false]}", + "gtceu.placeholder_info.itemCount.0": "Повертає кількість предметів (можна фільтрувати).", + "gtceu.placeholder_info.itemCount.1": "Використання:", + "gtceu.placeholder_info.itemCount.2": " {itemCount} -> загальна кількість предметів", + "gtceu.placeholder_info.itemCount.3": " {itemCount } -> кількість предметів з ідентифікаторами, що дорівнюють item_id", + "gtceu.placeholder_info.itemCount.4": " {itemCount filter } -> кількість предметів, що відповідають фільтру, у вказаному слоті цієї кришки", + "gtceu.placeholder_info.maintenance.0": "Повертає a 1, якщо є проблеми з обслуговуванням у блоці, до якого прикріплена кришка, 0 в іншому випадку.", + "gtceu.placeholder_info.maintenance.1": "Приклад: 'Стан обслуговування: {if {maintenance} FIXING\\ REQUIRED OK}'", + "gtceu.placeholder_info.maintenance.2": "Використання:", + "gtceu.placeholder_info.maintenance.3": " {maintenance} -> чи є проблеми з обслуговуванням", + "gtceu.placeholder_info.maxProgress.0": "Повертає максимальний прогрес поточного поточного рецепта блоку, до якого додається ця кришка.", + "gtceu.placeholder_info.maxProgress.1": "Приклад: 'Прогрес: {calc {calc {progress} / {maxProgress}} * 100}%'", + "gtceu.placeholder_info.maxProgress.2": "Використання:", + "gtceu.placeholder_info.maxProgress.3": " {maxProgress} -> максимальний прогрес поточного рецепта", + "gtceu.placeholder_info.nbt.0": "Повертає дані nbt предмета у вказаному слоті", + "gtceu.placeholder_info.nbt.1": "Використання:", + "gtceu.placeholder_info.nbt.2": " {nbt [key1] [key2] [key3] ...} -> item_nbt[key1][key2][key3][...]", + "gtceu.placeholder_info.obf.0": "Повертає текст з першого аргументу, заплутаний.", + "gtceu.placeholder_info.obf.1": "Використання:", + "gtceu.placeholder_info.obf.2": " {obf } -> заплутаний текст", + "gtceu.placeholder_info.previousText.0": "Повертає текст, який раніше відображався цією кришкою у вказаному рядку (перед обгортанням рядка).", + "gtceu.placeholder_info.previousText.1": "Використання:", + "gtceu.placeholder_info.previousText.2": " {previousText } -> текст, який раніше відображався у вказаному рядку (індекс починається з 1)", + "gtceu.placeholder_info.progress.0": "Повертає хід поточного поточного рецепту блоку, до якого додається ця кришка.", + "gtceu.placeholder_info.progress.1": "Зверніть увагу, що прогрес є цілим числом між 0 і {maxProgress}", + "gtceu.placeholder_info.progress.2": "Використання:", + "gtceu.placeholder_info.progress.3": " {progress} -> хід поточного рецепту", + "gtceu.placeholder_info.random.0": "Повертає випадкове число у вказаному інтервалі (включно).", + "gtceu.placeholder_info.random.1": "Використання:", + "gtceu.placeholder_info.random.2": " {random } -> випадкове число між min і max (включно)", + "gtceu.placeholder_info.redstone.0": "Повертає потужність сигналу червоного каменю або встановлює вихідну потужність червоного каменю", + "gtceu.placeholder_info.redstone.1": "Використання:", + "gtceu.placeholder_info.redstone.2": " {redstone get } -> потужність сигналу Redstone (0-15) на вказаній стороні", + "gtceu.placeholder_info.redstone.3": " {redstone get link } -> потужність сигналу Redstone частоти зв'язку Create redstone, заданої зв'язаним контролером у слоті #slot_index. freq_slot_index, є індексом частоти всередині контролера (зліва направо, 0-6)", + "gtceu.placeholder_info.redstone.4": " {redstone set } -> порожній рядок встановлює вихідну силу червоного каменю з боку цієї кришки", + "gtceu.placeholder_info.redstone.5": " {redstone set link } -> порожній рядок, транслює вказану потужність redstone на вказаній частоті посилання Create redstone", + "gtceu.placeholder_info.repeat.0": "Повертає текст з других аргументів, повторює кількість разів, вказаних у першому аргументі.", + "gtceu.placeholder_info.repeat.1": "Використання:", + "gtceu.placeholder_info.repeat.2": " {repeat } -> текст повторював вказану кількість разів", + "gtceu.placeholder_info.select.0": "Повертає аргумент за вказаним індексом (починаючи з 0)", + "gtceu.placeholder_info.select.1": "Використання:", + "gtceu.placeholder_info.select.2": " {select [arg1] [arg2] [arg3] ... -> аргумент при вказаному індексі", + "gtceu.placeholder_info.strike.0": "Повертає текст з першого тексту, відображаючи його так, ніби він був закреслений", + "gtceu.placeholder_info.strike.1": "Використання:", + "gtceu.placeholder_info.strike.2": " {strike } -> перекреслений текст", + "gtceu.placeholder_info.subList.0": "Повертає аргументи з з індексами від l (включно) до r (виключно) (починаючи з 0)", + "gtceu.placeholder_info.subList.1": "Використання:", + "gtceu.placeholder_info.subList.2": " {subList [arg0] [arg1] ...} -> всі аргументи з індексами від l до r, розділеними пробілами", + "gtceu.placeholder_info.tick.0": "Повертає кількість кліщів, що пройшли з моменту розміщення цієї кришки.", + "gtceu.placeholder_info.tick.1": "Використання:", + "gtceu.placeholder_info.tick.2": " {tick} -> кількість кліщів", + "gtceu.placeholder_info.tm.0": "Повертає символ ™", + "gtceu.placeholder_info.tm.1": "Використання:", + "gtceu.placeholder_info.tm.2": " {tm} -> символ ™", + "gtceu.placeholder_info.toAscii.0": "Повертає код ASCII наданого символу", + "gtceu.placeholder_info.toAscii.1": "Використання:", + "gtceu.placeholder_info.toAscii.2": " {toAscii } -> ASCII код символу", + "gtceu.placeholder_info.toChars.0": "Повертає символи наданого рядка з пробілами між ними", + "gtceu.placeholder_info.toChars.1": "Приклад: {toChars example} -> 'e x a m p l e'", + "gtceu.placeholder_info.toChars.2": "Використання:", + "gtceu.placeholder_info.toChars.3": " {toChars } -> персонажі", + "gtceu.placeholder_info.underline.0": "Повертає текст з першого аргументу, підкреслений", + "gtceu.placeholder_info.underline.1": "Використання:", + "gtceu.placeholder_info.underline.2": " {underline } -> підкреслений текст", + "gtceu.placeholder_info.voltage.0": "Повертає напругу в дроті/кабелі, на якому ввімкнена кришка.", + "gtceu.placeholder_info.voltage.1": "Використання:", + "gtceu.placeholder_info.voltage.2": " {voltage} -> напруга в дроті/кабелі", + "gtceu.plasma_generator": "Плазмовий генератор", + "gtceu.polarizer": "Намагнічувач", + "gtceu.primitive_blast_furnace": "Примітивна сталеливарня", + "gtceu.pyrolyse_oven": "Піролізна піч", + "gtceu.recipe.byproduct_tier": "Побічні продукти з %s§r+", + "gtceu.recipe.category.arc_furnace_recycling": "Дугова переробка", + "gtceu.recipe.category.chem_dyes": "Хімічне розфарбовування", + "gtceu.recipe.category.extractor_recycling": "Переливання металолому", + "gtceu.recipe.category.ingot_molding": "Лиття металів", + "gtceu.recipe.category.macerator_recycling": "Переробка", + "gtceu.recipe.category.ore_bathing": "Рудообробка", + "gtceu.recipe.category.ore_crushing": "Подрібнення руд", + "gtceu.recipe.category.ore_forging": "Дроблення руд", + "gtceu.recipe.chance": "Шанс: %s +%s/рівень", + "gtceu.recipe.cleanroom": "Потребує %s", + "gtceu.recipe.cleanroom.display_name": "Чиста кімната", + "gtceu.recipe.cleanroom_sterile.display_name": "Стерильна чиста кімната", + "gtceu.recipe.coil.tier": "Котушка: %s", + "gtceu.recipe.computation_per_tick": "Мін. обчислень: %s ОРО/т", + "gtceu.recipe.dimensions": "Виміри: %s", + "gtceu.recipe.duration": "Тривалість: %s секунд", + "gtceu.recipe.environmental_hazard": "§cВ області повинно бути: %s", + "gtceu.recipe.environmental_hazard.reverse": "§cОбласть повинна бути захищена від: %s", + "gtceu.recipe.eu": "Споживання: %s A @ %s", + "gtceu.recipe.eu.total": "%s EU/т", + "gtceu.recipe.eu_inverted": "Генерування: %s EU/т", + "gtceu.recipe.eu_to_start": "Стартове EU: %sEU%s", + "gtceu.recipe.explosive": "Вибухова речовина: %s", + "gtceu.recipe.max_eu": "Макс. EU: %s EU", + "gtceu.recipe.not_consumed": "Не витрачається в процесі роботи", + "gtceu.recipe.research": "Потребує дослідження", + "gtceu.recipe.scan_for_research": "Сканування для конвеєрної лінії", + "gtceu.recipe.temperature": "Температура: %sK", + "gtceu.recipe.total": "Загалом: %s EU", + "gtceu.recipe.total_computation": "Обчислення: %s ОРО", + "gtceu.recipe.total_eu": "Загальне споживання: %s EU/т", + "gtceu.recipe.voltage": "Споживання: %s A @ %s", + "gtceu.recipe_logic.condition_fails": "Умова не виконана", + "gtceu.recipe_logic.insufficient_fuel": "Недостатньо палива", + "gtceu.recipe_logic.insufficient_in": "Недостатньо входів", + "gtceu.recipe_logic.insufficient_out": "Недостатньо виходів", + "gtceu.recipe_logic.no_capabilities": "Машина не має відповідних можливостей", + "gtceu.recipe_logic.no_contents": "Рецепт не має змісту", + "gtceu.recipe_memory_widget.tooltip.0": "§7Клацніть ЛКМ, щоб автоматично внести цей рецепт до сітки виготовлення", + "gtceu.recipe_memory_widget.tooltip.1": "§7Клацайте із затиснутим Shift, щоб заблокувати/розблокувати цей рецепт", + "gtceu.recipe_type.show_recipes": "Показати рецепти", + "gtceu.rei.group.potion_fluids": "Рідини зіллів", + "gtceu.research_station": "Дослідницька станція", + "gtceu.rock_breaker": "Кам'яна дробарка", + "gtceu.scanner": "Сканер", + "gtceu.scanner.copy_stick_empty": "§oПорожня картка", + "gtceu.scanner.copy_stick_from": "§oКопіювання до картки", + "gtceu.scanner.copy_stick_to": "§oВставка з картки", + "gtceu.sifter": "Просіювач", + "gtceu.steam_boiler": "Паровий котел", + "gtceu.steam_turbine": "Парова турбіна", + "gtceu.subtitle.arc": "Дуги дзижчать", + "gtceu.subtitle.assembler": "Збирач конструює", + "gtceu.subtitle.bath": "Ванна шипить", + "gtceu.subtitle.boiler": "Котел гріється", + "gtceu.subtitle.centrifuge": "Центрифуга обертається", + "gtceu.subtitle.chainsaw": "Пила гуде", + "gtceu.subtitle.chemical": "Хімікати булькають", + "gtceu.subtitle.combustion": "Горіння", + "gtceu.subtitle.compressor": "Компресор віджимає", + "gtceu.subtitle.computation": "Комп'ютер тугодумає", + "gtceu.subtitle.cooling": "Морозильник гуде", + "gtceu.subtitle.cut": "Різак дзижчить", + "gtceu.subtitle.drill": "Свердління", + "gtceu.subtitle.electrolyzer": "Електролізер іскрить", + "gtceu.subtitle.file": "Скрегіт напилка", + "gtceu.subtitle.fire": "Потріскування вогню", + "gtceu.subtitle.forge_hammer": "Ковальський молот стукає", + "gtceu.subtitle.furnace": "Піч гріється", + "gtceu.subtitle.jet_engine": "Реактивне ревіння", + "gtceu.subtitle.macerator": "Подрібнювач дробить", + "gtceu.subtitle.metal_pipe": "Руйнування_металевого_стовпа_L_Хвилею_2_0_0.wav", + "gtceu.subtitle.miner": "Бур видобуває", + "gtceu.subtitle.mixer": "Змішувач міксує", + "gtceu.subtitle.mortar": "Ступка подрібнює", + "gtceu.subtitle.motor": "Двигун гуде", + "gtceu.subtitle.plunger": "Вантуз хлопає", + "gtceu.subtitle.portable_scanner": "Сканування", + "gtceu.subtitle.portal_closing": "Портал закривається", + "gtceu.subtitle.portal_opening": "Портал відкривається", + "gtceu.subtitle.replicator": "Реплікатор копіює", + "gtceu.subtitle.saw": "Пиляння", + "gtceu.subtitle.science": "н а у к а", + "gtceu.subtitle.screwdriver": "Закручування", + "gtceu.subtitle.soft_hammer": "М'який тик", + "gtceu.subtitle.spray_can": "Обприскування", + "gtceu.subtitle.sus": "Підозріло...", + "gtceu.subtitle.turbine": "Свист турбіни", + "gtceu.subtitle.wirecutter": "Дріт рветься", + "gtceu.subtitle.wrench": "Ключ брязкає", + "gtceu.thermal_centrifuge": "Термічна центрифуга", + "gtceu.tool.class.axe": "Сокира", + "gtceu.tool.class.butchery_knife": "М'ясний ніж", + "gtceu.tool.class.crowbar": "Лом", + "gtceu.tool.class.drill": "Бур", + "gtceu.tool.class.file": "Напилок", + "gtceu.tool.class.hammer": "Молот", + "gtceu.tool.class.hoe": "Мотика", + "gtceu.tool.class.knife": "Ніж", + "gtceu.tool.class.mallet": "Киянка", + "gtceu.tool.class.mining_hammer": "Шахтарський молот", + "gtceu.tool.class.mortar": "Ступка", + "gtceu.tool.class.pickaxe": "Кайло", + "gtceu.tool.class.plunger": "Вантуз", + "gtceu.tool.class.rolling_pin": "Качалка", + "gtceu.tool.class.saw": "Пила", + "gtceu.tool.class.screwdriver": "Викрутка", + "gtceu.tool.class.scythe": "Коса", + "gtceu.tool.class.shears": "Ножиці", + "gtceu.tool.class.shovel": "Лопата", + "gtceu.tool.class.spade": "Заступ", + "gtceu.tool.class.sword": "Меч", + "gtceu.tool.class.wire_cutter": "Кусачки", + "gtceu.tool.class.wrench": "Гайковий ключ", + "gtceu.tool_action.crowbar": "§8Використовуйте лом, щоб зняти кришки", + "gtceu.tool_action.hammer": "§8Використовуйте молот, щоб приглушити звуки", + "gtceu.tool_action.screwdriver.access_covers": "§8Використовуйте викрутку для доступу до кришок", + "gtceu.tool_action.screwdriver.auto_collapse": "§8Використовуйте викрутку, щоб увімкнути руйнування предметів", + "gtceu.tool_action.screwdriver.auto_output": "§8Використовуйте викрутку, щоб увімкнути автоматичний вихід", + "gtceu.tool_action.screwdriver.auto_output_covers": "§8Використовуйте викрутку, щоб увімкнути вхід з боку виходу або для доступу до кришок", + "gtceu.tool_action.screwdriver.toggle_mode": "§8Використовуйте викрутку для перемикання режимів", + "gtceu.tool_action.screwdriver.toggle_mode_covers": "§8Використовуйте викрутку для перемикання режимів або доступу до кришок", + "gtceu.tool_action.show_tooltips": "Утримуйте Shift, щоб показати інформацію інструмента", + "gtceu.tool_action.soft_mallet.reset": "§8Використовуйте киянку для перемикання робочого стану", + "gtceu.tool_action.soft_mallet.toggle_mode": "§8Використовуйте киянку для перемикання режимів", + "gtceu.tool_action.tape": "§8Використовуйте стрічку для усунення проблем з технічним обслуговуванням", + "gtceu.tool_action.wire_cutter.connect": "§8Використовуйте кусачки (дріт) або гайковий ключ (труба) для встановлення з'єднань", + "gtceu.tool_action.wrench.connect": "§8Використовуйте гайковий ключ для встановлення з'єднань, крадькома, щоб заблокувати з'єднання", + "gtceu.tool_action.wrench.set_facing": "§8Використовуйте ключ, щоб встановити напрямок", + "gtceu.tooltip.computer_monitor_config": "Конфігураційні дані кришки монітора збережень комп'ютера", + "gtceu.tooltip.computer_monitor_data": "Збережено даних: %s", + "gtceu.tooltip.fluid_pipe_hold_shift": "§7Утримуйте Shift, щоб показати інформацію про наявну рідину", + "gtceu.tooltip.hold_ctrl": "§7Утримуйте Ctrl для більшої інформації", + "gtceu.tooltip.hold_shift": "§7Утримуйте Shift для більшої інформації", + "gtceu.tooltip.player_bind": "Прив'язано до гравця: %s", + "gtceu.tooltip.potion.each": "%s %s§7 на§r %s§7 тактів, який застосується із§r %s%%§7 ймовірністю§r", + "gtceu.tooltip.potion.header": "§6Містить ефекти:", + "gtceu.tooltip.proxy_bind": "§fПрив'язати до буфера шаблонів у %s %s %s", + "gtceu.tooltip.status.trinary.false": "Брехня", + "gtceu.tooltip.status.trinary.true": "Істина", + "gtceu.tooltip.status.trinary.unknown": "Невідомо", + "gtceu.tooltip.tool_fluid_hold_shift": "§7Утримуйте Shift, щоб показати інформацію інструмента та про наявну рідину", + "gtceu.tooltip.wireless_transmitter_bind": "Прив’язка до кришки передавача на %s %s %s, зверненій до %s у %s", + "gtceu.top.allow_output_input": "Відкритий вхід", + "gtceu.top.auto_output": "Автовиведення", + "gtceu.top.buffer_bound_pos": "Прив'язано до - X: %s, Y: %s, Z: %s", + "gtceu.top.buffer_not_bound": "Буфер наразі не прив'язаний", + "gtceu.top.cable_amperage": "Сила струму: ", + "gtceu.top.cable_voltage": "Напруга: ", + "gtceu.top.convert_eu": "Конвертація§e EU§r ->§c FE§r", + "gtceu.top.convert_fe": "Конвертація§c FE§r ->§e EU§r", + "gtceu.top.energy_consumption": "Використання", + "gtceu.top.energy_production": "Вироблення", + "gtceu.top.energy_stored": " / %d EU", + "gtceu.top.exhaust_vent_blocked": "Заблоковано", + "gtceu.top.exhaust_vent_direction": "Витяжна вентиляція: %s", + "gtceu.top.filter.label": "Фільтр:", + "gtceu.top.fluid_auto_output": "Вихід рідини: %s", + "gtceu.top.fuel_min_consume": "Потребує", + "gtceu.top.fuel_none": "Нема палива", + "gtceu.top.invalid_structure": "Конструкція незавершена", + "gtceu.top.item_auto_output": "Вихід предметів: %s", + "gtceu.top.link_cover.color": "Колір:", + "gtceu.top.machine_mode": "Режим машини: ", + "gtceu.top.maintenance.crowbar": "Цьому тут не місце", + "gtceu.top.maintenance.hard_hammer": "Покриття має вм'ятини", + "gtceu.top.maintenance.screwdriver": "Гвинти розхитані", + "gtceu.top.maintenance.soft_mallet": "Щось заклинило", + "gtceu.top.maintenance.wire_cutter": "Дроти перегоріли", + "gtceu.top.maintenance.wrench": "Труба відійшла", + "gtceu.top.maintenance_broken": "Потребує технічного обслуговування", + "gtceu.top.maintenance_fixed": "Обслуговування завершено", + "gtceu.top.mode.export": "Експортування", + "gtceu.top.mode.import": "Імпортування", + "gtceu.top.obstructed_structure": "Щось заважає формуванню конструкції", + "gtceu.top.primitive_pump_production": "Вироблення: %s мВ/с", + "gtceu.top.progress_computation": " / %s ОРО", + "gtceu.top.progress_sec": " / %s с", + "gtceu.top.progress_tick": " / %s т", + "gtceu.top.proxies_bound": "Прив'язані буферні проксі: %s", + "gtceu.top.recipe_output": "Виходи рецептів:", + "gtceu.top.stained": "Фарбування: %s", + "gtceu.top.transform_down": "§aКрок вниз§r %s", + "gtceu.top.transform_input": "§6Вхід:§r %s", + "gtceu.top.transform_output": "§9Вихід:§r %s", + "gtceu.top.transform_up": "§cКрок вгору§r %s", + "gtceu.top.unit.fluid_buckets": "кЛ", + "gtceu.top.unit.fluid_milibuckets": "Л", + "gtceu.top.unit.items": "Предмети", + "gtceu.top.valid_structure": "Конструкцію сформовано", + "gtceu.top.working_disabled": "Робота зупинена", + "gtceu.universal.clear_nbt_recipe.tooltip": "§cЦе знищить увесь вміст!", + "gtceu.universal.kiloliters": "%s B", + "gtceu.universal.liters": "%s мВ", + "gtceu.universal.padded_parentheses": " (%s) ", + "gtceu.universal.padded_spaced_parentheses": " ( %s ) ", + "gtceu.universal.parentheses": "(%s)", + "gtceu.universal.spaced_parentheses": "( %s )", + "gtceu.universal.tooltip.amperage_in": "§eСила струму на вході:§f %dA", + "gtceu.universal.tooltip.amperage_in_out": "§eСила струму на вході/виході:§f %dA", + "gtceu.universal.tooltip.amperage_in_out_till": "§eСила струму на вході/виході до:§f %dA", + "gtceu.universal.tooltip.amperage_in_till": "§eСила струму на вході до:§f %dA", + "gtceu.universal.tooltip.amperage_out": "§eСила струму на виході:§f %dA", + "gtceu.universal.tooltip.amperage_out_till": "§eСила струму на виході до: §f%dA", + "gtceu.universal.tooltip.base_production_eut": "§eБазове виробництво:§f %d EU/т", + "gtceu.universal.tooltip.base_production_fluid": "§eБазове виробництво:§f %d мВ/т", + "gtceu.universal.tooltip.chunk_mode": "Режим чанків: ", + "gtceu.universal.tooltip.deprecated": "§4§l ПОПЕРЕДЖЕННЯ:§r§4 ЗАСТАРІЛО. БУДЕ ВИДАЛЕНО В МАЙБУТНІХ ВЕРСІЯХ.§r", + "gtceu.universal.tooltip.energy_storage_capacity": "§cЕнергетична ємність:§r %d EU", + "gtceu.universal.tooltip.energy_tier_range": "§aДопустимі рівні напруги:§f %s§f - %s", + "gtceu.universal.tooltip.fluid_storage_capacity": "§9Рідинна ємність:§f %d мВ", + "gtceu.universal.tooltip.fluid_storage_capacity_mult": "§9Рідинна ємність:§f %d§7 резервуарів,§f %d мВ§7 кожний", + "gtceu.universal.tooltip.fluid_stored": "§2Збережена рідина:§f %s, %d мВ", + "gtceu.universal.tooltip.fluid_transfer_rate": "§bШвидкість передачі:§f %d мВ/т", + "gtceu.universal.tooltip.item_storage_capacity": "§6Предметних слотів:§f %d", + "gtceu.universal.tooltip.item_storage_total": "§6Предметна місткість:§f %d предметів", + "gtceu.universal.tooltip.item_stored": "§dПредметний вміст:§f %s, %d предметів", + "gtceu.universal.tooltip.item_transfer_rate": "§bШвидкість передачі:§f %d предметів/с", + "gtceu.universal.tooltip.item_transfer_rate_stacks": "§bШвидкість передачі:§f %d стосів/с", + "gtceu.universal.tooltip.max_voltage_in": "§aМакс. напруга на вході:§f %d (%s§f)", + "gtceu.universal.tooltip.max_voltage_in_out": "§aМакс. напруга на вході/виході:§f %d EU/т (%s§f)", + "gtceu.universal.tooltip.max_voltage_out": "§aМакс. напруга на виході:§f %d (%s§f)", + "gtceu.universal.tooltip.parallel": "§dМакс. паралелей:§f %d", + "gtceu.universal.tooltip.produces_fluid": "§eВиробляє:§f %d мВ/т", + "gtceu.universal.tooltip.requires_redstone": "§4Потребує заживлення редстоуном", + "gtceu.universal.tooltip.silk_touch": "Шовковий дотик: ", + "gtceu.universal.tooltip.terrain_resist": "Ця машина не вибухне під час контакту з хім. елементами", + "gtceu.universal.tooltip.uses_per_hour_lubricant": "Використовує§f %d мВ/год§7§6 мастила§7 під час роботи", + "gtceu.universal.tooltip.uses_per_op": "Використовує§f %d EU на операцію", + "gtceu.universal.tooltip.uses_per_second": "Використовує§f %d EU/c§7 під час роботи", + "gtceu.universal.tooltip.uses_per_tick": "Використовує§f %d EU/т§7 під час роботи", + "gtceu.universal.tooltip.uses_per_tick_steam": "Використовує§f %d мВ/т§7§f пари§7 під час роботи", + "gtceu.universal.tooltip.voltage_in": "§aНапруга на вході:§f %d EU/т (%s§f)", + "gtceu.universal.tooltip.voltage_in_out": "§aНапруга на вході/виході:§f %d EU/т (%s§f)", + "gtceu.universal.tooltip.voltage_out": "§aНапруга на виході:§f %d EU/т (%s§f)", + "gtceu.universal.tooltip.working_area": "§bРобоча зона:§f %dx%d", + "gtceu.universal.tooltip.working_area_chunks": "§bРобоча зона:§f %dx%d чанків", + "gtceu.universal.tooltip.working_area_chunks_max": "§bМакс. робоча зона:§f %dx%d чанків", + "gtceu.universal.tooltip.working_area_max": "§bМакс. робоча зона:§f %dx%d", + "gtceu.vacuum_freezer": "Вакуумна морозильна камера", + "gtceu.wiremill": "Волок", + "gui.gtceu.refund_all.desc": "Повернути збережений вміст до AE2", + "gui.gtceu.rename.desc": "Перейменувати буфер деталей", + "gui.gtceu.share_inventory.desc.0": "Ділиться вставленими предметами з усіма шаблонами в буфері!", + "gui.gtceu.share_inventory.desc.1": "Дозволяє значно автоматизувати роботу, зберігаючи каталізатори", + "gui.gtceu.share_inventory.title": "Інвентар спільних предметів", + "gui.gtceu.share_tank.desc.0": "Ділиться вставленими рідинами/газами/тощо з усіма шаблонами в буфері!", + "gui.gtceu.share_tank.title": "Інвентар спільного резервуара", + "gui.widget.incrementButton.default_tooltip": "Утримуйте Shift, Ctrl чи обидва, щоб змінити кількість", + "gui.widget.recipeProgressWidget.default_tooltip": "Показати рецепти", + "item.glass_lens": "Скляна лінза (Біла)", + "item.gtceu.activity_detector_cover": "Детектор активності", + "item.gtceu.activity_detector_cover.tooltip": "§7Видає§f статус активності§7 як редстоун та§f кришка§7.", + "item.gtceu.advanced_activity_detector_cover": "Вдосконалений детектор активності", + "item.gtceu.advanced_activity_detector_cover.tooltip": "§7Видає§f прогрес машини§7 як редстоун та§f кришка§7.", + "item.gtceu.advanced_electric_jetpack": "Вдосконалений електричний реактивний ранець", + "item.gtceu.advanced_energy_detector_cover": "Вдосконалений детектор енергії", + "item.gtceu.advanced_energy_detector_cover.tooltip": "§7Видає§f RS-засув§7 контрольований§f статус енергії§7 як редстоун та§f кришка§7.", + "item.gtceu.advanced_fluid_detector_cover": "Вдосконалений детектор рідин", + "item.gtceu.advanced_fluid_detector_cover.tooltip": "§7Видає§f RS-засув§7 контрольований§f статус наявної рідини§7 як редстоун та§f кришка§7.", + "item.gtceu.advanced_fluid_voiding_cover": "Вдосконалена кришка видалення рідини", + "item.gtceu.advanced_fluid_voiding_cover.tooltip.0": "§7Видаляє§f рідини§7 з контролем кількості, як§f кришка§7.", + "item.gtceu.advanced_fluid_voiding_cover.tooltip.1": "Активуйте§f киянкою§7 після розміщення.", + "item.gtceu.advanced_integrated_circuit": "Вдосконалена інтегральна схема", + "item.gtceu.advanced_integrated_circuit.tooltip.0": "§7Менша та потужніша", + "item.gtceu.advanced_integrated_circuit.tooltip.1": "§6Схема HV рівня", + "item.gtceu.advanced_item_detector_cover": "Вдосконалений детектор предметів", + "item.gtceu.advanced_item_detector_cover.tooltip": "§7Видає§f RS-засув§7 контрольований§f статус наявних предметів§7 як редстоун та§f кришка§7.", + "item.gtceu.advanced_item_voiding_cover": "Вдосконалена кришка видалення предметів", + "item.gtceu.advanced_item_voiding_cover.tooltip.0": "§7Видаляє§f предмети§7 з контролем кількості, як§f кришка§7.", + "item.gtceu.advanced_item_voiding_cover.tooltip.1": "Активуйте§f киянкою§7 після розміщення.", + "item.gtceu.advanced_nanomuscle_chestplate": "Нагрудник вдосконаленого костюма NanoMuscle™", + "item.gtceu.advanced_power_thruster": "Вдосконалений силовий рушій", + "item.gtceu.advanced_quarktech_chestplate": "Нагрудник вдосконаленого костюма QuarkTech™", + "item.gtceu.advanced_smd_capacitor": "Вдосконалений SMD конденсатор", + "item.gtceu.advanced_smd_capacitor.tooltip": "§7Вдосконалений електронний компонент", + "item.gtceu.advanced_smd_diode": "Вдосконалений SMD діод", + "item.gtceu.advanced_smd_diode.tooltip": "§7Вдосконалений електронний компонент", + "item.gtceu.advanced_smd_inductor": "Вдосконалений SMD індуктор", + "item.gtceu.advanced_smd_inductor.tooltip": "§7Вдосконалений електронний компонент", + "item.gtceu.advanced_smd_resistor": "Вдосконалений SMD резистор", + "item.gtceu.advanced_smd_resistor.tooltip": "§7Вдосконалений електронний компонент", + "item.gtceu.advanced_smd_transistor": "Вдосконалений SMD транзистор", + "item.gtceu.advanced_smd_transistor.tooltip": "§7Вдосконалений електронний компонент", + "item.gtceu.advanced_soc": "ASoC", + "item.gtceu.advanced_soc.tooltip": "§7Вдосконалена система на чіпі", + "item.gtceu.advanced_soc_wafer": "Підкладка ASoC", + "item.gtceu.advanced_soc_wafer.tooltip": "§7Заготовка вдосконаленої схеми", + "item.gtceu.aluminium_fluid_cell": "Алюмінієва комірка (%s)", + "item.gtceu.anvil_casting_mold": "Відливна форма (ковадло)", + "item.gtceu.anvil_casting_mold.tooltip": "§7Форма для формування ковадл", + "item.gtceu.armor.boots": "Чоботи (%s)", + "item.gtceu.armor.chestplate": "Нагрудник (%s)", + "item.gtceu.armor.helmet": "Шолом (%s)", + "item.gtceu.armor.leggings": "Наголінники (%s)", + "item.gtceu.ash_dust": "Попіл", + "item.gtceu.axe_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення сокир", + "item.gtceu.ball_casting_mold": "Відливна форма (куля)", + "item.gtceu.ball_casting_mold.tooltip": "§7Форма для виготовлення куль", + "item.gtceu.basaltic_mineral_sand_dust": "Базальтовий мінеральний пісок", + "item.gtceu.basic_electronic_circuit": "Базова електросхема", + "item.gtceu.basic_electronic_circuit.tooltip.0": "§7Ваша перша схема", + "item.gtceu.basic_electronic_circuit.tooltip.1": "§cСхема LV рівня", + "item.gtceu.basic_integrated_circuit": "Базова інтегральна схема", + "item.gtceu.basic_integrated_circuit.tooltip.0": "§7Менша та потужніша", + "item.gtceu.basic_integrated_circuit.tooltip.1": "§6Схема LV рівня", + "item.gtceu.basic_tape": "Клейка стрічка", + "item.gtceu.basic_tape.tooltip": "§7Недостатньо міцна для механічних проблем\nМожна використовувати для підняття ящиків, не скидаючи предмети з них", + "item.gtceu.battery.charge_detailed": "%s/%s EU§7 - рівень %s §7(§aзалишилось %s/%s %s§7)", + "item.gtceu.battery.charge_time": "§aМістить %s %s заряду (%s)", + "item.gtceu.battery.charge_unit.hour": "годин", + "item.gtceu.battery.charge_unit.minute": "хвилин", + "item.gtceu.battery.charge_unit.second": "секунд", + "item.gtceu.bentonite_dust": "Бентоніт", + "item.gtceu.bio_chaff": "Біо полова", + "item.gtceu.black_dye_spray_can": "Аерозольний балончик (чорний)", + "item.gtceu.black_glass_lens": "Скляна лінза (Чорна)", + "item.gtceu.blacklight": "Чорне світло", + "item.gtceu.blacklight.tooltip": "Довгохвильове§d ультрафіолетове§7 джерело світла", + "item.gtceu.block_casting_mold": "Відливна форма (блок)", + "item.gtceu.block_casting_mold.tooltip": "§7Форма для виготовлення блоків", + "item.gtceu.block_extruder_mold": "Відтискна форма (блок)", + "item.gtceu.block_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення блоків", + "item.gtceu.blue_dye_spray_can": "Аерозольний балончик (синій)", + "item.gtceu.blue_glass_lens": "Скляна лінза (Синя)", + "item.gtceu.bolt_extruder_mold": "Відтискна форма (болт)", + "item.gtceu.bolt_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення болтів", + "item.gtceu.bone_dust": "Кісткове борошно", + "item.gtceu.borosilicate_glass_ingot": "Злиток боросилікатного скла", + "item.gtceu.bottle.purple.drink.tooltip": "§7Як щодо лимонаду? або чаю з льодом? У мене є фіолетовий напій!", + "item.gtceu.bottle_casting_mold": "Відливна форма (пляшка)", + "item.gtceu.bottle_casting_mold.tooltip": "§7Форма для виготовлення пляшок", + "item.gtceu.bottle_extruder_mold": "Відтискна форма (пляшка)", + "item.gtceu.bottle_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення пляшок", + "item.gtceu.brick_wooden_form": "Дерев'яна форма цеглини", + "item.gtceu.brown_dye_spray_can": "Аерозольний балончик (коричневий)", + "item.gtceu.brown_glass_lens": "Скляна лінза (Коричнева)", + "item.gtceu.bucket": "%s (у відрі)", + "item.gtceu.capacitor": "Конденсатор", + "item.gtceu.capacitor.tooltip": "§7Базовий електронний компонент", + "item.gtceu.carbon_fiber_mesh": "Сітка з вуглецевого волокна", + "item.gtceu.carbon_fiber_plate": "Плита з вуглецевого волокна", + "item.gtceu.carbon_fibers": "Сире вуглецеве волокно", + "item.gtceu.casing_casting_mold.tooltip": "§7Форма для виготовлення предметних каркасів", + "item.gtceu.casing_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення предметних корпусів", + "item.gtceu.cassiterite_sand_dust": "Каситеритовий пісок", + "item.gtceu.cell_extruder_mold": "Відтискна форма (комірка)", + "item.gtceu.cell_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення комірок", + "item.gtceu.chemical_black_dye": "Хімічний чорний барвник", + "item.gtceu.chemical_blue_dye": "Хімічний синій барвник", + "item.gtceu.chemical_brown_dye": "Хімічний коричневий барвник", + "item.gtceu.chemical_cyan_dye": "Хімічний бірюзовий барвник", + "item.gtceu.chemical_gray_dye": "Хімічний сірий барвник", + "item.gtceu.chemical_green_dye": "Хімічний зелений барвник", + "item.gtceu.chemical_light_blue_dye": "Хімічний блакитний барвник", + "item.gtceu.chemical_light_gray_dye": "Хімічний світло-сірий барвник", + "item.gtceu.chemical_lime_dye": "Хімічний лаймовий барвник", + "item.gtceu.chemical_magenta_dye": "Хімічний пурпурний барвник", + "item.gtceu.chemical_orange_dye": "Хімічний помаранчевий барвник", + "item.gtceu.chemical_pink_dye": "Хімічний рожевий барвник", + "item.gtceu.chemical_purple_dye": "Хімічний фіолетовий барвник", + "item.gtceu.chemical_red_dye": "Хімічний червоний барвник", + "item.gtceu.chemical_white_dye": "Хімічний білий барвник", + "item.gtceu.chemical_yellow_dye": "Хімічний жовтий барвник", + "item.gtceu.chipped_glass_gem": "Надщерблений скляний кристал", + "item.gtceu.chipped_sugar_gem": "Маленький кубик цукру", + "item.gtceu.circuit.integrated.gui": "§7Конфігурація програмної плати", + "item.gtceu.coke_oven_brick": "Цеглина коксової печі", + "item.gtceu.compressed_clay": "Пресована глина", + "item.gtceu.compressed_coke_clay": "Пресована коксова глина", + "item.gtceu.compressed_fireclay": "Пресована шамотна глина", + "item.gtceu.computer_monitor_cover": "Комп'ютерний монітор", + "item.gtceu.computer_monitor_cover.tooltip": "§7Відображає§f дані§7 як§f кришка§7.", + "item.gtceu.conveyor.module.tooltip": "§7Переміщує§f предмети§7 із певною кількістю як§f кришка§7.", + "item.gtceu.cpu_chip": "Чіп CPU", + "item.gtceu.cpu_chip.tooltip": "§7Центральний процесорний блок", + "item.gtceu.cpu_wafer": "Підкладка CPU", + "item.gtceu.cpu_wafer.tooltip": "§7Заготовка процесорного блоку", + "item.gtceu.crushed_bentonite_ore": "Дроблений бентоніт", + "item.gtceu.crushed_cassiterite_sand_ore": "Дроблений каситеритовий пісок", + "item.gtceu.crushed_pitchblende_ore": "Дроблений настуран", + "item.gtceu.crushed_talc_ore_ore": "Дроблений тальк", + "item.gtceu.crystal_cpu": "Кришталевий CPU", + "item.gtceu.crystal_cpu.tooltip": "§7Кришталевий процесорний блок", + "item.gtceu.crystal_processor": "Кришталевий процесор", + "item.gtceu.crystal_processor.tooltip.0": "§7Використання переваг кришталевого гравіювання", + "item.gtceu.crystal_processor.tooltip.1": "§9Схема IV рівня", + "item.gtceu.crystal_processor_assembly": "Кришталевий процесорний вузол", + "item.gtceu.crystal_processor_assembly.tooltip.0": "§7Використання переваг кришталевого гравіювання", + "item.gtceu.crystal_processor_assembly.tooltip.1": "§9Схема LuV рівня", + "item.gtceu.crystal_processor_computer": "Кришталевий процесорний суперкомп'ютер", + "item.gtceu.crystal_processor_computer.tooltip.0": "§7Використання переваг кришталевого гравіювання", + "item.gtceu.crystal_processor_computer.tooltip.1": "§9Схема ZPM рівня", + "item.gtceu.crystal_processor_mainframe": "Кришталевий процесорний мейнфрейм", + "item.gtceu.crystal_processor_mainframe.tooltip.0": "§7Використання переваг кришталевого гравіювання", + "item.gtceu.crystal_processor_mainframe.tooltip.1": "§9Схема UV рівня", + "item.gtceu.crystal_soc": "Кришталева SoC", + "item.gtceu.crystal_soc.tooltip": "§7Кришталева система на чіпі", + "item.gtceu.cyan_dye_spray_can": "Аерозольний балончик (бірюзовий)", + "item.gtceu.cyan_glass_lens": "Скляна лінза (Бірюзова)", + "item.gtceu.cylinder_casting_mold": "Відливна форма (циліндр)", + "item.gtceu.cylinder_casting_mold.tooltip": "§7Форма для формування циліндрів", + "item.gtceu.dark_ash_dust": "Темний попіл", + "item.gtceu.data_module": "Модуль даних", + "item.gtceu.data_orb": "Сфера даних", + "item.gtceu.data_orb.tooltip": "§7Сховище даних великої місткості", + "item.gtceu.data_stick": "Картка даних", + "item.gtceu.data_stick.tooltip": "§7Сховище даних малої місткості", + "item.gtceu.diamond_grinding_head": "Діамантова шліфувальна головка", + "item.gtceu.diode": "Діод", + "item.gtceu.diode.tooltip": "§7Базовий електронний компонент", + "item.gtceu.dough": "Тісто", + "item.gtceu.duct_tape": "BrainTech аерокосмічна вдосконалена армована клейка стрічка FAL-84", + "item.gtceu.duct_tape.tooltip": "§7Якщо ви не можете виправити це за допомогою цього, використовуйте більше!", + "item.gtceu.dynamite": "Динамітна шашка", + "item.gtceu.electric.pump.tooltip": "§7Переміщує§f рідини§7 із певною кількістю як§f кришка§7.", + "item.gtceu.electric_jetpack": "Електричний реактивний ранець", + "item.gtceu.empty_mold": "Порожня форма", + "item.gtceu.empty_mold.tooltip": "§7Сира плита для виготовлення прес-форм та формових відтисків", + "item.gtceu.empty_spray_can": "Аерозольний балончик (порожній)", + "item.gtceu.empty_spray_can.tooltip": "§7Можна наповнити аерозолем різних кольорів", + "item.gtceu.empty_wooden_form": "Порожня дерев'яна форма", + "item.gtceu.ender_fluid_link_cover": "Рідинний зв'язок Енду", + "item.gtceu.ender_fluid_link_cover.tooltip": "§7Переміщує §fрідини§7 за допомогою§f безпровідого з'єднання §dЕнду§f§7 як§f кришка§7.", + "item.gtceu.ender_item_link_cover": "Предметний зв'язок Енду", + "item.gtceu.ender_redstone_link_cover": "Редстоуновий зв'язок Енду", + "item.gtceu.energium_dust": "Енергієвий пил", + "item.gtceu.energy_cluster": "Енергетичний кластер", + "item.gtceu.energy_cluster.tooltip": "§7Багаторазова батарея", + "item.gtceu.energy_crystal": "Енергієвий кристал", + "item.gtceu.energy_crystal.tooltip": "§7Багаторазова батарея", + "item.gtceu.energy_detector_cover": "Енергетичний детектор", + "item.gtceu.energy_detector_cover.tooltip": "§7Видає§f кількість енергії§7 як редстоун та§f кришка§7.", + "item.gtceu.energy_module": "Енергетичний модуль", + "item.gtceu.energy_module.tooltip": "§7Багаторазова батарея", + "item.gtceu.engraved_crystal_chip": "Гравірований кришталевий чіп", + "item.gtceu.engraved_crystal_chip.tooltip": "§7Потрібно для схем", + "item.gtceu.engraved_lapotron_crystal_chip": "Гравірований лапотронний кришталевий чіп", + "item.gtceu.epoxy_circuit_board": "Епоксидна плата", + "item.gtceu.epoxy_circuit_board.tooltip": "§7Вдосконалена плата", + "item.gtceu.epoxy_printed_circuit_board": "Епоксидна друкована плата", + "item.gtceu.epoxy_printed_circuit_board.tooltip": "§7Вдосконалена плата", + "item.gtceu.ev_battery_hull": "Малий корпус ванадієвої батареї", + "item.gtceu.ev_battery_hull.tooltip": "§7Порожній корпус§5 EV§7 батареї", + "item.gtceu.ev_conveyor_module": "EV конвеєрний модуль", + "item.gtceu.ev_electric_motor": "EV електричний мотор", + "item.gtceu.ev_electric_piston": "EV електричний поршень", + "item.gtceu.ev_electric_pump": "EV електрична помпа", + "item.gtceu.ev_emitter": "EV випромінювач", + "item.gtceu.ev_field_generator": "EV генератор поля", + "item.gtceu.ev_fluid_regulator": "EV регулятор рідини", + "item.gtceu.ev_power_unit": "EV блок живлення", + "item.gtceu.ev_robot_arm": "EV маніпулятор", + "item.gtceu.ev_sensor": "EV сенсор", + "item.gtceu.ev_solar_panel": "Сонячна панель екстремальної напруги", + "item.gtceu.ev_vanadium_battery": "Мала ванадієва батарея", + "item.gtceu.ev_vanadium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.ev_voltage_coil": "Котушка екстремальної напруги", + "item.gtceu.ev_voltage_coil.tooltip": "Екстремальна котушка", + "item.gtceu.exquisite_glass_gem": "Бездоганний скляний кристал", + "item.gtceu.facade_cover": "Накладний фасад (%s)", + "item.gtceu.facade_cover.tooltip.0": "§7Декоративне§f покриття§7.", + "item.gtceu.facade_cover.tooltip.1": "§7Створюється з 3 залізних листів та будь-якого блоку", + "item.gtceu.face_mask": "Лицьова маска", + "item.gtceu.fertilizer": "Добриво", + "item.gtceu.fiber_reinforced_circuit_board": "Армована волокном плата", + "item.gtceu.fiber_reinforced_circuit_board.tooltip": "§7Екстремальна плата", + "item.gtceu.fiber_reinforced_printed_circuit_board": "Армована волокном друкована плата", + "item.gtceu.fiber_reinforced_printed_circuit_board.tooltip": "§7Вдосконаленіша плата", + "item.gtceu.file_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення напилків", + "item.gtceu.fine_borosilicate_glass_wire": "Боросилікатне скловолокно", + "item.gtceu.firebrick": "Шамотна цеглина", + "item.gtceu.firebrick.tooltip": "§7Термостійка", + "item.gtceu.flawed_glass_gem": "Огранований скляний кристал", + "item.gtceu.flawed_sugar_gem": "Крихітний кубик цукру", + "item.gtceu.flawless_glass_gem": "Вишуканий скляний кристал", + "item.gtceu.fluid.regulator.tooltip": "§7Обмежує§f рідини§7 до певної кількості як§f кришка§7.", + "item.gtceu.fluid_cell": "Рідинна комірка (%s)", + "item.gtceu.fluid_detector_cover": "Детектор рідин", + "item.gtceu.fluid_detector_cover.tooltip": "§7Видає§f кількість рідини§7 як редстоун та§f кришка§7.", + "item.gtceu.fluid_filter": "Фільтр рідин", + "item.gtceu.fluid_filter.tooltip.0": "§7Фільтрує§f рідинний§7 вхід/вихід як§f кришка§7.", + "item.gtceu.fluid_filter.tooltip.1": "Може використовуватися як§f електрична помпа§7 та покращення§f рідинного регулятора§7.", + "item.gtceu.fluid_tag_filter": "Рідинний теговий фільтр", + "item.gtceu.fluid_tag_filter.tooltip.0": "§7Фільтрує§f рідинний§7 вхід/вихід із§f рідинними тегами§7 як§f кришка§7.", + "item.gtceu.fluid_tag_filter.tooltip.1": "Може використовуватися як§f електрична помпа§7 та покращення§f рідинного регулятора§7.", + "item.gtceu.fluid_voiding_cover": "Кришка видалення рідини", + "item.gtceu.fluid_voiding_cover.tooltip.0": "§7Видаляє§f рідини§7 як§f кришка§7.", + "item.gtceu.fluid_voiding_cover.tooltip.1": "Активуйте§f киянкою§7 після розміщення.", + "item.gtceu.foam_sprayer.tooltip.0": "§7Розпилює будівельну піні", + "item.gtceu.foam_sprayer.tooltip.1": "Використовуйте на боці, щоб вкрити піною прилеглі сторони", + "item.gtceu.foam_sprayer.tooltip.2": "Піну можна пофарбувати", + "item.gtceu.foil_extruder_mold": "Відтискна форма (тонка пластина)", + "item.gtceu.foil_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення тонких пластин", + "item.gtceu.fullers_earth_dust": "Відбілювальні глини", + "item.gtceu.garnet_sand_dust": "Гранатовий пісок", + "item.gtceu.gear_casting_mold": "Відливна форма (шестерня)", + "item.gtceu.gear_casting_mold.small.tooltip": "§7Форма для виготовлення малих шестерень", + "item.gtceu.gear_casting_mold.tooltip": "§7Форма для виготовлення шестерень", + "item.gtceu.gear_extruder_mold": "Відтискна форма (шестерня)", + "item.gtceu.gear_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення шестерень", + "item.gtceu.gear_small_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення малих шестерень", + "item.gtceu.gelled_toluene": "Гелевий толуол", + "item.gtceu.gelled_toluene.tooltip": "§7Сира вибухівка", + "item.gtceu.glass_gem": "Скляний кристал", + "item.gtceu.glass_plate": "Шибка", + "item.gtceu.glass_tube": "Скляна трубка", + "item.gtceu.glass_vial": "Скляна пробірка (%s)", + "item.gtceu.glauconite_sand_dust": "Глауконітове скло", + "item.gtceu.good_electronic_circuit": "Хороша електросхема", + "item.gtceu.good_electronic_circuit.tooltip.0": "§7Ваша друга схема", + "item.gtceu.good_electronic_circuit.tooltip.1": "§cСхема MV рівня", + "item.gtceu.good_integrated_circuit": "Хороша інтегральна схема", + "item.gtceu.good_integrated_circuit.tooltip.0": "§7Менша та потужніша", + "item.gtceu.good_integrated_circuit.tooltip.1": "§6Схема MV рівня", + "item.gtceu.granitic_mineral_sand_dust": "Гранітний мінеральний пісок", + "item.gtceu.gravi_star": "Граві-зірка", + "item.gtceu.gravi_star.tooltip": "§7Ультимативна зірка Незеру", + "item.gtceu.gravitation_engine_unit": "Блок гравітаційного двигуна", + "item.gtceu.gray_dye_spray_can": "Аерозольний балончик (сірий)", + "item.gtceu.gray_glass_lens": "Скляна лінза (Сіра)", + "item.gtceu.green_dye_spray_can": "Аерозольний балончик (зелений)", + "item.gtceu.green_glass_lens": "Скляна лінза (Зелена)", + "item.gtceu.hammer_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення малотків", + "item.gtceu.hazmat_boots": "Чоботи костюма для роботи з небезпечними матеріалами", + "item.gtceu.hazmat_chestpiece": "Куртка костюма для роботи з небезпечними матеріалами", + "item.gtceu.hazmat_headpiece": "Головний убір костюма для роботи з небезпечними матеріалами", + "item.gtceu.hazmat_leggings": "Штани костюма для роботи з небезпечними матеріалами", + "item.gtceu.highly_advanced_soc": "HASoC", + "item.gtceu.highly_advanced_soc.tooltip": "§7Високорозвинена система на чіпі", + "item.gtceu.highly_advanced_soc_wafer": "Підкладка HASoC", + "item.gtceu.highly_advanced_soc_wafer.tooltip": "§7Заготовка високорозвиненої схеми", + "item.gtceu.hoe_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення мотик", + "item.gtceu.hpic_chip": "Чіп HPIC", + "item.gtceu.hpic_chip.tooltip": "§7IC високої напруги", + "item.gtceu.hpic_wafer": "Підкладка HPIC", + "item.gtceu.hpic_wafer.tooltip": "§7Заготовка високопотужної схеми", + "item.gtceu.huge_pipe_casting_mold": "Відливна форма (величезна труба)", + "item.gtceu.huge_pipe_extruder_mold": "Відтискна форма (величезна труба)", + "item.gtceu.hv_battery_hull": "Великий корпус батареї", + "item.gtceu.hv_battery_hull.tooltip": "§7Порожній корпус§6 HV§7 батареї", + "item.gtceu.hv_cadmium_battery": "Велика кадмієва батарея", + "item.gtceu.hv_cadmium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.hv_conveyor_module": "HV конвеєрний модуль", + "item.gtceu.hv_electric_motor": "HV електричний мотор", + "item.gtceu.hv_electric_piston": "HV електричний поршень", + "item.gtceu.hv_electric_pump": "HV електрична помпа", + "item.gtceu.hv_emitter": "HV випромінювач", + "item.gtceu.hv_field_generator": "HV генератор поля", + "item.gtceu.hv_fluid_regulator": "HV регулятор рідини", + "item.gtceu.hv_item_magnet": "HV предметний магніт", + "item.gtceu.hv_lithium_battery": "Велика літієва батарея", + "item.gtceu.hv_lithium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.hv_power_unit": "HV блок живлення", + "item.gtceu.hv_robot_arm": "HV маніпулятор", + "item.gtceu.hv_sensor": "HV сенсор", + "item.gtceu.hv_sodium_battery": "Велика натрієва батарея", + "item.gtceu.hv_sodium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.hv_solar_panel": "Сонячна панель високої напруги", + "item.gtceu.hv_voltage_coil": "Котушка високої напруги", + "item.gtceu.hv_voltage_coil.tooltip": "Вдосконалена котушка", + "item.gtceu.ice_dust": "Подрібнений лід", + "item.gtceu.ilc_chip": "Чіп IC", + "item.gtceu.ilc_chip.tooltip": "§7Інтегральна логічна схема", + "item.gtceu.ilc_wafer": "Підкладка ILC", + "item.gtceu.ilc_wafer.tooltip": "§7Заготовка інтегральної схеми", + "item.gtceu.image_module": "Модуль зображення", + "item.gtceu.impure_bentonite_dust": "Забруднений пил бентоніту", + "item.gtceu.impure_cassiterite_sand_dust": "Забруднений пил каситеритового піску", + "item.gtceu.impure_pitchblende_dust": "Забруднений пил настурану", + "item.gtceu.impure_rock_salt_dust": "Забруднений пил кам'яної солі", + "item.gtceu.impure_salt_dust": "Забруднена сіль", + "item.gtceu.impure_talc_dust": "Забруднений пил тальку", + "item.gtceu.inductor": "Індуктор", + "item.gtceu.inductor.tooltip": "§7Мала котушка", + "item.gtceu.inert_metal_mixture_dust": "Інертна металева суміш", + "item.gtceu.infinite_water_cover": "Кришка джерела води", + "item.gtceu.infinite_water_cover.tooltip": "§7Заповнює приєднані контейнери§9 водою§7 як§f кришка§7.", + "item.gtceu.ingot_casting_mold": "Відливна форма (злиток)", + "item.gtceu.ingot_casting_mold.tooltip": "§7Форма для виготовлення злитків", + "item.gtceu.ingot_extruder_mold": "Відтискна форма (злиток)", + "item.gtceu.ingot_extruder_mold.tooltip": "§7Формовий відтиск для... зачекайте, чи не можна просто використати піч?", + "item.gtceu.invar_lighter": "Інварова запальничка", + "item.gtceu.iridium_metal_residue_dust": "Металевий залишок іридію", + "item.gtceu.iron_minecart_wheels": "Залізні колеса вагонетки", + "item.gtceu.item_detector_cover": "Детектор предметів", + "item.gtceu.item_detector_cover.tooltip": "§7Видає§f кількість предметів§7 як редстоун та§f кришка§7.", + "item.gtceu.item_filter": "Фільтр предметів", + "item.gtceu.item_filter.tooltip.0": "§7Фільтрує§f предметний§7 вхід/вихід як§f кришка§7.", + "item.gtceu.item_filter.tooltip.1": "Може використовуватися як§f конвеєрний модуль§7 та покращення§f маніпулятора§7.", + "item.gtceu.item_smart_filter": "Розумний фільтр предметів", + "item.gtceu.item_smart_filter.tooltip.0": "§7Фільтрує§f предметний§7 вхід/вихід із§f рецептами машини§7 як§f кришка§7.", + "item.gtceu.item_smart_filter.tooltip.1": "Може використовуватися як§f конвеєрний модуль§7 та покращення§f маніпулятора§7.", + "item.gtceu.item_tag_filter": "Предметний теговий фільтр", + "item.gtceu.item_tag_filter.tooltip.0": "§7Фільтрує§f предметний§7 вхід/вихід із§f предметними тегами§7 як§f кришка§7.", + "item.gtceu.item_tag_filter.tooltip.1": "Може використовуватися як§f конвеєрний модуль§7 та покращення§f маніпулятора§7.", + "item.gtceu.item_voiding_cover": "Кришка видалення предметів", + "item.gtceu.item_voiding_cover.tooltip.0": "§7Видаляє§f предмети§7 як§f кришка§7.", + "item.gtceu.item_voiding_cover.tooltip.1": "Активуйте§f киянкою§7 після розміщення.", + "item.gtceu.iv_battery_hull": "Середній корпус ванадієвої батареї", + "item.gtceu.iv_battery_hull.tooltip": "§7Порожній корпус§1 IV§7 батареї", + "item.gtceu.iv_conveyor_module": "IV конвеєрний модуль", + "item.gtceu.iv_electric_motor": "IV електричний мотор", + "item.gtceu.iv_electric_piston": "IV електричний поршень", + "item.gtceu.iv_electric_pump": "IV електрична помпа", + "item.gtceu.iv_emitter": "IV випромінювач", + "item.gtceu.iv_field_generator": "IV генератор поля", + "item.gtceu.iv_fluid_regulator": "IV регулятор рідини", + "item.gtceu.iv_power_unit": "IV блок живлення", + "item.gtceu.iv_robot_arm": "IV маніпулятор", + "item.gtceu.iv_sensor": "IV сенсор", + "item.gtceu.iv_solar_panel": "Сонячна панель неможливої напруги", + "item.gtceu.iv_vanadium_battery": "Середня ванадієва батарея", + "item.gtceu.iv_vanadium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.iv_voltage_coil": "Котушка божевільної напруги", + "item.gtceu.iv_voltage_coil.tooltip": "Елітна котушка", + "item.gtceu.lapotron_crystal": "Лапотронний кристал", + "item.gtceu.lapotron_crystal.tooltip": "§7Багаторазова батарея", + "item.gtceu.lapotronic_energy_orb": "Лапотронна енергетична сфера", + "item.gtceu.lapotronic_energy_orb.tooltip": "§7Багаторазова батарея", + "item.gtceu.lapotronic_energy_orb_cluster": "Кластер лапотронної енергетичної сфери", + "item.gtceu.lapotronic_energy_orb_cluster.tooltip": "§7Багаторазова батарея", + "item.gtceu.large_pipe_casting_mold": "Відливна форма (велика труба)", + "item.gtceu.large_pipe_extruder_mold": "Відтискна форма (велика труба)", + "item.gtceu.light_blue_dye_spray_can": "Аерозольний балончик (блакитний)", + "item.gtceu.light_blue_glass_lens": "Скляна лінза (Блакитна)", + "item.gtceu.light_gray_dye_spray_can": "Аерозольний балончик (світло-сірий)", + "item.gtceu.light_gray_glass_lens": "Скляна лінза (Світло-сіра)", + "item.gtceu.lime_dye_spray_can": "Аерозольний балончик (лаймовий)", + "item.gtceu.lime_glass_lens": "Скляна лінза (Лаймова)", + "item.gtceu.liquid_fuel_jetpack": "Рідкопаливний реактивний ранець", + "item.gtceu.long_treated_wood_rod": "Довга оброблена дерев'яна палиця", + "item.gtceu.long_wood_rod": "Довга палиця", + "item.gtceu.lpic_chip": "Чіп LPIC", + "item.gtceu.lpic_chip.tooltip": "§7IC низької напруги", + "item.gtceu.lpic_wafer": "Підкладка LPIC", + "item.gtceu.lpic_wafer.tooltip": "§7Заготовка низькопотужної схеми", + "item.gtceu.luv_battery_hull": "Великий корпус ванадієвої батареї", + "item.gtceu.luv_battery_hull.tooltip": "§7Порожній корпус§d LuV§7 батареї", + "item.gtceu.luv_conveyor_module": "LuV конвеєрний модуль", + "item.gtceu.luv_electric_motor": "LuV електричний мотор", + "item.gtceu.luv_electric_piston": "LuV електричний поршень", + "item.gtceu.luv_electric_pump": "LuV електрична помпа", + "item.gtceu.luv_emitter": "LuV випромінювач", + "item.gtceu.luv_field_generator": "LuV генератор поля", + "item.gtceu.luv_fluid_regulator": "LuV регулятор рідини", + "item.gtceu.luv_robot_arm": "LuV маніпулятор", + "item.gtceu.luv_sensor": "LuV сенсор", + "item.gtceu.luv_solar_panel": "Сонячна панель абсурдної напруги", + "item.gtceu.luv_vanadium_battery": "Велика ванадієва батарея", + "item.gtceu.luv_vanadium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.luv_voltage_coil": "Котушка абсурдної напруги", + "item.gtceu.luv_voltage_coil.tooltip": "Майстерська котушка", + "item.gtceu.lv_battery_hull": "Малий корпус батареї", + "item.gtceu.lv_battery_hull.tooltip": "§7Порожній корпус LV батареї", + "item.gtceu.lv_cadmium_battery": "Мала кадмієва батарея", + "item.gtceu.lv_cadmium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.lv_conveyor_module": "LV конвеєрний модуль", + "item.gtceu.lv_electric_motor": "LV електричний мотор", + "item.gtceu.lv_electric_piston": "LV електричний поршень", + "item.gtceu.lv_electric_pump": "LV електрична помпа", + "item.gtceu.lv_emitter": "LV випромінювач", + "item.gtceu.lv_field_generator": "LV генератор поля", + "item.gtceu.lv_fluid_regulator": "LV регулятор рідини", + "item.gtceu.lv_item_magnet": "LV предметний магніт", + "item.gtceu.lv_lithium_battery": "Мала літієва батарея", + "item.gtceu.lv_lithium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.lv_power_unit": "LV блок живлення", + "item.gtceu.lv_robot_arm": "LV маніпулятор", + "item.gtceu.lv_sensor": "LV сенсор", + "item.gtceu.lv_sodium_battery": "Мала натрієва батарея", + "item.gtceu.lv_sodium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.lv_solar_panel": "Сонячна панель низької напруги", + "item.gtceu.lv_voltage_coil": "Котушка низької напруги", + "item.gtceu.lv_voltage_coil.tooltip": "Базова котушка", + "item.gtceu.machine_controller.tooltip": "§7Перемикає стан§f машини§7 як§f кришка§7.", + "item.gtceu.machine_controller_cover": "Контролер машини", + "item.gtceu.machine_memory_card": "Карта пам'яті машини", + "item.gtceu.magenta_dye_spray_can": "Аерозольний балончик (пурпурний)", + "item.gtceu.magenta_glass_lens": "Скляна лінза (Пурпурова)", + "item.gtceu.maintenance_detector_cover": "Детектор технічного обслуговування", + "item.gtceu.mask_filter": "Фільтр газової маски", + "item.gtceu.matchbox": "Упаковка сірників", + "item.gtceu.matches": "Сірник", + "item.gtceu.max_battery": "Ультимативна батарея", + "item.gtceu.max_battery.tooltip": "§7Зарядіть це щоб перемогти Minecraft", + "item.gtceu.max_voltage_coil.tooltip": "Максимальна котушка", + "item.gtceu.meat_dust": "Фарш", + "item.gtceu.micro_processor": "Мікропроцессор", + "item.gtceu.micro_processor.tooltip.0": "§7Вражаюча швидкість обчислень!", + "item.gtceu.micro_processor.tooltip.1": "§eСхема MV рівня", + "item.gtceu.micro_processor_assembly": "Мікропроцесорний вузол", + "item.gtceu.micro_processor_assembly.tooltip.0": "§7Вражаюча швидкість обчислень!", + "item.gtceu.micro_processor_assembly.tooltip.1": "§eСхема HV рівня", + "item.gtceu.micro_processor_computer": "Мікропроцесорний суперкомп'ютер", + "item.gtceu.micro_processor_computer.tooltip.0": "§7Вражаюча швидкість обчислень!", + "item.gtceu.micro_processor_computer.tooltip.1": "§eСхема EV рівня", + "item.gtceu.micro_processor_mainframe": "Мікропроцесорний мейнфрейм", + "item.gtceu.micro_processor_mainframe.tooltip.0": "§7Вражаюча швидкість обчислень!", + "item.gtceu.micro_processor_mainframe.tooltip.1": "§eСхема IV рівня", + "item.gtceu.microchip_processor": "Мікрочіповий процесор", + "item.gtceu.microchip_processor.tooltip.0": "§7Відмінна базова схема", + "item.gtceu.microchip_processor.tooltip.1": "§eСхема LV рівня", + "item.gtceu.mpic_chip": "Чіп MPIC", + "item.gtceu.mpic_chip.tooltip": "§7IC напруги", + "item.gtceu.mpic_wafer": "Підкладка MPIC", + "item.gtceu.mpic_wafer.tooltip": "§7Заготовка потужної схеми", + "item.gtceu.multilayer_fiber_reinforced_circuit_board": "Багатошарова армована волокном плата", + "item.gtceu.multilayer_fiber_reinforced_circuit_board.tooltip": "§7Елітна плата", + "item.gtceu.multilayer_fiber_reinforced_printed_circuit_board": "Багатошарова армована волокном друкована плата", + "item.gtceu.multilayer_fiber_reinforced_printed_circuit_board.tooltip": "§7Елітна плата", + "item.gtceu.mv_battery_hull": "Середній корпус батареї", + "item.gtceu.mv_battery_hull.tooltip": "§7Порожній корпус§b MV§7 батареї", + "item.gtceu.mv_cadmium_battery": "Середня кадмієва батарея", + "item.gtceu.mv_cadmium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.mv_conveyor_module": "MV конвеєрний модуль", + "item.gtceu.mv_electric_motor": "MV електричний мотор", + "item.gtceu.mv_electric_piston": "MV електричний поршень", + "item.gtceu.mv_electric_pump": "MV електрична помпа", + "item.gtceu.mv_emitter": "MV випромінювач", + "item.gtceu.mv_field_generator": "MV генератор поля", + "item.gtceu.mv_fluid_regulator": "MV регулятор рідини", + "item.gtceu.mv_lithium_battery": "Середня літієва батарея", + "item.gtceu.mv_lithium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.mv_power_unit": "MV блок живлення", + "item.gtceu.mv_robot_arm": "MV маніпулятор", + "item.gtceu.mv_sensor": "MV сенсор", + "item.gtceu.mv_sodium_battery": "Середня натрієва батарея", + "item.gtceu.mv_sodium_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.mv_solar_panel": "Сонячна панель середньої напруги", + "item.gtceu.mv_voltage_coil": "Котушка середньої напруги", + "item.gtceu.mv_voltage_coil.tooltip": "Хороша котушка", + "item.gtceu.name_casting_mold": "Відливна форма (Ім'я)", + "item.gtceu.name_casting_mold.tooltip": "§7Форма для іменування предметів у формовому пресі (перейменуйте форму у ковадлі)", + "item.gtceu.nan_certificate": "Сертифікат шо ти вже не нубік", + "item.gtceu.nan_certificate.tooltip": "Виклик прийнято!", + "item.gtceu.nand_chip": "Чіп NAND", + "item.gtceu.nand_chip.tooltip.0": "§7Надзвичайно простий електронний компонент", + "item.gtceu.nand_chip.tooltip.1": "§6Електросхема ULV-рівня", + "item.gtceu.nand_memory_chip": "Чіп пам'яті NAND", + "item.gtceu.nand_memory_chip.tooltip": "§7Логічний вентиль NAND", + "item.gtceu.nand_memory_wafer": "Підкладка пам'яті NAND", + "item.gtceu.nand_memory_wafer.tooltip": "§7Заготовка логічного вентиля", + "item.gtceu.nano_cpu_chip": "Чіп нано CPU", + "item.gtceu.nano_cpu_chip.tooltip": "§7Нано центральний процесорний блок", + "item.gtceu.nano_cpu_wafer": "Підкладка нано CPU", + "item.gtceu.nano_cpu_wafer.tooltip": "§7Заготовка нанотехнічної схеми", + "item.gtceu.nano_processor": "Нанопроцесор", + "item.gtceu.nano_processor.tooltip.0": "§7Менше, ніж будь-коли", + "item.gtceu.nano_processor.tooltip.1": "§bСхема HV рівня", + "item.gtceu.nano_processor_assembly": "Нанопроцесорний вузол", + "item.gtceu.nano_processor_assembly.tooltip.0": "§7Менше, ніж будь-коли", + "item.gtceu.nano_processor_assembly.tooltip.1": "§bСхема EV рівня", + "item.gtceu.nano_processor_computer": "Нанопроцесорний суперкомп'ютер", + "item.gtceu.nano_processor_computer.tooltip.0": "§7Менше, ніж будь-коли", + "item.gtceu.nano_processor_computer.tooltip.1": "§bСхема IV рівня", + "item.gtceu.nano_processor_mainframe": "Нанопроцесорний мейнфрейм", + "item.gtceu.nano_processor_mainframe.tooltip.0": "§7Менше, ніж будь-коли", + "item.gtceu.nano_processor_mainframe.tooltip.1": "§bСхема LuV рівня", + "item.gtceu.nano_saber": "Наношабля", + "item.gtceu.nano_saber.tooltip": "§7Скуштуй меча бога-дракона!", + "item.gtceu.nanomuscle_boots": "Чоботи костюма NanoMuscle™", + "item.gtceu.nanomuscle_chestplate": "Нагрудник костюма NanoMuscle™", + "item.gtceu.nanomuscle_helmet": "Шолом костюма NanoMuscle™", + "item.gtceu.nanomuscle_leggings": "Наголінники костюма NanoMuscle™", + "item.gtceu.naquadah_boule": "Легована наквадою монокристалічна силіконова маса", + "item.gtceu.naquadah_boule.tooltip": "§7Заготовка схеми", + "item.gtceu.naquadah_wafer": "Легована наквадою підкладка", + "item.gtceu.naquadah_wafer.tooltip": "§7Заготовка схеми", + "item.gtceu.neuro_processing_unit": "Нейропроцесорний блок", + "item.gtceu.neuro_processing_unit.tooltip": "§7Нейро CPU", + "item.gtceu.neutron_reflector": "Іридієвий відбивач нейтронів", + "item.gtceu.neutron_reflector.tooltip": "§7Незнищенний", + "item.gtceu.neutronium_boule": "Легована нейтронієм монокристалічна силіконова маса", + "item.gtceu.neutronium_boule.tooltip": "§7Заготовка схеми", + "item.gtceu.neutronium_wafer": "Легована нейтронієм підкладка", + "item.gtceu.neutronium_wafer.tooltip": "§7Заготовка схеми", + "item.gtceu.nightvision_goggles": "Окуляри нічного бачення", + "item.gtceu.nor_memory_chip": "Чіп пам'яті NOR", + "item.gtceu.nor_memory_chip.tooltip": "§7Логічний вентиль NOR", + "item.gtceu.nor_memory_wafer": "Підкладка пам'яті NOR", + "item.gtceu.nor_memory_wafer.tooltip": "§7Заготовка логічного вентиля", + "item.gtceu.normal_pipe_casting_mold": "Відливна форма (труба)", + "item.gtceu.normal_pipe_extruder_mold": "Відтискна форма (труба)", + "item.gtceu.nugget_casting_mold": "Відливна форма (самородок)", + "item.gtceu.nugget_casting_mold.tooltip": "§7Форма для виготовлення самородків", + "item.gtceu.opv_conveyor_module": "OpV конвеєрний модуль", + "item.gtceu.opv_electric_motor": "OpV електричний мотор", + "item.gtceu.opv_electric_piston": "OpV електричний поршень", + "item.gtceu.opv_electric_pump": "OpV електрична помпа", + "item.gtceu.opv_emitter": "OpV випромінювач", + "item.gtceu.opv_field_generator": "OpV генератор поля", + "item.gtceu.opv_fluid_regulator": "OpV регулятор рідини", + "item.gtceu.opv_robot_arm": "OpV маніпулятор", + "item.gtceu.opv_sensor": "OpV сенсор", + "item.gtceu.opv_voltage_coil.tooltip": "Легендарна котушка", + "item.gtceu.orange_dye_spray_can": "Аерозольний балончик (помаранчевий)", + "item.gtceu.orange_glass_lens": "Скляна лінза (Помаранчева)", + "item.gtceu.palladium_raw_dust": "Необроблений паладієвий пил", + "item.gtceu.paper_dust": "Паперова стружка", + "item.gtceu.paracetamol_pill": "Пігулка парацетамолу", + "item.gtceu.petri_dish": "Чашка петри", + "item.gtceu.petri_dish.tooltip": "§7Для вирощування клітин", + "item.gtceu.phenolic_circuit_board": "Фенольна плата", + "item.gtceu.phenolic_circuit_board.tooltip": "§7Хороша плата", + "item.gtceu.phenolic_printed_circuit_board": "Фенольна друкована плата", + "item.gtceu.phenolic_printed_circuit_board.tooltip": "§7Хороша плата", + "item.gtceu.phosphorus_boule": "Легована фосфором монокристалічна силіконова маса", + "item.gtceu.phosphorus_boule.tooltip": "§7Заготовка схеми", + "item.gtceu.phosphorus_wafer": "Легована фосфором підкладка", + "item.gtceu.phosphorus_wafer.tooltip": "§7Заготовка схеми", + "item.gtceu.pickaxe_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення кайл", + "item.gtceu.pill_casting_mold": "Відливна форма (пігулка)", + "item.gtceu.pink_dye_spray_can": "Аерозольний балончик (рожевий)", + "item.gtceu.pink_glass_lens": "Скляна лінза (Рожева)", + "item.gtceu.pipe.huge_casting_mold.tooltip": "§7Форма для відливання повноблочних труб", + "item.gtceu.pipe.huge_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення повноблочних труб", + "item.gtceu.pipe.large_casting_mold.tooltip": "§7Форма для відливання великих труб", + "item.gtceu.pipe.large_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення великих труб", + "item.gtceu.pipe.normal_casting_mold.tooltip": "§7Форма для відливання труб", + "item.gtceu.pipe.normal_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення труб", + "item.gtceu.pipe.small_casting_mold.tooltip": "§7Форма для відливання малих трубPipes", + "item.gtceu.pipe.small_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення малих труб", + "item.gtceu.pipe.tiny_casting_mold.tooltip": "§7Форма для відливання крихітних труб", + "item.gtceu.pipe.tiny_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення крихітних труб", + "item.gtceu.pitchblende_dust": "Настуран", + "item.gtceu.plant_ball": "Рослинна кулька", + "item.gtceu.plastic_circuit_board": "Пластикова плата", + "item.gtceu.plastic_circuit_board.tooltip": "§7Хороша плата", + "item.gtceu.plastic_printed_circuit_board": "Пластикова друкована плата", + "item.gtceu.plastic_printed_circuit_board.tooltip": "§7Хороша плата", + "item.gtceu.plate_casting_mold": "Відливна форма (лист)", + "item.gtceu.plate_casting_mold.tooltip": "§7Форма для виготовлення листів", + "item.gtceu.plate_extruder_mold": "Відтискна форма (лист)", + "item.gtceu.plate_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення листів", + "item.gtceu.platinum_group_sludge_dust": "Шлам платинової групи", + "item.gtceu.platinum_lighter": "Платинова запальничка", + "item.gtceu.platinum_raw_dust": "Пил необробленої платини", + "item.gtceu.platinum_sludge_residue_dust": "Залишок платинового шламу", + "item.gtceu.portable_debug_scanner": "Портативний налагоджувальний сканер", + "item.gtceu.portable_scanner": "Портативний сканер", + "item.gtceu.power_thruster": "Силовий рушій", + "item.gtceu.programmed_circuit": "Програмна плата", + "item.gtceu.programmed_circuit.tooltip.0": "Використайте, щоб відкрити інтерфейс конфігурації", + "item.gtceu.programmed_circuit.tooltip.1": "Shift+ПКМ по машині з гніздом", + "item.gtceu.programmed_circuit.tooltip.2": "плати, щоб встановити її", + "item.gtceu.programmed_circuit.tooltip.3": "на значення цієї плати.", + "item.gtceu.prospector.hv": "Вдосконалений розвідник (HV)", + "item.gtceu.prospector.luv": "Супер розвідник (LuV)", + "item.gtceu.prospector.lv": "Рудошукач (LV)", + "item.gtceu.pure_bentonite_dust": "Очищений пил бентоніту", + "item.gtceu.pure_cassiterite_sand_dust": "Очищений пил каситеритового піску", + "item.gtceu.pure_pitchblende_dust": "Очищений пил настурану", + "item.gtceu.pure_rock_salt_dust": "Очищений пил кам'яної солі", + "item.gtceu.pure_salt_dust": "Очищена сіль", + "item.gtceu.pure_talc_dust": "Очищений пил тальку", + "item.gtceu.purified_bentonite_ore": "Очищений бентоніт", + "item.gtceu.purified_cassiterite_sand_ore": "Очищений каситеритовий пісок", + "item.gtceu.purified_pitchblende_ore": "Очищений настуран", + "item.gtceu.purified_talc_ore": "Очищений тальк", + "item.gtceu.purple_drink": "Фіолетовий напій", + "item.gtceu.purple_dye_spray_can": "Аерозольний балончик (фіолетовий)", + "item.gtceu.purple_glass_lens": "Скляна лінза (Фіолетова)", + "item.gtceu.qbit_cpu_chip": "Чіп кубітного CPU", + "item.gtceu.qbit_cpu_chip.tooltip": "§7Кубітний центральний процесорний блок", + "item.gtceu.qbit_cpu_wafer": "Підкладка кубітного CPU", + "item.gtceu.qbit_cpu_wafer.tooltip": "§7Заготовка кубітної схеми", + "item.gtceu.quantum_eye": "Квантове око", + "item.gtceu.quantum_eye.tooltip": "§7Поліпшене око Енду", + "item.gtceu.quantum_processor": "Квантовий процесор", + "item.gtceu.quantum_processor.tooltip.0": "§7Квантові обчислення оживають!", + "item.gtceu.quantum_processor.tooltip.1": "§aСхема EV рівня", + "item.gtceu.quantum_processor_assembly": "Квантовий процесорний вузол", + "item.gtceu.quantum_processor_assembly.tooltip.0": "§7Квантові обчислення оживають!", + "item.gtceu.quantum_processor_assembly.tooltip.1": "§aСхема IV рівня", + "item.gtceu.quantum_processor_computer": "Квантовий процесорний суперкомп'ютер", + "item.gtceu.quantum_processor_computer.tooltip.0": "§7Квантові обчислення оживають!", + "item.gtceu.quantum_processor_computer.tooltip.1": "§aСхема LuV рівня", + "item.gtceu.quantum_processor_mainframe": "Квантовий процесорний мейнфрейм", + "item.gtceu.quantum_processor_mainframe.tooltip.0": "§7Квантові обчислення оживають!", + "item.gtceu.quantum_processor_mainframe.tooltip.1": "§aСхема ZPM рівня", + "item.gtceu.quantum_star": "Квантова зірка", + "item.gtceu.quantum_star.tooltip": "§7Поліпшена зірка Незеру", + "item.gtceu.quarktech_boots": "Чоботи косюма QuarkTech™", + "item.gtceu.quarktech_chestplate": "Нагрудник косюма QuarkTech™", + "item.gtceu.quarktech_helmet": "Шолом косюма QuarkTech™", + "item.gtceu.quarktech_leggings": "Наголінники косюма QuarkTech™", + "item.gtceu.quartz_sand_dust": "Кварцовий пісок", + "item.gtceu.rad_away_pill": "Пігулка антирадину™", + "item.gtceu.ram_chip": "Чіп RAM", + "item.gtceu.ram_chip.tooltip": "§7Оперативна пам'ять", + "item.gtceu.ram_wafer": "Підкладка RAM", + "item.gtceu.ram_wafer.tooltip": "§7Заготовка пам'яті", + "item.gtceu.rare_earth_dust": "Рідкісноземельний пил", + "item.gtceu.rarest_metal_mixture_dust": "Суміш найрідкісніших металів", + "item.gtceu.raw_crystal_chip": "Заготовка кришталевого чіпу", + "item.gtceu.raw_crystal_chip.tooltip": "§7Заготовка кришталевого чіпу", + "item.gtceu.raw_crystal_chip_parts": "Частинки заготовки кристалічного чіпу", + "item.gtceu.raw_crystal_chip_parts.tooltip": "§7Частинки заготовки кристалічного процесора", + "item.gtceu.red_dye_spray_can": "Аерозольний балончик (червоний)", + "item.gtceu.red_glass_lens": "Скляна лінза (Червона)", + "item.gtceu.refined_bentonite_ore": "Рафінований бентоніт", + "item.gtceu.refined_cassiterite_sand_ore": "Рафінований каситеритовий пісок", + "item.gtceu.refined_pitchblende_ore": "Рафінований настуран", + "item.gtceu.refined_talc_ore": "Рафінований тальк", + "item.gtceu.resin_circuit_board": "Резинова плата", + "item.gtceu.resin_circuit_board.tooltip": "§7Покрита плата", + "item.gtceu.resin_printed_circuit_board": "Резинова друкована плата", + "item.gtceu.resin_printed_circuit_board.tooltip": "§7Базова плата", + "item.gtceu.resistor": "Резистор", + "item.gtceu.resistor.tooltip": "§7Базовий електронний компонент", + "item.gtceu.ring_extruder_mold": "Відтискна форма (кільце)", + "item.gtceu.ring_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення кілець", + "item.gtceu.robot.arm.tooltip": "§7Обмежує§f предмети§7 до певної кількості як§f кришка§7.", + "item.gtceu.rock_salt_dust": "Кам'яна сіль", + "item.gtceu.rod_extruder_mold": "Відтискна форма (стрижень)", + "item.gtceu.rod_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення стрижнів", + "item.gtceu.rod_long_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення довгих стрижнів", + "item.gtceu.rotor_casting_mold": "Відливна форма (ротор)", + "item.gtceu.rotor_casting_mold.tooltip": "§7Форма для виготовлення роторів", + "item.gtceu.rotor_extruder_mold": "Відтискна форма (Rotor)", + "item.gtceu.rotor_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення роторів", + "item.gtceu.rubber_boat": "Каучуковий човен", + "item.gtceu.rubber_chest_boat": "Каучуковий човен зі скринею", + "item.gtceu.rubber_gloves": "Гумові рукавиці", + "item.gtceu.salt_dust": "Сіль", + "item.gtceu.saw_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення пил", + "item.gtceu.shovel_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення лоавт", + "item.gtceu.shutter_module_cover": "Модуль затвору", + "item.gtceu.shutter_module_cover.tooltip": "§fПереміщує блоки§7 через приєднаний бік як§f кришка§7.", + "item.gtceu.silicon_boule": "Монокристалічна силіконова маса", + "item.gtceu.silicon_boule.tooltip": "§7Заготовка схеми", + "item.gtceu.silicon_wafer": "Силіконова підкладка", + "item.gtceu.silicon_wafer.tooltip": "§7Заготовка схеми", + "item.gtceu.simple_soc": "Базова SoC", + "item.gtceu.simple_soc.tooltip": "§7Базова система на чіпі", + "item.gtceu.simple_soc_wafer": "Підкладка базової SoC", + "item.gtceu.simple_soc_wafer.tooltip": "§7Заготовка простої схеми", + "item.gtceu.small_ash_dust": "Дрібний пил попелу", + "item.gtceu.small_basaltic_mineral_sand_dust": "Дрібний пил базальтового мінерального піску", + "item.gtceu.small_bentonite_dust": "Дрібний пил бентоніту", + "item.gtceu.small_blaze_dust": "Дрібний порох пломеня", + "item.gtceu.small_bone_dust": "Дрібне кісткове борошно", + "item.gtceu.small_cassiterite_sand_dust": "Дрібний пил каситеритового піску", + "item.gtceu.small_dark_ash_dust": "Дрібний темний попіл", + "item.gtceu.small_fullers_earth_dust": "Дрібний пил відбілювальних глин", + "item.gtceu.small_garnet_sand_dust": "Дрібний пил гранатового піску", + "item.gtceu.small_gear_casting_mold": "Відливна форма (мала шестерня)", + "item.gtceu.small_gear_extruder_mold": "Відтискна форма (мала шестерня)", + "item.gtceu.small_glauconite_sand_dust": "Дрібний пил глауконітового піску", + "item.gtceu.small_granitic_mineral_sand_dust": "Дрібний пил гранітового мінерального піску", + "item.gtceu.small_gunpowder_dust": "Дрібний порох", + "item.gtceu.small_ice_dust": "Колотий лід", + "item.gtceu.small_inert_metal_mixture_dust": "Дрібний пил суміші інертних металів", + "item.gtceu.small_iridium_metal_residue_dust": "Дрібний пил металевого залишку іридію", + "item.gtceu.small_meat_dust": "Дрібний фарш", + "item.gtceu.small_palladium_raw_dust": "Дрібний необроблений паладієвий пил", + "item.gtceu.small_paper_dust": "Дрібна паперова стружка", + "item.gtceu.small_pipe_casting_mold": "Відливна форма (мала труба)", + "item.gtceu.small_pipe_extruder_mold": "Відтискна форма (мала труба)", + "item.gtceu.small_pitchblende_dust": "Дрібний пил настурану", + "item.gtceu.small_platinum_group_sludge_dust": "Дрібний пил шламу платинової групи", + "item.gtceu.small_platinum_raw_dust": "Дрібний необроблений платиновий пил", + "item.gtceu.small_platinum_sludge_residue_dust": "Дрібний пил залишку платинового шламу", + "item.gtceu.small_quartz_sand_dust": "Дрібний пил кварцового піску", + "item.gtceu.small_rare_earth_dust": "Дрібний рідкісноземельний пил", + "item.gtceu.small_rarest_metal_mixture_dust": "Дрібний пил суміші найрідкісніших металів", + "item.gtceu.small_rock_salt_dust": "Дрібний пил кам'яної солі", + "item.gtceu.small_salt_dust": "Дрібна сіль", + "item.gtceu.small_sugar_dust": "Дрібний цукор", + "item.gtceu.small_talc_dust": "Дрібний пил тальку", + "item.gtceu.small_treated_wood_dust": "Дрібна оброблена деревна целюлоза", + "item.gtceu.small_wheat_dust": "Дрібне борошно", + "item.gtceu.small_wood_dust": "Дрібна деревна целюлоза", + "item.gtceu.smd_capacitor": "SMD конденсатор", + "item.gtceu.smd_capacitor.tooltip": "§7Електронний компонент", + "item.gtceu.smd_diode": "SMD діод", + "item.gtceu.smd_diode.tooltip": "§7Електронний компонент", + "item.gtceu.smd_inductor": "SMD індуктор", + "item.gtceu.smd_inductor.tooltip": "§7Електронний компонент", + "item.gtceu.smd_resistor": "SMD резистор", + "item.gtceu.smd_resistor.tooltip": "§7Електронний компонент", + "item.gtceu.smd_transistor": "SMD транзистор", + "item.gtceu.smd_transistor.tooltip": "§7Електронний компонент", + "item.gtceu.soc": "SoC", + "item.gtceu.soc.tooltip": "§7Система на чіпі", + "item.gtceu.soc_wafer": "Підкладка SoC", + "item.gtceu.soc_wafer.tooltip": "§7Заготовка базової схеми", + "item.gtceu.solar_panel": "Сонячна панель", + "item.gtceu.solar_panel.tooltip.0": "§7Нехай сонце буде з вами.", + "item.gtceu.solar_panel.tooltip.1": "Виробляє§f енергію§7 з§e сонця§7 як§f кришка§7.", + "item.gtceu.solvent_spray_can": "Аерозольний балончик (Розчинник)", + "item.gtceu.stainless_steel_fluid_cell": "Нержавіюча сталева комірка (%s)", + "item.gtceu.steel_fluid_cell": "Сталева комірка (%s)", + "item.gtceu.steel_minecart_wheels": "Сталеві колеса вагонетки", + "item.gtceu.stem_cells": "Стовбурові клітини", + "item.gtceu.stem_cells.tooltip": "§7Сирий розум", + "item.gtceu.sticky_resin": "Липка смола", + "item.gtceu.storage_cover": "Кришка сховища", + "item.gtceu.sugar_gem": "Кубик цукру", + "item.gtceu.sus_record": "Платівка", + "item.gtceu.sus_record.desc": "§7підозріло!", + "item.gtceu.sword_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення мечів", + "item.gtceu.tag_filter.tooltip.0": "§7Фільтрує§f предметний§7 вхід/вихід із§f тегами§7 як§f кришка§7.", + "item.gtceu.tag_filter.tooltip.1": "Може використовуватися як§f конвеєрний модуль§7 та покращення§f маніпулятора§7.", + "item.gtceu.talc_dust": "Тальк", + "item.gtceu.tantalum_capacitor": "Танталовий конденсатор", + "item.gtceu.terminal": "Термінал", + "item.gtceu.terminal.tooltip": "Shift+ПКМ по контролеру для автоматичної побудови конструкції", + "item.gtceu.text_module": "Модуль тексту", + "item.gtceu.tiny_ash_dust": "Крихта пилу попелу", + "item.gtceu.tiny_basaltic_mineral_sand_dust": "Крихта пилу базальтового мінерального піску", + "item.gtceu.tiny_bentonite_dust": "Крихта пилу бентоніту", + "item.gtceu.tiny_blaze_dust": "Крихта пороху пломеня", + "item.gtceu.tiny_bone_dust": "Крихта кісткового борошна", + "item.gtceu.tiny_cassiterite_sand_dust": "Крихта пилу каситеритового піску", + "item.gtceu.tiny_dark_ash_dust": "Крихта темного попелу", + "item.gtceu.tiny_fullers_earth_dust": "Крихта пилу відбілювальних глин", + "item.gtceu.tiny_garnet_sand_dust": "Крихта пилу гранатового піску", + "item.gtceu.tiny_glauconite_sand_dust": "Крихта пилу глауконітового піску", + "item.gtceu.tiny_granitic_mineral_sand_dust": "Крихта пилу гранітового мінерального піску", + "item.gtceu.tiny_gunpowder_dust": "Крихта пороху", + "item.gtceu.tiny_ice_dust": "Крихта подрібненого льоду", + "item.gtceu.tiny_inert_metal_mixture_dust": "Крихта пилу суміші інертних металів", + "item.gtceu.tiny_iridium_metal_residue_dust": "Крихта пилу металевого залишку іридію", + "item.gtceu.tiny_meat_dust": "Крихта фаршу", + "item.gtceu.tiny_palladium_raw_dust": "Крихта необробленого паладієвого пилу", + "item.gtceu.tiny_paper_dust": "Крихітна паперова стружка", + "item.gtceu.tiny_pipe_casting_mold": "Відливна форма (крихітна труба)", + "item.gtceu.tiny_pipe_extruder_mold": "Відтискна форма (крихітна труба)", + "item.gtceu.tiny_pitchblende_dust": "Крихта пилу настурану", + "item.gtceu.tiny_platinum_group_sludge_dust": "Крихта пилу шламу платинової групи", + "item.gtceu.tiny_platinum_raw_dust": "Крихта необробленого платинового пилу", + "item.gtceu.tiny_platinum_sludge_residue_dust": "Крихта пилу залишку платинового шламу", + "item.gtceu.tiny_quartz_sand_dust": "Крихта пилу кварцового піску", + "item.gtceu.tiny_rare_earth_dust": "Крихта рідкісноземельного пилу", + "item.gtceu.tiny_rarest_metal_mixture_dust": "Крихта пилу суміші найрідкісніших металів", + "item.gtceu.tiny_rock_salt_dust": "Крихта пилу кам'яної солі", + "item.gtceu.tiny_salt_dust": "Крихта солі", + "item.gtceu.tiny_sugar_dust": "Крихта цукру", + "item.gtceu.tiny_talc_dust": "Крихта пилу тальку", + "item.gtceu.tiny_treated_wood_dust": "Крихта обробленої деревної целюлози", + "item.gtceu.tiny_wheat_dust": "Крихта борошна", + "item.gtceu.tiny_wood_dust": "Крихта деревної целюлози", + "item.gtceu.titanium_fluid_cell": "Титанова комірка (%s)", + "item.gtceu.tool.aoe.columns": "Колони", + "item.gtceu.tool.aoe.layers": " Шари", + "item.gtceu.tool.aoe.rows": "Рядки", + "item.gtceu.tool.axe": "Сокира (%s)", + "item.gtceu.tool.behavior.aoe_mining": "§5Ефект по площі:§f %sx%sx%s", + "item.gtceu.tool.behavior.block_rotation": "§2Механіка:§f обертає блоки", + "item.gtceu.tool.behavior.crop_harvesting": "§aЖнивар:§f збирає дозрілі культури", + "item.gtceu.tool.behavior.damage_boost": "§4Збільшення шкоди:§f додаткова шкода проти %s", + "item.gtceu.tool.behavior.dowse_campfire": "§Вогнеборець: §fгасить багаття", + "item.gtceu.tool.behavior.grass_path": "§eКаток:§f створює трав'яні доріжки", + "item.gtceu.tool.behavior.ground_tilling": "§eФермер:§f оре ґрунт", + "item.gtceu.tool.behavior.plunger": "§9Вантуз:§f викачує рідини", + "item.gtceu.tool.behavior.prospecting.air": "Знайдено повітряну кишеню", + "item.gtceu.tool.behavior.prospecting.changing": "Виявлено зміну матеріала", + "item.gtceu.tool.behavior.prospecting.lava": "Знайдено лаву", + "item.gtceu.tool.behavior.prospecting.ore": "Знайдено руду: %s", + "item.gtceu.tool.behavior.prospecting.water": "Знайдено воду", + "item.gtceu.tool.behavior.rail_rotation": "§eЗалізничний інженер:§f повертає рейки", + "item.gtceu.tool.behavior.relocate_mining": "§2Магнетизм:§f телепортує добуті блоки та дроп мобів", + "item.gtceu.tool.behavior.remove_wax": "§6Очисник:§f знімає віск", + "item.gtceu.tool.behavior.scrape": "§bПолірувальник:§f видаляє окиснення", + "item.gtceu.tool.behavior.shield_disable": "§cБрутал:§f знешкоджує щити", + "item.gtceu.tool.behavior.silk_ice": "§bЛьодоріз:§f шовково добуває лід", + "item.gtceu.tool.behavior.strip_log": "§5Ремісник:§f обсічує колоди", + "item.gtceu.tool.behavior.torch_place": "§eСпелеолог:§f розміщує смолоскипи на ПКМ", + "item.gtceu.tool.behavior.tree_felling": "§4Лісоруб:§f повалює дерева", + "item.gtceu.tool.butchery_knife": "М'ясний ніж (%s)", + "item.gtceu.tool.butchery_knife.tooltip": "§8Має низьку швидкість атаки", + "item.gtceu.tool.buzzsaw": "LV електропила (%s)", + "item.gtceu.tool.buzzsaw.tooltip": "§8Не підходить для збору блоків", + "item.gtceu.tool.crowbar": "Лом (%s)", + "item.gtceu.tool.crowbar.tooltip": "§8Знімає кришки", + "item.gtceu.tool.ev_drill": "EV Бур (%s)", + "item.gtceu.tool.file": "Напилок (%s)", + "item.gtceu.tool.hammer": "Молот (%s)", + "item.gtceu.tool.hammer.tooltip": "§8Подрібнює блоки при добуванні", + "item.gtceu.tool.harvest_level.0": "§8Дерево", + "item.gtceu.tool.harvest_level.1": "§7Камінь", + "item.gtceu.tool.harvest_level.2": "§aЗалізо", + "item.gtceu.tool.harvest_level.3": "§bДіамант", + "item.gtceu.tool.harvest_level.4": "§dНезерит", + "item.gtceu.tool.harvest_level.5": "§9Дюран", + "item.gtceu.tool.harvest_level.6": "§cНейтроній", + "item.gtceu.tool.hoe": "Мотика (%s)", + "item.gtceu.tool.hv_chainsaw": "HV ланцюгова пила (%s)", + "item.gtceu.tool.hv_drill": "HV Бур (%s)", + "item.gtceu.tool.hv_wirecutter": "HV кусачки (%s)", + "item.gtceu.tool.hv_wrench": "HV гайковерт (%s)", + "item.gtceu.tool.hv_wrench.tooltip": "§8Утримуйте ЛКМ, щоб демонтовувати машини", + "item.gtceu.tool.iv_drill": "IV Бур (%s)", + "item.gtceu.tool.iv_wirecutter": "IV кусачки (%s)", + "item.gtceu.tool.iv_wrench": "IV гайковерт (%s)", + "item.gtceu.tool.iv_wrench.tooltip": "§8Утримуйте ЛКМ, щоб демонтовувати машини", + "item.gtceu.tool.knife": "Ніж (%s)", + "item.gtceu.tool.lighter.platinum.tooltip": "§7На ній викарбуваний відомий майстер пранків", + "item.gtceu.tool.lv_chainsaw": "LV ланцюгова пила (%s)", + "item.gtceu.tool.lv_drill": "LV Бур (%s)", + "item.gtceu.tool.lv_screwdriver": "LV викрутка (%s)", + "item.gtceu.tool.lv_screwdriver.tooltip": "§8Налаштовує кришки та машини", + "item.gtceu.tool.lv_wirecutter": "LV кусачки (%s)", + "item.gtceu.tool.lv_wrench": "LV гайковерт (%s)", + "item.gtceu.tool.lv_wrench.tooltip": "§8Утримуйте ЛКМ, щоб демонтовувати машини", + "item.gtceu.tool.mallet": "Киянка (%s)", + "item.gtceu.tool.mallet.tooltip.0": "§8Клацніть по машині крадькома, щоб зупинити її по завершенню поточної операції.", + "item.gtceu.tool.mallet.tooltip.1": "§8Зупиняє/запускає машини", + "item.gtceu.tool.matchbox.tooltip": "§7Це не авто", + "item.gtceu.tool.mining_hammer": "Шахтарський молот (%s)", + "item.gtceu.tool.mining_hammer.tooltip": "§8Добуває більшою площею (поки ви не крадетесь)", + "item.gtceu.tool.mortar": "Ступка (%s)", + "item.gtceu.tool.mv_chainsaw": "MV ланцюгова пила (%s)", + "item.gtceu.tool.mv_drill": "MV Бур (%s)", + "item.gtceu.tool.pickaxe": "Кайло (%s)", + "item.gtceu.tool.plunger": "Вантуз (%s)", + "item.gtceu.tool.plunger.tooltip": "§8Видаляє рідини з машин", + "item.gtceu.tool.replace_tool_head": "Об'єднайте з іншою головкою інструмента, щоб замінити її", + "item.gtceu.tool.rolling_pin": "Качалка (%s)", + "item.gtceu.tool.saw": "Пила (%s)", + "item.gtceu.tool.screwdriver": "Викрутка (%s)", + "item.gtceu.tool.screwdriver.tooltip": "§8Налаштовує кришки та машини", + "item.gtceu.tool.scythe": "Коса (%s)", + "item.gtceu.tool.scythe.tooltip": "§8Тому що коса не має сенсу", + "item.gtceu.tool.shears": "Ножиці (%s)", + "item.gtceu.tool.shovel": "Лопата (%s)", + "item.gtceu.tool.spade": "Заступ (%s)", + "item.gtceu.tool.spade.tooltip": "§8Добуває більшою площею (поки ви не крадетесь)", + "item.gtceu.tool.sword": "Меч (%s)", + "item.gtceu.tool.tooltip.attack_damage": "%s§c шкоди від атаки", + "item.gtceu.tool.tooltip.attack_speed": "%s§9 швидкости атаки", + "item.gtceu.tool.tooltip.crafting_uses": "%s§a використань у майструванні", + "item.gtceu.tool.tooltip.default_enchantments": "§5Усталені чари:", + "item.gtceu.tool.tooltip.general_uses": "%s§b міцности", + "item.gtceu.tool.tooltip.harvest_level": "§eРівень добування %s", + "item.gtceu.tool.tooltip.harvest_level_extra": "§eРівень добування %s§f (%s§f)", + "item.gtceu.tool.tooltip.max_uses": "%s§e загальної міцности", + "item.gtceu.tool.tooltip.mining_speed": "%s§d швидкости добування", + "item.gtceu.tool.tooltip.repair_info": "§8Утримуйте Shift, щоб показати інформацію з ремонтування", + "item.gtceu.tool.tooltip.repair_material": "§8Придатне для ремонту:§f§a %s", + "item.gtceu.tool.usable_as": "§8Використовується як:§f %s", + "item.gtceu.tool.wire_cutter": "Кусачки (%s)", + "item.gtceu.tool.wrench": "Гайковий ключ (%s)", + "item.gtceu.tool.wrench.tooltip": "§8Утримуйте ЛКМ, щоб демонтовувати машини", + "item.gtceu.transistor": "Транзистор", + "item.gtceu.transistor.tooltip": "§7Базовий електронний компонент", + "item.gtceu.treated_wood_boat": "Оброблений дерев'яний човен", + "item.gtceu.treated_wood_bolt": "Коротка оброблена дерев'яна палиця", + "item.gtceu.treated_wood_chest_boat": "Оброблений дерев'яний човен зі скринею", + "item.gtceu.treated_wood_dust": "Оброблена дерев'яна стружка", + "item.gtceu.treated_wood_plate": "Оброблена дерев'яна дошка", + "item.gtceu.treated_wood_rod": "Оброблена дерев'яна палиця", + "item.gtceu.tungsten_grinding_head": "Вольфрамова шліфувальна головка", + "item.gtceu.tungsten_steel_fluid_cell": "Вольфрамова сталева комірка (%s)", + "item.gtceu.turbine_rotor": "Ротор турбіни (%s)", + "item.gtceu.turbine_rotor.tooltip": "Ротор турбін для вашої електростанції", + "item.gtceu.uev_conveyor_module": "UEV конвеєрний модуль", + "item.gtceu.uev_electric_motor": "UEV електричний мотор", + "item.gtceu.uev_electric_piston": "UEV електричний поршень", + "item.gtceu.uev_electric_pump": "UEV електрична помпа", + "item.gtceu.uev_emitter": "UEV випромінювач", + "item.gtceu.uev_field_generator": "UEV генератор поля", + "item.gtceu.uev_fluid_regulator": "UEV регулятор рідини", + "item.gtceu.uev_robot_arm": "UEV маніпулятор", + "item.gtceu.uev_sensor": "UEV сенсор", + "item.gtceu.uev_voltage_coil.tooltip": "Нереальна котушка", + "item.gtceu.uhpic_chip": "Чіп UHPIC", + "item.gtceu.uhpic_chip.tooltip": "§7IC надмірно високої напруги", + "item.gtceu.uhpic_wafer": "Підкладка UHPIC", + "item.gtceu.uhpic_wafer.tooltip": "§7Заготовка надвисокопотужної схеми", + "item.gtceu.uhv_conveyor_module": "UHV конвеєрний модуль", + "item.gtceu.uhv_electric_motor": "UHV електричний мотор", + "item.gtceu.uhv_electric_piston": "UHV електричний поршень", + "item.gtceu.uhv_electric_pump": "UHV електрична помпа", + "item.gtceu.uhv_emitter": "UHV випромінювач", + "item.gtceu.uhv_field_generator": "UHV генератор поля", + "item.gtceu.uhv_fluid_regulator": "UHV регулятор рідини", + "item.gtceu.uhv_robot_arm": "UHV маніпулятор", + "item.gtceu.uhv_sensor": "UHV сенсор", + "item.gtceu.uhv_voltage_coil.tooltip": "Ультракотушка", + "item.gtceu.uiv_conveyor_module": "UIV конвеєрний модуль", + "item.gtceu.uiv_electric_motor": "UIV електричний мотор", + "item.gtceu.uiv_electric_piston": "UIV електричний поршень", + "item.gtceu.uiv_electric_pump": "UIV електрична помпа", + "item.gtceu.uiv_emitter": "UIV випромінювач", + "item.gtceu.uiv_field_generator": "UIV генератор поля", + "item.gtceu.uiv_fluid_regulator": "UIV регулятор рідини", + "item.gtceu.uiv_robot_arm": "UIV маніпулятор", + "item.gtceu.uiv_sensor": "UIV сенсор", + "item.gtceu.uiv_voltage_coil.tooltip": "Божевільна котушка", + "item.gtceu.ulpic_chip": "Чіп ULPIC", + "item.gtceu.ulpic_chip.tooltip": "§7IC надмірно низької напруги", + "item.gtceu.ulpic_wafer": "Підкладка ULPIC", + "item.gtceu.ulpic_wafer.tooltip": "§7Заготовка наднизькопотужної схеми", + "item.gtceu.ulv_solar_panel": "Сонячна панель ультранизької напруги", + "item.gtceu.ulv_tantalum_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.ulv_voltage_coil": "Котушка надмірно низької напруги", + "item.gtceu.ulv_voltage_coil.tooltip": "Примітивна котушка", + "item.gtceu.universal_fluid_cell": "Універсальна комірка (%s)", + "item.gtceu.uv_battery_hull": "Великий корпус наквадрієвої батареї", + "item.gtceu.uv_battery_hull.tooltip": "§7Порожній корпус§3 UV§7 батареї", + "item.gtceu.uv_conveyor_module": "UV конвеєрний модуль", + "item.gtceu.uv_electric_motor": "UV електричний мотор", + "item.gtceu.uv_electric_piston": "UV електричний поршень", + "item.gtceu.uv_electric_pump": "UV електрична помпа", + "item.gtceu.uv_emitter": "UV випромінювач", + "item.gtceu.uv_field_generator": "UV генератор поля", + "item.gtceu.uv_fluid_regulator": "UV регулятор рідини", + "item.gtceu.uv_naquadria_battery": "Велика наквадрієва батарея", + "item.gtceu.uv_naquadria_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.uv_robot_arm": "UV маніпулятор", + "item.gtceu.uv_sensor": "UV сенсор", + "item.gtceu.uv_solar_panel": "Сонячна панель ультимативної напруги", + "item.gtceu.uv_voltage_coil": "Котушка ультимативної напруги", + "item.gtceu.uv_voltage_coil.tooltip": "Ультимативна котушка", + "item.gtceu.uxv_conveyor_module": "UXV конвеєрний модуль", + "item.gtceu.uxv_electric_motor": "UXV електричний мотор", + "item.gtceu.uxv_electric_piston": "UXV електричний поршень", + "item.gtceu.uxv_electric_pump": "UXV електрична помпа", + "item.gtceu.uxv_emitter": "UXV випромінювач", + "item.gtceu.uxv_field_generator": "UXV генератор поля", + "item.gtceu.uxv_fluid_regulator": "UXV регулятор рідини", + "item.gtceu.uxv_robot_arm": "UXV маніпулятор", + "item.gtceu.uxv_sensor": "UXV сенсор", + "item.gtceu.uxv_voltage_coil.tooltip": "Епічна котушка", + "item.gtceu.vacuum_tube": "Вакуумна трубка", + "item.gtceu.vacuum_tube.tooltip.0": "§7Технічно це діод", + "item.gtceu.vacuum_tube.tooltip.1": "§cULV-рівень", + "item.gtceu.wetware_circuit_board": "Животехічна плата", + "item.gtceu.wetware_circuit_board.tooltip": "§7Плата, що містить життя", + "item.gtceu.wetware_printed_circuit_board": "Животехічна друкована плата", + "item.gtceu.wetware_printed_circuit_board.tooltip": "§7Плата, що містить життя", + "item.gtceu.wetware_processor": "Животехнічний процесор", + "item.gtceu.wetware_processor.tooltip.0": "§7Він ніби спостерігає за вами", + "item.gtceu.wetware_processor.tooltip.1": "§4Схема LuV рівня", + "item.gtceu.wetware_processor_assembly": "Животехнічний процесорний вузол", + "item.gtceu.wetware_processor_assembly.tooltip.0": "§7Може запустити Minecraft", + "item.gtceu.wetware_processor_assembly.tooltip.1": "§4Схема ZPM рівня", + "item.gtceu.wetware_processor_computer": "Животехнічний процесорний суперкомп'ютер", + "item.gtceu.wetware_processor_computer.tooltip.0": "§7Остаточне злиття плоті та машини", + "item.gtceu.wetware_processor_computer.tooltip.1": "§4Схема UV рівня", + "item.gtceu.wetware_processor_mainframe": "Животехнічний процесорний мейнфрейм", + "item.gtceu.wetware_processor_mainframe.tooltip.0": "§7Краще, що коли-небудь хтось бачив", + "item.gtceu.wetware_processor_mainframe.tooltip.1": "§4Схема UHV рівня", + "item.gtceu.wheat_dust": "Борошно", + "item.gtceu.white_dye_spray_can": "Аерозольний балончик (білий)", + "item.gtceu.wire_extruder_mold": "Відтискна форма (дріт)", + "item.gtceu.wire_extruder_mold.tooltip": "§7Формовий відтиск для виготовлення дротів", + "item.gtceu.wireless_transmitter_cover": "Бездротовий передавач", + "item.gtceu.wood_bolt": "Коротка палиця", + "item.gtceu.wood_dust": "Дерев'яна стружка", + "item.gtceu.wood_plate": "Дерев'яна дошка", + "item.gtceu.yellow_dye_spray_can": "Аерозольний балончик (жовтий)", + "item.gtceu.yellow_glass_lens": "Скляна лінза (Жовта)", + "item.gtceu.zero_point_module": "Модуль нульової точки", + "item.gtceu.zpm_battery_hull": "Середній корпус наквадрієвої батареї", + "item.gtceu.zpm_battery_hull.tooltip": "§7Порожній корпус§f ZPM§7 батареї", + "item.gtceu.zpm_conveyor_module": "ZPM конвеєрний модуль", + "item.gtceu.zpm_electric_motor": "ZPM електричний мотор", + "item.gtceu.zpm_electric_piston": "ZPM електричний поршень", + "item.gtceu.zpm_electric_pump": "ZPM електрична помпа", + "item.gtceu.zpm_emitter": "ZPM випромінювач", + "item.gtceu.zpm_field_generator": "ZPM генератор поля", + "item.gtceu.zpm_fluid_regulator": "ZPM регулятор рідини", + "item.gtceu.zpm_naquadria_battery": "Середня наквадрієва батарея", + "item.gtceu.zpm_naquadria_battery.tooltip": "§7Багаторазова батарея", + "item.gtceu.zpm_robot_arm": "ZPM маніпулятор", + "item.gtceu.zpm_sensor": "ZPM сенсор", + "item.gtceu.zpm_solar_panel": "Сонячна панель модуля нульової точки", + "item.gtceu.zpm_voltage_coil": "Котушки напруги модуля нульової точки", + "item.gtceu.zpm_voltage_coil.tooltip": "Суперкотушка", + "item.invalid.name": "Неприпустимий предмет", + "item.netherrack_nether_quartz": "Незерська кварцова руда", + "item.toggle.advanced.info.tooltip": "§8<Крадіться, щоб відобразити конфігурацію зберігання>", + "itemGroup.gtceu.decoration": "GregTechCEu: Декоративні блоки", + "itemGroup.gtceu.item": "GregTechCEu: Предмети", + "itemGroup.gtceu.machine": "GregTechCEU: Машини", + "itemGroup.gtceu.material_block": "GregTechCEu: Блоки матеріалів", + "itemGroup.gtceu.material_fluid": "GregTechCEu: Рідинні ємності матеріалів", + "itemGroup.gtceu.material_item": "GregTechCEu: Предмети матеріалів", + "itemGroup.gtceu.material_pipe": "GregTechCEu: Труби", + "itemGroup.gtceu.tool": "GregTechCEu: Інструменти", + "ldlib.gui.editor.group.widget.gtm_container": "GTM: Віджети контейнерів", + "ldlib.gui.editor.register.editor.gtceu.mui": "Проєкт машинного інтерфейсу", + "ldlib.gui.editor.register.editor.gtceu.rtui": "Проєкт інтерфейсу типу рецепта", + "ldlib.gui.editor.register.editor.gtceu.template_tab": "шаблони", + "ldlib.gui.editor.register.widget.container.gtm_fluid_slot": "GTM: Рідинний слот", + "ldlib.gui.editor.register.widget.container.gtm_item_slot": "GTM: Предметний слот", + "ldlib.gui.editor.register.widget.container.gtm_phantom_fluid_slot": "GTM: Фантомний рідинний слот", + "ldlib.gui.editor.register.widget.container.gtm_phantom_item_slot": "GTM: Фантомний предметний слот", + "mataarmor.hud.supply_mode": "Режим живлення: %s", + "material.gtceu.acetic_acid": "Оцтова кислота", + "material.gtceu.acetic_anhydride": "Оцтовий ангідрид", + "material.gtceu.acetone": "Ацетон", + "material.gtceu.acidic_enriched_naquadah_solution": "Кислотний збагачений розчин наквади", + "material.gtceu.acidic_naquadria_solution": "Кислотний розчин наквадрії", + "material.gtceu.acidic_osmium_solution": "Розчин осмієвої кислоти", + "material.gtceu.actinium": "Актиній", + "material.gtceu.activated_carbon": "Активоване вугілля", + "material.gtceu.agar": "Агар", + "material.gtceu.air": "Повітря", + "material.gtceu.allyl_chloride": "Алілхлорид", + "material.gtceu.almandine": "Альмандин", + "material.gtceu.aluminium": "Алюміній", + "material.gtceu.aluminium_sulfite": "Сульфіт алюмінію", + "material.gtceu.alunite": "Алуніт", + "material.gtceu.americium": "Америцій", + "material.gtceu.amethyst": "Аметист", + "material.gtceu.aminophenol": "Амінофенол", + "material.gtceu.ammonia": "Аміак", + "material.gtceu.ammonium_chloride": "Хлорид амонію", + "material.gtceu.ammonium_formate": "Форміат амонію", + "material.gtceu.andesite": "Андезит", + "material.gtceu.andradite": "Андрадит", + "material.gtceu.annealed_copper": "Відпалена мідь", + "material.gtceu.antimony": "Стибій", + "material.gtceu.antimony_trifluoride": "Фторид стибію", + "material.gtceu.antimony_trioxide": "Оксид стибію", + "material.gtceu.apatite": "Апатит", + "material.gtceu.aqua_regia": "Гетьманська горілка", + "material.gtceu.argon": "Аргон", + "material.gtceu.arsenic": "Арсен", + "material.gtceu.arsenic_trioxide": "Оксид арсену", + "material.gtceu.asbestos": "Азбест", + "material.gtceu.ash": "Попіл", + "material.gtceu.astatine": "Астат", + "material.gtceu.bacteria": "Бактерії", + "material.gtceu.bacterial_sludge": "Бактерієвий шлам", + "material.gtceu.barite": "Барит", + "material.gtceu.barium": "Барій", + "material.gtceu.barium_sulfide": "Сульфід барію", + "material.gtceu.basalt": "Базальт", + "material.gtceu.basaltic_mineral_sand": "Базальтовий мінеральний пісок", + "material.gtceu.bastnasite": "Бастнезит", + "material.gtceu.battery_alloy": "Батарейний злиток", + "material.gtceu.bauxite": "Боксит", + "material.gtceu.bauxite_slag": "Бокситовий шлак", + "material.gtceu.bauxite_sludge": "Бокситовий шлам", + "material.gtceu.bauxite_slurry": "Бокситова суспензія", + "material.gtceu.bentonite": "Бентоніт", + "material.gtceu.benzene": "Бензен", + "material.gtceu.berkelium": "Берклій", + "material.gtceu.beryllium": "Берилій", + "material.gtceu.bio_diesel": "Біодизель", + "material.gtceu.biomass": "Біомаса", + "material.gtceu.biotite": "Біотит", + "material.gtceu.biphenyl": "Діфеніл", + "material.gtceu.bismuth": "Бісмут", + "material.gtceu.bismuth_bronze": "Бісмутова бронза", + "material.gtceu.bisphenol_a": "Бісфенол A", + "material.gtceu.black_bronze": "Чорна бронза", + "material.gtceu.black_dye": "Чорний барвник", + "material.gtceu.black_steel": "Чорна сталь", + "material.gtceu.blackstone": "Чорнокамінь", + "material.gtceu.blaze": "Пломінь", + "material.gtceu.blue_alloy": "Синій сплав", + "material.gtceu.blue_dye": "Синій барвник", + "material.gtceu.blue_steel": "Синя сталь", + "material.gtceu.blue_topaz": "Синій топаз", + "material.gtceu.bohrium": "Борій", + "material.gtceu.bone": "Кістка", + "material.gtceu.borax": "Бура", + "material.gtceu.bornite": "Борніт", + "material.gtceu.boron": "Бор", + "material.gtceu.borosilicate_glass": "Боросілікатне скло", + "material.gtceu.brass": "Латунь", + "material.gtceu.brick": "Цеглина", + "material.gtceu.bromine": "Бром", + "material.gtceu.bronze": "Бронза", + "material.gtceu.brown_dye": "Коричневий барвник", + "material.gtceu.butadiene": "Бутадієн", + "material.gtceu.butane": "Бутан", + "material.gtceu.butene": "Бутен", + "material.gtceu.butyraldehyde": "Бутаналь", + "material.gtceu.cadmium": "Кадмій", + "material.gtceu.caesium": "Цезій", + "material.gtceu.calcite": "Кальцит", + "material.gtceu.calcium": "Кальцій", + "material.gtceu.calcium_carbonate": "Карбонат кальцію", + "material.gtceu.calcium_chloride": "Хлорид кальцію", + "material.gtceu.calcium_ferrocyanide": "Фероцианід кальцію", + "material.gtceu.calcium_hydroxide": "Гідроксид кальцію", + "material.gtceu.calcium_phosphide": "Фосфід кальцію", + "material.gtceu.californium": "Каліфорній", + "material.gtceu.caprolactam": "Капролактам", + "material.gtceu.carbon": "Вуглець", + "material.gtceu.carbon_dioxide": "Діоксид вуглецю", + "material.gtceu.carbon_monoxide": "Монооксид вуглецю", + "material.gtceu.cassiterite": "Каситерит", + "material.gtceu.cassiterite_sand": "Каситеритовий пісок", + "material.gtceu.cerium": "Церій", + "material.gtceu.certus_quartz": "Істинний кварц", + "material.gtceu.cetane_boosted_diesel": "Високоцитанове дизельне паливо", + "material.gtceu.chalcocite": "Халькозин", + "material.gtceu.chalcopyrite": "Халькопірит", + "material.gtceu.charcoal": "Деревне вугілля", + "material.gtceu.charcoal_byproducts": "Побічні продукти з деревного вугілля", + "material.gtceu.chlorine": "Хлор", + "material.gtceu.chlorobenzene": "Хлорбензен", + "material.gtceu.chloroform": "Хлороформ", + "material.gtceu.chloromethane": "Хлорометан", + "material.gtceu.chromite": "Хроміт", + "material.gtceu.chromium": "Хром", + "material.gtceu.chromium_trioxide": "Оксид хрому", + "material.gtceu.cinnabar": "Кіновар", + "material.gtceu.clay": "Глина", + "material.gtceu.coal": "Вугілля", + "material.gtceu.coal_gas": "Вугільний газ", + "material.gtceu.coal_tar": "Вугільна смола", + "material.gtceu.cobalt": "Кобальт", + "material.gtceu.cobalt_brass": "Кобальтова латунь", + "material.gtceu.cobalt_oxide": "Оксид кобальта", + "material.gtceu.cobaltite": "Кобальтит", + "material.gtceu.cocoa": "Какао", + "material.gtceu.coke": "Кокс", + "material.gtceu.collagen": "Колаген", + "material.gtceu.concrete": "Бетон", + "material.gtceu.construction_foam": "Будівельна піна", + "material.gtceu.cooperite": "Шелдоніт", + "material.gtceu.copernicium": "Коперницій", + "material.gtceu.copper": "Мідь", + "material.gtceu.cracked_bauxite_slurry": "Крекінгова бокситова суспензія", + "material.gtceu.creosote": "Креозот", + "material.gtceu.cumene": "Кумен", + "material.gtceu.cupric_oxide": "Оксид міді", + "material.gtceu.cupronickel": "Мельхіор", + "material.gtceu.curium": "Кюрій", + "material.gtceu.cyan_dye": "Бірюзовий барвник", + "material.gtceu.cyclohexane": "Циклогексан", + "material.gtceu.cyclohexanone_oxime": "Циклогексанон оксім", + "material.gtceu.damascus_steel": "Дамаск", + "material.gtceu.dark_ash": "Темний попіл", + "material.gtceu.darmstadtium": "Дармштадтій", + "material.gtceu.decalcified_bauxite_sludge": "Декальцинований бокситовий шлам", + "material.gtceu.deepslate": "Глибосланець", + "material.gtceu.depleted_uranium_hexafluoride": "Збіднений гексафторид урану", + "material.gtceu.deuterium": "Дейтерій", + "material.gtceu.diaminobenzidine": "Діамінобензидин", + "material.gtceu.diamond": "Діамант", + "material.gtceu.diatomite": "Діатоміт", + "material.gtceu.dichlorobenzene": "Діхлорбензен", + "material.gtceu.dichlorobenzidine": "Діхлорбензідін", + "material.gtceu.dichloroethane": "Діхлоретан", + "material.gtceu.diesel": "Дизель", + "material.gtceu.diethylenetriamine": "Діетілентріамін", + "material.gtceu.diethylenetriamine_pentaacetonitrile": "Діетілентріамін пентаоцтонітріл", + "material.gtceu.diethylenetriaminepentaacetic_acid": "Діетілентріамінопентаоцтова кислота", + "material.gtceu.diluted_hydrochloric_acid": "Розбавлена соляна кислота", + "material.gtceu.diluted_sulfuric_acid": "Розбавлена cульфатна кислота", + "material.gtceu.dimethylamine": "Диметиламін", + "material.gtceu.dimethylbenzene": "Диметилбензен", + "material.gtceu.dimethyldichlorosilane": "Диметилдихлорсилан", + "material.gtceu.dimethylhydrazine": "Диметилгідразин", + "material.gtceu.dinitrogen_tetroxide": "Азотний тетраоксид", + "material.gtceu.diorite": "Діорит", + "material.gtceu.diphenyl_isophthalate": "Діфеніл ізофталат", + "material.gtceu.dissolved_calcium_acetate": "Розчинений ацетат кальцію", + "material.gtceu.distilled_water": "Дистильована вода", + "material.gtceu.drilling_fluid": "Бурильна рідина", + "material.gtceu.dubnium": "Дубній", + "material.gtceu.duranium": "Дюраній", + "material.gtceu.dysprosium": "Диспрозій", + "material.gtceu.echo_shard": "Уламок відлуння", + "material.gtceu.einsteinium": "Ейнштейній", + "material.gtceu.electrotine": "Електротин", + "material.gtceu.electrum": "Електрум", + "material.gtceu.emerald": "Смарагд", + "material.gtceu.ender_air": "Повітря Енду", + "material.gtceu.ender_eye": "Око Енду", + "material.gtceu.ender_pearl": "Перлина Енду", + "material.gtceu.endstone": "Камінь Енду", + "material.gtceu.enriched_bacterial_sludge": "Збагачений бактерієвий шлам", + "material.gtceu.enriched_naquadah": "Збагачена наквада", + "material.gtceu.enriched_naquadah_solution": "Збагачений розчин наквади", + "material.gtceu.enriched_naquadah_sulfate": "Сульфат збагаченої наквади", + "material.gtceu.enriched_naquadah_trinium_europium_duranide": "Збагачений наквада триній європій дуранід", + "material.gtceu.enriched_naquadah_waste": "Відпрацьована збагачена наквада", + "material.gtceu.enriched_uranium_hexafluoride": "Збагачений гексафторид урану", + "material.gtceu.epichlorohydrin": "Епіхлоргідрин", + "material.gtceu.epoxy": "Епоксидна суміш", + "material.gtceu.erbium": "Ербій", + "material.gtceu.ethane": "Етан", + "material.gtceu.ethanol": "Етанол", + "material.gtceu.ethenone": "Етенон", + "material.gtceu.ethyl_tertbutyl_ether": "Метилтретинний бутиловий етер", + "material.gtceu.ethylbenzene": "Етилбензен", + "material.gtceu.ethylene": "Етилен", + "material.gtceu.europium": "Європій", + "material.gtceu.fermented_biomass": "Ферментована біомаса", + "material.gtceu.fermium": "Фермій", + "material.gtceu.ferrite_mixture": "Суміш феритів", + "material.gtceu.ferrosilite": "Феросиліт", + "material.gtceu.fireclay": "Шамот", + "material.gtceu.fish_oil": "Риб'ячий жир", + "material.gtceu.flerovium": "Флеровій", + "material.gtceu.flint": "Кремінь", + "material.gtceu.fluorine": "Фтор", + "material.gtceu.fluoroantimonic_acid": "Фторантимонова кислота", + "material.gtceu.formaldehyde": "Формальдегід", + "material.gtceu.formamide": "Формамід", + "material.gtceu.formic_acid": "Мурашина кислота", + "material.gtceu.francium": "Францій", + "material.gtceu.fullers_earth": "Відбілювальні глини", + "material.gtceu.gadolinium": "Гадоліній", + "material.gtceu.galena": "Галеніт", + "material.gtceu.gallium": "Галій", + "material.gtceu.gallium_arsenide": "Арсенід галію", + "material.gtceu.gallium_sulfide": "Сульфід галію", + "material.gtceu.garnet_sand": "Гранатовий пісок", + "material.gtceu.garnierite": "Гранетит", + "material.gtceu.gasoline": "Бензин", + "material.gtceu.gelatin": "Желатин", + "material.gtceu.gelatin_mixture": "Желатинова суміш", + "material.gtceu.germanium": "Германій", + "material.gtceu.glass": "Скло", + "material.gtceu.glauconite_sand": "Глауконітове скло", + "material.gtceu.glowstone": "Світлокамінь", + "material.gtceu.glue": "Клей", + "material.gtceu.glycerol": "Гліцерол", + "material.gtceu.glyceryl_trinitrate": "Гліцерил тринітрат", + "material.gtceu.glycolonitrile": "Гліконітрил", + "material.gtceu.goethite": "Ґетит", + "material.gtceu.gold": "Золото", + "material.gtceu.granite": "Граніт", + "material.gtceu.granite_red": "Червоний граніт", + "material.gtceu.granitic_mineral_sand": "Гранітний мінеральний пісок", + "material.gtceu.graphene": "Графен", + "material.gtceu.graphite": "Графіт", + "material.gtceu.gray_dye": "Сірий барвник", + "material.gtceu.green_dye": "Зелений барвник", + "material.gtceu.green_sapphire": "Зелений сапфір", + "material.gtceu.green_sapphire_slurry": "Зелено-сапфірова суспензія", + "material.gtceu.grossular": "Гросуляр", + "material.gtceu.gunpowder": "Порох", + "material.gtceu.gypsum": "Гіпс", + "material.gtceu.hafnium": "Гафній", + "material.gtceu.hassium": "Гасій", + "material.gtceu.hastelloy_c_276": "Хастелой C-276", + "material.gtceu.hastelloy_x": "Хастелой X", + "material.gtceu.heavy_fuel": "Важке паливо", + "material.gtceu.helium": "Гелій", + "material.gtceu.helium_3": "Гелій 3", + "material.gtceu.hematite": "Гематит", + "material.gtceu.high_octane_gasoline": "Високооктановий безин", + "material.gtceu.holmium": "Голмій", + "material.gtceu.hsla_steel": "HSLA-сталь", + "material.gtceu.hsse": "HSS-E", + "material.gtceu.hssg": "HSS-G", + "material.gtceu.hsss": "HSS-S", + "material.gtceu.hydro_cracked_butadiene": "Водневокрекінговий бутадієн", + "material.gtceu.hydro_cracked_butane": "Водневокрекінговий бутан", + "material.gtceu.hydro_cracked_butene": "Водневокрекінговий бутен", + "material.gtceu.hydro_cracked_ethane": "Водневокрекінговий етан", + "material.gtceu.hydro_cracked_ethylene": "Водневокрекінговий етилен", + "material.gtceu.hydro_cracked_propane": "Водневокрекінговий пропан", + "material.gtceu.hydro_cracked_propene": "Водневокрекінговий пропен", + "material.gtceu.hydrochloric_acid": "Соляна кислота", + "material.gtceu.hydrofluoric_acid": "Флуоридна кислота", + "material.gtceu.hydrogen": "Водень", + "material.gtceu.hydrogen_cyanide": "Синильна кислота", + "material.gtceu.hydrogen_peroxide": "Пероксид водню", + "material.gtceu.hydrogen_sulfide": "Сірководень", + "material.gtceu.hypochlorous_acid": "Гіпохлоритна кислота", + "material.gtceu.ice": "Лід", + "material.gtceu.ilmenite": "Ільменіт", + "material.gtceu.ilmenite_slag": "Ільменітовий шлам", + "material.gtceu.impure_enriched_naquadah_solution": "Нечистий збагачений розчин наквади", + "material.gtceu.impure_naquadria_solution": "Нечистий розчин наквадрії", + "material.gtceu.incoloy_ma_956": "Incoloy MA-956", + "material.gtceu.indium": "Індій", + "material.gtceu.indium_concentrate": "Концентрат індію", + "material.gtceu.indium_gallium_phosphide": "Фосфід індію-галію", + "material.gtceu.indium_phosphide": "Фосфід індію", + "material.gtceu.indium_tin_barium_titanium_cuprate": "Індій олово барій титановий купорос", + "material.gtceu.inert_metal_mixture": "Інертна металева суміш", + "material.gtceu.invar": "Інвар", + "material.gtceu.iodine": "Йод", + "material.gtceu.iridium": "Іридій", + "material.gtceu.iridium_chloride": "Хлорид іридію", + "material.gtceu.iridium_metal_residue": "Металевий залишок іридію", + "material.gtceu.iron": "Залізо", + "material.gtceu.iron_ii_chloride": "Хлорид заліза (II)", + "material.gtceu.iron_iii_chloride": "Хлорид заліза (III)", + "material.gtceu.isoprene": "Ізопрен", + "material.gtceu.kanthal": "Кантал", + "material.gtceu.krypton": "Криптон", + "material.gtceu.kyanite": "Кіаніт", + "material.gtceu.lanthanum": "Лантан", + "material.gtceu.lapis": "Лапіс", + "material.gtceu.lapotron": "Лапотрон", + "material.gtceu.lava": "Лава", + "material.gtceu.lawrencium": "Лоуренсій", + "material.gtceu.lazurite": "Лазурит", + "material.gtceu.lead": "Свинець", + "material.gtceu.lead_zinc_solution": "Свинцево-цинкова суміш", + "material.gtceu.lepidolite": "Лепідоліт", + "material.gtceu.light_blue_dye": "Блакитний барвник", + "material.gtceu.light_fuel": "Легке паливо", + "material.gtceu.light_gray_dye": "Світло-сірий барвник", + "material.gtceu.lightly_hydro_cracked_gas": "Легко-водневокрекінговий газ", + "material.gtceu.lightly_hydro_cracked_heavy_fuel": "Легко-водневокрекінгове важке паливо", + "material.gtceu.lightly_hydro_cracked_light_fuel": "Легко-водневокрекінгове легке паливо", + "material.gtceu.lightly_hydro_cracked_naphtha": "Легко-водневокрекінговий лігроїн", + "material.gtceu.lightly_steam_cracked_gas": "Легко-парокрекінговий газ", + "material.gtceu.lightly_steam_cracked_heavy_fuel": "Легко-парокрекінгове важке паливо", + "material.gtceu.lightly_steam_cracked_light_fuel": "Легко-парокрекінгове легке паливо", + "material.gtceu.lightly_steam_cracked_naphtha": "Легко-парокрекінговий лігроїн", + "material.gtceu.lime_dye": "Лаймовий барвник", + "material.gtceu.liquid_air": "Рідке повітря", + "material.gtceu.liquid_ender_air": "Рідке повітря Енду", + "material.gtceu.liquid_nether_air": "Рідке повітря Незеру", + "material.gtceu.lithium": "Літій", + "material.gtceu.lithium_chloride": "Хлорид літію", + "material.gtceu.livermorium": "Ліверморій", + "material.gtceu.lpg": "ЗНГ", + "material.gtceu.lubricant": "Мастило", + "material.gtceu.lutetium": "Лютецій", + "material.gtceu.magenta_dye": "Пурпуровий барвник", + "material.gtceu.magnalium": "Магналій", + "material.gtceu.magnesia": "Периклаз", + "material.gtceu.magnesite": "Магнезит", + "material.gtceu.magnesium": "Магнезій", + "material.gtceu.magnesium_chloride": "Хлорид магнезію", + "material.gtceu.magnesium_diboride": "Диборид магнію", + "material.gtceu.magnetic_iron": "Магнітне залізо", + "material.gtceu.magnetic_neodymium": "Магнітний неодим", + "material.gtceu.magnetic_samarium": "Магнітний самарій", + "material.gtceu.magnetic_steel": "Магнітна сталь", + "material.gtceu.magnetite": "Магнетит", + "material.gtceu.malachite": "Малахіт", + "material.gtceu.manganese": "Манган", + "material.gtceu.manganese_phosphide": "Фосфід мангану", + "material.gtceu.maraging_steel_300": "Марагенова сталь 300", + "material.gtceu.marble": "Мармур", + "material.gtceu.massicot": "Масикот", + "material.gtceu.mc_guffium_239": "МакГаффін 239", + "material.gtceu.meat": "М'ясо", + "material.gtceu.meitnerium": "Майтнерій", + "material.gtceu.mendelevium": "Менделевій", + "material.gtceu.mercury": "Ртуть", + "material.gtceu.mercury_barium_calcium_cuprate": "Ртуть барій кальцієвий купорос", + "material.gtceu.metal_mixture": "Суміш металів", + "material.gtceu.methane": "Метан", + "material.gtceu.methanol": "Метанол", + "material.gtceu.methyl_acetate": "Метилацетат", + "material.gtceu.mica": "Слюда", + "material.gtceu.milk": "Молоко", + "material.gtceu.mirabilite": "Мірабіліт", + "material.gtceu.molybdenite": "Молібденіт", + "material.gtceu.molybdenum": "Молібден", + "material.gtceu.molybdenum_disilicide": "Дисиліцид молібдену", + "material.gtceu.monazite": "Монацит", + "material.gtceu.monochloramine": "Хлорамін", + "material.gtceu.moscovium": "Московій", + "material.gtceu.mutagen": "Мутаген", + "material.gtceu.naphtha": "Лігроїн", + "material.gtceu.naphthalene": "Нафтален", + "material.gtceu.naquadah": "Наквада", + "material.gtceu.naquadah_alloy": "Наквадовий сплав", + "material.gtceu.naquadria": "Наквадрія", + "material.gtceu.naquadria_solution": "Розчин наквадрії", + "material.gtceu.naquadria_sulfate": "Сульфат наквадрії", + "material.gtceu.naquadria_waste": "Відпрацьована наквадрія", + "material.gtceu.natural_gas": "Природній газ", + "material.gtceu.neodymium": "Неодим", + "material.gtceu.neon": "Неон", + "material.gtceu.neptunium": "Нептуній", + "material.gtceu.nether_air": "Незерське повітря", + "material.gtceu.nether_quartz": "Незерський кварц", + "material.gtceu.nether_star": "Зірка Незеру", + "material.gtceu.netherite": "Незерит", + "material.gtceu.netherrack": "Незерак", + "material.gtceu.neutronium": "Нейтроній", + "material.gtceu.nichrome": "Ніхром", + "material.gtceu.nickel": "Нікель", + "material.gtceu.nickel_zinc_ferrite": "Ферит нікелю-цинку", + "material.gtceu.nihonium": "Ніхоній", + "material.gtceu.niobium": "Ніобій", + "material.gtceu.niobium_nitride": "Нітрит ніобію", + "material.gtceu.niobium_titanium": "Ніобій-титан", + "material.gtceu.nitration_mixture": "Нітратна суміш", + "material.gtceu.nitric_acid": "Нітратна кислота", + "material.gtceu.nitric_oxide": "Монооксид азоту", + "material.gtceu.nitrobenzene": "Нітробензен", + "material.gtceu.nitrochlorobenzene": "Нітрохлоробензен", + "material.gtceu.nitrogen": "Азот", + "material.gtceu.nitrogen_dioxide": "Діоксид азоту", + "material.gtceu.nitrosyl_chloride": "Хлорид нітрозила", + "material.gtceu.nitrous_oxide": "Оксид азоту (I)", + "material.gtceu.nobelium": "Нобелій", + "material.gtceu.obsidian": "Обсидіан", + "material.gtceu.octane": "Октан", + "material.gtceu.oganesson": "Оґанесон", + "material.gtceu.oil": "Нафта", + "material.gtceu.oil_heavy": "Важка нафта", + "material.gtceu.oil_light": "Легка нафта", + "material.gtceu.oil_medium": "Сира нафта", + "material.gtceu.oilsands": "Нафтоносні піски", + "material.gtceu.olivine": "Олівін", + "material.gtceu.opal": "Опал", + "material.gtceu.orange_dye": "Помаранчевий барвник", + "material.gtceu.osmiridium": "Осмиридій", + "material.gtceu.osmium": "Осмій", + "material.gtceu.osmium_tetroxide": "Оксид осмію", + "material.gtceu.oxygen": "Кисень", + "material.gtceu.palladium": "Паладій", + "material.gtceu.palladium_raw": "Необроблений паладій", + "material.gtceu.paper": "Папір", + "material.gtceu.paracetamol": "Парацетамол", + "material.gtceu.pcb_coolant": "ДП-охолоджуюча рідина", + "material.gtceu.pentlandite": "Пентландит", + "material.gtceu.perlite": "Перліт", + "material.gtceu.phenol": "Фенол", + "material.gtceu.phosphate": "Фосфат", + "material.gtceu.phosphoric_acid": "Ортофосфатна кислота", + "material.gtceu.phosphorus": "Фосфор", + "material.gtceu.phosphorus_pentoxide": "Оксид фосфору (V)", + "material.gtceu.phthalic_acid": "Фталева кислота", + "material.gtceu.pink_dye": "Рожевий барвник", + "material.gtceu.pitchblende": "Настуран", + "material.gtceu.platinum": "Платина", + "material.gtceu.platinum_group_sludge": "Шлам платинової групи", + "material.gtceu.platinum_raw": "Необроблена платина", + "material.gtceu.platinum_sludge_residue": "Залишок платинового шламу", + "material.gtceu.plutonium": "Плутоній", + "material.gtceu.plutonium_241": "Плутоній 241", + "material.gtceu.pollucite": "Поллуцит", + "material.gtceu.polonium": "Полоній", + "material.gtceu.polybenzimidazole": "Полібензимідазол", + "material.gtceu.polycaprolactam": "Полікапролактам", + "material.gtceu.polychlorinated_biphenyl": "Поліхлорований дифеніл", + "material.gtceu.polydimethylsiloxane": "Полідиметилсилоксан", + "material.gtceu.polyethylene": "Поліетилен", + "material.gtceu.polyphenylene_sulfide": "Сульфід поліфенілену", + "material.gtceu.polytetrafluoroethylene": "Політетрафторетилен", + "material.gtceu.polyvinyl_acetate": "Полівінілацетат", + "material.gtceu.polyvinyl_butyral": "Полівінілбутирал", + "material.gtceu.polyvinyl_chloride": "Полівінілхлорид", + "material.gtceu.potash": "Карбонат калію", + "material.gtceu.potassium": "Калій", + "material.gtceu.potassium_carbonate": "Карбонат калію", + "material.gtceu.potassium_cyanide": "Ціанід калію", + "material.gtceu.potassium_dichromate": "Дихромат калію", + "material.gtceu.potassium_feldspar": "Пертит", + "material.gtceu.potassium_ferrocyanide": "Гексаціаноферат(II) калію", + "material.gtceu.potassium_hydroxide": "Гідроксид калію", + "material.gtceu.potassium_iodide": "Йодид калію", + "material.gtceu.potassium_sulfate": "Сульфат калію", + "material.gtceu.potin": "Потін", + "material.gtceu.powellite": "Повеліт", + "material.gtceu.praseodymium": "Празеодим", + "material.gtceu.promethium": "Прометій", + "material.gtceu.propane": "Пропан", + "material.gtceu.propene": "Пропен", + "material.gtceu.protactinium": "Протактиній", + "material.gtceu.prussian_blue": "Берлінська лазур", + "material.gtceu.purple_dye": "Фіолетовий барвник", + "material.gtceu.pyrite": "Пірит", + "material.gtceu.pyrochlore": "Пірохлорид", + "material.gtceu.pyrolusite": "Піролюзит", + "material.gtceu.pyrope": "Піроп", + "material.gtceu.quartz_sand": "Кварцовий пісок", + "material.gtceu.quartzite": "Кварцит", + "material.gtceu.quicklime": "Оксид кальцію", + "material.gtceu.rad_away": "Антирадин", + "material.gtceu.radium": "Радій", + "material.gtceu.radon": "Радон", + "material.gtceu.rare_earth": "Рідкісноземельний пил", + "material.gtceu.rarest_metal_mixture": "Суміш найрідкісніших металів", + "material.gtceu.raw_gasoline": "Сирий бензин", + "material.gtceu.raw_growth_medium": "Сире живильне середовище", + "material.gtceu.raw_rubber": "Сира гума", + "material.gtceu.raw_styrene_butadiene_rubber": "Сира бутаден-стирольна гума", + "material.gtceu.realgar": "Реальгар", + "material.gtceu.red_alloy": "Червоний сплав", + "material.gtceu.red_dye": "Червоний барвник", + "material.gtceu.red_garnet": "Червоний гранат", + "material.gtceu.red_steel": "Червона сталь", + "material.gtceu.redrock": "Червоний камінь", + "material.gtceu.redstone": "Редстоун", + "material.gtceu.refinery_gas": "Нафтопереробний газ", + "material.gtceu.reinforced_epoxy_resin": "Посилена епоксидна смола", + "material.gtceu.rhenium": "Реній", + "material.gtceu.rhodium": "Родій", + "material.gtceu.rhodium_plated_palladium": "Паладій з родієвим покриттям", + "material.gtceu.rhodium_sulfate": "Сульфат родію", + "material.gtceu.rock_salt": "Кам'яна сіль", + "material.gtceu.rocket_fuel": "Ракетне паливо", + "material.gtceu.roentgenium": "Рентгеній", + "material.gtceu.rose_gold": "Рожеве золото", + "material.gtceu.rtm_alloy": "RTM-сплав", + "material.gtceu.rubber": "Гума", + "material.gtceu.rubidium": "Рубідій", + "material.gtceu.ruby": "Рубін", + "material.gtceu.ruby_slurry": "Рубінова суспензія", + "material.gtceu.ruridit": "Рурідіт", + "material.gtceu.ruthenium": "Рутеній", + "material.gtceu.ruthenium_tetroxide": "Оксид рутенію(VIII)", + "material.gtceu.ruthenium_trinium_americium_neutronate": "Рутеній триній америцій нейтронат", + "material.gtceu.rutherfordium": "Резерфордій", + "material.gtceu.rutile": "Рутил", + "material.gtceu.salt": "Сіль", + "material.gtceu.salt_water": "Солона вода", + "material.gtceu.saltpeter": "Селітра", + "material.gtceu.samarium": "Самарій", + "material.gtceu.samarium_iron_arsenic_oxide": "Самарій залізо арсеновий оксід", + "material.gtceu.sapphire": "Сапфір", + "material.gtceu.sapphire_slurry": "Сапфірова суспензія", + "material.gtceu.scandium": "Скандій", + "material.gtceu.scheelite": "Шеєліт", + "material.gtceu.sculk": "Скалк", + "material.gtceu.seaborgium": "Мореродень", + "material.gtceu.seed_oil": "Рослинна олія", + "material.gtceu.selenium": "Селен", + "material.gtceu.severely_hydro_cracked_gas": "Сильно-водневокрекінговий газ", + "material.gtceu.severely_hydro_cracked_heavy_fuel": "Сильно-водневокрекінгове важке паливо", + "material.gtceu.severely_hydro_cracked_light_fuel": "Сильно-водневокрекінгове легке паливо", + "material.gtceu.severely_hydro_cracked_naphtha": "Сильно-водневокрекінговий лігроїн", + "material.gtceu.severely_steam_cracked_gas": "Сильно-парокрекінговий газ", + "material.gtceu.severely_steam_cracked_heavy_fuel": "Сильно-парокрекінгове важке паливо", + "material.gtceu.severely_steam_cracked_light_fuel": "Сильно-парокрекінгове легке паливо", + "material.gtceu.severely_steam_cracked_naphtha": "Сильно-парокрекінговий лігроїн", + "material.gtceu.silicon": "Кремній", + "material.gtceu.silicon_dioxide": "Діоксид кремнію", + "material.gtceu.silicone_rubber": "Силіконова гума", + "material.gtceu.silver": "Срібло", + "material.gtceu.soapstone": "Стеатит", + "material.gtceu.soda_ash": "Кальцинована сода", + "material.gtceu.sodalite": "Содаліт", + "material.gtceu.sodium": "Натрій", + "material.gtceu.sodium_bicarbonate": "Гідрокарбонат натрію", + "material.gtceu.sodium_bisulfate": "Гідросульфат натрію", + "material.gtceu.sodium_hydroxide": "Гідроксид натрію", + "material.gtceu.sodium_nitrite": "Нітрит натрію", + "material.gtceu.sodium_persulfate": "Пероксодисульфат натрію", + "material.gtceu.sodium_potassium": "Натрій-калій", + "material.gtceu.sodium_sulfide": "Сульфід натрію", + "material.gtceu.soldering_alloy": "Припій", + "material.gtceu.spessartine": "Спесартин", + "material.gtceu.sphalerite": "Сфалерит", + "material.gtceu.spodumene": "Сподумен", + "material.gtceu.stainless_steel": "Нержавіюча сталь", + "material.gtceu.steam": "Пара", + "material.gtceu.steam_cracked_butadiene": "Парокрекінговий бутадієн", + "material.gtceu.steam_cracked_butane": "Парокрекінговий бутан", + "material.gtceu.steam_cracked_butene": "Парокрекінговий бутен", + "material.gtceu.steam_cracked_ethane": "Парокрекінговий етан", + "material.gtceu.steam_cracked_ethylene": "Парокрекінговий етилен", + "material.gtceu.steam_cracked_propane": "Парокрекінговий пропан", + "material.gtceu.steam_cracked_propene": "Парокрекінговий пропен", + "material.gtceu.steel": "Сталь", + "material.gtceu.stellite_100": "Стелліт-100", + "material.gtceu.sterilized_growth_medium": "Стерилізоване живильне середовище", + "material.gtceu.sterling_silver": "Стерлінгове срібло", + "material.gtceu.stibnite": "Антимоніт", + "material.gtceu.stone": "Камінь", + "material.gtceu.strontium": "Стронцій", + "material.gtceu.styrene": "Стирол", + "material.gtceu.styrene_butadiene_rubber": "Бутаден-стирольна гума", + "material.gtceu.sugar": "Цукор", + "material.gtceu.sulfur": "Сірка", + "material.gtceu.sulfur_dioxide": "Діоксид сірки", + "material.gtceu.sulfur_trioxide": "Триоксид сірки", + "material.gtceu.sulfuric_acid": "Сульфатна кислота", + "material.gtceu.sulfuric_copper_solution": "Сульфатний розчин міді", + "material.gtceu.sulfuric_gas": "Сірчаний газ", + "material.gtceu.sulfuric_heavy_fuel": "Сірчане важке паливо", + "material.gtceu.sulfuric_light_fuel": "Сірчане легке паливо", + "material.gtceu.sulfuric_naphtha": "Сірчаний лігроїн", + "material.gtceu.sulfuric_nickel_solution": "Сульфатний розчин нікелю", + "material.gtceu.talc": "Тальк", + "material.gtceu.tantalite": "Танталіт", + "material.gtceu.tantalum": "Тантал", + "material.gtceu.tantalum_carbide": "Карбід танталу", + "material.gtceu.technetium": "Технецій", + "material.gtceu.tellurium": "Телур", + "material.gtceu.tennessine": "Теннессин", + "material.gtceu.terbium": "Тербій", + "material.gtceu.tetrafluoroethylene": "Тетрафторетилен", + "material.gtceu.tetrahedrite": "Тетраедрит", + "material.gtceu.tetranitromethane": "Тетранітрометан", + "material.gtceu.thallium": "Талій", + "material.gtceu.thorium": "Торій", + "material.gtceu.thulium": "Тулій", + "material.gtceu.tin": "Олово", + "material.gtceu.tin_alloy": "Олов'яний сплав", + "material.gtceu.titanium": "Титан", + "material.gtceu.titanium_carbide": "Карбід титану", + "material.gtceu.titanium_tetrachloride": "Хлорид титану(IV)", + "material.gtceu.titanium_trifluoride": "Фторид титану(III)", + "material.gtceu.titanium_tungsten_carbide": "Карбід вольфрам-титану", + "material.gtceu.toluene": "Толуен", + "material.gtceu.topaz": "Топаз", + "material.gtceu.treated_wood": "Оброблена деревина", + "material.gtceu.tricalcium_phosphate": "Ортофосфат кальцію", + "material.gtceu.trinium": "Триній", + "material.gtceu.trinium_sulfide": "Сульфід тринію", + "material.gtceu.tritanium": "Тританій", + "material.gtceu.tritium": "Тритій", + "material.gtceu.trona": "Трона", + "material.gtceu.tungstate": "Вольфрамат", + "material.gtceu.tungsten": "Вольфрам", + "material.gtceu.tungsten_carbide": "Карбід вольфраму", + "material.gtceu.tungsten_steel": "Вольфрамова сталь", + "material.gtceu.tungstic_acid": "Вольфрамова кислота", + "material.gtceu.ultimet": "Ультимет", + "material.gtceu.uraninite": "Настуран", + "material.gtceu.uranium": "Уран", + "material.gtceu.uranium_235": "Уран 235", + "material.gtceu.uranium_hexafluoride": "Гексафторид урану", + "material.gtceu.uranium_rhodium_dinaquadide": "Уран родій динаквадид", + "material.gtceu.uranium_triplatinum": "Уран триплатинум", + "material.gtceu.uu_matter": "UU-матерія", + "material.gtceu.uvarovite": "Уваровіт", + "material.gtceu.vanadium": "Ванадій", + "material.gtceu.vanadium_gallium": "Галід ванадію", + "material.gtceu.vanadium_magnetite": "Ванадієвий магнетит", + "material.gtceu.vanadium_steel": "Ванадієва сталь", + "material.gtceu.vinyl_acetate": "Вінілацетат", + "material.gtceu.vinyl_chloride": "Вінілхлорид", + "material.gtceu.water": "Вода", + "material.gtceu.watertight_steel": "Водонепроникна сталь", + "material.gtceu.wax": "Віск", + "material.gtceu.wheat": "Пшениця", + "material.gtceu.white_dye": "Білий барвник", + "material.gtceu.wood": "Деревина", + "material.gtceu.wood_gas": "Деревний газ", + "material.gtceu.wood_tar": "Деревна смола", + "material.gtceu.wood_vinegar": "Деревний оцет", + "material.gtceu.wrought_iron": "Коване залізо", + "material.gtceu.wulfenite": "Вульфеніт", + "material.gtceu.xenon": "Ксенон", + "material.gtceu.yellow_dye": "Жовтий барвник", + "material.gtceu.yellow_garnet": "Жовтий гранат", + "material.gtceu.yellow_limonite": "Лимоніт", + "material.gtceu.ytterbium": "Ітербій", + "material.gtceu.yttrium": "Ітрій", + "material.gtceu.yttrium_barium_cuprate": "Ітрій-барієвий купорос", + "material.gtceu.zeolite": "Цеоліт", + "material.gtceu.zeron_100": "Zeron-100", + "material.gtceu.zinc": "Цинк", + "material.gtceu.zinc_sulfide": "Сульфід цинку", + "material.gtceu.zincite": "Цинкіт", + "material.gtceu.zirconium": "Цирконій", + "message.gtceu.new_veins.amount": "Виявлено %d нових жил!", + "message.gtceu.new_veins.name": "Виявлено %s!", + "metaarmor.energy_share.disable": "Енергопостачання: Заряджання приладів вимкнена", + "metaarmor.energy_share.enable": "Енергопостачання: Заряджання приладів увімкнено", + "metaarmor.energy_share.error": "Енергопостачання:§c Недостатньо енергії для заряджання приладів!", + "metaarmor.energy_share.tooltip": "Режим живлення: %s", + "metaarmor.energy_share.tooltip.guide": "Щоб змінити режим, клацніть ПКМ крадькома, утримуючи предмет", + "metaarmor.hud.energy_lvl": "Рівень енергії: %s", + "metaarmor.hud.engine_enabled": "Двигун увімкнено: %s", + "metaarmor.hud.fuel_lvl": "Рівень палива: %s", + "metaarmor.hud.gravi_engine": "Гравітаційний двигун: %s", + "metaarmor.hud.hover_mode": "Режим ширяння: %s", + "metaarmor.hud.status.disabled": "§cВИМК", + "metaarmor.hud.status.enabled": "§aУВІМК", + "metaarmor.jetpack.emergency_hover_mode": "Аварійний режим польоту увімкнено!", + "metaarmor.jetpack.flight.disable": "Реактивний ранець: Політ вимкнено.", + "metaarmor.jetpack.flight.enable": "Реактивний ранець: Політ увімкнено", + "metaarmor.jetpack.hover.disable": "Реактивний ранець: Режим ширяння вимкнено", + "metaarmor.jetpack.hover.enable": "Реактивний ранець: Режим ширяння увімкнено", + "metaarmor.message.nightvision.disabled": "§bНічне бачення:§c Вимкнено", + "metaarmor.message.nightvision.enabled": "§bНічне бачення:§a Увімкнено", + "metaarmor.message.nightvision.error": "§cНедостатньо енергії!", + "metaarmor.nms.boosted_jump.disabled": "Комплект NanoMuscle™: Посилення стрибків вимкнено", + "metaarmor.nms.boosted_jump.enabled": "Комплект NanoMuscle™: Прискорення стрибків увімкнено", + "metaarmor.nms.nightvision.disabled": "Комплект NanoMuscle™: Нічне бачення вимкнено", + "metaarmor.nms.nightvision.enabled": "Комплект NanoMuscle™: Нічне бачення увімкнено", + "metaarmor.nms.nightvision.error": "Комплект NanoMuscle™:§c Недостатньо енергії!", + "metaarmor.nms.share.disable": "Комплект NanoMuscle™: Заряджання вимкнено", + "metaarmor.nms.share.enable": "Комплект NanoMuscle™: Заряджання увімкнено", + "metaarmor.nms.share.error": "Комплект NanoMuscle™:§c Недостатньо енергії для заряджання!", + "metaarmor.qts.nightvision.disabled": "Комплект QuarkTech™: Нічне бачення вимкнено", + "metaarmor.qts.nightvision.enabled": "Комплект QuarkTech™: Нічне бачення увімкнено", + "metaarmor.qts.nightvision.error": "Комплект QuarkTech™:§c Недостатньо енергії!", + "metaarmor.qts.share.disable": "Комплект QuarkTech™: Заряджання вимкнено", + "metaarmor.qts.share.enable": "Комплект QuarkTech™: Заряджання увімкнено", + "metaarmor.qts.share.error": "Комплект QuarkTech™:§c Недостатньо енергії для заряджання!", + "metaarmor.tooltip.autoeat": "Поповнює очки голоду з інвентарю", + "metaarmor.tooltip.breath": "Поповнює очки запасу повітря", + "metaarmor.tooltip.burning": "Знешкоджує горіння", + "metaarmor.tooltip.falldamage": "Знешкоджує кінетичну шкоду", + "metaarmor.tooltip.freezing": "Запобігає замерзанню", + "metaarmor.tooltip.jump": "Збільшує висоту та відстань стрибка", + "metaarmor.tooltip.potions": "Знешкоджує шкідливі ефекти", + "metaarmor.tooltip.speed": "Збільшує швидкість бігу", + "metaarmor.tooltip.stepassist": "Збільшує висоту кроку", + "metaitem.behavior.mode_switch.current_mode": "Режим: %s", + "metaitem.behavior.mode_switch.mode_switched": "§eРежим встановлено на: %s", + "metaitem.behavior.mode_switch.tooltip": "Використайте крадькома, щоб змінити режим", + "metaitem.clipboard.tooltip": "Можна записувати (без жодного інструменту для письма). клацніть ПКМ на стіні, щоб розмістити, і Shift+ПКМ, щоб видалити", + "metaitem.cover.digital.mode.energy.disabled": "Клацніть, щоб увімкнути режим енергії", + "metaitem.cover.digital.mode.energy.enabled": "Увімкнено режим енергії", + "metaitem.cover.digital.mode.fluid.disabled": "Клацніть, щоб увімкнути режим рідини", + "metaitem.cover.digital.mode.fluid.enabled": "Увімкнено режим рідини", + "metaitem.cover.digital.mode.item.disabled": "Клацніть, щоб увімкнути режим предметів", + "metaitem.cover.digital.mode.item.enabled": "Увімкнено режим предметів", + "metaitem.cover.digital.mode.machine.disabled": "Клацніть, щоб увімкнути режим машин", + "metaitem.cover.digital.mode.machine.enabled": "Увімкнено режим машин", + "metaitem.cover.digital.mode.proxy.disabled": "Клацніть, щоб увімкнути режим проксі", + "metaitem.cover.digital.mode.proxy.enabled": "Увімкнено режим проксі", + "metaitem.cover.digital.tooltip": "Під'єднує машини за допомогою§f кабелів живлення§7 до§f центрального монітора§7 у вигляді§f кришки§7.", + "metaitem.cover.digital.wireless.tooltip.0": "§fБездротово§7 під'єднує машини до§f центрального монітора§7 у вигляді§f кришки§7.", + "metaitem.cover.digital.wireless.tooltip.1": "§fПКМ§7 по§f центральному монітору§7 для віддаленої прив'язки до нього.", + "metaitem.cover.digital.wireless.tooltip.2": "§fПКМ крадькома§7 для видалення поточної прив'язки.", + "metaitem.cover.digital.wireless.tooltip.3": "§aПрив'язка:§f %s", + "metaitem.crushed.tooltip.purify": "Клацніть ПКМ по казану із водою, щоб отримати очищену руду", + "metaitem.debug_scanner.tooltip": "Трикодер", + "metaitem.dust.tooltip.purify": "ПКМ по казану, щоб отримати очищений пил", + "metaitem.electric.discharge_mode.disabled": "§eРежим розряджання вимкнено", + "metaitem.electric.discharge_mode.enabled": "§eРежим розряджання увімкнено", + "metaitem.electric.discharge_mode.tooltip": "Використовуйте крадькома, щоб змінити режим розряджання", + "metaitem.generic.electric_item.stored": "%d/%d EU (%s)", + "metaitem.generic.electric_item.tooltip": "%d/%d EU - рівень %s", + "metaitem.generic.fluid_container.tooltip": "%d/%dЛ %s", + "metaitem.int_circuit.configuration": "Конфігурація: %d", + "metaitem.liquid_fuel_jetpack.tooltip": "Використовує паливо внутрішнього згоряння для створення тяги", + "metaitem.machine_configuration.mode": "§aНалаштований режим:§r %s", + "metaitem.plugin.proxy.tooltips.1": "(Будь ласка, налаштуйтеся на режим проксі на екрані)", + "metaitem.plugin.tooltips.1": "На екран можна додати плагіни для більшої функціональності.", + "metaitem.prospector.mode.bedrock_ore": "§bРежим розвідки глибокорінних руд§r", + "metaitem.prospector.mode.fluid": "§bРежим розвідки рідини§r", + "metaitem.prospector.mode.ores": "§aРежим розвідки руд§r", + "metaitem.prospector.tooltip.modes": "Доступні режими:", + "metaitem.prospector.tooltip.radius": "Діапазон сканування в радіусі %s чанків", + "metaitem.record.sus.tooltip": "§7Leonz — Among Us Drip", + "metaitem.terminal.tooltip": "Гострі інструменти роблять гарну роботу", + "metaitem.terminal.tooltip.creative": "§bТворчий режим", + "metaitem.terminal.tooltip.hardware": "§aОбладнання: %d", + "metaitem.tool.tooltip.durability": "§fМіцність:§a %d / %d", + "metaitem.tool.tooltip.primary_material": "§fМатеріал:§e %s", + "metaitem.tool.tooltip.rotor.efficiency": "Ефективність турбіни:§9 %d%%", + "metaitem.tool.tooltip.rotor.power": "Потужність турбіни:§9 %d%%", + "metaitem.tricorder_scanner.tooltip": "Трикодер", + "monitor.gui.title.argb": "ARGB:", + "monitor.gui.title.back": "Назад", + "monitor.gui.title.config": "Конфігурація", + "monitor.gui.title.plugin": "Плагін:", + "monitor.gui.title.scale": "Масштаб:", + "monitor.gui.title.slot": "Слот:", + "ore.spawnlocation.name": "Інформація про генерацію руд", + "recipe.capability.eu.name": "GTCEu Енергія", + "recipe.capability.fluid.name": "Рідина", + "recipe.capability.item.name": "Предмет", + "recipe.condition.adjacent_block.tooltip": "Блоки навколо", + "recipe.condition.adjacent_fluid.tooltip": "Блоки рідин навколо", + "recipe.condition.biome.tooltip": "Біом: %s", + "recipe.condition.daytime.day.tooltip": "Потрібен денний час для роботи", + "recipe.condition.daytime.night.tooltip": "Потрібен нічний час для роботи", + "recipe.condition.dimension.tooltip": "Вимір: %s", + "recipe.condition.dimension_marker.tooltip": "Вимір:", + "recipe.condition.eu_to_start.tooltip": "EU до запуску: %d%s", + "recipe.condition.gamestage.locked_stage": "Заборонено на етапі: %s", + "recipe.condition.gamestage.unlocked_stage": "Дозволено на етапі: %s", + "recipe.condition.pos_y.tooltip": "Рівень Y: %d <= Y <= %d", + "recipe.condition.quest.completed.tooltip": "Потребує виконання «%s»", + "recipe.condition.quest.not_completed.tooltip": "Потребує невиконання «%s»", + "recipe.condition.rain.tooltip": "Рівень дощу: %d", + "recipe.condition.steam_vent.tooltip": "Чистий вентиляційний отвір", + "recipe.condition.thunder.tooltip": "Рівень грози: %d", + "tagprefix.andesite": "%s (андезитова руда)", + "tagprefix.basalt": "%s (базальтова руда)", + "tagprefix.blackstone": "%s (чорнокам'яна руда)", + "tagprefix.block": "%s (блок)", + "tagprefix.bolt": "Болт (%s)", + "tagprefix.buzz_saw_blade": "Лезо електропили (%s)", + "tagprefix.cable_gt_double": "2x кабель (%s)", + "tagprefix.cable_gt_hex": "16x кабель (%s)", + "tagprefix.cable_gt_octal": "8x кабель (%s)", + "tagprefix.cable_gt_quadruple": "4x кабель (%s)", + "tagprefix.cable_gt_single": "1x кабель (%s)", + "tagprefix.chainsaw_head": "Голівка ланцюгової пили (%s)", + "tagprefix.chipped_gem": "Надщерблений кристал (%s)", + "tagprefix.crushed_ore": "%s (подрібнена руда)", + "tagprefix.deepslate": "%s (глибосланцева руда)", + "tagprefix.dense_plate": "%s (міцний лист)", + "tagprefix.diorite": "%s (діоритова руда)", + "tagprefix.door": "Двері (%s)", + "tagprefix.double_plate": "%s (подвійний лист)", + "tagprefix.drill_head": "Голівка бура (%s)", + "tagprefix.dust": "%s (пил)", + "tagprefix.dye": "Бравник (%s)", + "tagprefix.endstone": "%s (руда Енду)", + "tagprefix.exquisite_gem": "Бездоганний кристал (%s)", + "tagprefix.fence": "Паркан (%s)", + "tagprefix.fence_gate": "Хвіртка (%s)", + "tagprefix.fine_wire": "Дрот (%s)", + "tagprefix.flawed_gem": "Огранований кристал (%s)", + "tagprefix.flawless_gem": "Вишуканий кристал (%s)", + "tagprefix.foil": "Фольга (%s)", + "tagprefix.frame": "Каркас (%s)", + "tagprefix.gear": "Шестерня (%s)", + "tagprefix.gem": "%s", + "tagprefix.granite": "%s (гранітова руда)", + "tagprefix.gravel": "%s (гравієва руда)", + "tagprefix.hot_ingot": "%s (розпечений злиток)", + "tagprefix.impure_dust": "%s (неочищений пил)", + "tagprefix.ingot": "%s (злиток)", + "tagprefix.lens": "Лінза (%s)", + "tagprefix.log": "Колода (%s)", + "tagprefix.long_rod": "Довгий стрижень (%s)", + "tagprefix.marble": "%s (мармурова руда)", + "tagprefix.netherrack": "%s (незерська руда)", + "tagprefix.nugget": "%s (самородок)", + "tagprefix.null": "%s (невідома форма)", + "tagprefix.pipe_huge_fluid": "Величезна рідинна труба (%s)", + "tagprefix.pipe_huge_item": "Величезна предметна труба (%s)", + "tagprefix.pipe_huge_restrictive": "Величезна обмежувальна предметна труба (%s)", + "tagprefix.pipe_large_fluid": "Велика рідинна труба (%s)", + "tagprefix.pipe_large_item": "Велика предметна труба (%s)", + "tagprefix.pipe_large_restrictive": "Велика обмежувальна предметна труба (%s)", + "tagprefix.pipe_nonuple_fluid": "Дев'ятикамерна рідинна труба (%s)", + "tagprefix.pipe_normal_fluid": "Рідинна труба (%s)", + "tagprefix.pipe_normal_item": "Предметна труба (%s)", + "tagprefix.pipe_normal_restrictive": "Обмежувальна предметна труба (%s)", + "tagprefix.pipe_quadruple_fluid": "Чотирикамерна рідинна труба (%s)", + "tagprefix.pipe_small_fluid": "Мала рідинна труба (%s)", + "tagprefix.pipe_small_item": "Мала предметна труба (%s)", + "tagprefix.pipe_small_restrictive": "Мала обмежувальна предметна труба (%s)", + "tagprefix.pipe_tiny_fluid": "Крихітна рідинна труба (%s)", + "tagprefix.planks": "Дошки (%s)", + "tagprefix.plate": "%s (лист)", + "tagprefix.polymer.dense_plate": "%s (міцна пластина)", + "tagprefix.polymer.double_plate": "%s (подвійна пластина)", + "tagprefix.polymer.dust": "%s (целюлоза)", + "tagprefix.polymer.foil": "Тонка пластина (%s)", + "tagprefix.polymer.ingot": "%s (злиток)", + "tagprefix.polymer.nugget": "%s (шматок)", + "tagprefix.polymer.plate": "%s (пластина)", + "tagprefix.polymer.small_dust": "%s (дрібна целюлоза)", + "tagprefix.polymer.tiny_dust": "%s (крихта целюлози)", + "tagprefix.pure_dust": "%s (очищений пил)", + "tagprefix.purified_ore": "%s (очищена руда)", + "tagprefix.raw": "%s (необроблена копалина)", + "tagprefix.raw_ore_block": "%s (блок необробленої руди)", + "tagprefix.red_granite": "%s (червоногранітна руда)", + "tagprefix.red_sand": "%s (червонопіщана руда)", + "tagprefix.refined_ore": "%s (рафінована руда)", + "tagprefix.ring": "Кільце (%s)", + "tagprefix.rock": "%s", + "tagprefix.rod": "Стрижень (%s)", + "tagprefix.rotor": "Ротор (%s)", + "tagprefix.round": "Кулька (%s)", + "tagprefix.sand": "%s (піщана руда)", + "tagprefix.screw": "Гвинт (%s)", + "tagprefix.screwdriver_tip": "Наконечник викрутки (%s)", + "tagprefix.slab": "Плита (%s)", + "tagprefix.small_dust": "%s (дрібний пил)", + "tagprefix.small_gear": "Мала шестерня (%s)", + "tagprefix.small_spring": "Мала пружина (%s)", + "tagprefix.spring": "Пружина (%s)", + "tagprefix.stairs": "Сходи (%s)", + "tagprefix.stone": "%s (руда)", + "tagprefix.surface_rock": "%s (поверхневий камінь)", + "tagprefix.tiny_dust": "%s (крихта пилу)", + "tagprefix.tuff": "%s (туфова руда)", + "tagprefix.turbine_blade": "Лезо турбіни (%s)", + "tagprefix.wire_cutter_head": "Голівка кусачок (%s)", + "tagprefix.wire_gt_double": "2x дріт (%s)", + "tagprefix.wire_gt_hex": "16x дріт (%s)", + "tagprefix.wire_gt_octal": "8x дріт (%s)", + "tagprefix.wire_gt_quadruple": "4x дріт (%s)", + "tagprefix.wire_gt_single": "1x дріт (%s)", + "tagprefix.wrench_tip": "Голівка гайкового ключа (%s)", + "tile.gtceu.brittle_charcoal.name": "Крихке деревне вугілля", + "tile.gtceu.brittle_charcoal.tooltip.0": "Виробляється запалювачем вугільної купи.", + "tile.gtceu.brittle_charcoal.tooltip.1": "Зламайте його, щоб отримати деревне вугілля.", + "tile.gtceu.foam.name": "Піна", + "tile.gtceu.petrified_foam.name": "Скам'яніла піна", + "tile.gtceu.reinforced_foam.name": "Посилена піна", + "tile.gtceu.reinforced_stone.name": "Зміцнений камінь", + "tile.gtceu.seal.name": "Герметичний блок" } diff --git a/src/main/resources/assets/gtceu/lang/zh_cn.json b/src/main/resources/assets/gtceu/lang/zh_cn.json index 879fad21a61..5465e8d133e 100644 --- a/src/main/resources/assets/gtceu/lang/zh_cn.json +++ b/src/main/resources/assets/gtceu/lang/zh_cn.json @@ -9,6 +9,8 @@ "bedrock_fluid.gtceu.oil_deposit": "石油矿藏", "bedrock_fluid.gtceu.raw_oil_deposit": "原油矿藏", "bedrock_fluid.gtceu.salt_water_deposit": "盐水矿藏", + "behavior.data_item.data": "- §a%s", + "behavior.data_item.title": "§n%s结构数据:", "behavior.item_magnet.disabled": "§c磁场已禁用", "behavior.item_magnet.enabled": "§a磁场已启用", "behavior.portable_scanner.amp_per_sec": "平均(最后一秒):%s A", @@ -99,6 +101,7 @@ "behaviour.setting.output.direction.tooltip": "%s-输出面方向:%s", "behaviour.soft_hammer": "用来开启与关闭机器", "behaviour.soft_hammer.disabled": "已暂停工作", + "behaviour.soft_hammer.disabled_cycle": "本运行周期后暂停工作", "behaviour.soft_hammer.enabled": "已恢复工作", "behaviour.soft_hammer.idle_after_cycle": "本运行周期后暂停机器", "behaviour.wrench": "右击以旋转方块", @@ -106,6 +109,7 @@ "block.gtceu.active_transformer": "有源变压器", "block.gtceu.advanced_computer_casing": "高级计算机外壳", "block.gtceu.advanced_data_access_hatch": "高级数据访问仓", + "block.gtceu.advanced_monitor": "高级监控器", "block.gtceu.alloy_blast_smelter": "合金冶炼炉", "block.gtceu.aluminium_crate": "铝板条箱", "block.gtceu.aluminium_drum": "铝桶", @@ -116,6 +120,7 @@ "block.gtceu.assembly_line_unit": "装配线控制外壳", "block.gtceu.atomic_casing": "原子机械方块", "block.gtceu.auto_maintenance_hatch": "自动维护仓", + "block.gtceu.basic_data_access_hatch": "基础数据访问仓", "block.gtceu.bio_hazard_sign_block": "生化危害警示方块", "block.gtceu.black_borderless_lamp": "黑色无框灯", "block.gtceu.black_lamp": "黑色灯", @@ -136,7 +141,9 @@ "block.gtceu.bronze_gearbox": "青铜齿轮箱机械方块", "block.gtceu.bronze_large_boiler": "大型青铜锅炉", "block.gtceu.bronze_machine_casing": "青铜机器外壳", + "block.gtceu.bronze_multiblock_tank": "青铜多方块储罐", "block.gtceu.bronze_pipe_casing": "青铜管道方块", + "block.gtceu.bronze_tank_valve": "青铜储罐阀门", "block.gtceu.brown_borderless_lamp": "棕色无框灯", "block.gtceu.brown_lamp": "棕色灯", "block.gtceu.brown_large_metal_sheet": "棕色粗纹金属板方块", @@ -145,6 +152,7 @@ "block.gtceu.casing_coke_bricks": "焦炉砖块", "block.gtceu.casing_grate": "栅格机械方块", "block.gtceu.causality_hazard_sign_block": "因果律危害警示方块", + "block.gtceu.central_monitor": "中央监控器", "block.gtceu.charcoal_pile_igniter": "木炭堆点火器", "block.gtceu.chiseled_dark_concrete": "雕纹深色混凝土", "block.gtceu.chiseled_light_concrete": "雕纹淡色混凝土", @@ -173,6 +181,7 @@ "block.gtceu.creative_data_access_hatch": "创造模式数据访问仓", "block.gtceu.creative_energy": "创造模式能量单元", "block.gtceu.creative_tank": "创造模式储罐", + "block.gtceu.creosote": "杂酚油", "block.gtceu.crushing_wheels": "粉碎轮", "block.gtceu.cupronickel_coil_block": "白铜线圈方块", "block.gtceu.cyan_borderless_lamp": "青色无框灯", @@ -808,6 +817,7 @@ "block.gtceu.mob_infestation_hazard_sign_block": "怪物侵袭危害警示方块", "block.gtceu.mob_spawner_hazard_sign_block": "刷怪笼危害警示方块", "block.gtceu.molybdenum_disilicide_coil_block": "二硅化钼线圈方块", + "block.gtceu.monitor": "监控器", "block.gtceu.mossy_dark_concrete_bricks": "覆苔深色混凝土砖", "block.gtceu.mossy_dark_concrete_cobblestone": "覆苔深色混凝土圆石", "block.gtceu.mossy_light_concrete_bricks": "覆苔淡色混凝土砖", @@ -900,13 +910,16 @@ "block.gtceu.nichrome_coil_block": "镍铬合金线圈方块", "block.gtceu.noise_hazard_sign_block": "噪声危害警示方块", "block.gtceu.nonconducting_casing": "绝缘机械方块", - "block.gtceu.normal_duct_pipe": "普通风管", - "block.gtceu.normal_laser_pipe": "普通激光管道", + "block.gtceu.normal_duct_pipe": "标准风管", + "block.gtceu.normal_laser_pipe": "标准激光管道", "block.gtceu.normal_laser_pipe.tooltip": "§f无损§7传递能量,仅限直线摆放", "block.gtceu.normal_optical_pipe": "光缆", "block.gtceu.normal_optical_pipe.tooltip": "§7传递§f算力§7或§f研究数据§7", "block.gtceu.object_holder": "物品支架", "block.gtceu.oil": "石油", + "block.gtceu.oil_heavy": "重油", + "block.gtceu.oil_light": "轻油", + "block.gtceu.oil_medium": "原油", "block.gtceu.opv_1024a_laser_source_hatch": "1024§e安§r§9§lOpV§r激光源仓", "block.gtceu.opv_1024a_laser_target_hatch": "1024§e安§r§9§lOpV§r激光靶仓", "block.gtceu.opv_16a_energy_converter": "16§e安§r§9§lOpV§r能量转换器", @@ -1734,7 +1747,9 @@ "config.gtceu.option.addLoot": "添加战利品", "config.gtceu.option.ae2": "ae2", "config.gtceu.option.allUniqueStoneTypes": "所有独特石头类型", + "config.gtceu.option.allowDrumsInputFluidsFromOutputSide": "允许桶从输出面输入流体", "config.gtceu.option.animationTime": "动画时间", + "config.gtceu.option.arcRecyclingYield": "电弧炉回收率", "config.gtceu.option.armorHud": "盔甲HUD", "config.gtceu.option.batchDuration": "批处理持续时间", "config.gtceu.option.bedrockOreDistance": "基岩矿石距离", @@ -1749,6 +1764,7 @@ "config.gtceu.option.coloredTieredMachineOutline": "彩色电力机器轮廓", "config.gtceu.option.coloredWireOutline": "彩色线缆轮廓", "config.gtceu.option.compat": "兼容", + "config.gtceu.option.createCompat": "机械动力兼容", "config.gtceu.option.debug": "调试", "config.gtceu.option.debugWorldgen": "矿石位置Debug模式", "config.gtceu.option.defaultPaintingColor": "机器默认喷漆颜色", @@ -1760,10 +1776,14 @@ "config.gtceu.option.doDatafixers": "启用数据修复", "config.gtceu.option.doSuperflatOres": "超平坦世界生成矿石", "config.gtceu.option.doesExplosionDamagesTerrain": "机器爆炸是否破坏地形", + "config.gtceu.option.drum": "桶", "config.gtceu.option.dumpAssets": "导出资源", "config.gtceu.option.dumpRecipes": "导出配方", + "config.gtceu.option.enableArcRecycling": "启用电弧炉回收", "config.gtceu.option.enableCleanroom": "启用超净间", + "config.gtceu.option.enableExtractorRecycling": "启用提取机回收", "config.gtceu.option.enableFEConverters": "启用FE转换器", + "config.gtceu.option.enableMaceratorRecycling": "启用研磨机回收", "config.gtceu.option.enableMaintenance": "启用维护仓", "config.gtceu.option.enableResearch": "启用研究", "config.gtceu.option.enableTieredCasings": "启用分级机械方块", @@ -1775,6 +1795,7 @@ "config.gtceu.option.environmentalHazardDecayRate": "环境污染衰减速率", "config.gtceu.option.environmentalHazards": "环境污染", "config.gtceu.option.euToFeRatio": "GTEU到FE的转换比例", + "config.gtceu.option.extractorRecyclingYield": "提取机回收率", "config.gtceu.option.feToEuRatio": "FE到GTEU的转换比例", "config.gtceu.option.flintAndSteelRequireSteel": "打火石配方是否需要钢", "config.gtceu.option.ftbChunksIntegration": "FTB区块-集成", @@ -1815,9 +1836,12 @@ "config.gtceu.option.ldFluidPipeMinDistance": "长距流体管道最小距离", "config.gtceu.option.ldItemPipeMinDistance": "长距物品管道最小距离", "config.gtceu.option.liquidBoilerBaseOutput": "液体锅炉-基础输出", + "config.gtceu.option.maceratorRecyclingYield": "研磨机回收率", "config.gtceu.option.machineSounds": "机器音效", "config.gtceu.option.machines": "机器", "config.gtceu.option.machinesEmissiveTextures": "启用机器泛光纹理", + "config.gtceu.option.machinesHaveBERsByDefault": "机器是否默认启用方块实体渲染", + "config.gtceu.option.maintenanceCheckRate": "检查维护的频率", "config.gtceu.option.meHatchEnergyUsage": "ME仓能耗", "config.gtceu.option.minerSpeed": "采矿机速度", "config.gtceu.option.minimap": "小地图", @@ -1844,6 +1868,7 @@ "config.gtceu.option.ownerOPBypass": "跳过所有权检查的最低权限等级", "config.gtceu.option.prospectorEnergyUseMultiplier": "探矿仪能源消耗乘数", "config.gtceu.option.recipeProgressLowEnergy": "低能量时配方进度", + "config.gtceu.option.quantumTank": "超级/量子缸", "config.gtceu.option.recipes": "配方", "config.gtceu.option.removeSmeltingForEBFMetals": "移除需要电力高炉冶炼的金属的熔炉配方", "config.gtceu.option.removeVanillaBlockRecipes": "移除原版方块配方", @@ -1851,8 +1876,10 @@ "config.gtceu.option.removeVanillaOreGen": "移除原版矿石", "config.gtceu.option.removeVanillaTNTRecipe": "移除原版TNT配方", "config.gtceu.option.renderFluids": "渲染流体", + "config.gtceu.option.renderGrowingPlants": "渲染作物", "config.gtceu.option.renderer": "渲染器", "config.gtceu.option.replaceMinedBlocksWith": "用...替换采矿机采过的方块", + "config.gtceu.option.replaceWithCobbleVersion": "以特色圆石替换", "config.gtceu.option.requireGTToolsForBlocks": "方块需要格雷工具", "config.gtceu.option.rngDamageElectricTools": "电动工具耐久度消耗概率", "config.gtceu.option.rubberTreeSpawnChance": "橡胶树生成权重", @@ -1869,6 +1896,7 @@ "config.gtceu.option.steelBoilerMaxTemperature": "钢锅炉-最高温度", "config.gtceu.option.steelSteamMultiblocks": "用钢的蒸汽多方块结构", "config.gtceu.option.surfaceRockProspectRange": "地表岩石探测半径", + "config.gtceu.option.tankItemFluidPreview": "储罐流体预览", "config.gtceu.option.titaniumBoilerHeatSpeed": "钛锅炉-加热速度", "config.gtceu.option.titaniumBoilerMaxTemperature": "钛锅炉-最高温度", "config.gtceu.option.toggle": "切换", @@ -1897,6 +1925,7 @@ "config.jade.plugin_gtceu.auto_output_info": "[GTCEu] 自动输出信息", "config.jade.plugin_gtceu.cable_info": "[GTCEu] 线缆信息", "config.jade.plugin_gtceu.controllable_provider": "[GTCEu] 是否停工", + "config.jade.plugin_gtceu.data_bank": "[GTCEu] 数据库信息", "config.jade.plugin_gtceu.electric_container_provider": "[GTCEu] 电力槽", "config.jade.plugin_gtceu.energy_converter_provider": "[GTCEu] 能量转换器模式", "config.jade.plugin_gtceu.exhaust_vent_info": "[GTCEu] 排气口信息", @@ -1971,12 +2000,12 @@ "cover.conveyor.blocks_input.enabled.1": "§a已启用", "cover.conveyor.distribution.insert_first.0": "分配模式:§b优先级", "cover.conveyor.distribution.insert_first.1": "§7将物品输入至所搜寻到的优先级最高的物品存储空间", - "cover.conveyor.distribution.insert_first.2": "§7加固物品管道会降低管道路径的优先级。", + "cover.conveyor.distribution.insert_first.2": "§7低优先物品管道会降低管道路径的优先级。", "cover.conveyor.distribution.round_robin_global.0": "分配模式:§b轮询调度", "cover.conveyor.distribution.round_robin_global.1": "§7将物品平分至相连的物品存储空间。", - "cover.conveyor.distribution.round_robin_prio.0": "分配模式:§b轮询调度(加固管道)", + "cover.conveyor.distribution.round_robin_prio.0": "分配模式:§b轮询调度(低优先管道)", "cover.conveyor.distribution.round_robin_prio.1": "§7尝试将物品平分至相连的物品存储空间。", - "cover.conveyor.distribution.round_robin_prio.2": "§7除非没有其他可用路径,否则不会发送物品至加固物品管道。", + "cover.conveyor.distribution.round_robin_prio.2": "§7除非没有其他可用路径,否则不会发送物品至低优先物品管道。", "cover.conveyor.item_filter.title": "物品过滤", "cover.conveyor.mode": "模式:%s", "cover.conveyor.mode.export": "模式:输出", @@ -2000,6 +2029,8 @@ "cover.ender_fluid_link.tooltip.channel_name": "把输入文本设为频道名", "cover.ender_fluid_link.tooltip.clear_button": "清除频道描述", "cover.ender_fluid_link.tooltip.list_button": "显示频道列表", + "cover.ender_item_link.title": "末影物品连接", + "cover.ender_redstone_link.title": "末影红石连接", "cover.filter.blacklist.disabled": "白名单", "cover.filter.blacklist.enabled": "黑名单", "cover.filter.mode.filter_both": "过滤两者", @@ -2043,6 +2074,7 @@ "cover.machine_controller.mode.null": "控制目标:无", "cover.machine_controller.normal": "普通", "cover.machine_controller.redstone": "最小红石信号强度:%d", + "cover.machine_controller.suspend_powerfail": "防止跳电:", "cover.machine_controller.title": "机器控制设置", "cover.pump.fluid_filter.title": "流体过滤", "cover.pump.mode.export": "模式:输出", @@ -2178,12 +2210,49 @@ "gtceu.cable.loss_per_block": "§c线损/米/安:§r§c%d§7 伏", "gtceu.cable.superconductor": "%s§d超导体", "gtceu.cable.voltage": "§a最大电压:§r§a%d§a(%s§a)", + "gtceu.canner": "装罐机", + "gtceu.central_monitor.gui.create_group": "创建组", + "gtceu.central_monitor.gui.currently_editing": "当前编辑:%s", + "gtceu.central_monitor.gui.remove_from_group": "从组中移除", + "gtceu.central_monitor.gui.set_target": "设置目标", + "gtceu.central_monitor.info_tooltip.0": "若需使用监控器,你须先将它们分组。每个组中只能包含一个模块。", + "gtceu.central_monitor.info_tooltip.1": "单击左键选中它们,然后点击“创建组”。", + "gtceu.central_monitor.info_tooltip.2": "然后在该组的设置界面中,你可以插入一个模块,并在同一页面对其配置。", + "gtceu.central_monitor.info_tooltip.3": "要删除一个组,请选中它的所有组件,并点击“从组中移除”。", + "gtceu.central_monitor.info_tooltip.4": "你可以通过点击组的名称一键选择此组的所有组件。再次点击可取消。", + "gtceu.central_monitor.info_tooltip.5": "某些模块可能会根据它们的目标方块显示相关信息。如需为某一组设置目标,请先选择该组中的任意组件,然后右键点击目标组件。", + "gtceu.central_monitor.info_tooltip.6": "若需选择不在多方块结构上的目标,则必须使用无线发信器覆盖板。", + "gtceu.central_monitor.info_tooltip.7": "将覆盖板装在目标方块上,使用闪存右键点击绑定,并放入多方块结构的数据访问仓内。", + "gtceu.central_monitor.info_tooltip.8": "然后选择数据访问仓作为目标,并在弹出的数字栏中设为闪存所在的插槽的索引编号。", + "gtceu.central_monitor.size": "尺寸:(%d+1+%d)x(%d+1+%d)", + "gtceu.centrifuge": "离心机", "gtceu.chance_logic.and": "AND", "gtceu.chance_logic.first": "第一", "gtceu.chance_logic.none": "NONE", "gtceu.chance_logic.or": "OR", "gtceu.chance_logic.xor": "XOR", "gtceu.chat.cape": "§5恭喜你:你刚刚解锁了一件新披风!查看终端应用程序“披风选择器”来使用它。§r", + "gtceu.chemical_bath": "化学浸洗机", + "gtceu.chemical_reactor": "化学反应釜", + "gtceu.circuit_assembler": "电路组装机", + "gtceu.coke_oven": "焦炉", + "gtceu.combustion_generator": "内燃发电机", + "gtceu.compressor": "压缩机", + "gtceu.computer_monitor_cover.error.bf_invalid": "无效字符位于%d", + "gtceu.computer_monitor_cover.error.bf_invalid_num": "处理符号编号%2$d时,索引%1$d处的数无效。", + "gtceu.computer_monitor_cover.error.exception": "发生了意外异常:%s", + "gtceu.computer_monitor_cover.error.invalid_args": "无效参数!", + "gtceu.computer_monitor_cover.error.invalid_number": "无效的数字'%s'!", + "gtceu.computer_monitor_cover.error.missing_item": "插槽%2$d中缺少%1$s!", + "gtceu.computer_monitor_cover.error.no_ae": "覆盖板支架未接入AE2网络!", + "gtceu.computer_monitor_cover.error.no_cover": "无覆盖板!", + "gtceu.computer_monitor_cover.error.no_placeholder": "不存在占位符“%s”!", + "gtceu.computer_monitor_cover.error.not_enough_args": "至少需要%d个参数,但实际只有%d个!", + "gtceu.computer_monitor_cover.error.not_in_range": "期望%s在%d和%d之间(含边界),但得到%d", + "gtceu.computer_monitor_cover.error.not_supported": "该方块/覆盖板不支持此功能!", + "gtceu.computer_monitor_cover.error.unclosed_bracket": "括号未闭合!", + "gtceu.computer_monitor_cover.error.unexpected_bracket": "意外的右括号!", + "gtceu.computer_monitor_cover.error.wrong_number_of_args": "预期接收%d个参数,实际传入%d个!", "gtceu.cover.activity_detector.message_activity_inverted": "正在以反相模式监控活动状态", "gtceu.cover.activity_detector.message_activity_normal": "正在以普通模式监控活动状态", "gtceu.cover.activity_detector_advanced.message_activity_inverted": "正在以反相模式监控处理状态", @@ -2218,6 +2287,22 @@ "gtceu.direction.tooltip.right": "右面", "gtceu.direction.tooltip.up": "顶面", "gtceu.duct_pipe.transfer_rate": "§b空气传输速率:%s", + "gtceu.display_source.computer_monitor_cover": "电脑屏幕覆盖板", + "gtceu.display_target.computer_monitor_cover": "电脑屏幕覆盖板", + "gtceu.distillation_tower": "蒸馏塔", + "gtceu.distillery": "蒸馏室", + "gtceu.duct_pipe.transfer_rate": "§b空气传输速率:%s", + "gtceu.dummy": "占位符", + "gtceu.electric_blast_furnace": "电力高炉", + "gtceu.electric_furnace": "电炉", + "gtceu.electrolyzer": "电解机", + "gtceu.electromagnetic_separator": "电磁选矿机", + "gtceu.ender_item_link_cover.title": "末影物品连接", + "gtceu.ender_redstone_link_cover.label": "红石信号强度:%d", + "gtceu.ender_redstone_link_cover.title": "末影红石连接", + "gtceu.extractor": "提取机", + "gtceu.extruder": "压模器", + "gtceu.fermenter": "发酵槽", "gtceu.fluid.amount": "§9总量:%d/%d mB", "gtceu.fluid.click_combined": "§7手持流体容器点击流体槽以§c倒出§7或§b填入§7流体(Shift+单击以用整组容器倒出流体或用整组容器中的流体填入)", "gtceu.fluid.click_to_empty": "§7手持流体容器点击流体槽以§c倒出§7流体(Shift+单击以用整组容器倒出流体)", @@ -2246,7 +2331,19 @@ "gtceu.forming_press.naming.named": "§o已命名物品", "gtceu.forming_press.naming.press": "§o名称模板", "gtceu.forming_press.naming.to_name": "§o待命名物品", + "gtceu.fusion_reactor": "核聚变反应堆", + "gtceu.gas_collector": "集气室", + "gtceu.gas_turbine": "燃气轮机", + "gtceu.gui.adv_stocking_config.min_fluid_count": "自动拉取的最小流体量", + "gtceu.gui.adv_stocking_config.min_item_count": "自动拉取的最小物品量", + "gtceu.gui.adv_stocking_config.ticks_per_cycle": "物品列表更新之间的延迟", + "gtceu.gui.adv_stocking_config.title": "配置库存自动拉取", + "gtceu.gui.all_voiding": "§7销毁§c全部", "gtceu.gui.auto_output.name": "自动", + "gtceu.gui.central_monitor.group": "组:%s", + "gtceu.gui.central_monitor.group_default_name": "组#%d", + "gtceu.gui.central_monitor.none": "空", + "gtceu.gui.central_monitor.text_scale": "文字大小", "gtceu.gui.charger_slot.tooltip.0": "§f充电槽§r", "gtceu.gui.charger_slot.tooltip.1": "§7从%s电池中取电§7", "gtceu.gui.charger_slot.tooltip.2": "§7也可为%s工具或电池充电", @@ -2255,6 +2352,18 @@ "gtceu.gui.chunkmode.enabled.0": "区块模式§a启用§r:单击禁用。", "gtceu.gui.chunkmode.enabled.1": "§7切换需要机器待机。", "gtceu.gui.circuit.title": "电路设置", + "gtceu.gui.computer_monitor_cover.edit_blank_placeholders": "编辑空白占位符", + "gtceu.gui.computer_monitor_cover.edit_displayed_text": "编辑显示文本", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.0": "此处输入在第%d行显示的文本。", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.1": "它可以包含占位符,例如:“能量:{energy}/{energyCapacity} EU”", + "gtceu.gui.computer_monitor_cover.main_textbox_tooltip.2": "占位符也可以嵌套在其他占位符中。", + "gtceu.gui.computer_monitor_cover.placeholder_reference.0": "所有占位符:", + "gtceu.gui.computer_monitor_cover.placeholder_reference.1": "(悬停以获得更多信息)", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.0": "输入占位符,用于在此处代替%s‘{}’。", + "gtceu.gui.computer_monitor_cover.second_page_textbox_tooltip.1": "例如,你可以设字符串为“能量:{}/{} EU”,并在文本框中填入“energy”和“energyCapacity”。", + "gtceu.gui.computer_monitor_cover.slot_tooltip.0": "可供某些占位符引用的物品槽", + "gtceu.gui.computer_monitor_cover.slot_tooltip.1": "槽位编号:%d", + "gtceu.gui.computer_monitor_cover.update_interval": "更新间隔(单位:tick)", "gtceu.gui.config_slot": "§f配置槽位§r", "gtceu.gui.config_slot.auto_pull_managed": "§4禁用:§7由ME自动拉取管理", "gtceu.gui.config_slot.remove": "§7右击§4清除§7配置槽位。§r", @@ -2279,6 +2388,8 @@ "gtceu.gui.content.count_range": "%s-%sx", "gtceu.gui.content.fluid_range": "%s-%smB", "gtceu.gui.content.per_tick": "§a每刻(tick)消耗/产生§r", + "gtceu.gui.content.range": "%s-%s", + "gtceu.gui.content.times_item": "x %s", "gtceu.gui.content.tips.per_second_short": "§a/秒§r", "gtceu.gui.content.tips.per_tick_short": "§a/刻(tick)§r", "gtceu.gui.content.units.per_second": "/s", @@ -2293,10 +2404,18 @@ "gtceu.gui.fluid_auto_input.tooltip.enabled": "流体自动输入已启用", "gtceu.gui.fluid_auto_output.allow_input.disabled": "禁止从输出面输入流体", "gtceu.gui.fluid_auto_output.allow_input.enabled": "允许从输出面输入流体", + "gtceu.gui.fluid_auto_output.disabled": "流体自动输出:§c已禁用", + "gtceu.gui.fluid_auto_output.enabled": "流体自动输出:§a已启用", + "gtceu.gui.fluid_auto_output.other_direction.0": "流体自动输出:§6其他面", + "gtceu.gui.fluid_auto_output.other_direction.1": "§7本机器的流体输出口不在当前面。", + "gtceu.gui.fluid_auto_output.other_direction.2": "§7单击将输出口移动至当前面。", "gtceu.gui.fluid_auto_output.tooltip.disabled": "流体自动输出已禁用", "gtceu.gui.fluid_auto_output.tooltip.enabled": "流体自动输出已启用", + "gtceu.gui.fluid_auto_output.unselected.0": "流体自动输出", + "gtceu.gui.fluid_auto_output.unselected.1": "§7选择机器的一面来配置输出。", "gtceu.gui.fluid_lock.tooltip.disabled": "流体锁定已禁用", "gtceu.gui.fluid_lock.tooltip.enabled": "流体锁定已启用", + "gtceu.gui.fluid_voiding": "§7销毁§9流体", "gtceu.gui.fluid_voiding_partial.tooltip.disabled": "过量流体销毁已禁用", "gtceu.gui.fluid_voiding_partial.tooltip.enabled": "过量流体销毁已启用", "gtceu.gui.fuel_amount": "燃料总量:", @@ -2304,25 +2423,28 @@ "gtceu.gui.item_auto_input.tooltip.enabled": "物品自动输入已启用", "gtceu.gui.item_auto_output.allow_input.disabled": "禁止从输出面输入物品", "gtceu.gui.item_auto_output.allow_input.enabled": "允许从输出面输入物品", + "gtceu.gui.item_auto_output.disabled": "物品自动输出:§c已禁用", + "gtceu.gui.item_auto_output.enabled": "物品自动输出:§a已启用", + "gtceu.gui.item_auto_output.other_direction.0": "物品自动输出:§6其他面", + "gtceu.gui.item_auto_output.other_direction.1": "§7本机器的物品输出口不在当前面。", + "gtceu.gui.item_auto_output.other_direction.2": "§7单击将输出口移动至当前面。", "gtceu.gui.item_auto_output.tooltip.disabled": "物品自动输出已禁用", "gtceu.gui.item_auto_output.tooltip.enabled": "物品自动输出已启用", + "gtceu.gui.item_auto_output.unselected.0": "物品自动输出", + "gtceu.gui.item_auto_output.unselected.1": "§7选择机器的一面来配置输出。", "gtceu.gui.item_lock.tooltip.disabled": "物品锁定已禁用", "gtceu.gui.item_lock.tooltip.enabled": "物品锁定已启用", + "gtceu.gui.item_voiding": "§7销毁§6物品", "gtceu.gui.item_voiding_partial.tooltip.disabled": "物品过量销毁已禁用", "gtceu.gui.item_voiding_partial.tooltip.enabled": "物品过量销毁已开启", "gtceu.gui.machinemode": "当前机器模式:%s", + "gtceu.gui.machinemode.tab_tooltip": "更改当前机器模式", "gtceu.gui.machinemode.title": "当前机器模式", "gtceu.gui.me_bus.auto_pull_button": "单击以切换ME自动拉取模式", "gtceu.gui.me_network.offline": "网络状态:§4离线§r", "gtceu.gui.me_network.online": "网络状态:§2在线§r", - "gtceu.gui.multiblock_fluid_voiding.0": "销毁模式", - "gtceu.gui.multiblock_fluid_voiding.1": "§7销毁§9流体", - "gtceu.gui.multiblock_item_fluid_voiding.0": "销毁模式", - "gtceu.gui.multiblock_item_fluid_voiding.1": "§7销毁§6物品§7和§9流体", - "gtceu.gui.multiblock_item_voiding.0": "销毁模式", - "gtceu.gui.multiblock_item_voiding.1": "§7销毁§6物品", - "gtceu.gui.multiblock_no_voiding.0": "销毁模式", - "gtceu.gui.multiblock_no_voiding.1": "§7不销毁", + "gtceu.gui.multiblock.voiding_mode": "销毁模式:", + "gtceu.gui.no_voiding": "§7不销毁", "gtceu.gui.output_setting.title": "输出设置", "gtceu.gui.output_setting.tooltips.0": "左键单击以自动输出物品", "gtceu.gui.output_setting.tooltips.1": "右键单击以自动输出流体", @@ -2340,6 +2462,9 @@ "gtceu.gui.silktouch.enabled.0": "精准采集已启用:单击禁用。", "gtceu.gui.silktouch.enabled.1": "§7切换需要机器待机。", "gtceu.gui.sort": "分类", + "gtceu.gui.title.adv_stocking_config.min_fluid_count": "最小流体量", + "gtceu.gui.title.adv_stocking_config.min_item_count": "最小物品量", + "gtceu.gui.title.adv_stocking_config.ticks_per_cycle": "每次输出间隔Tick", "gtceu.gui.title_bar.back": "返回", "gtceu.gui.title_bar.page_switcher": "页面", "gtceu.gui.toggle_view.disabled": "切换视图(流体)", @@ -2359,8 +2484,11 @@ "gtceu.item_filter.footer": "§e手持物品右键覆盖设置", "gtceu.item_list.item_stored": "§7储量:%d", "gtceu.item_pipe.priority": "§9优先级:§f%d", + "gtceu.jade.amperage_use": "%s A", + "gtceu.jade.at": " @ ", "gtceu.jade.cleaned_this_second": "污染清理速率:%s/s", "gtceu.jade.energy_stored": "%d / %d EU", + "gtceu.jade.fluid_use": "%s mB/t", "gtceu.jade.progress_computation": "%s / %s CWU", "gtceu.jade.progress_sec": "%s / %s s", "gtceu.jade.progress_tick": "%s / %s t", @@ -2433,9 +2561,9 @@ "gtceu.machine.bedrock_ore_miner.production": "§e产量乘数:§f%dx,超频后%fx", "gtceu.machine.block_breaker.speed_bonus": "§e速度奖励:§f%d%%", "gtceu.machine.block_breaker.tooltip": "§7挖掘正面的方块并收集掉落物", - "gtceu.machine.boiler.info.cooling.down": "§9冷却中§r%s", - "gtceu.machine.boiler.info.heating.up": "§c加热中§r%s", - "gtceu.machine.boiler.info.producing.steam": "§a(沸腾)", + "gtceu.machine.boiler.info.cooling.down": "§9冷却中§r", + "gtceu.machine.boiler.info.heating.up": "§c加热中§r", + "gtceu.machine.boiler.info.production.data": "§a产出速率:%s§a mB/t", "gtceu.machine.buffer.tooltip": "存储物品和流体的小小缓冲器", "gtceu.machine.canner.jei_description": "填入或倒空流体容器,例如桶和流体单元", "gtceu.machine.central_monitor.tooltip": "但它能运行《毁灭战士》吗?", @@ -2823,6 +2951,7 @@ "gtceu.machine.miner.multi.modes": "具有精准采集和区块对齐模式。", "gtceu.machine.miner.multi.production": "它能产出§f三倍§7于§f研磨机§7的粉碎矿石。", "gtceu.machine.miner.per_block": "§7每个方块需要§f%d§7秒。", + "gtceu.machine.miner.progress": "进度:%d/%d", "gtceu.machine.miner.radius": "半径:%d", "gtceu.machine.miner.startx": "sX:%d", "gtceu.machine.miner.starty": "sY:%d", @@ -3069,7 +3198,7 @@ "gtceu.multiblock.active_transformer.max_input": "§a最大输入:§f%s EU/t", "gtceu.multiblock.active_transformer.max_output": "§c最大输出:§f%s EU/t", "gtceu.multiblock.assembly_line.description": "装配线是由5到16“片”组成的大型多方块结构。理论上,它是一个大型组装机,用于生产高级元件。", - "gtceu.multiblock.batch_enabled": "批处理模式:已启用(%sx)", + "gtceu.multiblock.batch_enabled": "- %dx 来自批处理", "gtceu.multiblock.blast_furnace.max_temperature": "热容:%s", "gtceu.multiblock.central_monitor.height": "屏幕高度:%d", "gtceu.multiblock.central_monitor.height_modify": "调整高度:%d", @@ -3138,7 +3267,7 @@ "gtceu.multiblock.implosion_compressor.description": "聚爆压缩机是一种多方块结构,能够借助炸药将宝石粉转化为相应的宝石。", "gtceu.multiblock.invalid_structure": "结构无效。", "gtceu.multiblock.invalid_structure.tooltip": "该方块是多方块结构的控制器,请查看该方块的JEI界面以获取搭建图示。", - "gtceu.multiblock.large_boiler.description": "大型锅炉是一种使用水和能量源产生蒸汽的多方块结构。这里说的“能量源”通常是指固体燃料和高密度流体。不同等级的锅炉仅在蒸汽产量上有所差别。", + "gtceu.multiblock.large_boiler.description": "大型锅炉是种用水和能量源生产蒸汽的多方块结构。这里说的“能量源”通常是指任何可以烧的固体燃料,或者柴油/半流质燃料。能够以每次5%%的幅度节流来减少蒸汽产出和燃料消耗。", "gtceu.multiblock.large_boiler.efficiency": "效率:%s", "gtceu.multiblock.large_boiler.explosion_tooltip": "无水时提供燃料将爆炸", "gtceu.multiblock.large_boiler.heat_time_tooltip": "§7需要§f%d秒§7预热", @@ -3200,7 +3329,7 @@ "gtceu.multiblock.page_switcher.io.export": "§4输出", "gtceu.multiblock.page_switcher.io.import": "§2输入", "gtceu.multiblock.parallel": "同时处理至多%d个配方", - "gtceu.multiblock.parallel.exact": "同时处理%d个配方", + "gtceu.multiblock.parallel.exact": "- %dx 来自并行", "gtceu.multiblock.parallelizable.tooltip": "通过并行控制仓让机器同时处理多个相同配方。", "gtceu.multiblock.pattern.clear_amount_1": "§6前方必须有1x1x1大小的空间§r", "gtceu.multiblock.pattern.clear_amount_3": "§6前方必须有3x3x1大小的空间§r", @@ -3266,7 +3395,9 @@ "gtceu.multiblock.steam.steam_stored": "蒸汽:%s / %s mB", "gtceu.multiblock.steam_grinder.description": "蒸汽时代的多方块研磨机。需要至少14块青铜机械方块成型。仅可使用输入/输出总线(蒸汽),并且只能用蒸汽仓供给蒸汽。", "gtceu.multiblock.steam_oven.description": "蒸汽时代的多方块熔炉。需要至少6块青铜机械方块成型。仅可使用输入/输出总线(蒸汽),并且只能用蒸汽仓供给蒸汽。蒸汽仓必须放置于结构底层,数量至多为一个。", + "gtceu.multiblock.subtick_parallels": "- %dx 来自超频", "gtceu.multiblock.title": "多方块结构", + "gtceu.multiblock.total_runs": "同时处理%d个配方", "gtceu.multiblock.turbine.efficiency": "涡轮效率:%s%%", "gtceu.multiblock.turbine.efficiency_tooltip": "转子支架等级超过%s§r时,每级§7增加§f10%%效率,并翻倍输出功率§7。", "gtceu.multiblock.turbine.energy_per_tick": "能量输出:%s/%s EU/t", @@ -3308,6 +3439,209 @@ "gtceu.ownership.name.player": "玩家", "gtceu.part_sharing.disabled": "多方块结构共享:§4禁止", "gtceu.part_sharing.enabled": "多方块结构共享:§a允许", + "gtceu.placeholder_info.active.0": "若覆盖板所贴附的方块处于工作状态,则返回1;否则返回0。", + "gtceu.placeholder_info.active.1": "用法:", + "gtceu.placeholder_info.active.2": "{active} -> 当前是否有正在运行的配方", + "gtceu.placeholder_info.ae2crafting.0": "返回覆盖板所贴附的方块所在的ME网络的自动合成信息", + "gtceu.placeholder_info.ae2crafting.1": "用法:", + "gtceu.placeholder_info.ae2crafting.10": "{ae2crafting get <索引编号> time} -> 指定的CPU从开始制作至现在所经过的时间(以纳秒为单位),若处于空闲状态则返回0", + "gtceu.placeholder_info.ae2crafting.2": " {ae2crafting get amount} -> ME网络中的合成CPU数量", + "gtceu.placeholder_info.ae2crafting.3": "{ae2crafting get <索引编号> storage} -> 指定的CPU的存储容量", + "gtceu.placeholder_info.ae2crafting.4": "{ae2crafting get <索引编号> threads} -> 指定的CPU所拥有的并行处理单元数量", + "gtceu.placeholder_info.ae2crafting.5": " {ae2crafting get <索引编号> name} -> 指定的合成CPU名称", + "gtceu.placeholder_info.ae2crafting.6": " {ae2crafting get <索引编号> selectionMode} -> 指定的CPU的自动分配模式(用于手动、自动或同时请求)", + "gtceu.placeholder_info.ae2crafting.7": " {ae2crafting get <索引编号> amount} -> 指定的CPU中请求物品的数量,处于空闲状态则返回0", + "gtceu.placeholder_info.ae2crafting.8": " {ae2crafting get <索引编号> item} -> 指定的CPU中请求物品的显示名称,处于空闲状态则返回0", + "gtceu.placeholder_info.ae2crafting.9": " {ae2crafting get <索引编号> progress} -> 指定的CPU中当前合成任务的进度,处于空闲状态则返回0", + "gtceu.placeholder_info.ae2energy.0": "返回覆盖板所贴附的方块所在的ME网络的现存能源大小。", + "gtceu.placeholder_info.ae2energy.1": "用法:", + "gtceu.placeholder_info.ae2energy.2": " {ae2energy} -> 此ME网络中的现存能源大小(以AE为单位)", + "gtceu.placeholder_info.ae2fluidCount.0": "与fluidCount类似,但统计的是覆盖板所贴附的方块所在的ME网络的流体数量。", + "gtceu.placeholder_info.ae2fluidCount.1": "注意:计算所有的流体可能会导致卡顿!", + "gtceu.placeholder_info.ae2fluidCount.2": "用法:", + "gtceu.placeholder_info.ae2fluidCount.3": " {fluidCount [流体id]} -> 所有流体的总量,若指定了流体id则返回该流体的数量", + "gtceu.placeholder_info.ae2itemCount.0": "与itemCount类似,但统计的是覆盖板所贴附的方块所在的ME网络的物品数量。", + "gtceu.placeholder_info.ae2itemCount.1": "注意:按过滤器筛选或计算所有物品可能会导致卡顿!", + "gtceu.placeholder_info.ae2itemCount.2": "用法:", + "gtceu.placeholder_info.ae2itemCount.3": " {itemCount} -> 总物品数量", + "gtceu.placeholder_info.ae2itemCount.4": " {itemCount <物品id>} -> 指定的物品的数量", + "gtceu.placeholder_info.ae2itemCount.5": " {itemCount filter <槽位id>} -> 覆盖板指定槽位中,符合筛选条件的物品的数量", + "gtceu.placeholder_info.ae2maxPower.0": "返回覆盖板所贴附的方块所在的ME网络的最大能源容量。", + "gtceu.placeholder_info.ae2maxPower.1": "用法:", + "gtceu.placeholder_info.ae2maxPower.2": " {ae2maxPower} -> 此ME网络的最大能源容量", + "gtceu.placeholder_info.ae2powerUsage.0": "返回覆盖板所贴附的方块所在的ME网络的耗能大小。", + "gtceu.placeholder_info.ae2powerUsage.1": "用法:", + "gtceu.placeholder_info.ae2powerUsage.2": " {ae2powerUsage} -> 此ME网络的耗能大小", + "gtceu.placeholder_info.ae2spatial.0": "返回覆盖板所贴附的方块所在的ME网络的空间I/O(空间塔)信息。", + "gtceu.placeholder_info.ae2spatial.1": "用法:", + "gtceu.placeholder_info.ae2spatial.2": " {ae2spatial power} -> 启动空间I/O的所需能源大小", + "gtceu.placeholder_info.ae2spatial.3": " {ae2spatial efficiency} -> 空间塔的效率", + "gtceu.placeholder_info.ae2spatial.4": "{ae2spatial size} -> 沿指定轴的SCS规模(例:'尺寸:{X轴长度}×{Y轴长度}×{Z轴长度}')", + "gtceu.placeholder_info.amperage.0": "返回覆盖板所贴附的的导线/线缆的电流大小。", + "gtceu.placeholder_info.amperage.1": "用法:", + "gtceu.placeholder_info.amperage.2": " {amperage} -> 此导线/线缆的电流", + "gtceu.placeholder_info.bf.0": "用法:", + "gtceu.placeholder_info.bf.1": " {bf <数据容器的槽位索引> <代码>} -> 空字符串", + "gtceu.placeholder_info.block.0": "返回方块符号‘█’。", + "gtceu.placeholder_info.block.1": "用法:", + "gtceu.placeholder_info.block.2": " {block} -> '█'", + "gtceu.placeholder_info.bufferText.0": "返回ComputerCraft可访问的缓冲区中的文本", + "gtceu.placeholder_info.bufferText.1": "用法:", + "gtceu.placeholder_info.bufferText.2": " {bufferText <行>} -> 缓冲区中指定行的文本(行号为1-100)", + "gtceu.placeholder_info.calc.0": "返回数学函数或运算的结果。", + "gtceu.placeholder_info.calc.1": "用法:", + "gtceu.placeholder_info.calc.2": " {calc <任意字符串>} -> 任意字符串", + "gtceu.placeholder_info.calc.3": " {calc <参数>} -> 指定运算的结果", + "gtceu.placeholder_info.calc.4": " {calc <+|-|*|/|//|>>|<<|%> } -> 指定运算的结果", + "gtceu.placeholder_info.click.0": "返回在当前tick之前,目标高级监控器是否被点击", + "gtceu.placeholder_info.click.1": "用法:", + "gtceu.placeholder_info.click.2": " {click} -> 如果目标高级监控器被点击,返回\"1\",否则返回\"0\"", + "gtceu.placeholder_info.click.3": " {click x} -> 最后一次点击时,x的坐标(0到1之间)", + "gtceu.placeholder_info.click.4": " {click y} -> 最后一次点击时,y的坐标(0到1之间)", + "gtceu.placeholder_info.cmd.0": "执行Minecraft命令并返回其输出结果。", + "gtceu.placeholder_info.cmd.1": "需要一个数据容器以绑定玩家,通过右键点击以绑定你自己", + "gtceu.placeholder_info.cmd.2": "用法:", + "gtceu.placeholder_info.cmd.3": " {cmd <槽位索引> <指令>} -> 指令输出结果", + "gtceu.placeholder_info.cmp.0": "根据参数中的表达式返回1或0", + "gtceu.placeholder_info.cmp.1": "用法:", + "gtceu.placeholder_info.cmp.2": " {cmp <运算符> } -> 1或0,运算符可是以下任意一个:>、<、>=、<=、==、!=", + "gtceu.placeholder_info.color.0": "返回用指定颜色(第一个参数)上色的文本(第二个参数)。可以用所有默认的Minecraft聊天颜色。", + "gtceu.placeholder_info.color.1": "用法:", + "gtceu.placeholder_info.color.2": " {color <颜色> <文本>} -> 上色的文本", + "gtceu.placeholder_info.combine.0": "组合所有参数为单一字符串(通过转义参数之间的所有空格)", + "gtceu.placeholder_info.combine.1": "例如:{combine abc def ghi jkl mno} -> \"abc\\ def\\ ghi\\ jkl\\ mno\"", + "gtceu.placeholder_info.combine.2": "用法:", + "gtceu.placeholder_info.combine.3": " {combine [参数1] [参数2] [参数3] ...} -> 单一字符串,将在后续占位符中被视为单个参数", + "gtceu.placeholder_info.count.0": "返回有多少参数与第一个参数相等(作为字符串比较,所以\"0\" != \"0.0\")", + "gtceu.placeholder_info.count.1": "用法:", + "gtceu.placeholder_info.count.2": " {count <参数1> [参数2] [参数3] [参数4] ...} -> 与第一个参数相等的参数的数量", + "gtceu.placeholder_info.data.0": "向槽位中的数据容器(闪存/数据球/数据模块)写入数据或读取数据。", + "gtceu.placeholder_info.data.1": "如果将<索引编号>参数留空,则会用值p代替(p是存储在数据容器的NBT中的整数,范围为0到容量 - 1)。", + "gtceu.placeholder_info.data.2": "用法:", + "gtceu.placeholder_info.data.3": " {data get <插槽> <索引编号>} -> 指定的插槽内物品存储的数据", + "gtceu.placeholder_info.data.4": " {data set <槽位> <索引编号> <值>} -> 设置指定插槽内物品存储的数据,返回一个空字符串", + "gtceu.placeholder_info.data.5": " {data getp <槽位>} -> p", + "gtceu.placeholder_info.data.6": " {data setp <槽位> <值>} -> 设置p,返回一个空字符串", + "gtceu.placeholder_info.data.7": " {data inc <槽位>} -> 将p加1,如果p大于等于容量,则把p设为0", + "gtceu.placeholder_info.data.8": " {data dec <槽位>} -> 将p减1,如果p小于0,则把p设为容量-1", + "gtceu.placeholder_info.displayTarget.0": "返回使用显示链接传输到此覆盖板的指定行", + "gtceu.placeholder_info.displayTarget.1": "用法:", + "gtceu.placeholder_info.displayTarget.2": " {displayTarget <行编号>} -> 指定行的文本(行编号在1-100之间)", + "gtceu.placeholder_info.ender.0": "与末影连接覆盖板交互", + "gtceu.placeholder_info.ender.1": "如果提供一个绑定了玩家的数据容器,就可以与私人频道交互", + "gtceu.placeholder_info.ender.10": "数据容器(玩家)槽位参数可留空(不是0,空字符串)", + "gtceu.placeholder_info.ender.2": "用法:", + "gtceu.placeholder_info.ender.3": " {ender item <频道> [数据容器(玩家)槽位]} -> 物品数量", + "gtceu.placeholder_info.ender.4": " {ender itemPull <频道> [数据容器(玩家)槽位]} -> 从末影连接缓存中拉取一个物品", + "gtceu.placeholder_info.ender.5": " {ender itemPush <频道> [数据容器(玩家)槽位] -> 推送一个物品至末影连接缓存", + "gtceu.placeholder_info.ender.6": " {ender itemId <频道> [数据容器(玩家)槽位]} -> 末影连接缓存里物品的id(例:\"26 minecraft:dirt\")", + "gtceu.placeholder_info.ender.7": " {ender fluid [数据容器(玩家)槽位]} -> 流体量", + "gtceu.placeholder_info.ender.8": " {ender redstone <频道> [数据容器(玩家)槽位] -> 红石信号等级", + "gtceu.placeholder_info.ender.9": " {ender redstone <频道> <数据容器(玩家)槽位> <信号等级>} -> 设置末影红石连接输出的红石信号,返回空字符串", + "gtceu.placeholder_info.energy.0": "返回已存储的能量值", + "gtceu.placeholder_info.energy.1": "用法:", + "gtceu.placeholder_info.energy.2": " {energy} -> 已存储的能量值", + "gtceu.placeholder_info.energyCapacity.0": "返回最大可存储的能量值", + "gtceu.placeholder_info.energyCapacity.1": "用法:", + "gtceu.placeholder_info.energyCapacity.2": "{energyCapacity} -> 能量容量", + "gtceu.placeholder_info.eval.0": "返回对提供的字符串执行的结果,其中可能包含占位符", + "gtceu.placeholder_info.eval.1": "用法:", + "gtceu.placeholder_info.eval.2": " {eval abcdefg} -> abcdefg", + "gtceu.placeholder_info.eval.3": " {eval \"repeating a: {repeat 5 \\\"a \\\"}\" -> repeating a: a a a a a ", + "gtceu.placeholder_info.eval.4": " {eval \\\"\"{some random text}\"\\\" -> {some random text}", + "gtceu.placeholder_info.eval.5": " {eval \"text \"\\\"\"{something with spaces}\"\\\"\" more text\" -> text {something with spaces} more text", + "gtceu.placeholder_info.fluidCount.0": "返回流体量(可被过滤)。", + "gtceu.placeholder_info.fluidCount.1": "用法:", + "gtceu.placeholder_info.fluidCount.2": " {fluidCount [流体id]} -> 所有流体的总量,若指定了流体id则返回该流体的数量", + "gtceu.placeholder_info.formatInt.0": "返回指定整数的字符串形式", + "gtceu.placeholder_info.formatInt.1": "例:{formatInt 1236457} -> 1.24M", + "gtceu.placeholder_info.formatInt.2": "用法:", + "gtceu.placeholder_info.formatInt.3": " {formatInt <参数>} -> 指定的整数的字符串形式", + "gtceu.placeholder_info.fromAscii.0": "返回指定ASCII码所代表的字符", + "gtceu.placeholder_info.fromAscii.1": "用法:", + "gtceu.placeholder_info.fromAscii.2": " {fromAscii <字符编码>} -> 字符", + "gtceu.placeholder_info.if.0": "根据条件返回参数之一。如果该参数不是空字符串且不等于0,则认为该条件为真。", + "gtceu.placeholder_info.if.1": "用法:", + "gtceu.placeholder_info.if.2": " {if <条件> <如果为真则被返回> [如果为假则被返回]}", + "gtceu.placeholder_info.itemCount.0": "返回物品的数量(可被过滤)。", + "gtceu.placeholder_info.itemCount.1": "用法:", + "gtceu.placeholder_info.itemCount.2": " {itemCount} -> 总物品数量", + "gtceu.placeholder_info.itemCount.3": " {itemCount <物品id>} -> 指定的物品的数量", + "gtceu.placeholder_info.itemCount.4": " {itemCount filter <槽位id>} -> 覆盖板指定槽位中,符合筛选条件的物品的数量", + "gtceu.placeholder_info.maintenance.0": "若覆盖板所贴附的方块有维护问题返回1,否则返回0。", + "gtceu.placeholder_info.maintenance.1": "例:'维护状态:{if {maintenance} 需要维护 已维护}'", + "gtceu.placeholder_info.maintenance.2": "用法:", + "gtceu.placeholder_info.maintenance.3": " {maintenance} -> 是否存在维护问题", + "gtceu.placeholder_info.maxProgress.0": "返回覆盖板所贴附的方块当前正在运行的配方的最大进度。", + "gtceu.placeholder_info.maxProgress.1": "例: '进度: {calc {calc {progress} / {maxProgress}} * 100}%'", + "gtceu.placeholder_info.maxProgress.2": "用法:", + "gtceu.placeholder_info.maxProgress.3": " {maxProgress} -> 当前正在运行的配方的最大进度", + "gtceu.placeholder_info.nbt.0": "指定的插槽内物品的NBT数据", + "gtceu.placeholder_info.nbt.1": "用法:", + "gtceu.placeholder_info.nbt.2": " {nbt <槽位> [键1] [键2] [键3] …} -> 物品NBT [键1] [键2] [键3] […]", + "gtceu.placeholder_info.obf.0": "返回混淆处理过的文本(第一个参数)。", + "gtceu.placeholder_info.obf.1": "用法:", + "gtceu.placeholder_info.obf.2": " {obf <文本>} -> 混淆过的文本", + "gtceu.placeholder_info.previousText.0": "返回此覆盖板在指定行(换行之前)之前显示的文本。", + "gtceu.placeholder_info.previousText.1": "用法:", + "gtceu.placeholder_info.previousText.2": " {previousText <行>} -> 在指定行之前显示的文本(行编号从1开始)", + "gtceu.placeholder_info.progress.0": "返回覆盖板所贴附的方块当前正在运行的配方的进度。", + "gtceu.placeholder_info.progress.1": "注意:此进度是个在0和{maxProgress}之间的整数", + "gtceu.placeholder_info.progress.2": "用法:", + "gtceu.placeholder_info.progress.3": " {progress} -> 当前正在运行的配方的进度", + "gtceu.placeholder_info.random.0": "返回指定区间(含边界)内的随机数。", + "gtceu.placeholder_info.random.1": "用法:", + "gtceu.placeholder_info.random.2": " {random <最小值> <最大值>} -> 介于最小值和最大值之间的随机数(含边界)", + "gtceu.placeholder_info.redstone.0": "返回或设置红石信号强度", + "gtceu.placeholder_info.redstone.1": "用法:", + "gtceu.placeholder_info.redstone.2": " {redstone get } -> 指定面的红石信号强度(0-15)", + "gtceu.placeholder_info.redstone.3": " {redstone get link <槽位索引> <频率槽位索引>} -> 指定的中央监视器槽位(槽位索引)中无线红石遥控器链接的机械动力红石频率上的信号强度。频率槽位索引是无线红石遥控器内部频率的索引(从左到右,0–6)", + "gtceu.placeholder_info.redstone.4": " {redstone set <强度>} -> 空字符串,设置红石信号输出强度,从此覆盖板方向输出", + "gtceu.placeholder_info.redstone.5": " {redstone set link <槽位索引> <频率槽位索引> <信号强度>} -> 空字符串,在指定的无线红石遥控器链接的机械动力红石频率上,设为指定的红石信号强度", + "gtceu.placeholder_info.repeat.0": "返回重复若干次(第一个参数)的文本(第二个参数)。", + "gtceu.placeholder_info.repeat.1": "用法:", + "gtceu.placeholder_info.repeat.2": " {repeat <数量> <文本>} -> 重复指定次数的文本", + "gtceu.placeholder_info.select.0": "返回指定索引处的参数(从0开始)", + "gtceu.placeholder_info.select.1": "用法:", + "gtceu.placeholder_info.select.2": " {select <索引编号> [参数1] [参数2] [参数3] ... -> 指定索引处的参数", + "gtceu.placeholder_info.strike.0": "返回有删除线的文本(第一个参数),就像被划掉一样", + "gtceu.placeholder_info.strike.1": "用法:", + "gtceu.placeholder_info.strike.2": " {strike <文本>} -> 有删除线的文本", + "gtceu.placeholder_info.subList.0": "返回参数列表中索引范围为左(含边界)至右(不含)的元素(从0开始计)", + "gtceu.placeholder_info.subList.1": "用法:", + "gtceu.placeholder_info.subList.2": " {subList <左> <右> [参数0] [参数1] ...} -> 从<左>到<右>的所有参数,以空格分隔", + "gtceu.placeholder_info.tick.0": "返回从安装此覆盖板时起经过的tick。", + "gtceu.placeholder_info.tick.1": "用法:", + "gtceu.placeholder_info.tick.2": " {tick} -> 自安装启度过的tick", + "gtceu.placeholder_info.tm.0": "返回™符号", + "gtceu.placeholder_info.tm.1": "用法:", + "gtceu.placeholder_info.tm.2": " {tm} -> ™符号", + "gtceu.placeholder_info.toAscii.0": "返回指定字符的ASCII码", + "gtceu.placeholder_info.toAscii.1": "用法:", + "gtceu.placeholder_info.toAscii.2": " {toAscii <字符>} -> 此字符的ASCII码", + "gtceu.placeholder_info.toChars.0": "返回将提供的字符串按字符分隔并以空格连接的结果", + "gtceu.placeholder_info.toChars.1": "例:{toChars example} -> 'e x a m p l e'", + "gtceu.placeholder_info.toChars.2": "用法:", + "gtceu.placeholder_info.toChars.3": " {toChars <参数>} -> 一串字符", + "gtceu.placeholder_info.underline.0": "返回有下划线的文本(第一个参数)", + "gtceu.placeholder_info.underline.1": "用法:", + "gtceu.placeholder_info.underline.2": " {underline <文本>} -> 有下划线的文本", + "gtceu.placeholder_info.voltage.0": "返回覆盖板所贴附的的导线/线缆的电压大小。", + "gtceu.placeholder_info.voltage.1": "用法:", + "gtceu.placeholder_info.voltage.2": " {voltage} -> 此导线/线缆的电压", + "gtceu.plasma_generator": "等离子燃料", + "gtceu.polarizer": "两极磁化机", + "gtceu.primitive_blast_furnace": "土高炉", + "gtceu.pyrolyse_oven": "热解炉", + "gtceu.recipe.byproduct_tier": "%s§r+时有副产品", + "gtceu.recipe.category.arc_furnace_recycling": "电弧炉:回收", + "gtceu.recipe.category.chem_dyes": "化学浸洗机:化学染色", + "gtceu.recipe.category.extractor_recycling": "流体提取机:重熔回收", + "gtceu.recipe.category.ingot_molding": "合金炉:金属成型", + "gtceu.recipe.category.macerator_recycling": "研磨机:粉碎回收", + "gtceu.recipe.category.ore_bathing": "化学浸洗机:矿物处理", + "gtceu.recipe.category.ore_crushing": "研磨机:矿物处理", + "gtceu.recipe.category.ore_forging": "锻造锤:矿物处理", "gtceu.recipe.chance": "概率:%s + %s/电压等级", "gtceu.recipe.cleanroom": "需要%s", "gtceu.recipe.cleanroom.display_name": "超净间", @@ -3422,9 +3756,12 @@ "gtceu.tool_action.wire_cutter.connect": "§8使用剪线钳连接/断开电线", "gtceu.tool_action.wrench.connect": "§8使用扳手连接/断开管道,潜行可以阻止输入", "gtceu.tool_action.wrench.set_facing": "§8使用扳手设置朝向", + "gtceu.tooltip.computer_monitor_config": "存储电脑屏幕覆盖板的配置数据", + "gtceu.tooltip.computer_monitor_data": "保存数据:%s", "gtceu.tooltip.fluid_pipe_hold_shift": "§7按住§6SHIFT§7以查看流体容器详情", "gtceu.tooltip.hold_ctrl": "§7按住CTRL获得更多信息", "gtceu.tooltip.hold_shift": "§7按住§6SHIFT§7获得更多信息", + "gtceu.tooltip.player_bind": "绑定至玩家:%s", "gtceu.tooltip.potion.each": "§r%4$s%%§7概率获得§r%1$s %2$s§7(§r%3$s§7tick)", "gtceu.tooltip.potion.header": "§6包含效果:", "gtceu.tooltip.proxy_bind": "§f绑定到%s %s %s处的样板总成", @@ -3432,6 +3769,7 @@ "gtceu.tooltip.status.trinary.true": "真", "gtceu.tooltip.status.trinary.unknown": "未知", "gtceu.tooltip.tool_fluid_hold_shift": "§7按住§6SHIFT§7以查看流体容器及工具详情", + "gtceu.tooltip.wireless_transmitter_bind": "绑定至无线发信器,其位于%5$s,%1$s %2$s %3$s,朝向%4$s", "gtceu.top.allow_output_input": "允许输入", "gtceu.top.auto_output": "自动输出", "gtceu.top.buffer_bound_pos": "已绑定至 - X:%s;Y:%s;Z:%s", @@ -3483,6 +3821,10 @@ "gtceu.universal.clear_nbt_recipe.tooltip": "§c这将清除所有内容物!", "gtceu.universal.kiloliters": "%s B", "gtceu.universal.liters": "%s mB", + "gtceu.universal.padded_parentheses": " (%s) ", + "gtceu.universal.padded_spaced_parentheses": " ( %s ) ", + "gtceu.universal.parentheses": "(%s)", + "gtceu.universal.spaced_parentheses": "( %s )", "gtceu.universal.tooltip.amperage_in": "§e输入电流:§f%dA", "gtceu.universal.tooltip.amperage_in_out": "§e输入/输出电流:§f%dA", "gtceu.universal.tooltip.amperage_in_out_till": "§e输入/输出电流上限:§f%dA", @@ -3707,6 +4049,8 @@ "item.gtceu.empty_wooden_form": "空木制模具", "item.gtceu.ender_fluid_link_cover": "末影流体连接覆盖板", "item.gtceu.ender_fluid_link_cover.tooltip": "§7作§f覆盖板§7时利用§f无线§7§d末影§f连接§7传输§f流体§7。", + "item.gtceu.ender_item_link_cover": "末影物品连接覆盖板", + "item.gtceu.ender_redstone_link_cover": "末影红石连接覆盖板", "item.gtceu.energium_dust": "能量粉", "item.gtceu.energy_cluster": "能量簇", "item.gtceu.energy_cluster.tooltip": "§7可充电电池", @@ -3743,7 +4087,7 @@ "item.gtceu.exquisite_glass_gem": "精致的玻璃晶体", "item.gtceu.facade_cover": "%s覆盖伪装板", "item.gtceu.facade_cover.tooltip.0": "§7可作为§f覆盖板§7加装的装饰性外壳。", - "item.gtceu.facade_cover.tooltip.1": "§7使用三个铁板与任意方块合成", + "item.gtceu.facade_cover.tooltip.1": "§7使用铁板与任意方块合成", "item.gtceu.face_mask": "面罩", "item.gtceu.fertilizer": "肥料", "item.gtceu.fiber_reinforced_circuit_board": "纤维强化电路基板", @@ -3818,6 +4162,7 @@ "item.gtceu.hpic_chip.tooltip": "§7高功率集成电路", "item.gtceu.hpic_wafer": "HPIC晶圆", "item.gtceu.hpic_wafer.tooltip": "§7高功率集成电路原料", + "item.gtceu.huge_pipe_casting_mold": "模具(巨型管道)", "item.gtceu.huge_pipe_extruder_mold": "模头(巨型管道)", "item.gtceu.hv_battery_hull": "大型电池外壳", "item.gtceu.hv_battery_hull.tooltip": "§7一个空的§6HV§7电池外壳", @@ -3846,6 +4191,7 @@ "item.gtceu.ilc_chip.tooltip": "§7集成逻辑电路", "item.gtceu.ilc_wafer": "ILC晶圆", "item.gtceu.ilc_wafer.tooltip": "§7集成电路原料", + "item.gtceu.image_module": "图像模块", "item.gtceu.impure_bentonite_dust": "含杂膨润土", "item.gtceu.impure_cassiterite_sand_dust": "含杂锡石矿砂", "item.gtceu.impure_pitchblende_dust": "含杂沥青铀矿", @@ -3898,6 +4244,7 @@ "item.gtceu.lapotronic_energy_orb.tooltip": "§7可充电电池", "item.gtceu.lapotronic_energy_orb_cluster": "兰波顿能量球簇", "item.gtceu.lapotronic_energy_orb_cluster.tooltip": "§7可充电电池", + "item.gtceu.large_pipe_casting_mold": "模具(大型管道)", "item.gtceu.large_pipe_extruder_mold": "模头(大型管道)", "item.gtceu.light_blue_dye_spray_can": "喷漆罐(淡蓝色)", "item.gtceu.light_blue_glass_lens": "玻璃透镜(淡蓝色)", @@ -4057,7 +4404,8 @@ "item.gtceu.nor_memory_chip.tooltip": "§7或非逻辑门", "item.gtceu.nor_memory_wafer": "NOR存储器晶圆", "item.gtceu.nor_memory_wafer.tooltip": "§7逻辑门原料", - "item.gtceu.normal_pipe_extruder_mold": "模头(普通管道)", + "item.gtceu.normal_pipe_casting_mold": "模具(标准管道)", + "item.gtceu.normal_pipe_extruder_mold": "模头(标准管道)", "item.gtceu.nugget_casting_mold": "模具(粒)", "item.gtceu.nugget_casting_mold.tooltip": "§7用来制作粒的模具", "item.gtceu.opv_conveyor_module": "§9§lOpV§r传送带", @@ -4089,10 +4437,15 @@ "item.gtceu.pill_casting_mold": "模具(药片)", "item.gtceu.pink_dye_spray_can": "喷漆罐(粉红色)", "item.gtceu.pink_glass_lens": "玻璃透镜(粉红色)", + "item.gtceu.pipe.huge_casting_mold.tooltip": "§7用来制作巨型管道的模具", "item.gtceu.pipe.huge_extruder_mold.tooltip": "§7用来制作占据整个方块的管道的模头", + "item.gtceu.pipe.large_casting_mold.tooltip": "§7用来制作大型管道的模具", "item.gtceu.pipe.large_extruder_mold.tooltip": "§7用来制作大型管道的模头", + "item.gtceu.pipe.normal_casting_mold.tooltip": "§7用来制作管道的模具", "item.gtceu.pipe.normal_extruder_mold.tooltip": "§7用来制作管道的模头", + "item.gtceu.pipe.small_casting_mold.tooltip": "§7用来制作小型管道的模具", "item.gtceu.pipe.small_extruder_mold.tooltip": "§7用来制作小型管道的模头", + "item.gtceu.pipe.tiny_casting_mold.tooltip": "§7用来制作微型管道的模具", "item.gtceu.pipe.tiny_extruder_mold.tooltip": "§7用来制作微型管道的模头", "item.gtceu.pitchblende_dust": "沥青铀矿", "item.gtceu.plant_ball": "植物球", @@ -4227,6 +4580,7 @@ "item.gtceu.small_meat_dust": "小堆肉末", "item.gtceu.small_palladium_raw_dust": "小堆粗钯粉", "item.gtceu.small_paper_dust": "小堆纸屑", + "item.gtceu.small_pipe_casting_mold": "模具(小型管道)", "item.gtceu.small_pipe_extruder_mold": "模头(小型管道)", "item.gtceu.small_pitchblende_dust": "小堆沥青铀矿", "item.gtceu.small_platinum_group_sludge_dust": "小堆铂系矿泥", @@ -4280,6 +4634,7 @@ "item.gtceu.tantalum_capacitor": "钽电容", "item.gtceu.terminal": "终端", "item.gtceu.terminal.tooltip": "潜行右击多方块控制器以自动搭建此多方块结构", + "item.gtceu.text_module": "文本模块", "item.gtceu.tiny_ash_dust": "小撮灰烬", "item.gtceu.tiny_basaltic_mineral_sand_dust": "小撮玄武岩矿砂", "item.gtceu.tiny_bentonite_dust": "小撮膨润土", @@ -4298,6 +4653,7 @@ "item.gtceu.tiny_meat_dust": "小撮肉末", "item.gtceu.tiny_palladium_raw_dust": "小撮粗钯粉", "item.gtceu.tiny_paper_dust": "小撮纸屑", + "item.gtceu.tiny_pipe_casting_mold": "模具(微型管道)", "item.gtceu.tiny_pipe_extruder_mold": "模头(微型管道)", "item.gtceu.tiny_pitchblende_dust": "小撮沥青铀矿", "item.gtceu.tiny_platinum_group_sludge_dust": "小撮铂系矿泥", @@ -4322,9 +4678,15 @@ "item.gtceu.tool.behavior.block_rotation": "§2精械师傅:§f旋转方块", "item.gtceu.tool.behavior.crop_harvesting": "§a庄稼收割:§f收获成熟的作物", "item.gtceu.tool.behavior.damage_boost": "§4伤害增益:§f对%s造成额外伤害", + "item.gtceu.tool.behavior.dowse_campfire": "§F消防战士:§f扑灭营火", "item.gtceu.tool.behavior.grass_path": "§e园林策划:§f制造草径", "item.gtceu.tool.behavior.ground_tilling": "§e耕地农夫:§f耕耘土地", "item.gtceu.tool.behavior.plunger": "§9水管工人:§f清除流体", + "item.gtceu.tool.behavior.prospecting.air": "找到个空腔", + "item.gtceu.tool.behavior.prospecting.changing": "探测到材质有所改变", + "item.gtceu.tool.behavior.prospecting.lava": "找到了熔岩", + "item.gtceu.tool.behavior.prospecting.ore": "找到矿石:%s", + "item.gtceu.tool.behavior.prospecting.water": "找到了水", "item.gtceu.tool.behavior.rail_rotation": "§e铁路技工:§f旋转轨道", "item.gtceu.tool.behavior.relocate_mining": "§2磁力吸引:§f吸入采掘的方块与生物掉落物", "item.gtceu.tool.behavior.remove_wax": "§6清洁试剂:§f脱蜡", @@ -4397,6 +4759,7 @@ "item.gtceu.tool.tooltip.attack_damage": "§c攻击伤害§r:%s", "item.gtceu.tool.tooltip.attack_speed": "§9攻击速度§r:%s", "item.gtceu.tool.tooltip.crafting_uses": "§a合成耐久度§r:%s", + "item.gtceu.tool.tooltip.default_enchantments": "§5默认附魔:", "item.gtceu.tool.tooltip.general_uses": "§b耐久度§r:%s", "item.gtceu.tool.tooltip.harvest_level": "§e采掘等级:%s", "item.gtceu.tool.tooltip.harvest_level_extra": "§e采掘等级:%s§f(%s§f)", @@ -4512,6 +4875,7 @@ "item.gtceu.white_dye_spray_can": "喷漆罐(白色)", "item.gtceu.wire_extruder_mold": "模头(导线)", "item.gtceu.wire_extruder_mold.tooltip": "§7用来制作导线的模头", + "item.gtceu.wireless_transmitter_cover": "无线发信器", "item.gtceu.wood_bolt": "短木棍", "item.gtceu.wood_dust": "木浆", "item.gtceu.wood_plate": "木板", @@ -5197,7 +5561,7 @@ "material.gtceu.xenon": "氙", "material.gtceu.yellow_dye": "黄色染料", "material.gtceu.yellow_garnet": "黄石榴石", - "material.gtceu.yellow_limonite": "黄褐铁矿", + "material.gtceu.yellow_limonite": "褐铁矿", "material.gtceu.ytterbium": "镱", "material.gtceu.yttrium": "钇", "material.gtceu.yttrium_barium_cuprate": "钇钡铜氧化物", @@ -5350,6 +5714,7 @@ "recipe.capability.fluid.name": "流体", "recipe.capability.item.name": "物品", "recipe.condition.adjacent_block.tooltip": "水平相邻方块应为", + "recipe.condition.adjacent_fluid.tooltip": "水平相邻流体应为", "recipe.condition.biome.tooltip": "生物群系:%s", "recipe.condition.daytime.day.tooltip": "需要白天才能工作", "recipe.condition.daytime.night.tooltip": "需要夜晚才能工作", @@ -5477,18 +5842,18 @@ "tagprefix.null": "%s Null", "tagprefix.pipe_huge_fluid": "巨型%s流体管道", "tagprefix.pipe_huge_item": "巨型%s物品管道", - "tagprefix.pipe_huge_restrictive": "巨型加固%s物品管道", + "tagprefix.pipe_huge_restrictive": "巨型低优先%s物品管道", "tagprefix.pipe_large_fluid": "大型%s流体管道", "tagprefix.pipe_large_item": "大型%s物品管道", - "tagprefix.pipe_large_restrictive": "大型加固%s物品管道", + "tagprefix.pipe_large_restrictive": "大型低优先%s物品管道", "tagprefix.pipe_nonuple_fluid": "九重%s流体管道", - "tagprefix.pipe_normal_fluid": "普通%s流体管道", - "tagprefix.pipe_normal_item": "普通%s物品管道", - "tagprefix.pipe_normal_restrictive": "普通加固%s物品管道", + "tagprefix.pipe_normal_fluid": "标准%s流体管道", + "tagprefix.pipe_normal_item": "标准%s物品管道", + "tagprefix.pipe_normal_restrictive": "标准低优先%s物品管道", "tagprefix.pipe_quadruple_fluid": "四重%s流体管道", "tagprefix.pipe_small_fluid": "小型%s流体管道", "tagprefix.pipe_small_item": "小型%s物品管道", - "tagprefix.pipe_small_restrictive": "小型加固%s物品管道", + "tagprefix.pipe_small_restrictive": "小型低优先%s物品管道", "tagprefix.pipe_tiny_fluid": "微型%s流体管道", "tagprefix.planks": "%s木板", "tagprefix.plate": "%s板", diff --git a/src/main/resources/assets/gtceu/lang/zh_tw.json b/src/main/resources/assets/gtceu/lang/zh_tw.json index 0876d80c581..968ee0cd5d3 100644 --- a/src/main/resources/assets/gtceu/lang/zh_tw.json +++ b/src/main/resources/assets/gtceu/lang/zh_tw.json @@ -3329,13 +3329,13 @@ "gtceu.recipe.eu_inverted": "產能功率:%s EU/t", "gtceu.recipe.eu_to_start": "啟動耗能:%sEU%s", "gtceu.recipe.explosive": "爆炸物:%s", - "gtceu.recipe.max_eu": "最大功率:%s EU", + "gtceu.recipe.max_eu": "最大耗能:%s EU", "gtceu.recipe.not_consumed": "不在加工中消耗", "gtceu.recipe.research": "需要研究", "gtceu.recipe.scan_for_research": "裝配線配方掃描", "gtceu.recipe.temperature": "溫度:%sK", "gtceu.recipe.total": "總計:%s EU", - "gtceu.recipe.total_computation": "算力:%s CWU", + "gtceu.recipe.total_computation": "總計算力:%s CWU", "gtceu.recipe_logic.condition_fails": "條件不足", "gtceu.recipe_logic.insufficient_fuel": "燃料不足", "gtceu.recipe_logic.insufficient_in": "需要輸入", @@ -5362,7 +5362,7 @@ "recipe.condition.quest.completed.tooltip": "完成任務:%s", "recipe.condition.quest.not_completed.tooltip": "未完成任務:%s", "recipe.condition.rain.tooltip": "雨量:%d", - "recipe.condition.rock_breaker.tooltip": "水平相鄰方塊需要為流體源", + "recipe.condition.adjacent_fluid.tooltip": "水平相鄰方塊需要為流體源", "recipe.condition.steam_vent.tooltip": "清潔蒸汽排氣口", "recipe.condition.thunder.tooltip": "雷級:%d", "recipe_category.gtceu.arc_furnace_recycling": "電弧爐:電漿回收", diff --git a/src/main/resources/assets/gtceu/models/block/machine/large_miner_active.json b/src/main/resources/assets/gtceu/models/block/machine/large_miner_active.json index ba9ded14a80..2cc46cd3b04 100644 --- a/src/main/resources/assets/gtceu/models/block/machine/large_miner_active.json +++ b/src/main/resources/assets/gtceu/models/block/machine/large_miner_active.json @@ -43,7 +43,7 @@ } }, { - "from": [ 0, 0, 16 ], + "from": [ 0, -0.01, 16 ], "to": [ 16, -16, 32 ], "faces": { "down": { "uv": [0, 0, 16, 16], "texture": "#overlay_pipe", "cullface": "down" } diff --git a/src/main/resources/assets/gtceu/models/block/machine/long_distance_fluid_pipeline_endpoint.json b/src/main/resources/assets/gtceu/models/block/machine/long_distance_fluid_pipeline_endpoint.json deleted file mode 100644 index ebe181e7dca..00000000000 --- a/src/main/resources/assets/gtceu/models/block/machine/long_distance_fluid_pipeline_endpoint.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "parent": "gtceu:block/machine/template/pipeline_endpoint_machine", - "textures": { - "overlay": "gtceu:block/pipe/ld_fluid_pipe/overlay", - "overlay_emissive": "gtceu:block/pipe/ld_fluid_pipe/overlay_emissive", - - "hatch_in": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", - "hatch_out": "gtceu:block/overlay/machine/overlay_fluid_hatch_output" - } -} diff --git a/src/main/resources/assets/gtceu/models/block/machine/long_distance_item_pipeline_endpoint.json b/src/main/resources/assets/gtceu/models/block/machine/long_distance_item_pipeline_endpoint.json deleted file mode 100644 index 6e0d92c73c9..00000000000 --- a/src/main/resources/assets/gtceu/models/block/machine/long_distance_item_pipeline_endpoint.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "parent": "gtceu:block/machine/template/pipeline_endpoint_machine", - "textures": { - "overlay": "gtceu:block/pipe/ld_item_pipe/overlay", - "overlay_emissive": "gtceu:block/pipe/ld_item_pipe/overlay_emissive", - - "hatch_in": "gtceu:block/overlay/machine/overlay_item_hatch_input", - "hatch_out": "gtceu:block/overlay/machine/overlay_item_hatch_output" - } -} diff --git a/src/main/resources/assets/gtceu/models/block/machine/part/computer_monitor.json b/src/main/resources/assets/gtceu/models/block/machine/part/computer_monitor.json new file mode 100644 index 00000000000..73c914a3038 --- /dev/null +++ b/src/main/resources/assets/gtceu/models/block/machine/part/computer_monitor.json @@ -0,0 +1,6 @@ +{ + "parent": "gtceu:block/overlay/front_all", + "textures": { + "overlay": "gtceu:block/overlay/machine/overlay_monitor" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/gtceu/models/block/machine/part/dual_input_hatch.json b/src/main/resources/assets/gtceu/models/block/machine/part/dual_input_hatch.json index 9531074ca92..b817c2f2683 100644 --- a/src/main/resources/assets/gtceu/models/block/machine/part/dual_input_hatch.json +++ b/src/main/resources/assets/gtceu/models/block/machine/part/dual_input_hatch.json @@ -1,7 +1,8 @@ { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { - "overlay": "gtceu:block/overlay/machine/overlay_pipe", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_dual_hatch" + "overlay": "gtceu:block/overlay/machine/overlay_dual_hatch_input", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive" } } \ No newline at end of file diff --git a/src/main/resources/assets/gtceu/models/block/machine/part/dual_output_hatch.json b/src/main/resources/assets/gtceu/models/block/machine/part/dual_output_hatch.json index 9531074ca92..fe74008c266 100644 --- a/src/main/resources/assets/gtceu/models/block/machine/part/dual_output_hatch.json +++ b/src/main/resources/assets/gtceu/models/block/machine/part/dual_output_hatch.json @@ -1,7 +1,8 @@ { "parent": "gtceu:block/machine/template/part/hatch_machine_emissive", "textures": { - "overlay": "gtceu:block/overlay/machine/overlay_pipe", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_dual_hatch" + "overlay": "gtceu:block/overlay/machine/overlay_dual_hatch_output", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive" } } \ No newline at end of file diff --git a/src/main/resources/assets/gtceu/models/block/machine/part/fluid_passthrough_hatch.json b/src/main/resources/assets/gtceu/models/block/machine/part/fluid_passthrough_hatch.json index 6847277ba03..819ce6a2b29 100644 --- a/src/main/resources/assets/gtceu/models/block/machine/part/fluid_passthrough_hatch.json +++ b/src/main/resources/assets/gtceu/models/block/machine/part/fluid_passthrough_hatch.json @@ -1,51 +1,10 @@ { - "credit": "Made with Blockbench", - "parent": "block/block", - "textures": { - "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", - "overlay_pipe_in": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_fluid_hatch_input": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", - "overlay_fluid_hatch_output": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", - "overlay_pipe_out": "gtceu:block/overlay/machine/overlay_pipe_out_emissive" - }, - "elements": [ - { - "from": [ 0, 0, 0 ], - "to": [ 16, 16, 16 ], - "faces": { - "down": { "texture": "#bottom", "cullface": "down", "tintindex": 1 }, - "up": { "texture": "#top", "cullface": "up", "tintindex": 1 }, - "north": { "texture": "#side", "cullface": "north", "tintindex": 1 }, - "south": { "texture": "#side", "cullface": "south", "tintindex": 1 }, - "west": { "texture": "#side", "cullface": "west", "tintindex": 1 }, - "east": { "texture": "#side", "cullface": "east", "tintindex": 1 } - } - }, - { - "from": [ -0.01, -0.01, -0.01 ], - "to": [ 16.01, 16.01, 16.01 ], - "faces": { - "north": { "uv": [0, 0, 16, 16], "texture": "#overlay_pipe", "cullface": "north" }, - "south": { "uv": [0, 0, 16, 16], "texture": "#overlay_pipe", "cullface": "south" } - } - }, - { - "from": [ -0.02, -0.02, -0.02 ], - "to": [ 16.02, 16.02, 16.02 ], - "neoforge_data": { "block_light": 15, "sky_light": 15 }, - "shade": false, - "faces": { - "north": { "uv": [0, 0, 16, 16], "texture": "#overlay_pipe_in", "cullface": "north" }, - "south": { "uv": [0, 0, 16, 16], "texture": "#overlay_pipe_out", "cullface": "south" } - } - }, - { - "from": [ -0.02, -0.02, -0.02 ], - "to": [ 16.02, 16.02, 16.02 ], - "faces": { - "north": { "uv": [0, 0, 16, 16], "texture": "#overlay_fluid_hatch_input", "cullface": "north" }, - "south": { "uv": [0, 0, 16, 16], "texture": "#overlay_fluid_hatch_output", "cullface": "south" } - } - } - ] + "parent": "gtceu:block/machine/template/pipeline_endpoint_machine", + "textures": { + "overlay_side": "gtceu:block/void", + "overlay_side_emissive": "gtceu:block/void", + + "overlay_hatch_in": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_hatch_out": "gtceu:block/overlay/machine/overlay_fluid_hatch_output" + } } \ No newline at end of file diff --git a/src/main/resources/assets/gtceu/models/block/machine/part/item_passthrough_hatch.json b/src/main/resources/assets/gtceu/models/block/machine/part/item_passthrough_hatch.json index 1b039c27c4d..7498cdd20e5 100644 --- a/src/main/resources/assets/gtceu/models/block/machine/part/item_passthrough_hatch.json +++ b/src/main/resources/assets/gtceu/models/block/machine/part/item_passthrough_hatch.json @@ -1,51 +1,10 @@ { - "credit": "Made with Blockbench", - "parent": "block/block", - "textures": { - "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", - "overlay_pipe_in": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "overlay_item_hatch_input": "gtceu:block/overlay/machine/overlay_item_hatch_input", - "overlay_item_hatch_output": "gtceu:block/overlay/machine/overlay_item_hatch_output", - "overlay_pipe_out": "gtceu:block/overlay/machine/overlay_pipe_out_emissive" - }, - "elements": [ - { - "from": [ 0, 0, 0 ], - "to": [ 16, 16, 16 ], - "faces": { - "down": { "texture": "#bottom", "cullface": "down", "tintindex": 1 }, - "up": { "texture": "#top", "cullface": "up", "tintindex": 1 }, - "north": { "texture": "#side", "cullface": "north", "tintindex": 1 }, - "south": { "texture": "#side", "cullface": "south", "tintindex": 1 }, - "west": { "texture": "#side", "cullface": "west", "tintindex": 1 }, - "east": { "texture": "#side", "cullface": "east", "tintindex": 1 } - } - }, - { - "from": [ -0.01, -0.01, -0.01 ], - "to": [ 16.01, 16.01, 16.01 ], - "faces": { - "north": { "uv": [0, 0, 16, 16], "texture": "#overlay_pipe", "cullface": "north" }, - "south": { "uv": [0, 0, 16, 16], "texture": "#overlay_pipe", "cullface": "south" } - } - }, - { - "from": [ -0.02, -0.02, -0.02 ], - "to": [ 16.02, 16.02, 16.02 ], - "neoforge_data": { "block_light": 15, "sky_light": 15 }, - "shade": false, - "faces": { - "north": { "uv": [0, 0, 16, 16], "texture": "#overlay_pipe_in", "cullface": "north" }, - "south": { "uv": [0, 0, 16, 16], "texture": "#overlay_pipe_out", "cullface": "south" } - } - }, - { - "from": [ -0.02, -0.02, -0.02 ], - "to": [ 16.02, 16.02, 16.02 ], - "faces": { - "north": { "uv": [0, 0, 16, 16], "texture": "#overlay_item_hatch_input", "cullface": "north" }, - "south": { "uv": [0, 0, 16, 16], "texture": "#overlay_item_hatch_output", "cullface": "south" } - } - } - ] + "parent": "gtceu:block/machine/template/pipeline_endpoint_machine", + "textures": { + "overlay_side": "gtceu:block/void", + "overlay_side_emissive": "gtceu:block/void", + + "overlay_hatch_in": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_hatch_out": "gtceu:block/overlay/machine/overlay_item_hatch_output" + } } \ No newline at end of file diff --git a/src/main/resources/assets/gtceu/models/block/machine/part/laser_source_hatch.json b/src/main/resources/assets/gtceu/models/block/machine/part/laser_source_hatch.json index aff258f1306..f1678db9e1d 100644 --- a/src/main/resources/assets/gtceu/models/block/machine/part/laser_source_hatch.json +++ b/src/main/resources/assets/gtceu/models/block/machine/part/laser_source_hatch.json @@ -2,6 +2,7 @@ "credit": "Made with Blockbench", "parent": "block/block", "textures": { + "particle": "#side", "overlay_laser": "gtceu:block/overlay/machine/overlay_laser_base", "overlay_laser_source": "gtceu:block/overlay/machine/overlay_laser_source", "overlay_laser_source_emissive": "gtceu:block/overlay/machine/overlay_laser_source_emissive" diff --git a/src/main/resources/assets/gtceu/models/block/machine/part/laser_target_hatch.json b/src/main/resources/assets/gtceu/models/block/machine/part/laser_target_hatch.json index 89032b93d7d..05c81b36821 100644 --- a/src/main/resources/assets/gtceu/models/block/machine/part/laser_target_hatch.json +++ b/src/main/resources/assets/gtceu/models/block/machine/part/laser_target_hatch.json @@ -2,6 +2,7 @@ "credit": "Made with Blockbench", "parent": "block/block", "textures": { + "particle": "#side", "overlay_laser": "gtceu:block/overlay/machine/overlay_laser_base", "overlay_laser_target": "gtceu:block/overlay/machine/overlay_laser_target", "overlay_laser_target_emissive": "gtceu:block/overlay/machine/overlay_laser_target_emissive" diff --git a/src/main/resources/assets/gtceu/models/block/machine/part/long_distance_fluid_pipeline_endpoint.json b/src/main/resources/assets/gtceu/models/block/machine/part/long_distance_fluid_pipeline_endpoint.json new file mode 100644 index 00000000000..269b69f9f8f --- /dev/null +++ b/src/main/resources/assets/gtceu/models/block/machine/part/long_distance_fluid_pipeline_endpoint.json @@ -0,0 +1,10 @@ +{ + "parent": "gtceu:block/machine/template/pipeline_endpoint_machine", + "textures": { + "overlay_side": "gtceu:block/pipe/ld_fluid_pipe/overlay", + "overlay_side_emissive": "gtceu:block/pipe/ld_fluid_pipe/overlay_emissive", + + "overlay_hatch_in": "gtceu:block/overlay/machine/overlay_fluid_hatch_input", + "overlay_hatch_out": "gtceu:block/overlay/machine/overlay_fluid_hatch_output" + } +} diff --git a/src/main/resources/assets/gtceu/models/block/machine/part/long_distance_item_pipeline_endpoint.json b/src/main/resources/assets/gtceu/models/block/machine/part/long_distance_item_pipeline_endpoint.json new file mode 100644 index 00000000000..aff7f4212fa --- /dev/null +++ b/src/main/resources/assets/gtceu/models/block/machine/part/long_distance_item_pipeline_endpoint.json @@ -0,0 +1,10 @@ +{ + "parent": "gtceu:block/machine/template/pipeline_endpoint_machine", + "textures": { + "overlay_side": "gtceu:block/pipe/ld_item_pipe/overlay", + "overlay_side_emissive": "gtceu:block/pipe/ld_item_pipe/overlay_emissive", + + "overlay_hatch_in": "gtceu:block/overlay/machine/overlay_item_hatch_input", + "overlay_hatch_out": "gtceu:block/overlay/machine/overlay_item_hatch_output" + } +} diff --git a/src/main/resources/assets/gtceu/models/block/machine/part/pump_hatch.json b/src/main/resources/assets/gtceu/models/block/machine/part/pump_hatch.json index f47920c6990..401dc419068 100644 --- a/src/main/resources/assets/gtceu/models/block/machine/part/pump_hatch.json +++ b/src/main/resources/assets/gtceu/models/block/machine/part/pump_hatch.json @@ -5,7 +5,8 @@ "top": "gtceu:block/casings/pump_deck/top", "side": "#top", - "overlay": "gtceu:block/overlay/machine/overlay_pipe", - "overlay_emissive": "gtceu:block/overlay/machine/overlay_fluid_hatch" + "overlay": "gtceu:block/overlay/machine/overlay_fluid_hatch_output", + "overlay_pipe": "gtceu:block/overlay/machine/overlay_pipe", + "overlay_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive" } } \ No newline at end of file diff --git a/src/main/resources/assets/gtceu/models/block/machine/template/pipeline_endpoint_machine.json b/src/main/resources/assets/gtceu/models/block/machine/template/pipeline_endpoint_machine.json index a50720f3a30..0971bad09fe 100644 --- a/src/main/resources/assets/gtceu/models/block/machine/template/pipeline_endpoint_machine.json +++ b/src/main/resources/assets/gtceu/models/block/machine/template/pipeline_endpoint_machine.json @@ -2,13 +2,10 @@ "parent": "block/block", "textures": { "particle": "#side", - "bottom": "gtceu:block/casings/voltage/lv/bottom", - "top": "gtceu:block/casings/voltage/lv/top", - "side": "gtceu:block/casings/voltage/lv/side", "pipe": "gtceu:block/overlay/machine/overlay_pipe", - "pipe_in": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", - "pipe_out": "gtceu:block/overlay/machine/overlay_pipe_out_emissive" + "overlay_pipe_in_emissive": "gtceu:block/overlay/machine/overlay_pipe_in_emissive", + "overlay_pipe_out_emissive": "gtceu:block/overlay/machine/overlay_pipe_out_emissive" }, "elements": [ { @@ -27,20 +24,20 @@ "from": [ -0.01, -0.01, -0.01 ], "to": [ 16.01, 16.01, 16.01 ], "faces": { - "north": { "uv": [0, 0, 16, 16], "texture": "#pipe_in", "rotation": 0, "cullface": "north" }, - "south": { "uv": [0, 0, 16, 16], "texture": "#pipe_out", "rotation": 0, "cullface": "south" }, - "up": { "uv": [0, 0, 16, 16], "texture": "#overlay", "rotation": 0, "cullface": "up" }, - "down": { "uv": [0, 0, 16, 16], "texture": "#overlay", "rotation": 180, "cullface": "down" }, - "west": { "uv": [0, 0, 16, 16], "texture": "#overlay", "rotation": 90, "cullface": "west" }, - "east": { "uv": [0, 0, 16, 16], "texture": "#overlay", "rotation": 270, "cullface": "east" } + "north": { "uv": [0, 0, 16, 16], "texture": "#pipe", "cullface": "north" }, + "south": { "uv": [0, 0, 16, 16], "texture": "#pipe", "cullface": "south" } } }, { "from": [ -0.02, -0.02, -0.02 ], "to": [ 16.02, 16.02, 16.02 ], "faces": { - "north": { "uv": [0, 0, 16, 16], "texture": "#pipe", "cullface": "north" }, - "south": { "uv": [0, 0, 16, 16], "texture": "#pipe", "cullface": "south" } + "north": { "uv": [0, 0, 16, 16], "texture": "#overlay_hatch_in", "rotation": 0, "cullface": "north" }, + "south": { "uv": [0, 0, 16, 16], "texture": "#overlay_hatch_out", "rotation": 0, "cullface": "south" }, + "up": { "uv": [0, 0, 16, 16], "texture": "#overlay_side", "rotation": 180, "cullface": "up" }, + "down": { "uv": [0, 0, 16, 16], "texture": "#overlay_side", "rotation": 0, "cullface": "down" }, + "west": { "uv": [0, 0, 16, 16], "texture": "#overlay_side", "rotation": 90, "cullface": "west" }, + "east": { "uv": [0, 0, 16, 16], "texture": "#overlay_side", "rotation": 270, "cullface": "east" } } }, { @@ -49,20 +46,12 @@ "neoforge_data": { "block_light": 15, "sky_light": 15 }, "shade": false, "faces": { - "up": { "uv": [0, 0, 16, 16], "texture": "#overlay_emissive", "rotation": 0, "cullface": "up", "tintindex": -101 }, - "down": { "uv": [0, 0, 16, 16], "texture": "#overlay_emissive", "rotation": 180, "cullface": "down", "tintindex": -101 }, - "west": { "uv": [0, 0, 16, 16], "texture": "#overlay_emissive", "rotation": 90, "cullface": "west", "tintindex": -101 }, - "east": { "uv": [0, 0, 16, 16], "texture": "#overlay_emissive", "rotation": 270, "cullface": "east", "tintindex": -101 }, - "north": { "uv": [0, 0, 16, 16], "texture": "#pipe_in", "cullface": "north", "tintindex": -101 }, - "south": { "uv": [0, 0, 16, 16], "texture": "#pipe_out", "cullface": "south", "tintindex": -101 } - } - }, - { - "from": [ -0.03, -0.03, -0.03 ], - "to": [ 16.03, 16.03, 16.03 ], - "faces": { - "north": { "uv": [0, 0, 16, 16], "texture": "#hatch_in", "cullface": "north" }, - "south": { "uv": [0, 0, 16, 16], "texture": "#hatch_out", "cullface": "south" } + "up": { "uv": [0, 0, 16, 16], "texture": "#overlay_side_emissive", "rotation": 180, "cullface": "up", "tintindex": -101 }, + "down": { "uv": [0, 0, 16, 16], "texture": "#overlay_side_emissive", "rotation": 0, "cullface": "down", "tintindex": -101 }, + "west": { "uv": [0, 0, 16, 16], "texture": "#overlay_side_emissive", "rotation": 90, "cullface": "west", "tintindex": -101 }, + "east": { "uv": [0, 0, 16, 16], "texture": "#overlay_side_emissive", "rotation": 270, "cullface": "east", "tintindex": -101 }, + "north": { "uv": [0, 0, 16, 16], "texture": "#overlay_pipe_in_emissive", "cullface": "north", "tintindex": -101 }, + "south": { "uv": [0, 0, 16, 16], "texture": "#overlay_pipe_out_emissive", "cullface": "south", "tintindex": -101 } } } ] diff --git a/src/main/resources/assets/gtceu/models/block/overlay/front_all.json b/src/main/resources/assets/gtceu/models/block/overlay/front_all.json new file mode 100644 index 00000000000..5f89a979bf0 --- /dev/null +++ b/src/main/resources/assets/gtceu/models/block/overlay/front_all.json @@ -0,0 +1,24 @@ +{ + "parent": "gtceu:block/cube/tinted/all", + "elements": [ + { + "from": [ 0, 0, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "texture": "#all", "cullface": "down", "tintindex": 1 }, + "up": { "texture": "#all", "cullface": "up", "tintindex": 1 }, + "north": { "texture": "#all", "cullface": "north", "tintindex": 1 }, + "south": { "texture": "#all", "cullface": "south", "tintindex": 1 }, + "west": { "texture": "#all", "cullface": "west", "tintindex": 1 }, + "east": { "texture": "#all", "cullface": "east", "tintindex": 1 } + } + }, + { + "from": [ 0, 0, -0.01 ], + "to": [ 16, 16, -0.01 ], + "faces": { + "north": { "uv": [0, 0, 16, 16], "texture": "#overlay", "cullface": "north" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/gtceu/models/item/material_sets/bright/ingot_double.json b/src/main/resources/assets/gtceu/models/item/material_sets/bright/ingot_double.json index 53d5565a325..171a8f42ad1 100644 --- a/src/main/resources/assets/gtceu/models/item/material_sets/bright/ingot_double.json +++ b/src/main/resources/assets/gtceu/models/item/material_sets/bright/ingot_double.json @@ -1,6 +1,8 @@ { - "parent": "gtceu:item/material_sets/bright/ingot", + "parent": "item/generated", "textures": { - "layer3": "gtceu:item/material_sets/dull/ingot_double_overlay" + "layer0": "gtceu:item/material_sets/bright/ingot_double", + "layer1": "gtceu:item/material_sets/bright/ingot_double_secondary", + "layer2": "gtceu:item/material_sets/bright/ingot_double_overlay" } } diff --git a/src/main/resources/assets/gtceu/models/item/material_sets/dull/ingot_double.json b/src/main/resources/assets/gtceu/models/item/material_sets/dull/ingot_double.json index a10ca09d785..ac6af3f85ce 100644 --- a/src/main/resources/assets/gtceu/models/item/material_sets/dull/ingot_double.json +++ b/src/main/resources/assets/gtceu/models/item/material_sets/dull/ingot_double.json @@ -1,6 +1,8 @@ { - "parent": "gtceu:item/material_sets/dull/ingot", + "parent": "item/generated", "textures": { - "layer3": "gtceu:item/material_sets/dull/ingot_double_overlay" + "layer0": "gtceu:item/material_sets/dull/ingot_double", + "layer1": "gtceu:item/material_sets/dull/ingot_double_secondary", + "layer2": "gtceu:item/material_sets/dull/ingot_double_overlay" } } diff --git a/src/main/resources/assets/gtceu/models/item/material_sets/metallic/ingot_double.json b/src/main/resources/assets/gtceu/models/item/material_sets/metallic/ingot_double.json index c94b4641717..ced1eda1be4 100644 --- a/src/main/resources/assets/gtceu/models/item/material_sets/metallic/ingot_double.json +++ b/src/main/resources/assets/gtceu/models/item/material_sets/metallic/ingot_double.json @@ -1,6 +1,8 @@ { - "parent": "gtceu:item/material_sets/metallic/ingot", + "parent": "item/generated", "textures": { - "layer3": "gtceu:item/material_sets/metallic/ingot_double_overlay" + "layer0": "gtceu:item/material_sets/metallic/ingot_double", + "layer1": "gtceu:item/material_sets/metallic/ingot_double_secondary", + "layer2": "gtceu:item/material_sets/metallic/ingot_double_overlay" } } diff --git a/src/main/resources/assets/gtceu/models/item/material_sets/shiny/ingot_double.json b/src/main/resources/assets/gtceu/models/item/material_sets/shiny/ingot_double.json index 589469e92a8..422c0df1009 100644 --- a/src/main/resources/assets/gtceu/models/item/material_sets/shiny/ingot_double.json +++ b/src/main/resources/assets/gtceu/models/item/material_sets/shiny/ingot_double.json @@ -1,6 +1,8 @@ { - "parent": "gtceu:item/material_sets/shiny/ingot", + "parent": "item/generated", "textures": { - "layer3": "gtceu:item/material_sets/shiny/ingot_double_overlay" + "layer0": "gtceu:item/material_sets/shiny/ingot_double", + "layer1": "gtceu:item/material_sets/shiny/ingot_double_secondary", + "layer2": "gtceu:item/material_sets/shiny/ingot_double_overlay" } } diff --git a/src/main/resources/assets/gtceu/models/item/material_sets/shiny/plate_double.json b/src/main/resources/assets/gtceu/models/item/material_sets/shiny/plate_double.json index 49b4fd51a30..830a49cb73f 100644 --- a/src/main/resources/assets/gtceu/models/item/material_sets/shiny/plate_double.json +++ b/src/main/resources/assets/gtceu/models/item/material_sets/shiny/plate_double.json @@ -3,6 +3,6 @@ "textures": { "layer0": "gtceu:item/material_sets/shiny/plate_double", "layer1": "gtceu:item/material_sets/shiny/plate_double_secondary", - "layer3": "gtceu:item/material_sets/shiny/plate_double_overlay" + "layer2": "gtceu:item/material_sets/shiny/plate_double_overlay" } } diff --git a/src/main/resources/assets/gtceu/models/item/tools/lv_chainsaw.json b/src/main/resources/assets/gtceu/models/item/tools/lv_chainsaw.json index 481d9e2285d..6d04bc3ea67 100644 --- a/src/main/resources/assets/gtceu/models/item/tools/lv_chainsaw.json +++ b/src/main/resources/assets/gtceu/models/item/tools/lv_chainsaw.json @@ -3,6 +3,7 @@ "textures": { "layer0": "gtceu:item/tools/power_unit_lv", "layer1": "gtceu:item/tools/chainsaw", - "layer2": "gtceu:item/tools/chainsaw_body" + "layer2": "gtceu:item/void", + "layer3": "gtceu:item/tools/chainsaw_body" } } diff --git a/src/main/resources/assets/gtceu/textures/block/cover/computer_monitor_emissive.png b/src/main/resources/assets/gtceu/textures/block/cover/computer_monitor_emissive.png deleted file mode 100644 index 39f7ce433dd..00000000000 Binary files a/src/main/resources/assets/gtceu/textures/block/cover/computer_monitor_emissive.png and /dev/null differ diff --git a/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link.png b/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link.png new file mode 100644 index 00000000000..45213f0d332 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link.png.mcmeta b/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link.png.mcmeta new file mode 100644 index 00000000000..23c14fb6718 --- /dev/null +++ b/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation":{ + "frametime":4 + } +} diff --git a/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link_emissive.png b/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link_emissive.png new file mode 100644 index 00000000000..1a1c7fda464 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link_emissive.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link_emissive.png.mcmeta b/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link_emissive.png.mcmeta new file mode 100644 index 00000000000..23c14fb6718 --- /dev/null +++ b/src/main/resources/assets/gtceu/textures/block/cover/ender_item_link_emissive.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation":{ + "frametime":4 + } +} diff --git a/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link.png b/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link.png new file mode 100644 index 00000000000..45213f0d332 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link.png.mcmeta b/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link.png.mcmeta new file mode 100644 index 00000000000..23c14fb6718 --- /dev/null +++ b/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation":{ + "frametime":4 + } +} diff --git a/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link_emissive.png b/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link_emissive.png new file mode 100644 index 00000000000..1a1c7fda464 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link_emissive.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link_emissive.png.mcmeta b/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link_emissive.png.mcmeta new file mode 100644 index 00000000000..23c14fb6718 --- /dev/null +++ b/src/main/resources/assets/gtceu/textures/block/cover/ender_redstone_link_emissive.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation":{ + "frametime":4 + } +} diff --git a/src/main/resources/assets/gtceu/textures/block/cover/wireless_transmitter.png b/src/main/resources/assets/gtceu/textures/block/cover/wireless_transmitter.png new file mode 100644 index 00000000000..68ddbb87707 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/cover/wireless_transmitter.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front.png b/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front.png new file mode 100644 index 00000000000..d6fcdf974a8 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front_active.png b/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front_active.png new file mode 100644 index 00000000000..d6fcdf974a8 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front_active.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front_active_emissive.png b/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front_active_emissive.png new file mode 100644 index 00000000000..a556f63bc84 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front_active_emissive.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front_active_emissive.png.mcmeta b/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front_active_emissive.png.mcmeta new file mode 100644 index 00000000000..3de4a0bdd81 --- /dev/null +++ b/src/main/resources/assets/gtceu/textures/block/multiblock/central_monitor/overlay_front_active_emissive.png.mcmeta @@ -0,0 +1,5 @@ +{ + "animation": { + "frametime": 8 + } +} diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_steel_boiler/overlay_front_paused.png b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_steel_boiler/overlay_front_paused.png index 901e9e1e126..9720a90d8c8 100644 Binary files a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_steel_boiler/overlay_front_paused.png and b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_steel_boiler/overlay_front_paused.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_steel_boiler/overlay_front_paused_emissive.png b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_steel_boiler/overlay_front_paused_emissive.png index f18b9aa3899..049854f6c81 100644 Binary files a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_steel_boiler/overlay_front_paused_emissive.png and b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_steel_boiler/overlay_front_paused_emissive.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front.png b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front.png index 729e656da01..8a0a9134784 100644 Binary files a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front.png and b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active.png b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active.png index cad1bcaa2bb..173f15cda60 100644 Binary files a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active.png and b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active.png.mcmeta b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active.png.mcmeta deleted file mode 100644 index cfcef74876f..00000000000 --- a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active.png.mcmeta +++ /dev/null @@ -1,10 +0,0 @@ -{ - "animation": { - "frametime": 16, - "frames": [ - 0, - 1, - 2 - ] - } -} \ No newline at end of file diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active_emissive.png b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active_emissive.png index 76c223417d8..4ed7c8ec02a 100644 Binary files a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active_emissive.png and b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active_emissive.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active_emissive.png.mcmeta b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active_emissive.png.mcmeta deleted file mode 100644 index cfcef74876f..00000000000 --- a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_active_emissive.png.mcmeta +++ /dev/null @@ -1,10 +0,0 @@ -{ - "animation": { - "frametime": 16, - "frames": [ - 0, - 1, - 2 - ] - } -} \ No newline at end of file diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_emissive.png b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_emissive.png index 0486a073200..e1ea0b2d792 100644 Binary files a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_emissive.png and b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_emissive.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_paused.png b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_paused.png index 901e9e1e126..bca74d28f46 100644 Binary files a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_paused.png and b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_paused.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_paused_emissive.png b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_paused_emissive.png index f18b9aa3899..9335e01fc4a 100644 Binary files a/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_paused_emissive.png and b/src/main/resources/assets/gtceu/textures/block/multiblock/generator/large_tungstensteel_boiler/overlay_front_paused_emissive.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_dual_hatch_input.png b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_dual_hatch_input.png new file mode 100644 index 00000000000..06dbce00473 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_dual_hatch_input.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_dual_hatch_output.png b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_dual_hatch_output.png new file mode 100644 index 00000000000..1a1fd572a1c Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_dual_hatch_output.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_fluid_hatch_output.png b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_fluid_hatch_output.png index 91b0b07d157..56af33b4718 100644 Binary files a/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_fluid_hatch_output.png and b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_fluid_hatch_output.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_monitor.png b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_monitor.png new file mode 100644 index 00000000000..af74a983e27 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_monitor.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_monitor.png.mcmeta b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_monitor.png.mcmeta new file mode 100644 index 00000000000..38c2c75c408 --- /dev/null +++ b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_monitor.png.mcmeta @@ -0,0 +1,5 @@ +{ + "ldlib": { + "connection": "gtceu:block/overlay/machine/overlay_monitor_ctm" + } +} diff --git a/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_monitor_ctm.png b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_monitor_ctm.png new file mode 100644 index 00000000000..1e6e270cc34 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/block/overlay/machine/overlay_monitor_ctm.png differ diff --git a/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay.png b/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay.png index dea20fbab81..5a30856923b 100644 Binary files a/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay.png and b/src/main/resources/assets/gtceu/textures/block/pipe/ld_item_pipe/overlay.png differ diff --git a/src/main/resources/assets/gtceu/textures/gui/icon/manual_io_mode/disabled.png b/src/main/resources/assets/gtceu/textures/gui/icon/manual_io_mode/disabled.png index 7eb473b4828..c257b727dd5 100644 Binary files a/src/main/resources/assets/gtceu/textures/gui/icon/manual_io_mode/disabled.png and b/src/main/resources/assets/gtceu/textures/gui/icon/manual_io_mode/disabled.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/ender_item_link_cover.png b/src/main/resources/assets/gtceu/textures/item/ender_item_link_cover.png new file mode 100644 index 00000000000..0634a16f99a Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/item/ender_item_link_cover.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/ender_redstone_link_cover.png b/src/main/resources/assets/gtceu/textures/item/ender_redstone_link_cover.png new file mode 100644 index 00000000000..0634a16f99a Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/item/ender_redstone_link_cover.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/huge_pipe_casting_mold.png b/src/main/resources/assets/gtceu/textures/item/huge_pipe_casting_mold.png new file mode 100644 index 00000000000..6f18a255051 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/item/huge_pipe_casting_mold.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/image_module.png b/src/main/resources/assets/gtceu/textures/item/image_module.png new file mode 100644 index 00000000000..8b532f20234 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/item/image_module.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/item_smart_filter.png b/src/main/resources/assets/gtceu/textures/item/item_smart_filter.png new file mode 100644 index 00000000000..f943b95be4f Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/item/item_smart_filter.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/large_pipe_casting_mold.png b/src/main/resources/assets/gtceu/textures/item/large_pipe_casting_mold.png new file mode 100644 index 00000000000..e67f9349d2a Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/item/large_pipe_casting_mold.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/normal_pipe_casting_mold.png b/src/main/resources/assets/gtceu/textures/item/normal_pipe_casting_mold.png new file mode 100644 index 00000000000..19abb0db7f4 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/item/normal_pipe_casting_mold.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/programmed_circuit/10.png b/src/main/resources/assets/gtceu/textures/item/programmed_circuit/10.png index a776e052586..6ea69cec358 100644 Binary files a/src/main/resources/assets/gtceu/textures/item/programmed_circuit/10.png and b/src/main/resources/assets/gtceu/textures/item/programmed_circuit/10.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/programmed_circuit/20.png b/src/main/resources/assets/gtceu/textures/item/programmed_circuit/20.png index 2d4fcd4a6b5..9b273e90e34 100644 Binary files a/src/main/resources/assets/gtceu/textures/item/programmed_circuit/20.png and b/src/main/resources/assets/gtceu/textures/item/programmed_circuit/20.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/small_pipe_casting_mold.png b/src/main/resources/assets/gtceu/textures/item/small_pipe_casting_mold.png new file mode 100644 index 00000000000..ba4a6e6a72c Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/item/small_pipe_casting_mold.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/text_module.png b/src/main/resources/assets/gtceu/textures/item/text_module.png new file mode 100644 index 00000000000..ad997f1a0ab Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/item/text_module.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/tiny_pipe_casting_mold.png b/src/main/resources/assets/gtceu/textures/item/tiny_pipe_casting_mold.png new file mode 100644 index 00000000000..a40679f3d52 Binary files /dev/null and b/src/main/resources/assets/gtceu/textures/item/tiny_pipe_casting_mold.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/tools/crowbar.png b/src/main/resources/assets/gtceu/textures/item/tools/crowbar.png index 585ee9d92f5..022d1e91037 100644 Binary files a/src/main/resources/assets/gtceu/textures/item/tools/crowbar.png and b/src/main/resources/assets/gtceu/textures/item/tools/crowbar.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/tools/crowbar_overlay.png b/src/main/resources/assets/gtceu/textures/item/tools/crowbar_overlay.png index 00295809ccd..85a9b8eecff 100644 Binary files a/src/main/resources/assets/gtceu/textures/item/tools/crowbar_overlay.png and b/src/main/resources/assets/gtceu/textures/item/tools/crowbar_overlay.png differ diff --git a/src/main/resources/assets/gtceu/textures/item/digital_interface_cover.png b/src/main/resources/assets/gtceu/textures/item/wireless_transmitter_cover.png similarity index 100% rename from src/main/resources/assets/gtceu/textures/item/digital_interface_cover.png rename to src/main/resources/assets/gtceu/textures/item/wireless_transmitter_cover.png diff --git a/src/main/resources/data/gtceu/gametest/structures/ebf.snbt b/src/main/resources/data/gtceu/gametest/structures/ebf.snbt deleted file mode 100644 index 91d1ae8fa5b..00000000000 --- a/src/main/resources/data/gtceu/gametest/structures/ebf.snbt +++ /dev/null @@ -1,69 +0,0 @@ -{ - DataVersion: 3465, - size: [3, 4, 4], - data: [ - {pos: [0, 0, 0], state: "gtceu:heatproof_machine_casing"}, - {pos: [0, 0, 1], state: "gtceu:heatproof_machine_casing"}, - {pos: [0, 0, 2], state: "gtceu:auto_maintenance_hatch{facing:south,server_tick:false}", nbt: {ForgeCaps: {}, cover: {}, id: "gtceu:auto_maintenance_hatch", paintingColor: -1}}, - {pos: [0, 0, 3], state: "minecraft:air"}, - {pos: [1, 0, 0], state: "gtceu:electric_blast_furnace{facing:north,server_tick:false}", nbt: {ForgeCaps: {}, activeRecipeType: 0, cover: {}, id: "gtceu:electric_blast_furnace", isFormed: 1b, isMuffled: 0b, paintingColor: -1, recipeLogic: {duration: 0, fuelMaxTime: 0, fuelTime: 0, progress: 0, status: "IDLE", totalContinuousRunningTime: 0L}}}, - {pos: [1, 0, 1], state: "gtceu:heatproof_machine_casing"}, - {pos: [1, 0, 2], state: "gtceu:heatproof_machine_casing"}, - {pos: [1, 0, 3], state: "minecraft:air"}, - {pos: [2, 0, 0], state: "gtceu:heatproof_machine_casing"}, - {pos: [2, 0, 1], state: "gtceu:heatproof_machine_casing"}, - {pos: [2, 0, 2], state: "gtceu:uv_energy_input_hatch{facing:south,server_tick:false}", nbt: {ForgeCaps: {}, cover: {}, energyContainer: {energyStored: 16777216L, isDistinct: 0b}, id: "gtceu:uv_energy_input_hatch", paintingColor: -1, workingEnabled: 1b}}, - {pos: [2, 0, 3], state: "gtceu:infinite_energy{server_tick:true}", nbt: {ForgeCaps: {}, active: 1b, amps: 2, cover: {}, energyIOPerSec: 0L, id: "gtceu:infinite_energy", paintingColor: -1, setTier: 8, source: 1b, voltage: 524288L}}, - {pos: [0, 1, 0], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [0, 1, 1], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [0, 1, 2], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [0, 1, 3], state: "minecraft:air"}, - {pos: [1, 1, 0], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [1, 1, 1], state: "minecraft:air"}, - {pos: [1, 1, 2], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [1, 1, 3], state: "minecraft:air"}, - {pos: [2, 1, 0], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [2, 1, 1], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [2, 1, 2], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [2, 1, 3], state: "minecraft:air"}, - {pos: [0, 2, 0], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [0, 2, 1], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [0, 2, 2], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [0, 2, 3], state: "minecraft:air"}, - {pos: [1, 2, 0], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [1, 2, 1], state: "minecraft:air"}, - {pos: [1, 2, 2], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [1, 2, 3], state: "minecraft:air"}, - {pos: [2, 2, 0], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [2, 2, 1], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [2, 2, 2], state: "gtceu:cupronickel_coil_block{active:false}"}, - {pos: [2, 2, 3], state: "minecraft:air"}, - {pos: [0, 3, 0], state: "gtceu:heatproof_machine_casing"}, - {pos: [0, 3, 1], state: "gtceu:heatproof_machine_casing"}, - {pos: [0, 3, 2], state: "gtceu:heatproof_machine_casing"}, - {pos: [0, 3, 3], state: "minecraft:air"}, - {pos: [1, 3, 0], state: "gtceu:lv_output_hatch{facing:north,server_tick:false}", nbt: {ForgeCaps: {}, cover: {}, id: "gtceu:lv_output_hatch", paintingColor: -1, tank: {isDistinct: 0b, storages: [{p: {Amount: 0L, FluidName: "minecraft:empty"}, t: 11b}]}, workingEnabled: 1b}}, - {pos: [1, 3, 1], state: "gtceu:iv_muffler_hatch{facing:up,server_tick:false}", nbt: {ForgeCaps: {}, cover: {}, id: "gtceu:iv_muffler_hatch", inventory: {Items: [], Size: 36}, paintingColor: -1}}, - {pos: [1, 3, 2], state: "gtceu:heatproof_machine_casing"}, - {pos: [1, 3, 3], state: "minecraft:air"}, - {pos: [2, 3, 0], state: "gtceu:lv_output_bus{facing:east,server_tick:false}", nbt: {ForgeCaps: {}, circuitInventory: {isDistinct: 0b, storage: {Items: [], Size: 0}}, cover: {}, id: "gtceu:lv_output_bus", inventory: {isDistinct: 0b, storage: {Items: [], Size: 4}}, paintingColor: -1, workingEnabled: 1b}}, - {pos: [2, 3, 1], state: "gtceu:lv_input_hatch{facing:east,server_tick:false}", nbt: {ForgeCaps: {}, cover: {}, id: "gtceu:lv_input_hatch", paintingColor: -1, tank: {isDistinct: 0b, storages: [{p: {Amount: 0L, FluidName: "minecraft:empty"}, t: 11b}]}, workingEnabled: 1b}}, - {pos: [2, 3, 2], state: "gtceu:lv_input_bus{facing:east,server_tick:false}", nbt: {ForgeCaps: {}, circuitInventory: {isDistinct: 0b, storage: {Items: [], Size: 1}}, cover: {}, id: "gtceu:lv_input_bus", inventory: {isDistinct: 0b, storage: {Items: [], Size: 4}}, paintingColor: -1, workingEnabled: 1b}}, - {pos: [2, 3, 3], state: "minecraft:air"} - ], - entities: [], - palette: [ - "gtceu:heatproof_machine_casing", - "gtceu:cupronickel_coil_block{active:false}", - "minecraft:air", - "gtceu:auto_maintenance_hatch{facing:south,server_tick:false}", - "gtceu:electric_blast_furnace{facing:north,server_tick:false}", - "gtceu:uv_energy_input_hatch{facing:south,server_tick:false}", - "gtceu:infinite_energy{server_tick:true}", - "gtceu:lv_output_hatch{facing:north,server_tick:false}", - "gtceu:iv_muffler_hatch{facing:up,server_tick:false}", - "gtceu:lv_output_bus{facing:east,server_tick:false}", - "gtceu:lv_input_hatch{facing:east,server_tick:false}", - "gtceu:lv_input_bus{facing:east,server_tick:false}" - ] -} diff --git a/src/main/resources/data/gtceu/gametest/structures/recipelogic.snbt b/src/main/resources/data/gtceu/gametest/structures/recipelogic.snbt deleted file mode 100644 index f0d9de6d453..00000000000 --- a/src/main/resources/data/gtceu/gametest/structures/recipelogic.snbt +++ /dev/null @@ -1,13 +0,0 @@ -{ - DataVersion: 3465, - size: [1, 2, 1], - data: [ - {pos: [0, 0, 0], state: "gtceu:infinite_energy{server_tick:true}", nbt: {ForgeCaps: {}, active: 1b, amps: 1, cover: {}, energyIOPerSec: 0L, id: "gtceu:infinite_energy", paintingColor: -1, setTier: 1, source: 1b, voltage: 32L}}, - {pos: [0, 1, 0], state: "gtceu:lv_chemical_reactor{facing:north,server_tick:false}", nbt: {ForgeCaps: {}, activeRecipeType: 0, allowInputFromOutputSideFluids: 0b, allowInputFromOutputSideItems: 0b, autoOutputFluids: 0b, autoOutputItems: 0b, chargerInventory: {Items: [], Size: 1}, circuitInventory: {isDistinct: 0b, storage: {Items: [], Size: 1}}, cover: {}, energyContainer: {energyStored: 2048L, isDistinct: 0b}, exportFluids: {isDistinct: 0b, storages: [{p: {Amount: 0L, FluidName: "minecraft:empty"}, t: 11b}, {p: {Amount: 0L, FluidName: "minecraft:empty"}, t: 11b}]}, exportItems: {isDistinct: 0b, storage: {Items: [{Count: 32b, Slot: 0, id: "minecraft:stone"}], Size: 2}}, id: "gtceu:lv_chemical_reactor", importFluids: {isDistinct: 0b, storages: [{p: {Amount: 0L, FluidName: "minecraft:empty"}, t: 11b}, {p: {Amount: 0L, FluidName: "minecraft:empty"}, t: 11b}, {p: {Amount: 0L, FluidName: "minecraft:empty"}, t: 11b}]}, importItems: {isDistinct: 0b, storage: {Items: [], Size: 2}}, isMuffled: 0b, outputFacingFluids: "south", outputFacingItems: "south", overclockTier: 1, paintingColor: -1, recipeLogic: {duration: 0, fuelMaxTime: 0, fuelTime: 0, progress: 0, status: "IDLE", totalContinuousRunningTime: 0L}}} - ], - entities: [], - palette: [ - "gtceu:infinite_energy{server_tick:true}", - "gtceu:lv_chemical_reactor{facing:north,server_tick:false}" - ] -} diff --git a/src/main/resources/data/gtceu/structures/recipelogictest.recipelogic.nbt_ b/src/main/resources/data/gtceu/structures/recipelogictest.recipelogic.nbt_ deleted file mode 100644 index c8ca803abd0..00000000000 Binary files a/src/main/resources/data/gtceu/structures/recipelogictest.recipelogic.nbt_ and /dev/null differ diff --git a/src/main/resources/gtceu.mixins.json b/src/main/resources/gtceu.mixins.json index fd100e0d170..d8dc14e13a4 100644 --- a/src/main/resources/gtceu.mixins.json +++ b/src/main/resources/gtceu.mixins.json @@ -41,6 +41,8 @@ "DataFixTypesMixin", "EntityMixin", "FluidStackAccessor", + "GrowingPlantBlockAccessor", + "IntegerPropertyAccessor", "InventoryMixin", "IOWorkerMixin", "LevelAccessor", @@ -64,6 +66,7 @@ "StructureMixin", "TagLoaderMixin", "TagManagerMixin", + "client.ItemEntityMixin", "emi.FillRecipePacketMixin", "emi.FluidEmiStackMixin", "jei.FluidHelperMixin", diff --git a/src/test/README.md b/src/test/README.md new file mode 100644 index 00000000000..3d9db0a74a5 --- /dev/null +++ b/src/test/README.md @@ -0,0 +1,238 @@ +# Guide to Writing GameTests in GTCEu + +--- + +## Table of Contents + +1. [Defining a Test Class](#defining-a-test-class) +2. [Writing Test Methods](#writing-test-methods) +3. [Structure Templates & Schematics](#structure-templates--schematics) +4. [Using GameTestHelper](#using-gametesthelper) +5. [Example: RecipeLogicTest](#example-recipelogictest) +6. [Running & Debugging Tests](#running--debugging-tests) +7. [Best Practices](#best-practices) + +--- + +## Defining a Test Class + +- Put it in the same class path as the main element you're trying to test, e.g. `test/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogicTest.java` +- Annotate with `@GameTestHolder(GTCEu.MOD_ID)` to register the class for testing. +- Use `@PrefixGameTestTemplate(false)` to ignore the automatic template prefix + - Without annotation: looks for `data/gtceu/structures/MyTests.basicBlockTest.singleblock.nbt` + - With annotation: looks for `data/gtceu/structures/singleblock.nbt` + +```java +@GameTestHolder(GTCEu.MOD_ID) +@PrefixGameTestTemplate(false) +public class MyTests { + // Test methods go here +} +``` + +--- + +## Writing Test Methods + +- Annotate each test method with `@GameTest`. +- Parameters: + - `template`: name of the structure or test chamber (in `data/gtceu/structures/`). + - `batch` (default 'defaultBatch'): group name for running subsets, see '@BeforeBatch' + - `timeoutTicks` (default 100): fail if not succeeded within ticks. + - `required`: (default true) fail the test run if this test fails. + - `setupTicks`: (default 0) wait N ticks before starting the test. + +For a more complete list, see [this gist](https://gist.github.com/SizableShrimp/60ad4109e3d0a23107a546b3bc0d9752) + +```java +@GameTestHolder(GTCEu.MOD_ID) +@PrefixGameTestTemplate(false) +public class MyTests { + + @GameTest(template = "singleblock") + public static void basicBlockTest(GameTestHelper helper) { + // Your test logic... + helper.succeed(); + } +} +``` + +--- + +## Structure Templates & Schematics +The testing system works with NBT files. You can use one that already exists, or make your own. +To make your own templates: +1. Spawn in a Structure Block in your game client `/give Dev minecraft:structure_block` +2. Build whatever you want to template above it +3. Open the structure block and navigate to the "SAVE" profile +4. Edit the relative offset and the structure size +5. Press "Save" +6. Copy `run/saves/[worldname]/generated/minecraft/structures/[name]` +7. Paste it in `src/test/resources/data/gtceu/structures/[name]` +8. Reference via `@GameTest(template = "[name]")` +9. Don't forget to git add it when committing :) + +--- + +## Using GameTestHelper + +`GameTestHelper` gives you assertions and world/manipulation utilities, including but not limited to: + +- `helper.getBlockState(BlockPos pos)` +- `helper.getBlockEntity(BlockPos pos)` +- `helper.setBlock(BlockPos pos, BlockState state)` +- `helper.runAfterDelay(long delay, Runnable task)` +- `helper.runAtTickTime(long tick, Runnable task)` +- `helper.assertTrue(boolean condition, String msg)` +- `helper.assertFalse(boolean condition, String msg)` +- `helper.assertSameBlockState(BlockState expected, BlockState actual, String msg)` +- `helper.assertSame[....]` a lot of these methods exist for minecraft primitives. +- `helper.succeed()` / `helper.fail(String message)` + +It can also help you interact with the world, spawn mock/fake players, assert conditions, etc. etc. + +You can also write your own utility methods for repeated patterns (e.g., checking inventories). +These go in `test/java/com/gregtechceu/gtceu/gametest/util/TestUtils.java` + +## Ensuring something does (not) happen +To ensure something does happen: +``` +helper.succeedWhen(()->{ + helper.assertTrue(thething, ...); +}); +``` + +To ensure something does not happen: +``` +helper.onEachTick(()->{ + helper.assertTrue(thing that should not happen doesn't happen); +}); +TestUtils.succeedAfterTest(helper); +``` +If your test has a timeout value different from 100, you can pass that as a second argument succeedAfterTest + + +--- + +## Example: RecipeLogicTest + +Here is a relatively complex test using the testing system. + +```java +@GameTestHolder(GTCEu.MOD_ID) +@PrefixGameTestTemplate(false) +public class RecipeLogicTest { + @GameTest(template = "singleblock_chem_reactor") + public static void recipeLogicSingleBlockTest(GameTestHelper helper) { + BlockEntity holder = helper.getBlockEntity(new BlockPos(0, 1, 0)); + if (!(holder instanceof MetaMachineBlockEntity metaMachineBlockEntity)) { + helper.fail("wrong block at relative pos [0,1,0]!"); + return; + } + MetaMachine machine = metaMachineBlockEntity.getMetaMachine(); + if (!(machine instanceof IRecipeLogicMachine recipeLogicMachine)) { + helper.fail("wrong machine in MetaMachineBlockEntity!"); + return; + } + + // force insert the recipe into the manager. + GTRecipeType type = recipeLogicMachine.getRecipeType(); + type.getLookup().removeAllRecipes(); + type.getLookup().addRecipe(type + .recipeBuilder(GTCEu.id("test-singleblock")) + .id(GTCEu.id("test-singleblock")) + .inputItems(new ItemStack(Blocks.COBBLESTONE)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(512).duration(1) + .buildRawRecipe()); + + RecipeLogic recipeLogic = recipeLogicMachine.getRecipeLogic(); + + recipeLogic.findAndHandleRecipe(); + + // no recipe found + helper.assertFalse(recipeLogic.isActive(), "Recipe logic is active, even when it shouldn't be"); + helper.assertTrue(recipeLogic.getLastRecipe() == null, + "Recipe logic has somehow found a recipe, when there should be none"); + + // put an item in the inventory that will trigger recipe recheck + NotifiableItemStackHandler inputSlots = getInputSlot(recipeLogicMachine); + NotifiableItemStackHandler outputSlots = getOutputSlot(recipeLogicMachine); + + inputSlots.insertItem(0, new ItemStack(Blocks.COBBLESTONE, 16), false); + inputSlots.onContentsChanged(); + + recipeLogic.findAndHandleRecipe(); + helper.assertFalse(recipeLogic.getLastRecipe() == null, + "Last recipe is empty, even though recipe logic should've found a recipe."); + helper.assertTrue(recipeLogic.isActive(), "Recipelogic is inactive, when it should be active."); + int stackCount = inputSlots.getStackInSlot(0).getCount(); + helper.assertTrue(stackCount == 15, "Count is wrong (should be 15, when it's %s)".formatted(stackCount)); + + // Save a reference to the old recipe so we can make sure it's getting reused + GTRecipe prev = recipeLogic.getLastRecipe(); + + // Finish the recipe, the output should generate, and the next iteration should begin + recipeLogic.serverTick(); + helper.assertTrue(recipeLogic.getLastRecipe().equals(prev), "lastRecipe is wrong"); + helper.assertTrue(TestUtils.isItemStackEqual( + outputSlots.getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), + "wrong output stack."); + helper.assertTrue(recipeLogic.isActive(), "RecipeLogic is not active, when it should be."); + + // Complete the second iteration, but the machine stops because its output is now full + outputSlots.setStackInSlot(0, + new ItemStack(Blocks.STONE, 63)); + outputSlots.setStackInSlot(1, + new ItemStack(Blocks.STONE, 64)); + recipeLogic.serverTick(); + helper.assertFalse(recipeLogic.isActive(), "RecipeLogic is active, when it shouldn't be."); + + // Try to process again and get failed out because of full buffer. + recipeLogic.serverTick(); + helper.assertFalse(recipeLogic.isActive(), "Recipelogic is active, when it shouldn't be."); + + // Some room is freed in the output bus, so we can continue now. + outputSlots.setStackInSlot(0, ItemStack.EMPTY); + recipeLogic.serverTick(); + helper.assertTrue(recipeLogic.isActive(), "RecipeLogic didn't start running again"); + recipeLogic.serverTick(); + helper.assertTrue( + TestUtils.isItemStackEqual( + outputSlots.getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), + "Wrong stack."); + + // Finish. + helper.succeed(); + } +} +``` + +--- + +## Running & Debugging Tests + +1. **Launch the GameTest server** + - Run the “Game Tests” run configuration. + - In logs you’ll see registered tests and pass/fail summaries. + +2. **Use Client Commands** + - Launch the client normally and use one of the following commands: + - `/test run :` + - `/test runAll` + +3. **Inspect Failure Reports** + - The log will pinpoint the tick and assertion message. + - You can run the "Game Tests" configuration with debug mode on, to step through the tests. + +--- + +## Best Practices + +- **Use descriptive names**: `@GameTest(template="…") public static void myFeaturedoSomething()`. +- **Limit test time**: avoid long loops, use `timeoutTicks` if needed. +- **Group related tests** with `batch` parameter. +- **Reuse helper methods** for common patterns (e.g., inventory insertion). +- **Assert early, clearly and often**: fail fast on mismatches to simplify debugging. diff --git a/src/test/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogicTest.java b/src/test/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogicTest.java new file mode 100644 index 00000000000..c9279a8beb1 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/api/machine/trait/RecipeLogicTest.java @@ -0,0 +1,250 @@ +package com.gregtechceu.gtceu.api.machine.trait; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; +import com.gregtechceu.gtceu.common.machine.multiblock.part.ItemBusPartMachine; +import com.gregtechceu.gtceu.data.recipe.GTRecipeTypes; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import static com.gregtechceu.gtceu.gametest.util.TestUtils.getMetaMachine; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class RecipeLogicTest { + + private static GTRecipeType LCR_RECIPE_TYPE; + private static GTRecipeType CR_RECIPE_TYPE; + + @BeforeBatch(batch = "RecipeLogic") + public static void prepare(ServerLevel level) { + LCR_RECIPE_TYPE = TestUtils.createRecipeType("recipe_logic_test_lcr", GTRecipeTypes.LARGE_CHEMICAL_RECIPES); + CR_RECIPE_TYPE = TestUtils.createRecipeType("recipe_logic_test_cr", GTRecipeTypes.CHEMICAL_RECIPES); + LCR_RECIPE_TYPE.getLookup().removeAllRecipes(); + CR_RECIPE_TYPE.getLookup().removeAllRecipes(); + + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_multiblock_recipelogic")) + .inputItems(new ItemStack(Blocks.COBBLESTONE)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.HV]).duration(1) + .build()); + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_multiblock_recipelogic_16_items")) + .inputItems(new ItemStack(Blocks.STONE, 16)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.HV]).duration(1) + .build()); + + CR_RECIPE_TYPE.getLookup().addRecipe(CR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_singleblock_recipelogic")) + .inputItems(new ItemStack(Blocks.COBBLESTONE)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.HV]).duration(1) + .build()); + } + + private record BusHolder(ItemBusPartMachine inputBus1, ItemBusPartMachine inputBus2, ItemBusPartMachine outputBus1, + WorkableMultiblockMachine controller) {} + + /** + * Retrieves the busses for this specific template and force a multiblock structure check + * + * @param helper the GameTestHelper + * @return the busses, in the BusHolder record. + */ + private static RecipeLogicTest.BusHolder getBussesAndForm(GameTestHelper helper) { + WorkableMultiblockMachine controller = (WorkableMultiblockMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 2, 0))); + TestUtils.formMultiblock(controller); + + controller.setRecipeType(LCR_RECIPE_TYPE); + ItemBusPartMachine inputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 1, 0))); + ItemBusPartMachine inputBus2 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 2, 0))); + ItemBusPartMachine outputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + return new RecipeLogicTest.BusHolder(inputBus1, inputBus2, outputBus1, controller); + } + + @GameTest(template = "lcr_input_separation", batch = "RecipeLogic") + public static void recipeLogicMultiBlockTest(GameTestHelper helper) { + BlockEntity holder = helper.getBlockEntity(new BlockPos(1, 2, 0)); + + RecipeLogicTest.BusHolder busHolder = getBussesAndForm(helper); + + helper.assertTrue(busHolder.controller.isFormed(), "Controller didn't form after structure check"); + helper.assertTrue(busHolder.controller.getParts().size() == 6, + "Controller didn't register all 6 parts after structure check, only registered " + + busHolder.controller.getParts().size()); + + RecipeLogic recipeLogic = busHolder.controller.getRecipeLogic(); + + recipeLogic.findAndHandleRecipe(); + + // No recipe found + helper.assertFalse(recipeLogic.isActive(), "Recipe logic is active, even when it shouldn't be"); + helper.assertTrue(recipeLogic.getLastRecipe() == null, + "Recipe logic has somehow found a recipe, when there should be none"); + + // Put an item in the inventory that will trigger recipe recheck + NotifiableItemStackHandler inputSlots = busHolder.inputBus1.getInventory(); + NotifiableItemStackHandler outputSlots = busHolder.outputBus1.getInventory(); + + inputSlots.insertItem(0, new ItemStack(Blocks.COBBLESTONE, 16), false); + + recipeLogic.findAndHandleRecipe(); + helper.assertFalse(recipeLogic.getLastRecipe() == null, + "Last recipe is empty, even though recipe logic should've found a recipe."); + helper.assertTrue(recipeLogic.isActive(), "Recipelogic is inactive, when it should be active."); + int stackCount = inputSlots.getStackInSlot(0).getCount(); + helper.assertTrue(stackCount == 15, "Count is wrong (should be 15, when it's %s)".formatted(stackCount)); + + // Save a reference to the old recipe so we can make sure it's getting reused + GTRecipe prev = recipeLogic.getLastRecipe(); + + // Finish the recipe, the output should generate, and the next iteration should begin + recipeLogic.serverTick(); + helper.assertTrue(recipeLogic.getLastRecipe().equals(prev), "lastRecipe is wrong"); + helper.assertTrue( + TestUtils.isItemStackEqual(outputSlots.getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), + "wrong output stack."); + helper.assertTrue(recipeLogic.isActive(), "RecipeLogic is not active, when it should be."); + + // Complete the second iteration, but the machine stops because its output is now full + // Fill up the recipe with enough stone to complete 1 more recipe and then nothing more. + outputSlots.setStackInSlot(0, + new ItemStack(Blocks.STONE, 63)); + for (int i = 1; i < outputSlots.getSlots(); i++) { + outputSlots.setStackInSlot(i, + new ItemStack(Blocks.STONE, 64)); + } + recipeLogic.serverTick(); + helper.assertFalse(recipeLogic.isActive(), "RecipeLogic is active, when it shouldn't be."); + + // Try to process again and get failed out because of full buffer. + recipeLogic.serverTick(); + helper.assertFalse(recipeLogic.isActive(), "Recipelogic is active, when it shouldn't be."); + + // Some room is freed in the output bus, so we can continue now. + outputSlots.setStackInSlot(0, ItemStack.EMPTY); + recipeLogic.serverTick(); + helper.assertTrue(recipeLogic.isActive(), "RecipeLogic didn't start running again"); + recipeLogic.serverTick(); + helper.assertTrue( + TestUtils.isItemStackEqual(outputSlots.getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), + "Wrong stack."); + + // Finish. + helper.succeed(); + } + + // spotless:off + // Blocked by LDLib sync issues + /* + @GameTest(template = "singleblock_charged_cr", batch = "RecipeLogic") + public static void recipeLogicSingleBlockTest(GameTestHelper helper) { + WorkableTieredMachine machine = (WorkableTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + + machine.setRecipeType(CR_RECIPE_TYPE); + NotifiableItemStackHandler inputSlots = (NotifiableItemStackHandler) machine + .getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).get(0); + NotifiableItemStackHandler outputSlots = (NotifiableItemStackHandler) machine + .getCapabilitiesFlat(IO.OUT, ItemRecipeCapability.CAP).get(0); + + + RecipeLogic recipeLogic = machine.getRecipeLogic(); + + recipeLogic.findAndHandleRecipe(); + + // no recipe found + helper.assertFalse(recipeLogic.isActive(), "Recipe logic is active, even when it shouldn't be"); + helper.assertTrue(recipeLogic.getLastRecipe() == null, + "Recipe logic has somehow found a recipe, when there should be none"); + + inputSlots.insertItem(0, new ItemStack(Blocks.COBBLESTONE, 16), false); + inputSlots.onContentsChanged(); + + recipeLogic.findAndHandleRecipe(); + helper.assertFalse(recipeLogic.getLastRecipe() == null, + "Last recipe is empty, even though recipe logic should've found a recipe."); + helper.assertTrue(recipeLogic.isActive(), "Recipelogic is inactive, when it should be active."); + int stackCount = inputSlots.getStackInSlot(0).getCount(); + helper.assertTrue(stackCount == 15, "Count is wrong (should be 15, when it's %s)".formatted(stackCount)); + + // Save a reference to the old recipe so we can make sure it's getting reused + ResourceLocation prev = recipeLogic.getLastRecipe().getId(); + + // Finish the recipe, the output should generate, and the next iteration should begin + recipeLogic.serverTick(); + helper.assertTrue(recipeLogic.getLastRecipe().getId().equals(prev), "lastRecipe is wrong"); + helper.assertTrue(TestUtils.isItemStackEqual( + outputSlots.getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), + "wrong output stack."); + helper.assertTrue(recipeLogic.isActive(), "RecipeLogic is not active, when it should be."); + + // Complete the second iteration, but the machine stops because its output is now full + outputSlots.setStackInSlot(0, + new ItemStack(Blocks.STONE, 63)); + outputSlots.setStackInSlot(1, + new ItemStack(Blocks.STONE, 64)); + recipeLogic.serverTick(); + helper.assertFalse(recipeLogic.isActive(), "RecipeLogic is active, when it shouldn't be."); + + // Try to process again and get failed out because of full buffer. + recipeLogic.serverTick(); + helper.assertFalse(recipeLogic.isActive(), "Recipelogic is active, when it shouldn't be."); + + // Some room is freed in the output bus, so we can continue now. + outputSlots.setStackInSlot(0, ItemStack.EMPTY); + recipeLogic.serverTick(); + helper.assertTrue(recipeLogic.isActive(), "RecipeLogic didn't start running again"); + recipeLogic.serverTick(); + helper.assertTrue( + TestUtils.isItemStackEqual( + outputSlots.getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), + "Wrong stack."); + + // Finish. + helper.succeed(); + } + */ + // spotless:on + + // Test for putting both ingredients in the same bus in 2 stacks. + @GameTest(template = "lcr_input_separation", batch = "RecipeLogicTest") + public static void recipeLogicInTwoStacksTest(GameTestHelper helper) { + RecipeLogicTest.BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.STONE, 10)); + busHolder.inputBus1.getInventory().setStackInSlot(1, new ItemStack(Blocks.STONE, 6)); + busHolder.controller.recipeLogic.findAndHandleRecipe(); + helper.assertTrue(busHolder.controller.recipeLogic.isWorking(), "Controller should be working!"); + busHolder.controller.recipeLogic.isWorking(); + helper.succeedWhen(() -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), + "Crafting items in same bus failed, expected STONE but was " + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializerTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializerTest.java new file mode 100644 index 00000000000..c5f4c638d28 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/GTRecipeSerializerTest.java @@ -0,0 +1,176 @@ +// PORT TODO: FIX +// package com.gregtechceu.gtceu.api.recipe; + +// import com.gregtechceu.gtceu.GTCEu; +// import com.gregtechceu.gtceu.api.registry.GTRegistries; +// import com.gregtechceu.gtceu.common.recipe.condition.AdjacentBlockCondition; +// import com.gregtechceu.gtceu.common.recipe.condition.AdjacentFluidCondition; +// import com.gregtechceu.gtceu.common.recipe.builder.GTRecipeBuilder; + +// import net.minecraft.core.Holder; +// import net.minecraft.core.HolderSet; +// import net.minecraft.core.registries.Registries; +// import net.minecraft.gametest.framework.GameTest; +// import net.minecraft.gametest.framework.GameTestHelper; +// import net.minecraft.resources.ResourceLocation; +// import net.minecraft.tags.TagKey; +// import net.minecraft.world.level.block.Block; +// import net.minecraft.world.level.block.Blocks; +// import net.minecraft.world.level.material.Fluid; +// import net.minecraft.world.level.material.Fluids; +// import net.neoforged.neoforge.gametest.GameTestHolder; +// import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +// import com.google.gson.JsonObject; + +// import java.util.HashSet; +// import java.util.List; +// import java.util.Objects; +// import java.util.Set; + +// @PrefixGameTestTemplate(false) +// @GameTestHolder(GTCEu.MOD_ID) +// public class GTRecipeSerializerTest { + +// @GameTest(template = "empty_5x5") +// public static void serializeTest(GameTestHelper helper) { +// // Create Fluid Condition based on fluidSetIn +// TagKey lavaTag = TagKey.create(Registries.FLUID, ResourceLocation.fromNamespaceAndPath("c", "lava")); +// HolderSet waterSet = HolderSet.direct(Fluids.WATER.builtInRegistryHolder(), +// Fluids.FLOWING_WATER.builtInRegistryHolder()); +// HolderSet lavaSet = GTRegistries.builtinRegistry() +// .registryOrThrow(Registries.FLUID) +// .getOrCreateTag(lavaTag); +// List> fluidSetIn = List.of(waterSet, lavaSet); +// AdjacentFluidCondition fluidCondition = new AdjacentFluidCondition(fluidSetIn); + +// // Create Block Condition based on blockSetIn +// TagKey oreTag = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "ores")); +// HolderSet blockSet = HolderSet.direct(Blocks.DIAMOND_BLOCK.builtInRegistryHolder(), +// Blocks.GOLD_BLOCK.builtInRegistryHolder()); +// HolderSet oreSet = GTRegistries.builtinRegistry() +// .registryOrThrow(Registries.BLOCK) +// .getOrCreateTag(oreTag); +// List> blockSetIn = List.of(blockSet, oreSet); +// AdjacentBlockCondition blockCondition = new AdjacentBlockCondition(blockSetIn); + +// // Serialize and back +// JsonObject AFConditionJSON = new JsonObject(); + +// GTRecipeBuilder.ofRaw().addCondition(fluidCondition).addCondition(blockCondition).toJson(AFConditionJSON); + +// GTRecipe recipe = GTRecipeSerializer.CODEC.compressedBuilder(JsonOps.INSTANCE) fromJson(GTCEu.id("test"), +// AFConditionJSON); + +// // Validate +// boolean foundFluid = false, foundBlock = false; +// for (var condition : recipe.conditions) { +// if (condition instanceof AdjacentBlockCondition recipeBlockCondition) { +// foundBlock = true; +// helper.assertTrue(equalHolderSetLists(recipeBlockCondition.getBlocks(), blockSetIn), +// "AdjacentBlockCondition did not deserialize properly"); +// } else if (condition instanceof AdjacentFluidCondition recipeFluidCondition) { +// foundFluid = true; +// helper.assertTrue(equalHolderSetLists(recipeFluidCondition.getFluids(), fluidSetIn), +// "AdjacentFluidCondition did not deserialize properly"); + +// } else { +// helper.fail("Found condition that should not be present: " + condition); +// } +// } +// if (!foundBlock) { +// helper.fail("AdjacentBlockCondition did not deserialize properly"); +// } +// if (!foundFluid) { +// helper.fail("AdjacentFluidCondition did not deserialize properly"); +// } +// helper.succeed(); +// } + +// @GameTest(template = "empty_5x5") +// public static void testSerializingFluidCondition(GameTestHelper helper) { +// TagKey lavaTag = TagKey.create(Registries.FLUID, ResourceLocation.fromNamespaceAndPath("c", "lava")); +// HolderSet waterSet = HolderSet.direct(Fluids.WATER.builtInRegistryHolder(), +// Fluids.FLOWING_WATER.builtInRegistryHolder()); +// HolderSet lavaSet = GTRegistries.builtinRegistry() +// .registryOrThrow(Registries.FLUID) +// .getOrCreateTag(lavaTag); +// List> fluidSetIn = List.of(waterSet, lavaSet); +// AdjacentFluidCondition condition = new AdjacentFluidCondition(fluidSetIn); + +// helper.assertTrue(equalHolderSetLists(condition.getFluids(), fluidSetIn), +// "AdjacentFluidCondition did not deserialize properly"); + +// JsonObject jsonConfig = condition.serialize(); +// AdjacentFluidCondition newCondition = (AdjacentFluidCondition) AdjacentFluidCondition.deserialize(jsonConfig); + +// helper.assertTrue(equalHolderSetLists(newCondition.getFluids(), fluidSetIn), +// "AdjacentFluidCondition did not deserialize properly"); + +// helper.succeed(); +// } + +// @GameTest(template = "empty_5x5") +// public static void testSerializingBlockCondition(GameTestHelper helper) { +// TagKey oreTag = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "ores")); +// HolderSet blockSet = HolderSet.direct(Blocks.DIAMOND_BLOCK.builtInRegistryHolder(), +// Blocks.GOLD_BLOCK.builtInRegistryHolder()); +// HolderSet oreSet = GTRegistries.builtinRegistry() +// .registryOrThrow(Registries.BLOCK) +// .getOrCreateTag(oreTag); +// List> blockSetIn = List.of(blockSet, oreSet); +// AdjacentBlockCondition condition = new AdjacentBlockCondition(blockSetIn); + +// helper.assertTrue(equalHolderSetLists(condition.getBlocks(), blockSetIn), +// "AdjacentBlockCondition did not deserialize properly"); + +// JsonObject jsonConfig = condition.serialize(); +// AdjacentBlockCondition newCondition = (AdjacentBlockCondition) AdjacentBlockCondition.deserialize(jsonConfig); + +// helper.assertTrue(equalHolderSetLists(newCondition.getBlocks(), blockSetIn), +// "AdjacentBlockCondition did not deserialize properly"); + +// helper.succeed(); +// } + +// public static boolean equalHolderSetLists(List> a, List> b) { +// if (a.size() != b.size()) return false; + +// // Convert list B into a mutable set for matching +// Set> unmatched = new HashSet<>(b); + +// outer: +// for (HolderSet setA : a) { +// for (HolderSet setB : unmatched) { +// if (holderSetEquals(setA, setB)) { +// unmatched.remove(setB); +// continue outer; +// } +// } +// // No match found for setA +// return false; +// } + +// // All matched +// return unmatched.isEmpty(); +// } + +// private static boolean holderSetEquals(HolderSet a, HolderSet b) { +// // Case 1: both are Named (tags) +// if (a.unwrapKey().isPresent() && b.unwrapKey().isPresent()) { +// TagKey tagA = a.unwrapKey().get(); +// TagKey tagB = b.unwrapKey().get(); +// return Objects.equals(tagA, tagB); +// } + +// // Case 2: both are Direct +// if (!a.unwrapKey().isPresent() && !b.unwrapKey().isPresent()) { +// Set> setA = new HashSet<>(a.stream().toList()); +// Set> setB = new HashSet<>(b.stream().toList()); +// return setA.equals(setB); +// } + +// // One is Named, the other is Direct → not equal +// return false; +// } +// } diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/InputSeparationTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/InputSeparationTest.java new file mode 100644 index 00000000000..9f811fae444 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/InputSeparationTest.java @@ -0,0 +1,205 @@ +package com.gregtechceu.gtceu.api.recipe; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockControllerMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.part.FluidHatchPartMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.part.ItemBusPartMachine; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Blocks; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import static com.gregtechceu.gtceu.data.recipe.GTRecipeTypes.LARGE_CHEMICAL_RECIPES; +import static com.gregtechceu.gtceu.gametest.util.TestUtils.getMetaMachine; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class InputSeparationTest { + + @BeforeBatch(batch = "InputSeparation") + public static void prepare(ServerLevel level) { + // LARGE_CHEMICAL_RECIPES = TestUtils.createRecipeType("input_separation_tests", 3, 3, 3, 3); + // Force insert the recipe into the manager. + LARGE_CHEMICAL_RECIPES.getLookup().removeAllRecipes(); + LARGE_CHEMICAL_RECIPES.getLookup().addRecipe(LARGE_CHEMICAL_RECIPES + .recipeBuilder(GTCEu.id("test-multiblock-input-separation")) + .id(GTCEu.id("test-multiblock-input-separation")) + .inputItems(new ItemStack(Blocks.COBBLESTONE), new ItemStack(Blocks.ACACIA_WOOD)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.HV]).duration(1) + // NBT has a schematic in it with an HV energy input hatch + .build()); + } + + private record BusHolder(ItemBusPartMachine inputBus1, ItemBusPartMachine inputBus2, ItemBusPartMachine outputBus1, + FluidHatchPartMachine outputHatch1) {} + + /** + * Retrieves the busses for this specific template and force a multiblock structure check + * + * @param helper the GameTestHelper + * @return the busses, in the BusHolder record. + */ + private static BusHolder getBussesAndForm(GameTestHelper helper) { + MultiblockControllerMachine controller = (MultiblockControllerMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 2, 0))); + TestUtils.formMultiblock(controller); + ItemBusPartMachine inputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 1, 0))); + ItemBusPartMachine inputBus2 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 2, 0))); + ItemBusPartMachine outputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + FluidHatchPartMachine outputHatch1 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 2, 0))); + return new BusHolder(inputBus1, inputBus2, outputBus1, outputHatch1); + } + + // Test for putting both ingredients in the same bus. + @GameTest(template = "lcr_input_separation", batch = "InputSeparation", setupTicks = 40, timeoutTicks = 200) + public static void inputSeparationSingleBusTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE)); + busHolder.inputBus1.getInventory().setStackInSlot(1, new ItemStack(Blocks.ACACIA_WOOD)); + helper.succeedWhen(() -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Crafting items in same bus failed, expected STONE but was " + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + // Test for putting both ingredients in 2 busses without separation. + @GameTest(template = "lcr_input_separation", batch = "InputSeparation", setupTicks = 40, timeoutTicks = 200) + public static void inputSeparationBothBussesWithoutSeparationTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Blocks.ACACIA_WOOD)); + helper.succeedWhen(() -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Crafting items in different busses with no color failed, expected STONE but was " + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + // Test for putting both ingredients in 2 busses with one undyed and one dyed. + @GameTest(template = "lcr_input_separation", batch = "InputSeparation", setupTicks = 40, timeoutTicks = 200) + public static void inputSeparationBothBussesWithOneColorTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.setPaintingColor(DyeColor.BLACK.getTextColor()); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Blocks.ACACIA_WOOD)); + helper.succeedWhen(() -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Crafting items in different busses with no color failed, expected STONE but was " + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + // Test for putting both ingredients in 2 busses with both dyed the same color. + @GameTest(template = "lcr_input_separation", batch = "InputSeparation", setupTicks = 40, timeoutTicks = 200) + public static void inputSeparationBothBussesWithTheSameColorTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.setPaintingColor(DyeColor.BLACK.getTextColor()); + busHolder.inputBus2.setPaintingColor(DyeColor.BLACK.getTextColor()); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Blocks.ACACIA_WOOD)); + helper.succeedWhen(() -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Crafting items in different busses with no color failed, expected STONE but was " + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + // Test for putting both ingredients in 2 busses with two dyed different colors. + @GameTest(template = "lcr_input_separation", batch = "InputSeparation", setupTicks = 40, timeoutTicks = 200) + public static void inputSeparationBothBussesWithDifferentColorsTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.setPaintingColor(DyeColor.BLACK.getTextColor()); + busHolder.inputBus2.setPaintingColor(DyeColor.BLUE.getTextColor()); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Blocks.ACACIA_WOOD)); + helper.onEachTick(() -> { + helper.assertTrue(busHolder.outputBus1.getInventory().getStackInSlot(0).isEmpty(), + "Crafting items in busses with different colors succeeded but shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } + + // Test for putting both ingredients in 2 busses with one distinct. + @GameTest(template = "lcr_input_separation", batch = "InputSeparation", setupTicks = 40, timeoutTicks = 200) + public static void inputSeparationBothBussesOneDistinctTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.setDistinct(true); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Blocks.ACACIA_WOOD)); + helper.onEachTick(() -> { + helper.assertTrue(busHolder.outputBus1.getInventory().getStackInSlot(0).isEmpty(), + "Crafting items in busses with distinct succeeded but shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } + + // Test for putting both ingredients in 2 busses with both distinct. + @GameTest(template = "lcr_input_separation", batch = "InputSeparation", setupTicks = 40, timeoutTicks = 200) + public static void inputSeparationBothBussesTwoDistinctTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.setDistinct(true); + busHolder.inputBus2.setDistinct(true); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Blocks.ACACIA_WOOD)); + helper.onEachTick(() -> { + helper.assertTrue(busHolder.outputBus1.getInventory().getStackInSlot(0).isEmpty(), + "Crafting items in busses with distinct succeeded but shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } + + // Test for putting both ingredients in 2 busses with two distinct and dyed different colors. + @GameTest(template = "lcr_input_separation", batch = "InputSeparation", setupTicks = 40, timeoutTicks = 200) + public static void inputSeparationBothBussesTwoDistinctAndColoredTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.setDistinct(true); + busHolder.inputBus2.setDistinct(true); + busHolder.inputBus1.setPaintingColor(DyeColor.BLACK.getTextColor()); + busHolder.inputBus2.setPaintingColor(DyeColor.BLUE.getTextColor()); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Blocks.ACACIA_WOOD)); + helper.onEachTick(() -> { + helper.assertTrue(busHolder.outputBus1.getInventory().getStackInSlot(0).isEmpty(), + "Crafting items in busses with distinct succeeded but shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } + + // Test for putting both ingredients in 2 busses with one distinct and one colored. + @GameTest(template = "lcr_input_separation", batch = "InputSeparation", setupTicks = 40, timeoutTicks = 200) + public static void inputSeparationBothBussesOneDistinctOneColoredTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.setDistinct(true); + busHolder.inputBus2.setPaintingColor(DyeColor.BLUE.getTextColor()); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Blocks.ACACIA_WOOD)); + helper.onEachTick(() -> { + helper.assertTrue(busHolder.outputBus1.getInventory().getStackInSlot(0).isEmpty(), + "Crafting items in busses with distinct succeeded but shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/MultipleEnergyHatchTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/MultipleEnergyHatchTest.java new file mode 100644 index 00000000000..9e5c66c49eb --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/MultipleEnergyHatchTest.java @@ -0,0 +1,374 @@ +package com.gregtechceu.gtceu.api.recipe; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; +import com.gregtechceu.gtceu.api.misc.EnergyContainerList; +import com.gregtechceu.gtceu.common.machine.multiblock.part.EnergyHatchPartMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.part.ItemBusPartMachine; +import com.gregtechceu.gtceu.data.recipe.GTRecipeTypes; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import java.util.List; +import java.util.Optional; + +import static com.gregtechceu.gtceu.api.GTValues.*; +import static com.gregtechceu.gtceu.gametest.util.TestUtils.getMetaMachine; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class MultipleEnergyHatchTest { + // This class tests the overclock logic: + // 1x 2a ev + 1x 2a mv: run ev with 0x oc, don't run iv + // 1x 2a ev + 1x 2a hv: run ev with 0x oc, don't run iv + // 2x 2a ev: run ev with 1x oc, run iv with 0x oc + // 1x 4a ev: run ev with 1x oc, don't run iv + // 1x 16a ev: run ev with 2x oc, don't run iv + // 1x 16a ev: run ev with 2x oc, don't run iv + // 1x 16a ev + 1x 4a ev: run ev with 2x oc, run iv with 1x oc + // 1x 2a iv + 1x 16a ev: run iv recipe with 0x oc, don't run LuV + + private static GTRecipeType LCR_RECIPE_TYPE; + + @BeforeBatch(batch = "MultipleEnergyHatch") + public static void prepare(ServerLevel level) { + LCR_RECIPE_TYPE = TestUtils.createRecipeType("multiple_energy_hatch_lcr_tests", + GTRecipeTypes.LARGE_CHEMICAL_RECIPES); + + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_multiple_energy_hatch_ev")) + .inputItems(new ItemStack(Items.CYAN_BED)) + .outputItems(new ItemStack(Items.CYAN_BED)) + .EUt(GTValues.V[EV]) + .duration(16) + .build()); + + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_multiple_energy_hatch_iv")) + .inputItems(new ItemStack(Items.BROWN_BED)) + .outputItems(new ItemStack(Items.BROWN_BED)) + .EUt(GTValues.V[GTValues.IV]) + .duration(16) + .build()); + + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_multiple_energy_hatch_iv")) + .inputItems(new ItemStack(Items.GREEN_BED)) + .outputItems(new ItemStack(Items.GREEN_BED)) + .EUt(GTValues.V[GTValues.LuV]) + .duration(16) + .build()); + } + + private record BusHolder(ItemBusPartMachine inputBus, ItemBusPartMachine outputBus, + WorkableElectricMultiblockMachine controller, + EnergyHatchPartMachine energyHatch1, Optional energyHatch2) {} + + /** + * Retrieves the busses for this specific template and force a multiblock structure check + * + * @param helper the GameTestHelper + * @return the busses, in the BusHolder record. + */ + private static BusHolder getBussesAndForm(GameTestHelper helper) { + WorkableElectricMultiblockMachine controller = (WorkableElectricMultiblockMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 2, 0))); + TestUtils.formMultiblock(controller); + controller.setRecipeType(LCR_RECIPE_TYPE); + ItemBusPartMachine inputBus = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 1, 0))); + ItemBusPartMachine outputBus = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + EnergyHatchPartMachine energyHatch = (EnergyHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 3, 0))); + // Some instances don't have a second energy hatch + var hatch2BE = helper.getBlockEntity(new BlockPos(1, 3, 0)); + if (hatch2BE instanceof MetaMachineBlockEntity hatch2MMBE) { + return new BusHolder(inputBus, outputBus, controller, energyHatch, + Optional.of((EnergyHatchPartMachine) hatch2MMBE.getMetaMachine())); + } + + return new BusHolder(inputBus, outputBus, controller, energyHatch, Optional.empty()); + } + + private record Hatch(int tier, int amps, long EU) { + + public Hatch(int tier, int amps) { + this(tier, amps, V[tier]); + } + } + + private static void checkContainerList(GameTestHelper helper, BusHolder busHolder, List hatches) { + long totalVoltage = 0; + for (var hatch : hatches) { + totalVoltage += hatch.EU * hatch.amps; + } + EnergyContainerList containerList = busHolder.controller.getEnergyContainer(); + + helper.assertTrue(totalVoltage == containerList.getInputVoltage(), + "Hatches on multiblock didn't match expected input voltage"); + } + + @GameTest(template = "energy/lcr_ev_mv", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void EvPlusMvHatchCanDoEVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(MV, 2), new Hatch(EV, 2))); + + EnergyContainerList containerList = busHolder.controller.getEnergyContainer(); + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.CYAN_BED)); + // One tick to start, 16 for the recipe to run + helper.succeedOnTickWhen(17, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.CYAN_BED)), + "Item didn't craft at the right tick with an on-tier recipe" + + busHolder.outputBus.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + @GameTest(template = "energy/lcr_ev_mv", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void EvPlusMvHatchCannotDoIVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(MV, 2), new Hatch(EV, 2))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.BROWN_BED)); + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.BROWN_BED)), + "Item crafted when it shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } + + @GameTest(template = "energy/lcr_ev_hv", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void EvPlusHvHatchCanDoEVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(HV, 2), new Hatch(EV, 2))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.CYAN_BED)); + // One tick to start, 16 for the recipe to run + helper.succeedOnTickWhen(17, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.CYAN_BED)), + "Item didn't craft at the right tick with an on-tier recipe" + + busHolder.outputBus.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + @GameTest(template = "energy/lcr_ev_hv", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void EvPlusHvHatchCannotIVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(HV, 2), new Hatch(EV, 2))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.BROWN_BED)); + // One tick to start, 16 for the recipe to run + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.BROWN_BED)), + "Item crafted when it shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } + + @GameTest(template = "energy/lcr_2x_ev", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void DoubleEVHatchCanDoEVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(EV, 2), new Hatch(EV, 2))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.CYAN_BED)); + // One tick to start, 4 for the recipe to run + helper.succeedOnTickWhen(5, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.CYAN_BED)), + "Item didn't craft at the right tick with an on-tier recipe" + + busHolder.outputBus.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + @GameTest(template = "energy/lcr_2x_ev", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void DoubleEVHatchCanDoIVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(EV, 2), new Hatch(EV, 2))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.BROWN_BED)); + // One tick to start, 16 for the recipe to run + helper.succeedOnTickWhen(17, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.BROWN_BED)), + "Item didn't craft at the right tick with an 1-above-tier recipe" + + busHolder.outputBus.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + @GameTest(template = "energy/lcr_4a_ev", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void FourAEVHatchCanDoEVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(EV, 4))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.CYAN_BED)); + // One tick to start, 4 for the recipe to run + helper.succeedOnTickWhen(5, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.CYAN_BED)), + "Item didn't craft at the right tick with an on-tier recipe" + + busHolder.outputBus.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + @GameTest(template = "energy/lcr_4a_ev", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void FourAEVHatchCanNotDoIVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(EV, 4))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.BROWN_BED)); + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.BROWN_BED)), + "Item crafted when it shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } + + @GameTest(template = "energy/lcr_16a_ev", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void SixteenAEVHatchCanDoEVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(EV, 16))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.CYAN_BED)); + // One tick to start, 1 for the recipe to run + helper.succeedOnTickWhen(2, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.CYAN_BED)), + "Item didn't craft at the right tick with an on-tier recipe" + + busHolder.outputBus.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + @GameTest(template = "energy/lcr_16a_ev", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void SixteenAEVHatchCanNotDoIVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(EV, 16))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.BROWN_BED)); + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.BROWN_BED)), + "Item crafted when it shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } + + @GameTest(template = "energy/lcr_16a_ev_hv", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void SixteenAEVPlus2AHVHatchCanDoEVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(HV, 2), new Hatch(EV, 16))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.CYAN_BED)); + // One tick to start, 1 for the recipe to run + helper.succeedOnTickWhen(2, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.CYAN_BED)), + "Item didn't craft at the right tick with an on-tier recipe" + + busHolder.outputBus.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + @GameTest(template = "energy/lcr_16a_ev_hv", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void SixteenAEVPlus2AHVHatchCanNotDoIVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(HV, 2), new Hatch(EV, 16))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.BROWN_BED)); + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.BROWN_BED)), + "Item crafted when it shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } + + @GameTest(template = "energy/lcr_16a_4a_ev", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void SixteenAPlus4AEVHatchCanDoEVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(EV, 16), new Hatch(EV, 4))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.CYAN_BED)); + // One tick to start, 1 for the recipe to run + helper.succeedOnTickWhen(2, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.CYAN_BED)), + "Item didn't craft at the right tick with an on-tier recipe" + + busHolder.outputBus.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + @GameTest(template = "energy/lcr_16a_4a_ev", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void SixteenAPlus4AEVHatchCanDoIVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(EV, 16), new Hatch(EV, 4))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.BROWN_BED)); + // One tick to start, 4 for the recipe to run + helper.succeedOnTickWhen(5, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.BROWN_BED)), + "Item didn't craft at the right tick with an on-tier recipe" + + busHolder.outputBus.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + @GameTest(template = "energy/lcr_iv_16a_ev", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void SixteenAEVPlus2AIVHatchCanDoIVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(IV, 2), new Hatch(EV, 16))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.BROWN_BED)); + // One tick to start, 4 for the recipe to run + helper.succeedOnTickWhen(5, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.BROWN_BED)), + "Item didn't craft at the right tick with an on-tier recipe" + + busHolder.outputBus.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + @GameTest(template = "energy/lcr_iv_16a_ev", batch = "MultipleEnergyHatch", setupTicks = 10L) + public static void SixteenAEVPlus2AIVHatchCannotDoLuVRecipeTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + checkContainerList(helper, busHolder, List.of(new Hatch(IV, 2), new Hatch(EV, 16))); + + busHolder.inputBus.getInventory().setStackInSlot(0, new ItemStack(Items.GREEN_BED)); + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus.getInventory().getStackInSlot(0), + new ItemStack(Items.GREEN_BED)), + "Item crafted when it shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/OverclockLogicTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/OverclockLogicTest.java new file mode 100644 index 00000000000..f348225d582 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/OverclockLogicTest.java @@ -0,0 +1,290 @@ +package com.gregtechceu.gtceu.api.recipe; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; +import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; +import com.gregtechceu.gtceu.common.machine.multiblock.part.ItemBusPartMachine; +import com.gregtechceu.gtceu.data.recipe.GTRecipeTypes; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Blocks; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import static com.gregtechceu.gtceu.api.recipe.OverclockingLogic.*; +import static com.gregtechceu.gtceu.data.recipe.GTRecipeModifiers.*; +import static com.gregtechceu.gtceu.data.recipe.GTRecipeTypes.LARGE_CHEMICAL_RECIPES; +import static com.gregtechceu.gtceu.gametest.util.TestUtils.getMetaMachine; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class OverclockLogicTest { + + static GTRecipeType LCR_RECIPE_TYPE; + static GTRecipeType CR_RECIPE_TYPE; + + @BeforeBatch(batch = "OverclockLogic") + public static void prepare(ServerLevel level) { + LCR_RECIPE_TYPE = TestUtils.createRecipeType("overclock_logic_lcr_tests", GTRecipeTypes.LARGE_CHEMICAL_RECIPES); + CR_RECIPE_TYPE = TestUtils.createRecipeType("overclock_logic_cr_tests", GTRecipeTypes.CHEMICAL_RECIPES); + + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_overclock_logic")) + .inputItems(new ItemStack(Items.RED_BED)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.HV]) + .duration(20) + // NBT has a schematic in it with an HV energy input hatch + .build()); + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test-overlock-logic-2")) + .id(GTCEu.id("test-overlock-logic-2")) + .inputItems(new ItemStack(Items.STICK)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.LV]) + .duration(1) + // NBT has a schematic in it with an HV energy input hatch + .build()); + LCR_RECIPE_TYPE.getLookup().addRecipe(LARGE_CHEMICAL_RECIPES + .recipeBuilder(GTCEu.id("test-overlock-logic-3")) + .id(GTCEu.id("test-overlock-logic-3")) + .inputItems(new ItemStack(Items.BROWN_BED)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.EV]) + .duration(1) + // NBT has a schematic in it with an HV energy input hatch + .build()); + } + + private record BusHolder(ItemBusPartMachine inputBus1, ItemBusPartMachine inputBus2, ItemBusPartMachine outputBus1, + WorkableMultiblockMachine controller) {} + + /** + * Retrieves the busses for this specific template and force a multiblock structure check + * + * @param helper the GameTestHelper + * @return the busses, in the BusHolder record. + */ + private static BusHolder getBussesAndForm(GameTestHelper helper) { + WorkableMultiblockMachine controller = (WorkableMultiblockMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 2, 0))); + controller.setRecipeType(LCR_RECIPE_TYPE); + TestUtils.formMultiblock(controller); + ItemBusPartMachine inputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 1, 0))); + ItemBusPartMachine inputBus2 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 2, 0))); + ItemBusPartMachine outputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + return new BusHolder(inputBus1, inputBus2, outputBus1, controller); + } + + // Test for running HV recipe at HV + @GameTest(template = "lcr_input_separation", batch = "OverclockLogic", setupTicks = 40, timeoutTicks = 200) + public static void overclockLogicOnTierNothingChanges(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Items.RED_BED)); + // One tick to start, 20 for the recipe to run + helper.succeedOnTickWhen(21, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Item didn't craft at the right tick with an on-tier recipe" + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + // Test for running LV 1t recipe at HV + @GameTest(template = "lcr_input_separation", batch = "OverclockLogic", setupTicks = 40, timeoutTicks = 200) + public static void overclockLogicTwoTiersAbove16Parallels(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Items.STICK, 64)); + // One tick to start, 4 for the recipe to run (16/t from ULV recipe to HV) + helper.succeedOnTickWhen(5, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE, 64)), + "Item didn't craft at the right tick with an on-tier recipe" + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + // Test for running EV recipe at HV + @GameTest(template = "lcr_input_separation", batch = "OverclockLogic", setupTicks = 40, timeoutTicks = 200) + public static void overclockLogicOverTierNothingHappens(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Items.BROWN_BED)); + helper.onEachTick(() -> { + helper.assertFalse( + busHolder.outputBus1.getInventory().getStackInSlot(0).getItem().equals(Blocks.STONE.asItem()), + "Item crafted at one tier over when it shouldn't have"); + }); + TestUtils.succeedAfterTest(helper, 200); + } + + // Test for code wise calculating perfect OC + @GameTest(template = "lcr_input_separation", batch = "OverclockLogic") + public static void overclockLogicApplyPerfectOverclockTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + // An HV LCR can overclock an MV recipe once + // We pass the controller because it is used to fetch .getMaxVoltageTier() and check input ingredients for + // parallel + GTRecipe recipeBeforeModifiers = LARGE_CHEMICAL_RECIPES + .recipeBuilder(GTCEu.id("test-multiblock-input-separation")) + .id(GTCEu.id("test-multiblock-input-separation")) + .inputItems(new ItemStack(Blocks.COBBLESTONE), new ItemStack(Blocks.ACACIA_WOOD)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.MV]).duration(100) + .build(); + + GTRecipe newRecipe = OC_PERFECT.applyModifier(busHolder.controller, recipeBeforeModifiers); + helper.assertTrue(newRecipe != null, "Could not apply overclock to recipe"); + helper.assertTrue(newRecipe.duration == (recipeBeforeModifiers.duration / PERFECT_DURATION_FACTOR_INV), + "Perfect perfect overclock didn't cut recipe time by 4"); + helper.assertTrue( + newRecipe.getInputEUt().getTotalEU() == + (recipeBeforeModifiers.getInputEUt().getTotalEU() * STD_VOLTAGE_FACTOR), + "Non perfect overclock didn't multiply EU by 4"); + helper.succeed(); + } + + // Test for code wise calculating non-perfect OC + @GameTest(template = "lcr_input_separation", batch = "OverclockLogic") + public static void overclockLogicApplyNonPerfectOverclockTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + // An HV LCR can overclock an MV recipe once + // We pass the controller because it is used to fetch .getMaxVoltageTier() and check input ingredients for + // parallel + GTRecipe recipeBeforeModifiers = LARGE_CHEMICAL_RECIPES + .recipeBuilder(GTCEu.id("test-multiblock-overclock-test-npo")) + .id(GTCEu.id("test-multiblock-overclock-test-npo")) + .inputItems(new ItemStack(Blocks.COBBLESTONE), new ItemStack(Blocks.ACACIA_WOOD)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.MV]).duration(100) + .build(); + + GTRecipe newRecipe = OC_NON_PERFECT.applyModifier(busHolder.controller, recipeBeforeModifiers); + helper.assertTrue(newRecipe != null, "Could not apply overclock to recipe"); + helper.assertTrue(newRecipe.duration == (recipeBeforeModifiers.duration / STD_DURATION_FACTOR_INV), + "Non perfect overclock didn't cut recipe time by 2"); + helper.assertTrue( + newRecipe.getInputEUt().getTotalEU() == + (recipeBeforeModifiers.getInputEUt().getTotalEU() * STD_VOLTAGE_FACTOR), + "Non perfect overclock didn't multiply EU by 4"); + helper.succeed(); + } + + // Test for code wise calculating subtick perfect OC + @GameTest(template = "lcr_input_separation", batch = "OverclockLogic") + public static void overclockLogicApplyPerfectParallelOverclockTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + // An HV LCR can overclock an MV recipe once + // We pass the controller because it is used to fetch .getMaxVoltageTier() and check input ingredients for + // parallel + GTRecipe recipeBeforeModifiers = LARGE_CHEMICAL_RECIPES + .recipeBuilder(GTCEu.id("test-multiblock-overclock-test-psto")) + .id(GTCEu.id("test-multiblock-overclock-test-psto")) + .inputItems(new ItemStack(Blocks.COBBLESTONE)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.MV]).duration(1) + .build(); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE, 64)); + + GTRecipe newRecipe = OC_PERFECT_SUBTICK.applyModifier(busHolder.controller, recipeBeforeModifiers); + + helper.assertTrue(newRecipe != null, "Could not apply overclock to recipe"); + helper.assertTrue(newRecipe.subtickParallels == PERFECT_DURATION_FACTOR_INV, + "Perfect subtick overclock didn't multiply parallels by 4"); + helper.assertTrue( + newRecipe.getInputEUt().getTotalEU() == + (recipeBeforeModifiers.getInputEUt().getTotalEU() * STD_VOLTAGE_FACTOR), + "Perfect subtick overclock didn't multiply EU by 4"); + helper.succeed(); + } + + // Test for code wise calculating subtick non-perfect OC + @GameTest(template = "lcr_input_separation", batch = "OverclockLogic") + public static void overclockLogicApplyNonPerfectParallelOverclockTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + // An HV LCR can overclock an MV recipe once + // We pass the controller because it is used to fetch .getMaxVoltageTier() and check input ingredients for + // parallel + GTRecipe recipeBeforeModifiers = LARGE_CHEMICAL_RECIPES + .recipeBuilder(GTCEu.id("test-multiblock-overclock-test-npsto")) + .id(GTCEu.id("test-multiblock-overclock-test-npsto")) + .inputItems(new ItemStack(Blocks.COBBLESTONE)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.MV]).duration(1) + .build(); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE, 64)); + + GTRecipe newRecipe = OC_NON_PERFECT_SUBTICK.applyModifier(busHolder.controller, recipeBeforeModifiers); + + helper.assertTrue(newRecipe != null, "Could not apply overclock to recipe"); + helper.assertTrue(newRecipe.subtickParallels == STD_DURATION_FACTOR_INV, + "Non-Perfect subtick overclock didn't multiply parallels by 2"); + helper.assertTrue( + newRecipe.getInputEUt().getTotalEU() == + (recipeBeforeModifiers.getInputEUt().getTotalEU() * STD_VOLTAGE_FACTOR), + "Non-Perfect subtick overclock didn't multiply EU by 4"); + helper.succeed(); + } + + // Test for code wise calculating non-subtick non-perfect OC on a 1t recipe + @GameTest(template = "lcr_input_separation", batch = "OverclockLogic") + public static void overclockLogicApplyNonPerfectNonParallel1tOverclockTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + // An HV LCR can overclock an MV recipe once + // We pass the controller because it is used to fetch .getMaxVoltageTier() and check input ingredients for + // parallel + GTRecipe recipeBeforeModifiers = LARGE_CHEMICAL_RECIPES + .recipeBuilder(GTCEu.id("test-multiblock-overclock-test-npsto")) + .id(GTCEu.id("test-multiblock-overclock-test-npsto")) + .inputItems(new ItemStack(Blocks.COBBLESTONE)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.MV]).duration(1) + .build(); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE, 64)); + + GTRecipe newRecipe = OC_NON_PERFECT.applyModifier(busHolder.controller, recipeBeforeModifiers); + + helper.assertTrue(newRecipe != null, "Could not apply overclock to recipe"); + helper.assertTrue(newRecipe.subtickParallels == 1, + "Non-Perfect Non-subtick overclock overclocked when it shouldn't have"); + helper.assertTrue( + newRecipe.getInputEUt().getTotalEU() == recipeBeforeModifiers.getInputEUt().getTotalEU(), + "Non-Perfect Non-subtick overclock at 1t changed EU"); + helper.succeed(); + } + + // Test for code wise calculating an overclock on a recipe that can't be run + @GameTest(template = "lcr_input_separation", batch = "OverclockLogic") + public static void overclockLogicEVRecipeHVMachineTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + // An HV LCR can overclock an MV recipe once + // We pass the controller because it is used to fetch .getMaxVoltageTier() and check input ingredients for + // parallel + GTRecipe recipeBeforeModifiers = LARGE_CHEMICAL_RECIPES + .recipeBuilder(GTCEu.id("test-multiblock-overclock-test-ev-hv")) + .id(GTCEu.id("test-multiblock-overclock-test-ev-hv")) + .inputItems(new ItemStack(Blocks.COBBLESTONE)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.EV]).duration(1) + .build(); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE, 64)); + + GTRecipe newRecipe = OC_NON_PERFECT.applyModifier(busHolder.controller, recipeBeforeModifiers); + + helper.assertTrue(newRecipe == null, "Applied EV overclock to HV recipe when it shouldn't have"); + + helper.succeed(); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java new file mode 100644 index 00000000000..155baaaccac --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderFluidIngredientTest.java @@ -0,0 +1,1025 @@ +package com.gregtechceu.gtceu.api.recipe.ingredient; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.SimpleTieredMachine; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.trait.NotifiableFluidTank; +import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.common.machine.multiblock.part.FluidHatchPartMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.part.ItemBusPartMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.part.ParallelHatchPartMachine; +import com.gregtechceu.gtceu.data.material.GTMaterials; +import com.gregtechceu.gtceu.data.recipe.GTRecipeTypes; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.crafting.SizedFluidIngredient; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import lombok.Getter; + +/** + * Test cases: + * Do many passes of most tests as a safeguard against bad rolls + * Same output more than once + * Out of bounds + * Output a multiple of batchparallels + * Rolls of 0 + * Forced rolls of 0 breaking recipes + */ +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class IntProviderFluidIngredientTest { + + private static GTRecipeType CR_RECIPE_TYPE; + private static GTRecipeType LCR_RECIPE_TYPE; + private static GTRecipeType CENTRIFUGE_RECIPE_TYPE; + + // fluids used in recipes. Up top here for quick replacements. + private static final FluidStack CR_IN = GTMaterials.Hydrogen.getFluid(1); + private static final FluidStack CR_OUT = GTMaterials.Iron.getFluid(1); + private static final FluidStack LCR_IN = GTMaterials.Oxygen.getFluid(1); + private static final FluidStack LCR_OUT = GTMaterials.Copper.getFluid(1); + private static final FluidStack LCENT_IN = GTMaterials.Nitrogen.getFluid(1); + private static final FluidStack LCENT_OUT = GTMaterials.Gold.getFluid(1); + private static final FluidStack RUBBER = GTMaterials.Rubber.getFluid(1); + private static final FluidStack REDSTONE = GTMaterials.Redstone.getFluid(1); + private static final ItemStack COBBLE = new ItemStack(Items.COBBLESTONE); + + /** + * How many times to repeat the Batch and Parallel random roll tests to avoid false positives + * Currently set to 7, with singleblock recipes processing up to 9 fluids, allowing for stacks of up to 63 fluids. + */ + @Getter + private static final int REPLICAS = 7; + + @BeforeBatch(batch = "RangedFluidIngredients") + public static void prepare(ServerLevel level) { + CR_RECIPE_TYPE = TestUtils.createRecipeType("ranged_fluid_ingredient_cr_tests", GTRecipeTypes.CHEMICAL_RECIPES); + LCR_RECIPE_TYPE = TestUtils.createRecipeType("ranged_fluid_ingredient_lcr_tests", + GTRecipeTypes.LARGE_CHEMICAL_RECIPES); + CENTRIFUGE_RECIPE_TYPE = TestUtils.createRecipeType("ranged_fluid_ingredient_centrifuge_tests", + GTRecipeTypes.CENTRIFUGE_RECIPES); + CR_RECIPE_TYPE.getLookup().removeAllRecipes(); + LCR_RECIPE_TYPE.getLookup().removeAllRecipes(); + CENTRIFUGE_RECIPE_TYPE.getLookup().removeAllRecipes(); + + CR_RECIPE_TYPE.getLookup().addRecipe(CR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_input_fluid_cr")) + .inputFluidsRanged(CR_IN, UniformInt.of(0, 9)) + .inputItems(COBBLE) + .outputFluids(REDSTONE) + .EUt(GTValues.V[GTValues.HV]) + .duration(2) + .build()); + + CR_RECIPE_TYPE.getLookup().addRecipe(CR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_output_fluid_cr")) + .inputFluids(CR_OUT) + .outputFluidsRanged(REDSTONE, UniformInt.of(0, 9)) + .EUt(GTValues.V[GTValues.HV]) + .duration(2) + .build()); + + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_input_fluid_lcr")) + .inputFluidsRanged(LCR_IN, UniformInt.of(0, 9)) + .inputFluids(RUBBER) + .outputFluids(REDSTONE) + .EUt(GTValues.V[GTValues.HV]) + .duration(2) + .build()); + + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_output_fluid_lcr")) + .inputFluids(LCR_OUT) + .outputFluidsRanged(REDSTONE, UniformInt.of(0, 9)) + .EUt(GTValues.V[GTValues.HV]) + .duration(2) + .build()); + + CENTRIFUGE_RECIPE_TYPE.getLookup().addRecipe(CENTRIFUGE_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_input_fluid_cent")) + .inputFluidsRanged(LCENT_IN, UniformInt.of(0, 40)) + .inputItems(COBBLE) + .outputFluids(REDSTONE) + .EUt(GTValues.V[GTValues.IV]) + .duration(4) + .build()); + + CENTRIFUGE_RECIPE_TYPE.getLookup().addRecipe(CENTRIFUGE_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_output_fluid_cent")) + .inputFluids(LCENT_OUT) + .outputFluidsRanged(REDSTONE, UniformInt.of(0, 40)) + .EUt(GTValues.V[GTValues.IV]) + .duration(4) + .build()); + } + + private static MetaMachine getMetaMachine(BlockEntity entity) { + return ((MetaMachineBlockEntity) entity).getMetaMachine(); + } + + private record BusHolder(ItemBusPartMachine inputBus1, FluidHatchPartMachine inputHatch1, + ItemBusPartMachine outputBus1, + FluidHatchPartMachine outputHatch1, WorkableMultiblockMachine controller) {} + + private record BusHolderBatchParallel(ItemBusPartMachine inputBus1, FluidHatchPartMachine inputHatch1, + ItemBusPartMachine outputBus1, + FluidHatchPartMachine outputHatch1, + WorkableElectricMultiblockMachine controller, + ParallelHatchPartMachine parallelHatch) {} + + /** + * Retrieves the busses for this LCR template and force a multiblock structure check + * + * @param helper the GameTestHelper + * @return the busses, in the BusHolder record. + */ + private static BusHolder getBussesAndFormLCR(GameTestHelper helper) { + WorkableMultiblockMachine controller = (WorkableMultiblockMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 2, 0))); + TestUtils.formMultiblock(controller); + controller.setRecipeType(LCR_RECIPE_TYPE); + ItemBusPartMachine inputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 1, 0))); + FluidHatchPartMachine inputHatch1 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 2, 0))); + ItemBusPartMachine outputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + FluidHatchPartMachine outputHatch1 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 2, 0))); + return new BusHolder(inputBus1, inputHatch1, outputBus1, outputHatch1, controller); + } + + /** + * Retrieves the busses for this Large Centrifuge template and force a multiblock structure check + * + * @param helper the GameTestHelper + * @return the busses, in the BusHolder record. + */ + private static BusHolderBatchParallel getBussesAndFormLCENT(GameTestHelper helper) { + WorkableElectricMultiblockMachine controller = (WorkableElectricMultiblockMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 2, 0))); + TestUtils.formMultiblock(controller); + controller.setRecipeType(CENTRIFUGE_RECIPE_TYPE); + ItemBusPartMachine inputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 2, 0))); + FluidHatchPartMachine inputHatch1 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 2, 0))); + ItemBusPartMachine outputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 1, 0))); + FluidHatchPartMachine outputHatch1 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 1, 0))); + ParallelHatchPartMachine parallelHatch = (ParallelHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(3, 3, 0))); + return new BusHolderBatchParallel(inputBus1, inputHatch1, outputBus1, outputHatch1, controller, parallelHatch); + } + + // test for IntProviderFluidIngredient.test() + @GameTest(template = "empty", batch = "RangedFluidIngredients") + public static void rangedFluidIngredientTestEqualTest(GameTestHelper helper) { + var ingredient = IntProviderFluidIngredient.of(GTMaterials.Water.getFluid(1), 1, 5); + helper.assertTrue(ingredient.test(GTMaterials.Water.getFluid(3)), + "IntProviderFluidIngredient.test doesn't match when it should have"); + // This should work since test only tries the fluid type. + helper.assertTrue(ingredient.test(GTMaterials.Water.getFluid(64)), + "IntProviderFluidIngredient.test doesn't match when it should have with value outside bounds"); + helper.assertFalse(ingredient.test(GTMaterials.Lava.getFluid(3)), + "IntProviderFluidIngredient.test shouldn't match with different fluids"); + helper.succeed(); + } + + // test for IntProviderFluidIngredient.getStacks() + @GameTest(template = "empty", batch = "RangedFluidIngredients") + public static void rangedFluidIngredientGetStacksTest(GameTestHelper helper) { + var ingredient = IntProviderFluidIngredient.of(GTMaterials.Water.getFluid(1), 1, 500000); + var stacks = ingredient.getFluidStacks(); + helper.assertTrue(stacks.length == 1, + "IntProviderFluidIngredient should only return 1 fluid when made with 1 fluid"); + // helper.assertTrue(stacks[0].isFluidEqual(GTMaterials.Water.getFluid(1)), + // "IntProviderFluidIngredient should have fluid equal to what it was made with"); + helper.assertTrue(FluidStack.matches(stacks[0], ingredient.getFluidStacks()[0]), + "IntProviderFluidIngredient.getStacks shouldn't change between getStacks calls"); + ingredient.reset(); + helper.assertFalse(FluidStack.matches(stacks[0], ingredient.getStacks()[0]), + "IntProviderFluidIngredient.getStacks should have changed after rerolling"); + helper.succeed(); + } + + // test for IntProviderFluidIngredient.toJson() + // @GameTest(template = "empty", batch = "RangedFluidIngredients") + // public static void rangedIngredientJsonTest(GameTestHelper helper) { + // var ingredient = IntProviderFluidIngredient.of(GTMaterials.Water.getFluid(1), 1, 500000); + + // // serialize/deserialize before rolling count + // var jsonPreRoll = ingredient.toJson(); + // var ingredientDeserializedPreRoll = IntProviderFluidIngredient.fromJson(jsonPreRoll); + + // var stacks = ingredient.getStacks(); + // var stacksDeserializedPreRoll = ingredientDeserializedPreRoll.getStacks(); + + // // serialize/deserialize after rolling count + // var jsonPostRoll = ingredient.toJson(); + // var ingredientDeserializedPostRoll = IntProviderFluidIngredient.fromJson(jsonPostRoll); + // var stacksDeserializedPostRoll = ingredientDeserializedPostRoll.getStacks(); + + // helper.assertTrue( + // stacks.length == stacksDeserializedPreRoll.length && stacks.length == stacksDeserializedPostRoll.length, + // "IntProviderFluidIngredient should only return 1 fluid when made with 1 fluid, even after serializing"); + // helper.assertTrue(stacksDeserializedPreRoll[0].isFluidEqual(GTMaterials.Water.getFluid(1)), + // "IntProviderFluidIngredient should have fluid equal to what it was made with after serializing"); + // helper.assertTrue(stacksDeserializedPostRoll[0].isFluidEqual(GTMaterials.Water.getFluid(1)), + // "IntProviderFluidIngredient should have fluid equal to what it was made with after serializing"); + // helper.assertFalse(TestUtils.areFluidStacksEqual(stacksDeserializedPreRoll, ingredient.getStacks()), + // "IntProviderFluidIngredient.getStacks should be different if it wasn't rolled before serializing"); + // helper.assertTrue(TestUtils.areFluidStacksEqual(stacksDeserializedPostRoll, ingredient.getStacks()), + // "IntProviderFluidIngredient.getStacks shouldn't change between getStacks calls if it was rolled before + // serializing"); + // helper.succeed(); + // } + + // Test for singleblock machine with ranged fluid input. + // Forcibly sabotages the first recipe run, setting its output amount to 0 to ensure that doesn't break the recipe. + // This is specifically a test for #3593 / #3594 + @GameTest(template = "singleblock_charged_cr", batch = "RangedFluidIngredients") + public static void singleblockRangedFluidOutputSabotaged(GameTestHelper helper) { + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + + machine.setRecipeType(CR_RECIPE_TYPE); + NotifiableFluidTank fluidIn = machine.importFluids; + NotifiableFluidTank fluidOut = machine.exportFluids; + + int runs = 7; + fluidIn.setFluidInTank(0, CR_OUT.copyWithAmount(runs)); + // 1t to turn on, 2t per recipe run + // get the result of each roll independently + int[] addedRolls = new int[runs]; + + helper.runAfterDelay(2, () -> { + if (machine.getRecipeLogic().getLastRecipe().getOutputContents(FluidRecipeCapability.CAP).get(0) + .getContent() instanceof SizedFluidIngredient superingredient) { + if (superingredient.ingredient() instanceof IntProviderFluidIngredient ingredient) { + ingredient.setSampledCount(0); + + if (ingredient.getSampledCount() != 0) { + helper.fail("Singleblock Ranged Fluid Output sabotage failed! " + + "Output count not was altered!"); + } + } else { + helper.fail("Singleblock Ranged Fluid Output sabotage failed! " + + "Recipe logic did not contain a Ranged Output!"); + } + } else { + helper.fail("Singleblock Ranged Fluid Output sabotage failed! " + + "Recipe logic did not contain a Output!"); + } + }); + for (int i = 0; i < runs; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(2 * i + 3, () -> { + addedRolls[finalI] = (int) fluidOut.getTotalContentAmount(); + }); + } + // check the results of all rolls together + helper.runAfterDelay(runs * 2 + 1, () -> { + FluidStack results = fluidOut.getFluidInTank(0); + helper.assertFalse((results.getAmount() == runs * 0), + "Sabotaged Singleblock Ranged Fluid Output rolled min value on every roll! " + + "This is the failure this sabotage was intended to induce."); + helper.assertFalse((results.getAmount() == runs * 9), + "Sabotaged Singleblock CR rolled max value on every roll (how??)"); + helper.assertTrue(TestUtils.isFluidWithinRange(results, runs, runs * 9), + "Sabotaged Singleblock CR didn't produce correct number of fluids, produced [" + + results.getAmount() + "] not [" + runs + "-" + (runs * 9) + "]"); + + // check if all the rolls were equal, but not min/max + int[] rolls = new int[runs]; + rolls[0] = addedRolls[0]; + boolean allEqual = false; + for (int i = 1; i < runs; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (rolls[i] == rolls[i - 1]) { + allEqual = true; + } else { + allEqual = false; + break; + } + } + helper.assertFalse(allEqual, + "Sabotaged Singleblock CR rolled the same value on every input roll (rolled " + rolls[0] + ")"); + helper.succeed(); + }); + } + + // Failure Test for singleblock machine with ranged fluid input + // Provides too little input fluid, should not run recipes. + @GameTest(template = "singleblock_charged_cr", batch = "RangedFluidIngredients") + public static void singleblockRangedFluidInputFailure(GameTestHelper helper) { + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + + machine.setRecipeType(CR_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableFluidTank fluidIn = machine.importFluids; + NotifiableFluidTank fluidOut = machine.exportFluids; + + int runs = 10; + fluidIn.setFluidInTank(0, CR_IN.copyWithAmount(8)); + itemIn.setStackInSlot(1, COBBLE.copyWithCount(runs)); + // 1t to turn on, 2t per non-recipe run + helper.runAfterDelay(runs * 2 + 1, () -> { + FluidStack results = fluidIn.getFluidInTank(0); + + helper.assertTrue(fluidOut.isEmpty(), + "Singleblock CR should not have run, ran [" + + fluidOut.getFluidInTank(0).getAmount() + "] times"); + helper.assertTrue(TestUtils.isFluidStackEqual(results, CR_IN.copyWithAmount(8)), + "Singleblock CR should not have consumed items, consumed [" + + (8 - results.getAmount()) + "]"); + + helper.succeed(); + }); + } + + // Test for singleblock machine with ranged fluid input + @GameTest(template = "singleblock_charged_cr", batch = "RangedFluidIngredients") + public static void singleblockRangedFluidInput(GameTestHelper helper) { + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + + machine.setRecipeType(CR_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableFluidTank fluidIn = machine.importFluids; + NotifiableFluidTank fluidOut = machine.exportFluids; + + int runs = 7; + fluidIn.setFluidInTank(0, CR_IN.copyWithAmount(64)); + itemIn.setStackInSlot(0, COBBLE.copyWithCount(runs)); + // 1t to turn on, 2t per recipe run + // get the result of each roll independently + int[] addedRolls = new int[runs]; + for (int i = 0; i < runs; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(2 * i + 1, () -> { + addedRolls[finalI] = fluidIn.getFluidInTank(0).getAmount(); + }); + } + // check the results of all rolls together + helper.runAfterDelay(runs * 2 + 2, () -> { + FluidStack results = fluidIn.getFluidInTank(0); + int upperLimit = 64 - (runs * 0); + int lowerLimit = 64 - (runs * 9); + helper.assertTrue(TestUtils.isFluidStackEqual(fluidOut.getFluidInTank(0), REDSTONE.copyWithAmount(runs)), + "Singleblock CR didn't complete correct number of recipes, completed [" + + fluidOut.getFluidInTank(0).getAmount() + "] not [" + runs + "]"); + helper.assertTrue(TestUtils.isFluidWithinRange(results, lowerLimit, upperLimit), + "Singleblock CR didn't consume correct number of fluids, consumed [" + + (64 - results.getAmount()) + "] not [" + lowerLimit + "-" + upperLimit + "]"); + helper.assertFalse((results.getAmount() == lowerLimit), + "Singleblock CR rolled max value on every roll"); + helper.assertFalse((results.getAmount() == upperLimit), + "Singleblock CR rolled min value on every roll"); + + // check if all the rolls were equal, but not min/max + int[] rolls = new int[runs]; + rolls[0] = 64 - addedRolls[0]; + boolean allEqual = false; + for (int i = 1; i < runs; i++) { + rolls[i] = addedRolls[i - 1] - addedRolls[i]; + if (rolls[i] == rolls[i - 1]) { + allEqual = true; + } else { + allEqual = false; + break; + } + } + helper.assertFalse(allEqual, + "Singleblock CR rolled the same value on every input roll (rolled " + rolls[0] + ")"); + helper.succeed(); + }); + } + + // Test for singleblock machine with ranged fluid input + @GameTest(template = "singleblock_charged_cr", batch = "RangedFluidIngredients") + public static void singleblockRangedFluidOutput(GameTestHelper helper) { + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + + machine.setRecipeType(CR_RECIPE_TYPE); + NotifiableFluidTank fluidIn = machine.importFluids; + NotifiableFluidTank fluidOut = machine.exportFluids; + + int runs = 7; + fluidIn.setFluidInTank(0, CR_OUT.copyWithAmount(runs)); + // 1t to turn on, 2t per recipe run + // get the result of each roll independently + int[] addedRolls = new int[runs]; + for (int i = 0; i < runs; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(2 * i + 3, () -> { + addedRolls[finalI] = fluidOut.getFluidInTank(0).getAmount(); + }); + } + // check the results of all rolls together + helper.runAfterDelay(runs * 2 + 1, () -> { + helper.assertTrue(fluidIn.getFluidInTank(0).isEmpty(), + "Singleblock CR didn't complete correct number of recipes, completed [" + + fluidIn.getFluidInTank(0).getAmount() + "] not [" + runs + "]"); + FluidStack results = fluidOut.getFluidInTank(0); + helper.assertTrue(TestUtils.isFluidWithinRange(results, runs, runs * 9), + "Singleblock CR didn't produce correct number of fluids, produced [" + + results.getAmount() + "] not [" + runs + "-" + (runs * 9) + "]"); + helper.assertFalse((results.getAmount() == runs * 9), + "Singleblock CR rolled max value on every roll"); + helper.assertFalse((results.getAmount() == runs * 0), + "Singleblock CR rolled min value on every roll"); + + // check if all the rolls were equal, but not min/max + int[] rolls = new int[runs]; + rolls[0] = addedRolls[0]; + boolean allEqual = false; + for (int i = 1; i < runs; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (rolls[i] == rolls[i - 1]) { + allEqual = true; + } else { + allEqual = false; + break; + } + } + helper.assertFalse(allEqual, + "Singleblock CR rolled the same value on every input roll (rolled " + rolls[0] + ")"); + helper.succeed(); + }); + } + + // test for multiblock machine with ranged fluid input + @GameTest(template = "lcr_ranged_ingredients", + batch = "RangedFluidIngredients") + public static void multiblockLCRRangedFluidInput(GameTestHelper helper) { + BusHolder busHolder = getBussesAndFormLCR(helper); + + NotifiableFluidTank fluidIn = busHolder.inputHatch1.tank; + NotifiableFluidTank fluidOut = busHolder.outputHatch1.tank; + + int runs = 7; + fluidIn.setFluidInTank(0, LCR_IN.copyWithAmount(64)); + fluidIn.setFluidInTank(1, RUBBER.copyWithAmount(runs)); + // 1t to turn on, 2t per recipe run + // get the result of each roll independently + int[] addedRolls = new int[runs]; + for (int i = 0; i < runs; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(2 * i + 1, () -> { + addedRolls[finalI] = fluidIn.getFluidInTank(0).getAmount(); + }); + } + // check the results of all rolls together + helper.runAfterDelay(runs * 2 + 2, () -> { + FluidStack results = fluidIn.getFluidInTank(0); + int upperLimit = 64 - (runs * 0); + int lowerLimit = 64 - (runs * 9); + helper.assertTrue(TestUtils.isFluidStackEqual(fluidOut.getFluidInTank(0), REDSTONE.copyWithAmount(runs)), + "LCR didn't complete correct number of recipes, completed [" + + fluidOut.getFluidInTank(0).getAmount() + "] not [" + runs + "]"); + helper.assertTrue(TestUtils.isFluidWithinRange(results, lowerLimit, upperLimit), + "LCR didn't consume correct number of fluids, consumed [" + + (64 - results.getAmount()) + "] not [" + lowerLimit + "-" + upperLimit + "]"); + helper.assertFalse((results.getAmount() == lowerLimit), + "LCR rolled max value on every roll"); + helper.assertFalse((results.getAmount() == upperLimit), + "LCR rolled min value on every roll"); + + // check if all the rolls were equal, but not min/max + int[] rolls = new int[runs]; + rolls[0] = 64 - addedRolls[0]; + boolean allEqual = false; + for (int i = 1; i < runs; i++) { + rolls[i] = addedRolls[i - 1] - addedRolls[i]; + if (rolls[i] == rolls[i - 1]) { + allEqual = true; + } else { + allEqual = false; + break; + } + } + helper.assertFalse(allEqual, + "LCR rolled the same value on every input roll (rolled " + rolls[0] + ")"); + helper.succeed(); + }); + } + + // test for multiblock machine with ranged fluid input + @GameTest(template = "lcr_ranged_ingredients", + batch = "RangedFluidIngredients") + public static void multiblockLCRRangedFluidOutput(GameTestHelper helper) { + BusHolder busHolder = getBussesAndFormLCR(helper); + + final NotifiableFluidTank fluidIn = busHolder.inputHatch1.tank; + final NotifiableFluidTank fluidOut = busHolder.outputHatch1.tank; + + int runs = 7; + fluidIn.setFluidInTank(0, LCR_OUT.copyWithAmount(runs)); + // 1t to turn on, 2t per recipe run + // get the result of each roll independently + int[] addedRolls = new int[runs]; + for (int i = 0; i < runs; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(2 * i + 3, () -> { + addedRolls[finalI] = fluidOut.getFluidInTank(0).getAmount(); + }); + } + // check the results of all rolls together + helper.runAfterDelay(runs * 2 + 1, () -> { + helper.assertTrue(fluidIn.getFluidInTank(0).isEmpty(), + "LCR didn't complete correct number of recipes, completed [" + + fluidIn.getFluidInTank(0).getAmount() + "] not [" + runs + "]"); + FluidStack results = fluidOut.getFluidInTank(0); + helper.assertTrue(TestUtils.isFluidWithinRange(results, runs, runs * 9), + "LCR didn't produce correct number of fluids, produced [" + + results.getAmount() + "] not [" + runs + "-" + (runs * 9) + "]"); + helper.assertFalse((results.getAmount() == runs * 9), + "LCR rolled max value on every roll"); + helper.assertFalse((results.getAmount() == runs * 0), + "LCR rolled min value on every roll"); + + // check if all the rolls were equal, but not min/max + int[] rolls = new int[runs]; + rolls[0] = addedRolls[0]; + boolean allEqual = false; + for (int i = 1; i < runs; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (rolls[i] == rolls[i - 1]) { + allEqual = true; + } else { + allEqual = false; + break; + } + } + helper.assertFalse(allEqual, + "LCR rolled the same value on every input roll (rolled " + rolls[0] + ")"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged fluid input + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedFluidIngredients", + timeoutTicks = 200) + public static void multiblockLCentRangedFluidInput16Parallel(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + NotifiableItemStackHandler itemIn = busHolder.inputBus1.getInventory(); + final NotifiableFluidTank fluidIn = busHolder.inputHatch1.tank; + final NotifiableFluidTank fluidOut = busHolder.outputHatch1.tank; + + int batches = 1; // unused on this test + int parallels = 16; + final int amount = 40 * batches * parallels; + busHolder.controller.setBatchEnabled(false); + busHolder.parallelHatch.setCurrentParallel(parallels); + + itemIn.setStackInSlot(0, COBBLE.copyWithCount(batches * parallels)); + fluidIn.setFluidInTank(0, LCENT_IN.copyWithAmount(amount)); + + // 1t to turn on, 4t per recipe run + // 16 parallels + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] rolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(17 * finalI, () -> { + FluidStack results = fluidIn.getFluidInTank(0); + int upperLimit = amount - (batches * parallels * 0); + int lowerLimit = amount - (batches * parallels * 40); + int completed = batches * parallels * finalI; + helper.assertTrue( + TestUtils.isFluidStackEqual(fluidOut.getFluidInTank(0).copyWithAmount( + ((int) Math.round(fluidOut.getTotalContentAmount()))), + REDSTONE.copyWithAmount(completed)), + "Parallel LCent didn't complete correct number of recipes, completed [" + + ((int) Math.round(fluidOut.getTotalContentAmount())) + "] not [" + + completed + "]"); + helper.assertTrue(TestUtils.isFluidWithinRange(results, lowerLimit, upperLimit), + "Parallel LCent didn't consume correct number of fluids, consumed " + + (amount - results.getAmount()) + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + rolls[finalI - 1] = amount - results.getAmount(); + + // reset for a rerun + itemIn.setStackInSlot(0, COBBLE.copyWithCount(batches * parallels)); + fluidIn.setFluidInTank(0, LCENT_IN.copyWithAmount(40 * batches * parallels)); + }); + } + + helper.runAfterDelay(1 + 17 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + for (int i = 0; i < REPLICAS; i++) { + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Parallel LCent ranged fluid input test iteration " + i + " consumed [" + + rolls[i] + "] fluids, a multiple of its Batch * Parallel count (" + (parallels) + + "). If this message only appears once, this is likely a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Parallel LCent ranged fluid input test rolled exactly even to " + + "Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged fluid output + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedFluidIngredients", + timeoutTicks = 200) + public static void multiblockLCentRangedFluidOutput16Parallel(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + final NotifiableFluidTank fluidIn = busHolder.inputHatch1.tank; + final NotifiableFluidTank fluidOut = busHolder.outputHatch1.tank; + + int batches = 1; // unused on this test + int parallels = 16; + fluidIn.setFluidInTank(0, LCENT_OUT.copyWithAmount(16)); + + busHolder.controller.setBatchEnabled(false); + busHolder.parallelHatch.setCurrentParallel(parallels); + + // 1t to turn on, 1t per recipe run + // 16 parallels + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] addedRolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(17 * finalI, () -> { + int runs = finalI * batches * parallels; + helper.assertTrue(fluidIn.getFluidInTank(0).isEmpty(), + "Parallel LCent didn't complete correct number of recipes, completed [" + + fluidIn.getFluidInTank(0).getAmount() + "] not [" + runs + "]"); + int resultCount = (int) Math.round(fluidOut.getTotalContentAmount()); + int lowerLimit = runs * 0; + int upperLimit = runs * 40; + helper.assertTrue(TestUtils.isCountWithinRange(resultCount, lowerLimit, upperLimit), + "Parallel LCent didn't produce correct number of fluids, produced [" + + resultCount + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + addedRolls[finalI - 1] = resultCount; + + // reset for a rerun + fluidIn.setFluidInTank(0, LCENT_OUT.copyWithAmount(16)); + }); + } + + helper.runAfterDelay(1 + 17 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + int[] rolls = new int[REPLICAS]; + + rolls[0] = addedRolls[0]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[0], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Parallel LCent ranged fluid output test iteration " + 1 + " produced [" + + rolls[0] + "] fluids, a multiple of its Batch * Parallel count (" + (batches * parallels) + + "). If this message only appears once, this is likely a false positive."); + } + for (int i = 1; i < REPLICAS; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Parallel LCent ranged fluid output test iteration " + (i + 1) + " produced [" + + rolls[i] + "] fluids, a multiple of its Batch * Parallel count (" + (batches * parallels) + + "). If this message only appears once, this is likely a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Parallel LCent ranged fluid output test rolled exactly even to " + + "Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged fluid input + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedFluidIngredients", + timeoutTicks = 200) + public static void multiblockLCentRangedFluidInputBatched(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + NotifiableItemStackHandler itemIn = busHolder.inputBus1.getInventory(); + final NotifiableFluidTank fluidIn = busHolder.inputHatch1.tank; + final NotifiableFluidTank fluidOut = busHolder.outputHatch1.tank; + + int batches = 16; + int parallels = 1; + final int amount = 40 * batches * parallels; + busHolder.controller.setBatchEnabled(true); + busHolder.parallelHatch.setCurrentParallel(parallels); + + itemIn.setStackInSlot(0, COBBLE.copyWithCount(batches * parallels)); + fluidIn.setFluidInTank(0, LCENT_IN.copyWithAmount(amount)); + + // 1t to turn on, 1t per recipe run + // 16 batches + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] rolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(17 * finalI, () -> { + FluidStack results = fluidIn.getFluidInTank(0); + int upperLimit = amount - (batches * parallels * 0); + int lowerLimit = amount - (batches * parallels * 40); + int completed = batches * parallels * finalI; + helper.assertTrue( + TestUtils.isFluidStackEqual(fluidOut.getFluidInTank(0).copyWithAmount( + ((int) Math.round(fluidOut.getTotalContentAmount()))), + REDSTONE.copyWithAmount(completed)), + "Batched LCent didn't complete correct number of recipes, completed [" + + ((int) Math.round(fluidOut.getTotalContentAmount())) + "] not [" + + completed + "]"); + helper.assertTrue(TestUtils.isFluidWithinRange(results, lowerLimit, upperLimit), + "Batched LCent didn't consume correct number of fluids, consumed " + + (amount - results.getAmount()) + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + rolls[finalI - 1] = amount - results.getAmount(); + + // reset for a rerun + itemIn.setStackInSlot(0, COBBLE.copyWithCount(batches * parallels)); + fluidIn.setFluidInTank(0, LCENT_IN.copyWithAmount(amount)); + }); + } + + helper.runAfterDelay(1 + 17 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + for (int i = 0; i < REPLICAS; i++) { + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Batched LCent ranged fluid input test iteration " + i + " consumed [" + + rolls[i] + "] fluids, a multiple of its Batch * Parallel count (" + (batches * parallels) + + "). If this message only appears once, this is likely a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Batched LCent ranged fluid input test rolled exactly even to " + + "Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged fluid output + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedFluidIngredients", + timeoutTicks = 200) + public static void multiblockLCentRangedFluidOutputBatched(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + final NotifiableFluidTank fluidIn = busHolder.inputHatch1.tank; + final NotifiableFluidTank fluidOut = busHolder.outputHatch1.tank; + + int batches = 16; + int parallels = 1; // unused on this test + fluidIn.setFluidInTank(0, LCENT_OUT.copyWithAmount(16)); + + busHolder.controller.setBatchEnabled(true); + busHolder.parallelHatch.setCurrentParallel(parallels); + + // 1t to turn on, 1t per recipe run + // 16 parallels + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] addedRolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(17 * finalI, () -> { + int runs = finalI * batches * parallels; + helper.assertTrue(fluidIn.getFluidInTank(0).isEmpty(), + "Batched LCent didn't complete correct number of recipes, completed [" + + fluidIn.getFluidInTank(0).getAmount() + "] not [" + runs + "]"); + int resultCount = (int) Math.round(fluidOut.getTotalContentAmount()); + int lowerLimit = runs * 0; + int upperLimit = runs * 40; + helper.assertTrue(TestUtils.isCountWithinRange(resultCount, lowerLimit, upperLimit), + "Batched LCent didn't produce correct number of fluids, produced [" + + resultCount + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + addedRolls[finalI - 1] = resultCount; + + // reset for a rerun + fluidIn.setFluidInTank(0, LCENT_OUT.copyWithAmount(16)); + }); + } + + helper.runAfterDelay(1 + 17 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + int[] rolls = new int[REPLICAS]; + + rolls[0] = addedRolls[0]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[0], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Batched LCent ranged fluid output test iteration " + 1 + " produced [" + + rolls[0] + "] fluids, a multiple of its Batch * Parallel count (" + batches + + "). If this message only appears once, this is likely a false positive."); + } + for (int i = 1; i < REPLICAS; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Batched LCent ranged fluid output test iteration " + (i + 1) + " produced [" + + rolls[i] + "] fluids, a multiple of its Batch * Parallel count (" + batches + + "). If this message only appears once, this is likely a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Batched LCent ranged fluid output test rolled exactly even to " + + "Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged fluid input + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedFluidIngredients", + timeoutTicks = 500) + public static void multiblockLCentRangedFluidInput16ParallelBatched(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + NotifiableItemStackHandler itemIn = busHolder.inputBus1.getInventory(); + final NotifiableFluidTank fluidIn = busHolder.inputHatch1.tank; + final NotifiableFluidTank fluidOut = busHolder.outputHatch1.tank; + + int batches = 16; + int parallels = 16; + final int amount = batches * parallels * 40; + busHolder.controller.setBatchEnabled(true); + busHolder.parallelHatch.setCurrentParallel(parallels); + + int stacks = batches * parallels / 64; + + for (int j = 0; j < stacks; j++) { + itemIn.setStackInSlot(j, COBBLE.copyWithCount((batches * parallels / stacks))); + } + fluidIn.setFluidInTank(0, LCENT_IN.copyWithAmount(amount)); + + // 1t to turn on, 64t per recipe run + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] rolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(65 * finalI, () -> { + FluidStack results = fluidIn.getFluidInTank(0); + int completed = batches * parallels * finalI; + helper.assertTrue( + TestUtils.isFluidStackEqual( + fluidOut.getFluidInTank(0).copyWithAmount(fluidOut.getFluidInTank(0).getAmount()), + REDSTONE.copyWithAmount(completed)), + "Batched Parallel LCent didn't complete correct number of recipes, completed [" + + (fluidOut.getFluidInTank(0).getAmount()) + "] not [" + completed + "]"); + int upperLimit = amount - (batches * parallels * 0); + int lowerLimit = amount - (batches * parallels * 40); + helper.assertTrue(TestUtils.isFluidWithinRange(results, lowerLimit, upperLimit), + "Batched Parallel LCent didn't consume correct number of fluids, consumed " + + (amount - results.getAmount()) + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + rolls[finalI - 1] = 64 - results.getAmount(); + + // reset for a rerun + for (int l = 0; l < stacks; l++) { + itemIn.setStackInSlot(l, + COBBLE.copyWithCount((batches * parallels / stacks))); + } + fluidIn.setFluidInTank(0, LCENT_IN.copyWithAmount(40 * batches * parallels)); + }); + } + + helper.runAfterDelay(1 + 65 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + for (int i = 0; i < REPLICAS; i++) { + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Batched Parallel LCent ranged fluid input test iteration " + i + " consumed [" + + rolls[i] + "] fluids, a multiple of its Batch * Parallel count (" + (batches * parallels) + + "). If this message only appears once, this is likely a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Batched Parallel LCent ranged fluid input test rolled exactly even to" + + " Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged fluid output + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedFluidIngredients", + timeoutTicks = 500) + public static void multiblockLCentRangedFluidOutput16ParallelBatched(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + final NotifiableFluidTank fluidIn = busHolder.inputHatch1.tank; + final NotifiableFluidTank fluidOut = busHolder.outputHatch1.tank; + + int batches = 16; + int parallels = 16; + busHolder.controller.setBatchEnabled(true); + busHolder.parallelHatch.setCurrentParallel(parallels); + + fluidIn.setFluidInTank(0, LCENT_OUT.copyWithAmount(batches * parallels)); + + // 1t to turn on, 64t per recipe run + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] addedRolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(65 * finalI, () -> { + int runs = finalI * batches * parallels; + helper.assertTrue(fluidIn.isEmpty(), + "Batched Parallel LCent didn't complete correct number of recipes, completed [" + + (runs - fluidIn.getFluidInTank(0).getAmount()) + "] not [" + runs + "]"); + int resultCount = fluidOut.getFluidInTank(0).getAmount(); + int lowerLimit = runs * 0; + int upperLimit = runs * 40; + helper.assertTrue(TestUtils.isCountWithinRange(resultCount, lowerLimit, upperLimit), + "Batched Parallel LCent didn't produce correct number of fluids, produced [" + + resultCount + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + addedRolls[finalI - 1] = resultCount; + + // reset for a rerun + fluidIn.setFluidInTank(0, LCENT_OUT.copyWithAmount(batches * parallels)); + }); + } + + helper.runAfterDelay(1 + 65 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + int[] rolls = new int[REPLICAS]; + + rolls[0] = addedRolls[0]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[0], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Batched Parallel LCent ranged fluid output test iteration " + 1 + " produced [" + + rolls[0] + "] fluids, a multiple of its Batch * Parallel count (" + (batches * parallels) + + "). If this message only appears once, this is likely a false positive."); + } + for (int i = 1; i < REPLICAS; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Batched Parallel LCent ranged fluid output test iteration " + (i + 1) + + " produced [" + rolls[i] + "] fluids, a multiple of its Batch * Parallel count (" + + (batches * parallels) + "). If this message only appears once, this is likely" + + " a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Batched Parallel LCent ranged fluid output test rolled exactly even to" + + " Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java new file mode 100644 index 00000000000..b79f58c22ba --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/IntProviderIngredientTest.java @@ -0,0 +1,1017 @@ +package com.gregtechceu.gtceu.api.recipe.ingredient; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.SimpleTieredMachine; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableElectricMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; +import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.common.machine.multiblock.part.FluidHatchPartMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.part.ItemBusPartMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.part.ParallelHatchPartMachine; +import com.gregtechceu.gtceu.data.recipe.GTRecipeTypes; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.neoforged.neoforge.common.crafting.SizedIngredient; + +import lombok.Getter; + +/** + * Test cases: + * do many passes of most tests as a safeguard against bad rolls + * Same output more than once + * Out of bounds + * Output a multiple of batchparallels + * Rolls of 0 + * Forced rolls of 0 breaking recipes + */ +// @PrefixGameTestTemplate(false) +// @GameTestHolder(GTCEu.MOD_ID) +// Gametests blocked until gtm#4326 is fixed +public class IntProviderIngredientTest { + + private static GTRecipeType CR_RECIPE_TYPE; + private static GTRecipeType LCR_RECIPE_TYPE; + private static GTRecipeType CENTRIFUGE_RECIPE_TYPE; + + // items used in recipes. Up top here for quick replacements. + private static final ItemStack CR_IN = new ItemStack(Items.GREEN_STAINED_GLASS); + private static final ItemStack CR_OUT = new ItemStack(Items.BRICK_SLAB); + private static final ItemStack LCR_IN = new ItemStack(Items.BLACK_STAINED_GLASS); + private static final ItemStack LCR_OUT = new ItemStack(Items.BRICK_STAIRS); + private static final ItemStack LCENT_IN = new ItemStack(Items.LIME_STAINED_GLASS); + private static final ItemStack LCENT_OUT = new ItemStack(Items.BRICK_WALL); + private static final ItemStack COBBLE = new ItemStack(Items.COBBLESTONE); + private static final ItemStack STONE = new ItemStack(Items.STONE); + + /** + * How many times to repeat the Batch and Parallel random roll tests to avoid false positives + * Currently set to 7, with singleblock recipes processing up to 9 items, allowing for stacks of up to 63 items. + */ + @Getter + private static final int REPLICAS = 7; + + @BeforeBatch(batch = "RangedIngredients") + public static void prepare(ServerLevel level) { + CR_RECIPE_TYPE = TestUtils.createRecipeType("ranged_ingredient_cr_tests", GTRecipeTypes.CHEMICAL_RECIPES); + LCR_RECIPE_TYPE = TestUtils.createRecipeType("ranged_ingredient_lcr_tests", + GTRecipeTypes.LARGE_CHEMICAL_RECIPES); + CENTRIFUGE_RECIPE_TYPE = TestUtils.createRecipeType("ranged_ingredient_centrifuge_tests", + GTRecipeTypes.CENTRIFUGE_RECIPES); + CR_RECIPE_TYPE.getLookup().addRecipe(CR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_input_item_cr")) + .inputItemsRanged(CR_IN, UniformInt.of(0, 9)) + .inputItems(COBBLE) + .outputItems(STONE) + .EUt(GTValues.V[GTValues.HV]) + .duration(2) + .build()); + + CR_RECIPE_TYPE.getLookup().addRecipe(CR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_output_item_cr")) + .inputItems(CR_OUT) + .outputItemsRanged(STONE, UniformInt.of(0, 9)) + .EUt(GTValues.V[GTValues.HV]) + .duration(2) + .build()); + + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_input_item_lcr")) + .inputItemsRanged(LCR_IN, UniformInt.of(0, 9)) + .inputItems(COBBLE) + .outputItems(STONE) + .EUt(GTValues.V[GTValues.HV]) + .duration(2) + .build()); + + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_output_item_lcr")) + .inputItems(LCR_OUT) + .outputItemsRanged(STONE, UniformInt.of(0, 9)) + .EUt(GTValues.V[GTValues.HV]) + .duration(2) + .build()); + + CENTRIFUGE_RECIPE_TYPE.getLookup().addRecipe(CENTRIFUGE_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_input_item_cent")) + .inputItemsRanged(LCENT_IN, UniformInt.of(0, 4)) + .inputItems(COBBLE) + .outputItems(STONE) + .EUt(GTValues.V[GTValues.IV]) + .duration(4) + .build()); + + CENTRIFUGE_RECIPE_TYPE.getLookup().addRecipe(CENTRIFUGE_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_ranged_output_item_cent")) + .inputItems(LCENT_OUT) + .outputItemsRanged(STONE, UniformInt.of(0, 4)) + .EUt(GTValues.V[GTValues.IV]) + .duration(4) + .build()); + } + + private static MetaMachine getMetaMachine(BlockEntity entity) { + return ((MetaMachineBlockEntity) entity).getMetaMachine(); + } + + private record BusHolder(ItemBusPartMachine inputBus1, FluidHatchPartMachine inputHatch1, + ItemBusPartMachine outputBus1, + FluidHatchPartMachine outputHatch1, WorkableMultiblockMachine controller) {} + + private record BusHolderBatchParallel(ItemBusPartMachine inputBus1, FluidHatchPartMachine inputHatch1, + ItemBusPartMachine outputBus1, + FluidHatchPartMachine outputHatch1, + WorkableElectricMultiblockMachine controller, + ParallelHatchPartMachine parallelHatch) {} + + /** + * Retrieves the busses for this LCR template and force a multiblock structure check + * + * @param helper the GameTestHelper + * @return the busses, in the BusHolder record. + */ + private static BusHolder getBussesAndFormLCR(GameTestHelper helper) { + WorkableMultiblockMachine controller = (WorkableMultiblockMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 2, 0))); + TestUtils.formMultiblock(controller); + controller.setRecipeType(LCR_RECIPE_TYPE); + ItemBusPartMachine inputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 1, 0))); + FluidHatchPartMachine inputHatch1 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 2, 0))); + ItemBusPartMachine outputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + FluidHatchPartMachine outputHatch1 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 2, 0))); + return new BusHolder(inputBus1, inputHatch1, outputBus1, outputHatch1, controller); + } + + /** + * Retrieves the busses for this Large Centrifuge template and force a multiblock structure check + * + * @param helper the GameTestHelper + * @return the busses, in the BusHolder record. + */ + private static BusHolderBatchParallel getBussesAndFormLCENT(GameTestHelper helper) { + WorkableElectricMultiblockMachine controller = (WorkableElectricMultiblockMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 2, 0))); + TestUtils.formMultiblock(controller); + controller.setRecipeType(CENTRIFUGE_RECIPE_TYPE); + ItemBusPartMachine inputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 2, 0))); + FluidHatchPartMachine inputHatch1 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 2, 0))); + ItemBusPartMachine outputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 1, 0))); + FluidHatchPartMachine outputHatch1 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 1, 0))); + ParallelHatchPartMachine parallelHatch = (ParallelHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(3, 3, 0))); + return new BusHolderBatchParallel(inputBus1, inputHatch1, outputBus1, outputHatch1, controller, parallelHatch); + } + + // test for IntProviderIngredient.test() + @GameTest(template = "empty", batch = "RangedIngredients") + public static void rangedIngredientTestEqualTest(GameTestHelper helper) { + var ingredient = IntProviderIngredient.of(new ItemStack(Items.BRICK, 1), UniformInt.of(1, 5)); + helper.assertTrue(ingredient.test(new ItemStack(Items.BRICK, 3)), + "IntProviderIngredient.test doesn't match when it should have"); + // This should work since test only tries the item type. + helper.assertTrue(ingredient.test(new ItemStack(Items.BRICK, 64)), + "IntProviderIngredient.test doesn't match when it should have with value outside bounds"); + helper.assertFalse(ingredient.test(new ItemStack(Items.COBBLESTONE, 3)), + "IntProviderIngredient.test shouldn't match with different items"); + helper.succeed(); + } + + // test for IntProviderIngredient.getStacks() + @GameTest(template = "empty", batch = "RangedIngredients") + public static void rangedIngredientGetStacksTest(GameTestHelper helper) { + var ingredient = IntProviderIngredient.of(new ItemStack(Items.BRICK, 1), UniformInt.of(1, 5000)); + var stacks = ingredient.getItems().toList(); + helper.assertTrue(stacks.size() == 1, "IntProviderIngredient should only return 1 item when made with 1 item"); + helper.assertTrue(stacks.get(0).is(new ItemStack(Items.BRICK, 1).getItem()), + "IntProviderIngredient should have item equal to what it was made with"); + helper.assertTrue(TestUtils.areItemStacksEqual(stacks, ingredient.getItems().toList()), + "IntProviderIngredient.getItems shouldn't change between getStacks calls"); + ingredient.reset(); + helper.assertFalse(TestUtils.areItemStacksEqual(stacks, ingredient.getItems().toList()), + "IntProviderIngredient.getItems should have changed after rerolling"); + helper.succeed(); + } + + // test for IntProviderIngredient.toJson() + // @GameTest(template = "empty", batch = "RangedIngredients") + // public static void rangedIngredientJsonTest(GameTestHelper helper) { + // var ingredient = IntProviderIngredient.of(new ItemStack(Items.BRICK, 1), UniformInt.of(1, 5000)); + + // // serialize/deserialize before rolling count + // var jsonPreRoll = ingredient.toJson(); + // var ingredientDeserializedPreRoll = IntProviderIngredient.fromJson(jsonPreRoll); + + // var stacks = ingredient.getItems(); + // var stacksDeserializedPreRoll = ingredientDeserializedPreRoll.getItems(); + + // // serialize/deserialize after rolling count + // var jsonPostRoll = ingredient.toJson(); + // var ingredientDeserializedPostRoll = IntProviderIngredient.fromJson(jsonPostRoll); + // var stacksDeserializedPostRoll = ingredientDeserializedPostRoll.getItems(); + + // helper.assertTrue( + // stacks.length == stacksDeserializedPreRoll.length && stacks.length == stacksDeserializedPostRoll.length, + // "IntProviderIngredient should only return 1 item when made with 1 item, even after serializing"); + // helper.assertTrue(stacksDeserializedPreRoll[0].is(new ItemStack(Items.BRICK, 1).getItem()), + // "IntProviderIngredient should have item equal to what it was made with after serializing"); + // helper.assertTrue(stacksDeserializedPostRoll[0].is(new ItemStack(Items.BRICK, 1).getItem()), + // "IntProviderIngredient should have item equal to what it was made with after serializing"); + // helper.assertFalse(TestUtils.areItemStacksEqual(stacksDeserializedPreRoll, ingredient.getItems()), + // "IntProviderIngredient.getItems should be different if it wasn't rolled before serializing"); + // helper.assertTrue(TestUtils.areItemStacksEqual(stacksDeserializedPostRoll, ingredient.getItems()), + // "IntProviderIngredient.getItems shouldn't change between getItems calls if it was rolled before serializing"); + // helper.succeed(); + // } + + // Test for singleblock machine with ranged item input. + // Forcibly sabotages the first recipe run, setting its output amount to 0 to ensure that doesn't break the recipe. + // This is specifically a test for #3593 / #3594 + @GameTest(template = "singleblock_charged_cr", batch = "RangedIngredients", required = false) + public static void singleblockRangedItemOutputSabotaged(GameTestHelper helper) { + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + + machine.setRecipeType(CR_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableItemStackHandler itemOut = machine.exportItems; + + int runs = 7; + itemIn.setStackInSlot(0, CR_OUT.copyWithCount(runs)); + // 1t to turn on, 2t per recipe run + // get the result of each roll independently + int[] addedRolls = new int[runs]; + + helper.runAfterDelay(2, () -> { + if (machine.getRecipeLogic().getLastRecipe().getOutputContents(ItemRecipeCapability.CAP).get(0) + .getContent() instanceof SizedIngredient upperingredient) { + if (upperingredient.ingredient().getCustomIngredient() instanceof IntProviderIngredient ingredient) { + ingredient.setSampledCount(0); + + if (ingredient.getSampledCount() != 0) { + helper.fail("Singleblock Ranged Item Output sabotage failed! " + + "Output count not was altered!"); + } + } else { + helper.fail("Singleblock Ranged Item Output sabotage failed! " + + "Recipe logic did not contain a Ranged Output!"); + } + } else { + helper.fail("Singleblock Ranged Item Output sabotage failed! " + + "Recipe logic did not contain a Output!"); + } + }); + for (int i = 0; i < runs; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(2 * i + 3, () -> { + addedRolls[finalI] = itemOut.getStackInSlot(0).getCount(); + }); + } + // check the results of all rolls together + helper.runAfterDelay(runs * 2 + 1, () -> { + ItemStack results = itemOut.getStackInSlot(0); + helper.assertFalse((results.getCount() == runs * 0), + "Sabotaged Singleblock Ranged Item Output rolled min value on every roll! " + + "This is the failure this sabotage was intended to induce."); + helper.assertFalse((results.getCount() == runs * 9), + "Sabotaged Singleblock CR rolled max value on every roll (how??)"); + + helper.assertTrue(TestUtils.isItemWithinRange(results, runs, runs * 9), + "Sabotaged Singleblock CR didn't produce correct number of items, produced [" + + results.getCount() + "] not [" + runs + "-" + (runs * 9) + "]"); + + // check if all the rolls were equal, but not min/max + int[] rolls = new int[runs]; + rolls[0] = addedRolls[0]; + boolean allEqual = false; + for (int i = 1; i < runs; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (rolls[i] == rolls[i - 1]) { + allEqual = true; + } else { + allEqual = false; + break; + } + } + helper.assertFalse(allEqual, + "Sabotaged Singleblock CR rolled the same value on every input roll (rolled " + rolls[0] + ")"); + helper.succeed(); + }); + } + + // Failure Test for singleblock machine with ranged item input + // Provides too few input items, should not run recipes. + @GameTest(template = "singleblock_charged_cr", batch = "RangedIngredients") + public static void singleblockRangedItemInputFailure(GameTestHelper helper) { + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + + machine.setRecipeType(CR_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableItemStackHandler itemOut = machine.exportItems; + + int runs = 10; + itemIn.setStackInSlot(0, CR_IN.copyWithCount(8)); + itemIn.setStackInSlot(1, COBBLE.copyWithCount(runs)); + // 1t to turn on, 2t per non- recipe run + helper.runAfterDelay(runs * 2 + 1, () -> { + ItemStack results = itemIn.getStackInSlot(0); + + helper.assertTrue(itemOut.isEmpty(), + "Singleblock CR should not have run, ran [" + + itemOut.getStackInSlot(0).getCount() + "] times"); + helper.assertTrue(TestUtils.isItemStackEqual(results, CR_IN.copyWithCount(8)), + "Singleblock CR should not have consumed items, consumed [" + + (8 - results.getCount()) + "]"); + + helper.succeed(); + }); + } + + // Test for singleblock machine with ranged item input + @GameTest(template = "singleblock_charged_cr", batch = "RangedIngredients") + public static void singleblockRangedItemInput(GameTestHelper helper) { + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + + machine.setRecipeType(CR_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableItemStackHandler itemOut = machine.exportItems; + + int runs = 7; + itemIn.setStackInSlot(0, CR_IN.copyWithCount(64)); + itemIn.setStackInSlot(1, COBBLE.copyWithCount(runs)); + // 1t to turn on, 2t per recipe run + // get the result of each roll independently + int[] addedRolls = new int[runs]; + for (int i = 0; i < runs; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(2 * i + 1, () -> { + addedRolls[finalI] = itemIn.getStackInSlot(0).getCount(); + }); + } + // check the results of all rolls together + helper.runAfterDelay(runs * 2 + 1, () -> { + ItemStack results = itemIn.getStackInSlot(0); + int upperLimit = 64 - (runs * 0); + int lowerLimit = 64 - (runs * 9); + helper.assertTrue(TestUtils.isItemStackEqual(itemOut.getStackInSlot(0), STONE.copyWithCount(runs)), + "Singleblock CR didn't complete correct number of recipes, completed [" + + itemOut.getStackInSlot(0).getCount() + "] not [" + runs + "]"); + helper.assertTrue(TestUtils.isItemWithinRange(results, lowerLimit, upperLimit), + "Singleblock CR didn't consume correct number of items, consumed [" + + (64 - results.getCount()) + "] not [" + lowerLimit + "-" + upperLimit + "]"); + helper.assertFalse((results.getCount() == lowerLimit), + "Singleblock CR rolled max value on every roll"); + helper.assertFalse((results.getCount() == upperLimit), + "Singleblock CR rolled min value on every roll"); + + // check if all the rolls were equal, but not min/max + int[] rolls = new int[runs]; + rolls[0] = 64 - addedRolls[0]; + boolean allEqual = false; + for (int i = 1; i < runs; i++) { + rolls[i] = addedRolls[i - 1] - addedRolls[i]; + if (rolls[i] == rolls[i - 1]) { + allEqual = true; + } else { + allEqual = false; + break; + } + } + helper.assertFalse(allEqual, + "Singleblock CR rolled the same value on every input roll (rolled " + rolls[0] + ")"); + helper.succeed(); + }); + } + + // Test for singleblock machine with ranged item output + @GameTest(template = "singleblock_charged_cr", batch = "RangedIngredients") + public static void singleblockRangedItemOutput(GameTestHelper helper) { + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + + machine.setRecipeType(CR_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableItemStackHandler itemOut = machine.exportItems; + + int runs = 7; + itemIn.setStackInSlot(0, CR_OUT.copyWithCount(runs)); + // 1t to turn on, 2t per recipe run + // get the result of each roll independently + int[] addedRolls = new int[runs]; + for (int i = 0; i < runs; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(2 * i + 3, () -> { + addedRolls[finalI] = itemOut.getStackInSlot(0).getCount(); + }); + } + // check the results of all rolls together + helper.runAfterDelay(runs * 2 + 1, () -> { + helper.assertTrue(itemIn.getStackInSlot(0).isEmpty(), + "Singleblock CR didn't complete correct number of recipes, completed [" + + itemIn.getStackInSlot(0).getCount() + "] not [" + runs + "]"); + ItemStack results = itemOut.getStackInSlot(0); + helper.assertTrue(TestUtils.isItemWithinRange(results, runs, runs * 9), + "Singleblock CR didn't produce correct number of items, produced [" + + results.getCount() + "] not [" + runs + "-" + (runs * 9) + "]"); + helper.assertFalse((results.getCount() == runs * 9), + "Singleblock CR rolled max value on every roll"); + helper.assertFalse((results.getCount() == runs * 0), + "Singleblock CR rolled min value on every roll"); + + // check if all the rolls were equal, but not min/max + int[] rolls = new int[runs]; + rolls[0] = addedRolls[0]; + boolean allEqual = false; + for (int i = 1; i < runs; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (rolls[i] == rolls[i - 1]) { + allEqual = true; + } else { + allEqual = false; + break; + } + } + helper.assertFalse(allEqual, + "Singleblock CR rolled the same value on every input roll (rolled " + rolls[0] + ")"); + helper.succeed(); + }); + } + + // test for multiblock machine with ranged item input + @GameTest(template = "lcr_ranged_ingredients", batch = "RangedIngredients") + public static void multiblockLCRRangedItemInput(GameTestHelper helper) { + BusHolder busHolder = getBussesAndFormLCR(helper); + + NotifiableItemStackHandler itemIn = busHolder.inputBus1.getInventory(); + NotifiableItemStackHandler itemOut = busHolder.outputBus1.getInventory(); + + int runs = 7; + itemIn.setStackInSlot(0, LCR_IN.copyWithCount(64)); + itemIn.setStackInSlot(1, COBBLE.copyWithCount(runs)); + // 1t to turn on, 2t per recipe run + // get the result of each roll independently + int[] addedRolls = new int[runs]; + for (int i = 0; i < runs; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(2 * i + 1, () -> { + addedRolls[finalI] = itemIn.getStackInSlot(0).getCount(); + }); + } + // check the results of all rolls together + helper.runAfterDelay(runs * 2 + 1, () -> { + ItemStack results = itemIn.getStackInSlot(0); + int upperLimit = 64 - (runs * 0); + int lowerLimit = 64 - (runs * 9); + helper.assertTrue(TestUtils.isItemStackEqual(itemOut.getStackInSlot(0), STONE.copyWithCount(runs)), + "LCR didn't complete correct number of recipes, completed [" + + itemOut.getStackInSlot(0).getCount() + "] not [" + runs + "]"); + helper.assertTrue(TestUtils.isItemWithinRange(results, lowerLimit, upperLimit), + "LCR didn't consume correct number of items, consumed [" + + (64 - results.getCount()) + "] not [" + lowerLimit + "-" + upperLimit + "]"); + helper.assertFalse((results.getCount() == lowerLimit), + "LCR rolled max value on every roll"); + helper.assertFalse((results.getCount() == upperLimit), + "LCR rolled min value on every roll"); + + // check if all the rolls were equal, but not min/max + int[] rolls = new int[runs]; + rolls[0] = 64 - addedRolls[0]; + boolean allEqual = false; + for (int i = 1; i < runs; i++) { + rolls[i] = addedRolls[i - 1] - addedRolls[i]; + if (rolls[i] == rolls[i - 1]) { + allEqual = true; + } else { + allEqual = false; + break; + } + } + helper.assertFalse(allEqual, + "LCR rolled the same value on every input roll (rolled " + rolls[0] + ")"); + helper.succeed(); + }); + } + + // test for multiblock machine with ranged item input + @GameTest(template = "lcr_ranged_ingredients", batch = "RangedIngredients") + public static void multiblockLCRRangedItemOutput(GameTestHelper helper) { + BusHolder busHolder = getBussesAndFormLCR(helper); + + NotifiableItemStackHandler itemIn = busHolder.inputBus1.getInventory(); + NotifiableItemStackHandler itemOut = busHolder.outputBus1.getInventory(); + + int runs = 7; + itemIn.setStackInSlot(0, LCR_OUT.copyWithCount(runs)); + // 1t to turn on, 2t per recipe run + // get the result of each roll independently + int[] addedRolls = new int[runs]; + for (int i = 0; i < runs; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(2 * i + 3, () -> { + addedRolls[finalI] = itemOut.getStackInSlot(0).getCount(); + }); + } + // check the results of all rolls together + helper.runAfterDelay(runs * 2 + 1, () -> { + helper.assertTrue(itemIn.getStackInSlot(0).isEmpty(), + "LCR didn't complete correct number of recipes, completed [" + + itemIn.getStackInSlot(0).getCount() + "] not [" + runs + "]"); + ItemStack results = itemOut.getStackInSlot(0); + helper.assertTrue(TestUtils.isItemWithinRange(results, runs, runs * 9), + "LCR didn't produce correct number of items, produced [" + + results.getCount() + "] not [" + runs + "-" + (runs * 9) + "]"); + helper.assertFalse((results.getCount() == runs * 9), + "LCR rolled max value on every roll"); + helper.assertFalse((results.getCount() == runs * 0), + "LCR rolled min value on every roll"); + + // check if all the rolls were equal, but not min/max + int[] rolls = new int[runs]; + rolls[0] = addedRolls[0]; + boolean allEqual = false; + for (int i = 1; i < runs; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (rolls[i] == rolls[i - 1]) { + allEqual = true; + } else { + allEqual = false; + break; + } + } + helper.assertFalse(allEqual, + "LCR rolled the same value on every input roll (rolled " + rolls[0] + ")"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged item input + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedIngredients", + timeoutTicks = 200) + public static void multiblockLCentRangedItemInput16Parallel(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + NotifiableItemStackHandler itemIn = busHolder.inputBus1.getInventory(); + NotifiableItemStackHandler itemOut = busHolder.outputBus1.getInventory(); + + int batches = 1; // unused on this test + int parallels = 16; + busHolder.controller.setBatchEnabled(false); + busHolder.parallelHatch.setCurrentParallel(parallels); + + itemIn.setStackInSlot(0, LCENT_IN.copyWithCount(64)); + itemIn.setStackInSlot(1, COBBLE.copyWithCount(parallels)); + + // 1t to turn on, 4t per recipe run + // 16 parallels + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] rolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(17 * finalI, () -> { + ItemStack results = itemIn.getStackInSlot(0); + int upperLimit = 64 - (batches * parallels * 0); + int lowerLimit = 64 - (batches * parallels * 4); + int completed = batches * parallels * finalI; + helper.assertTrue( + TestUtils.isItemStackEqual(itemOut.getStackInSlot(0) + .copyWithCount((int) Math.round(itemOut.getTotalContentAmount())), + STONE.copyWithCount(completed)), + "Parallel LCent didn't complete correct number of recipes, completed [" + + ((int) Math.round(itemOut.getTotalContentAmount())) + "] not [" + + completed + "]"); + helper.assertTrue(TestUtils.isItemWithinRange(results, lowerLimit, upperLimit), + "Parallel LCent didn't consume correct number of items, consumed " + + (64 - results.getCount()) + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + rolls[finalI - 1] = 64 - results.getCount(); + + // reset for a rerun + itemIn.setStackInSlot(0, LCENT_IN.copyWithCount(64)); + itemIn.setStackInSlot(1, COBBLE.copyWithCount(parallels)); + }); + } + + helper.runAfterDelay(1 + 17 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + for (int i = 0; i < REPLICAS; i++) { + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Parallel LCent ranged item input test iteration " + i + " consumed [" + + rolls[i] + "] items, a multiple of its Batch * Parallel count (" + (parallels) + + "). If this message only appears once, this is likely a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Parallel LCent ranged item input test rolled exactly even to " + + "Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged item output + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedIngredients", + timeoutTicks = 200) + public static void multiblockLCentRangedItemOutput16Parallel(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + NotifiableItemStackHandler itemIn = busHolder.inputBus1.getInventory(); + NotifiableItemStackHandler itemOut = busHolder.outputBus1.getInventory(); + + int batches = 1; // unused on this test + int parallels = 16; + itemIn.setStackInSlot(0, LCENT_OUT.copyWithCount(16)); + + busHolder.controller.setBatchEnabled(false); + busHolder.parallelHatch.setCurrentParallel(parallels); + + // 1t to turn on, 1t per recipe run + // 16 parallels + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] addedRolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(17 * finalI, () -> { + int runs = finalI * batches * parallels; + helper.assertTrue(itemIn.getStackInSlot(0).isEmpty(), + "Parallel LCent didn't complete correct number of recipes, completed [" + + itemIn.getStackInSlot(0).getCount() + "] not [" + runs + "]"); + int resultCount = (int) Math.round(itemOut.getTotalContentAmount()); + int lowerLimit = runs * 0; + int upperLimit = runs * 4; + helper.assertTrue(TestUtils.isCountWithinRange(resultCount, lowerLimit, upperLimit), + "Parallel LCent didn't produce correct number of items, produced [" + + resultCount + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + addedRolls[finalI - 1] = resultCount; + + // reset for a rerun + itemIn.setStackInSlot(0, LCENT_OUT.copyWithCount(16)); + }); + } + + helper.runAfterDelay(1 + 17 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + int[] rolls = new int[REPLICAS]; + + rolls[0] = addedRolls[0]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[0], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Parallel LCent ranged item output test iteration " + 1 + " produced [" + + rolls[0] + "] items, a multiple of its Batch * Parallel count (" + (batches * parallels) + + "). If this message only appears once, this is likely a false positive."); + } + for (int i = 1; i < REPLICAS; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Parallel LCent ranged item output test iteration " + (i + 1) + " produced [" + + rolls[i] + "] items, a multiple of its Batch * Parallel count (" + (batches * parallels) + + "). If this message only appears once, this is likely a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Parallel LCent ranged item output test rolled exactly even to " + + "Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged item input + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedIngredients", + timeoutTicks = 200) + public static void multiblockLCentRangedItemInputBatched(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + NotifiableItemStackHandler itemIn = busHolder.inputBus1.getInventory(); + NotifiableItemStackHandler itemOut = busHolder.outputBus1.getInventory(); + + int batches = 16; + int parallels = 1; // unused on this test + busHolder.controller.setBatchEnabled(true); + busHolder.parallelHatch.setCurrentParallel(parallels); + + itemIn.setStackInSlot(0, LCENT_IN.copyWithCount(64)); + itemIn.setStackInSlot(1, COBBLE.copyWithCount(batches)); + + // 1t to turn on, 1t per recipe run + // 16 batches + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] rolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(17 * finalI, () -> { + ItemStack results = itemIn.getStackInSlot(0); + int upperLimit = 64 - (batches * parallels * 0); + int lowerLimit = 64 - (batches * parallels * 4); + int completed = batches * parallels * finalI; + helper.assertTrue( + TestUtils.isItemStackEqual(itemOut.getStackInSlot(0) + .copyWithCount((int) Math.round(itemOut.getTotalContentAmount())), + STONE.copyWithCount(completed)), + "Parallel LCent didn't complete correct number of recipes, completed [" + + ((int) Math.round(itemOut.getTotalContentAmount())) + "] not [" + + completed + "]"); + helper.assertTrue(TestUtils.isItemWithinRange(results, lowerLimit, upperLimit), + "Parallel LCent didn't consume correct number of items, consumed " + + (64 - results.getCount()) + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + rolls[finalI - 1] = 64 - results.getCount(); + + // reset for a rerun + itemIn.setStackInSlot(0, LCENT_IN.copyWithCount(64)); + itemIn.setStackInSlot(1, COBBLE.copyWithCount(batches)); + }); + } + + helper.runAfterDelay(1 + 17 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + for (int i = 0; i < REPLICAS; i++) { + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Parallel LCent ranged item input test iteration " + i + " consumed [" + + rolls[i] + "] items, a multiple of its Batch * Parallel count (" + (batches * parallels) + + "). If this message only appears once, this is likely a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Parallel LCent ranged item input test rolled exactly even to " + + "Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged item output + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedIngredients", + timeoutTicks = 200) + public static void multiblockLCentRangedItemOutputBatched(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + NotifiableItemStackHandler itemIn = busHolder.inputBus1.getInventory(); + NotifiableItemStackHandler itemOut = busHolder.outputBus1.getInventory(); + + int batches = 16; + int parallels = 1; // unused on this test + itemIn.setStackInSlot(0, LCENT_OUT.copyWithCount(16)); + + busHolder.controller.setBatchEnabled(true); + busHolder.parallelHatch.setCurrentParallel(parallels); + + // 1t to turn on, 1t per recipe run + // 16 parallels + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] addedRolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(17 * finalI, () -> { + int runs = finalI * batches * parallels; + helper.assertTrue(itemIn.getStackInSlot(0).isEmpty(), + "Batched LCent didn't complete correct number of recipes, completed [" + + itemIn.getStackInSlot(0).getCount() + "] not [" + runs + "]"); + int resultCount = (int) Math.round(itemOut.getTotalContentAmount()); + int lowerLimit = runs * 0; + int upperLimit = runs * 4; + helper.assertTrue(TestUtils.isCountWithinRange(resultCount, lowerLimit, upperLimit), + "Batched LCent didn't produce correct number of items, produced [" + + resultCount + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + addedRolls[finalI - 1] = resultCount; + + // reset for a rerun + itemIn.setStackInSlot(0, LCENT_OUT.copyWithCount(16)); + }); + } + + helper.runAfterDelay(1 + 17 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + int[] rolls = new int[REPLICAS]; + + rolls[0] = addedRolls[0]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[0], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Batched LCent ranged item output test iteration " + 1 + " produced [" + + rolls[0] + "] items, a multiple of its Batch * Parallel count (" + batches + + "). If this message only appears once, this is likely a false positive."); + } + for (int i = 1; i < REPLICAS; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Batched LCent ranged item output test iteration " + (i + 1) + " produced [" + + rolls[i] + "] items, a multiple of its Batch * Parallel count (" + batches + + "). If this message only appears once, this is likely a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Batched LCent ranged item output test rolled exactly even to " + + "Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged item input + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedIngredients", + timeoutTicks = 500) + public static void multiblockLCentRangedItemInput16ParallelBatched(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + NotifiableItemStackHandler itemIn = busHolder.inputBus1.getInventory(); + NotifiableItemStackHandler itemOut = busHolder.outputBus1.getInventory(); + + int batches = 16; + int parallels = 16; + busHolder.controller.setBatchEnabled(true); + busHolder.parallelHatch.setCurrentParallel(parallels); + + int j; + int stacks = batches * parallels / 64; + + for (j = 0; j < stacks; j++) { + itemIn.setStackInSlot(j, COBBLE.copyWithCount((batches * parallels / stacks))); + } + for (int k = j; k < stacks + batches; k++) { + itemIn.setStackInSlot(k, LCENT_IN.copyWithCount(64)); + } + + // 1t to turn on, 1t per recipe run + // 16 parallels + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] rolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(65 * finalI, () -> { + ItemStack results = itemIn.getStackInSlot(0); + int upperLimit = 64 - (batches * parallels * 0); + int lowerLimit = 64 - (batches * parallels * 4); + int completed = batches * parallels * finalI; + helper.assertTrue(TestUtils.isItemStackEqual(itemOut.getStackInSlot(0) + .copyWithCount((int) Math.round(itemOut.getTotalContentAmount())), + STONE.copyWithCount(completed)), + "Batched Parallel LCent didn't complete correct number of recipes, completed [" + + Math.round(itemOut.getTotalContentAmount()) + "] not [" + + completed + "]"); + helper.assertTrue(TestUtils.isItemWithinRange(results, lowerLimit, upperLimit), + "Batched Parallel LCent didn't consume correct number of items, consumed " + + (64 - results.getCount()) + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + rolls[finalI - 1] = 64 - results.getCount(); + + // reset for a rerun + int l; + for (l = 0; l < stacks; l++) { + itemIn.setStackInSlot(l, + COBBLE.copyWithCount((batches * parallels / stacks))); + } + for (int k = l; k < stacks + batches; k++) { + itemIn.setStackInSlot(k, LCENT_IN.copyWithCount(64)); + } + }); + } + + helper.runAfterDelay(1 + 65 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + for (int i = 0; i < REPLICAS; i++) { + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Batched Parallel LCent ranged item input test iteration " + i + " consumed [" + + rolls[i] + "] items, a multiple of its Batch * Parallel count (" + (batches * parallels) + + "). If this message only appears once, this is likely a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Batched Parallel LCent ranged item input test rolled exactly even to" + + " Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } + + // test for multiblock machine with 16x Parallels with ranged item output + @GameTest(template = "large_centrifuge_zpm_batch_parallel16", + batch = "RangedIngredients", + timeoutTicks = 500) + public static void multiblockLCentRangedItemOutput16ParallelBatched(GameTestHelper helper) { + BusHolderBatchParallel busHolder = getBussesAndFormLCENT(helper); + + NotifiableItemStackHandler itemIn = busHolder.inputBus1.getInventory(); + NotifiableItemStackHandler itemOut = busHolder.outputBus1.getInventory(); + + int batches = 16; + int parallels = 16; + busHolder.controller.setBatchEnabled(true); + busHolder.parallelHatch.setCurrentParallel(parallels); + + for (int j = 0; j < batches; j++) { + itemIn.setStackInSlot(j, LCENT_OUT.copyWithCount(16)); + } + + // 1t to turn on, 1t per recipe run + // 16 parallels + // check the results of all rolls together + // repeat recipe REPLICAS times + int[] addedRolls = new int[REPLICAS]; + for (int i = 1; i <= REPLICAS; i++) { + final int finalI = i; // lambda preserve you + helper.runAfterDelay(65 * finalI, () -> { + int runs = finalI * batches * parallels; + helper.assertTrue(itemIn.isEmpty(), + "Batched Parallel LCent didn't complete correct number of recipes, completed [" + + Math.round(runs - itemIn.getTotalContentAmount()) + "] not [" + runs + "]"); + int resultCount = (int) Math.round(itemOut.getTotalContentAmount()); + int lowerLimit = runs * 0; + int upperLimit = runs * 4; + helper.assertTrue(TestUtils.isCountWithinRange(resultCount, lowerLimit, upperLimit), + "Batched Parallel LCent didn't produce correct number of items, produced [" + + resultCount + "] not [" + lowerLimit + "-" + upperLimit + "]"); + + addedRolls[finalI - 1] = resultCount; + + // reset for a rerun + for (int j = 0; j < batches; j++) { + itemIn.setStackInSlot(j, LCENT_OUT.copyWithCount(16)); + } + }); + } + + helper.runAfterDelay(1 + 65 * REPLICAS, () -> { + // check if each roll was a multiple of run count + boolean sus = false; + int[] rolls = new int[REPLICAS]; + + rolls[0] = addedRolls[0]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[0], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Batched Parallel LCent ranged item output test iteration " + 1 + " produced [" + + rolls[0] + "] items, a multiple of its Batch * Parallel count (" + (batches * parallels) + + "). If this message only appears once, this is likely a false positive."); + } + for (int i = 1; i < REPLICAS; i++) { + rolls[i] = addedRolls[i] - addedRolls[i - 1]; + if (TestUtils.isStackSizeExactlyEvenMultiple(rolls[i], batches, parallels, 1)) { + sus = true; + GTCEu.LOGGER.warn("Batched Parallel LCent ranged item output test iteration " + (i + 1) + + " produced [" + rolls[i] + "] items, a multiple of its Batch * Parallel count (" + + (batches * parallels) + "). If this message only appears once, this is likely" + + " a false positive."); + } else { + sus = false; + break; + } + } + + helper.assertFalse(sus, "Batched Parallel LCent ranged item output test rolled exactly even to" + + " Batch * Parallel count on every iteration"); + helper.succeed(); + }); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/NBTPredicateTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/NBTPredicateTest.java new file mode 100644 index 00000000000..478d0ddf3d4 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/ingredient/NBTPredicateTest.java @@ -0,0 +1,358 @@ +// package com.gregtechceu.gtceu.api.recipe.ingredient; + +// import com.gregtechceu.gtceu.GTCEu; +// import com.gregtechceu.gtceu.api.GTValues; +// import com.gregtechceu.gtceu.api.capability.recipe.IO; +// import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; +// import com.gregtechceu.gtceu.api.machine.SimpleTieredMachine; +// import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; +// import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +// import com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate.NBTPredicate; +// import com.gregtechceu.gtceu.gametest.util.TestUtils; + +// import net.minecraft.core.BlockPos; +// import net.minecraft.gametest.framework.BeforeBatch; +// import net.minecraft.gametest.framework.GameTest; +// import net.minecraft.gametest.framework.GameTestHelper; +// import net.minecraft.nbt.CompoundTag; +// import net.minecraft.server.level.ServerLevel; +// import net.minecraft.util.valueproviders.UniformInt; +// import net.minecraft.world.item.ItemStack; +// import net.minecraft.world.item.Items; +// import net.minecraftforge.gametest.GameTestHolder; +// import net.minecraftforge.gametest.PrefixGameTestTemplate; + +// import static com.gregtechceu.gtceu.api.recipe.ingredient.nbtpredicate.NBTPredicates.*; +// import static com.gregtechceu.gtceu.common.data.GTRecipeTypes.CHEMICAL_RECIPES; +// import static com.gregtechceu.gtceu.gametest.util.TestUtils.getMetaMachine; + +// @PrefixGameTestTemplate(false) +// @GameTestHolder(GTCEu.MOD_ID) +// public class NBTPredicateTest { + +// private static GTRecipeType CR_RECIPE_TYPE; + +// @BeforeBatch(batch = "NBTPredicateTest") +// public static void prepare(ServerLevel level) { +// CR_RECIPE_TYPE = TestUtils.createRecipeType("nbt_predicate_ingredient_cr_tests", CHEMICAL_RECIPES); +// CR_RECIPE_TYPE.getLookup().addRecipe( +// CR_RECIPE_TYPE.recipeBuilder("nbt_predicate_test") +// .inputItemNbtPredicate(new ItemStack(Items.FEATHER), eq("foo", "bar")) +// .outputItems(new ItemStack(Items.COAL)) +// .EUt(GTValues.V[GTValues.HV]) +// .duration(5) +// .buildRawRecipe()); + +// CR_RECIPE_TYPE.getLookup().addRecipe( +// CR_RECIPE_TYPE.recipeBuilder("nbt_predicate_test_chanced") +// .chance(4000) +// .inputItemNbtPredicate(new ItemStack(Items.FEATHER), eq("bin", "bar")) +// .chance(10000) +// .outputItems(new ItemStack(Items.CHARCOAL)) +// .EUt(GTValues.V[GTValues.HV]) +// .duration(4) +// .buildRawRecipe()); + +// CR_RECIPE_TYPE.getLookup().addRecipe( +// CR_RECIPE_TYPE.recipeBuilder("nbt_predicate_test_ranged") +// .inputItemRanged(new IntProviderIngredient(new NBTPredicateIngredient( +// new ItemStack(Items.FEATHER), eq("bash", "bar")), UniformInt.of(0, 4))) +// .outputItems(new ItemStack(Items.COBBLESTONE)) +// .EUt(GTValues.V[GTValues.HV]) +// .duration(4) +// .buildRawRecipe()); + +// CR_RECIPE_TYPE.getLookup().addRecipe( +// CR_RECIPE_TYPE.recipeBuilder("nbt_predicate_test_chanced_ranged") +// .chance(4000) +// .inputItemRanged(new IntProviderIngredient(new NBTPredicateIngredient( +// new ItemStack(Items.FEATHER), eq("bash", "botch")), UniformInt.of(0, 4))) +// .chance(10000) +// .outputItems(new ItemStack(Items.DEEPSLATE)) +// .EUt(GTValues.V[GTValues.HV]) +// .duration(4) +// .buildRawRecipe()); +// } + +// @GameTest(template = "empty", batch = "NBTPredicateTest") +// public static void NBTPredicateEqualsTest(GameTestHelper helper) { +// CompoundTag tag = new CompoundTag(); +// tag.putString("foo", "bar"); +// helper.assertTrue(eq("foo", "bar").test(tag), "String equality NBTPredicate failed when it shouldn't have"); +// helper.assertFalse(eq("foo", "baz").test(tag), "String equality NBTPredicate succeeded when it shouldn't have"); +// helper.assertFalse(eq("foo", 1).test(tag), "String equality NBTPredicate succeeded when it shouldn't have"); +// helper.assertFalse(eq("foo", new CompoundTag()).test(tag), +// "String equality NBTPredicate succeeded when it shouldn't have"); + +// helper.assertFalse(neq("foo", "bar").test(tag), +// "String inequality NBTPredicate succeeded when it shouldn't have"); +// helper.assertTrue(neq("foo", "baz").test(tag), "String inequality NBTPredicate failed when it shouldn't have"); +// helper.assertTrue(neq("foo", 1).test(tag), "String inequality NBTPredicate failed when it shouldn't have"); +// helper.assertTrue(neq("foo", new CompoundTag()).test(tag), +// "String inequality NBTPredicate failed when it shouldn't have"); + +// CompoundTag numberTag = new CompoundTag(); +// numberTag.putFloat("foo", 7f); +// helper.assertTrue(eqDouble("foo", 7d).test(numberTag), +// "Double equality failed when it shouldn't have (number conversion)"); +// helper.assertTrue(eqInt("foo", 7).test(numberTag), +// "Int equality failed when it shouldn't have (number conversion)"); +// helper.assertTrue(eqFloat("foo", 7).test(numberTag), +// "Float equality failed when it shouldn't have (number conversion)"); +// helper.assertTrue(eqByte("foo", (byte) 7).test(numberTag), +// "Float equality failed when it shouldn't have (number conversion)"); +// helper.succeed(); +// } + +// @GameTest(template = "empty", batch = "NBTPredicateTest") +// public static void NBTPredicateComparisonTest(GameTestHelper helper) { +// CompoundTag tag = new CompoundTag(); +// tag.putDouble("num", 10); + +// helper.assertTrue(gt("num", 5).test(tag), +// "Greater-than NBTPredicate failed when it shouldn't have"); +// helper.assertFalse(gt("num", 10).test(tag), +// "Greater-than NBTPredicate succeeded when it shouldn't have"); +// helper.assertFalse(gt("num", 11).test(tag), +// "Greater-than NBTPredicate succeeded when it shouldn't have"); + +// helper.assertTrue(gte("num", 5).test(tag), +// "Greater-or-equal NBTPredicate failed when it shouldn't have"); +// helper.assertTrue(gte("num", 10).test(tag), +// "Greater-or-equal NBTPredicate failed when it shouldn't have"); +// helper.assertFalse(gte("num", 11).test(tag), +// "Greater-or-equal NBTPredicate succeeded when it shouldn't have"); + +// helper.assertTrue(lt("num", 15).test(tag), +// "Less-than NBTPredicate failed when it shouldn't have"); +// helper.assertFalse(lt("num", 10).test(tag), +// "Less-than NBTPredicate succeeded when it shouldn't have"); +// helper.assertFalse(lt("num", 9).test(tag), +// "Less-than NBTPredicate succeeded when it shouldn't have"); + +// helper.assertTrue(lte("num", 15).test(tag), +// "Less-or-equal NBTPredicate failed when it shouldn't have"); +// helper.assertTrue(lte("num", 10).test(tag), +// "Less-or-equal NBTPredicate failed when it shouldn't have"); +// helper.assertFalse(lte("num", 9).test(tag), +// "Less-or-equal NBTPredicate succeeded when it shouldn't have"); + +// helper.succeed(); +// } + +// @GameTest(template = "empty", batch = "NBTPredicateTest") +// public static void NBTPredicateAnyTest(GameTestHelper helper) { +// CompoundTag tag = new CompoundTag(); +// tag.putInt("a", 5); +// tag.putInt("b", 10); + +// NBTPredicate predicate = any( +// eq("a", 7), +// eq("b", 10), +// eq("c", 99)); + +// helper.assertTrue(predicate.test(tag), +// "AnyNBTPredicate failed when one child was true"); + +// NBTPredicate predicateFail = any( +// eq("a", 1), +// eq("b", 2)); + +// helper.assertFalse(predicateFail.test(tag), +// "AnyNBTPredicate succeeded though all children were false"); + +// helper.succeed(); +// } + +// @GameTest(template = "empty", batch = "NBTPredicateTest") +// public static void NBTPredicateAllTest(GameTestHelper helper) { +// CompoundTag tag = new CompoundTag(); +// tag.putInt("x", 3); +// tag.putInt("y", 9); + +// NBTPredicate predicate = all( +// lt("x", 5), +// gt("y", 5)); + +// helper.assertTrue(predicate.test(tag), +// "AllNBTPredicate failed when all children were true"); + +// NBTPredicate predicateFail = all( +// lt("x", 1), +// gt("y", 5)); + +// helper.assertFalse(predicateFail.test(tag), +// "AllNBTPredicate succeeded though one child was false"); + +// helper.succeed(); +// } + +// @GameTest(template = "empty", batch = "NBTPredicateTest") +// public static void NBTPredicateNotTest(GameTestHelper helper) { +// CompoundTag tag = new CompoundTag(); +// tag.putBoolean("enabled", true); + +// NBTPredicate base = eq("enabled", true); +// NBTPredicate inverse = not(base); + +// helper.assertTrue(base.test(tag), +// "Base NBTPredicate should return true for enabled=true"); +// helper.assertFalse(inverse.test(tag), +// "NotNBTPredicate did not invert result correctly"); + +// helper.succeed(); +// } + +// @GameTest(template = "empty", batch = "NBTPredicateTest") +// public static void NBTPredicateEmptyTest(GameTestHelper helper) { +// CompoundTag tag = new CompoundTag(); + +// helper.assertFalse(eq("foo", "bar").test(tag), "String equality NBTPredicate succeeded with empty tag"); +// helper.assertFalse(eq("foo", "baz").test(tag), "String equality NBTPredicate succeeded with empty tag"); +// helper.assertFalse(eq("foo", 1).test(tag), "String equality NBTPredicate succeeded with empty tag"); +// helper.assertFalse(eq("foo", new CompoundTag()).test(tag), +// "String equality NBTPredicate succeeded with empty tag"); + +// helper.assertFalse(neq("foo", "bar").test(tag), "String inequality NBTPredicate succeeded with empty tag"); +// helper.assertFalse(neq("foo", "baz").test(tag), "String inequality NBTPredicate succeeded with empty tag"); +// helper.assertFalse(neq("foo", 1).test(tag), "String inequality NBTPredicate succeeded with empty tag"); +// helper.assertFalse(neq("foo", new CompoundTag()).test(tag), +// "String inequality NBTPredicate succeeded with empty tag"); + +// helper.assertFalse(gt("num", 5).test(tag), +// "Greater-than NBTPredicate succeeded with empty tag"); +// helper.assertFalse(gte("num", 5).test(tag), +// "Greater-or-equal NBTPredicate succeeded with empty tag"); +// helper.assertFalse(lt("num", 15).test(tag), +// "Less-than NBTPredicate succeeded with empty tag"); +// helper.assertFalse(lte("num", 9).test(tag), +// "Less-or-equal NBTPredicate succeeded with empty tag"); +// helper.succeed(); +// } + +// @GameTest(template = "singleblock_chem_reactor", batch = "NBTPredicateTest") +// public static void NBTPredicateMachineCRTestSucceeds(GameTestHelper helper) { +// SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( +// helper.getBlockEntity(new BlockPos(0, 1, 0))); + +// machine.setRecipeType(CR_RECIPE_TYPE); +// NotifiableItemStackHandler itemIn = (NotifiableItemStackHandler) machine +// .getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).get(0); +// NotifiableItemStackHandler itemOut = (NotifiableItemStackHandler) machine +// .getCapabilitiesFlat(IO.OUT, ItemRecipeCapability.CAP).get(0); + +// var inputStack = new ItemStack(Items.FEATHER); +// inputStack.getOrCreateTag().putString("foo", "bar"); +// itemIn.setStackInSlot(0, inputStack); +// helper.runAfterDelay(10, () -> { +// helper.assertTrue(ItemStack.isSameItemSameTags(itemOut.getStackInSlot(0), new ItemStack(Items.COAL)), +// "NBT Predicate test didn't run when it should have."); +// helper.succeed(); +// }); +// } + +// @GameTest(template = "singleblock_chem_reactor", batch = "NBTPredicateTest") +// public static void NBTPredicateMachineCRTestDoesntSucceed(GameTestHelper helper) { +// SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( +// helper.getBlockEntity(new BlockPos(0, 1, 0))); + +// machine.setRecipeType(CR_RECIPE_TYPE); +// NotifiableItemStackHandler itemIn = (NotifiableItemStackHandler) machine +// .getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).get(0); +// NotifiableItemStackHandler itemOut = (NotifiableItemStackHandler) machine +// .getCapabilitiesFlat(IO.OUT, ItemRecipeCapability.CAP).get(0); + +// var inputStack = new ItemStack(Items.FEATHER); +// inputStack.getOrCreateTag().putString("foo", "baz"); +// itemIn.setStackInSlot(0, inputStack); +// helper.runAfterDelay(10, () -> { +// helper.assertFalse(ItemStack.isSameItemSameTags(itemOut.getStackInSlot(0), new ItemStack(Items.COAL)), +// "NBT Predicate test ran when it shouldn't have."); +// helper.succeed(); +// }); +// } + +// @GameTest(template = "singleblock_chem_reactor", batch = "NBTPredicateTest") +// public static void NBTPredicateMachineCRTestChanced(GameTestHelper helper) { +// SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( +// helper.getBlockEntity(new BlockPos(0, 1, 0))); + +// machine.setRecipeType(CR_RECIPE_TYPE); +// NotifiableItemStackHandler itemIn = (NotifiableItemStackHandler) machine +// .getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).get(0); +// NotifiableItemStackHandler itemOut = (NotifiableItemStackHandler) machine +// .getCapabilitiesFlat(IO.OUT, ItemRecipeCapability.CAP).get(0); + +// var inputStack = new ItemStack(Items.FEATHER, 15); // one short, a chance roll needs to fail +// inputStack.getOrCreateTag().putString("bin", "bar"); +// itemIn.setStackInSlot(0, inputStack); +// helper.runAfterDelay(4 * 16 + 1, () -> { +// helper.assertTrue(ItemStack.isSameItemSameTags(itemOut.getStackInSlot(0), new ItemStack(Items.CHARCOAL)), +// "NBT Predicate Chanced test ran the wrong recipe!"); +// helper.assertTrue(itemOut.getStackInSlot(0).getCount() == 16, +// "NBT Predicate Chanced test didn't complete enough recipe runs, completed [" + +// itemOut.getStackInSlot(0).getCount() + "], not [16]"); +// helper.assertFalse(itemIn.getStackInSlot(0).getCount() == 15, +// "NBT Predicate Chanced test didn't consume items"); +// helper.assertFalse(itemIn.getStackInSlot(0).isEmpty(), +// "NBT Predicate Chanced test consumed too many items"); +// helper.succeed(); +// }); +// } + +// @GameTest(template = "singleblock_chem_reactor", batch = "NBTPredicateTest") +// public static void NBTPredicateMachineCRTestRanged(GameTestHelper helper) { +// SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( +// helper.getBlockEntity(new BlockPos(0, 1, 0))); + +// machine.setRecipeType(CR_RECIPE_TYPE); +// NotifiableItemStackHandler itemIn = (NotifiableItemStackHandler) machine +// .getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).get(0); +// NotifiableItemStackHandler itemOut = (NotifiableItemStackHandler) machine +// .getCapabilitiesFlat(IO.OUT, ItemRecipeCapability.CAP).get(0); + +// var inputStack = new ItemStack(Items.FEATHER, 63); // one short, a range needs to roll not max +// inputStack.getOrCreateTag().putString("bash", "bar"); +// itemIn.setStackInSlot(0, inputStack); +// helper.runAfterDelay(4 * 16 + 1, () -> { +// helper.assertTrue(ItemStack.isSameItemSameTags(itemOut.getStackInSlot(0), new ItemStack(Items.COBBLESTONE)), +// "NBT Predicate Ranged test ran the wrong recipe!"); +// helper.assertTrue(itemOut.getStackInSlot(0).getCount() == 16, +// "NBT Predicate Ranged test didn't complete enough recipe runs, completed [" + +// itemOut.getStackInSlot(0).getCount() + "], not [16]"); +// helper.assertFalse(itemIn.getStackInSlot(0).getCount() == 15, +// "NBT Predicate Ranged test didn't consume items"); +// helper.assertFalse(itemIn.getStackInSlot(0).isEmpty(), +// "NBT Predicate Ranged test consumed too many items"); +// helper.succeed(); +// }); +// } + +// @GameTest(template = "singleblock_chem_reactor", batch = "NBTPredicateTest") +// public static void NBTPredicateMachineCRTestChancedRanged(GameTestHelper helper) { +// SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( +// helper.getBlockEntity(new BlockPos(0, 1, 0))); + +// machine.setRecipeType(CR_RECIPE_TYPE); +// NotifiableItemStackHandler itemIn = (NotifiableItemStackHandler) machine +// .getCapabilitiesFlat(IO.IN, ItemRecipeCapability.CAP).get(0); +// NotifiableItemStackHandler itemOut = (NotifiableItemStackHandler) machine +// .getCapabilitiesFlat(IO.OUT, ItemRecipeCapability.CAP).get(0); + +// var inputStack = new ItemStack(Items.FEATHER, 63); // one short, a chance or range needs to not max +// inputStack.getOrCreateTag().putString("bash", "botch"); +// itemIn.setStackInSlot(0, inputStack); +// helper.runAfterDelay(4 * 16 + 1, () -> { +// helper.assertTrue(ItemStack.isSameItemSameTags(itemOut.getStackInSlot(0), new ItemStack(Items.DEEPSLATE)), +// "NBT Predicate Chanced Ranged test ran the wrong recipe!"); +// helper.assertTrue(itemOut.getStackInSlot(0).getCount() == 16, +// "NBT Predicate Chanced Ranged test didn't complete enough recipe runs, completed [" + +// itemOut.getStackInSlot(0).getCount() + "], not [16]"); +// helper.assertFalse(itemIn.getStackInSlot(0).getCount() == 15, +// "NBT Predicate Chanced Ranged test didn't consume items"); +// helper.assertFalse(itemIn.getStackInSlot(0).isEmpty(), +// "NBT Predicate Chanced Ranged test consumed too many items"); +// helper.succeed(); +// }); +// } +// } diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookupTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookupTest.java new file mode 100644 index 00000000000..5442bef3781 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/lookup/GTRecipeLookupTest.java @@ -0,0 +1,248 @@ +package com.gregtechceu.gtceu.api.recipe.lookup; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; +import com.gregtechceu.gtceu.api.recipe.kind.GTRecipe; +import com.gregtechceu.gtceu.api.recipe.lookup.ingredient.AbstractMapIngredient; +import com.gregtechceu.gtceu.api.recipe.lookup.ingredient.fluid.FluidStackMapIngredient; +import com.gregtechceu.gtceu.api.recipe.lookup.ingredient.item.ItemStackMapIngredient; +import com.gregtechceu.gtceu.api.registry.GTRegistries; +import com.gregtechceu.gtceu.data.material.GTMaterials; + +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.valueproviders.UniformInt; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.RecipeType; +import net.neoforged.neoforge.common.crafting.SizedIngredient; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.function.Predicate; + +import static com.gregtechceu.gtceu.data.recipe.GTRecipeTypes.ELECTRIC; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class GTRecipeLookupTest { + + private static GTRecipeLookup lookup; + private static final Predicate ALWAYS_TRUE = gtRecipe -> true; + private static final Predicate ALWAYS_FALSE = gtRecipe -> false; + // private static GTRecipeType RECIPE_TYPE; + private static GTRecipe SMELT_STONE, SMELT_ACACIA_WOOD, SMELT_BIRCH_WOOD, SMELT_CHERRY_WOOD; + private static GTRecipe RANGED_INPUT_ITEM, RANGED_INPUT_FLUID, RANGED_INPUT_BOTH; + + @BeforeBatch(batch = "GTRecipeLookup") + public static void prepare(ServerLevel level) { + ((MappedRegistry) GTRegistries.RECIPE_CATEGORIES).unfreeze(); + ((MappedRegistry>) BuiltInRegistries.RECIPE_TYPE).unfreeze(); + RecipeType proxyRecipes = RecipeType.SMELTING; + GTRecipeType type = new GTRecipeType(GTCEu.id("test_recipes"), ELECTRIC, proxyRecipes) + .setEUIO(IO.IN) + .setMaxIOSize(1, 1, 1, 1); + lookup = new GTRecipeLookup(type); + + SMELT_STONE = type.recipeBuilder("smelt_stone") + .inputItems(Items.COBBLESTONE, 1) + .outputItems(Items.STONE, 1) + .build(); + SMELT_ACACIA_WOOD = type.recipeBuilder("smelt_acacia_wood") + .inputItems(Items.ACACIA_WOOD, 1) + .outputItems(Items.CHARCOAL, 1) + .build(); + SMELT_BIRCH_WOOD = type.recipeBuilder("smelt_birch_wood") + .inputItems(Items.BIRCH_WOOD, 1) + .outputItems(Items.CHARCOAL, 1) + .build(); + SMELT_CHERRY_WOOD = type.recipeBuilder("smelt_cherry_wood") + .inputItems(Items.CHERRY_WOOD, 16) + .outputItems(Items.CHARCOAL, 1) + .build(); + RANGED_INPUT_ITEM = type.recipeBuilder("ranged_input_item") + .inputItemsRanged(Items.RED_WOOL, UniformInt.of(0, 4)) + .outputItems(Items.CHARCOAL, 1) + .build(); + RANGED_INPUT_FLUID = type.recipeBuilder("ranged_input_fluid") + .inputFluidsRanged(GTMaterials.Helium.getFluid(1), UniformInt.of(0, 4)) + .outputItems(Items.CHARCOAL, 1) + .build(); + RANGED_INPUT_BOTH = type.recipeBuilder("ranged_input_both") + .inputItemsRanged(Items.BLUE_WOOL, UniformInt.of(0, 4)) + .inputFluidsRanged(GTMaterials.Iron.getFluid(1), UniformInt.of(0, 4)) + .outputItems(Items.CHARCOAL, 1) + .build(); + + lookup.removeAllRecipes(); + for (GTRecipe recipe : List.of(SMELT_STONE, + SMELT_ACACIA_WOOD, + SMELT_BIRCH_WOOD, + SMELT_CHERRY_WOOD, + RANGED_INPUT_ITEM, + RANGED_INPUT_FLUID, + RANGED_INPUT_BOTH)) { + lookup.addRecipe(recipe); + } + + ((MappedRegistry) GTRegistries.RECIPE_CATEGORIES).freeze(); + ((MappedRegistry>) BuiltInRegistries.RECIPE_TYPE).freeze(); + } + + private static List> createIngredients(ItemStack... stacks) { + return List.of( + Arrays.stream(stacks) + .map(stack -> (AbstractMapIngredient) new ItemStackMapIngredient(stack)) + .toList()); + } + + private static List> createIngredients(FluidStack... stacks) { + return List.of( + Arrays.stream(stacks) + .map(stack -> (AbstractMapIngredient) new FluidStackMapIngredient(stack)) + .toList()); + } + + private static List> createIngredients(List>... stacks) { + return Arrays.stream(stacks).flatMap(Collection::stream).toList(); + } + + // Simple recipe test whose lookup should succeed + @GameTest(template = "empty", batch = "GTRecipeLookup") + public static void recipeLookupSimpleSuccessTest(GameTestHelper helper) { + var ingredients = createIngredients(new ItemStack(Items.COBBLESTONE, 1)); + GTRecipe resultRecipe = lookup.recurseIngredientTreeFindRecipe(ingredients, lookup.getLookup(), ALWAYS_TRUE); + helper.assertTrue(SMELT_STONE.equals(resultRecipe), + "GT Recipe should be smelt_stone, instead was " + resultRecipe); + helper.succeed(); + } + + // Simple recipe test whose lookup should fail because we pass an ingredient + // that does not match any of the recipes. + @GameTest(template = "empty", batch = "GTRecipeLookup") + public static void recipeLookupSimpleFailureTest(GameTestHelper helper) { + var ingredients = createIngredients(new ItemStack(Items.REDSTONE_TORCH, 1)); + GTRecipe resultRecipe = lookup.recurseIngredientTreeFindRecipe(ingredients, lookup.getLookup(), ALWAYS_TRUE); + helper.assertTrue(resultRecipe == null, "GT Recipe should be empty (null), instead was " + resultRecipe); + helper.succeed(); + } + + // Recipe test whose lookup should fail because the predicate for canHandle + // always evaluates to false. + @GameTest(template = "empty", batch = "GTRecipeLookup") + public static void recipeLookupFalsePredicateFailureTest(GameTestHelper helper) { + var ingredients = createIngredients(new ItemStack(Items.COBBLESTONE, 1)); + GTRecipe resultRecipe = lookup.recurseIngredientTreeFindRecipe(ingredients, lookup.getLookup(), ALWAYS_FALSE); + helper.assertTrue(resultRecipe == null, "GT Recipe should be empty (null), instead was " + resultRecipe); + helper.succeed(); + } + + // Recipe test whose lookup should succeed even when passed ingredients that don't have a recipe + @GameTest(template = "empty", batch = "GTRecipeLookup") + public static void recipeLookupMultipleIngredientsSuccessTest(GameTestHelper helper) { + var ingredients = createIngredients(new ItemStack(Items.COBBLESTONE, 1), + new ItemStack(Items.REDSTONE_TORCH, 1)); + GTRecipe resultRecipe = lookup.recurseIngredientTreeFindRecipe(ingredients, lookup.getLookup(), ALWAYS_TRUE); + helper.assertTrue(SMELT_STONE.equals(resultRecipe), + "GT Recipe should be smelt_stone, instead was " + resultRecipe); + helper.succeed(); + } + + // Recipe test whose lookup should succeed because even though the amount in the recipe is not enough, + // ingredients don't count items + @GameTest(template = "empty", batch = "GTRecipeLookup") + public static void recipeLookupIngredientCountSucceedTest(GameTestHelper helper) { + // NOTE: RecipeLookup only checks item type, not item count, so this will still work + var notEnoughIngredients = createIngredients(new ItemStack(Items.CHERRY_WOOD, 8)); + GTRecipe resultRecipe = lookup.recurseIngredientTreeFindRecipe(notEnoughIngredients, lookup.getLookup(), + ALWAYS_TRUE); + helper.assertTrue(SMELT_CHERRY_WOOD.equals(resultRecipe), + "GT Recipe should be smelt_cherry_wood, instead was " + resultRecipe); + + var enoughIngredients = createIngredients(new ItemStack(Items.CHERRY_WOOD, 16)); + resultRecipe = lookup.recurseIngredientTreeFindRecipe(enoughIngredients, lookup.getLookup(), ALWAYS_TRUE); + helper.assertTrue(SMELT_CHERRY_WOOD.equals(resultRecipe), + "GT Recipe should be smelt_cherry_wood, instead was " + resultRecipe); + helper.succeed(); + } + + // Recipe test with a recipe-based canHandle check + @GameTest(template = "empty", batch = "GTRecipeLookup") + public static void recipeLookupCustomCountCanHandleTest(GameTestHelper helper) { + var ingredients = createIngredients(new ItemStack(Items.CHERRY_WOOD, 16)); + // Do a recipe check with a condition that requires at least 4 ingredients in the inputs + // The recipe has 8, so this should succeed + GTRecipe resultRecipe = lookup.recurseIngredientTreeFindRecipe(ingredients, lookup.getLookup(), + recipe -> recipe.inputs + .getOrDefault(ItemRecipeCapability.CAP, List.of()) + .stream() + .allMatch(content -> ((SizedIngredient) content.getContent()).count() > 4)); + helper.assertTrue(SMELT_CHERRY_WOOD.equals(resultRecipe), + "GT Recipe should be smelt_cherry_wood, instead was " + resultRecipe); + + // Do a recipe check with a condition that requires at least 32 ingredients in the inputs + // The recipe has 8, so this should fail + resultRecipe = lookup.recurseIngredientTreeFindRecipe(ingredients, lookup.getLookup(), recipe -> recipe.inputs + .getOrDefault(ItemRecipeCapability.CAP, List.of()) + .stream() + .allMatch(content -> ((SizedIngredient) content.getContent()).count() > 32)); + helper.assertTrue(resultRecipe == null, "GT Recipe should be empty (null), instead was " + resultRecipe); + + helper.succeed(); + } + + // Simple recipe test with ranged item input, whose lookup should succeed + // Repeats 100 times to make sure there's no random roll interference + @GameTest(template = "empty", batch = "GTRecipeLookup") + public static void recipeLookupSimpleRangedItemSuccessTest(GameTestHelper helper) { + var ingredients = createIngredients(new ItemStack(Items.RED_WOOL, 4)); + for (int i = 0; i < 100; i++) { + GTRecipe resultRecipe = lookup.recurseIngredientTreeFindRecipe(ingredients, lookup.getLookup(), + ALWAYS_TRUE); + helper.assertTrue(RANGED_INPUT_ITEM.equals(resultRecipe), + "GT Recipe should be ranged_input_item, instead was " + resultRecipe + ". Failed on check " + i); + } + helper.succeed(); + } + + // Simple recipe test with ranged fluid input, whose lookup should succeed + // Repeats 100 times to make sure there's no random roll interference + @GameTest(template = "empty", batch = "GTRecipeLookup") + public static void recipeLookupSimpleRangedFluidSuccessTest(GameTestHelper helper) { + var ingredients = createIngredients(GTMaterials.Helium.getFluid(4)); + for (int i = 0; i < 100; i++) { + GTRecipe resultRecipe = lookup.recurseIngredientTreeFindRecipe(ingredients, lookup.getLookup(), + ALWAYS_TRUE); + helper.assertTrue(RANGED_INPUT_FLUID.equals(resultRecipe), + "GT Recipe should be ranged_input_fluid, instead was " + resultRecipe + ". Failed on check " + i); + } + helper.succeed(); + } + + // Simple recipe test with ranged item and fluid inputs, whose lookup should succeed + // Repeats 100 times to make sure there's no random roll interference + @GameTest(template = "empty", batch = "GTRecipeLookup") + public static void recipeLookupSimpleRangedItemFluidSuccessTest(GameTestHelper helper) { + var ingredients = createIngredients( + createIngredients(new ItemStack(Items.BLUE_WOOL, 4)), + createIngredients(GTMaterials.Iron.getFluid(4))); + for (int i = 0; i < 100; i++) { + GTRecipe resultRecipe = lookup.recurseIngredientTreeFindRecipe(ingredients, lookup.getLookup(), + ALWAYS_TRUE); + helper.assertTrue(RANGED_INPUT_BOTH.equals(resultRecipe), + "GT Recipe should be raged_input_both, instead was " + resultRecipe + ". Failed on check " + i); + } + helper.succeed(); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/item/NBTItemStackMapIngredientLookupTest.java b/src/test/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/item/NBTItemStackMapIngredientLookupTest.java new file mode 100644 index 00000000000..94dbc7533a3 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/api/recipe/lookup/ingredient/item/NBTItemStackMapIngredientLookupTest.java @@ -0,0 +1,229 @@ +// PORT TODO: Fix this +// package com.gregtechceu.gtceu.api.recipe.lookup.ingredient.item; + +// import com.gregtechceu.gtceu.GTCEu; +// import com.gregtechceu.gtceu.api.recipe.GTRecipe; +// import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +// import com.gregtechceu.gtceu.api.recipe.lookup.GTRecipeLookup; +// import com.gregtechceu.gtceu.gametest.util.TestUtils; + +// import net.minecraft.gametest.framework.BeforeBatch; +// import net.minecraft.gametest.framework.GameTest; +// import net.minecraft.gametest.framework.GameTestHelper; +// import net.minecraft.nbt.CompoundTag; +// import net.minecraft.server.level.ServerLevel; +// import net.minecraft.world.item.Item; +// import net.minecraft.world.item.ItemStack; +// import net.minecraft.world.item.Items; +// import net.neoforged.neoforge.gametest.GameTestHolder; +// import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +// import java.util.List; +// import java.util.function.Predicate; + +// @PrefixGameTestTemplate(false) +// @GameTestHolder(GTCEu.MOD_ID) +// public class NBTItemStackMapIngredientLookupTest { + +// private static GTRecipeLookup LOOKUP; +// private static final Predicate ALWAYS_TRUE = gtRecipe -> true; +// private static final Predicate ALWAYS_FALSE = gtRecipe -> false; +// private static GTRecipeType RECIPE_TYPE; +// private static GTRecipe PARTIAL_TAG_1, PARTIAL_TAG_2, STRICT_TAG_1, STRICT_TAG_2; + +// private static CompoundTag tag1, tag2; + +// @BeforeBatch(batch = "NBTItemStackMapIngredientLookup") +// public static void prepare(ServerLevel level) { +// RECIPE_TYPE = TestUtils.createRecipeType("NBT_item_stack_map_ingredient_lookup"); +// LOOKUP = RECIPE_TYPE.getLookup(); + +// tag1 = new CompoundTag(); +// tag1.putString("tag1", "tag1"); + +// tag2 = new CompoundTag(); +// tag2.putString("tag1", "tag1"); +// var otherStuff = new CompoundTag(); +// otherStuff.putBoolean("a", true); +// otherStuff.putLong("b", 4); +// tag2.put("testTag", otherStuff); + +// // Partial tag 2 matches a recipe looking for partial tag 1 +// // apart from these, all ingredients should only match themselves +// // +// // Recipe looking for ingredient X : Does it match recipe Y +// // pt1: pt1 pt2 x x +// // pt2: x pt2 x x +// // st1: x x st1 x +// // st2: x x x st2 + +// AbstractIngredient PARTIAL_TAG_1_INGREDIENT = PartialNBTIngredient.of(Items.RED_BED, tag1); +// AbstractIngredient PARTIAL_TAG_2_INGREDIENT = PartialNBTIngredient.of(Items.BROWN_BED, tag2); +// AbstractIngredient STRICT_TAG_1_INGREDIENT = createStrictTaggedIngredient(Items.GREEN_BED, tag1); +// AbstractIngredient STRICT_TAG_2_INGREDIENT = createStrictTaggedIngredient(Items.BLUE_BED, tag2); + +// PARTIAL_TAG_1 = RECIPE_TYPE.recipeBuilder("partial_match_NBT_1") +// .inputItems(PARTIAL_TAG_1_INGREDIENT) +// .outputItems(Items.RED_BED, 1) +// .build(); + +// PARTIAL_TAG_2 = RECIPE_TYPE.recipeBuilder("partial_match_NBT_2") +// .inputItems(PARTIAL_TAG_2_INGREDIENT) +// .outputItems(Items.BROWN_BED, 1) +// .build(); + +// STRICT_TAG_1 = RECIPE_TYPE.recipeBuilder("strict_match_NBT_1") +// .inputItems(STRICT_TAG_1_INGREDIENT) +// .outputItems(Items.GREEN_BED, 1) +// .build(); + +// STRICT_TAG_2 = RECIPE_TYPE.recipeBuilder("strict_match_NBT_2") +// .inputItems(STRICT_TAG_2_INGREDIENT) +// .outputItems(Items.BLUE_BED, 1) +// .build(); + +// for (GTRecipe recipe : List.of(PARTIAL_TAG_1, +// PARTIAL_TAG_2, +// STRICT_TAG_1, +// STRICT_TAG_2)) { +// LOOKUP.addRecipe(recipe); +// } +// } + +// private static StrictNBTIngredient createStrictTaggedIngredient(Item item, CompoundTag tag) { +// ItemStack stack = new ItemStack(item); +// for (var tagKey : tag.getAllKeys()) { +// stack.getOrCreateTag().put(tagKey, tag.get(tagKey)); +// } +// return StrictNBTIngredient.of(stack); +// } + +// @GameTest(template = "empty", batch = "NBTItemStackMapIngredientLookup") +// public static void NBTItemStackMapIngredientMatchingPartialTag1Test(GameTestHelper helper) { +// // Partial tag 1 fits in Partial tag 1 +// GTRecipe resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// PartialNBTItemStackMapIngredient.from(PartialNBTIngredient.of(Items.RED_BED, tag1))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == PARTIAL_TAG_1, +// "GT Recipe should be PARTIAL_TAG_1, instead was " + resultRecipe); + +// // Partial tag 2 fits in Partial tag 1 +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// PartialNBTItemStackMapIngredient.from(PartialNBTIngredient.of(Items.RED_BED, tag2))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == PARTIAL_TAG_1, +// "GT Recipe should be PARTIAL_TAG_1, instead was " + resultRecipe); + +// // Strict tag 1 and 2 should never fit in partial tag 1 +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// StrictNBTItemStackMapIngredient.from(createStrictTaggedIngredient(Items.RED_BED, tag1))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == null, "GT Recipe should be null, instead was " + resultRecipe); + +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// StrictNBTItemStackMapIngredient.from(createStrictTaggedIngredient(Items.RED_BED, tag2))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == null, "GT Recipe should be null, instead was " + resultRecipe); +// helper.succeed(); +// } + +// @GameTest(template = "empty", batch = "NBTItemStackMapIngredientLookup") +// public static void NBTItemStackMapIngredientMatchingPartialTag2Test(GameTestHelper helper) { +// // Partial tag 1 should not fit in partial tag 2 +// GTRecipe resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// PartialNBTItemStackMapIngredient.from(PartialNBTIngredient.of(Items.BROWN_BED, tag1))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == null, "GT Recipe should be null, instead was " + resultRecipe); + +// // Partial tag 2 fits in Partial tag 2 +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// PartialNBTItemStackMapIngredient.from(PartialNBTIngredient.of(Items.BROWN_BED, tag2))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == PARTIAL_TAG_2, +// "GT Recipe should be PARTIAL_TAG_2, instead was " + resultRecipe); + +// // Strict tag 1 and 2 should never fit in partial tag 2 +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// StrictNBTItemStackMapIngredient.from(createStrictTaggedIngredient(Items.BROWN_BED, tag1))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == null, "GT Recipe should be null, instead was " + resultRecipe); + +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// StrictNBTItemStackMapIngredient.from(createStrictTaggedIngredient(Items.BROWN_BED, tag2))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == null, "GT Recipe should be null, instead was " + resultRecipe); +// helper.succeed(); +// } + +// @GameTest(template = "empty", batch = "NBTItemStackMapIngredientLookup") +// public static void NBTItemStackMapIngredientMatchingStrictTag1Test(GameTestHelper helper) { +// // Partial tag 1 and 2 should not fit in strict tag 1 +// GTRecipe resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// PartialNBTItemStackMapIngredient.from(PartialNBTIngredient.of(Items.GREEN_BED, tag1))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == null, "GT Recipe should be null, instead was " + resultRecipe); + +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// PartialNBTItemStackMapIngredient.from(PartialNBTIngredient.of(Items.GREEN_BED, tag2))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == null, "GT Recipe should be null, instead was " + resultRecipe); + +// // Strict tag 1 should fit in strict tag 1 +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// StrictNBTItemStackMapIngredient.from(createStrictTaggedIngredient(Items.GREEN_BED, tag1))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == STRICT_TAG_1, +// "GT Recipe should be STRICT_TAG_1, instead was " + resultRecipe); + +// // Strict tag 2 should not fit in strict tag 1 +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// StrictNBTItemStackMapIngredient.from(createStrictTaggedIngredient(Items.GREEN_BED, tag2))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == null, "GT Recipe should be null, instead was " + resultRecipe); +// helper.succeed(); +// } + +// @GameTest(template = "empty", batch = "NBTItemStackMapIngredientLookup") +// public static void NBTItemStackMapIngredientMatchingStrictTag2Test(GameTestHelper helper) { +// // Partial tag 1 and 2 should not fit in strict tag 2 +// GTRecipe resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// PartialNBTItemStackMapIngredient.from(PartialNBTIngredient.of(Items.BLUE_BED, tag1))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == null, "GT Recipe should be null, instead was " + resultRecipe); + +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// PartialNBTItemStackMapIngredient.from(PartialNBTIngredient.of(Items.BLUE_BED, tag2))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == null, "GT Recipe should be null, instead was " + resultRecipe); + +// // Strict tag 1 should not fit in strict tag 2 +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// StrictNBTItemStackMapIngredient.from(createStrictTaggedIngredient(Items.BLUE_BED, tag1))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == null, "GT Recipe should be null, instead was " + resultRecipe); + +// // Strict tag 2 should fit in strict tag 2 +// resultRecipe = LOOKUP.recurseIngredientTreeFindRecipe( +// List.of( +// StrictNBTItemStackMapIngredient.from(createStrictTaggedIngredient(Items.BLUE_BED, tag2))), +// LOOKUP.getLookup(), ALWAYS_TRUE); +// helper.assertTrue(resultRecipe == STRICT_TAG_2, +// "GT Recipe should be STRICT_TAG_2, instead was " + resultRecipe); +// helper.succeed(); +// } +// } diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/AdvancedDetectorCoverTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/AdvancedDetectorCoverTest.java new file mode 100644 index 00000000000..04cbd701910 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/AdvancedDetectorCoverTest.java @@ -0,0 +1,117 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.SimpleTieredMachine; +import com.gregtechceu.gtceu.common.cover.detector.AdvancedFluidDetectorCover; +import com.gregtechceu.gtceu.common.cover.detector.AdvancedItemDetectorCover; +import com.gregtechceu.gtceu.data.item.GTItems; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.material.Fluids; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +/** + * The "electrolyzer" template contains a creative tank with water, + * that is set to auto-output into an electrolyzer when supplied with a redstone signal + * The redstone lamp is connected to the covers that are placed in the tests in this class. + * The creative tank's rate of output is equal to the electrolyzer's rate of processing + */ +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class AdvancedDetectorCoverTest { + + @GameTest(template = "electrolyzer", batch = "coverTests", required = false) + public static void BLOCKED_BY_LDLIB_WEIRDNESS_PROBABLY_testAdvancedActivityDetectorCover(GameTestHelper helper) { + helper.pullLever(new BlockPos(2, 2, 2)); + MetaMachine machine = ((IMachineBlockEntity) helper.getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine(); + TestUtils.placeCover(helper, machine, GTItems.COVER_ACTIVITY_DETECTOR_ADVANCED.asStack(), Direction.WEST); + helper.runAtTickTime(30, () -> helper.assertRedstoneSignal( + new BlockPos(1, 2, 1), + Direction.WEST, + signal -> signal > 0, + () -> "expected redstone signal")); + } + + @GameTest(template = "electrolyzer", batch = "coverTests", required = false) + public static void BLOCKED_BY_LDLIB_WEIRDNESS_TOO_PROBABLY_testAdvancedActivityDetectorCover(GameTestHelper helper) { + helper.pullLever(new BlockPos(2, 2, 2)); + MetaMachine machine = ((IMachineBlockEntity) helper.getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine(); + TestUtils.placeCover(helper, machine, GTItems.COVER_ACTIVITY_DETECTOR_ADVANCED.asStack(), Direction.WEST); + helper.runAtTickTime(35, () -> helper.pullLever(2, 2, 2)); + helper.runAtTickTime(40, () -> { + TestUtils.assertLampOff(helper, new BlockPos(0, 2, 1)); + helper.succeed(); + }); + } + + @GameTest(template = "electrolyzer", batch = "coverTests") + public static void testAdvancedFluidDetectorCover(GameTestHelper helper) { + helper.pullLever(new BlockPos(2, 2, 2)); + SimpleTieredMachine machine = (SimpleTieredMachine) ((IMachineBlockEntity) helper + .getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine(); + machine.importFluids.setFluidInTank(0, new FluidStack(Fluids.WATER, 10000)); + AdvancedFluidDetectorCover cover = (AdvancedFluidDetectorCover) TestUtils.placeCover(helper, machine, + GTItems.COVER_FLUID_DETECTOR_ADVANCED.asStack(), Direction.WEST); + cover.setMaxValue(100000); + cover.setMinValue(1); + cover.setLatched(false); + // At t=40, 36k will be inside, giving a redstone value of 5 + helper.runAtTickTime(40, () -> { + TestUtils.assertLampOn(helper, new BlockPos(0, 2, 1)); + helper.succeed(); + }); + } + + @GameTest(template = "electrolyzer", batch = "coverTests") + public static void testAdvancedItemDetectorCover(GameTestHelper helper) { + helper.pullLever(new BlockPos(2, 2, 2)); + MetaMachine machine = ((IMachineBlockEntity) helper.getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine(); + AdvancedItemDetectorCover cover = (AdvancedItemDetectorCover) TestUtils.placeCover(helper, machine, + GTItems.COVER_ITEM_DETECTOR_ADVANCED.asStack(), Direction.WEST); + cover.setLatched(true); + helper.runAtTickTime(40, () -> { + TestUtils.assertLampOn(helper, new BlockPos(0, 2, 1)); + helper.succeed(); + }); + } + + @GameTest(template = "electrolyzer", batch = "coverTests") + public static void testAdvancedItemDetectorCoverBelowThreshold(GameTestHelper helper) { + helper.pullLever(new BlockPos(2, 2, 2)); + MetaMachine machine = ((IMachineBlockEntity) helper.getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine(); + AdvancedItemDetectorCover cover = (AdvancedItemDetectorCover) TestUtils.placeCover(helper, machine, + GTItems.COVER_ITEM_DETECTOR_ADVANCED.asStack(), Direction.WEST); + cover.setMinValue(1); + cover.setMaxValue(4); + helper.runAtTickTime(40, () -> { + TestUtils.assertLampOff(helper, new BlockPos(0, 2, 1)); + helper.succeed(); + }); + } + + @GameTest(template = "electrolyzer", batch = "coverTests") + public static void testAdvancedItemDetectorCoverAboveThreshold(GameTestHelper helper) { + helper.pullLever(new BlockPos(2, 2, 2)); + MetaMachine machine = ((IMachineBlockEntity) helper.getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine(); + machine.getItemHandlerCap(null, false).setStackInSlot(0, new ItemStack(Items.DIRT, 5)); + AdvancedItemDetectorCover cover = (AdvancedItemDetectorCover) TestUtils.placeCover(helper, machine, + GTItems.COVER_ITEM_DETECTOR_ADVANCED.asStack(), Direction.WEST); + cover.setMinValue(1); + cover.setMaxValue(4); + cover.setLatched(true); + helper.runAtTickTime(40, () -> { + TestUtils.assertLampOff(helper, new BlockPos(0, 2, 1)); + helper.succeed(); + }); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/ConveyorCoverTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/ConveyorCoverTest.java new file mode 100644 index 00000000000..c8b6d33afef --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/ConveyorCoverTest.java @@ -0,0 +1,98 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.common.machine.storage.BufferMachine; +import com.gregtechceu.gtceu.data.item.GTItems; +import com.gregtechceu.gtceu.data.machine.GTMachines; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class ConveyorCoverTest { + + public static void setupCrates(GameTestHelper helper) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BUFFER[GTValues.LV].getBlock()); + helper.setBlock(new BlockPos(0, 2, 0), GTMachines.BUFFER[GTValues.LV].getBlock()); + } + + // Test for seeing if conveyors pass items + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void conveyorTransfersItemsTest(GameTestHelper helper) { + setupCrates(helper); + BufferMachine crate1 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + BufferMachine crate2 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.getInventory().setStackInSlot(0, new ItemStack(Items.FLINT, 16)); + // LV Cover + ConveyorCover cover = (ConveyorCover) TestUtils.placeCover(helper, crate2, GTItems.CONVEYOR_MODULE_LV.asStack(), + Direction.DOWN); + // Set the cover to import from crate1 to crate2 + cover.setIo(IO.IN); + + helper.succeedWhen(() -> { + helper.assertTrue( + TestUtils.isItemStackEqual(crate2.getInventory().getStackInSlot(0), new ItemStack(Items.FLINT, 16)), + "Conveyor didn't transfer right amount of items"); + }); + } + + // Test for seeing if conveyors don't pass items if set to the wrong direction + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void conveyorTransfersItemsWrongDirectionTest(GameTestHelper helper) { + setupCrates(helper); + BufferMachine crate1 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + BufferMachine crate2 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.getInventory().setStackInSlot(0, new ItemStack(Items.FLINT, 16)); + // LV Cover + ConveyorCover cover = (ConveyorCover) TestUtils.placeCover(helper, crate2, GTItems.CONVEYOR_MODULE_LV.asStack(), + Direction.DOWN); + // Set the cover to import from crate2 to crate1 + // This shouldn't do anything, as the items are in crate1 + cover.setIo(IO.OUT); + + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(crate2.getInventory().getStackInSlot(0), new ItemStack(Items.FLINT, 16)), + "Conveyor transferred when it shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } + + // Test for seeing if pumps transfer items + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void conveyorPumpDoesntTransferItemsTest(GameTestHelper helper) { + setupCrates(helper); + BufferMachine crate1 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + BufferMachine crate2 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.getInventory().setStackInSlot(0, new ItemStack(Items.FLINT, 16)); + // LV Cover + PumpCover cover = (PumpCover) TestUtils.placeCover(helper, crate2, GTItems.ELECTRIC_PUMP_LV.asStack(), + Direction.DOWN); + // Set the cover to import from crate1 to crate2 + cover.setIo(IO.IN); + + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(crate2.getInventory().getStackInSlot(0), new ItemStack(Items.FLINT, 16)), + "Pump transferred when it shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/DetectorCoverTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/DetectorCoverTest.java new file mode 100644 index 00000000000..f7544e33fa0 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/DetectorCoverTest.java @@ -0,0 +1,59 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.SimpleTieredMachine; +import com.gregtechceu.gtceu.data.item.GTItems; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.level.material.Fluids; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class DetectorCoverTest { + + @GameTest(template = "electrolyzer", batch = "coverTests") + public static void testActivityDetectorCover(GameTestHelper helper) { + helper.pullLever(new BlockPos(2, 2, 2)); + SimpleTieredMachine machine = (SimpleTieredMachine) ((IMachineBlockEntity) helper + .getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine(); + machine.importFluids.setFluidInTank(0, new FluidStack(Fluids.WATER, machine.importFluids.getTankCapacity(0))); + TestUtils.placeCover(helper, machine, GTItems.COVER_ACTIVITY_DETECTOR.asStack(), Direction.WEST); + helper.runAtTickTime(40, () -> { + TestUtils.assertLampOn(helper, new BlockPos(0, 2, 1)); + helper.succeed(); + }); + } + + @GameTest(template = "electrolyzer", batch = "coverTests") + public static void testFluidDetectorCover(GameTestHelper helper) { + helper.pullLever(new BlockPos(2, 2, 2)); + SimpleTieredMachine machine = (SimpleTieredMachine) ((IMachineBlockEntity) helper + .getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine(); + machine.exportFluids.setFluidInTank(0, new FluidStack(Fluids.WATER, machine.exportFluids.getTankCapacity(0))); + TestUtils.placeCover(helper, machine, GTItems.COVER_FLUID_DETECTOR.asStack(), Direction.WEST); + helper.runAtTickTime(40, () -> { + TestUtils.assertLampOn(helper, new BlockPos(0, 2, 1)); + helper.succeed(); + }); + } + + @GameTest(template = "electrolyzer", batch = "coverTests") + public static void testItemDetectorCover(GameTestHelper helper) { + helper.pullLever(new BlockPos(2, 2, 2)); + SimpleTieredMachine machine = (SimpleTieredMachine) ((IMachineBlockEntity) helper + .getBlockEntity(new BlockPos(1, 2, 1))).getMetaMachine(); + TestUtils.placeCover(helper, machine, GTItems.COVER_ITEM_DETECTOR.asStack(), Direction.WEST); + helper.runAtTickTime(40, () -> { + TestUtils.assertLampOff(helper, new BlockPos(0, 2, 1)); + helper.succeed(); + }); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/EnderCoversTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/EnderCoversTest.java new file mode 100644 index 00000000000..4b8e463bf7d --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/EnderCoversTest.java @@ -0,0 +1,97 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.common.cover.ender.EnderFluidLinkCover; +import com.gregtechceu.gtceu.common.cover.ender.EnderItemLinkCover; +import com.gregtechceu.gtceu.common.cover.ender.EnderRedstoneLinkCover; +import com.gregtechceu.gtceu.common.machine.storage.QuantumChestMachine; +import com.gregtechceu.gtceu.common.machine.storage.QuantumTankMachine; +import com.gregtechceu.gtceu.data.item.GTItems; +import com.gregtechceu.gtceu.data.machine.GTMachines; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.LeverBlock; +import net.minecraft.world.level.block.state.properties.AttachFace; +import net.minecraft.world.level.material.Fluids; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.fluids.capability.IFluidHandler; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class EnderCoversTest { + + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void fluidLinkCoverTest(GameTestHelper helper) { + QuantumTankMachine tank1 = (QuantumTankMachine) TestUtils.setMachine(helper, new BlockPos(1, 1, 1), + GTMachines.SUPER_TANK[1]); + QuantumTankMachine tank2 = (QuantumTankMachine) TestUtils.setMachine(helper, new BlockPos(1, 1, 3), + GTMachines.SUPER_TANK[1]); + EnderFluidLinkCover cover1 = (EnderFluidLinkCover) TestUtils.placeCover(helper, tank1, + GTItems.COVER_ENDER_FLUID_LINK.asStack(), Direction.UP); + EnderFluidLinkCover cover2 = (EnderFluidLinkCover) TestUtils.placeCover(helper, tank2, + GTItems.COVER_ENDER_FLUID_LINK.asStack(), Direction.UP); + cover1.setIo(IO.IN); + cover2.setIo(IO.OUT); + tank1.getFluidHandlerCap(Direction.UP, false).fill(new FluidStack(Fluids.WATER, 1000), + IFluidHandler.FluidAction.EXECUTE); + helper.runAtTickTime(20, () -> { + helper.assertTrue(TestUtils.isFluidStackEqual(tank2.getStored(), new FluidStack(Fluids.WATER, 1000)), + "ender fluid link cover didn't transfer fluid"); + helper.succeed(); + }); + } + + @GameTest(template = "empty_5x5", batch = "coverTests", required = false) + public static void only_works_in_game_itemLinkCoverTest(GameTestHelper helper) { + QuantumChestMachine chest1 = (QuantumChestMachine) TestUtils.setMachine(helper, new BlockPos(1, 1, 1), + GTMachines.SUPER_CHEST[1]); + QuantumChestMachine chest2 = (QuantumChestMachine) TestUtils.setMachine(helper, new BlockPos(1, 1, 3), + GTMachines.SUPER_CHEST[1]); + EnderItemLinkCover cover1 = (EnderItemLinkCover) TestUtils.placeCover(helper, chest1, + GTItems.COVER_ENDER_ITEM_LINK.asStack(), Direction.UP); + EnderItemLinkCover cover2 = (EnderItemLinkCover) TestUtils.placeCover(helper, chest2, + GTItems.COVER_ENDER_ITEM_LINK.asStack(), Direction.UP); + cover1.setIo(IO.IN); + cover2.setIo(IO.OUT); + chest1.getItemHandlerCap(Direction.UP, false).insertItem(0, new ItemStack(Items.DIAMOND, 64), false); + helper.runAtTickTime(20, () -> { + helper.assertTrue(TestUtils.isItemStackEqual(chest2.getStored(), new ItemStack(Items.DIAMOND, 64)), + "ender item link cover didn't transfer items"); + helper.succeed(); + }); + } + + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void redstoneLinkCoverTest(GameTestHelper helper) { + QuantumTankMachine tank1 = (QuantumTankMachine) TestUtils.setMachine(helper, new BlockPos(1, 1, 1), + GTMachines.SUPER_TANK[1]); + QuantumTankMachine tank2 = (QuantumTankMachine) TestUtils.setMachine(helper, new BlockPos(1, 1, 3), + GTMachines.SUPER_TANK[1]); + EnderRedstoneLinkCover cover1 = (EnderRedstoneLinkCover) TestUtils.placeCover(helper, tank1, + GTItems.COVER_ENDER_REDSTONE_LINK.asStack(), Direction.UP); + EnderRedstoneLinkCover cover2 = (EnderRedstoneLinkCover) TestUtils.placeCover(helper, tank2, + GTItems.COVER_ENDER_REDSTONE_LINK.asStack(), Direction.UP); + cover1.setIo(IO.IN); + cover2.setIo(IO.OUT); + helper.setBlock(new BlockPos(1, 2, 1), + Blocks.LEVER.defaultBlockState().setValue(LeverBlock.FACE, AttachFace.FLOOR)); + helper.setBlock(new BlockPos(1, 2, 3), Blocks.REDSTONE_LAMP); + helper.pullLever(new BlockPos(1, 2, 1)); + + helper.onEachTick(() -> { + if (helper.getTick() < 10) return; + TestUtils.assertLampOn(helper, new BlockPos(1, 2, 3)); + }); + helper.runAtTickTime(20, helper::succeed); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/ItemFilterCoverTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/ItemFilterCoverTest.java new file mode 100644 index 00000000000..d372fff5dd9 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/ItemFilterCoverTest.java @@ -0,0 +1,94 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.api.cover.filter.SimpleItemFilter; +import com.gregtechceu.gtceu.common.cover.data.FilterMode; +import com.gregtechceu.gtceu.common.machine.storage.BufferMachine; +import com.gregtechceu.gtceu.data.item.GTDataComponents; +import com.gregtechceu.gtceu.data.item.GTItems; +import com.gregtechceu.gtceu.data.machine.GTMachines; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class ItemFilterCoverTest { + + private static ItemStack makeDiamondFilter() { + ItemStack stack = GTItems.ITEM_FILTER.asStack(); + SimpleItemFilter filter = SimpleItemFilter.loadFilter(stack); + filter.getMatches()[0] = Items.DIAMOND.getDefaultInstance(); + stack.set(GTDataComponents.SIMPLE_ITEM_FILTER, filter); + return stack; + } + + public static void setupCrates(GameTestHelper helper) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BUFFER[GTValues.LV].getBlock()); + helper.setBlock(new BlockPos(0, 2, 0), GTMachines.BUFFER[GTValues.LV].getBlock()); + } + + // Test for seeing if conveyors pass filtered items correctly + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void conveyorTransfersFilteredItemsTest(GameTestHelper helper) { + setupCrates(helper); + BufferMachine crate1 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + BufferMachine crate2 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.getInventory().setStackInSlot(0, new ItemStack(Items.FLINT, 8)); + crate1.getInventory().setStackInSlot(1, new ItemStack(Items.DIAMOND, 16)); + // LV Cover + ConveyorCover cover = (ConveyorCover) TestUtils.placeCover(helper, crate2, GTItems.CONVEYOR_MODULE_LV.asStack(), + Direction.DOWN); + // Set the cover to import from crate1 to crate2 + cover.setIo(IO.IN); + // Filter to whitelist diamonds + ItemFilterCover filterCover = (ItemFilterCover) TestUtils.placeCover(helper, crate1, + makeDiamondFilter(), Direction.UP); + filterCover.setFilterMode(FilterMode.FILTER_EXTRACT); + + helper.succeedWhen(() -> { + TestUtils.assertEqual(helper, crate2.getInventory().getStackInSlot(0), new ItemStack(Items.DIAMOND, 8)); + TestUtils.assertEqual(helper, crate2.getInventory().getStackInSlot(1), ItemStack.EMPTY); + helper.succeed(); + }); + } + + // Test for seeing if conveyors pass filtered items correctly + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void conveyorDoesntTransferFilteredItemsTest(GameTestHelper helper) { + setupCrates(helper); + BufferMachine crate1 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + BufferMachine crate2 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.getInventory().setStackInSlot(0, new ItemStack(Items.FLINT, 16)); + crate1.getInventory().setStackInSlot(1, new ItemStack(Items.DIAMOND, 16)); + // LV Cover + ConveyorCover cover = (ConveyorCover) TestUtils.placeCover(helper, crate2, GTItems.CONVEYOR_MODULE_LV.asStack(), + Direction.DOWN); + // Set the cover to import from crate1 to crate2 + cover.setIo(IO.IN); + // Filter to whitelist diamonds + ItemFilterCover filterCover = (ItemFilterCover) TestUtils.placeCover(helper, crate1, makeDiamondFilter(), + Direction.UP); + filterCover.setFilterMode(FilterMode.FILTER_INSERT); // filter is for insert only, so should block transfer + + helper.runAtTickTime(40, () -> { + TestUtils.assertEqual(helper, crate2.getInventory().getStackInSlot(0), ItemStack.EMPTY); + TestUtils.assertEqual(helper, crate2.getInventory().getStackInSlot(1), ItemStack.EMPTY); + helper.succeed(); + }); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/MonitorCoverTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/MonitorCoverTest.java new file mode 100644 index 00000000000..4a788e4ec87 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/MonitorCoverTest.java @@ -0,0 +1,56 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.common.machine.electric.BatteryBufferMachine; +import com.gregtechceu.gtceu.data.item.GTItems; +import com.gregtechceu.gtceu.data.machine.GTMachines; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import java.util.List; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class MonitorCoverTest { + + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void testEnergyPlaceholders(GameTestHelper helper) { + BatteryBufferMachine machine = (BatteryBufferMachine) TestUtils.setMachine(helper, new BlockPos(0, 1, 0), + GTMachines.BATTERY_BUFFER_4[GTValues.HV]); + machine.getBatteryInventory().insertItem(0, GTItems.BATTERY_HV_LITHIUM.asStack(), false); + ComputerMonitorCover cover = (ComputerMonitorCover) TestUtils.placeCover(helper, machine, + GTItems.COVER_SCREEN.asStack(), Direction.UP); + cover.getFormatStringLines().add("Energy: {}/{} EU"); + cover.getFormatStringArgs().addAll(List.of( + "energy", + "energyCapacity")); + cover.setUpdateInterval(1); + helper.runAtTickTime(5, () -> { + TestUtils.assertEqual(helper, cover.getText(), + "Energy: 0/" + machine.energyContainer.getEnergyCapacity() + " EU"); + helper.succeed(); + }); + } + + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void testCombinePlaceholder(GameTestHelper helper) { + BatteryBufferMachine machine = (BatteryBufferMachine) TestUtils.setMachine(helper, new BlockPos(0, 1, 0), + GTMachines.BATTERY_BUFFER_4[GTValues.HV]); + ComputerMonitorCover cover = (ComputerMonitorCover) TestUtils.placeCover(helper, machine, + GTItems.COVER_SCREEN.asStack(), Direction.UP); + cover.getFormatStringLines() + .add("{if 1 {combine test 1 2 3 lol {repeat 5 \"a \"}} \"if placeholder failed somehow\"}"); + cover.setUpdateInterval(1); + helper.runAtTickTime(5, () -> { + TestUtils.assertEqual(helper, cover.getText(), "test 1 2 3 lol a a a a a "); + helper.succeed(); + }); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/PumpCoverTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/PumpCoverTest.java new file mode 100644 index 00000000000..55f2207441d --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/PumpCoverTest.java @@ -0,0 +1,99 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.common.machine.storage.BufferMachine; +import com.gregtechceu.gtceu.data.item.GTItems; +import com.gregtechceu.gtceu.data.machine.GTMachines; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.material.Fluids; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +@SuppressWarnings("DataFlowIssue") +@GameTestHolder(GTCEu.MOD_ID) +@PrefixGameTestTemplate(false) +public class PumpCoverTest { + + public static void setupCrates(GameTestHelper helper) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BUFFER[GTValues.LV].getBlock()); + helper.setBlock(new BlockPos(0, 2, 0), GTMachines.BUFFER[GTValues.LV].getBlock()); + } + + // Test for seeing if pumps pass fluids + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void pumpTransfersFluidsTest(GameTestHelper helper) { + setupCrates(helper); + BufferMachine crate1 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + BufferMachine crate2 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.getFluidHandlerCap(Direction.NORTH, false).setFluidInTank(0, new FluidStack(Fluids.WATER, 1000)); + // LV Cover + PumpCover cover = (PumpCover) TestUtils.placeCover(helper, crate2, GTItems.ELECTRIC_PUMP_LV.asStack(), + Direction.DOWN); + cover.setIo(IO.IN); + + helper.succeedWhen(() -> helper.assertTrue( + TestUtils.isFluidStackEqual( + crate2.getFluidHandlerCap(Direction.NORTH, false).getFluidInTank(0), + new FluidStack(Fluids.WATER, 1000)), + "Pump transferred didn't transfer fluid")); + TestUtils.succeedAfterTest(helper); + } + + // Test for seeing if conveyors don't pass items if set to the wrong direction + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void pumpTransfersFluidsWrongDirectionTest(GameTestHelper helper) { + setupCrates(helper); + BufferMachine crate1 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + BufferMachine crate2 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.getFluidHandlerCap(Direction.NORTH, false).setFluidInTank(0, new FluidStack(Fluids.WATER, 1000)); + // LV Cover + PumpCover cover = (PumpCover) TestUtils.placeCover(helper, crate2, GTItems.ELECTRIC_PUMP_LV.asStack(), + Direction.DOWN); + // Set the cover to import from crate2 to crate1 + // This shouldn't do anything, as the items fluids in crate1 + cover.setIo(IO.OUT); + + helper.onEachTick(() -> helper.assertFalse( + TestUtils.isFluidStackEqual( + crate2.getFluidHandlerCap(Direction.NORTH, false).getFluidInTank(0), + new FluidStack(Fluids.WATER, 1000)), + "Pump transferred when it shouldn't have")); + TestUtils.succeedAfterTest(helper); + } + + // Test for seeing if pumps transfer items + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void pumpDoesntTransferItemsTest(GameTestHelper helper) { + setupCrates(helper); + BufferMachine crate1 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + BufferMachine crate2 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.getInventory().setStackInSlot(0, new ItemStack(Items.FLINT, 16)); + // LV Cover + PumpCover cover = (PumpCover) TestUtils.placeCover(helper, crate2, GTItems.ELECTRIC_PUMP_LV.asStack(), + Direction.DOWN); + // Set the cover to import from crate1 to crate2 + cover.setIo(IO.IN); + + helper.onEachTick(() -> helper.assertFalse( + TestUtils.isItemStackEqual(crate2.getInventory().getStackInSlot(0), new ItemStack(Items.FLINT, 16)), + "Pump transferred when it shouldn't have")); + TestUtils.succeedAfterTest(helper); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/RobotArmTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/RobotArmTest.java new file mode 100644 index 00000000000..93f1c49b758 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/RobotArmTest.java @@ -0,0 +1,106 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.common.cover.data.TransferMode; +import com.gregtechceu.gtceu.common.machine.storage.CrateMachine; +import com.gregtechceu.gtceu.data.item.GTItems; +import com.gregtechceu.gtceu.data.machine.GTMachines; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import static com.gregtechceu.gtceu.data.cover.GTCovers.*; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class RobotArmTest { + + public static void setupCrates(GameTestHelper helper) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BRONZE_CRATE.getBlock()); + helper.setBlock(new BlockPos(0, 2, 0), GTMachines.BRONZE_CRATE.getBlock()); + } + + // Test for seeing if robot arm transfers more than keepExact's limit + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void robotArmKeepExactTest(GameTestHelper helper) { + setupCrates(helper); + CrateMachine crate1 = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + CrateMachine crate2 = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.inventory.setStackInSlot(0, new ItemStack(Items.FLINT, 16)); + // LV Cover + RobotArmCover cover = (RobotArmCover) TestUtils.placeCover(helper, crate2, GTItems.ROBOT_ARM_LV.asStack(), + Direction.DOWN); + // Set the cover to import from crate1 to crate2 exactly 7 items + cover.setIo(IO.IN); + cover.setTransferMode(TransferMode.KEEP_EXACT); + cover.setGlobalTransferLimit(7); + + helper.runAtTickTime(20, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(crate2.inventory.getStackInSlot(0), new ItemStack(Items.FLINT, 7)), + "Conveyor didn't transfer right amount of items"); + helper.succeed(); + }); + } + + // Test for seeing if robot arm transfers correct amount when using transfer exact + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void robotArmTransferExactTest(GameTestHelper helper) { + setupCrates(helper); + CrateMachine crate1 = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + CrateMachine crate2 = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.inventory.setStackInSlot(0, new ItemStack(Items.FLINT, 16)); + // LV Cover + RobotArmCover cover = (RobotArmCover) TestUtils.placeCover(helper, crate2, GTItems.ROBOT_ARM_LV.asStack(), + Direction.DOWN); + // Set the cover to import from crate1 to crate2 exactly 7 items 2 times + cover.setIo(IO.IN); + cover.setTransferMode(TransferMode.TRANSFER_EXACT); + cover.setGlobalTransferLimit(7); + + helper.runAtTickTime(40, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(crate2.inventory.getStackInSlot(0), new ItemStack(Items.FLINT, 14)), + "Conveyor didn't transfer right amount of items"); + helper.succeed(); + }); + } + + // Test for seeing if robot arm transfers all items when using transfer any + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void robotArmTransferAnyTest(GameTestHelper helper) { + setupCrates(helper); + CrateMachine crate1 = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + CrateMachine crate2 = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.inventory.setStackInSlot(0, new ItemStack(Items.FLINT, 16)); + // LV Cover + RobotArmCover cover = (RobotArmCover) TestUtils.placeCover(helper, crate2, GTItems.ROBOT_ARM_LV.asStack(), + Direction.DOWN); + // Set the cover to import from crate1 to crate2 all items + cover.setIo(IO.IN); + cover.setTransferMode(TransferMode.TRANSFER_ANY); + cover.setGlobalTransferLimit(13); // arbitrary amount, if the cover works correctly it shouldn't matter + + helper.runAtTickTime(40, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(crate2.inventory.getStackInSlot(0), new ItemStack(Items.FLINT, 16)), + "Conveyor didn't transfer right amount of items"); + helper.succeed(); + }); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/ShutterCoverTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/ShutterCoverTest.java new file mode 100644 index 00000000000..dd24dee2960 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/ShutterCoverTest.java @@ -0,0 +1,52 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.common.machine.storage.BufferMachine; +import com.gregtechceu.gtceu.data.item.GTItems; +import com.gregtechceu.gtceu.data.machine.GTMachines; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class ShutterCoverTest { + + public static void setupCrates(GameTestHelper helper) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BUFFER[GTValues.LV].getBlock()); + helper.setBlock(new BlockPos(0, 2, 0), GTMachines.BUFFER[GTValues.LV].getBlock()); + } + + @GameTest(template = "empty_5x5", batch = "coverTests") + public static void shutterCoverBlocksTransferTest(GameTestHelper helper) { + setupCrates(helper); + BufferMachine crate1 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + BufferMachine crate2 = (BufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + crate1.getInventory().setStackInSlot(0, new ItemStack(Items.FLINT, 16)); + crate1.getInventory().setStackInSlot(1, new ItemStack(Items.DIAMOND, 16)); + // LV Cover + ConveyorCover cover = (ConveyorCover) TestUtils.placeCover(helper, crate2, GTItems.CONVEYOR_MODULE_LV.asStack(), + Direction.DOWN); + // Set the cover to import from crate1 to crate2 + cover.setIo(IO.IN); + TestUtils.placeCover(helper, crate1, GTItems.COVER_SHUTTER.asStack(), Direction.UP); + + helper.runAtTickTime(40, () -> { + TestUtils.assertEqual(helper, crate2.getInventory().getStackInSlot(0), ItemStack.EMPTY); + TestUtils.assertEqual(helper, crate2.getInventory().getStackInSlot(1), ItemStack.EMPTY); + helper.succeed(); + }); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/SolarPanelTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/SolarPanelTest.java new file mode 100644 index 00000000000..9a41b658b03 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/SolarPanelTest.java @@ -0,0 +1,65 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.common.machine.electric.BatteryBufferMachine; +import com.gregtechceu.gtceu.data.item.GTItems; +import com.gregtechceu.gtceu.data.machine.GTMachines; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.block.Blocks; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class SolarPanelTest { + + @BeforeBatch(batch = "SolarTests") + public static void prepare(ServerLevel level) { + level.setDayTime(6000); + } + + private static BatteryBufferMachine makeBatteryBuffer(GameTestHelper helper, int tier) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BATTERY_BUFFER_4[tier].getBlock()); + return (BatteryBufferMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + } + + private static void placeSolar(GameTestHelper helper, MetaMachine machine) { + TestUtils.placeCover(helper, machine, GTItems.COVER_SOLAR_PANEL_HV.asStack(), Direction.UP); + } + + @GameTest(template = "empty_5x5", batch = "SolarTests") + public static void generatesEnergyAtDayTest(GameTestHelper helper) { + BatteryBufferMachine machine = makeBatteryBuffer(helper, GTValues.HV); + machine.getBatteryInventory().insertItem(0, GTItems.BATTERY_HV_LITHIUM.asStack(), false); + placeSolar(helper, machine); + helper.runAtTickTime(80, () -> { + helper.assertTrue(machine.energyContainer.getEnergyStored() > 0, + "Solar panel cover didn't generate energy at day time"); + helper.succeed(); + }); + } + + @GameTest(template = "empty_5x5", batch = "SolarTests") + public static void doesntGenerateEnergyAtDayWhenBlockedTest(GameTestHelper helper) { + BatteryBufferMachine machine = makeBatteryBuffer(helper, GTValues.HV); + helper.setBlock(new BlockPos(0, 3, 0), Blocks.DIAMOND_BLOCK); + machine.getBatteryInventory().insertItem(0, GTItems.BATTERY_HV_LITHIUM.asStack(), false); + placeSolar(helper, machine); + helper.runAtTickTime(40, () -> { + helper.assertTrue(machine.energyContainer.getEnergyStored() == 0, + "Solar panel cover generated energy when blocked"); + helper.succeed(); + }); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/cover/WirelessTransmitterCoverTest.java b/src/test/java/com/gregtechceu/gtceu/common/cover/WirelessTransmitterCoverTest.java new file mode 100644 index 00000000000..929ecaf2b81 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/cover/WirelessTransmitterCoverTest.java @@ -0,0 +1,37 @@ +package com.gregtechceu.gtceu.common.cover; + +import com.gregtechceu.gtceu.GTCEu; + +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class WirelessTransmitterCoverTest { + + // @GameTest(template = "central_monitor", batch = "coverTests") + // public static void wirelessTransmitterCoverTest(GameTestHelper helper) { + // CentralMonitorMachine machine = (CentralMonitorMachine) TestUtils + // .getMetaMachine(helper.getBlockEntity(new BlockPos(1, 3, 2))); + // DataAccessHatchMachine dataHatch = (DataAccessHatchMachine) TestUtils + // .getMetaMachine(helper.getBlockEntity(new BlockPos(1, 2, 2))); + // BatteryBufferMachine batteryBuffer = (BatteryBufferMachine) TestUtils + // .getMetaMachine(helper.getBlockEntity(new BlockPos(2, 2, 3))); + // WirelessTransmitterCover cover = (WirelessTransmitterCover) batteryBuffer.getCoverContainer() + // .getCoverAtSide(Direction.UP); + // MonitorGroup group = machine.getMonitorGroups().get(0); + // group.setTarget(dataHatch.getPos()); + // Supplier module = () -> group.getItemStackHandler().getStackInSlot(0); + // ItemStack stack = dataHatch.getDataItems().getStackInSlot(3); + // // noinspection DataFlowIssue + // cover.onDataStickUse(helper.makeMockPlayer(GameType.CREATIVE), stack); + // dataHatch.importItems.setStackInSlot(3, stack); + // TestUtils.assertEqual(helper, module.get(), GTItems.TEXT_MODULE.asStack()); + // helper.runAtTickTime(40, () -> { + // TestUtils.assertEqual(helper, group.getTarget(helper.getLevel()), + // helper.absolutePos(new BlockPos(2, 2, 3))); + // TestUtils.assertEqual(helper, new TextModuleBehaviour().getText(module.get()), "Energy: 5.40M/7.20M EU\n"); + // helper.succeed(); + // }); + // } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineTests.java b/src/test/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineTests.java new file mode 100644 index 00000000000..1271824a1d6 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/machine/multiblock/electric/AssemblyLineTests.java @@ -0,0 +1,260 @@ +package com.gregtechceu.gtceu.common.machine.multiblock.electric; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.common.machine.multiblock.part.FluidHatchPartMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.part.ItemBusPartMachine; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.material.Fluids; +import net.neoforged.neoforge.fluids.FluidStack; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import static com.gregtechceu.gtceu.data.recipe.GTRecipeTypes.ASSEMBLY_LINE_RECIPES; +import static com.gregtechceu.gtceu.gametest.util.TestUtils.getMetaMachine; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class AssemblyLineTests { + + private static GTRecipeType ASSLINE_RECIPE_TYPE; + + @BeforeBatch(batch = "Assline") + public static void prepare(ServerLevel level) { + ASSLINE_RECIPE_TYPE = TestUtils.createRecipeType("assline_tests", ASSEMBLY_LINE_RECIPES); + ASSLINE_RECIPE_TYPE.getLookup().addRecipe(ASSLINE_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_assline")) + .inputItems(new ItemStack(Blocks.COBBLESTONE), new ItemStack(Blocks.ACACIA_WOOD)) + .inputFluids(new FluidStack(Fluids.WATER, 1), new FluidStack(Fluids.LAVA, 1)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.VA[GTValues.HV]).duration(1) + // NBT has a schematic in it with an EV energy input hatch + .build()); + } + + private record BusHolder(ItemBusPartMachine inputBus1, ItemBusPartMachine inputBus2, + ItemBusPartMachine inputBus3, ItemBusPartMachine inputBus4, + FluidHatchPartMachine inputHatch1, FluidHatchPartMachine inputHatch2, + FluidHatchPartMachine inputHatch3, FluidHatchPartMachine inputHatch4, + ItemBusPartMachine outputBus1, WorkableMultiblockMachine controller) {} + + /** + * Retrieves the busses for this specific template and force a multiblock structure check + * + * @param helper the GameTestHelper + * @return the busses, in the BusHolder record. + */ + private static BusHolder getBussesAndForm(GameTestHelper helper) { + WorkableMultiblockMachine controller = (WorkableMultiblockMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 3, 0))); + TestUtils.formMultiblock(controller); + controller.setRecipeType(ASSLINE_RECIPE_TYPE); + ItemBusPartMachine inputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 1))); + ItemBusPartMachine inputBus2 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 1, 1))); + ItemBusPartMachine inputBus3 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 1, 1))); + ItemBusPartMachine inputBus4 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(3, 1, 1))); + ItemBusPartMachine outputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(4, 1, 1))); + FluidHatchPartMachine inputHatch1 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + FluidHatchPartMachine inputHatch2 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 1, 0))); + FluidHatchPartMachine inputHatch3 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 1, 0))); + FluidHatchPartMachine inputHatch4 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(3, 1, 0))); + return new BusHolder(inputBus1, inputBus2, inputBus3, inputBus4, + inputHatch1, inputHatch2, inputHatch3, inputHatch4, outputBus1, controller); + } + + @GameTest(template = "ass_line_4aev_4in", batch = "Assline") + public static void AsslineRecipeRunsTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Items.COBBLESTONE)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Items.ACACIA_WOOD)); + busHolder.inputHatch1.tank.setFluidInTank(0, new FluidStack(Fluids.WATER, 1)); + busHolder.inputHatch2.tank.setFluidInTank(0, new FluidStack(Fluids.LAVA, 1)); + helper.succeedOnTickWhen(2, () -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Item didn't craft at the right tick with ok recipe" + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + @GameTest(template = "ass_line_4aev_4in", batch = "Assline") + public static void AsslineRecipeDoesntRunWhenItemsMovedByOneTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Items.COBBLESTONE)); + busHolder.inputBus3.getInventory().setStackInSlot(0, new ItemStack(Items.ACACIA_WOOD)); + busHolder.inputHatch1.tank.setFluidInTank(0, new FluidStack(Fluids.WATER, 1)); + busHolder.inputHatch2.tank.setFluidInTank(0, new FluidStack(Fluids.LAVA, 1)); + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Item crafted with inputs moved" + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + TestUtils.succeedAfterTest(helper); + } + + @GameTest(template = "ass_line_4aev_4in", batch = "Assline") + public static void AsslineRecipeDoesntRunWhenFluidsMovedByOneTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Items.COBBLESTONE)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Items.ACACIA_WOOD)); + busHolder.inputHatch2.tank.setFluidInTank(0, new FluidStack(Fluids.WATER, 1)); + busHolder.inputHatch3.tank.setFluidInTank(0, new FluidStack(Fluids.LAVA, 1)); + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Item crafted with inputs moved" + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + TestUtils.succeedAfterTest(helper); + } + + @GameTest(template = "ass_line_4aev_4in", batch = "Assline") + public static void AsslineRecipeDoesntRunWhenBothMovedByOneTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Items.COBBLESTONE)); + busHolder.inputBus3.getInventory().setStackInSlot(0, new ItemStack(Items.ACACIA_WOOD)); + busHolder.inputHatch2.tank.setFluidInTank(0, new FluidStack(Fluids.WATER, 1)); + busHolder.inputHatch3.tank.setFluidInTank(0, new FluidStack(Fluids.LAVA, 1)); + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Item crafted with inputs moved" + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + TestUtils.succeedAfterTest(helper); + } + + @GameTest(template = "ass_line_4aev_4in", batch = "Assline") + public static void AsslineRecipeRunsAndOnlyConsumesOneTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Items.COBBLESTONE, 2)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Items.ACACIA_WOOD, 2)); + busHolder.inputHatch1.tank.setFluidInTank(0, new FluidStack(Fluids.WATER, 2)); + busHolder.inputHatch2.tank.setFluidInTank(0, new FluidStack(Fluids.LAVA, 2)); + helper.runAtTickTime(1, () -> { + // All 4 inputs had 1 consumed + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.inputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.COBBLESTONE)), + "Assline consumed both items when it should have consumed one"); + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.inputBus2.getInventory().getStackInSlot(0), + new ItemStack(Blocks.ACACIA_WOOD)), + "Assline consumed both items when it should have consumed one"); + helper.assertTrue( + TestUtils.isFluidStackEqual(busHolder.inputHatch1.tank.getFluidInTank(0), + new FluidStack(Fluids.WATER, 1)), + "Assline consumed both fluids when it should have consumed one"); + helper.assertTrue( + TestUtils.isFluidStackEqual(busHolder.inputHatch2.tank.getFluidInTank(0), + new FluidStack(Fluids.LAVA, 1)), + "Assline consumed both fluids when it should have consumed one"); + }); + helper.runAtTickTime(2, () -> { + // First recipe finished + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Item didn't craft at the right tick with ok recipe" + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + // All 4 inputs had the second one consumed + helper.assertTrue( + busHolder.inputBus1.getInventory().getStackInSlot(0).isEmpty(), + "Assline consumed didn't consume both items when it should have"); + helper.assertTrue( + busHolder.inputBus2.getInventory().getStackInSlot(0).isEmpty(), + "Assline consumed didn't consume both items when it should have"); + helper.assertTrue( + busHolder.inputHatch1.tank.getFluidInTank(0).isEmpty(), + "Assline consumed didn't consume both fluids when it should have"); + helper.assertTrue( + busHolder.inputHatch2.tank.getFluidInTank(0).isEmpty(), + "Assline consumed didn't consume both fluids when it should have"); + }); + helper.runAtTickTime(3, () -> { + // Recipe 2 has finished + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE, 2)), + "Item didn't craft at the right tick with ok recipe" + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + TestUtils.succeedAfterTest(helper); + } + + @GameTest(template = "ass_line_4aev_4in", batch = "Assline") + public static void AsslineRecipeDoesntRunWhenItemsSwappedTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Items.COBBLESTONE)); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Items.ACACIA_WOOD)); + busHolder.inputHatch1.tank.setFluidInTank(0, new FluidStack(Fluids.WATER, 1)); + busHolder.inputHatch2.tank.setFluidInTank(0, new FluidStack(Fluids.LAVA, 1)); + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Item crafted with inputs moved" + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + TestUtils.succeedAfterTest(helper); + } + + @GameTest(template = "ass_line_4aev_4in", batch = "Assline") + public static void AsslineRecipeDoesntRunWhenFluidsSwappedTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Items.COBBLESTONE)); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Items.ACACIA_WOOD)); + busHolder.inputHatch2.tank.setFluidInTank(0, new FluidStack(Fluids.WATER, 1)); + busHolder.inputHatch1.tank.setFluidInTank(0, new FluidStack(Fluids.LAVA, 1)); + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Item crafted with inputs moved" + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + TestUtils.succeedAfterTest(helper); + } + + @GameTest(template = "ass_line_4aev_4in", batch = "Assline") + public static void AsslineRecipeDoesntRunWhenBothSwappedTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.inputBus2.getInventory().setStackInSlot(0, new ItemStack(Items.COBBLESTONE)); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Items.ACACIA_WOOD)); + busHolder.inputHatch2.tank.setFluidInTank(0, new FluidStack(Fluids.WATER, 1)); + busHolder.inputHatch1.tank.setFluidInTank(0, new FluidStack(Fluids.LAVA, 1)); + helper.onEachTick(() -> { + helper.assertFalse( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Item crafted with inputs moved" + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + TestUtils.succeedAfterTest(helper); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachineTest.java b/src/test/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachineTest.java new file mode 100644 index 00000000000..4664cce062b --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/machine/multiblock/part/ItemBusPartMachineTest.java @@ -0,0 +1,153 @@ +package com.gregtechceu.gtceu.common.machine.multiblock.part; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.common.machine.storage.CrateMachine; +import com.gregtechceu.gtceu.data.machine.GTMachines; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Blocks; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class ItemBusPartMachineTest { + + @BeforeBatch(batch = "ItemBusPartMachine") + public static void prepare(ServerLevel level) {} + + // Test for input busses auto importing + @GameTest(template = "empty_5x5", batch = "ItemBusPartMachine") + public static void ItemBusPartMachineAutoImportTest(GameTestHelper helper) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BRONZE_CRATE.getBlock()); + helper.setBlock(new BlockPos(0, 2, 0), GTMachines.ITEM_IMPORT_BUS[1].getBlock()); + CrateMachine crate = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + ItemBusPartMachine itemBus = (ItemBusPartMachine) ((MetaMachineBlockEntity) helper + .getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + itemBus.setFrontFacing(Direction.DOWN); + crate.inventory.setStackInSlot(0, new ItemStack(Blocks.STONE, 16)); + helper.succeedWhen(() -> { + helper.assertTrue(TestUtils.isItemStackEqual( + itemBus.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE, 16)), "Input bus didn't automatically import"); + }); + } + + // Test for input busses not auto importing when off + @GameTest(template = "empty_5x5", batch = "ItemBusPartMachine") + public static void ItemBusPartMachineAutoImportFalseWhenOffTest(GameTestHelper helper) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BRONZE_CRATE.getBlock()); + helper.setBlock(new BlockPos(0, 2, 0), GTMachines.ITEM_IMPORT_BUS[1].getBlock()); + CrateMachine crate = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + ItemBusPartMachine itemBus = (ItemBusPartMachine) ((MetaMachineBlockEntity) helper + .getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + itemBus.setFrontFacing(Direction.DOWN); + itemBus.setWorkingEnabled(false); + crate.inventory.setStackInSlot(0, new ItemStack(Blocks.STONE, 16)); + helper.onEachTick(() -> { + helper.assertFalse(TestUtils.isItemStackEqual( + itemBus.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE, 16)), "Input bus automatically imported when off"); + }); + TestUtils.succeedAfterTest(helper); + } + + // Test for output busses auto exporting + @GameTest(template = "empty_5x5", batch = "ItemBusPartMachine") + public static void ItemBusPartMachineAutoExportTest(GameTestHelper helper) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BRONZE_CRATE.getBlock()); + helper.setBlock(new BlockPos(0, 2, 0), GTMachines.ITEM_EXPORT_BUS[1].getBlock()); + CrateMachine crate = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + ItemBusPartMachine itemBus = (ItemBusPartMachine) ((MetaMachineBlockEntity) helper + .getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + itemBus.setFrontFacing(Direction.DOWN); + itemBus.getInventory().setStackInSlot(0, new ItemStack(Blocks.STONE, 16)); + helper.succeedWhen(() -> { + helper.assertTrue(TestUtils.isItemStackEqual( + crate.inventory.getStackInSlot(0), + new ItemStack(Blocks.STONE, 16)), "Input bus didn't automatically export"); + }); + } + + // Test for export busses not auto export when off + @GameTest(template = "empty_5x5", batch = "ItemBusPartMachine") + public static void ItemBusPartMachineAutoExportFalseWhenOffTest(GameTestHelper helper) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BRONZE_CRATE.getBlock()); + helper.setBlock(new BlockPos(0, 2, 0), GTMachines.ITEM_EXPORT_BUS[1].getBlock()); + CrateMachine crate = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + ItemBusPartMachine itemBus = (ItemBusPartMachine) ((MetaMachineBlockEntity) helper + .getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + itemBus.setFrontFacing(Direction.DOWN); + itemBus.setWorkingEnabled(false); + itemBus.getInventory().setStackInSlot(0, new ItemStack(Blocks.STONE, 16)); + helper.onEachTick(() -> { + helper.assertFalse(TestUtils.isItemStackEqual( + crate.inventory.getStackInSlot(0), + new ItemStack(Blocks.STONE, 16)), "Export bus automatically exported when off"); + }); + TestUtils.succeedAfterTest(helper); + } + + // Test for passthrough busses auto passthrough'ing + @GameTest(template = "empty_5x5", batch = "ItemBusPartMachine") + public static void ItemBusPartMachineAutoPassthroughTest(GameTestHelper helper) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BRONZE_CRATE.getBlock()); + helper.setBlock(new BlockPos(0, 2, 0), GTMachines.ITEM_PASSTHROUGH_HATCH[1].getBlock()); + helper.setBlock(new BlockPos(0, 3, 0), GTMachines.BRONZE_CRATE.getBlock()); + CrateMachine crate = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + ItemBusPartMachine itemBus = (ItemBusPartMachine) ((MetaMachineBlockEntity) helper + .getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + CrateMachine crate2 = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 3, 0))) + .getMetaMachine(); + itemBus.setFrontFacing(Direction.DOWN); + crate.inventory.setStackInSlot(0, new ItemStack(Blocks.STONE, 16)); + helper.succeedWhen(() -> { + helper.assertTrue(TestUtils.isItemStackEqual( + crate2.inventory.getStackInSlot(0), + new ItemStack(Blocks.STONE, 16)), "Passthrough bus didn't automatically export"); + }); + } + + // Test for passthrough busses not auto passthrough when off + @GameTest(template = "empty_5x5", batch = "ItemBusPartMachine") + public static void ItemBusPartMachineAutoPassthroughFalseWhenOffTest(GameTestHelper helper) { + helper.setBlock(new BlockPos(0, 1, 0), GTMachines.BRONZE_CRATE.getBlock()); + helper.setBlock(new BlockPos(0, 2, 0), GTMachines.ITEM_PASSTHROUGH_HATCH[1].getBlock()); + helper.setBlock(new BlockPos(0, 3, 0), GTMachines.BRONZE_CRATE.getBlock()); + CrateMachine crate = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 1, 0))) + .getMetaMachine(); + ItemBusPartMachine itemBus = (ItemBusPartMachine) ((MetaMachineBlockEntity) helper + .getBlockEntity(new BlockPos(0, 2, 0))) + .getMetaMachine(); + CrateMachine crate2 = (CrateMachine) ((MetaMachineBlockEntity) helper.getBlockEntity(new BlockPos(0, 3, 0))) + .getMetaMachine(); + itemBus.setFrontFacing(Direction.DOWN); + itemBus.setWorkingEnabled(false); + crate.inventory.setStackInSlot(0, new ItemStack(Blocks.STONE, 16)); + helper.onEachTick(() -> { + helper.assertFalse(TestUtils.isItemStackEqual( + crate2.inventory.getStackInSlot(0), + new ItemStack(Blocks.STONE, 16)), + "Passthrough bus automatically exported when they shouldn't have"); + }); + TestUtils.succeedAfterTest(helper); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentFluidConditionTest.java b/src/test/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentFluidConditionTest.java new file mode 100644 index 00000000000..e18c562b270 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/common/recipe/condition/AdjacentFluidConditionTest.java @@ -0,0 +1,201 @@ +package com.gregtechceu.gtceu.common.recipe.condition; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.machine.SimpleTieredMachine; +import com.gregtechceu.gtceu.api.machine.trait.NotifiableItemStackHandler; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.data.recipe.GTRecipeTypes; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Blocks; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import static com.gregtechceu.gtceu.gametest.util.TestUtils.getMetaMachine; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class AdjacentFluidConditionTest { + + private static GTRecipeType ROCK_BREAKER_RECIPE_TYPE; + + @BeforeBatch(batch = "AdjacentFluidCondition") + public static void prepare(ServerLevel level) { + ROCK_BREAKER_RECIPE_TYPE = TestUtils.createRecipeType("adjacent_fluid_conditions_tests", + GTRecipeTypes.ROCK_BREAKER_RECIPES); + ROCK_BREAKER_RECIPE_TYPE.getLookup().addRecipe(ROCK_BREAKER_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_adjacent_fluid_conditions")) + .inputItems(new ItemStack(Blocks.COBBLESTONE)) + .outputItems(new ItemStack(Blocks.STONE)) + .adjacentFluidTag(FluidTags.WATER) + .EUt(GTValues.VA[GTValues.HV]) + .duration(8) + .build()); + + ROCK_BREAKER_RECIPE_TYPE.getLookup().addRecipe(ROCK_BREAKER_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_adjacent_fluid_conditions_multiple_fluids")) + .inputItems(new ItemStack(Blocks.OAK_WOOD)) + .outputItems(new ItemStack(Items.CHARCOAL)) + .adjacentFluidTag(FluidTags.WATER, FluidTags.LAVA) + .EUt(GTValues.VA[GTValues.HV]) + .duration(8) + .build()); + } + + // Test for checking if the rock breaker works when the condition is fulfilled + @GameTest(template = "charged_hv_rock_breaker", batch = "AdjacentFluidCondition") + public static void adjacentFluidConditionCorrectFluidPresentTest(GameTestHelper helper) { + // Machine is at 1,1,1 so 0,1,1 is next to it + helper.setBlock(new BlockPos(0, 1, 1), Blocks.WATER); + + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 1, 1))); + + machine.setRecipeType(ROCK_BREAKER_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableItemStackHandler itemOut = machine.exportItems; + + itemIn.setStackInSlot(0, new ItemStack(Items.COBBLESTONE)); + // 1t to turn on, 8t to run the recipe + helper.succeedOnTickWhen(9, () -> { + helper.assertTrue(TestUtils.isItemStackEqual( + itemOut.getStackInSlot(0), + new ItemStack(Blocks.STONE, 1)), + "Singleblock Rock Breaker didn't run recipe in correct time"); + }); + } + + // Test for checking if the rock breaker works when there are no fluids + @GameTest(template = "charged_hv_rock_breaker", batch = "AdjacentFluidCondition") + public static void adjacentFluidConditionNoFluidPresentTest(GameTestHelper helper) { + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 1, 1))); + + machine.setRecipeType(ROCK_BREAKER_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableItemStackHandler itemOut = machine.exportItems; + + itemIn.setStackInSlot(0, new ItemStack(Items.COBBLESTONE)); + helper.onEachTick(() -> { + helper.assertTrue( + itemOut.isEmpty(), + "Singleblock Rock Breaker ran recipe without fluid present"); + }); + TestUtils.succeedAfterTest(helper); + } + + // Test for checking if the rock breaker works when there is the wrong fluids + @GameTest(template = "charged_hv_rock_breaker", batch = "AdjacentFluidCondition") + public static void adjacentFluidConditionWrongFluidPresentTest(GameTestHelper helper) { + // Machine is at 1,1,1 so 0,1,1 is next to it + helper.setBlock(new BlockPos(0, 1, 1), Blocks.LAVA); + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 1, 1))); + + machine.setRecipeType(ROCK_BREAKER_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableItemStackHandler itemOut = machine.exportItems; + + itemIn.setStackInSlot(0, new ItemStack(Items.COBBLESTONE)); + // 1t to turn on, 8t to run the recipe + helper.onEachTick(() -> { + helper.assertTrue( + itemOut.isEmpty(), + "Singleblock Rock Breaker ran recipe with wrong fluid present"); + }); + TestUtils.succeedAfterTest(helper); + } + + // Test for checking if the rock breaker works when two fluids are present + @GameTest(template = "charged_hv_rock_breaker", batch = "AdjacentFluidCondition") + public static void adjacentFluidConditionTwoFluidCorrectFluidsPresentTest(GameTestHelper helper) { + // Machine is at 1,1,1 so 0,1,1 and 1,1,0 are next to it + helper.setBlock(new BlockPos(0, 1, 1), Blocks.LAVA); + helper.setBlock(new BlockPos(1, 1, 0), Blocks.WATER); + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 1, 1))); + + machine.setRecipeType(ROCK_BREAKER_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableItemStackHandler itemOut = machine.exportItems; + + itemIn.setStackInSlot(0, new ItemStack(Items.OAK_WOOD)); + // 1t to turn on, 8t to run the recipe + helper.succeedOnTickWhen(9, () -> { + helper.assertTrue(TestUtils.isItemStackEqual( + itemOut.getStackInSlot(0), + new ItemStack(Items.CHARCOAL, 1)), + "Singleblock Rock Breaker didn't run recipe in correct time"); + }); + } + + // Test for checking if the rock breaker works when one of the two fluids are present + @GameTest(template = "charged_hv_rock_breaker", batch = "AdjacentFluidCondition") + public static void adjacentFluidConditionTwoFluidNr1FluidPresentTest(GameTestHelper helper) { + // Machine is at 1,1,1 so 0,1,1 and 1,1,0 are next to it + helper.setBlock(new BlockPos(1, 1, 0), Blocks.WATER); + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 1, 1))); + + machine.setRecipeType(ROCK_BREAKER_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableItemStackHandler itemOut = machine.exportItems; + + itemIn.setStackInSlot(0, new ItemStack(Items.OAK_WOOD)); + helper.onEachTick(() -> { + helper.assertTrue( + itemOut.isEmpty(), + "Singleblock Rock Breaker ran with only 1 of 2 fluids present"); + }); + TestUtils.succeedAfterTest(helper); + } + + // Test for checking if the rock breaker works when one of the two fluids are present + @GameTest(template = "charged_hv_rock_breaker", batch = "AdjacentFluidCondition") + public static void adjacentFluidConditionTwoFluidNr2FluidPresentTest(GameTestHelper helper) { + // Machine is at 1,1,1 so 0,1,1 and 1,1,0 are next to it + helper.setBlock(new BlockPos(1, 1, 0), Blocks.LAVA); + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 1, 1))); + + machine.setRecipeType(ROCK_BREAKER_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableItemStackHandler itemOut = machine.exportItems; + + itemIn.setStackInSlot(0, new ItemStack(Items.OAK_WOOD)); + helper.onEachTick(() -> { + helper.assertTrue( + itemOut.isEmpty(), + "Singleblock Rock Breaker ran with only 1 of 2 fluids present"); + }); + TestUtils.succeedAfterTest(helper); + } + + // Test for checking if the rock breaker works when one of the two fluids are present + @GameTest(template = "charged_hv_rock_breaker", batch = "AdjacentFluidCondition") + public static void adjacentFluidConditionTwoFluidNoFluidPresentTest(GameTestHelper helper) { + SimpleTieredMachine machine = (SimpleTieredMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 1, 1))); + + machine.setRecipeType(ROCK_BREAKER_RECIPE_TYPE); + NotifiableItemStackHandler itemIn = machine.importItems; + NotifiableItemStackHandler itemOut = machine.exportItems; + + itemIn.setStackInSlot(0, new ItemStack(Items.OAK_WOOD)); + helper.onEachTick(() -> { + helper.assertTrue( + itemOut.isEmpty(), + "Singleblock Rock Breaker ran with no fluids present"); + }); + TestUtils.succeedAfterTest(helper); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/gametest/example/ExampleTest.java b/src/test/java/com/gregtechceu/gtceu/gametest/example/ExampleTest.java new file mode 100644 index 00000000000..e2b36621f8a --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/gametest/example/ExampleTest.java @@ -0,0 +1,19 @@ +package com.gregtechceu.gtceu.gametest.example; + +import com.gregtechceu.gtceu.GTCEu; + +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class ExampleTest { + + @GameTest(template = "empty") + public static void myTest(GameTestHelper helper) { + helper.assertTrue(true, "true is false"); + helper.succeed(); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/gametest/util/TestUtils.java b/src/test/java/com/gregtechceu/gtceu/gametest/util/TestUtils.java new file mode 100644 index 00000000000..9d400cc1d2d --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/gametest/util/TestUtils.java @@ -0,0 +1,320 @@ +package com.gregtechceu.gtceu.gametest.util; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.blockentity.MetaMachineBlockEntity; +import com.gregtechceu.gtceu.api.capability.recipe.FluidRecipeCapability; +import com.gregtechceu.gtceu.api.capability.recipe.IO; +import com.gregtechceu.gtceu.api.capability.recipe.ItemRecipeCapability; +import com.gregtechceu.gtceu.api.cover.CoverBehavior; +import com.gregtechceu.gtceu.api.cover.CoverDefinition; +import com.gregtechceu.gtceu.api.item.IComponentItem; +import com.gregtechceu.gtceu.api.item.component.IItemComponent; +import com.gregtechceu.gtceu.api.machine.IMachineBlockEntity; +import com.gregtechceu.gtceu.api.machine.MachineDefinition; +import com.gregtechceu.gtceu.api.machine.MetaMachine; +import com.gregtechceu.gtceu.api.machine.multiblock.MultiblockControllerMachine; +import com.gregtechceu.gtceu.api.placeholder.MultiLineComponent; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.api.recipe.category.GTRecipeCategory; +import com.gregtechceu.gtceu.api.registry.GTRegistries; +import com.gregtechceu.gtceu.common.item.behavior.CoverPlaceBehavior; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.MappedRegistry; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.RedstoneLampBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.neoforged.neoforge.fluids.FluidStack; + +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Objects; + +import static com.gregtechceu.gtceu.data.recipe.GTRecipeTypes.ELECTRIC; + +public class TestUtils { + + /** + * Compares two itemstacks' items and amounts + * DOES NOT CHECK TAGS OR NBT ETC! + * + * @return {@code true} if items and amounts are equal + */ + public static boolean isItemStackEqual(ItemStack stack1, ItemStack stack2) { + return ItemStack.isSameItem(stack1, stack2) && stack1.getCount() == stack2.getCount(); + } + + /** + * Compares two itemstacks and a range. + * + * @return {@code true} if items are equal, and if stack2's amount is within range. + */ + public static boolean isItemStackWithinRange(ItemStack stack1, ItemStack stack2, int min, int max) { + return ItemStack.isSameItem(stack1, stack2) && isItemWithinRange(stack2, min, max); + } + + /** + * Compares an int representing an itemstack's size with a number of batches, parallels, and runs. + * Intended to test if an IntProvider is being rolled correctly for a batch, or if it is returning a single value + * multiplied. + * This test can trigger false positives from bad luck and should be run more than once to reduce the odds of bad + * luck. + * + * @return {@code true} if the size is an exact multiple of the total run count. TRUE INDICATES FAILURE. + */ + public static boolean isStackSizeExactlyEvenMultiple(int size, int batches, int parallels, int runs) { + return size % (batches * parallels * runs) == 0; + } + + /** + * Compares two itemstack[]s' items and amounts + * Necessary because itemStack does not implement .equals() + */ + public static boolean areItemStacksEqual(ItemStack[] stack1, ItemStack[] stack2) { + if (stack1.length != stack2.length) + return false; + + for (int i = 0; i < stack1.length; i++) { + if (!isItemStackEqual(stack1[i], stack2[i])) + return false; + } + return true; + } + + /** + * Compares two itemstack[]s' items and amounts + * Necessary because itemStack does not implement .equals() + */ + public static boolean areItemStacksEqual(List stack1, List stack2) { + if (stack1.size() != stack2.size()) + return false; + + for (int i = 0; i < stack1.size(); i++) { + if (!isItemStackEqual(stack1.get(i), stack2.get(i))) + return false; + } + return true; + } + + /** + * Compares two fluidstacks' fluids and amounts + * DOES NOT CHECK TAGS OR NBT ETC! + * + * @return {@code true} if fluids and amounts are equal + */ + public static boolean isFluidStackEqual(FluidStack stack1, FluidStack stack2) { + return stack1.isFluidEqual(stack2) && stack1.getAmount() == stack2.getAmount(); + } + + /** + * Compares two fluidstacks and a range. + * + * @return {@code true} if items are equal, and if stack2's amount is within range. + */ + public static boolean isFluidStackWithinRange(FluidStack stack1, FluidStack stack2, int min, int max) { + return stack1.isFluidEqual(stack2) && isFluidWithinRange(stack2, min, max); + } + + /** + * Compares two fluidstack[]s' fluids and amounts + * Necessary because fluidStack's implementation of .equals() does not check amounts + */ + public static boolean areFluidStacksEqual(FluidStack[] stack1, FluidStack[] stack2) { + if (stack1.length != stack2.length) + return false; + + for (int i = 0; i < stack1.length; i++) { + if (!isFluidStackEqual(stack1[i], stack2[i])) + return false; + } + return true; + } + + /** + * Compares an ItemStack with a range + * + * @return {@code true} if the ItemStack's count is within range + */ + public static boolean isItemWithinRange(ItemStack stack, int min, int max) { + return stack.getCount() <= max && stack.getCount() >= min; + } + + /** + * Compares a FluidStack with a range + * + * @return {@code true} if the FluidStack's amount is within range + */ + public static boolean isFluidWithinRange(FluidStack stack, int min, int max) { + return stack.getAmount() <= max && stack.getAmount() >= min; + } + + /** + * compares an integer with a range + * + * @return {@code true} if the integer count is within range + */ + public static boolean isCountWithinRange(int stack, int min, int max) { + return stack <= max && stack >= min; + } + + /** + * Forces a structure check on multiblocks after being placed, to avoid having to wait ticks. + * Ideally this doesn't need to happen, but it seems not doing this makes the multiblock tests flakey + */ + public static void formMultiblock(MultiblockControllerMachine controller) { + controller.getPattern().checkPatternAt(controller.getMultiblockState(), false); + controller.onStructureFormed(); + } + + /** + * Creates a dummy recipe type that also includes a basic, HV, 1 tick, cobblestone -> stone recipe + * Requires a {@link GTRecipeType} to inherit I/O counts from + */ + public static GTRecipeType createRecipeTypeAndInsertRecipe(String name, GTRecipeType original) { + GTRecipeType type = createRecipeType(name, original); + type.getLookup().addRecipe(type + .recipeBuilder(GTCEu.id("test_recipe")) + .inputItems(new ItemStack(Items.COBBLESTONE)) + .outputItems(new ItemStack(Blocks.STONE)) + .EUt(GTValues.V[GTValues.HV]) + .duration(1).build()); + return type; + } + + /** + * Creates a dummy recipe type. Safe for use in recipe lookup. + * DO NOT USE THIS FOR MACHINE RECIPES. Use {@link #createRecipeType(String, GTRecipeType)} for that. + */ + @Deprecated + public static GTRecipeType createRecipeType(String name) { + return createRecipeType(name, 2, 2, 2, 2); + } + + /** + * Creates a recipe type for writing test cases. + * Requires a {@link GTRecipeType} to inherit I/O counts from. + */ + public static GTRecipeType createRecipeType(String name, GTRecipeType original) { + return createRecipeType(name, + original.getMaxInputs(ItemRecipeCapability.CAP), + original.getMaxOutputs(ItemRecipeCapability.CAP), + original.getMaxInputs(FluidRecipeCapability.CAP), + original.getMaxOutputs(FluidRecipeCapability.CAP)); + } + + /** + * Creates a recipe type for writing test cases. + * Requires setting I/O counts manually. + * You probably want to be using {@link #createRecipeType(String, GTRecipeType)} + */ + public static GTRecipeType createRecipeType(String name, int maxInputs, int maxOutputs, int maxFluidInputs, + int maxFluidOutputs) { + if (BuiltInRegistries.RECIPE_TYPE.containsKey(GTCEu.id(name))) + return (GTRecipeType) BuiltInRegistries.RECIPE_TYPE.get(GTCEu.id(name)); + ((MappedRegistry) GTRegistries.RECIPE_CATEGORIES).unfreeze(); + ((MappedRegistry>) BuiltInRegistries.RECIPE_TYPE).unfreeze(); + GTRecipeType type = new GTRecipeType(GTCEu.id(name), ELECTRIC, RecipeType.SMELTING) + .setEUIO(IO.IN) + .setMaxIOSize(maxInputs, maxOutputs, maxFluidInputs, maxFluidOutputs); + + ((MappedRegistry) GTRegistries.RECIPE_CATEGORIES).freeze(); + ((MappedRegistry>) BuiltInRegistries.RECIPE_TYPE).freeze(); + return type; + } + + public static CoverBehavior placeCover(GameTestHelper helper, MetaMachine machine, ItemStack stack, + Direction direction) { + return placeCover(helper, machine, stack, direction, false); + } + + public static CoverBehavior placeCover(GameTestHelper helper, MetaMachine machine, ItemStack stack, + Direction direction, boolean shouldFail) { + CoverDefinition coverDefinition = null; + if (stack.getItem() instanceof IComponentItem componentItem) { + for (IItemComponent component : componentItem.getComponents()) { + if (component instanceof CoverPlaceBehavior coverPlaceBehavior) { + helper.assertTrue(coverDefinition == null, "stack has multiple coverPlaceBehaviours"); + coverDefinition = coverPlaceBehavior.coverDefinition(); + } + } + } + helper.assertTrue(coverDefinition != null, "attempted to place cover with item that is not a cover"); + assert coverDefinition != null; + helper.assertTrue(shouldFail ^ machine.getCoverContainer().placeCoverOnSide( + direction, stack, coverDefinition, null), "failed to place cover"); + return machine.getCoverContainer().getCoverAtSide(direction); + } + + public static MetaMachine setMachine(GameTestHelper helper, BlockPos pos, MachineDefinition machineDefinition) { + helper.setBlock(pos, machineDefinition.getBlock()); + return ((IMachineBlockEntity) Objects.requireNonNull(helper.getBlockEntity(pos))).getMetaMachine(); + } + + public static void assertEqual(GameTestHelper helper, List text, String s) { + MultiLineComponent component = new MultiLineComponent(text); + helper.assertTrue(component.equalsString(s), + "strings not equal: \"%s\" != \"%s\"".formatted(component.toString(), s)); + } + + public static void assertEqual(GameTestHelper helper, ItemStack stack1, ItemStack stack2) { + helper.assertTrue(isItemStackEqual(stack1, stack2), + "Item stacks not equal: \"%s\" != \"%s\"".formatted(stack1.toString(), stack2.toString())); + } + + public static void assertEqual(GameTestHelper helper, FluidStack stack1, FluidStack stack2) { + helper.assertTrue(stack1.isFluidStackIdentical(stack2), + "Fluid stacks not equal: \"%s %d\" != \"%s %d\"".formatted( + stack1.getDisplayName().getString(), stack1.getAmount(), + stack2.getDisplayName().getString(), stack2.getAmount())); + } + + public static void assertLampOn(GameTestHelper helper, BlockPos pos) { + helper.assertBlockProperty(pos, RedstoneLampBlock.LIT, true); + } + + public static void assertLampOff(GameTestHelper helper, BlockPos pos) { + helper.assertBlockProperty(pos, RedstoneLampBlock.LIT, false); + } + + /** + * Shortcut function to retrieve a metamachine from a blockentity's + * + * @param entity The MetaMachineBlockEntity + * @return the machine held, if any + */ + public static MetaMachine getMetaMachine(BlockEntity entity) { + return ((MetaMachineBlockEntity) entity).getMetaMachine(); + } + + /** + * Helper function to succeed after the test is over + * + * @param helper GameTestHelper + */ + public static void succeedAfterTest(GameTestHelper helper) { + succeedAfterTest(helper, 100); + } + + /** + * Helper function to succeed after the test is over + * + * @param helper GameTestHelper + * @param timeout Ticks to wait until succeeding + */ + public static void succeedAfterTest(GameTestHelper helper, long timeout) { + helper.runAtTickTime(timeout, helper::succeed); + } + + public static void assertEqual(GameTestHelper helper, @Nullable BlockPos pos1, @Nullable BlockPos pos2) { + helper.assertTrue(pos1 != null && pos1.equals(pos2), "Expected %s to equal to %s".formatted(pos1, pos2)); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/gametest/world/RealWorldItemUsage.java b/src/test/java/com/gregtechceu/gtceu/gametest/world/RealWorldItemUsage.java new file mode 100644 index 00000000000..a737dc0924b --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/gametest/world/RealWorldItemUsage.java @@ -0,0 +1,73 @@ +package com.gregtechceu.gtceu.gametest.world; + +import com.gregtechceu.gtceu.GTCEu; + +import net.minecraft.commands.arguments.EntityAnchorArgument.Anchor; +import net.minecraft.core.BlockPos; +import net.minecraft.core.registries.Registries; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.GameType; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.phys.Vec3; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; +import net.neoforged.testframework.gametest.ExtendedGameTestHelper; +import net.neoforged.testframework.gametest.GameTestPlayer; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class RealWorldItemUsage { + + public static void lookAndBreak(GameTestPlayer player, ExtendedGameTestHelper helper, BlockPos pos) { + player.lookAt(Anchor.EYES, helper.absoluteVec(pos.getCenter())); + helper.runAfterDelay(1, () -> { + helper.breakBlock(pos, player.getMainHandItem(), player); + }); + } + + @GameTest(template = "empty_5x5") + public static void testPickaxeInstantPickup(GameTestHelper _helper) { + var helper = new ExtendedGameTestHelper(_helper.testInfo); + var player = helper.makeTickingMockServerPlayerInLevel(GameType.SURVIVAL); + player.moveTo(helper.absoluteVec(new Vec3(2.5, 2.0, 2.5))); + player.setItemSlot(EquipmentSlot.MAINHAND, + new ItemStack(helper.getLevel().registryAccess().registry(Registries.ITEM).orElseThrow() + .getOrThrow(ResourceKey.create(Registries.ITEM, GTCEu.id("neutronium_pickaxe"))))); + // Allow player to stand + helper.setBlock(new BlockPos(2, 1, 2), Blocks.BEDROCK); + // Blocks to break + BlockPos[] positions = { + new BlockPos(1, 1, 1), + new BlockPos(1, 1, 2), + new BlockPos(1, 1, 3), + new BlockPos(2, 1, 1), + new BlockPos(2, 1, 3), + new BlockPos(3, 1, 1), + new BlockPos(3, 1, 2), + new BlockPos(3, 1, 3), }; + for (var pos : positions) { + helper.setBlock(pos, Blocks.STONE); + } + long i = 0; + for (var pos : positions) { + helper.runAtTickTime(i * 2, () -> { + lookAndBreak(player, helper, pos); + }); + i += 1; + } + helper.runAtTickTime(i * 2 + 8, () -> { + helper.assertPlayerHasItem(player, Items.COBBLESTONE); + helper.assertBlockState(new BlockPos(1, 1, 1), BlockBehaviour.BlockStateBase::isAir, () -> "Expected air!"); + var slot = player.getInventory().findSlotMatchingItem(new ItemStack(Items.COBBLESTONE)); + helper.assertTrue(player.getSlot(slot).get().getCount() == positions.length, + "Player should have picked up four cobblestone"); + helper.succeed(); + }); + } +} diff --git a/src/test/java/com/gregtechceu/gtceu/integration/ae2/machine/PatternBufferTest.java b/src/test/java/com/gregtechceu/gtceu/integration/ae2/machine/PatternBufferTest.java new file mode 100644 index 00000000000..ccb9c4c5791 --- /dev/null +++ b/src/test/java/com/gregtechceu/gtceu/integration/ae2/machine/PatternBufferTest.java @@ -0,0 +1,233 @@ +package com.gregtechceu.gtceu.integration.ae2.machine; + +import com.gregtechceu.gtceu.GTCEu; +import com.gregtechceu.gtceu.api.GTValues; +import com.gregtechceu.gtceu.api.machine.multiblock.WorkableMultiblockMachine; +import com.gregtechceu.gtceu.api.recipe.GTRecipeType; +import com.gregtechceu.gtceu.common.machine.multiblock.part.FluidHatchPartMachine; +import com.gregtechceu.gtceu.common.machine.multiblock.part.ItemBusPartMachine; +import com.gregtechceu.gtceu.data.recipe.GTRecipeTypes; +import com.gregtechceu.gtceu.gametest.util.TestUtils; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.gametest.framework.BeforeBatch; +import net.minecraft.gametest.framework.GameTest; +import net.minecraft.gametest.framework.GameTestHelper; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.Blocks; +import net.neoforged.neoforge.gametest.GameTestHolder; +import net.neoforged.neoforge.gametest.PrefixGameTestTemplate; + +import appeng.api.networking.IGrid; +import appeng.api.networking.crafting.CalculationStrategy; +import appeng.api.networking.crafting.ICraftingPlan; +import appeng.api.networking.crafting.ICraftingService; +import appeng.api.networking.crafting.ICraftingSubmitResult; +import appeng.api.networking.security.IActionSource; +import appeng.api.stacks.AEItemKey; +import appeng.blockentity.networking.CableBusBlockEntity; +import appeng.parts.encoding.PatternEncodingTerminalPart; + +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import static com.gregtechceu.gtceu.gametest.util.TestUtils.getMetaMachine; + +@PrefixGameTestTemplate(false) +@GameTestHolder(GTCEu.MOD_ID) +public class PatternBufferTest { + + private static GTRecipeType LCR_RECIPE_TYPE; + + @BeforeBatch(batch = "PatternBuffer") + public static void prepare(ServerLevel level) { + LCR_RECIPE_TYPE = TestUtils.createRecipeTypeAndInsertRecipe("pattern_buffer_tests", + GTRecipeTypes.LARGE_CHEMICAL_RECIPES); + + LCR_RECIPE_TYPE.getLookup().addRecipe(LCR_RECIPE_TYPE + .recipeBuilder(GTCEu.id("test_recipe_pattern_buffer")) + .id(GTCEu.id("test_recipe_pattern_buffer")) + .inputItems(new ItemStack(Items.RED_BED)) + .outputItems(new ItemStack(Blocks.BROWN_BED)) + .EUt(GTValues.V[GTValues.EV]) + .duration(1).build()); + } + + private record BusHolder(ItemBusPartMachine inputBus1, ItemBusPartMachine inputBus2, ItemBusPartMachine outputBus1, + FluidHatchPartMachine outputHatch1, MEPatternBufferPartMachine patternBuffer, + WorkableMultiblockMachine controller) {} + + /** + * Retrieves the busses for this specific template and force a multiblock structure check + * + * @param helper the GameTestHelper + * @return the busses, in the BusHolder record. + */ + private static BusHolder getBussesAndForm(GameTestHelper helper) { + WorkableMultiblockMachine controller = (WorkableMultiblockMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(1, 2, 0))); + TestUtils.formMultiblock(controller); + controller.setRecipeType(LCR_RECIPE_TYPE); + ItemBusPartMachine inputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 1, 0))); + ItemBusPartMachine inputBus2 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 2, 0))); + ItemBusPartMachine outputBus1 = (ItemBusPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 1, 0))); + FluidHatchPartMachine outputHatch1 = (FluidHatchPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(0, 2, 0))); + MEPatternBufferPartMachine patternBuffer = (MEPatternBufferPartMachine) getMetaMachine( + helper.getBlockEntity(new BlockPos(2, 2, 1))); + patternBuffer.getTerminalPatternInventory().setItemDirect(0, + patternBuffer.getTerminalPatternInventory().getStackInSlot(0)); + return new BusHolder(inputBus1, inputBus2, outputBus1, outputHatch1, patternBuffer, controller); + } + + // Test for putting ingredient on the normal input bus when the pattern buffer exists on machine + @GameTest(template = "patternbuffertest", batch = "PatternBuffer", setupTicks = 40, timeoutTicks = 200) + public static void patternBufferNormalInputBusTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.patternBuffer.getPatternInventory().onContentsChanged(0); + busHolder.inputBus1.getInventory().setStackInSlot(0, new ItemStack(Blocks.COBBLESTONE)); + helper.succeedWhen(() -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Crafting items in same bus failed, expected STONE but was " + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + } + + // Test for checking if pattern buffers work at all + @GameTest(template = "patternbuffertest", batch = "PatternBuffer", setupTicks = 40, timeoutTicks = 200) + public static void patternBufferBasicRequestTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.patternBuffer.getPatternInventory().onContentsChanged(0); + + IGrid grid = busHolder.patternBuffer.getGrid(); + + ICraftingService craftingService = grid.getCraftingService(); + + CableBusBlockEntity cbbe = (CableBusBlockEntity) helper.getBlockEntity(new BlockPos(3, 2, 1)); + PatternEncodingTerminalPart terminal = (PatternEncodingTerminalPart) cbbe.getCableBus() + .getPart(Direction.NORTH); + + Future plan = craftingService.beginCraftingCalculation( + helper.getLevel(), + () -> IActionSource.ofMachine(terminal), + AEItemKey.of(Items.STONE), + 1, + CalculationStrategy.REPORT_MISSING_ITEMS); + + helper.runAfterDelay(40, () -> { + ICraftingPlan job; + try { + job = plan.get(5, TimeUnit.SECONDS); + } catch (Exception e) { + helper.fail("Job didn't get queued in 40 ticks"); + throw new RuntimeException("Oopsie, could not get job to start craft"); + } + ICraftingSubmitResult result = craftingService.submitJob(job, null, null, true, IActionSource.empty()); + + helper.assertTrue(result.successful(), "Could not queue crafting job"); + + helper.succeedWhen(() -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Crafting items in same bus failed, expected STONE but was " + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + }); + } + + // Test for checking if pattern buffers work if you set distinct + @GameTest(template = "patternbuffertest", batch = "PatternBuffer", setupTicks = 40, timeoutTicks = 200) + public static void patternBufferDistinctDoesNothingTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.patternBuffer.setDistinct(true); + + IGrid grid = busHolder.patternBuffer.getGrid(); + + ICraftingService craftingService = grid.getCraftingService(); + + CableBusBlockEntity cbbe = (CableBusBlockEntity) helper.getBlockEntity(new BlockPos(3, 2, 1)); + PatternEncodingTerminalPart terminal = (PatternEncodingTerminalPart) cbbe.getCableBus() + .getPart(Direction.NORTH); + + Future plan = craftingService.beginCraftingCalculation( + helper.getLevel(), + () -> IActionSource.ofMachine(terminal), + AEItemKey.of(Items.STONE), + 1, + CalculationStrategy.REPORT_MISSING_ITEMS); + + helper.runAfterDelay(40, () -> { + ICraftingPlan job; + try { + job = plan.get(5, TimeUnit.SECONDS); + } catch (Exception e) { + helper.fail("Job didn't get queued in 40 ticks"); + throw new RuntimeException("Oopsie, could not get job to start craft"); + } + ICraftingSubmitResult result = craftingService.submitJob(job, null, null, true, + IActionSource.ofMachine(terminal)); + + helper.assertTrue(result.successful(), "Could not queue crafting job"); + + helper.succeedWhen(() -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Crafting items in same bus failed, expected STONE but was " + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + }); + } + + // Test for checking if pattern buffers work if you dye them + @GameTest(template = "patternbuffertest", batch = "PatternBuffer", setupTicks = 40, timeoutTicks = 200) + public static void patternBufferDyeingDoesNothingTest(GameTestHelper helper) { + BusHolder busHolder = getBussesAndForm(helper); + busHolder.patternBuffer.setPaintingColor(0xff); + + IGrid grid = busHolder.patternBuffer.getGrid(); + + ICraftingService craftingService = grid.getCraftingService(); + + CableBusBlockEntity cbbe = (CableBusBlockEntity) helper.getBlockEntity(new BlockPos(3, 2, 1)); + PatternEncodingTerminalPart terminal = (PatternEncodingTerminalPart) cbbe.getCableBus() + .getPart(Direction.NORTH); + + Future plan = craftingService.beginCraftingCalculation( + helper.getLevel(), + () -> IActionSource.ofMachine(terminal), + AEItemKey.of(Items.STONE), + 1, + CalculationStrategy.REPORT_MISSING_ITEMS); + + helper.runAfterDelay(40, () -> { + ICraftingPlan job; + try { + job = plan.get(5, TimeUnit.SECONDS); + } catch (Exception e) { + helper.fail("Job didn't get queued in 40 ticks"); + throw new RuntimeException("Oopsie, could not get job to start craft"); + } + ICraftingSubmitResult result = craftingService.submitJob(job, null, null, true, IActionSource.empty()); + + helper.assertTrue(result.successful(), "Could not queue crafting job"); + + helper.succeedWhen(() -> { + helper.assertTrue( + TestUtils.isItemStackEqual(busHolder.outputBus1.getInventory().getStackInSlot(0), + new ItemStack(Blocks.STONE)), + "Crafting items in same bus failed, expected STONE but was " + + busHolder.outputBus1.getInventory().getStackInSlot(0).getDisplayName()); + }); + }); + } +} diff --git a/src/test/resources/data/gtceu/structure/ass_line_4aev_4in.nbt b/src/test/resources/data/gtceu/structure/ass_line_4aev_4in.nbt new file mode 100644 index 00000000000..72a3c7b657a Binary files /dev/null and b/src/test/resources/data/gtceu/structure/ass_line_4aev_4in.nbt differ diff --git a/src/test/resources/data/gtceu/structure/central_monitor.nbt b/src/test/resources/data/gtceu/structure/central_monitor.nbt new file mode 100644 index 00000000000..252ce8f8a05 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/central_monitor.nbt differ diff --git a/src/test/resources/data/gtceu/structure/charged_hv_rock_breaker.nbt b/src/test/resources/data/gtceu/structure/charged_hv_rock_breaker.nbt new file mode 100644 index 00000000000..2da78bad801 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/charged_hv_rock_breaker.nbt differ diff --git a/src/test/resources/data/gtceu/structure/electrolyzer.nbt b/src/test/resources/data/gtceu/structure/electrolyzer.nbt new file mode 100644 index 00000000000..5bad1f0d681 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/electrolyzer.nbt differ diff --git a/src/test/resources/data/gtceu/structure/empty.nbt b/src/test/resources/data/gtceu/structure/empty.nbt new file mode 100644 index 00000000000..7234628794b Binary files /dev/null and b/src/test/resources/data/gtceu/structure/empty.nbt differ diff --git a/src/test/resources/data/gtceu/structure/empty_5x5.nbt b/src/test/resources/data/gtceu/structure/empty_5x5.nbt new file mode 100644 index 00000000000..08994623c64 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/empty_5x5.nbt differ diff --git a/src/test/resources/data/gtceu/structure/energy/lcr_16a_4a_ev.nbt b/src/test/resources/data/gtceu/structure/energy/lcr_16a_4a_ev.nbt new file mode 100644 index 00000000000..bbcbd6c5cb6 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/energy/lcr_16a_4a_ev.nbt differ diff --git a/src/test/resources/data/gtceu/structure/energy/lcr_16a_ev.nbt b/src/test/resources/data/gtceu/structure/energy/lcr_16a_ev.nbt new file mode 100644 index 00000000000..84c2453dbbd Binary files /dev/null and b/src/test/resources/data/gtceu/structure/energy/lcr_16a_ev.nbt differ diff --git a/src/test/resources/data/gtceu/structure/energy/lcr_16a_ev_hv.nbt b/src/test/resources/data/gtceu/structure/energy/lcr_16a_ev_hv.nbt new file mode 100644 index 00000000000..da8489fa420 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/energy/lcr_16a_ev_hv.nbt differ diff --git a/src/test/resources/data/gtceu/structure/energy/lcr_2x_ev.nbt b/src/test/resources/data/gtceu/structure/energy/lcr_2x_ev.nbt new file mode 100644 index 00000000000..3aa2b5c1578 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/energy/lcr_2x_ev.nbt differ diff --git a/src/test/resources/data/gtceu/structure/energy/lcr_4a_ev.nbt b/src/test/resources/data/gtceu/structure/energy/lcr_4a_ev.nbt new file mode 100644 index 00000000000..8cca60e4772 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/energy/lcr_4a_ev.nbt differ diff --git a/src/test/resources/data/gtceu/structure/energy/lcr_ev_hv.nbt b/src/test/resources/data/gtceu/structure/energy/lcr_ev_hv.nbt new file mode 100644 index 00000000000..414a0124942 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/energy/lcr_ev_hv.nbt differ diff --git a/src/test/resources/data/gtceu/structure/energy/lcr_ev_mv.nbt b/src/test/resources/data/gtceu/structure/energy/lcr_ev_mv.nbt new file mode 100644 index 00000000000..a72b6540056 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/energy/lcr_ev_mv.nbt differ diff --git a/src/test/resources/data/gtceu/structure/energy/lcr_iv_16a_ev.nbt b/src/test/resources/data/gtceu/structure/energy/lcr_iv_16a_ev.nbt new file mode 100644 index 00000000000..af44df3fc02 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/energy/lcr_iv_16a_ev.nbt differ diff --git a/src/test/resources/data/gtceu/structure/large_centrifuge_zpm_batch_parallel16.nbt b/src/test/resources/data/gtceu/structure/large_centrifuge_zpm_batch_parallel16.nbt new file mode 100644 index 00000000000..d8a1be28dec Binary files /dev/null and b/src/test/resources/data/gtceu/structure/large_centrifuge_zpm_batch_parallel16.nbt differ diff --git a/src/test/resources/data/gtceu/structure/lcr.nbt b/src/test/resources/data/gtceu/structure/lcr.nbt new file mode 100644 index 00000000000..0d80abad927 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/lcr.nbt differ diff --git a/src/test/resources/data/gtceu/structure/lcr_input_separation.nbt b/src/test/resources/data/gtceu/structure/lcr_input_separation.nbt new file mode 100644 index 00000000000..08cecd58932 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/lcr_input_separation.nbt differ diff --git a/src/test/resources/data/gtceu/structure/lcr_ranged_ingredients.nbt b/src/test/resources/data/gtceu/structure/lcr_ranged_ingredients.nbt new file mode 100644 index 00000000000..4d66dd54a86 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/lcr_ranged_ingredients.nbt differ diff --git a/src/test/resources/data/gtceu/structure/patternbuffertest.nbt b/src/test/resources/data/gtceu/structure/patternbuffertest.nbt new file mode 100644 index 00000000000..7017b6723f7 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/patternbuffertest.nbt differ diff --git a/src/test/resources/data/gtceu/structure/patternbuffertest.nbt.old b/src/test/resources/data/gtceu/structure/patternbuffertest.nbt.old new file mode 100644 index 00000000000..2727a885a69 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/patternbuffertest.nbt.old differ diff --git a/src/test/resources/data/gtceu/structure/singleblock_charged_cr.nbt b/src/test/resources/data/gtceu/structure/singleblock_charged_cr.nbt new file mode 100644 index 00000000000..5f4609bfe5e Binary files /dev/null and b/src/test/resources/data/gtceu/structure/singleblock_charged_cr.nbt differ diff --git a/src/test/resources/data/gtceu/structure/singleblock_chem_reactor.nbt b/src/test/resources/data/gtceu/structure/singleblock_chem_reactor.nbt new file mode 100644 index 00000000000..447bf77a531 Binary files /dev/null and b/src/test/resources/data/gtceu/structure/singleblock_chem_reactor.nbt differ