Skip to content

Commit 8fee80a

Browse files
M-W-Kghzdude
andauthored
Implement Toolbelt (#2493)
Co-authored-by: Ghzdude <44148655+ghzdude@users.noreply.github.com>
1 parent 400f1db commit 8fee80a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1985
-281
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package gregtech.api.items;
2+
3+
import net.minecraft.block.BlockCauldron;
4+
import net.minecraft.block.state.IBlockState;
5+
import net.minecraft.entity.player.EntityPlayer;
6+
import net.minecraft.item.ItemStack;
7+
import net.minecraft.nbt.NBTTagCompound;
8+
import net.minecraft.util.EnumActionResult;
9+
import net.minecraft.util.EnumFacing;
10+
import net.minecraft.util.EnumHand;
11+
import net.minecraft.util.math.BlockPos;
12+
import net.minecraft.world.World;
13+
import net.minecraftforge.common.util.Constants;
14+
15+
import org.jetbrains.annotations.NotNull;
16+
17+
public interface IDyeableItem {
18+
19+
String COLOR_KEY = "gt_color";
20+
21+
default boolean hasColor(ItemStack stack) {
22+
NBTTagCompound nbttagcompound = stack.getTagCompound();
23+
return nbttagcompound != null && nbttagcompound.hasKey(COLOR_KEY, Constants.NBT.TAG_INT);
24+
}
25+
26+
default int getColor(ItemStack stack) {
27+
NBTTagCompound nbttagcompound = stack.getTagCompound();
28+
if (nbttagcompound != null && nbttagcompound.hasKey(COLOR_KEY, Constants.NBT.TAG_INT)) {
29+
return nbttagcompound.getInteger(COLOR_KEY);
30+
}
31+
return getDefaultColor(stack);
32+
}
33+
34+
default int getDefaultColor(ItemStack stack) {
35+
return 0xFFFFFF;
36+
}
37+
38+
default void removeColor(ItemStack stack) {
39+
NBTTagCompound nbttagcompound = stack.getTagCompound();
40+
if (nbttagcompound != null && nbttagcompound.hasKey(COLOR_KEY)) {
41+
nbttagcompound.removeTag(COLOR_KEY);
42+
}
43+
}
44+
45+
default void setColor(ItemStack stack, int color) {
46+
NBTTagCompound nbttagcompound = stack.getTagCompound();
47+
if (nbttagcompound == null) {
48+
nbttagcompound = new NBTTagCompound();
49+
stack.setTagCompound(nbttagcompound);
50+
}
51+
nbttagcompound.setInteger(COLOR_KEY, color);
52+
}
53+
54+
default @NotNull EnumActionResult onItemUseFirst(@NotNull EntityPlayer player, @NotNull World world,
55+
@NotNull BlockPos pos, @NotNull EnumFacing side, float hitX,
56+
float hitY, float hitZ, @NotNull EnumHand hand) {
57+
ItemStack stack = player.getHeldItem(hand);
58+
if (this.hasColor(stack)) {
59+
IBlockState iblockstate = world.getBlockState(pos);
60+
if (iblockstate.getBlock() instanceof BlockCauldron cauldron) {
61+
int water = iblockstate.getValue(BlockCauldron.LEVEL);
62+
if (water > 0) {
63+
this.removeColor(stack);
64+
cauldron.setWaterLevel(world, pos, iblockstate, water - 1);
65+
return EnumActionResult.SUCCESS;
66+
}
67+
}
68+
}
69+
return EnumActionResult.PASS;
70+
}
71+
72+
/**
73+
* Controls whether the dyeing recipe simply removes the dyeable item from the crafting grid,
74+
* or calls {@link net.minecraftforge.common.ForgeHooks#getContainerItem(ItemStack)} on it.
75+
*/
76+
default boolean shouldGetContainerItem() {
77+
return true;
78+
}
79+
}

src/main/java/gregtech/api/items/toolitem/IGTTool.java

Lines changed: 104 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,12 @@
55
import gregtech.api.capability.GregtechCapabilities;
66
import gregtech.api.capability.impl.CombinedCapabilityProvider;
77
import gregtech.api.capability.impl.ElectricItem;
8-
import gregtech.api.gui.GuiTextures;
9-
import gregtech.api.gui.ModularUI;
10-
import gregtech.api.gui.widgets.ClickButtonWidget;
11-
import gregtech.api.gui.widgets.DynamicLabelWidget;
128
import gregtech.api.items.gui.ItemUIFactory;
13-
import gregtech.api.items.gui.PlayerInventoryHolder;
149
import gregtech.api.items.metaitem.ElectricStats;
1510
import gregtech.api.items.toolitem.aoe.AoESymmetrical;
1611
import gregtech.api.items.toolitem.behavior.IToolBehavior;
12+
import gregtech.api.mui.GTGuiTextures;
13+
import gregtech.api.mui.GTGuis;
1714
import gregtech.api.recipes.ModHandler;
1815
import gregtech.api.unification.OreDictUnifier;
1916
import gregtech.api.unification.material.Material;
@@ -63,6 +60,17 @@
6360
import appeng.api.implementations.items.IAEWrench;
6461
import buildcraft.api.tools.IToolWrench;
6562
import cofh.api.item.IToolHammer;
63+
import com.cleanroommc.modularui.api.drawable.IKey;
64+
import com.cleanroommc.modularui.api.widget.IWidget;
65+
import com.cleanroommc.modularui.factory.HandGuiData;
66+
import com.cleanroommc.modularui.factory.ItemGuiFactory;
67+
import com.cleanroommc.modularui.screen.ModularPanel;
68+
import com.cleanroommc.modularui.utils.Alignment;
69+
import com.cleanroommc.modularui.value.sync.IntSyncValue;
70+
import com.cleanroommc.modularui.value.sync.PanelSyncManager;
71+
import com.cleanroommc.modularui.widgets.ButtonWidget;
72+
import com.cleanroommc.modularui.widgets.TextWidget;
73+
import com.cleanroommc.modularui.widgets.layout.Flow;
6674
import com.enderio.core.common.interfaces.IOverlayRenderAware;
6775
import com.google.common.collect.HashMultimap;
6876
import com.google.common.collect.Multimap;
@@ -207,7 +215,7 @@ default ItemStack get(Material material) {
207215

208216
// Set behaviours
209217
NBTTagCompound behaviourTag = getBehaviorsTag(stack);
210-
getToolStats().getBehaviors().forEach(behavior -> behavior.addBehaviorNBT(stack, behaviourTag));
218+
getBehaviors(stack).forEach(behavior -> behavior.addBehaviorNBT(stack, behaviourTag));
211219

212220
if (aoeDefinition != AoESymmetrical.none()) {
213221
behaviourTag.setInteger(MAX_AOE_COLUMN_KEY, aoeDefinition.column);
@@ -409,14 +417,14 @@ default AoESymmetrical getAoEDefinition(ItemStack stack) {
409417
}
410418

411419
default boolean definition$hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) {
412-
getToolStats().getBehaviors().forEach(behavior -> behavior.hitEntity(stack, target, attacker));
420+
getBehaviors(stack).forEach(behavior -> behavior.hitEntity(stack, target, attacker));
413421
damageItem(stack, attacker, getToolStats().getToolDamagePerAttack(stack));
414422
return true;
415423
}
416424

417425
default boolean definition$onBlockStartBreak(ItemStack stack, BlockPos pos, EntityPlayer player) {
418426
if (player.world.isRemote) return false;
419-
getToolStats().getBehaviors().forEach(behavior -> behavior.onBlockStartBreak(stack, pos, player));
427+
getBehaviors(stack).forEach(behavior -> behavior.onBlockStartBreak(stack, pos, player));
420428

421429
if (!player.isSneaking()) {
422430
EntityPlayerMP playerMP = (EntityPlayerMP) player;
@@ -458,7 +466,7 @@ default AoESymmetrical getAoEDefinition(ItemStack stack) {
458466
default boolean definition$onBlockDestroyed(ItemStack stack, World worldIn, IBlockState state, BlockPos pos,
459467
EntityLivingBase entityLiving) {
460468
if (!worldIn.isRemote) {
461-
getToolStats().getBehaviors()
469+
getBehaviors(stack)
462470
.forEach(behavior -> behavior.onBlockDestroyed(stack, worldIn, state, pos, entityLiving));
463471

464472
if ((double) state.getBlockHardness(worldIn, pos) != 0.0D) {
@@ -522,7 +530,7 @@ default AoESymmetrical getAoEDefinition(ItemStack stack) {
522530

523531
default boolean definition$canDisableShield(ItemStack stack, ItemStack shield, EntityLivingBase entity,
524532
EntityLivingBase attacker) {
525-
return getToolStats().getBehaviors().stream()
533+
return getBehaviors(stack).stream()
526534
.anyMatch(behavior -> behavior.canDisableShield(stack, shield, entity, attacker));
527535
}
528536

@@ -570,7 +578,7 @@ default AoESymmetrical getAoEDefinition(ItemStack stack) {
570578
}
571579

572580
default boolean definition$onEntitySwing(EntityLivingBase entityLiving, ItemStack stack) {
573-
getToolStats().getBehaviors().forEach(behavior -> behavior.onEntitySwing(entityLiving, stack));
581+
getBehaviors(stack).forEach(behavior -> behavior.onEntitySwing(entityLiving, stack));
574582
return false;
575583
}
576584

@@ -622,7 +630,7 @@ default AoESymmetrical getAoEDefinition(ItemStack stack) {
622630
if (isElectric()) {
623631
providers.add(ElectricStats.createElectricItem(0L, getElectricTier()).createProvider(stack));
624632
}
625-
for (IToolBehavior behavior : getToolStats().getBehaviors()) {
633+
for (IToolBehavior behavior : getBehaviors(stack)) {
626634
ICapabilityProvider behaviorProvider = behavior.createProvider(stack, nbt);
627635
if (behaviorProvider != null) {
628636
providers.add(behaviorProvider);
@@ -633,10 +641,15 @@ default AoESymmetrical getAoEDefinition(ItemStack stack) {
633641
return new CombinedCapabilityProvider(providers);
634642
}
635643

644+
@NotNull
645+
default List<IToolBehavior> getBehaviors(ItemStack stack) {
646+
return getToolStats().getBehaviors();
647+
}
648+
636649
default EnumActionResult definition$onItemUseFirst(@NotNull EntityPlayer player, @NotNull World world,
637650
@NotNull BlockPos pos, @NotNull EnumFacing facing, float hitX,
638651
float hitY, float hitZ, @NotNull EnumHand hand) {
639-
for (IToolBehavior behavior : getToolStats().getBehaviors()) {
652+
for (IToolBehavior behavior : getBehaviors(player.getHeldItem(hand))) {
640653
if (behavior.onItemUseFirst(player, world, pos, facing, hitX, hitY, hitZ, hand) ==
641654
EnumActionResult.SUCCESS) {
642655
return EnumActionResult.SUCCESS;
@@ -648,8 +661,9 @@ default AoESymmetrical getAoEDefinition(ItemStack stack) {
648661

649662
default EnumActionResult definition$onItemUse(EntityPlayer player, World world, BlockPos pos, EnumHand hand,
650663
EnumFacing facing, float hitX, float hitY, float hitZ) {
651-
for (IToolBehavior behavior : getToolStats().getBehaviors()) {
652-
if (behavior.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ) == EnumActionResult.SUCCESS) {
664+
for (IToolBehavior behavior : getBehaviors(player.getHeldItem(hand))) {
665+
if (behavior.onItemUse(player, world, pos, hand, facing, hitX, hitY, hitZ) ==
666+
EnumActionResult.SUCCESS) {
653667
return EnumActionResult.SUCCESS;
654668
}
655669
}
@@ -662,12 +676,12 @@ default AoESymmetrical getAoEDefinition(ItemStack stack) {
662676
if (!world.isRemote) {
663677
// TODO: relocate to keybind action when keybind PR happens
664678
if (player.isSneaking() && getMaxAoEDefinition(stack) != AoESymmetrical.none()) {
665-
PlayerInventoryHolder.openHandItemUI(player, hand);
679+
ItemGuiFactory.INSTANCE.open((EntityPlayerMP) player, hand);
666680
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
667681
}
668682
}
669683

670-
for (IToolBehavior behavior : getToolStats().getBehaviors()) {
684+
for (IToolBehavior behavior : getBehaviors(stack)) {
671685
if (behavior.onItemRightClick(world, player, hand).getType() == EnumActionResult.SUCCESS) {
672686
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
673687
}
@@ -762,10 +776,10 @@ default AoESymmetrical getAoEDefinition(ItemStack stack) {
762776
tooltip.add(I18n.format("item.gt.tool.behavior.relocate_mining"));
763777
}
764778

765-
if (!addedBehaviorNewLine && !toolStats.getBehaviors().isEmpty()) {
779+
if (!addedBehaviorNewLine && !getBehaviors(stack).isEmpty()) {
766780
tooltip.add("");
767781
}
768-
toolStats.getBehaviors().forEach(behavior -> behavior.addInformation(stack, world, tooltip, flag));
782+
getBehaviors(stack).forEach(behavior -> behavior.addInformation(stack, world, tooltip, flag));
769783

770784
// unique tooltip
771785
String uniqueTooltip = "item.gt.tool." + getToolId() + ".tooltip";
@@ -878,6 +892,7 @@ default ModelResourceLocation getModelLocation() {
878892

879893
// Sound Playing
880894
default void playCraftingSound(EntityPlayer player, ItemStack stack) {
895+
stack = toolbeltPassthrough(stack);
881896
// player null check for things like auto-crafters
882897
if (ConfigHolder.client.toolCraftingSounds && getSound() != null && player != null) {
883898
if (canPlaySound(stack)) {
@@ -903,45 +918,76 @@ default void playSound(EntityPlayer player) {
903918
}
904919
}
905920

906-
default ModularUI createUI(PlayerInventoryHolder holder, EntityPlayer entityPlayer) {
907-
NBTTagCompound tag = getBehaviorsTag(holder.getCurrentItem());
908-
AoESymmetrical defaultDefinition = getMaxAoEDefinition(holder.getCurrentItem());
909-
return ModularUI.builder(GuiTextures.BORDERED_BACKGROUND, 120, 80)
910-
.label(6, 10, "item.gt.tool.aoe.columns")
911-
.label(49, 10, "item.gt.tool.aoe.rows")
912-
.label(79, 10, "item.gt.tool.aoe.layers")
913-
.widget(new ClickButtonWidget(15, 24, 20, 20, "+", data -> {
914-
AoESymmetrical.increaseColumn(tag, defaultDefinition);
915-
holder.markAsDirty();
916-
}))
917-
.widget(new ClickButtonWidget(15, 44, 20, 20, "-", data -> {
918-
AoESymmetrical.decreaseColumn(tag, defaultDefinition);
919-
holder.markAsDirty();
920-
}))
921-
.widget(new ClickButtonWidget(50, 24, 20, 20, "+", data -> {
922-
AoESymmetrical.increaseRow(tag, defaultDefinition);
923-
holder.markAsDirty();
924-
}))
925-
.widget(new ClickButtonWidget(50, 44, 20, 20, "-", data -> {
926-
AoESymmetrical.decreaseRow(tag, defaultDefinition);
927-
holder.markAsDirty();
928-
}))
929-
.widget(new ClickButtonWidget(85, 24, 20, 20, "+", data -> {
930-
AoESymmetrical.increaseLayer(tag, defaultDefinition);
931-
holder.markAsDirty();
932-
}))
933-
.widget(new ClickButtonWidget(85, 44, 20, 20, "-", data -> {
934-
AoESymmetrical.decreaseLayer(tag, defaultDefinition);
935-
holder.markAsDirty();
936-
}))
937-
.widget(new DynamicLabelWidget(23, 65, () -> Integer.toString(
938-
1 + 2 * AoESymmetrical.getColumn(getBehaviorsTag(holder.getCurrentItem()), defaultDefinition))))
939-
.widget(new DynamicLabelWidget(58, 65, () -> Integer.toString(
940-
1 + 2 * AoESymmetrical.getRow(getBehaviorsTag(holder.getCurrentItem()), defaultDefinition))))
941-
.widget(new DynamicLabelWidget(93, 65,
942-
() -> Integer.toString(1 +
943-
AoESymmetrical.getLayer(getBehaviorsTag(holder.getCurrentItem()), defaultDefinition))))
944-
.build(holder, entityPlayer);
921+
@Override
922+
default ModularPanel buildUI(HandGuiData guiData, PanelSyncManager manager) {
923+
final var usedStack = guiData.getUsedItemStack();
924+
final var behaviorsTag = getBehaviorsTag(usedStack);
925+
final var defaultDefinition = getMaxAoEDefinition(usedStack);
926+
927+
var columnValue = new IntSyncValue(
928+
() -> AoESymmetrical.getColumn(behaviorsTag, defaultDefinition),
929+
i -> AoESymmetrical.setColumn(behaviorsTag, i, defaultDefinition));
930+
var rowValue = new IntSyncValue(
931+
() -> AoESymmetrical.getRow(behaviorsTag, defaultDefinition),
932+
i -> AoESymmetrical.setRow(behaviorsTag, i, defaultDefinition));
933+
var layerValue = new IntSyncValue(
934+
() -> AoESymmetrical.getLayer(behaviorsTag, defaultDefinition),
935+
i -> AoESymmetrical.setLayer(behaviorsTag, i, defaultDefinition));
936+
937+
manager.syncValue("row_value", rowValue);
938+
manager.syncValue("column_value", columnValue);
939+
manager.syncValue("layer_value", layerValue);
940+
941+
return GTGuis.createPanel(usedStack.getTranslationKey(), 120, 80)
942+
.child(Flow.row()
943+
.widthRel(1f)
944+
.margin(4, 0)
945+
.alignY(0.5f)
946+
.coverChildrenHeight()
947+
.mainAxisAlignment(Alignment.MainAxis.SPACE_BETWEEN)
948+
.child(createColumn(columnValue, "columns", true, defaultDefinition.column))
949+
.child(createColumn(rowValue, "rows", true, defaultDefinition.row))
950+
.child(createColumn(layerValue, "layers", false, defaultDefinition.layer)));
951+
}
952+
953+
default Flow createColumn(IntSyncValue syncValue, String lang, boolean shouldDouble, int max) {
954+
final var display = IKey.dynamic(
955+
() -> String.valueOf(1 + (shouldDouble ? 2 * syncValue.getIntValue() : syncValue.getIntValue())));
956+
957+
IWidget increaseButton = new ButtonWidget<>()
958+
.size(9, 18)
959+
.background(GTGuiTextures.MC_BUTTON)
960+
.overlay(GTGuiTextures.PLUS)
961+
.disableHoverBackground()
962+
.onMousePressed(data -> {
963+
int val = syncValue.getIntValue();
964+
if (val < max) syncValue.setIntValue(++val);
965+
return true;
966+
});
967+
968+
IWidget decreaseButton = new ButtonWidget<>()
969+
.size(9, 18)
970+
.background(GTGuiTextures.MC_BUTTON)
971+
.overlay(GTGuiTextures.MINUS)
972+
.disableHoverBackground()
973+
.onMousePressed(data -> {
974+
int val = syncValue.getIntValue();
975+
if (val > 0) syncValue.setIntValue(--val);
976+
return true;
977+
});
978+
979+
return Flow.column()
980+
.coverChildren()
981+
.child(new TextWidget(IKey.lang("item.gt.tool.aoe." + lang))
982+
.marginBottom(5))
983+
.child(Flow.row()
984+
.coverChildren()
985+
.marginBottom(5)
986+
.child(increaseButton)
987+
.child(decreaseButton))
988+
.child(new TextWidget(display)
989+
.alignment(Alignment.Center)
990+
.widthRel(1f));
945991
}
946992

947993
Set<String> getToolClasses(ItemStack stack);

src/main/java/gregtech/api/items/toolitem/ItemGTHoe.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ public EnumActionResult onItemUse(@NotNull EntityPlayer player, @NotNull World w
314314
@Override
315315
public boolean hitEntity(@NotNull ItemStack stack, @NotNull EntityLivingBase target,
316316
@NotNull EntityLivingBase attacker) {
317-
getToolStats().getBehaviors().forEach(behavior -> behavior.hitEntity(stack, target, attacker));
317+
getBehaviors(stack).forEach(behavior -> behavior.hitEntity(stack, target, attacker));
318318
// damage by 1, as this is what vanilla does
319319
ToolHelper.damageItem(stack, attacker, 1);
320320
return true;

0 commit comments

Comments
 (0)