Logistical enhancements and fixes
- Arms can no longer insert into powered brass funnels - Slight ArmInteractionPoint refactor - Arms can now interact with Millstones, Basins, Jukeboxes, Crushing Wheels and the Mechanical Saw - Fixed crash when logging into a world with a running mixer - Arms now start to dance when one of their in or outputs is a running jukebox - Arms can now be mounted on the ceiling - Arms now always prefer the interaction points that were selected first - Fixed belt funnels not updating their blockstate properly when transitioning from other funnel types - Vertical funnels next to the end of a belt will now stall the belt when unable to collect incoming items - Minor model & texture touch ups - Arm no longer cancels player interaction when its empty handed - Fixed chutes not vertically interacting with andesite funnels
@ -179,7 +179,7 @@ b7506b862d13b3f915c60d38bb7a20afc935f70a assets\create\blockstates\limestone_pil
|
|||||||
69790737767e06f000c7824749c46664a123160e assets\create\blockstates\linear_chassis.json
|
69790737767e06f000c7824749c46664a123160e assets\create\blockstates\linear_chassis.json
|
||||||
c793ab3aa6cf09d8d6d4136757629689f0365771 assets\create\blockstates\linked_extractor.json
|
c793ab3aa6cf09d8d6d4136757629689f0365771 assets\create\blockstates\linked_extractor.json
|
||||||
c5422866667331f1d5cf6753c0889747ee02762b assets\create\blockstates\linked_transposer.json
|
c5422866667331f1d5cf6753c0889747ee02762b assets\create\blockstates\linked_transposer.json
|
||||||
e82e69ae4c7a784ef89fc5d954b2b01946746d48 assets\create\blockstates\mechanical_arm.json
|
3b3250d6e209403a93d025604a8081087965016e assets\create\blockstates\mechanical_arm.json
|
||||||
ddcf4bb281e046fbb1026b8f46a2cf12448598df assets\create\blockstates\mechanical_bearing.json
|
ddcf4bb281e046fbb1026b8f46a2cf12448598df assets\create\blockstates\mechanical_bearing.json
|
||||||
5586beef2d9183dc34d8e8d2723620c0569592ae assets\create\blockstates\mechanical_crafter.json
|
5586beef2d9183dc34d8e8d2723620c0569592ae assets\create\blockstates\mechanical_crafter.json
|
||||||
044db7d50e19008bae8bf3325eac2ed0eb1ea6d2 assets\create\blockstates\mechanical_drill.json
|
044db7d50e19008bae8bf3325eac2ed0eb1ea6d2 assets\create\blockstates\mechanical_drill.json
|
||||||
@ -338,16 +338,16 @@ c77b46d8b459e5c7cc495393546f3fcca8a1fa1d assets\create\blockstates\weathered_lim
|
|||||||
7f39521b211441f5c3e06d60c5978cebe16cacfb assets\create\blockstates\zinc_block.json
|
7f39521b211441f5c3e06d60c5978cebe16cacfb assets\create\blockstates\zinc_block.json
|
||||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets\create\blockstates\zinc_ore.json
|
b7181bcd8182b2f17088e5aa881f374c9c65470c assets\create\blockstates\zinc_ore.json
|
||||||
541831ab0cf2f0222f0b7e42ec6c4b0ae636168d assets\create\lang\en_ud.json
|
541831ab0cf2f0222f0b7e42ec6c4b0ae636168d assets\create\lang\en_ud.json
|
||||||
fe44adfde38a1084754fe46b632811f90dcfcd7f assets\create\lang\en_us.json
|
fd57d2d8144286e26033a087a501f45f2df9ea34 assets\create\lang\en_us.json
|
||||||
143b76ed828949330ef0e338fb6709c28561ac2d assets\create\lang\unfinished\de_de.json
|
87c28254c2acb462fe6a994f688a19e31a4c7a9d assets\create\lang\unfinished\de_de.json
|
||||||
95bf7693b162141c2c76617ed4e04bec474e2def assets\create\lang\unfinished\fr_fr.json
|
6cd93a72126063c634f49db190d4da545e5a6c43 assets\create\lang\unfinished\fr_fr.json
|
||||||
b3bf60afc7d0dea72a9d7d01df36d34affd6a296 assets\create\lang\unfinished\it_it.json
|
401d0b295988cfa31af1a94f8c50d86eb54cad0d assets\create\lang\unfinished\it_it.json
|
||||||
ef336e01a8e3ed3f8c2713c66476bcc708e3e3b0 assets\create\lang\unfinished\ja_jp.json
|
30f1189e1963d0a87a9505bfdac9b663ff9d09d1 assets\create\lang\unfinished\ja_jp.json
|
||||||
66c84c388e552ee8259eca2ab1009493456fc4d3 assets\create\lang\unfinished\ko_kr.json
|
a56d5b51d410821b7993bdbfd1b141e51be11b54 assets\create\lang\unfinished\ko_kr.json
|
||||||
66b3140ef158b51208a191e6a90473fba5bb1749 assets\create\lang\unfinished\nl_nl.json
|
e8a39cb4afc7668f2690bcacda1f06afd9c82579 assets\create\lang\unfinished\nl_nl.json
|
||||||
775702e0f3fbdab7ef8b1714e3cff69da56bd500 assets\create\lang\unfinished\pt_br.json
|
3876e40fbc9c6e8561cc761949a6fb9565a03fce assets\create\lang\unfinished\pt_br.json
|
||||||
7c4c4e7a00456f893538a6baa35d726a8786bf93 assets\create\lang\unfinished\ru_ru.json
|
cc2c01ee69a5a394c9d6dc87f77e08f05adf38a7 assets\create\lang\unfinished\ru_ru.json
|
||||||
ce16074d9dc5d504f2a91b164258f0059163260b assets\create\lang\unfinished\zh_cn.json
|
7a8b2739021d2e1d2b563f2bed3a201bd3f1b00f assets\create\lang\unfinished\zh_cn.json
|
||||||
846200eb548d3bfa2e77b41039de159b4b6cfb45 assets\create\models\block\acacia_window.json
|
846200eb548d3bfa2e77b41039de159b4b6cfb45 assets\create\models\block\acacia_window.json
|
||||||
1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets\create\models\block\acacia_window_pane_noside.json
|
1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets\create\models\block\acacia_window_pane_noside.json
|
||||||
1763ea2c9b981d187f5031ba608f3d5d3be3986a assets\create\models\block\acacia_window_pane_noside_alt.json
|
1763ea2c9b981d187f5031ba608f3d5d3be3986a assets\create\models\block\acacia_window_pane_noside_alt.json
|
||||||
@ -1365,10 +1365,12 @@ e4e3c1bd7ecf501b40cffc26d8ad145ab4e89118 data\create\advancements\deployer.json
|
|||||||
62f3610188f7dbd3900ab305edc2d06282705a38 data\create\advancements\goggles.json
|
62f3610188f7dbd3900ab305edc2d06282705a38 data\create\advancements\goggles.json
|
||||||
7e12b7ccb198ef0db7964b8cbef152d8347e333c data\create\advancements\its_alive.json
|
7e12b7ccb198ef0db7964b8cbef152d8347e333c data\create\advancements\its_alive.json
|
||||||
3d0fc63191ef507a018ef996ebf9406a523f3976 data\create\advancements\lava_wheel.json
|
3d0fc63191ef507a018ef996ebf9406a523f3976 data\create\advancements\lava_wheel.json
|
||||||
|
90393cdb6b699c9c0fd4dd9400159c3aa6911a6b data\create\advancements\mechanical_arm.json
|
||||||
786c2058805ceca3cd3970cc6e918560b54747f5 data\create\advancements\mechanical_drill.json
|
786c2058805ceca3cd3970cc6e918560b54747f5 data\create\advancements\mechanical_drill.json
|
||||||
41444ae151ce90d2d68dcda0ed3565f98509c594 data\create\advancements\mechanical_saw.json
|
41444ae151ce90d2d68dcda0ed3565f98509c594 data\create\advancements\mechanical_saw.json
|
||||||
9c7f0c2484a84ccf42166704475fafcb1f232ce6 data\create\advancements\millstone.json
|
9c7f0c2484a84ccf42166704475fafcb1f232ce6 data\create\advancements\millstone.json
|
||||||
704c7fc0ed357b1a116ffdc0b6c64fe64e337a5a data\create\advancements\mixer.json
|
704c7fc0ed357b1a116ffdc0b6c64fe64e337a5a data\create\advancements\mixer.json
|
||||||
|
8085b46ca0dd8c511841cabd88e51bff4baceefd data\create\advancements\musical_arm.json
|
||||||
a135eec618e448f440d9f42cc7a3e6c63fc45a71 data\create\advancements\overstressed.json
|
a135eec618e448f440d9f42cc7a3e6c63fc45a71 data\create\advancements\overstressed.json
|
||||||
72025d8bf73ab8096c29f12d0c8d9a346f09cd64 data\create\advancements\polished_rose_quartz.json
|
72025d8bf73ab8096c29f12d0c8d9a346f09cd64 data\create\advancements\polished_rose_quartz.json
|
||||||
1e3cd82e36fd4bcd053d652a0eead4458ed7f315 data\create\advancements\press.json
|
1e3cd82e36fd4bcd053d652a0eead4458ed7f315 data\create\advancements\press.json
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
{
|
{
|
||||||
"variants": {
|
"variants": {
|
||||||
"": {
|
"ceiling=false": {
|
||||||
"model": "create:block/mechanical_arm/block"
|
"model": "create:block/mechanical_arm/block"
|
||||||
|
},
|
||||||
|
"ceiling=true": {
|
||||||
|
"model": "create:block/mechanical_arm/block",
|
||||||
|
"x": 180
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -457,6 +457,10 @@
|
|||||||
"advancement.create.crafter.desc": "Place and power some Mechanical Crafters",
|
"advancement.create.crafter.desc": "Place and power some Mechanical Crafters",
|
||||||
"advancement.create.deployer": "Poke, Place, and Attack",
|
"advancement.create.deployer": "Poke, Place, and Attack",
|
||||||
"advancement.create.deployer.desc": "Place and power a Deployer, the perfect reflection of yourself.",
|
"advancement.create.deployer.desc": "Place and power a Deployer, the perfect reflection of yourself.",
|
||||||
|
"advancement.create.mechanical_arm": "Mechanical Grab'n'Drop",
|
||||||
|
"advancement.create.mechanical_arm.desc": "Craft a Mechanical Arm, select in- and outputs, place it down and give it power; then watch it do all the work for you.",
|
||||||
|
"advancement.create.musical_arm": "Play me my Theme Tune!",
|
||||||
|
"advancement.create.musical_arm.desc": "Watch a Mechanical Arm operate your Jukebox.",
|
||||||
"advancement.create.fist_bump": "Pound It, Bro!",
|
"advancement.create.fist_bump": "Pound It, Bro!",
|
||||||
"advancement.create.fist_bump.desc": "Make two Deployers fist-bump.",
|
"advancement.create.fist_bump.desc": "Make two Deployers fist-bump.",
|
||||||
"advancement.create.crushing_wheel": "A Pair of Giants",
|
"advancement.create.crushing_wheel": "A Pair of Giants",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_": "Missing Localizations: 777",
|
"_": "Missing Localizations: 781",
|
||||||
|
|
||||||
"_": "->------------------------] Game Elements [------------------------<-",
|
"_": "->------------------------] Game Elements [------------------------<-",
|
||||||
|
|
||||||
@ -458,6 +458,10 @@
|
|||||||
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
||||||
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
||||||
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
||||||
|
"advancement.create.mechanical_arm": "UNLOCALIZED: Mechanical Grab'n'Drop",
|
||||||
|
"advancement.create.mechanical_arm.desc": "UNLOCALIZED: Craft a Mechanical Arm, select in- and outputs, place it down and give it power; then watch it do all the work for you.",
|
||||||
|
"advancement.create.musical_arm": "UNLOCALIZED: Play me my Theme Tune!",
|
||||||
|
"advancement.create.musical_arm.desc": "UNLOCALIZED: Watch a Mechanical Arm operate your Jukebox.",
|
||||||
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
||||||
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
||||||
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_": "Missing Localizations: 380",
|
"_": "Missing Localizations: 384",
|
||||||
|
|
||||||
"_": "->------------------------] Game Elements [------------------------<-",
|
"_": "->------------------------] Game Elements [------------------------<-",
|
||||||
|
|
||||||
@ -458,6 +458,10 @@
|
|||||||
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
||||||
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
||||||
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
||||||
|
"advancement.create.mechanical_arm": "UNLOCALIZED: Mechanical Grab'n'Drop",
|
||||||
|
"advancement.create.mechanical_arm.desc": "UNLOCALIZED: Craft a Mechanical Arm, select in- and outputs, place it down and give it power; then watch it do all the work for you.",
|
||||||
|
"advancement.create.musical_arm": "UNLOCALIZED: Play me my Theme Tune!",
|
||||||
|
"advancement.create.musical_arm.desc": "UNLOCALIZED: Watch a Mechanical Arm operate your Jukebox.",
|
||||||
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
||||||
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
||||||
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_": "Missing Localizations: 364",
|
"_": "Missing Localizations: 368",
|
||||||
|
|
||||||
"_": "->------------------------] Game Elements [------------------------<-",
|
"_": "->------------------------] Game Elements [------------------------<-",
|
||||||
|
|
||||||
@ -458,6 +458,10 @@
|
|||||||
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
||||||
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
||||||
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
||||||
|
"advancement.create.mechanical_arm": "UNLOCALIZED: Mechanical Grab'n'Drop",
|
||||||
|
"advancement.create.mechanical_arm.desc": "UNLOCALIZED: Craft a Mechanical Arm, select in- and outputs, place it down and give it power; then watch it do all the work for you.",
|
||||||
|
"advancement.create.musical_arm": "UNLOCALIZED: Play me my Theme Tune!",
|
||||||
|
"advancement.create.musical_arm.desc": "UNLOCALIZED: Watch a Mechanical Arm operate your Jukebox.",
|
||||||
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
||||||
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
||||||
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_": "Missing Localizations: 359",
|
"_": "Missing Localizations: 363",
|
||||||
|
|
||||||
"_": "->------------------------] Game Elements [------------------------<-",
|
"_": "->------------------------] Game Elements [------------------------<-",
|
||||||
|
|
||||||
@ -458,6 +458,10 @@
|
|||||||
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
||||||
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
||||||
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
||||||
|
"advancement.create.mechanical_arm": "UNLOCALIZED: Mechanical Grab'n'Drop",
|
||||||
|
"advancement.create.mechanical_arm.desc": "UNLOCALIZED: Craft a Mechanical Arm, select in- and outputs, place it down and give it power; then watch it do all the work for you.",
|
||||||
|
"advancement.create.musical_arm": "UNLOCALIZED: Play me my Theme Tune!",
|
||||||
|
"advancement.create.musical_arm.desc": "UNLOCALIZED: Watch a Mechanical Arm operate your Jukebox.",
|
||||||
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
||||||
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
||||||
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_": "Missing Localizations: 364",
|
"_": "Missing Localizations: 368",
|
||||||
|
|
||||||
"_": "->------------------------] Game Elements [------------------------<-",
|
"_": "->------------------------] Game Elements [------------------------<-",
|
||||||
|
|
||||||
@ -458,6 +458,10 @@
|
|||||||
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
||||||
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
||||||
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
||||||
|
"advancement.create.mechanical_arm": "UNLOCALIZED: Mechanical Grab'n'Drop",
|
||||||
|
"advancement.create.mechanical_arm.desc": "UNLOCALIZED: Craft a Mechanical Arm, select in- and outputs, place it down and give it power; then watch it do all the work for you.",
|
||||||
|
"advancement.create.musical_arm": "UNLOCALIZED: Play me my Theme Tune!",
|
||||||
|
"advancement.create.musical_arm.desc": "UNLOCALIZED: Watch a Mechanical Arm operate your Jukebox.",
|
||||||
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
||||||
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
||||||
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_": "Missing Localizations: 714",
|
"_": "Missing Localizations: 718",
|
||||||
|
|
||||||
"_": "->------------------------] Game Elements [------------------------<-",
|
"_": "->------------------------] Game Elements [------------------------<-",
|
||||||
|
|
||||||
@ -458,6 +458,10 @@
|
|||||||
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
||||||
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
||||||
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
||||||
|
"advancement.create.mechanical_arm": "UNLOCALIZED: Mechanical Grab'n'Drop",
|
||||||
|
"advancement.create.mechanical_arm.desc": "UNLOCALIZED: Craft a Mechanical Arm, select in- and outputs, place it down and give it power; then watch it do all the work for you.",
|
||||||
|
"advancement.create.musical_arm": "UNLOCALIZED: Play me my Theme Tune!",
|
||||||
|
"advancement.create.musical_arm.desc": "UNLOCALIZED: Watch a Mechanical Arm operate your Jukebox.",
|
||||||
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
||||||
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
||||||
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_": "Missing Localizations: 784",
|
"_": "Missing Localizations: 788",
|
||||||
|
|
||||||
"_": "->------------------------] Game Elements [------------------------<-",
|
"_": "->------------------------] Game Elements [------------------------<-",
|
||||||
|
|
||||||
@ -458,6 +458,10 @@
|
|||||||
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
||||||
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
||||||
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
||||||
|
"advancement.create.mechanical_arm": "UNLOCALIZED: Mechanical Grab'n'Drop",
|
||||||
|
"advancement.create.mechanical_arm.desc": "UNLOCALIZED: Craft a Mechanical Arm, select in- and outputs, place it down and give it power; then watch it do all the work for you.",
|
||||||
|
"advancement.create.musical_arm": "UNLOCALIZED: Play me my Theme Tune!",
|
||||||
|
"advancement.create.musical_arm.desc": "UNLOCALIZED: Watch a Mechanical Arm operate your Jukebox.",
|
||||||
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
||||||
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
||||||
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_": "Missing Localizations: 778",
|
"_": "Missing Localizations: 782",
|
||||||
|
|
||||||
"_": "->------------------------] Game Elements [------------------------<-",
|
"_": "->------------------------] Game Elements [------------------------<-",
|
||||||
|
|
||||||
@ -458,6 +458,10 @@
|
|||||||
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
"advancement.create.crafter.desc": "UNLOCALIZED: Place and power some Mechanical Crafters",
|
||||||
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
"advancement.create.deployer": "UNLOCALIZED: Poke, Place, and Attack",
|
||||||
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
"advancement.create.deployer.desc": "UNLOCALIZED: Place and power a Deployer, the perfect reflection of yourself.",
|
||||||
|
"advancement.create.mechanical_arm": "UNLOCALIZED: Mechanical Grab'n'Drop",
|
||||||
|
"advancement.create.mechanical_arm.desc": "UNLOCALIZED: Craft a Mechanical Arm, select in- and outputs, place it down and give it power; then watch it do all the work for you.",
|
||||||
|
"advancement.create.musical_arm": "UNLOCALIZED: Play me my Theme Tune!",
|
||||||
|
"advancement.create.musical_arm.desc": "UNLOCALIZED: Watch a Mechanical Arm operate your Jukebox.",
|
||||||
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
"advancement.create.fist_bump": "UNLOCALIZED: Pound It, Bro!",
|
||||||
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
"advancement.create.fist_bump.desc": "UNLOCALIZED: Make two Deployers fist-bump.",
|
||||||
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
"advancement.create.crushing_wheel": "UNLOCALIZED: A Pair of Giants",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"_": "Missing Localizations: 40",
|
"_": "Missing Localizations: 44",
|
||||||
|
|
||||||
"_": "->------------------------] Game Elements [------------------------<-",
|
"_": "->------------------------] Game Elements [------------------------<-",
|
||||||
|
|
||||||
@ -458,6 +458,10 @@
|
|||||||
"advancement.create.crafter.desc": "放置一些机械合成台并且为其供能",
|
"advancement.create.crafter.desc": "放置一些机械合成台并且为其供能",
|
||||||
"advancement.create.deployer": "我就指着你了咋地?",
|
"advancement.create.deployer": "我就指着你了咋地?",
|
||||||
"advancement.create.deployer.desc": "放置并且功能一个机械手。这可是你右手的完美复制品",
|
"advancement.create.deployer.desc": "放置并且功能一个机械手。这可是你右手的完美复制品",
|
||||||
|
"advancement.create.mechanical_arm": "UNLOCALIZED: Mechanical Grab'n'Drop",
|
||||||
|
"advancement.create.mechanical_arm.desc": "UNLOCALIZED: Craft a Mechanical Arm, select in- and outputs, place it down and give it power; then watch it do all the work for you.",
|
||||||
|
"advancement.create.musical_arm": "UNLOCALIZED: Play me my Theme Tune!",
|
||||||
|
"advancement.create.musical_arm.desc": "UNLOCALIZED: Watch a Mechanical Arm operate your Jukebox.",
|
||||||
"advancement.create.fist_bump": "来碰个拳,哥们~",
|
"advancement.create.fist_bump": "来碰个拳,哥们~",
|
||||||
"advancement.create.fist_bump.desc": "使两个机械臂互相碰拳",
|
"advancement.create.fist_bump.desc": "使两个机械臂互相碰拳",
|
||||||
"advancement.create.crushing_wheel": "一对大家伙",
|
"advancement.create.crushing_wheel": "一对大家伙",
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"parent": "create:brass_casing",
|
||||||
|
"display": {
|
||||||
|
"icon": {
|
||||||
|
"item": "create:mechanical_arm"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"translate": "advancement.create.mechanical_arm"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"translate": "advancement.create.mechanical_arm.desc"
|
||||||
|
},
|
||||||
|
"frame": "goal",
|
||||||
|
"show_toast": true,
|
||||||
|
"announce_to_chat": true,
|
||||||
|
"hidden": false
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"0": {
|
||||||
|
"trigger": "minecraft:placed_block",
|
||||||
|
"conditions": {
|
||||||
|
"block": "create:mechanical_arm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"trigger": "create:kinetic_block",
|
||||||
|
"conditions": {
|
||||||
|
"block": "create:mechanical_arm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"trigger": "create:mechanical_arm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"0"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"2"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"parent": "create:mechanical_arm",
|
||||||
|
"display": {
|
||||||
|
"icon": {
|
||||||
|
"item": "minecraft:music_disc_13"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"translate": "advancement.create.musical_arm"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"translate": "advancement.create.musical_arm.desc"
|
||||||
|
},
|
||||||
|
"frame": "task",
|
||||||
|
"show_toast": true,
|
||||||
|
"announce_to_chat": true,
|
||||||
|
"hidden": false
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"0": {
|
||||||
|
"trigger": "minecraft:placed_block",
|
||||||
|
"conditions": {
|
||||||
|
"block": "create:mechanical_arm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"trigger": "create:kinetic_block",
|
||||||
|
"conditions": {
|
||||||
|
"block": "create:mechanical_arm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"trigger": "create:musical_arm"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"0"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"1"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"2"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -700,7 +700,11 @@ public class AllBlocks {
|
|||||||
|
|
||||||
public static final BlockEntry<ArmBlock> MECHANICAL_ARM = REGISTRATE.block("mechanical_arm", ArmBlock::new)
|
public static final BlockEntry<ArmBlock> MECHANICAL_ARM = REGISTRATE.block("mechanical_arm", ArmBlock::new)
|
||||||
.initialProperties(SharedProperties::softMetal)
|
.initialProperties(SharedProperties::softMetal)
|
||||||
.blockstate((c, p) -> p.simpleBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
|
.blockstate((c, p) -> p.getVariantBuilder(c.get())
|
||||||
|
.forAllStates(s -> ConfiguredModel.builder()
|
||||||
|
.modelFile(AssetLookup.partialBaseModel(c, p))
|
||||||
|
.rotationX(s.get(ArmBlock.CEILING) ? 180 : 0)
|
||||||
|
.build()))
|
||||||
.transform(StressConfigDefaults.setImpact(8.0))
|
.transform(StressConfigDefaults.setImpact(8.0))
|
||||||
.item(ArmItem::new)
|
.item(ArmItem::new)
|
||||||
.transform(customItemModel())
|
.transform(customItemModel())
|
||||||
|
@ -135,6 +135,8 @@ public class AllShapes {
|
|||||||
.build(),
|
.build(),
|
||||||
MECHANICAL_ARM = shape(2, 0, 2, 14, 10, 14).add(3, 0, 3, 13, 14, 13)
|
MECHANICAL_ARM = shape(2, 0, 2, 14, 10, 14).add(3, 0, 3, 13, 14, 13)
|
||||||
.build(),
|
.build(),
|
||||||
|
MECHANICAL_ARM_CEILING = shape(2, 6, 2, 14, 16, 14).add(3, 2, 3, 13, 16, 13)
|
||||||
|
.build(),
|
||||||
CHUTE = shape(1, 8, 1, 15, 16, 15).add(2, 0, 2, 14, 8, 14)
|
CHUTE = shape(1, 8, 1, 15, 16, 15).add(2, 0, 2, 14, 8, 14)
|
||||||
.build(),
|
.build(),
|
||||||
TANK = shape(1, 0, 1, 15, 16, 15).build(), TANK_TOP = shape(TANK_TOP_LID).add(TANK)
|
TANK = shape(1, 0, 1, 15, 16, 15).build(), TANK_TOP = shape(TANK_TOP_LID).add(TANK)
|
||||||
|
@ -118,6 +118,13 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
|
|||||||
return super.write(compound);
|
return super.write(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void lazyTick() {
|
||||||
|
super.lazyTick();
|
||||||
|
if (world.isRemote && running && !basinItemInv.isPresent())
|
||||||
|
updateBasin();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
@ -156,6 +163,8 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity {
|
|||||||
public void renderParticles() {
|
public void renderParticles() {
|
||||||
IItemHandler itemHandler = basinItemInv.orElse(null);
|
IItemHandler itemHandler = basinItemInv.orElse(null);
|
||||||
BasinInventory inv = (BasinInventory) itemHandler;
|
BasinInventory inv = (BasinInventory) itemHandler;
|
||||||
|
if (inv == null)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int slot = 0; slot < inv.getInputHandler()
|
for (int slot = 0; slot < inv.getInputHandler()
|
||||||
.getSlots(); slot++) {
|
.getSlots(); slot++) {
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
package com.simibubi.create.content.contraptions.fluids;
|
package com.simibubi.create.content.contraptions.fluids;
|
||||||
|
|
||||||
import net.minecraft.fluid.Fluid;
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.nbt.ListNBT;
|
import net.minecraft.nbt.ListNBT;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
@ -8,11 +13,6 @@ import net.minecraftforge.common.util.NonNullConsumer;
|
|||||||
import net.minecraftforge.fluids.FluidStack;
|
import net.minecraftforge.fluids.FluidStack;
|
||||||
import net.minecraftforge.fluids.capability.IFluidHandler;
|
import net.minecraftforge.fluids.capability.IFluidHandler;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.IntStream;
|
|
||||||
|
|
||||||
public class CombinedFluidHandler implements IFluidHandler {
|
public class CombinedFluidHandler implements IFluidHandler {
|
||||||
private final int capacity;
|
private final int capacity;
|
||||||
private final FluidStack[] tanks;
|
private final FluidStack[] tanks;
|
||||||
|
@ -147,8 +147,8 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
BlockState stateBelow = world.getBlockState(pos.down());
|
BlockState stateBelow = world.getBlockState(pos.down());
|
||||||
if (AllBlocks.BRASS_FUNNEL.has(stateBelow)) {
|
if (stateBelow.getBlock() instanceof FunnelBlock) {
|
||||||
if (stateBelow.get(BrassFunnelBlock.POWERED))
|
if (stateBelow.has(BrassFunnelBlock.POWERED) && stateBelow.get(BrassFunnelBlock.POWERED))
|
||||||
return false;
|
return false;
|
||||||
if (stateBelow.get(BrassFunnelBlock.FACING) != Direction.UP)
|
if (stateBelow.get(BrassFunnelBlock.FACING) != Direction.UP)
|
||||||
return false;
|
return false;
|
||||||
@ -187,9 +187,9 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||||||
|
|
||||||
private boolean handleUpwardOutput(boolean simulate) {
|
private boolean handleUpwardOutput(boolean simulate) {
|
||||||
BlockState stateAbove = world.getBlockState(pos.up());
|
BlockState stateAbove = world.getBlockState(pos.up());
|
||||||
if (AllBlocks.BRASS_FUNNEL.has(stateAbove)) {
|
if (stateAbove.getBlock() instanceof FunnelBlock) {
|
||||||
if (!stateAbove.get(BrassFunnelBlock.POWERED)
|
boolean powered = stateAbove.has(BrassFunnelBlock.POWERED) && stateAbove.get(BrassFunnelBlock.POWERED);
|
||||||
&& stateAbove.get(BrassFunnelBlock.FACING) == Direction.DOWN) {
|
if (!powered && stateAbove.get(BrassFunnelBlock.FACING) == Direction.DOWN) {
|
||||||
ItemStack remainder = FunnelBlock.tryInsert(world, pos.up(), item, simulate);
|
ItemStack remainder = FunnelBlock.tryInsert(world, pos.up(), item, simulate);
|
||||||
if (remainder.isEmpty()) {
|
if (remainder.isEmpty()) {
|
||||||
if (!simulate)
|
if (!simulate)
|
||||||
|
@ -4,6 +4,8 @@ import com.simibubi.create.AllBlocks;
|
|||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
|
|
||||||
public class AndesiteFunnelBlock extends FunnelBlock {
|
public class AndesiteFunnelBlock extends FunnelBlock {
|
||||||
|
|
||||||
@ -12,14 +14,14 @@ public class AndesiteFunnelBlock extends FunnelBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getEquivalentBeltFunnel(BlockState state) {
|
public BlockState getEquivalentBeltFunnel(IBlockReader world, BlockPos pos, BlockState state) {
|
||||||
Direction facing = state.get(FACING);
|
Direction facing = state.get(FACING);
|
||||||
return AllBlocks.ANDESITE_BELT_FUNNEL.getDefaultState()
|
return AllBlocks.ANDESITE_BELT_FUNNEL.getDefaultState()
|
||||||
.with(BeltFunnelBlock.HORIZONTAL_FACING, facing);
|
.with(BeltFunnelBlock.HORIZONTAL_FACING, facing);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getEquivalentChuteFunnel(BlockState state) {
|
public BlockState getEquivalentChuteFunnel(IBlockReader world, BlockPos pos, BlockState state) {
|
||||||
Direction facing = state.get(FACING);
|
Direction facing = state.get(FACING);
|
||||||
return AllBlocks.ANDESITE_CHUTE_FUNNEL.getDefaultState()
|
return AllBlocks.ANDESITE_CHUTE_FUNNEL.getDefaultState()
|
||||||
.with(ChuteFunnelBlock.HORIZONTAL_FACING, facing);
|
.with(ChuteFunnelBlock.HORIZONTAL_FACING, facing);
|
||||||
|
@ -23,7 +23,6 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.ILightReader;
|
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.IWorldReader;
|
import net.minecraft.world.IWorldReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
@ -55,9 +54,12 @@ public abstract class BeltFunnelBlock extends HorizontalInteractionFunnelBlock {
|
|||||||
@Override
|
@Override
|
||||||
public BlockState getStateForPlacement(BlockItemUseContext ctx) {
|
public BlockState getStateForPlacement(BlockItemUseContext ctx) {
|
||||||
BlockState state = super.getStateForPlacement(ctx);
|
BlockState state = super.getStateForPlacement(ctx);
|
||||||
World world = ctx.getWorld();
|
return getStateForPosition(ctx.getWorld(), ctx.getPos(), state, ctx.getFace());
|
||||||
BlockPos posBelow = ctx.getPos()
|
}
|
||||||
.down();
|
|
||||||
|
public BlockState getStateForPosition(World world, BlockPos pos, BlockState defaultState, Direction facing) {
|
||||||
|
BlockState state = defaultState.with(HORIZONTAL_FACING, facing);
|
||||||
|
BlockPos posBelow = pos.down();
|
||||||
BlockState stateBelow = world.getBlockState(posBelow);
|
BlockState stateBelow = world.getBlockState(posBelow);
|
||||||
if (!AllBlocks.BELT.has(stateBelow))
|
if (!AllBlocks.BELT.has(stateBelow))
|
||||||
return state;
|
return state;
|
||||||
@ -68,8 +70,7 @@ public abstract class BeltFunnelBlock extends HorizontalInteractionFunnelBlock {
|
|||||||
if (beltTileEntity.getSpeed() == 0)
|
if (beltTileEntity.getSpeed() == 0)
|
||||||
return state;
|
return state;
|
||||||
Direction movementFacing = beltTileEntity.getMovementFacing();
|
Direction movementFacing = beltTileEntity.getMovementFacing();
|
||||||
Direction funnelFacing = ctx.getFace();
|
return state.with(PUSHING, movementFacing == facing);
|
||||||
return state.with(PUSHING, movementFacing == funnelFacing);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -107,7 +108,7 @@ public abstract class BeltFunnelBlock extends HorizontalInteractionFunnelBlock {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockState updateShape(BlockState state, ILightReader world, BlockPos pos) {
|
public static BlockState updateShape(BlockState state, IBlockReader world, BlockPos pos) {
|
||||||
state = state.with(SHAPE, Shape.RETRACTED);
|
state = state.with(SHAPE, Shape.RETRACTED);
|
||||||
BlockState neighbour = world.getBlockState(pos.offset(state.get(HORIZONTAL_FACING)));
|
BlockState neighbour = world.getBlockState(pos.offset(state.get(HORIZONTAL_FACING)));
|
||||||
if (canConnectTo(state, neighbour))
|
if (canConnectTo(state, neighbour))
|
||||||
|
@ -10,6 +10,7 @@ import net.minecraft.state.StateContainer.Builder;
|
|||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class BrassFunnelBlock extends FunnelBlock {
|
public class BrassFunnelBlock extends FunnelBlock {
|
||||||
@ -48,7 +49,7 @@ public class BrassFunnelBlock extends FunnelBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getEquivalentBeltFunnel(BlockState state) {
|
public BlockState getEquivalentBeltFunnel(IBlockReader world, BlockPos pos, BlockState state) {
|
||||||
Direction facing = state.get(FACING);
|
Direction facing = state.get(FACING);
|
||||||
return AllBlocks.BRASS_BELT_FUNNEL.getDefaultState()
|
return AllBlocks.BRASS_BELT_FUNNEL.getDefaultState()
|
||||||
.with(BeltFunnelBlock.HORIZONTAL_FACING, facing)
|
.with(BeltFunnelBlock.HORIZONTAL_FACING, facing)
|
||||||
@ -56,7 +57,7 @@ public class BrassFunnelBlock extends FunnelBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockState getEquivalentChuteFunnel(BlockState state) {
|
public BlockState getEquivalentChuteFunnel(IBlockReader world, BlockPos pos, BlockState state) {
|
||||||
Direction facing = state.get(FACING);
|
Direction facing = state.get(FACING);
|
||||||
return AllBlocks.BRASS_CHUTE_FUNNEL.getDefaultState()
|
return AllBlocks.BRASS_CHUTE_FUNNEL.getDefaultState()
|
||||||
.with(ChuteFunnelBlock.HORIZONTAL_FACING, facing)
|
.with(ChuteFunnelBlock.HORIZONTAL_FACING, facing)
|
||||||
|
@ -61,7 +61,7 @@ public abstract class FunnelBlock extends ProperDirectionalBlock implements ITE<
|
|||||||
BlockRayTraceResult hit) {
|
BlockRayTraceResult hit) {
|
||||||
|
|
||||||
ItemStack heldItem = player.getHeldItem(handIn);
|
ItemStack heldItem = player.getHeldItem(handIn);
|
||||||
boolean shouldntInsertItem = AllBlocks.MECHANICAL_ARM.isIn(heldItem);
|
boolean shouldntInsertItem = AllBlocks.MECHANICAL_ARM.isIn(heldItem) || !canInsertIntoFunnel(state);
|
||||||
|
|
||||||
if (hit.getFace() == getFunnelFacing(state) && !shouldntInsertItem) {
|
if (hit.getFace() == getFunnelFacing(state) && !shouldntInsertItem) {
|
||||||
if (!worldIn.isRemote)
|
if (!worldIn.isRemote)
|
||||||
@ -144,17 +144,17 @@ public abstract class FunnelBlock extends ProperDirectionalBlock implements ITE<
|
|||||||
if (facing.getAxis()
|
if (facing.getAxis()
|
||||||
.isHorizontal()) {
|
.isHorizontal()) {
|
||||||
if (direction == Direction.DOWN) {
|
if (direction == Direction.DOWN) {
|
||||||
BlockState equivalentFunnel = getEquivalentBeltFunnel(state);
|
BlockState equivalentFunnel = getEquivalentBeltFunnel(null, null, state);
|
||||||
if (BeltFunnelBlock.isOnValidBelt(equivalentFunnel, world, pos))
|
if (BeltFunnelBlock.isOnValidBelt(equivalentFunnel, world, pos))
|
||||||
return equivalentFunnel;
|
return BeltFunnelBlock.updateShape(equivalentFunnel, world, pos);
|
||||||
}
|
}
|
||||||
if (direction == facing) {
|
if (direction == facing) {
|
||||||
BlockState equivalentFunnel = getEquivalentChuteFunnel(state);
|
BlockState equivalentFunnel = getEquivalentChuteFunnel(null, null, state);
|
||||||
if (ChuteFunnelBlock.isOnValidChute(equivalentFunnel, world, pos))
|
if (ChuteFunnelBlock.isOnValidChute(equivalentFunnel, world, pos))
|
||||||
return equivalentFunnel;
|
return equivalentFunnel;
|
||||||
}
|
}
|
||||||
if (direction == facing.getOpposite()) {
|
if (direction == facing.getOpposite()) {
|
||||||
BlockState equivalentFunnel = getEquivalentChuteFunnel(state);
|
BlockState equivalentFunnel = getEquivalentChuteFunnel(null, null, state);
|
||||||
if (ChuteFunnelBlock.isOnValidChute(equivalentFunnel, world, pos))
|
if (ChuteFunnelBlock.isOnValidChute(equivalentFunnel, world, pos))
|
||||||
return equivalentFunnel;
|
return equivalentFunnel;
|
||||||
}
|
}
|
||||||
@ -162,9 +162,9 @@ public abstract class FunnelBlock extends ProperDirectionalBlock implements ITE<
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract BlockState getEquivalentChuteFunnel(BlockState state);
|
public abstract BlockState getEquivalentChuteFunnel(IBlockReader world, BlockPos pos, BlockState state);
|
||||||
|
|
||||||
public abstract BlockState getEquivalentBeltFunnel(BlockState state);
|
public abstract BlockState getEquivalentBeltFunnel(IBlockReader world, BlockPos pos, BlockState state);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
|
public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
|
||||||
|
@ -29,6 +29,8 @@ public class FunnelItem extends BlockItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected BlockState getStateForPlacement(BlockItemUseContext ctx) {
|
protected BlockState getStateForPlacement(BlockItemUseContext ctx) {
|
||||||
|
World world = ctx.getWorld();
|
||||||
|
BlockPos pos = ctx.getPos();
|
||||||
BlockState state = super.getStateForPlacement(ctx);
|
BlockState state = super.getStateForPlacement(ctx);
|
||||||
if (state == null)
|
if (state == null)
|
||||||
return state;
|
return state;
|
||||||
@ -40,9 +42,9 @@ public class FunnelItem extends BlockItem {
|
|||||||
return state;
|
return state;
|
||||||
|
|
||||||
FunnelBlock block = (FunnelBlock) getBlock();
|
FunnelBlock block = (FunnelBlock) getBlock();
|
||||||
Block beltFunnelBlock = block.getEquivalentBeltFunnel(state)
|
Block beltFunnelBlock = block.getEquivalentBeltFunnel(world, pos, state)
|
||||||
.getBlock();
|
.getBlock();
|
||||||
Block chuteFunnelBlock = block.getEquivalentChuteFunnel(state)
|
Block chuteFunnelBlock = block.getEquivalentChuteFunnel(world, pos, state)
|
||||||
.getBlock();
|
.getBlock();
|
||||||
|
|
||||||
BlockState equivalentBeltFunnel = beltFunnelBlock.getStateForPlacement(ctx)
|
BlockState equivalentBeltFunnel = beltFunnelBlock.getStateForPlacement(ctx)
|
||||||
@ -52,8 +54,6 @@ public class FunnelItem extends BlockItem {
|
|||||||
BlockState reversedChuteFunnel = equivalentChuteFunnel.rotate(Rotation.CLOCKWISE_180)
|
BlockState reversedChuteFunnel = equivalentChuteFunnel.rotate(Rotation.CLOCKWISE_180)
|
||||||
.cycle(ChuteFunnelBlock.PUSHING);
|
.cycle(ChuteFunnelBlock.PUSHING);
|
||||||
|
|
||||||
World world = ctx.getWorld();
|
|
||||||
BlockPos pos = ctx.getPos();
|
|
||||||
if (BeltFunnelBlock.isOnValidBelt(equivalentBeltFunnel, world, pos))
|
if (BeltFunnelBlock.isOnValidBelt(equivalentBeltFunnel, world, pos))
|
||||||
return BeltFunnelBlock.updateShape(equivalentBeltFunnel, world, pos);
|
return BeltFunnelBlock.updateShape(equivalentBeltFunnel, world, pos);
|
||||||
if (ChuteFunnelBlock.isOnValidChute(equivalentChuteFunnel, world, pos))
|
if (ChuteFunnelBlock.isOnValidChute(equivalentChuteFunnel, world, pos))
|
||||||
|
@ -34,6 +34,7 @@ public class FunnelTileEntity extends SmartTileEntity {
|
|||||||
private FilteringBehaviour filtering;
|
private FilteringBehaviour filtering;
|
||||||
private InsertingBehaviour inserting;
|
private InsertingBehaviour inserting;
|
||||||
private ExtractingBehaviour extracting;
|
private ExtractingBehaviour extracting;
|
||||||
|
private DirectBeltInputBehaviour beltInputBehaviour;
|
||||||
|
|
||||||
int sendFlap;
|
int sendFlap;
|
||||||
InterpolatedChasingValue flap;
|
InterpolatedChasingValue flap;
|
||||||
@ -183,6 +184,15 @@ public class FunnelTileEntity extends SmartTileEntity {
|
|||||||
filtering.onlyActiveWhen(this::supportsFiltering);
|
filtering.onlyActiveWhen(this::supportsFiltering);
|
||||||
behaviours.add(filtering);
|
behaviours.add(filtering);
|
||||||
|
|
||||||
|
beltInputBehaviour = new DirectBeltInputBehaviour(this).onlyInsertWhen(this::supportsDirectBeltInput)
|
||||||
|
.setInsertionHandler(this::handleDirectBeltInput);
|
||||||
|
behaviours.add(beltInputBehaviour);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsDirectBeltInput(Direction side) {
|
||||||
|
BlockState blockState = getBlockState();
|
||||||
|
return blockState != null && blockState.getBlock() instanceof FunnelBlock
|
||||||
|
&& blockState.get(FunnelBlock.FACING) == Direction.UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean supportsFiltering() {
|
private boolean supportsFiltering() {
|
||||||
@ -190,6 +200,15 @@ public class FunnelTileEntity extends SmartTileEntity {
|
|||||||
return blockState != null && blockState.has(BlockStateProperties.POWERED);
|
return blockState != null && blockState.has(BlockStateProperties.POWERED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ItemStack handleDirectBeltInput(TransportedItemStack stack, Direction side, boolean simulate) {
|
||||||
|
ItemStack inserted = stack.stack;
|
||||||
|
if (!filtering.test(inserted))
|
||||||
|
return inserted;
|
||||||
|
if (determineCurrentMode() == Mode.PAUSED)
|
||||||
|
return inserted;
|
||||||
|
return inserting.insert(inserted, simulate);
|
||||||
|
}
|
||||||
|
|
||||||
public void flap(boolean inward) {
|
public void flap(boolean inward) {
|
||||||
sendFlap = inward ? 1 : -1;
|
sendFlap = inward ? 1 : -1;
|
||||||
sendData();
|
sendData();
|
||||||
|
@ -86,9 +86,12 @@ public abstract class HorizontalInteractionFunnelBlock extends HorizontalBlock i
|
|||||||
@Override
|
@Override
|
||||||
public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState neighbour, IWorld world,
|
public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState neighbour, IWorld world,
|
||||||
BlockPos pos, BlockPos p_196271_6_) {
|
BlockPos pos, BlockPos p_196271_6_) {
|
||||||
if (!canStillInteract(state, world, pos))
|
if (!canStillInteract(state, world, pos)) {
|
||||||
return parent.getDefaultState()
|
BlockState parentState = parent.getDefaultState();
|
||||||
.with(FunnelBlock.FACING, state.get(HORIZONTAL_FACING));
|
if (state.has(POWERED) && state.get(POWERED))
|
||||||
|
parentState = parentState.with(POWERED, true);
|
||||||
|
return parentState.with(FunnelBlock.FACING, state.get(HORIZONTAL_FACING));
|
||||||
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ public class CreativeCrateInventory implements IItemHandler {
|
|||||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||||
ItemStack filter = te.filter.getFilter().copy();
|
ItemStack filter = te.filter.getFilter().copy();
|
||||||
if (!filter.isEmpty())
|
if (!filter.isEmpty())
|
||||||
filter.setCount(amount);
|
filter.setCount(Math.min(filter.getMaxStackSize(), amount));
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,10 +24,13 @@ public class ArmAngleTarget {
|
|||||||
headAngle = -15;
|
headAngle = -15;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArmAngleTarget(BlockPos armPos, Vec3d pointTarget, Direction clawFacing) {
|
public ArmAngleTarget(BlockPos armPos, Vec3d pointTarget, Direction clawFacing, boolean ceiling) {
|
||||||
|
// if (ceiling)
|
||||||
|
// clawFacing = clawFacing.getOpposite();
|
||||||
|
|
||||||
Vec3d target = pointTarget;
|
Vec3d target = pointTarget;
|
||||||
Vec3d origin = VecHelper.getCenterOf(armPos)
|
Vec3d origin = VecHelper.getCenterOf(armPos)
|
||||||
.add(0, 4 / 16f, 0);
|
.add(0, ceiling ? -4 / 16f : 4 / 16f, 0);
|
||||||
Vec3d clawTarget = target;
|
Vec3d clawTarget = target;
|
||||||
target = target.add(new Vec3d(clawFacing.getOpposite()
|
target = target.add(new Vec3d(clawFacing.getOpposite()
|
||||||
.getDirectionVec()).scale(.5f));
|
.getDirectionVec()).scale(.5f));
|
||||||
@ -37,6 +40,11 @@ public class ArmAngleTarget {
|
|||||||
.length();
|
.length();
|
||||||
|
|
||||||
float baseAngle = AngleHelper.deg(MathHelper.atan2(diff.x, diff.z)) + 180;
|
float baseAngle = AngleHelper.deg(MathHelper.atan2(diff.x, diff.z)) + 180;
|
||||||
|
if (ceiling) {
|
||||||
|
diff = diff.mul(1, -1, 1);
|
||||||
|
baseAngle = 180 - baseAngle;
|
||||||
|
}
|
||||||
|
|
||||||
float alphaOffset = AngleHelper.deg(MathHelper.atan2(diff.y, horizontalDistance));
|
float alphaOffset = AngleHelper.deg(MathHelper.atan2(diff.y, horizontalDistance));
|
||||||
|
|
||||||
float a = 18 / 16f; // lower arm length
|
float a = 18 / 16f; // lower arm length
|
||||||
@ -61,8 +69,13 @@ public class ArmAngleTarget {
|
|||||||
headPos = VecHelper.rotate(headPos.add(0, b, 0), beta + 180, Axis.X);
|
headPos = VecHelper.rotate(headPos.add(0, b, 0), beta + 180, Axis.X);
|
||||||
headPos = VecHelper.rotate(headPos.add(0, a, 0), alpha - 90, Axis.X);
|
headPos = VecHelper.rotate(headPos.add(0, a, 0), alpha - 90, Axis.X);
|
||||||
headPos = VecHelper.rotate(headPos, baseAngle, Axis.Y);
|
headPos = VecHelper.rotate(headPos, baseAngle, Axis.Y);
|
||||||
|
headPos = VecHelper.rotate(headPos, ceiling ? 180 : 0, Axis.X);
|
||||||
headPos = headPos.add(origin);
|
headPos = headPos.add(origin);
|
||||||
Vec3d headDiff = clawTarget.subtract(headPos);
|
Vec3d headDiff = clawTarget.subtract(headPos);
|
||||||
|
|
||||||
|
if (ceiling)
|
||||||
|
headDiff = headDiff.mul(1, -1, 1);
|
||||||
|
|
||||||
float horizontalHeadDistance = (float) headDiff.mul(1, 0, 1)
|
float horizontalHeadDistance = (float) headDiff.mul(1, 0, 1)
|
||||||
.length();
|
.length();
|
||||||
float headAngle =
|
float headAngle =
|
||||||
|
@ -1,17 +1,24 @@
|
|||||||
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
|
|
||||||
import com.simibubi.create.AllShapes;
|
import com.simibubi.create.AllShapes;
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticBlock;
|
import com.simibubi.create.content.contraptions.base.KineticBlock;
|
||||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase;
|
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase;
|
||||||
import com.simibubi.create.foundation.block.ITE;
|
import com.simibubi.create.foundation.block.ITE;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.inventory.InventoryHelper;
|
import net.minecraft.inventory.InventoryHelper;
|
||||||
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.state.BooleanProperty;
|
||||||
|
import net.minecraft.state.StateContainer.Builder;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.ActionResultType;
|
import net.minecraft.util.ActionResultType;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@ -24,8 +31,21 @@ import net.minecraft.world.World;
|
|||||||
|
|
||||||
public class ArmBlock extends KineticBlock implements ITE<ArmTileEntity> {
|
public class ArmBlock extends KineticBlock implements ITE<ArmTileEntity> {
|
||||||
|
|
||||||
|
public static final BooleanProperty CEILING = BooleanProperty.create("ceiling");
|
||||||
|
|
||||||
public ArmBlock(Properties properties) {
|
public ArmBlock(Properties properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
|
setDefaultState(getDefaultState().with(CEILING, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void fillStateContainer(Builder<Block, BlockState> p_206840_1_) {
|
||||||
|
super.fillStateContainer(p_206840_1_.add(CEILING));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getStateForPlacement(BlockItemUseContext ctx) {
|
||||||
|
return getDefaultState().with(CEILING, ctx.getFace() == Direction.DOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -34,9 +54,9 @@ public class ArmBlock extends KineticBlock implements ITE<ArmTileEntity> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VoxelShape getShape(BlockState p_220053_1_, IBlockReader p_220053_2_, BlockPos p_220053_3_,
|
public VoxelShape getShape(BlockState state, IBlockReader p_220053_2_, BlockPos p_220053_3_,
|
||||||
ISelectionContext p_220053_4_) {
|
ISelectionContext p_220053_4_) {
|
||||||
return AllShapes.MECHANICAL_ARM;
|
return state.get(CEILING) ? AllShapes.MECHANICAL_ARM_CEILING : AllShapes.MECHANICAL_ARM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -70,18 +90,21 @@ public class ArmBlock extends KineticBlock implements ITE<ArmTileEntity> {
|
|||||||
@Override
|
@Override
|
||||||
public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player,
|
public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player,
|
||||||
Hand p_225533_5_, BlockRayTraceResult p_225533_6_) {
|
Hand p_225533_5_, BlockRayTraceResult p_225533_6_) {
|
||||||
if (world.isRemote)
|
MutableBoolean success = new MutableBoolean(false);
|
||||||
return ActionResultType.SUCCESS;
|
|
||||||
withTileEntityDo(world, pos, te -> {
|
withTileEntityDo(world, pos, te -> {
|
||||||
if (te.heldItem.isEmpty())
|
if (te.heldItem.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
success.setTrue();
|
||||||
|
if (world.isRemote)
|
||||||
|
return;
|
||||||
player.inventory.placeItemBackInInventory(world, te.heldItem);
|
player.inventory.placeItemBackInInventory(world, te.heldItem);
|
||||||
te.heldItem = ItemStack.EMPTY;
|
te.heldItem = ItemStack.EMPTY;
|
||||||
te.phase = Phase.SEARCH_INPUTS;
|
te.phase = Phase.SEARCH_INPUTS;
|
||||||
te.markDirty();
|
te.markDirty();
|
||||||
te.sendData();
|
te.sendData();
|
||||||
});
|
});
|
||||||
return ActionResultType.SUCCESS;
|
|
||||||
|
return success.booleanValue() ? ActionResultType.SUCCESS : ActionResultType.PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.content.contraptions.components.saw.SawBlock;
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock;
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock;
|
||||||
import com.simibubi.create.content.logistics.block.funnel.FunnelBlock;
|
import com.simibubi.create.content.logistics.block.funnel.FunnelBlock;
|
||||||
|
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InsertingBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InsertingBehaviour;
|
||||||
@ -14,9 +19,14 @@ import com.simibubi.create.foundation.utility.NBTHelper;
|
|||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.JukeboxBlock;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.nbt.NBTUtil;
|
import net.minecraft.nbt.NBTUtil;
|
||||||
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.tileentity.JukeboxTileEntity;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@ -43,6 +53,19 @@ public abstract class ArmInteractionPoint {
|
|||||||
private LazyOptional<IItemHandler> cachedHandler;
|
private LazyOptional<IItemHandler> cachedHandler;
|
||||||
private ArmAngleTarget cachedAngles;
|
private ArmAngleTarget cachedAngles;
|
||||||
|
|
||||||
|
private static ImmutableMap<ArmInteractionPoint, Supplier<ArmInteractionPoint>> POINTS =
|
||||||
|
ImmutableMap.<ArmInteractionPoint, Supplier<ArmInteractionPoint>>builder()
|
||||||
|
.put(new Belt(), Belt::new)
|
||||||
|
.put(new Depot(), Depot::new)
|
||||||
|
.put(new Saw(), Saw::new)
|
||||||
|
.put(new Chute(), Chute::new)
|
||||||
|
.put(new Jukebox(), Jukebox::new)
|
||||||
|
.put(new Basin(), Basin::new)
|
||||||
|
.put(new Millstone(), Millstone::new)
|
||||||
|
.put(new Funnel(), Funnel::new)
|
||||||
|
.put(new CrushingWheels(), CrushingWheels::new)
|
||||||
|
.build();
|
||||||
|
|
||||||
public ArmInteractionPoint() {
|
public ArmInteractionPoint() {
|
||||||
cachedHandler = LazyOptional.empty();
|
cachedHandler = LazyOptional.empty();
|
||||||
}
|
}
|
||||||
@ -66,16 +89,19 @@ public abstract class ArmInteractionPoint {
|
|||||||
return Direction.DOWN;
|
return Direction.DOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract boolean isValid(BlockState state);
|
abstract boolean isValid(IBlockReader reader, BlockPos pos, BlockState state);
|
||||||
|
|
||||||
static boolean isInteractable(BlockState state) {
|
static boolean isInteractable(IBlockReader reader, BlockPos pos, BlockState state) {
|
||||||
return AllBlocks.DEPOT.has(state) || AllBlocks.BELT.has(state) || AllBlocks.CHUTE.has(state)
|
for (ArmInteractionPoint armInteractionPoint : POINTS.keySet())
|
||||||
|| state.getBlock() instanceof FunnelBlock;
|
if (armInteractionPoint.isValid(reader, pos, state))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArmAngleTarget getTargetAngles(BlockPos armPos) {
|
ArmAngleTarget getTargetAngles(BlockPos armPos, boolean ceiling) {
|
||||||
if (cachedAngles == null)
|
if (cachedAngles == null)
|
||||||
cachedAngles = new ArmAngleTarget(armPos, getInteractionPositionVector(), getInteractionDirection());
|
cachedAngles =
|
||||||
|
new ArmAngleTarget(armPos, getInteractionPositionVector(), getInteractionDirection(), ceiling);
|
||||||
return cachedAngles;
|
return cachedAngles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,15 +146,10 @@ public abstract class ArmInteractionPoint {
|
|||||||
BlockState state = world.getBlockState(pos);
|
BlockState state = world.getBlockState(pos);
|
||||||
ArmInteractionPoint point = null;
|
ArmInteractionPoint point = null;
|
||||||
|
|
||||||
if (AllBlocks.DEPOT.has(state))
|
for (ArmInteractionPoint armInteractionPoint : POINTS.keySet())
|
||||||
point = new Depot();
|
if (armInteractionPoint.isValid(world, pos, state))
|
||||||
if (AllBlocks.BELT.has(state) && !(world.getBlockState(pos.up())
|
point = POINTS.get(armInteractionPoint)
|
||||||
.getBlock() instanceof BeltTunnelBlock))
|
.get();
|
||||||
point = new Belt();
|
|
||||||
if (AllBlocks.CHUTE.has(state))
|
|
||||||
point = new Chute();
|
|
||||||
if (state.getBlock() instanceof FunnelBlock)
|
|
||||||
point = new Funnel();
|
|
||||||
|
|
||||||
if (point != null) {
|
if (point != null) {
|
||||||
point.state = state;
|
point.state = state;
|
||||||
@ -155,6 +176,15 @@ public abstract class ArmInteractionPoint {
|
|||||||
return interactionPoint;
|
return interactionPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static abstract class TopFaceArmInteractionPoint extends ArmInteractionPoint {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Vec3d getInteractionPositionVector() {
|
||||||
|
return new Vec3d(pos).add(.5f, 1, .5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static class Depot extends ArmInteractionPoint {
|
static class Depot extends ArmInteractionPoint {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -163,29 +193,117 @@ public abstract class ArmInteractionPoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isValid(BlockState state) {
|
boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
|
||||||
return AllBlocks.DEPOT.has(state);
|
return AllBlocks.DEPOT.has(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class Saw extends Depot {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.MECHANICAL_SAW.has(state) && state.get(SawBlock.RUNNING)
|
||||||
|
&& state.get(SawBlock.FACING) == Direction.UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Millstone extends ArmInteractionPoint {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.MILLSTONE.has(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class CrushingWheels extends TopFaceArmInteractionPoint {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.CRUSHING_WHEEL_CONTROLLER.has(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Basin extends ArmInteractionPoint {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
|
||||||
|
return AllBlocks.BASIN.has(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Jukebox extends TopFaceArmInteractionPoint {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
|
||||||
|
return state.getBlock() instanceof JukeboxBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
int getSlotCount(World world) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
ItemStack insert(World world, ItemStack stack, boolean simulate) {
|
||||||
|
TileEntity tileEntity = world.getTileEntity(pos);
|
||||||
|
if (!(tileEntity instanceof JukeboxTileEntity))
|
||||||
|
return stack;
|
||||||
|
if (!(state.getBlock() instanceof JukeboxBlock))
|
||||||
|
return stack;
|
||||||
|
JukeboxBlock jukeboxBlock = (JukeboxBlock) state.getBlock();
|
||||||
|
JukeboxTileEntity jukeboxTE = (JukeboxTileEntity) tileEntity;
|
||||||
|
if (!jukeboxTE.getRecord()
|
||||||
|
.isEmpty())
|
||||||
|
return stack;
|
||||||
|
ItemStack remainder = stack.copy();
|
||||||
|
ItemStack toInsert = remainder.split(1);
|
||||||
|
if (!simulate && !world.isRemote) {
|
||||||
|
jukeboxBlock.insertRecord(world, pos, state, toInsert);
|
||||||
|
world.playEvent((PlayerEntity) null, 1010, pos, Item.getIdFromItem(toInsert.getItem()));
|
||||||
|
AllTriggers.triggerForNearbyPlayers(AllTriggers.MUSICAL_ARM, world, pos, 10);
|
||||||
|
}
|
||||||
|
return remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
ItemStack extract(World world, int slot, int amount, boolean simulate) {
|
||||||
|
TileEntity tileEntity = world.getTileEntity(pos);
|
||||||
|
if (!(tileEntity instanceof JukeboxTileEntity))
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
if (!(state.getBlock() instanceof JukeboxBlock))
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
JukeboxTileEntity jukeboxTE = (JukeboxTileEntity) tileEntity;
|
||||||
|
ItemStack itemstack = jukeboxTE.getRecord();
|
||||||
|
if (itemstack.isEmpty())
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
if (!simulate && !world.isRemote) {
|
||||||
|
world.playEvent(1010, pos, 0);
|
||||||
|
jukeboxTE.clear();
|
||||||
|
world.setBlockState(pos, state.with(JukeboxBlock.HAS_RECORD, false), 2);
|
||||||
|
}
|
||||||
|
return itemstack;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static class Belt extends Depot {
|
static class Belt extends Depot {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isValid(BlockState state) {
|
boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
|
||||||
return AllBlocks.BELT.has(state);
|
return AllBlocks.BELT.has(state) && !(reader.getBlockState(pos.up())
|
||||||
|
.getBlock() instanceof BeltTunnelBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Chute extends ArmInteractionPoint {
|
static class Chute extends TopFaceArmInteractionPoint {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Vec3d getInteractionPositionVector() {
|
boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
|
||||||
return new Vec3d(pos).add(.5f, 1, .5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean isValid(BlockState state) {
|
|
||||||
return AllBlocks.CHUTE.has(state);
|
return AllBlocks.CHUTE.has(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,6 +337,9 @@ public abstract class ArmInteractionPoint {
|
|||||||
ItemStack insert(World world, ItemStack stack, boolean simulate) {
|
ItemStack insert(World world, ItemStack stack, boolean simulate) {
|
||||||
FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
||||||
InsertingBehaviour inserter = TileEntityBehaviour.get(world, pos, InsertingBehaviour.TYPE);
|
InsertingBehaviour inserter = TileEntityBehaviour.get(world, pos, InsertingBehaviour.TYPE);
|
||||||
|
BlockState state = world.getBlockState(pos);
|
||||||
|
if (state.has(BlockStateProperties.POWERED) && state.get(BlockStateProperties.POWERED))
|
||||||
|
return stack;
|
||||||
if (inserter == null)
|
if (inserter == null)
|
||||||
return stack;
|
return stack;
|
||||||
if (filtering != null && !filtering.test(stack))
|
if (filtering != null && !filtering.test(stack))
|
||||||
@ -227,7 +348,7 @@ public abstract class ArmInteractionPoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean isValid(BlockState state) {
|
boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
|
||||||
return state.getBlock() instanceof FunnelBlock;
|
return state.getBlock() instanceof FunnelBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
package com.simibubi.create.content.logistics.block.mechanicalArm;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.List;
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
@ -30,7 +30,7 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
|||||||
@EventBusSubscriber(value = Dist.CLIENT)
|
@EventBusSubscriber(value = Dist.CLIENT)
|
||||||
public class ArmInteractionPointHandler {
|
public class ArmInteractionPointHandler {
|
||||||
|
|
||||||
static Map<BlockPos, ArmInteractionPoint> currentSelection = new HashMap<>();
|
static List<ArmInteractionPoint> currentSelection = new ArrayList<>();
|
||||||
static ItemStack currentItem;
|
static ItemStack currentItem;
|
||||||
|
|
||||||
static long lastBlockPos = -1;
|
static long lastBlockPos = -1;
|
||||||
@ -44,15 +44,17 @@ public class ArmInteractionPointHandler {
|
|||||||
if (!world.isRemote)
|
if (!world.isRemote)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!currentSelection.containsKey(pos)) {
|
ArmInteractionPoint selected = getSelected(pos);
|
||||||
|
|
||||||
|
if (selected == null) {
|
||||||
ArmInteractionPoint point = ArmInteractionPoint.createAt(world, pos);
|
ArmInteractionPoint point = ArmInteractionPoint.createAt(world, pos);
|
||||||
if (point == null)
|
if (point == null)
|
||||||
return;
|
return;
|
||||||
currentSelection.put(pos, point);
|
selected = point;
|
||||||
|
put(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentSelection.get(pos)
|
selected.cycleMode();
|
||||||
.cycleMode();
|
|
||||||
event.setCanceled(true);
|
event.setCanceled(true);
|
||||||
event.setCancellationResult(ActionResultType.SUCCESS);
|
event.setCancellationResult(ActionResultType.SUCCESS);
|
||||||
}
|
}
|
||||||
@ -64,7 +66,7 @@ public class ArmInteractionPointHandler {
|
|||||||
if (!event.getWorld().isRemote)
|
if (!event.getWorld().isRemote)
|
||||||
return;
|
return;
|
||||||
BlockPos pos = event.getPos();
|
BlockPos pos = event.getPos();
|
||||||
if (currentSelection.remove(pos) != null) {
|
if (remove(pos) != null) {
|
||||||
event.setCanceled(true);
|
event.setCanceled(true);
|
||||||
event.setCancellationResult(ActionResultType.SUCCESS);
|
event.setCancellationResult(ActionResultType.SUCCESS);
|
||||||
}
|
}
|
||||||
@ -73,7 +75,7 @@ public class ArmInteractionPointHandler {
|
|||||||
public static void flushSettings(BlockPos pos) {
|
public static void flushSettings(BlockPos pos) {
|
||||||
if (currentItem == null)
|
if (currentItem == null)
|
||||||
return;
|
return;
|
||||||
AllPackets.channel.sendToServer(new ArmPlacementPacket(currentSelection.values(), pos));
|
AllPackets.channel.sendToServer(new ArmPlacementPacket(currentSelection, pos));
|
||||||
currentSelection.clear();
|
currentSelection.clear();
|
||||||
currentItem = null;
|
currentItem = null;
|
||||||
}
|
}
|
||||||
@ -122,8 +124,8 @@ public class ArmInteractionPointHandler {
|
|||||||
if (lastBlockPos == -1 || lastBlockPos != pos.toLong()) {
|
if (lastBlockPos == -1 || lastBlockPos != pos.toLong()) {
|
||||||
currentSelection.clear();
|
currentSelection.clear();
|
||||||
ArmTileEntity arm = (ArmTileEntity) te;
|
ArmTileEntity arm = (ArmTileEntity) te;
|
||||||
arm.inputs.forEach(point -> currentSelection.put(point.pos, point));
|
arm.inputs.forEach(ArmInteractionPointHandler::put);
|
||||||
arm.outputs.forEach(point -> currentSelection.put(point.pos, point));
|
arm.outputs.forEach(ArmInteractionPointHandler::put);
|
||||||
lastBlockPos = pos.toLong();
|
lastBlockPos = pos.toLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,16 +134,14 @@ public class ArmInteractionPointHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void drawOutlines(Map<BlockPos, ArmInteractionPoint> selection) {
|
private static void drawOutlines(Collection<ArmInteractionPoint> selection) {
|
||||||
World world = Minecraft.getInstance().world;
|
World world = Minecraft.getInstance().world;
|
||||||
for (Iterator<Entry<BlockPos, ArmInteractionPoint>> iterator = selection.entrySet()
|
for (Iterator<ArmInteractionPoint> iterator = selection.iterator(); iterator.hasNext();) {
|
||||||
.iterator(); iterator.hasNext();) {
|
ArmInteractionPoint point = iterator.next();
|
||||||
Entry<BlockPos, ArmInteractionPoint> entry = iterator.next();
|
BlockPos pos = point.pos;
|
||||||
BlockPos pos = entry.getKey();
|
|
||||||
BlockState state = world.getBlockState(pos);
|
BlockState state = world.getBlockState(pos);
|
||||||
ArmInteractionPoint point = entry.getValue();
|
|
||||||
|
|
||||||
if (!point.isValid(state)) {
|
if (!point.isValid(world, pos, state)) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -158,4 +158,23 @@ public class ArmInteractionPointHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void put(ArmInteractionPoint point) {
|
||||||
|
currentSelection.add(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ArmInteractionPoint remove(BlockPos pos) {
|
||||||
|
ArmInteractionPoint result = getSelected(pos);
|
||||||
|
if (result != null)
|
||||||
|
currentSelection.remove(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ArmInteractionPoint getSelected(BlockPos pos) {
|
||||||
|
for (ArmInteractionPoint point : currentSelection) {
|
||||||
|
if (point.pos.equals(pos))
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,9 @@ public class ArmItem extends BlockItem {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionResultType onItemUse(ItemUseContext ctx) {
|
public ActionResultType onItemUse(ItemUseContext ctx) {
|
||||||
if (ArmInteractionPoint.isInteractable(ctx.getWorld()
|
World world = ctx.getWorld();
|
||||||
.getBlockState(ctx.getPos())))
|
BlockPos pos = ctx.getPos();
|
||||||
|
if (ArmInteractionPoint.isInteractable(world, pos, world.getBlockState(pos)))
|
||||||
return ActionResultType.SUCCESS;
|
return ActionResultType.SUCCESS;
|
||||||
return super.onItemUse(ctx);
|
return super.onItemUse(ctx);
|
||||||
}
|
}
|
||||||
@ -37,9 +38,9 @@ public class ArmItem extends BlockItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPlayerBreakBlockWhileHolding(BlockState state, World p_195938_2_, BlockPos p_195938_3_,
|
public boolean canPlayerBreakBlockWhileHolding(BlockState state, World world, BlockPos pos,
|
||||||
PlayerEntity p_195938_4_) {
|
PlayerEntity p_195938_4_) {
|
||||||
return !ArmInteractionPoint.isInteractable(state);
|
return !ArmInteractionPoint.isInteractable(world, pos, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,9 @@ import com.mojang.blaze3d.vertex.IVertexBuilder;
|
|||||||
import com.simibubi.create.AllBlockPartials;
|
import com.simibubi.create.AllBlockPartials;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||||
|
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase;
|
||||||
|
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||||
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
import com.simibubi.create.foundation.utility.SuperByteBuffer;
|
||||||
@ -18,6 +21,7 @@ import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
|||||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||||
import net.minecraft.item.BlockItem;
|
import net.minecraft.item.BlockItem;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
|
||||||
public class ArmRenderer extends KineticTileEntityRenderer {
|
public class ArmRenderer extends KineticTileEntityRenderer {
|
||||||
|
|
||||||
@ -35,6 +39,21 @@ public class ArmRenderer extends KineticTileEntityRenderer {
|
|||||||
MatrixStacker msr = MatrixStacker.of(ms);
|
MatrixStacker msr = MatrixStacker.of(ms);
|
||||||
int color = 0xFFFFFF;
|
int color = 0xFFFFFF;
|
||||||
|
|
||||||
|
float baseAngle = arm.baseAngle.get(pt);
|
||||||
|
float lowerArmAngle = arm.lowerArmAngle.get(pt) - 135;
|
||||||
|
float upperArmAngle = arm.upperArmAngle.get(pt) - 90;
|
||||||
|
float headAngle = arm.headAngle.get(pt);
|
||||||
|
|
||||||
|
boolean rave = te instanceof ArmTileEntity && ((ArmTileEntity) te).phase == Phase.DANCING;
|
||||||
|
float renderTick = AnimationTickHolder.getRenderTick() + (te.hashCode() % 64);
|
||||||
|
if (rave) {
|
||||||
|
baseAngle = (renderTick * 10) % 360;
|
||||||
|
lowerArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 4) + 1) / 2, -45, 15);
|
||||||
|
upperArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 8) + 1) / 4, -45, 95);
|
||||||
|
headAngle = -lowerArmAngle;
|
||||||
|
color = ColorHelper.rainbowColor(AnimationTickHolder.ticks * 100);
|
||||||
|
}
|
||||||
|
|
||||||
ms.push();
|
ms.push();
|
||||||
|
|
||||||
SuperByteBuffer base = AllBlockPartials.ARM_BASE.renderOn(blockState).light(light);
|
SuperByteBuffer base = AllBlockPartials.ARM_BASE.renderOn(blockState).light(light);
|
||||||
@ -46,23 +65,26 @@ public class ArmRenderer extends KineticTileEntityRenderer {
|
|||||||
|
|
||||||
msr.centre();
|
msr.centre();
|
||||||
|
|
||||||
|
if (blockState.get(ArmBlock.CEILING))
|
||||||
|
msr.rotateX(180);
|
||||||
|
|
||||||
ms.translate(0, 4 / 16d, 0);
|
ms.translate(0, 4 / 16d, 0);
|
||||||
msr.rotateY(arm.baseAngle.get(pt));
|
msr.rotateY(baseAngle);
|
||||||
base.renderInto(ms, builder);
|
base.renderInto(ms, builder);
|
||||||
|
|
||||||
ms.translate(0, 1 / 16d, -2 / 16d);
|
ms.translate(0, 1 / 16d, -2 / 16d);
|
||||||
msr.rotateX(arm.lowerArmAngle.get(pt) - 135);
|
msr.rotateX(lowerArmAngle);
|
||||||
ms.translate(0, -1 / 16d, 0);
|
ms.translate(0, -1 / 16d, 0);
|
||||||
lowerBody.color(color)
|
lowerBody.color(color)
|
||||||
.renderInto(ms, builder);
|
.renderInto(ms, builder);
|
||||||
|
|
||||||
ms.translate(0, 12 / 16d, 12 / 16d);
|
ms.translate(0, 12 / 16d, 12 / 16d);
|
||||||
msr.rotateX(arm.upperArmAngle.get(pt) - 90);
|
msr.rotateX(upperArmAngle);
|
||||||
upperBody.color(color)
|
upperBody.color(color)
|
||||||
.renderInto(ms, builder);
|
.renderInto(ms, builder);
|
||||||
|
|
||||||
ms.translate(0, 11 / 16d, -11 / 16d);
|
ms.translate(0, 11 / 16d, -11 / 16d);
|
||||||
msr.rotateX(arm.headAngle.get(pt));
|
msr.rotateX(headAngle);
|
||||||
head.renderInto(ms, builder);
|
head.renderInto(ms, builder);
|
||||||
|
|
||||||
ms.translate(0, 0, -4 / 16d);
|
ms.translate(0, 0, -4 / 16d);
|
||||||
|
@ -6,11 +6,15 @@ import java.util.List;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
|
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Jukebox;
|
||||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode;
|
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode;
|
||||||
|
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||||
import com.simibubi.create.foundation.gui.widgets.InterpolatedAngle;
|
import com.simibubi.create.foundation.gui.widgets.InterpolatedAngle;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.JukeboxBlock;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.nbt.INBT;
|
import net.minecraft.nbt.INBT;
|
||||||
@ -43,7 +47,7 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||||||
boolean updateInteractionPoints;
|
boolean updateInteractionPoints;
|
||||||
|
|
||||||
enum Phase {
|
enum Phase {
|
||||||
SEARCH_INPUTS, MOVE_TO_INPUT, SEARCH_OUTPUTS, MOVE_TO_OUTPUT, IDLE
|
SEARCH_INPUTS, MOVE_TO_INPUT, SEARCH_OUTPUTS, MOVE_TO_OUTPUT, DANCING
|
||||||
}
|
}
|
||||||
|
|
||||||
public ArmTileEntity(TileEntityType<?> typeIn) {
|
public ArmTileEntity(TileEntityType<?> typeIn) {
|
||||||
@ -86,12 +90,34 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||||||
return;
|
return;
|
||||||
if (chasedPointProgress < .5f)
|
if (chasedPointProgress < .5f)
|
||||||
return;
|
return;
|
||||||
if (phase == Phase.SEARCH_INPUTS)
|
if (phase == Phase.SEARCH_INPUTS || phase == Phase.DANCING) {
|
||||||
|
checkForMusic();
|
||||||
searchForItem();
|
searchForItem();
|
||||||
|
}
|
||||||
if (phase == Phase.SEARCH_OUTPUTS)
|
if (phase == Phase.SEARCH_OUTPUTS)
|
||||||
searchForDestination();
|
searchForDestination();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkForMusic() {
|
||||||
|
boolean hasMusic = checkForMusicAmong(inputs) || checkForMusicAmong(outputs);
|
||||||
|
if (hasMusic != (phase == Phase.DANCING)) {
|
||||||
|
phase = hasMusic ? Phase.DANCING : Phase.SEARCH_INPUTS;
|
||||||
|
markDirty();
|
||||||
|
sendData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkForMusicAmong(List<ArmInteractionPoint> list) {
|
||||||
|
for (ArmInteractionPoint armInteractionPoint : list) {
|
||||||
|
if (!(armInteractionPoint instanceof Jukebox))
|
||||||
|
continue;
|
||||||
|
BlockState state = world.getBlockState(armInteractionPoint.pos);
|
||||||
|
if (state.has(JukeboxBlock.HAS_RECORD) && state.get(JukeboxBlock.HAS_RECORD))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void tickMovementProgress() {
|
private void tickMovementProgress() {
|
||||||
chasedPointProgress += Math.min(256, Math.abs(getSpeed())) / 1024f;
|
chasedPointProgress += Math.min(256, Math.abs(getSpeed())) / 1024f;
|
||||||
if (chasedPointProgress > 1)
|
if (chasedPointProgress > 1)
|
||||||
@ -101,8 +127,8 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||||||
|
|
||||||
ArmInteractionPoint targetedInteractionPoint = getTargetedInteractionPoint();
|
ArmInteractionPoint targetedInteractionPoint = getTargetedInteractionPoint();
|
||||||
ArmAngleTarget previousTarget = this.previousTarget;
|
ArmAngleTarget previousTarget = this.previousTarget;
|
||||||
ArmAngleTarget target =
|
ArmAngleTarget target = targetedInteractionPoint == null ? ArmAngleTarget.NO_TARGET
|
||||||
targetedInteractionPoint == null ? ArmAngleTarget.NO_TARGET : targetedInteractionPoint.getTargetAngles(pos);
|
: targetedInteractionPoint.getTargetAngles(pos, isOnCeiling());
|
||||||
|
|
||||||
baseAngle.set(AngleHelper.angleLerp(chasedPointProgress, previousBaseAngle,
|
baseAngle.set(AngleHelper.angleLerp(chasedPointProgress, previousBaseAngle,
|
||||||
target == ArmAngleTarget.NO_TARGET ? previousBaseAngle : target.baseAngle));
|
target == ArmAngleTarget.NO_TARGET ? previousBaseAngle : target.baseAngle));
|
||||||
@ -116,7 +142,13 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||||||
|
|
||||||
lowerArmAngle.set(MathHelper.lerp(progress, previousTarget.lowerArmAngle, target.lowerArmAngle));
|
lowerArmAngle.set(MathHelper.lerp(progress, previousTarget.lowerArmAngle, target.lowerArmAngle));
|
||||||
upperArmAngle.set(MathHelper.lerp(progress, previousTarget.upperArmAngle, target.upperArmAngle));
|
upperArmAngle.set(MathHelper.lerp(progress, previousTarget.upperArmAngle, target.upperArmAngle));
|
||||||
headAngle.set(AngleHelper.angleLerp(progress, previousTarget.headAngle, target.headAngle));
|
|
||||||
|
headAngle.set(AngleHelper.angleLerp(progress, previousTarget.headAngle % 360, target.headAngle % 360));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isOnCeiling() {
|
||||||
|
BlockState state = getBlockState();
|
||||||
|
return hasWorld() && state != null && state.has(ArmBlock.CEILING) && state.get(ArmBlock.CEILING);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -182,6 +214,9 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||||||
chasedPointIndex = -1;
|
chasedPointIndex = -1;
|
||||||
sendData();
|
sendData();
|
||||||
markDirty();
|
markDirty();
|
||||||
|
|
||||||
|
if (!world.isRemote)
|
||||||
|
AllTriggers.triggerForNearbyPlayers(AllTriggers.MECHANICAL_ARM, world, pos, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void collectItem() {
|
protected void collectItem() {
|
||||||
@ -277,9 +312,9 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||||||
int previousIndex = chasedPointIndex;
|
int previousIndex = chasedPointIndex;
|
||||||
Phase previousPhase = phase;
|
Phase previousPhase = phase;
|
||||||
ListNBT interactionPointTagBefore = interactionPointTag;
|
ListNBT interactionPointTagBefore = interactionPointTag;
|
||||||
|
|
||||||
super.readClientUpdate(tag);
|
super.readClientUpdate(tag);
|
||||||
|
|
||||||
|
boolean ceiling = isOnCeiling();
|
||||||
if (interactionPointTagBefore == null || interactionPointTagBefore.size() != interactionPointTag.size())
|
if (interactionPointTagBefore == null || interactionPointTagBefore.size() != interactionPointTag.size())
|
||||||
updateInteractionPoints = true;
|
updateInteractionPoints = true;
|
||||||
if (previousIndex != chasedPointIndex || (previousPhase != phase)) {
|
if (previousIndex != chasedPointIndex || (previousPhase != phase)) {
|
||||||
@ -288,9 +323,10 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||||||
previousPoint = inputs.get(previousIndex);
|
previousPoint = inputs.get(previousIndex);
|
||||||
if (previousPhase == Phase.MOVE_TO_OUTPUT && previousIndex < outputs.size())
|
if (previousPhase == Phase.MOVE_TO_OUTPUT && previousIndex < outputs.size())
|
||||||
previousPoint = outputs.get(previousIndex);
|
previousPoint = outputs.get(previousIndex);
|
||||||
previousTarget = previousPoint == null ? ArmAngleTarget.NO_TARGET : previousPoint.getTargetAngles(pos);
|
previousTarget =
|
||||||
|
previousPoint == null ? ArmAngleTarget.NO_TARGET : previousPoint.getTargetAngles(pos, ceiling);
|
||||||
if (previousPoint != null)
|
if (previousPoint != null)
|
||||||
previousBaseAngle = previousPoint.getTargetAngles(pos).baseAngle;
|
previousBaseAngle = previousPoint.getTargetAngles(pos, ceiling).baseAngle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,8 +80,8 @@ public class AllAdvancements implements IDataProvider {
|
|||||||
|
|
||||||
andesiteExpertLane(t, andesite_casing);
|
andesiteExpertLane(t, andesite_casing);
|
||||||
|
|
||||||
Advancement drill =
|
Advancement drill = kinecticAdvancement("mechanical_drill", AllBlocks.MECHANICAL_DRILL.get(), TaskType.NORMAL)
|
||||||
kinecticAdvancement("mechanical_drill", AllBlocks.MECHANICAL_DRILL.get(), TaskType.NORMAL).withParent(andesite_casing)
|
.withParent(andesite_casing)
|
||||||
.register(t, id + ":mechanical_drill");
|
.register(t, id + ":mechanical_drill");
|
||||||
|
|
||||||
Advancement press =
|
Advancement press =
|
||||||
@ -98,7 +98,8 @@ public class AllAdvancements implements IDataProvider {
|
|||||||
itemAdvancement("electron_tube", AllItems.ELECTRON_TUBE, TaskType.NORMAL).withParent(rose_quartz)
|
itemAdvancement("electron_tube", AllItems.ELECTRON_TUBE, TaskType.NORMAL).withParent(rose_quartz)
|
||||||
.register(t, id + ":electron_tube");
|
.register(t, id + ":electron_tube");
|
||||||
|
|
||||||
Advancement saw = kinecticAdvancement("mechanical_saw", AllBlocks.MECHANICAL_SAW.get(), TaskType.NORMAL).withParent(press)
|
Advancement saw =
|
||||||
|
kinecticAdvancement("mechanical_saw", AllBlocks.MECHANICAL_SAW.get(), TaskType.NORMAL).withParent(press)
|
||||||
.register(t, id + ":mechanical_saw");
|
.register(t, id + ":mechanical_saw");
|
||||||
|
|
||||||
Advancement basin = advancement("basin", AllBlocks.BASIN.get(), TaskType.NORMAL).withParent(press)
|
Advancement basin = advancement("basin", AllBlocks.BASIN.get(), TaskType.NORMAL).withParent(press)
|
||||||
@ -196,6 +197,20 @@ public class AllAdvancements implements IDataProvider {
|
|||||||
.withCriterion("0", AllTriggers.GIGA_EXTENDO.instance())
|
.withCriterion("0", AllTriggers.GIGA_EXTENDO.instance())
|
||||||
.register(t, id + ":dual_extendo_grip");
|
.register(t, id + ":dual_extendo_grip");
|
||||||
|
|
||||||
|
Advancement mechanical_arm = advancement("mechanical_arm", AllBlocks.MECHANICAL_ARM.get(), TaskType.GOAL)
|
||||||
|
.withCriterion("0", placeBlock(AllBlocks.MECHANICAL_ARM.get()))
|
||||||
|
.withCriterion("1", isPowered(AllBlocks.MECHANICAL_ARM.get()))
|
||||||
|
.withCriterion("2", AllTriggers.MECHANICAL_ARM.instance())
|
||||||
|
.withParent(brass_casing)
|
||||||
|
.register(t, id + ":mechanical_arm");
|
||||||
|
|
||||||
|
Advancement musical_arm = advancement("musical_arm", Items.MUSIC_DISC_13, TaskType.MILESTONE)
|
||||||
|
.withCriterion("0", placeBlock(AllBlocks.MECHANICAL_ARM.get()))
|
||||||
|
.withCriterion("1", isPowered(AllBlocks.MECHANICAL_ARM.get()))
|
||||||
|
.withCriterion("2", AllTriggers.MUSICAL_ARM.instance())
|
||||||
|
.withParent(mechanical_arm)
|
||||||
|
.register(t, id + ":musical_arm");
|
||||||
|
|
||||||
Advancement deployer =
|
Advancement deployer =
|
||||||
kinecticAdvancement("deployer", AllBlocks.DEPLOYER.get(), TaskType.GOAL).withParent(brass_casing)
|
kinecticAdvancement("deployer", AllBlocks.DEPLOYER.get(), TaskType.GOAL).withParent(brass_casing)
|
||||||
.register(t, id + ":deployer");
|
.register(t, id + ":deployer");
|
||||||
|
@ -33,6 +33,8 @@ public class AllTriggers {
|
|||||||
UPGRADED_ZAPPER = simple("upgraded_zapper"),
|
UPGRADED_ZAPPER = simple("upgraded_zapper"),
|
||||||
EXTENDO = simple("extendo"),
|
EXTENDO = simple("extendo"),
|
||||||
GIGA_EXTENDO = simple("giga_extendo"),
|
GIGA_EXTENDO = simple("giga_extendo"),
|
||||||
|
MECHANICAL_ARM = simple("mechanical_arm"),
|
||||||
|
MUSICAL_ARM = simple("musical_arm"),
|
||||||
MIXER_MIX = simple("mixer");
|
MIXER_MIX = simple("mixer");
|
||||||
|
|
||||||
private static SimpleTrigger simple(String id) {
|
private static SimpleTrigger simple(String id) {
|
||||||
|
@ -61,6 +61,10 @@
|
|||||||
"advancement.create.crafter.desc": "Place and power some Mechanical Crafters",
|
"advancement.create.crafter.desc": "Place and power some Mechanical Crafters",
|
||||||
"advancement.create.deployer": "Poke, Place, and Attack",
|
"advancement.create.deployer": "Poke, Place, and Attack",
|
||||||
"advancement.create.deployer.desc": "Place and power a Deployer, the perfect reflection of yourself.",
|
"advancement.create.deployer.desc": "Place and power a Deployer, the perfect reflection of yourself.",
|
||||||
|
"advancement.create.mechanical_arm": "Mechanical Grab'n'Drop",
|
||||||
|
"advancement.create.mechanical_arm.desc": "Craft a Mechanical Arm, select in- and outputs, place it down and give it power; then watch it do all the work for you.",
|
||||||
|
"advancement.create.musical_arm": "Play me my Theme Tune!",
|
||||||
|
"advancement.create.musical_arm.desc": "Watch a Mechanical Arm operate your Jukebox.",
|
||||||
"advancement.create.fist_bump": "Pound It, Bro!",
|
"advancement.create.fist_bump": "Pound It, Bro!",
|
||||||
"advancement.create.fist_bump.desc": "Make two Deployers fist-bump.",
|
"advancement.create.fist_bump.desc": "Make two Deployers fist-bump.",
|
||||||
"advancement.create.crushing_wheel": "A Pair of Giants",
|
"advancement.create.crushing_wheel": "A Pair of Giants",
|
||||||
|
@ -121,8 +121,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Back",
|
"name": "Back",
|
||||||
"from": [3, -2, 3],
|
"from": [3.1, -1.9, 3.1],
|
||||||
"to": [13, 2, 13],
|
"to": [12.9, 2, 12.9],
|
||||||
"faces": {
|
"faces": {
|
||||||
"north": {"uv": [9.5, 9, 14.5, 11], "texture": "#4"},
|
"north": {"uv": [9.5, 9, 14.5, 11], "texture": "#4"},
|
||||||
"east": {"uv": [9.5, 9, 14.5, 11], "texture": "#4"},
|
"east": {"uv": [9.5, 9, 14.5, 11], "texture": "#4"},
|
||||||
|
Before Width: | Height: | Size: 978 B After Width: | Height: | Size: 984 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 297 B After Width: | Height: | Size: 297 B |
Before Width: | Height: | Size: 948 B After Width: | Height: | Size: 952 B |
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |