55import lombok .AllArgsConstructor ;
66import lombok .Getter ;
77import net .minecraft .client .Minecraft ;
8+ import net .minecraft .network .chat .Component ;
89import net .minecraft .world .entity .EntityType ;
910import net .minecraft .world .entity .EquipmentSlot ;
1011import net .minecraft .world .entity .decoration .ArmorStand ;
@@ -28,7 +29,9 @@ public class DeployableManager {
2829
2930 /** The DeployableManager instance. */
3031 @ Getter private static final DeployableManager instance = new DeployableManager ();
32+ private static final Minecraft MC = Minecraft .getInstance ();
3133 private static final Pattern POWER_ORB_PATTERN = Pattern .compile ("[A-Za-z ]* (?<seconds>[0-9]*)s" );
34+ private static final Pattern TOTEM_PATTERN = Pattern .compile ("Remaining: (?:(?<minutes>\\ d{1,2})m )?(?<seconds>\\ d{1,2})s" );
3235
3336 /** Entry displaying {@link Deployable#SOS_FLARE} at 90 seconds for the edit screen */
3437 public static ArmorStand DUMMY_ARMOR_STAND ;
@@ -37,7 +40,7 @@ public class DeployableManager {
3740 private final Map <Deployable , DeployableEntry > deployableEntryMap = new HashMap <>();
3841
3942 static {
40- DUMMY_ARMOR_STAND = new ArmorStand (EntityType .ARMOR_STAND , Minecraft . getInstance () .level );
43+ DUMMY_ARMOR_STAND = new ArmorStand (EntityType .ARMOR_STAND , MC .level );
4144 DUMMY_ARMOR_STAND .setItemSlot (EquipmentSlot .HEAD , ItemUtils .getTexturedHead ("SOS_FLARE" ));
4245 DUMMY_ARMOR_STAND .setInvisible (true );
4346 DUMMY_DEPLOYABLE_ENTRY = new DeployableEntry (Deployable .SOS_FLARE , 90 , DUMMY_ARMOR_STAND .getUUID ());
@@ -70,48 +73,65 @@ public DeployableEntry getActiveDeployable() {
7073 * @param entityArmorStand The entity to detect whether it is a deployable or not.
7174 */
7275 public void detectDeployables (ArmorStand entityArmorStand ) {
73- if (entityArmorStand .getCustomName () != null ) {
74- Minecraft mc = Minecraft .getInstance ();
75-
76- String customNameTag ;
77- if (entityArmorStand .getCustomName () != null ) {
78- customNameTag = entityArmorStand .getCustomName ().getString ();
79- } else {
80- return ;
81- }
82-
83- Deployable orb = Deployable .getByDisplayName (customNameTag );
84-
85- if (orb != null && orb .isInRadius (entityArmorStand .distanceToSqr (mc .player ))) {
86- Matcher matcher = POWER_ORB_PATTERN .matcher (customNameTag );
76+ Component customName = entityArmorStand .getCustomName ();
8777
88- if (matcher .matches ()) {
89- int seconds ;
90- try {
91- // Apparently they don't have a second count for moment after spawning, that's what this try-catch is for
92- seconds = Integer .parseInt (matcher .group ("seconds" ));
93- } catch (NumberFormatException ex ) {
94- // It's okay, just don't add the deployable I guess...
95- return ;
96- }
78+ if (customName != null ) {
79+ String customNameString = customName .getString ();
80+ Deployable orb = Deployable .getByDisplayName (customNameString );
9781
98- if (mc .level == null ) return ;
99- List <ArmorStand > surroundingArmorStands = mc .level .getEntitiesOfClass (
82+ if (orb != null && orb .isInRadius (entityArmorStand .distanceToSqr (MC .player ))) {
83+ if (orb == Deployable .TOTEM_OF_CORRUPTION ) {
84+ List <ArmorStand > surroundingArmorStands = MC .level .getEntitiesOfClass (
10085 ArmorStand .class ,
10186 new AABB (
10287 entityArmorStand .getX () - 0.1 ,
10388 entityArmorStand .getY () - 1 ,
10489 entityArmorStand .getZ () - 0.1 ,
10590 entityArmorStand .getX () + 0.1 ,
106- entityArmorStand .getY () + 1 ,
91+ entityArmorStand .getY (),
10792 entityArmorStand .getZ () + 0.1
108- ),
109- armorStandEntity -> armorStandEntity .getItemBySlot (EquipmentSlot .HEAD ) != ItemStack .EMPTY
93+ )
11094 );
111- if (!surroundingArmorStands .isEmpty ()) {
112- ArmorStand orbArmorStand = surroundingArmorStands .getFirst ();
113-
114- put (orb , seconds , orbArmorStand == null ? null : orbArmorStand .getUUID ());
95+ for (ArmorStand entry : surroundingArmorStands ) {
96+ Component entryCustomName = entry .getCustomName ();
97+ if (entryCustomName == null ) continue ;
98+
99+ Matcher matcher = TOTEM_PATTERN .matcher (entryCustomName .getString ());
100+ if (matcher .matches ()) {
101+ put (orb , getSeconds (matcher ), entry .getUUID ());
102+ break ;
103+ }
104+ }
105+ } else {
106+ Matcher matcher = POWER_ORB_PATTERN .matcher (customNameString );
107+
108+ if (matcher .matches ()) {
109+ int seconds ;
110+ try {
111+ // Apparently they don't have a second count for moment after spawning, that's what this try-catch is for
112+ seconds = Integer .parseInt (matcher .group ("seconds" ));
113+ } catch (NumberFormatException ex ) {
114+ // It's okay, just don't add the deployable I guess...
115+ return ;
116+ }
117+
118+ List <ArmorStand > surroundingArmorStands = MC .level .getEntitiesOfClass (
119+ ArmorStand .class ,
120+ new AABB (
121+ entityArmorStand .getX () - 0.1 ,
122+ entityArmorStand .getY () - 1 ,
123+ entityArmorStand .getZ () - 0.1 ,
124+ entityArmorStand .getX () + 0.1 ,
125+ entityArmorStand .getY () + 1 ,
126+ entityArmorStand .getZ () + 0.1
127+ ),
128+ armorStandEntity -> armorStandEntity .getItemBySlot (EquipmentSlot .HEAD ) != ItemStack .EMPTY
129+ );
130+ if (!surroundingArmorStands .isEmpty ()) {
131+ ArmorStand orbArmorStand = surroundingArmorStands .getFirst ();
132+
133+ put (orb , seconds , orbArmorStand == null ? null : orbArmorStand .getUUID ());
134+ }
115135 }
116136 }
117137 }
@@ -128,7 +148,7 @@ public void detectDeployables(ArmorStand entityArmorStand) {
128148 if (decodedTextureUrl == null ) return ;
129149
130150 Deployable flare = Deployable .getByTextureId (decodedTextureUrl );
131- if (flare != null && flare .isInRadius (entityArmorStand .distanceToSqr (Minecraft . getInstance () .player ))) {
151+ if (flare != null && flare .isInRadius (entityArmorStand .distanceToSqr (MC .player ))) {
132152 // Default exist time of flares
133153 int seconds = 180 ;
134154 // 1 tick = 50ms
@@ -140,6 +160,21 @@ public void detectDeployables(ArmorStand entityArmorStand) {
140160 }
141161 }
142162
163+ private static int getSeconds (Matcher matcher ) {
164+ String secondsStr = matcher .group ("seconds" );
165+ int seconds = 0 ;
166+ if (secondsStr != null && !secondsStr .isEmpty ()) {
167+ seconds = Integer .parseInt (secondsStr );
168+ }
169+
170+ String minutesStr = matcher .group ("minutes" );
171+ if (minutesStr != null && !minutesStr .isEmpty ()) {
172+ seconds += Integer .parseInt (minutesStr ) * 60 ;
173+ }
174+
175+ return seconds ;
176+ }
177+
143178 @ Getter @ AllArgsConstructor
144179 public static class DeployableEntry {
145180 /** The Deployable type. */
0 commit comments