mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-15 22:03:41 +01:00
Merge branch 'mc1.16/dev' of https://github.com/Creators-of-Create/Create into mc1.16/fix-bugs
This commit is contained in:
commit
b0dad3bf79
106 changed files with 4096 additions and 969 deletions
|
@ -16,6 +16,7 @@ indent_size = 2
|
|||
|
||||
[*.java]
|
||||
indent_style = tab
|
||||
ij_continuation_indent_size = 8
|
||||
ij_java_class_count_to_use_import_on_demand = 99
|
||||
ij_java_names_count_to_use_import_on_demand = 99
|
||||
ij_java_imports_layout = $*,|,java.**,|,javax.**,|,org.**,|,com.**,|,*
|
|
@ -53,7 +53,7 @@ b59324f051f21d8ce1a48a08f4721a61a3c414d6 assets/create/blockstates/chute.json
|
|||
e5e3757e99c139d67b2a70288466d8a74d818841 assets/create/blockstates/cogwheel.json
|
||||
36f54136a7756c97f71bc6b47ef4e8e575e72879 assets/create/blockstates/content_observer.json
|
||||
cfea7283f0ebd2432d67e80a523f2a12e24c0bd5 assets/create/blockstates/controller_rail.json
|
||||
2a956df55577ce02384af372a15f41ec626b84b0 assets/create/blockstates/copper_backtank.json
|
||||
961b615124ea9a5a5735e8a79f81a702de7da2cf assets/create/blockstates/copper_backtank.json
|
||||
f8eff64c75fc599e9a44a003f54ae9931cd8ce7c assets/create/blockstates/copper_block.json
|
||||
cabf6b8c59eb0e3d56a0a5a856ca058bb3200882 assets/create/blockstates/copper_casing.json
|
||||
3355a852cdc717e257ca19b3db836068964733e3 assets/create/blockstates/copper_ore.json
|
||||
|
@ -408,20 +408,20 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j
|
|||
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
|
||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
||||
a6d814f94926d88764c38862cc4ece9c367e023b assets/create/lang/en_ud.json
|
||||
80e3112fe5ab12a9bbe7c272ab50904eee351f44 assets/create/lang/en_us.json
|
||||
9b8c1f501cb57098f3ac67c8fd4532246a0c59bb assets/create/lang/unfinished/de_de.json
|
||||
9d0482aa7a410bdb9b44bb7c1e24bda0343e1306 assets/create/lang/unfinished/es_es.json
|
||||
6e401a93ef63da54673d125892893468f04931be assets/create/lang/unfinished/es_mx.json
|
||||
466fe4336c8c45fab9027e18103f8c7ef5c94fef assets/create/lang/unfinished/fr_fr.json
|
||||
62d87f787237fbf2ace70eafb536cf5283c4dd16 assets/create/lang/unfinished/it_it.json
|
||||
e83d8ed48ebf35ce6ba3fac10efff80ce9ffc050 assets/create/lang/unfinished/ja_jp.json
|
||||
448bdf719bd40bb4cb8f013d29e1c65c1277f4ff assets/create/lang/unfinished/ko_kr.json
|
||||
a4229b2f23223f31a1b869d5a07ff61128ddd2e8 assets/create/lang/unfinished/nl_nl.json
|
||||
9d1594172ba55eab5b96bd48f5204b082493e5e8 assets/create/lang/unfinished/pl_pl.json
|
||||
ba271a34ebf9c23c239fcdf94d71623bfcaaefb1 assets/create/lang/unfinished/pt_br.json
|
||||
0c78fdaa30db8d54122bb055167ee41e4d1e010c assets/create/lang/unfinished/ru_ru.json
|
||||
899752fff0af288e71fb1f7c771910395c701477 assets/create/lang/unfinished/zh_cn.json
|
||||
a7189982351b90b3cde43529a0fbdef696bda22e assets/create/lang/unfinished/zh_tw.json
|
||||
95f238e0df097f74a7845a58a02d27c3989305ce assets/create/lang/en_us.json
|
||||
e03638c344f9f80f5cee92c5e4ce4986478e65a5 assets/create/lang/unfinished/de_de.json
|
||||
dae908c13b54fa5123bad98dd38ba35d58edaaf0 assets/create/lang/unfinished/es_es.json
|
||||
bf9142028bbd21a4441381c06c3b4557e60e49c5 assets/create/lang/unfinished/es_mx.json
|
||||
e4f70996f672bc50e8cfeaccd150075c0a07a917 assets/create/lang/unfinished/fr_fr.json
|
||||
34c1226afddeaf7824fc1aaf65f40505b3811a91 assets/create/lang/unfinished/it_it.json
|
||||
17a4ed49d461a537ca8e59fc95d12909780105d7 assets/create/lang/unfinished/ja_jp.json
|
||||
dd1e77bf533b4bf0e7fa358d48ce5643d08b21c3 assets/create/lang/unfinished/ko_kr.json
|
||||
0faf1940b7c9664be63d02b3685ed0252528a9ce assets/create/lang/unfinished/nl_nl.json
|
||||
996e1392e3ffcdb6d41a66cf6bd752e301c52b12 assets/create/lang/unfinished/pl_pl.json
|
||||
49e35e88d59fb49cb1889e960a18371d0616b963 assets/create/lang/unfinished/pt_br.json
|
||||
af5ee82802fc0e42012c575cd9da1cf36b88b035 assets/create/lang/unfinished/ru_ru.json
|
||||
63db3153b522775cad4f91eb509e14568bfb0c3c assets/create/lang/unfinished/zh_cn.json
|
||||
f533c7c7c1cc2b11908377bd807ff006902d5e34 assets/create/lang/unfinished/zh_tw.json
|
||||
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
||||
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
|
||||
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json
|
||||
|
@ -1651,8 +1651,8 @@ d080b1b25e5bc8baf5aee68691b08c7f12ece3b0 assets/create/models/item/windmill_bear
|
|||
866fbb0ce2878a73e0440d1caf6534c8bd7c384f assets/create/models/item/zinc_ingot.json
|
||||
a80fb25a0b655e76be986b5b49fcb0f03461a1ab assets/create/models/item/zinc_nugget.json
|
||||
b1689617190c05ef34bd18456b0c7ae09bb3210f assets/create/models/item/zinc_ore.json
|
||||
7b73f40a65af0c2288c886928c609ec783c0fc40 assets/create/sounds.json
|
||||
0f1b4b980afba9bf2caf583b88e261bba8b10313 data/create/advancements/aesthetics.json
|
||||
3fd540489a0038a78c6b02f81e89d95e53596b2b assets/create/sounds.json
|
||||
5d0cc4c0255dc241e61c173b31ddca70c88d08e4 data/create/advancements/aesthetics.json
|
||||
187921fa131b06721bfaf63f2623a28c141aae9a data/create/advancements/andesite_alloy.json
|
||||
0ea2db7173b5be28b289ea7c9a6a0cf5805c60c7 data/create/advancements/andesite_casing.json
|
||||
83c046bd200623933545c9e4326f782fb02c87fa data/create/advancements/arm_blaze_burner.json
|
||||
|
|
|
@ -1,17 +1,32 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=north": {
|
||||
"facing=north,waterlogged=false": {
|
||||
"model": "create:block/copper_backtank/block"
|
||||
},
|
||||
"facing=south": {
|
||||
"facing=south,waterlogged=false": {
|
||||
"model": "create:block/copper_backtank/block",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west": {
|
||||
"facing=west,waterlogged=false": {
|
||||
"model": "create:block/copper_backtank/block",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east": {
|
||||
"facing=east,waterlogged=false": {
|
||||
"model": "create:block/copper_backtank/block",
|
||||
"y": 90
|
||||
},
|
||||
"facing=north,waterlogged=true": {
|
||||
"model": "create:block/copper_backtank/block"
|
||||
},
|
||||
"facing=south,waterlogged=true": {
|
||||
"model": "create:block/copper_backtank/block",
|
||||
"y": 180
|
||||
},
|
||||
"facing=west,waterlogged=true": {
|
||||
"model": "create:block/copper_backtank/block",
|
||||
"y": 270
|
||||
},
|
||||
"facing=east,waterlogged=true": {
|
||||
"model": "create:block/copper_backtank/block",
|
||||
"y": 90
|
||||
}
|
||||
|
|
|
@ -1146,6 +1146,7 @@
|
|||
"create.subtitle.blaze_munch": "Blaze Burner munches",
|
||||
"create.subtitle.schematicannon_launch_block": "Schematicannon fires",
|
||||
"create.subtitle.funnel_flap": "Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "Schematicannon dings",
|
||||
"create.subtitle.scroll_value": "Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "Mechanical Press clangs",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 939",
|
||||
"_": "Missing Localizations: 940",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "Lohe kaut glücklich",
|
||||
"create.subtitle.schematicannon_launch_block": "Bauplankanone schießt",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "Bauplankanone endet",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "Mechanische Presse wird aktiviert",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 640",
|
||||
"_": "Missing Localizations: 641",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "Blaze mastica felizmente",
|
||||
"create.subtitle.schematicannon_launch_block": "Disparos de Schematicannon",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "Acabados de Schematicannon",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "La Prensa Mecánica se activa",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1263",
|
||||
"_": "Missing Localizations: 1264",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze Burner munches",
|
||||
"create.subtitle.schematicannon_launch_block": "UNLOCALIZED: Schematicannon fires",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "UNLOCALIZED: Schematicannon dings",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "UNLOCALIZED: Mechanical Press clangs",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1191",
|
||||
"_": "Missing Localizations: 1192",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze Burner munches",
|
||||
"create.subtitle.schematicannon_launch_block": "Tir de schémacanon",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "Fin de schémacanon",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "Activation de la presse mechanique",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 657",
|
||||
"_": "Missing Localizations: 658",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "Il blaze lo gusta felicemente",
|
||||
"create.subtitle.schematicannon_launch_block": "Tiri del cannoneschematico",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "Finiture cannoneschematico",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "Pressa meccanica attiva",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 21",
|
||||
"_": "Missing Localizations: 22",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "ブレイズの咀嚼音",
|
||||
"create.subtitle.schematicannon_launch_block": "概略図砲が発射する",
|
||||
"create.subtitle.funnel_flap": "ファンネルがはためく",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "概略図砲が作業を終える",
|
||||
"create.subtitle.scroll_value": "スクロールのカチカチ音",
|
||||
"create.subtitle.mechanical_press_activation": "メカニカルプレスがガーンと鳴る",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 710",
|
||||
"_": "Missing Localizations: 711",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "블레이즈가 행복하게 섭취함",
|
||||
"create.subtitle.schematicannon_launch_block": "청사진 대포가 발포함",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "청사진 대포가 끝남",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "압착기가 가동됨",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1574",
|
||||
"_": "Missing Localizations: 1575",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze Burner munches",
|
||||
"create.subtitle.schematicannon_launch_block": "UNLOCALIZED: Schematicannon fires",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "UNLOCALIZED: Schematicannon dings",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "UNLOCALIZED: Mechanical Press clangs",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 35",
|
||||
"_": "Missing Localizations: 36",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "Płomyk szczęśliwie przeżuwa",
|
||||
"create.subtitle.schematicannon_launch_block": "Schematoarmata strzela",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "Schematoarmata skończyła",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "Mechaniczna prasa się uruchamia",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1626",
|
||||
"_": "Missing Localizations: 1627",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "UNLOCALIZED: Blaze Burner munches",
|
||||
"create.subtitle.schematicannon_launch_block": "UNLOCALIZED: Schematicannon fires",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "UNLOCALIZED: Schematicannon dings",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "UNLOCALIZED: Mechanical Press clangs",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 554",
|
||||
"_": "Missing Localizations: 555",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "Всполох радостно жуёт",
|
||||
"create.subtitle.schematicannon_launch_block": "Выстрелы схематичной пушки",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "Схематичная пушка закончила работу",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "Механический пресс активирован",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 40",
|
||||
"_": "Missing Localizations: 41",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "烈焰人:咀嚼",
|
||||
"create.subtitle.schematicannon_launch_block": "蓝图加农炮:发射",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "蓝图加农炮:叮",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "辊压机:工作中",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 659",
|
||||
"_": "Missing Localizations: 660",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1147,6 +1147,7 @@
|
|||
"create.subtitle.blaze_munch": "烈焰使者開心地吃著",
|
||||
"create.subtitle.schematicannon_launch_block": "藍圖大炮發射",
|
||||
"create.subtitle.funnel_flap": "UNLOCALIZED: Funnel Flaps",
|
||||
"create.subtitle.copper_armor_equip": "UNLOCALIZED: Diving equipment clinks",
|
||||
"create.subtitle.schematicannon_finish": "藍圖大炮完成任務",
|
||||
"create.subtitle.scroll_value": "UNLOCALIZED: Scroll-input clicks",
|
||||
"create.subtitle.mechanical_press_activation": "液壓機工作",
|
||||
|
|
|
@ -49,6 +49,15 @@
|
|||
],
|
||||
"subtitle": "create.subtitle.contraption_disassemble"
|
||||
},
|
||||
"copper_armor_equip": {
|
||||
"sounds": [
|
||||
{
|
||||
"name": "minecraft:item.armor.equip_gold",
|
||||
"type": "event"
|
||||
}
|
||||
],
|
||||
"subtitle": "create.subtitle.copper_armor_equip"
|
||||
},
|
||||
"crafter_click": {
|
||||
"sounds": [
|
||||
{
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
"trigger": "create:bracket_apply",
|
||||
"conditions": {
|
||||
"accepted_entries": [
|
||||
"create:cogwheel",
|
||||
"create:large_cogwheel"
|
||||
"create:large_cogwheel",
|
||||
"create:cogwheel"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
@ -100,6 +100,7 @@ public class AllBlockPartials {
|
|||
EJECTOR_TOP = get("weighted_ejector/top"),
|
||||
|
||||
COPPER_BACKTANK_SHAFT = get("copper_backtank/block_shaft_input"),
|
||||
COPPER_BACKTANK_COGS = get("copper_backtank/block_cogs"),
|
||||
|
||||
COUPLING_ATTACHMENT = getEntity("minecart_coupling/attachment"),
|
||||
COUPLING_RING = getEntity("minecart_coupling/ring"),
|
||||
|
|
|
@ -1292,6 +1292,7 @@ public class AllBlocks {
|
|||
REGISTRATE.block("copper_backtank", CopperBacktankBlock::new)
|
||||
.initialProperties(SharedProperties::softMetal)
|
||||
.blockstate((c, p) -> p.horizontalBlock(c.getEntry(), AssetLookup.partialBaseModel(c, p)))
|
||||
.addLayer(() -> RenderType::getCutoutMipped)
|
||||
.transform(StressConfigDefaults.setImpact(4.0))
|
||||
.loot((lt, block) -> {
|
||||
Builder builder = LootTable.builder();
|
||||
|
|
|
@ -261,23 +261,24 @@ public class AllItems {
|
|||
REGISTRATE.startSection(CURIOSITIES);
|
||||
}
|
||||
|
||||
public static final ItemEntry<TreeFertilizerItem> TREE_FERTILIZER =
|
||||
REGISTRATE.item("tree_fertilizer", TreeFertilizerItem::new)
|
||||
.register();
|
||||
|
||||
public static final ItemEntry<? extends CopperArmorItem>
|
||||
|
||||
DIVING_HELMET = REGISTRATE.item("diving_helmet", DivingHelmetItem::new)
|
||||
.register(),
|
||||
|
||||
COPPER_BACKTANK = REGISTRATE
|
||||
COPPER_BACKTANK =
|
||||
REGISTRATE
|
||||
.item("copper_backtank", p -> new CopperBacktankItem(p, new BlockItem(AllBlocks.COPPER_BACKTANK.get(), p)))
|
||||
.model(AssetLookup.<CopperBacktankItem>customGenericItemModel("_", "item"))
|
||||
.register(),
|
||||
|
||||
DIVING_HELMET = REGISTRATE.item("diving_helmet", DivingHelmetItem::new)
|
||||
.register(),
|
||||
|
||||
DIVING_BOOTS = REGISTRATE.item("diving_boots", DivingBootsItem::new)
|
||||
.register();
|
||||
|
||||
public static final ItemEntry<TreeFertilizerItem> TREE_FERTILIZER =
|
||||
REGISTRATE.item("tree_fertilizer", TreeFertilizerItem::new)
|
||||
.register();
|
||||
|
||||
// Schematics
|
||||
|
||||
static {
|
||||
|
|
|
@ -148,6 +148,11 @@ public class AllSoundEvents {
|
|||
.category(SoundCategory.BLOCKS)
|
||||
.build(),
|
||||
|
||||
COPPER_ARMOR_EQUIP = create("copper_armor_equip").subtitle("Diving equipment clinks")
|
||||
.playExisting(SoundEvents.ITEM_ARMOR_EQUIP_GOLD, 1f, 1f)
|
||||
.category(SoundCategory.PLAYERS)
|
||||
.build(),
|
||||
|
||||
BLAZE_MUNCH = create("blaze_munch").subtitle("Blaze Burner munches")
|
||||
.playExisting(SoundEvents.ENTITY_GENERIC_EAT, .5f, 1f)
|
||||
.category(SoundCategory.BLOCKS)
|
||||
|
@ -163,6 +168,11 @@ public class AllSoundEvents {
|
|||
entry.register(registry);
|
||||
}
|
||||
|
||||
public static void prepare() {
|
||||
for (SoundEntry entry : entries.values())
|
||||
entry.prepare();
|
||||
}
|
||||
|
||||
public static JsonElement provideLangEntries() {
|
||||
JsonObject object = new JsonObject();
|
||||
for (SoundEntry entry : entries.values())
|
||||
|
@ -278,6 +288,8 @@ public class AllSoundEvents {
|
|||
this.category = category;
|
||||
}
|
||||
|
||||
public abstract void prepare();
|
||||
|
||||
public abstract void register(IForgeRegistry<SoundEvent> registry);
|
||||
|
||||
public abstract void write(JsonObject json);
|
||||
|
@ -348,16 +360,21 @@ public class AllSoundEvents {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void register(IForgeRegistry<SoundEvent> registry) {
|
||||
public void prepare() {
|
||||
for (int i = 0; i < wrappedEvents.size(); i++) {
|
||||
ResourceLocation location = Create.asResource(getIdOf(i));
|
||||
SoundEvent sound = new SoundEvent(location).setRegistryName(location);
|
||||
registry.register(sound);
|
||||
compiledEvents.add(Pair.of(sound, wrappedEvents.get(i)
|
||||
.getSecond()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(IForgeRegistry<SoundEvent> registry) {
|
||||
for (Pair<SoundEvent, Couple<Float>> pair : compiledEvents)
|
||||
registry.register(pair.getFirst());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SoundEvent getMainEvent() {
|
||||
return compiledEvents.get(0)
|
||||
|
@ -415,9 +432,14 @@ public class AllSoundEvents {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void register(IForgeRegistry<SoundEvent> registry) {
|
||||
public void prepare() {
|
||||
ResourceLocation location = getLocation();
|
||||
registry.register(event = new SoundEvent(location).setRegistryName(location));
|
||||
event = new SoundEvent(location).setRegistryName(location);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(IForgeRegistry<SoundEvent> registry) {
|
||||
registry.register(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -78,6 +78,7 @@ public class Create {
|
|||
IEventBus modEventBus = FMLJavaModLoadingContext.get()
|
||||
.getModEventBus();
|
||||
|
||||
AllSoundEvents.prepare();
|
||||
AllBlocks.register();
|
||||
AllItems.register();
|
||||
AllFluids.register();
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.simibubi.create.content.curiosities.armor.CopperBacktankArmorLayer;
|
|||
import com.simibubi.create.content.schematics.ClientSchematicLoader;
|
||||
import com.simibubi.create.content.schematics.client.SchematicAndQuillHandler;
|
||||
import com.simibubi.create.content.schematics.client.SchematicHandler;
|
||||
import com.simibubi.create.events.ClientEvents;
|
||||
import com.simibubi.create.foundation.ResourceReloadHandler;
|
||||
import com.simibubi.create.foundation.block.render.CustomBlockModels;
|
||||
import com.simibubi.create.foundation.block.render.SpriteShifter;
|
||||
|
@ -82,6 +83,7 @@ public class CreateClient {
|
|||
modEventBus.addListener(CreateClient::onModelRegistry);
|
||||
modEventBus.addListener(CreateClient::onTextureStitch);
|
||||
modEventBus.addListener(AllParticleTypes::registerFactories);
|
||||
modEventBus.addListener(ClientEvents::loadCompleted);
|
||||
|
||||
Backend.init();
|
||||
OptifineHandler.init();
|
||||
|
@ -112,6 +114,7 @@ public class CreateClient {
|
|||
PonderIndex.registerTags();
|
||||
|
||||
UIRenderHelper.init();
|
||||
UIRenderHelper.enableStencil();
|
||||
|
||||
IResourceManager resourceManager = Minecraft.getInstance()
|
||||
.getResourceManager();
|
||||
|
|
|
@ -53,7 +53,6 @@ import mezz.jei.api.registration.IGuiHandlerRegistration;
|
|||
import mezz.jei.api.registration.IRecipeCatalystRegistration;
|
||||
import mezz.jei.api.registration.IRecipeCategoryRegistration;
|
||||
import mezz.jei.api.registration.IRecipeRegistration;
|
||||
import mezz.jei.api.registration.ISubtypeRegistration;
|
||||
import mezz.jei.api.runtime.IIngredientManager;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
|
|
@ -73,7 +73,7 @@ public class PolishingCategory extends CreateRecipeCategory<SandPaperPolishingRe
|
|||
tag.put("Polishing", matchingStacks[0].serializeNBT());
|
||||
tag.putBoolean("JEI", true);
|
||||
GuiGameElement.of(renderedSandpaper)
|
||||
.at(getBackground().getWidth() / 2 - 16, 0, 0)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(getBackground().getWidth() / 2 - 16, 0, 0)
|
||||
.scale(2)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ public class SequencedGearshiftScreen extends AbstractSimiScreen {
|
|||
0xffffff);
|
||||
|
||||
GuiGameElement.of(renderedItem)
|
||||
.at(guiLeft + background.width + 10, guiTop + 100, -150)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + background.width + 10, guiTop + 100, -150)
|
||||
.scale(5)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
large = block.isLarge;
|
||||
|
||||
placementHelperId = PlacementHelpers.register(large ? new LargeCogHelper() : new SmallCogHelper());
|
||||
integratedCogHelperId = large ? PlacementHelpers.register(new IntegratedCogHelper()) : -1;
|
||||
integratedCogHelperId = PlacementHelpers.register(large ? new IntegratedLargeCogHelper() : new IntegratedSmallCogHelper());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -93,7 +93,7 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
for (int offset1 : Iterate.positiveAndNegative) {
|
||||
for (int offset2 : Iterate.positiveAndNegative) {
|
||||
BlockPos connectedPos = pos.offset(d1, offset1)
|
||||
.offset(d2, offset2);
|
||||
.offset(d2, offset2);
|
||||
BlockState blockState = world.getBlockState(connectedPos);
|
||||
if (!(blockState.getBlock() instanceof CogWheelBlock))
|
||||
continue;
|
||||
|
@ -123,7 +123,7 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
|
||||
if (!((CogWheelBlock) state.getBlock()).isLarge) {
|
||||
List<Direction> directions =
|
||||
IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getHitVec(), state.get(AXIS));
|
||||
IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getHitVec(), state.get(AXIS));
|
||||
|
||||
for (Direction dir : directions) {
|
||||
BlockPos newPos = pos.offset(dir);
|
||||
|
@ -132,8 +132,8 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
continue;
|
||||
|
||||
if (!world.getBlockState(newPos)
|
||||
.getMaterial()
|
||||
.isReplaceable())
|
||||
.getMaterial()
|
||||
.isReplaceable())
|
||||
continue;
|
||||
|
||||
return PlacementOffset.success(newPos, s -> s.with(AXIS, state.get(AXIS)));
|
||||
|
@ -162,19 +162,19 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
|
||||
if (((CogWheelBlock) state.getBlock()).isLarge) {
|
||||
Direction side = IPlacementHelper.orderedByDistanceOnlyAxis(pos, ray.getHitVec(), state.get(AXIS))
|
||||
.get(0);
|
||||
.get(0);
|
||||
List<Direction> directions =
|
||||
IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getHitVec(), state.get(AXIS));
|
||||
IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getHitVec(), state.get(AXIS));
|
||||
for (Direction dir : directions) {
|
||||
BlockPos newPos = pos.offset(dir)
|
||||
.offset(side);
|
||||
.offset(side);
|
||||
|
||||
if (!CogWheelBlock.isValidCogwheelPosition(true, world, newPos, dir.getAxis()))
|
||||
continue;
|
||||
|
||||
if (!world.getBlockState(newPos)
|
||||
.getMaterial()
|
||||
.isReplaceable())
|
||||
.getMaterial()
|
||||
.isReplaceable())
|
||||
continue;
|
||||
|
||||
return PlacementOffset.success(newPos, s -> s.with(AXIS, dir.getAxis()));
|
||||
|
@ -199,16 +199,16 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
public PlacementOffset getOffset(PlayerEntity player, World world, BlockState state, BlockPos pos, BlockRayTraceResult ray) {
|
||||
// diagonal gears of different size
|
||||
Direction closest = IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getHitVec(), state.get(AXIS))
|
||||
.get(0);
|
||||
.get(0);
|
||||
List<Direction> directions = IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getHitVec(),
|
||||
state.get(AXIS), d -> d.getAxis() != closest.getAxis());
|
||||
state.get(AXIS), d -> d.getAxis() != closest.getAxis());
|
||||
|
||||
for (Direction dir : directions) {
|
||||
BlockPos newPos = pos.offset(dir)
|
||||
.offset(closest);
|
||||
.offset(closest);
|
||||
if (!world.getBlockState(newPos)
|
||||
.getMaterial()
|
||||
.isReplaceable())
|
||||
.getMaterial()
|
||||
.isReplaceable())
|
||||
continue;
|
||||
|
||||
if (!CogWheelBlock.isValidCogwheelPosition(ICogWheel.isLargeCog(state), world, newPos, state.get(AXIS)))
|
||||
|
@ -222,16 +222,16 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
|
||||
protected boolean hitOnShaft(BlockState state, BlockRayTraceResult ray) {
|
||||
return AllShapes.SIX_VOXEL_POLE.get(state.get(AXIS))
|
||||
.getBoundingBox()
|
||||
.grow(0.001)
|
||||
.contains(ray.getHitVec()
|
||||
.subtract(ray.getHitVec()
|
||||
.align(Iterate.axisSet)));
|
||||
.getBoundingBox()
|
||||
.grow(0.001)
|
||||
.contains(ray.getHitVec()
|
||||
.subtract(ray.getHitVec()
|
||||
.align(Iterate.axisSet)));
|
||||
}
|
||||
}
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
public static class IntegratedCogHelper implements IPlacementHelper {
|
||||
public static class IntegratedLargeCogHelper implements IPlacementHelper {
|
||||
|
||||
@Override
|
||||
public Predicate<ItemStack> getItemPredicate() {
|
||||
|
@ -250,10 +250,10 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
|
||||
if (state.contains(HorizontalKineticBlock.HORIZONTAL_FACING))
|
||||
newAxis = state.get(HorizontalKineticBlock.HORIZONTAL_FACING)
|
||||
.getAxis();
|
||||
.getAxis();
|
||||
else if (state.contains(DirectionalKineticBlock.FACING))
|
||||
newAxis = state.get(DirectionalKineticBlock.FACING)
|
||||
.getAxis();
|
||||
.getAxis();
|
||||
else
|
||||
newAxis = Axis.Y;
|
||||
|
||||
|
@ -261,15 +261,15 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
return PlacementOffset.fail();
|
||||
|
||||
List<Direction> directions =
|
||||
IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getHitVec(), face.getAxis(), newAxis);
|
||||
IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getHitVec(), face.getAxis(), newAxis);
|
||||
|
||||
for (Direction d : directions) {
|
||||
BlockPos newPos = pos.offset(face)
|
||||
.offset(d);
|
||||
.offset(d);
|
||||
|
||||
if (!world.getBlockState(newPos)
|
||||
.getMaterial()
|
||||
.isReplaceable())
|
||||
.getMaterial()
|
||||
.isReplaceable())
|
||||
continue;
|
||||
|
||||
if (!CogWheelBlock.isValidCogwheelPosition(false, world, newPos, newAxis))
|
||||
|
@ -282,4 +282,57 @@ public class CogwheelBlockItem extends BlockItem {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
@MethodsReturnNonnullByDefault
|
||||
public static class IntegratedSmallCogHelper implements IPlacementHelper {
|
||||
|
||||
@Override
|
||||
public Predicate<ItemStack> getItemPredicate() {
|
||||
return ((Predicate<ItemStack>) ICogWheel::isSmallCogItem).and(ICogWheel::isDedicatedCogItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate<BlockState> getStatePredicate() {
|
||||
return s -> !ICogWheel.isDedicatedCogWheel(s.getBlock()) && ICogWheel.isSmallCog(s);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlacementOffset getOffset(PlayerEntity player, World world, BlockState state, BlockPos pos, BlockRayTraceResult ray) {
|
||||
Direction face = ray.getFace();
|
||||
Axis newAxis;
|
||||
|
||||
if (state.contains(HorizontalKineticBlock.HORIZONTAL_FACING))
|
||||
newAxis = state.get(HorizontalKineticBlock.HORIZONTAL_FACING)
|
||||
.getAxis();
|
||||
else if (state.contains(DirectionalKineticBlock.FACING))
|
||||
newAxis = state.get(DirectionalKineticBlock.FACING)
|
||||
.getAxis();
|
||||
else
|
||||
newAxis = Axis.Y;
|
||||
|
||||
if (face.getAxis() == newAxis)
|
||||
return PlacementOffset.fail();
|
||||
|
||||
List<Direction> directions = IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getHitVec(), newAxis);
|
||||
|
||||
for (Direction d : directions) {
|
||||
BlockPos newPos = pos.offset(d);
|
||||
|
||||
if (!world.getBlockState(newPos)
|
||||
.getMaterial()
|
||||
.isReplaceable())
|
||||
continue;
|
||||
|
||||
if (!CogWheelBlock.isValidCogwheelPosition(false, world, newPos, newAxis))
|
||||
return PlacementOffset.fail();
|
||||
|
||||
return PlacementOffset.success()
|
||||
.at(newPos)
|
||||
.withTransform(s -> s.with(CogWheelBlock.AXIS, newAxis));
|
||||
}
|
||||
|
||||
return PlacementOffset.fail();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,6 @@ import net.minecraft.item.ItemUseContext;
|
|||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
|
|
@ -3,21 +3,20 @@ package com.simibubi.create.content.curiosities.armor;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
|
||||
import net.minecraft.inventory.EquipmentSlotType;
|
||||
import net.minecraft.item.IArmorMaterial;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
import net.minecraft.util.LazyValue;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public enum AllArmorMaterials implements IArmorMaterial {
|
||||
|
||||
COPPER("copper", 7, new int[] { 1, 3, 5, 2 }, 25, SoundEvents.ITEM_ARMOR_EQUIP_GOLD, 0.0F, 0.0F, () -> {
|
||||
return Ingredient.fromItems(AllItems.COPPER_INGOT.get());
|
||||
})
|
||||
COPPER("copper", 7, new int[] { 1, 3, 4, 2 }, 25, AllSoundEvents.COPPER_ARMOR_EQUIP.getMainEvent(), 0.0F, 0.0F,
|
||||
() -> Ingredient.fromItems(AllItems.COPPER_INGOT.get()))
|
||||
|
||||
;
|
||||
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
package com.simibubi.create.content.curiosities.armor;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.gui.GuiGameElement;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.MainWindow;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer.Impl;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
|
@ -19,7 +26,11 @@ import net.minecraft.client.renderer.entity.model.BipedModel;
|
|||
import net.minecraft.client.renderer.entity.model.EntityModel;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.Pose;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.StringUtils;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
public class CopperBacktankArmorLayer<T extends LivingEntity, M extends EntityModel<T>> extends LayerRenderer<T, M> {
|
||||
|
||||
|
@ -49,15 +60,29 @@ public class CopperBacktankArmorLayer<T extends LivingEntity, M extends EntityMo
|
|||
BipedModel<?> model = (BipedModel<?>) entityModel;
|
||||
BlockState renderedState = AllBlocks.COPPER_BACKTANK.getDefaultState()
|
||||
.with(CopperBacktankBlock.HORIZONTAL_FACING, Direction.SOUTH);
|
||||
RenderType renderType = RenderType.getSolid();
|
||||
RenderType renderType = RenderType.getCutout();
|
||||
|
||||
SuperByteBuffer backtank = CreateClient.bufferCache.renderBlock(renderedState);
|
||||
SuperByteBuffer cogs =
|
||||
CreateClient.bufferCache.renderPartial(AllBlockPartials.COPPER_BACKTANK_COGS, renderedState);
|
||||
|
||||
model.bipedBody.rotate(ms);
|
||||
ms.translate(-1 / 2f, 10 / 16f, 1f);
|
||||
ms.scale(1, -1, -1);
|
||||
|
||||
backtank.light(light)
|
||||
.renderInto(ms, buffer.getBuffer(renderType));
|
||||
|
||||
cogs.matrixStacker()
|
||||
.centre()
|
||||
.rotateY(180)
|
||||
.unCentre()
|
||||
.translate(0, 6.5f / 16, 11f / 16)
|
||||
.rotate(Direction.EAST, AngleHelper.rad(2 * AnimationTickHolder.getRenderTime(entity.world) % 360))
|
||||
.translate(0, -6.5f / 16, -11f / 16);
|
||||
|
||||
cogs.light(light)
|
||||
.renderInto(ms, buffer.getBuffer(renderType));
|
||||
|
||||
if (buffer instanceof Impl)
|
||||
((Impl) buffer).draw(renderType);
|
||||
ms.pop();
|
||||
|
@ -78,4 +103,39 @@ public class CopperBacktankArmorLayer<T extends LivingEntity, M extends EntityMo
|
|||
new CopperBacktankArmorLayer<>((LivingRenderer<?, ?>) entityRenderer);
|
||||
}
|
||||
|
||||
public static void renderRemainingAirOverlay(MatrixStack ms, Impl buffers, int light, int overlay, float pt) {
|
||||
ClientPlayerEntity player = Minecraft.getInstance().player;
|
||||
if (player == null)
|
||||
return;
|
||||
if (player.isSpectator() || player.isCreative())
|
||||
return;
|
||||
if (!player.getPersistentData()
|
||||
.contains("VisualBacktankAir"))
|
||||
return;
|
||||
if (!player.areEyesInFluid(FluidTags.WATER))
|
||||
return;
|
||||
|
||||
int timeLeft = player.getPersistentData()
|
||||
.getInt("VisualBacktankAir");
|
||||
|
||||
ms.push();
|
||||
|
||||
MainWindow window = Minecraft.getInstance()
|
||||
.getWindow();
|
||||
ms.translate(window.getScaledWidth() / 2 + 90, window.getScaledHeight() - 53, 0);
|
||||
|
||||
ITextComponent text = new StringTextComponent(StringUtils.ticksToElapsedTime(timeLeft * 20));
|
||||
GuiGameElement.of(AllItems.COPPER_BACKTANK.asStack())
|
||||
.at(0, 0)
|
||||
.render(ms);
|
||||
int color = 0xFF_FFFFFF;
|
||||
if (timeLeft < 60 && timeLeft % 2 == 0) {
|
||||
color = ColorHelper.mixColors(0xFF_FF0000, color, Math.max(timeLeft / 60f, .25f));
|
||||
}
|
||||
Minecraft.getInstance().fontRenderer.drawWithShadow(ms, text, 16, 5, color);
|
||||
buffers.draw();
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,31 +8,74 @@ import com.simibubi.create.AllTileEntities;
|
|||
import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.IWaterLoggable;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.fluid.FluidState;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.inventory.EquipmentSlotType;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.pathfinding.PathType;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
import net.minecraft.util.SoundEvents;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
|
||||
public class CopperBacktankBlock extends HorizontalKineticBlock implements ITE<CopperBacktankTileEntity> {
|
||||
public class CopperBacktankBlock extends HorizontalKineticBlock
|
||||
implements ITE<CopperBacktankTileEntity>, IWaterLoggable {
|
||||
|
||||
public CopperBacktankBlock(Properties properties) {
|
||||
super(properties);
|
||||
setDefaultState(super.getDefaultState().with(BlockStateProperties.WATERLOGGED, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public FluidState getFluidState(BlockState state) {
|
||||
return state.get(BlockStateProperties.WATERLOGGED) ? Fluids.WATER.getStillFluidState(false)
|
||||
: Fluids.EMPTY.getDefaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillStateContainer(Builder<Block, BlockState> builder) {
|
||||
builder.add(BlockStateProperties.WATERLOGGED);
|
||||
super.fillStateContainer(builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState updatePostPlacement(BlockState state, Direction direction, BlockState neighbourState,
|
||||
IWorld world, BlockPos pos, BlockPos neighbourPos) {
|
||||
if (state.get(BlockStateProperties.WATERLOGGED)) {
|
||||
world.getPendingFluidTicks()
|
||||
.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickRate(world));
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
FluidState ifluidstate = context.getWorld()
|
||||
.getFluidState(context.getPos());
|
||||
return super.getStateForPlacement(context).with(BlockStateProperties.WATERLOGGED,
|
||||
Boolean.valueOf(ifluidstate.getFluid() == Fluids.WATER));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,14 +106,20 @@ public class CopperBacktankBlock extends HorizontalKineticBlock implements ITE<C
|
|||
@Override
|
||||
public ActionResultType onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand p_225533_5_,
|
||||
BlockRayTraceResult p_225533_6_) {
|
||||
if (player == null)
|
||||
return ActionResultType.PASS;
|
||||
if (player instanceof FakePlayer)
|
||||
return ActionResultType.PASS;
|
||||
if (player.getHeldItemMainhand().getItem() instanceof BlockItem)
|
||||
if (player.isSneaking())
|
||||
return ActionResultType.PASS;
|
||||
if (player.getHeldItemMainhand()
|
||||
.getItem() instanceof BlockItem)
|
||||
return ActionResultType.PASS;
|
||||
if (!player.getItemStackFromSlot(EquipmentSlotType.CHEST)
|
||||
.isEmpty())
|
||||
return ActionResultType.PASS;
|
||||
if (!world.isRemote) {
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.PLAYERS, .75f, 1);
|
||||
player.setItemStackToSlot(EquipmentSlotType.CHEST, getItem(world, pos, state));
|
||||
world.destroyBlock(pos, false);
|
||||
}
|
||||
|
@ -108,4 +157,9 @@ public class CopperBacktankBlock extends HorizontalKineticBlock implements ITE<C
|
|||
return CopperBacktankTileEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsMovement(BlockState state, IBlockReader reader, BlockPos pos, PathType type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
package com.simibubi.create.content.curiosities.armor;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlockPartials;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.render.PartialBufferer;
|
||||
import com.simibubi.create.foundation.render.SuperByteBuffer;
|
||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
public class CopperBacktankRenderer extends KineticTileEntityRenderer {
|
||||
|
||||
|
@ -14,6 +21,26 @@ public class CopperBacktankRenderer extends KineticTileEntityRenderer {
|
|||
super(dispatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||
int light, int overlay) {
|
||||
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
|
||||
|
||||
SuperByteBuffer cogs =
|
||||
CreateClient.bufferCache.renderPartial(AllBlockPartials.COPPER_BACKTANK_COGS, te.getBlockState());
|
||||
cogs.matrixStacker()
|
||||
.centre()
|
||||
.rotateY(180 + AngleHelper.horizontalAngle(te.getBlockState()
|
||||
.get(CopperBacktankBlock.HORIZONTAL_FACING)))
|
||||
.unCentre()
|
||||
.translate(0, 6.5f / 16, 11f / 16)
|
||||
.rotate(Direction.EAST,
|
||||
AngleHelper.rad(te.getSpeed() / 4f * AnimationTickHolder.getRenderTime(te.getWorld()) % 360))
|
||||
.translate(0, -6.5f / 16, -11f / 16);
|
||||
cogs.light(light)
|
||||
.renderInto(ms, buffer.getBuffer(RenderType.getSolid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SuperByteBuffer getRotatedModel(KineticTileEntity te) {
|
||||
return PartialBufferer.get(AllBlockPartials.COPPER_BACKTANK_SHAFT, te.getBlockState());
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.curiosities.armor;
|
||||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||
import com.simibubi.create.content.contraptions.particle.AirParticleData;
|
||||
|
@ -11,6 +12,7 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.INameable;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
|
@ -37,16 +39,12 @@ public class CopperBacktankTileEntity extends KineticTileEntity implements IName
|
|||
return;
|
||||
}
|
||||
|
||||
Integer max = AllConfigs.SERVER.curiosities.maxAirInBacktank.get();
|
||||
int max = getMaxAir();
|
||||
if (world.isRemote) {
|
||||
Vector3d centerOf = VecHelper.getCenterOf(pos);
|
||||
Vector3d v = VecHelper.offsetRandomly(centerOf, Create.random, .65f);
|
||||
Vector3d m = centerOf.subtract(v);
|
||||
if (airLevel == max) {
|
||||
if (Create.random.nextFloat() < 1 / 8f) {
|
||||
world.addParticle(ParticleTypes.HAPPY_VILLAGER, v.x, v.y, v.z, 0, 0, 0);
|
||||
}
|
||||
} else
|
||||
if (airLevel != max)
|
||||
world.addParticle(new AirParticleData(1, .05f), v.x, v.y, v.z, m.x, m.y, m.z);
|
||||
return;
|
||||
}
|
||||
|
@ -62,6 +60,10 @@ public class CopperBacktankTileEntity extends KineticTileEntity implements IName
|
|||
airLevelTimer = MathHelper.clamp((int) (128f - abs / 5f) - 108, 0, 20);
|
||||
}
|
||||
|
||||
protected int getMaxAir() {
|
||||
return AllConfigs.SERVER.curiosities.maxAirInBacktank.get();
|
||||
}
|
||||
|
||||
public int getAirLevel() {
|
||||
return airLevel;
|
||||
}
|
||||
|
@ -91,10 +93,26 @@ public class CopperBacktankTileEntity extends KineticTileEntity implements IName
|
|||
@Override
|
||||
protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) {
|
||||
super.fromTag(state, compound, clientPacket);
|
||||
int prev = airLevel;
|
||||
airLevel = compound.getInt("Air");
|
||||
airLevelTimer = compound.getInt("Timer");
|
||||
if (compound.contains("CustomName", 8))
|
||||
this.customName = ITextComponent.Serializer.fromJson(compound.getString("CustomName"));
|
||||
if (prev != 0 && prev != airLevel && airLevel == getMaxAir() && clientPacket)
|
||||
playFilledEffect();
|
||||
}
|
||||
|
||||
protected void playFilledEffect() {
|
||||
AllSoundEvents.CONFIRM.playAt(world, pos, 0.4f, 1, true);
|
||||
Vector3d baseMotion = new Vector3d(.25, 0.1, 0);
|
||||
Vector3d baseVec = VecHelper.getCenterOf(pos);
|
||||
for (int i = 0; i < 360; i += 10) {
|
||||
Vector3d m = VecHelper.rotate(baseMotion, i, Axis.Y);
|
||||
Vector3d v = baseVec.add(m.normalize()
|
||||
.scale(.25f));
|
||||
|
||||
world.addParticle(ParticleTypes.SPIT, v.x, v.y, v.z, m.x, m.y, m.z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,4 +122,9 @@ public class CopperBacktankTileEntity extends KineticTileEntity implements IName
|
|||
.getTranslationKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRenderAsTE() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.potion.EffectInstance;
|
||||
import net.minecraft.potion.Effects;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
|
@ -22,11 +23,13 @@ public class DivingHelmetItem extends CopperArmorItem {
|
|||
@SubscribeEvent
|
||||
public static void breatheUnderwater(LivingUpdateEvent event) {
|
||||
LivingEntity entity = event.getEntityLiving();
|
||||
boolean second = entity.world.getGameTime() % 20 == 0;
|
||||
World world = entity.world;
|
||||
boolean second = world.getGameTime() % 20 == 0;
|
||||
boolean drowning = entity.getAir() == 0;
|
||||
|
||||
if (!second && !drowning)
|
||||
return;
|
||||
if (world.isRemote)
|
||||
entity.getPersistentData()
|
||||
.remove("VisualBacktankAir");
|
||||
|
||||
if (!AllItems.DIVING_HELMET.get()
|
||||
.isWornBy(entity))
|
||||
|
@ -52,6 +55,11 @@ public class DivingHelmetItem extends CopperArmorItem {
|
|||
|
||||
if (drowning)
|
||||
entity.setAir(10);
|
||||
|
||||
if (world.isRemote)
|
||||
entity.getPersistentData()
|
||||
.putInt("VisualBacktankAir", airRemaining);
|
||||
|
||||
if (!second)
|
||||
return;
|
||||
|
||||
|
|
|
@ -121,10 +121,10 @@ public class SymmetryWandScreen extends AbstractSimiScreen {
|
|||
textRenderer.draw(matrixStack, wand.getDisplayName(), guiLeft + 11, guiTop + 4, 0x6B3802);
|
||||
renderBlock(matrixStack);
|
||||
GuiGameElement.of(wand)
|
||||
.at(guiLeft + 170, guiTop + 490, -150)
|
||||
.scale(4)
|
||||
.rotate(-70, 20, 20)
|
||||
.render(matrixStack);
|
||||
.scale(4)
|
||||
.rotate(-70, 20, 20)
|
||||
.at(guiLeft + 170, guiTop + 490, -150)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
||||
protected void renderBlock(MatrixStack ms) {
|
||||
|
|
|
@ -135,9 +135,9 @@ public class ZapperScreen extends AbstractSimiScreen {
|
|||
|
||||
protected void renderZapper(MatrixStack matrixStack) {
|
||||
GuiGameElement.of(zapper)
|
||||
.at((this.width - this.sWidth) / 2 + 220, this.height / 2 - this.sHeight / 4 + 27, -150)
|
||||
.scale(4)
|
||||
.render(matrixStack);
|
||||
.scale(4)
|
||||
.at((this.width - this.sWidth) / 2 + 220, this.height / 2 - this.sHeight / 4 + 27, -150)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
||||
protected void renderBlock(MatrixStack matrixStack) {
|
||||
|
|
|
@ -97,7 +97,7 @@ public class AdjustableCrateScreen extends AbstractSimiContainerScreen<Adjustabl
|
|||
}
|
||||
|
||||
GuiGameElement.of(renderedItem)
|
||||
.at(guiLeft + ADJUSTABLE_CRATE.width + 110, guiTop + 70, -150)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + ADJUSTABLE_CRATE.width + 110, guiTop + 70, -150)
|
||||
.scale(5)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ public class StockpileSwitchScreen extends AbstractSimiScreen {
|
|||
|
||||
matrixStack.push();
|
||||
GuiGameElement.of(renderedItem)
|
||||
.at(guiLeft + STOCKSWITCH.width + 15, guiTop + 40, -250)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + STOCKSWITCH.width + 15, guiTop + 40, -250)
|
||||
.scale(5)
|
||||
.render(matrixStack);
|
||||
matrixStack.pop();
|
||||
|
|
|
@ -69,7 +69,7 @@ public abstract class AbstractFilterScreen<F extends AbstractFilterContainer> ex
|
|||
textRenderer.draw(ms, I18n.format(container.filterItem.getTranslationKey()), x + 15, y + 3, 0xdedede);
|
||||
|
||||
GuiGameElement.of(container.filterItem)
|
||||
.at(x + background.width, guiTop + background.height - 60)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(x + background.width, guiTop + background.height - 60)
|
||||
.scale(5)
|
||||
.render(ms);
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ public class SchematicTableScreen extends AbstractSimiContainerScreen<SchematicT
|
|||
textRenderer.drawWithShadow(matrixStack, noSchematics, mainLeft + 54, mainTop + 26, 0xd3d3d3);
|
||||
|
||||
GuiGameElement.of(renderedItem)
|
||||
.at(mainLeft + 217, mainTop + 50, -150)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(mainLeft + 217, mainTop + 50, -150)
|
||||
.scale(3)
|
||||
.render(matrixStack);
|
||||
|
||||
|
|
|
@ -262,7 +262,7 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
|||
renderBlueprintHighlight(matrixStack);
|
||||
|
||||
GuiGameElement.of(renderedItem)
|
||||
.at(guiLeft + 230, guiTop + 110, -200)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + 230, guiTop + 110, -200)
|
||||
.scale(5)
|
||||
.render(matrixStack);
|
||||
|
||||
|
@ -274,7 +274,7 @@ public class SchematicannonScreen extends AbstractSimiContainerScreen<Schematica
|
|||
if (te.missingItem != null) {
|
||||
stringWidth += 15;
|
||||
GuiGameElement.of(te.missingItem)
|
||||
.at(guiLeft + 150, guiTop + 46, 100)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + 150, guiTop + 46, 100)
|
||||
.scale(1)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ public class SchematicEditScreen extends AbstractSimiScreen {
|
|||
x + 93 - textRenderer.getStringWidth(handler.getCurrentSchematicName()) / 2, y + 3, 0xffffff);
|
||||
|
||||
GuiGameElement.of(AllItems.SCHEMATIC.asStack())
|
||||
.at(guiLeft + 200, guiTop + 82, 0)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(guiLeft + 200, guiTop + 82, 0)
|
||||
.scale(3)
|
||||
.render(matrixStack);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.tra
|
|||
import com.simibubi.create.content.contraptions.components.turntable.TurntableHandler;
|
||||
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.item.BeltConnectorHandler;
|
||||
import com.simibubi.create.content.curiosities.armor.CopperBacktankArmorLayer;
|
||||
import com.simibubi.create.content.curiosities.tools.ExtendoGripRenderHandler;
|
||||
import com.simibubi.create.content.curiosities.zapper.ZapperItem;
|
||||
import com.simibubi.create.content.curiosities.zapper.ZapperRenderHandler;
|
||||
|
@ -30,6 +31,7 @@ import com.simibubi.create.content.curiosities.zapper.terrainzapper.WorldshaperR
|
|||
import com.simibubi.create.content.logistics.block.depot.EjectorTargetHandler;
|
||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPointHandler;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.config.ui.BaseConfigScreen;
|
||||
import com.simibubi.create.foundation.fluid.FluidHelper;
|
||||
import com.simibubi.create.foundation.item.ItemDescription;
|
||||
import com.simibubi.create.foundation.item.TooltipHelper;
|
||||
|
@ -54,6 +56,7 @@ import com.simibubi.create.foundation.utility.worldWrappers.WrappedClientWorld;
|
|||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.ActiveRenderInfo;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer.Impl;
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
|
@ -79,7 +82,11 @@ import net.minecraftforge.event.entity.player.ItemTooltipEvent;
|
|||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.ExtensionPoint;
|
||||
import net.minecraftforge.fml.ModContainer;
|
||||
import net.minecraftforge.fml.ModList;
|
||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
|
||||
|
||||
@EventBusSubscriber(value = Dist.CLIENT)
|
||||
public class ClientEvents {
|
||||
|
@ -195,12 +202,20 @@ public class ClientEvents {
|
|||
|
||||
@SubscribeEvent
|
||||
public static void onRenderOverlay(RenderGameOverlayEvent.Post event) {
|
||||
MatrixStack ms = event.getMatrixStack();
|
||||
Impl buffers = Minecraft.getInstance()
|
||||
.getBufferBuilders()
|
||||
.getEntityVertexConsumers();
|
||||
int light = 0xF000F0;
|
||||
int overlay = OverlayTexture.DEFAULT_UV;
|
||||
float pt = event.getPartialTicks();
|
||||
|
||||
if (event.getType() == ElementType.AIR)
|
||||
CopperBacktankArmorLayer.renderRemainingAirOverlay(ms, buffers, light, overlay, pt);
|
||||
if (event.getType() != ElementType.HOTBAR)
|
||||
return;
|
||||
|
||||
onRenderHotbar(event.getMatrixStack(), Minecraft.getInstance()
|
||||
.getBufferBuilders()
|
||||
.getEntityVertexConsumers(), 0xF000F0, OverlayTexture.DEFAULT_UV, event.getPartialTicks());
|
||||
onRenderHotbar(ms, buffers, light, overlay, pt);
|
||||
}
|
||||
|
||||
public static void onRenderHotbar(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay,
|
||||
|
@ -319,4 +334,9 @@ public class ClientEvents {
|
|||
}
|
||||
}
|
||||
|
||||
public static void loadCompleted(FMLLoadCompleteEvent event) {
|
||||
ModContainer createContainer = ModList.get().getModContainerById("create").orElseThrow(() -> new IllegalStateException("Create Mod Container missing after loadCompleted"));
|
||||
createContainer.registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, () -> (mc, previousScreen) -> new BaseConfigScreen(previousScreen));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,20 +21,22 @@ public class AllCommands {
|
|||
LiteralCommandNode<CommandSource> util = buildUtilityCommands();
|
||||
|
||||
LiteralCommandNode<CommandSource> createRoot = dispatcher.register(Commands.literal("create")
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
// general purpose
|
||||
.then(new ToggleExperimentalRenderingCommand().register())
|
||||
.then(new ToggleDebugCommand().register())
|
||||
.then(FabulousWarningCommand.register())
|
||||
.then(OverlayConfigCommand.register())
|
||||
.then(FixLightingCommand.register())
|
||||
.then(HighlightCommand.register())
|
||||
.then(CouplingCommand.register())
|
||||
.then(CloneCommand.register())
|
||||
.then(PonderCommand.register())
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
// general purpose
|
||||
.then(new ToggleExperimentalRenderingCommand().register())
|
||||
.then(new ToggleDebugCommand().register())
|
||||
.then(FabulousWarningCommand.register())
|
||||
.then(OverlayConfigCommand.register())
|
||||
.then(FixLightingCommand.register())
|
||||
.then(HighlightCommand.register())
|
||||
.then(CouplingCommand.register())
|
||||
.then(ConfigCommand.register())
|
||||
.then(PonderCommand.register())
|
||||
.then(CloneCommand.register())
|
||||
|
||||
// utility
|
||||
.then(util));
|
||||
// utility
|
||||
.then(util)
|
||||
);
|
||||
|
||||
createRoot.addChild(buildRedirect("u", util));
|
||||
|
||||
|
@ -50,12 +52,12 @@ public class AllCommands {
|
|||
private static LiteralCommandNode<CommandSource> buildUtilityCommands() {
|
||||
|
||||
return Commands.literal("util")
|
||||
.then(ReplaceInCommandBlocksCommand.register())
|
||||
.then(ClearBufferCacheCommand.register())
|
||||
.then(ChunkUtilCommand.register())
|
||||
.then(FlySpeedCommand.register())
|
||||
// .then(KillTPSCommand.register())
|
||||
.build();
|
||||
.then(ReplaceInCommandBlocksCommand.register())
|
||||
.then(ClearBufferCacheCommand.register())
|
||||
.then(ChunkUtilCommand.register())
|
||||
.then(FlySpeedCommand.register())
|
||||
//.then(KillTPSCommand.register())
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
|
@ -72,15 +74,15 @@ public class AllCommands {
|
|||
*
|
||||
* @return the built node
|
||||
*/
|
||||
public static LiteralCommandNode<CommandSource> buildRedirect(final String alias,
|
||||
final LiteralCommandNode<CommandSource> destination) {
|
||||
public static LiteralCommandNode<CommandSource> buildRedirect(final String alias, final LiteralCommandNode<CommandSource> destination) {
|
||||
// Redirects only work for nodes with children, but break the top argument-less command.
|
||||
// Manually adding the root command after setting the redirect doesn't fix it.
|
||||
// See https://github.com/Mojang/brigadier/issues/46). Manually clone the node instead.
|
||||
LiteralArgumentBuilder<CommandSource> builder = LiteralArgumentBuilder.<CommandSource>literal(alias)
|
||||
.requires(destination.getRequirement())
|
||||
.forward(destination.getRedirect(), destination.getRedirectModifier(), destination.isFork())
|
||||
.executes(destination.getCommand());
|
||||
LiteralArgumentBuilder<CommandSource> builder = LiteralArgumentBuilder
|
||||
.<CommandSource>literal(alias)
|
||||
.requires(destination.getRequirement())
|
||||
.forward(destination.getRedirect(), destination.getRedirectModifier(), destination.isFork())
|
||||
.executes(destination.getCommand());
|
||||
for (CommandNode<CommandSource> child : destination.getChildren()) {
|
||||
builder.then(child);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
package com.simibubi.create.foundation.command;
|
||||
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.command.Commands;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.builder.ArgumentBuilder;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
|
||||
public class ConfigCommand {
|
||||
|
||||
public static ArgumentBuilder<CommandSource, ?> register() {
|
||||
return Commands.literal("config")
|
||||
.executes(ctx -> {
|
||||
ServerPlayerEntity player = ctx.getSource().asPlayer();
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.configScreen.name(), "")
|
||||
);
|
||||
|
||||
return Command.SINGLE_SUCCESS;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -13,16 +13,18 @@ public class FabulousWarningCommand {
|
|||
|
||||
public static ArgumentBuilder<CommandSource, ?> register() {
|
||||
return Commands.literal("dismissFabulousWarning")
|
||||
.requires(AllCommands.sourceIsPlayer)
|
||||
.executes(ctx -> {
|
||||
ServerPlayerEntity player = ctx.getSource()
|
||||
.asPlayer();
|
||||
.requires(AllCommands.sourceIsPlayer)
|
||||
.executes(ctx -> {
|
||||
ServerPlayerEntity player = ctx.getSource()
|
||||
.asPlayer();
|
||||
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.fabulousWarning.name(), ""));
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.fabulousWarning.name(), "")
|
||||
);
|
||||
|
||||
return Command.SINGLE_SUCCESS;
|
||||
});
|
||||
return Command.SINGLE_SUCCESS;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ public class FixLightingCommand {
|
|||
.executes(ctx -> {
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource()
|
||||
.getEntity()),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.fixLighting.name(), String.valueOf(true)));
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.fixLighting.name(), String.valueOf(true)));
|
||||
|
||||
ctx.getSource()
|
||||
.sendFeedback(
|
||||
|
|
|
@ -15,35 +15,32 @@ public class OverlayConfigCommand {
|
|||
|
||||
public static ArgumentBuilder<CommandSource, ?> register() {
|
||||
return Commands.literal("overlay")
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
.then(Commands.literal("reset")
|
||||
.executes(ctx -> {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
|
||||
() -> () -> ConfigureConfigPacket.Actions.overlayReset.performAction(""));
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
.then(Commands.literal("reset")
|
||||
.executes(ctx -> {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> SConfigureConfigPacket.Actions.overlayReset.performAction(""));
|
||||
|
||||
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER,
|
||||
() -> () -> AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource()
|
||||
.getEntity()),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.overlayReset.name(), "")));
|
||||
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () ->
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.overlayReset.name(), "")));
|
||||
|
||||
ctx.getSource()
|
||||
.sendFeedback(new StringTextComponent("reset overlay offset"), true);
|
||||
|
||||
return 1;
|
||||
}))
|
||||
.executes(ctx -> {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
|
||||
() -> () -> ConfigureConfigPacket.Actions.overlayScreen.performAction(""));
|
||||
return 1;
|
||||
})
|
||||
)
|
||||
.executes(ctx -> {
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> SConfigureConfigPacket.Actions.overlayScreen.performAction(""));
|
||||
|
||||
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER,
|
||||
() -> () -> AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource()
|
||||
.getEntity()),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.overlayScreen.name(), "")));
|
||||
DistExecutor.unsafeRunWhenOn(Dist.DEDICATED_SERVER, () -> () ->
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> (ServerPlayerEntity) ctx.getSource().getEntity()),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.overlayScreen.name(), "")));
|
||||
|
||||
ctx.getSource()
|
||||
.sendFeedback(new StringTextComponent("window opened"), true);
|
||||
ctx.getSource()
|
||||
.sendFeedback(new StringTextComponent("window opened"), true);
|
||||
|
||||
return 1;
|
||||
});
|
||||
|
|
|
@ -21,26 +21,20 @@ import net.minecraftforge.common.util.FakePlayer;
|
|||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public class PonderCommand {
|
||||
public static final SuggestionProvider<CommandSource> ITEM_PONDERS = SuggestionProviders.register(
|
||||
new ResourceLocation("all_ponders"),
|
||||
(iSuggestionProviderCommandContext, builder) -> ISuggestionProvider.func_212476_a(PonderRegistry.all.keySet()
|
||||
.stream(), builder));
|
||||
public static final SuggestionProvider<CommandSource> ITEM_PONDERS = SuggestionProviders.register(new ResourceLocation("all_ponders"), (iSuggestionProviderCommandContext, builder) -> ISuggestionProvider.func_212476_a(PonderRegistry.all.keySet().stream(), builder));
|
||||
|
||||
static ArgumentBuilder<CommandSource, ?> register() {
|
||||
return Commands.literal("ponder")
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
.executes(ctx -> openScene("index", ctx.getSource()
|
||||
.asPlayer()))
|
||||
.then(Commands.argument("scene", ResourceLocationArgument.resourceLocation())
|
||||
.suggests(ITEM_PONDERS)
|
||||
.executes(ctx -> openScene(ResourceLocationArgument.getResourceLocation(ctx, "scene")
|
||||
.toString(),
|
||||
ctx.getSource()
|
||||
.asPlayer()))
|
||||
.then(Commands.argument("targets", EntityArgument.players())
|
||||
.requires(cs -> cs.hasPermissionLevel(2))
|
||||
.executes(ctx -> openScene(ResourceLocationArgument.getResourceLocation(ctx, "scene")
|
||||
.toString(), EntityArgument.getPlayers(ctx, "targets")))));
|
||||
.requires(cs -> cs.hasPermissionLevel(0))
|
||||
.executes(ctx -> openScene("index", ctx.getSource().asPlayer()))
|
||||
.then(Commands.argument("scene", ResourceLocationArgument.resourceLocation())
|
||||
.suggests(ITEM_PONDERS)
|
||||
.executes(ctx -> openScene(ResourceLocationArgument.getResourceLocation(ctx, "scene").toString(), ctx.getSource().asPlayer()))
|
||||
.then(Commands.argument("targets", EntityArgument.players())
|
||||
.requires(cs -> cs.hasPermissionLevel(2))
|
||||
.executes(ctx -> openScene(ResourceLocationArgument.getResourceLocation(ctx, "scene").toString(), EntityArgument.getPlayers(ctx, "targets")))
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
@ -53,8 +47,9 @@ public class PonderCommand {
|
|||
if (player instanceof FakePlayer)
|
||||
continue;
|
||||
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.openPonder.name(), sceneId));
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.openPonder.name(), sceneId));
|
||||
}
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.apache.logging.log4j.LogManager;
|
|||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.goggles.GoggleConfigScreen;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.config.ui.BaseConfigScreen;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
import com.simibubi.create.foundation.ponder.PonderRegistry;
|
||||
|
@ -31,17 +32,17 @@ import net.minecraftforge.common.ForgeConfig;
|
|||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
public class ConfigureConfigPacket extends SimplePacketBase {
|
||||
public class SConfigureConfigPacket extends SimplePacketBase {
|
||||
|
||||
private final String option;
|
||||
private final String value;
|
||||
|
||||
public ConfigureConfigPacket(String option, String value) {
|
||||
public SConfigureConfigPacket(String option, String value) {
|
||||
this.option = option;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public ConfigureConfigPacket(PacketBuffer buffer) {
|
||||
public SConfigureConfigPacket(PacketBuffer buffer) {
|
||||
this.option = buffer.readString(32767);
|
||||
this.value = buffer.readString(32767);
|
||||
}
|
||||
|
@ -69,7 +70,8 @@ public class ConfigureConfigPacket extends SimplePacketBase {
|
|||
.setPacketHandled(true);
|
||||
}
|
||||
|
||||
enum Actions {
|
||||
public enum Actions {
|
||||
configScreen(() -> Actions::configScreen),
|
||||
rainbowDebug(() -> Actions::rainbowDebug),
|
||||
overlayScreen(() -> Actions::overlayScreen),
|
||||
fixLighting(() -> Actions::experimentalLighting),
|
||||
|
@ -91,6 +93,11 @@ public class ConfigureConfigPacket extends SimplePacketBase {
|
|||
.accept(value);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static void configScreen(String value) {
|
||||
ScreenOpener.open(new BaseConfigScreen(null));
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static void rainbowDebug(String value) {
|
||||
ClientPlayerEntity player = Minecraft.getInstance().player;
|
|
@ -13,7 +13,9 @@ public class ToggleDebugCommand extends ConfigureConfigCommand {
|
|||
|
||||
@Override
|
||||
protected void sendPacket(ServerPlayerEntity player, String option) {
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.rainbowDebug.name(), option));
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.rainbowDebug.name(), option)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,9 @@ public class ToggleExperimentalRenderingCommand extends ConfigureConfigCommand {
|
|||
|
||||
@Override
|
||||
protected void sendPacket(ServerPlayerEntity player, String option) {
|
||||
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> player),
|
||||
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.experimentalRendering.name(), option));
|
||||
AllPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureConfigPacket(SConfigureConfigPacket.Actions.experimentalRendering.name(), option)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,8 +107,7 @@ public abstract class ConfigBase {
|
|||
if (comment.length > 0) {
|
||||
String[] comments = new String[comment.length + 1];
|
||||
comments[0] = "";
|
||||
for (int i = 0; i < comment.length; i++)
|
||||
comments[i + 1] = comment[i];
|
||||
System.arraycopy(comment, 0, comments, 1, comment.length);
|
||||
builder.comment(comments);
|
||||
} else
|
||||
builder.comment("");
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.gui.TextStencilElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
|
||||
public class BaseConfigScreen extends ConfigScreen {
|
||||
|
||||
BoxWidget clientConfigWidget;
|
||||
BoxWidget commonConfigWidget;
|
||||
BoxWidget serverConfigWidget;
|
||||
|
||||
public BaseConfigScreen(Screen parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
widgets.clear();
|
||||
super.init();
|
||||
|
||||
TextStencilElement text = new TextStencilElement(client.fontRenderer, new StringTextComponent("Client Settings").formatted(TextFormatting.BOLD)).centered(true, true);
|
||||
widgets.add(clientConfigWidget = new BoxWidget(width / 2 - 100, height / 2 - 15 - 30, 200, 16)
|
||||
.showingElement(text)
|
||||
.withCallback(() -> ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.CLIENT, AllConfigs.CLIENT.specification)))
|
||||
);
|
||||
text.withElementRenderer(BoxWidget.gradientFactory.apply(clientConfigWidget));
|
||||
|
||||
TextStencilElement text2 = new TextStencilElement(client.fontRenderer, new StringTextComponent("World Generation Settings").formatted(TextFormatting.BOLD)).centered(true, true);
|
||||
widgets.add(commonConfigWidget = new BoxWidget(width / 2 - 100, height / 2 - 15, 200, 16)
|
||||
.showingElement(text2)
|
||||
.withCallback(() -> ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.COMMON, AllConfigs.COMMON.specification)))
|
||||
);
|
||||
text2.withElementRenderer(BoxWidget.gradientFactory.apply(commonConfigWidget));
|
||||
|
||||
TextStencilElement text3 = new TextStencilElement(client.fontRenderer, new StringTextComponent("Gameplay Settings").formatted(TextFormatting.BOLD)).centered(true, true);
|
||||
widgets.add(serverConfigWidget = new BoxWidget(width / 2 - 100, height / 2 - 15 + 30, 200, 16)
|
||||
.showingElement(text3)
|
||||
);
|
||||
|
||||
if (Minecraft.getInstance().world != null) {
|
||||
serverConfigWidget.withCallback(() -> ScreenOpener.open(new SubMenuConfigScreen(this, ModConfig.Type.SERVER, AllConfigs.SERVER.specification)));
|
||||
text3.withElementRenderer(BoxWidget.gradientFactory.apply(serverConfigWidget));
|
||||
} else {
|
||||
serverConfigWidget.active = false;
|
||||
serverConfigWidget.updateColorsFromState();
|
||||
text3.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, Theme.i(Theme.Key.BUTTON_DISABLE, true), Theme.i(Theme.Key.BUTTON_DISABLE, false) | 0x40_000000));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.foundation.command.SConfigureConfigPacket;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public class CConfigureConfigPacket<T> extends SimplePacketBase {
|
||||
|
||||
private String path;
|
||||
private String value;
|
||||
|
||||
public CConfigureConfigPacket(String path, T value) {
|
||||
this.path = path;
|
||||
this.value = serialize(value);
|
||||
}
|
||||
|
||||
public CConfigureConfigPacket(PacketBuffer buffer) {
|
||||
this.path = buffer.readString(32767);
|
||||
this.value = buffer.readString(32767);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer) {
|
||||
buffer.writeString(path);
|
||||
buffer.writeString(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Supplier<NetworkEvent.Context> context) {
|
||||
ServerPlayerEntity sender = context.get().getSender();
|
||||
if (sender == null || !sender.hasPermissionLevel(2))
|
||||
return;
|
||||
|
||||
ForgeConfigSpec.ValueSpec valueSpec = AllConfigs.SERVER.specification.getRaw(path);
|
||||
ForgeConfigSpec.ConfigValue<T> configValue = AllConfigs.SERVER.specification.getValues().get(path);
|
||||
|
||||
T v = (T) deserialize(configValue.get(), value);
|
||||
if (!valueSpec.test(v))
|
||||
return;
|
||||
|
||||
configValue.set(v);
|
||||
|
||||
}
|
||||
|
||||
public String serialize(T value) {
|
||||
if (value instanceof Boolean)
|
||||
return Boolean.toString((Boolean) value);
|
||||
if (value instanceof Enum<?>)
|
||||
return ((Enum<?>) value).name();
|
||||
if (value instanceof Integer)
|
||||
return Integer.toString((Integer) value);
|
||||
if (value instanceof Float)
|
||||
return Float.toString((Float) value);
|
||||
if (value instanceof Double)
|
||||
return Double.toString((Double) value);
|
||||
|
||||
throw new IllegalArgumentException("unknown type " + value + ": " + value.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public Object deserialize(Object type, String sValue) {
|
||||
if (type instanceof Boolean)
|
||||
return Boolean.parseBoolean(sValue);
|
||||
if (type instanceof Enum<?>)
|
||||
return Enum.valueOf(((Enum<?>) type).getClass(), sValue);
|
||||
if (type instanceof Integer)
|
||||
return Integer.parseInt(sValue);
|
||||
if (type instanceof Float)
|
||||
return Float.parseFloat(sValue);
|
||||
if (type instanceof Double)
|
||||
return Double.parseDouble(sValue);
|
||||
|
||||
throw new IllegalArgumentException("unknown type " + type + ": " + type.getClass().getSimpleName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock;
|
||||
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
|
||||
import com.simibubi.create.foundation.gui.GuiGameElement;
|
||||
import com.simibubi.create.foundation.gui.StencilElement;
|
||||
import com.simibubi.create.foundation.utility.animation.Force;
|
||||
import com.simibubi.create.foundation.utility.animation.PhysicalFloat;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
public abstract class ConfigScreen extends AbstractSimiScreen {
|
||||
|
||||
/*
|
||||
*
|
||||
* zelo's list for configUI
|
||||
*
|
||||
* reduce number of packets sent to the server when saving a bunch of values
|
||||
* maybe replace java's awt color with something mutable
|
||||
* find out why framebuffer blending is incorrect
|
||||
*
|
||||
* FIXME
|
||||
*
|
||||
* tooltips are hidden underneath the scrollbar, if the bar is near the middle
|
||||
*
|
||||
* */
|
||||
|
||||
public static final PhysicalFloat cogSpin = PhysicalFloat.create().withDrag(0.3).addForce(new Force.Static(.2f));
|
||||
public static final BlockState cogwheelState = AllBlocks.LARGE_COGWHEEL.getDefaultState().with(CogWheelBlock.AXIS, Direction.Axis.Y);
|
||||
public static final Map<String, Object> changes = new HashMap<>();
|
||||
protected final Screen parent;
|
||||
|
||||
public ConfigScreen(Screen parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
cogSpin.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderBackground(@Nonnull MatrixStack ms) {
|
||||
net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.client.event.GuiScreenEvent.BackgroundDrawnEvent(this, ms));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
if (this.client != null && this.client.world != null) {
|
||||
fill(ms, 0, 0, this.width, this.height, 0xb0_282c34);
|
||||
} else {
|
||||
fill(ms, 0, 0, this.width, this.height, 0xff_282c34);
|
||||
}
|
||||
|
||||
new StencilElement() {
|
||||
@Override
|
||||
protected void renderStencil(MatrixStack ms) {
|
||||
renderCog(ms, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderElement(MatrixStack ms) {
|
||||
fill(ms, -200, -200, 200, 200, 0x60_000000);
|
||||
}
|
||||
}.at(width * 0.5f, height * 0.5f, 0).render(ms);
|
||||
|
||||
super.renderWindowBackground(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(double mouseX, double mouseY, double delta) {
|
||||
cogSpin.bump(3, -delta * 5);
|
||||
|
||||
return super.mouseScrolled(mouseX, mouseY, delta);
|
||||
}
|
||||
|
||||
public static String toHumanReadable(String key) {
|
||||
String s = key.replaceAll("_", " ");
|
||||
s = Arrays.stream(StringUtils.splitByCharacterTypeCamelCase(s)).map(StringUtils::capitalize).collect(Collectors.joining(" "));
|
||||
s = s.replaceAll("\\s\\s+", " ");
|
||||
return s;
|
||||
}
|
||||
|
||||
protected void renderCog(MatrixStack ms, float partialTicks) {
|
||||
ms.push();
|
||||
|
||||
ms.translate(-100, 100, -100);
|
||||
ms.scale(200, 200, 1);
|
||||
GuiGameElement.of(cogwheelState)
|
||||
.rotateBlock(22.5, cogSpin.getValue(partialTicks), 22.5)
|
||||
.render(ms);
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,176 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.simibubi.create.foundation.config.ui.entries.NumberEntry;
|
||||
import com.simibubi.create.foundation.gui.TextStencilElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
|
||||
import net.minecraft.client.MainWindow;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.IGuiEventListener;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.client.gui.widget.list.ExtendedList;
|
||||
import net.minecraft.util.text.IFormattableTextComponent;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraftforge.fml.client.gui.GuiUtils;
|
||||
|
||||
public class ConfigScreenList extends ExtendedList<ConfigScreenList.Entry> {
|
||||
|
||||
public static TextFieldWidget currentText;
|
||||
|
||||
public boolean isForServer = false;
|
||||
|
||||
public ConfigScreenList(Minecraft client, int width, int height, int top, int bottom, int elementHeight) {
|
||||
super(client, width, height, top, bottom, elementHeight);
|
||||
func_244605_b(false);
|
||||
func_244606_c(false);
|
||||
setRenderSelection(false);
|
||||
currentText = null;
|
||||
headerHeight = 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
UIRenderHelper.angledGradient(ms, 90, left + width / 2, top, width, 5, 0x60_000000, 0x0);
|
||||
UIRenderHelper.angledGradient(ms, -90, left + width / 2, bottom, width, 5, 0x60_000000, 0x0);
|
||||
UIRenderHelper.angledGradient(ms, 0, left, top + height / 2, height, 5, 0x60_000000, 0x0);
|
||||
UIRenderHelper.angledGradient(ms, 180, right, top + height / 2, height, 5, 0x60_000000, 0x0);
|
||||
|
||||
super.render(ms, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderList(MatrixStack p_238478_1_, int p_238478_2_, int p_238478_3_, int p_238478_4_, int p_238478_5_, float p_238478_6_) {
|
||||
MainWindow window = Minecraft.getInstance().getWindow();
|
||||
double d0 = window.getGuiScaleFactor();
|
||||
RenderSystem.enableScissor((int) (this.left * d0), (int) (window.getFramebufferHeight() - (this.bottom * d0)), (int) (this.width * d0), (int) (this.height * d0));
|
||||
super.renderList(p_238478_1_, p_238478_2_, p_238478_3_, p_238478_4_, p_238478_5_, p_238478_6_);
|
||||
RenderSystem.disableScissor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double x, double y, int button) {
|
||||
children().stream().filter(e -> e instanceof NumberEntry<?>).forEach(e -> e.mouseClicked(x, y, button));
|
||||
|
||||
return super.mouseClicked(x, y, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRowWidth() {
|
||||
return width - 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getScrollbarPositionX() {
|
||||
return left + this.width - 6;
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
for(int i = 0; i < getItemCount(); ++i) {
|
||||
int top = this.getRowTop(i);
|
||||
int bot = top + itemHeight;
|
||||
if (bot >= this.top && top <= this.bottom)
|
||||
this.getEntry(i).tick();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void bumpCog(float force) {
|
||||
ConfigScreen.cogSpin.bump(3, force);
|
||||
}
|
||||
|
||||
public static abstract class Entry extends ExtendedList.AbstractListEntry<Entry> {
|
||||
protected List<IGuiEventListener> listeners;
|
||||
|
||||
protected Entry() {
|
||||
listeners = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(double x, double y, int button) {
|
||||
return getGuiListeners().stream().anyMatch(l -> l.mouseClicked(x, y, button));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int code, int keyPressed_2_, int keyPressed_3_) {
|
||||
return getGuiListeners().stream().anyMatch(l -> l.keyPressed(code, keyPressed_2_, keyPressed_3_));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean charTyped(char ch, int code) {
|
||||
return getGuiListeners().stream().anyMatch(l -> l.charTyped(ch, code));
|
||||
}
|
||||
|
||||
public void tick() {}
|
||||
|
||||
public List<IGuiEventListener> getGuiListeners() {
|
||||
return listeners;
|
||||
}
|
||||
|
||||
protected void setEditable(boolean b) {}
|
||||
}
|
||||
|
||||
public static class LabeledEntry extends Entry {
|
||||
|
||||
protected static final float labelWidthMult = 0.4f;
|
||||
|
||||
protected TextStencilElement label;
|
||||
protected List<ITextComponent> labelTooltip;
|
||||
protected String unit = null;
|
||||
|
||||
public LabeledEntry(String label) {
|
||||
this.label = new TextStencilElement(Minecraft.getInstance().fontRenderer, label);
|
||||
this.label.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, Theme.p(Theme.Key.TEXT_ACCENT_STRONG)));
|
||||
labelTooltip = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms, int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean p_230432_9_, float partialTicks) {
|
||||
UIRenderHelper.streak(ms, 0, x, y + height / 2, height - 6, width, 0xdd_000000);
|
||||
IFormattableTextComponent component = label.getComponent();
|
||||
FontRenderer font = Minecraft.getInstance().fontRenderer;
|
||||
if (font.getWidth(component) > getLabelWidth(width) - 10) {
|
||||
label.withText(font.trimToWidth(component, getLabelWidth(width) - 15).getString() + "...");
|
||||
}
|
||||
if (unit != null) {
|
||||
int unitWidth = font.getStringWidth(unit);
|
||||
font.draw(ms, unit, x + getLabelWidth(width) - unitWidth - 5, y + height / 2 + 2, Theme.i(Theme.Key.TEXT_DARKER));
|
||||
label.at(x + 10, y + height / 2 - 10, 0).render(ms);
|
||||
} else {
|
||||
label.at(x + 10, y + height / 2 - 4, 0).render(ms);
|
||||
}
|
||||
|
||||
|
||||
if (mouseX > x && mouseX < x + getLabelWidth(width) && mouseY > y + 5 && mouseY < y + height - 5) {
|
||||
List<ITextComponent> tooltip = getLabelTooltip();
|
||||
if (tooltip.isEmpty())
|
||||
return;
|
||||
|
||||
GL11.glDisable(GL11.GL_SCISSOR_TEST);
|
||||
Screen screen = Minecraft.getInstance().currentScreen;
|
||||
ms.push();
|
||||
ms.translate(0, 0, 400);
|
||||
GuiUtils.drawHoveringText(ms, tooltip, mouseX, mouseY, screen.width, screen.height, 300, font);
|
||||
ms.pop();
|
||||
GL11.glEnable(GL11.GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
public List<ITextComponent> getLabelTooltip() {
|
||||
return labelTooltip;
|
||||
}
|
||||
|
||||
protected int getLabelWidth(int totalWidth) {
|
||||
return totalWidth;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
public class ConfigTextField extends TextFieldWidget {
|
||||
|
||||
protected FontRenderer font;
|
||||
protected String unit;
|
||||
|
||||
public ConfigTextField(FontRenderer font, int x, int y, int width, int height, String unit) {
|
||||
super(font, x, y, width, height, StringTextComponent.EMPTY);
|
||||
this.font = font;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFocused2(boolean focus) {
|
||||
super.setFocused2(focus);
|
||||
|
||||
if (!focus) {
|
||||
if (ConfigScreenList.currentText == this)
|
||||
ConfigScreenList.currentText = null;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ConfigScreenList.currentText != null && ConfigScreenList.currentText != this)
|
||||
ConfigScreenList.currentText.setFocused2(false);
|
||||
|
||||
ConfigScreenList.currentText = this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,345 @@
|
|||
package com.simibubi.create.foundation.config.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import com.electronwill.nightconfig.core.AbstractConfig;
|
||||
import com.electronwill.nightconfig.core.UnmodifiableConfig;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.config.ui.entries.BooleanEntry;
|
||||
import com.simibubi.create.foundation.config.ui.entries.EnumEntry;
|
||||
import com.simibubi.create.foundation.config.ui.entries.NumberEntry;
|
||||
import com.simibubi.create.foundation.config.ui.entries.SubMenuEntry;
|
||||
import com.simibubi.create.foundation.config.ui.entries.ValueEntry;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.gui.ConfirmationScreen;
|
||||
import com.simibubi.create.foundation.gui.DelegatedStencilElement;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
import com.simibubi.create.foundation.item.TooltipHelper;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.IGuiEventListener;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.util.text.ITextProperties;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
|
||||
public class SubMenuConfigScreen extends ConfigScreen {
|
||||
|
||||
public final ModConfig.Type type;
|
||||
protected ForgeConfigSpec spec;
|
||||
protected UnmodifiableConfig configGroup;
|
||||
protected ConfigScreenList list;
|
||||
|
||||
protected BoxWidget resetAll;
|
||||
protected BoxWidget saveChanges;
|
||||
protected BoxWidget discardChanges;
|
||||
protected BoxWidget goBack;
|
||||
protected BoxWidget serverLocked;
|
||||
protected int listWidth;
|
||||
protected String title;
|
||||
|
||||
|
||||
public SubMenuConfigScreen(Screen parent, String title, ModConfig.Type type, ForgeConfigSpec configSpec, UnmodifiableConfig configGroup) {
|
||||
super(parent);
|
||||
this.type = type;
|
||||
this.spec = configSpec;
|
||||
this.title = title;
|
||||
this.configGroup = configGroup;
|
||||
}
|
||||
|
||||
public SubMenuConfigScreen(Screen parent, ModConfig.Type type, ForgeConfigSpec configSpec) {
|
||||
super(parent);
|
||||
this.type = type;
|
||||
this.spec = configSpec;
|
||||
this.title = "root";
|
||||
this.configGroup = configSpec.getValues();
|
||||
}
|
||||
|
||||
protected void clearChanges() {
|
||||
changes.clear();
|
||||
list.children()
|
||||
.stream()
|
||||
.filter(e -> e instanceof ValueEntry)
|
||||
.forEach(e -> ((ValueEntry<?>) e).onValueChange());
|
||||
}
|
||||
|
||||
protected void saveChanges() {
|
||||
UnmodifiableConfig values = spec.getValues();
|
||||
changes.forEach((path, value) -> {
|
||||
ForgeConfigSpec.ConfigValue configValue = values.get(path);
|
||||
configValue.set(value);
|
||||
if (type == ModConfig.Type.SERVER) {
|
||||
AllPackets.channel.sendToServer(new CConfigureConfigPacket<>(path, value));
|
||||
}
|
||||
});
|
||||
clearChanges();
|
||||
}
|
||||
|
||||
protected void resetConfig(UnmodifiableConfig values) {
|
||||
values.valueMap().forEach((key, obj) -> {
|
||||
if (obj instanceof AbstractConfig) {
|
||||
resetConfig((UnmodifiableConfig) obj);
|
||||
} else if (obj instanceof ForgeConfigSpec.ConfigValue<?>) {
|
||||
ForgeConfigSpec.ConfigValue<?> configValue = (ForgeConfigSpec.ConfigValue<?>) obj;
|
||||
ForgeConfigSpec.ValueSpec valueSpec = spec.getRaw(configValue.getPath());
|
||||
|
||||
if (!configValue.get().equals(valueSpec.getDefault()))
|
||||
changes.put(String.join(".", configValue.getPath()), valueSpec.getDefault());
|
||||
}
|
||||
});
|
||||
|
||||
list.children()
|
||||
.stream()
|
||||
.filter(e -> e instanceof ValueEntry)
|
||||
.forEach(e -> ((ValueEntry<?>) e).onValueChange());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
list.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
widgets.clear();
|
||||
super.init();
|
||||
|
||||
listWidth = Math.min(width - 80, 300);
|
||||
|
||||
int yCenter = height / 2;
|
||||
int listL = this.width / 2 - listWidth / 2;
|
||||
int listR = this.width / 2 + listWidth / 2;
|
||||
|
||||
resetAll = new BoxWidget(listR + 10, yCenter - 25, 20, 20)
|
||||
.withPadding(2, 2)
|
||||
.withCallback((x, y) ->
|
||||
new ConfirmationScreen()
|
||||
.at(x, y)
|
||||
.withText(ITextProperties.plain("You are about to reset all settings for the " + type.toString() + " config. Are you sure?"))
|
||||
.withAction(success -> {
|
||||
if (success)
|
||||
resetConfig(spec.getValues());
|
||||
})
|
||||
.open(this)
|
||||
);
|
||||
|
||||
resetAll.showingElement(AllIcons.I_CONFIG_RESET.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(resetAll)));
|
||||
resetAll.getToolTip().add(new StringTextComponent("Reset All"));
|
||||
resetAll.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to reset all configs to their default value.", TextFormatting.GRAY, TextFormatting.GRAY));
|
||||
|
||||
saveChanges = new BoxWidget(listL - 30, yCenter - 25, 20, 20)
|
||||
.withPadding(2, 2)
|
||||
.withCallback((x, y) -> {
|
||||
if (changes.isEmpty())
|
||||
return;
|
||||
|
||||
new ConfirmationScreen()
|
||||
.at(x, y)
|
||||
.withText(ITextProperties.plain("You are about to change " + changes.size() + " value" + (changes.size() != 1 ? "s" : "") + ". Are you sure?"))
|
||||
.withAction(success -> {
|
||||
if (success)
|
||||
saveChanges();
|
||||
})
|
||||
.open(this);
|
||||
});
|
||||
saveChanges.showingElement(AllIcons.I_CONFIG_SAVE.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(saveChanges)));
|
||||
saveChanges.getToolTip().add(new StringTextComponent("Save Changes"));
|
||||
saveChanges.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to save your current changes.", TextFormatting.GRAY, TextFormatting.GRAY));
|
||||
|
||||
discardChanges = new BoxWidget(listL - 30, yCenter + 5, 20, 20)
|
||||
.withPadding(2, 2)
|
||||
.withCallback((x, y) -> {
|
||||
if (changes.isEmpty())
|
||||
return;
|
||||
|
||||
new ConfirmationScreen()
|
||||
.at(x, y)
|
||||
.withText(ITextProperties.plain("You are about to discard " + changes.size() + " unsaved change" + (changes.size() != 1 ? "s" : "") + ". Are you sure?"))
|
||||
.withAction(success -> {
|
||||
if (success)
|
||||
clearChanges();
|
||||
})
|
||||
.open(this);
|
||||
});
|
||||
discardChanges.showingElement(AllIcons.I_CONFIG_DISCARD.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(discardChanges)));
|
||||
discardChanges.getToolTip().add(new StringTextComponent("Discard Changes"));
|
||||
discardChanges.getToolTip().addAll(TooltipHelper.cutStringTextComponent("Click here to discard all the changes you made.", TextFormatting.GRAY, TextFormatting.GRAY));
|
||||
|
||||
goBack = new BoxWidget(listL - 30, yCenter + 65, 20, 20)
|
||||
.withPadding(2, 2)
|
||||
.withCallback(this::attemptBackstep);
|
||||
goBack.showingElement(AllIcons.I_CONFIG_BACK.asStencil().withElementRenderer(BoxWidget.gradientFactory.apply(goBack)));
|
||||
goBack.getToolTip().add(new StringTextComponent("Go Back"));
|
||||
|
||||
widgets.add(resetAll);
|
||||
widgets.add(saveChanges);
|
||||
widgets.add(discardChanges);
|
||||
widgets.add(goBack);
|
||||
|
||||
list = new ConfigScreenList(client, listWidth, height - 60, 45, height - 15, 40);
|
||||
list.setLeftPos(this.width / 2 - list.getWidth() / 2);
|
||||
|
||||
children.add(list);
|
||||
|
||||
configGroup.valueMap().forEach((key, obj) -> {
|
||||
String humanKey = toHumanReadable(key);
|
||||
|
||||
if (obj instanceof AbstractConfig) {
|
||||
SubMenuEntry entry = new SubMenuEntry(this, humanKey, spec, (UnmodifiableConfig) obj);
|
||||
list.children().add(entry);
|
||||
|
||||
} else if (obj instanceof ForgeConfigSpec.ConfigValue<?>) {
|
||||
ForgeConfigSpec.ConfigValue<?> configValue = (ForgeConfigSpec.ConfigValue<?>) obj;
|
||||
ForgeConfigSpec.ValueSpec valueSpec = spec.getRaw(configValue.getPath());
|
||||
Object value = configValue.get();
|
||||
|
||||
if (value instanceof Boolean) {
|
||||
BooleanEntry entry = new BooleanEntry(humanKey, (ForgeConfigSpec.ConfigValue<Boolean>) configValue, valueSpec);
|
||||
list.children().add(entry);
|
||||
} else if (value instanceof Enum) {
|
||||
EnumEntry entry = new EnumEntry(humanKey, (ForgeConfigSpec.ConfigValue<Enum<?>>) configValue, valueSpec);
|
||||
list.children().add(entry);
|
||||
} else if (value instanceof Number) {
|
||||
NumberEntry<? extends Number> entry = NumberEntry.create(value, humanKey, configValue, valueSpec);
|
||||
if (entry != null) {
|
||||
list.children().add(entry);
|
||||
} else {
|
||||
list.children().add(new ConfigScreenList.LabeledEntry("n-" + obj.getClass().getSimpleName() + " " + humanKey + " : " + value));
|
||||
}
|
||||
} else {
|
||||
list.children().add(new ConfigScreenList.LabeledEntry(humanKey + " : " + value));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//extras for server configs
|
||||
if (type != ModConfig.Type.SERVER)
|
||||
return;
|
||||
|
||||
list.isForServer = true;
|
||||
boolean canEdit = client != null && client.player != null && client.player.hasPermissionLevel(2);
|
||||
|
||||
Couple<Color> red = Theme.p(Theme.Key.BUTTON_FAIL);
|
||||
Couple<Color> green = Theme.p(Theme.Key.BUTTON_SUCCESS);
|
||||
|
||||
DelegatedStencilElement stencil = new DelegatedStencilElement();
|
||||
|
||||
serverLocked = new BoxWidget(listR + 10, yCenter + 5, 20, 20)
|
||||
.withPadding(2, 2)
|
||||
.showingElement(stencil);
|
||||
|
||||
if (!canEdit) {
|
||||
list.children().forEach(e -> e.setEditable(false));
|
||||
resetAll.active = false;
|
||||
stencil.withStencilRenderer((ms, w, h, alpha) -> AllIcons.I_CONFIG_LOCKED.draw(ms, 0, 0));
|
||||
stencil.withElementRenderer((ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, red));
|
||||
serverLocked.withBorderColors(red);
|
||||
serverLocked.getToolTip().add(new StringTextComponent("Locked").formatted(TextFormatting.BOLD));
|
||||
serverLocked.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You don't have enough permissions to edit the server config. You can still look at the current values here though.", TextFormatting.GRAY, TextFormatting.GRAY));
|
||||
} else {
|
||||
stencil.withStencilRenderer((ms, w, h, alpha) -> AllIcons.I_CONFIG_UNLOCKED.draw(ms, 0, 0));
|
||||
stencil.withElementRenderer((ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, 8, 0, 16, 16, green));
|
||||
serverLocked.withBorderColors(green);
|
||||
serverLocked.getToolTip().add(new StringTextComponent("Unlocked").formatted(TextFormatting.BOLD));
|
||||
serverLocked.getToolTip().addAll(TooltipHelper.cutStringTextComponent("You have enough permissions to edit the server config. Changes you make here will be synced with the server when you save them.", TextFormatting.GRAY, TextFormatting.GRAY));
|
||||
}
|
||||
|
||||
widgets.add(serverLocked);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
super.renderWindow(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
int x = width/2;
|
||||
drawCenteredString(ms, client.fontRenderer, "Editing config: " + type.toString() + "@" + title, x, 15, Theme.i(Theme.Key.TEXT));
|
||||
|
||||
list.render(ms, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindowForeground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
super.renderWindowForeground(ms, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(@Nonnull Minecraft client, int width, int height) {
|
||||
double scroll = list.getScrollAmount();
|
||||
init(client, width, height);
|
||||
list.setScrollAmount(scroll);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IGuiEventListener getFocused() {
|
||||
if (ConfigScreenList.currentText != null)
|
||||
return ConfigScreenList.currentText;
|
||||
|
||||
return super.getFocused();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int code, int p_keyPressed_2_, int p_keyPressed_3_) {
|
||||
if (super.keyPressed(code, p_keyPressed_2_, p_keyPressed_3_))
|
||||
return true;
|
||||
|
||||
if (code == GLFW.GLFW_KEY_BACKSPACE) {
|
||||
attemptBackstep();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void attemptBackstep() {
|
||||
if (!changes.isEmpty() && parent instanceof BaseConfigScreen) {
|
||||
new ConfirmationScreen()
|
||||
.centered()
|
||||
.addText(ITextProperties.plain("You still have " + changes.size() + " unsaved change" + (changes.size() != 1 ? "s" : "") + " for this config."))
|
||||
.addText(ITextProperties.plain("Leaving this screen will discard them without saving. Are you sure?"))
|
||||
.withAction(success -> {
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
changes.clear();
|
||||
ScreenOpener.open(parent);
|
||||
})
|
||||
.open(this);
|
||||
} else {
|
||||
ScreenOpener.open(parent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
if (changes.isEmpty()) {
|
||||
super.onClose();
|
||||
return;
|
||||
}
|
||||
|
||||
new ConfirmationScreen()
|
||||
.centered()
|
||||
.addText(ITextProperties.plain("You still have " + changes.size() + " unsaved change" + (changes.size() != 1 ? "s" : "") + " for this config."))
|
||||
.addText(ITextProperties.plain("Leaving this screen will discard them without saving. Are you sure?"))
|
||||
.withAction(success -> {
|
||||
if (!success)
|
||||
return;
|
||||
|
||||
changes.clear();
|
||||
super.onClose();
|
||||
})
|
||||
.open(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package com.simibubi.create.foundation.config.ui.entries;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.gui.RenderElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
public class BooleanEntry extends ValueEntry<Boolean> {
|
||||
|
||||
RenderElement enabled;
|
||||
RenderElement disabled;
|
||||
BoxWidget button;
|
||||
|
||||
public BooleanEntry(String label, ForgeConfigSpec.ConfigValue<Boolean> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
|
||||
enabled = AllIcons.I_CONFIRM.asStencil()
|
||||
.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, Theme.p(Theme.Key.BUTTON_SUCCESS)))
|
||||
.at(10, 0);
|
||||
|
||||
disabled = AllIcons.I_DISABLE.asStencil()
|
||||
.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2, height, width, Theme.p(Theme.Key.BUTTON_FAIL)))
|
||||
.at(10, 0);
|
||||
|
||||
button = new BoxWidget().showingElement(enabled)
|
||||
.withCallback(() -> setValue(!getValue()));
|
||||
|
||||
listeners.add(button);
|
||||
onReset();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEditable(boolean b) {
|
||||
super.setEditable(b);
|
||||
button.active = b;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
button.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms, int index, int y, int x, int width, int height, int mouseX, int mouseY,
|
||||
boolean p_230432_9_, float partialTicks) {
|
||||
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
|
||||
|
||||
button.x = x + width - 80 - resetWidth;
|
||||
button.y = y + 10;
|
||||
button.setWidth(35);
|
||||
button.setHeight(height - 20);
|
||||
button.render(ms, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueChange(Boolean newValue) {
|
||||
super.onValueChange(newValue);
|
||||
button.showingElement(newValue ? enabled : disabled);
|
||||
bumpCog(newValue ? 15f : -16f);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package com.simibubi.create.foundation.config.ui.entries;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.gui.BoxElement;
|
||||
import com.simibubi.create.foundation.gui.DelegatedStencilElement;
|
||||
import com.simibubi.create.foundation.gui.TextStencilElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
public class EnumEntry extends ValueEntry<Enum<?>> {
|
||||
|
||||
protected static final int cycleWidth = 34;
|
||||
|
||||
protected TextStencilElement valueText;
|
||||
protected BoxWidget cycleLeft;
|
||||
protected BoxWidget cycleRight;
|
||||
|
||||
public EnumEntry(String label, ForgeConfigSpec.ConfigValue<Enum<?>> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
|
||||
valueText = new TextStencilElement(Minecraft.getInstance().fontRenderer, "YEP").centered(true, true);
|
||||
valueText.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, 0, height / 2,
|
||||
height, width, Theme.p(Theme.Key.TEXT)));
|
||||
|
||||
DelegatedStencilElement l = AllIcons.I_CONFIG_PREV.asStencil();
|
||||
cycleLeft = new BoxWidget(0, 0, cycleWidth + 8, 16).showingElement(l)
|
||||
.withCallback(() -> cycleValue(-1));
|
||||
l.withElementRenderer(BoxWidget.gradientFactory.apply(cycleLeft));
|
||||
|
||||
DelegatedStencilElement r = AllIcons.I_CONFIG_NEXT.asStencil();
|
||||
cycleRight = new BoxWidget(0, 0, cycleWidth + 8, 16).showingElement(r)
|
||||
.withCallback(() -> cycleValue(1));
|
||||
r.at(cycleWidth - 8, 0);
|
||||
r.withElementRenderer(BoxWidget.gradientFactory.apply(cycleRight));
|
||||
|
||||
listeners.add(cycleLeft);
|
||||
listeners.add(cycleRight);
|
||||
|
||||
onReset();
|
||||
}
|
||||
|
||||
protected void cycleValue(int direction) {
|
||||
Enum<?> e = getValue();
|
||||
Enum<?>[] options = e.getDeclaringClass()
|
||||
.getEnumConstants();
|
||||
e = options[Math.floorMod(e.ordinal() + direction, options.length)];
|
||||
setValue(e);
|
||||
bumpCog(direction * 15f);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEditable(boolean b) {
|
||||
super.setEditable(b);
|
||||
cycleLeft.active = b;
|
||||
cycleLeft.animateGradientFromState();
|
||||
cycleRight.active = b;
|
||||
cycleRight.animateGradientFromState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
cycleLeft.tick();
|
||||
cycleRight.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms, int index, int y, int x, int width, int height, int mouseX, int mouseY,
|
||||
boolean p_230432_9_, float partialTicks) {
|
||||
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
|
||||
|
||||
cycleLeft.x = x + getLabelWidth(width) + 4;
|
||||
cycleLeft.y = y + 10;
|
||||
cycleLeft.render(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
valueText.at(cycleLeft.x + cycleWidth - 8, y + 11, 200)
|
||||
.withBounds(width - getLabelWidth(width) - 2 * cycleWidth - resetWidth - 4, 16)
|
||||
.render(ms);
|
||||
|
||||
cycleRight.x = x + width - cycleWidth * 2 - resetWidth + 10;
|
||||
cycleRight.y = y + 10;
|
||||
cycleRight.render(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
new BoxElement()
|
||||
.withBackground(0)
|
||||
.flatBorder(0)
|
||||
.withBounds(10, 10)
|
||||
.at(cycleLeft.x + cycleWidth + 4, cycleLeft.y + 3)
|
||||
.render(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueChange(Enum<?> newValue) {
|
||||
super.onValueChange(newValue);
|
||||
valueText.withText(newValue.name());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
package com.simibubi.create.foundation.config.ui.entries;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.config.ui.ConfigTextField;
|
||||
import com.simibubi.create.foundation.gui.TextStencilElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
public abstract class NumberEntry<T extends Number> extends ValueEntry<T> {
|
||||
|
||||
protected int minOffset = 0, maxOffset = 0;
|
||||
protected TextStencilElement minText = null, maxText = null;
|
||||
protected TextFieldWidget textField;
|
||||
|
||||
@Nullable
|
||||
public static NumberEntry<? extends Number> create(Object type, String label, ForgeConfigSpec.ConfigValue<?> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
if (type instanceof Integer) {
|
||||
return new IntegerEntry(label, (ForgeConfigSpec.ConfigValue<Integer>) value, spec);
|
||||
} else if (type instanceof Float) {
|
||||
return new FloatEntry(label, (ForgeConfigSpec.ConfigValue<Float>) value, spec);
|
||||
} else if (type instanceof Double) {
|
||||
return new DoubleEntry(label, (ForgeConfigSpec.ConfigValue<Double>) value, spec);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public NumberEntry(String label, ForgeConfigSpec.ConfigValue<T> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
textField = new ConfigTextField(Minecraft.getInstance().fontRenderer, 0, 0, 200, 20, unit);
|
||||
textField.setText(String.valueOf(getValue()));
|
||||
textField.setTextColor(Theme.i(Theme.Key.TEXT));
|
||||
|
||||
Object range = spec.getRange();
|
||||
try {
|
||||
Field minField = range.getClass().getDeclaredField("min");
|
||||
Field maxField = range.getClass().getDeclaredField("max");
|
||||
minField.setAccessible(true);
|
||||
maxField.setAccessible(true);
|
||||
T min = (T) minField.get(range);
|
||||
T max = (T) maxField.get(range);
|
||||
|
||||
FontRenderer font = Minecraft.getInstance().fontRenderer;
|
||||
if (min.doubleValue() > getTypeMin().doubleValue()) {
|
||||
StringTextComponent t = new StringTextComponent(formatBound(min) + " < ");
|
||||
minText = new TextStencilElement(font, t).centered(true, false);
|
||||
minText.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0 ,0, height/2, height, width, Theme.p(Theme.Key.TEXT_DARKER)));
|
||||
minOffset = font.getWidth(t);
|
||||
}
|
||||
if (max.doubleValue() < getTypeMax().doubleValue()) {
|
||||
StringTextComponent t = new StringTextComponent(" < " + formatBound(max));
|
||||
maxText = new TextStencilElement(font, t).centered(true, false);
|
||||
maxText.withElementRenderer((ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0 ,0, height/2, height, width, Theme.p(Theme.Key.TEXT_DARKER)));
|
||||
maxOffset = font.getWidth(t);
|
||||
}
|
||||
} catch (NoSuchFieldException | IllegalAccessException | ClassCastException | NullPointerException ignored) {
|
||||
|
||||
}
|
||||
|
||||
textField.setResponder(s -> {
|
||||
try {
|
||||
T number = getParser().apply(s);
|
||||
if (!spec.test(number))
|
||||
throw new IllegalArgumentException();
|
||||
|
||||
textField.setTextColor(Theme.i(Theme.Key.TEXT));
|
||||
setValue(number);
|
||||
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
textField.setTextColor(Theme.i(Theme.Key.BUTTON_FAIL));
|
||||
}
|
||||
});
|
||||
|
||||
listeners.add(textField);
|
||||
onReset();
|
||||
}
|
||||
|
||||
protected String formatBound(T bound) {
|
||||
String sci = String.format("%.2E", bound.doubleValue());
|
||||
String str = String.valueOf(bound);
|
||||
return sci.length() < str.length() ? sci : str;
|
||||
}
|
||||
|
||||
protected abstract T getTypeMin();
|
||||
|
||||
protected abstract T getTypeMax();
|
||||
|
||||
protected abstract Function<String, T> getParser();
|
||||
|
||||
@Override
|
||||
protected void setEditable(boolean b) {
|
||||
super.setEditable(b);
|
||||
textField.setEnabled(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onValueChange(T newValue) {
|
||||
super.onValueChange(newValue);
|
||||
String newText = String.valueOf(newValue);
|
||||
if (textField.getText().equals(newText))
|
||||
return;
|
||||
|
||||
textField.setText(newText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
textField.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms, int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean p_230432_9_, float partialTicks) {
|
||||
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
|
||||
|
||||
textField.x = x + width - 82 - resetWidth;
|
||||
textField.y = y + 8;
|
||||
textField.setWidth(Math.min(width - getLabelWidth(width) - resetWidth - minOffset - maxOffset, 40));
|
||||
textField.setHeight(20);
|
||||
textField.render(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
if (minText != null)
|
||||
minText
|
||||
.at(textField.x - minOffset, textField.y, 0)
|
||||
.withBounds(minOffset, textField.unusedGetHeight())
|
||||
.render(ms);
|
||||
|
||||
if (maxText != null)
|
||||
maxText
|
||||
.at(textField.x + textField.getWidth(), textField.y, 0)
|
||||
.withBounds(maxOffset, textField.unusedGetHeight())
|
||||
.render(ms);
|
||||
}
|
||||
|
||||
public static class IntegerEntry extends NumberEntry<Integer> {
|
||||
|
||||
public IntegerEntry(String label, ForgeConfigSpec.ConfigValue<Integer> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer getTypeMin() {
|
||||
return Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer getTypeMax() {
|
||||
return Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<String, Integer> getParser() {
|
||||
return Integer::parseInt;
|
||||
}
|
||||
}
|
||||
|
||||
public static class FloatEntry extends NumberEntry<Float> {
|
||||
|
||||
public FloatEntry(String label, ForgeConfigSpec.ConfigValue<Float> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Float getTypeMin() {
|
||||
return -Float.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Float getTypeMax() {
|
||||
return Float.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<String, Float> getParser() {
|
||||
return Float::parseFloat;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DoubleEntry extends NumberEntry<Double> {
|
||||
|
||||
public DoubleEntry(String label, ForgeConfigSpec.ConfigValue<Double> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label, value, spec);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double getTypeMin() {
|
||||
return (double) -Float.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Double getTypeMax() {
|
||||
return (double) Float.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<String, Double> getParser() {
|
||||
return Double::parseDouble;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.simibubi.create.foundation.config.ui.entries;
|
||||
|
||||
import com.electronwill.nightconfig.core.UnmodifiableConfig;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.config.ui.ConfigScreenList;
|
||||
import com.simibubi.create.foundation.config.ui.SubMenuConfigScreen;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.gui.DelegatedStencilElement;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
public class SubMenuEntry extends ConfigScreenList.LabeledEntry {
|
||||
|
||||
protected BoxWidget button;
|
||||
|
||||
public SubMenuEntry(SubMenuConfigScreen parent, String label, ForgeConfigSpec spec, UnmodifiableConfig config) {
|
||||
super(label);
|
||||
|
||||
button = new BoxWidget(0, 0, 35, 16)
|
||||
.showingElement(AllIcons.I_CONFIG_OPEN.asStencil().at(10, 0))
|
||||
.withCallback(() -> ScreenOpener.open(new SubMenuConfigScreen(parent, label, parent.type, spec, config)));
|
||||
button.modifyElement(e -> ((DelegatedStencilElement) e).withElementRenderer(BoxWidget.gradientFactory.apply(button)));
|
||||
|
||||
listeners.add(button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
button.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms, int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean p_230432_9_, float partialTicks) {
|
||||
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
|
||||
|
||||
button.x = x + width - 108;
|
||||
button.y = y + 10;
|
||||
button.setHeight(height - 20);
|
||||
button.render(ms, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLabelWidth(int totalWidth) {
|
||||
return (int) (totalWidth * labelWidthMult) + 30;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
package com.simibubi.create.foundation.config.ui.entries;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.config.ui.ConfigScreen;
|
||||
import com.simibubi.create.foundation.config.ui.ConfigScreenList;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.gui.DelegatedStencilElement;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
|
||||
import net.minecraft.util.text.IFormattableTextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
|
||||
public class ValueEntry<T> extends ConfigScreenList.LabeledEntry {
|
||||
|
||||
protected static final IFormattableTextComponent modComponent = new StringTextComponent("* ").formatted(TextFormatting.BOLD, TextFormatting.DARK_BLUE).append(StringTextComponent.EMPTY.copy().formatted(TextFormatting.RESET));
|
||||
protected static final int resetWidth = 28;//including 6px offset on either side
|
||||
public static final Pattern unitPattern = Pattern.compile("\\[(in .*)]");
|
||||
|
||||
protected ForgeConfigSpec.ConfigValue<T> value;
|
||||
protected ForgeConfigSpec.ValueSpec spec;
|
||||
protected BoxWidget resetButton;
|
||||
protected boolean editable = true;
|
||||
protected String path;
|
||||
|
||||
public ValueEntry(String label, ForgeConfigSpec.ConfigValue<T> value, ForgeConfigSpec.ValueSpec spec) {
|
||||
super(label);
|
||||
this.value = value;
|
||||
this.spec = spec;
|
||||
this.path = String.join(".", value.getPath());
|
||||
|
||||
resetButton = new BoxWidget(0, 0, resetWidth - 12, 16)
|
||||
.showingElement(AllIcons.I_CONFIG_RESET.asStencil())
|
||||
.withCallback(() -> {
|
||||
setValue((T) spec.getDefault());
|
||||
this.onReset();
|
||||
});
|
||||
resetButton.modifyElement(e -> ((DelegatedStencilElement) e).withElementRenderer(BoxWidget.gradientFactory.apply(resetButton)));
|
||||
|
||||
listeners.add(resetButton);
|
||||
|
||||
List<String> path = value.getPath();
|
||||
labelTooltip.add(new StringTextComponent(path.get(path.size()-1)).formatted(TextFormatting.GRAY));
|
||||
String comment = spec.getComment();
|
||||
if (comment == null || comment.isEmpty())
|
||||
return;
|
||||
String[] commentLines = comment.split("\n");
|
||||
//find unit in the comment
|
||||
for (int i = 0; i < commentLines.length; i++) {
|
||||
if (commentLines[i].isEmpty()) {
|
||||
commentLines = ArrayUtils.remove(commentLines, i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
Matcher matcher = unitPattern.matcher(commentLines[i]);
|
||||
if (!matcher.matches())
|
||||
continue;
|
||||
|
||||
String u = matcher.group(1);
|
||||
if (u.equals("in Revolutions per Minute"))
|
||||
u = "in RPM";
|
||||
if (u.equals("in Stress Units"))
|
||||
u = "in SU";
|
||||
unit = u;
|
||||
}
|
||||
//add comment to tooltip
|
||||
labelTooltip.addAll(Arrays.stream(commentLines).map(StringTextComponent::new).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setEditable(boolean b) {
|
||||
editable = b;
|
||||
resetButton.active = editable && !isCurrentValueDefault();
|
||||
resetButton.animateGradientFromState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
resetButton.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms, int index, int y, int x, int width, int height, int mouseX, int mouseY, boolean p_230432_9_, float partialTicks) {
|
||||
if (isCurrentValueChanged()) {
|
||||
IFormattableTextComponent original = label.getComponent();
|
||||
IFormattableTextComponent changed = modComponent.copy().append(original);
|
||||
label.withText(changed);
|
||||
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
|
||||
label.withText(original);
|
||||
} else {
|
||||
super.render(ms, index, y, x, width, height, mouseX, mouseY, p_230432_9_, partialTicks);
|
||||
}
|
||||
|
||||
resetButton.x = x + width - resetWidth + 6;
|
||||
resetButton.y = y + 10;
|
||||
resetButton.render(ms, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLabelWidth(int totalWidth) {
|
||||
return (int) (totalWidth * labelWidthMult) + 30;
|
||||
}
|
||||
|
||||
public void setValue(@Nonnull T value) {
|
||||
if (value.equals(this.value.get())) {
|
||||
ConfigScreen.changes.remove(path);
|
||||
onValueChange(value);
|
||||
return;
|
||||
}
|
||||
|
||||
ConfigScreen.changes.put(path, value);
|
||||
onValueChange(value);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public T getValue() {
|
||||
//noinspection unchecked
|
||||
return (T) ConfigScreen.changes.getOrDefault(path, this.value.get());
|
||||
}
|
||||
|
||||
protected boolean isCurrentValueChanged() {
|
||||
return ConfigScreen.changes.containsKey(path);
|
||||
}
|
||||
|
||||
protected boolean isCurrentValueDefault() {
|
||||
return spec.getDefault().equals(getValue());
|
||||
}
|
||||
|
||||
public void onReset() {
|
||||
onValueChange(getValue());
|
||||
}
|
||||
|
||||
public void onValueChange() {
|
||||
onValueChange(getValue());
|
||||
}
|
||||
public void onValueChange(T newValue) {
|
||||
resetButton.active = editable && !isCurrentValueDefault();
|
||||
resetButton.animateGradientFromState();
|
||||
}
|
||||
|
||||
protected void bumpCog() {bumpCog(10f);}
|
||||
protected void bumpCog(float force) {
|
||||
if (list != null && list instanceof ConfigScreenList)
|
||||
((ConfigScreenList) list).bumpCog(force);
|
||||
}
|
||||
}
|
|
@ -69,8 +69,6 @@ public abstract class AbstractSimiContainerScreen<T extends Container> extends C
|
|||
RenderSystem.disableLighting();
|
||||
RenderSystem.disableDepthTest();
|
||||
renderWindowForeground(matrixStack, mouseX, mouseY, partialTicks);
|
||||
for (Widget widget : widgets)
|
||||
widget.renderToolTip(matrixStack, mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -152,9 +150,12 @@ public abstract class AbstractSimiContainerScreen<T extends Container> extends C
|
|||
if (!widget.isHovered())
|
||||
continue;
|
||||
|
||||
if (widget instanceof AbstractSimiWidget && !((AbstractSimiWidget) widget).getToolTip()
|
||||
.isEmpty()) {
|
||||
renderTooltip(matrixStack, ((AbstractSimiWidget) widget).getToolTip(), mouseX, mouseY);
|
||||
if (widget instanceof AbstractSimiWidget) {
|
||||
if (!((AbstractSimiWidget) widget).getToolTip().isEmpty())
|
||||
renderTooltip(matrixStack, ((AbstractSimiWidget) widget).getToolTip(), mouseX, mouseY);
|
||||
|
||||
} else {
|
||||
widget.renderToolTip(matrixStack, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,13 @@ public abstract class AbstractSimiScreen extends Screen {
|
|||
guiTop = (this.height - sHeight) / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
widgets.stream().filter(w -> w instanceof AbstractSimiWidget).forEach(w -> ((AbstractSimiWidget) w).tick());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
partialTicks = partialTicks == 10 ? 0
|
||||
|
@ -46,8 +53,6 @@ public abstract class AbstractSimiScreen extends Screen {
|
|||
for (Widget widget : widgets)
|
||||
widget.render(ms, mouseX, mouseY, partialTicks);
|
||||
renderWindowForeground(ms, mouseX, mouseY, partialTicks);
|
||||
for (Widget widget : widgets)
|
||||
widget.renderToolTip(ms, mouseX, mouseY);
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -62,6 +67,10 @@ public abstract class AbstractSimiScreen extends Screen {
|
|||
for (Widget widget : widgets)
|
||||
if (widget.mouseClicked(x, y, button))
|
||||
result = true;
|
||||
|
||||
if (!result) {
|
||||
result = super.mouseClicked(x, y, button);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -127,9 +136,12 @@ public abstract class AbstractSimiScreen extends Screen {
|
|||
if (!widget.isHovered())
|
||||
continue;
|
||||
|
||||
if (widget instanceof AbstractSimiWidget && !((AbstractSimiWidget) widget).getToolTip()
|
||||
.isEmpty()) {
|
||||
renderTooltip(ms, ((AbstractSimiWidget) widget).getToolTip(), mouseX, mouseY);
|
||||
if (widget instanceof AbstractSimiWidget) {
|
||||
if (!((AbstractSimiWidget) widget).getToolTip().isEmpty())
|
||||
renderTooltip(ms, ((AbstractSimiWidget) widget).getToolTip(), mouseX, mouseY);
|
||||
|
||||
} else {
|
||||
widget.renderToolTip(ms, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.Create;
|
||||
|
||||
|
@ -80,8 +82,8 @@ public enum AllGuiTextures implements IScreenRenderable {
|
|||
INDICATOR_YELLOW("widgets.png", 54, 18, 18, 6),
|
||||
INDICATOR_RED("widgets.png", 72, 18, 18, 6),
|
||||
|
||||
SPEECH_TOOLTIP("widgets.png", 0, 24, 8, 8),
|
||||
SPEECH_TOOLTIP_HIGHLIGHT("widgets.png", 8, 24, 8, 8),
|
||||
SPEECH_TOOLTIP_BACKGROUND("widgets.png", 0, 24, 8, 8),
|
||||
SPEECH_TOOLTIP_COLOR("widgets.png", 8, 24, 8, 8),
|
||||
|
||||
// PlacementIndicator
|
||||
PLACEMENT_INDICATOR_SHEET("placement_indicator.png", 0, 0, 16, 256);
|
||||
|
@ -123,4 +125,9 @@ public enum AllGuiTextures implements IScreenRenderable {
|
|||
bind();
|
||||
screen.drawTexture(ms, x, y, startX, startY, width, height);
|
||||
}
|
||||
|
||||
public void draw(MatrixStack ms, int x, int y, Color c) {
|
||||
bind();
|
||||
UIRenderHelper.drawColoredTexture(ms, c, x, y, startX, startY, width, height);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,45 +22,121 @@ public class AllIcons implements IScreenRenderable {
|
|||
private int iconX;
|
||||
private int iconY;
|
||||
|
||||
public static final AllIcons I_ADD = newRow(), I_TRASH = next(), I_3x3 = next(), I_TARGET = next(),
|
||||
I_PRIORITY_VERY_LOW = next(), I_PRIORITY_LOW = next(), I_PRIORITY_HIGH = next(), I_PRIORITY_VERY_HIGH = next(),
|
||||
I_BLACKLIST = next(), I_WHITELIST = next(), I_WHITELIST_OR = next(), I_WHITELIST_AND = next(),
|
||||
I_WHITELIST_NOT = next(), I_RESPECT_NBT = next(), I_IGNORE_NBT = next();
|
||||
public static final AllIcons
|
||||
I_ADD = newRow(),
|
||||
I_TRASH = next(),
|
||||
I_3x3 = next(),
|
||||
I_TARGET = next(),
|
||||
I_PRIORITY_VERY_LOW = next(),
|
||||
I_PRIORITY_LOW = next(),
|
||||
I_PRIORITY_HIGH = next(),
|
||||
I_PRIORITY_VERY_HIGH = next(),
|
||||
I_BLACKLIST = next(),
|
||||
I_WHITELIST = next(),
|
||||
I_WHITELIST_OR = next(),
|
||||
I_WHITELIST_AND = next(),
|
||||
I_WHITELIST_NOT = next(),
|
||||
I_RESPECT_NBT = next(),
|
||||
I_IGNORE_NBT = next();
|
||||
|
||||
public static final AllIcons I_CONFIRM = newRow(), I_NONE = next(), I_OPEN_FOLDER = next(), I_REFRESH = next(),
|
||||
I_ACTIVE = next(), I_PASSIVE = next(), I_ROTATE_PLACE = next(), I_ROTATE_PLACE_RETURNED = next(),
|
||||
I_ROTATE_NEVER_PLACE = next(), I_MOVE_PLACE = next(), I_MOVE_PLACE_RETURNED = next(),
|
||||
I_MOVE_NEVER_PLACE = next(), I_CART_ROTATE = next(), I_CART_ROTATE_PAUSED = next(),
|
||||
public static final AllIcons
|
||||
I_CONFIRM = newRow(),
|
||||
I_NONE = next(),
|
||||
I_OPEN_FOLDER = next(),
|
||||
I_REFRESH = next(),
|
||||
I_ACTIVE = next(),
|
||||
I_PASSIVE = next(),
|
||||
I_ROTATE_PLACE = next(),
|
||||
I_ROTATE_PLACE_RETURNED = next(),
|
||||
I_ROTATE_NEVER_PLACE = next(),
|
||||
I_MOVE_PLACE = next(),
|
||||
I_MOVE_PLACE_RETURNED = next(),
|
||||
I_MOVE_NEVER_PLACE = next(),
|
||||
I_CART_ROTATE = next(),
|
||||
I_CART_ROTATE_PAUSED = next(),
|
||||
I_CART_ROTATE_LOCKED = next();
|
||||
|
||||
public static final AllIcons I_DONT_REPLACE = newRow(), I_REPLACE_SOLID = next(), I_REPLACE_ANY = next(),
|
||||
I_REPLACE_EMPTY = next(), I_CENTERED = next(), I_ATTACHED = next(), I_INSERTED = next(), I_FILL = next(),
|
||||
I_PLACE = next(), I_REPLACE = next(), I_CLEAR = next(), I_OVERLAY = next(), I_FLATTEN = next(), I_LMB = next(),
|
||||
I_SCROLL = next(), I_RMB = next();
|
||||
public static final AllIcons
|
||||
I_DONT_REPLACE = newRow(),
|
||||
I_REPLACE_SOLID = next(),
|
||||
I_REPLACE_ANY = next(),
|
||||
I_REPLACE_EMPTY = next(),
|
||||
I_CENTERED = next(),
|
||||
I_ATTACHED = next(),
|
||||
I_INSERTED = next(),
|
||||
I_FILL = next(),
|
||||
I_PLACE = next(),
|
||||
I_REPLACE = next(),
|
||||
I_CLEAR = next(),
|
||||
I_OVERLAY = next(),
|
||||
I_FLATTEN = next(),
|
||||
I_LMB = next(),
|
||||
I_SCROLL = next(),
|
||||
I_RMB = next();
|
||||
|
||||
public static final AllIcons I_TOOL_DEPLOY = newRow(), I_SKIP_MISSING = next(), I_SKIP_TILES = next(),
|
||||
I_DICE = next(), I_TUNNEL_SPLIT = next(), I_TUNNEL_FORCED_SPLIT = next(), I_TUNNEL_ROUND_ROBIN = next(),
|
||||
I_TUNNEL_FORCED_ROUND_ROBIN = next(), I_TUNNEL_PREFER_NEAREST = next(), I_TUNNEL_RANDOMIZE = next(),
|
||||
public static final AllIcons
|
||||
I_TOOL_DEPLOY = newRow(),
|
||||
I_SKIP_MISSING = next(),
|
||||
I_SKIP_TILES = next(),
|
||||
I_DICE = next(),
|
||||
I_TUNNEL_SPLIT = next(),
|
||||
I_TUNNEL_FORCED_SPLIT = next(),
|
||||
I_TUNNEL_ROUND_ROBIN = next(),
|
||||
I_TUNNEL_FORCED_ROUND_ROBIN = next(),
|
||||
I_TUNNEL_PREFER_NEAREST = next(),
|
||||
I_TUNNEL_RANDOMIZE = next(),
|
||||
I_TUNNEL_SYNCHRONIZE = next(),
|
||||
|
||||
I_TOOL_MOVE_XZ = newRow(), I_TOOL_MOVE_Y = next(), I_TOOL_ROTATE = next(), I_TOOL_MIRROR = next(),
|
||||
I_ARM_ROUND_ROBIN = next(), I_ARM_FORCED_ROUND_ROBIN = next(), I_ARM_PREFER_FIRST = next(),
|
||||
I_TOOL_MOVE_XZ = newRow(),
|
||||
I_TOOL_MOVE_Y = next(),
|
||||
I_TOOL_ROTATE = next(),
|
||||
I_TOOL_MIRROR = next(),
|
||||
I_ARM_ROUND_ROBIN = next(),
|
||||
I_ARM_FORCED_ROUND_ROBIN = next(),
|
||||
I_ARM_PREFER_FIRST = next(),
|
||||
|
||||
I_ADD_INVERTED_ATTRIBUTE = next(), I_FLIP = next(),
|
||||
I_ADD_INVERTED_ATTRIBUTE = next(),
|
||||
I_FLIP = next(),
|
||||
|
||||
I_PLAY = newRow(), I_PAUSE = next(), I_STOP = next(), I_PLACEMENT_SETTINGS = next(), I_ROTATE_CCW = next(),
|
||||
I_HOUR_HAND_FIRST = next(), I_MINUTE_HAND_FIRST = next(), I_HOUR_HAND_FIRST_24 = next(),
|
||||
I_PLAY = newRow(),
|
||||
I_PAUSE = next(),
|
||||
I_STOP = next(),
|
||||
I_PLACEMENT_SETTINGS = next(),
|
||||
I_ROTATE_CCW = next(),
|
||||
I_HOUR_HAND_FIRST = next(),
|
||||
I_MINUTE_HAND_FIRST = next(),
|
||||
I_HOUR_HAND_FIRST_24 = next(),
|
||||
|
||||
I_PATTERN_SOLID = newRow(), I_PATTERN_CHECKERED = next(), I_PATTERN_CHECKERED_INVERSED = next(),
|
||||
I_PATTERN_SOLID = newRow(),
|
||||
I_PATTERN_CHECKERED = next(),
|
||||
I_PATTERN_CHECKERED_INVERSED = next(),
|
||||
I_PATTERN_CHANCE_25 = next(),
|
||||
|
||||
I_PATTERN_CHANCE_50 = newRow(), I_PATTERN_CHANCE_75 = next(), I_FOLLOW_DIAGONAL = next(),
|
||||
I_PATTERN_CHANCE_50 = newRow(),
|
||||
I_PATTERN_CHANCE_75 = next(),
|
||||
I_FOLLOW_DIAGONAL = next(),
|
||||
I_FOLLOW_MATERIAL = next(),
|
||||
|
||||
I_SCHEMATIC = newRow(),
|
||||
|
||||
I_MTD_LEFT = newRow(), I_MTD_CLOSE = next(), I_MTD_RIGHT = next(), I_MTD_SCAN = next(), I_MTD_REPLAY = next(),
|
||||
I_MTD_USER_MODE = next(), I_MTD_SLOW_MODE = next();
|
||||
I_MTD_LEFT = newRow(),
|
||||
I_MTD_CLOSE = next(),
|
||||
I_MTD_RIGHT = next(),
|
||||
I_MTD_SCAN = next(),
|
||||
I_MTD_REPLAY = next(),
|
||||
I_MTD_USER_MODE = next(),
|
||||
I_MTD_SLOW_MODE = next(),
|
||||
|
||||
I_CONFIG_UNLOCKED = newRow(),
|
||||
I_CONFIG_LOCKED = next(),
|
||||
I_CONFIG_DISCARD = next(),
|
||||
I_CONFIG_SAVE = next(),
|
||||
I_CONFIG_RESET = next(),
|
||||
I_CONFIG_BACK = next(),
|
||||
I_CONFIG_PREV = next(),
|
||||
I_CONFIG_NEXT = next(),
|
||||
I_DISABLE = next(),
|
||||
I_CONFIG_OPEN = next();
|
||||
|
||||
public AllIcons(int x, int y) {
|
||||
iconX = x * 16;
|
||||
|
@ -116,8 +192,12 @@ public class AllIcons implements IScreenRenderable {
|
|||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private void vertex(Entry peek, IVertexBuilder builder, int j, int k, Vector3d rgb, Vector3d vec, float u,
|
||||
float v) {
|
||||
public DelegatedStencilElement asStencil() {
|
||||
return new DelegatedStencilElement().withStencilRenderer((ms, w, h, alpha) -> this.draw(ms, 0, 0)).withBounds(16, 16);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private void vertex(Entry peek, IVertexBuilder builder, int j, int k, Vector3d rgb, Vector3d vec, float u, float v) {
|
||||
builder.vertex(peek.getModel(), (float) vec.x, (float) vec.y, (float) vec.z)
|
||||
.color((float) rgb.x, (float) rgb.y, (float) rgb.z, 1)
|
||||
.texture(u, v)
|
||||
|
|
160
src/main/java/com/simibubi/create/foundation/gui/BoxElement.java
Normal file
160
src/main/java/com/simibubi/create/foundation/gui/BoxElement.java
Normal file
|
@ -0,0 +1,160 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
|
||||
public class BoxElement extends RenderElement {
|
||||
|
||||
protected Color background = new Color(0xff000000, true);
|
||||
protected Color borderTop = new Color(0x40ffeedd, true);
|
||||
protected Color borderBot = new Color(0x20ffeedd, true);
|
||||
protected int borderOffset = 2;
|
||||
|
||||
public <T extends BoxElement> T withBackground(Color color) {
|
||||
this.background = color;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T withBackground(int color) {
|
||||
return withBackground(new Color(color, true));
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T flatBorder(Color color) {
|
||||
this.borderTop = color;
|
||||
this.borderBot = color;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T flatBorder(int color) {
|
||||
return flatBorder(new Color(color, true));
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T gradientBorder(Couple<Color> colors) {
|
||||
this.borderTop = colors.getFirst();
|
||||
this.borderBot = colors.getSecond();
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T gradientBorder(Color top, Color bot) {
|
||||
this.borderTop = top;
|
||||
this.borderBot = bot;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T gradientBorder(int top, int bot) {
|
||||
return gradientBorder(new Color(top, true), new Color(bot, true));
|
||||
}
|
||||
|
||||
public <T extends BoxElement> T withBorderOffset(int offset) {
|
||||
this.borderOffset = offset;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms) {
|
||||
renderBox(ms);
|
||||
}
|
||||
|
||||
//total box width = 1 * 2 (outer border) + 1 * 2 (inner color border) + 2 * borderOffset + width
|
||||
//defaults to 2 + 2 + 4 + 16 = 24px
|
||||
//batch everything together to save a bunch of gl calls over GuiUtils
|
||||
protected void renderBox(MatrixStack ms) {
|
||||
/*
|
||||
* _____________
|
||||
* _|_____________|_
|
||||
* | | ___________ | |
|
||||
* | | | | | | |
|
||||
* | | | | | | |
|
||||
* | | |--* | | | |
|
||||
* | | | h | | |
|
||||
* | | | --w-+ | | |
|
||||
* | | | | | |
|
||||
* | | |_________| | |
|
||||
* |_|_____________|_|
|
||||
* |_____________|
|
||||
*
|
||||
* */
|
||||
RenderSystem.disableTexture();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.shadeModel(GL11.GL_SMOOTH);
|
||||
|
||||
int f = borderOffset;
|
||||
Color c1 = ColorHelper.applyAlpha(background, alpha);
|
||||
Color c2 = ColorHelper.applyAlpha(borderTop, alpha);
|
||||
Color c3 = ColorHelper.applyAlpha(borderBot, alpha);
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
BufferBuilder b = tessellator.getBuffer();
|
||||
Matrix4f model = ms.peek().getModel();
|
||||
b.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
|
||||
//outer top
|
||||
b.vertex(model, x - f - 1 , y - f - 2 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f - 2 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
//outer left
|
||||
b.vertex(model, x - f - 2 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 2 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
//outer bottom
|
||||
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y + f + 2 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + 2 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
//outer right
|
||||
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 2 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 2 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
//inner background - also render behind the inner edges
|
||||
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c1.getRed(), c1.getGreen(), c1.getBlue(), c1.getAlpha()).endVertex();
|
||||
tessellator.draw();
|
||||
b.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
|
||||
//inner top - includes corners
|
||||
b.vertex(model, x - f - 1 , y - f - 1 , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f - 1 , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
//inner left - excludes corners
|
||||
b.vertex(model, x - f - 1 , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f , y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
//inner bottom - includes corners
|
||||
b.vertex(model, x - f - 1 , y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x - f - 1 , y + f + 1 + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + 1 + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
//inner right - excludes corners
|
||||
b.vertex(model, x + f + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y + f + height, z).color(c3.getRed(), c3.getGreen(), c3.getBlue(), c3.getAlpha()).endVertex();
|
||||
b.vertex(model, x + f + 1 + width, y - f , z).color(c2.getRed(), c2.getGreen(), c2.getBlue(), c2.getAlpha()).endVertex();
|
||||
|
||||
tessellator.draw();
|
||||
|
||||
RenderSystem.shadeModel(GL11.GL_FLAT);
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.enableTexture();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
public class CombinedStencilElement extends StencilElement {
|
||||
|
||||
private StencilElement element1;
|
||||
private StencilElement element2;
|
||||
private ElementMode mode;
|
||||
|
||||
private CombinedStencilElement() {}
|
||||
|
||||
public static CombinedStencilElement of(@Nonnull StencilElement element1, @Nonnull StencilElement element2) {
|
||||
return of(element1, element2, ElementMode.FIRST);
|
||||
}
|
||||
|
||||
public static CombinedStencilElement of(@Nonnull StencilElement element1, @Nonnull StencilElement element2, ElementMode mode) {
|
||||
CombinedStencilElement e = new CombinedStencilElement();
|
||||
e.element1 = element1;
|
||||
e.element2 = element2;
|
||||
e.mode = mode;
|
||||
return e;
|
||||
}
|
||||
|
||||
public <T extends CombinedStencilElement> T withFirst(StencilElement element) {
|
||||
this.element1 = element;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends CombinedStencilElement> T withSecond(StencilElement element) {
|
||||
this.element2 = element;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends CombinedStencilElement> T withMode(ElementMode mode) {
|
||||
this.mode = mode;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderStencil(MatrixStack ms) {
|
||||
ms.push();
|
||||
element1.transform(ms);
|
||||
element1.withBounds(width, height);
|
||||
element1.renderStencil(ms);
|
||||
ms.pop();
|
||||
ms.push();
|
||||
element2.transform(ms);
|
||||
element2.withBounds(width, height);
|
||||
element2.renderStencil(ms);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderElement(MatrixStack ms) {
|
||||
if (mode.rendersFirst())
|
||||
element1.<StencilElement>withBounds(width, height).renderElement(ms);
|
||||
|
||||
if (mode.rendersSecond())
|
||||
element2.<StencilElement>withBounds(width, height).renderElement(ms);
|
||||
}
|
||||
|
||||
public enum ElementMode {
|
||||
FIRST, SECOND, BOTH;
|
||||
|
||||
boolean rendersFirst() {
|
||||
return this == FIRST || this == BOTH;
|
||||
}
|
||||
|
||||
boolean rendersSecond() {
|
||||
return this == SECOND || this == BOTH;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.lwjgl.opengl.GL30;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.shader.Framebuffer;
|
||||
import net.minecraft.util.text.ITextProperties;
|
||||
import net.minecraft.util.text.Style;
|
||||
|
||||
public class ConfirmationScreen extends AbstractSimiScreen {
|
||||
|
||||
private Screen source;
|
||||
private Consumer<Boolean> action = _success -> {};
|
||||
private List<ITextProperties> text = new ArrayList<>();
|
||||
private boolean centered = false;
|
||||
private int x;
|
||||
private int y;
|
||||
private int textWidth;
|
||||
private int textHeight;
|
||||
|
||||
private BoxWidget confirm;
|
||||
private BoxWidget cancel;
|
||||
private BoxElement textBackground;
|
||||
|
||||
/*
|
||||
* Removes text lines from the back of the list
|
||||
* */
|
||||
public ConfirmationScreen removeTextLines(int amount) {
|
||||
if (amount > text.size())
|
||||
return clearText();
|
||||
|
||||
text.subList(text.size() - amount, text.size()).clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfirmationScreen clearText() {
|
||||
this.text.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfirmationScreen addText(ITextProperties text) {
|
||||
this.text.add(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfirmationScreen withText(ITextProperties text) {
|
||||
return clearText().addText(text);
|
||||
}
|
||||
|
||||
public ConfirmationScreen at(int x, int y) {
|
||||
this.x = Math.max(x, 0);
|
||||
this.y = Math.max(y, 0);
|
||||
this.centered = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfirmationScreen centered() {
|
||||
this.centered = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfirmationScreen withAction(Consumer<Boolean> action) {
|
||||
this.action = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void open(@Nonnull Screen source) {
|
||||
this.source = source;
|
||||
Minecraft client = source.getMinecraft();
|
||||
this.init(client, client.getWindow().getScaledWidth(), client.getWindow().getScaledHeight());
|
||||
this.client.currentScreen = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
confirm.tick();
|
||||
cancel.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
widgets.clear();
|
||||
|
||||
ArrayList<ITextProperties> copy = new ArrayList<>(text);
|
||||
text.clear();
|
||||
copy.forEach(t -> text.addAll(client.fontRenderer.getTextHandler().wrapLines(t, 300, Style.EMPTY)));
|
||||
|
||||
textHeight = text.size() * (client.fontRenderer.FONT_HEIGHT + 1) + 4;
|
||||
textWidth = 300;
|
||||
|
||||
if (x + textWidth > width) {
|
||||
x = width - textWidth;
|
||||
}
|
||||
|
||||
if (y + textHeight + 30 > height) {
|
||||
y = height - textHeight - 30;
|
||||
}
|
||||
|
||||
if (centered) {
|
||||
x = width/2 - textWidth/2 - 2;
|
||||
y = height/2 - textHeight/2 - 16;
|
||||
}
|
||||
|
||||
TextStencilElement confirmText = new TextStencilElement(client.fontRenderer, "Confirm").centered(true, true);
|
||||
confirm = new BoxWidget(x + 4, y + textHeight + 2 , textWidth/2 - 10, 20)
|
||||
.withCallback(() -> accept(true));
|
||||
confirm.showingElement(confirmText.withElementRenderer(BoxWidget.gradientFactory.apply(confirm)));
|
||||
|
||||
TextStencilElement cancelText = new TextStencilElement(client.fontRenderer, "Cancel").centered(true, true);
|
||||
cancel = new BoxWidget(x + textWidth/2 + 6, y + textHeight + 2, textWidth/2 - 10, 20)
|
||||
.withCallback(() -> accept(false));
|
||||
cancel.showingElement(cancelText.withElementRenderer(BoxWidget.gradientFactory.apply(cancel)));
|
||||
|
||||
widgets.add(confirm);
|
||||
widgets.add(cancel);
|
||||
|
||||
textBackground = new BoxElement()
|
||||
.gradientBorder(Theme.p(Theme.Key.BUTTON_DISABLE))
|
||||
.withBounds(textWidth, textHeight)
|
||||
.at(x, y);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose() {
|
||||
accept(false);
|
||||
}
|
||||
|
||||
private void accept(boolean success) {
|
||||
client.currentScreen = source;
|
||||
action.accept(success);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindow(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
|
||||
textBackground.render(ms);
|
||||
int offset = client.fontRenderer.FONT_HEIGHT + 1;
|
||||
int lineY = y - offset;
|
||||
|
||||
ms.push();
|
||||
ms.translate(0, 0, 200);
|
||||
|
||||
for (ITextProperties line : text) {
|
||||
lineY = lineY + offset;
|
||||
|
||||
if (line == null)
|
||||
continue;
|
||||
|
||||
client.fontRenderer.draw(ms, line.getString(), x, lineY, 0xeaeaea);
|
||||
}
|
||||
|
||||
ms.pop();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
|
||||
UIRenderHelper.framebuffer.framebufferClear(Minecraft.IS_RUNNING_ON_MAC);
|
||||
|
||||
ms.push();
|
||||
UIRenderHelper.framebuffer.bindFramebuffer(true);
|
||||
source.render(ms, mouseX, mouseY, 10);
|
||||
UIRenderHelper.framebuffer.unbindFramebuffer();
|
||||
Framebuffer mainBuffer = Minecraft.getInstance().getFramebuffer();
|
||||
ms.pop();
|
||||
|
||||
//fixme replace with glVersioned-backend calls once they are merged from jozu's branch
|
||||
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, UIRenderHelper.framebuffer.framebufferObject);
|
||||
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, mainBuffer.framebufferObject);
|
||||
GL30.glBlitFramebuffer(0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, 0, 0, mainBuffer.framebufferWidth, mainBuffer.framebufferHeight, GL30.GL_COLOR_BUFFER_BIT, GL30.GL_LINEAR);
|
||||
mainBuffer.bindFramebuffer(true);
|
||||
|
||||
this.fillGradient(ms, 0, 0, this.width, this.height, 0x70101010, 0x80101010);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resize(@Nonnull Minecraft client, int width, int height) {
|
||||
super.resize(client, width, height);
|
||||
source.resize(client, width, height);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
|
||||
public class DelegatedStencilElement extends StencilElement {
|
||||
|
||||
protected static final ElementRenderer EMPTY_RENDERER = (ms, width, height, alpha) -> {};
|
||||
protected static final ElementRenderer DEFAULT_ELEMENT = (ms, width, height, alpha) -> UIRenderHelper.angledGradient(ms, 0, -3, 5, height+4, width+6, ColorHelper.applyAlpha(0xff_10dd10, alpha), ColorHelper.applyAlpha(0xff_1010dd, alpha));
|
||||
|
||||
protected ElementRenderer stencil;
|
||||
protected ElementRenderer element;
|
||||
|
||||
public DelegatedStencilElement() {
|
||||
stencil = EMPTY_RENDERER;
|
||||
element = DEFAULT_ELEMENT;
|
||||
}
|
||||
|
||||
public DelegatedStencilElement(ElementRenderer stencil, ElementRenderer element) {
|
||||
this.stencil = stencil;
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
public <T extends DelegatedStencilElement> T withStencilRenderer(ElementRenderer renderer) {
|
||||
stencil = renderer;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends DelegatedStencilElement> T withElementRenderer(ElementRenderer renderer) {
|
||||
element = renderer;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderStencil(MatrixStack ms) {
|
||||
stencil.render(ms, width, height, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderElement(MatrixStack ms) {
|
||||
element.render(ms, width, height, alpha);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ElementRenderer {
|
||||
void render(MatrixStack ms, int width, int height, float alpha);
|
||||
}
|
||||
|
||||
}
|
|
@ -63,31 +63,17 @@ public class GuiGameElement {
|
|||
.with(FlowingFluidBlock.LEVEL, 0));
|
||||
}
|
||||
|
||||
public static abstract class GuiRenderBuilder {
|
||||
double xBeforeScale, yBeforeScale, zBeforeScale = 0;
|
||||
double x, y, z;
|
||||
public static abstract class GuiRenderBuilder extends RenderElement {
|
||||
double xLocal, yLocal, zLocal;
|
||||
double xRot, yRot, zRot;
|
||||
double scale = 1;
|
||||
int color = 0xFFFFFF;
|
||||
Vector3d rotationOffset = Vector3d.ZERO;
|
||||
|
||||
public GuiRenderBuilder atLocal(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GuiRenderBuilder at(double x, double y) {
|
||||
this.xBeforeScale = x;
|
||||
this.yBeforeScale = y;
|
||||
return this;
|
||||
}
|
||||
|
||||
public GuiRenderBuilder at(double x, double y, double z) {
|
||||
this.xBeforeScale = x;
|
||||
this.yBeforeScale = y;
|
||||
this.zBeforeScale = z;
|
||||
this.xLocal = x;
|
||||
this.yLocal = y;
|
||||
this.zLocal = z;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -136,9 +122,9 @@ public class GuiGameElement {
|
|||
|
||||
@Deprecated
|
||||
protected void transform() {
|
||||
RenderSystem.translated(xBeforeScale, yBeforeScale, 0);
|
||||
RenderSystem.translated(x, y, 0);
|
||||
RenderSystem.scaled(scale, scale, scale);
|
||||
RenderSystem.translated(x, y, z);
|
||||
RenderSystem.translated(xLocal, yLocal, zLocal);
|
||||
RenderSystem.scaled(1, -1, 1);
|
||||
RenderSystem.translated(rotationOffset.x, rotationOffset.y, rotationOffset.z);
|
||||
RenderSystem.rotatef((float) zRot, 0, 0, 1);
|
||||
|
@ -148,9 +134,9 @@ public class GuiGameElement {
|
|||
}
|
||||
|
||||
protected void transformMatrix(MatrixStack matrixStack) {
|
||||
matrixStack.translate(xBeforeScale, yBeforeScale, zBeforeScale);
|
||||
matrixStack.scale((float) scale, (float) scale, (float) scale);
|
||||
matrixStack.translate(x, y, z);
|
||||
matrixStack.scale((float) scale, (float) scale, (float) scale);
|
||||
matrixStack.translate(xLocal, yLocal, zLocal);
|
||||
matrixStack.scale(1, -1, 1);
|
||||
matrixStack.translate(rotationOffset.x, rotationOffset.y, rotationOffset.z);
|
||||
matrixStack.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion((float) zRot));
|
||||
|
@ -272,23 +258,10 @@ public class GuiGameElement {
|
|||
@Override
|
||||
public void render(MatrixStack matrixStack) {
|
||||
prepareMatrix(matrixStack);
|
||||
// matrixStack.translate(0, 80, 0);
|
||||
transformMatrix(matrixStack);
|
||||
renderItemIntoGUI(matrixStack, stack);
|
||||
cleanUpMatrix(matrixStack);
|
||||
}
|
||||
/*
|
||||
* public void render() {
|
||||
* prepare();
|
||||
* transform();
|
||||
* RenderSystem.scaled(1, -1, 1);
|
||||
* RenderSystem.translated(0, 0, -75);
|
||||
* Minecraft.getInstance()
|
||||
* .getItemRenderer()
|
||||
* .renderItemIntoGUI(stack, 0, 0);
|
||||
* cleanUp();
|
||||
* }
|
||||
*/
|
||||
|
||||
public static void renderItemIntoGUI(MatrixStack matrixStack, ItemStack stack) {
|
||||
ItemRenderer renderer = Minecraft.getInstance()
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.client.gui.AbstractGui;
|
||||
|
||||
public abstract class RenderElement implements IScreenRenderable {
|
||||
|
||||
public static RenderElement EMPTY = new RenderElement() {@Override public void render(MatrixStack ms) {}};
|
||||
|
||||
public static RenderElement of(IScreenRenderable renderable) {
|
||||
return new SimpleRenderElement(renderable);
|
||||
}
|
||||
|
||||
protected int width = 16, height = 16;
|
||||
protected float x = 0, y = 0, z = 0;
|
||||
protected float alpha = 1f;
|
||||
|
||||
public <T extends RenderElement> T at(float x, float y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends RenderElement> T at(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends RenderElement> T withBounds(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends RenderElement> T withAlpha(float alpha) {
|
||||
this.alpha = alpha;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public float getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public float getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public float getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public abstract void render(MatrixStack ms);
|
||||
|
||||
@Override
|
||||
public void draw(MatrixStack ms, AbstractGui screen, int x, int y) {
|
||||
this.at(x, y).render(ms);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(MatrixStack ms, int x, int y) {
|
||||
this.at(x, y).render(ms);
|
||||
}
|
||||
|
||||
public static class SimpleRenderElement extends RenderElement {
|
||||
|
||||
private IScreenRenderable renderable;
|
||||
|
||||
public SimpleRenderElement(IScreenRenderable renderable) {
|
||||
this.renderable = renderable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms) {
|
||||
renderable.draw(ms, (int) x, (int) y);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,7 +65,7 @@ public class ScreenOpener {
|
|||
if (screenHistory.isEmpty())
|
||||
return false;
|
||||
Screen previouslyRenderedScreen = screenHistory.get(0);
|
||||
if (!(previouslyRenderedScreen instanceof AbstractSimiScreen))
|
||||
if (!(previouslyRenderedScreen instanceof NavigatableSimiScreen))
|
||||
return false;
|
||||
if (!screen.isEquivalentTo((NavigatableSimiScreen) previouslyRenderedScreen))
|
||||
return false;
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
public abstract class StencilElement extends RenderElement {
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack ms) {
|
||||
ms.push();
|
||||
transform(ms);
|
||||
prepareStencil(ms);
|
||||
renderStencil(ms);
|
||||
prepareElement(ms);
|
||||
renderElement(ms);
|
||||
cleanUp(ms);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
protected abstract void renderStencil(MatrixStack ms);
|
||||
|
||||
protected abstract void renderElement(MatrixStack ms);
|
||||
|
||||
protected void transform(MatrixStack ms) {
|
||||
ms.translate(x, y, z);
|
||||
}
|
||||
|
||||
protected void prepareStencil(MatrixStack ms) {
|
||||
GL11.glDisable(GL11.GL_STENCIL_TEST);
|
||||
RenderSystem.stencilMask(~0);
|
||||
RenderSystem.clear(GL11.GL_STENCIL_BUFFER_BIT, Minecraft.IS_RUNNING_ON_MAC);
|
||||
GL11.glEnable(GL11.GL_STENCIL_TEST);
|
||||
RenderSystem.stencilOp(GL11.GL_REPLACE, GL11.GL_KEEP, GL11.GL_KEEP);
|
||||
RenderSystem.stencilMask(0xFF);
|
||||
RenderSystem.stencilFunc(GL11.GL_NEVER, 1, 0xFF);
|
||||
}
|
||||
|
||||
protected void prepareElement(MatrixStack ms) {
|
||||
GL11.glEnable(GL11.GL_STENCIL_TEST);
|
||||
RenderSystem.stencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP);
|
||||
RenderSystem.stencilFunc(GL11.GL_EQUAL, 1, 0xFF);
|
||||
}
|
||||
|
||||
protected void cleanUp(MatrixStack ms) {
|
||||
GL11.glDisable(GL11.GL_STENCIL_TEST);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.util.text.IFormattableTextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
public class TextStencilElement extends DelegatedStencilElement {
|
||||
|
||||
protected FontRenderer font;
|
||||
protected IFormattableTextComponent component;
|
||||
protected boolean centerVertically = false;
|
||||
protected boolean centerHorizontally = false;
|
||||
|
||||
public TextStencilElement(FontRenderer font) {
|
||||
super();
|
||||
this.font = font;
|
||||
height = 10;
|
||||
}
|
||||
|
||||
public TextStencilElement(FontRenderer font, String text) {
|
||||
this(font);
|
||||
component = new StringTextComponent(text);
|
||||
}
|
||||
|
||||
public TextStencilElement(FontRenderer font, IFormattableTextComponent component) {
|
||||
this(font);
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
public TextStencilElement withText(String text) {
|
||||
component = new StringTextComponent(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextStencilElement withText(IFormattableTextComponent component) {
|
||||
this.component = component;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextStencilElement centered(boolean vertical, boolean horizontal) {
|
||||
this.centerVertically = vertical;
|
||||
this.centerHorizontally = horizontal;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderStencil(MatrixStack ms) {
|
||||
|
||||
float x = 0, y = 0;
|
||||
if (centerHorizontally)
|
||||
x = width / 2f - font.getWidth(component) / 2f;
|
||||
|
||||
if (centerVertically)
|
||||
y = height / 2f - font.FONT_HEIGHT / 2f;
|
||||
|
||||
font.draw(ms, component, x, y, 0xff_000000);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderElement(MatrixStack ms) {
|
||||
float x = 0, y = 0;
|
||||
if (centerHorizontally)
|
||||
x = width / 2f - font.getWidth(component) / 2f;
|
||||
|
||||
if (centerVertically)
|
||||
y = height / 2f - font.FONT_HEIGHT / 2f;
|
||||
|
||||
ms.push();
|
||||
ms.translate(x, y, 0);
|
||||
element.render(ms, font.getWidth(component), font.FONT_HEIGHT + 2, alpha);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
public IFormattableTextComponent getComponent() {
|
||||
return component;
|
||||
}
|
||||
}
|
177
src/main/java/com/simibubi/create/foundation/gui/Theme.java
Normal file
177
src/main/java/com/simibubi/create/foundation/gui/Theme.java
Normal file
|
@ -0,0 +1,177 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
|
||||
public class Theme {
|
||||
|
||||
private static final Theme base = new Theme();
|
||||
private static Theme custom = null;
|
||||
|
||||
public static void setTheme(@Nullable Theme theme) {
|
||||
custom = theme;
|
||||
}
|
||||
|
||||
private static ColorHolder resolve(String key) {
|
||||
ColorHolder h = null;
|
||||
|
||||
if (custom != null)
|
||||
h = custom.get(key);
|
||||
|
||||
if (h == null)
|
||||
h = base.get(key);
|
||||
|
||||
if (h == null)
|
||||
h = ColorHolder.missing;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
@Nonnull public static Couple<Color> p(@Nonnull Key key) {return p(key.get());}
|
||||
@Nonnull public static Couple<Color> p(String key) {return resolve(key).asPair();}
|
||||
|
||||
@Nonnull public static Color c(@Nonnull Key key, boolean first) {return c(key.get(), first);}
|
||||
@Nonnull public static Color c(String key, boolean first) {return p(key).get(first);}
|
||||
|
||||
public static int i(@Nonnull Key key, boolean first) {return i(key.get(), first);}
|
||||
public static int i(String key, boolean first) {return p(key).get(first).getRGB();}
|
||||
|
||||
@Nonnull public static Color c(@Nonnull Key key) {return c(key.get());}
|
||||
@Nonnull public static Color c(String key) {return resolve(key).get();}
|
||||
|
||||
public static int i(@Nonnull Key key) {return i(key.get());}
|
||||
public static int i(String key) {return resolve(key).get().getRGB();}
|
||||
|
||||
//-----------//
|
||||
|
||||
protected final Map<String, ColorHolder> colors;
|
||||
|
||||
protected Theme() {
|
||||
colors = new HashMap<>();
|
||||
init();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
put(Key.BUTTON_IDLE, new Color(0x60_c0c0ff, true), new Color(0x30_c0c0ff, true));
|
||||
put(Key.BUTTON_HOVER, new Color(0xa0_c0c0ff, true), new Color(0x50_c0c0ff, true));
|
||||
put(Key.BUTTON_CLICK, new Color(0xff_4b4bff), new Color(0xff_3b3bdd));
|
||||
put(Key.BUTTON_DISABLE, new Color(0x80_909090, true), new Color(0x20_909090, true));
|
||||
put(Key.BUTTON_SUCCESS, new Color(0xcc_88f788, true), new Color(0xcc_20cc20, true));
|
||||
put(Key.BUTTON_FAIL, new Color(0xcc_f78888, true), new Color(0xcc_cc2020, true));
|
||||
put(Key.TEXT, new Color(0xff_eeeeee), new Color(0xff_a3a3a3));
|
||||
put(Key.TEXT_DARKER, new Color(0xff_a3a3a3), new Color(0xff_808080));
|
||||
put(Key.TEXT_ACCENT_STRONG, new Color(0xff_7b7ba3), new Color(0xff_616192));
|
||||
put(Key.TEXT_ACCENT_SLIGHT, new Color(0xff_ddeeff), new Color(0xff_a0b0c0));
|
||||
put(Key.STREAK, new Color(0x101010, false));
|
||||
|
||||
put(Key.PONDER_BACKGROUND_TRANSPARENT, new Color(0xdd_000000, true));
|
||||
put(Key.PONDER_BACKGROUND_FLAT, new Color(0xff_000000, false));
|
||||
put(Key.PONDER_IDLE, new Color(0x40ffeedd, true), new Color(0x20ffeedd, true));
|
||||
put(Key.PONDER_HOVER, new Color(0x70ffffff, true), new Color(0x30ffffff, true));
|
||||
put(Key.PONDER_HIGHLIGHT, new Color(0xf0ffeedd, true), new Color(0x60ffeedd, true));
|
||||
put(Key.TEXT_WINDOW_BORDER, new Color(0x607a6000, true), new Color(0x207a6000, true));
|
||||
put(Key.PONDER_BACK_ARROW, new Color(0x70aa9999, true), new Color(0x30aa9999, true));
|
||||
put(Key.PONDER_PROGRESSBAR, new Color(0x80ffeedd, true), new Color(0x50ffeedd, true));
|
||||
put(Key.PONDER_MISSING_CREATE, new Color(0x70_984500, true), new Color(0x70_692400, true));
|
||||
put(Key.PONDER_MISSING_VANILLA, new Color(0x50_5000ff, true), new Color(0x50_300077, true));
|
||||
//put(Key., new Color(0x, true), new Color(0x, true));
|
||||
}
|
||||
|
||||
protected void put(String key, Color c) {
|
||||
colors.put(key, ColorHolder.single(c));
|
||||
}
|
||||
|
||||
protected void put(Key key, Color c) {
|
||||
put(key.get(), c);
|
||||
}
|
||||
|
||||
protected void put(String key, Color c1, Color c2) {
|
||||
colors.put(key, ColorHolder.pair(c1, c2));
|
||||
}
|
||||
|
||||
protected void put(Key key, Color c1, Color c2) {
|
||||
put(key.get(), c1 , c2);
|
||||
}
|
||||
|
||||
@Nullable protected ColorHolder get(String key) {
|
||||
return colors.get(key);
|
||||
}
|
||||
|
||||
public static class Key {
|
||||
|
||||
public static Key BUTTON_IDLE = new Key();
|
||||
public static Key BUTTON_HOVER = new Key();
|
||||
public static Key BUTTON_CLICK = new Key();
|
||||
public static Key BUTTON_DISABLE = new Key();
|
||||
public static Key BUTTON_SUCCESS = new Key();
|
||||
public static Key BUTTON_FAIL = new Key();
|
||||
|
||||
public static Key TEXT = new Key();
|
||||
public static Key TEXT_DARKER = new Key();
|
||||
public static Key TEXT_ACCENT_STRONG = new Key();
|
||||
public static Key TEXT_ACCENT_SLIGHT = new Key();
|
||||
|
||||
public static Key STREAK = new Key();
|
||||
|
||||
public static Key PONDER_BACKGROUND_TRANSPARENT = new Key();
|
||||
public static Key PONDER_BACKGROUND_FLAT = new Key();
|
||||
public static Key PONDER_IDLE = new Key();
|
||||
public static Key PONDER_HOVER = new Key();
|
||||
public static Key PONDER_HIGHLIGHT = new Key();
|
||||
public static Key TEXT_WINDOW_BORDER = new Key();
|
||||
public static Key PONDER_BACK_ARROW = new Key();
|
||||
public static Key PONDER_PROGRESSBAR = new Key();
|
||||
public static Key PONDER_MISSING_CREATE = new Key();
|
||||
public static Key PONDER_MISSING_VANILLA = new Key();
|
||||
|
||||
private static int index = 0;
|
||||
|
||||
private final String s;
|
||||
|
||||
protected Key() {
|
||||
this.s = "_" + index++;
|
||||
}
|
||||
|
||||
protected Key(String s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
public String get() {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ColorHolder {
|
||||
|
||||
private static final ColorHolder missing = ColorHolder.single(Color.BLACK);
|
||||
|
||||
private Couple<Color> colors;
|
||||
|
||||
private static ColorHolder single(Color c) {
|
||||
ColorHolder h = new ColorHolder();
|
||||
h.colors = Couple.create(c, c);
|
||||
return h;
|
||||
}
|
||||
|
||||
private static ColorHolder pair(Color first, Color second) {
|
||||
ColorHolder h = new ColorHolder();
|
||||
h.colors = Couple.create(first, second);
|
||||
return h;
|
||||
}
|
||||
|
||||
private Color get() {
|
||||
return colors.getFirst();
|
||||
}
|
||||
|
||||
private Couple<Color> asPair() {
|
||||
return colors;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,15 +1,21 @@
|
|||
package com.simibubi.create.foundation.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
|
||||
import net.minecraft.client.MainWindow;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.WorldVertexBufferUploader;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.shader.Framebuffer;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
|
@ -18,32 +24,26 @@ import net.minecraftforge.fml.client.gui.GuiUtils;
|
|||
|
||||
public class UIRenderHelper {
|
||||
|
||||
public static void enableStencil() {
|
||||
RenderSystem.recordRenderCall(() -> Minecraft.getInstance().getFramebuffer().enableStencil());
|
||||
}
|
||||
|
||||
public static Framebuffer framebuffer;
|
||||
|
||||
public static void init() {
|
||||
RenderSystem.recordRenderCall(() -> {
|
||||
MainWindow mainWindow = Minecraft.getInstance()
|
||||
.getWindow();
|
||||
.getWindow();
|
||||
framebuffer = new Framebuffer(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), true,
|
||||
Minecraft.IS_RUNNING_ON_MAC);
|
||||
Minecraft.IS_RUNNING_ON_MAC);
|
||||
framebuffer.setFramebufferColor(0, 0, 0, 0);
|
||||
// framebuffer.deleteFramebuffer();
|
||||
framebuffer.enableStencil();
|
||||
});
|
||||
}
|
||||
|
||||
public static void prepFramebufferSize() {
|
||||
MainWindow window = Minecraft.getInstance()
|
||||
.getWindow();
|
||||
if (framebuffer.framebufferWidth != window.getFramebufferWidth()
|
||||
|| framebuffer.framebufferHeight != window.getFramebufferHeight()) {
|
||||
framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(),
|
||||
Minecraft.IS_RUNNING_ON_MAC);
|
||||
}
|
||||
}
|
||||
|
||||
public static void drawFramebuffer(float alpha) {
|
||||
MainWindow window = Minecraft.getInstance()
|
||||
.getWindow();
|
||||
.getWindow();
|
||||
|
||||
float vx = (float) window.getScaledWidth();
|
||||
float vy = (float) window.getScaledHeight();
|
||||
|
@ -51,10 +51,6 @@ public class UIRenderHelper {
|
|||
float ty = (float) framebuffer.framebufferHeight / (float) framebuffer.framebufferTextureHeight;
|
||||
|
||||
RenderSystem.enableTexture();
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.disableLighting();
|
||||
RenderSystem.disableAlphaTest();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
framebuffer.bindFramebufferTexture();
|
||||
|
@ -63,33 +59,21 @@ public class UIRenderHelper {
|
|||
BufferBuilder bufferbuilder = tessellator.getBuffer();
|
||||
bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEXTURE);
|
||||
|
||||
bufferbuilder.vertex(0, vy, 0)
|
||||
.color(1, 1, 1, alpha)
|
||||
.texture(0, 0)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(vx, vy, 0)
|
||||
.color(1, 1, 1, alpha)
|
||||
.texture(tx, 0)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(vx, 0, 0)
|
||||
.color(1, 1, 1, alpha)
|
||||
.texture(tx, ty)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(0, 0, 0)
|
||||
.color(1, 1, 1, alpha)
|
||||
.texture(0, ty)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(0, vy, 0).color(1, 1, 1, alpha).texture(0, 0).endVertex();
|
||||
bufferbuilder.vertex(vx, vy, 0).color(1, 1, 1, alpha).texture(tx, 0).endVertex();
|
||||
bufferbuilder.vertex(vx, 0, 0).color(1, 1, 1, alpha).texture(tx, ty).endVertex();
|
||||
bufferbuilder.vertex(0, 0, 0).color(1, 1, 1, alpha).texture(0, ty).endVertex();
|
||||
|
||||
tessellator.draw();
|
||||
framebuffer.unbindFramebufferTexture();
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.enableAlphaTest();
|
||||
}
|
||||
|
||||
public static void streak(MatrixStack ms, float angle, int x, int y, int breadth, int length) {streak(ms, angle, x, y, breadth, length, Theme.i(Theme.Key.STREAK));}
|
||||
|
||||
// angle in degrees; 0° -> fading to the right
|
||||
// x and y specify the middle point of the starting edge
|
||||
// width is the total width of the streak
|
||||
public static void streak(MatrixStack ms, float angle, int x, int y, int width, int length, int color) {
|
||||
// breadth is the total width of the streak
|
||||
public static void streak(MatrixStack ms, float angle, int x, int y, int breadth, int length, int color) {
|
||||
int a1 = 0xa0 << 24;
|
||||
int a2 = 0x80 << 24;
|
||||
int a3 = 0x10 << 24;
|
||||
|
@ -105,7 +89,7 @@ public class UIRenderHelper {
|
|||
ms.translate(x, y, 0);
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(angle - 90));
|
||||
|
||||
streak(ms, width / 2, length, c1, c2, c3, c4);
|
||||
streak(ms, breadth / 2, length, c1, c2, c3, c4);
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -113,16 +97,59 @@ public class UIRenderHelper {
|
|||
private static void streak(MatrixStack ms, int width, int height, int c1, int c2, int c3, int c4) {
|
||||
double split1 = .5;
|
||||
double split2 = .75;
|
||||
Matrix4f model = ms.peek()
|
||||
.getModel();
|
||||
Matrix4f model = ms.peek().getModel();
|
||||
RenderSystem.disableAlphaTest();
|
||||
GuiUtils.drawGradientRect(model, 0, -width, 0, width, (int) (split1 * height), c1, c2);
|
||||
GuiUtils.drawGradientRect(model, 0, -width, (int) (split1 * height), width, (int) (split2 * height), c2, c3);
|
||||
GuiUtils.drawGradientRect(model, 0, -width, (int) (split2 * height), width, height, c3, c4);
|
||||
RenderSystem.enableAlphaTest();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #angledGradient(MatrixStack, float, int, int, int, int, int, int, int)
|
||||
*/
|
||||
public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int breadth, int length, Couple<Color> c) {
|
||||
angledGradient(ms, angle, x, y, 0, breadth, length, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #angledGradient(MatrixStack, float, int, int, int, int, int, int, int)
|
||||
*/
|
||||
public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int z, int breadth, int length, Couple<Color> c) {
|
||||
angledGradient(ms, angle, x, y, z, breadth, length, c.getFirst().getRGB(), c.getSecond().getRGB());
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #angledGradient(MatrixStack, float, int, int, int, int, int, int, int)
|
||||
*/
|
||||
public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int breadth, int length, int color1, int color2) {
|
||||
angledGradient(ms, angle, x, y, 0, breadth, length, color1, color2);
|
||||
}
|
||||
|
||||
/**
|
||||
* x and y specify the middle point of the starting edge
|
||||
*
|
||||
* @param angle the angle of the gradient in degrees; 0° means from left to right
|
||||
* @param color1 the color at the starting edge
|
||||
* @param color2 the color at the ending edge
|
||||
* @param breadth the total width of the gradient
|
||||
*/
|
||||
public static void angledGradient(@Nonnull MatrixStack ms, float angle, int x, int y, int z, int breadth, int length, int color1, int color2) {
|
||||
ms.push();
|
||||
ms.translate(x, y, z);
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(angle - 90));
|
||||
|
||||
Matrix4f model = ms.peek().getModel();
|
||||
int w = breadth / 2;
|
||||
GuiUtils.drawGradientRect(model, 0, -w, 0, w, length, color1, color2);
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
public static void breadcrumbArrow(MatrixStack matrixStack, int x, int y, int z, int width, int height, int indent, Couple<Color> colors) {breadcrumbArrow(matrixStack, x, y, z, width, height, indent, colors.getFirst().getRGB(), colors.getSecond().getRGB());}
|
||||
|
||||
// draws a wide chevron-style breadcrumb arrow pointing left
|
||||
public static void breadcrumbArrow(MatrixStack matrixStack, int x, int y, int z, int width, int height, int indent,
|
||||
int startColor, int endColor) {
|
||||
public static void breadcrumbArrow(MatrixStack matrixStack, int x, int y, int z, int width, int height, int indent, int startColor, int endColor) {
|
||||
matrixStack.push();
|
||||
matrixStack.translate(x - indent, y, z);
|
||||
|
||||
|
@ -134,13 +161,13 @@ public class UIRenderHelper {
|
|||
private static void breadcrumbArrow(MatrixStack ms, int width, int height, int indent, int c1, int c2) {
|
||||
|
||||
/*
|
||||
* 0,0 x1,y1 ********************* x4,y4 ***** x7,y7
|
||||
* **** ****
|
||||
* **** ****
|
||||
* x0,y0 x2,y2 x5,y5
|
||||
* **** ****
|
||||
* **** ****
|
||||
* x3,y3 ********************* x6,y6 ***** x8,y8
|
||||
* 0,0 x1,y1 ********************* x4,y4 ***** x7,y7
|
||||
* **** ****
|
||||
* **** ****
|
||||
* x0,y0 x2,y2 x5,y5
|
||||
* **** ****
|
||||
* **** ****
|
||||
* x3,y3 ********************* x6,y6 ***** x8,y8
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -170,69 +197,32 @@ public class UIRenderHelper {
|
|||
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
BufferBuilder bufferbuilder = tessellator.getBuffer();
|
||||
Matrix4f model = ms.peek()
|
||||
.getModel();
|
||||
Matrix4f model = ms.peek().getModel();
|
||||
bufferbuilder.begin(GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_COLOR);
|
||||
|
||||
bufferbuilder.vertex(model, x0, y0, 0)
|
||||
.color(fc1 >> 16 & 0xFF, fc1 >> 8 & 0xFF, fc1 & 0xFF, fc1 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x1, y1, 0)
|
||||
.color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x2, y2, 0)
|
||||
.color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x0, y0, 0).color(fc1 >> 16 & 0xFF, fc1 >> 8 & 0xFF, fc1 & 0xFF, fc1 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x1, y1, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x2, y2, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
|
||||
|
||||
bufferbuilder.vertex(model, x0, y0, 0)
|
||||
.color(fc1 >> 16 & 0xFF, fc1 >> 8 & 0xFF, fc1 & 0xFF, fc1 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x2, y2, 0)
|
||||
.color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x3, y3, 0)
|
||||
.color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x0, y0, 0).color(fc1 >> 16 & 0xFF, fc1 >> 8 & 0xFF, fc1 & 0xFF, fc1 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x2, y2, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x3, y3, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
|
||||
|
||||
bufferbuilder.vertex(model, x3, y3, 0)
|
||||
.color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x1, y1, 0)
|
||||
.color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x4, y4, 0)
|
||||
.color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x3, y3, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x1, y1, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x4, y4, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
|
||||
|
||||
bufferbuilder.vertex(model, x3, y3, 0)
|
||||
.color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x4, y4, 0)
|
||||
.color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x6, y6, 0)
|
||||
.color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x3, y3, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x4, y4, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x6, y6, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
|
||||
|
||||
bufferbuilder.vertex(model, x5, y5, 0)
|
||||
.color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x4, y4, 0)
|
||||
.color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x7, y7, 0)
|
||||
.color(fc4 >> 16 & 0xFF, fc4 >> 8 & 0xFF, fc4 & 0xFF, fc4 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x5, y5, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x4, y4, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x7, y7, 0).color(fc4 >> 16 & 0xFF, fc4 >> 8 & 0xFF, fc4 & 0xFF, fc4 >> 24 & 0xFF).endVertex();
|
||||
|
||||
bufferbuilder.vertex(model, x6, y6, 0)
|
||||
.color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x5, y5, 0)
|
||||
.color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x8, y8, 0)
|
||||
.color(fc4 >> 16 & 0xFF, fc4 >> 8 & 0xFF, fc4 & 0xFF, fc4 >> 24 & 0xFF)
|
||||
.endVertex();
|
||||
bufferbuilder.vertex(model, x6, y6, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x5, y5, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
|
||||
bufferbuilder.vertex(model, x8, y8, 0).color(fc4 >> 16 & 0xFF, fc4 >> 8 & 0xFF, fc4 & 0xFF, fc4 >> 24 & 0xFF).endVertex();
|
||||
|
||||
tessellator.draw();
|
||||
RenderSystem.shadeModel(GL11.GL_FLAT);
|
||||
|
@ -241,4 +231,30 @@ public class UIRenderHelper {
|
|||
RenderSystem.enableAlphaTest();
|
||||
RenderSystem.enableTexture();
|
||||
}
|
||||
|
||||
//just like AbstractGui#drawTexture, but with a color at every vertex
|
||||
public static void drawColoredTexture(MatrixStack ms, Color c, int x, int y, int tex_left, int tex_top, int width, int height) {
|
||||
drawColoredTexture(ms, c, x, y, 0, (float) tex_left, (float) tex_top, width, height, 256, 256);
|
||||
}
|
||||
|
||||
public static void drawColoredTexture(MatrixStack ms, Color c, int x, int y, int z, float tex_left, float tex_top, int width, int height, int sheet_width, int sheet_height) {
|
||||
drawColoredTexture(ms, c, x, x + width, y, y + height, z, width, height, tex_left, tex_top, sheet_width, sheet_height);
|
||||
}
|
||||
|
||||
private static void drawColoredTexture(MatrixStack ms, Color c, int left, int right, int top, int bot, int z, int tex_width, int tex_height, float tex_left, float tex_top, int sheet_width, int sheet_height) {
|
||||
drawTexturedQuad(ms.peek().getModel(), c, left, right, top, bot, z, (tex_left + 0.0F) / (float) sheet_width, (tex_left + (float) tex_width) / (float) sheet_width, (tex_top + 0.0F) / (float) sheet_height, (tex_top + (float) tex_height) / (float) sheet_height);
|
||||
}
|
||||
|
||||
private static void drawTexturedQuad(Matrix4f m, Color c, int left, int right, int top, int bot, int z, float u1, float u2, float v1, float v2) {
|
||||
RenderSystem.enableBlend();
|
||||
BufferBuilder bufferbuilder = Tessellator.getInstance().getBuffer();
|
||||
bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEXTURE);
|
||||
bufferbuilder.vertex(m, (float) left , (float) bot, (float) z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).texture(u1, v2).endVertex();
|
||||
bufferbuilder.vertex(m, (float) right, (float) bot, (float) z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).texture(u2, v2).endVertex();
|
||||
bufferbuilder.vertex(m, (float) right, (float) top, (float) z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).texture(u2, v1).endVertex();
|
||||
bufferbuilder.vertex(m, (float) left , (float) top, (float) z).color(c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()).texture(u1, v1).endVertex();
|
||||
bufferbuilder.finishDrawing();
|
||||
RenderSystem.enableAlphaTest();
|
||||
WorldVertexBufferUploader.draw(bufferbuilder);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,9 @@ package com.simibubi.create.foundation.gui.widgets;
|
|||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
|
@ -11,19 +14,78 @@ import net.minecraft.util.text.StringTextComponent;
|
|||
|
||||
public abstract class AbstractSimiWidget extends Widget {
|
||||
|
||||
protected List<ITextComponent> toolTip;
|
||||
protected float z;
|
||||
protected boolean wasHovered = false;
|
||||
protected List<ITextComponent> toolTip = new LinkedList<>();
|
||||
protected BiConsumer<Integer, Integer> onClick = (_$, _$$) -> {};
|
||||
|
||||
public AbstractSimiWidget(int xIn, int yIn, int widthIn, int heightIn) {
|
||||
super(xIn, yIn, widthIn, heightIn, StringTextComponent.EMPTY);
|
||||
toolTip = new LinkedList<>();
|
||||
protected AbstractSimiWidget() {
|
||||
this(0, 0);
|
||||
}
|
||||
|
||||
protected AbstractSimiWidget(int x, int y) {
|
||||
this(x, y, 16, 16);
|
||||
}
|
||||
|
||||
protected AbstractSimiWidget(int x, int y, int width, int height) {
|
||||
super(x, y, width, height, StringTextComponent.EMPTY);
|
||||
}
|
||||
|
||||
public <T extends AbstractSimiWidget> T withCallback(BiConsumer<Integer, Integer> cb) {
|
||||
this.onClick = cb;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends AbstractSimiWidget> T withCallback(Runnable cb) {
|
||||
return withCallback((_$, _$$) -> cb.run());
|
||||
}
|
||||
|
||||
public <T extends AbstractSimiWidget> T atZLevel(float z) {
|
||||
this.z = z;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public List<ITextComponent> getToolTip() {
|
||||
return toolTip;
|
||||
}
|
||||
|
||||
public void tick() {}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrixStack, int p_renderButton_1_, int p_renderButton_2_, float p_renderButton_3_) {
|
||||
public void render(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
if (visible) {
|
||||
hovered = isMouseOver(mouseX, mouseY);
|
||||
beforeRender(ms, mouseX, mouseY, partialTicks);
|
||||
renderButton(ms, mouseX, mouseY, partialTicks);
|
||||
afterRender(ms, mouseX, mouseY, partialTicks);
|
||||
wasHovered = isHovered();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {}
|
||||
|
||||
@Override
|
||||
protected boolean clicked(double mouseX, double mouseY) {
|
||||
return active && visible && isMouseOver(mouseX, mouseY);
|
||||
}
|
||||
|
||||
protected void beforeRender(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
ms.push();
|
||||
}
|
||||
|
||||
protected void afterRender(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
public void runCallback(double mouseX, double mouseY) {
|
||||
onClick.accept((int) mouseX, (int) mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(double mouseX, double mouseY) {
|
||||
runCallback(mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
package com.simibubi.create.foundation.gui.widgets;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.BoxElement;
|
||||
import com.simibubi.create.foundation.gui.DelegatedStencilElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
|
||||
public class BoxWidget extends ElementWidget {
|
||||
|
||||
public static final Function<BoxWidget, DelegatedStencilElement.ElementRenderer> gradientFactory = (box) -> (ms, w, h, alpha) -> UIRenderHelper.angledGradient(ms, 90, w/2, -2, w + 4, h + 4, box.gradientColor1.getRGB(), box.gradientColor2.getRGB());
|
||||
|
||||
protected BoxElement box;
|
||||
|
||||
protected Color customBorderTop;
|
||||
protected Color customBorderBot;
|
||||
protected boolean animateColors = true;
|
||||
protected LerpedFloat colorAnimation = LerpedFloat.linear();
|
||||
protected Color gradientColor1, gradientColor2;
|
||||
private Color colorTarget1 = Theme.c(Theme.Key.BUTTON_IDLE, true), colorTarget2 = Theme.c(Theme.Key.BUTTON_IDLE, false);
|
||||
private Color previousColor1, previousColor2;
|
||||
|
||||
public BoxWidget() {
|
||||
this(0, 0);
|
||||
}
|
||||
|
||||
public BoxWidget(int x, int y) {
|
||||
this(x, y, 16, 16);
|
||||
}
|
||||
|
||||
public BoxWidget(int x, int y, int width, int height) {
|
||||
super(x, y, width, height);
|
||||
box = new BoxElement()
|
||||
.at(x, y)
|
||||
.withBounds(width, height);
|
||||
gradientColor1 = colorTarget1;
|
||||
gradientColor2 = colorTarget2;
|
||||
}
|
||||
|
||||
public <T extends BoxWidget> T withBounds(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxWidget> T withBorderColors(Couple<Color> colors) {
|
||||
this.customBorderTop = colors.getFirst();
|
||||
this.customBorderBot = colors.getSecond();
|
||||
updateColorsFromState();
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxWidget> T withBorderColors(Color top, Color bot) {
|
||||
this.customBorderTop = top;
|
||||
this.customBorderBot = bot;
|
||||
updateColorsFromState();
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends BoxWidget> T animateColors(boolean b) {
|
||||
this.animateColors = b;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
colorAnimation.tickChaser();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(double x, double y) {
|
||||
super.onClick(x, y);
|
||||
|
||||
gradientColor1 = Theme.c(Theme.Key.BUTTON_CLICK, true);
|
||||
gradientColor2 = Theme.c(Theme.Key.BUTTON_CLICK, true);
|
||||
startGradientAnimation(getColorForState(true), getColorForState(false), true, 0.15);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeRender(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
super.beforeRender(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
if (hovered != wasHovered) {
|
||||
startGradientAnimation(
|
||||
getColorForState(true),
|
||||
getColorForState(false),
|
||||
hovered
|
||||
);
|
||||
}
|
||||
|
||||
if (colorAnimation.settled()) {
|
||||
gradientColor1 = colorTarget1;
|
||||
gradientColor2 = colorTarget2;
|
||||
} else {
|
||||
float animationValue = 1 - Math.abs(colorAnimation.getValue(partialTicks));
|
||||
gradientColor1 = ColorHelper.mixColors(previousColor1, colorTarget1, animationValue);
|
||||
gradientColor2 = ColorHelper.mixColors(previousColor2, colorTarget2, animationValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
float fadeValue = fade.getValue(partialTicks);
|
||||
if (fadeValue < .1f)
|
||||
return;
|
||||
|
||||
box.withAlpha(fadeValue);
|
||||
box.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_TRANSPARENT))
|
||||
.gradientBorder(gradientColor1, gradientColor2)
|
||||
.at(x, y, z)
|
||||
.withBounds(width, height)
|
||||
.render(ms);
|
||||
|
||||
super.renderButton(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
wasHovered = hovered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMouseOver(double mX, double mY) {
|
||||
if (!active || !visible)
|
||||
return false;
|
||||
|
||||
return
|
||||
x - 4 <= mX &&
|
||||
y - 4 <= mY &&
|
||||
mX <= x + 4 + width &&
|
||||
mY <= y + 4 + height;
|
||||
}
|
||||
|
||||
public BoxElement getBox() {
|
||||
return box;
|
||||
}
|
||||
|
||||
public void updateColorsFromState() {
|
||||
colorTarget1 = getColorForState(true);
|
||||
colorTarget2 = getColorForState(false);
|
||||
}
|
||||
|
||||
public void animateGradientFromState() {
|
||||
startGradientAnimation(
|
||||
getColorForState(true),
|
||||
getColorForState(false),
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
private void startGradientAnimation(Color c1, Color c2, boolean positive, double expSpeed) {
|
||||
if (!animateColors)
|
||||
return;
|
||||
|
||||
colorAnimation.startWithValue(positive ? 1 : -1);
|
||||
colorAnimation.chase(0, expSpeed, LerpedFloat.Chaser.EXP);
|
||||
colorAnimation.tickChaser();
|
||||
|
||||
previousColor1 = gradientColor1;
|
||||
previousColor2 = gradientColor2;
|
||||
|
||||
colorTarget1 = c1;
|
||||
colorTarget2 = c2;
|
||||
}
|
||||
|
||||
private void startGradientAnimation(Color c1, Color c2, boolean positive) {
|
||||
startGradientAnimation(c1, c2, positive, 0.3);
|
||||
}
|
||||
|
||||
private Color getColorForState(boolean first) {
|
||||
if (!active)
|
||||
return Theme.p(Theme.Key.BUTTON_DISABLE).get(first);
|
||||
|
||||
if (hovered) {
|
||||
if (first)
|
||||
return customBorderTop != null ? customBorderTop.darker() : Theme.c(Theme.Key.BUTTON_HOVER, true);
|
||||
else
|
||||
return customBorderBot != null ? customBorderBot.darker() : Theme.c(Theme.Key.BUTTON_HOVER, false);
|
||||
}
|
||||
|
||||
if (first)
|
||||
return customBorderTop != null ? customBorderTop : Theme.c(Theme.Key.BUTTON_IDLE, true);
|
||||
else
|
||||
return customBorderBot != null ? customBorderBot : Theme.c(Theme.Key.BUTTON_IDLE, false);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
package com.simibubi.create.foundation.gui.widgets;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.IScreenRenderable;
|
||||
import com.simibubi.create.foundation.gui.RenderElement;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
|
||||
public class ElementWidget extends AbstractSimiWidget {
|
||||
|
||||
protected RenderElement element = RenderElement.EMPTY;
|
||||
|
||||
protected boolean usesFade = false;
|
||||
protected int fadeModX;
|
||||
protected int fadeModY;
|
||||
protected LerpedFloat fade = LerpedFloat.linear().startWithValue(1);
|
||||
|
||||
protected boolean rescaleElement = false;
|
||||
protected float rescaleSizeX;
|
||||
protected float rescaleSizeY;
|
||||
|
||||
protected float paddingX = 0;
|
||||
protected float paddingY = 0;
|
||||
|
||||
public ElementWidget(int x, int y) {
|
||||
super(x, y);
|
||||
}
|
||||
|
||||
public ElementWidget(int x, int y, int width, int height) {
|
||||
super(x, y, width, height);
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T showingElement(RenderElement element) {
|
||||
this.element = element;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T showing(IScreenRenderable renderable) {
|
||||
return this.showingElement(RenderElement.of(renderable));
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T modifyElement(Consumer<RenderElement> consumer) {
|
||||
if (element != null)
|
||||
consumer.accept(element);
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T mapElement(UnaryOperator<RenderElement> function) {
|
||||
if (element != null)
|
||||
element = function.apply(element);
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T withPadding(float paddingX, float paddingY) {
|
||||
this.paddingX = paddingX;
|
||||
this.paddingY = paddingY;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T enableFade(int fadeModifierX, int fadeModifierY) {
|
||||
this.fade.startWithValue(0);
|
||||
this.usesFade = true;
|
||||
this.fadeModX = fadeModifierX;
|
||||
this.fadeModY = fadeModifierY;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T disableFade() {
|
||||
this.fade.startWithValue(1);
|
||||
this.usesFade = false;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public LerpedFloat fade() {
|
||||
return fade;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T fade(float target) {
|
||||
fade.chase(target, 0.1, LerpedFloat.Chaser.EXP);
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T rescaleElement(float rescaleSizeX, float rescaleSizeY) {
|
||||
this.rescaleElement = true;
|
||||
this.rescaleSizeX = rescaleSizeX;
|
||||
this.rescaleSizeY = rescaleSizeY;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public <T extends ElementWidget> T disableRescale() {
|
||||
this.rescaleElement = false;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
fade.tickChaser();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beforeRender(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
super.beforeRender(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
float fadeValue = fade.getValue(partialTicks);
|
||||
element.withAlpha(fadeValue);
|
||||
if (fadeValue < 1) {
|
||||
ms.translate((1 - fadeValue) * fadeModX, (1 - fadeValue) * fadeModY, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
ms.push();
|
||||
ms.translate(x + paddingX, y + paddingY, z);
|
||||
float innerWidth = width - 2 * paddingX;
|
||||
float innerHeight = height - 2 * paddingY;
|
||||
if (rescaleElement) {
|
||||
float xScale = innerWidth / rescaleSizeX;
|
||||
float yScale = innerHeight / rescaleSizeY;
|
||||
ms.scale(xScale, yScale, 1);
|
||||
element.at(element.getX() / xScale, element.getY() / yScale);
|
||||
}
|
||||
element.withBounds((int) innerWidth, (int) innerHeight).render(ms);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
public RenderElement getRenderElement() {
|
||||
return element;
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ import com.simibubi.create.foundation.gui.AllIcons;
|
|||
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class IconButton extends AbstractSimiWidget {
|
||||
|
||||
private AllIcons icon;
|
||||
|
@ -18,7 +20,7 @@ public class IconButton extends AbstractSimiWidget {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
|
||||
public void renderButton(@Nonnull MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
|
||||
if (this.visible) {
|
||||
this.hovered =
|
||||
mouseX >= this.x && mouseY >= this.y && mouseX < this.x + this.width && mouseY < this.y + this.height;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.foundation.gui.widgets;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.AllGuiTextures;
|
||||
|
@ -22,7 +24,7 @@ public class Indicator extends AbstractSimiWidget {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks ) {
|
||||
public void render(@Nonnull MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks ) {
|
||||
AllGuiTextures toDraw;
|
||||
switch(state) {
|
||||
case ON: toDraw = AllGuiTextures.INDICATOR_WHITE; break;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.foundation.gui.widgets;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
|
@ -69,7 +71,7 @@ public class Label extends AbstractSimiWidget {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
|
||||
public void render(@Nonnull MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
|
||||
if (!visible)
|
||||
return;
|
||||
if (text == null || text.getString().isEmpty())
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package com.simibubi.create.foundation.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
|
||||
import net.minecraft.client.MainWindow;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Mixin(Minecraft.class)
|
||||
public class WindowResizeMixin {
|
||||
|
||||
@Shadow @Final private MainWindow mainWindow;
|
||||
|
||||
@Inject(at = @At("TAIL"), method = "updateWindowSize")
|
||||
private void updateWindowSize(CallbackInfo ci) {
|
||||
if (UIRenderHelper.framebuffer != null)
|
||||
UIRenderHelper.framebuffer.func_216491_a(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), Minecraft.IS_RUNNING_ON_MAC);
|
||||
}
|
||||
|
||||
}
|
|
@ -38,8 +38,9 @@ import com.simibubi.create.content.schematics.packet.InstantSchematicPacket;
|
|||
import com.simibubi.create.content.schematics.packet.SchematicPlacePacket;
|
||||
import com.simibubi.create.content.schematics.packet.SchematicSyncPacket;
|
||||
import com.simibubi.create.content.schematics.packet.SchematicUploadPacket;
|
||||
import com.simibubi.create.foundation.command.ConfigureConfigPacket;
|
||||
import com.simibubi.create.foundation.command.SConfigureConfigPacket;
|
||||
import com.simibubi.create.foundation.command.HighlightPacket;
|
||||
import com.simibubi.create.foundation.config.ui.CConfigureConfigPacket;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringCountUpdatePacket;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollValueUpdatePacket;
|
||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||
|
@ -80,12 +81,13 @@ public enum AllPackets {
|
|||
PLACE_EJECTOR(EjectorPlacementPacket.class, EjectorPlacementPacket::new, PLAY_TO_SERVER),
|
||||
TRIGGER_EJECTOR(EjectorTriggerPacket.class, EjectorTriggerPacket::new, PLAY_TO_SERVER),
|
||||
EJECTOR_ELYTRA(EjectorElytraPacket.class, EjectorElytraPacket::new, PLAY_TO_SERVER),
|
||||
C_CONFIGURE_CONFIG(CConfigureConfigPacket.class, CConfigureConfigPacket::new, PLAY_TO_SERVER),
|
||||
|
||||
// Server to Client
|
||||
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),
|
||||
SERVER_SPEED(ServerSpeedProvider.Packet.class, ServerSpeedProvider.Packet::new, PLAY_TO_CLIENT),
|
||||
BEAM_EFFECT(ZapperBeamPacket.class, ZapperBeamPacket::new, PLAY_TO_CLIENT),
|
||||
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new, PLAY_TO_CLIENT),
|
||||
S_CONFIGURE_CONFIG(SConfigureConfigPacket.class, SConfigureConfigPacket::new, PLAY_TO_CLIENT),
|
||||
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new, PLAY_TO_CLIENT),
|
||||
CONTRAPTION_DISASSEMBLE(ContraptionDisassemblyPacket.class, ContraptionDisassemblyPacket::new, PLAY_TO_CLIENT),
|
||||
GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new, PLAY_TO_CLIENT),
|
||||
|
|
|
@ -9,9 +9,11 @@ import org.apache.commons.lang3.mutable.MutableInt;
|
|||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
|
||||
import com.simibubi.create.foundation.gui.IScreenRenderable;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.ponder.content.PonderTagScreen;
|
||||
import com.simibubi.create.foundation.ponder.ui.PonderButton;
|
||||
|
@ -76,9 +78,9 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen {
|
|||
if (screen instanceof PonderTagScreen)
|
||||
icon = ((PonderTagScreen) screen).getTag();
|
||||
|
||||
widgets.add(backTrack = new PonderButton(31, height - 31 - PonderButton.SIZE, () -> {
|
||||
ScreenOpener.openPreviousScreen(this, Optional.empty());
|
||||
}).fade(0, -1));
|
||||
widgets.add(backTrack = new PonderButton(31, height - 31 - 20)
|
||||
.enableFade(0, 5)
|
||||
.withCallback(() -> ScreenOpener.openPreviousScreen(this, Optional.empty())));
|
||||
backTrack.fade(1);
|
||||
|
||||
if (icon != null)
|
||||
|
@ -97,7 +99,7 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen {
|
|||
ms.push();
|
||||
ms.translate(0, 0, 500);
|
||||
if (backTrack.isHovered()) {
|
||||
textRenderer.draw(ms, Lang.translate(THINK_BACK), 15, height - 16, 0xffa3a3a3);
|
||||
textRenderer.draw(ms, Lang.translate(THINK_BACK), 15, height - 16, Theme.i(Theme.Key.TEXT_DARKER));
|
||||
if (MathHelper.epsilonEquals(arrowAnimation.getValue(), arrowAnimation.getChaseTarget())) {
|
||||
arrowAnimation.setValue(1);
|
||||
arrowAnimation.setValue(1);// called twice to also set the previous value to 1
|
||||
|
@ -108,7 +110,18 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen {
|
|||
|
||||
@Override
|
||||
protected void renderWindowBackground(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
if (transition.getChaseTarget() == 0) {
|
||||
if (backTrack != null) {
|
||||
int x = (int) MathHelper.lerp(arrowAnimation.getValue(partialTicks), -9, 21);
|
||||
int maxX = backTrack.x + backTrack.getWidth();
|
||||
|
||||
if (x + 30 < backTrack.x)
|
||||
UIRenderHelper.breadcrumbArrow(ms, x + 30, height - 51, 0, maxX - (x + 30), 20, 5, Theme.p(Theme.Key.PONDER_BACK_ARROW));
|
||||
|
||||
UIRenderHelper.breadcrumbArrow(ms, x, height - 51, 0, 30, 20, 5, Theme.p(Theme.Key.PONDER_BACK_ARROW));
|
||||
UIRenderHelper.breadcrumbArrow(ms, x - 30, height - 51, 0, 30, 20, 5, Theme.p(Theme.Key.PONDER_BACK_ARROW));
|
||||
}
|
||||
|
||||
if (transition.getChaseTarget() == 0 || transition.settled()) {
|
||||
renderBackground(ms);
|
||||
return;
|
||||
}
|
||||
|
@ -121,14 +134,14 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen {
|
|||
|
||||
// draw last screen into buffer
|
||||
if (lastScreen != null && lastScreen != this && !transition.settled()) {
|
||||
ms.push();// 1
|
||||
ms.push();
|
||||
UIRenderHelper.framebuffer.framebufferClear(Minecraft.IS_RUNNING_ON_MAC);
|
||||
UIRenderHelper.prepFramebufferSize();
|
||||
ms.push();// 2
|
||||
ms.translate(0, 0, -1000);
|
||||
UIRenderHelper.framebuffer.bindFramebuffer(true);
|
||||
lastScreen.render(ms, mouseX, mouseY, 10);
|
||||
ms.pop();// 2
|
||||
lastScreen.render(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
ms.pop();
|
||||
ms.push();
|
||||
|
||||
// use the buffer texture
|
||||
Minecraft.getInstance()
|
||||
|
@ -144,32 +157,23 @@ public abstract class NavigatableSimiScreen extends AbstractSimiScreen {
|
|||
dpy = ((NavigatableSimiScreen) lastScreen).depthPointY;
|
||||
}
|
||||
|
||||
// transitionV is 1/-1 when the older screen is hidden
|
||||
// transitionV is 0 when the older screen is still fully visible
|
||||
ms.translate(dpx, dpy, 0);
|
||||
ms.scale((float) scale, (float) scale, 1);
|
||||
ms.scale(scale, scale, 1);
|
||||
ms.translate(-dpx, -dpy, 0);
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.disableAlphaTest();
|
||||
UIRenderHelper.drawFramebuffer(1f - Math.abs(transitionValue));
|
||||
ms.pop();// 1
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.enableAlphaTest();
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
// modify current screen as well
|
||||
scale = transitionValue > 0 ? 1 - 0.5f * (1 - transitionValue) : 1 + .5f * (1 + transitionValue);
|
||||
ms.translate(depthPointX, depthPointY, 0);
|
||||
ms.scale((float) scale, (float) scale, 1);
|
||||
ms.scale(scale, scale, 1);
|
||||
ms.translate(-depthPointX, -depthPointY, 0);
|
||||
|
||||
if (backTrack != null) {
|
||||
int x = (int) MathHelper.lerp(arrowAnimation.getValue(partialTicks), -9, 21);
|
||||
int maxX = backTrack.x + backTrack.getWidth();
|
||||
|
||||
if (x + 30 < backTrack.x)
|
||||
UIRenderHelper.breadcrumbArrow(ms, x + 30, height - 51, 0, maxX - (x + 30), 20, 5, 0x40aa9999,
|
||||
0x10aa9999);
|
||||
|
||||
UIRenderHelper.breadcrumbArrow(ms, x, height - 51, 0, 30, 20, 5, 0x40aa9999, 0x10aa9999);
|
||||
UIRenderHelper.breadcrumbArrow(ms, x - 30, height - 51, 0, 30, 20, 5, 0x40aa9999, 0x10aa9999);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package com.simibubi.create.foundation.ponder;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.BoxElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
|
@ -15,7 +17,6 @@ import net.minecraftforge.fml.client.gui.GuiUtils;
|
|||
public class PonderProgressBar extends AbstractSimiWidget {
|
||||
|
||||
LerpedFloat progress;
|
||||
LerpedFloat flash;
|
||||
|
||||
PonderUI ponder;
|
||||
|
||||
|
@ -24,35 +25,20 @@ public class PonderProgressBar extends AbstractSimiWidget {
|
|||
|
||||
this.ponder = ponder;
|
||||
progress = LerpedFloat.linear()
|
||||
.startWithValue(0);
|
||||
flash = LerpedFloat.linear()
|
||||
.startWithValue(0);
|
||||
.startWithValue(0);
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
progress.chase(ponder.getActiveScene()
|
||||
.getSceneProgress(), .5f, LerpedFloat.Chaser.EXP);
|
||||
.getSceneProgress(), .5f, LerpedFloat.Chaser.EXP);
|
||||
progress.tickChaser();
|
||||
|
||||
if (hovered)
|
||||
flash();
|
||||
}
|
||||
|
||||
public void flash() {
|
||||
float value = flash.getValue();
|
||||
flash.setValue(value + (1 - value) * .2f);
|
||||
}
|
||||
|
||||
public void dim() {
|
||||
float value = flash.getValue();
|
||||
flash.setValue(value * .5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean clicked(double mouseX, double mouseY) {
|
||||
return this.active && this.visible && !ponder.getActiveScene().keyframeTimes.isEmpty()
|
||||
&& mouseX >= (double) this.x && mouseX < (double) (this.x + this.width + 4) && mouseY >= (double) this.y - 3
|
||||
&& mouseY < (double) (this.y + this.height + 20);
|
||||
&& mouseX >= (double) this.x && mouseX < (double) (this.x + this.width + 4) && mouseY >= (double) this.y - 3
|
||||
&& mouseY < (double) (this.y + this.height + 20);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -102,58 +88,46 @@ public class PonderProgressBar extends AbstractSimiWidget {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
|
||||
hovered = clicked(mouseX, mouseY);
|
||||
|
||||
ms.push();
|
||||
ms.translate(0, 0, 250);
|
||||
/*
|
||||
* ponderButtons are at z+400
|
||||
* renderBox is at z+100
|
||||
* gradients have to be in front of the box so z>+100
|
||||
*/
|
||||
new BoxElement()
|
||||
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
|
||||
.at(x, y, 250)
|
||||
.withBounds(width, height)
|
||||
.render(ms);
|
||||
|
||||
ms.push();
|
||||
PonderUI.renderBox(ms, x, y, width, height, false);
|
||||
ms.pop();
|
||||
|
||||
ms.push();
|
||||
ms.translate(x - 2, y - 2, 0);
|
||||
ms.translate(x - 2, y - 2, 150);
|
||||
|
||||
ms.push();
|
||||
ms.scale((width + 4) * progress.getValue(partialTicks), 1, 1);
|
||||
GuiUtils.drawGradientRect(ms.peek()
|
||||
.getModel(), 110, 0, 3, 1, 4, 0x80ffeedd, 0x80ffeedd);
|
||||
GuiUtils.drawGradientRect(ms.peek()
|
||||
.getModel(), 110, 0, 4, 1, 5, 0x50ffeedd, 0x50ffeedd);
|
||||
int c1 = Theme.i(Theme.Key.PONDER_PROGRESSBAR, true);
|
||||
int c2 = Theme.i(Theme.Key.PONDER_PROGRESSBAR, false);
|
||||
GuiUtils.drawGradientRect(ms.peek().getModel(), 110, 0, 3, 1, 4, c1, c1);
|
||||
GuiUtils.drawGradientRect(ms.peek().getModel(), 110, 0, 4, 1, 5, c2, c2);
|
||||
ms.pop();
|
||||
|
||||
renderKeyframes(ms, mouseX, partialTicks);
|
||||
|
||||
ms.pop();
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
private void renderKeyframes(MatrixStack ms, int mouseX, float partialTicks) {
|
||||
PonderScene activeScene = ponder.getActiveScene();
|
||||
|
||||
int hoverStartColor;
|
||||
int hoverEndColor;
|
||||
int hoverStartColor = Theme.i(Theme.Key.PONDER_HOVER, true) | 0xa0_000000;
|
||||
int hoverEndColor = Theme.i(Theme.Key.PONDER_HOVER, false) | 0xa0_000000;
|
||||
int idleStartColor = Theme.i(Theme.Key.PONDER_IDLE, true) | 0x40_000000;
|
||||
int idleEndColor = Theme.i(Theme.Key.PONDER_IDLE, false) | 0x40_000000;
|
||||
int hoverIndex;
|
||||
|
||||
if (hovered) {
|
||||
hoverIndex = getHoveredKeyframeIndex(activeScene, mouseX);
|
||||
float flashValue = flash.getValue(partialTicks) * 3
|
||||
+ (float) Math.sin((AnimationTickHolder.getTicks() + partialTicks) / 6);
|
||||
|
||||
hoverEndColor = ColorHelper.applyAlpha(0x70ffffff, flashValue);
|
||||
hoverStartColor = ColorHelper.applyAlpha(0x30ffffff, flashValue);
|
||||
} else {
|
||||
hoverIndex = -2;
|
||||
hoverEndColor = 0;
|
||||
hoverStartColor = 0;
|
||||
}
|
||||
IntList keyframeTimes = activeScene.keyframeTimes;
|
||||
|
||||
|
@ -167,8 +141,8 @@ public class PonderProgressBar extends AbstractSimiWidget {
|
|||
int keyframePos = (int) (((float) keyframeTime) / ((float) activeScene.totalTime) * (width + 4));
|
||||
|
||||
boolean selected = i == hoverIndex;
|
||||
int startColor = selected ? hoverStartColor : 0x30ffeedd;
|
||||
int endColor = selected ? hoverEndColor : 0x60ffeedd;
|
||||
int startColor = selected ? hoverStartColor : idleStartColor;
|
||||
int endColor = selected ? hoverEndColor : idleEndColor;
|
||||
int height = selected ? 8 : 4;
|
||||
|
||||
drawKeyframe(ms, activeScene, selected, keyframeTime, keyframePos, startColor, endColor, height);
|
||||
|
@ -176,12 +150,11 @@ public class PonderProgressBar extends AbstractSimiWidget {
|
|||
}
|
||||
}
|
||||
|
||||
private void drawKeyframe(MatrixStack ms, PonderScene activeScene, boolean selected, int keyframeTime,
|
||||
int keyframePos, int startColor, int endColor, int height) {
|
||||
private void drawKeyframe(MatrixStack ms, PonderScene activeScene, boolean selected, int keyframeTime, int keyframePos, int startColor, int endColor, int height) {
|
||||
if (selected) {
|
||||
FontRenderer font = Minecraft.getInstance().fontRenderer;
|
||||
GuiUtils.drawGradientRect(ms.peek()
|
||||
.getModel(), 100, keyframePos, 10, keyframePos + 1, 10 + height, endColor, startColor);
|
||||
.getModel(), 100, keyframePos, 10, keyframePos + 1, 10 + height, endColor, startColor);
|
||||
ms.push();
|
||||
ms.translate(0, 0, 100);
|
||||
String text;
|
||||
|
@ -198,7 +171,7 @@ public class PonderProgressBar extends AbstractSimiWidget {
|
|||
}
|
||||
|
||||
GuiUtils.drawGradientRect(ms.peek()
|
||||
.getModel(), 500, keyframePos, -1, keyframePos + 1, 2 + height, startColor, endColor);
|
||||
.getModel(), 500, keyframePos, -1, keyframePos + 1, 2 + height, startColor, endColor);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,13 +2,13 @@ package com.simibubi.create.foundation.ponder;
|
|||
|
||||
import static com.simibubi.create.foundation.ponder.PonderLocalization.LANG_PREFIX;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
@ -16,8 +16,10 @@ import com.mojang.blaze3d.systems.RenderSystem;
|
|||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.gui.AllGuiTextures;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.gui.BoxElement;
|
||||
import com.simibubi.create.foundation.gui.GuiGameElement;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.ponder.PonderScene.SceneTransform;
|
||||
import com.simibubi.create.foundation.ponder.content.DebugScenes;
|
||||
|
@ -29,6 +31,7 @@ import com.simibubi.create.foundation.ponder.elements.TextWindowElement;
|
|||
import com.simibubi.create.foundation.ponder.ui.PonderButton;
|
||||
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.FontHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
@ -43,14 +46,12 @@ import net.minecraft.client.MainWindow;
|
|||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.widget.Widget;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.MutableBoundingBox;
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.util.math.vector.Vector3f;
|
||||
import net.minecraft.util.text.IFormattableTextComponent;
|
||||
|
@ -166,13 +167,16 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
int i = tagButtons.size();
|
||||
int x = 31;
|
||||
int y = 81 + i * 30;
|
||||
PonderButton b = new PonderButton(x, y, (mouseX, mouseY) -> {
|
||||
centerScalingOn(mouseX, mouseY);
|
||||
ScreenOpener.transitionTo(new PonderTagScreen(t));
|
||||
}).showing(t);
|
||||
|
||||
widgets.add(b);
|
||||
tagButtons.add(b);
|
||||
PonderButton b2 = new PonderButton(x, y)
|
||||
.showing(t)
|
||||
.withCallback((mX, mY) -> {
|
||||
centerScalingOn(mX, mY);
|
||||
ScreenOpener.transitionTo(new PonderTagScreen(t));
|
||||
});
|
||||
|
||||
widgets.add(b2);
|
||||
tagButtons.add(b2);
|
||||
|
||||
LerpedFloat chase = LerpedFloat.linear()
|
||||
.startWithValue(0)
|
||||
|
@ -181,10 +185,10 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
|
||||
});
|
||||
|
||||
if (chapter != null) {
|
||||
/*if (chapter != null) {
|
||||
widgets.add(chap = new PonderButton(width - 31 - 24, 31, () -> {
|
||||
}).showing(chapter));
|
||||
}
|
||||
}*/
|
||||
|
||||
GameSettings bindings = client.gameSettings;
|
||||
int spacing = 8;
|
||||
|
@ -193,53 +197,63 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
|
||||
{
|
||||
int pX = (width / 2) - 110;
|
||||
int pY = bY + PonderButton.SIZE + 4;
|
||||
int pY = bY + 20 + 4;
|
||||
int pW = width - 2 * pX;
|
||||
widgets.add(progressBar = new PonderProgressBar(this, pX, pY, pW, 1));
|
||||
}
|
||||
|
||||
widgets.add(scan = new PonderButton(bX, bY, () -> {
|
||||
identifyMode = !identifyMode;
|
||||
if (!identifyMode)
|
||||
scenes.get(index)
|
||||
.deselect();
|
||||
else
|
||||
ponderPartialTicksPaused = client.getRenderPartialTicks();
|
||||
}).showing(AllIcons.I_MTD_SCAN)
|
||||
.shortcut(bindings.keyBindDrop)
|
||||
.fade(0, -1));
|
||||
widgets.add(scan = new PonderButton(bX, bY)
|
||||
.withShortcut(bindings.keyBindDrop)
|
||||
.showing(AllIcons.I_MTD_SCAN)
|
||||
.enableFade(0, 5)
|
||||
.withCallback(() -> {
|
||||
identifyMode = !identifyMode;
|
||||
if (!identifyMode)
|
||||
scenes.get(index)
|
||||
.deselect();
|
||||
else
|
||||
ponderPartialTicksPaused = client.getRenderPartialTicks();
|
||||
}));
|
||||
|
||||
widgets.add(slowMode = new PonderButton(width - 20 - 31, bY, () -> {
|
||||
setComfyReadingEnabled(!isComfyReadingEnabled());
|
||||
}).showing(AllIcons.I_MTD_SLOW_MODE)
|
||||
.fade(0, -1));
|
||||
widgets.add(slowMode = new PonderButton(width - 20 - 31, bY)
|
||||
.showing(AllIcons.I_MTD_SLOW_MODE)
|
||||
.enableFade(0, 5)
|
||||
.withCallback(() -> setComfyReadingEnabled(!isComfyReadingEnabled())));
|
||||
|
||||
if (PonderIndex.EDITOR_MODE) {
|
||||
widgets.add(userMode = new PonderButton(width - 50 - 31, bY, () -> {
|
||||
userViewMode = !userViewMode;
|
||||
}).showing(AllIcons.I_MTD_USER_MODE)
|
||||
.fade(0, -1));
|
||||
widgets.add(userMode = new PonderButton(width - 50 - 31, bY)
|
||||
.showing(AllIcons.I_MTD_USER_MODE)
|
||||
.enableFade(0, 5)
|
||||
.withCallback(() -> userViewMode = !userViewMode));
|
||||
}
|
||||
|
||||
bX += 50 + spacing;
|
||||
widgets.add(left = new PonderButton(bX, bY, () -> this.scroll(false)).showing(AllIcons.I_MTD_LEFT)
|
||||
.shortcut(bindings.keyBindLeft)
|
||||
.fade(0, -1));
|
||||
widgets.add(left = new PonderButton(bX, bY)
|
||||
.withShortcut(bindings.keyBindLeft)
|
||||
.showing(AllIcons.I_MTD_LEFT)
|
||||
.enableFade(0, 5)
|
||||
.withCallback(() -> this.scroll(false)));
|
||||
|
||||
bX += 20 + spacing;
|
||||
widgets.add(close = new PonderButton(bX, bY, this::onClose).showing(AllIcons.I_MTD_CLOSE)
|
||||
.shortcut(bindings.keyBindInventory)
|
||||
.fade(0, -1));
|
||||
widgets.add(close = new PonderButton(bX, bY)
|
||||
.withShortcut(bindings.keyBindInventory)
|
||||
.showing(AllIcons.I_MTD_CLOSE)
|
||||
.enableFade(0, 5)
|
||||
.withCallback(this::onClose));
|
||||
|
||||
bX += 20 + spacing;
|
||||
widgets.add(right = new PonderButton(bX, bY, () -> this.scroll(true)).showing(AllIcons.I_MTD_RIGHT)
|
||||
.shortcut(bindings.keyBindRight)
|
||||
.fade(0, -1));
|
||||
widgets.add(right = new PonderButton(bX, bY)
|
||||
.withShortcut(bindings.keyBindRight)
|
||||
.showing(AllIcons.I_MTD_RIGHT)
|
||||
.enableFade(0, 5)
|
||||
.withCallback(() -> this.scroll(true)));
|
||||
|
||||
bX += 50 + spacing;
|
||||
widgets.add(replay = new PonderButton(bX, bY, this::replay).showing(AllIcons.I_MTD_REPLAY)
|
||||
.shortcut(bindings.keyBindBack)
|
||||
.fade(0, -1));
|
||||
widgets.add(replay = new PonderButton(bX, bY)
|
||||
.withShortcut(bindings.keyBindBack)
|
||||
.showing(AllIcons.I_MTD_REPLAY)
|
||||
.enableFade(0, 5)
|
||||
.withCallback(this::replay));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -429,7 +443,6 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
|
||||
MutableBoundingBox bounds = story.getBounds();
|
||||
ms.push();
|
||||
// ms.peek().getModel().multiply(ms.peek().getModel());
|
||||
|
||||
// kool shadow fx
|
||||
{
|
||||
|
@ -527,17 +540,16 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
float lazyIndexValue = lazyIndex.getValue(partialTicks);
|
||||
float indexDiff = Math.abs(lazyIndexValue - index);
|
||||
PonderScene activeScene = scenes.get(index);
|
||||
int textColor = 0xeeeeee;
|
||||
|
||||
boolean noWidgetsHovered = true;
|
||||
for (Widget widget : widgets)
|
||||
noWidgetsHovered &= !widget.isMouseOver(mouseX, mouseY);
|
||||
|
||||
int tooltipColor = 0xffa3a3a3;
|
||||
int tooltipColor = Theme.i(Theme.Key.TEXT_DARKER);
|
||||
{
|
||||
// Chapter title
|
||||
ms.push();
|
||||
ms.translate(0, 0, 300);
|
||||
ms.translate(0, 0, 100);
|
||||
int x = 31 + 20 + 8;
|
||||
int y = 31;
|
||||
|
||||
|
@ -545,36 +557,40 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
int wordWrappedHeight = textRenderer.getWordWrappedHeight(title, left.x - 51);
|
||||
|
||||
int streakHeight = 35 - 9 + wordWrappedHeight;
|
||||
UIRenderHelper.streak(ms, 0, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (150 * fade), 0x101010);
|
||||
UIRenderHelper.streak(ms, 180, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (30 * fade), 0x101010);
|
||||
renderBox(ms, 21, 21, 30, 30, false);
|
||||
UIRenderHelper.streak(ms, 0, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (150 * fade));
|
||||
UIRenderHelper.streak(ms, 180, x - 4, y - 12 + streakHeight / 2, streakHeight, (int) (30 * fade));
|
||||
new BoxElement()
|
||||
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
|
||||
.at(21, 21, 100)
|
||||
.withBounds(30, 30)
|
||||
.render(ms);
|
||||
|
||||
|
||||
GuiGameElement.of(stack)
|
||||
.at(x - 39, y - 11)
|
||||
.scale(2)
|
||||
.render(ms);
|
||||
.scale(2)
|
||||
.at(x - 39, y - 11)
|
||||
.render(ms);
|
||||
|
||||
textRenderer.draw(ms, Lang.translate(PONDERING), x, y - 6, tooltipColor);
|
||||
y += 8;
|
||||
x += 0;
|
||||
// ms.translate(0, 3 * (indexDiff), 0);
|
||||
ms.translate(x, y, 0);
|
||||
ms.multiply(Vector3f.NEGATIVE_X.getDegreesQuaternion(indexDiff * -75));
|
||||
ms.translate(0, 0, 5);
|
||||
FontHelper.drawSplitString(ms, textRenderer, title, 0, 0, left.x - 51,
|
||||
ColorHelper.applyAlpha(textColor, 1 - indexDiff));
|
||||
ColorHelper.applyAlpha(Theme.i(Theme.Key.TEXT), 1 - indexDiff));
|
||||
ms.pop();
|
||||
|
||||
if (chapter != null) {
|
||||
ms.push();
|
||||
|
||||
ms.translate(chap.x - 4 - 4, chap.y, 0);
|
||||
UIRenderHelper.streak(ms, 180, 4, 10, 26, (int) (150 * fade), 0x101010);
|
||||
UIRenderHelper.streak(ms, 180, 4, 10, 26, (int) (150 * fade));
|
||||
|
||||
drawRightAlignedString(textRenderer, ms, Lang.translate(IN_CHAPTER)
|
||||
.getString(), 0, 0, tooltipColor);
|
||||
drawRightAlignedString(textRenderer, ms, Lang.translate(LANG_PREFIX + "chapter." + chapter.getId())
|
||||
.getString(), 0, 12, 0xffeeeeee);
|
||||
drawRightAlignedString(textRenderer, ms, Lang.translate(IN_CHAPTER).getString(), 0, 0, tooltipColor);
|
||||
drawRightAlignedString(textRenderer, ms,
|
||||
Lang.translate(LANG_PREFIX + "chapter." + chapter.getId()).getString(), 0, 12, Theme.i(Theme.Key.TEXT));
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -590,29 +606,24 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
ms.push();
|
||||
ms.translate(mouseX, mouseY, 100);
|
||||
if (hoveredTooltipItem.isEmpty()) {
|
||||
IFormattableTextComponent text = Lang
|
||||
.translate(IDENTIFY_MODE,
|
||||
((IFormattableTextComponent) client.gameSettings.keyBindDrop.getBoundKeyLocalizedText())
|
||||
.formatted(TextFormatting.WHITE))
|
||||
.formatted(TextFormatting.GRAY);
|
||||
IFormattableTextComponent text = Lang.translate(
|
||||
IDENTIFY_MODE,
|
||||
((IFormattableTextComponent) client.gameSettings.keyBindDrop.getBoundKeyLocalizedText()).formatted(TextFormatting.WHITE)
|
||||
).formatted(TextFormatting.GRAY);
|
||||
|
||||
// renderOrderedTooltip(ms, textRenderer.wrapLines(text, width / 3), 0, 0);
|
||||
renderWrappedToolTip(ms, textRenderer.getTextHandler()
|
||||
.wrapLines(text, width / 3, Style.EMPTY), 0, 0, textRenderer);
|
||||
/*
|
||||
* String tooltip = Lang
|
||||
* .createTranslationTextComponent(IDENTIFY_MODE, client.gameSettings.keyBindDrop.getBoundKeyLocalizedText().applyTextStyle(TextFormatting.WHITE))
|
||||
* .applyTextStyle(TextFormatting.GRAY)
|
||||
* .getFormattedText();
|
||||
* renderTooltip(font.listFormattedStringToWidth(tooltip, width / 3), 0, 0);
|
||||
*/
|
||||
//renderOrderedTooltip(ms, textRenderer.wrapLines(text, width / 3), 0, 0);
|
||||
renderWrappedToolTip(ms, textRenderer.getTextHandler().wrapLines(text, width / 3, Style.EMPTY), 0, 0, textRenderer);
|
||||
/*String tooltip = Lang
|
||||
.createTranslationTextComponent(IDENTIFY_MODE, client.gameSettings.keyBindDrop.getBoundKeyLocalizedText().applyTextStyle(TextFormatting.WHITE))
|
||||
.applyTextStyle(TextFormatting.GRAY)
|
||||
.getFormattedText();
|
||||
renderTooltip(font.listFormattedStringToWidth(tooltip, width / 3), 0, 0);*/
|
||||
} else
|
||||
renderTooltip(ms, hoveredTooltipItem, 0, 0);
|
||||
if (hoveredBlockPos != null && PonderIndex.EDITOR_MODE && !userViewMode) {
|
||||
ms.translate(0, -15, 0);
|
||||
boolean copied = copiedBlockPos != null && hoveredBlockPos.equals(copiedBlockPos);
|
||||
IFormattableTextComponent coords = new StringTextComponent(
|
||||
hoveredBlockPos.getX() + ", " + hoveredBlockPos.getY() + ", " + hoveredBlockPos.getZ())
|
||||
IFormattableTextComponent coords = new StringTextComponent(hoveredBlockPos.getX() + ", " + hoveredBlockPos.getY() + ", " + hoveredBlockPos.getZ())
|
||||
.formatted(copied ? TextFormatting.GREEN : TextFormatting.GOLD);
|
||||
renderTooltip(ms, coords, 0, 0);
|
||||
}
|
||||
|
@ -649,15 +660,14 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
// Widgets
|
||||
widgets.forEach(w -> {
|
||||
if (w instanceof PonderButton) {
|
||||
PonderButton mtdButton = (PonderButton) w;
|
||||
mtdButton.fade(fade);
|
||||
((PonderButton) w).fade().startWithValue(fade);
|
||||
}
|
||||
});
|
||||
|
||||
if (index == 0 || index == 1 && lazyIndexValue < index)
|
||||
left.fade(lazyIndexValue);
|
||||
left.fade().startWithValue(lazyIndexValue);
|
||||
if (index == scenes.size() - 1 || index == scenes.size() - 2 && lazyIndexValue > index)
|
||||
right.fade(scenes.size() - lazyIndexValue - 1);
|
||||
right.fade().startWithValue(scenes.size() - lazyIndexValue - 1);
|
||||
|
||||
boolean finished = activeScene.isFinished();
|
||||
if (finished)
|
||||
|
@ -693,14 +703,14 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
ms.translate(x, y + 5 * (1 - fade), 800);
|
||||
|
||||
float fadedWidth = 200 * chase.getValue(partialTicks);
|
||||
UIRenderHelper.streak(ms, 0, 0, 12, 26, (int) fadedWidth, 0x101010);
|
||||
UIRenderHelper.streak(ms, 0, 0, 12, 26, (int) fadedWidth);
|
||||
|
||||
GL11.glScissor((int) (x * s), 0, (int) (fadedWidth * s), (int) (height * s));
|
||||
GL11.glEnable(GL11.GL_SCISSOR_TEST);
|
||||
|
||||
String tagName = this.tags.get(i)
|
||||
.getTitle();
|
||||
textRenderer.draw(ms, tagName, 3, 8, 0xffeedd);
|
||||
textRenderer.draw(ms, tagName, 3, 8, Theme.i(Theme.Key.TEXT_ACCENT_SLIGHT));
|
||||
|
||||
GL11.glDisable(GL11.GL_SCISSOR_TEST);
|
||||
|
||||
|
@ -727,24 +737,6 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
ms.pop();
|
||||
}
|
||||
|
||||
protected void lowerButtonGroup(MatrixStack ms, int index, int mouseX, int mouseY, float fade, AllIcons icon,
|
||||
KeyBinding key) {
|
||||
int bWidth = 20;
|
||||
int bHeight = 20;
|
||||
int bX = (width - bWidth) / 2 + (index - 1) * (bWidth + 8);
|
||||
int bY = height - bHeight - 31;
|
||||
|
||||
ms.push();
|
||||
if (fade < fadeIn.getChaseTarget())
|
||||
ms.translate(0, (1 - fade) * 5, 0);
|
||||
boolean hovered = isMouseOver(mouseX, mouseY, bX, bY, bWidth, bHeight);
|
||||
renderBox(ms, bX, bY, bWidth, bHeight, hovered);
|
||||
icon.draw(ms, bX + 2, bY + 2);
|
||||
drawCenteredText(ms, textRenderer, key.getBoundKeyLocalizedText(), bX + bWidth / 2 + 8, bY + bHeight - 6,
|
||||
0xff606060);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
private void renderOverlay(MatrixStack ms, int i, float partialTicks) {
|
||||
if (identifyMode)
|
||||
return;
|
||||
|
@ -756,23 +748,6 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
|
||||
@Override
|
||||
public boolean mouseClicked(double x, double y, int button) {
|
||||
MutableBoolean handled = new MutableBoolean(false);
|
||||
widgets.forEach(w -> {
|
||||
if (handled.booleanValue())
|
||||
return;
|
||||
if (!w.isMouseOver(x, y))
|
||||
return;
|
||||
if (w instanceof PonderButton) {
|
||||
PonderButton mtdButton = (PonderButton) w;
|
||||
mtdButton.runCallback(x, y);
|
||||
handled.setTrue();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (handled.booleanValue())
|
||||
return true;
|
||||
|
||||
if (identifyMode && hoveredBlockPos != null && PonderIndex.EDITOR_MODE) {
|
||||
long handle = client.getWindow()
|
||||
.getHandle();
|
||||
|
@ -843,8 +818,8 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
.getString();
|
||||
|
||||
return stack.getItem()
|
||||
.getName()
|
||||
.getString();
|
||||
.getName()
|
||||
.getString();
|
||||
}
|
||||
|
||||
public FontRenderer getFontRenderer() {
|
||||
|
@ -857,13 +832,8 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
return hovered;
|
||||
}
|
||||
|
||||
public static void renderBox(MatrixStack ms, int x, int y, int w, int h, boolean highlighted) {
|
||||
renderBox(ms, x, y, w, h, 0xff000000, highlighted ? 0xf0ffeedd : 0x40ffeedd,
|
||||
highlighted ? 0x60ffeedd : 0x20ffeedd);
|
||||
}
|
||||
|
||||
public static void renderSpeechBox(MatrixStack ms, int x, int y, int w, int h, boolean highlighted,
|
||||
Pointing pointing, boolean returnWithLocalTransform) {
|
||||
public static void renderSpeechBox(MatrixStack ms, int x, int y, int w, int h, boolean highlighted, Pointing pointing,
|
||||
boolean returnWithLocalTransform) {
|
||||
if (!returnWithLocalTransform)
|
||||
ms.push();
|
||||
|
||||
|
@ -875,6 +845,8 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
int divotSize = 8;
|
||||
int distance = 1;
|
||||
int divotRadius = divotSize / 2;
|
||||
Couple<Color> borderColors = Theme.p(highlighted ? Theme.Key.PONDER_HIGHLIGHT : Theme.Key.PONDER_IDLE);
|
||||
Color c;
|
||||
|
||||
switch (pointing) {
|
||||
default:
|
||||
|
@ -884,6 +856,7 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
boxY -= h + divotSize + 1 + distance;
|
||||
divotX -= divotRadius;
|
||||
divotY -= divotSize + distance;
|
||||
c = borderColors.getSecond();
|
||||
break;
|
||||
case LEFT:
|
||||
divotRotation = 90;
|
||||
|
@ -891,6 +864,7 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
boxY -= h / 2;
|
||||
divotX += distance;
|
||||
divotY -= divotRadius;
|
||||
c = ColorHelper.mixColors(borderColors, 0.5f);
|
||||
break;
|
||||
case RIGHT:
|
||||
divotRotation = 270;
|
||||
|
@ -898,6 +872,7 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
boxY -= h / 2;
|
||||
divotX -= divotSize + distance;
|
||||
divotY -= divotRadius;
|
||||
c = ColorHelper.mixColors(borderColors, 0.5f);
|
||||
break;
|
||||
case UP:
|
||||
divotRotation = 180;
|
||||
|
@ -905,17 +880,23 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
boxY += divotSize + 1 + distance;
|
||||
divotX -= divotRadius;
|
||||
divotY += distance;
|
||||
c = borderColors.getFirst();
|
||||
break;
|
||||
}
|
||||
|
||||
renderBox(ms, boxX, boxY, w, h, highlighted);
|
||||
new BoxElement()
|
||||
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(borderColors)
|
||||
.at(boxX, boxY, 100)
|
||||
.withBounds(w, h)
|
||||
.render(ms);
|
||||
|
||||
ms.push();
|
||||
AllGuiTextures toRender = highlighted ? AllGuiTextures.SPEECH_TOOLTIP_HIGHLIGHT : AllGuiTextures.SPEECH_TOOLTIP;
|
||||
ms.translate(divotX + divotRadius, divotY + divotRadius, 10);
|
||||
ms.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(divotRotation));
|
||||
ms.translate(-divotRadius, -divotRadius, 0);
|
||||
toRender.draw(ms, 0, 0);
|
||||
AllGuiTextures.SPEECH_TOOLTIP_BACKGROUND.draw(ms, 0, 0);
|
||||
AllGuiTextures.SPEECH_TOOLTIP_COLOR.draw(ms, 0, 0, c);
|
||||
ms.pop();
|
||||
|
||||
if (returnWithLocalTransform) {
|
||||
|
@ -927,24 +908,6 @@ public class PonderUI extends NavigatableSimiScreen {
|
|||
|
||||
}
|
||||
|
||||
public static void renderBox(MatrixStack ms, int x, int y, int w, int h, int backgroundColor, int borderColorStart,
|
||||
int borderColorEnd) {
|
||||
int z = 100;
|
||||
Matrix4f model = ms.peek()
|
||||
.getModel();
|
||||
GuiUtils.drawGradientRect(model, z, x - 3, y - 4, x + w + 3, y - 3, backgroundColor, backgroundColor);
|
||||
GuiUtils.drawGradientRect(model, z, x - 3, y + h + 3, x + w + 3, y + h + 4, backgroundColor, backgroundColor);
|
||||
GuiUtils.drawGradientRect(model, z, x - 3, y - 3, x + w + 3, y + h + 3, backgroundColor, backgroundColor);
|
||||
GuiUtils.drawGradientRect(model, z, x - 4, y - 3, x - 3, y + h + 3, backgroundColor, backgroundColor);
|
||||
GuiUtils.drawGradientRect(model, z, x + w + 3, y - 3, x + w + 4, y + h + 3, backgroundColor, backgroundColor);
|
||||
GuiUtils.drawGradientRect(model, z, x - 3, y - 3 + 1, x - 3 + 1, y + h + 3 - 1, borderColorStart,
|
||||
borderColorEnd);
|
||||
GuiUtils.drawGradientRect(model, z, x + w + 2, y - 3 + 1, x + w + 3, y + h + 3 - 1, borderColorStart,
|
||||
borderColorEnd);
|
||||
GuiUtils.drawGradientRect(model, z, x - 3, y - 3, x + w + 3, y - 3 + 1, borderColorStart, borderColorStart);
|
||||
GuiUtils.drawGradientRect(model, z, x - 3, y + h + 2, x + w + 3, y + h + 3, borderColorEnd, borderColorEnd);
|
||||
}
|
||||
|
||||
public ItemStack getHoveredTooltipItem() {
|
||||
return hoveredTooltipItem;
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
|||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.crank.ValveHandleBlock;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.ponder.NavigatableSimiScreen;
|
||||
import com.simibubi.create.foundation.ponder.PonderRegistry;
|
||||
|
@ -106,17 +107,17 @@ public class PonderIndexScreen extends NavigatableSimiScreen {
|
|||
int itemCenterY = (int) (height * itemYmult);
|
||||
|
||||
for (Item item : items) {
|
||||
PonderButton button =
|
||||
new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4, (x, y) -> {
|
||||
if (!PonderRegistry.all.containsKey(item.getRegistryName()))
|
||||
return;
|
||||
PonderButton b = new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4)
|
||||
.showing(new ItemStack(item))
|
||||
.withCallback((x, y) -> {
|
||||
if (!PonderRegistry.all.containsKey(item.getRegistryName()))
|
||||
return;
|
||||
|
||||
centerScalingOn(x, y);
|
||||
ScreenOpener.transitionTo(PonderUI.of(new ItemStack(item)));
|
||||
}).showing(new ItemStack(item));
|
||||
centerScalingOn(x, y);
|
||||
ScreenOpener.transitionTo(PonderUI.of(new ItemStack(item)));
|
||||
});
|
||||
|
||||
button.fade(1);
|
||||
widgets.add(button);
|
||||
widgets.add(b);
|
||||
layout.next();
|
||||
}
|
||||
|
||||
|
@ -158,8 +159,8 @@ public class PonderIndexScreen extends NavigatableSimiScreen {
|
|||
ms.push();
|
||||
ms.translate(x, y, 0);
|
||||
|
||||
UIRenderHelper.streak(ms, 0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220, 0x101010);
|
||||
textRenderer.draw(ms, "Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, 0xffddeeff);
|
||||
UIRenderHelper.streak(ms, 0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220);
|
||||
textRenderer.draw(ms, "Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, Theme.i(Theme.Key.TEXT));
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -170,8 +171,8 @@ public class PonderIndexScreen extends NavigatableSimiScreen {
|
|||
ms.push();
|
||||
ms.translate(x, y, 0);
|
||||
|
||||
UIRenderHelper.streak(ms, 0, itemArea.getX() - 10, itemArea.getY() - 20, 20, 220, 0x101010);
|
||||
textRenderer.draw(ms, "Items to inspect", itemArea.getX() - 5, itemArea.getY() - 25, 0xffddeeff);
|
||||
UIRenderHelper.streak(ms, 0, itemArea.getX() - 10, itemArea.getY() - 20, 20, 220);
|
||||
textRenderer.draw(ms, "Items to inspect", itemArea.getX() - 5, itemArea.getY() - 25, Theme.i(Theme.Key.TEXT));
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -189,7 +190,7 @@ public class PonderIndexScreen extends NavigatableSimiScreen {
|
|||
ms.pop();
|
||||
}
|
||||
|
||||
@Override
|
||||
/*@Override
|
||||
public boolean mouseClicked(double x, double y, int button) {
|
||||
MutableBoolean handled = new MutableBoolean(false);
|
||||
widgets.forEach(w -> {
|
||||
|
@ -207,7 +208,7 @@ public class PonderIndexScreen extends NavigatableSimiScreen {
|
|||
if (handled.booleanValue())
|
||||
return true;
|
||||
return super.mouseClicked(x, y, button);
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public boolean isEquivalentTo(NavigatableSimiScreen other) {
|
||||
|
|
|
@ -9,7 +9,9 @@ import org.apache.commons.lang3.mutable.MutableBoolean;
|
|||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.gui.BoxElement;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.ponder.NavigatableSimiScreen;
|
||||
import com.simibubi.create.foundation.ponder.PonderLocalization;
|
||||
|
@ -84,24 +86,26 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
int itemCenterY = getItemsY();
|
||||
|
||||
for (Item i : items) {
|
||||
final boolean canClick = PonderRegistry.all.containsKey(i.getRegistryName());
|
||||
PonderButton button =
|
||||
new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4, (mouseX, mouseY) -> {
|
||||
if (!canClick)
|
||||
return;
|
||||
PonderButton b = new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4)
|
||||
.showing(new ItemStack(i));
|
||||
|
||||
if (PonderRegistry.all.containsKey(i.getRegistryName())) {
|
||||
b.withCallback((mouseX, mouseY) -> {
|
||||
centerScalingOn(mouseX, mouseY);
|
||||
ScreenOpener.transitionTo(PonderUI.of(new ItemStack(i), tag));
|
||||
}).showing(new ItemStack(i));
|
||||
if (!canClick)
|
||||
});
|
||||
} else {
|
||||
if (i.getRegistryName()
|
||||
.getNamespace()
|
||||
.equals(Create.ID))
|
||||
button.customColors(0x70984500, 0x70692400);
|
||||
.getNamespace()
|
||||
.equals(Create.ID))
|
||||
b.withBorderColors(Theme.p(Theme.Key.PONDER_MISSING_CREATE))
|
||||
.animateColors(false);
|
||||
else
|
||||
button.customColors(0x505000FF, 0x50300077);
|
||||
b.withBorderColors(Theme.p(Theme.Key.PONDER_MISSING_VANILLA))
|
||||
.animateColors(false);
|
||||
}
|
||||
|
||||
button.fade(1);
|
||||
widgets.add(button);
|
||||
widgets.add(b);
|
||||
layout.next();
|
||||
}
|
||||
|
||||
|
@ -109,23 +113,26 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
ResourceLocation registryName = tag.getMainItem()
|
||||
.getItem()
|
||||
.getRegistryName();
|
||||
final boolean canClick = PonderRegistry.all.containsKey(registryName);
|
||||
PonderButton button =
|
||||
new PonderButton(itemCenterX - layout.getTotalWidth() / 2 - 42, itemCenterY - 10, (mouseX, mouseY) -> {
|
||||
if (!canClick)
|
||||
return;
|
||||
centerScalingOn(mouseX, mouseY);
|
||||
ScreenOpener.transitionTo(PonderUI.of(tag.getMainItem(), tag));
|
||||
}).showing(tag.getMainItem());
|
||||
if (!canClick)
|
||||
|
||||
PonderButton b = new PonderButton(itemCenterX - layout.getTotalWidth() / 2 - 42, itemCenterY - 10)
|
||||
.showing(tag.getMainItem());
|
||||
|
||||
if (PonderRegistry.all.containsKey(registryName)) {
|
||||
b.withCallback((mouseX, mouseY) -> {
|
||||
centerScalingOn(mouseX, mouseY);
|
||||
ScreenOpener.transitionTo(PonderUI.of(tag.getMainItem(), tag));
|
||||
});
|
||||
} else {
|
||||
if (registryName.getNamespace()
|
||||
.equals(Create.ID))
|
||||
button.customColors(0x70984500, 0x70692400);
|
||||
b.withBorderColors(Theme.p(Theme.Key.PONDER_MISSING_CREATE))
|
||||
.animateColors(false);
|
||||
else
|
||||
button.customColors(0x505000FF, 0x50300077);
|
||||
b.withBorderColors(Theme.p(Theme.Key.PONDER_MISSING_VANILLA))
|
||||
.animateColors(false);
|
||||
}
|
||||
|
||||
button.fade(1);
|
||||
widgets.add(button);
|
||||
widgets.add(b);
|
||||
}
|
||||
|
||||
// chapters
|
||||
|
@ -187,15 +194,21 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
String title = tag.getTitle();
|
||||
|
||||
int streakHeight = 35;
|
||||
UIRenderHelper.streak(ms, 0, x - 4, y - 12 + streakHeight / 2, streakHeight, 240, 0x101010);
|
||||
PonderUI.renderBox(ms, 21, 21, 30, 30, false);
|
||||
UIRenderHelper.streak(ms, 0, x - 4, y - 12 + streakHeight / 2, streakHeight, 240);
|
||||
//PonderUI.renderBox(ms, 21, 21, 30, 30, false);
|
||||
new BoxElement()
|
||||
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
|
||||
.at(21, 21, 100)
|
||||
.withBounds(30, 30)
|
||||
.render(ms);
|
||||
|
||||
textRenderer.draw(ms, Lang.translate(PonderUI.PONDERING), x, y - 6, 0xffa3a3a3);
|
||||
textRenderer.draw(ms, Lang.translate(PonderUI.PONDERING), x, y - 6, Theme.i(Theme.Key.TEXT_DARKER));
|
||||
y += 8;
|
||||
x += 0;
|
||||
ms.translate(x, y, 0);
|
||||
ms.translate(0, 0, 5);
|
||||
textRenderer.draw(ms, title, 0, 0, 0xeeeeee);
|
||||
textRenderer.draw(ms, title, 0, 0, Theme.i(Theme.Key.TEXT));
|
||||
ms.pop();
|
||||
|
||||
ms.push();
|
||||
|
@ -214,9 +227,16 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
int h = textRenderer.getWordWrappedHeight(desc, w);
|
||||
|
||||
|
||||
PonderUI.renderBox(ms, x - 3, y - 3, w + 6, h + 6, false);
|
||||
//PonderUI.renderBox(ms, x - 3, y - 3, w + 6, h + 6, false);
|
||||
new BoxElement()
|
||||
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
|
||||
.at(x - 3, y - 3, 90)
|
||||
.withBounds(w + 6, h + 6)
|
||||
.render(ms);
|
||||
|
||||
ms.translate(0, 0, 100);
|
||||
FontHelper.drawSplitString(ms, textRenderer, desc, x, y, w, 0xeeeeee);
|
||||
FontHelper.drawSplitString(ms, textRenderer, desc, x, y, w, Theme.i(Theme.Key.TEXT));
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
|
@ -232,16 +252,23 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
|
||||
ms.push();
|
||||
ms.translate(x, y, 0);
|
||||
PonderUI.renderBox(ms, (sWidth - stringWidth) / 2 - 5, itemArea.getY() - 21, stringWidth + 10, 10, false);
|
||||
//PonderUI.renderBox(ms, (sWidth - stringWidth) / 2 - 5, itemArea.getY() - 21, stringWidth + 10, 10, false);
|
||||
new BoxElement()
|
||||
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.PONDER_IDLE))
|
||||
.at((sWidth - stringWidth) / 2f - 5, itemArea.getY() - 21, 100)
|
||||
.withBounds(stringWidth + 10, 10)
|
||||
.render(ms);
|
||||
|
||||
ms.translate(0, 0, 200);
|
||||
|
||||
// UIRenderHelper.streak(0, itemArea.getX() - 10, itemArea.getY() - 20, 20, 180, 0x101010);
|
||||
drawCenteredString(ms, textRenderer, relatedTitle, sWidth / 2, itemArea.getY() - 20, 0xeeeeee);
|
||||
drawCenteredString(ms, textRenderer, relatedTitle, sWidth / 2, itemArea.getY() - 20, Theme.i(Theme.Key.TEXT));
|
||||
|
||||
ms.translate(0,0, -200);
|
||||
|
||||
UIRenderHelper.streak(ms, 0, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth() / 2 + 75, 0x101010);
|
||||
UIRenderHelper.streak(ms, 180, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth() / 2 + 75, 0x101010);
|
||||
UIRenderHelper.streak(ms, 0, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth() / 2 + 75);
|
||||
UIRenderHelper.streak(ms, 180, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth() / 2 + 75);
|
||||
|
||||
ms.pop();
|
||||
|
||||
|
@ -261,8 +288,8 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
ms.push();
|
||||
ms.translate(chapterX, chapterY, 0);
|
||||
|
||||
UIRenderHelper.streak(ms, 0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220, 0x101010);
|
||||
textRenderer.draw(ms, "More Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, 0xffddeeff);
|
||||
UIRenderHelper.streak(ms, 0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220);
|
||||
textRenderer.draw(ms, "More Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, Theme.i(Theme.Key.TEXT_ACCENT_SLIGHT));
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
@ -291,7 +318,7 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
return hoveredItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
/*@Override
|
||||
public boolean mouseClicked(double x, double y, int button) {
|
||||
MutableBoolean handled = new MutableBoolean(false);
|
||||
widgets.forEach(w -> {
|
||||
|
@ -310,7 +337,7 @@ public class PonderTagScreen extends NavigatableSimiScreen {
|
|||
if (handled.booleanValue())
|
||||
return true;
|
||||
return super.mouseClicked(x, y, button);
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public boolean isEquivalentTo(NavigatableSimiScreen other) {
|
||||
|
|
|
@ -136,7 +136,7 @@ public class InputWindowElement extends AnimatedOverlayElement {
|
|||
|
||||
if (hasItem) {
|
||||
GuiGameElement.of(item)
|
||||
.at(keyWidth + (hasIcon ? 24 : 0), 0)
|
||||
.<GuiGameElement.GuiRenderBuilder>at(keyWidth + (hasIcon ? 24 : 0), 0)
|
||||
.scale(1.5)
|
||||
.render(ms);
|
||||
RenderSystem.disableDepthTest();
|
||||
|
|
|
@ -4,6 +4,8 @@ import java.util.List;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.BoxElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.ponder.PonderLocalization;
|
||||
import com.simibubi.create.foundation.ponder.PonderScene;
|
||||
import com.simibubi.create.foundation.ponder.PonderUI;
|
||||
|
@ -110,7 +112,14 @@ public class TextWindowElement extends AnimatedOverlayElement {
|
|||
ms.push();
|
||||
ms.translate(0, sceneToScreen.y, 400);
|
||||
|
||||
PonderUI.renderBox(ms, targetX - 10, 3, boxWidth, boxHeight - 1, 0xaa000000, 0x30eebb00, 0x10eebb00);
|
||||
new BoxElement()
|
||||
.withBackground(Theme.c(Theme.Key.PONDER_BACKGROUND_FLAT))
|
||||
.gradientBorder(Theme.p(Theme.Key.TEXT_WINDOW_BORDER))
|
||||
.at(targetX - 10, 3, 100)
|
||||
.withBounds(boxWidth, boxHeight - 1)
|
||||
.render(ms);
|
||||
|
||||
//PonderUI.renderBox(ms, targetX - 10, 3, boxWidth, boxHeight - 1, 0xaa000000, 0x30eebb00, 0x10eebb00);
|
||||
|
||||
int brighterColor = ColorHelper.mixAlphaColors(color, 0xFFffffdd, 1 / 2f);
|
||||
if (vec != null) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.function.BiConsumer;
|
|||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.UIRenderHelper;
|
||||
import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget;
|
||||
import com.simibubi.create.foundation.ponder.content.PonderChapter;
|
||||
|
@ -20,17 +21,18 @@ public class ChapterLabel extends AbstractSimiWidget {
|
|||
public ChapterLabel(PonderChapter chapter, int x, int y, BiConsumer<Integer, Integer> onClick) {
|
||||
super(x, y, 175, 38);
|
||||
|
||||
this.button = new PonderButton(x + 4, y + 4, onClick, 30, 30).showing(chapter);
|
||||
this.button.fade(1);
|
||||
this.button = new PonderButton(x + 4, y + 4, 30, 30)
|
||||
.showing(chapter)
|
||||
.withCallback(onClick);
|
||||
|
||||
this.chapter = chapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
UIRenderHelper.streak(ms, 0, x, y + height / 2, height - 2, width, 0x101010);
|
||||
UIRenderHelper.streak(ms, 0, x, y + height / 2, height - 2, width);
|
||||
Minecraft.getInstance().fontRenderer.draw(ms, Lang.translate("ponder.chapter." + chapter.getId()), x + 50,
|
||||
y + 20, 0xffddeeff);
|
||||
y + 20, Theme.i(Theme.Key.TEXT_ACCENT_SLIGHT));
|
||||
|
||||
button.renderButton(ms, mouseX, mouseY, partialTicks);
|
||||
super.render(ms, mouseX, mouseY, partialTicks);
|
||||
|
|
|
@ -1,175 +1,105 @@
|
|||
package com.simibubi.create.foundation.ponder.ui;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
import java.awt.Color;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.simibubi.create.foundation.gui.GuiGameElement;
|
||||
import com.simibubi.create.foundation.gui.IScreenRenderable;
|
||||
import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget;
|
||||
import com.simibubi.create.foundation.ponder.PonderUI;
|
||||
import com.simibubi.create.foundation.gui.RenderElement;
|
||||
import com.simibubi.create.foundation.gui.Theme;
|
||||
import com.simibubi.create.foundation.gui.widgets.BoxWidget;
|
||||
import com.simibubi.create.foundation.gui.widgets.ElementWidget;
|
||||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
import com.simibubi.create.foundation.utility.Couple;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.settings.KeyBinding;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class PonderButton extends AbstractSimiWidget {
|
||||
public class PonderButton extends BoxWidget {
|
||||
|
||||
private IScreenRenderable icon;
|
||||
private ItemStack item;
|
||||
protected boolean pressed;
|
||||
private BiConsumer<Integer, Integer> onClick;
|
||||
private int xFadeModifier;
|
||||
private int yFadeModifier;
|
||||
private float fade;
|
||||
private KeyBinding shortcut;
|
||||
private LerpedFloat flash;
|
||||
private Couple<Integer> customPassiveBorder;
|
||||
protected ItemStack item;
|
||||
protected KeyBinding shortcut;
|
||||
protected LerpedFloat flash = LerpedFloat.linear().startWithValue(0).chase(0, 0.1f, LerpedFloat.Chaser.EXP);
|
||||
|
||||
public static final int SIZE = 20;
|
||||
public PonderButton(int x, int y) {
|
||||
this(x, y, 20, 20);
|
||||
}
|
||||
|
||||
public PonderButton(int x, int y, BiConsumer<Integer, Integer> onClick, int width, int height) {
|
||||
public PonderButton(int x, int y, int width, int height) {
|
||||
super(x, y, width, height);
|
||||
this.onClick = onClick;
|
||||
flash = LerpedFloat.linear()
|
||||
.startWithValue(0);
|
||||
z = 400;
|
||||
paddingX = 2;
|
||||
paddingY = 2;
|
||||
}
|
||||
|
||||
public PonderButton(int x, int y, BiConsumer<Integer, Integer> onClick) {
|
||||
this(x, y, onClick, SIZE, SIZE);
|
||||
}
|
||||
|
||||
public PonderButton(int x, int y, Runnable onClick) {
|
||||
this(x, y, ($, $$) -> onClick.run());
|
||||
}
|
||||
|
||||
public PonderButton showing(IScreenRenderable icon) {
|
||||
this.icon = icon;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PonderButton showing(ItemStack item) {
|
||||
this.item = item;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PonderButton customColors(int start, int end) {
|
||||
this.customPassiveBorder = Couple.create(start, end);
|
||||
return this;
|
||||
}
|
||||
|
||||
public PonderButton shortcut(KeyBinding key) {
|
||||
public <T extends PonderButton> T withShortcut(KeyBinding key) {
|
||||
this.shortcut = key;
|
||||
return this;
|
||||
//noinspection unchecked
|
||||
return (T) this;
|
||||
}
|
||||
|
||||
public PonderButton fade(int xModifier, int yModifier) {
|
||||
this.xFadeModifier = xModifier;
|
||||
this.yFadeModifier = yModifier;
|
||||
return this;
|
||||
public <T extends PonderButton> T showing(ItemStack item) {
|
||||
this.item = item;
|
||||
return super.showingElement(GuiGameElement.of(item)
|
||||
.scale(1.5f)
|
||||
.at(-4, -4));
|
||||
}
|
||||
|
||||
public void fade(float fade) {
|
||||
this.fade = fade;
|
||||
@Override
|
||||
public <T extends ElementWidget> T showingElement(RenderElement element) {
|
||||
return super.showingElement(element);
|
||||
}
|
||||
|
||||
public void flash() {
|
||||
float value = flash.getValue();
|
||||
flash.setValue(value + (1 - value) * .2f);
|
||||
flash.updateChaseTarget(1);
|
||||
}
|
||||
|
||||
public void dim() {
|
||||
float value = flash.getValue();
|
||||
flash.setValue(value * .5f);
|
||||
flash.updateChaseTarget(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
if (!visible)
|
||||
return;
|
||||
if (fade < .1f)
|
||||
return;
|
||||
public void tick() {
|
||||
super.tick();
|
||||
flash.tickChaser();
|
||||
}
|
||||
|
||||
hovered = isMouseOver(mouseX, mouseY) && fade > .75f;
|
||||
|
||||
ms.push();
|
||||
RenderSystem.disableDepthTest();
|
||||
if (fade < 1)
|
||||
ms.translate((1 - fade) * -5 * xFadeModifier, (1 - fade) * -5 * yFadeModifier, 0);
|
||||
@Override
|
||||
protected void beforeRender(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
super.beforeRender(ms, mouseX, mouseY, partialTicks);
|
||||
|
||||
float flashValue = flash.getValue(partialTicks);
|
||||
if (flashValue > .1f)
|
||||
fade *= 3 * flashValue + Math.sin((PonderUI.ponderTicks + partialTicks) / 6);
|
||||
|
||||
int backgroundColor = ColorHelper.applyAlpha(0xdd000000, fade);
|
||||
int borderColorStart = customPassiveBorder != null ? customPassiveBorder.getFirst() : hovered ? 0x70ffffff : 0x40aa9999;
|
||||
int borderColorEnd = customPassiveBorder != null ? customPassiveBorder.getSecond() : hovered ? 0x30ffffff : 0x20aa9999;
|
||||
borderColorStart = ColorHelper.applyAlpha(borderColorStart, fade);
|
||||
borderColorEnd = ColorHelper.applyAlpha(borderColorEnd, fade);
|
||||
|
||||
ms.translate(0, 0, 400);
|
||||
PonderUI.renderBox(ms, x, y, width, height, backgroundColor, borderColorStart, borderColorEnd);
|
||||
ms.translate(0, 0, 100);
|
||||
|
||||
if (icon != null) {
|
||||
RenderSystem.enableBlend();
|
||||
RenderSystem.color4f(1, 1, 1, fade);
|
||||
ms.push();
|
||||
ms.translate(x + 2, y + 2, 0);
|
||||
ms.scale((width - 4) / 16f, (height - 4) / 16f, 1);
|
||||
icon.draw(ms, this, 0, 0);
|
||||
ms.pop();
|
||||
if (flashValue > .1f) {
|
||||
float sin = 0.5f + 0.5f * MathHelper.sin((AnimationTickHolder.getTicks(true) + partialTicks) / 6f);
|
||||
sin *= flashValue;
|
||||
Color c1 = gradientColor1;
|
||||
Color c2 = gradientColor2;
|
||||
Color nc1 = new Color(c1.getRed(), c1.getGreen(), c1.getBlue(), MathHelper.clamp(c1.getAlpha() + 50, 0, 255));
|
||||
Color nc2 = new Color(c2.getRed(), c2.getGreen(), c2.getBlue(), MathHelper.clamp(c2.getAlpha() + 50, 0, 255));
|
||||
gradientColor1 = ColorHelper.mixColors(c1, nc1, sin);
|
||||
gradientColor2 = ColorHelper.mixColors(c2, nc2, sin);
|
||||
}
|
||||
if (item != null) {
|
||||
ms.push();
|
||||
ms.translate(0, 0, -100);
|
||||
GuiGameElement.of(item)
|
||||
.at(x - 2, y - 2)
|
||||
.scale(1.5f)
|
||||
.render(ms);
|
||||
ms.pop();
|
||||
}
|
||||
if (shortcut != null)
|
||||
drawCenteredText(ms, Minecraft.getInstance().fontRenderer, shortcut.getBoundKeyLocalizedText(), x + width / 2 + 8,
|
||||
y + height - 6, ColorHelper.applyAlpha(0xff606060, fade));
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
public void runCallback(double mouseX, double mouseY) {
|
||||
onClick.accept((int) mouseX, (int) mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(double p_onClick_1_, double p_onClick_3_) {
|
||||
super.onClick(p_onClick_1_, p_onClick_3_);
|
||||
this.pressed = true;
|
||||
}
|
||||
public void renderButton(@Nonnull MatrixStack ms, int mouseX, int mouseY, float partialTicks) {
|
||||
super.renderButton(ms, mouseX, mouseY, partialTicks);
|
||||
float fadeValue = fade.getValue();
|
||||
|
||||
@Override
|
||||
public void onRelease(double p_onRelease_1_, double p_onRelease_3_) {
|
||||
super.onRelease(p_onRelease_1_, p_onRelease_3_);
|
||||
this.pressed = false;
|
||||
}
|
||||
if (fadeValue < .1f)
|
||||
return;
|
||||
|
||||
/*public void setToolTip(String text) {
|
||||
toolTip.clear();
|
||||
toolTip.add(text);
|
||||
}*/
|
||||
if (shortcut != null) {
|
||||
ms.translate(0, 0, z+50);
|
||||
drawCenteredText(ms, Minecraft.getInstance().fontRenderer, shortcut.getBoundKeyLocalizedText(), x + width / 2 + 8, y + height - 6, ColorHelper.applyAlpha(Theme.i(Theme.Key.TEXT_DARKER), fadeValue));
|
||||
}
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMouseOver(double x, double y) {
|
||||
double m = 4;
|
||||
x = Math.floor(x);
|
||||
y = Math.floor(y);
|
||||
return active && visible
|
||||
&& !(x < this.x - m || x > this.x + width + m - 1 || y < this.y - m || y > this.y + height + m - 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,20 +10,28 @@ import net.minecraft.world.IWorld;
|
|||
public class AnimationTickHolder {
|
||||
|
||||
private static int ticks;
|
||||
private static int paused_ticks;
|
||||
|
||||
public static void reset() {
|
||||
ticks = 0;
|
||||
paused_ticks = 0;
|
||||
}
|
||||
|
||||
public static void tick() {
|
||||
if (!Minecraft.getInstance()
|
||||
.isGamePaused()) {
|
||||
ticks = (ticks + 1) % 1_728_000; // wrap around every 24 hours so we maintain enough floating point precision
|
||||
} else {
|
||||
paused_ticks = (paused_ticks + 1) % 1_728_000;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getTicks() {
|
||||
return ticks;
|
||||
return getTicks(false);
|
||||
}
|
||||
|
||||
public static int getTicks(boolean includePaused) {
|
||||
return includePaused ? ticks + paused_ticks : ticks;
|
||||
}
|
||||
|
||||
public static float getRenderTime() {
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
@ -39,6 +42,10 @@ public class ColorHelper {
|
|||
return (color & 0xFFFFFF) | alphaChannel << 24;
|
||||
}
|
||||
|
||||
public static Color applyAlpha(Color c, float alpha) {
|
||||
return new Color(applyAlpha(c.getRGB(), alpha), true);
|
||||
}
|
||||
|
||||
public static int mixColors(int color1, int color2, float w) {
|
||||
int r1 = (color1 >> 16);
|
||||
int g1 = (color1 >> 8) & 0xFF;
|
||||
|
@ -52,6 +59,23 @@ public class ColorHelper {
|
|||
return color;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static Color mixColors(@Nonnull Color c1, @Nonnull Color c2, float w) {
|
||||
float[] cmp1 = c1.getRGBComponents(null);
|
||||
float[] cmp2 = c2.getRGBComponents(null);
|
||||
return new Color(
|
||||
cmp1[0] + (cmp2[0] - cmp1[0]) * w,
|
||||
cmp1[1] + (cmp2[1] - cmp1[1]) * w,
|
||||
cmp1[2] + (cmp2[2] - cmp1[2]) * w,
|
||||
cmp1[3] + (cmp2[3] - cmp1[3]) * w
|
||||
);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static Color mixColors(@Nonnull Couple<Color> colors, float w) {
|
||||
return mixColors(colors.getFirst(), colors.getSecond(), w);
|
||||
}
|
||||
|
||||
public static int mixAlphaColors(int color1, int color2, float w) {
|
||||
int a1 = (color1 >> 24);
|
||||
int r1 = (color1 >> 16) & 0xFF;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue