3
3
import dev .wuffs .squatgrow .actions .Action ;
4
4
import dev .wuffs .squatgrow .actions .ActionContext ;
5
5
import dev .wuffs .squatgrow .actions .Actions ;
6
+ import dev .wuffs .squatgrow .config .SquatGrowConfig ;
6
7
import net .minecraft .core .BlockPos ;
7
8
import net .minecraft .core .Direction ;
8
9
import net .minecraft .core .particles .ParticleTypes ;
10
+ import net .minecraft .resources .ResourceLocation ;
9
11
import net .minecraft .server .level .ServerLevel ;
10
12
import net .minecraft .server .level .ServerPlayer ;
11
13
import net .minecraft .sounds .SoundEvents ;
12
14
import net .minecraft .sounds .SoundSource ;
13
15
import net .minecraft .tags .ItemTags ;
14
16
import net .minecraft .util .Mth ;
17
+ import net .minecraft .world .entity .EquipmentSlot ;
15
18
import net .minecraft .world .entity .player .Player ;
16
19
import net .minecraft .world .item .ItemStack ;
17
20
import net .minecraft .world .level .GameType ;
18
21
import net .minecraft .world .level .Level ;
19
22
import net .minecraft .world .level .block .Blocks ;
20
23
import net .minecraft .world .level .block .state .BlockState ;
24
+ import org .apache .commons .lang3 .tuple .Pair ;
21
25
22
- import java .util .Set ;
26
+ import java .util .* ;
23
27
24
28
import static dev .wuffs .squatgrow .SquatGrow .config ;
25
29
@@ -28,13 +32,84 @@ public static void performAction(Level level, Player player) {
28
32
if (level .isClientSide ) return ;
29
33
if (!config .allowAdventureTwerking && ((ServerPlayer ) player ).gameMode .getGameModeForPlayer () == GameType .ADVENTURE ) return ;
30
34
31
- boolean handContainsHoe = (player .getMainHandItem ().is (ItemTags .HOES ) | player .getOffhandItem ().is (ItemTags .HOES ));
32
- if (config .requireHoe && !handContainsHoe ) return ;
35
+ Pair <Boolean , List <ItemStack >> requirementsTest = passesRequirements (player );
36
+ if (!requirementsTest .getKey ()) {
37
+ return ;
38
+ }
39
+
40
+ grow (level , (ServerPlayer ) player , requirementsTest .getValue ());
41
+ }
42
+
43
+ public static Pair <Boolean , List <ItemStack >> passesRequirements (Player player ) {
44
+ List <ItemStack > itemsThatHandleDamage = new ArrayList <>();
45
+ // Legacy support, if this is enabled, the requirements system is disabled.
46
+ if (config .requireHoe ) {
47
+ ItemStack mainHand = player .getMainHandItem ();
48
+ if (mainHand .is (ItemTags .HOES )) {
49
+ itemsThatHandleDamage .add (mainHand );
50
+ return Pair .of (true , itemsThatHandleDamage );
51
+ }
52
+
53
+ ItemStack offHand = player .getOffhandItem ();
54
+ if (offHand .is (ItemTags .HOES )) {
55
+ itemsThatHandleDamage .add (offHand );
56
+ return Pair .of (true , itemsThatHandleDamage );
57
+ }
58
+
59
+ return Pair .of (false , itemsThatHandleDamage );
60
+ }
61
+
62
+ SquatGrowConfig .Requirements requirements = config .requirements ;
63
+ if (requirements .enabled ) {
64
+ if (requirements .heldItemRequirement .isEmpty () && requirements .equipmentRequirement .isEmpty ()) {
65
+ return Pair .of (true , itemsThatHandleDamage );
66
+ }
67
+
68
+ // Let's check the correct things. First, the lighter of the two checks
69
+ boolean passesEquipment = false ;
70
+ if (!requirements .heldItemRequirement .isEmpty ()) {
71
+ BitSet foundItems = new BitSet ();
72
+ for (Map .Entry <EquipmentSlot , String > entry : requirements .equipmentRequirement .entrySet ()) {
73
+ ItemStack stack = player .getItemBySlot (entry .getKey ());
74
+ if (stack .isEmpty ()) {
75
+ continue ;
76
+ }
77
+
78
+ // Now compare the item in the slot to the requirement
79
+ if (stack .getItem ().arch$registryName ().toString ().equals (entry .getValue ())) {
80
+ foundItems .set (entry .getKey ().getIndex ());
81
+ itemsThatHandleDamage .add (stack );
82
+ }
83
+ }
84
+
85
+ if (foundItems .cardinality () == requirements .heldItemRequirement .size ()) {
86
+ passesEquipment = true ;
87
+ }
88
+ }
89
+
90
+ if (!requirements .equipmentRequirement .isEmpty () && !passesEquipment ) {
91
+ return Pair .of (false , itemsThatHandleDamage ); // If the equipment check is required and failed, we can return false
92
+ }
93
+
94
+ // Now, the heavier of the two checks
95
+ // We can only have gotten here if heldItemRequirement is not empty so no need to check again
96
+ BitSet foundItems = new BitSet ();
97
+ for (String item : requirements .heldItemRequirement ) {
98
+ ResourceLocation itemLocation = new ResourceLocation (item );
99
+ if (player .getMainHandItem ().getItem ().arch$registryName ().equals (itemLocation ) || player .getOffhandItem ().getItem ().arch$registryName ().equals (itemLocation )) {
100
+ foundItems .set (itemLocation .hashCode ());
101
+ itemsThatHandleDamage .add (player .getMainHandItem ());
102
+ }
103
+ }
104
+
105
+ var passes = foundItems .cardinality () == requirements .heldItemRequirement .size ();
106
+ return Pair .of (passes , itemsThatHandleDamage );
107
+ }
33
108
34
- grow ( level , ( ServerPlayer ) player );
109
+ return Pair . of ( true , itemsThatHandleDamage );
35
110
}
36
111
37
- public static void grow (Level level , ServerPlayer player ) {
112
+ public static void grow (Level level , ServerPlayer player , List < ItemStack > itemsToDamage ) {
38
113
BlockPos pos = player .blockPosition ();
39
114
40
115
var r = level .random ;
@@ -75,17 +150,16 @@ public static void grow(Level level, ServerPlayer player) {
75
150
didGrow = action .execute (context );
76
151
}
77
152
78
- if (didGrow ) {
79
- if (config .requireHoe && config .hoeTakesDamage ) {
80
- ItemStack hoe = player .getMainHandItem ();
81
- if (!hoe .is (ItemTags .HOES )) {
82
- hoe = player .getOffhandItem ();
83
- }
84
-
85
- hoe .hurtAndBreak (1 , player , (playerEntity ) -> {
153
+ if ((config .hoeTakesDamage || config .requirements .requiredItemTakesDamage ) && didGrow && !itemsToDamage .isEmpty ()) {
154
+ var durabilityToApply = config .hoeTakesDamage ? 1 : config .requirements .durabilityDamage ;
155
+ for (ItemStack item : itemsToDamage ) {
156
+ item .hurtAndBreak (durabilityToApply , player , (playerEntity ) -> {
86
157
playerEntity .broadcastBreakEvent (player .getUsedItemHand ());
87
158
});
88
159
}
160
+ }
161
+
162
+ if (didGrow ) {
89
163
addGrowthParticles ((ServerLevel ) level , offsetLocation , player );
90
164
}
91
165
}
0 commit comments