Skip to content

Commit

Permalink
More work on crafting bee and connect four
Browse files Browse the repository at this point in the history
  • Loading branch information
Matyrobbrt committed Oct 19, 2024
1 parent 239cd2f commit 82e9e59
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.lovetropics.minigames.common.content.connect4;

import com.lovetropics.lib.BlockBox;
import com.lovetropics.lib.codec.MoreCodecs;
import com.lovetropics.minigames.common.content.MinigameTexts;
import com.lovetropics.minigames.common.core.game.GameException;
import com.lovetropics.minigames.common.core.game.GameStopReason;
Expand Down Expand Up @@ -39,20 +40,28 @@ public class ConnectFourBehavior implements IGameBehavior {
public static final MapCodec<ConnectFourBehavior> CODEC = RecordCodecBuilder.mapCodec(in -> in.group(
Codec.unboundedMap(GameTeamKey.CODEC, GameBlock.CODEC.codec()).fieldOf("team_blocks").forGetter(c -> c.teamBlocks),
Codec.STRING.fieldOf("placing_region").forGetter(c -> c.placingRegionKey),
BlockState.CODEC.fieldOf("separator").forGetter(c -> c.separator),
BlockState.CODEC.fieldOf("blocker").forGetter(c -> c.blocker)
MoreCodecs.BLOCK_STATE.fieldOf("separator").forGetter(c -> c.separator),
MoreCodecs.BLOCK_STATE.fieldOf("blocker").forGetter(c -> c.blocker),
Codec.INT.fieldOf("grid_width").forGetter(c -> c.width),
Codec.INT.fieldOf("grid_height").forGetter(c -> c.height),
Codec.INT.optionalFieldOf("connect", 4).forGetter(c -> c.connectAmount)
).apply(in, ConnectFourBehavior::new));

private final Map<GameTeamKey, GameBlock> teamBlocks;
private final String placingRegionKey;
private final BlockState separator;
private final BlockState blocker;

public ConnectFourBehavior(Map<GameTeamKey, GameBlock> teamBlocks, String placingRegionKey, BlockState separator, BlockState blocker) {
private final int width, height, connectAmount;

public ConnectFourBehavior(Map<GameTeamKey, GameBlock> teamBlocks, String placingRegionKey, BlockState separator, BlockState blocker, int width, int height, int connectAmount) {
this.teamBlocks = teamBlocks;
this.placingRegionKey = placingRegionKey;
this.separator = separator;
this.blocker = blocker;
this.width = width;
this.height = height;
this.connectAmount = connectAmount;
}

private IGamePhase game;
Expand All @@ -74,7 +83,7 @@ public void register(IGamePhase game, EventRegistrar events) throws GameExceptio
placingRegion = game.mapRegions().getOrThrow(placingRegionKey);
teams = game.instanceState().getOrThrow(TeamState.KEY);

pieces = new GameTeamKey[7][6];
pieces = new GameTeamKey[width][height];
placedPieces = 0;

events.listen(GamePhaseEvents.START, this::onStart);
Expand Down Expand Up @@ -161,7 +170,7 @@ private void onBlockLanded(Level level, BlockPos pos, BlockState state) {
game.schedule(1.5f, () -> game.allPlayers().sendMessage(MinigameTexts.TEAM_WON.apply(teamConfig.styledName()).withStyle(ChatFormatting.GREEN), true));
game.schedule(5, () -> game.requestStop(GameStopReason.finished()));
} else {
if (placedPieces == 7 * 6) {
if (placedPieces == width * height) {
game.invoker(GameLogicEvents.GAME_OVER).onGameOver();

game.schedule(1.5f, () -> game.allPlayers().sendMessage(MinigameTexts.NOBODY_WON, true));
Expand Down Expand Up @@ -190,16 +199,16 @@ private boolean checkWin(int x, int y, GameTeamKey team) {
return true;
}

for (int offset = 0; offset < 4; ++offset) {
if (checkLine(x - 3 + offset, y, 1, 0, team)) { // horizontal
for (int offset = 0; offset < connectAmount; offset++) {
if (checkLine(x - (connectAmount - 1) + offset, y, 1, 0, team)) { // horizontal
return true;
}

if (checkLine(x - 3 + offset, y + 3 - offset, 1, -1, team)) { // leading diagonal
if (checkLine(x - (connectAmount + 1) + offset, y + (connectAmount - 1) - offset, 1, -1, team)) { // leading diagonal
return true;
}

if (checkLine(x - 3 + offset, y - 3 + offset, 1, 1, team)) { // trailing diagonal
if (checkLine(x - (connectAmount + 1) + offset, y - (connectAmount + 1) + offset, 1, 1, team)) { // trailing diagonal
return true;
}
}
Expand All @@ -209,7 +218,7 @@ private boolean checkWin(int x, int y, GameTeamKey team) {


private boolean checkLine(int xs, int ys, int dx, int dy, GameTeamKey team) {
for (int i = 0; i < 4; i++) {
for (int i = 0; i < connectAmount; i++) {
int x = xs + (dx * i);
int y = ys + (dy * i);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.lovetropics.minigames.common.core.game.behavior.event.GamePhaseEvents;
import com.lovetropics.minigames.common.core.game.behavior.event.GamePlayerEvents;
import com.lovetropics.minigames.common.core.game.client_state.GameClientState;
import com.lovetropics.minigames.common.core.game.client_state.GameClientStateTypes;
import com.lovetropics.minigames.common.core.game.client_state.instance.CraftingBeeCraftsClientState;
import com.lovetropics.minigames.common.core.game.player.PlayerSet;
import com.lovetropics.minigames.common.core.game.state.statistics.StatisticKey;
Expand Down Expand Up @@ -48,7 +49,7 @@

public class CraftingBeeBehavior implements IGameBehavior {
public static final MapCodec<CraftingBeeBehavior> CODEC = RecordCodecBuilder.mapCodec(in -> in.group(
RecipeSelector.CODEC.codec().listOf().fieldOf("selectors").forGetter(c -> c.selectors),
RecipeSelector.CODEC.listOf().fieldOf("selectors").forGetter(c -> c.selectors),
IngredientDecomposer.CODEC.codec().listOf().fieldOf("decomposers").forGetter(c -> c.decomposers),
Codec.INT.optionalFieldOf("hints_per_player", 3).forGetter(c -> c.allowedHints)
).apply(in, CraftingBeeBehavior::new));
Expand Down Expand Up @@ -81,6 +82,9 @@ public void register(IGamePhase game, EventRegistrar events) throws GameExceptio
events.listen(GamePhaseEvents.START, this::start);
events.listen(GamePlayerEvents.CRAFT, this::onCraft);
events.listen(GamePlayerEvents.USE_BLOCK, this::useBlock);

events.listen(GamePhaseEvents.STOP, reason -> GameClientState.removeFromPlayers(GameClientStateTypes.CRAFTING_BEE_CRAFTS.get(), game.allPlayers()));
events.listen(GamePlayerEvents.REMOVE, player -> GameClientState.removeFromPlayer(GameClientStateTypes.CRAFTING_BEE_CRAFTS.get(), player));
}

private void start() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,24 @@

import com.google.common.collect.BiMap;
import com.google.common.collect.ImmutableBiMap;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.Codec;
import com.mojang.serialization.MapCodec;
import net.minecraft.Util;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.RecipeType;

import java.util.List;
import java.util.Optional;

public interface RecipeSelector {
BiMap<String, MapCodec<? extends RecipeSelector>> TYPES = ImmutableBiMap.of("from_list", FromList.CODEC);
MapCodec<RecipeSelector> CODEC = Codec.STRING.dispatchMap(s -> TYPES.inverse().get(s.getType()), TYPES::get);
BiMap<String, MapCodec<? extends RecipeSelector>> TYPES = ImmutableBiMap.of("from_list", FromList.CODEC, "one_of", OneOf.CODEC, "from_item_tag", FromItemTag.CODEC);
Codec<RecipeSelector> CODEC = Codec.STRING.dispatch(s -> TYPES.inverse().get(s.getType()), TYPES::get);

SelectedRecipe select(ServerLevel level);

Expand All @@ -24,9 +31,58 @@ record FromList(List<ResourceLocation> recipes) implements RecipeSelector {

@Override
public SelectedRecipe select(ServerLevel level) {
var key = Util.getRandom(recipes, level.getRandom());
var recipe = level.getRecipeManager().byKey(key).orElseThrow(() -> new NullPointerException("Recipe " + key + " doesn't exist"));
return new SelectedRecipe(recipe);
Optional<RecipeHolder<?>> recipe = Optional.empty();
while (recipe.isEmpty()) {
var key = Util.getRandom(recipes, level.getRandom());
recipe = level.getRecipeManager().byKey(key);
if (recipe.isEmpty()) {
LogUtils.getLogger().error("Recipe '{}' doesn't exist", key);
}
}
return new SelectedRecipe(recipe.get());
}

@Override
public MapCodec<? extends RecipeSelector> getType() {
return CODEC;
}
}

record OneOf(List<RecipeSelector> selectors) implements RecipeSelector {
public static final MapCodec<OneOf> CODEC = MapCodec.assumeMapUnsafe(Codec.lazyInitialized(() -> RecipeSelector.CODEC.listOf().fieldOf("selectors")
.xmap(OneOf::new, OneOf::selectors).codec()));
@Override
public SelectedRecipe select(ServerLevel level) {
return Util.getRandom(selectors, level.getRandom()).select(level);
}

@Override
public MapCodec<? extends RecipeSelector> getType() {
return CODEC;
}
}

class FromItemTag implements RecipeSelector {
public static final MapCodec<FromItemTag> CODEC = TagKey.hashedCodec(Registries.ITEM).fieldOf("tag")
.xmap(FromItemTag::new, s -> s.tag);

private final TagKey<Item> tag;

private List<SelectedRecipe> cache;

public FromItemTag(TagKey<Item> tag) {
this.tag = tag;
}

@Override
public SelectedRecipe select(ServerLevel level) {
if (cache == null) {
cache = level.getRecipeManager().getAllRecipesFor(RecipeType.CRAFTING)
.stream().filter(h -> h.value().getResultItem(level.registryAccess()).is(tag) && h.id().getNamespace().equals(ResourceLocation.DEFAULT_NAMESPACE))
.map(SelectedRecipe::new)
.toList();
}
return Util.getRandom(cache, level.getRandom());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public record SimpleTagToItemDecomposer() implements IngredientDecomposer {
public @Nullable List<Ingredient> decompose(Ingredient ingredient) {
// This is a "hack". Neo will sometimes replace a vanilla recipe with a difference ingredient (#chests - #chests/trapped)
// we just resolve it and return the first item
if (ingredient.getCustomIngredient() instanceof DifferenceIngredient) {
if (ingredient.getCustomIngredient() != null) {
return List.of(Ingredient.of(ingredient.getItems()[0]));
} else if (ingredient.getValues().length == 1 && ingredient.getValues()[0] instanceof Ingredient.TagValue) {
var items = ingredient.getValues()[0].getItems();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.lovetropics.minigames.common.core.game.IGamePhase;
import com.lovetropics.minigames.common.core.game.behavior.IGameBehavior;
import com.lovetropics.minigames.common.core.game.behavior.event.EventRegistrar;
import com.lovetropics.minigames.common.core.game.behavior.event.GamePhaseEvents;
import com.lovetropics.minigames.common.core.game.client_state.GameClientState;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
Expand All @@ -15,5 +16,6 @@ public record SetGameClientStateBehavior(GameClientState state) implements IGame
@Override
public void register(IGamePhase game, EventRegistrar events) {
GameClientState.applyGlobally(state, events);
events.listen(GamePhaseEvents.STOP, reason -> GameClientState.removeFromPlayers(state.getType(), game.allPlayers()));
}
}

0 comments on commit 82e9e59

Please sign in to comment.