Merge branch 'mc1.15/dev' into mc1.15/collision

This commit is contained in:
simibubi 2020-07-22 19:07:33 +02:00
commit f5af1cd81e
340 changed files with 9681 additions and 5865 deletions

View File

@ -69,6 +69,10 @@ minecraft {
}
}
compileJava {
options.compilerArgs = ["-Xdiags:verbose"]
}
sourceSets.main.resources {
srcDir 'src/generated/resources'
}

File diff suppressed because it is too large Load Diff

View File

@ -14,18 +14,11 @@
"model": "create:block/andesite_tunnel/window",
"y": 90
},
"axis=x,shape=halfshade": {
"model": "create:block/andesite_tunnel/halfshade"
"axis=x,shape=closed": {
"model": "create:block/andesite_tunnel/straight"
},
"axis=z,shape=halfshade": {
"model": "create:block/andesite_tunnel/halfshade",
"y": 90
},
"axis=x,shape=fullshade": {
"model": "create:block/andesite_tunnel/fullshade"
},
"axis=z,shape=fullshade": {
"model": "create:block/andesite_tunnel/fullshade",
"axis=z,shape=closed": {
"model": "create:block/andesite_tunnel/straight",
"y": 90
},
"axis=x,shape=t_left": {

View File

@ -1,7 +1,7 @@
{
"variants": {
"casing=false,facing=north,part=start,slope=horizontal": {
"model": "create:block/belt/horizontal_start",
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=north,part=start,slope=horizontal": {
@ -9,13 +9,13 @@
"y": 180
},
"casing=false,facing=south,part=start,slope=horizontal": {
"model": "create:block/belt/horizontal_start"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=start,slope=horizontal": {
"model": "create:block/belt_casing/horizontal_start"
},
"casing=false,facing=west,part=start,slope=horizontal": {
"model": "create:block/belt/horizontal_start",
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=west,part=start,slope=horizontal": {
@ -23,7 +23,7 @@
"y": 90
},
"casing=false,facing=east,part=start,slope=horizontal": {
"model": "create:block/belt/horizontal_start",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=start,slope=horizontal": {
@ -31,7 +31,7 @@
"y": 270
},
"casing=false,facing=north,part=middle,slope=horizontal": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=north,part=middle,slope=horizontal": {
@ -39,13 +39,13 @@
"y": 180
},
"casing=false,facing=south,part=middle,slope=horizontal": {
"model": "create:block/belt/horizontal_middle"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=middle,slope=horizontal": {
"model": "create:block/belt_casing/horizontal_middle"
},
"casing=false,facing=west,part=middle,slope=horizontal": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=west,part=middle,slope=horizontal": {
@ -53,7 +53,7 @@
"y": 90
},
"casing=false,facing=east,part=middle,slope=horizontal": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=middle,slope=horizontal": {
@ -61,7 +61,7 @@
"y": 270
},
"casing=false,facing=north,part=end,slope=horizontal": {
"model": "create:block/belt/horizontal_end",
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=north,part=end,slope=horizontal": {
@ -69,13 +69,13 @@
"y": 180
},
"casing=false,facing=south,part=end,slope=horizontal": {
"model": "create:block/belt/horizontal_end"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=end,slope=horizontal": {
"model": "create:block/belt_casing/horizontal_end"
},
"casing=false,facing=west,part=end,slope=horizontal": {
"model": "create:block/belt/horizontal_end",
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=west,part=end,slope=horizontal": {
@ -83,7 +83,7 @@
"y": 90
},
"casing=false,facing=east,part=end,slope=horizontal": {
"model": "create:block/belt/horizontal_end",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=end,slope=horizontal": {
@ -91,7 +91,7 @@
"y": 270
},
"casing=false,facing=north,part=pulley,slope=horizontal": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=north,part=pulley,slope=horizontal": {
@ -99,13 +99,13 @@
"y": 180
},
"casing=false,facing=south,part=pulley,slope=horizontal": {
"model": "create:block/belt/horizontal_middle"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=pulley,slope=horizontal": {
"model": "create:block/belt_casing/horizontal_pulley"
},
"casing=false,facing=west,part=pulley,slope=horizontal": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=west,part=pulley,slope=horizontal": {
@ -113,7 +113,7 @@
"y": 90
},
"casing=false,facing=east,part=pulley,slope=horizontal": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=pulley,slope=horizontal": {
@ -121,127 +121,127 @@
"y": 270
},
"casing=false,facing=north,part=start,slope=upward": {
"model": "create:block/belt/upward_start",
"y": 180
"model": "create:block/belt/particle"
},
"casing=true,facing=north,part=start,slope=upward": {
"model": "create:block/belt_casing/diagonal_start"
},
"casing=false,facing=south,part=start,slope=upward": {
"model": "create:block/belt/upward_start"
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=south,part=start,slope=upward": {
"model": "create:block/belt_casing/diagonal_start",
"y": 180
},
"casing=false,facing=west,part=start,slope=upward": {
"model": "create:block/belt/upward_start",
"y": 90
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=west,part=start,slope=upward": {
"model": "create:block/belt_casing/diagonal_start",
"y": 270
},
"casing=false,facing=east,part=start,slope=upward": {
"model": "create:block/belt/upward_start",
"y": 270
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=east,part=start,slope=upward": {
"model": "create:block/belt_casing/diagonal_start",
"y": 90
},
"casing=false,facing=north,part=middle,slope=upward": {
"model": "create:block/belt/upward_middle",
"y": 180
"model": "create:block/belt/particle"
},
"casing=true,facing=north,part=middle,slope=upward": {
"model": "create:block/belt_casing/diagonal_middle"
},
"casing=false,facing=south,part=middle,slope=upward": {
"model": "create:block/belt/upward_middle"
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=south,part=middle,slope=upward": {
"model": "create:block/belt_casing/diagonal_middle",
"y": 180
},
"casing=false,facing=west,part=middle,slope=upward": {
"model": "create:block/belt/upward_middle",
"y": 90
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=west,part=middle,slope=upward": {
"model": "create:block/belt_casing/diagonal_middle",
"y": 270
},
"casing=false,facing=east,part=middle,slope=upward": {
"model": "create:block/belt/upward_middle",
"y": 270
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=east,part=middle,slope=upward": {
"model": "create:block/belt_casing/diagonal_middle",
"y": 90
},
"casing=false,facing=north,part=end,slope=upward": {
"model": "create:block/belt/upward_end",
"y": 180
"model": "create:block/belt/particle"
},
"casing=true,facing=north,part=end,slope=upward": {
"model": "create:block/belt_casing/diagonal_end"
},
"casing=false,facing=south,part=end,slope=upward": {
"model": "create:block/belt/upward_end"
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=south,part=end,slope=upward": {
"model": "create:block/belt_casing/diagonal_end",
"y": 180
},
"casing=false,facing=west,part=end,slope=upward": {
"model": "create:block/belt/upward_end",
"y": 90
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=west,part=end,slope=upward": {
"model": "create:block/belt_casing/diagonal_end",
"y": 270
},
"casing=false,facing=east,part=end,slope=upward": {
"model": "create:block/belt/upward_end",
"y": 270
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=east,part=end,slope=upward": {
"model": "create:block/belt_casing/diagonal_end",
"y": 90
},
"casing=false,facing=north,part=pulley,slope=upward": {
"model": "create:block/belt/upward_middle",
"y": 180
"model": "create:block/belt/particle"
},
"casing=true,facing=north,part=pulley,slope=upward": {
"model": "create:block/belt_casing/diagonal_pulley"
},
"casing=false,facing=south,part=pulley,slope=upward": {
"model": "create:block/belt/upward_middle"
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=south,part=pulley,slope=upward": {
"model": "create:block/belt_casing/diagonal_pulley",
"y": 180
},
"casing=false,facing=west,part=pulley,slope=upward": {
"model": "create:block/belt/upward_middle",
"y": 90
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=west,part=pulley,slope=upward": {
"model": "create:block/belt_casing/diagonal_pulley",
"y": 270
},
"casing=false,facing=east,part=pulley,slope=upward": {
"model": "create:block/belt/upward_middle",
"y": 270
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=east,part=pulley,slope=upward": {
"model": "create:block/belt_casing/diagonal_pulley",
"y": 90
},
"casing=false,facing=north,part=start,slope=downward": {
"model": "create:block/belt/downward_start",
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=north,part=start,slope=downward": {
@ -249,13 +249,13 @@
"y": 180
},
"casing=false,facing=south,part=start,slope=downward": {
"model": "create:block/belt/downward_start"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=start,slope=downward": {
"model": "create:block/belt_casing/diagonal_end"
},
"casing=false,facing=west,part=start,slope=downward": {
"model": "create:block/belt/downward_start",
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=west,part=start,slope=downward": {
@ -263,7 +263,7 @@
"y": 90
},
"casing=false,facing=east,part=start,slope=downward": {
"model": "create:block/belt/downward_start",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=start,slope=downward": {
@ -271,7 +271,7 @@
"y": 270
},
"casing=false,facing=north,part=middle,slope=downward": {
"model": "create:block/belt/downward_middle",
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=north,part=middle,slope=downward": {
@ -279,13 +279,13 @@
"y": 180
},
"casing=false,facing=south,part=middle,slope=downward": {
"model": "create:block/belt/downward_middle"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=middle,slope=downward": {
"model": "create:block/belt_casing/diagonal_middle"
},
"casing=false,facing=west,part=middle,slope=downward": {
"model": "create:block/belt/downward_middle",
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=west,part=middle,slope=downward": {
@ -293,7 +293,7 @@
"y": 90
},
"casing=false,facing=east,part=middle,slope=downward": {
"model": "create:block/belt/downward_middle",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=middle,slope=downward": {
@ -301,7 +301,7 @@
"y": 270
},
"casing=false,facing=north,part=end,slope=downward": {
"model": "create:block/belt/downward_end",
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=north,part=end,slope=downward": {
@ -309,13 +309,13 @@
"y": 180
},
"casing=false,facing=south,part=end,slope=downward": {
"model": "create:block/belt/downward_end"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=end,slope=downward": {
"model": "create:block/belt_casing/diagonal_start"
},
"casing=false,facing=west,part=end,slope=downward": {
"model": "create:block/belt/downward_end",
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=west,part=end,slope=downward": {
@ -323,7 +323,7 @@
"y": 90
},
"casing=false,facing=east,part=end,slope=downward": {
"model": "create:block/belt/downward_end",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=end,slope=downward": {
@ -331,7 +331,7 @@
"y": 270
},
"casing=false,facing=north,part=pulley,slope=downward": {
"model": "create:block/belt/downward_middle",
"model": "create:block/belt/particle",
"y": 180
},
"casing=true,facing=north,part=pulley,slope=downward": {
@ -339,13 +339,13 @@
"y": 180
},
"casing=false,facing=south,part=pulley,slope=downward": {
"model": "create:block/belt/downward_middle"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=pulley,slope=downward": {
"model": "create:block/belt_casing/diagonal_pulley"
},
"casing=false,facing=west,part=pulley,slope=downward": {
"model": "create:block/belt/downward_middle",
"model": "create:block/belt/particle",
"y": 90
},
"casing=true,facing=west,part=pulley,slope=downward": {
@ -353,7 +353,7 @@
"y": 90
},
"casing=false,facing=east,part=pulley,slope=downward": {
"model": "create:block/belt/downward_middle",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=pulley,slope=downward": {
@ -361,7 +361,7 @@
"y": 270
},
"casing=false,facing=north,part=start,slope=vertical": {
"model": "create:block/belt/horizontal_end",
"model": "create:block/belt/particle",
"x": 90,
"y": 180
},
@ -371,7 +371,7 @@
"y": 270
},
"casing=false,facing=south,part=start,slope=vertical": {
"model": "create:block/belt/horizontal_start",
"model": "create:block/belt/particle",
"x": 90
},
"casing=true,facing=south,part=start,slope=vertical": {
@ -380,7 +380,7 @@
"y": 90
},
"casing=false,facing=west,part=start,slope=vertical": {
"model": "create:block/belt/horizontal_end",
"model": "create:block/belt/particle",
"x": 90,
"y": 90
},
@ -390,7 +390,7 @@
"y": 180
},
"casing=false,facing=east,part=start,slope=vertical": {
"model": "create:block/belt/horizontal_start",
"model": "create:block/belt/particle",
"x": 90,
"y": 270
},
@ -399,7 +399,7 @@
"x": 90
},
"casing=false,facing=north,part=middle,slope=vertical": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"x": 90,
"y": 180
},
@ -409,7 +409,7 @@
"y": 270
},
"casing=false,facing=south,part=middle,slope=vertical": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"x": 90
},
"casing=true,facing=south,part=middle,slope=vertical": {
@ -418,7 +418,7 @@
"y": 90
},
"casing=false,facing=west,part=middle,slope=vertical": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"x": 90,
"y": 90
},
@ -428,7 +428,7 @@
"y": 180
},
"casing=false,facing=east,part=middle,slope=vertical": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"x": 90,
"y": 270
},
@ -437,7 +437,7 @@
"x": 90
},
"casing=false,facing=north,part=end,slope=vertical": {
"model": "create:block/belt/horizontal_start",
"model": "create:block/belt/particle",
"x": 90,
"y": 180
},
@ -447,7 +447,7 @@
"y": 270
},
"casing=false,facing=south,part=end,slope=vertical": {
"model": "create:block/belt/horizontal_end",
"model": "create:block/belt/particle",
"x": 90
},
"casing=true,facing=south,part=end,slope=vertical": {
@ -456,7 +456,7 @@
"y": 90
},
"casing=false,facing=west,part=end,slope=vertical": {
"model": "create:block/belt/horizontal_start",
"model": "create:block/belt/particle",
"x": 90,
"y": 90
},
@ -466,7 +466,7 @@
"y": 180
},
"casing=false,facing=east,part=end,slope=vertical": {
"model": "create:block/belt/horizontal_end",
"model": "create:block/belt/particle",
"x": 90,
"y": 270
},
@ -475,7 +475,7 @@
"x": 90
},
"casing=false,facing=north,part=pulley,slope=vertical": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"x": 90,
"y": 180
},
@ -485,7 +485,7 @@
"y": 270
},
"casing=false,facing=south,part=pulley,slope=vertical": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"x": 90
},
"casing=true,facing=south,part=pulley,slope=vertical": {
@ -494,7 +494,7 @@
"y": 90
},
"casing=false,facing=west,part=pulley,slope=vertical": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"x": 90,
"y": 90
},
@ -504,7 +504,7 @@
"y": 180
},
"casing=false,facing=east,part=pulley,slope=vertical": {
"model": "create:block/belt/horizontal_middle",
"model": "create:block/belt/particle",
"x": 90,
"y": 270
},
@ -513,7 +513,7 @@
"x": 90
},
"casing=false,facing=north,part=start,slope=sideways": {
"model": "create:block/belt/sideways_end",
"model": "create:block/belt/particle",
"x": 180,
"y": 180
},
@ -523,13 +523,13 @@
"y": 180
},
"casing=false,facing=south,part=start,slope=sideways": {
"model": "create:block/belt/sideways_start"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=start,slope=sideways": {
"model": "create:block/belt_casing/sideways_start"
},
"casing=false,facing=west,part=start,slope=sideways": {
"model": "create:block/belt/sideways_end",
"model": "create:block/belt/particle",
"x": 180,
"y": 90
},
@ -539,7 +539,7 @@
"y": 90
},
"casing=false,facing=east,part=start,slope=sideways": {
"model": "create:block/belt/sideways_start",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=start,slope=sideways": {
@ -547,7 +547,7 @@
"y": 270
},
"casing=false,facing=north,part=middle,slope=sideways": {
"model": "create:block/belt/sideways_middle",
"model": "create:block/belt/particle",
"x": 180,
"y": 180
},
@ -557,13 +557,13 @@
"y": 180
},
"casing=false,facing=south,part=middle,slope=sideways": {
"model": "create:block/belt/sideways_middle"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=middle,slope=sideways": {
"model": "create:block/belt_casing/sideways_middle"
},
"casing=false,facing=west,part=middle,slope=sideways": {
"model": "create:block/belt/sideways_middle",
"model": "create:block/belt/particle",
"x": 180,
"y": 90
},
@ -573,7 +573,7 @@
"y": 90
},
"casing=false,facing=east,part=middle,slope=sideways": {
"model": "create:block/belt/sideways_middle",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=middle,slope=sideways": {
@ -581,7 +581,7 @@
"y": 270
},
"casing=false,facing=north,part=end,slope=sideways": {
"model": "create:block/belt/sideways_start",
"model": "create:block/belt/particle",
"x": 180,
"y": 180
},
@ -591,13 +591,13 @@
"y": 180
},
"casing=false,facing=south,part=end,slope=sideways": {
"model": "create:block/belt/sideways_end"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=end,slope=sideways": {
"model": "create:block/belt_casing/sideways_end"
},
"casing=false,facing=west,part=end,slope=sideways": {
"model": "create:block/belt/sideways_start",
"model": "create:block/belt/particle",
"x": 180,
"y": 90
},
@ -607,7 +607,7 @@
"y": 90
},
"casing=false,facing=east,part=end,slope=sideways": {
"model": "create:block/belt/sideways_end",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=end,slope=sideways": {
@ -615,7 +615,7 @@
"y": 270
},
"casing=false,facing=north,part=pulley,slope=sideways": {
"model": "create:block/belt/sideways_middle",
"model": "create:block/belt/particle",
"x": 180,
"y": 180
},
@ -625,13 +625,13 @@
"y": 180
},
"casing=false,facing=south,part=pulley,slope=sideways": {
"model": "create:block/belt/sideways_middle"
"model": "create:block/belt/particle"
},
"casing=true,facing=south,part=pulley,slope=sideways": {
"model": "create:block/belt_casing/sideways_pulley"
},
"casing=false,facing=west,part=pulley,slope=sideways": {
"model": "create:block/belt/sideways_middle",
"model": "create:block/belt/particle",
"x": 180,
"y": 90
},
@ -641,7 +641,7 @@
"y": 90
},
"casing=false,facing=east,part=pulley,slope=sideways": {
"model": "create:block/belt/sideways_middle",
"model": "create:block/belt/particle",
"y": 270
},
"casing=true,facing=east,part=pulley,slope=sideways": {

View File

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "create:block/blaze_heater/block"
}
}
}

View File

@ -14,18 +14,11 @@
"model": "create:block/brass_tunnel/window",
"y": 90
},
"axis=x,shape=halfshade": {
"model": "create:block/brass_tunnel/halfshade"
"axis=x,shape=closed": {
"model": "create:block/brass_tunnel/straight"
},
"axis=z,shape=halfshade": {
"model": "create:block/brass_tunnel/halfshade",
"y": 90
},
"axis=x,shape=fullshade": {
"model": "create:block/brass_tunnel/fullshade"
},
"axis=z,shape=fullshade": {
"model": "create:block/brass_tunnel/fullshade",
"axis=z,shape=closed": {
"model": "create:block/brass_tunnel/straight",
"y": 90
},
"axis=x,shape=t_left": {

View File

@ -181,10 +181,10 @@
},
{
"when": {
"north": "false",
"south": "true",
"west": "true",
"east": "false"
"east": "false",
"north": "false",
"south": "true"
},
"apply": {
"model": "create:block/fluid_pipe/lu_y"
@ -192,10 +192,10 @@
},
{
"when": {
"north": "false",
"south": "true",
"west": "false",
"east": "true"
"east": "true",
"north": "false",
"south": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ru_y"
@ -203,10 +203,10 @@
},
{
"when": {
"north": "true",
"south": "false",
"west": "true",
"east": "false"
"east": "false",
"north": "true",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/ld_y"
@ -214,10 +214,10 @@
},
{
"when": {
"north": "true",
"south": "false",
"west": "false",
"east": "true"
"east": "true",
"north": "true",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/rd_y"
@ -225,10 +225,10 @@
},
{
"when": {
"west": "false",
"east": "false",
"north": "true",
"south": "true",
"west": "false",
"east": "false"
"south": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ud_y"
@ -236,10 +236,10 @@
},
{
"when": {
"west": "false",
"east": "false",
"north": "false",
"south": "true",
"west": "false",
"east": "false"
"south": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ud_y"
@ -247,10 +247,10 @@
},
{
"when": {
"west": "false",
"east": "false",
"north": "true",
"south": "false",
"west": "false",
"east": "false"
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/ud_y"
@ -258,10 +258,10 @@
},
{
"when": {
"north": "false",
"south": "false",
"west": "true",
"east": "true"
"east": "true",
"north": "false",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_y"
@ -269,10 +269,10 @@
},
{
"when": {
"north": "false",
"south": "false",
"west": "true",
"east": "false"
"east": "false",
"north": "false",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_y"
@ -280,10 +280,10 @@
},
{
"when": {
"north": "false",
"south": "false",
"west": "false",
"east": "true"
"east": "true",
"north": "false",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_y"
@ -291,10 +291,10 @@
},
{
"when": {
"north": "false",
"south": "false",
"west": "false",
"east": "false"
"east": "false",
"north": "false",
"south": "false"
},
"apply": {
"model": "create:block/fluid_pipe/none_y"
@ -302,10 +302,10 @@
},
{
"when": {
"up": "true",
"west": "false",
"down": "false",
"east": "true"
"east": "true",
"up": "true",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lu_z"
@ -313,10 +313,10 @@
},
{
"when": {
"up": "true",
"west": "true",
"down": "false",
"east": "false"
"east": "false",
"up": "true",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/ru_z"
@ -324,10 +324,10 @@
},
{
"when": {
"up": "false",
"west": "false",
"down": "true",
"east": "true"
"east": "true",
"up": "false",
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ld_z"
@ -335,10 +335,10 @@
},
{
"when": {
"up": "false",
"west": "true",
"down": "true",
"east": "false"
"east": "false",
"up": "false",
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/rd_z"
@ -346,10 +346,10 @@
},
{
"when": {
"west": "false",
"east": "false",
"up": "true",
"west": "false",
"down": "true",
"east": "false"
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ud_z"
@ -357,10 +357,10 @@
},
{
"when": {
"west": "false",
"east": "false",
"up": "true",
"west": "false",
"down": "false",
"east": "false"
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/ud_z"
@ -368,10 +368,10 @@
},
{
"when": {
"up": "false",
"west": "false",
"down": "true",
"east": "false"
"east": "false",
"up": "false",
"down": "true"
},
"apply": {
"model": "create:block/fluid_pipe/ud_z"
@ -379,10 +379,10 @@
},
{
"when": {
"up": "false",
"west": "true",
"down": "false",
"east": "true"
"east": "true",
"up": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_z"
@ -390,10 +390,10 @@
},
{
"when": {
"up": "false",
"west": "false",
"down": "false",
"east": "true"
"east": "true",
"up": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_z"
@ -401,10 +401,10 @@
},
{
"when": {
"up": "false",
"west": "true",
"down": "false",
"east": "false"
"east": "false",
"up": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/lr_z"
@ -412,10 +412,10 @@
},
{
"when": {
"up": "false",
"west": "false",
"down": "false",
"east": "false"
"east": "false",
"up": "false",
"down": "false"
},
"apply": {
"model": "create:block/fluid_pipe/none_z"

View File

@ -1,25 +1,76 @@
{
"multipart": [
{
"when": {
"top": "true"
},
"apply": {
"model": "create:block/fluid_tank/block_top"
}
"variants": {
"bottom=false,shape=plain,top=false": {
"model": "create:block/fluid_tank/block_middle"
},
{
"apply": {
"model": "create:block/fluid_tank/block_windows"
}
"bottom=true,shape=plain,top=false": {
"model": "create:block/fluid_tank/block_bottom"
},
{
"when": {
"bottom": "true"
},
"apply": {
"model": "create:block/fluid_tank/block_bottom"
}
"bottom=false,shape=window,top=false": {
"model": "create:block/fluid_tank/block_middle_window"
},
"bottom=true,shape=window,top=false": {
"model": "create:block/fluid_tank/block_bottom_window"
},
"bottom=false,shape=window_nw,top=false": {
"model": "create:block/fluid_tank/block_middle_window_nw"
},
"bottom=true,shape=window_nw,top=false": {
"model": "create:block/fluid_tank/block_bottom_window_nw"
},
"bottom=false,shape=window_sw,top=false": {
"model": "create:block/fluid_tank/block_middle_window_sw"
},
"bottom=true,shape=window_sw,top=false": {
"model": "create:block/fluid_tank/block_bottom_window_sw"
},
"bottom=false,shape=window_ne,top=false": {
"model": "create:block/fluid_tank/block_middle_window_ne"
},
"bottom=true,shape=window_ne,top=false": {
"model": "create:block/fluid_tank/block_bottom_window_ne"
},
"bottom=false,shape=window_se,top=false": {
"model": "create:block/fluid_tank/block_middle_window_se"
},
"bottom=true,shape=window_se,top=false": {
"model": "create:block/fluid_tank/block_bottom_window_se"
},
"bottom=false,shape=plain,top=true": {
"model": "create:block/fluid_tank/block_top"
},
"bottom=true,shape=plain,top=true": {
"model": "create:block/fluid_tank/block_single"
},
"bottom=false,shape=window,top=true": {
"model": "create:block/fluid_tank/block_top_window"
},
"bottom=true,shape=window,top=true": {
"model": "create:block/fluid_tank/block_single_window"
},
"bottom=false,shape=window_nw,top=true": {
"model": "create:block/fluid_tank/block_top_window_nw"
},
"bottom=true,shape=window_nw,top=true": {
"model": "create:block/fluid_tank/block_single_window_nw"
},
"bottom=false,shape=window_sw,top=true": {
"model": "create:block/fluid_tank/block_top_window_sw"
},
"bottom=true,shape=window_sw,top=true": {
"model": "create:block/fluid_tank/block_single_window_sw"
},
"bottom=false,shape=window_ne,top=true": {
"model": "create:block/fluid_tank/block_top_window_ne"
},
"bottom=true,shape=window_ne,top=true": {
"model": "create:block/fluid_tank/block_single_window_ne"
},
"bottom=false,shape=window_se,top=true": {
"model": "create:block/fluid_tank/block_top_window_se"
},
"bottom=true,shape=window_se,top=true": {
"model": "create:block/fluid_tank/block_single_window_se"
}
]
}
}

View File

@ -29,8 +29,8 @@
},
{
"when": {
"axis": "x",
"sticky_south": "true"
"sticky_south": "true",
"axis": "x"
},
"apply": {
"model": "create:block/radial_chassis_side_x_sticky",
@ -39,8 +39,8 @@
},
{
"when": {
"axis": "y",
"sticky_south": "true"
"sticky_south": "true",
"axis": "y"
},
"apply": {
"model": "create:block/radial_chassis_side_y_sticky"
@ -48,8 +48,8 @@
},
{
"when": {
"axis": "z",
"sticky_south": "true"
"sticky_south": "true",
"axis": "z"
},
"apply": {
"model": "create:block/radial_chassis_side_x_sticky",
@ -59,8 +59,8 @@
},
{
"when": {
"axis": "x",
"sticky_south": "false"
"sticky_south": "false",
"axis": "x"
},
"apply": {
"model": "create:block/radial_chassis_side_x",
@ -69,8 +69,8 @@
},
{
"when": {
"axis": "y",
"sticky_south": "false"
"sticky_south": "false",
"axis": "y"
},
"apply": {
"model": "create:block/radial_chassis_side_y"
@ -78,8 +78,8 @@
},
{
"when": {
"axis": "z",
"sticky_south": "false"
"sticky_south": "false",
"axis": "z"
},
"apply": {
"model": "create:block/radial_chassis_side_x",

View File

@ -26,6 +26,7 @@
"block.create.birch_window": "\u028Dopu\u0131M \u0265\u0254\u0279\u0131\u15FA",
"block.create.birch_window_pane": "\u01DDu\u0250\u0500 \u028Dopu\u0131M \u0265\u0254\u0279\u0131\u15FA",
"block.create.black_seat": "\u0287\u0250\u01DDS \u029E\u0254\u0250\u05DF\u15FA",
"block.create.blaze_heater": "\u0279\u01DD\u0287\u0250\u01DDH \u01DDz\u0250\u05DF\u15FA",
"block.create.blue_seat": "\u0287\u0250\u01DDS \u01DDn\u05DF\u15FA",
"block.create.brass_belt_funnel": "\u05DF\u01DDuun\u2132 \u0287\u05DF\u01DD\u15FA ss\u0250\u0279\u15FA",
"block.create.brass_block": "\u029E\u0254o\u05DF\u15FA ss\u0250\u0279\u15FA",
@ -355,6 +356,7 @@
"block.create.zinc_block": "\u029E\u0254o\u05DF\u15FA \u0254u\u0131Z",
"block.create.zinc_ore": "\u01DD\u0279O \u0254u\u0131Z",
"entity.create.contraption": "uo\u0131\u0287d\u0250\u0279\u0287uo\u0186",
"entity.create.seat": "\u0287\u0250\u01DDS",
"entity.create.stationary_contraption": "uo\u0131\u0287d\u0250\u0279\u0287uo\u0186 \u028E\u0279\u0250uo\u0131\u0287\u0250\u0287S",
"entity.create.super_glue": "\u01DDn\u05DF\u2141 \u0279\u01DDdnS",
"item.create.andesite_alloy": "\u028Eo\u05DF\u05DF\u2C6F \u01DD\u0287\u0131s\u01DDpu\u2C6F",
@ -380,6 +382,7 @@
"item.create.empty_schematic": "\u0254\u0131\u0287\u0250\u026F\u01DD\u0265\u0254S \u028E\u0287d\u026F\u018E",
"item.create.extendo_grip": "d\u0131\u0279\u2141 opu\u01DD\u0287x\u018E",
"item.create.filter": "\u0279\u01DD\u0287\u05DF\u0131\u2132",
"item.create.fuel_pellet": "\u0287\u01DD\u05DF\u05DF\u01DD\u0500 \u05DF\u01DDn\u2132",
"item.create.furnace_minecart_contraption": "uo\u0131\u0287d\u0250\u0279\u0287uo\u0186 \u0287\u0279\u0250\u0254\u01DDu\u0131W \u01DD\u0254\u0250u\u0279n\u2132",
"item.create.goggles": "s\u01DD\u05DFbbo\u2141 s,\u0279\u01DD\u01DDu\u0131bu\u018E",
"item.create.golden_sheet": "\u0287\u01DD\u01DD\u0265S u\u01DDp\u05DFo\u2141",

View File

@ -29,6 +29,7 @@
"block.create.birch_window": "Birch Window",
"block.create.birch_window_pane": "Birch Window Pane",
"block.create.black_seat": "Black Seat",
"block.create.blaze_heater": "Blaze Heater",
"block.create.blue_seat": "Blue Seat",
"block.create.brass_belt_funnel": "Brass Belt Funnel",
"block.create.brass_block": "Brass Block",
@ -359,6 +360,7 @@
"block.create.zinc_ore": "Zinc Ore",
"entity.create.contraption": "Contraption",
"entity.create.seat": "Seat",
"entity.create.stationary_contraption": "Stationary Contraption",
"entity.create.super_glue": "Super Glue",
@ -385,6 +387,7 @@
"item.create.empty_schematic": "Empty Schematic",
"item.create.extendo_grip": "Extendo Grip",
"item.create.filter": "Filter",
"item.create.fuel_pellet": "Fuel Pellet",
"item.create.furnace_minecart_contraption": "Furnace Minecart Contraption",
"item.create.goggles": "Engineer's Goggles",
"item.create.golden_sheet": "Golden Sheet",
@ -863,6 +866,7 @@
"create.subtitle.blockzapper_confirm": "Affirmative Ding",
"create.subtitle.blockzapper_deny": "Declining Boop",
"create.subtitle.block_funnel_eat": "Funnel CHOMPS",
"create.subtitle.blaze_munch": "Blaze munches happily",
"_": "->------------------------] Item Descriptions [------------------------<-",
@ -1079,6 +1083,15 @@
"block.create.basin.tooltip": "BASIN",
"block.create.basin.tooltip.summary": "A handy _item_ _container_ used in processing with the _Mechanical_ _Mixer_ and the _Mechanical_ _Press_. Supports _Redstone_ _Comparators_.",
"block.create.blaze_heater.tooltip": "BLAZE HEATER",
"block.create.blaze_heater.tooltip.summary": "A block to heat a basin when housing a tamed blaze.",
"block.create.blaze_heater.tooltip.condition1": "When using on a blaze or blaze spawner",
"block.create.blaze_heater.tooltip.behaviour1": "_Captures_ a blaze in the item",
"block.create.blaze_heater.tooltip.condition2": "When placed below a basin",
"block.create.blaze_heater.tooltip.behaviour2": "Provides _heat_ to basin recipes.",
"block.create.blaze_heater.tooltip.condition3": "When fuel is used on the blaze heater",
"block.create.blaze_heater.tooltip.behaviour3": "Increases the remaining burn time by the furnace brn time of the used item. Consumes the item. Use _special_ _fuel_ for best results.",
"block.create.reinforced_rail.tooltip": "REINFORCED RAIL",
"block.create.reinforced_rail.tooltip.summary": "A timber stabilized rail, _does_ _not_ _need_ _supports_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 797",
"_": "Missing Localizations: 809",
"_": "->------------------------] Game Elements [------------------------<-",
@ -30,6 +30,7 @@
"block.create.birch_window": "UNLOCALIZED: Birch Window",
"block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane",
"block.create.black_seat": "UNLOCALIZED: Black Seat",
"block.create.blaze_heater": "UNLOCALIZED: Blaze Heater",
"block.create.blue_seat": "UNLOCALIZED: Blue Seat",
"block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel",
"block.create.brass_block": "UNLOCALIZED: Brass Block",
@ -360,6 +361,7 @@
"block.create.zinc_ore": "UNLOCALIZED: Zinc Ore",
"entity.create.contraption": "UNLOCALIZED: Contraption",
"entity.create.seat": "UNLOCALIZED: Seat",
"entity.create.stationary_contraption": "UNLOCALIZED: Stationary Contraption",
"entity.create.super_glue": "UNLOCALIZED: Super Glue",
@ -386,6 +388,7 @@
"item.create.empty_schematic": "Leerer Bauplan",
"item.create.extendo_grip": "UNLOCALIZED: Extendo Grip",
"item.create.filter": "Filter",
"item.create.fuel_pellet": "UNLOCALIZED: Fuel Pellet",
"item.create.furnace_minecart_contraption": "UNLOCALIZED: Furnace Minecart Contraption",
"item.create.goggles": "UNLOCALIZED: Engineer's Goggles",
"item.create.golden_sheet": "UNLOCALIZED: Golden Sheet",
@ -864,6 +867,7 @@
"create.subtitle.blockzapper_confirm": "UNLOCALIZED: Affirmative Ding",
"create.subtitle.blockzapper_deny": "UNLOCALIZED: Declining Boop",
"create.subtitle.block_funnel_eat": "UNLOCALIZED: Funnel CHOMPS",
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze munches happily",
"_": "->------------------------] Item Descriptions [------------------------<-",
@ -1080,6 +1084,15 @@
"block.create.basin.tooltip": "UNLOCALIZED: BASIN",
"block.create.basin.tooltip.summary": "UNLOCALIZED: A handy _item_ _container_ used in processing with the _Mechanical_ _Mixer_ and the _Mechanical_ _Press_. Supports _Redstone_ _Comparators_.",
"block.create.blaze_heater.tooltip": "UNLOCALIZED: BLAZE HEATER",
"block.create.blaze_heater.tooltip.summary": "UNLOCALIZED: A block to heat a basin when housing a tamed blaze.",
"block.create.blaze_heater.tooltip.condition1": "UNLOCALIZED: When using on a blaze or blaze spawner",
"block.create.blaze_heater.tooltip.behaviour1": "UNLOCALIZED: _Captures_ a blaze in the item",
"block.create.blaze_heater.tooltip.condition2": "UNLOCALIZED: When placed below a basin",
"block.create.blaze_heater.tooltip.behaviour2": "UNLOCALIZED: Provides _heat_ to basin recipes.",
"block.create.blaze_heater.tooltip.condition3": "UNLOCALIZED: When fuel is used on the blaze heater",
"block.create.blaze_heater.tooltip.behaviour3": "UNLOCALIZED: Increases the remaining burn time by the furnace brn time of the used item. Consumes the item. Use _special_ _fuel_ for best results.",
"block.create.reinforced_rail.tooltip": "UNLOCALIZED: REINFORCED RAIL",
"block.create.reinforced_rail.tooltip.summary": "UNLOCALIZED: A timber stabilized rail, _does_ _not_ _need_ _supports_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 400",
"_": "Missing Localizations: 412",
"_": "->------------------------] Game Elements [------------------------<-",
@ -30,6 +30,7 @@
"block.create.birch_window": "UNLOCALIZED: Birch Window",
"block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane",
"block.create.black_seat": "UNLOCALIZED: Black Seat",
"block.create.blaze_heater": "UNLOCALIZED: Blaze Heater",
"block.create.blue_seat": "UNLOCALIZED: Blue Seat",
"block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel",
"block.create.brass_block": "UNLOCALIZED: Brass Block",
@ -360,6 +361,7 @@
"block.create.zinc_ore": "Minerai de zinc",
"entity.create.contraption": "UNLOCALIZED: Contraption",
"entity.create.seat": "UNLOCALIZED: Seat",
"entity.create.stationary_contraption": "UNLOCALIZED: Stationary Contraption",
"entity.create.super_glue": "UNLOCALIZED: Super Glue",
@ -386,6 +388,7 @@
"item.create.empty_schematic": "Schéma vide",
"item.create.extendo_grip": "UNLOCALIZED: Extendo Grip",
"item.create.filter": "Filtre",
"item.create.fuel_pellet": "UNLOCALIZED: Fuel Pellet",
"item.create.furnace_minecart_contraption": "UNLOCALIZED: Furnace Minecart Contraption",
"item.create.goggles": "Lunettes d'ingénieur",
"item.create.golden_sheet": "UNLOCALIZED: Golden Sheet",
@ -864,6 +867,7 @@
"create.subtitle.blockzapper_confirm": "Ding d'affirmation",
"create.subtitle.blockzapper_deny": "Boop de déclin",
"create.subtitle.block_funnel_eat": "Croc d'entonoir",
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze munches happily",
"_": "->------------------------] Item Descriptions [------------------------<-",
@ -1080,6 +1084,15 @@
"block.create.basin.tooltip": "BASSIN",
"block.create.basin.tooltip.summary": "Un _objet_ _conteneur_ pratique utilisé dans le traitement avec le _mixeur_ _mécanique_ et la _presse_ _mecanique_. Prend en charge les _comparateur_ _de_ _redstone_.",
"block.create.blaze_heater.tooltip": "UNLOCALIZED: BLAZE HEATER",
"block.create.blaze_heater.tooltip.summary": "UNLOCALIZED: A block to heat a basin when housing a tamed blaze.",
"block.create.blaze_heater.tooltip.condition1": "UNLOCALIZED: When using on a blaze or blaze spawner",
"block.create.blaze_heater.tooltip.behaviour1": "UNLOCALIZED: _Captures_ a blaze in the item",
"block.create.blaze_heater.tooltip.condition2": "UNLOCALIZED: When placed below a basin",
"block.create.blaze_heater.tooltip.behaviour2": "UNLOCALIZED: Provides _heat_ to basin recipes.",
"block.create.blaze_heater.tooltip.condition3": "UNLOCALIZED: When fuel is used on the blaze heater",
"block.create.blaze_heater.tooltip.behaviour3": "UNLOCALIZED: Increases the remaining burn time by the furnace brn time of the used item. Consumes the item. Use _special_ _fuel_ for best results.",
"block.create.reinforced_rail.tooltip": "UNLOCALIZED: REINFORCED RAIL",
"block.create.reinforced_rail.tooltip.summary": "UNLOCALIZED: A timber stabilized rail, _does_ _not_ _need_ _supports_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 384",
"_": "Missing Localizations: 396",
"_": "->------------------------] Game Elements [------------------------<-",
@ -30,6 +30,7 @@
"block.create.birch_window": "UNLOCALIZED: Birch Window",
"block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane",
"block.create.black_seat": "UNLOCALIZED: Black Seat",
"block.create.blaze_heater": "UNLOCALIZED: Blaze Heater",
"block.create.blue_seat": "UNLOCALIZED: Blue Seat",
"block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel",
"block.create.brass_block": "Blocco di Ottone",
@ -360,6 +361,7 @@
"block.create.zinc_ore": "Zinco Grezzo",
"entity.create.contraption": "UNLOCALIZED: Contraption",
"entity.create.seat": "UNLOCALIZED: Seat",
"entity.create.stationary_contraption": "UNLOCALIZED: Stationary Contraption",
"entity.create.super_glue": "UNLOCALIZED: Super Glue",
@ -386,6 +388,7 @@
"item.create.empty_schematic": "Schematica Vuota",
"item.create.extendo_grip": "UNLOCALIZED: Extendo Grip",
"item.create.filter": "Filtro",
"item.create.fuel_pellet": "UNLOCALIZED: Fuel Pellet",
"item.create.furnace_minecart_contraption": "UNLOCALIZED: Furnace Minecart Contraption",
"item.create.goggles": "Occhiali da Ingegnere",
"item.create.golden_sheet": "UNLOCALIZED: Golden Sheet",
@ -864,6 +867,7 @@
"create.subtitle.blockzapper_confirm": "Ding Affermativo",
"create.subtitle.blockzapper_deny": "Boop in Calo",
"create.subtitle.block_funnel_eat": "CHOMPS a Imbuto",
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze munches happily",
"_": "->------------------------] Item Descriptions [------------------------<-",
@ -1080,6 +1084,15 @@
"block.create.basin.tooltip": "BACINELLA",
"block.create.basin.tooltip.summary": "Un pratico _contenitore_ _di_ _oggetti_ utilizzato nella lavorazione con il _Miscelatore_ _Meccanico_ e la _Pressa_ _Meccanica_. Supporta i _Comparatori_ _Redstone_.",
"block.create.blaze_heater.tooltip": "UNLOCALIZED: BLAZE HEATER",
"block.create.blaze_heater.tooltip.summary": "UNLOCALIZED: A block to heat a basin when housing a tamed blaze.",
"block.create.blaze_heater.tooltip.condition1": "UNLOCALIZED: When using on a blaze or blaze spawner",
"block.create.blaze_heater.tooltip.behaviour1": "UNLOCALIZED: _Captures_ a blaze in the item",
"block.create.blaze_heater.tooltip.condition2": "UNLOCALIZED: When placed below a basin",
"block.create.blaze_heater.tooltip.behaviour2": "UNLOCALIZED: Provides _heat_ to basin recipes.",
"block.create.blaze_heater.tooltip.condition3": "UNLOCALIZED: When fuel is used on the blaze heater",
"block.create.blaze_heater.tooltip.behaviour3": "UNLOCALIZED: Increases the remaining burn time by the furnace brn time of the used item. Consumes the item. Use _special_ _fuel_ for best results.",
"block.create.reinforced_rail.tooltip": "UNLOCALIZED: REINFORCED RAIL",
"block.create.reinforced_rail.tooltip.summary": "UNLOCALIZED: A timber stabilized rail, _does_ _not_ _need_ _supports_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 379",
"_": "Missing Localizations: 391",
"_": "->------------------------] Game Elements [------------------------<-",
@ -30,6 +30,7 @@
"block.create.birch_window": "UNLOCALIZED: Birch Window",
"block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane",
"block.create.black_seat": "UNLOCALIZED: Black Seat",
"block.create.blaze_heater": "UNLOCALIZED: Blaze Heater",
"block.create.blue_seat": "UNLOCALIZED: Blue Seat",
"block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel",
"block.create.brass_block": "真鍮ブロック",
@ -360,6 +361,7 @@
"block.create.zinc_ore": "亜鉛鉱石",
"entity.create.contraption": "UNLOCALIZED: Contraption",
"entity.create.seat": "UNLOCALIZED: Seat",
"entity.create.stationary_contraption": "UNLOCALIZED: Stationary Contraption",
"entity.create.super_glue": "UNLOCALIZED: Super Glue",
@ -386,6 +388,7 @@
"item.create.empty_schematic": "空の概略図",
"item.create.extendo_grip": "UNLOCALIZED: Extendo Grip",
"item.create.filter": "フィルター",
"item.create.fuel_pellet": "UNLOCALIZED: Fuel Pellet",
"item.create.furnace_minecart_contraption": "UNLOCALIZED: Furnace Minecart Contraption",
"item.create.goggles": "エンジニアのゴーグル",
"item.create.golden_sheet": "UNLOCALIZED: Golden Sheet",
@ -864,6 +867,7 @@
"create.subtitle.blockzapper_confirm": "アファーマティブディン",
"create.subtitle.blockzapper_deny": "衰退するブープ",
"create.subtitle.block_funnel_eat": "ファンネルCHOMPS",
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze munches happily",
"_": "->------------------------] Item Descriptions [------------------------<-",
@ -1080,6 +1084,15 @@
"block.create.basin.tooltip": "鉢",
"block.create.basin.tooltip.summary": "_メカニカルミキサー_と_メカニカルプレス_での処理に使用される便利な_アイテムの入れ物_。_レッドストーンコンパレータ_をサポートします。",
"block.create.blaze_heater.tooltip": "UNLOCALIZED: BLAZE HEATER",
"block.create.blaze_heater.tooltip.summary": "UNLOCALIZED: A block to heat a basin when housing a tamed blaze.",
"block.create.blaze_heater.tooltip.condition1": "UNLOCALIZED: When using on a blaze or blaze spawner",
"block.create.blaze_heater.tooltip.behaviour1": "UNLOCALIZED: _Captures_ a blaze in the item",
"block.create.blaze_heater.tooltip.condition2": "UNLOCALIZED: When placed below a basin",
"block.create.blaze_heater.tooltip.behaviour2": "UNLOCALIZED: Provides _heat_ to basin recipes.",
"block.create.blaze_heater.tooltip.condition3": "UNLOCALIZED: When fuel is used on the blaze heater",
"block.create.blaze_heater.tooltip.behaviour3": "UNLOCALIZED: Increases the remaining burn time by the furnace brn time of the used item. Consumes the item. Use _special_ _fuel_ for best results.",
"block.create.reinforced_rail.tooltip": "UNLOCALIZED: REINFORCED RAIL",
"block.create.reinforced_rail.tooltip.summary": "UNLOCALIZED: A timber stabilized rail, _does_ _not_ _need_ _supports_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 384",
"_": "Missing Localizations: 396",
"_": "->------------------------] Game Elements [------------------------<-",
@ -30,6 +30,7 @@
"block.create.birch_window": "UNLOCALIZED: Birch Window",
"block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane",
"block.create.black_seat": "UNLOCALIZED: Black Seat",
"block.create.blaze_heater": "UNLOCALIZED: Blaze Heater",
"block.create.blue_seat": "UNLOCALIZED: Blue Seat",
"block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel",
"block.create.brass_block": "황동 블럭",
@ -360,6 +361,7 @@
"block.create.zinc_ore": "아연 광석",
"entity.create.contraption": "UNLOCALIZED: Contraption",
"entity.create.seat": "UNLOCALIZED: Seat",
"entity.create.stationary_contraption": "UNLOCALIZED: Stationary Contraption",
"entity.create.super_glue": "UNLOCALIZED: Super Glue",
@ -386,6 +388,7 @@
"item.create.empty_schematic": "빈 청사진",
"item.create.extendo_grip": "UNLOCALIZED: Extendo Grip",
"item.create.filter": "필터 틀",
"item.create.fuel_pellet": "UNLOCALIZED: Fuel Pellet",
"item.create.furnace_minecart_contraption": "UNLOCALIZED: Furnace Minecart Contraption",
"item.create.goggles": "엔지니어의 고글",
"item.create.golden_sheet": "UNLOCALIZED: Golden Sheet",
@ -864,6 +867,7 @@
"create.subtitle.blockzapper_confirm": "확인 효과음",
"create.subtitle.blockzapper_deny": "취소 효과음",
"create.subtitle.block_funnel_eat": "깔때기가 흡입함",
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze munches happily",
"_": "->------------------------] Item Descriptions [------------------------<-",
@ -1080,6 +1084,15 @@
"block.create.basin.tooltip": "BASIN",
"block.create.basin.tooltip.summary": "믹서나 압착기와 같이 쓰이는 간편한 _아이템_ _저장소_입니다. 레드스톤 비교기와 호환됩니다.",
"block.create.blaze_heater.tooltip": "UNLOCALIZED: BLAZE HEATER",
"block.create.blaze_heater.tooltip.summary": "UNLOCALIZED: A block to heat a basin when housing a tamed blaze.",
"block.create.blaze_heater.tooltip.condition1": "UNLOCALIZED: When using on a blaze or blaze spawner",
"block.create.blaze_heater.tooltip.behaviour1": "UNLOCALIZED: _Captures_ a blaze in the item",
"block.create.blaze_heater.tooltip.condition2": "UNLOCALIZED: When placed below a basin",
"block.create.blaze_heater.tooltip.behaviour2": "UNLOCALIZED: Provides _heat_ to basin recipes.",
"block.create.blaze_heater.tooltip.condition3": "UNLOCALIZED: When fuel is used on the blaze heater",
"block.create.blaze_heater.tooltip.behaviour3": "UNLOCALIZED: Increases the remaining burn time by the furnace brn time of the used item. Consumes the item. Use _special_ _fuel_ for best results.",
"block.create.reinforced_rail.tooltip": "UNLOCALIZED: REINFORCED RAIL",
"block.create.reinforced_rail.tooltip.summary": "UNLOCALIZED: A timber stabilized rail, _does_ _not_ _need_ _supports_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 734",
"_": "Missing Localizations: 746",
"_": "->------------------------] Game Elements [------------------------<-",
@ -30,6 +30,7 @@
"block.create.birch_window": "UNLOCALIZED: Birch Window",
"block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane",
"block.create.black_seat": "UNLOCALIZED: Black Seat",
"block.create.blaze_heater": "UNLOCALIZED: Blaze Heater",
"block.create.blue_seat": "UNLOCALIZED: Blue Seat",
"block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel",
"block.create.brass_block": "UNLOCALIZED: Brass Block",
@ -360,6 +361,7 @@
"block.create.zinc_ore": "UNLOCALIZED: Zinc Ore",
"entity.create.contraption": "UNLOCALIZED: Contraption",
"entity.create.seat": "UNLOCALIZED: Seat",
"entity.create.stationary_contraption": "UNLOCALIZED: Stationary Contraption",
"entity.create.super_glue": "UNLOCALIZED: Super Glue",
@ -386,6 +388,7 @@
"item.create.empty_schematic": "Lege bouwtekening",
"item.create.extendo_grip": "UNLOCALIZED: Extendo Grip",
"item.create.filter": "Filter",
"item.create.fuel_pellet": "UNLOCALIZED: Fuel Pellet",
"item.create.furnace_minecart_contraption": "UNLOCALIZED: Furnace Minecart Contraption",
"item.create.goggles": "Ingenieur's Bril",
"item.create.golden_sheet": "UNLOCALIZED: Golden Sheet",
@ -864,6 +867,7 @@
"create.subtitle.blockzapper_confirm": "UNLOCALIZED: Affirmative Ding",
"create.subtitle.blockzapper_deny": "UNLOCALIZED: Declining Boop",
"create.subtitle.block_funnel_eat": "UNLOCALIZED: Funnel CHOMPS",
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze munches happily",
"_": "->------------------------] Item Descriptions [------------------------<-",
@ -1080,6 +1084,15 @@
"block.create.basin.tooltip": "UNLOCALIZED: BASIN",
"block.create.basin.tooltip.summary": "UNLOCALIZED: A handy _item_ _container_ used in processing with the _Mechanical_ _Mixer_ and the _Mechanical_ _Press_. Supports _Redstone_ _Comparators_.",
"block.create.blaze_heater.tooltip": "UNLOCALIZED: BLAZE HEATER",
"block.create.blaze_heater.tooltip.summary": "UNLOCALIZED: A block to heat a basin when housing a tamed blaze.",
"block.create.blaze_heater.tooltip.condition1": "UNLOCALIZED: When using on a blaze or blaze spawner",
"block.create.blaze_heater.tooltip.behaviour1": "UNLOCALIZED: _Captures_ a blaze in the item",
"block.create.blaze_heater.tooltip.condition2": "UNLOCALIZED: When placed below a basin",
"block.create.blaze_heater.tooltip.behaviour2": "UNLOCALIZED: Provides _heat_ to basin recipes.",
"block.create.blaze_heater.tooltip.condition3": "UNLOCALIZED: When fuel is used on the blaze heater",
"block.create.blaze_heater.tooltip.behaviour3": "UNLOCALIZED: Increases the remaining burn time by the furnace brn time of the used item. Consumes the item. Use _special_ _fuel_ for best results.",
"block.create.reinforced_rail.tooltip": "UNLOCALIZED: REINFORCED RAIL",
"block.create.reinforced_rail.tooltip.summary": "UNLOCALIZED: A timber stabilized rail, _does_ _not_ _need_ _supports_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 804",
"_": "Missing Localizations: 816",
"_": "->------------------------] Game Elements [------------------------<-",
@ -30,6 +30,7 @@
"block.create.birch_window": "UNLOCALIZED: Birch Window",
"block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane",
"block.create.black_seat": "UNLOCALIZED: Black Seat",
"block.create.blaze_heater": "UNLOCALIZED: Blaze Heater",
"block.create.blue_seat": "UNLOCALIZED: Blue Seat",
"block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel",
"block.create.brass_block": "UNLOCALIZED: Brass Block",
@ -360,6 +361,7 @@
"block.create.zinc_ore": "UNLOCALIZED: Zinc Ore",
"entity.create.contraption": "UNLOCALIZED: Contraption",
"entity.create.seat": "UNLOCALIZED: Seat",
"entity.create.stationary_contraption": "UNLOCALIZED: Stationary Contraption",
"entity.create.super_glue": "UNLOCALIZED: Super Glue",
@ -386,6 +388,7 @@
"item.create.empty_schematic": "Esquema vazio",
"item.create.extendo_grip": "UNLOCALIZED: Extendo Grip",
"item.create.filter": "Filtro",
"item.create.fuel_pellet": "UNLOCALIZED: Fuel Pellet",
"item.create.furnace_minecart_contraption": "UNLOCALIZED: Furnace Minecart Contraption",
"item.create.goggles": "UNLOCALIZED: Engineer's Goggles",
"item.create.golden_sheet": "UNLOCALIZED: Golden Sheet",
@ -864,6 +867,7 @@
"create.subtitle.blockzapper_confirm": "UNLOCALIZED: Affirmative Ding",
"create.subtitle.blockzapper_deny": "UNLOCALIZED: Declining Boop",
"create.subtitle.block_funnel_eat": "UNLOCALIZED: Funnel CHOMPS",
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze munches happily",
"_": "->------------------------] Item Descriptions [------------------------<-",
@ -1080,6 +1084,15 @@
"block.create.basin.tooltip": "UNLOCALIZED: BASIN",
"block.create.basin.tooltip.summary": "UNLOCALIZED: A handy _item_ _container_ used in processing with the _Mechanical_ _Mixer_ and the _Mechanical_ _Press_. Supports _Redstone_ _Comparators_.",
"block.create.blaze_heater.tooltip": "UNLOCALIZED: BLAZE HEATER",
"block.create.blaze_heater.tooltip.summary": "UNLOCALIZED: A block to heat a basin when housing a tamed blaze.",
"block.create.blaze_heater.tooltip.condition1": "UNLOCALIZED: When using on a blaze or blaze spawner",
"block.create.blaze_heater.tooltip.behaviour1": "UNLOCALIZED: _Captures_ a blaze in the item",
"block.create.blaze_heater.tooltip.condition2": "UNLOCALIZED: When placed below a basin",
"block.create.blaze_heater.tooltip.behaviour2": "UNLOCALIZED: Provides _heat_ to basin recipes.",
"block.create.blaze_heater.tooltip.condition3": "UNLOCALIZED: When fuel is used on the blaze heater",
"block.create.blaze_heater.tooltip.behaviour3": "UNLOCALIZED: Increases the remaining burn time by the furnace brn time of the used item. Consumes the item. Use _special_ _fuel_ for best results.",
"block.create.reinforced_rail.tooltip": "UNLOCALIZED: REINFORCED RAIL",
"block.create.reinforced_rail.tooltip.summary": "UNLOCALIZED: A timber stabilized rail, _does_ _not_ _need_ _supports_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 798",
"_": "Missing Localizations: 810",
"_": "->------------------------] Game Elements [------------------------<-",
@ -30,6 +30,7 @@
"block.create.birch_window": "UNLOCALIZED: Birch Window",
"block.create.birch_window_pane": "UNLOCALIZED: Birch Window Pane",
"block.create.black_seat": "UNLOCALIZED: Black Seat",
"block.create.blaze_heater": "UNLOCALIZED: Blaze Heater",
"block.create.blue_seat": "UNLOCALIZED: Blue Seat",
"block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel",
"block.create.brass_block": "UNLOCALIZED: Brass Block",
@ -360,6 +361,7 @@
"block.create.zinc_ore": "UNLOCALIZED: Zinc Ore",
"entity.create.contraption": "UNLOCALIZED: Contraption",
"entity.create.seat": "UNLOCALIZED: Seat",
"entity.create.stationary_contraption": "UNLOCALIZED: Stationary Contraption",
"entity.create.super_glue": "UNLOCALIZED: Super Glue",
@ -386,6 +388,7 @@
"item.create.empty_schematic": "Пустая схема",
"item.create.extendo_grip": "UNLOCALIZED: Extendo Grip",
"item.create.filter": "Фильтр",
"item.create.fuel_pellet": "UNLOCALIZED: Fuel Pellet",
"item.create.furnace_minecart_contraption": "UNLOCALIZED: Furnace Minecart Contraption",
"item.create.goggles": "UNLOCALIZED: Engineer's Goggles",
"item.create.golden_sheet": "UNLOCALIZED: Golden Sheet",
@ -864,6 +867,7 @@
"create.subtitle.blockzapper_confirm": "UNLOCALIZED: Affirmative Ding",
"create.subtitle.blockzapper_deny": "UNLOCALIZED: Declining Boop",
"create.subtitle.block_funnel_eat": "UNLOCALIZED: Funnel CHOMPS",
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze munches happily",
"_": "->------------------------] Item Descriptions [------------------------<-",
@ -1080,6 +1084,15 @@
"block.create.basin.tooltip": "UNLOCALIZED: BASIN",
"block.create.basin.tooltip.summary": "UNLOCALIZED: A handy _item_ _container_ used in processing with the _Mechanical_ _Mixer_ and the _Mechanical_ _Press_. Supports _Redstone_ _Comparators_.",
"block.create.blaze_heater.tooltip": "UNLOCALIZED: BLAZE HEATER",
"block.create.blaze_heater.tooltip.summary": "UNLOCALIZED: A block to heat a basin when housing a tamed blaze.",
"block.create.blaze_heater.tooltip.condition1": "UNLOCALIZED: When using on a blaze or blaze spawner",
"block.create.blaze_heater.tooltip.behaviour1": "UNLOCALIZED: _Captures_ a blaze in the item",
"block.create.blaze_heater.tooltip.condition2": "UNLOCALIZED: When placed below a basin",
"block.create.blaze_heater.tooltip.behaviour2": "UNLOCALIZED: Provides _heat_ to basin recipes.",
"block.create.blaze_heater.tooltip.condition3": "UNLOCALIZED: When fuel is used on the blaze heater",
"block.create.blaze_heater.tooltip.behaviour3": "UNLOCALIZED: Increases the remaining burn time by the furnace brn time of the used item. Consumes the item. Use _special_ _fuel_ for best results.",
"block.create.reinforced_rail.tooltip": "UNLOCALIZED: REINFORCED RAIL",
"block.create.reinforced_rail.tooltip.summary": "UNLOCALIZED: A timber stabilized rail, _does_ _not_ _need_ _supports_.",

View File

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 60",
"_": "Missing Localizations: 72",
"_": "->------------------------] Game Elements [------------------------<-",
@ -30,6 +30,7 @@
"block.create.birch_window": "白桦窗户",
"block.create.birch_window_pane": "白桦窗户板",
"block.create.black_seat": "UNLOCALIZED: Black Seat",
"block.create.blaze_heater": "UNLOCALIZED: Blaze Heater",
"block.create.blue_seat": "UNLOCALIZED: Blue Seat",
"block.create.brass_belt_funnel": "UNLOCALIZED: Brass Belt Funnel",
"block.create.brass_block": "黄铜块",
@ -360,6 +361,7 @@
"block.create.zinc_ore": "锌矿石",
"entity.create.contraption": "结构",
"entity.create.seat": "UNLOCALIZED: Seat",
"entity.create.stationary_contraption": "固定结构",
"entity.create.super_glue": "强力胶",
@ -386,6 +388,7 @@
"item.create.empty_schematic": "空白蓝图",
"item.create.extendo_grip": "伸缩机械手",
"item.create.filter": "过滤器",
"item.create.fuel_pellet": "UNLOCALIZED: Fuel Pellet",
"item.create.furnace_minecart_contraption": "装配过的动力矿车",
"item.create.goggles": "工程师护目镜",
"item.create.golden_sheet": "金板",
@ -864,6 +867,7 @@
"create.subtitle.blockzapper_confirm": "选择方块",
"create.subtitle.blockzapper_deny": "放置失败",
"create.subtitle.block_funnel_eat": "漏斗吞食",
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze munches happily",
"_": "->------------------------] Item Descriptions [------------------------<-",
@ -1080,6 +1084,15 @@
"block.create.basin.tooltip": "BASIN",
"block.create.basin.tooltip.summary": "一种方便的_物品容器_,常常用于_辊压机_和_搅拌机_,可以被_红石比较器_检测",
"block.create.blaze_heater.tooltip": "UNLOCALIZED: BLAZE HEATER",
"block.create.blaze_heater.tooltip.summary": "UNLOCALIZED: A block to heat a basin when housing a tamed blaze.",
"block.create.blaze_heater.tooltip.condition1": "UNLOCALIZED: When using on a blaze or blaze spawner",
"block.create.blaze_heater.tooltip.behaviour1": "UNLOCALIZED: _Captures_ a blaze in the item",
"block.create.blaze_heater.tooltip.condition2": "UNLOCALIZED: When placed below a basin",
"block.create.blaze_heater.tooltip.behaviour2": "UNLOCALIZED: Provides _heat_ to basin recipes.",
"block.create.blaze_heater.tooltip.condition3": "UNLOCALIZED: When fuel is used on the blaze heater",
"block.create.blaze_heater.tooltip.behaviour3": "UNLOCALIZED: Increases the remaining burn time by the furnace brn time of the used item. Consumes the item. Use _special_ _fuel_ for best results.",
"block.create.reinforced_rail.tooltip": "UNLOCALIZED: REINFORCED RAIL",
"block.create.reinforced_rail.tooltip.summary": "UNLOCALIZED: A timber stabilized rail, _does_ _not_ _need_ _supports_.",

View File

@ -1,8 +1,9 @@
{
"parent": "create:block/belt_tunnel/cross",
"textures": {
"0": "create:block/andesite_tunnel",
"1": "create:block/andesite_tunnel_top",
"2": "create:block/andesite_tunnel",
"3": "create:block/andesite_tunnel_top_window",
"particle": "block/polished_andesite"
}
}

View File

@ -1,8 +0,0 @@
{
"parent": "create:block/belt_tunnel/fullshade",
"textures": {
"0": "create:block/andesite_tunnel",
"1": "create:block/andesite_tunnel_top",
"particle": "block/polished_andesite"
}
}

View File

@ -1,8 +0,0 @@
{
"parent": "create:block/belt_tunnel/halfshade",
"textures": {
"0": "create:block/andesite_tunnel",
"1": "create:block/andesite_tunnel_top",
"particle": "block/polished_andesite"
}
}

View File

@ -1,8 +1,9 @@
{
"parent": "create:block/belt_tunnel/straight",
"textures": {
"0": "create:block/andesite_tunnel",
"1": "create:block/andesite_tunnel_top",
"2": "create:block/andesite_tunnel",
"3": "create:block/andesite_tunnel_top_window",
"particle": "block/polished_andesite"
}
}

View File

@ -1,8 +1,9 @@
{
"parent": "create:block/belt_tunnel/t_left",
"textures": {
"0": "create:block/andesite_tunnel",
"1": "create:block/andesite_tunnel_top",
"2": "create:block/andesite_tunnel",
"3": "create:block/andesite_tunnel_top_window",
"particle": "block/polished_andesite"
}
}

View File

@ -1,8 +1,9 @@
{
"parent": "create:block/belt_tunnel/t_right",
"textures": {
"0": "create:block/andesite_tunnel",
"1": "create:block/andesite_tunnel_top",
"2": "create:block/andesite_tunnel",
"3": "create:block/andesite_tunnel_top_window",
"particle": "block/polished_andesite"
}
}

View File

@ -1,8 +1,9 @@
{
"parent": "create:block/belt_tunnel/window",
"textures": {
"0": "create:block/andesite_tunnel",
"1": "create:block/andesite_tunnel_top",
"2": "create:block/andesite_tunnel",
"3": "create:block/andesite_tunnel_top_window",
"particle": "block/polished_andesite"
}
}

View File

@ -1,8 +1,9 @@
{
"parent": "create:block/belt_tunnel/cross",
"textures": {
"0": "create:block/brass_tunnel",
"1": "create:block/brass_tunnel_top",
"2": "create:block/brass_tunnel",
"3": "create:block/brass_tunnel_top_window",
"particle": "create:block/brass_block"
}
}

View File

@ -1,8 +0,0 @@
{
"parent": "create:block/belt_tunnel/fullshade",
"textures": {
"0": "create:block/brass_tunnel",
"1": "create:block/brass_tunnel_top",
"particle": "create:block/brass_block"
}
}

View File

@ -1,8 +0,0 @@
{
"parent": "create:block/belt_tunnel/halfshade",
"textures": {
"0": "create:block/brass_tunnel",
"1": "create:block/brass_tunnel_top",
"particle": "create:block/brass_block"
}
}

View File

@ -1,8 +1,9 @@
{
"parent": "create:block/belt_tunnel/straight",
"textures": {
"0": "create:block/brass_tunnel",
"1": "create:block/brass_tunnel_top",
"2": "create:block/brass_tunnel",
"3": "create:block/brass_tunnel_top_window",
"particle": "create:block/brass_block"
}
}

View File

@ -1,8 +1,9 @@
{
"parent": "create:block/belt_tunnel/t_left",
"textures": {
"0": "create:block/brass_tunnel",
"1": "create:block/brass_tunnel_top",
"2": "create:block/brass_tunnel",
"3": "create:block/brass_tunnel_top_window",
"particle": "create:block/brass_block"
}
}

View File

@ -1,8 +1,9 @@
{
"parent": "create:block/belt_tunnel/t_right",
"textures": {
"0": "create:block/brass_tunnel",
"1": "create:block/brass_tunnel_top",
"2": "create:block/brass_tunnel",
"3": "create:block/brass_tunnel_top_window",
"particle": "create:block/brass_block"
}
}

View File

@ -1,8 +1,9 @@
{
"parent": "create:block/belt_tunnel/window",
"textures": {
"0": "create:block/brass_tunnel",
"1": "create:block/brass_tunnel_top",
"2": "create:block/brass_tunnel",
"3": "create:block/brass_tunnel_top_window",
"particle": "create:block/brass_block"
}
}

View File

@ -1,8 +1,8 @@
{
"parent": "create:block/belt_tunnel/item",
"textures": {
"0": "create:block/andesite_tunnel",
"1": "create:block/andesite_tunnel_top",
"2": "create:block/andesite_tunnel",
"particle": "block/polished_andesite"
}
}

View File

@ -0,0 +1,3 @@
{
"parent": "create:block/blaze_heater/block"
}

View File

@ -1,8 +1,8 @@
{
"parent": "create:block/belt_tunnel/item",
"textures": {
"0": "create:block/brass_tunnel",
"1": "create:block/brass_tunnel_top",
"2": "create:block/brass_tunnel",
"particle": "create:block/brass_block"
}
}

View File

@ -1,3 +1,3 @@
{
"parent": "create:block/fluid_tank/item"
"parent": "create:block/fluid_tank/block_single_window"
}

View File

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/fuel_pellet"
}
}

View File

@ -1,16 +1,16 @@
{
"creeperclock": {
"sounds": [
"create:creeperclock"
],
"subtitle": "create.subtitle.creeperclock"
},
"pigclock": {
"sounds": [
"create:pigclock"
],
"subtitle": "create.subtitle.pigclock"
},
"creeperclock": {
"sounds": [
"create:creeperclock"
],
"subtitle": "create.subtitle.creeperclock"
},
"schematicannon_launch_block": {
"sounds": [
{
@ -91,5 +91,14 @@
}
],
"subtitle": "create.subtitle.block_funnel_eat"
},
"blaze_munch": {
"sounds": [
{
"name": "minecraft:entity.generic.eat",
"type": "event"
}
],
"subtitle": "create.subtitle.blaze_munch"
}
}

View File

@ -0,0 +1,19 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "create:blaze_heater"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View File

@ -10,6 +10,9 @@
"create:extractor",
"create:vertical_extractor",
"create:linked_extractor",
"create:vertical_linked_extractor"
"create:vertical_linked_extractor",
"#minecraft:doors",
"minecraft:flower_pot",
"minecraft:bell"
]
}

View File

@ -0,0 +1,10 @@
{
"replace": false,
"values": [
"create:blaze_heater",
"minecraft:magma_block",
"minecraft:campfire",
"minecraft:lava",
"minecraft:fire"
]
}

View File

@ -0,0 +1,8 @@
{
"replace": false,
"values": [
"create:blaze_heater",
"#minecraft:fences",
"minecraft:iron_bars"
]
}

View File

@ -8,8 +8,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.tuple.Pair;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate;
@ -26,21 +24,31 @@ import net.minecraftforge.client.model.ModelLoader;
public class AllBlockPartials {
private static List<AllBlockPartials> all = new ArrayList<>();
public static final AllBlockPartials
SCHEMATICANNON_CONNECTOR = get("schematicannon/connector"),
private static final List<AllBlockPartials> all = new ArrayList<>();
public static final AllBlockPartials SCHEMATICANNON_CONNECTOR = get("schematicannon/connector"),
SCHEMATICANNON_PIPE = get("schematicannon/pipe"),
SHAFTLESS_COGWHEEL = get("cogwheel_shaftless"),
BELT_PULLEY = get("belt_pulley"),
SHAFTLESS_COGWHEEL = get("cogwheel_shaftless"),
SHAFT_HALF = get("shaft_half"),
BELT_PULLEY = get("belt_pulley"),
BELT_START = get("belt/start"),
BELT_MIDDLE = get("belt/middle"),
BELT_END = get("belt/end"),
BELT_START_BOTTOM = get("belt/start_bottom"),
BELT_MIDDLE_BOTTOM = get("belt/middle_bottom"),
BELT_END_BOTTOM = get("belt/end_bottom"),
BELT_DIAGONAL_START = get("belt/diagonal_start"),
BELT_DIAGONAL_MIDDLE = get("belt/diagonal_middle"),
BELT_DIAGONAL_END = get("belt/diagonal_end"),
ENCASED_FAN_INNER = get("encased_fan/propeller"),
HAND_CRANK_HANDLE = get("hand_crank/handle"),
MECHANICAL_PRESS_HEAD = get("mechanical_press/head"),
MECHANICAL_MIXER_POLE = get("mechanical_mixer/pole"),
MECHANICAL_MIXER_HEAD = get("mechanical_mixer/head"),
ENCASED_FAN_INNER = get("encased_fan/propeller"), HAND_CRANK_HANDLE = get("hand_crank/handle"),
MECHANICAL_PRESS_HEAD = get("mechanical_press/head"), MECHANICAL_MIXER_POLE = get("mechanical_mixer/pole"),
MECHANICAL_MIXER_HEAD = get("mechanical_mixer/head"), BLAZE_HEATER_BLAZE_ONE = get("blaze_heater/blaze/one"),
BLAZE_HEATER_BLAZE_TWO = get("blaze_heater/blaze/two"),
BLAZE_HEATER_BLAZE_THREE = get("blaze_heater/blaze/three"),
BLAZE_HEATER_BLAZE_FOUR = get("blaze_heater/blaze/four"),
MECHANICAL_CRAFTER_LID = get("mechanical_crafter/lid"),
MECHANICAL_CRAFTER_ARROW = get("mechanical_crafter/arrow"),
MECHANICAL_CRAFTER_BELT_FRAME = get("mechanical_crafter/belt"),
@ -63,46 +71,32 @@ public class AllBlockPartials {
FLEXPEATER_INDICATOR = get("diodes/indicator"),
FLYWHEEL = get("flywheel/wheel"),
FLYWHEEL_UPPER_ROTATING = get("flywheel/upper_rotating_connector"),
FLYWHEEL_LOWER_ROTATING = get("flywheel/lower_rotating_connector"),
FLYWHEEL_UPPER_SLIDING = get("flywheel/upper_sliding_connector"),
FLYWHEEL_LOWER_SLIDING = get("flywheel/lower_sliding_connector"),
FURNACE_GENERATOR_FRAME = get("furnace_engine/frame"),
CUCKOO_MINUTE_HAND = get("cuckoo_clock/minute_hand"),
CUCKOO_HOUR_HAND = get("cuckoo_clock/hour_hand"),
CUCKOO_LEFT_DOOR = get("cuckoo_clock/left_door"),
CUCKOO_RIGHT_DOOR = get("cuckoo_clock/right_door"),
CUCKOO_PIG = get("cuckoo_clock/pig"),
CUCKOO_CREEPER = get("cuckoo_clock/creeper"),
ROPE_COIL = get("rope_pulley/rope_coil"),
ROPE_HALF = get("rope_pulley/rope_half"),
ROPE_HALF_MAGNET = get("rope_pulley/rope_half_magnet"),
MILLSTONE_COG = get("millstone/inner"),
PACKAGER_SEALER = get("packager/sealer"),
FURNACE_GENERATOR_FRAME = get("furnace_engine/frame"), CUCKOO_MINUTE_HAND = get("cuckoo_clock/minute_hand"),
CUCKOO_HOUR_HAND = get("cuckoo_clock/hour_hand"), CUCKOO_LEFT_DOOR = get("cuckoo_clock/left_door"),
CUCKOO_RIGHT_DOOR = get("cuckoo_clock/right_door"), CUCKOO_PIG = get("cuckoo_clock/pig"),
CUCKOO_CREEPER = get("cuckoo_clock/creeper"), ROPE_COIL = get("rope_pulley/rope_coil"),
ROPE_HALF = get("rope_pulley/rope_half"), ROPE_HALF_MAGNET = get("rope_pulley/rope_half_magnet"),
MILLSTONE_COG = get("millstone/inner"), PACKAGER_SEALER = get("packager/sealer"),
SYMMETRY_PLANE = get("symmetry_effect/plane"),
SYMMETRY_CROSSPLANE = get("symmetry_effect/crossplane"),
SYMMETRY_PLANE = get("symmetry_effect/plane"), SYMMETRY_CROSSPLANE = get("symmetry_effect/crossplane"),
SYMMETRY_TRIPLEPLANE = get("symmetry_effect/tripleplane"),
ARM_COG = get("mechanical_arm/cog"),
ARM_BASE = get("mechanical_arm/base"),
ARM_LOWER_BODY = get("mechanical_arm/lower_body"),
ARM_UPPER_BODY = get("mechanical_arm/upper_body"),
ARM_HEAD = get("mechanical_arm/head"),
ARM_CLAW_BASE = get("mechanical_arm/claw_base"),
ARM_CLAW_GRIP = get("mechanical_arm/claw_grip"),
FLAG_SHORT_IN = get("mechanical_arm/flag/short_in"),
FLAG_SHORT_OUT = get("mechanical_arm/flag/short_out"),
FLAG_LONG_IN = get("mechanical_arm/flag/long_in"),
FLAG_LONG_OUT = get("mechanical_arm/flag/long_out"),
MECHANICAL_PUMP_ARROW = get("mechanical_pump/arrow"),
MECHANICAL_PUMP_COG = get("mechanical_pump/cog"),
ARM_COG = get("mechanical_arm/cog"), ARM_BASE = get("mechanical_arm/base"),
ARM_LOWER_BODY = get("mechanical_arm/lower_body"), ARM_UPPER_BODY = get("mechanical_arm/upper_body"),
ARM_HEAD = get("mechanical_arm/head"), ARM_CLAW_BASE = get("mechanical_arm/claw_base"),
ARM_CLAW_GRIP = get("mechanical_arm/claw_grip"),
FLAG_SHORT_IN = get("mechanical_arm/flag/short_in"), FLAG_SHORT_OUT = get("mechanical_arm/flag/short_out"),
FLAG_LONG_IN = get("mechanical_arm/flag/long_in"), FLAG_LONG_OUT = get("mechanical_arm/flag/long_out"),
MECHANICAL_PUMP_ARROW = get("mechanical_pump/arrow"), MECHANICAL_PUMP_COG = get("mechanical_pump/cog"),
FLUID_PIPE_CASING = get("fluid_pipe/casing");
public static final Map<Direction, AllBlockPartials> PIPE_RIMS = map();
public static final Map<Pair<Boolean, Direction>, AllBlockPartials> TANK_LID_FILLERS = map();
public static final Map<Pair<Boolean, Boolean>, AllBlockPartials> TANK_DIAGONAL_FILLERS = map();
static {
populateMaps();
@ -113,27 +107,12 @@ public class AllBlockPartials {
private ResourceLocation modelLocation;
private IBakedModel bakedModel;
private AllBlockPartials() {
}
private AllBlockPartials() {}
private static void populateMaps() {
for (Direction d : Iterate.directions) {
boolean horizontal = d.getAxis()
.isHorizontal();
PIPE_RIMS.put(d, get("fluid_pipe/rim/" + d.getName()));
if (horizontal) {
for (boolean top : Iterate.trueAndFalse)
TANK_LID_FILLERS.put(Pair.of(top, d),
get("fluid_tank/lid_fillers/" + (top ? "top" : "bottom") + "_" + d.getName()));
}
}
for (boolean north : Iterate.trueAndFalse)
for (boolean east : Iterate.trueAndFalse)
TANK_DIAGONAL_FILLERS.put(Pair.of(north, east),
get("fluid_tank/diagonal_fillers/" + (north ? "north" : "south") + "_" + (east ? "east" : "west")));
}
private static <T, U> Map<T, U> map() {
@ -184,9 +163,7 @@ public class AllBlockPartials {
.rotateY(AngleHelper.horizontalAngle(facing))
.rotateX(AngleHelper.verticalAngle(facing))
.unCentre();
SuperByteBuffer renderPartial =
CreateClient.bufferCache.renderDirectionalPartial(this, referenceState, facing, ms);
return renderPartial;
return CreateClient.bufferCache.renderDirectionalPartial(this, referenceState, facing, ms);
}
}

View File

@ -54,9 +54,13 @@ import com.simibubi.create.content.contraptions.components.waterwheel.WaterWheel
import com.simibubi.create.content.contraptions.fluids.FluidPipeBlock;
import com.simibubi.create.content.contraptions.fluids.FluidPipeModel;
import com.simibubi.create.content.contraptions.fluids.FluidTankBlock;
import com.simibubi.create.content.contraptions.fluids.FluidTankGenerator;
import com.simibubi.create.content.contraptions.fluids.FluidTankItem;
import com.simibubi.create.content.contraptions.fluids.FluidTankModel;
import com.simibubi.create.content.contraptions.fluids.PumpBlock;
import com.simibubi.create.content.contraptions.processing.BasinBlock;
import com.simibubi.create.content.contraptions.processing.HeaterBlock;
import com.simibubi.create.content.contraptions.processing.HeaterBlockItem;
import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerBlock;
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftBlock;
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftGenerator;
@ -208,7 +212,7 @@ public class AllBlocks {
public static final BlockEntry<EncasedShaftBlock> ENCASED_SHAFT =
REGISTRATE.block("encased_shaft", EncasedShaftBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.transform(StressConfigDefaults.setNoImpact())
.blockstate(BlockStateGen.axisBlockProvider(true))
.item()
@ -217,7 +221,7 @@ public class AllBlocks {
public static final BlockEntry<GearboxBlock> GEARBOX = REGISTRATE.block("gearbox", GearboxBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.transform(StressConfigDefaults.setNoImpact())
.blockstate(BlockStateGen.axisBlockProvider(true))
.item()
@ -226,7 +230,7 @@ public class AllBlocks {
public static final BlockEntry<ClutchBlock> CLUTCH = REGISTRATE.block("clutch", ClutchBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.transform(StressConfigDefaults.setNoImpact())
.blockstate((c, p) -> BlockStateGen.axisBlock(c, p, AssetLookup.forPowered(c, p)))
.item()
@ -235,7 +239,7 @@ public class AllBlocks {
public static final BlockEntry<GearshiftBlock> GEARSHIFT = REGISTRATE.block("gearshift", GearshiftBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.transform(StressConfigDefaults.setNoImpact())
.blockstate((c, p) -> BlockStateGen.axisBlock(c, p, AssetLookup.forPowered(c, p)))
.item()
@ -245,7 +249,7 @@ public class AllBlocks {
public static final BlockEntry<EncasedBeltBlock> ENCASED_BELT =
REGISTRATE.block("encased_belt", EncasedBeltBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.transform(StressConfigDefaults.setNoImpact())
.blockstate((c, p) -> new EncasedBeltGenerator((state, suffix) -> p.models()
.getExistingFile(p.modLoc("block/" + c.getName() + "/" + suffix))).generate(c, p))
@ -256,7 +260,7 @@ public class AllBlocks {
public static final BlockEntry<AdjustablePulleyBlock> ADJUSTABLE_PULLEY =
REGISTRATE.block("adjustable_pulley", AdjustablePulleyBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.transform(StressConfigDefaults.setNoImpact())
.blockstate((c, p) -> new EncasedBeltGenerator((state, suffix) -> {
String powered = state.get(AdjustablePulleyBlock.POWERED) ? "_powered" : "";
@ -291,7 +295,7 @@ public class AllBlocks {
public static final BlockEntry<WaterWheelBlock> WATER_WHEEL = REGISTRATE.block("water_wheel", WaterWheelBlock::new)
.initialProperties(SharedProperties::wooden)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.blockstate(BlockStateGen.horizontalWheelProvider(false))
.addLayer(() -> RenderType::getCutoutMipped)
.transform(StressConfigDefaults.setCapacity(16.0))
@ -355,7 +359,7 @@ public class AllBlocks {
public static final BlockEntry<CrushingWheelBlock> CRUSHING_WHEEL =
REGISTRATE.block("crushing_wheel", CrushingWheelBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.blockstate(BlockStateGen.axisBlockProvider(false))
.addLayer(() -> RenderType::getCutoutMipped)
.transform(StressConfigDefaults.setImpact(8.0))
@ -375,7 +379,7 @@ public class AllBlocks {
public static final BlockEntry<MechanicalPressBlock> MECHANICAL_PRESS =
REGISTRATE.block("mechanical_press", MechanicalPressBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.blockstate(BlockStateGen.horizontalBlockProvider(true))
.transform(StressConfigDefaults.setImpact(8.0))
.item(BasinOperatorBlockItem::new)
@ -385,7 +389,7 @@ public class AllBlocks {
public static final BlockEntry<MechanicalMixerBlock> MECHANICAL_MIXER =
REGISTRATE.block("mechanical_mixer", MechanicalMixerBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
.addLayer(() -> RenderType::getCutoutMipped)
.transform(StressConfigDefaults.setImpact(4.0))
@ -399,6 +403,16 @@ public class AllBlocks {
.simpleItem()
.register();
public static final BlockEntry<HeaterBlock> HEATER = REGISTRATE.block("blaze_heater", HeaterBlock::new)
.initialProperties(SharedProperties::softMetal)
.properties(p -> p.lightValue(12))
.addLayer(() -> RenderType::getCutoutMipped)
.tag(AllBlockTags.FAN_TRANSPARENT.tag, AllBlockTags.FAN_HEATERS.tag)
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
.item(HeaterBlockItem::new)
.build()
.register();
public static final BlockEntry<DepotBlock> DEPOT = REGISTRATE.block("depot", DepotBlock::new)
.initialProperties(SharedProperties::stone)
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
@ -450,11 +464,13 @@ public class AllBlocks {
public static final BlockEntry<FluidTankBlock> FLUID_TANK = REGISTRATE.block("fluid_tank", FluidTankBlock::new)
.initialProperties(SharedProperties::softMetal)
.blockstate(BlockStateGen.tank())
.properties(Block.Properties::nonOpaque)
.blockstate(new FluidTankGenerator()::generate)
.onRegister(CreateRegistrate.blockModel(() -> FluidTankModel::new))
.addLayer(() -> RenderType::getCutoutMipped)
.item()
.transform(customItemModel())
.item(FluidTankItem::new)
.model(AssetLookup.<FluidTankItem>customItemModel("_", "block_single_window"))
.build()
.register();
// Contraptions
@ -525,7 +541,7 @@ public class AllBlocks {
public static final BlockEntry<CartAssemblerBlock> CART_ASSEMBLER =
REGISTRATE.block("cart_assembler", CartAssemblerBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.blockstate(BlockStateGen.cartAssembler())
.addLayer(() -> RenderType::getCutoutMipped)
.tag(BlockTags.RAILS)
@ -536,7 +552,7 @@ public class AllBlocks {
public static final BlockEntry<ReinforcedRailBlock> REINFORCED_RAIL =
REGISTRATE.block("reinforced_rail", ReinforcedRailBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.blockstate(BlockStateGen.reinforcedRail())
.addLayer(() -> RenderType::getCutoutMipped)
.tag(BlockTags.RAILS)
@ -663,7 +679,7 @@ public class AllBlocks {
public static final BlockEntry<MechanicalCrafterBlock> MECHANICAL_CRAFTER =
REGISTRATE.block("mechanical_crafter", MechanicalCrafterBlock::new)
.initialProperties(SharedProperties::softMetal)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.blockstate(BlockStateGen.horizontalBlockProvider(true))
.transform(StressConfigDefaults.setImpact(2.0))
.onRegister(CreateRegistrate.connectedTextures(new CrafterCTBehaviour()))
@ -675,7 +691,7 @@ public class AllBlocks {
public static final BlockEntry<SequencedGearshiftBlock> SEQUENCED_GEARSHIFT =
REGISTRATE.block("sequenced_gearshift", SequencedGearshiftBlock::new)
.initialProperties(SharedProperties::stone)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.transform(StressConfigDefaults.setNoImpact())
.blockstate(new SequencedGearshiftGenerator()::generate)
.item()
@ -684,7 +700,7 @@ public class AllBlocks {
public static final BlockEntry<FlywheelBlock> FLYWHEEL = REGISTRATE.block("flywheel", FlywheelBlock::new)
.initialProperties(SharedProperties::softMetal)
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.transform(StressConfigDefaults.setNoImpact())
.blockstate(new FlywheelGenerator()::generate)
.item()
@ -835,7 +851,7 @@ public class AllBlocks {
public static final BlockEntry<PackagerBlock> PACKAGER = REGISTRATE.block("packager", PackagerBlock::new)
.initialProperties(SharedProperties::softMetal)
.transform(StressConfigDefaults.setImpact(4.0))
.properties(p -> p.nonOpaque())
.properties(Block.Properties::nonOpaque)
.blockstate((c, p) -> p.getVariantBuilder(c.get())
.forAllStates(s -> ConfiguredModel.builder()
.modelFile(AssetLookup.partialBaseModel(c, p))

View File

@ -20,6 +20,7 @@ import com.simibubi.create.content.contraptions.wrench.WrenchItem;
import com.simibubi.create.content.contraptions.wrench.WrenchModel;
import com.simibubi.create.content.curiosities.ChromaticCompoundColor;
import com.simibubi.create.content.curiosities.ChromaticCompoundItem;
import com.simibubi.create.content.curiosities.CombustibleItem;
import com.simibubi.create.content.curiosities.RefinedRadianceItem;
import com.simibubi.create.content.curiosities.ShadowSteelItem;
import com.simibubi.create.content.curiosities.TreeFertilizerItem;
@ -175,6 +176,10 @@ public class AllItems {
REGISTRATE.item("tree_fertilizer", TreeFertilizerItem::new)
.register();
public static final ItemEntry<CombustibleItem> FUEL_PELLET = REGISTRATE.item("fuel_pellet", CombustibleItem::new)
// .onRegister(item -> item.setBurnTime(2048))
.register();
public static final ItemEntry<BlockzapperItem> BLOCKZAPPER =
REGISTRATE.item("handheld_blockzapper", BlockzapperItem::new)
.transform(CreateRegistrate.customRenderedItem(() -> BlockzapperModel::new))

View File

@ -3,11 +3,15 @@ package com.simibubi.create;
import java.util.function.Supplier;
import com.simibubi.create.content.contraptions.particle.AirFlowParticleData;
import com.simibubi.create.content.contraptions.particle.CubeParticle;
import com.simibubi.create.content.contraptions.particle.CubeParticleData;
import com.simibubi.create.content.contraptions.particle.HeaterParticleData;
import com.simibubi.create.content.contraptions.particle.ICustomParticle;
import com.simibubi.create.content.contraptions.particle.RotationIndicatorParticleData;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.client.Minecraft;
import net.minecraft.client.particle.IParticleFactory;
import net.minecraft.client.particle.ParticleManager;
import net.minecraft.particles.IParticleData;
import net.minecraft.particles.ParticleType;
@ -22,14 +26,22 @@ public enum AllParticleTypes {
ROTATION_INDICATOR(RotationIndicatorParticleData::new),
AIR_FLOW(AirFlowParticleData::new),
HEATER_PARTICLE(HeaterParticleData::new),
CUBE(CubeParticleData::dummy, () -> CubeParticle.Factory::new)
;
private ParticleEntry<?> entry;
private <D extends IParticleData> AllParticleTypes(Supplier<? extends ICustomParticle<D>> typeFactory) {
<D extends IParticleData> AllParticleTypes(Supplier<? extends ICustomParticle<D>> typeFactory) {
String asId = Lang.asId(this.name());
entry = new ParticleEntry<D>(new ResourceLocation(Create.ID, asId), typeFactory);
entry = new ParticleEntry<>(new ResourceLocation(Create.ID, asId), typeFactory);
}
<D extends IParticleData> AllParticleTypes(Supplier<? extends ICustomParticle<D>> typeFactory,
Supplier<Supplier<IParticleFactory<D>>> particleMetaFactory) {
String asId = Lang.asId(this.name());
entry = new ParticleEntry<>(new ResourceLocation(Create.ID, asId), typeFactory, particleMetaFactory);
}
public static void register(RegistryEvent.Register<ParticleType<?>> event) {
@ -40,26 +52,33 @@ public enum AllParticleTypes {
@OnlyIn(Dist.CLIENT)
public static void registerFactories(ParticleFactoryRegisterEvent event) {
ParticleManager particles = Minecraft.getInstance().particles;
for (AllParticleTypes particle : values())
for (AllParticleTypes particle : values())
particle.entry.registerFactory(particles);
}
public ParticleType<?> get() {
return entry.getType();
}
public String parameter() {
return Lang.asId(name());
}
private class ParticleEntry<D extends IParticleData> {
Supplier<? extends ICustomParticle<D>> typeFactory;
Supplier<Supplier<IParticleFactory<D>>> particleMetaFactory;
ParticleType<D> type;
ResourceLocation id;
public ParticleEntry(ResourceLocation id, Supplier<? extends ICustomParticle<D>> typeFactory) {
public ParticleEntry(ResourceLocation id, Supplier<? extends ICustomParticle<D>> typeFactory,
Supplier<Supplier<IParticleFactory<D>>> particleMetaFactory) {
this.id = id;
this.typeFactory = typeFactory;
this.particleMetaFactory = particleMetaFactory;
}
public ParticleEntry(ResourceLocation id, Supplier<? extends ICustomParticle<D>> typeFactory) {
this(id, typeFactory, null);
}
ParticleType<?> getType() {
@ -74,7 +93,8 @@ public enum AllParticleTypes {
void makeType() {
if (type == null) {
type = typeFactory.get().createType();
type = typeFactory.get()
.createType();
type.setRegistryName(id);
}
}
@ -82,7 +102,11 @@ public enum AllParticleTypes {
@OnlyIn(Dist.CLIENT)
void registerFactory(ParticleManager particles) {
makeType();
particles.registerFactory(type, typeFactory.get().getFactory());
if (particleMetaFactory == null)
particles.registerFactory(type, typeFactory.get()
.getFactory());
else
particles.registerFactory(type, particleMetaFactory.get().get());
}
}

View File

@ -1,7 +1,5 @@
package com.simibubi.create;
import java.util.function.Supplier;
import com.simibubi.create.compat.jei.ConversionRecipe;
import com.simibubi.create.content.contraptions.components.crafter.MechanicalCraftingRecipe;
import com.simibubi.create.content.contraptions.components.crusher.CrushingRecipe;
@ -12,11 +10,11 @@ import com.simibubi.create.content.contraptions.components.press.PressingRecipe;
import com.simibubi.create.content.contraptions.components.saw.CuttingRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipeSerializer;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipeSerializer.IExtendedRecipeFactory;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipeSerializer.IRecipeFactory;
import com.simibubi.create.content.curiosities.tools.SandPaperPolishingRecipe;
import com.simibubi.create.content.curiosities.zapper.blockzapper.BlockzapperUpgradeRecipe;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.IRecipeSerializer;
@ -26,18 +24,20 @@ import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;
import net.minecraftforge.event.RegistryEvent;
import java.util.function.Supplier;
public enum AllRecipeTypes {
BLOCKZAPPER_UPGRADE(BlockzapperUpgradeRecipe.Serializer::new, IRecipeType.CRAFTING),
MECHANICAL_CRAFTING(MechanicalCraftingRecipe.Serializer::new),
CRUSHING(processingSerializer(CrushingRecipe::new)),
MILLING(processingSerializer(MillingRecipe::new)),
SPLASHING(processingSerializer(SplashingRecipe::new)),
PRESSING(processingSerializer(PressingRecipe::new)),
CUTTING(processingSerializer(CuttingRecipe::new)),
MIXING(processingSerializer(MixingRecipe::new)),
SANDPAPER_POLISHING(processingSerializer(SandPaperPolishingRecipe::new)),
CONVERSION(processingSerializer(ConversionRecipe::new)),
CRUSHING(processingSerializer(CrushingRecipe::new)),
CUTTING(processingSerializer(CuttingRecipe::new)),
MECHANICAL_CRAFTING(MechanicalCraftingRecipe.Serializer::new),
MILLING(processingSerializer(MillingRecipe::new)),
MIXING(extendedProcessingSerializer(MixingRecipe::new)),
PRESSING(processingSerializer(PressingRecipe::new)),
SANDPAPER_POLISHING(processingSerializer(SandPaperPolishingRecipe::new)),
SPLASHING(processingSerializer(SplashingRecipe::new)),
;
@ -45,34 +45,30 @@ public enum AllRecipeTypes {
public Supplier<IRecipeSerializer<?>> supplier;
public IRecipeType<? extends IRecipe<? extends IInventory>> type;
@SuppressWarnings("unchecked")
public <T extends IRecipeType<?>> T getType() {
return (T) type;
}
private AllRecipeTypes(Supplier<IRecipeSerializer<?>> supplier) {
AllRecipeTypes(Supplier<IRecipeSerializer<?>> supplier) {
this(supplier, null);
}
private AllRecipeTypes(Supplier<IRecipeSerializer<?>> supplier,
IRecipeType<? extends IRecipe<? extends IInventory>> existingType) {
AllRecipeTypes(Supplier<IRecipeSerializer<?>> supplier,
IRecipeType<? extends IRecipe<? extends IInventory>> existingType) {
this.supplier = supplier;
this.type = existingType;
}
public static void register(RegistryEvent.Register<IRecipeSerializer<?>> event) {
ShapedRecipe.setCraftingSize(9, 9);
for (AllRecipeTypes r : AllRecipeTypes.values()) {
if (r.type == null)
r.type = customType(Lang.asId(r.name()));
r.serializer = r.supplier.get();
ResourceLocation location = new ResourceLocation(Create.ID, Lang.asId(r.name()));
event.getRegistry().register(r.serializer.setRegistryName(location));
event.getRegistry()
.register(r.serializer.setRegistryName(location));
}
}
private static <T extends IRecipe<?>> IRecipeType<T> customType(String id) {
return Registry.register(Registry.RECIPE_TYPE, new ResourceLocation(Create.ID, id), new IRecipeType<T>() {
public String toString() {
@ -80,10 +76,19 @@ public enum AllRecipeTypes {
}
});
}
private static Supplier<IRecipeSerializer<?>> processingSerializer(IRecipeFactory<? extends ProcessingRecipe<?>> factory) {
private static Supplier<IRecipeSerializer<?>> processingSerializer(
IRecipeFactory<? extends ProcessingRecipe<?>> factory) {
return () -> new ProcessingRecipeSerializer<>(factory);
}
private static Supplier<IRecipeSerializer<?>> extendedProcessingSerializer(
IExtendedRecipeFactory<? extends ProcessingRecipe<?>> factory) {
return () -> new ProcessingRecipeSerializer<>(factory);
}
@SuppressWarnings("unchecked")
public <T extends IRecipeType<?>> T getType() {
return (T) type;
}
}

View File

@ -113,7 +113,10 @@ public class AllShapes {
BASIN_BLOCK_SHAPE = shape(0, 2, 0, 16, 13, 16).erase(2, 5, 2, 14, 14, 14)
.add(2, 0, 2, 14, 2, 14)
.build(),
.build(), HEATER_BLOCK_SHAPE =
shape(2, 0, 2, 14, 14, 14).add(0, 0, 0, 16, 4, 16)
.build(),
HEATER_BLOCK_SPECIAL_COLLISION_SHAPE = shape(0, 0, 0, 16, 4, 16).build(),
CRUSHING_WHEEL_COLLISION_SHAPE = cuboid(0, 0, 0, 16, 22, 16),
SEAT = cuboid(0, 0, 0, 16, 8, 16),
SEAT_COLLISION = cuboid(0, 0, 0, 16, 6, 16),

View File

@ -9,6 +9,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.data.DataGenerator;
import net.minecraft.data.DirectoryCache;
import net.minecraft.data.IDataProvider;
import net.minecraft.util.ResourceLocation;
@ -19,8 +20,8 @@ import net.minecraftforge.registries.IForgeRegistry;
public enum AllSoundEvents implements IDataProvider {
CUCKOO_PIG("creeperclock"),
CUCKOO_CREEPER("pigclock"),
CUCKOO_PIG("pigclock"),
CUCKOO_CREEPER("creeperclock"),
SCHEMATICANNON_LAUNCH_BLOCK(SoundEvents.ENTITY_GENERIC_EXPLODE),
SCHEMATICANNON_FINISH(SoundEvents.BLOCK_NOTE_BLOCK_BELL),
@ -31,11 +32,13 @@ public enum AllSoundEvents implements IDataProvider {
BLOCKZAPPER_CONFIRM(SoundEvents.BLOCK_NOTE_BLOCK_BELL),
BLOCKZAPPER_DENY(SoundEvents.BLOCK_NOTE_BLOCK_BASS),
BLOCK_FUNNEL_EAT(SoundEvents.ENTITY_GENERIC_EAT),
BLAZE_MUNCH(SoundEvents.ENTITY_GENERIC_EAT)
;
String id;
SoundEvent event, child;
private DataGenerator generator;
// For adding our own sounds at assets/create/sounds/name.ogg
AllSoundEvents() {
@ -62,6 +65,11 @@ public enum AllSoundEvents implements IDataProvider {
return id;
}
public AllSoundEvents generator(DataGenerator generator){
this.generator = generator;
return this;
}
public static void register(RegistryEvent.Register<SoundEvent> event) {
IForgeRegistry<SoundEvent> registry = event.getRegistry();
@ -107,7 +115,7 @@ public enum AllSoundEvents implements IDataProvider {
@Override
public void act(DirectoryCache cache) throws IOException {
generate(generator.getOutputFolder(), cache);
}
@Override

View File

@ -48,10 +48,12 @@ public class AllSpriteShifts {
public static final CTSpriteShiftEntry
BRASS_TUNNEL_TOP = vertical("brass_tunnel_top"),
FLUID_TANK = getCT(CTType.OMNIDIRECTIONAL, "fluid_tank");
FLUID_TANK = getCT(CTType.CROSS, "fluid_tank");
public static final SpriteShiftEntry
BELT = SpriteShifter.get("block/belt", "block/belt_animated"),
BELT_OFFSET = SpriteShifter.get("block/belt_offset", "block/belt_animated"),
BELT_DIAGONAL = SpriteShifter.get("block/belt_diagonal", "block/belt_diagonal_animated"),
ANDESIDE_BELT_CASING = SpriteShifter.get("block/brass_casing_belt", "block/andesite_casing_belt"),
CRAFTER_THINGIES = SpriteShifter.get("block/crafter_thingies", "block/crafter_thingies");

View File

@ -12,6 +12,7 @@ import com.tterrag.registrate.util.nullness.NonNullFunction;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@ -88,28 +89,53 @@ public class AllTags {
}
public static enum AllBlockTags {
WINDMILL_SAILS, FAN_HEATERS, WINDOWABLE, NON_MOVABLE, BRITTLE
WINDMILL_SAILS, FAN_HEATERS, WINDOWABLE, NON_MOVABLE, BRITTLE, FAN_TRANSPARENT
;
public Tag<Block> tag;
private AllBlockTags() {
this("");
this(MOD, "");
}
private AllBlockTags(String path) {
private AllBlockTags(NameSpace namespace) {
this(namespace, "");
}
private AllBlockTags(NameSpace namespace, String path) {
tag = new BlockTags.Wrapper(
new ResourceLocation(Create.ID, (path.isEmpty() ? "" : path + "/") + Lang.asId(name())));
new ResourceLocation(namespace.id, (path.isEmpty() ? "" : path + "/") + Lang.asId(name())));
}
public boolean matches(BlockState block) {
return tag.contains(block.getBlock());
}
public void includeIn(AllBlockTags parent) {
REGISTRATE.addDataGenerator(ProviderType.BLOCK_TAGS, prov -> prov.getBuilder(parent.tag)
.add(tag));
}
public void includeAll(Tag<Block> child) {
REGISTRATE.addDataGenerator(ProviderType.BLOCK_TAGS, prov -> prov.getBuilder(tag).add(child));
}
public void add(Block ...values) {
REGISTRATE.addDataGenerator(ProviderType.BLOCK_TAGS, prov -> prov.getBuilder(tag).add(values));
}
}
public static void register() {
AllItemTags.CREATE_INGOTS.includeIn(AllItemTags.BEACON_PAYMENT);
AllItemTags.CREATE_INGOTS.includeIn(AllItemTags.INGOTS);
AllBlockTags.BRITTLE.includeAll(BlockTags.DOORS);
AllBlockTags.BRITTLE.add(Blocks.FLOWER_POT, Blocks.BELL);
AllBlockTags.FAN_TRANSPARENT.includeAll(BlockTags.FENCES);
AllBlockTags.FAN_TRANSPARENT.add(Blocks.IRON_BARS);
AllBlockTags.FAN_HEATERS.add(Blocks.MAGMA_BLOCK, Blocks.CAMPFIRE, Blocks.LAVA, Blocks.FIRE);
}
}

View File

@ -49,8 +49,7 @@ import com.simibubi.create.content.contraptions.fluids.FluidTankRenderer;
import com.simibubi.create.content.contraptions.fluids.FluidTankTileEntity;
import com.simibubi.create.content.contraptions.fluids.PumpRenderer;
import com.simibubi.create.content.contraptions.fluids.PumpTileEntity;
import com.simibubi.create.content.contraptions.processing.BasinRenderer;
import com.simibubi.create.content.contraptions.processing.BasinTileEntity;
import com.simibubi.create.content.contraptions.processing.*;
import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerRenderer;
import com.simibubi.create.content.contraptions.relays.advanced.SpeedControllerTileEntity;
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftTileEntity;
@ -201,6 +200,8 @@ public class AllTileEntities {
register("deployer", DeployerTileEntity::new, AllBlocks.DEPLOYER);
public static final TileEntityEntry<BasinTileEntity> BASIN =
register("basin", BasinTileEntity::new, AllBlocks.BASIN);
public static final TileEntityEntry<HeaterTileEntity> HEATER =
register("blaze_heater", HeaterTileEntity::new, AllBlocks.HEATER);
public static final TileEntityEntry<MechanicalCrafterTileEntity> MECHANICAL_CRAFTER =
register("mechanical_crafter", MechanicalCrafterTileEntity::new, AllBlocks.MECHANICAL_CRAFTER);
public static final TileEntityEntry<SequencedGearshiftTileEntity> SEQUENCED_GEARSHIFT =
@ -300,6 +301,7 @@ public class AllTileEntities {
bind(SPEEDOMETER, GaugeRenderer::speed);
bind(STRESSOMETER, GaugeRenderer::stress);
bind(BASIN, BasinRenderer::new);
bind(HEATER, HeaterRenderer::new);
bind(DEPLOYER, DeployerRenderer::new);
bind(FLYWHEEL, FlywheelRenderer::new);
bind(FURNACE_ENGINE, EngineRenderer::new);

View File

@ -109,6 +109,7 @@ public class Create {
DataGenerator gen = event.getGenerator();
gen.addProvider(new AllAdvancements(gen));
gen.addProvider(new LangMerger(gen));
gen.addProvider(AllSoundEvents.BLAZE_MUNCH.generator(gen));
}
}

View File

@ -1,8 +1,10 @@
package com.simibubi.create.compat.jei;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.processing.ProcessingIngredient;
@ -21,23 +23,25 @@ import net.minecraftforge.items.wrapper.RecipeWrapper;
* @author simibubi
*
*/
@ParametersAreNonnullByDefault
public class ConversionRecipe extends ProcessingRecipe<RecipeWrapper> {
public ConversionRecipe(ResourceLocation id, String group, List<ProcessingIngredient> ingredients,
List<ProcessingOutput> results, int processingDuration) {
List<ProcessingOutput> results, int processingDuration) {
super(AllRecipeTypes.CONVERSION, id, group, ingredients, results, processingDuration);
}
static int counter = 0;
public static ConversionRecipe create(ItemStack from, ItemStack to) {
List<ProcessingIngredient> ingredients = Arrays.asList(new ProcessingIngredient(Ingredient.fromStacks(from)));
List<ProcessingOutput> outputs = Arrays.asList(new ProcessingOutput(to, 1));
List<ProcessingIngredient> ingredients =
Collections.singletonList(new ProcessingIngredient(Ingredient.fromStacks(from)));
List<ProcessingOutput> outputs = Collections.singletonList(new ProcessingOutput(to, 1));
return new ConversionRecipe(new ResourceLocation(Create.ID, "conversion_" + counter++), ingredients, outputs);
}
public ConversionRecipe(ResourceLocation id, List<ProcessingIngredient> ingredients,
List<ProcessingOutput> results) {
List<ProcessingOutput> results) {
this(id, "conversions", ingredients, results, -1);
}

View File

@ -162,6 +162,7 @@ public class CreateJEI implements IModPlugin {
registration.addRecipeCatalyst(new ItemStack(AllItems.BLOCKZAPPER.get()), blockzapperCategory.getUid());
registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_MIXER.get()), mixingCategory.getUid());
registration.addRecipeCatalyst(new ItemStack(AllBlocks.BASIN.get()), mixingCategory.getUid());
registration.addRecipeCatalyst(new ItemStack(AllBlocks.HEATER.get()), mixingCategory.getUid());
registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_SAW.get()), sawingCategory.getUid());
registration.addRecipeCatalyst(new ItemStack(AllBlocks.MECHANICAL_SAW.get()), blockCuttingCategory.getUid());
registration.addRecipeCatalyst(new ItemStack(Blocks.STONECUTTER), blockCuttingCategory.getUid());

View File

@ -59,10 +59,10 @@ public abstract class CreateRecipeCategory<T extends IRecipe<?>> implements IRec
if (!(recipe instanceof ProcessingRecipe))
return jeiSlot;
ProcessingRecipe<?> processingRecipe = (ProcessingRecipe<?>) recipe;
List<ProcessingOutput> rollableResults = processingRecipe.getRollableResults();
List<ProcessingOutput> rollableResults = processingRecipe.getRollableItemResults();
if (rollableResults.size() <= index)
return jeiSlot;
if (processingRecipe.getRollableResults().get(index).getChance() == 1)
if (processingRecipe.getRollableItemResults().get(index).getChance() == 1)
return jeiSlot;
return AllGuiTextures.JEI_CHANCE_SLOT;
}

View File

@ -41,7 +41,7 @@ public class CrushingCategory extends CreateRecipeCategory<AbstractCrushingRecip
itemStacks.init(0, true, 50, 2);
itemStacks.set(0, Arrays.asList(recipe.getIngredients().get(0).getMatchingStacks()));
List<ProcessingOutput> results = recipe.getRollableResults();
List<ProcessingOutput> results = recipe.getRollableItemResults();
int size = results.size();
int offset = -size * 19 / 2;
for (int outputIndex = 0; outputIndex < size; outputIndex++) {
@ -54,7 +54,7 @@ public class CrushingCategory extends CreateRecipeCategory<AbstractCrushingRecip
@Override
public void draw(AbstractCrushingRecipe recipe, double mouseX, double mouseY) {
List<ProcessingOutput> results = recipe.getRollableResults();
List<ProcessingOutput> results = recipe.getRollableItemResults();
AllGuiTextures.JEI_SLOT.draw(50, 2);
AllGuiTextures.JEI_DOWN_ARROW.draw(72, 7);

View File

@ -43,7 +43,7 @@ public class MillingCategory extends CreateRecipeCategory<AbstractCrushingRecipe
.get(0)
.getMatchingStacks()));
List<ProcessingOutput> results = recipe.getRollableResults();
List<ProcessingOutput> results = recipe.getRollableItemResults();
boolean single = results.size() == 1;
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++) {
int xOffset = outputIndex % 2 == 0 ? 0 : 19;

View File

@ -10,6 +10,7 @@ import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.compat.jei.category.animations.AnimatedBlazeHeater;
import com.simibubi.create.compat.jei.category.animations.AnimatedMixer;
import com.simibubi.create.content.contraptions.components.mixer.MixingRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingIngredient;
@ -27,10 +28,11 @@ import net.minecraft.util.NonNullList;
public class MixingCategory extends CreateRecipeCategory<MixingRecipe> {
private AnimatedMixer mixer = new AnimatedMixer();
private AnimatedBlazeHeater heater = new AnimatedBlazeHeater();
public MixingCategory() {
super("mixing", doubleItemIcon(AllBlocks.MECHANICAL_MIXER.get(), AllBlocks.BASIN.get()),
emptyBackground(177, 70));
emptyBackground(177, 110));
}
@Override
@ -54,8 +56,9 @@ public class MixingCategory extends CreateRecipeCategory<MixingRecipe> {
Map<Integer, Float> catalystIndices = new HashMap<>(9);
for (int i = 0; i < actualIngredients.size(); i++) {
for (ProcessingIngredient processingIngredient : recipe.getRollableIngredients()) {
if (processingIngredient.isCatalyst() && ItemHelper
.matchIngredients(processingIngredient.getIngredient(), actualIngredients.get(i).getKey())) {
if (processingIngredient.isCatalyst()
&& ItemHelper.matchIngredients(processingIngredient.getIngredient(), actualIngredients.get(i)
.getKey())) {
catalystIndices.put(i, processingIngredient.getOutputChance());
break;
}
@ -65,20 +68,26 @@ public class MixingCategory extends CreateRecipeCategory<MixingRecipe> {
int size = actualIngredients.size();
int xOffset = size < 3 ? (3 - size) * 19 / 2 : 0;
int i = 0;
int yOffset = recipe.getHeatLevelRequired() > 0 ? 30 : 10;
while (i < size) {
Pair<Ingredient, MutableInt> ingredient = actualIngredients.get(i);
itemStacks.init(i, true, 16 + xOffset + (i % 3) * 19, 50 - (i / 3) * 19);
List<ItemStack> asList = Arrays.asList(ingredient.getKey().getMatchingStacks());
itemStacks.set(i, asList.stream().map(stack -> {
stack = stack.copy();
stack.setCount(ingredient.getRight().getValue());
return stack;
}).collect(Collectors.toList()));
itemStacks.init(i, true, 16 + xOffset + (i % 3) * 19, 50 - (i / 3) * 19 + yOffset);
List<ItemStack> asList = Arrays.asList(ingredient.getKey()
.getMatchingStacks());
itemStacks.set(i, asList.stream()
.map(stack -> {
stack = stack.copy();
stack.setCount(ingredient.getRight()
.getValue());
return stack;
})
.collect(Collectors.toList()));
i++;
}
itemStacks.init(i, false, 141, 50);
itemStacks.set(i, recipe.getRecipeOutput().getStack());
itemStacks.init(i, false, 141, 50 + yOffset);
itemStacks.set(i, recipe.getRecipeOutput()
.getStack());
addCatalystTooltip(itemStacks, catalystIndices);
}
@ -89,21 +98,25 @@ public class MixingCategory extends CreateRecipeCategory<MixingRecipe> {
int size = actualIngredients.size();
int xOffset = size < 3 ? (3 - size) * 19 / 2 : 0;
int yOffset = recipe.getHeatLevelRequired() > 0 ? 30 : 10;
for (int i = 0; i < size; i++) {
AllGuiTextures jeiSlot = AllGuiTextures.JEI_SLOT;
for (ProcessingIngredient processingIngredient : recipe.getRollableIngredients()) {
if (processingIngredient.isCatalyst() && ItemHelper
.matchIngredients(processingIngredient.getIngredient(), actualIngredients.get(i).getKey())) {
if (processingIngredient.isCatalyst()
&& ItemHelper.matchIngredients(processingIngredient.getIngredient(), actualIngredients.get(i)
.getKey())) {
jeiSlot = AllGuiTextures.JEI_CATALYST_SLOT;
break;
}
}
jeiSlot.draw(16 + xOffset + (i % 3) * 19, 50 - (i / 3) * 19);
jeiSlot.draw(16 + xOffset + (i % 3) * 19, 50 - (i / 3) * 19 + yOffset);
}
AllGuiTextures.JEI_SLOT.draw(141, 50);
AllGuiTextures.JEI_DOWN_ARROW.draw(136, 32);
AllGuiTextures.JEI_SHADOW.draw(81, 57);
mixer.draw(getBackground().getWidth() / 2 + 3, 25);
AllGuiTextures.JEI_SLOT.draw(141, 50 + yOffset);
AllGuiTextures.JEI_DOWN_ARROW.draw(136, 32 + yOffset);
AllGuiTextures.JEI_SHADOW.draw(81, 57 + yOffset);
if (recipe.getHeatLevelRequired() > 0)
heater.drawWithHeatLevel(getBackground().getWidth() / 2 + 3, 55, recipe.getHeatLevelRequired());
mixer.draw(getBackground().getWidth() / 2 + 3, 34);
}
}

View File

@ -41,7 +41,7 @@ public class MysteriousItemConversionCategory extends CreateRecipeCategory<Conve
@Override
public void setRecipe(IRecipeLayout recipeLayout, ConversionRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
List<ProcessingOutput> results = recipe.getRollableResults();
List<ProcessingOutput> results = recipe.getRollableItemResults();
itemStacks.init(0, true, 26, 16);
itemStacks.set(0, Arrays.asList(recipe.getIngredients().get(0).getMatchingStacks()));
itemStacks.init(1, false, 131, 16);

View File

@ -43,7 +43,7 @@ public class PolishingCategory extends CreateRecipeCategory<SandPaperPolishingRe
@Override
public void setRecipe(IRecipeLayout recipeLayout, SandPaperPolishingRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
List<ProcessingOutput> results = recipe.getRollableResults();
List<ProcessingOutput> results = recipe.getRollableItemResults();
itemStacks.init(0, true, 26, 28);
itemStacks.set(0, Arrays.asList(recipe.getIngredients().get(0).getMatchingStacks()));

View File

@ -41,7 +41,7 @@ public class PressingCategory extends CreateRecipeCategory<PressingRecipe> {
itemStacks.init(0, true, 26, 50);
itemStacks.set(0, Arrays.asList(recipe.getIngredients().get(0).getMatchingStacks()));
List<ProcessingOutput> results = recipe.getRollableResults();
List<ProcessingOutput> results = recipe.getRollableItemResults();
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++) {
itemStacks.init(outputIndex + 1, false, 131 + 19 * outputIndex, 50);
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
@ -54,7 +54,7 @@ public class PressingCategory extends CreateRecipeCategory<PressingRecipe> {
public void draw(PressingRecipe recipe, double mouseX, double mouseY) {
AllGuiTextures.JEI_SLOT.draw(26, 50);
getRenderedSlot(recipe, 0).draw(131, 50);
if (recipe.getRollableResults().size() > 1)
if (recipe.getRollableItemResults().size() > 1)
getRenderedSlot(recipe, 1).draw(131 + 19, 50);
AllGuiTextures.JEI_SHADOW.draw(61, 41);
AllGuiTextures.JEI_LONG_ARROW.draw(52, 54);

View File

@ -40,7 +40,7 @@ public class SawingCategory extends CreateRecipeCategory<CuttingRecipe> {
itemStacks.init(0, true, 43, 4);
itemStacks.set(0, Arrays.asList(recipe.getIngredients().get(0).getMatchingStacks()));
List<ProcessingOutput> results = recipe.getRollableResults();
List<ProcessingOutput> results = recipe.getRollableItemResults();
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++) {
int xOffset = outputIndex % 2 == 0 ? 0 : 19;
int yOffset = (outputIndex / 2) * -19;
@ -55,7 +55,7 @@ public class SawingCategory extends CreateRecipeCategory<CuttingRecipe> {
@Override
public void draw(CuttingRecipe recipe, double mouseX, double mouseY) {
AllGuiTextures.JEI_SLOT.draw(43, 4);
int size = recipe.getRollableResults().size();
int size = recipe.getRollableItemResults().size();
for (int i = 0; i < size; i++) {
int xOffset = i % 2 == 0 ? 0 : 19;
int yOffset = (i / 2) * -19;

View File

@ -42,7 +42,7 @@ public class SplashingCategory extends ProcessingViaFanCategory<SplashingRecipe>
.get(0)
.getMatchingStacks()));
List<ProcessingOutput> results = recipe.getRollableResults();
List<ProcessingOutput> results = recipe.getRollableItemResults();
boolean single = results.size() == 1;
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++) {
int xOffset = outputIndex % 2 == 0 ? 0 : 19;

View File

@ -0,0 +1,57 @@
package com.simibubi.create.compat.jei.category.animations;
import java.util.HashMap;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.gui.GuiGameElement;
import mezz.jei.api.gui.drawable.IDrawable;
public class AnimatedBlazeHeater implements IDrawable {
private static final HashMap<Integer, AllBlockPartials> blazeModelMap = new HashMap<>();
public AnimatedBlazeHeater() {
super();
blazeModelMap.put(2, AllBlockPartials.BLAZE_HEATER_BLAZE_TWO);
blazeModelMap.put(3, AllBlockPartials.BLAZE_HEATER_BLAZE_THREE);
blazeModelMap.put(4, AllBlockPartials.BLAZE_HEATER_BLAZE_FOUR);
}
@Override
public void draw(int xOffset, int yOffset) {
drawWithHeatLevel(xOffset, yOffset, 3);
}
public void drawWithHeatLevel(int xOffset, int yOffset, int heatLevel) {
RenderSystem.pushMatrix();
RenderSystem.translatef(xOffset, yOffset, 200);
RenderSystem.rotatef(-15.5f, 1, 0, 0);
RenderSystem.rotatef(22.5f, 0, 1, 0);
int scale = 23;
GuiGameElement.of(AllBlocks.HEATER.getDefaultState())
.atLocal(0, 1.65, 0)
.scale(scale)
.render();
GuiGameElement.of(blazeModelMap.getOrDefault(heatLevel, AllBlockPartials.BLAZE_HEATER_BLAZE_ONE))
.atLocal(1, 1.65, 1)
.rotate(0, 180, 0)
.scale(scale)
.render();
RenderSystem.popMatrix();
}
@Override
public int getWidth() {
return 50;
}
@Override
public int getHeight() {
return 50;
}
}

View File

@ -13,7 +13,7 @@ import net.minecraftforge.items.wrapper.RecipeWrapper;
public abstract class AbstractCrushingRecipe extends ProcessingRecipe<RecipeWrapper> {
public AbstractCrushingRecipe(AllRecipeTypes recipeType, ResourceLocation id, String group,
List<ProcessingIngredient> ingredients, List<ProcessingOutput> results, int processingDuration) {
List<ProcessingIngredient> ingredients, List<ProcessingOutput> results, int processingDuration) {
super(recipeType, id, group, ingredients, results, processingDuration);
}

View File

@ -1,19 +1,20 @@
package com.simibubi.create.content.contraptions.components.crusher;
import java.util.List;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.content.contraptions.processing.ProcessingIngredient;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.items.wrapper.RecipeWrapper;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
@ParametersAreNonnullByDefault
public class CrushingRecipe extends AbstractCrushingRecipe {
public CrushingRecipe(ResourceLocation id, String group, List<ProcessingIngredient> ingredients,
List<ProcessingOutput> results, int processingDuration) {
List<ProcessingOutput> results, int processingDuration) {
super(AllRecipeTypes.CRUSHING, id, group, ingredients, results, processingDuration);
}
@ -21,9 +22,10 @@ public class CrushingRecipe extends AbstractCrushingRecipe {
public boolean matches(RecipeWrapper inv, World worldIn) {
if (inv.isEmpty())
return false;
return ingredients.get(0).test(inv.getStackInSlot(0));
return ingredients.get(0)
.test(inv.getStackInSlot(0));
}
@Override
protected int getMaxOutputCount() {
return 7;

View File

@ -191,7 +191,7 @@ public class CrushingWheelControllerTileEntity extends SmartTileEntity {
inventory.clear();
for (int roll = 0; roll < rolls; roll++) {
List<ItemStack> rolledResults = recipe.get()
.rollResults();
.rollResults().getItemStacks();
for (int i = 0; i < rolledResults.size(); i++) {
ItemStack stack = rolledResults.get(i);
ItemHelper.addToList(stack, list);

View File

@ -108,11 +108,14 @@ public class DeployerFakePlayer extends FakePlayer {
if (trueSource != null && trueSource instanceof DeployerFakePlayer) {
DeployerFakePlayer fakePlayer = (DeployerFakePlayer) trueSource;
event.getDrops()
.forEach(stack -> fakePlayer.inventory.placeItemBackInInventory(trueSource.world, stack.getItem()));
.forEach(stack -> fakePlayer.inventory.placeItemBackInInventory(trueSource.world, stack.getItem()));
event.setCanceled(true);
}
}
@Override
protected void playEquipSound(ItemStack p_184606_1_) {}
@Override
public void remove(boolean keepData) {
if (blockBreakingProgress != null && !world.isRemote)
@ -156,13 +159,11 @@ public class DeployerFakePlayer extends FakePlayer {
}
@Override
public void sendPacket(IPacket<?> packetIn) {
}
public void sendPacket(IPacket<?> packetIn) {}
@Override
public void sendPacket(IPacket<?> packetIn,
GenericFutureListener<? extends Future<? super Void>> futureListeners) {
}
GenericFutureListener<? extends Future<? super Void>> futureListeners) {}
}
}

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.simibubi.create.AllTags;
import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.content.contraptions.particle.AirFlowParticleData;
@ -304,11 +305,7 @@ public class AirCurrent {
}
private static boolean shouldAlwaysPass(BlockState state) {
if (state.isIn(Tags.Blocks.FENCES))
return true;
if (state.getBlock() == Blocks.IRON_BARS)
return true;
return false;
return AllTags.AllBlockTags.FAN_TRANSPARENT.matches(state);
}
public InWorldProcessing.Type getSegmentAt(float offset) {

View File

@ -2,10 +2,11 @@ package com.simibubi.create.content.contraptions.components.fan;
import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity;
import com.simibubi.create.content.contraptions.processing.HeaterBlock;
import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.config.CKinetics;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
@ -72,9 +73,20 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
}
public boolean blockBelowIsHot() {
return world.getBlockState(pos.down())
.getBlock()
.isIn(AllBlockTags.FAN_HEATERS.tag);
if (world == null)
return false;
BlockState checkState = world.getBlockState(pos.down());
if (!checkState.getBlock().isIn(AllBlockTags.FAN_HEATERS.tag))
return false;
if (checkState.has(HeaterBlock.BLAZE_LEVEL) && !checkState.get(HeaterBlock.BLAZE_LEVEL).min(HeaterBlock.HeatLevel.FADING))
return false;
if (checkState.has(BlockStateProperties.LIT) && !checkState.get(BlockStateProperties.LIT))
return false;
return true;
}
public float getMaxDistance() {

View File

@ -1,21 +1,22 @@
package com.simibubi.create.content.contraptions.components.fan;
import java.util.List;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.content.contraptions.processing.ProcessingIngredient;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
import com.simibubi.create.content.logistics.InWorldProcessing;
import com.simibubi.create.content.logistics.InWorldProcessing.SplashingInv;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
@ParametersAreNonnullByDefault
public class SplashingRecipe extends ProcessingRecipe<InWorldProcessing.SplashingInv> {
public SplashingRecipe(ResourceLocation id, String group, List<ProcessingIngredient> ingredients,
List<ProcessingOutput> results, int processingDuration) {
List<ProcessingOutput> results, int processingDuration) {
super(AllRecipeTypes.SPLASHING, id, group, ingredients, results, processingDuration);
}
@ -23,9 +24,10 @@ public class SplashingRecipe extends ProcessingRecipe<InWorldProcessing.Splashin
public boolean matches(SplashingInv inv, World worldIn) {
if (inv.isEmpty())
return false;
return ingredients.get(0).test(inv.getStackInSlot(0));
return ingredients.get(0)
.test(inv.getStackInSlot(0));
}
@Override
protected int getMaxOutputCount() {
return 6;

View File

@ -1,20 +1,21 @@
package com.simibubi.create.content.contraptions.components.millstone;
import java.util.List;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.content.contraptions.components.crusher.AbstractCrushingRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingIngredient;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.items.wrapper.RecipeWrapper;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
@ParametersAreNonnullByDefault
public class MillingRecipe extends AbstractCrushingRecipe {
public MillingRecipe(ResourceLocation id, String group, List<ProcessingIngredient> ingredients,
List<ProcessingOutput> results, int processingDuration) {
List<ProcessingOutput> results, int processingDuration) {
super(AllRecipeTypes.MILLING, id, group, ingredients, results, processingDuration);
}
@ -22,12 +23,12 @@ public class MillingRecipe extends AbstractCrushingRecipe {
public boolean matches(RecipeWrapper inv, World worldIn) {
if (inv.isEmpty())
return false;
return ingredients.get(0).test(inv.getStackInSlot(0));
return ingredients.get(0)
.test(inv.getStackInSlot(0));
}
@Override
protected int getMaxOutputCount() {
return 4;
}
}

View File

@ -94,7 +94,7 @@ public class MillstoneTileEntity extends KineticTileEntity {
ItemStack stackInSlot = inputInv.getStackInSlot(0);
stackInSlot.shrink(1);
inputInv.setStackInSlot(0, stackInSlot);
lastRecipe.rollResults().forEach(stack -> ItemHandlerHelper.insertItemStacked(outputInv, stack, false));
lastRecipe.rollResults().forEachItemStack(stack -> ItemHandlerHelper.insertItemStacked(outputInv, stack, false));
sendData();
markDirty();
}

View File

@ -1,20 +1,24 @@
package com.simibubi.create.content.contraptions.components.mixer;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity;
import com.simibubi.create.content.contraptions.fluids.CombinedFluidHandler;
import com.simibubi.create.content.contraptions.processing.BasinOperatingTileEntity;
import com.simibubi.create.content.contraptions.processing.BasinTileEntity.BasinInventory;
import com.simibubi.create.content.contraptions.processing.CombinedItemFluidList;
import com.simibubi.create.content.contraptions.processing.HeaterBlock;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.CenteredSideValueBoxTransform;
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueBehaviour;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
@ -31,6 +35,8 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.items.IItemHandler;
import static com.simibubi.create.content.contraptions.processing.HeaterBlock.getHeaterLevel;
public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
private static final Object shapelessOrMixingRecipesKey = new Object();
@ -65,7 +71,7 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
}
public float getRenderedHeadOffset(float partialTicks) {
int localTick = 0;
int localTick;
float offset = 0;
if (running) {
if (runningTicks < 20) {
@ -121,7 +127,7 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
@Override
public void lazyTick() {
super.lazyTick();
if (world.isRemote && running && !basinItemInv.isPresent())
if (world != null && world.isRemote && running && !basinItemInv.isPresent())
updateBasin();
}
@ -163,7 +169,7 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
public void renderParticles() {
IItemHandler itemHandler = basinItemInv.orElse(null);
BasinInventory inv = (BasinInventory) itemHandler;
if (inv == null)
if (inv == null || world == null)
return;
for (int slot = 0; slot < inv.getInputHandler()
@ -204,14 +210,16 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
.allMatch(ingredient -> (ingredient.isSimple() || ingredient.getMatchingStacks().length == 1)))
return false;
List<ItemStack> remaining = new ArrayList<>();
CombinedItemFluidList remaining = new CombinedItemFluidList();
inputs.forEachItemStack(stack -> remaining.add(stack.copy()));
basinFluidInv.ifPresent(
fluidInv -> ((CombinedFluidHandler) fluidInv).forEachTank(fluidStack -> remaining.add(fluidStack.copy())));
// sort by leniency
List<Ingredient> sortedIngredients = new LinkedList<>(ingredients);
sortedIngredients.sort(Comparator.comparingInt(i -> i.getMatchingStacks().length));
Ingredients: for (Ingredient ingredient : sortedIngredients) {
for (ItemStack stack : remaining) {
for (ItemStack stack : remaining.getItemStacks()) {
if (stack.isEmpty())
continue;
if (ingredient.test(stack)) {
@ -221,7 +229,10 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
}
return false;
}
return true;
if (!(recipe instanceof MixingRecipe))
return true;
return ((MixingRecipe) recipe).getHeatLevelRequired() <= getHeatLevelApplied().ordinal();
}
@Override
@ -258,4 +269,12 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
return running;
}
private HeaterBlock.HeatLevel getHeatLevelApplied() {
if (world == null)
return HeaterBlock.HeatLevel.NONE;
BlockState state = world.getBlockState(pos.down(3));
if (state.has(HeaterBlock.BLAZE_LEVEL))
return state.get(HeaterBlock.BLAZE_LEVEL);
return AllTags.AllBlockTags.FAN_HEATERS.matches(state) ? HeaterBlock.HeatLevel.SMOULDERING : HeaterBlock.HeatLevel.NONE;
}
}

View File

@ -1,52 +1,58 @@
package com.simibubi.create.content.contraptions.components.mixer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.content.contraptions.processing.BasinTileEntity.BasinInputInventory;
import com.simibubi.create.content.contraptions.processing.ProcessingIngredient;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.item.crafting.Ingredient;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nonnull;
import java.util.*;
public class MixingRecipe extends ProcessingRecipe<BasinInputInventory> {
public MixingRecipe(ResourceLocation id, String group, List<ProcessingIngredient> ingredients,
List<ProcessingOutput> results, int processingDuration) {
super(AllRecipeTypes.MIXING, id, group, ingredients, results, processingDuration);
List<ProcessingOutput> results, int processingDuration, List<FluidStack> fluidIngredients,
List<FluidStack> fluidResults, int requiredHeat) {
super(AllRecipeTypes.MIXING, id, group, ingredients, results, processingDuration, fluidIngredients,
fluidResults, requiredHeat);
}
public static MixingRecipe of(IRecipe<?> recipe) {
return new MixingRecipe(recipe.getId(), recipe.getGroup(), ProcessingIngredient.list(recipe.getIngredients()),
Collections.singletonList(new ProcessingOutput(recipe.getRecipeOutput(), 1)), -1, null, null, 0);
}
@Override
protected int getMaxInputCount() {
return 9;
}
@Override
protected int getMaxOutputCount() {
return 1;
}
@Override
protected boolean canHaveCatalysts() {
return true;
}
@Override
public boolean matches(BasinInputInventory inv, World worldIn) {
public boolean matches(BasinInputInventory inv, @Nonnull World worldIn) {
if (inv.isEmpty())
return false;
NonNullList<Ingredient> ingredients = getIngredients();
if (!ingredients.stream().allMatch(Ingredient::isSimple))
NonNullList<Ingredient> ingredients = this.getIngredients();
if (!ingredients.stream()
.allMatch(Ingredient::isSimple))
return false;
List<ItemStack> remaining = new ArrayList<>();
@ -59,7 +65,7 @@ public class MixingRecipe extends ProcessingRecipe<BasinInputInventory> {
// sort by leniency
List<Ingredient> sortedIngredients = new LinkedList<>(ingredients);
sortedIngredients.sort((i1, i2) -> i1.getMatchingStacks().length - i2.getMatchingStacks().length);
sortedIngredients.sort(Comparator.comparingInt(i -> i.getMatchingStacks().length));
Ingredients: for (Ingredient ingredient : sortedIngredients) {
for (ItemStack stack : remaining) {
if (stack.isEmpty())
@ -74,9 +80,22 @@ public class MixingRecipe extends ProcessingRecipe<BasinInputInventory> {
return true;
}
public static MixingRecipe of(IRecipe<?> recipe) {
return new MixingRecipe(recipe.getId(), recipe.getGroup(), ProcessingIngredient.list(recipe.getIngredients()),
Arrays.asList(new ProcessingOutput(recipe.getRecipeOutput(), 1)), -1);
@Override
protected boolean canHaveFluidIngredient() {
return true;
}
@Override
protected boolean canHaveFluidOutput() {
return true;
}
@Override
protected boolean requiresHeating() {
return this.requiredHeat > 0;
}
public int getHeatLevelRequired() {
return requiredHeat;
}
}

View File

@ -6,8 +6,10 @@ import java.util.Optional;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.content.contraptions.fluids.CombinedFluidHandler;
import com.simibubi.create.content.contraptions.processing.BasinOperatingTileEntity;
import com.simibubi.create.content.contraptions.processing.BasinTileEntity.BasinInventory;
import com.simibubi.create.content.contraptions.processing.CombinedItemFluidList;
import com.simibubi.create.content.logistics.InWorldProcessing;
import com.simibubi.create.foundation.advancement.AllTriggers;
import com.simibubi.create.foundation.item.ItemHelper;
@ -297,11 +299,12 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
.allMatch(Ingredient::isSimple))
return false;
List<ItemStack> remaining = new ArrayList<>();
CombinedItemFluidList remaining = new CombinedItemFluidList();
inputs.forEachItemStack(stack -> remaining.add(stack.copy()));
basinFluidInv.ifPresent(fluidInv -> ((CombinedFluidHandler) fluidInv).forEachTank(fluidStack -> remaining.add(fluidStack.copy())));
Ingredients: for (Ingredient ingredient : ingredients) {
for (ItemStack stack : remaining) {
for (ItemStack stack : remaining.getItemStacks()) {
if (stack.isEmpty())
continue;
if (ingredient.test(stack)) {

View File

@ -1,20 +1,21 @@
package com.simibubi.create.content.contraptions.components.press;
import java.util.List;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity.PressingInv;
import com.simibubi.create.content.contraptions.processing.ProcessingIngredient;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
@ParametersAreNonnullByDefault
public class PressingRecipe extends ProcessingRecipe<MechanicalPressTileEntity.PressingInv> {
public PressingRecipe(ResourceLocation id, String group, List<ProcessingIngredient> ingredients,
List<ProcessingOutput> results, int processingDuration) {
List<ProcessingOutput> results, int processingDuration) {
super(AllRecipeTypes.PRESSING, id, group, ingredients, results, processingDuration);
}
@ -22,12 +23,12 @@ public class PressingRecipe extends ProcessingRecipe<MechanicalPressTileEntity.P
public boolean matches(PressingInv inv, World worldIn) {
if (inv.isEmpty())
return false;
return ingredients.get(0).test(inv.getStackInSlot(0));
return ingredients.get(0)
.test(inv.getStackInSlot(0));
}
@Override
protected int getMaxOutputCount() {
return 2;
}
}

View File

@ -1,20 +1,21 @@
package com.simibubi.create.content.contraptions.components.saw;
import java.util.List;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.content.contraptions.processing.ProcessingIngredient;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.items.wrapper.RecipeWrapper;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
@ParametersAreNonnullByDefault
public class CuttingRecipe extends ProcessingRecipe<RecipeWrapper> {
public CuttingRecipe(ResourceLocation id, String group, List<ProcessingIngredient> ingredients,
List<ProcessingOutput> results, int processingDuration) {
List<ProcessingOutput> results, int processingDuration) {
super(AllRecipeTypes.CUTTING, id, group, ingredients, results, processingDuration);
}
@ -22,9 +23,10 @@ public class CuttingRecipe extends ProcessingRecipe<RecipeWrapper> {
public boolean matches(RecipeWrapper inv, World worldIn) {
if (inv.isEmpty())
return false;
return ingredients.get(0).test(inv.getStackInSlot(0));
return ingredients.get(0)
.test(inv.getStackInSlot(0));
}
@Override
protected int getMaxOutputCount() {
return 4;

View File

@ -248,7 +248,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
for (int roll = 0; roll < rolls; roll++) {
List<ItemStack> results = new LinkedList<ItemStack>();
if (recipe instanceof CuttingRecipe)
results = ((CuttingRecipe) recipe).rollResults();
results = ((CuttingRecipe) recipe).rollResults().getItemStacks();
else if (recipe instanceof StonecuttingRecipe)
results.add(recipe.getRecipeOutput()
.copy());

View File

@ -1,140 +1,194 @@
package com.simibubi.create.content.contraptions.fluids;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.fluid.FluidHelper;
import com.simibubi.create.foundation.fluid.FluidHelper.FluidExchange;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.block.SoundType;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.Fluid;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.particles.BlockParticleData;
import net.minecraft.particles.ParticleTypes;
import net.minecraft.state.BooleanProperty;
import net.minecraft.state.EnumProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tags.FluidTags;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.ILightReader;
import net.minecraft.world.IWorld;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
public class FluidTankBlock extends Block {
public class FluidTankBlock extends Block implements IWrenchable, ITE<FluidTankTileEntity> {
public static final BooleanProperty TOP = BooleanProperty.create("top");
public static final BooleanProperty BOTTOM = BooleanProperty.create("bottom");
public static final EnumProperty<Shape> SHAPE = EnumProperty.create("shape", Shape.class);
public FluidTankBlock(Properties p_i48440_1_) {
super(p_i48440_1_);
setDefaultState(getDefaultState().with(TOP, true)
.with(BOTTOM, true));
}
public static boolean shouldDrawDiagonalFiller(ILightReader world, BlockPos pos, BlockState state, boolean north,
boolean east) {
if (!isTank(state))
return false;
int northOffset = north ? 1 : -1;
int eastOffset = east ? 1 : -1;
if (!isTank(world.getBlockState(pos.north(northOffset))))
return false;
if (!isTank(world.getBlockState(pos.east(eastOffset))))
return false;
return !isTank(world.getBlockState(pos.east(eastOffset)
.north(northOffset)));
}
public static boolean shouldDrawCapFiller(ILightReader world, BlockPos pos, BlockState state, Direction direction,
boolean top) {
if (!isTank(state))
return false;
if (top && !state.get(TOP))
return false;
if (!top && !state.get(BOTTOM))
return false;
BlockPos adjacentPos = pos.offset(direction);
BlockState adjacentState = world.getBlockState(adjacentPos);
if (!isTank(adjacentState))
return false;
if (top && adjacentState.get(TOP))
return false;
return top || !adjacentState.get(BOTTOM);
.with(BOTTOM, true)
.with(SHAPE, Shape.WINDOW));
}
public static boolean isTank(BlockState state) {
return state.getBlock() instanceof FluidTankBlock;
}
@Override
public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState oldState, boolean p_220082_5_) {
if (oldState.getBlock() == state.getBlock())
return;
withTileEntityDo(world, pos, FluidTankTileEntity::updateConnectivity);
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> p_206840_1_) {
p_206840_1_.add(TOP, BOTTOM);
p_206840_1_.add(TOP, BOTTOM, SHAPE);
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext p_196258_1_) {
World world = p_196258_1_.getWorld();
BlockPos pos = p_196258_1_.getPos();
BlockState state = super.getStateForPlacement(p_196258_1_);
state = updateState(state, world, pos, Direction.UP);
state = updateState(state, world, pos, Direction.DOWN);
return state;
}
private boolean isTankToDirection(IBlockReader world, BlockPos pos, Direction direction) {
return world.getBlockState(pos.offset(direction)).getBlock() instanceof FluidTankBlock;
}
public AxisAlignedBB getTankShape(IBlockReader world, BlockPos pos) {
return new AxisAlignedBB((isTankToDirection(world, pos, Direction.WEST) ? 0 : 2) / 16f,
(isTankToDirection(world, pos, Direction.DOWN) ? 0 : 4) / 16f,
(isTankToDirection(world, pos, Direction.NORTH) ? 0 : 2) / 16f,
(isTankToDirection(world, pos, Direction.EAST) ? 16 : 14) / 16f,
(isTankToDirection(world, pos, Direction.UP) ? 16 : 12) / 16f,
(isTankToDirection(world, pos, Direction.SOUTH) ? 16 : 14) / 16f);
}
public AxisAlignedBB getBodyShape(IBlockReader world, BlockPos pos) {
return new AxisAlignedBB((isTankToDirection(world, pos, Direction.WEST) ? 0 : 1) / 16f,
0,
(isTankToDirection(world, pos, Direction.NORTH) ? 0 : 1) / 16f,
(isTankToDirection(world, pos, Direction.EAST) ? 16 : 15) / 16f,
1,
(isTankToDirection(world, pos, Direction.SOUTH) ? 16 : 15) / 16f);
public int getLightValue(BlockState state, IBlockReader world, BlockPos pos) {
FluidTankTileEntity tankAt = FluidTankConnectivityHandler.tankAt(world, pos);
if (tankAt == null)
return 0;
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
if (controllerTE == null || !controllerTE.window)
return 0;
return tankAt.luminosity;
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos,
ISelectionContext p_220053_4_) {
boolean top = state.get(TOP);
boolean bottom = state.get(BOTTOM);
return VoxelShapes.or(top ? bottom ? AllShapes.TANK_TOP_BOTTOM : AllShapes.TANK_TOP
: bottom ? AllShapes.TANK_BOTTOM : AllShapes.TANK, VoxelShapes.create(getBodyShape(world, pos)));
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
withTileEntityDo(context.getWorld(), context.getPos(), FluidTankTileEntity::toggleWindows);
return ActionResultType.SUCCESS;
}
@Override
public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState p_196271_3_, IWorld world,
BlockPos pos, BlockPos p_196271_6_) {
return updateState(state, world, pos, direction);
}
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand,
BlockRayTraceResult ray) {
ItemStack heldItem = player.getHeldItem(hand);
private BlockState updateState(BlockState state, ILightReader reader, BlockPos pos, Direction direction) {
if (direction.getAxis()
.isHorizontal())
return state;
return state.with(direction == Direction.UP ? TOP : BOTTOM,
!AllBlocks.FLUID_TANK.has(reader.getBlockState(pos.offset(direction))));
}
ItemStack copy = heldItem.copy();
copy.setCount(1);
LazyOptional<IFluidHandlerItem> capability =
copy.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY);
if (!capability.isPresent())
return ActionResultType.PASS;
@Override
@OnlyIn(Dist.CLIENT)
public boolean isSideInvisible(BlockState state, BlockState adjacentBlockState, Direction side) {
return adjacentBlockState.getBlock() == this;
TileEntity te = world.getTileEntity(pos);
LazyOptional<IFluidHandler> tankCapability =
te.getCapability(CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY, ray.getFace());
if (!tankCapability.isPresent())
return ActionResultType.PASS;
boolean onClient = world.isRemote;
IFluidHandlerItem fluidItem = capability.orElse(null);
IFluidHandler fluidTank = tankCapability.orElse(null);
FluidStack prevFluidInTank = fluidTank.getFluidInTank(0)
.copy();
FluidExchange exchange = FluidHelper.exchange(fluidTank, fluidItem, FluidExchange.TANK_TO_ITEM, 1000);
FluidStack fluidInTank = fluidTank.getFluidInTank(0);
if (!player.isCreative() && !onClient) {
if (heldItem.getCount() > 1) {
heldItem.shrink(1);
player.addItemStackToInventory(fluidItem.getContainer());
} else {
player.setHeldItem(hand, fluidItem.getContainer());
}
}
SoundEvent soundevent = null;
BlockState fluidState = null;
if (exchange == FluidExchange.ITEM_TO_TANK) {
Fluid fluid = fluidInTank.getFluid();
fluidState = fluid.getDefaultState()
.getBlockState();
FluidAttributes attributes = fluid.getAttributes();
soundevent = attributes.getEmptySound();
if (soundevent == null)
soundevent =
fluid.isIn(FluidTags.LAVA) ? SoundEvents.ITEM_BUCKET_EMPTY_LAVA : SoundEvents.ITEM_BUCKET_EMPTY;
}
if (exchange == FluidExchange.TANK_TO_ITEM) {
Fluid fluid = prevFluidInTank.getFluid();
fluidState = fluid.getDefaultState()
.getBlockState();
soundevent = fluid.getAttributes()
.getFillSound();
if (soundevent == null)
soundevent =
fluid.isIn(FluidTags.LAVA) ? SoundEvents.ITEM_BUCKET_FILL_LAVA : SoundEvents.ITEM_BUCKET_FILL;
}
if (soundevent != null && !onClient) {
float pitch = MathHelper
.clamp(1 - (1f * fluidInTank.getAmount() / (FluidTankTileEntity.getCapacityMultiplier() * 16)), 0, 1);
pitch /= 1.5f;
pitch += .5f;
pitch += (world.rand.nextFloat() - .5f) / 4f;
world.playSound(null, pos, soundevent, SoundCategory.BLOCKS, .5f, pitch);
}
if (!fluidInTank.isFluidStackIdentical(prevFluidInTank)) {
if (te instanceof FluidTankTileEntity) {
FluidTankTileEntity controllerTE = ((FluidTankTileEntity) te).getControllerTE();
if (controllerTE != null) {
if (fluidState != null && onClient) {
BlockParticleData blockParticleData = new BlockParticleData(ParticleTypes.BLOCK, fluidState);
float level = (float) fluidInTank.getAmount() / fluidTank.getTankCapacity(0);
boolean reversed = fluidInTank.getFluid()
.getAttributes()
.isLighterThanAir();
if (reversed)
level = 1 - level;
Vec3d vec = ray.getHitVec();
vec = new Vec3d(vec.x, controllerTE.getPos()
.getY() + level * (controllerTE.height - .5f) + .25f, vec.z);
Vec3d motion = player.getPositionVec()
.subtract(vec)
.scale(1 / 20f);
vec = vec.add(motion);
world.addParticle(blockParticleData, vec.x, vec.y, vec.z, motion.x, motion.y, motion.z);
return ActionResultType.SUCCESS;
}
controllerTE.sendData();
controllerTE.markDirty();
}
}
}
return ActionResultType.SUCCESS;
}
@Override
@ -142,8 +196,48 @@ public class FluidTankBlock extends Block {
return true;
}
@Override
public void onReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean isMoving) {
if (state.hasTileEntity() && (state.getBlock() != newState.getBlock() || !newState.hasTileEntity())) {
TileEntity te = world.getTileEntity(pos);
if (!(te instanceof FluidTankTileEntity))
return;
FluidTankTileEntity tankTE = (FluidTankTileEntity) te;
world.removeTileEntity(pos);
FluidTankConnectivityHandler.splitTank(tankTE);
}
}
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return AllTileEntities.FLUID_TANK.create();
}
@Override
public Class<FluidTankTileEntity> getTileEntityClass() {
return FluidTankTileEntity.class;
}
public enum Shape implements IStringSerializable {
PLAIN, WINDOW, WINDOW_NW, WINDOW_SW, WINDOW_NE, WINDOW_SE;
@Override
public String getName() {
return Lang.asId(name());
}
}
// Tanks are less noisy when placed in batch
public static final SoundType SILENCED_METAL =
new SoundType(0.1F, 1.5F, SoundEvents.BLOCK_METAL_BREAK, SoundEvents.BLOCK_METAL_STEP,
SoundEvents.BLOCK_METAL_PLACE, SoundEvents.BLOCK_METAL_HIT, SoundEvents.BLOCK_METAL_FALL);
@Override
public SoundType getSoundType(BlockState state, IWorldReader world, BlockPos pos, Entity entity) {
SoundType soundType = super.getSoundType(state, world, pos, entity);
if (entity != null && entity.getPersistentData()
.contains("SilenceTankSound"))
return SILENCED_METAL;
return soundType;
}
}

View File

@ -13,8 +13,7 @@ public class FluidTankCTBehaviour extends HorizontalCTBehaviour {
public FluidTankCTBehaviour(CTSpriteShiftEntry layerShift, CTSpriteShiftEntry topShift) {
super(layerShift, topShift);
}
@Override
public boolean buildContextForOccludedDirections() {
return true;
}
@ -22,7 +21,6 @@ public class FluidTankCTBehaviour extends HorizontalCTBehaviour {
@Override
public boolean connectsTo(BlockState state, BlockState other, ILightReader reader, BlockPos pos, BlockPos otherPos,
Direction face) {
// TODO only if TEs are actually connected
return state.getBlock() == other.getBlock();
return state.getBlock() == other.getBlock() && FluidTankConnectivityHandler.isConnected(reader, pos, otherPos);
}
}

View File

@ -0,0 +1,347 @@
package com.simibubi.create.content.contraptions.fluids;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.PriorityQueue;
import java.util.Set;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
public class FluidTankConnectivityHandler {
public static void formTanks(FluidTankTileEntity te) {
TankSearchCache cache = new TankSearchCache();
List<FluidTankTileEntity> frontier = new ArrayList<>();
frontier.add(te);
formTanks(te.getWorld(), cache, frontier);
}
private static void formTanks(IBlockReader world, TankSearchCache cache, List<FluidTankTileEntity> frontier) {
PriorityQueue<Pair<Integer, FluidTankTileEntity>> creationQueue = makeCreationQueue();
Set<BlockPos> visited = new HashSet<>();
int minX = Integer.MAX_VALUE;
int minZ = Integer.MAX_VALUE;
for (FluidTankTileEntity fluidTankTileEntity : frontier) {
BlockPos pos = fluidTankTileEntity.getPos();
minX = Math.min(pos.getX(), minX);
minZ = Math.min(pos.getZ(), minZ);
}
minX -= FluidTankTileEntity.getMaxSize();
minZ -= FluidTankTileEntity.getMaxSize();
while (!frontier.isEmpty()) {
FluidTankTileEntity tank = frontier.remove(0);
BlockPos tankPos = tank.getPos();
if (visited.contains(tankPos))
continue;
visited.add(tankPos);
int amount = tryToFormNewTank(tank, cache, true);
if (amount > 1)
creationQueue.add(Pair.of(amount, tank));
for (Axis axis : Iterate.axes) {
Direction d = Direction.getFacingFromAxis(AxisDirection.NEGATIVE, axis);
BlockPos next = tankPos.offset(d);
if (next.getX() <= minX || next.getZ() <= minZ)
continue;
if (visited.contains(next))
continue;
FluidTankTileEntity nextTank = tankAt(world, next);
if (nextTank == null)
continue;
if (nextTank.isRemoved())
continue;
frontier.add(nextTank);
}
}
visited.clear();
while (!creationQueue.isEmpty()) {
Pair<Integer, FluidTankTileEntity> next = creationQueue.poll();
FluidTankTileEntity toCreate = next.getValue();
if (visited.contains(toCreate.getPos()))
continue;
visited.add(toCreate.getPos());
tryToFormNewTank(toCreate, cache, false);
}
}
public static void splitTank(FluidTankTileEntity te) {
splitTankAndInvalidate(te, null, false);
}
private static int tryToFormNewTank(FluidTankTileEntity te, TankSearchCache cache, boolean simulate) {
int bestWidth = 1;
int bestAmount = -1;
if (!te.isController())
return 0;
for (int w = 1; w <= FluidTankTileEntity.getMaxSize(); w++) {
int amount = tryToFormNewTankOfWidth(te, w, cache, true);
if (amount < bestAmount)
continue;
bestWidth = w;
bestAmount = amount;
}
if (!simulate) {
if (te.width == bestWidth && te.width * te.width * te.height == bestAmount)
return bestAmount;
splitTankAndInvalidate(te, cache, false);
te.applyFluidTankSize(bestAmount);
tryToFormNewTankOfWidth(te, bestWidth, cache, simulate);
te.updateConnectivity = false;
te.width = bestWidth;
te.height = bestAmount / bestWidth / bestWidth;
BlockState state = te.getBlockState();
if (FluidTankBlock.isTank(state)) {
state = state.with(FluidTankBlock.BOTTOM, true);
state = state.with(FluidTankBlock.TOP, te.height == 1);
te.getWorld()
.setBlockState(te.getPos(), state, 22);
}
te.setWindows(te.window);
te.onFluidStackChanged(te.tankInventory.getFluid());
te.markDirty();
}
return bestAmount;
}
private static int tryToFormNewTankOfWidth(FluidTankTileEntity te, int width, TankSearchCache cache,
boolean simulate) {
int amount = 0;
int height = 0;
World world = te.getWorld();
BlockPos origin = te.getPos();
FluidStack fluid = te.getTankInventory()
.getFluid();
Search:
for (int yOffset = 0; yOffset < FluidTankTileEntity.getMaxHeight(); yOffset++) {
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos pos = origin.add(xOffset, yOffset, zOffset);
Optional<FluidTankTileEntity> tank = cache.getOrCache(world, pos);
if (!tank.isPresent())
break Search;
FluidTankTileEntity controller = tank.get();
int otherWidth = controller.width;
if (otherWidth > width)
break Search;
BlockPos controllerPos = controller.getPos();
if (!controllerPos.equals(origin)) {
if (controllerPos.getX() < origin.getX())
break Search;
if (controllerPos.getZ() < origin.getZ())
break Search;
if (controllerPos.getX() + otherWidth > origin.getX() + width)
break Search;
if (controllerPos.getZ() + otherWidth > origin.getZ() + width)
break Search;
}
FluidStack otherFluid = controller.getTankInventory()
.getFluid();
if (!fluid.isEmpty() && !otherFluid.isEmpty() && !fluid.isFluidEqual(otherFluid))
break Search;
}
}
amount += width * width;
height++;
}
if (simulate)
return amount;
for (int yOffset = 0; yOffset < height; yOffset++) {
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos pos = origin.add(xOffset, yOffset, zOffset);
FluidTankTileEntity tank = tankAt(world, pos);
if (tank == te)
continue;
if (tank.isController()) {
te.tankInventory.fill(tank.tankInventory.getFluid(), FluidAction.EXECUTE);
tank.tankInventory.setFluid(FluidStack.EMPTY);
}
splitTankAndInvalidate(tank, cache, false);
tank.setController(origin);
tank.updateConnectivity = false;
cache.put(pos, te);
BlockState state = world.getBlockState(pos);
if (!FluidTankBlock.isTank(state))
continue;
state = state.with(FluidTankBlock.BOTTOM, yOffset == 0);
state = state.with(FluidTankBlock.TOP, yOffset == height - 1);
world.setBlockState(pos, state, 22);
}
}
}
return amount;
}
private static void splitTankAndInvalidate(FluidTankTileEntity te, @Nullable TankSearchCache cache,
boolean tryReconnect) {
// tryReconnect helps whenever only few tanks have been removed
te = te.getControllerTE();
if (te == null)
return;
int height = te.height;
int width = te.width;
if (width == 1 && height == 1)
return;
World world = te.getWorld();
BlockPos origin = te.getPos();
List<FluidTankTileEntity> frontier = new ArrayList<>();
FluidStack toDistribute = te.tankInventory.getFluid()
.copy();
int maxCapacity = FluidTankTileEntity.getCapacityMultiplier();
if (!toDistribute.isEmpty())
toDistribute.shrink(maxCapacity);
for (int yOffset = 0; yOffset < height; yOffset++) {
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos pos = origin.add(xOffset, yOffset, zOffset);
FluidTankTileEntity tankAt = tankAt(world, pos);
if (tankAt == null)
continue;
if (!tankAt.getController()
.equals(origin))
continue;
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
tankAt.window = controllerTE == null || controllerTE.window;
tankAt.removeController();
if (!toDistribute.isEmpty() && tankAt != te) {
int split = Math.min(maxCapacity, toDistribute.getAmount());
FluidStack copy = toDistribute.copy();
copy.setAmount(split);
toDistribute.shrink(split);
tankAt.tankInventory.fill(copy, FluidAction.EXECUTE);
}
if (tryReconnect) {
frontier.add(tankAt);
tankAt.updateConnectivity = false;
}
if (cache != null)
cache.put(pos, tankAt);
}
}
}
if (tryReconnect)
formTanks(world, cache == null ? new TankSearchCache() : cache, frontier);
}
private static PriorityQueue<Pair<Integer, FluidTankTileEntity>> makeCreationQueue() {
return new PriorityQueue<>(new Comparator<Pair<Integer, FluidTankTileEntity>>() {
@Override
public int compare(Pair<Integer, FluidTankTileEntity> o1, Pair<Integer, FluidTankTileEntity> o2) {
return o2.getKey() - o1.getKey();
}
});
}
@Nullable
public static FluidTankTileEntity tankAt(IBlockReader world, BlockPos pos) {
TileEntity te = world.getTileEntity(pos);
if (te instanceof FluidTankTileEntity)
return (FluidTankTileEntity) te;
return null;
}
private static class TankSearchCache {
Map<BlockPos, Optional<FluidTankTileEntity>> controllerMap;
public TankSearchCache() {
controllerMap = new HashMap<>();
}
void put(BlockPos pos, FluidTankTileEntity target) {
controllerMap.put(pos, Optional.of(target));
}
void putEmpty(BlockPos pos) {
controllerMap.put(pos, Optional.empty());
}
boolean hasVisited(BlockPos pos) {
return controllerMap.containsKey(pos);
}
Optional<FluidTankTileEntity> getOrCache(IBlockReader world, BlockPos pos) {
if (hasVisited(pos))
return controllerMap.get(pos);
FluidTankTileEntity tankAt = tankAt(world, pos);
if (tankAt == null) {
putEmpty(pos);
return Optional.empty();
}
FluidTankTileEntity controller = tankAt.getControllerTE();
if (controller == null) {
putEmpty(pos);
return Optional.empty();
}
put(pos, controller);
return Optional.of(controller);
}
}
public static boolean isConnected(IBlockReader world, BlockPos tankPos, BlockPos otherTankPos) {
TileEntity te1 = world.getTileEntity(tankPos);
TileEntity te2 = world.getTileEntity(otherTankPos);
if (!(te1 instanceof FluidTankTileEntity) || !(te2 instanceof FluidTankTileEntity))
return false;
return ((FluidTankTileEntity) te1).getController()
.equals(((FluidTankTileEntity) te2).getController());
}
}

View File

@ -0,0 +1,44 @@
package com.simibubi.create.content.contraptions.fluids;
import com.simibubi.create.content.contraptions.fluids.FluidTankBlock.Shape;
import com.simibubi.create.foundation.data.AssetLookup;
import com.simibubi.create.foundation.data.SpecialBlockStateGen;
import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraftforge.client.model.generators.ModelFile;
public class FluidTankGenerator extends SpecialBlockStateGen {
@Override
protected int getXRotation(BlockState state) {
return 0;
}
@Override
protected int getYRotation(BlockState state) {
return 0;
}
@Override
public <T extends Block> ModelFile getModel(DataGenContext<Block, T> ctx, RegistrateBlockstateProvider prov,
BlockState state) {
Boolean top = state.get(FluidTankBlock.TOP);
Boolean bottom = state.get(FluidTankBlock.BOTTOM);
Shape shape = state.get(FluidTankBlock.SHAPE);
String shapeName = "middle";
if (top && bottom)
shapeName = "single";
else if (top)
shapeName = "top";
else if (bottom)
shapeName = "bottom";
return AssetLookup.partialBaseModel(ctx, prov,
shapeName + (shape == Shape.PLAIN ? "" : "_" + shape.getName()));
}
}

View File

@ -0,0 +1,97 @@
package com.simibubi.create.content.contraptions.fluids;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class FluidTankItem extends BlockItem {
public FluidTankItem(Block p_i48527_1_, Properties p_i48527_2_) {
super(p_i48527_1_, p_i48527_2_);
}
@Override
public ActionResultType tryPlace(BlockItemUseContext ctx) {
ActionResultType initialResult = super.tryPlace(ctx);
if (initialResult != ActionResultType.SUCCESS)
return initialResult;
tryMultiPlace(ctx);
return initialResult;
}
private void tryMultiPlace(BlockItemUseContext ctx) {
PlayerEntity player = ctx.getPlayer();
if (player == null)
return;
if (player.isSneaking())
return;
Direction face = ctx.getFace();
if (!face.getAxis()
.isVertical())
return;
ItemStack stack = ctx.getItem();
World world = ctx.getWorld();
BlockPos pos = ctx.getPos();
BlockPos placedOnPos = pos.offset(face.getOpposite());
BlockState placedOnState = world.getBlockState(placedOnPos);
if (!FluidTankBlock.isTank(placedOnState))
return;
FluidTankTileEntity tankAt = FluidTankConnectivityHandler.tankAt(world, placedOnPos);
if (tankAt == null)
return;
FluidTankTileEntity controllerTE = tankAt.getControllerTE();
if (controllerTE == null)
return;
int width = controllerTE.width;
if (width == 1)
return;
int tanksToPlace = 0;
BlockPos startPos = face == Direction.DOWN ? controllerTE.getPos()
.down()
: controllerTE.getPos()
.up(controllerTE.height);
if (startPos.getY() != pos.getY())
return;
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos offsetPos = startPos.add(xOffset, 0, zOffset);
BlockState blockState = world.getBlockState(offsetPos);
if (FluidTankBlock.isTank(blockState))
continue;
if (!blockState.getMaterial()
.isReplaceable())
return;
tanksToPlace++;
}
}
if (!player.isCreative() && stack.getCount() < tanksToPlace)
return;
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos offsetPos = startPos.add(xOffset, 0, zOffset);
BlockState blockState = world.getBlockState(offsetPos);
if (FluidTankBlock.isTank(blockState))
continue;
BlockItemUseContext context = BlockItemUseContext.func_221536_a(ctx, offsetPos, face);
player.getPersistentData().putBoolean("SilenceTankSound", true);
super.tryPlace(context);
player.getPersistentData().remove("SilenceTankSound");
}
}
}
}

View File

@ -1,12 +1,11 @@
package com.simibubi.create.content.contraptions.fluids;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.AllSpriteShifts;
import com.simibubi.create.foundation.block.connected.CTModel;
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour;
@ -19,86 +18,63 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ILightReader;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelProperty;
public class FluidTankModel extends CTModel {
private static ModelProperty<TankModelData> TANK_PROPERTY = new ModelProperty<>();
private static ConnectedTextureBehaviour ctBehaviour =
protected static ModelProperty<CullData> CULL_PROPERTY = new ModelProperty<>();
static ConnectedTextureBehaviour CT_BEHAVIOUR =
new FluidTankCTBehaviour(AllSpriteShifts.FLUID_TANK, AllSpriteShifts.COPPER_CASING);
public FluidTankModel(IBakedModel model) {
super(model, ctBehaviour);
public FluidTankModel(IBakedModel originalModel) {
super(originalModel, CT_BEHAVIOUR);
}
@Override
public IModelData getModelData(ILightReader world, BlockPos pos, BlockState state, IModelData tileData) {
TankModelData data = new TankModelData();
for (boolean top : Iterate.trueAndFalse)
for (Direction d : Iterate.horizontalDirections)
data.setCapFiller(d, top, FluidTankBlock.shouldDrawCapFiller(world, pos, state, d, top));
for (boolean north : Iterate.trueAndFalse)
for (boolean east : Iterate.trueAndFalse)
data.setDiagonalFiller(north, east,
FluidTankBlock.shouldDrawDiagonalFiller(world, pos, state, north, east));
return new ModelDataMap.Builder().withInitial(CT_PROPERTY, createCTData(world, pos, state))
.withInitial(TANK_PROPERTY, data)
CullData cullData = new CullData();
for (Direction d : Iterate.horizontalDirections)
cullData.setCulled(d, FluidTankConnectivityHandler.isConnected(world, pos, pos.offset(d)));
return getCTDataMapBuilder(world, pos, state).withInitial(CULL_PROPERTY, cullData)
.build();
}
@Override
public List<BakedQuad> getQuads(BlockState state, Direction side, Random rand, IModelData data) {
List<BakedQuad> quads = super.getQuads(state, side, rand, data);
if (data instanceof ModelDataMap) {
ModelDataMap modelDataMap = (ModelDataMap) data;
if (modelDataMap.hasProperty(TANK_PROPERTY))
addQuads(quads, state, side, rand, modelDataMap, modelDataMap.getData(TANK_PROPERTY));
public List<BakedQuad> getQuads(BlockState state, Direction side, Random rand, IModelData extraData) {
if (side != null)
return Collections.emptyList();
List<BakedQuad> quads = new ArrayList<>();
for (Direction d : Iterate.directions) {
if (extraData.hasProperty(CULL_PROPERTY) && extraData.getData(CULL_PROPERTY)
.isCulled(d))
continue;
quads.addAll(super.getQuads(state, d, rand, extraData));
}
quads.addAll(super.getQuads(state, null, rand, extraData));
return quads;
}
private void addQuads(List<BakedQuad> quads, BlockState state, Direction side, Random rand, IModelData data,
TankModelData pipeData) {
for (boolean top : Iterate.trueAndFalse)
for (Direction d : Iterate.horizontalDirections)
if (pipeData.getCapFiller(d, top))
quads.addAll(AllBlockPartials.TANK_LID_FILLERS.get(Pair.of(top, d))
.get()
.getQuads(state, side, rand, data));
for (boolean north : Iterate.trueAndFalse)
for (boolean east : Iterate.trueAndFalse)
if (pipeData.getDiagonalFiller(north, east))
quads.addAll(AllBlockPartials.TANK_DIAGONAL_FILLERS.get(Pair.of(north, east))
.get()
.getQuads(state, side, rand, data));
}
private class CullData {
boolean[] culledFaces;
private class TankModelData {
boolean[] capFillers;
boolean[] diagonalFillers;
public TankModelData() {
capFillers = new boolean[2 * 4];
diagonalFillers = new boolean[2 * 2];
Arrays.fill(capFillers, false);
Arrays.fill(diagonalFillers, false);
public CullData() {
culledFaces = new boolean[4];
Arrays.fill(culledFaces, false);
}
public void setCapFiller(Direction face, boolean top, boolean filler) {
capFillers[(top ? 0 : 4) + face.getHorizontalIndex()] = filler;
void setCulled(Direction face, boolean cull) {
if (face.getAxis()
.isVertical())
return;
culledFaces[face.getHorizontalIndex()] = cull;
}
public void setDiagonalFiller(boolean north, boolean east, boolean filler) {
diagonalFillers[(north ? 0 : 2) + (east ? 0 : 1)] = filler;
}
public boolean getCapFiller(Direction face, boolean top) {
return capFillers[(top ? 0 : 4) + face.getHorizontalIndex()];
}
public boolean getDiagonalFiller(boolean north, boolean east) {
return diagonalFillers[(north ? 0 : 2) + (east ? 0 : 1)];
boolean isCulled(Direction face) {
if (face.getAxis()
.isVertical())
return false;
return culledFaces[face.getHorizontalIndex()];
}
}

View File

@ -1,216 +1,68 @@
package com.simibubi.create.content.contraptions.fluids;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.simibubi.create.foundation.fluid.FluidRenderer;
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.fluid.Fluid;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraftforge.fluids.IFluidTank;
import java.util.Collections;
import java.util.List;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.templates.FluidTank;
public class FluidTankRenderer extends SafeTileEntityRenderer<FluidTankTileEntity> {
public FluidTankRenderer(TileEntityRendererDispatcher dispatcher) {
super(dispatcher);
}
public FluidTankRenderer(TileEntityRendererDispatcher dispatcher) {
super(dispatcher);
}
private static int[] decomposeColor(int color) {
int[] res = new int[4];
res[0] = color >> 24 & 0xff;
res[1] = color >> 16 & 0xff;
res[2] = color >> 8 & 0xff;
res[3] = color & 0xff;
return res;
}
@Override
protected void renderSafe(FluidTankTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) {
if (!te.isController())
return;
if (!te.window)
return;
@Override
protected void renderSafe(FluidTankTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) {
renderFluid(te, ms, buffer, light);
}
InterpolatedChasingValue fluidLevel = te.fluidLevel;
if (fluidLevel == null)
return;
private void renderFluid(FluidTankTileEntity te, MatrixStack ms, IRenderTypeBuffer buffer,
int light) {
if (te.getWorld() != null && te.getWorld().isAreaLoaded(te.getPos(), 0)) {
IVertexBuilder builder = buffer.getBuffer(RenderType.getTranslucent());
float capHeight = 1 / 4f;
float tankHullWidth = 1 / 16f + 1 / 128f;
float minPuddleHeight = 1 / 16f;
float totalHeight = te.height - 2 * capHeight - minPuddleHeight;
Matrix4f posMat = ms.peek().getModel();
for (FluidTankRenderInfo tankRenderInfo : getTanksToRender(te)) {
doRender(builder, tankRenderInfo, posMat, light);
}
}
}
float level = fluidLevel.get(partialTicks);
if (level < 1 / (512f * totalHeight))
return;
float clamp = MathHelper.clamp(level * totalHeight, 0, totalHeight);
private void doRender(IVertexBuilder builder, FluidTankRenderInfo tankRenderInfo, Matrix4f posMat, int combinedLight) {
IFluidTank tank = tankRenderInfo.getTank();
if (tank.getFluidAmount() == 0) return;
FluidTank tank = te.tankInventory;
FluidStack fluidStack = tank.getFluid();
Fluid fluid = tank.getFluid().getFluid();
ResourceLocation texture = fluid.getAttributes().getStillTexture(tank.getFluid());
boolean top = fluidStack.getFluid()
.getAttributes()
.isLighterThanAir();
@SuppressWarnings("deprecation")
TextureAtlasSprite still = Minecraft.getInstance().getSpriteAtlas(AtlasTexture.LOCATION_BLOCKS_TEXTURE).apply(texture);
int[] cols = decomposeColor(fluid.getAttributes().getColor(tank.getFluid()));
float xMin = tankHullWidth;
float xMax = xMin + te.width - 2 * tankHullWidth;
float yMin = totalHeight + capHeight + minPuddleHeight - clamp;
float yMax = yMin + clamp;
AxisAlignedBB bounds = getRenderBounds(tank, tankRenderInfo.getBounds());
float x1 = (float) bounds.minX;
float x2 = (float) bounds.maxX;
float y1 = (float) bounds.minY;
float y2 = (float) bounds.maxY;
float z1 = (float) bounds.minZ;
float z2 = (float) bounds.maxZ;
double bx1 = bounds.minX * 16;
double bx2 = bounds.maxX * 16;
double by1 = bounds.minY * 16;
double by2 = bounds.maxY * 16;
double bz1 = bounds.minZ * 16;
double bz2 = bounds.maxZ * 16;
if (top) {
yMin += totalHeight - clamp;
yMax += totalHeight - clamp;
}
if (tankRenderInfo.shouldRender(Direction.DOWN)) {
float u1 = still.getInterpolatedU(bx1);
float u2 = still.getInterpolatedU(bx2);
float v1 = still.getInterpolatedV(bz1);
float v2 = still.getInterpolatedV(bz2);
renderDown(builder, posMat, combinedLight, cols, x1, y1, z1, z2, u1, v1, v2);
renderDown(builder, posMat, combinedLight, cols, x2, y1, z2, z1, u2, v2, v1);
}
float zMin = tankHullWidth;
float zMax = zMin + te.width - 2 * tankHullWidth;
if (tankRenderInfo.shouldRender(Direction.UP)) {
float u1 = still.getInterpolatedU(bx1);
float u2 = still.getInterpolatedU(bx2);
float v1 = still.getInterpolatedV(bz1);
float v2 = still.getInterpolatedV(bz2);
renderUp(builder, posMat, combinedLight, cols, x2, x1, y2, z2, u2, u1, v2);
renderUp(builder, posMat, combinedLight, cols, x1, x2, y2, z1, u1, u2, v1);
}
ms.push();
ms.translate(0, clamp - totalHeight, 0);
FluidRenderer.renderTiledFluidBB(fluidStack, xMin, yMin, zMin, xMax, yMax, zMax, buffer, ms, light, false);
ms.pop();
}
if (tankRenderInfo.shouldRender(Direction.NORTH)) {
float u1 = still.getInterpolatedU(bx1);
float u2 = still.getInterpolatedU(bx2);
float v1 = still.getInterpolatedV(by1);
float v2 = still.getInterpolatedV(by2);
renderNorth(builder, posMat, combinedLight, cols, x1, y1, y2, z1, u1, v1, v2);
renderNorth(builder, posMat, combinedLight, cols, x2, y2, y1, z1, u2, v2, v1);
}
if (tankRenderInfo.shouldRender(Direction.SOUTH)) {
float u1 = still.getInterpolatedU(bx1);
float u2 = still.getInterpolatedU(bx2);
float v1 = still.getInterpolatedV(by1);
float v2 = still.getInterpolatedV(by2);
renderSouth(builder, posMat, combinedLight, cols, x2, y1, y2, z2, u2, v1, v2);
renderSouth(builder, posMat, combinedLight, cols, x1, y2, y1, z2, u1, v2, v1);
}
if (tankRenderInfo.shouldRender(Direction.WEST)) {
float u1 = still.getInterpolatedU(by1);
float u2 = still.getInterpolatedU(by2);
float v1 = still.getInterpolatedV(bz1);
float v2 = still.getInterpolatedV(bz2);
renderWest(builder, posMat, combinedLight, cols, x1, y1, y2, z2, u1, u2, v2);
renderWest(builder, posMat, combinedLight, cols, x1, y2, y1, z1, u2, u1, v1);
}
if (tankRenderInfo.shouldRender(Direction.EAST)) {
float u1 = still.getInterpolatedU(by1);
float u2 = still.getInterpolatedU(by2);
float v1 = still.getInterpolatedV(bz1);
float v2 = still.getInterpolatedV(bz2);
renderEast(builder, posMat, combinedLight, cols, x2, y1, y2, z1, u1, u2, v1);
renderEast(builder, posMat, combinedLight, cols, x2, y2, y1, z2, u2, u1, v2);
}
}
private void renderEast(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x2, float y1, float y2, float z1, float u1, float u2, float v1) {
builder.vertex(posMat, x2, y1, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v1).light(combinedLight).normal(1f, 0f, 0f).endVertex();
builder.vertex(posMat, x2, y2, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u2, v1).light(combinedLight).normal(1f, 0f, 0f).endVertex();
}
private void renderWest(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x1, float y1, float y2, float z2, float u1, float u2, float v2) {
builder.vertex(posMat, x1, y1, z2).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v2).light(combinedLight).normal(-1f, 0f, 0f).endVertex();
builder.vertex(posMat, x1, y2, z2).color(cols[1], cols[2], cols[3], cols[0]).texture(u2, v2).light(combinedLight).normal(-1f, 0f, 0f).endVertex();
}
private void renderSouth(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x2, float y1, float y2, float z2, float u2, float v1, float v2) {
builder.vertex(posMat, x2, y1, z2).color(cols[1], cols[2], cols[3], cols[0]).texture(u2, v1).light(combinedLight).normal(0f, 0f, 1f).endVertex();
builder.vertex(posMat, x2, y2, z2).color(cols[1], cols[2], cols[3], cols[0]).texture(u2, v2).light(combinedLight).normal(0f, 0f, 1f).endVertex();
}
private void renderNorth(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x1, float y1, float y2, float z1, float u1, float v1, float v2) {
builder.vertex(posMat, x1, y1, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v1).light(combinedLight).normal(0f, 0f, -1f).endVertex();
builder.vertex(posMat, x1, y2, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v2).light(combinedLight).normal(0f, 0f, -1f).endVertex();
}
private void renderUp(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x1, float x2, float y2, float z1, float u1, float u2, float v1) {
builder.vertex(posMat, x2, y2, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u2, v1).light(combinedLight).normal(0f, 1f, 0f).endVertex();
builder.vertex(posMat, x1, y2, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v1).light(combinedLight).normal(0f, 1f, 0f).endVertex();
}
private void renderDown(IVertexBuilder builder, Matrix4f posMat, int combinedLight, int[] cols, float x1, float y1, float z1, float z2, float u1, float v1, float v2) {
builder.vertex(posMat, x1, y1, z2).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v2).light(combinedLight).normal(0f, -1f, 0f).endVertex();
builder.vertex(posMat, x1, y1, z1).color(cols[1], cols[2], cols[3], cols[0]).texture(u1, v1).light(combinedLight).normal(0f, -1f, 0f).endVertex();
}
private AxisAlignedBB getRenderBounds(IFluidTank tank, AxisAlignedBB tankBounds) {
double percent = (double) tank.getFluidAmount() / (double) tank.getCapacity();
double y1 = tankBounds.minY;
double y2 = tank.getFluidAmount() < tank.getCapacity() ? (4 + 8 * percent) / 16f : 1f;
if (tank.getFluid().getFluid().getAttributes().isLighterThanAir()) {
double yOff = tankBounds.maxY - y2; // FIXME: lighter than air fluids move to the top of the tank, add behavior in TE
y1 += yOff;
y2 += yOff;
}
return new AxisAlignedBB(tankBounds.minX, y1, tankBounds.minZ, tankBounds.maxX, y2, tankBounds.maxZ);
}
private List<FluidTankRenderInfo> getTanksToRender(FluidTankTileEntity te) {
return Collections.singletonList(new FluidTankRenderInfo(te, ((FluidTankBlock) te.getBlockState().getBlock()).getTankShape(te.getWorld(), te.getPos())));
}
private static class FluidTankRenderInfo {
private final IFluidTank tank;
private final AxisAlignedBB bounds;
private final FluidTankTileEntity te;
FluidTankRenderInfo(FluidTankTileEntity te, AxisAlignedBB bounds) {
this.te = te;
this.bounds = bounds;
this.tank = te.getTank();
}
public boolean shouldRender(Direction face) {
FluidTankTileEntity offsetTE = te.getOtherFluidTankTileEntity(face);
switch (face) {
case UP:
return (offsetTE != null && (offsetTE.getTank().getFluidAmount() == 0 || te.getTank().getFluid().getRawFluid() != offsetTE.getTank().getFluid().getRawFluid()))
|| getTank().getFluidAmount() < getTank().getCapacity()
&& !getTank().getFluid().getFluid().getAttributes().isLighterThanAir();
case DOWN:
return (offsetTE != null && (offsetTE.getTank().getFluidAmount() < offsetTE.getTank().getCapacity() || te.getTank().getFluid().getRawFluid() != offsetTE.getTank().getFluid().getRawFluid()))
|| getTank().getFluidAmount() < getTank().getCapacity()
&& getTank().getFluid().getFluid().getAttributes().isLighterThanAir();
default:
return offsetTE == null || te.getTank().getFluid().getRawFluid() != offsetTE.getTank().getFluid().getRawFluid();
}
}
public IFluidTank getTank() {
return tank;
}
public AxisAlignedBB getBounds() {
return bounds;
}
}
}

View File

@ -1,158 +1,361 @@
package com.simibubi.create.content.contraptions.fluids;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.templates.FluidTank;
import static java.lang.Math.abs;
import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import com.simibubi.create.content.contraptions.fluids.FluidTankBlock.Shape;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.fluid.SmartFluidTank;
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidAttributes;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.templates.FluidTank;
public class FluidTankTileEntity extends SmartTileEntity {
LazyOptional<FluidTank> fluid = LazyOptional.of(this::createFluidHandler);
private int priority = 1000;
private static final int MAX_SIZE = 3;
public FluidTankTileEntity(TileEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
}
protected LazyOptional<IFluidHandler> fluidCapability;
protected boolean forceFluidLevelUpdate;
protected FluidTank tankInventory;
protected BlockPos controller;
protected boolean updateConnectivity;
protected boolean window;
protected int luminosity;
protected int width;
protected int height;
private int calculateDrainAmount(FluidTankTileEntity other, int delta) {
boolean roundDirection = other.getPriority() < this.getPriority();
return (int) Math.abs(roundDirection ? Math.floor(delta / 2f) : Math.ceil(delta / 2f));
}
// For rendering purposes only
InterpolatedChasingValue fluidLevel;
@Override
public void tick() {
super.tick();
updatePriority();
public FluidTankTileEntity(TileEntityType<?> tileEntityTypeIn) {
super(tileEntityTypeIn);
tankInventory = new SmartFluidTank(getCapacityMultiplier(), this::onFluidStackChanged);
fluidCapability = LazyOptional.of(() -> tankInventory);
forceFluidLevelUpdate = true;
updateConnectivity = false;
window = true;
height = 1;
width = 1;
}
FluidTankTileEntity other;
protected void updateConnectivity() {
updateConnectivity = false;
if (world.isRemote)
return;
if (!isController())
return;
FluidTankConnectivityHandler.formTanks(this);
}
other = getOtherFluidTankTileEntity(Direction.NORTH);
if (other != null && other.getTank().isFluidValid(this.getTank().getFluid())) {
int delta = other.getTank().getFluidAmount() - this.getTank().getFluidAmount();
if (delta > 0) {
this.getTank().fill(other.getTank().drain(calculateDrainAmount(other, delta), FluidAction.EXECUTE), FluidAction.EXECUTE);
other.markDirty();
this.markDirty();
other.sendData();
sendData();
} else if (delta < 0) {
other.getTank().fill(this.getTank().drain(calculateDrainAmount(other, delta), FluidAction.EXECUTE), FluidAction.EXECUTE);
other.markDirty();
this.markDirty();
other.sendData();
sendData();
}
}
@Override
public void tick() {
super.tick();
if (updateConnectivity)
updateConnectivity();
if (fluidLevel != null)
fluidLevel.tick();
}
public boolean isController() {
return controller == null || controller.equals(pos);
}
other = getOtherFluidTankTileEntity(Direction.WEST);
if (other != null && other.getTank().isFluidValid(this.getTank().getFluid())) {
int delta = other.getTank().getFluidAmount() - this.getTank().getFluidAmount();
if (delta > 0) {
this.getTank().fill(other.getTank().drain(calculateDrainAmount(other, delta), FluidAction.EXECUTE), FluidAction.EXECUTE);
other.markDirty();
this.markDirty();
other.sendData();
sendData();
} else if (delta < 0) {
other.getTank().fill(this.getTank().drain(calculateDrainAmount(other, delta), FluidAction.EXECUTE), FluidAction.EXECUTE);
other.markDirty();
this.markDirty();
other.sendData();
sendData();
}
}
@Override
public void initialize() {
super.initialize();
sendData();
}
other = getOtherFluidTankTileEntity(Direction.UP);
if (other != null && other.getTank().isFluidValid(this.getTank().getFluid())) {
int space = this.getTank().getCapacity() - this.getTank().getFluidAmount();
if (space > 0 && other.getTank().getFluidAmount() > 0) {
this.getTank().fill(other.getTank().drain(space, FluidAction.EXECUTE), FluidAction.EXECUTE);
other.markDirty();
this.markDirty();
other.sendData();
sendData();
}
}
}
protected void onFluidStackChanged(FluidStack newFluidStack) {
if (!hasWorld())
return;
@Nullable
public FluidTankTileEntity getOtherFluidTankTileEntity(Direction direction) {
TileEntity otherTE = world.getTileEntity(pos.offset(direction));
if (otherTE instanceof FluidTankTileEntity)
return (FluidTankTileEntity) otherTE;
return null;
}
FluidAttributes attributes = newFluidStack.getFluid()
.getAttributes();
int luminosity = attributes.getLuminosity(newFluidStack) / 2;
boolean reversed = attributes.isLighterThanAir();
int maxY = (int) ((getFillState() * height) + 1);
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
return fluid.cast();
}
return super.getCapability(cap, side);
}
for (int yOffset = 0; yOffset < height; yOffset++) {
boolean isBright = reversed ? (height - yOffset <= maxY) : (yOffset < maxY);
int actualLuminosity = isBright ? luminosity : luminosity > 0 ? 1 : 0;
@Override
public void read(CompoundNBT tag) {
fluid.ifPresent(h -> h.readFromNBT(tag));
super.read(tag);
}
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos pos = this.pos.add(xOffset, yOffset, zOffset);
FluidTankTileEntity tankAt = FluidTankConnectivityHandler.tankAt(world, pos);
if (tankAt == null)
continue;
if (tankAt.luminosity == actualLuminosity)
continue;
tankAt.setLuminosity(actualLuminosity);
}
}
}
}
@Override
public CompoundNBT write(CompoundNBT tag) {
fluid.ifPresent(h -> h.writeToNBT(tag));
return super.write(tag);
}
protected void setLuminosity(int luminosity) {
if (world.isRemote)
return;
if (this.luminosity == luminosity)
return;
this.luminosity = luminosity;
sendData();
}
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
}
public FluidTankTileEntity getControllerTE() {
if (isController())
return this;
TileEntity tileEntity = world.getTileEntity(controller);
if (tileEntity instanceof FluidTankTileEntity)
return (FluidTankTileEntity) tileEntity;
return null;
}
@Nonnull
public FluidTank createFluidHandler() {
return new FluidTank(16000);
}
public void applyFluidTankSize(int blocks) {
tankInventory.setCapacity(blocks * getCapacityMultiplier());
int overflow = tankInventory.getFluidAmount() - tankInventory.getCapacity();
if (overflow > 0)
tankInventory.drain(overflow, FluidAction.EXECUTE);
forceFluidLevelUpdate = true;
}
public IFluidTank getTank() {
return fluid.orElseGet(this::createFluidHandler);
}
public void removeController() {
if (world.isRemote)
return;
updateConnectivity = true;
applyFluidTankSize(1);
controller = null;
width = 1;
height = 1;
onFluidStackChanged(tankInventory.getFluid());
private void updatePriority() {
FluidTankTileEntity other = getOtherFluidTankTileEntity(Direction.DOWN);
priority = 1000;
if (other != null) {
priority = 0;
return;
}
BlockState state = getBlockState();
if (FluidTankBlock.isTank(state)) {
state = state.with(FluidTankBlock.BOTTOM, true);
state = state.with(FluidTankBlock.TOP, true);
state = state.with(FluidTankBlock.SHAPE, window ? Shape.WINDOW : Shape.PLAIN);
getWorld().setBlockState(pos, state, 22);
}
updatePriorityFrom(Direction.SOUTH);
updatePriorityFrom(Direction.NORTH);
updatePriorityFrom(Direction.WEST);
updatePriorityFrom(Direction.EAST);
}
markDirty();
sendData();
}
private void updatePriorityFrom(Direction direction) {
FluidTankTileEntity other = getOtherFluidTankTileEntity(direction);
if (other != null && other.getPriority() + 1 < priority) {
priority = other.getPriority() + 1;
}
}
public void toggleWindows() {
FluidTankTileEntity te = getControllerTE();
if (te == null)
return;
te.setWindows(!te.window);
}
public void setWindows(boolean window) {
this.window = window;
for (int yOffset = 0; yOffset < height; yOffset++) {
for (int xOffset = 0; xOffset < width; xOffset++) {
for (int zOffset = 0; zOffset < width; zOffset++) {
BlockPos pos = this.pos.add(xOffset, yOffset, zOffset);
BlockState blockState = world.getBlockState(pos);
if (!FluidTankBlock.isTank(blockState))
continue;
Shape shape = Shape.PLAIN;
if (window) {
// SIZE 1: Every tank has a window
if (width == 1)
shape = Shape.WINDOW;
// SIZE 2: Every tank has a corner window
if (width == 2)
shape = xOffset == 0 ? zOffset == 0 ? Shape.WINDOW_NW : Shape.WINDOW_SW
: zOffset == 0 ? Shape.WINDOW_NE : Shape.WINDOW_SE;
// SIZE 3: Tanks in the center have a window
if (width == 3 && abs(abs(xOffset) - abs(zOffset)) == 1)
shape = Shape.WINDOW;
}
world.setBlockState(pos, blockState.with(FluidTankBlock.SHAPE, shape), 22);
world.getChunkProvider()
.getLightManager()
.checkBlock(pos);
}
}
}
}
public void setController(BlockPos controller) {
if (world.isRemote)
return;
if (controller.equals(this.controller))
return;
this.controller = controller;
markDirty();
sendData();
}
public BlockPos getController() {
return isController() ? pos : controller;
}
@Override
@OnlyIn(Dist.CLIENT)
public AxisAlignedBB getRenderBoundingBox() {
return super.getRenderBoundingBox().expand(width - 1, height - 1, width - 1);
}
@Nullable
public FluidTankTileEntity getOtherFluidTankTileEntity(Direction direction) {
TileEntity otherTE = world.getTileEntity(pos.offset(direction));
if (otherTE instanceof FluidTankTileEntity)
return (FluidTankTileEntity) otherTE;
return null;
}
@Override
public void read(CompoundNBT tag) {
super.read(tag);
updateConnectivity = tag.contains("Uninitialized");
luminosity = tag.getInt("Luminosity");
controller = null;
if (tag.contains("Controller"))
controller = NBTUtil.readBlockPos(tag.getCompound("Controller"));
if (isController()) {
window = tag.getBoolean("Window");
width = tag.getInt("Size");
height = tag.getInt("Height");
tankInventory.setCapacity(getTotalTankSize() * getCapacityMultiplier());
tankInventory.readFromNBT(tag.getCompound("TankContent"));
if (tankInventory.getSpace() < 0)
tankInventory.drain(-tankInventory.getSpace(), FluidAction.EXECUTE);
}
if (tag.contains("ForceFluidLevel") || fluidLevel == null)
fluidLevel = new InterpolatedChasingValue().start(getFillState())
.withSpeed(1 / 2f);
}
@Override
public void readClientUpdate(CompoundNBT tag) {
BlockPos controllerBefore = controller;
int prevSize = width;
int prevHeight = height;
int prevLum = luminosity;
super.readClientUpdate(tag);
boolean changeOfController =
controllerBefore == null ? controller != null : !controllerBefore.equals(controller);
if (changeOfController || prevSize != width || prevHeight != height) {
if (hasWorld())
world.notifyBlockUpdate(getPos(), getBlockState(), getBlockState(), 16);
if (isController())
tankInventory.setCapacity(getCapacityMultiplier() * getTotalTankSize());
}
if (isController()) {
float fillState = getFillState();
if (tag.contains("ForceFluidLevel") || fluidLevel == null)
fluidLevel = new InterpolatedChasingValue().start(fillState)
.withSpeed(1 / 2f);
fluidLevel.target(fillState);
}
if (luminosity != prevLum && hasWorld())
world.getChunkProvider()
.getLightManager()
.checkBlock(pos);
}
protected float getFillState() {
return (float) tankInventory.getFluidAmount() / tankInventory.getCapacity();
}
@Override
public CompoundNBT write(CompoundNBT tag) {
if (updateConnectivity)
tag.putBoolean("Uninitialized", true);
if (!isController())
tag.put("Controller", NBTUtil.writeBlockPos(controller));
if (isController()) {
tag.putBoolean("Window", window);
tag.put("TankContent", tankInventory.writeToNBT(new CompoundNBT()));
tag.putInt("Size", width);
tag.putInt("Height", height);
}
tag.putInt("Luminosity", luminosity);
return super.write(tag);
}
@Override
public CompoundNBT writeToClient(CompoundNBT compound) {
if (forceFluidLevelUpdate)
compound.putBoolean("ForceFluidLevel", true);
forceFluidLevelUpdate = false;
return super.writeToClient(compound);
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, @Nullable Direction side) {
if (cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
FluidTankTileEntity controller = getControllerTE();
if (controller != null)
return controller.fluidCapability.cast();
}
return super.getCapability(cap, side);
}
@Override
public void remove() {
super.remove();
fluidCapability.invalidate();
}
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {}
public IFluidTank getTankInventory() {
return tankInventory;
}
public int getTotalTankSize() {
return width * width * height;
}
public static int getMaxSize() {
return MAX_SIZE;
}
protected static int getCapacityMultiplier() {
return AllConfigs.SERVER.fluids.fluidTankCapacity.get() * 1000;
}
public static int getMaxHeight() {
return AllConfigs.SERVER.fluids.fluidTankMaxHeight.get();
}
public int getPriority() {
return priority;
}
}

View File

@ -0,0 +1,152 @@
package com.simibubi.create.content.contraptions.particle;
import org.lwjgl.opengl.GL11;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.particle.IParticleFactory;
import net.minecraft.client.particle.IParticleRenderType;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class CubeParticle extends Particle {
public static final Vec3d[] CUBE = {
// TOP
new Vec3d(1, 1, -1), new Vec3d(1, 1, 1), new Vec3d(-1, 1, 1), new Vec3d(-1, 1, -1),
// BOTTOM
new Vec3d(-1, -1, -1), new Vec3d(-1, -1, 1), new Vec3d(1, -1, 1), new Vec3d(1, -1, -1),
// FRONT
new Vec3d(-1, -1, 1), new Vec3d(-1, 1, 1), new Vec3d(1, 1, 1), new Vec3d(1, -1, 1),
// BACK
new Vec3d(1, -1, -1), new Vec3d(1, 1, -1), new Vec3d(-1, 1, -1), new Vec3d(-1, -1, -1),
// LEFT
new Vec3d(-1, -1, -1), new Vec3d(-1, 1, -1), new Vec3d(-1, 1, 1), new Vec3d(-1, -1, 1),
// RIGHT
new Vec3d(1, -1, 1), new Vec3d(1, 1, 1), new Vec3d(1, 1, -1), new Vec3d(1, -1, -1) };
public static final Vec3d[] CUBE_NORMALS = {
// modified normals for the sides
new Vec3d(0, 1, 0), new Vec3d(0, -1, 0), new Vec3d(0, 0, 1), new Vec3d(0, 0, 1), new Vec3d(0, 0, 1),
new Vec3d(0, 0, 1),
/*
* new Vec3d(0, 1, 0), new Vec3d(0, -1, 0), new Vec3d(0, 0, 1), new Vec3d(0, 0,
* -1), new Vec3d(-1, 0, 0), new Vec3d(1, 0, 0)
*/
};
private static final IParticleRenderType renderType = new IParticleRenderType() {
@Override
public void beginRender(BufferBuilder builder, TextureManager textureManager) {
RenderSystem.disableTexture();
// transparent, additive blending
RenderSystem.depthMask(false);
RenderSystem.enableBlend();
RenderSystem.blendFunc(GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ONE);
RenderSystem.enableLighting();
RenderSystem.enableColorMaterial();
// opaque
// RenderSystem.depthMask(true);
// RenderSystem.disableBlend();
// RenderSystem.enableLighting();
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
}
@Override
public void finishRender(Tessellator tessellator) {
tessellator.draw();
RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA,
GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
RenderSystem.enableTexture();
}
};
protected float scale;
public CubeParticle(World world, double x, double y, double z, double motionX, double motionY, double motionZ) {
super(world, x, y, z);
this.motionX = motionX;
this.motionY = motionY;
this.motionZ = motionZ;
setScale(0.2F);
}
public void setScale(float scale) {
this.scale = scale;
this.setSize(scale, scale);
}
public void averageAge(int age) {
this.maxAge = (int) (age + (rand.nextDouble() * 2D - 1D) * 8);
}
@Override
public void buildGeometry(IVertexBuilder builder, ActiveRenderInfo renderInfo, float p_225606_3_) {
Vec3d projectedView = renderInfo.getProjectedView();
float lerpedX = (float) (MathHelper.lerp(p_225606_3_, this.prevPosX, this.posX) - projectedView.getX());
float lerpedY = (float) (MathHelper.lerp(p_225606_3_, this.prevPosY, this.posY) - projectedView.getY());
float lerpedZ = (float) (MathHelper.lerp(p_225606_3_, this.prevPosZ, this.posZ) - projectedView.getZ());
// int light = getBrightnessForRender(p_225606_3_);
int light = 15728880;// 15<<20 && 15<<4
double ageMultiplier = 1 - Math.pow(age, 3) / Math.pow(maxAge, 3);
for (int i = 0; i < 6; i++) {
// 6 faces to a cube
for (int j = 0; j < 4; j++) {
Vec3d vec = CUBE[i * 4 + j];
vec = vec
/* .rotate(?) */
.scale(scale * ageMultiplier)
.add(lerpedX, lerpedY, lerpedZ);
Vec3d normal = CUBE_NORMALS[i];
builder.vertex(vec.x, vec.y, vec.z)
.color(particleRed, particleGreen, particleBlue, particleAlpha)
.texture(0, 0)
.light(light)
.normal((float) normal.x, (float) normal.y, (float) normal.z)
.endVertex();
}
}
}
@Override
public IParticleRenderType getRenderType() {
return renderType;
}
public static class Factory implements IParticleFactory<CubeParticleData> {
public Factory() {}
@Override
public Particle makeParticle(CubeParticleData data, World world, double x, double y, double z, double motionX,
double motionY, double motionZ) {
CubeParticle particle = new CubeParticle(world, x, y, z, motionX, motionY, motionZ);
particle.setColor(data.r, data.g, data.b);
particle.setScale(data.scale);
particle.averageAge(data.avgAge);
return particle;
}
}
}

View File

@ -0,0 +1,87 @@
package com.simibubi.create.content.contraptions.particle;
import java.util.Locale;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.simibubi.create.AllParticleTypes;
import net.minecraft.client.particle.ParticleManager;
import net.minecraft.network.PacketBuffer;
import net.minecraft.particles.IParticleData;
import net.minecraft.particles.ParticleType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class CubeParticleData implements IParticleData, ICustomParticle<CubeParticleData> {
public static final IParticleData.IDeserializer<CubeParticleData> DESERIALIZER = new IParticleData.IDeserializer<CubeParticleData>() {
@Override
public CubeParticleData deserialize(ParticleType<CubeParticleData> type, StringReader reader) throws CommandSyntaxException {
reader.expect(' ');
float r = reader.readFloat();
reader.expect(' ');
float g = reader.readFloat();
reader.expect(' ');
float b = reader.readFloat();
reader.expect(' ');
float scale = reader.readFloat();
reader.expect(' ');
int avgAge = reader.readInt();
return new CubeParticleData(r, g, b, scale, avgAge);
}
@Override
public CubeParticleData read(ParticleType<CubeParticleData> type, PacketBuffer buffer) {
return new CubeParticleData(buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readInt());
}
};
final float r;
final float g;
final float b;
final float scale;
final int avgAge;
public CubeParticleData(float r, float g, float b, float scale, int avgAge) {
this.r = r;
this.g = g;
this.b = b;
this.scale = scale;
this.avgAge = avgAge;
}
public static CubeParticleData dummy() {
return new CubeParticleData(0, 0, 0, 0, 0);
}
@Override
public IDeserializer<CubeParticleData> getDeserializer() {
return DESERIALIZER;
}
@Override
@OnlyIn(Dist.CLIENT)
public ParticleManager.IParticleMetaFactory<CubeParticleData> getFactory() {
return null;
}
@Override
public ParticleType<?> getType() {
return AllParticleTypes.CUBE.get();
}
@Override
public void write(PacketBuffer buffer) {
buffer.writeFloat(r);
buffer.writeFloat(g);
buffer.writeFloat(b);
buffer.writeFloat(scale);
buffer.writeInt(avgAge);
}
@Override
public String getParameters() {
return String.format(Locale.ROOT, "%s %f %f %f %f %d", AllParticleTypes.CUBE.parameter(), r, g, b, scale, avgAge);
}
}

View File

@ -0,0 +1,110 @@
package com.simibubi.create.content.contraptions.particle;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.particle.IAnimatedSprite;
import net.minecraft.client.particle.IParticleFactory;
import net.minecraft.client.particle.IParticleRenderType;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.SimpleAnimatedParticle;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import javax.annotation.ParametersAreNonnullByDefault;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class HeaterParticle extends SimpleAnimatedParticle {
private final IAnimatedSprite animatedSprite;
public HeaterParticle(World worldIn, float r, float g, float b, double x, double y, double z, double vx, double vy,
double vz, IAnimatedSprite spriteSet) {
super(worldIn, x, y, z, spriteSet, worldIn.rand.nextFloat() * .5f);
this.animatedSprite = spriteSet;
this.motionX = this.motionX * (double) 0.01F + vx;
this.motionY = this.motionY * (double) 0.01F + vy;
this.motionZ = this.motionZ * (double) 0.01F + vz;
this.particleRed = r;
this.particleGreen = g;
this.particleBlue = b;
this.posX += (this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F;
this.posY += (this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F;
this.posZ += (this.rand.nextFloat() - this.rand.nextFloat()) * 0.05F;
this.maxAge = (int) (8.0D / (Math.random() * 0.8D + 0.2D)) + 4;
this.particleScale *= 1.875F;
this.selectSpriteWithAge(animatedSprite);
}
@Override
public IParticleRenderType getRenderType() {
return IParticleRenderType.PARTICLE_SHEET_LIT;
}
@Override
public float getScale(float p_217561_1_) {
float f = ((float) this.age + p_217561_1_) / (float) this.maxAge;
return this.particleScale * (1.0F - f * f * 0.5F);
}
@Override
public void move(double x, double y, double z) {
this.setBoundingBox(this.getBoundingBox()
.offset(x, y, z));
this.resetPositionToBB();
}
@Override
public int getBrightnessForRender(float p_189214_1_) {
float f = ((float) this.age + p_189214_1_) / (float) this.maxAge;
f = MathHelper.clamp(f, 0.0F, 1.0F);
int i = super.getBrightnessForRender(p_189214_1_);
int j = i & 255;
int k = i >> 16 & 255;
j = j + (int) (f * 15.0F * 16.0F);
if (j > 240) {
j = 240;
}
return j | k << 16;
}
@Override
public void tick() {
this.prevPosX = this.posX;
this.prevPosY = this.posY;
this.prevPosZ = this.posZ;
if (this.age++ >= this.maxAge) {
this.setExpired();
} else {
this.selectSpriteWithAge(animatedSprite);
this.move(this.motionX, this.motionY, this.motionZ);
this.motionX *= (double) 0.96F;
this.motionY *= (double) 0.96F;
this.motionZ *= (double) 0.96F;
if (this.onGround) {
this.motionX *= (double) 0.7F;
this.motionZ *= (double) 0.7F;
}
}
}
public static class Factory implements IParticleFactory<HeaterParticleData> {
private final IAnimatedSprite spriteSet;
public Factory(IAnimatedSprite animatedSprite) {
this.spriteSet = animatedSprite;
}
@Override
public Particle makeParticle(HeaterParticleData data, World worldIn, double x, double y, double z, double vx,
double vy, double vz) {
return new HeaterParticle(worldIn, data.r, data.g, data.b, x, y, z, vx, vy, vz, this.spriteSet);
}
}
}

View File

@ -0,0 +1,85 @@
package com.simibubi.create.content.contraptions.particle;
import java.util.Locale;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.simibubi.create.AllParticleTypes;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.particle.ParticleManager.IParticleMetaFactory;
import net.minecraft.network.PacketBuffer;
import net.minecraft.particles.IParticleData;
import net.minecraft.particles.ParticleType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class HeaterParticleData implements IParticleData, ICustomParticle<HeaterParticleData> {
public static final IParticleData.IDeserializer<HeaterParticleData> DESERIALIZER =
new IParticleData.IDeserializer<HeaterParticleData>() {
@Override
public HeaterParticleData deserialize(ParticleType<HeaterParticleData> arg0, StringReader reader)
throws CommandSyntaxException {
reader.expect(' ');
float r = reader.readFloat();
reader.expect(' ');
float g = reader.readFloat();
reader.expect(' ');
float b = reader.readFloat();
return new HeaterParticleData(r, g, b);
}
@Override
public HeaterParticleData read(ParticleType<HeaterParticleData> type, PacketBuffer buffer) {
return new HeaterParticleData(buffer.readFloat(), buffer.readFloat(), buffer.readFloat());
}
};
final float r;
final float g;
final float b;
public HeaterParticleData(float r, float g, float b) {
this.r = r;
this.g = g;
this.b = b;
}
public HeaterParticleData() {
this(0, 0, 0);
}
@Override
public IDeserializer<HeaterParticleData> getDeserializer() {
return DESERIALIZER;
}
@Override
@OnlyIn(Dist.CLIENT)
public IParticleMetaFactory<HeaterParticleData> getFactory() {
return HeaterParticle.Factory::new;
}
@Override
public String getParameters() {
return String.format(Locale.ROOT, "%s %f %f %f", AllParticleTypes.HEATER_PARTICLE.parameter(), r, g, b);
}
@Override
public ParticleType<?> getType() {
return AllParticleTypes.HEATER_PARTICLE.get();
}
@Override
public void write(PacketBuffer buffer) {
buffer.writeFloat(r);
buffer.writeFloat(g);
buffer.writeFloat(b);
}
}

View File

@ -37,7 +37,7 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
protected IRecipe<?> lastRecipe;
protected LazyOptional<IItemHandler> basinItemInv = LazyOptional.empty();
protected LazyOptional<IFluidHandler> basinFluidInv = LazyOptional.empty();
protected MultiIngredientTypeList inputs;
protected CombinedItemFluidList inputs;
public BasinOperatingTileEntity(TileEntityType<?> typeIn) {
super(typeIn);
@ -59,7 +59,7 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
}
public void gatherInputs() {
inputs = new MultiIngredientTypeList();
inputs = new CombinedItemFluidList();
basinItemInv.ifPresent(inv -> {
IItemHandlerModifiable inputHandler = ((BasinInventory) inv).getInputHandler();

View File

@ -3,6 +3,8 @@ package com.simibubi.create.content.contraptions.processing;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nonnull;
import com.simibubi.create.content.contraptions.fluids.CombinedFluidHandler;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
@ -10,6 +12,7 @@ import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputB
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
@ -24,8 +27,6 @@ import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import net.minecraftforge.items.wrapper.RecipeWrapper;
import javax.annotation.Nonnull;
public class BasinTileEntity extends SmartTileEntity implements ITickableTileEntity {
public boolean contentsChanged;
@ -121,7 +122,7 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
super.read(compound);
inputItemInventory.deserializeNBT(compound.getCompound("InputItems"));
outputItemInventory.deserializeNBT(compound.getCompound("OutputItems"));
if (compound.hasUniqueId("fluids"))
if (compound.contains("fluids"))
fluidInventory
.ifPresent(combinedFluidHandler -> combinedFluidHandler.readFromNBT(compound.getList("fluids", 10)));
}
@ -131,7 +132,10 @@ public class BasinTileEntity extends SmartTileEntity implements ITickableTileEnt
super.write(compound);
compound.put("InputItems", inputItemInventory.serializeNBT());
compound.put("OutputItems", outputItemInventory.serializeNBT());
fluidInventory.ifPresent(combinedFuidHandler -> compound.put("fluids", combinedFuidHandler.getListNBT()));
fluidInventory.ifPresent(combinedFuidHandler -> {
ListNBT nbt = combinedFuidHandler.getListNBT();
compound.put("fluids", nbt);
});
return compound;
}

View File

@ -6,23 +6,31 @@ import net.minecraftforge.fluids.FluidStack;
import java.util.ArrayList;
import java.util.function.Consumer;
public class MultiIngredientTypeList {
private final ArrayList<ItemStack> itemIngredients = new ArrayList<>();
private final ArrayList<FluidStack> fluidIngredients = new ArrayList<>();
public class CombinedItemFluidList {
private final ArrayList<ItemStack> itemStacks = new ArrayList<>();
private final ArrayList<FluidStack> fluidStacks = new ArrayList<>();
public void add(ItemStack itemstack) {
itemIngredients.add(itemstack);
itemStacks.add(itemstack);
}
public void add(FluidStack fluidStack) {
fluidIngredients.add(fluidStack);
fluidStacks.add(fluidStack);
}
public void forEachItemStack(Consumer<? super ItemStack> itemStackConsumer) {
itemIngredients.forEach(itemStackConsumer);
itemStacks.forEach(itemStackConsumer);
}
public void forEachFluidStack(Consumer<? super FluidStack> fluidStackConsumer) {
fluidIngredients.forEach(fluidStackConsumer);
fluidStacks.forEach(fluidStackConsumer);
}
public ArrayList<ItemStack> getItemStacks() {
return itemStacks;
}
public ArrayList<FluidStack> getFluidStacks() {
return fluidStacks;
}
}

View File

@ -0,0 +1,144 @@
package com.simibubi.create.content.contraptions.processing;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import com.simibubi.create.AllShapes;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.foundation.block.ITE;
import com.simibubi.create.foundation.utility.Lang;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.EnumProperty;
import net.minecraft.state.IProperty;
import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class HeaterBlock extends Block implements ITE<HeaterTileEntity> {
//public static IProperty<Integer> BLAZE_LEVEL = IntegerProperty.create("blaze_level", 0, 4);
public static IProperty<HeatLevel> BLAZE_LEVEL = EnumProperty.create("blaze", HeatLevel.class);
public HeaterBlock(Properties properties) {
super(properties);
setDefaultState(super.getDefaultState().with(BLAZE_LEVEL, HeatLevel.NONE));
}
@Override
protected void fillStateContainer(Builder<Block, BlockState> builder) {
super.fillStateContainer(builder);
builder.add(BLAZE_LEVEL);
}
@Override
public boolean hasTileEntity(BlockState state) {
return state.get(BLAZE_LEVEL).min(HeatLevel.SMOULDERING);
}
@Nullable
@Override
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
return AllTileEntities.HEATER.create();
}
@Override
public Class<HeaterTileEntity> getTileEntityClass() {
return HeaterTileEntity.class;
}
@Override
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult blockRayTraceResult) {
if (!hasTileEntity(state))
return ActionResultType.PASS;
TileEntity te = world.getTileEntity(pos);
if (!(te instanceof HeaterTileEntity))
return ActionResultType.PASS;
if (!((HeaterTileEntity) te).tryUpdateFuel(player.getHeldItem(hand), player))
return ActionResultType.PASS;
if (!player.isCreative())
player.getHeldItem(hand).shrink(1);
return ActionResultType.SUCCESS;
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
if (!context.getItem().hasTag())
return getDefaultState();
CompoundNBT tag = context.getItem().getTag();
if (!tag.contains("has_blaze"))
return getDefaultState();
if (tag.getBoolean("has_blaze"))
return getDefaultState().with(BLAZE_LEVEL, HeatLevel.SMOULDERING);
return getDefaultState();
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader reader, BlockPos pos, ISelectionContext context) {
return AllShapes.HEATER_BLOCK_SHAPE;
}
@Override
public VoxelShape getCollisionShape(BlockState p_220071_1_, IBlockReader p_220071_2_, BlockPos p_220071_3_, ISelectionContext p_220071_4_) {
if (p_220071_4_ == ISelectionContext.dummy())
return AllShapes.HEATER_BLOCK_SPECIAL_COLLISION_SHAPE;
return super.getShape(p_220071_1_, p_220071_2_, p_220071_3_, p_220071_4_);
}
@Override
public int getLightValue(BlockState state, IBlockReader world, BlockPos pos) {
return MathHelper.clamp(state.get(BLAZE_LEVEL).ordinal() * 4 - 1, 0, 15);
}
static void setBlazeLevel(@Nullable World world, BlockPos pos, HeatLevel blazeLevel) {
if (world != null)
world.setBlockState(pos, world.getBlockState(pos).with(BLAZE_LEVEL, blazeLevel));
}
public static HeatLevel getHeaterLevel(BlockState blockState) {
return blockState.has(HeaterBlock.BLAZE_LEVEL) ? blockState.get(HeaterBlock.BLAZE_LEVEL) : HeatLevel.NONE;
}
public enum HeatLevel implements IStringSerializable {
NONE,
SMOULDERING,
FADING,
KINDLED,
SEETHING,
//if you think you have better names let me know :)
;
@Override
public String getName() {
return Lang.asId(name());
}
public boolean min(HeatLevel heatLevel) {
return this.ordinal() >= heatLevel.ordinal();
}
}
}

View File

@ -0,0 +1,73 @@
package com.simibubi.create.content.contraptions.processing;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.Block;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.monster.BlazeEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.tileentity.MobSpawnerTileEntity;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import net.minecraftforge.common.util.FakePlayer;
@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public class HeaterBlockItem extends BlockItem {
public HeaterBlockItem(Block block, Properties properties) {
super(block, properties);
}
@Override
public ActionResultType onItemUse(ItemUseContext context) {
TileEntity te = context.getWorld()
.getTileEntity(context.getPos());
if (te instanceof MobSpawnerTileEntity && ((MobSpawnerTileEntity) te).getSpawnerBaseLogic()
.getCachedEntity() instanceof BlazeEntity) {
ItemStack itemWithBlaze = withBlaze(context.getItem());
context.getItem()
.shrink(1);
dropOrPlaceBack(context.getWorld(), context.getPlayer(), itemWithBlaze);
return ActionResultType.SUCCESS;
}
return super.onItemUse(context);
}
@Override
public boolean itemInteractionForEntity(ItemStack heldItem, PlayerEntity player, LivingEntity entity, Hand hand) {
if (entity instanceof BlazeEntity) {
ItemStack itemWithBlaze = withBlaze(heldItem);
heldItem.shrink(1);
dropOrPlaceBack(player.getEntityWorld(), player, itemWithBlaze);
entity.remove();
return true;
}
return super.itemInteractionForEntity(heldItem, player, entity, hand);
}
private static ItemStack withBlaze(ItemStack base) {
ItemStack newItem = new ItemStack(base.getItem(), 1);
CompoundNBT tag = new CompoundNBT();
tag.putBoolean("has_blaze", true);
newItem.setTag(tag);
return newItem;
}
private static void dropOrPlaceBack(@Nullable World world, @Nullable PlayerEntity player, ItemStack item) {
if (player == null)
return;
if (player instanceof FakePlayer || world == null) {
player.dropItem(item, false, false);
} else {
player.inventory.placeItemBackInInventory(world, item);
}
}
}

View File

@ -0,0 +1,52 @@
package com.simibubi.create.content.contraptions.processing;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.SuperByteBuffer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.util.Direction;
import java.util.HashMap;
public class HeaterRenderer extends SafeTileEntityRenderer<HeaterTileEntity> {
private static final Minecraft INSTANCE = Minecraft.getInstance();
private static final HashMap<HeaterBlock.HeatLevel, AllBlockPartials> blazeModelMap = new HashMap<>();
public HeaterRenderer(TileEntityRendererDispatcher dispatcher) {
super(dispatcher);
blazeModelMap.put(HeaterBlock.HeatLevel.FADING, AllBlockPartials.BLAZE_HEATER_BLAZE_TWO);
blazeModelMap.put(HeaterBlock.HeatLevel.KINDLED, AllBlockPartials.BLAZE_HEATER_BLAZE_THREE);
blazeModelMap.put(HeaterBlock.HeatLevel.SEETHING, AllBlockPartials.BLAZE_HEATER_BLAZE_FOUR);
}
@Override
protected void renderSafe(HeaterTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) {
AllBlockPartials blazeModel =
blazeModelMap.getOrDefault(te.getHeatLevel(), AllBlockPartials.BLAZE_HEATER_BLAZE_ONE);
float angle;
if (INSTANCE.player == null) {
angle = 0;
} else {
Vector3f difference = new Vector3f(INSTANCE.player.getPositionVector()
.subtract(te.getPos()
.getX() + 0.5, 0,
te.getPos()
.getZ() + 0.5)
.mul(1, 0, 1));
difference.normalize();
angle = (float) ((difference.getX() < 0 ? 1 : -1) * Math.acos(Direction.NORTH.getUnitVector()
.dot(difference)));
}
SuperByteBuffer blazeBuffer = blazeModel.renderOn(te.getBlockState());
blazeBuffer.rotateCentered(Direction.UP, angle);
blazeBuffer.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
}
}

Some files were not shown because too many files have changed in this diff Show More