сборОЧКА
This commit is contained in:
commit
010856f3ae
BIN
EMI Create Schematics [1.0.1 Fabric 1.20.1].jar
Normal file
BIN
EMI Create Schematics [1.0.1 Fabric 1.20.1].jar
Normal file
Binary file not shown.
BIN
FarmersDelight-1.20.1-2.2.5+refabricated.jar
Normal file
BIN
FarmersDelight-1.20.1-2.2.5+refabricated.jar
Normal file
Binary file not shown.
BIN
Female-Gender-Mod-fabric-1.20-3.0.1.jar
Normal file
BIN
Female-Gender-Mod-fabric-1.20-3.0.1.jar
Normal file
Binary file not shown.
BIN
ForgeConfigAPIPort-v8.0.1-1.20.1-Fabric.jar
Normal file
BIN
ForgeConfigAPIPort-v8.0.1-1.20.1-Fabric.jar
Normal file
Binary file not shown.
BIN
ImmediatelyFast-Fabric-1.3.3+1.20.4.jar
Normal file
BIN
ImmediatelyFast-Fabric-1.3.3+1.20.4.jar
Normal file
Binary file not shown.
BIN
NetherSizeEquilifier-1.0.jar
Normal file
BIN
NetherSizeEquilifier-1.0.jar
Normal file
Binary file not shown.
BIN
NethersDelight-Refabricated-1.20.1-4.1.1.jar
Normal file
BIN
NethersDelight-Refabricated-1.20.1-4.1.1.jar
Normal file
Binary file not shown.
BIN
Steam_Rails-1.6.9+fabric-mc1.20.1.jar
Normal file
BIN
Steam_Rails-1.6.9+fabric-mc1.20.1.jar
Normal file
Binary file not shown.
BIN
XaerosWorldMap_1.39.2_Fabric_1.20.jar
Normal file
BIN
XaerosWorldMap_1.39.2_Fabric_1.20.jar
Normal file
Binary file not shown.
BIN
Xaeros_Minimap_25.0.0_Fabric_1.20.jar
Normal file
BIN
Xaeros_Minimap_25.0.0_Fabric_1.20.jar
Normal file
Binary file not shown.
BIN
YetAnotherConfigLib-3.6.2+1.20.1-fabric.jar
Normal file
BIN
YetAnotherConfigLib-3.6.2+1.20.1-fabric.jar
Normal file
Binary file not shown.
BIN
YungsApi-1.20-Fabric-4.0.6.jar
Normal file
BIN
YungsApi-1.20-Fabric-4.0.6.jar
Normal file
Binary file not shown.
BIN
YungsBetterDesertTemples-1.20-Fabric-3.0.3.jar
Normal file
BIN
YungsBetterDesertTemples-1.20-Fabric-3.0.3.jar
Normal file
Binary file not shown.
BIN
YungsBetterDungeons-1.20-Fabric-4.0.4.jar
Normal file
BIN
YungsBetterDungeons-1.20-Fabric-4.0.4.jar
Normal file
Binary file not shown.
BIN
YungsBetterJungleTemples-1.20-Fabric-2.0.5.jar
Normal file
BIN
YungsBetterJungleTemples-1.20-Fabric-2.0.5.jar
Normal file
Binary file not shown.
BIN
YungsBetterMineshafts-1.20-Fabric-4.0.4.jar
Normal file
BIN
YungsBetterMineshafts-1.20-Fabric-4.0.4.jar
Normal file
Binary file not shown.
BIN
YungsBetterNetherFortresses-1.20-Fabric-2.0.6.jar
Normal file
BIN
YungsBetterNetherFortresses-1.20-Fabric-2.0.6.jar
Normal file
Binary file not shown.
BIN
YungsBetterOceanMonuments-1.20-Fabric-3.0.4.jar
Normal file
BIN
YungsBetterOceanMonuments-1.20-Fabric-3.0.4.jar
Normal file
Binary file not shown.
BIN
YungsBetterStrongholds-1.20-Fabric-4.0.3.jar
Normal file
BIN
YungsBetterStrongholds-1.20-Fabric-4.0.3.jar
Normal file
Binary file not shown.
BIN
YungsBetterWitchHuts-1.20-Fabric-3.0.3.jar
Normal file
BIN
YungsBetterWitchHuts-1.20-Fabric-3.0.3.jar
Normal file
Binary file not shown.
BIN
Zoomify-2.14.2+1.20.1.jar
Normal file
BIN
Zoomify-2.14.2+1.20.1.jar
Normal file
Binary file not shown.
BIN
alternate-current-mc1.20-1.9.0.jar
Normal file
BIN
alternate-current-mc1.20-1.9.0.jar
Normal file
Binary file not shown.
BIN
appleskin-fabric-mc1.20.1-2.5.1.jar
Normal file
BIN
appleskin-fabric-mc1.20.1-2.5.1.jar
Normal file
Binary file not shown.
BIN
architectury-9.2.14-fabric.jar
Normal file
BIN
architectury-9.2.14-fabric.jar
Normal file
Binary file not shown.
BIN
balm-fabric-1.20.1-7.3.11.jar
Normal file
BIN
balm-fabric-1.20.1-7.3.11.jar
Normal file
Binary file not shown.
BIN
bellsandwhistles-0.4.5+1.20.1-FABRIC.jar
Normal file
BIN
bellsandwhistles-0.4.5+1.20.1-FABRIC.jar
Normal file
Binary file not shown.
BIN
bobby-5.0.1.jar
Normal file
BIN
bobby-5.0.1.jar
Normal file
Binary file not shown.
BIN
carryon-fabric-1.20.1-2.1.2.7.jar
Normal file
BIN
carryon-fabric-1.20.1-2.1.2.7.jar
Normal file
Binary file not shown.
BIN
cc-tweaked-1.20.1-fabric-1.114.3.jar
Normal file
BIN
cc-tweaked-1.20.1-fabric-1.114.3.jar
Normal file
Binary file not shown.
BIN
cccbridge-mc1.20.1-fabric-v1.6.2b.jar
Normal file
BIN
cccbridge-mc1.20.1-fabric-v1.6.2b.jar
Normal file
Binary file not shown.
BIN
cloth-config-11.1.136-fabric.jar
Normal file
BIN
cloth-config-11.1.136-fabric.jar
Normal file
Binary file not shown.
BIN
copycats-2.1.4+mc.1.20.1-fabric.jar
Normal file
BIN
copycats-2.1.4+mc.1.20.1-fabric.jar
Normal file
Binary file not shown.
BIN
create-fabric-0.5.1-j-build.1631+mc1.20.1.jar
Normal file
BIN
create-fabric-0.5.1-j-build.1631+mc1.20.1.jar
Normal file
Binary file not shown.
BIN
create-tempered-steel-1.3.jar
Normal file
BIN
create-tempered-steel-1.3.jar
Normal file
Binary file not shown.
BIN
create_enchantment_industry-1.2.16.jar
Normal file
BIN
create_enchantment_industry-1.2.16.jar
Normal file
Binary file not shown.
BIN
createaddition-fabric+1.20.1-1.2.4.jar
Normal file
BIN
createaddition-fabric+1.20.1-1.2.4.jar
Normal file
Binary file not shown.
5
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/.gitattributes
vendored
Normal file
5
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/.gitattributes
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# Disable autocrlf on generated files, they always generate with LF
|
||||
# Add any extra files or paths here to make git stop saying they
|
||||
# are changed when only line endings change.
|
||||
src/generated/**/.cache/cache text eol=lf
|
||||
src/generated/**/*.json text eol=lf
|
@ -0,0 +1,19 @@
|
||||
---
|
||||
name: Fabric Bug report
|
||||
about: Create bug template
|
||||
title: ''
|
||||
labels: bug, fabric
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
**Additional context**
|
||||
- Mod version:
|
||||
- Fabric version:
|
||||
- Create version:
|
@ -0,0 +1,19 @@
|
||||
---
|
||||
name: Forge Bug report
|
||||
about: Create bug template
|
||||
title: ''
|
||||
labels: bug, forge
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
|
||||
**Additional context**
|
||||
- Mod version:
|
||||
- Forge version:
|
||||
- Create version:
|
10
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/.github/ISSUE_TEMPLATE/suggestion.md
vendored
Normal file
10
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/.github/ISSUE_TEMPLATE/suggestion.md
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
name: Suggestion
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: suggestion
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
|
43
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/.github/workflows/gradle.yml
vendored
Normal file
43
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/.github/workflows/gradle.yml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
# This workflow will build a Java project with Gradle
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: Java CI with Gradle
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '8'
|
||||
distribution: 'adopt'
|
||||
- name: Cache Gradle packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Package
|
||||
path: build/libs
|
||||
- name: Cleanup Gradle Cache
|
||||
# Remove some files from the Gradle cache, so they aren't cached by GitHub Actions.
|
||||
# Restoring these files from a GitHub Actions cache might cause problems for future builds.
|
||||
run: rm -f ~/.gradle/caches/modules-2/modules-2.lock & rm -f ~/.gradle/caches/modules-2/gc.properties
|
22
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/.gitignore
vendored
Normal file
22
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/.gitignore
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
# eclipse
|
||||
bin
|
||||
*.launch
|
||||
.settings
|
||||
.metadata
|
||||
.classpath
|
||||
.project
|
||||
|
||||
# idea
|
||||
out
|
||||
*.ipr
|
||||
*.iws
|
||||
*.iml
|
||||
.idea
|
||||
|
||||
# gradle
|
||||
build
|
||||
.gradle
|
||||
|
||||
# other
|
||||
eclipse
|
||||
run
|
@ -0,0 +1,6 @@
|
||||
{
|
||||
"ExpandedNodes": [
|
||||
""
|
||||
],
|
||||
"PreviewInSolutionExplorer": false
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
@ -0,0 +1,277 @@
|
||||
# Create Crafts & Additions: Computercraft Peripheral API
|
||||
|
||||
Version 1.1
|
||||
|
||||
Supported Blocks:
|
||||
- [Electric Motor](#electric-motor)
|
||||
- [Accumulator](#accumulator)
|
||||
- [Portable Energy Interface](#portable-energy-interface-pei)
|
||||
- [Redstone Relay](#redstone-relay)
|
||||
- [Digital Adapter](#digital-adapter)
|
||||
- [Rotational Speed Controller](#rotational-speed-controller)
|
||||
- [Stressometer](#stressometer)
|
||||
- [Speedometer](#speedometer)
|
||||
- [Rope, Hose, and Elevator Pulley](#pulleys)
|
||||
- [Elevator Pulley](#elevator-pulley)
|
||||
- [Mechanical Piston](#mechanical-piston)
|
||||
- [Mechanical Bearing](#mechanical-bearing)
|
||||
- [Display Link](#display-link)
|
||||
- [Other](#other)
|
||||
|
||||
## Other Languages
|
||||
[简体中文 (Simplified Chinese)](COMPUTERCRAFT_zh-CN.md)
|
||||
|
||||
# Electric Motor
|
||||
To set the speed of the Electric Motor, call `setSpeed(rpm)` where the argument *rpm* is a number between `-256` and `256`. The function will throw an exception if it is called too many times per second.
|
||||
```lua
|
||||
motor.setSpeed(rpm)
|
||||
```
|
||||
The function `stop()` is a shorthand for `setSpeed(0)`.
|
||||
```lua
|
||||
motor.stop()
|
||||
```
|
||||
In the following example, the motor attached to the left of the computer will rotate at 32RPM for 5 seconds and then stop.
|
||||
```lua
|
||||
local motor = peripheral.wrap("left")
|
||||
motor.setSpeed(32)
|
||||
sleep(5)
|
||||
motor.stop()
|
||||
```
|
||||
|
||||
The function `rotate(degrees, [rpm])` will return the time it will take to rotate the shaft by the argument *degrees* at the current speed. If the optional argument *rpm* is given it will set the speed of the motor and return the rotation time at the new speed.
|
||||
```lua
|
||||
motor.setSpeed(32)
|
||||
sleep(motor.rotate(90))
|
||||
motor.stop()
|
||||
```
|
||||
In the following example, the motor will first rotate 180 degrees in the clockwise direction, then 180 degrees at half the speed in the anti-clockwise direction and then finaly stop.
|
||||
```lua
|
||||
local motor = peripheral.wrap("left")
|
||||
sleep(motor.rotate(180, 32))
|
||||
sleep(motor.rotate(-180, 16))
|
||||
motor.stop()
|
||||
```
|
||||
|
||||
The function `translate(blocks, [rpm])` will return the time it will take to rotate the shaft to push a piston or gantry shaft by distance given by the argument *blocks* at the current speed. If the optional argument *rpm* is given it will set the speed of the motor and return the action time at the new speed.
|
||||
```lua
|
||||
motor.setSpeed(32)
|
||||
sleep(motor.translate(5))
|
||||
motor.stop()
|
||||
```
|
||||
In the following example, the motor attached to a piston will extend the piston by 5 blocks, stop for a second, retract, and then finally stop.
|
||||
```lua
|
||||
local motor = peripheral.wrap("left")
|
||||
sleep(motor.translate(5, 32))
|
||||
sleep(1)
|
||||
sleep(motor.translate(-5, 32))
|
||||
motor.stop()
|
||||
```
|
||||
|
||||
The function `getSpeed()` will return the current motor speed.
|
||||
```lua
|
||||
local rpm = motor.getSpeed()
|
||||
```
|
||||
The function `getStressCapacity()` will return the produced stress capacity (output su).
|
||||
```lua
|
||||
local su = motor.getStressCapacity()
|
||||
```
|
||||
The function `getEnergyConsumption()` will return the motor energy consumption in FE/t.
|
||||
```lua
|
||||
local fe = motor.getEnergyConsumption()
|
||||
```
|
||||
The function `getMaxInsert()` will return the Motor max input in fe.
|
||||
```lua
|
||||
local fe = motor.getMaxInsert()
|
||||
```
|
||||
The function `getMaxExtract()` will return the Motor max output in fe (Always 0).
|
||||
```lua
|
||||
local fe = motor.getMaxExtract()
|
||||
```
|
||||
The function `getType()` will return the motor peripheral name, which will always be "electric_motor".
|
||||
```lua
|
||||
print("Peripheral: " .. motor.getType())
|
||||
```
|
||||
# Accumulator
|
||||
In the following example, we get the peripheral of an Accumulator on the left.
|
||||
```lua
|
||||
local accumulator = peripheral.wrap("left")
|
||||
```
|
||||
The function `getEnergy()` will return the accumulator total stored charge in fe.
|
||||
```lua
|
||||
local fe = accumulator.getEnergy()
|
||||
```
|
||||
The function `getCapacity()` will return the accumulator total capacity in fe.
|
||||
```lua
|
||||
local fe = accumulator.getCapacity()
|
||||
```
|
||||
The function `getPercent()` will return the accumulator total charge in relation to the total capacity in percent.
|
||||
```lua
|
||||
local percent = accumulator.getPercent()
|
||||
```
|
||||
The function `getMaxInsert()` will return the accumulator max input per block face in fe.
|
||||
```lua
|
||||
local fe = accumulator.getMaxInsert()
|
||||
```
|
||||
The function `getMaxExtract()` will return the accumulator max output per block face in fe.
|
||||
```lua
|
||||
local fe = accumulator.getMaxExtract()
|
||||
```
|
||||
The function `getHeight()` will return the accumulator height in block.
|
||||
```lua
|
||||
local blocks = accumulator.getHeight()
|
||||
```
|
||||
The function `getWidth()` will return the accumulator width in block.
|
||||
```lua
|
||||
local blocks = accumulator.getWidth()
|
||||
```
|
||||
The function `getType()` will return the accumulator peripheral name, which will always be "modular_accumulator".
|
||||
```lua
|
||||
print("Peripheral: " .. accumulator.getType())
|
||||
```
|
||||
# Portable Energy Interface (PEI)
|
||||
In the following example, we get the peripheral of a PEI on the left.
|
||||
```lua
|
||||
local pei = peripheral.wrap("left")
|
||||
```
|
||||
The function `getEnergy()` will return the connected contraption total stored charge in fe, (-1 if not connected).
|
||||
```lua
|
||||
local fe = pei.getEnergy()
|
||||
```
|
||||
The function `getCapacity()` will return the connected contraption total capacity in fe, (-1 if not connected).
|
||||
```lua
|
||||
local fe = pei.getCapacity()
|
||||
```
|
||||
The function `isConnected()` will return true if a contraption is connected.
|
||||
```lua
|
||||
local connected = pei.isConnected()
|
||||
```
|
||||
The function `getMaxInsert()` will return the PEI max input in fe.
|
||||
```lua
|
||||
local fe = accumulator.getMaxInsert()
|
||||
```
|
||||
The function `getMaxExtract()` will return the PEI max output in fe.
|
||||
```lua
|
||||
local fe = accumulator.getMaxExtract()
|
||||
```
|
||||
The function `getType()` will return the PEI peripheral name, which will always be "portable_energy_interface".
|
||||
```lua
|
||||
print("Peripheral: " .. pei.getType())
|
||||
```
|
||||
# Redstone Relay
|
||||
In the following example, we get the peripheral of a Redstone Relay on the left.
|
||||
```lua
|
||||
local relay = peripheral.wrap("left")
|
||||
```
|
||||
The function `getMaxInsert()` will return the Relay max input in fe.
|
||||
```lua
|
||||
local fe = relay.getMaxInsert()
|
||||
```
|
||||
The function `getMaxExtract()` will return the Relay max output in fe.
|
||||
```lua
|
||||
local fe = relay.getMaxExtract()
|
||||
```
|
||||
The function `getThroughput()` will return the current throughput in fe.
|
||||
```lua
|
||||
local fe = relay.getThroughput()
|
||||
```
|
||||
The function `isPowered()` will return the redstone state of the Relay.
|
||||
```lua
|
||||
local powered = relay.isPowered()
|
||||
```
|
||||
The function `getType()` will return the Relay peripheral name, which will always be "redstone_relay".
|
||||
```lua
|
||||
print("Peripheral: " .. relay.getType())
|
||||
```
|
||||
# Digital Adapter
|
||||
In the following example, we get the peripheral of a Digital Adapter on the left.
|
||||
```lua
|
||||
local da = peripheral.wrap("left")
|
||||
```
|
||||
The function `getType()` will return the Adapter peripheral name, which will always be "digital_adapter".
|
||||
```lua
|
||||
print("Peripheral: " .. da.getType())
|
||||
```
|
||||
### Rotational Speed Controller
|
||||
The function `setTargetSpeed(side, speed)` will set the target speed of a Rotation Speed Controller attached to the side of a Digital Adapter.
|
||||
```lua
|
||||
da.setTargetSpeed("top", 64)
|
||||
```
|
||||
The function `getTargetSpeed(side, speed)` will get the target speed of a Rotation Speed Controller attached to the side of a Digital Adapter.
|
||||
```lua
|
||||
local speed = da.getTargetSpeed("top")
|
||||
```
|
||||
### Stressometer
|
||||
The function `getKineticStress(side)` will get the stress of a Stressometer attached to the side of a Digital Adapter.
|
||||
```lua
|
||||
local stress = da.getKineticStress("bottom")
|
||||
```
|
||||
The function `getKineticCapacity(side)` will get the stress capacity of a Stressometer attached to the side of a Digital Adapter.
|
||||
```lua
|
||||
local capacity = da.getKineticCapacity("bottom")
|
||||
```
|
||||
### Speedometer
|
||||
The function `getKineticSpeed(side)` will get the speed of a Speedometer attached to the side of a Digital Adapter.
|
||||
```lua
|
||||
local speed = da.getKineticSpeed("north")
|
||||
```
|
||||
The function `getKineticTopSpeed()` will get the top speed as set by Create.
|
||||
```lua
|
||||
local topSpeed = da.getKineticTopSpeed()
|
||||
```
|
||||
### Pulleys
|
||||
The function `getPulleyDistance(side)` will get the extended distance of a Rope, Hose, or Elevator -Pulley attached to the side of a Digital Adapter.
|
||||
```lua
|
||||
local blocks = da.getPulleyDistance("south")
|
||||
```
|
||||
### Elevator Pulley
|
||||
The function `getElevatorFloor(side)` will get the current floor index of an Elevator Pulley attached to the side of a Digital Adapter.
|
||||
```lua
|
||||
local floor = da.getElevatorFloor("south")
|
||||
```
|
||||
The function `getElevatorFloors(side)` will get the number of floors of an Elevator Pulley attached to the side of a Digital Adapter.
|
||||
```lua
|
||||
local floorCount = da.getElevatorFloors("south")
|
||||
```
|
||||
The function `getElevatorFloorName(side, index)` will get floor name at floor index of a Elevator Pulley attached to the side of a Digital Adapter.
|
||||
```lua
|
||||
local floorName = da.getElevatorFloorName("south", 0)
|
||||
```
|
||||
The function `gotoElevatorFloor(side, index)` will trigger a Elevator Pulley attached to the side of a Digital Adapter to move to the given floor index and returns the delta-y to move.
|
||||
```lua
|
||||
local floorName = da.gotoElevatorFloor("south", 0)
|
||||
```
|
||||
### Mechanical Piston
|
||||
The function `getPistonDistance(side)` will get the extended distance of a Mechanical Piston attached to the side of a Digital Adapter.
|
||||
```lua
|
||||
local blocks = da.getPistonDistance("east")
|
||||
```
|
||||
### Mechanical Bearing
|
||||
The function `getBearingAngle(side)` will get the angle of a Mechanical Bearing attached to the side of a Digital Adapter.
|
||||
```lua
|
||||
local degrees = da.getBearingAngle("west")
|
||||
```
|
||||
### Display Link
|
||||
The function `print(text)` will print a string on the currently selected line to an internal buffer which can be read by a Display Link and put on a Display Board, print will increment the currently selected line.
|
||||
```lua
|
||||
print("Hello World!")
|
||||
```
|
||||
The function `clearLine()` will clear the text on the currently selected line.
|
||||
|
||||
The function `clear()` will clear all the text on all lines.
|
||||
|
||||
The function `getLine()` will return the currently selected line (starts at 1).
|
||||
|
||||
The function `setLine(line)` will set the currently selected line to *line* (starts at 1).
|
||||
```lua
|
||||
da.print("Text on first line")
|
||||
da.print("Text on second line")
|
||||
da.setLine(1)
|
||||
da.print("Text on first line again")
|
||||
```
|
||||
The function `getMaxLines()` will return the max number of lines that can be displayable using the Digital Adapter (will always return 16).
|
||||
|
||||
### Other
|
||||
|
||||
The function `getDurationDistance(blocks, rpm)` will return the time needed to push a Mechanical Piston, Pulley or Gantry a number of blocks at the given rpm.
|
||||
|
||||
The function `getDurationAngle(degrees, rpm)` will return the time needed to rotate a Mechanical Bearing by a number of degrees at the given rpm.
|
@ -0,0 +1,258 @@
|
||||
# Create Crafts & Additions: Computercraft Peripheral API 中文版本
|
||||
|
||||
>If you are using English, please view [COMPUTERCRAFT.md](COMPUTERCRAFT.md). Links to other languages (if any) are in that file too.
|
||||
|
||||
>本文件为纯手动翻译,如有不足或错误欢迎修改。
|
||||
>我已经尽量保证译名与模组翻译文件同步。
|
||||
>内容可能不是最新,请以英文版本为准。
|
||||
|
||||
>This document is a purely manual translation. If there are any shortcomings or errors, please feel free to modify them.
|
||||
>I have tried my best to ensure that the translated name is synchronized with the mod translation file.
|
||||
>The content may not be the latest, please refer to the English version.
|
||||
|
||||
Version 1.1
|
||||
|
||||
支持的方块:
|
||||
- [电动马达](#电动马达)
|
||||
- [蓄电池](#蓄电池)
|
||||
- [移动式能量接口](#移动式能量接口-pei)
|
||||
- [红石继电器](#红石继电器)
|
||||
- [数字适配器](#数字适配器)
|
||||
- [速度表](#速度表)
|
||||
- [应力表](#应力表)
|
||||
- [绳索滑轮](#绳索滑轮)
|
||||
- [动力活塞](#动力活塞)
|
||||
- [动力轴承](#动力轴承)
|
||||
- [显示链接器](#显示链接器)
|
||||
- [Other](#other)
|
||||
|
||||
# 电动马达
|
||||
可以通过调用 `setSpeed(rpm)` 设置电动马达的速度。参数 *rpm* 是一个介于 `-256` 和 `256` 之间的数字。如果此函数在每秒被调用的次数过多,它会抛出一个异常。
|
||||
```lua
|
||||
motor.setSpeed(rpm)
|
||||
```
|
||||
函数 `stop()` 是 `setSpeed(0)` 的简写。
|
||||
```lua
|
||||
motor.stop()
|
||||
```
|
||||
在如下的例子中,连接到电脑左侧的电动马达会以 32RPM 旋转 5s 然后停止。
|
||||
```lua
|
||||
local motor = peripheral.wrap("left")
|
||||
motor.setSpeed(32)
|
||||
sleep(5)
|
||||
motor.stop()
|
||||
```
|
||||
|
||||
函数 `rotate(degrees, [rpm])` 会返回以当前速度将轴旋转 *degrees* 角度所需的时间。如果传递了可选的 *rpm* 参数,它会将电动马达设置到该速度并返回以新的速度将轴旋转 *degrees* 角度所需的时间。
|
||||
```lua
|
||||
motor.setSpeed(32)
|
||||
sleep(motor.rotate(90))
|
||||
motor.stop()
|
||||
```
|
||||
在如下的例子中,电机将首先沿顺时针方向旋转180度,然后沿逆时针方向以一半速度旋转180度,最终停止。
|
||||
```lua
|
||||
local motor = peripheral.wrap("left")
|
||||
sleep(motor.rotate(180, 32))
|
||||
sleep(motor.rotate(-180, 16))
|
||||
motor.stop()
|
||||
```
|
||||
|
||||
函数 `translate(blocks, [rpm])` 会返回以当前速度推动动力活塞或起重机移动 *blocks* 方块所需的时间。如果传递了可选的 *rpm* 参数,它会将电动马达设置到该速度并返回以新的速度完成动作所需的时间。
|
||||
```lua
|
||||
motor.setSpeed(32)
|
||||
sleep(motor.translate(5))
|
||||
motor.stop()
|
||||
```
|
||||
在如下的例子中,连接到动力活塞上的电机将使动力活塞推出 5 个方块的距离,等待一秒钟,缩回,最终停止。
|
||||
```lua
|
||||
local motor = peripheral.wrap("left")
|
||||
sleep(motor.translate(5, 32))
|
||||
sleep(1)
|
||||
sleep(motor.translate(-5, 32))
|
||||
motor.stop()
|
||||
```
|
||||
|
||||
函数 `getSpeed()` 会返回当前电动马达的速度。
|
||||
```lua
|
||||
local rpm = motor.getSpeed()
|
||||
```
|
||||
函数 `getStressCapacity()` 将返回产生的应力(单位:su)。
|
||||
```lua
|
||||
local su = motor.getStressCapacity()
|
||||
```
|
||||
函数 `getEnergyConsumption()` 将返回电动马达当前能耗(单位:FE/t)。
|
||||
```lua
|
||||
local fe = motor.getEnergyConsumption()
|
||||
```
|
||||
函数 `getMaxInsert()` 将返回电动马达的最大输入(单位:FE)。
|
||||
```lua
|
||||
local fe = motor.getMaxInsert()
|
||||
```
|
||||
函数 `getMaxExtract()` 将返回以FE为单位的电动马达最大输出(始终为0)。
|
||||
```lua
|
||||
local fe = motor.getMaxExtract()
|
||||
```
|
||||
函数 `getType()` 将返回电动马达的设备名称,该名称将始终为 "electric_motor"。
|
||||
```lua
|
||||
print("Peripheral: " .. motor.getType())
|
||||
```
|
||||
# 蓄电池
|
||||
在如下的例子中,我们获取左侧蓄电池的外围设备句柄。
|
||||
```lua
|
||||
local accumulator = peripheral.wrap("left")
|
||||
```
|
||||
函数 `getEnergy()` 会返回蓄电池已经存储的能量(单位:FE)。
|
||||
```lua
|
||||
local fe = accumulator.getEnergy()
|
||||
```
|
||||
函数 `getCapacity()` 会返回蓄电池的总容量(单位:FE)。
|
||||
```lua
|
||||
local fe = accumulator.getCapacity()
|
||||
```
|
||||
函数 `getPercent()` 将返回蓄电池相对于总容量的总充电量(单位:%)。
|
||||
```lua
|
||||
local percent = accumulator.getPercent()
|
||||
```
|
||||
函数 `getMaxInsert()` 将返回蓄电池每个方块表面的最大输入(单位:FE)。
|
||||
```lua
|
||||
local fe = accumulator.getMaxInsert()
|
||||
```
|
||||
函数 `getMaxExtract()` 将返回蓄电池每个方块表面的最大输出(单位:FE)。
|
||||
```lua
|
||||
local fe = accumulator.getMaxExtract()
|
||||
```
|
||||
函数 `getHeight()` 会返回蓄电池多方块结构的高度(单位:方块)。
|
||||
```lua
|
||||
local blocks = accumulator.getHeight()
|
||||
```
|
||||
函数 `getWidth()` 会返回蓄电池多方块结构的宽度(单位:块)。
|
||||
```lua
|
||||
local blocks = accumulator.getWidth()
|
||||
```
|
||||
函数 `getType()` 将返回蓄电池的设备名称,该名称将始终为 "modular_accumulator"。
|
||||
```lua
|
||||
print("Peripheral: " .. accumulator.getType())
|
||||
```
|
||||
# 移动式能量接口 (PEI)
|
||||
在如下的例子中, 我们可以获得一个左侧 PEI 的外围设备接口。
|
||||
```lua
|
||||
local pei = peripheral.wrap("left")
|
||||
```
|
||||
函数 `getEnergy()` 会返回连接的可移动结构已经存储的能量(-1 如果没有连接)(单位:FE)。
|
||||
```lua
|
||||
local fe = pei.getEnergy()
|
||||
```
|
||||
函数 `getCapacity()` 会返回连接的可移动结构的总容量(-1 如果没有连接)(单位:FE)。
|
||||
```lua
|
||||
local fe = pei.getCapacity()
|
||||
```
|
||||
函数 `isConnected()` 会在有可移动结构连接时返回 true 。
|
||||
```lua
|
||||
local connected = pei.isConnected()
|
||||
```
|
||||
函数 `getMaxInsert()` 会返回 PEI 的最大输入(单位:FE)。
|
||||
```lua
|
||||
local fe = accumulator.getMaxInsert()
|
||||
```
|
||||
函数 `getMaxExtract()` 会返回 PEI 的最大输出(单位:FE)。
|
||||
```lua
|
||||
local fe = accumulator.getMaxExtract()
|
||||
```
|
||||
函数 `getType()` 将返回 PEI 的设备名称,该名称将始终为 "portable_energy_interface".
|
||||
```lua
|
||||
print("Peripheral: " .. pei.getType())
|
||||
```
|
||||
# 红石继电器
|
||||
在如下的例子中, 我们可以获得一个左侧红石继电器的外围设备接口。
|
||||
```lua
|
||||
local relay = peripheral.wrap("left")
|
||||
```
|
||||
函数 `getMaxInsert()` 会返回继电器的最大输入(单位:FE)。
|
||||
```lua
|
||||
local fe = relay.getMaxInsert()
|
||||
```
|
||||
函数 `getMaxExtract()` 会返回继电器的最大输出(单位:FE)。
|
||||
```lua
|
||||
local fe = relay.getMaxExtract()
|
||||
```
|
||||
函数 `getThroughput()` 会返回继电器当前的流量(单位:FE)。
|
||||
```lua
|
||||
local fe = relay.getThroughput()
|
||||
```
|
||||
函数 `isPowered()` 会返回继电器的红石状态。
|
||||
```lua
|
||||
local powered = relay.isPowered()
|
||||
```
|
||||
函数 `getType()` 将返回红石继电器的外围设备名称,该名称将始终为 "redstone_relay".
|
||||
```lua
|
||||
print("Peripheral: " .. relay.getType())
|
||||
```
|
||||
函数 `getType()` 将返回数字适配器的外围设备名称,该名称将始终为 "digital_adapter"。
|
||||
```lua
|
||||
print("Peripheral: " .. da.getType())
|
||||
```
|
||||
### Rotation Speed Controller
|
||||
函数 `setTargetSpeed(side, speed)` 可以设置数字适配器的 *side* 面上的 转速控制器`(create:rotation_speed_conroller)` 的目标转速到 *speed*。
|
||||
```lua
|
||||
setTargetSpeed("top", 64)
|
||||
```
|
||||
函数 `getTargetSpeed(side, speed)` 可以获得数字适配器的 *side* 面上的 转速控制器 的目标转速到 *speed*。
|
||||
```lua
|
||||
local speed = da.getTargetSpeed("top")
|
||||
```
|
||||
### 应力表
|
||||
函数 `getKineticStress(side)` 可以获得数字适配器的 *side* 面上的 应力表`(create:stressometer)` 的当前应力。
|
||||
```lua
|
||||
local stress = da.getKineticStress("up")
|
||||
```
|
||||
函数 `getKineticCapacity(side)` 可以获得数字适配器的 *side* 面上的 应力表 的应力最大值。
|
||||
```lua
|
||||
local capacity = da.getKineticCapacity("up")
|
||||
```
|
||||
### 速度表
|
||||
函数 `getKineticSpeed(side)` 可以获得数字适配器的 *side* 面上的 速度表`(create:speedometer)` 的转速。
|
||||
```lua
|
||||
local speed = da.getKineticSpeed("up")
|
||||
```
|
||||
### 绳索滑轮
|
||||
函数 `getPulleyDistance(side)` 可以获得连接到数字适配器的 *side* 面的绳索滑轮的伸出长度。
|
||||
```lua
|
||||
local blocks = da.getPulleyDistance("south")
|
||||
```
|
||||
### 动力活塞
|
||||
函数 `getPistonDistance(side)` 可以获得连接到数字适配器的 *side* 面的动力活塞的伸出长度。
|
||||
```lua
|
||||
local blocks = da.getPistonDistance("east")
|
||||
```
|
||||
### 动力轴承
|
||||
函数 `getBearingAngle(side)` 可以获得连接到数字适配器的 *side* 面的动力轴承的角度。
|
||||
```lua
|
||||
local degrees = da.getBearingAngle("west")
|
||||
```
|
||||
### 显示链接器
|
||||
函数 `print(text)` 将当前所选行上的字符串打印到内部缓冲区,该缓冲区可由 显示链接器`(create:display_link)` 读取并显示到 翻牌显示器`(create:display_board)` 上,打印将在当前所选行追加。
|
||||
|
||||
>_此段不保证完全准确,因为我无法准确翻译最后一句。请以英文文档为准。_
|
||||
```lua
|
||||
print("Hello World!")
|
||||
```
|
||||
函数 `clearLine()` 将清除所选行的文本。
|
||||
|
||||
函数 `clear()` 将清除所有行的所有文本。
|
||||
|
||||
函数 `getLine()` 会返回当前选中的行(从 1 开始)。
|
||||
|
||||
函数 `setLine(line)` 会设置当前选中的行到 *line*(从 1 开始)。
|
||||
```lua
|
||||
da.print("Text on first line")
|
||||
da.print("Text on second line")
|
||||
da.setLine(1)
|
||||
da.print("Text on first line again")
|
||||
```
|
||||
函数 `getMaxLines()` 将返回使用数字适配器可以显示的最大行数(将始终返回16)。
|
||||
|
||||
### Other
|
||||
|
||||
The function `getDurationDistance(blocks, rpm)` will return the time needed to push a Mechanical Piston, Pulley or Gantry a number of blocks at the given rpm.
|
||||
|
||||
The function `getDurationAngle(degrees, rpm)` will return the time needed to rotate a Mechanical Bearing by a number of degrees at the given rpm.
|
@ -0,0 +1,25 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 MRH
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
This repository includes audio from:
|
||||
- pixabay.com LICENSE: https://pixabay.com/service/license-summary/
|
||||
- freesound.org LICENSE: https://creativecommons.org/publicdomain/zero/1.0/
|
@ -0,0 +1,57 @@
|
||||
# Create Crafts & Additions by MRH0
|
||||
Addon to the Create mod by the Create Team.
|
||||
|
||||
Create Crafts & Aditions
|
||||
Minecraft Forge Mod by MRH0
|
||||
|
||||
# Download
|
||||
|
||||
Minecraft 1.16, 1.17, 1.18, 1.19, 1.20
|
||||
|
||||
At: https://www.curseforge.com/minecraft/mc-mods/createaddition
|
||||
|
||||
# About
|
||||
|
||||
Create Crafts & Additions extends Create and acts as a bridge between electricity and kinetic energy from Create.
|
||||
|
||||
# Content
|
||||
|
||||

|
||||
|
||||
- Electric Motor.
|
||||
- Alternator.
|
||||
- Rolling Mill.
|
||||
- Creative Generator.
|
||||
- Telsa Coil.
|
||||
- Accumulator.
|
||||
- Digital Adapter.
|
||||
- Energy transport.
|
||||
- Diamond Grit Sandpaper.
|
||||
|
||||
And more!
|
||||
|
||||
# License
|
||||
|
||||
Available under MIT the license more info at: https://tldrlegal.com/license/mit-license
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright 2022 MRH0
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
@ -0,0 +1,2 @@
|
||||
gradlew build
|
||||
pause
|
@ -0,0 +1,156 @@
|
||||
//file:noinspection GroovyUnusedAssignment
|
||||
plugins {
|
||||
id 'fabric-loom' version '1.5-SNAPSHOT'
|
||||
id 'eclipse'
|
||||
id 'maven-publish'
|
||||
//id 'io.github.juuxel.loom-quiltflower' version '1.+'
|
||||
id 'org.quiltmc.quilt-mappings-on-loom' version '4.2.+'
|
||||
}
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
|
||||
version = project.mod_version
|
||||
group = 'com.mrh0.createaddition'
|
||||
archivesBaseName = "createaddition-fabric+${project.minecraft_version}"
|
||||
|
||||
println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch'))
|
||||
|
||||
loom {
|
||||
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
||||
accessWidenerPath = file("src/main/resources/ca.accesswidener")
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name 'Shedman maven'
|
||||
url 'https://maven.shedaniel.me/'
|
||||
}
|
||||
|
||||
maven {
|
||||
name 'blamejared'
|
||||
url 'https://maven.blamejared.com'
|
||||
}
|
||||
maven { url = "https://api.modrinth.com/maven" }
|
||||
maven { url = "https://mvn.devos.one/releases/" }
|
||||
maven { url = "https://mvn.devos.one/snapshots/" }
|
||||
maven { url = "https://maven.tterrag.com/" }
|
||||
maven { url = "https://jitpack.io/" }
|
||||
maven { url = "https://maven.terraformersmc.com/" }
|
||||
maven {
|
||||
url 'https://www.cursemaven.com'
|
||||
content {
|
||||
includeGroup "curse.maven"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url = "https://maven.jamieswhiteshirt.com/libs-release"
|
||||
content {
|
||||
includeGroup("com.jamieswhiteshirt")
|
||||
}
|
||||
}
|
||||
maven { url = "https://maven.terraformersmc.com/" }
|
||||
maven { url = "https://maven.cafeteria.dev/releases" }
|
||||
maven {
|
||||
name = 'Ladysnake Mods'
|
||||
url = 'https://maven.ladysnake.org/releases'
|
||||
}
|
||||
/*maven {
|
||||
name = "Progwml6 maven"
|
||||
url = "https://dvs1.progwml6.com/files/maven/"
|
||||
}*/
|
||||
maven {
|
||||
name = "ModMaven"
|
||||
url = "https://modmaven.dev"
|
||||
}
|
||||
maven {
|
||||
name = 'ParchmentMC'
|
||||
url = 'https://maven.parchmentmc.org'
|
||||
}
|
||||
maven {
|
||||
url "https://maven2.bai.lol"
|
||||
content {
|
||||
includeGroup "lol.bai"
|
||||
includeGroup "mcp.mobius.waila"
|
||||
}
|
||||
}
|
||||
maven { url = "https://maven.terraformersmc.com/" } // Mod Menu, Trinkets
|
||||
//ComputerCraft
|
||||
maven {
|
||||
url "https://squiddev.cc/maven/"
|
||||
content {
|
||||
includeGroup("cc.tweaked")
|
||||
includeModule("org.squiddev", "Cobalt")
|
||||
}
|
||||
}
|
||||
maven { url = "https://raw.githubusercontent.com/Fuzss/modresources/main/maven/" } //forge config api port
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft("com.mojang:minecraft:${project.minecraft_version}")
|
||||
|
||||
mappings loom.layered {
|
||||
it.officialMojangMappings()
|
||||
it.parchment("org.parchmentmc.data:parchment-${project.minecraft_version}:${project.parchment_version}")
|
||||
}
|
||||
|
||||
modImplementation("net.fabricmc:fabric-loader:${project.loader_version}")
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}+${project.minecraft_version}"
|
||||
|
||||
modImplementation("me.shedaniel:RoughlyEnoughItems-api-fabric:${project.rei_version}")
|
||||
modImplementation("me.shedaniel:RoughlyEnoughItems-fabric:${project.rei_version}")
|
||||
|
||||
modCompileOnly("mezz.jei:jei-$minecraft_version-fabric:$jei_version") { transitive = false }
|
||||
modCompileOnly("dev.emi:emi-fabric:1.0.9+1.20.1") { transitive = false }
|
||||
|
||||
modImplementation("dev.architectury:architectury-fabric:${project.architectury_version}")
|
||||
|
||||
modImplementation("dev.onyxstudios.cardinal-components-api:cardinal-components-base:${cardinal_components_version}")
|
||||
|
||||
modImplementation("com.simibubi.create:create-fabric-${project.minecraft_version}:" +
|
||||
"${project.create_version}+mc${project.minecraft_version}")
|
||||
|
||||
modCompileOnly("cc.tweaked:cc-tweaked-$minecraft_version-fabric-api:$cc_tweaked_version")
|
||||
modRuntimeOnly("cc.tweaked:cc-tweaked-$minecraft_version-fabric:$cc_tweaked_version")
|
||||
|
||||
modImplementation("appeng:appliedenergistics2-fabric:${project.ae2_version}")
|
||||
|
||||
modImplementation("com.tterrag.registrate_fabric:Registrate:MC${project.minecraft_version}-${project.registrate_version}")
|
||||
modCompileOnly"mcp.mobius.waila:wthit-api:fabric-${wthit_version}"
|
||||
|
||||
modApi("me.shedaniel.cloth:cloth-config-fabric:${project.cloth_version}") {
|
||||
exclude(group: "net.fabricmc.fabric-api")
|
||||
}
|
||||
|
||||
|
||||
include modApi('teamreborn:energy:2.3.0') {
|
||||
exclude(group: "net.fabricmc.fabric-api")
|
||||
}
|
||||
|
||||
modLocalRuntime("com.terraformersmc:modmenu:$modmenu_version")
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
filesMatching("fabric.mod.json") {
|
||||
expand "version": project.version
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
withSourcesJar()
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
artifact jar
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
maven {
|
||||
url "file://${project.projectDir}/mcmodsrepo"
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
@ -0,0 +1,3 @@
|
||||
files:
|
||||
- source: /src/main/resources/assets/createaddition/lang/en_us.json
|
||||
translation: /src/main/resources/assets/createaddition/lang/%locale_with_underscore%.json
|
@ -0,0 +1 @@
|
||||
gradlew eclipse -Dorg.gradle.java.home="C:/Program Files/Java/jdk1.8.0_191"
|
@ -0,0 +1,36 @@
|
||||
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
|
||||
# This is required to provide enough memory for the Minecraft decompilation process.
|
||||
org.gradle.jvmargs=-Xmx3G
|
||||
org.gradle.daemon=false
|
||||
|
||||
# check these on https://fabricmc.net/develop/
|
||||
minecraft_version = 1.20.1
|
||||
loader_version = 0.16.10
|
||||
fabric_api_version = 0.92.3
|
||||
mod_version = 1.2.4
|
||||
|
||||
cardinal_components_version = 5.0.2
|
||||
forgegradle_version = 5.1.+
|
||||
mixingradle_version = 0.7-SNAPSHOT
|
||||
mixin_version = 0.8.5
|
||||
librarian_version = 1.+
|
||||
shadow_version = 7.1.0
|
||||
cursegradle_version = 1.4.0
|
||||
create_version = 0.5.1-f-build.1335
|
||||
registrate_version = 1.1.42
|
||||
jei_version = 15.2.0.27
|
||||
cloth_version=11.1.106
|
||||
ae2_version = 15.0.7-beta
|
||||
wthit_version = 8.3.1
|
||||
cc_tweaked_version = 1.108.0
|
||||
|
||||
# https://ldtteam.jfrog.io/ui/native/parchmentmc-public/org/parchmentmc/data/parchment-1.18.1/BLEEDING-SNAPSHOT
|
||||
parchment_version = 2023.08.20
|
||||
# https://www.curseforge.com/minecraft/mc-mods/roughly-enough-items/files
|
||||
rei_version = 12.0.645
|
||||
# https://www.curseforge.com/minecraft/mc-mods/forge-config-api-port-fabric/files
|
||||
config_api_version = 4633444
|
||||
# https://www.curseforge.com/minecraft/mc-mods/architectury-fabric
|
||||
architectury_version = 9.1.12
|
||||
# https://modrinth.com/mod/modmenu/versions
|
||||
modmenu_version = 7.2.1
|
BIN
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
249
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/gradlew
vendored
Normal file
249
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/gradlew
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# This is normally unused
|
||||
# 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
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD=java
|
||||
if ! command -v java >/dev/null 2>&1
|
||||
then
|
||||
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||
# shellcheck disable=SC3045
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
92
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/gradlew.bat
vendored
Normal file
92
createaddition-fabric-1.20.1/createaddition-fabric-1.20.1/gradlew.bat
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
@rem This is normally unused
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
@ -0,0 +1,2 @@
|
||||
gradlew runClient
|
||||
pause
|
@ -0,0 +1,8 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
maven { url = 'https://maven.fabricmc.net/' }
|
||||
maven { url = "https://maven.quiltmc.org/repository/release" }
|
||||
maven { url = 'https://server.bbkr.space/artifactory/libs-release/' }
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
@ -0,0 +1,118 @@
|
||||
package com.mrh0.createaddition;
|
||||
|
||||
import com.mrh0.createaddition.blocks.liquid_blaze_burner.LiquidBlazeBurnerBlock;
|
||||
import com.mrh0.createaddition.commands.CCApiCommand;
|
||||
import com.mrh0.createaddition.compat.computercraft.ComputerCraftCompat;
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
import com.mrh0.createaddition.event.GameEvents;
|
||||
import com.mrh0.createaddition.groups.ModGroup;
|
||||
import com.mrh0.createaddition.index.*;
|
||||
import com.mrh0.createaddition.index.CASounds;
|
||||
import com.mrh0.createaddition.network.CANetwork;
|
||||
import com.mrh0.createaddition.trains.schedule.CASchedule;
|
||||
import com.simibubi.create.content.fluids.tank.BoilerHeaters;
|
||||
import com.simibubi.create.content.kinetics.BlockStressValues;
|
||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.foundation.data.CreateRegistrate;
|
||||
import com.simibubi.create.foundation.item.ItemDescription;
|
||||
import com.simibubi.create.foundation.item.KineticStats;
|
||||
import com.simibubi.create.foundation.item.TooltipHelper;
|
||||
import com.simibubi.create.foundation.item.TooltipModifier;
|
||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||
import fuzs.forgeconfigapiport.api.config.v2.ForgeConfigRegistry;
|
||||
import io.github.fabricators_of_create.porting_lib.event.common.ModsLoadedCallback;
|
||||
import me.pepperbell.simplenetworking.SimpleChannel;
|
||||
import net.fabricmc.api.ModInitializer;
|
||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mrh0.createaddition.blocks.liquid_blaze_burner.LiquidBlazeBurnerBlock;
|
||||
import com.mrh0.createaddition.commands.CCApiCommand;
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
import com.mrh0.createaddition.groups.ModGroup;
|
||||
import com.mrh0.createaddition.network.EnergyNetworkPacket;
|
||||
import com.mrh0.createaddition.network.ObservePacket;
|
||||
import com.simibubi.create.foundation.data.CreateRegistrate;
|
||||
import com.simibubi.create.foundation.item.TooltipModifier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class CreateAddition implements ModInitializer{
|
||||
public static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public static final String MODID = "createaddition";
|
||||
|
||||
public static boolean IE_ACTIVE = false;
|
||||
public static boolean CC_ACTIVE = false;
|
||||
public static boolean AE2_ACTIVE = false;
|
||||
|
||||
public static final CreateRegistrate REGISTRATE = CreateRegistrate.create(CreateAddition.MODID);
|
||||
|
||||
private static final String PROTOCOL = "1";
|
||||
public static final SimpleChannel Network = new SimpleChannel(new ResourceLocation(MODID, "main"));
|
||||
|
||||
static {
|
||||
REGISTRATE.setTooltipModifierFactory(item -> new ItemDescription.Modifier(item, TooltipHelper.Palette.STANDARD_CREATE)
|
||||
.andThen(TooltipModifier.mapNull(KineticStats.create(item))));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInitialize() {
|
||||
ModsLoadedCallback.EVENT.register(envType -> setup());
|
||||
|
||||
CommandRegistrationCallback.EVENT.register(CCApiCommand::register);
|
||||
|
||||
ForgeConfigRegistry.INSTANCE.register(MODID, ModConfig.Type.COMMON, Config.COMMON_CONFIG);
|
||||
Config.loadConfig(Config.COMMON_CONFIG, FabricLoader.getInstance().getConfigDir().resolve("createaddition-common.toml"));
|
||||
|
||||
IE_ACTIVE = FabricLoader.getInstance().isModLoaded("immersiveengineering");
|
||||
CC_ACTIVE = FabricLoader.getInstance().isModLoaded("computercraft");
|
||||
AE2_ACTIVE = FabricLoader.getInstance().isModLoaded("ae2");
|
||||
CAArmInteractions.register();
|
||||
CABlocks.register();
|
||||
CABlockEntities.register();
|
||||
CAItems.register();
|
||||
CAFluids.register();
|
||||
CAEffects.register();
|
||||
CARecipes.register();
|
||||
CASounds.register();
|
||||
CASchedule.register();
|
||||
ModGroup.register();
|
||||
REGISTRATE.register();
|
||||
|
||||
// Setup events
|
||||
GameEvents.initCommon();
|
||||
|
||||
CANetwork.initServer();
|
||||
|
||||
System.out.println("Create Crafts & Additions Initialized!");
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
CAPotatoCannonProjectiles.register();
|
||||
BlockStressValues.registerProvider(MODID, AllConfigs.server().kinetics.stressValues);
|
||||
BoilerHeaters.registerHeater(CABlocks.LIQUID_BLAZE_BURNER.get(), (level, pos, state) -> {
|
||||
BlazeBurnerBlock.HeatLevel value = state.getValue(LiquidBlazeBurnerBlock.HEAT_LEVEL);
|
||||
if (value == BlazeBurnerBlock.HeatLevel.NONE) return -1;
|
||||
if (value == BlazeBurnerBlock.HeatLevel.SEETHING) return 2;
|
||||
if (value.isAtLeast(BlazeBurnerBlock.HeatLevel.FADING)) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
if(CC_ACTIVE){
|
||||
ComputerCraftCompat.registerCompat();
|
||||
}
|
||||
}
|
||||
|
||||
public static ResourceLocation asResource(String path) {
|
||||
return new ResourceLocation(MODID, path);
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.mrh0.createaddition;
|
||||
|
||||
import com.mrh0.createaddition.event.ClientEventHandler;
|
||||
import com.mrh0.createaddition.event.GameEvents;
|
||||
import com.mrh0.createaddition.index.CABlocks;
|
||||
import com.mrh0.createaddition.index.CAItemProperties;
|
||||
import com.mrh0.createaddition.index.CAPartials;
|
||||
import com.mrh0.createaddition.index.CAPonder;
|
||||
import com.mrh0.createaddition.network.CANetwork;
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
|
||||
import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
||||
public class CreateAdditionClient implements ClientModInitializer {
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
CANetwork.initClient();
|
||||
GameEvents.initClient();
|
||||
CAPonder.register();
|
||||
//CAEntities.registerRenderers();
|
||||
CAPartials.init();
|
||||
CAItemProperties.register();
|
||||
|
||||
ClientTickEvents.START_WORLD_TICK.register(ClientEventHandler::playerRendererEvent);
|
||||
|
||||
RenderType cutout = RenderType.cutoutMipped();
|
||||
|
||||
BlockRenderLayerMap.INSTANCE.putBlocks(cutout, CABlocks.TESLA_COIL.get(), CABlocks.BARBED_WIRE.get(), CABlocks.SMALL_LIGHT_CONNECTOR.get());
|
||||
}
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
package com.mrh0.createaddition.blocks.accumulator;
|
||||
|
||||
import com.mrh0.createaddition.energy.IWireNode;
|
||||
import com.mrh0.createaddition.energy.NodeRotation;
|
||||
import com.mrh0.createaddition.index.CABlockEntities;
|
||||
import com.mrh0.createaddition.util.IComparatorOverride;
|
||||
import com.simibubi.create.content.contraptions.ITransformableBlock;
|
||||
import com.simibubi.create.content.contraptions.StructureTransform;
|
||||
import com.simibubi.create.content.equipment.wrench.IWrenchable;
|
||||
|
||||
import com.simibubi.create.foundation.block.IBE;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public class AccumulatorBlock extends Block implements IBE<AccumulatorBlockEntity>, IWrenchable, ITransformableBlock {
|
||||
|
||||
public static final VoxelShape ACCUMULATOR_SHAPE_MAIN = Block.box(0, 0, 0, 16, 12, 16);
|
||||
public static final VoxelShape ACCUMULATOR_SHAPE_X = Shapes.or(ACCUMULATOR_SHAPE_MAIN, Block.box(1, 0, 6, 5, 16, 10), Block.box(11, 0, 6, 15, 16, 10));
|
||||
public static final VoxelShape ACCUMULATOR_SHAPE_Z = Shapes.or(ACCUMULATOR_SHAPE_MAIN, Block.box(6, 0, 1, 10, 16, 5), Block.box(6, 0, 11, 10, 16, 15));
|
||||
|
||||
public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
public AccumulatorBlock(Properties properties) {
|
||||
super(properties);
|
||||
this.registerDefaultState(this.defaultBlockState()
|
||||
.setValue(FACING, Direction.NORTH)
|
||||
.setValue(NodeRotation.ROTATION, NodeRotation.NONE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter worlIn, BlockPos pos, CollisionContext context) {
|
||||
Axis axis = state.getValue(FACING).getAxis();
|
||||
return axis == Axis.X ? ACCUMULATOR_SHAPE_X : ACCUMULATOR_SHAPE_Z;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
|
||||
builder.add(FACING, NodeRotation.ROTATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext c) {
|
||||
return defaultBlockState().setValue(FACING, c.getPlayer().isShiftKeyDown() ? c.getHorizontalDirection().getCounterClockWise() : c.getHorizontalDirection().getClockWise());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity entity, ItemStack stack) {
|
||||
BlockEntity te = world.getBlockEntity(pos);
|
||||
if(te != null) {
|
||||
if(te instanceof AccumulatorBlockEntity) {
|
||||
AccumulatorBlockEntity ate = (AccumulatorBlockEntity) te;
|
||||
if(stack.hasTag()) {
|
||||
CompoundTag nbt = stack.getTag();
|
||||
if(nbt.contains("energy"))
|
||||
ate.setEnergy(nbt.getInt("energy"));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
super.setPlacedBy(world, pos, state, entity, stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerWillDestroy(Level worldIn, BlockPos pos, BlockState state, Player player) {
|
||||
super.playerWillDestroy(worldIn, pos, state, player);
|
||||
|
||||
if (worldIn.isClientSide()) return;
|
||||
BlockEntity te = worldIn.getBlockEntity(pos);
|
||||
if (te == null) return;
|
||||
if (!(te instanceof IWireNode cte)) return;
|
||||
cte.dropWires(worldIn, !player.isCreative());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult onSneakWrenched(BlockState state, UseOnContext c) {
|
||||
BlockEntity te = c.getLevel().getBlockEntity(c.getClickedPos());
|
||||
if(te == null)
|
||||
return IWrenchable.super.onSneakWrenched(state, c);
|
||||
if(!(te instanceof IWireNode))
|
||||
return IWrenchable.super.onSneakWrenched(state, c);
|
||||
IWireNode cte = (IWireNode) te;
|
||||
|
||||
if (!c.getLevel().isClientSide())
|
||||
cte.dropWires(c.getLevel(), c.getPlayer(), !c.getPlayer().isCreative());
|
||||
|
||||
return IWrenchable.super.onSneakWrenched(state, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasAnalogOutputSignal(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAnalogOutputSignal(BlockState blockState, Level worldIn, BlockPos pos) {
|
||||
return IComparatorOverride.getComparatorOverride(worldIn, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState state, Rotation direction) {
|
||||
return state.setValue(FACING, direction.rotate(state.getValue(FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState mirror(BlockState state, Mirror mirror) {
|
||||
return state.setValue(FACING, mirror.mirror(state.getValue(FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState transform(BlockState state, StructureTransform transform) {
|
||||
NodeRotation rotation = NodeRotation.get(transform.rotationAxis, transform.rotation);
|
||||
// Handle default rotation & mirroring.
|
||||
if (transform.mirror != null) state = mirror(state, transform.mirror);
|
||||
if (transform.rotationAxis == Axis.Y) state = rotate(state, transform.rotation);
|
||||
// Set the rotation state, which will be used to update the nodes.
|
||||
return state.setValue(NodeRotation.ROTATION, rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<AccumulatorBlockEntity> getBlockEntityClass() {
|
||||
return AccumulatorBlockEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityType<? extends AccumulatorBlockEntity> getBlockEntityType() {
|
||||
return CABlockEntities.ACCUMULATOR.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return CABlockEntities.ACCUMULATOR.create(pos, state);
|
||||
}
|
||||
}
|
@ -0,0 +1,474 @@
|
||||
package com.mrh0.createaddition.blocks.accumulator;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.mrh0.createaddition.CreateAddition;
|
||||
import com.mrh0.createaddition.blocks.connector.ConnectorType;
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
import com.mrh0.createaddition.energy.*;
|
||||
import com.mrh0.createaddition.energy.network.EnergyNetwork;
|
||||
import com.mrh0.createaddition.index.CABlocks;
|
||||
import com.mrh0.createaddition.network.EnergyNetworkPacket;
|
||||
import com.mrh0.createaddition.network.IObserveTileEntity;
|
||||
import com.mrh0.createaddition.network.ObservePacket;
|
||||
import com.mrh0.createaddition.util.IComparatorOverride;
|
||||
import com.mrh0.createaddition.util.Util;
|
||||
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
|
||||
import io.github.fabricators_of_create.porting_lib.transfer.TransferUtil;
|
||||
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class AccumulatorBlockEntity extends BaseElectricBlockEntity implements IWireNode, IHaveGoggleInformation, IComparatorOverride, IObserveTileEntity {
|
||||
|
||||
private final Set<LocalNode> wireCache = new HashSet<>();
|
||||
private final LocalNode[] localNodes;
|
||||
private final IWireNode[] nodeCache;
|
||||
|
||||
private boolean wasContraption = false;
|
||||
private boolean firstTick = true;
|
||||
|
||||
public static Vec3 OFFSET_NORTH = new Vec3( 0f, 9f/16f, -5f/16f);
|
||||
public static Vec3 OFFSET_WEST = new Vec3( -5f/16f, 9f/16f, 0f);
|
||||
public static Vec3 OFFSET_SOUTH = new Vec3( 0f, 9f/16f, 5f/16f);
|
||||
public static Vec3 OFFSET_EAST = new Vec3( 5f/16f, 9f/16f, 0f);
|
||||
|
||||
public static final int NODE_COUNT = 8;
|
||||
|
||||
public AccumulatorBlockEntity(BlockEntityType<?> tileEntityTypeIn, BlockPos pos, BlockState state) {
|
||||
super(tileEntityTypeIn, pos, state);
|
||||
|
||||
setLazyTickRate(20);
|
||||
|
||||
this.localNodes = new LocalNode[getNodeCount()];
|
||||
this.nodeCache = new IWireNode[getNodeCount()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCapacity() {
|
||||
return Config.ACCUMULATOR_CAPACITY.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxIn() {
|
||||
return Config.ACCUMULATOR_MAX_INPUT.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxOut() {
|
||||
return Config.ACCUMULATOR_MAX_OUTPUT.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable IWireNode getWireNode(int index) {
|
||||
return IWireNode.getWireNodeFrom(index, this, this.localNodes, this.nodeCache, level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable LocalNode getLocalNode(int index) {
|
||||
return this.localNodes[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getNodeOffset(int node) {
|
||||
if(node > 3) {
|
||||
switch(getBlockState().getValue(AccumulatorBlock.FACING)) {
|
||||
case NORTH:
|
||||
return OFFSET_NORTH;
|
||||
case WEST:
|
||||
return OFFSET_WEST;
|
||||
case SOUTH:
|
||||
return OFFSET_SOUTH;
|
||||
case EAST:
|
||||
return OFFSET_EAST;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch(getBlockState().getValue(AccumulatorBlock.FACING)) {
|
||||
case NORTH:
|
||||
return OFFSET_SOUTH;
|
||||
case WEST:
|
||||
return OFFSET_EAST;
|
||||
case SOUTH:
|
||||
return OFFSET_NORTH;
|
||||
case EAST:
|
||||
return OFFSET_WEST;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return OFFSET_NORTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnergyInput(Direction side) {
|
||||
return side != Direction.UP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnergyOutput(Direction side) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNodeInput(int node) {
|
||||
return node < 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNodeOutput(int node) {
|
||||
return !isNodeInput(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAvailableNode(Vec3 pos) {
|
||||
Direction dir = level.getBlockState(worldPosition).getValue(AccumulatorBlock.FACING);
|
||||
boolean upper = true;
|
||||
pos = pos.subtract(worldPosition.getX(), worldPosition.getY(), worldPosition.getZ());
|
||||
switch(dir) {
|
||||
case NORTH:
|
||||
upper = pos.z() < 0.5d;
|
||||
break;
|
||||
case WEST:
|
||||
upper = pos.x() < 0.5d;
|
||||
break;
|
||||
case SOUTH:
|
||||
upper = pos.z() > 0.5d;
|
||||
break;
|
||||
case EAST:
|
||||
upper = pos.x() > 0.5d;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for(int i = upper ? 4 : 0; i < (upper ? 8 : 4); i++) {
|
||||
if(hasConnection(i))
|
||||
continue;
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNode(int index, int other, BlockPos pos, WireType type) {
|
||||
this.localNodes[index] = new LocalNode(this, index, other, type, pos);
|
||||
|
||||
notifyUpdate();
|
||||
|
||||
// Invalidate
|
||||
if(networkIn != null)
|
||||
networkIn.invalidate();
|
||||
if(networkOut != null)
|
||||
networkOut.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode(int index, boolean dropWire) {
|
||||
LocalNode old = this.localNodes[index];
|
||||
this.localNodes[index] = null;
|
||||
this.nodeCache[index] = null;
|
||||
|
||||
this.invalidateNodeCache();
|
||||
notifyUpdate();
|
||||
|
||||
// Invalidate
|
||||
if(networkIn != null)
|
||||
networkIn.invalidate();
|
||||
if(networkOut != null)
|
||||
networkOut.invalidate();
|
||||
// Drop wire next tick.
|
||||
if (dropWire && old != null) this.wireCache.add(old);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPos() {
|
||||
return getBlockPos();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundTag nbt, boolean clientPacket) {
|
||||
super.read(nbt, clientPacket);
|
||||
// Convert old nbt data. x0, y0, z0, node0 & type0 etc.
|
||||
if (!clientPacket && nbt.contains("node0")) {
|
||||
convertOldNbt(nbt);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
// Read the nodes.
|
||||
invalidateLocalNodes();
|
||||
invalidateNodeCache();
|
||||
ListTag nodes = nbt.getList(LocalNode.NODES, Tag.TAG_COMPOUND);
|
||||
nodes.forEach(tag -> {
|
||||
LocalNode localNode = new LocalNode(this, (CompoundTag) tag);
|
||||
this.localNodes[localNode.getIndex()] = localNode;
|
||||
});
|
||||
|
||||
// Check if this was a contraption.
|
||||
if (nbt.contains("contraption") && !clientPacket) {
|
||||
this.wasContraption = nbt.getBoolean("contraption");
|
||||
NodeRotation rotation = getBlockState().getValue(NodeRotation.ROTATION);
|
||||
if (rotation != NodeRotation.NONE)
|
||||
level.setBlock(getBlockPos(), getBlockState().setValue(NodeRotation.ROTATION, NodeRotation.NONE), 0);
|
||||
// Loop over all nodes and update their relative positions.
|
||||
for (LocalNode localNode : this.localNodes) {
|
||||
if (localNode == null) continue;
|
||||
localNode.updateRelative(rotation);
|
||||
}
|
||||
}
|
||||
|
||||
// Invalidate the network if we updated the nodes.
|
||||
if (!nodes.isEmpty() && this.networkIn != null && this.networkOut != null) {
|
||||
this.networkIn.invalidate();
|
||||
this.networkOut.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag nbt, boolean clientPacket) {
|
||||
super.write(nbt, clientPacket);
|
||||
// Write nodes.
|
||||
ListTag nodes = new ListTag();
|
||||
for (int i = 0; i < getNodeCount(); i++) {
|
||||
LocalNode localNode = this.localNodes[i];
|
||||
if (localNode == null) continue;
|
||||
CompoundTag tag = new CompoundTag();
|
||||
localNode.write(tag);
|
||||
nodes.add(tag);
|
||||
}
|
||||
nbt.put(LocalNode.NODES, nodes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNodeCount() {
|
||||
return NODE_COUNT;
|
||||
}
|
||||
|
||||
public void invalidateLocalNodes() {
|
||||
for(int i = 0; i < getNodeCount(); i++)
|
||||
this.localNodes[i] = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateNodeCache() {
|
||||
for(int i = 0; i < getNodeCount(); i++)
|
||||
this.nodeCache[i] = null;
|
||||
}
|
||||
|
||||
private int lastComparator = 0;
|
||||
int lastEnergy = 0;
|
||||
|
||||
@Override
|
||||
public void lazyTick() {
|
||||
super.lazyTick();
|
||||
|
||||
int comp = getComparatorOverride();
|
||||
if(comp != lastComparator) {
|
||||
assert level != null;
|
||||
level.updateNeighborsAt(worldPosition, CABlocks.ACCUMULATOR.get());
|
||||
}
|
||||
lastComparator = comp;
|
||||
|
||||
//if(energy.getEnergyStored() != lastEnergy)
|
||||
// causeBlockUpdate();
|
||||
//lastEnergy = energy.getEnergyStored();
|
||||
}
|
||||
|
||||
private boolean firstTickState = true;
|
||||
|
||||
/**
|
||||
* Called after the tile entity has been part of a contraption.
|
||||
* Only runs on the server.
|
||||
*/
|
||||
private void validateNodes() {
|
||||
boolean changed = validateLocalNodes(this.localNodes);
|
||||
|
||||
// Always set as changed if we were a contraption, as nodes might have been rotated.
|
||||
notifyUpdate();
|
||||
|
||||
if (changed) {
|
||||
invalidateNodeCache();
|
||||
// Invalidate
|
||||
if (this.networkIn != null) this.networkIn.invalidate();
|
||||
if (this.networkOut != null) this.networkOut.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (this.firstTick) {
|
||||
this.firstTick = false;
|
||||
// Check if this blockentity was a part of a contraption.
|
||||
// If it was, then make sure all the nodes are valid.
|
||||
if (this.wasContraption && !level.isClientSide()) {
|
||||
this.wasContraption = false;
|
||||
validateNodes();
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we need to drop any wires due to contraption.
|
||||
if (!this.wireCache.isEmpty() && !isRemoved()) handleWireCache(level, this.wireCache);
|
||||
|
||||
if(firstTickState)
|
||||
firstTick();
|
||||
firstTickState = false;
|
||||
if(level.isClientSide())
|
||||
return;
|
||||
networkTick();
|
||||
}
|
||||
|
||||
private long demandOut = 0;
|
||||
private long demandIn = 0;
|
||||
private void networkTick() {
|
||||
if(awakeNetwork(level)) {
|
||||
//EnergyNetwork.nextNode(world, new EnergyNetwork(world), new HashMap<>(), this, 0);//EnergyNetwork.buildNetwork(world, this);
|
||||
//causeBlockUpdate();
|
||||
notifyUpdate();
|
||||
}
|
||||
if(networkOut == null) {
|
||||
//System.out.println("WARN!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try (Transaction t = TransferUtil.getTransaction()) {
|
||||
long toExtract = 0;
|
||||
try (Transaction nested = TransferUtil.getTransaction()) {
|
||||
toExtract = localEnergy.extract(demandOut, nested);
|
||||
}
|
||||
localEnergy.extract(networkOut.push(toExtract), t);
|
||||
t.commit();
|
||||
}
|
||||
|
||||
demandOut = networkOut.getDemand();
|
||||
try (Transaction t = TransferUtil.getTransaction()) {
|
||||
long toInsert = 0;
|
||||
try (Transaction nested = TransferUtil.getTransaction()) {
|
||||
toInsert = localEnergy.insert(getMaxIn(), nested);
|
||||
}
|
||||
localEnergy.insert(networkIn.pull(Math.min(demandIn, toInsert)), t);
|
||||
t.commit();
|
||||
}
|
||||
try (Transaction t = TransferUtil.getTransaction()) {
|
||||
demandIn = networkIn.demand(localEnergy.insert(getMaxIn(), t));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if (level.isClientSide()) return;
|
||||
for(int i = 0; i < getNodeCount(); i++) {
|
||||
LocalNode localNode = getLocalNode(i);
|
||||
if (localNode == null) continue;
|
||||
IWireNode otherNode = getWireNode(i);
|
||||
if(otherNode == null) continue;
|
||||
|
||||
int ourNode = localNode.getOtherIndex();
|
||||
if (localNode.isInvalid()) otherNode.removeNode(ourNode);
|
||||
else otherNode.removeNode(ourNode, true); // Make the other node drop the wires.
|
||||
}
|
||||
invalidateNodeCache();
|
||||
invalidateCaps();
|
||||
// Invalidate
|
||||
if(networkIn != null)
|
||||
networkIn.invalidate();
|
||||
if(networkOut != null)
|
||||
networkOut.invalidate();
|
||||
}
|
||||
|
||||
private EnergyNetwork networkIn;
|
||||
private EnergyNetwork networkOut;
|
||||
|
||||
@Override
|
||||
public EnergyNetwork getNetwork(int node) {
|
||||
return isNodeInput(node) ? networkIn : networkOut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNetwork(int node, EnergyNetwork network) {
|
||||
if(isNodeInput(node))
|
||||
networkIn = network;
|
||||
if(isNodeOutput(node))
|
||||
networkOut = network;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNodeIndeciesConnected(int in, int other) {
|
||||
return isNodeInput(in) == isNodeInput(other);
|
||||
}
|
||||
|
||||
public void setEnergy(int energy) {
|
||||
this.localEnergy.setEnergy(energy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getComparatorOverride() {
|
||||
return (int)((double)localEnergy.getAmount() / (double)localEnergy.getCapacity() * 15d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
|
||||
@SuppressWarnings("resource")
|
||||
HitResult ray = Minecraft.getInstance().hitResult;
|
||||
if(ray == null)
|
||||
return false;
|
||||
int node = getAvailableNode(ray.getLocation());
|
||||
|
||||
ObservePacket.send(worldPosition, node);
|
||||
|
||||
tooltip.add(Component.literal(spacing)
|
||||
.append(Component.translatable(CreateAddition.MODID + ".tooltip.accumulator.info").withStyle(ChatFormatting.WHITE)));
|
||||
tooltip.add(Component.literal(spacing)
|
||||
.append(Component.translatable(CreateAddition.MODID + ".tooltip.energy.stored").withStyle(ChatFormatting.GRAY)));
|
||||
tooltip.add(Component.literal(spacing).append(Component.literal(" "))
|
||||
.append(Util.getTextComponent(localEnergy)));
|
||||
|
||||
tooltip.add(Component.literal(spacing)
|
||||
.append(Component.translatable(CreateAddition.MODID + ".tooltip.energy.selected").withStyle(ChatFormatting.GRAY)));
|
||||
tooltip.add(Component.literal(spacing).append(Component.literal(" "))
|
||||
.append(Component.translatable(isNodeInput(node) ? "createaddition.tooltip.energy.push" : "createaddition.tooltip.energy.pull").withStyle(ChatFormatting.AQUA)));
|
||||
|
||||
tooltip.add(Component.literal(spacing)
|
||||
.append(Component.translatable(CreateAddition.MODID + ".tooltip.energy.usage").withStyle(ChatFormatting.GRAY)));
|
||||
tooltip.add(Component.literal(spacing).append(" ")
|
||||
.append(Util.format(EnergyNetworkPacket.clientBuff)).append("fe/t").withStyle(ChatFormatting.AQUA));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onObserved(ServerPlayer player, ObservePacket pack) {
|
||||
if(isNetworkValid(0))
|
||||
EnergyNetworkPacket.send(worldPosition, getNetwork(pack.node()).getPulled(), getNetwork(pack.node()).getPushed(), player);
|
||||
//causeBlockUpdate();
|
||||
notifyUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectorType getConnectorType() {
|
||||
return ConnectorType.Small;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxWireLength() {
|
||||
return Config.SMALL_CONNECTOR_MAX_LENGTH.get();
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.mrh0.createaddition.blocks.accumulator;
|
||||
|
||||
import com.mrh0.createaddition.rendering.WireNodeRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
|
||||
|
||||
public class AccumulatorRenderer extends WireNodeRenderer<AccumulatorBlockEntity> {
|
||||
|
||||
public AccumulatorRenderer(BlockEntityRendererProvider.Context context) {
|
||||
super(context);
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package com.mrh0.createaddition.blocks.alternator;
|
||||
|
||||
import com.mrh0.createaddition.index.CABlockEntities;
|
||||
import com.mrh0.createaddition.shapes.CAShapes;
|
||||
import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
|
||||
import com.simibubi.create.content.kinetics.base.IRotate;
|
||||
import com.simibubi.create.foundation.block.IBE;
|
||||
import com.simibubi.create.foundation.utility.VoxelShaper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public class AlternatorBlock extends DirectionalKineticBlock implements IBE<AlternatorBlockEntity>, IRotate {
|
||||
|
||||
public static final VoxelShaper ALTERNATOR_SHAPE = CAShapes.shape(0, 3, 0, 16, 13, 16).add(2, 0, 2, 14, 14, 14).forDirectional();
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
|
||||
return ALTERNATOR_SHAPE.get(state.getValue(FACING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
Direction preferred = getPreferredFacing(context);
|
||||
if ((context.getPlayer() != null && context.getPlayer()
|
||||
.isShiftKeyDown()) || preferred == null)
|
||||
return super.getStateForPlacement(context);
|
||||
return defaultBlockState().setValue(FACING, preferred);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hideStressImpact() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public AlternatorBlock(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) {
|
||||
return face == state.getValue(FACING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Axis getRotationAxis(BlockState state) {
|
||||
return state.getValue(FACING)
|
||||
.getAxis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityType<? extends AlternatorBlockEntity> getBlockEntityType() {
|
||||
return CABlockEntities.ALTERNATOR.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<AlternatorBlockEntity> getBlockEntityClass() {
|
||||
return AlternatorBlockEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return CABlockEntities.ALTERNATOR.create(pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpeedLevel getMinimumRequiredSpeedLevel() {
|
||||
return SpeedLevel.MEDIUM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) {
|
||||
BlockEntity tileentity = state.hasBlockEntity() ? worldIn.getBlockEntity(pos) : null;
|
||||
if(tileentity != null) {
|
||||
if(tileentity instanceof AlternatorBlockEntity) {
|
||||
((AlternatorBlockEntity)tileentity).updateCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
package com.mrh0.createaddition.blocks.alternator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.mrh0.createaddition.CreateAddition;
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
import com.mrh0.createaddition.energy.InternalEnergyStorage;
|
||||
import com.mrh0.createaddition.index.CABlocks;
|
||||
import com.mrh0.createaddition.sound.CASoundScapes;
|
||||
import com.mrh0.createaddition.sound.CASoundScapes.AmbienceGroup;
|
||||
import com.mrh0.createaddition.util.Util;
|
||||
import com.mrh0.createaddition.transfer.EnergyTransferable;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import io.github.fabricators_of_create.porting_lib.util.LazyOptional;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import team.reborn.energy.api.EnergyStorage;
|
||||
import team.reborn.energy.api.EnergyStorageUtil;
|
||||
|
||||
public class AlternatorBlockEntity extends KineticBlockEntity implements EnergyTransferable {
|
||||
|
||||
protected final InternalEnergyStorage energy;
|
||||
|
||||
public AlternatorBlockEntity(BlockEntityType<?> typeIn, BlockPos pos, BlockState state) {
|
||||
super(typeIn, pos, state);
|
||||
energy = new InternalEnergyStorage(Config.ALTERNATOR_CAPACITY.get(), 0, Config.ALTERNATOR_MAX_OUTPUT.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
|
||||
tooltip.add(Component.literal(spacing).append(Component.translatable(CreateAddition.MODID + ".tooltip.energy.production").withStyle(ChatFormatting.GRAY)));
|
||||
tooltip.add(Component.literal(spacing).append(Component.literal(" " + Util.format(getEnergyProductionRate((int) (isSpeedRequirementFulfilled() ? getSpeed() : 0))) + "fe/t ") // fix
|
||||
.withStyle(ChatFormatting.AQUA)).append(Lang.translateDirect("gui.goggles.at_current_speed").withStyle(ChatFormatting.DARK_GRAY)));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float calculateStressApplied() {
|
||||
float impact = Config.MAX_STRESS.get()/256f;
|
||||
this.lastStressApplied = impact;
|
||||
return impact;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnergyStorage getEnergyStorage(Direction side) {
|
||||
return energy;
|
||||
}
|
||||
|
||||
public boolean isEnergyInput(Direction side) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isEnergyOutput(Direction side) {
|
||||
return true; //side != getBlockState().getValue(AlternatorBlock.FACING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundTag compound, boolean clientPacket) {
|
||||
super.read(compound, clientPacket);
|
||||
energy.read(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag compound, boolean clientPacket) {
|
||||
super.write(compound, clientPacket);
|
||||
energy.write(compound);
|
||||
}
|
||||
|
||||
private boolean firstTickState = true;
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if(level.isClientSide()) return;
|
||||
if(firstTickState) firstTick();
|
||||
firstTickState = false;
|
||||
|
||||
if(Math.abs(getSpeed()) > 0 && isSpeedRequirementFulfilled())
|
||||
energy.internalProduceEnergy(getEnergyProductionRate((int)getSpeed()));
|
||||
|
||||
for(Direction d : Direction.values()) {
|
||||
if(!isEnergyOutput(d))
|
||||
continue;
|
||||
EnergyStorage ies = getCachedEnergy(d);
|
||||
if(ies == null)
|
||||
continue;
|
||||
try(Transaction t = Transaction.openOuter()) {
|
||||
EnergyStorageUtil.move(energy, ies, Config.ALTERNATOR_MAX_OUTPUT.get(), t);
|
||||
t.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
@Override
|
||||
public void tickAudio() {
|
||||
super.tickAudio();
|
||||
|
||||
float componentSpeed = Math.abs(getSpeed());
|
||||
if (componentSpeed == 0 || !isSpeedRequirementFulfilled())
|
||||
return;
|
||||
|
||||
float pitch = Mth.clamp((componentSpeed / 256f) + .5f, .5f, 1.5f);
|
||||
CASoundScapes.play(AmbienceGroup.DYNAMO, worldPosition, pitch);
|
||||
}
|
||||
|
||||
public static int getEnergyProductionRate(int rpm) {
|
||||
rpm = Math.abs(rpm);
|
||||
return (int)((double)Config.FE_RPM.get() * ((double)Math.abs(rpm) / 256d) * Config.ALTERNATOR_EFFICIENCY.get());//return (int)((double)Config.FE_TO_SU.get() * ((double)Math.abs(rpm)/256d) * EFFICIENCY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Block getStressConfigKey() {
|
||||
return CABlocks.ALTERNATOR.get();
|
||||
}
|
||||
|
||||
public void firstTick() {
|
||||
updateCache();
|
||||
}
|
||||
public void updateCache() {
|
||||
if(level.isClientSide()) return;
|
||||
for(Direction side : Direction.values()) {
|
||||
BlockEntity te = level.getBlockEntity(worldPosition.relative(side));
|
||||
if(te == null) {
|
||||
setCache(side, LazyOptional.empty());
|
||||
continue;
|
||||
}
|
||||
LazyOptional<EnergyStorage> le = LazyOptional.ofObject(EnergyStorage.SIDED.find(level, worldPosition.relative(side), side.getOpposite()));
|
||||
setCache(side, le);
|
||||
}
|
||||
}
|
||||
|
||||
private LazyOptional<EnergyStorage> escacheUp = LazyOptional.empty();
|
||||
private LazyOptional<EnergyStorage> escacheDown = LazyOptional.empty();
|
||||
private LazyOptional<EnergyStorage> escacheNorth = LazyOptional.empty();
|
||||
private LazyOptional<EnergyStorage> escacheEast = LazyOptional.empty();
|
||||
private LazyOptional<EnergyStorage> escacheSouth = LazyOptional.empty();
|
||||
private LazyOptional<EnergyStorage> escacheWest = LazyOptional.empty();
|
||||
|
||||
public void setCache(Direction side, LazyOptional<EnergyStorage> storage) {
|
||||
switch (side) {
|
||||
case DOWN -> escacheDown = storage;
|
||||
case EAST -> escacheEast = storage;
|
||||
case NORTH -> escacheNorth = storage;
|
||||
case SOUTH -> escacheSouth = storage;
|
||||
case UP -> escacheUp = storage;
|
||||
case WEST -> escacheWest = storage;
|
||||
}
|
||||
}
|
||||
|
||||
public EnergyStorage getCachedEnergy(Direction side) {
|
||||
return switch (side) {
|
||||
case DOWN -> escacheDown.orElse(null);
|
||||
case EAST -> escacheEast.orElse(null);
|
||||
case NORTH -> escacheNorth.orElse(null);
|
||||
case SOUTH -> escacheSouth.orElse(null);
|
||||
case UP -> escacheUp.orElse(null);
|
||||
case WEST -> escacheWest.orElse(null);
|
||||
};
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.mrh0.createaddition.blocks.alternator;
|
||||
|
||||
import com.simibubi.create.AllPartialModels;
|
||||
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
|
||||
import com.simibubi.create.foundation.render.CachedBufferer;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
|
||||
public class AlternatorRenderer extends KineticBlockEntityRenderer {
|
||||
|
||||
public AlternatorRenderer(Context dispatcher) {
|
||||
super(dispatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SuperByteBuffer getRotatedModel(KineticBlockEntity te, BlockState state) {
|
||||
return CachedBufferer.partialFacing(AllPartialModels.SHAFT_HALF, state);
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package com.mrh0.createaddition.blocks.barbed_wire;
|
||||
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
import com.mrh0.createaddition.index.CADamageSources;
|
||||
import io.github.fabricators_of_create.porting_lib.extensions.extensions.IShearable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
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.level.block.state.StateDefinition.Builder;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class BarbedWireBlock extends Block implements IShearable {
|
||||
public static final BooleanProperty VERTICAL = BooleanProperty.create("vertical");
|
||||
public static final DirectionProperty HORIZONTAL_FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
|
||||
public BarbedWireBlock(Properties props) {
|
||||
super(props);
|
||||
this.registerDefaultState(this.defaultBlockState().setValue(VERTICAL, false).setValue(HORIZONTAL_FACING, Direction.NORTH));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) {
|
||||
double delta = Math.abs(entity.getX() - entity.xOld) + Math.abs(entity.getY() - entity.yOld) + Math.abs(entity.getZ() - entity.zOld);
|
||||
if((entity instanceof LivingEntity) && delta > 0d) {
|
||||
if(entity.hurt(CADamageSources.barbedWire(level), Config.BARBED_WIRE_DAMAGE.get().floatValue()))
|
||||
entity.playSound(SoundEvents.PLAYER_HURT_SWEET_BERRY_BUSH, 1f, 1f);
|
||||
}
|
||||
entity.makeStuckInBlock(state, new Vec3(0.25D, (double)0.05F, 0.25D));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
|
||||
builder.add(VERTICAL, HORIZONTAL_FACING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext c) {
|
||||
if(c.getClickedFace().getAxis() == Axis.Y)
|
||||
return defaultBlockState().setValue(HORIZONTAL_FACING, c.getPlayer().isShiftKeyDown() ? c.getHorizontalDirection().getClockWise() : c.getHorizontalDirection()).setValue(VERTICAL, false);
|
||||
else
|
||||
return defaultBlockState().setValue(HORIZONTAL_FACING, c.getClickedFace().getOpposite()).setValue(VERTICAL, true);
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.mrh0.createaddition.blocks.cake;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.stats.Stats;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.CakeBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
|
||||
public class CACakeBlock extends CakeBlock {
|
||||
|
||||
public CACakeBlock(Properties props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player,
|
||||
InteractionHand hand, BlockHitResult ray) {
|
||||
if (world.isClientSide) {
|
||||
ItemStack itemstack = player.getItemInHand(hand);
|
||||
if (eat(world, pos, state, player).consumesAction())
|
||||
return InteractionResult.SUCCESS;
|
||||
if (itemstack.isEmpty())
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
return eat(world, pos, state, player);
|
||||
}
|
||||
|
||||
protected static InteractionResult eat(LevelAccessor world, BlockPos pos, BlockState state, Player player) {
|
||||
if (!player.canEat(false))
|
||||
return InteractionResult.PASS;
|
||||
else {
|
||||
player.awardStat(Stats.EAT_CAKE_SLICE);
|
||||
player.getFoodData().eat(3, 0.3F);
|
||||
int i = state.getValue(BITES);
|
||||
if (i < 6)
|
||||
world.setBlock(pos, state.setValue(BITES, Integer.valueOf(i + 1)), 3);
|
||||
else
|
||||
world.removeBlock(pos, false);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
package com.mrh0.createaddition.blocks.centrifugal_governor;
|
||||
|
||||
public class CentrifugalGovernor {
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.mrh0.createaddition.blocks.connector;
|
||||
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
|
||||
public enum ConnectorType {
|
||||
Small("small"),
|
||||
Large("large");
|
||||
|
||||
public final String name;
|
||||
|
||||
ConnectorType(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.mrh0.createaddition.blocks.connector;
|
||||
|
||||
import com.mrh0.createaddition.blocks.connector.base.AbstractConnectorBlock;
|
||||
import com.mrh0.createaddition.index.CABlockEntities;
|
||||
import com.mrh0.createaddition.shapes.CAShapes;
|
||||
import com.simibubi.create.foundation.utility.VoxelShaper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public class LargeConnectorBlock extends AbstractConnectorBlock<LargeConnectorBlockEntity> {
|
||||
public static final VoxelShaper CONNECTOR_SHAPE = CAShapes.shape(5, 0, 5, 11, 7, 11).forDirectional();
|
||||
public LargeConnectorBlock(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<LargeConnectorBlockEntity> getBlockEntityClass() {
|
||||
return LargeConnectorBlockEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityType<? extends LargeConnectorBlockEntity> getBlockEntityType() {
|
||||
return CABlockEntities.LARGE_CONNECTOR.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return CABlockEntities.LARGE_CONNECTOR.create(pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
|
||||
return CONNECTOR_SHAPE.get(state.getValue(FACING).getOpposite());
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.mrh0.createaddition.blocks.connector;
|
||||
|
||||
import com.mrh0.createaddition.blocks.connector.base.AbstractConnectorBlock;
|
||||
import com.mrh0.createaddition.blocks.connector.base.AbstractConnectorBlockEntity;
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LargeConnectorBlockEntity extends AbstractConnectorBlockEntity {
|
||||
|
||||
private final static float OFFSET_HEIGHT = 1f;
|
||||
public final static Vec3 OFFSET_DOWN = new Vec3(0f, -OFFSET_HEIGHT/16f, 0f);
|
||||
public final static Vec3 OFFSET_UP = new Vec3(0f, OFFSET_HEIGHT/16f, 0f);
|
||||
public final static Vec3 OFFSET_NORTH = new Vec3(0f, 0f, -OFFSET_HEIGHT/16f);
|
||||
public final static Vec3 OFFSET_WEST = new Vec3(-OFFSET_HEIGHT/16f, 0f, 0f);
|
||||
public final static Vec3 OFFSET_SOUTH = new Vec3(0f, 0f, OFFSET_HEIGHT/16f);
|
||||
public final static Vec3 OFFSET_EAST = new Vec3(OFFSET_HEIGHT/16f, 0f, 0f);
|
||||
|
||||
public LargeConnectorBlockEntity(BlockEntityType<?> blockEntityTypeIn, BlockPos pos, BlockState state) {
|
||||
super(blockEntityTypeIn, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> list) {}
|
||||
|
||||
@Override
|
||||
public long getMaxIn() {
|
||||
return Config.LARGE_CONNECTOR_MAX_INPUT.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxOut() {
|
||||
return Config.LARGE_CONNECTOR_MAX_OUTPUT.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNodeCount() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getNodeOffset(int node) {
|
||||
return switch (getBlockState().getValue(AbstractConnectorBlock.FACING)) {
|
||||
case DOWN -> OFFSET_DOWN;
|
||||
case UP -> OFFSET_UP;
|
||||
case NORTH -> OFFSET_NORTH;
|
||||
case WEST -> OFFSET_WEST;
|
||||
case SOUTH -> OFFSET_SOUTH;
|
||||
case EAST -> OFFSET_EAST;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectorType getConnectorType() {
|
||||
return ConnectorType.Large;
|
||||
}
|
||||
|
||||
public int getMaxWireLength() {
|
||||
return Config.LARGE_CONNECTOR_MAX_LENGTH.get();
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package com.mrh0.createaddition.blocks.connector;
|
||||
|
||||
import com.mrh0.createaddition.blocks.connector.base.AbstractConnectorBlock;
|
||||
import com.mrh0.createaddition.index.CABlockEntities;
|
||||
import com.mrh0.createaddition.shapes.CAShapes;
|
||||
import com.simibubi.create.foundation.utility.VoxelShaper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SmallConnectorBlock extends AbstractConnectorBlock<SmallConnectorBlockEntity> {
|
||||
public static final VoxelShaper CONNECTOR_SHAPE = CAShapes.shape(6, 0, 6, 10, 5, 10).forDirectional();
|
||||
public SmallConnectorBlock(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<SmallConnectorBlockEntity> getBlockEntityClass() {
|
||||
return SmallConnectorBlockEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityType<? extends SmallConnectorBlockEntity> getBlockEntityType() {
|
||||
return CABlockEntities.SMALL_CONNECTOR.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return CABlockEntities.SMALL_CONNECTOR.create(pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
|
||||
return CONNECTOR_SHAPE.get(state.getValue(FACING).getOpposite());
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.mrh0.createaddition.blocks.connector;
|
||||
|
||||
import com.mrh0.createaddition.blocks.connector.base.AbstractConnectorBlock;
|
||||
import com.mrh0.createaddition.blocks.connector.base.AbstractConnectorBlockEntity;
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SmallConnectorBlockEntity extends AbstractConnectorBlockEntity {
|
||||
|
||||
private final static float OFFSET_HEIGHT = 3f;
|
||||
public final static Vec3 OFFSET_DOWN = new Vec3(0f, -OFFSET_HEIGHT/16f, 0f);
|
||||
public final static Vec3 OFFSET_UP = new Vec3(0f, OFFSET_HEIGHT/16f, 0f);
|
||||
public final static Vec3 OFFSET_NORTH = new Vec3(0f, 0f, -OFFSET_HEIGHT/16f);
|
||||
public final static Vec3 OFFSET_WEST = new Vec3(-OFFSET_HEIGHT/16f, 0f, 0f);
|
||||
public final static Vec3 OFFSET_SOUTH = new Vec3(0f, 0f, OFFSET_HEIGHT/16f);
|
||||
public final static Vec3 OFFSET_EAST = new Vec3(OFFSET_HEIGHT/16f, 0f, 0f);
|
||||
|
||||
public SmallConnectorBlockEntity(BlockEntityType<?> blockEntityTypeIn, BlockPos pos, BlockState state) {
|
||||
super(blockEntityTypeIn, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> list) {}
|
||||
|
||||
@Override
|
||||
public long getMaxIn() {
|
||||
return Config.SMALL_CONNECTOR_MAX_INPUT.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxOut() {
|
||||
return Config.SMALL_CONNECTOR_MAX_OUTPUT.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNodeCount() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getNodeOffset(int node) {
|
||||
return switch (getBlockState().getValue(AbstractConnectorBlock.FACING)) {
|
||||
case DOWN -> OFFSET_DOWN;
|
||||
case UP -> OFFSET_UP;
|
||||
case NORTH -> OFFSET_NORTH;
|
||||
case WEST -> OFFSET_WEST;
|
||||
case SOUTH -> OFFSET_SOUTH;
|
||||
case EAST -> OFFSET_EAST;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectorType getConnectorType() {
|
||||
return ConnectorType.Small;
|
||||
}
|
||||
|
||||
public int getMaxWireLength() {
|
||||
return Config.SMALL_CONNECTOR_MAX_LENGTH.get();
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.mrh0.createaddition.blocks.connector;
|
||||
|
||||
import com.mrh0.createaddition.blocks.connector.base.AbstractConnectorBlock;
|
||||
import com.mrh0.createaddition.energy.NodeRotation;
|
||||
import com.mrh0.createaddition.index.CABlockEntities;
|
||||
import com.mrh0.createaddition.shapes.CAShapes;
|
||||
import com.simibubi.create.foundation.utility.VoxelShaper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public class SmallLightConnectorBlock extends AbstractConnectorBlock<SmallLightConnectorBlockEntity> {
|
||||
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||
|
||||
public static final VoxelShaper CONNECTOR_SHAPE = CAShapes.shape(6, 0, 6, 10, 5, 10).add(5, 4, 5, 11, 10, 11).forDirectional();
|
||||
public SmallLightConnectorBlock(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext c) {
|
||||
return super.getStateForPlacement(c).setValue(POWERED, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||
builder.add(FACING, MODE, NodeRotation.ROTATION, VARIANT, POWERED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<SmallLightConnectorBlockEntity> getBlockEntityClass() {
|
||||
return SmallLightConnectorBlockEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityType<? extends SmallLightConnectorBlockEntity> getBlockEntityType() {
|
||||
return CABlockEntities.SMALL_LIGHT_CONNECTOR.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return CABlockEntities.SMALL_LIGHT_CONNECTOR.create(pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
|
||||
return CONNECTOR_SHAPE.get(state.getValue(FACING).getOpposite());
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package com.mrh0.createaddition.blocks.connector;
|
||||
|
||||
import com.mrh0.createaddition.blocks.connector.base.AbstractConnectorBlock;
|
||||
import com.mrh0.createaddition.blocks.connector.base.AbstractConnectorBlockEntity;
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
import com.mrh0.createaddition.energy.network.EnergyNetwork;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SmallLightConnectorBlockEntity extends AbstractConnectorBlockEntity {
|
||||
|
||||
private final static float OFFSET_HEIGHT = 5.5f;
|
||||
public final static Vec3 OFFSET_DOWN = new Vec3(0f, -OFFSET_HEIGHT/16f, 0f);
|
||||
public final static Vec3 OFFSET_UP = new Vec3(0f, OFFSET_HEIGHT/16f, 0f);
|
||||
public final static Vec3 OFFSET_NORTH = new Vec3(0f, 0f, -OFFSET_HEIGHT/16f);
|
||||
public final static Vec3 OFFSET_WEST = new Vec3(-OFFSET_HEIGHT/16f, 0f, 0f);
|
||||
public final static Vec3 OFFSET_SOUTH = new Vec3(0f, 0f, OFFSET_HEIGHT/16f);
|
||||
public final static Vec3 OFFSET_EAST = new Vec3(OFFSET_HEIGHT/16f, 0f, 0f);
|
||||
|
||||
private int posTimeOffset = 0;
|
||||
|
||||
public SmallLightConnectorBlockEntity(BlockEntityType<?> blockEntityTypeIn, BlockPos pos, BlockState state) {
|
||||
super(blockEntityTypeIn, pos, state);
|
||||
|
||||
posTimeOffset = 10 + (Math.abs(pos.getX()*31 + pos.getY()*45 + pos.getZ()*33) % 7) * 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundTag nbt, boolean clientPacket) {
|
||||
tickToggleTimer = nbt.getInt("tick_toggle_timer");
|
||||
super.read(nbt, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag nbt, boolean clientPacket) {
|
||||
nbt.putInt("tick_toggle_timer", tickToggleTimer);
|
||||
super.write(nbt, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> list) {}
|
||||
|
||||
@Override
|
||||
public long getMaxIn() {
|
||||
return Config.SMALL_CONNECTOR_MAX_INPUT.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxOut() {
|
||||
return Config.SMALL_CONNECTOR_MAX_OUTPUT.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNodeCount() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getNodeOffset(int node) {
|
||||
return switch (getBlockState().getValue(AbstractConnectorBlock.FACING)) {
|
||||
case DOWN -> OFFSET_DOWN;
|
||||
case UP -> OFFSET_UP;
|
||||
case NORTH -> OFFSET_NORTH;
|
||||
case WEST -> OFFSET_WEST;
|
||||
case SOUTH -> OFFSET_SOUTH;
|
||||
case EAST -> OFFSET_EAST;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectorType getConnectorType() {
|
||||
return ConnectorType.Small;
|
||||
}
|
||||
|
||||
public int getMaxWireLength() {
|
||||
return Config.SMALL_CONNECTOR_MAX_LENGTH.get();
|
||||
}
|
||||
|
||||
private int tickToggleTimer = 0;
|
||||
@Override
|
||||
protected void specialTick() {
|
||||
if(getLevel() == null) return;
|
||||
if(level.isClientSide()) return;
|
||||
EnergyNetwork network = getNetwork(0);
|
||||
boolean hasEnergy = network != null && network.pull(Config.SMALL_LIGHT_CONNECTOR_CONSUMPTION.get()) > 0;
|
||||
tickToggleTimer = tickToggleTimer + (hasEnergy ? 1 : -1);
|
||||
|
||||
if (tickToggleTimer >= posTimeOffset) {
|
||||
tickToggleTimer = posTimeOffset;
|
||||
if (!getBlockState().getValue(SmallLightConnectorBlock.POWERED))
|
||||
getLevel().setBlockAndUpdate(getBlockPos(), getBlockState()
|
||||
.setValue(SmallLightConnectorBlock.POWERED, true));
|
||||
}
|
||||
|
||||
if (tickToggleTimer <= -posTimeOffset) {
|
||||
tickToggleTimer = -posTimeOffset;
|
||||
if (getBlockState().getValue(SmallLightConnectorBlock.POWERED))
|
||||
getLevel().setBlockAndUpdate(getBlockPos(), getBlockState()
|
||||
.setValue(SmallLightConnectorBlock.POWERED, false));
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
package com.mrh0.createaddition.blocks.connector.base;
|
||||
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
import com.mrh0.createaddition.energy.IWireNode;
|
||||
import com.mrh0.createaddition.energy.NodeRotation;
|
||||
import com.simibubi.create.content.contraptions.ITransformableBlock;
|
||||
import com.simibubi.create.content.contraptions.StructureTransform;
|
||||
import com.simibubi.create.content.equipment.wrench.IWrenchable;
|
||||
import com.simibubi.create.foundation.block.IBE;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Mirror;
|
||||
import net.minecraft.world.level.block.Rotation;
|
||||
import net.minecraft.world.level.block.SupportType;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||
import net.minecraft.world.phys.shapes.BooleanOp;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public abstract class AbstractConnectorBlock<BE extends AbstractConnectorBlockEntity> extends Block implements IBE<BE>, IWrenchable, ITransformableBlock {
|
||||
public static final DirectionProperty FACING = BlockStateProperties.FACING;
|
||||
public static final EnumProperty<ConnectorMode> MODE = EnumProperty.create("mode", ConnectorMode.class);
|
||||
public static final EnumProperty<ConnectorVariant> VARIANT = EnumProperty.create("variant", ConnectorVariant.class);
|
||||
private static final VoxelShape boxwe = Block.box(0,7,7,10,9,9);
|
||||
private static final VoxelShape boxsn = Block.box(7,7,0,9,9,10);
|
||||
|
||||
public AbstractConnectorBlock(Properties properties) {
|
||||
super(properties);
|
||||
this.registerDefaultState(this.defaultBlockState()
|
||||
.setValue(FACING, Direction.NORTH)
|
||||
.setValue(MODE, ConnectorMode.None)
|
||||
.setValue(NodeRotation.ROTATION, NodeRotation.NONE)
|
||||
.setValue(VARIANT, ConnectorVariant.Default));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
|
||||
builder.add(FACING, MODE, NodeRotation.ROTATION, VARIANT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext c) {
|
||||
Direction dir = c.getClickedFace().getOpposite();
|
||||
ConnectorMode mode = ConnectorMode.test(c.getLevel(), c.getClickedPos().relative(dir), c.getClickedFace());
|
||||
ConnectorVariant variant = ConnectorVariant.test(c.getLevel(), c.getClickedPos().relative(dir), c.getClickedFace());
|
||||
return this.defaultBlockState().setValue(FACING, dir).setValue(MODE, mode).setValue(VARIANT, variant);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerWillDestroy(Level worldIn, BlockPos pos, BlockState state, Player player) {
|
||||
super.playerWillDestroy(worldIn, pos, state, player);
|
||||
|
||||
if (worldIn.isClientSide()) return;
|
||||
BlockEntity te = worldIn.getBlockEntity(pos);
|
||||
if (te == null) return;
|
||||
if (!(te instanceof IWireNode cte)) return;
|
||||
cte.dropWires(worldIn, !player.isCreative());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult onWrenched(BlockState state, UseOnContext c) {
|
||||
if (c.getLevel().isClientSide()) {
|
||||
c.getLevel().playLocalSound(c.getClickedPos().getX(), c.getClickedPos().getY(), c.getClickedPos().getZ(), SoundEvents.BONE_BLOCK_HIT, SoundSource.BLOCKS, 1f, 1f, false);
|
||||
}
|
||||
c.getLevel().setBlockAndUpdate(c.getClickedPos(), state.setValue(MODE, state.getValue(MODE).getNext()));
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult onSneakWrenched(BlockState state, UseOnContext c) {
|
||||
BlockEntity be = c.getLevel().getBlockEntity(c.getClickedPos());
|
||||
if(be == null) return IWrenchable.super.onSneakWrenched(state, c);
|
||||
if(!(be instanceof IWireNode cbe)) return IWrenchable.super.onSneakWrenched(state, c);
|
||||
// if(be instanceof AbstractConnectorBlockEntity acbe) acbe.updateExternalEnergyStorage();
|
||||
|
||||
if (!c.getLevel().isClientSide() && c.getPlayer() != null)
|
||||
cbe.dropWires(c.getLevel(), c.getPlayer(), !c.getPlayer().isCreative());
|
||||
|
||||
return IWrenchable.super.onSneakWrenched(state, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) {
|
||||
BlockEntity blockEntity = state.hasBlockEntity() ? worldIn.getBlockEntity(pos) : null;
|
||||
if(blockEntity != null) {
|
||||
if(blockEntity instanceof AbstractConnectorBlockEntity) {
|
||||
((AbstractConnectorBlockEntity)blockEntity).updateExternalEnergyStorage();
|
||||
}
|
||||
}
|
||||
if (!state.canSurvive(worldIn, pos)) {
|
||||
dropResources(state, worldIn, pos, blockEntity);
|
||||
|
||||
if(blockEntity instanceof IWireNode)
|
||||
((IWireNode) blockEntity).dropWires(worldIn, true);
|
||||
|
||||
worldIn.removeBlock(pos, false);
|
||||
|
||||
for (Direction direction : Direction.values())
|
||||
worldIn.updateNeighborsAt(pos.relative(direction), this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||
Direction dir = state.getValue(FACING);
|
||||
return
|
||||
!Shapes.joinIsNotEmpty(world.getBlockState(pos.relative(dir)).getBlockSupportShape(world,pos.relative(dir)).getFaceShape(dir.getOpposite()), boxwe, BooleanOp.ONLY_SECOND) ||
|
||||
!Shapes.joinIsNotEmpty(world.getBlockState(pos.relative(dir)).getBlockSupportShape(world,pos.relative(dir)).getFaceShape(dir.getOpposite()), boxsn, BooleanOp.ONLY_SECOND) ||
|
||||
world.getBlockState(pos.relative(dir)).isFaceSturdy(world, pos, dir.getOpposite(), SupportType.CENTER) || Config.CONNECTOR_IGNORE_FACE_CHECK.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState state, Rotation direction) {
|
||||
// Handle old rotation.
|
||||
return state.setValue(FACING, direction.rotate(state.getValue(FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState mirror(BlockState state, Mirror mirror) {
|
||||
return state.setValue(FACING, mirror.mirror(state.getValue(FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState transform(BlockState state, StructureTransform transform) {
|
||||
NodeRotation rotation = NodeRotation.get(transform.rotationAxis, transform.rotation);
|
||||
// Handle default rotation & mirroring.
|
||||
if (transform.mirror != null) state = mirror(state, transform.mirror);
|
||||
state = state.setValue(FACING, rotation.rotate(state.getValue(FACING), false));
|
||||
// Set the rotation state, which will be used to update the nodes.
|
||||
return state.setValue(NodeRotation.ROTATION, rotation);
|
||||
}
|
||||
}
|
@ -0,0 +1,428 @@
|
||||
package com.mrh0.createaddition.blocks.connector.base;
|
||||
|
||||
import com.mrh0.createaddition.CreateAddition;
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
import com.mrh0.createaddition.debug.IDebugDrawer;
|
||||
import com.mrh0.createaddition.energy.IWireNode;
|
||||
import com.mrh0.createaddition.energy.LocalNode;
|
||||
import com.mrh0.createaddition.energy.NodeRotation;
|
||||
import com.mrh0.createaddition.energy.WireType;
|
||||
import com.mrh0.createaddition.energy.network.EnergyNetwork;
|
||||
import com.mrh0.createaddition.network.EnergyNetworkPacket;
|
||||
import com.mrh0.createaddition.network.IObserveTileEntity;
|
||||
import com.mrh0.createaddition.network.ObservePacket;
|
||||
import com.mrh0.createaddition.transfer.EnergyTransferable;
|
||||
import com.mrh0.createaddition.util.Util;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
|
||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||
import io.github.fabricators_of_create.porting_lib.transfer.TransferUtil;
|
||||
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction;
|
||||
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import team.reborn.energy.api.EnergyStorage;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public abstract class AbstractConnectorBlockEntity extends SmartBlockEntity implements EnergyTransferable, IWireNode, IObserveTileEntity, IHaveGoggleInformation, IDebugDrawer {
|
||||
|
||||
private final Set<LocalNode> wireCache = new HashSet<>();
|
||||
private final LocalNode[] localNodes;
|
||||
private final IWireNode[] nodeCache;
|
||||
private EnergyNetwork network;
|
||||
private long demand = 0;
|
||||
|
||||
private boolean wasContraption = false;
|
||||
private boolean firstTick = true;
|
||||
|
||||
@NotNull
|
||||
protected EnergyStorage networkStorage = new NetworkEnergyStorage();
|
||||
@NotNull
|
||||
protected EnergyStorage externalStorage = EnergyStorage.EMPTY;
|
||||
|
||||
public AbstractConnectorBlockEntity(BlockEntityType<?> blockEntityTypeIn, BlockPos pos, BlockState state) {
|
||||
super(blockEntityTypeIn, pos, state);
|
||||
this.localNodes = new LocalNode[getNodeCount()];
|
||||
this.nodeCache = new IWireNode[getNodeCount()];
|
||||
}
|
||||
|
||||
public EnergyStorage getEnergyStorage(Direction side){
|
||||
if(isEnergyInput(side)||isEnergyOutput(side)) {
|
||||
return networkStorage;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public abstract long getMaxIn();
|
||||
public abstract long getMaxOut();
|
||||
//Renamed to prevent name conflict
|
||||
public long getCapacityOutside() {
|
||||
return Math.min(getMaxIn(), getMaxOut());
|
||||
}
|
||||
private class NetworkEnergyStorage implements EnergyStorage {
|
||||
|
||||
@Override
|
||||
public long insert(long maxAmount, TransactionContext transaction) {
|
||||
if(!Config.CONNECTOR_ALLOW_PASSIVE_IO.get()) return 0;
|
||||
if(getMode() != ConnectorMode.Pull) return 0;
|
||||
if (network == null) return 0;
|
||||
maxAmount = Math.min(maxAmount, getMaxIn());
|
||||
return network.push(maxAmount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long extract(long maxAmount, TransactionContext transaction) {
|
||||
if(!Config.CONNECTOR_ALLOW_PASSIVE_IO.get()) return 0;
|
||||
if(getMode() != ConnectorMode.Push) return 0;
|
||||
if (network == null) return 0;
|
||||
maxAmount = Math.min(maxAmount, getMaxOut());
|
||||
return network.pull(maxAmount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAmount() {
|
||||
if (network == null) return 0;
|
||||
return Math.min(getCapacity(), network.getBuff());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getCapacity() {
|
||||
return getCapacityOutside();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable IWireNode getWireNode(int index) {
|
||||
return IWireNode.getWireNodeFrom(index, this, this.localNodes, this.nodeCache, level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable LocalNode getLocalNode(int index) {
|
||||
return this.localNodes[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNode(int index, int other, BlockPos pos, WireType type) {
|
||||
this.localNodes[index] = new LocalNode(this, index, other, type, pos);
|
||||
|
||||
notifyUpdate();
|
||||
|
||||
// Invalidate
|
||||
if (network != null) network.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNode(int index, boolean dropWire) {
|
||||
LocalNode old = this.localNodes[index];
|
||||
this.localNodes[index] = null;
|
||||
this.nodeCache[index] = null;
|
||||
|
||||
invalidateNodeCache();
|
||||
notifyUpdate();
|
||||
|
||||
// Invalidate
|
||||
if (network != null) network.invalidate();
|
||||
// Drop wire next tick.
|
||||
if (dropWire && old != null) this.wireCache.add(old);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPos() {
|
||||
return getBlockPos();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNetwork(int node, EnergyNetwork network) {
|
||||
this.network = network;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnergyNetwork getNetwork(int node) {
|
||||
return network;
|
||||
}
|
||||
|
||||
public boolean isEnergyInput(Direction side) {
|
||||
return getBlockState().getValue(AbstractConnectorBlock.FACING) == side;
|
||||
}
|
||||
|
||||
public boolean isEnergyOutput(Direction side) {
|
||||
return getBlockState().getValue(AbstractConnectorBlock.FACING) == side;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundTag nbt, boolean clientPacket) {
|
||||
super.read(nbt, clientPacket);
|
||||
// Convert old nbt data. x0, y0, z0, node0 & type0 etc.
|
||||
if (!clientPacket && nbt.contains("node0")) {
|
||||
convertOldNbt(nbt);
|
||||
setChanged();
|
||||
}
|
||||
|
||||
// Read the nodes.
|
||||
invalidateLocalNodes();
|
||||
invalidateNodeCache();
|
||||
ListTag nodes = nbt.getList(LocalNode.NODES, Tag.TAG_COMPOUND);
|
||||
nodes.forEach(tag -> {
|
||||
LocalNode localNode = new LocalNode(this, (CompoundTag) tag);
|
||||
this.localNodes[localNode.getIndex()] = localNode;
|
||||
});
|
||||
|
||||
// Check if this was a contraption.
|
||||
if (nbt.contains("contraption") && !clientPacket) {
|
||||
this.wasContraption = nbt.getBoolean("contraption");
|
||||
NodeRotation rotation = getBlockState().getValue(NodeRotation.ROTATION);
|
||||
if(level == null) return;
|
||||
if (rotation != NodeRotation.NONE)
|
||||
level.setBlock(getBlockPos(), getBlockState().setValue(NodeRotation.ROTATION, NodeRotation.NONE), 0);
|
||||
// Loop over all nodes and update their relative positions.
|
||||
for (LocalNode localNode : this.localNodes) {
|
||||
if (localNode == null) continue;
|
||||
localNode.updateRelative(rotation);
|
||||
}
|
||||
}
|
||||
|
||||
// Invalidate the network if we updated the nodes.
|
||||
if (!nodes.isEmpty() && this.network != null) this.network.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag nbt, boolean clientPacket) {
|
||||
super.write(nbt, clientPacket);
|
||||
// Write nodes.
|
||||
ListTag nodes = new ListTag();
|
||||
for (int i = 0; i < getNodeCount(); i++) {
|
||||
LocalNode localNode = this.localNodes[i];
|
||||
if (localNode == null) continue;
|
||||
CompoundTag tag = new CompoundTag();
|
||||
localNode.write(tag);
|
||||
nodes.add(tag);
|
||||
}
|
||||
nbt.put(LocalNode.NODES, nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called after the tile entity has been part of a contraption.
|
||||
* Only runs on the server.
|
||||
*/
|
||||
private void validateNodes() {
|
||||
boolean changed = validateLocalNodes(this.localNodes);
|
||||
|
||||
// Always set as changed if we were a contraption, as nodes might have been rotated.
|
||||
notifyUpdate();
|
||||
|
||||
if (changed) {
|
||||
invalidateNodeCache();
|
||||
// Invalidate
|
||||
if (this.network != null) this.network.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void firstTick() {
|
||||
this.firstTick = false;
|
||||
// Check if this blockentity was a part of a contraption.
|
||||
// If it was, then make sure all the nodes are valid.
|
||||
if(level == null) return;
|
||||
if (this.wasContraption && !level.isClientSide()) {
|
||||
this.wasContraption = false;
|
||||
validateNodes();
|
||||
}
|
||||
|
||||
updateExternalEnergyStorage();
|
||||
}
|
||||
|
||||
protected void specialTick() {}
|
||||
|
||||
boolean externalStorageInvalid = false;
|
||||
@Override
|
||||
public void tick() {
|
||||
if (this.firstTick) firstTick();
|
||||
if (level == null) return;
|
||||
if (!level.isLoaded(getBlockPos())) return;
|
||||
|
||||
// Check if we need to drop any wires due to contraption.
|
||||
if (!this.wireCache.isEmpty() && !isRemoved()) handleWireCache(level, this.wireCache);
|
||||
|
||||
specialTick();
|
||||
|
||||
if (getMode() == ConnectorMode.None) return;
|
||||
super.tick();
|
||||
|
||||
if(level == null) return;
|
||||
if(level.isClientSide()) return;
|
||||
if(awakeNetwork(level)) notifyUpdate();
|
||||
|
||||
networkTick(network);
|
||||
|
||||
if (externalStorageInvalid) updateExternalEnergyStorage();
|
||||
}
|
||||
|
||||
private void networkTick(EnergyNetwork network) {
|
||||
ConnectorMode mode = getMode();
|
||||
if(level == null) return;
|
||||
if(level.isClientSide()) return;
|
||||
|
||||
if (mode == ConnectorMode.Push) {
|
||||
long pulled;
|
||||
try (Transaction t = TransferUtil.getTransaction()){
|
||||
pulled = network.pull(network.demand(externalStorage.insert(getMaxOut(), t)));
|
||||
}
|
||||
try (Transaction t = TransferUtil.getTransaction()) {
|
||||
externalStorage.insert(pulled, t);
|
||||
t.commit();
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == ConnectorMode.Pull) {
|
||||
long toPush;
|
||||
try(Transaction t = TransferUtil.getTransaction()) {
|
||||
toPush = externalStorage.extract(network.push(getMaxIn(), true), t);
|
||||
t.commit();
|
||||
}
|
||||
network.push(toPush);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
if(level == null) return;
|
||||
if (level.isClientSide()) return;
|
||||
// Remove all nodes.
|
||||
for (int i = 0; i < getNodeCount(); i++) {
|
||||
LocalNode localNode = getLocalNode(i);
|
||||
if (localNode == null) continue;
|
||||
IWireNode otherNode = getWireNode(i);
|
||||
if(otherNode == null) continue;
|
||||
|
||||
int ourNode = localNode.getOtherIndex();
|
||||
if (localNode.isInvalid())
|
||||
otherNode.removeNode(ourNode);
|
||||
else
|
||||
otherNode.removeNode(ourNode, true); // Make the other node drop the wires.
|
||||
}
|
||||
|
||||
invalidateNodeCache();
|
||||
invalidateCaps();
|
||||
|
||||
// Invalidate
|
||||
if (network != null) network.invalidate();
|
||||
}
|
||||
|
||||
public void invalidateLocalNodes() {
|
||||
for(int i = 0; i < getNodeCount(); i++)
|
||||
this.localNodes[i] = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateNodeCache() {
|
||||
for(int i = 0; i < getNodeCount(); i++)
|
||||
this.nodeCache[i] = null;
|
||||
}
|
||||
|
||||
public ConnectorMode getMode() {
|
||||
return getBlockState().getValue(AbstractConnectorBlock.MODE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onObserved(ServerPlayer player, ObservePacket pack) {
|
||||
if(isNetworkValid(0)) {
|
||||
EnergyNetworkPacket.send(worldPosition, getNetwork(0).getPulled(), getNetwork(0).getPushed(), player);
|
||||
} else {
|
||||
EnergyNetworkPacket.send(worldPosition, 0, 0, player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
|
||||
ObservePacket.send(worldPosition, 0);
|
||||
|
||||
tooltip.add(Component.literal(spacing)
|
||||
.append(Component.translatable(CreateAddition.MODID + ".tooltip.connector.info").withStyle(ChatFormatting.WHITE)));
|
||||
|
||||
tooltip.add(Component.literal(spacing)
|
||||
.append(Component.translatable(CreateAddition.MODID + ".tooltip.energy.mode").withStyle(ChatFormatting.GRAY)));
|
||||
tooltip.add(Component.literal(spacing).append(Component.literal(" "))
|
||||
.append(getBlockState().getValue(AbstractConnectorBlock.MODE).getTooltip().withStyle(ChatFormatting.AQUA)));
|
||||
|
||||
tooltip.add(Component.literal(spacing)
|
||||
.append(Component.translatable(CreateAddition.MODID + ".tooltip.energy.usage").withStyle(ChatFormatting.GRAY)));
|
||||
tooltip.add(Component.literal(spacing).append(" ")
|
||||
.append(Util.format((int)EnergyNetworkPacket.clientBuff)).append("fe/t").withStyle(ChatFormatting.AQUA));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean ignoreCapSide() {
|
||||
return this.getBlockState().getValue(AbstractConnectorBlock.MODE).isActive();
|
||||
}
|
||||
|
||||
public void updateExternalEnergyStorage() {
|
||||
if (level == null) return;
|
||||
if (!level.isLoaded(getBlockPos())) return;
|
||||
externalStorageInvalid = false;
|
||||
var side = getBlockState().getValue(AbstractConnectorBlock.FACING);
|
||||
BlockPos externalPos = worldPosition.relative(side);
|
||||
if (!level.isLoaded(externalPos)) {
|
||||
externalStorage = EnergyStorage.EMPTY;
|
||||
return;
|
||||
}
|
||||
EnergyStorage es = EnergyStorage.SIDED.find(level, externalPos, side.getOpposite());
|
||||
if(ignoreCapSide() && es == null) {
|
||||
es = EnergyStorage.SIDED.find(level, externalPos, null);
|
||||
}
|
||||
if(es == null){
|
||||
externalStorage = EnergyStorage.EMPTY;
|
||||
} else {
|
||||
externalStorage = es;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawDebug() {
|
||||
if (level == null) return;
|
||||
// Outline all connected nodes.
|
||||
for (int i = 0; i < getNodeCount(); i++) {
|
||||
LocalNode localNode = this.localNodes[i];
|
||||
if (localNode == null) continue;
|
||||
BlockPos pos = localNode.getPos();
|
||||
BlockState state = level.getBlockState(pos);
|
||||
VoxelShape shape = state.getBlockSupportShape(level, pos);
|
||||
int color;
|
||||
if (i == 0) color = 0xFF0000;
|
||||
else if (i == 1) color = 0x00FF00;
|
||||
else if (i == 2) color = 0x0000FF;
|
||||
else color = 0xFFFFFF;
|
||||
// Make sure the node is a connector block.
|
||||
if (!(level.getBlockEntity(pos) instanceof IWireNode)) {
|
||||
shape = Shapes.block();
|
||||
color = 0xFF00FF;
|
||||
}
|
||||
// ca_ = Create Addition
|
||||
CreateClient.OUTLINER.chaseAABB("ca_nodes_" + i, shape.bounds().move(pos)).lineWidth(0.0625F).colored(color);
|
||||
}
|
||||
// Outline connected power
|
||||
BlockPos pos = worldPosition.relative(getBlockState().getValue(AbstractConnectorBlock.FACING));
|
||||
EnergyStorage cap = EnergyStorage.SIDED.find(level, pos, getBlockState().getValue(AbstractConnectorBlock.FACING).getOpposite());
|
||||
if(cap == null) return;
|
||||
|
||||
// if(ignoreCapSide() && !cap.isPresent()) cap = te.getCapability(CapabilityEnergy.ENERGY);
|
||||
|
||||
VoxelShape shape = level.getBlockState(pos).getBlockSupportShape(level, pos);
|
||||
CreateClient.OUTLINER.chaseAABB("ca_output", shape.bounds().move(pos)).lineWidth(0.0625F).colored(0x5B5BFF);
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package com.mrh0.createaddition.blocks.connector.base;
|
||||
|
||||
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.util.StringRepresentable;
|
||||
import net.minecraft.world.level.Level;
|
||||
import team.reborn.energy.api.EnergyStorage;
|
||||
|
||||
public enum ConnectorMode implements StringRepresentable {
|
||||
Push("push"),
|
||||
Pull("pull"),
|
||||
None("none"),
|
||||
Passive("passive");
|
||||
|
||||
private String name;
|
||||
|
||||
ConnectorMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSerializedName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public ConnectorMode getNext() {
|
||||
switch (this) {
|
||||
//case Passive:
|
||||
// return None;
|
||||
case None:
|
||||
return Pull;
|
||||
case Pull:
|
||||
return Push;
|
||||
case Push:
|
||||
return None;
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
public MutableComponent getTooltip() {
|
||||
switch (this) {
|
||||
case Passive:
|
||||
return Component.translatable("createaddition.tooltip.energy.passive");
|
||||
case None:
|
||||
return Component.translatable("createaddition.tooltip.energy.none");
|
||||
case Pull:
|
||||
return Component.translatable("createaddition.tooltip.energy.pull");
|
||||
case Push:
|
||||
return Component.translatable("createaddition.tooltip.energy.push");
|
||||
}
|
||||
return Component.translatable("createaddition.tooltip.energy.none");
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this == Push || this == Pull;
|
||||
}
|
||||
|
||||
public static ConnectorMode test(Level level, BlockPos pos, Direction face) {
|
||||
EnergyStorage e = EnergyStorage.SIDED.find(level, pos, face);
|
||||
if(e == null) return None;
|
||||
|
||||
if(e.supportsExtraction()) return Pull;
|
||||
if(e.supportsInsertion()) return Push;
|
||||
|
||||
return None;
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.mrh0.createaddition.blocks.connector.base;
|
||||
|
||||
import com.mrh0.createaddition.rendering.WireNodeRenderer;
|
||||
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
|
||||
|
||||
public class ConnectorRenderer extends WireNodeRenderer<AbstractConnectorBlockEntity> {
|
||||
|
||||
public ConnectorRenderer(BlockEntityRendererProvider.Context context) {
|
||||
super(context);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
package com.mrh0.createaddition.blocks.connector.base;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.decoration.girder.GirderBlock;
|
||||
import com.simibubi.create.content.decoration.girder.GirderEncasedShaftBlock;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.StringRepresentable;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public enum ConnectorVariant implements StringRepresentable {
|
||||
Default("default"),
|
||||
Girder("girder");
|
||||
|
||||
private String name;
|
||||
ConnectorVariant(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSerializedName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public static ConnectorVariant test(Level level, BlockPos pos, Direction face) {
|
||||
BlockState state = level.getBlockState(pos);
|
||||
if(state.is(AllBlocks.METAL_GIRDER.get())) {
|
||||
if(state.getValue(GirderBlock.TOP) && face == Direction.UP) return Default;
|
||||
if(state.getValue(GirderBlock.BOTTOM) && face == Direction.DOWN) return Default;
|
||||
if(state.getValue(GirderBlock.X) && face.getAxis() == Direction.Axis.X) return Default;
|
||||
if(state.getValue(GirderBlock.Z) && face.getAxis() == Direction.Axis.Z) return Default;
|
||||
return Girder;
|
||||
}
|
||||
if(state.is(AllBlocks.METAL_GIRDER_ENCASED_SHAFT.get())){
|
||||
if(!state.getValue(GirderEncasedShaftBlock.TOP) && face == Direction.UP) return Girder;
|
||||
if(!state.getValue(GirderEncasedShaftBlock.BOTTOM) && face == Direction.DOWN) return Girder;
|
||||
return Default;
|
||||
}
|
||||
return Default;
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package com.mrh0.createaddition.blocks.creative_energy;
|
||||
|
||||
import com.mrh0.createaddition.index.CABlockEntities;
|
||||
import com.mrh0.createaddition.shapes.CAShapes;
|
||||
import com.simibubi.create.content.logistics.crate.CrateBlock;
|
||||
import com.simibubi.create.foundation.block.IBE;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public class CreativeEnergyBlock extends CrateBlock implements IBE<CreativeEnergyBlockEntity> {
|
||||
|
||||
public static final VoxelShape CREATIVE_ENERGY_SHAPE = CAShapes.shape(1,0,1,15,16,15).add(0,2,0,16,14,16).build();
|
||||
|
||||
public CreativeEnergyBlock(Properties props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
|
||||
return CREATIVE_ENERGY_SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<CreativeEnergyBlockEntity> getBlockEntityClass() {
|
||||
return CreativeEnergyBlockEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityType<? extends CreativeEnergyBlockEntity> getBlockEntityType() {
|
||||
return CABlockEntities.CREATIVE_ENERGY.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) {
|
||||
BlockEntity tileentity = state.hasBlockEntity() ? worldIn.getBlockEntity(pos) : null;
|
||||
if(tileentity != null) {
|
||||
if(tileentity instanceof CreativeEnergyBlockEntity) {
|
||||
((CreativeEnergyBlockEntity)tileentity).updateCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return CABlockEntities.CREATIVE_ENERGY.create(pos, state);
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package com.mrh0.createaddition.blocks.creative_energy;
|
||||
|
||||
import com.mrh0.createaddition.energy.CreativeEnergyStorage;
|
||||
import com.mrh0.createaddition.transfer.EnergyTransferable;
|
||||
import com.simibubi.create.content.logistics.crate.CrateBlockEntity;
|
||||
import net.fabricmc.fabric.api.transfer.v1.transaction.Transaction;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import team.reborn.energy.api.EnergyStorage;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class CreativeEnergyBlockEntity extends CrateBlockEntity implements EnergyTransferable{
|
||||
|
||||
protected final CreativeEnergyStorage energy;
|
||||
public CreativeEnergyBlockEntity(BlockEntityType<?> tileEntityTypeIn, BlockPos pos, BlockState state) {
|
||||
super(tileEntityTypeIn, pos, state);
|
||||
energy = new CreativeEnergyStorage();
|
||||
}
|
||||
|
||||
private boolean firstTickState = true;
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if(level.isClientSide())
|
||||
return;
|
||||
if(firstTickState)
|
||||
firstTick();
|
||||
firstTickState = false;
|
||||
|
||||
for(Direction d : Direction.values()) {
|
||||
EnergyStorage ies = getCachedEnergy(d);
|
||||
if(ies == null)
|
||||
continue;
|
||||
try(Transaction t = Transaction.openOuter()) {
|
||||
long r = ies.insert(Integer.MAX_VALUE, t);
|
||||
t.commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void firstTick() {
|
||||
updateCache();
|
||||
}
|
||||
|
||||
public void updateCache() {
|
||||
if(level.isClientSide())
|
||||
return;
|
||||
for(Direction side : Direction.values()) {
|
||||
setCache(side, EnergyStorage.SIDED.find(level, worldPosition.relative(side), side.getOpposite()));
|
||||
}
|
||||
}
|
||||
|
||||
private EnergyStorage escacheUp = null;
|
||||
private EnergyStorage escacheDown = null;
|
||||
private EnergyStorage escacheNorth = null;
|
||||
private EnergyStorage escacheEast = null;
|
||||
private EnergyStorage escacheSouth = null;
|
||||
private EnergyStorage escacheWest = null;
|
||||
|
||||
public void setCache(Direction side, EnergyStorage storage) {
|
||||
switch (side) {
|
||||
case DOWN -> escacheDown = storage;
|
||||
case EAST -> escacheEast = storage;
|
||||
case NORTH -> escacheNorth = storage;
|
||||
case SOUTH -> escacheSouth = storage;
|
||||
case UP -> escacheUp = storage;
|
||||
case WEST -> escacheWest = storage;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("DataFlowIssue")
|
||||
public EnergyStorage getCachedEnergy(Direction side) {
|
||||
return switch (side) {
|
||||
case DOWN -> escacheDown;
|
||||
case EAST -> escacheEast;
|
||||
case NORTH -> escacheNorth;
|
||||
case SOUTH -> escacheSouth;
|
||||
case UP -> escacheUp;
|
||||
case WEST -> escacheWest;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnergyStorage getEnergyStorage(@Nullable Direction direction) {
|
||||
return energy;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.mrh0.createaddition.blocks.crops;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.item.Items;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.ItemLike;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.CropBlock;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public class HarmfulPlantBlock extends CropBlock {
|
||||
private static final VoxelShape[] SHAPE_BY_AGE = new VoxelShape[]{Block.box(0.0D, 0.0D, 0.0D, 16.0D, 2.0D, 16.0D), Block.box(0.0D, 0.0D, 0.0D, 16.0D, 3.0D, 16.0D), Block.box(0.0D, 0.0D, 0.0D, 16.0D, 4.0D, 16.0D), Block.box(0.0D, 0.0D, 0.0D, 16.0D, 5.0D, 16.0D), Block.box(0.0D, 0.0D, 0.0D, 16.0D, 6.0D, 16.0D), Block.box(0.0D, 0.0D, 0.0D, 16.0D, 7.0D, 16.0D), Block.box(0.0D, 0.0D, 0.0D, 16.0D, 8.0D, 16.0D), Block.box(0.0D, 0.0D, 0.0D, 16.0D, 9.0D, 16.0D)};
|
||||
|
||||
public HarmfulPlantBlock(BlockBehaviour.Properties pProperties) {
|
||||
super(pProperties);
|
||||
}
|
||||
|
||||
protected ItemLike getBaseSeedId() {
|
||||
return Items.CARROT;
|
||||
}
|
||||
|
||||
public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
|
||||
return SHAPE_BY_AGE[pState.getValue(this.getAgeProperty())];
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.mrh0.createaddition.blocks.digital_adapter;
|
||||
|
||||
import com.mrh0.createaddition.index.CABlockEntities;
|
||||
import com.simibubi.create.content.equipment.wrench.IWrenchable;
|
||||
import com.simibubi.create.foundation.block.IBE;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class DigitalAdapterBlock extends Block implements IBE<DigitalAdapterBlockEntity>, IWrenchable {
|
||||
public DigitalAdapterBlock(Properties props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<DigitalAdapterBlockEntity> getBlockEntityClass() {
|
||||
return DigitalAdapterBlockEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityType<? extends DigitalAdapterBlockEntity> getBlockEntityType() {
|
||||
return CABlockEntities.DIGITAL_ADAPTER.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return CABlockEntities.DIGITAL_ADAPTER.create(pos, state);
|
||||
}
|
||||
}
|
@ -0,0 +1,139 @@
|
||||
package com.mrh0.createaddition.blocks.digital_adapter;
|
||||
|
||||
import com.simibubi.create.content.contraptions.bearing.MechanicalBearingBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.elevator.ElevatorPulleyBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.piston.MechanicalPistonBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.pulley.PulleyBlockEntity;
|
||||
import com.simibubi.create.content.fluids.hosePulley.HosePulleyBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.gauge.SpeedGaugeBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.gauge.StressGaugeBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.speedController.SpeedControllerBlockEntity;
|
||||
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.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DigitalAdapterBlockEntity extends BlockEntity {
|
||||
public final List<MutableComponent> textLines;
|
||||
public static final int MAX_LINES = 16;
|
||||
public static final MutableComponent EMPTY_LINE = Component.literal("");
|
||||
|
||||
public DigitalAdapterBlockEntity(BlockEntityType<?> tileEntityTypeIn, BlockPos pos, BlockState state) {
|
||||
super(tileEntityTypeIn, pos, state);
|
||||
textLines = new ArrayList<>();
|
||||
for(int i = 0; i < MAX_LINES; i++) textLines.add(EMPTY_LINE);
|
||||
}
|
||||
|
||||
private int line = 1;
|
||||
|
||||
public void incrementLine() {
|
||||
line = Math.min(line + 1, DigitalAdapterBlockEntity.MAX_LINES);
|
||||
}
|
||||
|
||||
public void setTextLine(int ln, MutableComponent text) {
|
||||
if(ln < 1 || ln > MAX_LINES) return;
|
||||
textLines.set(ln-1, text);
|
||||
}
|
||||
|
||||
public MutableComponent getTextLine(int ln) {
|
||||
if(ln < 1 || ln > MAX_LINES) return EMPTY_LINE;
|
||||
return textLines.get(ln-1);
|
||||
}
|
||||
|
||||
public void clearLine(int ln) {
|
||||
setTextLine(ln, EMPTY_LINE);
|
||||
}
|
||||
|
||||
public void clearAll() {
|
||||
for(int i = 1; i < MAX_LINES+1; i++)
|
||||
clearLine(i);
|
||||
}
|
||||
|
||||
public void append(int ln, MutableComponent text) {
|
||||
setTextLine(ln, getTextLine(ln).append(text));
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
public int setLine(int ln) {
|
||||
return line = ln < 1 || ln > DigitalAdapterBlockEntity.MAX_LINES ? line : ln;
|
||||
}
|
||||
|
||||
public SpeedControllerBlockEntity getSpeedController(Direction dir) {
|
||||
BlockEntity be = this.level.getBlockEntity(getBlockPos().relative(dir));
|
||||
if(be == null) return null;
|
||||
if(be instanceof SpeedControllerBlockEntity scte) return scte;
|
||||
return null;
|
||||
}
|
||||
|
||||
public PulleyBlockEntity getRopePulley(Direction dir) {
|
||||
BlockEntity be = this.level.getBlockEntity(getBlockPos().relative(dir));
|
||||
if(be == null) return null;
|
||||
if(be instanceof PulleyBlockEntity pte) return pte;
|
||||
return null;
|
||||
}
|
||||
|
||||
public HosePulleyBlockEntity getHosePulley(Direction dir) {
|
||||
BlockEntity be = this.level.getBlockEntity(getBlockPos().relative(dir));
|
||||
if(be == null) return null;
|
||||
if(be instanceof HosePulleyBlockEntity pte) return pte;
|
||||
return null;
|
||||
}
|
||||
|
||||
public ElevatorPulleyBlockEntity getElevatorPulley(Direction dir) {
|
||||
BlockEntity be = this.level.getBlockEntity(getBlockPos().relative(dir));
|
||||
if(be == null) return null;
|
||||
if(be instanceof ElevatorPulleyBlockEntity epbe) return epbe;
|
||||
return null;
|
||||
}
|
||||
|
||||
public MechanicalPistonBlockEntity getMechanicalPiston(Direction dir) {
|
||||
BlockEntity be = this.level.getBlockEntity(getBlockPos().relative(dir));
|
||||
if(be == null) return null;
|
||||
if(be instanceof MechanicalPistonBlockEntity mpte) return mpte;
|
||||
return null;
|
||||
}
|
||||
|
||||
public MechanicalBearingBlockEntity getMechanicalBearing(Direction dir) {
|
||||
BlockEntity be = this.level.getBlockEntity(getBlockPos().relative(dir));
|
||||
if(be == null) return null;
|
||||
if(be instanceof MechanicalBearingBlockEntity mpte) return mpte;
|
||||
return null;
|
||||
}
|
||||
|
||||
public StressGaugeBlockEntity getStressGauge(Direction dir) {
|
||||
BlockEntity be = this.level.getBlockEntity(getBlockPos().relative(dir));
|
||||
if(be == null) return null;
|
||||
if(be instanceof StressGaugeBlockEntity sgte) return sgte;
|
||||
return null;
|
||||
}
|
||||
|
||||
public SpeedGaugeBlockEntity getSpeedGauge(Direction dir) {
|
||||
BlockEntity be = this.level.getBlockEntity(getBlockPos().relative(dir));
|
||||
if(be == null) return null;
|
||||
if(be instanceof SpeedGaugeBlockEntity sgte) return sgte;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setTargetSpeed(Direction dir, int speed) {
|
||||
SpeedControllerBlockEntity scte = getSpeedController(dir);
|
||||
if(scte == null) return;
|
||||
ISpeedControllerAdapter sts = (ISpeedControllerAdapter)((Object)scte);
|
||||
sts.setTargetSpeed(speed);
|
||||
}
|
||||
|
||||
public int getTargetSpeed(Direction dir) {
|
||||
SpeedControllerBlockEntity scte = getSpeedController(dir);
|
||||
if(scte == null) return 0;
|
||||
ISpeedControllerAdapter sts = (ISpeedControllerAdapter)((Object)scte);
|
||||
return sts.getTargetSpeed();
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.mrh0.createaddition.blocks.digital_adapter;
|
||||
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
public class DigitalAdapterBlockItem extends BlockItem {
|
||||
public DigitalAdapterBlockItem(Block block, Properties props) {
|
||||
super(block, props);
|
||||
}
|
||||
|
||||
/*public void fillItemCategory(CreativeModeTab tab, NonNullList<ItemStack> stacks) {
|
||||
if (tab == CreativeModeTab.TAB_SEARCH) {
|
||||
super.fillItemCategory(tab, stacks);
|
||||
}
|
||||
if(tab == ModGroup.MAIN && CreateAddition.CC_ACTIVE) {
|
||||
super.fillItemCategory(tab, stacks);
|
||||
}
|
||||
}*/
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.mrh0.createaddition.blocks.digital_adapter;
|
||||
|
||||
import com.simibubi.create.content.redstone.displayLink.DisplayLinkContext;
|
||||
import com.simibubi.create.content.redstone.displayLink.source.DisplaySource;
|
||||
import com.simibubi.create.content.redstone.displayLink.target.DisplayTargetStats;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DigitalAdapterDisplaySource extends DisplaySource {
|
||||
@Override
|
||||
public List<MutableComponent> provideText(DisplayLinkContext context, DisplayTargetStats stats) {
|
||||
if(context.getSourceBlockEntity() == null) return List.of();
|
||||
if(context.getSourceBlockEntity() instanceof DigitalAdapterBlockEntity date)
|
||||
return date.textLines;
|
||||
return List.of();
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.mrh0.createaddition.blocks.digital_adapter;
|
||||
|
||||
public interface ISpeedControllerAdapter {
|
||||
void setTargetSpeed(int speed);
|
||||
int getTargetSpeed();
|
||||
}
|
@ -0,0 +1,136 @@
|
||||
package com.mrh0.createaddition.blocks.electric_motor;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.mrh0.createaddition.index.CABlockEntities;
|
||||
import com.mrh0.createaddition.shapes.CAShapes;
|
||||
import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
|
||||
import com.simibubi.create.content.kinetics.base.IRotate;
|
||||
import com.simibubi.create.foundation.block.IBE;
|
||||
import com.simibubi.create.foundation.utility.VoxelShaper;
|
||||
import io.github.fabricators_of_create.porting_lib.block.ConnectableRedstoneBlock;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public class ElectricMotorBlock extends DirectionalKineticBlock implements IBE<ElectricMotorBlockEntity>, ConnectableRedstoneBlock {
|
||||
|
||||
public static final VoxelShaper ELECTRIC_MOTOR_SHAPE = CAShapes.shape(0, 5, 0, 16, 11, 16).add(3, 0, 3, 13, 14, 13)
|
||||
.forDirectional();
|
||||
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||
|
||||
public ElectricMotorBlock(Properties properties) {
|
||||
super(properties);
|
||||
registerDefaultState(defaultBlockState().setValue(POWERED, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
|
||||
super.createBlockStateDefinition(builder);
|
||||
builder.add(POWERED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
|
||||
return ELECTRIC_MOTOR_SHAPE.get(state.getValue(FACING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||
Direction preferred = getPreferredFacing(context);
|
||||
if ((context.getPlayer() != null && context.getPlayer().isShiftKeyDown()) || preferred == null)
|
||||
return super.getStateForPlacement(context);
|
||||
return defaultBlockState().setValue(FACING, preferred);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<ElectricMotorBlockEntity> getBlockEntityClass() {
|
||||
return ElectricMotorBlockEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityType<? extends ElectricMotorBlockEntity> getBlockEntityType() {
|
||||
return CABlockEntities.ELECTRIC_MOTOR.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) {
|
||||
return face == state.getValue(FACING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Axis getRotationAxis(BlockState state) {
|
||||
return state.getValue(FACING).getAxis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hideStressImpact() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setPowered(Level world, BlockPos pos, boolean powered) {
|
||||
world.setBlock(pos, world.getBlockState(pos).setValue(POWERED, powered), 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos, Direction side) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos from, boolean b) {
|
||||
if (!world.isClientSide) {
|
||||
boolean flag = state.getValue(POWERED);
|
||||
if (flag != world.hasNeighborSignal(pos)) {
|
||||
if (flag)
|
||||
world.scheduleTick(pos, this, 4);
|
||||
else
|
||||
world.setBlock(pos, state.cycle(POWERED), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos from, boolean b) {
|
||||
if (!world.isClientSide) {
|
||||
boolean flag = state.getValue(POWERED);
|
||||
if (flag != world.hasNeighborSignal(pos)) {
|
||||
if (flag){
|
||||
setPowered(world, pos, false);
|
||||
world.scheduleTick(pos, this, 4);
|
||||
}
|
||||
else{
|
||||
setPowered(world, pos, true);
|
||||
world.setBlock(pos, state.cycle(POWERED), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource pRandom) {
|
||||
if (state.getValue(POWERED) && !world.hasNeighborSignal(pos))
|
||||
world.setBlock(pos, state.cycle(POWERED), 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return CABlockEntities.ELECTRIC_MOTOR.create(pos, state);
|
||||
}
|
||||
}
|
@ -0,0 +1,255 @@
|
||||
package com.mrh0.createaddition.blocks.electric_motor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.mrh0.createaddition.CreateAddition;
|
||||
import com.mrh0.createaddition.blocks.tesla_coil.TeslaCoilBlock;
|
||||
import com.mrh0.createaddition.compat.computercraft.ElectricMotorPeripheral;
|
||||
import com.mrh0.createaddition.compat.computercraft.Peripherals;
|
||||
import com.mrh0.createaddition.config.Config;
|
||||
import com.mrh0.createaddition.energy.InternalEnergyStorage;
|
||||
import com.mrh0.createaddition.index.CABlocks;
|
||||
import com.mrh0.createaddition.sound.CASoundScapes;
|
||||
import com.mrh0.createaddition.transfer.EnergyTransferable;
|
||||
import com.mrh0.createaddition.util.Util;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.kinetics.base.GeneratingKineticBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.motor.KineticScrollValueBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.CenteredSideValueBoxTransform;
|
||||
import com.simibubi.create.foundation.blockEntity.behaviour.scrollValue.ScrollValueBehaviour;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import io.github.fabricators_of_create.porting_lib.util.LazyOptional;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import team.reborn.energy.api.EnergyStorage;
|
||||
|
||||
public class ElectricMotorBlockEntity extends GeneratingKineticBlockEntity implements EnergyTransferable {
|
||||
|
||||
protected ScrollValueBehaviour generatedSpeed;
|
||||
protected final InternalEnergyStorage energy;
|
||||
private final LazyOptional<EnergyStorage> lazyEnergy;
|
||||
private boolean cc_update_rpm = false;
|
||||
private int cc_new_rpm = 32;
|
||||
|
||||
private boolean active = false;
|
||||
|
||||
public ElectricMotorBlockEntity(BlockEntityType<? extends ElectricMotorBlockEntity> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
energy = new InternalEnergyStorage(Config.ELECTRIC_MOTOR_CAPACITY.get(), Config.ELECTRIC_MOTOR_MAX_INPUT.get(), 0);
|
||||
lazyEnergy = LazyOptional.of(() -> energy);
|
||||
setLazyTickRate(20);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
super.addBehaviours(behaviours);
|
||||
|
||||
CenteredSideValueBoxTransform slot =
|
||||
new CenteredSideValueBoxTransform((motor, side) -> motor.getValue(ElectricMotorBlock.FACING) == side.getOpposite());
|
||||
|
||||
generatedSpeed = new KineticScrollValueBehaviour(Lang.translateDirect("generic.speed"), this, slot);
|
||||
generatedSpeed.between(-Config.ELECTRIC_MOTOR_RPM_RANGE.get(), Config.ELECTRIC_MOTOR_RPM_RANGE.get());
|
||||
generatedSpeed.value = 32;
|
||||
//generatedSpeed.withUnit(i -> Lang.translateDirect("generic.unit.rpm"));
|
||||
generatedSpeed.withCallback(i -> this.updateGeneratedRotation(i));
|
||||
//generatedSpeed.withStepFunction(ElectricMotorTileEntity::step);
|
||||
behaviours.add(generatedSpeed);
|
||||
}
|
||||
|
||||
public static int step(ScrollValueBehaviour.StepContext context) {
|
||||
int current = context.currentValue;
|
||||
int step = 1;
|
||||
|
||||
if (!context.shift) {
|
||||
int magnitude = Math.abs(current) - (context.forward == current > 0 ? 0 : 1);
|
||||
|
||||
if (magnitude >= 4) step *= 4;
|
||||
if (magnitude >= 32) step *= 4;
|
||||
if (magnitude >= 128) step *= 4;
|
||||
}
|
||||
|
||||
return step;
|
||||
}
|
||||
|
||||
public float calculateAddedStressCapacity() {
|
||||
float capacity = Config.MAX_STRESS.get()/256f;
|
||||
this.lastCapacityProvided = capacity;
|
||||
return capacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
|
||||
super.addToGoggleTooltip(tooltip, isPlayerSneaking);
|
||||
tooltip.add(Component.literal(spacing).append(Component.translatable(CreateAddition.MODID + ".tooltip.energy.consumption").withStyle(ChatFormatting.GRAY)));
|
||||
tooltip.add(Component.literal(spacing).append(Component.literal(" " + Util.format(getEnergyConsumptionRate(generatedSpeed.getValue())) + "fe/t ")
|
||||
.withStyle(ChatFormatting.AQUA)).append(Lang.translateDirect("gui.goggles.at_current_speed").withStyle(ChatFormatting.DARK_GRAY)));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateGeneratedRotation(int i) {
|
||||
super.updateGeneratedRotation();
|
||||
cc_new_rpm = i;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
if (!hasSource() || getGeneratedSpeed() > getTheoreticalSpeed())
|
||||
updateGeneratedRotation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getGeneratedSpeed() {
|
||||
if (!CABlocks.ELECTRIC_MOTOR.has(getBlockState())) return 0;
|
||||
return convertToDirection(active ? generatedSpeed.getValue() : 0, getBlockState().getValue(ElectricMotorBlock.FACING));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Block getStressConfigKey() {
|
||||
return AllBlocks.WATER_WHEEL.get();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public InternalEnergyStorage getEnergyStorage() {
|
||||
return energy;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public EnergyStorage getEnergyStorage(@Nullable Direction side) {
|
||||
return lazyEnergy.getValueUnsafer();
|
||||
// if(CreateAddition.CC_ACTIVE)
|
||||
// Peripherals.isPeripheral(getLevel(), getBlockPos(), side);
|
||||
}
|
||||
|
||||
public boolean isEnergyInput(Direction side) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isEnergyOutput(Direction side) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundTag compound, boolean clientPacket) {
|
||||
super.read(compound, clientPacket);
|
||||
energy.read(compound);
|
||||
active = compound.getBoolean("active");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag compound, boolean clientPacket) {
|
||||
super.write(compound, clientPacket);
|
||||
energy.write(compound);
|
||||
compound.putBoolean("active", active);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lazyTick() {
|
||||
super.lazyTick();
|
||||
cc_antiSpam = 5;
|
||||
|
||||
}
|
||||
|
||||
public static int getEnergyConsumptionRate(int rpm) {
|
||||
return Math.abs(rpm) > 0 ? (int)Math.max((double)Config.FE_RPM.get() * ((double)Math.abs(rpm) / 256d), (double)Config.ELECTRIC_MOTOR_MINIMUM_CONSUMPTION.get()) : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
lazyEnergy.invalidate();
|
||||
super.remove();
|
||||
}
|
||||
|
||||
// CC
|
||||
int cc_antiSpam = 0;
|
||||
boolean first = true;
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if(first) {
|
||||
updateGeneratedRotation();
|
||||
first = false;
|
||||
}
|
||||
|
||||
if(cc_update_rpm && cc_antiSpam > 0) {
|
||||
generatedSpeed.setValue(cc_new_rpm);
|
||||
cc_update_rpm = false;
|
||||
cc_antiSpam--;
|
||||
updateGeneratedRotation();
|
||||
}
|
||||
|
||||
//Old Lazy
|
||||
if(level.isClientSide()) return;
|
||||
int con = getEnergyConsumptionRate(generatedSpeed.getValue());
|
||||
if(!active) {
|
||||
if(energy.getAmount() > con * 2L && !getBlockState().getValue(ElectricMotorBlock.POWERED)) {
|
||||
active = true;
|
||||
updateGeneratedRotation();
|
||||
}
|
||||
}
|
||||
else {
|
||||
long ext = energy.internalConsumeEnergy(con);
|
||||
if (ext < con || getBlockState().getValue(ElectricMotorBlock.POWERED)) {
|
||||
active = false;
|
||||
updateGeneratedRotation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tickAudio() {
|
||||
super.tickAudio();
|
||||
if (!active) return;
|
||||
CASoundScapes.play(CASoundScapes.AmbienceGroup.DYNAMO, worldPosition, 1);
|
||||
}
|
||||
|
||||
public static int getDurationAngle(int deg, float initialProgress, float speed) {
|
||||
speed = Math.abs(speed);
|
||||
deg = Math.abs(deg);
|
||||
if(speed < 0.1f) return 0;
|
||||
double degreesPerTick = (speed * 360) / 60 / 20;
|
||||
return (int) ((1 - initialProgress) * deg / degreesPerTick + 1);
|
||||
}
|
||||
|
||||
public static int getDurationDistance(int dis, float initialProgress, float speed) {
|
||||
speed = Math.abs(speed);
|
||||
dis = Math.abs(dis);
|
||||
if(speed < 0.1f) return 0;
|
||||
double metersPerTick = speed / 512;
|
||||
return (int) ((1 - initialProgress) * dis / metersPerTick);
|
||||
}
|
||||
|
||||
public boolean setRPM(int rpm) {
|
||||
rpm = Math.max(Math.min(rpm, Config.ELECTRIC_MOTOR_RPM_RANGE.get()), -Config.ELECTRIC_MOTOR_RPM_RANGE.get());
|
||||
cc_new_rpm = rpm;
|
||||
cc_update_rpm = true;
|
||||
return cc_antiSpam > 0;
|
||||
}
|
||||
|
||||
public int getRPM() {
|
||||
return cc_new_rpm;//generatedSpeed.getValue();
|
||||
}
|
||||
|
||||
public int getGeneratedStress() {
|
||||
return (int) calculateAddedStressCapacity();
|
||||
}
|
||||
|
||||
public int getEnergyConsumption() {
|
||||
return getEnergyConsumptionRate(generatedSpeed.getValue());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public boolean isPoweredState() {
|
||||
return getBlockState().getValue(TeslaCoilBlock.POWERED);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.mrh0.createaddition.blocks.electric_motor;
|
||||
|
||||
import com.simibubi.create.AllPartialModels;
|
||||
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
|
||||
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
|
||||
import com.simibubi.create.foundation.render.CachedBufferer;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
|
||||
public class ElectricMotorRenderer extends KineticBlockEntityRenderer {
|
||||
|
||||
public ElectricMotorRenderer(Context dispatcher) {
|
||||
super(dispatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SuperByteBuffer getRotatedModel(KineticBlockEntity te, BlockState state) {
|
||||
return CachedBufferer.partialFacing(AllPartialModels.SHAFT_HALF, state);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,272 @@
|
||||
/*package com.mrh0.createaddition.blocks.energy_meter;
|
||||
|
||||
import com.mrh0.createaddition.energy.IWireNode;
|
||||
import com.mrh0.createaddition.energy.NodeRotation;
|
||||
import com.mrh0.createaddition.index.CATileEntities;
|
||||
import com.mrh0.createaddition.shapes.CAShapes;
|
||||
import com.simibubi.create.content.contraptions.ITransformableBlock;
|
||||
import com.simibubi.create.content.contraptions.StructureTransform;
|
||||
import com.simibubi.create.content.equipment.wrench.IWrenchable;
|
||||
import com.simibubi.create.foundation.block.IBE;
|
||||
import com.simibubi.create.foundation.utility.VoxelShaper;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.item.context.UseOnContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.LevelReader;
|
||||
import net.minecraft.world.level.block.*;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.level.block.state.properties.DirectionProperty;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraft.world.ticks.TickPriority;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class EnergyMeterBlock extends Block implements IBE<EnergyMeterTileEntity>, IWrenchable, ITransformableBlock {
|
||||
|
||||
public static final BooleanProperty VERTICAL = BooleanProperty.create("vertical");
|
||||
public static final DirectionProperty HORIZONTAL_FACING = BlockStateProperties.HORIZONTAL_FACING;
|
||||
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||
|
||||
public static final VoxelShape HORIZONTAL_SHAPE_MAIN = Block.box(0, 0, 0, 16, 2, 16);
|
||||
public static final VoxelShape HORIZONTAL_SHAPE_X = Shapes.or(HORIZONTAL_SHAPE_MAIN, Block.box(1, 0, 6, 5, 7, 10), Block.box(11, 0, 6, 15, 7, 10));
|
||||
public static final VoxelShape HORIZONTAL_SHAPE_Z = Shapes.or(HORIZONTAL_SHAPE_MAIN, Block.box(6, 0, 1, 10, 7, 5), Block.box(6, 0, 11, 10, 7, 15));
|
||||
|
||||
//public static final VoxelShaper VERTICAL_SHAPE = CAShapes.shape(0, 0, 14, 16, 16, 16).add(1, 6, 9, 5, 10, 16).add(11, 6, 9, 15, 10, 16).forDirectional();
|
||||
|
||||
public static final VoxelShaper VERTICAL_SHAPE = CAShapes.shape(0, 0, 0, 16, 2, 16).add(1, 0, 6, 5, 7, 10).add(11, 0, 6, 15, 7, 10).forDirectional();
|
||||
|
||||
protected static final VoxelShape WEST_SHAPE = Block.box(0, 0, 0, 2, 16, 16);
|
||||
protected static final VoxelShape EAST_SHAPE = Block.box(14, 0, 0, 16, 16, 16);
|
||||
protected static final VoxelShape NORTH_SHAPE = Block.box(0, 0, 0, 16, 16, 2);
|
||||
protected static final VoxelShape SOUTH_SHAPE = Block.box(0, 0, 14, 16, 16, 16);
|
||||
|
||||
|
||||
public EnergyMeterBlock(Properties properties) {
|
||||
super(properties);
|
||||
this.registerDefaultState(this.defaultBlockState()
|
||||
.setValue(VERTICAL, false)
|
||||
.setValue(HORIZONTAL_FACING, Direction.NORTH)
|
||||
.setValue(POWERED, false)
|
||||
.setValue(NodeRotation.ROTATION, NodeRotation.NONE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
|
||||
Direction dir = state.getValue(HORIZONTAL_FACING);
|
||||
if(state.getValue(VERTICAL))
|
||||
return VERTICAL_SHAPE.get(dir.getOpposite());
|
||||
Axis axis = dir.getAxis();
|
||||
return axis == Axis.X ? HORIZONTAL_SHAPE_X : HORIZONTAL_SHAPE_Z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<EnergyMeterTileEntity> getBlockEntityClass() {
|
||||
return EnergyMeterTileEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntityType<? extends EnergyMeterTileEntity> getBlockEntityType() {
|
||||
return CATileEntities.REDSTONE_RELAY.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
|
||||
builder.add(VERTICAL, HORIZONTAL_FACING, POWERED, NodeRotation.ROTATION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext c) {
|
||||
if(c.getClickedFace().getAxis() == Axis.Y)
|
||||
return defaultBlockState().setValue(HORIZONTAL_FACING, c.getPlayer().isShiftKeyDown() ? c.getHorizontalDirection().getCounterClockWise() : c.getHorizontalDirection().getClockWise()).setValue(VERTICAL, false);
|
||||
else
|
||||
return defaultBlockState().setValue(HORIZONTAL_FACING, c.getClickedFace().getOpposite()).setValue(VERTICAL, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(BlockState state, ServerLevel worldIn, BlockPos pos, Random rand) {
|
||||
boolean flag = state.getValue(POWERED);
|
||||
boolean flag1 = this.shouldBePowered(worldIn, pos, state);
|
||||
if (flag && !flag1) {
|
||||
worldIn.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(false)), 2);
|
||||
}
|
||||
else if (!flag) {
|
||||
worldIn.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(true)), 2);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) {
|
||||
if (state.canSurvive(worldIn, pos))
|
||||
this.updateState(worldIn, pos, state);
|
||||
else {
|
||||
BlockEntity tileentity = state.hasBlockEntity() ? worldIn.getBlockEntity(pos) : null;
|
||||
dropResources(state, worldIn, pos, tileentity);
|
||||
worldIn.removeBlock(pos, false);
|
||||
|
||||
for (Direction direction : Direction.values())
|
||||
worldIn.updateNeighborsAt(pos.relative(direction), this);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) {
|
||||
boolean vertical = state.getValue(VERTICAL);
|
||||
Direction direction = state.getValue(HORIZONTAL_FACING);
|
||||
return canSupportCenter(world, vertical ? pos.relative(direction) : pos.below(), vertical ? direction.getOpposite() : Direction.UP);
|
||||
}
|
||||
|
||||
protected void updateState(Level worldIn, BlockPos pos, BlockState state) {
|
||||
boolean flag = state.getValue(POWERED);
|
||||
boolean flag1 = this.shouldBePowered(worldIn, pos, state);
|
||||
if (flag != flag1 && !worldIn.getBlockTicks().willTickThisTick(pos, this)) {
|
||||
TickPriority tickpriority = TickPriority.VERY_HIGH;
|
||||
|
||||
worldIn.scheduleTick(pos, this, this.getDelay(state), tickpriority);
|
||||
}
|
||||
}
|
||||
|
||||
private int getDelay(BlockState state) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
protected boolean shouldBePowered(Level worldIn, BlockPos pos, BlockState state) {
|
||||
return this.calculateInputStrength(worldIn, pos, state) > 0;
|
||||
}
|
||||
|
||||
protected int calculateInputStrength(Level worldIn, BlockPos pos, BlockState state) {
|
||||
boolean vertical = state.getValue(VERTICAL);
|
||||
|
||||
if(vertical) {
|
||||
BlockPos blockpos1 = pos.relative(Direction.UP);
|
||||
BlockPos blockpos2 = pos.relative(Direction.DOWN);
|
||||
int i = Math.max(worldIn.getSignal(blockpos1, Direction.DOWN), worldIn.getSignal(blockpos2, Direction.UP));
|
||||
|
||||
BlockState blockstate1 = worldIn.getBlockState(blockpos1);
|
||||
BlockState blockstate2 = worldIn.getBlockState(blockpos2);
|
||||
return Math.max(i, Math.max(blockstate1.is(Blocks.REDSTONE_WIRE) ? blockstate1.getValue(RedStoneWireBlock.POWER) : 0, blockstate2.is(Blocks.REDSTONE_WIRE) ? blockstate2.getValue(RedStoneWireBlock.POWER) : 0));
|
||||
}
|
||||
else {
|
||||
Direction direction = state.getValue(HORIZONTAL_FACING);
|
||||
BlockPos blockpos1 = pos.relative(direction.getClockWise());
|
||||
BlockPos blockpos2 = pos.relative(direction.getCounterClockWise());
|
||||
int i = Math.max(worldIn.getSignal(blockpos1, direction.getClockWise()), worldIn.getSignal(blockpos2, direction.getCounterClockWise()));
|
||||
int j = Math.max(worldIn.getDirectSignal(blockpos1, direction.getClockWise()), worldIn.getDirectSignal(blockpos2, direction.getCounterClockWise()));
|
||||
|
||||
BlockState blockstate1 = worldIn.getBlockState(blockpos1);
|
||||
BlockState blockstate2 = worldIn.getBlockState(blockpos2);
|
||||
return Math.max(Math.max(i, j), Math.max(blockstate1.is(Blocks.REDSTONE_WIRE) ? blockstate1.getValue(RedStoneWireBlock.POWER) : 0, blockstate2.is(Blocks.REDSTONE_WIRE) ? blockstate2.getValue(RedStoneWireBlock.POWER) : 0));
|
||||
}
|
||||
}
|
||||
protected int getPowerOnSides(LevelReader worldIn, BlockPos pos, Direction direction) {
|
||||
Direction direction1 = direction.getClockWise();
|
||||
Direction direction2 = direction.getCounterClockWise();
|
||||
return Math.max(this.getPowerOnSide(worldIn, pos.relative(direction1), direction2), this.getPowerOnSide(worldIn, pos.relative(direction2), direction1));
|
||||
}
|
||||
|
||||
protected int getPowerOnSide(LevelReader worldIn, BlockPos pos, Direction side) {
|
||||
BlockState blockstate = worldIn.getBlockState(pos);
|
||||
if (this.isAlternateInput(blockstate)) {
|
||||
if (blockstate.is(Blocks.REDSTONE_BLOCK))
|
||||
return 15;
|
||||
else
|
||||
return blockstate.is(Blocks.REDSTONE_WIRE) ? blockstate.getValue(RedStoneWireBlock.POWER) : worldIn.getDirectSignal(pos, side);
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected boolean isAlternateInput(BlockState state) {
|
||||
return state.isSignalSource();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlacedBy(Level worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
|
||||
if (this.shouldBePowered(worldIn, pos, state)) {
|
||||
worldIn.scheduleTick(pos, this, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerWillDestroy(Level worldIn, BlockPos pos, BlockState state, Player player) {
|
||||
super.playerWillDestroy(worldIn, pos, state, player);
|
||||
|
||||
if (worldIn.isClientSide()) return;
|
||||
BlockEntity te = worldIn.getBlockEntity(pos);
|
||||
if (te == null) return;
|
||||
if (!(te instanceof IWireNode cte)) return;
|
||||
cte.dropWires(worldIn, !player.isCreative());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult onSneakWrenched(BlockState state, UseOnContext c) {
|
||||
BlockEntity te = c.getLevel().getBlockEntity(c.getClickedPos());
|
||||
if(te == null)
|
||||
return IWrenchable.super.onSneakWrenched(state, c);
|
||||
if(!(te instanceof IWireNode))
|
||||
return IWrenchable.super.onSneakWrenched(state, c);
|
||||
IWireNode cte = (IWireNode) te;
|
||||
|
||||
if (!c.getLevel().isClientSide())
|
||||
cte.dropWires(c.getLevel(), c.getPlayer(), !c.getPlayer().isCreative());
|
||||
|
||||
return IWrenchable.super.onSneakWrenched(state, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos, Direction side) {
|
||||
if(pos == null || side == null || state == null || world == null)
|
||||
return false;
|
||||
return !state.getValue(VERTICAL).booleanValue() && side.getAxis() != state.getValue(HORIZONTAL_FACING).getAxis();
|
||||
}
|
||||
|
||||
private BlockState fromRotation(BlockState state, Direction dir) {
|
||||
return state.setValue(HORIZONTAL_FACING, dir);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState state, Rotation direction) {
|
||||
return fromRotation(state, direction.rotate(state.getValue(HORIZONTAL_FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState rotate(BlockState state, LevelAccessor world, BlockPos pos, Rotation direction) {
|
||||
return rotate(state, direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState mirror(BlockState state, Mirror mirror) {
|
||||
return fromRotation(state, mirror.mirror(state.getValue(HORIZONTAL_FACING)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState transform(BlockState state, StructureTransform transform) {
|
||||
NodeRotation rotation = NodeRotation.get(transform.rotationAxis, transform.rotation);
|
||||
// Handle default rotation & mirroring.
|
||||
if (transform.mirror != null) state = mirror(state, transform.mirror);
|
||||
if (transform.rotationAxis == Axis.Y) state = rotate(state, transform.rotation);
|
||||
// Set the rotation state, which will be used to update the nodes.
|
||||
return state.setValue(NodeRotation.ROTATION, rotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
|
||||
return CATileEntities.REDSTONE_RELAY.create(pos, state);
|
||||
}
|
||||
}
|
||||
*/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user