1616import org .rusherhack .client .api .RusherHackAPI ;
1717import org .rusherhack .client .api .feature .module .ModuleCategory ;
1818import org .rusherhack .client .api .feature .module .ToggleableModule ;
19- import org .rusherhack .client .api .utils .InventoryUtils ;
20- import org .rusherhack .core .setting .BooleanSetting ;
21- import org .rusherhack .core .event .listener .EventListener ;
2219import org .rusherhack .core .event .subscribe .Subscribe ;
20+ import org .rusherhack .core .setting .BooleanSetting ;
21+ import org .rusherhack .core .setting .NumberSetting ;
2322import org .rusherhack .client .api .events .client .EventUpdate ;
23+ import org .rusherhack .client .api .utils .InventoryUtils ;
2424
2525import java .util .List ;
2626import java .util .function .Predicate ;
2727
2828/**
2929 * AutoBucket module for automatically capturing various entities in buckets.
3030 * This module can capture entities such as Axolotls, Cod, Pufferfish, Salmon, Tadpoles, and Tropical Fish.
31+ * It also features rapid capture functionality with customizable cooldown settings.
3132 */
32- public class AutoBucketModule extends ToggleableModule implements EventListener {
33+ public class AutoBucketModule extends ToggleableModule {
34+
35+ // Instance of the Minecraft game for accessing player and world data
3336 private final Minecraft minecraft = Minecraft .getInstance ();
3437
35- // Settings for automatically capturing entities
36- private final BooleanSetting targetAxolotls ;
37- private final BooleanSetting targetCod ;
38- private final BooleanSetting targetPufferfish ;
39- private final BooleanSetting targetSalmon ;
40- private final BooleanSetting targetTadpoles ;
41- private final BooleanSetting targetTropicalFish ;
38+ // Settings to specify which entities should be captured
39+ private final BooleanSetting targetAxolotls = new BooleanSetting ("Axolotls" , "Bucket Axolotls" , true );
40+ private final BooleanSetting targetCod = new BooleanSetting ("Cod" , "Bucket Cod" , true );
41+ private final BooleanSetting targetPufferfish = new BooleanSetting ("Pufferfish" , "Bucket Pufferfish" , true );
42+ private final BooleanSetting targetSalmon = new BooleanSetting ("Salmon" , "Bucket Salmon" , true );
43+ private final BooleanSetting targetTadpoles = new BooleanSetting ("Tadpoles" , "Bucket Tadpoles" , true );
44+ private final BooleanSetting targetTropicalFish = new BooleanSetting ("TropicalFish" , "Bucket Tropical Fish" , true );
45+
46+ // Rapid capture functionality settings
47+ private final BooleanSetting rapidCatch = new BooleanSetting ("RapidCatch" , "Enable rapid capture of entities" , false );
48+ private final NumberSetting <Integer > rapidCooldown = new NumberSetting <>("RapidCooldown" , "Cooldown between rapid captures (ticks)" , 1 , 1 , 20 )
49+ .setVisibility (rapidCatch ::getValue );
4250
4351 // Tick counter to throttle capture attempts
4452 private int tick ;
@@ -48,20 +56,19 @@ public class AutoBucketModule extends ToggleableModule implements EventListener
4856 * Initializes the settings and registers them with the module.
4957 */
5058 public AutoBucketModule () {
51- super ("AutoBucket" , ModuleCategory .MISC );
59+ super ("AutoBucket" , "Automatically buckets certain entities" , ModuleCategory .MISC );
5260
53- // Settings to target specific entities
54- targetAxolotls = new BooleanSetting ("Axolotls" , "Bucket Axolotls" , true );
55- targetCod = new BooleanSetting ("Cod" , "Bucket Cod" , true );
56- targetPufferfish = new BooleanSetting ("Pufferfish" , "Bucket Pufferfish" , true );
57- targetSalmon = new BooleanSetting ("Salmon" , "Bucket Salmon" , true );
58- targetTadpoles = new BooleanSetting ("Tadpoles" , "Bucket Tadpoles" , true );
59- targetTropicalFish = new BooleanSetting ("TropicalFish" , "Bucket Tropical Fish" , true );
60-
61- // Add target settings as settings
62- this .registerSettings (targetAxolotls , targetCod , targetPufferfish , targetSalmon , targetTadpoles , targetTropicalFish );
63-
64- tick = 0 ;
61+ // Register settings for the module
62+ this .registerSettings (
63+ this .rapidCatch ,
64+ this .rapidCooldown ,
65+ this .targetAxolotls ,
66+ this .targetCod ,
67+ this .targetPufferfish ,
68+ this .targetSalmon ,
69+ this .targetTadpoles ,
70+ this .targetTropicalFish
71+ );
6572 }
6673
6774 /**
@@ -70,7 +77,6 @@ public AutoBucketModule() {
7077 */
7178 @ Override
7279 public void onEnable () {
73- super .onEnable ();
7480 RusherHackAPI .getEventBus ().subscribe (this );
7581 }
7682
@@ -80,7 +86,6 @@ public void onEnable() {
8086 */
8187 @ Override
8288 public void onDisable () {
83- super .onDisable ();
8489 RusherHackAPI .getEventBus ().unsubscribe (this );
8590 }
8691
@@ -102,34 +107,38 @@ public void onUpdate(EventUpdate event) {
102107 }
103108
104109 if (this .isToggled ()) {
105- autoBucketEntities ();
110+ autoBucketEntities (minecraft .player );
111+
112+ // Use normal cooldown for regular capture and sub-setting for RapidCatch
113+ tick = rapidCatch .getValue () ? rapidCooldown .getValue () : 40 ;
106114 }
107115 }
108116
109117 /**
110118 * Attempts to capture nearby entities using available water buckets.
119+ *
120+ * @param player The player entity performing the capture.
111121 */
112- private void autoBucketEntities () {
113- if (minecraft .player == null || minecraft .level == null ) {
114- return ;
115- }
116-
122+ private void autoBucketEntities (Entity player ) {
117123 // Predicate to filter bucketable entities based on settings
118- Predicate <Entity > bucketableEntities = entity ->
119- (entity instanceof Axolotl && targetAxolotls .getValue ()) ||
120- (entity instanceof Cod && targetCod .getValue ()) ||
121- (entity instanceof Pufferfish && targetPufferfish .getValue ()) ||
122- (entity instanceof Salmon && targetSalmon .getValue ()) ||
123- (entity instanceof Tadpole && targetTadpoles .getValue ()) ||
124- (entity instanceof TropicalFish && targetTropicalFish .getValue ());
124+ Predicate <Entity > bucketableEntities = entity -> {
125+ if (entity instanceof Axolotl && targetAxolotls .getValue ()) return true ;
126+ if (entity instanceof Cod && targetCod .getValue ()) return true ;
127+ if (entity instanceof Pufferfish && targetPufferfish .getValue ()) return true ;
128+ if (entity instanceof Salmon && targetSalmon .getValue ()) return true ;
129+ if (entity instanceof Tadpole && targetTadpoles .getValue ()) return true ;
130+ return entity instanceof TropicalFish && targetTropicalFish .getValue ();
131+ };
125132
126133 // Find entities within a 5 block radius
127- List <Entity > entities = minecraft .level .getEntities ((Entity ) null , minecraft .player .getBoundingBox ().inflate (5.0 ), bucketableEntities );
134+ assert minecraft .level != null ;
135+ List <Entity > entities = minecraft .level .getEntities ((Entity ) null , player .getBoundingBox ().inflate (5.0 ), bucketableEntities );
128136
137+ // Attempt to capture each entity
129138 for (Entity entity : entities ) {
130139 if (useMainHandBucketOnEntity (entity ) || useHotbarBucketOnEntity (entity ) || useInventoryBucketOnEntity (entity )) {
131- tick = 20 ; // Throttle capture attempts
132- break ;
140+ tick = rapidCatch . getValue () ? rapidCooldown . getValue () : 40 ; // Set cooldown
141+ break ; // Stop after successfully capturing one entity
133142 }
134143 }
135144 }
@@ -155,8 +164,7 @@ private boolean useMainHandBucketOnEntity(Entity entity) {
155164 * @return True if holding a water bucket, false otherwise.
156165 */
157166 private boolean isHoldingWaterBucket () {
158- assert minecraft .player != null ;
159- ItemStack mainHandItem = minecraft .player .getMainHandItem ();
167+ ItemStack mainHandItem = minecraft .player != null ? minecraft .player .getMainHandItem () : ItemStack .EMPTY ;
160168 return mainHandItem .getItem () == Items .WATER_BUCKET ;
161169 }
162170
@@ -182,7 +190,7 @@ private boolean useInventoryBucketOnEntity(Entity entity) {
182190 if (slot != -1 ) {
183191 int hotbarSlot = findEmptyHotbarSlot ();
184192 if (hotbarSlot != -1 ) {
185- InventoryUtils .swapSlots (slot , hotbarSlot );
193+ InventoryUtils .swapSlots (slot , hotbarSlot ); // Using InventoryUtils to swap slots
186194 boolean result = useBucketOnEntityFromSlot (entity , hotbarSlot );
187195 InventoryUtils .swapSlots (slot , hotbarSlot ); // Swap back to the original slot
188196 return result ;
@@ -199,21 +207,16 @@ private boolean useInventoryBucketOnEntity(Entity entity) {
199207 * @return True if the entity was successfully captured, false otherwise.
200208 */
201209 private boolean useBucketOnEntityFromSlot (Entity entity , int slot ) {
202- assert minecraft .player != null ;
203- int originalSlot = minecraft .player .getInventory ().selected ;
204-
205- // Swap to the water bucket slot
206- minecraft .player .connection .send (new ServerboundSetCarriedItemPacket (slot ));
210+ int originalSlot = minecraft .player != null ? minecraft .player .getInventory ().selected : -1 ;
207211
208- // Send interaction packet
209- minecraft .player .connection .send (ServerboundInteractPacket .createInteractionPacket (entity , false , InteractionHand .MAIN_HAND ));
210-
211- // Restore the original slot
212- minecraft .player .connection .send (new ServerboundSetCarriedItemPacket (originalSlot ));
213-
214- // Check if the interaction was successful
215- ItemStack currentItem = minecraft .player .getInventory ().getItem (slot );
216- return hasCapturedEntity (entity , currentItem );
212+ if (originalSlot != -1 ) {
213+ minecraft .player .connection .send (new ServerboundSetCarriedItemPacket (slot ));
214+ minecraft .player .connection .send (ServerboundInteractPacket .createInteractionPacket (entity , false , InteractionHand .MAIN_HAND ));
215+ minecraft .player .connection .send (new ServerboundSetCarriedItemPacket (originalSlot ));
216+ ItemStack currentItem = minecraft .player .getInventory ().getItem (slot );
217+ return hasCapturedEntity (entity , currentItem );
218+ }
219+ return false ;
217220 }
218221
219222 /**
@@ -224,12 +227,12 @@ private boolean useBucketOnEntityFromSlot(Entity entity, int slot) {
224227 * @return True if the item stack has captured the entity, false otherwise.
225228 */
226229 private boolean hasCapturedEntity (Entity entity , ItemStack itemStack ) {
227- return (entity instanceof Axolotl && itemStack .getItem () == Items .AXOLOTL_BUCKET ) ||
228- (entity instanceof Cod && itemStack .getItem () == Items .COD_BUCKET ) ||
229- (entity instanceof Pufferfish && itemStack .getItem () == Items .PUFFERFISH_BUCKET ) ||
230- (entity instanceof Salmon && itemStack .getItem () == Items .SALMON_BUCKET ) ||
231- (entity instanceof Tadpole && itemStack .getItem () == Items .TADPOLE_BUCKET ) ||
232- ( entity instanceof TropicalFish && itemStack .getItem () == Items .TROPICAL_FISH_BUCKET ) ;
230+ if (entity instanceof Axolotl && itemStack .getItem () == Items .AXOLOTL_BUCKET ) return true ;
231+ if (entity instanceof Cod && itemStack .getItem () == Items .COD_BUCKET ) return true ;
232+ if (entity instanceof Pufferfish && itemStack .getItem () == Items .PUFFERFISH_BUCKET ) return true ;
233+ if (entity instanceof Salmon && itemStack .getItem () == Items .SALMON_BUCKET ) return true ;
234+ if (entity instanceof Tadpole && itemStack .getItem () == Items .TADPOLE_BUCKET ) return true ;
235+ return entity instanceof TropicalFish && itemStack .getItem () == Items .TROPICAL_FISH_BUCKET ;
233236 }
234237
235238 /**
@@ -238,10 +241,11 @@ private boolean hasCapturedEntity(Entity entity, ItemStack itemStack) {
238241 * @return The slot index of the water bucket, or -1 if not found.
239242 */
240243 private int findWaterBucketInHotbar () {
241- for (int i = 0 ; i < 9 ; i ++) {
242- assert minecraft .player != null ;
243- if (minecraft .player .getInventory ().getItem (i ).getItem () == Items .WATER_BUCKET ) {
244- return i ;
244+ if (minecraft .player != null ) {
245+ for (int i = 0 ; i < 9 ; i ++) {
246+ if (minecraft .player .getInventory ().getItem (i ).getItem () == Items .WATER_BUCKET ) {
247+ return i ;
248+ }
245249 }
246250 }
247251 return -1 ;
@@ -253,10 +257,11 @@ private int findWaterBucketInHotbar() {
253257 * @return The slot index of the water bucket, or -1 if not found.
254258 */
255259 private int findWaterBucketInInventory () {
256- for (int i = 9 ; i < 36 ; i ++) {
257- assert minecraft .player != null ;
258- if (minecraft .player .getInventory ().getItem (i ).getItem () == Items .WATER_BUCKET ) {
259- return i ;
260+ if (minecraft .player != null ) {
261+ for (int i = 9 ; i < 36 ; i ++) {
262+ if (minecraft .player .getInventory ().getItem (i ).getItem () == Items .WATER_BUCKET ) {
263+ return i ;
264+ }
260265 }
261266 }
262267 return -1 ;
@@ -268,10 +273,11 @@ private int findWaterBucketInInventory() {
268273 * @return The slot index of an empty hotbar slot, or -1 if none are empty.
269274 */
270275 private int findEmptyHotbarSlot () {
271- for (int i = 0 ; i < 9 ; i ++) {
272- assert minecraft .player != null ;
273- if (minecraft .player .getInventory ().getItem (i ).isEmpty ()) {
274- return i ;
276+ if (minecraft .player != null ) {
277+ for (int i = 0 ; i < 9 ; i ++) {
278+ if (minecraft .player .getInventory ().getItem (i ).isEmpty ()) {
279+ return i ;
280+ }
275281 }
276282 }
277283 return -1 ;
0 commit comments