99import com .enderio .conduits .common .conduit .connection .DynamicConnectionState ;
1010import com .enderio .conduits .common .conduit .type .item .ItemConduitData .ItemSidedData ;
1111import com .enderio .conduits .common .conduit .type .item .ItemConduitType ;
12+ import com .enderio .conduits .common .init .ConduitLang ;
1213import com .enderio .conduits .common .network .C2SSyncProbeState ;
1314import com .enderio .conduits .common .util .InteractionUtil ;
1415import com .enderio .core .common .network .CoreNetwork ;
1718import net .minecraft .core .Direction ;
1819import net .minecraft .nbt .CompoundTag ;
1920import net .minecraft .network .chat .Component ;
21+ import net .minecraft .network .chat .MutableComponent ;
22+ import net .minecraft .resources .ResourceLocation ;
23+ import net .minecraft .world .entity .player .Player ;
2024import net .minecraft .world .InteractionResult ;
2125import net .minecraft .world .item .Item ;
2226import net .minecraft .world .item .ItemStack ;
2327import net .minecraft .world .item .TooltipFlag ;
2428import net .minecraft .world .item .context .UseOnContext ;
2529import net .minecraft .world .level .Level ;
2630import net .minecraft .world .level .block .entity .BlockEntity ;
31+ import com .enderio .base .common .lang .EIOLang ;
2732import org .apache .commons .lang3 .StringUtils ;
2833import org .jetbrains .annotations .Nullable ;
2934
35+ import java .util .ArrayList ;
3036import java .util .List ;
3137import java .util .Objects ;
38+ import java .util .Set ;
3239
3340public class ConduitProbeItem extends Item {
3441 public static final String STATE_FIELD = "STATE" ;
@@ -42,7 +49,10 @@ public class ConduitProbeItem extends Item {
4249 public static final String ROUND_ROBIN = "ROUND_ROBIN" ;
4350 public static final String SELF_FEED = "SELF_FEED" ;
4451 public static final String PRIORITY = "PRIORITY" ;
45-
52+
53+ public static final Set <String > BOOL_TAG = Set .of (IS_INSERT , IS_EXTRACT , ROUND_ROBIN , SELF_FEED );
54+ public static final Set <String > COLOR_CONTROL_TAG = Set .of (INSERT_CHANNEL , EXTRACT_CHANNEL , REDSTONE_CHANNEL );
55+
4656 public ConduitProbeItem (Properties properties ) {
4757 super (properties );
4858 }
@@ -68,39 +78,50 @@ public static void switchState(ItemStack stack, boolean syncToServer) {
6878 @ Override
6979 public InteractionResult onItemUseFirst (ItemStack stack , UseOnContext context ) {
7080 BlockEntity block = context .getLevel ().getBlockEntity (context .getClickedPos ());
71- if (block instanceof ConduitBlockEntity conduit ) {
72- if (context .getLevel ().isClientSide ()) return InteractionResult .SUCCESS ;
73- switch (getState (stack )) {
81+ Player player = context .getPlayer ();
82+ if (player == null ) {
83+ return InteractionResult .FAIL ;
84+ }
85+ if (context .getLevel ().isClientSide ()) {
86+ return InteractionResult .SUCCESS ;
87+ }
88+ if (!(block instanceof ConduitBlockEntity conduit )) {
89+ return super .onItemUseFirst (stack , context );
90+ }
91+
92+ switch (getState (stack )) {
7493 case COPY_PASTE -> {
7594 if (context .isSecondaryUseActive ()) {
7695 handleCopy (conduit ,
7796 InteractionUtil .fromClickLocation (context .getClickLocation (), context .getClickedPos ().getCenter ()),
78- stack );
97+ stack ,
98+ player );
7999 } else {
80100 handlePaste (conduit ,
81101 InteractionUtil .fromClickLocation (context .getClickLocation (), context .getClickedPos ().getCenter ()),
82- stack );
102+ stack ,
103+ player );
83104 }
84105 }
85106 case PROBE -> {
86- context .getPlayer ().sendSystemMessage (Component .literal ("This feature isn't implemented yet." ).withStyle (ChatFormatting .RED ));
87- }
107+ player .sendSystemMessage (Component .literal ("This feature isn't implemented yet." ).withStyle (ChatFormatting .RED ));
88108 }
89- return InteractionResult .SUCCESS ;
90109 }
91- return super . onItemUseFirst ( stack , context ) ;
110+ return InteractionResult . SUCCESS ;
92111 }
93112
94- private void handleCopy (ConduitBlockEntity conduitBlock , Direction face , ItemStack itemStack ) {
113+ private void handleCopy (ConduitBlockEntity conduitBlock , Direction face , ItemStack itemStack , Player player ) {
95114 CompoundTag tag = itemStack .getOrCreateTag ();
96115 CompoundTag conduitData = new CompoundTag ();
97116 tag .put (CONDUIT_DATA , conduitData );
98117 ConduitBundle bundle = conduitBlock .getBundle ();
99118 if (bundle .getConnectedTypes (face ).isEmpty ()) {
100119 return ;
101120 }
102- bundle .getTypes ().forEach (conduitType -> {
103- ConnectionState connectionState = bundle .getConnectionState (face , conduitType );
121+ MutableComponent message = Component .empty ();
122+ bundle .getTypes ().forEach (conduit -> {
123+ String conduitKey = ConduitType .getKey (conduit ).toString ();
124+ ConnectionState connectionState = bundle .getConnectionState (face , conduit );
104125 CompoundTag typeTag = new CompoundTag ();
105126 if (connectionState instanceof DynamicConnectionState dynamic ) {
106127 typeTag .putBoolean (IS_INSERT , dynamic .isInsert ());
@@ -110,7 +131,7 @@ private void handleCopy(ConduitBlockEntity conduitBlock, Direction face, ItemSta
110131 typeTag .putInt (REDSTONE_CONTROL , dynamic .control ().ordinal ());
111132 typeTag .putInt (REDSTONE_CHANNEL , dynamic .redstoneChannel ().ordinal ());
112133
113- if (conduitType instanceof ItemConduitType itemConduitType ) {
134+ if (conduit instanceof ItemConduitType itemConduitType ) {
114135 ItemSidedData sidedData = bundle .getNodeFor (itemConduitType ).getConduitData ().get (face );
115136 typeTag .putBoolean (ROUND_ROBIN , sidedData .isRoundRobin );
116137 typeTag .putBoolean (SELF_FEED , sidedData .isSelfFeed );
@@ -120,19 +141,44 @@ private void handleCopy(ConduitBlockEntity conduitBlock, Direction face, ItemSta
120141 typeTag .putBoolean (IS_INSERT , false );
121142 typeTag .putBoolean (IS_EXTRACT , false );
122143 }
123- conduitData .put (Objects .requireNonNull (ConduitType .getKey (conduitType )).toString (), typeTag );
144+ conduitData .put (conduitKey , typeTag );
145+
146+ message .append (Component .literal ("\n " + conduitKeyToDisplayName (conduitKey ).getString () + ":\n " ).withStyle (ChatFormatting .UNDERLINE ));
147+ typeTag .getAllKeys ().forEach (key -> {
148+ StringBuilder sb = new StringBuilder ();
149+ sb .append (" - " + key + ": " );
150+ if (BOOL_TAG .contains (key )) {
151+ sb .append (typeTag .getBoolean (key ));
152+ } else if (COLOR_CONTROL_TAG .contains (key )) {
153+ sb .append (ColorControl .values ()[typeTag .getInt (key )]);
154+ } else if (key .equals (REDSTONE_CONTROL )) {
155+ sb .append (RedstoneControl .values ()[typeTag .getInt (key )]);
156+ } else {
157+ sb .append (typeTag .get (key ));
158+ }
159+ sb .append ("\n " );
160+ message .append (Component .literal (sb .toString ()).withStyle (ChatFormatting .GRAY ));
161+ });
124162 });
163+ player .sendSystemMessage (TooltipUtil .withArgs (EIOLang .CONDUIT_PROBE_MESSAGE_COPIED , message ));
125164 }
126-
127- public void handlePaste (ConduitBlockEntity conduitBlock , Direction face , ItemStack itemStack ) {
165+
166+ public void handlePaste (ConduitBlockEntity conduitBlock , Direction face , ItemStack itemStack , Player player ) {
128167 CompoundTag tag = itemStack .getTag ();
129168 if (tag == null || !(tag .get (CONDUIT_DATA ) instanceof CompoundTag conduitData )) {
130169 return ;
131170 }
171+
172+ List <String > pastedConduits = new ArrayList <String >();
132173 ConduitBundle bundle = conduitBlock .getBundle ();
133- bundle .getTypes ().forEach (conduitType -> {
134- CompoundTag typeTag = conduitData .getCompound (Objects .requireNonNull (ConduitType .getKey (conduitType )).toString ());
135- ConnectionState prevConnectionState = bundle .getConnectionState (face , conduitType );
174+ bundle .getTypes ().forEach (conduit -> {
175+ String conduitKey = ConduitType .getKey (conduit ).toString ();
176+ CompoundTag typeTag = conduitData .getCompound (conduitKey );
177+ if (typeTag == null || typeTag .isEmpty ()) {
178+ return ;
179+ }
180+
181+ ConnectionState prevConnectionState = bundle .getConnectionState (face , conduit );
136182 DynamicConnectionState connectionState = null ;
137183 if (prevConnectionState instanceof DynamicConnectionState ) connectionState = (DynamicConnectionState ) prevConnectionState ;
138184 boolean wasConnected = connectionState != null ;
@@ -144,15 +190,21 @@ public void handlePaste(ConduitBlockEntity conduitBlock, Direction face, ItemSta
144190 ColorControl .values ()[typeTag .getInt (REDSTONE_CHANNEL )], wasConnected ? connectionState .filterInsert () : ItemStack .EMPTY ,
145191 wasConnected ? connectionState .filterExtract () : ItemStack .EMPTY , wasConnected ? connectionState .upgradeExtract () : ItemStack .EMPTY
146192 );
147- conduitBlock .handleConnectionStateUpdate (face , conduitType , newState );
193+ conduitBlock .handleConnectionStateUpdate (face , conduit , newState );
148194
149- if (conduitType instanceof ItemConduitType itemConduitType && typeTag .contains (ROUND_ROBIN )) {
195+ if (conduit instanceof ItemConduitType itemConduitType && typeTag .contains (ROUND_ROBIN )) {
150196 ItemSidedData sidedData = bundle .getNodeFor (itemConduitType ).getConduitData ().compute (face );
151197 sidedData .isRoundRobin = typeTag .getBoolean (ROUND_ROBIN );
152198 sidedData .isSelfFeed = typeTag .getBoolean (SELF_FEED );
153199 sidedData .setPriority (typeTag .getInt (PRIORITY ));
154200 }
201+ pastedConduits .add (conduitKeyToDisplayName (conduitKey ).getString ());
155202 });
203+
204+ if (!pastedConduits .isEmpty ()) {
205+ String pastedConduitsString = String .join (", " , pastedConduits );
206+ player .sendSystemMessage (TooltipUtil .withArgs (EIOLang .CONDUIT_PROBE_MESSAGE_PASTED , pastedConduitsString ));
207+ }
156208 conduitBlock .setChanged ();
157209 conduitBlock .updateClient ();
158210 }
@@ -162,19 +214,35 @@ public void appendHoverText(ItemStack stack, @Nullable Level level, List<Compone
162214 if (!(stack .getItem () instanceof ConduitProbeItem )) {
163215 return ;
164216 }
165- StringBuilder builder = new StringBuilder ();
166- for (String s : ConduitProbeItem .getState (stack ).toString ().toLowerCase ().split ("_" )) {
167- builder .append (StringUtils .capitalize (s ));
168- builder .append (" " );
217+
218+ tooltipComponents .add (TooltipUtil .styledWithArgs (EIOLang .CONDUIT_PROBE_MODE , ConduitProbeItem .getState (stack ).getStateText ()));
219+
220+ CompoundTag tag = stack .getTag ();
221+ if (tag != null && (tag .get (CONDUIT_DATA ) instanceof CompoundTag conduitData ) && !conduitData .getAllKeys ().isEmpty ()) {
222+ tooltipComponents .add (EIOLang .CONDUIT_PROBE_CONTAINS_COPIED .withStyle (ChatFormatting .GRAY ));
223+ conduitData .getAllKeys ().forEach (conduitKey -> {
224+ tooltipComponents .add (Component .literal ("- " + conduitKeyToDisplayName (conduitKey ).getString ()).withStyle (ChatFormatting .DARK_GRAY ));
225+ });
169226 }
170- builder .deleteCharAt (builder .length () - 1 );
171- tooltipComponents .add (TooltipUtil .style (Component .translatable ("tooltip.enderio.conduit_probe.mode" , builder .toString ())));
172-
227+
173228 super .appendHoverText (stack , level , tooltipComponents , isAdvanced );
174229 }
175230
231+ // Can't use ResourceLocation because of backwards compatibility of conduitData
232+ private Component conduitKeyToDisplayName (String conduitKey ) {
233+ String translationKey = "item." + conduitKey .replace (":" , "." );
234+ return Component .translatable (translationKey );
235+ }
236+
176237 public enum State {
177238 PROBE ,
178- COPY_PASTE
239+ COPY_PASTE ;
240+
241+ public Component getStateText () {
242+ return switch (this ) {
243+ case PROBE -> EIOLang .CONDUIT_PROBE_PROBE ;
244+ case COPY_PASTE -> EIOLang .CONDUIT_PROBE_COPY_PASTE ;
245+ };
246+ }
179247 }
180248}
0 commit comments