Skip to content

Commit d06f1e0

Browse files
feat: #24 #16 (kinda)
1 parent 9e2e9aa commit d06f1e0

File tree

2 files changed

+112
-15
lines changed

2 files changed

+112
-15
lines changed

common/src/main/java/dev/wuffs/squatgrow/SquatAction.java

Lines changed: 87 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,27 @@
33
import dev.wuffs.squatgrow.actions.Action;
44
import dev.wuffs.squatgrow.actions.ActionContext;
55
import dev.wuffs.squatgrow.actions.Actions;
6+
import dev.wuffs.squatgrow.config.SquatGrowConfig;
67
import net.minecraft.core.BlockPos;
78
import net.minecraft.core.Direction;
89
import net.minecraft.core.particles.ParticleTypes;
10+
import net.minecraft.resources.ResourceLocation;
911
import net.minecraft.server.level.ServerLevel;
1012
import net.minecraft.server.level.ServerPlayer;
1113
import net.minecraft.sounds.SoundEvents;
1214
import net.minecraft.sounds.SoundSource;
1315
import net.minecraft.tags.ItemTags;
1416
import net.minecraft.util.Mth;
17+
import net.minecraft.world.entity.EquipmentSlot;
1518
import net.minecraft.world.entity.player.Player;
1619
import net.minecraft.world.item.ItemStack;
1720
import net.minecraft.world.level.GameType;
1821
import net.minecraft.world.level.Level;
1922
import net.minecraft.world.level.block.Blocks;
2023
import net.minecraft.world.level.block.state.BlockState;
24+
import org.apache.commons.lang3.tuple.Pair;
2125

22-
import java.util.Set;
26+
import java.util.*;
2327

2428
import static dev.wuffs.squatgrow.SquatGrow.config;
2529

@@ -28,13 +32,84 @@ public static void performAction(Level level, Player player) {
2832
if (level.isClientSide) return;
2933
if (!config.allowAdventureTwerking && ((ServerPlayer) player).gameMode.getGameModeForPlayer() == GameType.ADVENTURE) return;
3034

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+
}
33108

34-
grow(level, (ServerPlayer) player);
109+
return Pair.of(true, itemsThatHandleDamage);
35110
}
36111

37-
public static void grow(Level level, ServerPlayer player) {
112+
public static void grow(Level level, ServerPlayer player, List<ItemStack> itemsToDamage) {
38113
BlockPos pos = player.blockPosition();
39114

40115
var r = level.random;
@@ -75,17 +150,16 @@ public static void grow(Level level, ServerPlayer player) {
75150
didGrow = action.execute(context);
76151
}
77152

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) -> {
86157
playerEntity.broadcastBreakEvent(player.getUsedItemHand());
87158
});
88159
}
160+
}
161+
162+
if (didGrow) {
89163
addGrowthParticles((ServerLevel) level, offsetLocation, player);
90164
}
91165
}

common/src/main/java/dev/wuffs/squatgrow/config/SquatGrowConfig.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,22 @@
55
import me.shedaniel.autoconfig.annotation.Config;
66
import me.shedaniel.autoconfig.annotation.ConfigEntry;
77
import me.shedaniel.cloth.clothconfig.shadowed.blue.endless.jankson.Comment;
8+
import net.minecraft.world.entity.EquipmentSlot;
89

910
import java.util.ArrayList;
1011
import java.util.Arrays;
1112
import java.util.List;
13+
import java.util.Map;
1214

1315
@Config(name = SquatGrow.MOD_ID + "-common")
1416
public class SquatGrowConfig implements ConfigData {
1517
@Comment("Enable debug logging")
1618
public boolean debug = false;
1719

18-
@Comment("Require hoe to allow growth")
20+
@Comment("Require hoe to allow growth, LEGACY, PLEASE SWITCH TO THE NEW SYSTEM, SEE REQUIREMENTS")
1921
public boolean requireHoe = false;
2022

21-
@Comment("Hoe takes damage on growth")
23+
@Comment("Hoe takes damage on growth, LEGACY, PLEASE SWITCH TO THE NEW SYSTEM, SEE REQUIREMENTS")
2224
public boolean hoeTakesDamage = false;
2325

2426
@Comment("Use whitelist instead of blacklist, default false")
@@ -64,4 +66,25 @@ public class SquatGrowConfig implements ConfigData {
6466

6567
@Comment("When the player is holding a grass block in their offhand, they will be able to randomly convert dirt into grass")
6668
public boolean enableDirtToGrass = true;
69+
70+
@ConfigEntry.Category("requirements")
71+
@Comment("Requirements for growing")
72+
public Requirements requirements = new Requirements();
73+
74+
public static class Requirements {
75+
@Comment("Enabled the new requirements system")
76+
public boolean enabled = true;
77+
78+
@Comment("List of blocks that require a hoe to grow, leave empty to disable")
79+
public List<String> heldItemRequirement = new ArrayList<>();
80+
81+
@Comment("Map of equipment slots to items required to grow, leave empty to disable")
82+
public Map<EquipmentSlot, String> equipmentRequirement = Map.of();
83+
84+
@Comment("Durability based items take damage when used to grow")
85+
public boolean requiredItemTakesDamage = false;
86+
87+
@Comment("Amount of damage to take when used to grow")
88+
public int durabilityDamage = 1;
89+
}
6790
}

0 commit comments

Comments
 (0)