Skip to content

Commit 97058a3

Browse files
committed
feat: Add /littlejoys command for triggering events #10
1 parent 5983555 commit 97058a3

File tree

8 files changed

+237
-61
lines changed

8 files changed

+237
-61
lines changed

common/src/main/java/net/blay09/mods/littlejoys/LittleJoys.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import net.blay09.mods.littlejoys.api.LittleJoysAPI;
55
import net.blay09.mods.littlejoys.block.ModBlocks;
66
import net.blay09.mods.littlejoys.block.entity.ModBlockEntities;
7+
import net.blay09.mods.littlejoys.command.LittleJoysCommand;
78
import net.blay09.mods.littlejoys.entity.ModEntities;
89
import net.blay09.mods.littlejoys.handler.DigSpotHandler;
910
import net.blay09.mods.littlejoys.handler.DropRushHandler;
@@ -61,6 +62,7 @@ public static void initialize() {
6162
ModSounds.initialize(Balm.getSounds());
6263
ModParticles.initialize(Balm.getParticles());
6364
ModPoiTypes.initialize(Balm.getWorldGen());
65+
Balm.getCommands().register(LittleJoysCommand::register);
6466

6567
DropRushHandler.initialize();
6668
GoldRushHandler.initialize();
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package net.blay09.mods.littlejoys.command;
2+
3+
import com.mojang.brigadier.CommandDispatcher;
4+
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
5+
import net.blay09.mods.balm.api.command.BalmCommands;
6+
import net.blay09.mods.littlejoys.LittleJoys;
7+
import net.blay09.mods.littlejoys.handler.DigSpotHandler;
8+
import net.blay09.mods.littlejoys.handler.DropRushHandler;
9+
import net.blay09.mods.littlejoys.handler.FishingSpotHandler;
10+
import net.blay09.mods.littlejoys.handler.GoldRushHandler;
11+
import net.blay09.mods.littlejoys.recipe.DigSpotRecipe;
12+
import net.blay09.mods.littlejoys.recipe.DropRushRecipe;
13+
import net.blay09.mods.littlejoys.recipe.FishingSpotRecipe;
14+
import net.blay09.mods.littlejoys.recipe.GoldRushRecipe;
15+
import net.minecraft.commands.CommandSourceStack;
16+
import net.minecraft.commands.Commands;
17+
import net.minecraft.commands.arguments.ResourceKeyArgument;
18+
import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
19+
import net.minecraft.core.registries.Registries;
20+
import net.minecraft.network.chat.Component;
21+
import net.minecraft.resources.ResourceKey;
22+
import net.minecraft.resources.ResourceLocation;
23+
import net.minecraft.world.item.crafting.RecipeHolder;
24+
25+
public class LittleJoysCommand {
26+
27+
private static final ResourceLocation PERMISSION_LITTLEJOYS_DIGSPOT = LittleJoys.id("command.littlejoys.digspot");
28+
private static final ResourceLocation PERMISSION_LITTLEJOYS_FISHINGSPOT = LittleJoys.id("command.littlejoys.fishingspot");
29+
private static final ResourceLocation PERMISSION_LITTLEJOYS_GOLDRUSH = LittleJoys.id("command.littlejoys.goldrush");
30+
private static final ResourceLocation PERMISSION_LITTLEJOYS_DROPRUSH = LittleJoys.id("command.littlejoys.droprush");
31+
32+
private static final DynamicCommandExceptionType ERROR_UNKNOWN_RECIPE = new DynamicCommandExceptionType((arg) -> Component.translatable("recipe.notFound", arg));
33+
34+
@SuppressWarnings("unchecked")
35+
public static void register(CommandDispatcher<CommandSourceStack> dispatcher) {
36+
BalmCommands.registerPermission(PERMISSION_LITTLEJOYS_DIGSPOT, 2);
37+
BalmCommands.registerPermission(PERMISSION_LITTLEJOYS_FISHINGSPOT, 2);
38+
BalmCommands.registerPermission(PERMISSION_LITTLEJOYS_GOLDRUSH, 2);
39+
BalmCommands.registerPermission(PERMISSION_LITTLEJOYS_DROPRUSH, 2);
40+
41+
dispatcher.register(Commands.literal("littlejoys")
42+
.then(Commands.literal("digspot")
43+
.requires(BalmCommands.requirePermission(PERMISSION_LITTLEJOYS_DIGSPOT))
44+
.then(Commands.argument("position", BlockPosArgument.blockPos())
45+
.executes(context -> {
46+
final var level = context.getSource().getLevel();
47+
final var player = context.getSource().getPlayerOrException();
48+
final var pos = BlockPosArgument.getBlockPos(context, "position");
49+
return DigSpotHandler.createDigSpot(level, pos, player) ? 1 : 0;
50+
})
51+
.then(Commands.argument("recipe", ResourceKeyArgument.key(Registries.RECIPE))
52+
.executes(context -> {
53+
final var level = context.getSource().getLevel();
54+
final var pos = BlockPosArgument.getBlockPos(context, "position");
55+
final var recipeHolder = ResourceKeyArgument.getRecipe(context, "recipe");
56+
if (recipeHolder.value() instanceof DigSpotRecipe) {
57+
DigSpotHandler.createDigSpot(level, pos, (RecipeHolder<DigSpotRecipe>) recipeHolder);
58+
return 1;
59+
} else {
60+
throw ERROR_UNKNOWN_RECIPE.create(context.getArgument("recipe", ResourceKey.class));
61+
}
62+
}))))
63+
.then(Commands.literal("fishingspot")
64+
.requires(BalmCommands.requirePermission(PERMISSION_LITTLEJOYS_FISHINGSPOT))
65+
.then(Commands.argument("position", BlockPosArgument.blockPos())
66+
.executes(context -> {
67+
final var level = context.getSource().getLevel();
68+
final var player = context.getSource().getPlayerOrException();
69+
final var pos = BlockPosArgument.getBlockPos(context, "position");
70+
return FishingSpotHandler.createFishingSpot(level, pos, player) ? 1 : 0;
71+
})
72+
.then(Commands.argument("recipe", ResourceKeyArgument.key(Registries.RECIPE))
73+
.executes(context -> {
74+
final var level = context.getSource().getLevel();
75+
final var pos = BlockPosArgument.getBlockPos(context, "position");
76+
final var recipeHolder = ResourceKeyArgument.getRecipe(context, "recipe");
77+
if (recipeHolder.value() instanceof FishingSpotRecipe) {
78+
FishingSpotHandler.createFishingSpot(level, pos, (RecipeHolder<FishingSpotRecipe>) recipeHolder);
79+
return 1;
80+
} else {
81+
throw ERROR_UNKNOWN_RECIPE.create(context.getArgument("recipe", ResourceKey.class));
82+
}
83+
}))))
84+
.then(Commands.literal("goldrush")
85+
.requires(BalmCommands.requirePermission(PERMISSION_LITTLEJOYS_GOLDRUSH))
86+
.then(Commands.argument("position", BlockPosArgument.blockPos())
87+
.executes(context -> {
88+
final var level = context.getSource().getLevel();
89+
final var player = context.getSource().getPlayerOrException();
90+
final var pos = BlockPosArgument.getBlockPos(context, "position");
91+
GoldRushHandler.startGoldRush(level, pos, level.getBlockState(pos), player);
92+
return 1;
93+
})
94+
.then(Commands.argument("recipe", ResourceKeyArgument.key(Registries.RECIPE))
95+
.executes(context -> {
96+
final var level = context.getSource().getLevel();
97+
final var player = context.getSource().getPlayerOrException();
98+
final var pos = BlockPosArgument.getBlockPos(context, "position");
99+
final var recipeHolder = ResourceKeyArgument.getRecipe(context, "recipe");
100+
if (recipeHolder.value() instanceof GoldRushRecipe) {
101+
GoldRushHandler.startGoldRush(level, pos, level.getBlockState(pos), player, (RecipeHolder<GoldRushRecipe>) recipeHolder);
102+
return 1;
103+
} else {
104+
throw ERROR_UNKNOWN_RECIPE.create(context.getArgument("recipe", ResourceKey.class));
105+
}
106+
}))))
107+
.then(Commands.literal("droprush")
108+
.requires(BalmCommands.requirePermission(PERMISSION_LITTLEJOYS_DROPRUSH))
109+
.then(Commands.argument("position", BlockPosArgument.blockPos())
110+
.executes(context -> {
111+
final var level = context.getSource().getLevel();
112+
final var player = context.getSource().getPlayerOrException();
113+
final var pos = BlockPosArgument.getBlockPos(context, "position");
114+
DropRushHandler.startDropRush(level, pos, level.getBlockState(pos), player);
115+
return 0;
116+
}).then(Commands.argument("recipe", ResourceKeyArgument.key(Registries.RECIPE))
117+
.executes(context -> {
118+
final var level = context.getSource().getLevel();
119+
final var player = context.getSource().getPlayerOrException();
120+
final var pos = BlockPosArgument.getBlockPos(context, "position");
121+
final var recipeHolder = ResourceKeyArgument.getRecipe(context, "recipe");
122+
if (recipeHolder.value() instanceof DropRushRecipe) {
123+
DropRushHandler.startDropRush(level, pos, player, (RecipeHolder<DropRushRecipe>) recipeHolder);
124+
return 1;
125+
} else {
126+
throw ERROR_UNKNOWN_RECIPE.create(context.getArgument("recipe", ResourceKey.class));
127+
}
128+
}))))
129+
);
130+
}
131+
}

common/src/main/java/net/blay09/mods/littlejoys/handler/DigSpotHandler.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,12 @@ public static void initialize() {
6767
return;
6868
}
6969

70-
findRecipe(level, aboveSurfacePos, player).ifPresentOrElse(recipeHolder -> {
71-
level.setBlock(aboveSurfacePos, ModBlocks.digSpot.defaultBlockState(), 3);
72-
if (level.getBlockEntity(aboveSurfacePos) instanceof DigSpotBlockEntity digSpot) {
73-
digSpot.setRecipeId(recipeHolder.id());
74-
}
75-
ChunkLimitManager.get(level).trackDigSpot(aboveSurfacePos);
70+
if (createDigSpot(level, aboveSurfacePos, player)) {
7671
littleJoysData.putInt(DIG_SPOT_COOLDOWN, Math.round(LittleJoysConfig.getActive().digSpots.spawnIntervalSeconds * 20));
77-
}, () -> littleJoysData.putInt(DIG_SPOT_COOLDOWN, 20));
72+
} else {
73+
// Cool down for a second if we failed
74+
littleJoysData.putInt(DIG_SPOT_COOLDOWN, 20);
75+
}
7876
} else {
7977
// If we have one in range, don't bother re-checking until 10 seconds have passed
8078
littleJoysData.putInt(DIG_SPOT_COOLDOWN, 200);
@@ -83,6 +81,21 @@ public static void initialize() {
8381
});
8482
}
8583

84+
public static boolean createDigSpot(ServerLevel level, BlockPos pos, ServerPlayer player) {
85+
return findRecipe(level, pos, player).map(recipeHolder -> {
86+
createDigSpot(level, pos, recipeHolder);
87+
return true;
88+
}).orElse(false);
89+
}
90+
91+
public static void createDigSpot(ServerLevel level, BlockPos pos, RecipeHolder<DigSpotRecipe> recipeHolder) {
92+
level.setBlock(pos, ModBlocks.digSpot.defaultBlockState(), 3);
93+
if (level.getBlockEntity(pos) instanceof DigSpotBlockEntity digSpot) {
94+
digSpot.setRecipeId(recipeHolder.id());
95+
}
96+
ChunkLimitManager.get(level).trackDigSpot(pos);
97+
}
98+
8699
private static BlockPos getOriginForNextSpawn(Player player) {
87100
final var projectForwardDistance = LittleJoysConfig.getActive().digSpots.projectForwardDistance;
88101
final var forwardDirection = player.getDirection();

common/src/main/java/net/blay09/mods/littlejoys/handler/DropRushHandler.java

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public static void initialize() {
6767
return;
6868
}
6969

70-
handleDropRushChance(serverLevel, event.getPos(), event.getState(), serverPlayer);
70+
rollForDropRush(serverLevel, event.getPos(), event.getState(), serverPlayer);
7171
});
7272

7373
Balm.getEvents().onTickEvent(TickType.ServerLevel, TickPhase.Start, level -> {
@@ -102,31 +102,42 @@ public static void initialize() {
102102
});
103103
}
104104

105-
public static void handleDropRushChance(ServerLevel level, BlockPos pos, BlockState state, ServerPlayer player) {
106-
findRecipe(level, pos, state, player).ifPresent(recipeHolder -> {
107-
final var recipe = recipeHolder.value();
108-
final var dropRushInstance = new DropRushInstance(
109-
player.getUUID(),
110-
pos,
111-
state,
112-
recipe.lootTable(),
113-
(int) Math.floor(20 * recipe.seconds()));
114-
final var lootParamsBuilder = (new LootParams.Builder(level))
115-
.withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos))
116-
.withParameter(LootContextParams.TOOL, ItemStack.EMPTY)
117-
.withOptionalParameter(LootContextParams.BLOCK_ENTITY, level.getBlockEntity(pos));
118-
final var lootTableId = recipe.lootTable();
105+
public static boolean rollForDropRush(ServerLevel level, BlockPos pos, BlockState state, ServerPlayer player) {
106+
return rollRecipe(level, pos, state, player, false).map(recipeHolder -> {
107+
startDropRush(level, pos, player, recipeHolder);
108+
return true;
109+
}).orElse(false);
110+
}
111+
112+
public static boolean startDropRush(ServerLevel level, BlockPos pos, BlockState state, ServerPlayer player) {
113+
return rollRecipe(level, pos, state, player, true).map(recipeHolder -> {
114+
startDropRush(level, pos, player, recipeHolder);
115+
return true;
116+
}).orElse(false);
117+
}
118+
119+
public static void startDropRush(ServerLevel level, BlockPos pos, ServerPlayer player, RecipeHolder<DropRushRecipe> recipeHolder) {
120+
final var recipe = recipeHolder.value();
121+
final var dropRushInstance = new DropRushInstance(
122+
player.getUUID(),
123+
pos,
124+
recipe.lootTable(),
125+
(int) Math.floor(20 * recipe.seconds()));
126+
final var lootParamsBuilder = (new LootParams.Builder(level))
127+
.withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos))
128+
.withParameter(LootContextParams.TOOL, ItemStack.EMPTY)
129+
.withOptionalParameter(LootContextParams.BLOCK_ENTITY, level.getBlockEntity(pos));
130+
final var lootTableId = recipe.lootTable();
119131
final var lootParams = lootParamsBuilder.withParameter(LootContextParams.BLOCK_STATE, level.getBlockState(pos))
120132
.create(LootContextParamSets.BLOCK);
121133
final var lootTable = level.getServer().reloadableRegistries().getLootTable(lootTableId);
122134
for (int i = 0; i < recipe.rolls(); i++) {
123135
lootTable.getRandomItems(lootParams).forEach(dropRushInstance::addDrop);
124136
}
125-
dropRushInstance.setTicksPerDrop(Math.max(DROP_TICKS / Math.max(1, dropRushInstance.getDrops().size()), 1));
126-
Balm.getNetworking().sendTo(player, new ClientboundStartDropRushPacket(dropRushInstance.getMaxTicks()));
127-
player.awardStat(ModStats.dropRushesTriggered);
128-
activeDropRushes.put(level.dimension(), pos, dropRushInstance);
129-
});
137+
dropRushInstance.setTicksPerDrop(Math.max(DROP_TICKS / Math.max(1, dropRushInstance.getDrops().size()), 1));
138+
Balm.getNetworking().sendTo(player, new ClientboundStartDropRushPacket(dropRushInstance.getMaxTicks()));
139+
player.awardStat(ModStats.dropRushesTriggered);
140+
activeDropRushes.put(level.dimension(), pos, dropRushInstance);
130141
}
131142

132143
private static void spawnDropRushItem(Level level, DropRushInstance dropRush, ItemStack itemStack) {
@@ -145,15 +156,15 @@ private static void spawnDropRushItem(Level level, DropRushInstance dropRush, It
145156
dropRush.addEntity(itemEntity);
146157
}
147158

148-
private static Optional<RecipeHolder<DropRushRecipe>> findRecipe(ServerLevel level, BlockPos pos, BlockState state, ServerPlayer player) {
159+
private static Optional<RecipeHolder<DropRushRecipe>> rollRecipe(ServerLevel level, BlockPos pos, BlockState state, ServerPlayer player, boolean force) {
149160
final var recipeManager = level.getServer().getRecipeManager();
150161
final var recipeMap = ((RecipeManagerAccessor) recipeManager).getRecipes();
151162
final var recipes = recipeMap.byType(ModRecipeTypes.dropRushRecipeType);
152163
final var candidates = new ArrayList<RecipeHolder<DropRushRecipe>>();
153164
final var baseChance = LittleJoysConfig.getActive().dropRush.baseChance;
154165
final var roll = random.nextFloat();
155166
for (final var recipeHolder : recipes) {
156-
if (isValidRecipeFor(recipeHolder, level, pos, state, player) && roll <= baseChance * recipeHolder.value().chanceMultiplier()) {
167+
if (isValidRecipeFor(recipeHolder, level, pos, state, player) && (force || roll <= baseChance * recipeHolder.value().chanceMultiplier())) {
157168
candidates.add(recipeHolder);
158169
}
159170
}

common/src/main/java/net/blay09/mods/littlejoys/handler/DropRushInstance.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import net.minecraft.core.BlockPos;
55
import net.minecraft.resources.ResourceKey;
66
import net.minecraft.resources.ResourceLocation;
7-
import net.minecraft.world.entity.player.Player;
87
import net.minecraft.world.item.ItemStack;
98
import net.minecraft.world.level.block.state.BlockState;
109
import net.minecraft.world.level.storage.loot.LootTable;
@@ -16,7 +15,6 @@
1615
public final class DropRushInstance {
1716
private final UUID playerId;
1817
private final BlockPos pos;
19-
private final BlockState initialState;
2018
private final ResourceKey<LootTable> lootTable;
2119
private final int maxTicks;
2220

@@ -27,10 +25,9 @@ public final class DropRushInstance {
2725
private int ticksPassed;
2826
private int dropCooldownTicks;
2927

30-
public DropRushInstance(UUID playerId, BlockPos pos, BlockState initialState, ResourceKey<LootTable> lootTable, int maxTicks) {
28+
public DropRushInstance(UUID playerId, BlockPos pos, ResourceKey<LootTable> lootTable, int maxTicks) {
3129
this.playerId = playerId;
3230
this.pos = pos;
33-
this.initialState = initialState;
3431
this.lootTable = lootTable;
3532
this.maxTicks = maxTicks;
3633
}
@@ -43,10 +40,6 @@ public BlockPos getPos() {
4340
return pos;
4441
}
4542

46-
public BlockState getInitialState() {
47-
return initialState;
48-
}
49-
5043
public ResourceKey<LootTable> getLootTable() {
5144
return lootTable;
5245
}

0 commit comments

Comments
 (0)