diff --git a/common/src/main/java/io/github/gaming32/bingo/Bingo.java b/common/src/main/java/io/github/gaming32/bingo/Bingo.java index 53e6f490..edf303dc 100644 --- a/common/src/main/java/io/github/gaming32/bingo/Bingo.java +++ b/common/src/main/java/io/github/gaming32/bingo/Bingo.java @@ -4,9 +4,9 @@ import com.mojang.logging.LogUtils; import io.github.gaming32.bingo.conditions.BingoConditions; import io.github.gaming32.bingo.data.BingoDifficulty; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoRegistries; import io.github.gaming32.bingo.data.BingoTag; +import io.github.gaming32.bingo.data.goal.GoalManager; import io.github.gaming32.bingo.data.icons.GoalIconType; import io.github.gaming32.bingo.data.progresstrackers.ProgressTrackerType; import io.github.gaming32.bingo.data.subs.BingoSubType; @@ -162,7 +162,7 @@ private static void registerDatapackRegistries() { private static void registerDataReloadListeners() { BingoPlatform.platform.registerDataReloadListeners(registrar -> { - registrar.register(BingoGoal.ReloadListener.ID, BingoGoal.ReloadListener::new); + registrar.register(GoalManager.ID, GoalManager::new); }); } diff --git a/common/src/main/java/io/github/gaming32/bingo/BingoCommand.java b/common/src/main/java/io/github/gaming32/bingo/BingoCommand.java index ffabbc34..a1d5e086 100644 --- a/common/src/main/java/io/github/gaming32/bingo/BingoCommand.java +++ b/common/src/main/java/io/github/gaming32/bingo/BingoCommand.java @@ -14,9 +14,10 @@ import io.github.gaming32.bingo.commandswitch.CommandSwitch; import io.github.gaming32.bingo.data.BingoDifficulties; import io.github.gaming32.bingo.data.BingoDifficulty; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoRegistries; import io.github.gaming32.bingo.data.BingoTag; +import io.github.gaming32.bingo.data.goal.GoalHolder; +import io.github.gaming32.bingo.data.goal.GoalManager; import io.github.gaming32.bingo.game.ActiveGoal; import io.github.gaming32.bingo.game.BingoBoard; import io.github.gaming32.bingo.game.BingoGame; @@ -148,7 +149,7 @@ public class BingoCommand { CommandSwitch.argument("--require-goal", ResourceLocationArgument.id()) .getter(ResourceLocationArgument::getId) .suggests((context, builder) -> SharedSuggestionProvider.suggestResource( - BingoGoal.getGoalIds(), builder + GoalManager.getGoalIds(), builder )) .buildRepeatable(HashSet::new); private static final CommandSwitch> EXCLUDE_TAG = @@ -419,9 +420,9 @@ private static int startGame(CommandContext context, int tea throw NO_TEAMS.create(); } - final List requiredGoals = requiredGoalIds.stream() + final List requiredGoals = requiredGoalIds.stream() .map(id -> { - final BingoGoal.GoalHolder goal = BingoGoal.getGoal(id); + final GoalHolder goal = GoalManager.getGoal(id); if (goal == null) { throwInBlock(UNKNOWN_GOAL.create(id)); } diff --git a/common/src/main/java/io/github/gaming32/bingo/data/BingoGoal.java b/common/src/main/java/io/github/gaming32/bingo/data/BingoGoal.java deleted file mode 100644 index d10b4b64..00000000 --- a/common/src/main/java/io/github/gaming32/bingo/data/BingoGoal.java +++ /dev/null @@ -1,628 +0,0 @@ -package io.github.gaming32.bingo.data; - -import com.demonwav.mcdev.annotations.Translatable; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.gson.JsonElement; -import com.mojang.datafixers.util.Pair; -import com.mojang.serialization.Codec; -import com.mojang.serialization.DataResult; -import com.mojang.serialization.Dynamic; -import com.mojang.serialization.DynamicOps; -import com.mojang.serialization.JsonOps; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import io.github.gaming32.bingo.Bingo; -import io.github.gaming32.bingo.data.icons.BlockIcon; -import io.github.gaming32.bingo.data.icons.EmptyIcon; -import io.github.gaming32.bingo.data.icons.GoalIcon; -import io.github.gaming32.bingo.data.progresstrackers.CriterionProgressTracker; -import io.github.gaming32.bingo.data.progresstrackers.EmptyProgressTracker; -import io.github.gaming32.bingo.data.progresstrackers.ProgressTracker; -import io.github.gaming32.bingo.data.subs.BingoSub; -import io.github.gaming32.bingo.game.ActiveGoal; -import io.github.gaming32.bingo.util.BingoCodecs; -import io.github.gaming32.bingo.util.BingoUtil; -import io.github.gaming32.bingo.util.ResourceLocations; -import net.minecraft.advancements.AdvancementRequirements; -import net.minecraft.advancements.Criterion; -import net.minecraft.advancements.CriterionTrigger; -import net.minecraft.core.Holder; -import net.minecraft.core.HolderGetter; -import net.minecraft.core.HolderLookup; -import net.minecraft.core.HolderSet; -import net.minecraft.core.RegistryCodecs; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.ComponentSerialization; -import net.minecraft.network.chat.HoverEvent; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.RegistryFixedCodec; -import net.minecraft.resources.RegistryOps; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.packs.resources.ResourceManager; -import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; -import net.minecraft.util.ExtraCodecs; -import net.minecraft.util.RandomSource; -import net.minecraft.util.profiling.ProfilerFiller; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.block.Block; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.OptionalInt; -import java.util.Set; -import java.util.function.Consumer; - -public class BingoGoal { - public static final Codec CODEC = RecordCodecBuilder.create( - instance -> instance.group( - Codec.unboundedMap(Codec.STRING, BingoSub.CODEC).optionalFieldOf("bingo_subs", Map.of()).forGetter(BingoGoal::getSubs), - Codec.unboundedMap(Codec.STRING, Codec.PASSTHROUGH).fieldOf("criteria").forGetter(BingoGoal::getCriteria), - AdvancementRequirements.CODEC.optionalFieldOf("requirements").forGetter(g -> Optional.of(g.requirements)), - ProgressTracker.CODEC.optionalFieldOf("progress", EmptyProgressTracker.INSTANCE).forGetter(BingoGoal::getProgress), - BingoCodecs.optionalDynamicField("required_count", BingoCodecs.EMPTY_DYNAMIC.createInt(1)).forGetter(BingoGoal::getRequiredCount), - RegistryCodecs.homogeneousList(BingoRegistries.TAG).optionalFieldOf("tags", HolderSet.empty()).forGetter(BingoGoal::getTags), - Codec.PASSTHROUGH.fieldOf("name").forGetter(BingoGoal::getName), - BingoCodecs.optionalDynamicField("tooltip").forGetter(BingoGoal::getTooltip), - ResourceLocation.CODEC.optionalFieldOf("tooltip_icon").forGetter(BingoGoal::getTooltipIcon), - BingoCodecs.optionalDynamicField("icon").forGetter(BingoGoal::getIcon), - BingoCodecs.optionalPositiveInt("infrequency").forGetter(BingoGoal::getInfrequency), - BingoCodecs.minifiedSetField(Codec.STRING, "antisynergy").forGetter(BingoGoal::getAntisynergy), - BingoCodecs.minifiedSetField(Codec.STRING, "catalyst").forGetter(BingoGoal::getCatalyst), - BingoCodecs.minifiedSetField(Codec.STRING, "reactant").forGetter(BingoGoal::getReactant), - RegistryFixedCodec.create(BingoRegistries.DIFFICULTY).fieldOf("difficulty").forGetter(BingoGoal::getDifficulty), - RegistryOps.retrieveGetter(Registries.TRIGGER_TYPE) - ).apply(instance, BingoGoal::new) - ).validate(BingoGoal::validate); - - private static Map goals = Map.of(); - private static Map> goalsByDifficulty = Map.of(); - - private final Map subs; - private final Map> criteria; - private final AdvancementRequirements requirements; - private final ProgressTracker progress; - private final Dynamic requiredCount; - private final HolderSet tags; - private final Dynamic name; - private final Dynamic tooltip; - private final Optional tooltipIcon; - private final Dynamic icon; - private final OptionalInt infrequency; - private final Set antisynergy; - private final Set catalyst; - private final Set reactant; - private final Holder difficulty; - - private final BingoTag.SpecialType specialType; - private final boolean requiredOnClient; - - public BingoGoal( - Map subs, - Map> criteria, - Optional requirements, - ProgressTracker progress, - Dynamic requiredCount, - HolderSet tags, - Dynamic name, - Dynamic tooltip, - Optional tooltipIcon, - Dynamic icon, - OptionalInt infrequency, - Collection antisynergy, - Collection catalyst, - Collection reactant, - Holder difficulty, - HolderGetter> triggerTypes - ) { - this.subs = ImmutableMap.copyOf(subs); - this.criteria = ImmutableMap.copyOf(criteria); - this.requirements = requirements.orElseGet(() -> AdvancementRequirements.allOf(criteria.keySet())); - this.progress = progress; - this.requiredCount = requiredCount; - this.tags = tags; - this.name = name; - this.tooltip = tooltip; - this.tooltipIcon = tooltipIcon; - this.icon = icon; - this.infrequency = infrequency; - this.antisynergy = ImmutableSet.copyOf(antisynergy); - this.catalyst = ImmutableSet.copyOf(catalyst); - this.reactant = ImmutableSet.copyOf(reactant); - this.difficulty = difficulty; - - BingoTag.SpecialType specialType = BingoTag.SpecialType.NONE; - for (final var tag : tags) { - if (tag.value().specialType() != BingoTag.SpecialType.NONE) { - specialType = tag.value().specialType(); - break; - } - } - this.specialType = specialType; - - boolean requiresClient = false; - final var triggerCodec = ResourceKey.codec(Registries.TRIGGER_TYPE); - for (final Dynamic criterion : criteria.values()) { - final var triggerKey = criterion.get("trigger") - .flatMap(triggerCodec::parse) - .result() - .orElse(null); - if (triggerKey == null) continue; - final var trigger = triggerTypes.get(triggerKey); - if (trigger.isPresent() && trigger.get().value().bingo$requiresClientCode()) { - requiresClient = true; - break; - } - } - this.requiredOnClient = requiresClient; - } - - public DataResult validate() { - final DataResult requirementsResult = requirements.validate(criteria.keySet()); - if (requirementsResult.error().isPresent()) { - return DataResult.error(requirementsResult.error().get()::message); - } - - final var triggerCodec = ResourceKey.codec(Registries.TRIGGER_TYPE); - for (final Dynamic criterion : criteria.values()) { - final var triggerKey = criterion.get("trigger").flatMap(triggerCodec::parse); - if (triggerKey.isError()) { - //noinspection OptionalGetWithoutIsPresent - return DataResult.error(triggerKey.error().get().messageSupplier()); - } - } - - for (final var tag : tags) { - final BingoTag.SpecialType type = tag.value().specialType(); - if (type != BingoTag.SpecialType.NONE && type != specialType) { - return DataResult.error(() -> "Inconsistent specialTypes: " + type + " does not match " + specialType); - } - } - if (specialType == BingoTag.SpecialType.FINISH && requirements.size() != 1) { - return DataResult.error(() -> "\"finish\" goals must have only ORed requirements"); - } - - final DataResult progressResult = progress.validate(this); - if (progressResult.error().isPresent()) { - return DataResult.error(progressResult.error().get()::message); - } - - return DataResult.success(this); - } - - public static Set getGoalIds() { - return goals.keySet(); - } - - @Nullable - public static BingoGoal.GoalHolder getGoal(ResourceLocation id) { - return goals.get(id); - } - - public static List getGoalsByDifficulty(int difficulty) { - if (difficulty < 0) { - throw new IllegalArgumentException("Difficulties < 0 aren't allowed"); - } - return goalsByDifficulty.getOrDefault(difficulty, List.of()); - } - - public Map getSubs() { - return subs; - } - - public Map> getCriteria() { - return criteria; - } - - public AdvancementRequirements getRequirements() { - return requirements; - } - - public ProgressTracker getProgress() { - return progress; - } - - public Dynamic getRequiredCount() { - return requiredCount; - } - - public HolderSet getTags() { - return tags; - } - - public Dynamic getName() { - return name; - } - - public Dynamic getTooltip() { - return tooltip; - } - - public Optional getTooltipIcon() { - return tooltipIcon; - } - - public Dynamic getIcon() { - return icon; - } - - public OptionalInt getInfrequency() { - return infrequency; - } - - public Set getAntisynergy() { - return antisynergy; - } - - public Set getCatalyst() { - return catalyst; - } - - public Set getReactant() { - return reactant; - } - - public Holder getDifficulty() { - return difficulty; - } - - public BingoTag.SpecialType getSpecialType() { - return specialType; - } - - public boolean isRequiredOnClient() { - return requiredOnClient; - } - - public Map> buildSubs(RandomSource rand) { - final Map> result = new LinkedHashMap<>(); - for (final var entry : subs.entrySet()) { - result.put(entry.getKey(), entry.getValue().substitute(result, rand)); - } - return ImmutableMap.copyOf(result); - } - - public MutableComponent buildName(Map> referable, RandomSource rand) { - return BingoUtil.ensureHasFallback(BingoUtil.fromDynamic( - ComponentSerialization.CODEC, - performSubstitutions(name, referable, rand) - ).copy()); - } - - public Optional buildTooltip(Map> referable, RandomSource rand) { - if (tooltip.getValue() == tooltip.getOps().empty()) { - return Optional.empty(); - } - return Optional.of( - BingoUtil.ensureHasFallback(BingoUtil.fromDynamic( - ComponentSerialization.CODEC, - performSubstitutions(tooltip, referable, rand) - ).copy()) - ); - } - - public GoalIcon buildIcon(Map> referable, RandomSource rand) { - if (icon.getValue() == icon.getOps().empty()) { - return EmptyIcon.INSTANCE; - } - return BingoUtil.fromDynamic(GoalIcon.CODEC, performSubstitutions(icon, referable, rand)); - } - - public Map> buildCriteria(Map> referable, RandomSource rand) { - final ImmutableMap.Builder> result = ImmutableMap.builderWithExpectedSize(criteria.size()); - for (final var entry : criteria.entrySet()) { - result.put(entry.getKey(), BingoUtil.fromDynamic(Criterion.CODEC, performSubstitutions(entry.getValue(), referable, rand))); - } - return result.build(); - } - - public int buildRequiredCount(Map> referable, RandomSource rand) { - return BingoUtil.fromDynamic(ExtraCodecs.POSITIVE_INT, performSubstitutions(requiredCount, referable, rand)); - } - - public static Dynamic performSubstitutions( - Dynamic value, - Map> referable, - RandomSource rand - ) { - final var asList = value.asStreamOpt(); - if (asList.result().isPresent()) { - return value.createList( - asList.result().get().map(d -> performSubstitutions(d, referable, rand).convert(d.getOps())) - ); - } - - if (value.get("bingo_type").result().isPresent()) { - return BingoUtil.fromDynamic(BingoSub.INNER_CODEC, value).substitute(referable, rand); - } - - final var asMap = value.asMapOpt(); - if (asMap.result().isPresent()) { - return value.createMap(asMap.result().get() - .collect(ImmutableMap.toImmutableMap( - Pair::getFirst, - e -> performSubstitutions(e.getSecond(), referable, rand).convert(e.getSecond().getOps()) - )) - ); - } - - return value; - } - - public static Builder builder(ResourceLocation id) { - return new Builder(id); - } - - public record GoalHolder(ResourceLocation id, BingoGoal goal) { - public ActiveGoal build(RandomSource rand) { - final Map> subs = goal.buildSubs(rand); - final Optional tooltip = goal.buildTooltip(subs, rand); - final MutableComponent name = goal.buildName(subs, rand); - tooltip.ifPresent(t -> name.withStyle(s -> s - .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, t)) - )); - return new ActiveGoal( - id, name, - tooltip, goal.tooltipIcon, - goal.buildIcon(subs, rand), - goal.buildCriteria(subs, rand), - goal.buildRequiredCount(subs, rand), - Optional.of(goal.difficulty), - goal.requirements, - goal.specialType, - goal.progress - ); - } - - @Override - public String toString() { - return id.toString(); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof GoalHolder h && id.equals(h.id); - } - - @Override - public int hashCode() { - return id.hashCode(); - } - } - - public static final class Builder { - public static final ThreadLocal> JSON_OPS = ThreadLocal.withInitial(() -> JsonOps.INSTANCE); - - private final ResourceLocation id; - private final ImmutableMap.Builder subs = ImmutableMap.builder(); - private final ImmutableMap.Builder> criteria = ImmutableMap.builder(); - private Optional requirements = Optional.empty(); - private ProgressTracker progress = EmptyProgressTracker.INSTANCE; - private Dynamic requiredCount = BingoCodecs.EMPTY_DYNAMIC.createInt(1); - private AdvancementRequirements.Strategy requirementsStrategy = AdvancementRequirements.Strategy.AND; - private final ImmutableSet.Builder> tags = ImmutableSet.builder(); - private Optional> name = Optional.empty(); - private Dynamic tooltip = BingoCodecs.EMPTY_DYNAMIC; - private Optional tooltipIcon = Optional.empty(); - private Dynamic icon = BingoCodecs.EMPTY_DYNAMIC; - private OptionalInt infrequency = OptionalInt.empty(); - private ImmutableSet.Builder antisynergy = ImmutableSet.builder(); - private final ImmutableSet.Builder catalyst = ImmutableSet.builder(); - private final ImmutableSet.Builder reactant = ImmutableSet.builder(); - private Optional> difficulty; - - private Builder(ResourceLocation id) { - this.id = id; - } - - public Builder sub(String key, BingoSub sub) { - this.subs.put(key, sub); - return this; - } - - public Builder criterion(String key, Criterion criterion) { - return criterion(key, criterion, subber -> {}); - } - - public Builder criterion(String key, Criterion criterion, Consumer subber) { - JsonSubber json = new JsonSubber(Criterion.CODEC.encodeStart(JSON_OPS.get(), criterion).getOrThrow()); - subber.accept(json); - this.criteria.put(key, new Dynamic<>(JsonOps.INSTANCE, json.json())); - return this; - } - - public Builder requirements(AdvancementRequirements requirements) { - this.requirements = Optional.of(requirements); - return this; - } - - public Builder requirements(AdvancementRequirements.Strategy strategy) { - this.requirementsStrategy = strategy; - return this; - } - - public Builder progress(ProgressTracker progress) { - this.progress = progress; - return this; - } - - public Builder progress(String criterion) { - return progress(CriterionProgressTracker.unscaled(criterion)); - } - - public Builder requiredCount(int requiredCount) { - this.requiredCount = BingoCodecs.EMPTY_DYNAMIC.createInt(requiredCount); - return this; - } - - public Builder requiredCount(BingoSub requiredCountSub) { - this.requiredCount = BingoUtil.toDynamic(BingoSub.INNER_CODEC, requiredCountSub); - return this; - } - - @SafeVarargs - public final Builder tags(ResourceKey... tags) { - this.tags.add(tags); - return this; - } - - public Builder name(@Translatable(prefix = "bingo.goal.") String name) { - return this.name(Component.translatable("bingo.goal." + name)); - } - - public Builder name(Component name) { - return this.name(name, subber -> {}); - } - - public Builder name(Component name, Consumer subber) { - JsonSubber json = new JsonSubber(ComponentSerialization.CODEC.encodeStart(JSON_OPS.get(), name).getOrThrow()); - subber.accept(json); - this.name = Optional.of(new Dynamic<>(JsonOps.INSTANCE, json.json())); - return this; - } - - public Builder tooltip(@Translatable(prefix = "bingo.goal.", suffix = ".tooltip") String tooltip) { - return this.tooltip(Component.translatable("bingo.goal." + tooltip + ".tooltip")); - } - - public Builder tooltip(Component tooltip) { - return this.tooltip(tooltip, subber -> {}); - } - - public Builder tooltip(Component tooltip, Consumer subber) { - JsonSubber json = new JsonSubber(ComponentSerialization.CODEC.encodeStart(JSON_OPS.get(), tooltip).getOrThrow()); - subber.accept(json); - this.tooltip = new Dynamic<>(JsonOps.INSTANCE, json.json()); - return this; - } - - public Builder tooltipIcon(ResourceLocation tooltipIcon) { - this.tooltipIcon = Optional.of(tooltipIcon); - return this; - } - - public Builder icon(Object icon) { - return icon(icon, subber -> {}); - } - - public Builder icon(Object icon, Consumer subber) { - return icon(GoalIcon.infer(icon), subber); - } - - public Builder icon(Block icon, ItemLike fallback) { - return icon(icon, fallback, subber -> {}); - } - - public Builder icon(Block icon, ItemLike fallback, Consumer subber) { - return icon(BlockIcon.ofBlockAndItem(icon, fallback), subber); - } - - public Builder icon(GoalIcon icon) { - return icon(icon, subber -> {}); - } - - public Builder icon(GoalIcon icon, Consumer subber) { - JsonSubber jsonSubber = new JsonSubber(GoalIcon.CODEC.encodeStart(JSON_OPS.get(), icon).getOrThrow()); - subber.accept(jsonSubber); - this.icon = new Dynamic<>(JsonOps.INSTANCE, jsonSubber.json()); - return this; - } - - public Builder infrequency(int infrequency) { - this.infrequency = OptionalInt.of(infrequency); - return this; - } - - public Builder setAntisynergy(String... antisynergy) { - this.antisynergy = ImmutableSet.builderWithExpectedSize(antisynergy.length); - return this.antisynergy(antisynergy); - } - - public Builder antisynergy(String... antisynergy) { - this.antisynergy.add(antisynergy); - return this; - } - - public Builder catalyst(String... catalyst) { - this.catalyst.add(catalyst); - return this; - } - - public Builder reactant(String... reactant) { - this.reactant.add(reactant); - return this; - } - - public Builder difficulty(ResourceKey difficulty) { - this.difficulty = Optional.of(difficulty); - return this; - } - - public GoalHolder build(HolderLookup.Provider registries) { - final Map> criteria = this.criteria.build(); - return new GoalHolder(id, new BingoGoal( - subs.buildOrThrow(), - criteria, - requirements.or(() -> Optional.of(requirementsStrategy.create(criteria.keySet()))), - progress, - requiredCount, - HolderSet.direct(registries.lookupOrThrow(BingoRegistries.TAG)::getOrThrow, tags.build()), - name.orElseThrow(() -> new IllegalStateException("Bingo goal name has not been set")), - tooltip, - tooltipIcon, - icon, - infrequency, - antisynergy.build(), - catalyst.build(), - reactant.build(), - registries.lookupOrThrow(BingoRegistries.DIFFICULTY).getOrThrow( - difficulty.orElseThrow(() -> new IllegalStateException("Bingo goal difficulty has not been set")) - ), - registries.lookupOrThrow(Registries.TRIGGER_TYPE) - )); - } - - } - - public static class ReloadListener extends SimpleJsonResourceReloadListener { - public static final ResourceLocation ID = ResourceLocations.bingo("goals"); - - public ReloadListener(HolderLookup.Provider registries) { - super(registries, CODEC, "bingo/goal"); - } - - @NotNull - @Override - public String getName() { - return ID.toString(); - } - - @Override - protected void apply(Map goals, ResourceManager resourceManager, ProfilerFiller profiler) { - final ImmutableMap.Builder result = ImmutableMap.builder(); - final Map> byDifficulty = new HashMap<>(); - for (final var entry : goals.entrySet()) { - final var goal = entry.getValue(); - final GoalHolder holder = new GoalHolder(entry.getKey(), goal); - result.put(holder.id, holder); - byDifficulty.computeIfAbsent(goal.difficulty.value().number(), k -> ImmutableList.builder()).add(holder); - } - BingoGoal.goals = result.build(); - goalsByDifficulty = byDifficulty.entrySet() - .stream() - .collect(ImmutableMap.toImmutableMap( - Map.Entry::getKey, - e -> e.getValue().build() - )); - Bingo.LOGGER.info("Loaded {} bingo goals", BingoGoal.goals.size()); - } - } -} diff --git a/common/src/main/java/io/github/gaming32/bingo/data/goal/BingoGoal.java b/common/src/main/java/io/github/gaming32/bingo/data/goal/BingoGoal.java new file mode 100644 index 00000000..a7b6d47f --- /dev/null +++ b/common/src/main/java/io/github/gaming32/bingo/data/goal/BingoGoal.java @@ -0,0 +1,295 @@ +package io.github.gaming32.bingo.data.goal; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.Dynamic; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.github.gaming32.bingo.data.BingoDifficulty; +import io.github.gaming32.bingo.data.BingoRegistries; +import io.github.gaming32.bingo.data.BingoTag; +import io.github.gaming32.bingo.data.icons.EmptyIcon; +import io.github.gaming32.bingo.data.icons.GoalIcon; +import io.github.gaming32.bingo.data.progresstrackers.EmptyProgressTracker; +import io.github.gaming32.bingo.data.progresstrackers.ProgressTracker; +import io.github.gaming32.bingo.data.subs.BingoSub; +import io.github.gaming32.bingo.util.BingoCodecs; +import io.github.gaming32.bingo.util.BingoUtil; +import net.minecraft.advancements.AdvancementRequirements; +import net.minecraft.advancements.Criterion; +import net.minecraft.advancements.CriterionTrigger; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderGetter; +import net.minecraft.core.HolderSet; +import net.minecraft.core.RegistryCodecs; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.RegistryFixedCodec; +import net.minecraft.resources.RegistryOps; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.ExtraCodecs; +import net.minecraft.util.RandomSource; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Optional; +import java.util.OptionalInt; +import java.util.Set; + +public class BingoGoal { + public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + Codec.unboundedMap(Codec.STRING, BingoSub.CODEC).optionalFieldOf("bingo_subs", Map.of()).forGetter(BingoGoal::getSubs), + Codec.unboundedMap(Codec.STRING, Codec.PASSTHROUGH).fieldOf("criteria").forGetter(BingoGoal::getCriteria), + AdvancementRequirements.CODEC.optionalFieldOf("requirements").forGetter(g -> Optional.of(g.requirements)), + ProgressTracker.CODEC.optionalFieldOf("progress", EmptyProgressTracker.INSTANCE).forGetter(BingoGoal::getProgress), + BingoCodecs.optionalDynamicField("required_count", BingoCodecs.EMPTY_DYNAMIC.createInt(1)).forGetter(BingoGoal::getRequiredCount), + RegistryCodecs.homogeneousList(BingoRegistries.TAG).optionalFieldOf("tags", HolderSet.empty()).forGetter(BingoGoal::getTags), + Codec.PASSTHROUGH.fieldOf("name").forGetter(BingoGoal::getName), + BingoCodecs.optionalDynamicField("tooltip").forGetter(BingoGoal::getTooltip), + ResourceLocation.CODEC.optionalFieldOf("tooltip_icon").forGetter(BingoGoal::getTooltipIcon), + BingoCodecs.optionalDynamicField("icon").forGetter(BingoGoal::getIcon), + BingoCodecs.optionalPositiveInt("infrequency").forGetter(BingoGoal::getInfrequency), + BingoCodecs.minifiedSetField(Codec.STRING, "antisynergy").forGetter(BingoGoal::getAntisynergy), + BingoCodecs.minifiedSetField(Codec.STRING, "catalyst").forGetter(BingoGoal::getCatalyst), + BingoCodecs.minifiedSetField(Codec.STRING, "reactant").forGetter(BingoGoal::getReactant), + RegistryFixedCodec.create(BingoRegistries.DIFFICULTY).fieldOf("difficulty").forGetter(BingoGoal::getDifficulty), + RegistryOps.retrieveGetter(Registries.TRIGGER_TYPE) + ).apply(instance, BingoGoal::new) + ).validate(BingoGoal::validate); + + private final Map subs; + private final Map> criteria; + private final AdvancementRequirements requirements; + private final ProgressTracker progress; + private final Dynamic requiredCount; + private final HolderSet tags; + private final Dynamic name; + private final Dynamic tooltip; + private final Optional tooltipIcon; + private final Dynamic icon; + private final OptionalInt infrequency; + private final Set antisynergy; + private final Set catalyst; + private final Set reactant; + private final Holder difficulty; + + private final BingoTag.SpecialType specialType; + private final boolean requiredOnClient; + + public BingoGoal( + Map subs, + Map> criteria, + Optional requirements, + ProgressTracker progress, + Dynamic requiredCount, + HolderSet tags, + Dynamic name, + Dynamic tooltip, + Optional tooltipIcon, + Dynamic icon, + OptionalInt infrequency, + Collection antisynergy, + Collection catalyst, + Collection reactant, + Holder difficulty, + HolderGetter> triggerTypes + ) { + this.subs = ImmutableMap.copyOf(subs); + this.criteria = ImmutableMap.copyOf(criteria); + this.requirements = requirements.orElseGet(() -> AdvancementRequirements.allOf(criteria.keySet())); + this.progress = progress; + this.requiredCount = requiredCount; + this.tags = tags; + this.name = name; + this.tooltip = tooltip; + this.tooltipIcon = tooltipIcon; + this.icon = icon; + this.infrequency = infrequency; + this.antisynergy = ImmutableSet.copyOf(antisynergy); + this.catalyst = ImmutableSet.copyOf(catalyst); + this.reactant = ImmutableSet.copyOf(reactant); + this.difficulty = difficulty; + + BingoTag.SpecialType specialType = BingoTag.SpecialType.NONE; + for (final var tag : tags) { + if (tag.value().specialType() != BingoTag.SpecialType.NONE) { + specialType = tag.value().specialType(); + break; + } + } + this.specialType = specialType; + + boolean requiresClient = false; + final var triggerCodec = ResourceKey.codec(Registries.TRIGGER_TYPE); + for (final Dynamic criterion : criteria.values()) { + final var triggerKey = criterion.get("trigger") + .flatMap(triggerCodec::parse) + .result() + .orElse(null); + if (triggerKey == null) continue; + final var trigger = triggerTypes.get(triggerKey); + if (trigger.isPresent() && trigger.get().value().bingo$requiresClientCode()) { + requiresClient = true; + break; + } + } + this.requiredOnClient = requiresClient; + } + + public DataResult validate() { + final DataResult requirementsResult = requirements.validate(criteria.keySet()); + if (requirementsResult.error().isPresent()) { + return DataResult.error(requirementsResult.error().get()::message); + } + + final var triggerCodec = ResourceKey.codec(Registries.TRIGGER_TYPE); + for (final Dynamic criterion : criteria.values()) { + final var triggerKey = criterion.get("trigger").flatMap(triggerCodec::parse); + if (triggerKey.isError()) { + //noinspection OptionalGetWithoutIsPresent + return DataResult.error(triggerKey.error().get().messageSupplier()); + } + } + + for (final var tag : tags) { + final BingoTag.SpecialType type = tag.value().specialType(); + if (type != BingoTag.SpecialType.NONE && type != specialType) { + return DataResult.error(() -> "Inconsistent specialTypes: " + type + " does not match " + specialType); + } + } + if (specialType == BingoTag.SpecialType.FINISH && requirements.size() != 1) { + return DataResult.error(() -> "\"finish\" goals must have only ORed requirements"); + } + + final DataResult progressResult = progress.validate(this); + if (progressResult.error().isPresent()) { + return DataResult.error(progressResult.error().get()::message); + } + + return DataResult.success(this); + } + + public Map getSubs() { + return subs; + } + + public Map> getCriteria() { + return criteria; + } + + public AdvancementRequirements getRequirements() { + return requirements; + } + + public ProgressTracker getProgress() { + return progress; + } + + public Dynamic getRequiredCount() { + return requiredCount; + } + + public HolderSet getTags() { + return tags; + } + + public Dynamic getName() { + return name; + } + + public Dynamic getTooltip() { + return tooltip; + } + + public Optional getTooltipIcon() { + return tooltipIcon; + } + + public Dynamic getIcon() { + return icon; + } + + public OptionalInt getInfrequency() { + return infrequency; + } + + public Set getAntisynergy() { + return antisynergy; + } + + public Set getCatalyst() { + return catalyst; + } + + public Set getReactant() { + return reactant; + } + + public Holder getDifficulty() { + return difficulty; + } + + public BingoTag.SpecialType getSpecialType() { + return specialType; + } + + public boolean isRequiredOnClient() { + return requiredOnClient; + } + + public Map> buildSubs(RandomSource rand) { + final Map> result = new LinkedHashMap<>(); + for (final var entry : subs.entrySet()) { + result.put(entry.getKey(), entry.getValue().substitute(result, rand)); + } + return ImmutableMap.copyOf(result); + } + + public MutableComponent buildName(Map> referable, RandomSource rand) { + return BingoUtil.ensureHasFallback(BingoUtil.fromDynamic( + ComponentSerialization.CODEC, + GoalSubstitutionSystem.performSubstitutions(name, referable, rand) + ).copy()); + } + + public Optional buildTooltip(Map> referable, RandomSource rand) { + if (tooltip.getValue() == tooltip.getOps().empty()) { + return Optional.empty(); + } + return Optional.of( + BingoUtil.ensureHasFallback(BingoUtil.fromDynamic( + ComponentSerialization.CODEC, + GoalSubstitutionSystem.performSubstitutions(tooltip, referable, rand) + ).copy()) + ); + } + + public GoalIcon buildIcon(Map> referable, RandomSource rand) { + if (icon.getValue() == icon.getOps().empty()) { + return EmptyIcon.INSTANCE; + } + return BingoUtil.fromDynamic(GoalIcon.CODEC, GoalSubstitutionSystem.performSubstitutions(icon, referable, rand)); + } + + public Map> buildCriteria(Map> referable, RandomSource rand) { + final ImmutableMap.Builder> result = ImmutableMap.builderWithExpectedSize(criteria.size()); + for (final var entry : criteria.entrySet()) { + result.put(entry.getKey(), BingoUtil.fromDynamic(Criterion.CODEC, GoalSubstitutionSystem.performSubstitutions(entry.getValue(), referable, rand))); + } + return result.build(); + } + + public int buildRequiredCount(Map> referable, RandomSource rand) { + return BingoUtil.fromDynamic(ExtraCodecs.POSITIVE_INT, GoalSubstitutionSystem.performSubstitutions(requiredCount, referable, rand)); + } + + public static GoalBuilder builder(ResourceLocation id) { + return new GoalBuilder(id); + } +} diff --git a/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalBuilder.java b/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalBuilder.java new file mode 100644 index 00000000..66134407 --- /dev/null +++ b/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalBuilder.java @@ -0,0 +1,236 @@ +package io.github.gaming32.bingo.data.goal; + +import com.demonwav.mcdev.annotations.Translatable; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.gson.JsonElement; +import com.mojang.serialization.Dynamic; +import com.mojang.serialization.DynamicOps; +import com.mojang.serialization.JsonOps; +import io.github.gaming32.bingo.data.BingoDifficulty; +import io.github.gaming32.bingo.data.BingoRegistries; +import io.github.gaming32.bingo.data.BingoTag; +import io.github.gaming32.bingo.data.JsonSubber; +import io.github.gaming32.bingo.data.icons.BlockIcon; +import io.github.gaming32.bingo.data.icons.GoalIcon; +import io.github.gaming32.bingo.data.progresstrackers.CriterionProgressTracker; +import io.github.gaming32.bingo.data.progresstrackers.EmptyProgressTracker; +import io.github.gaming32.bingo.data.progresstrackers.ProgressTracker; +import io.github.gaming32.bingo.data.subs.BingoSub; +import io.github.gaming32.bingo.util.BingoCodecs; +import io.github.gaming32.bingo.util.BingoUtil; +import net.minecraft.advancements.AdvancementRequirements; +import net.minecraft.advancements.Criterion; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.HolderSet; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.Block; + +import java.util.Map; +import java.util.Optional; +import java.util.OptionalInt; +import java.util.function.Consumer; + +public final class GoalBuilder { + public static final ThreadLocal> JSON_OPS = ThreadLocal.withInitial(() -> JsonOps.INSTANCE); + + private final ResourceLocation id; + private final ImmutableMap.Builder subs = ImmutableMap.builder(); + private final ImmutableMap.Builder> criteria = ImmutableMap.builder(); + private Optional requirements = Optional.empty(); + private ProgressTracker progress = EmptyProgressTracker.INSTANCE; + private Dynamic requiredCount = BingoCodecs.EMPTY_DYNAMIC.createInt(1); + private AdvancementRequirements.Strategy requirementsStrategy = AdvancementRequirements.Strategy.AND; + private final ImmutableSet.Builder> tags = ImmutableSet.builder(); + private Optional> name = Optional.empty(); + private Dynamic tooltip = BingoCodecs.EMPTY_DYNAMIC; + private Optional tooltipIcon = Optional.empty(); + private Dynamic icon = BingoCodecs.EMPTY_DYNAMIC; + private OptionalInt infrequency = OptionalInt.empty(); + private ImmutableSet.Builder antisynergy = ImmutableSet.builder(); + private final ImmutableSet.Builder catalyst = ImmutableSet.builder(); + private final ImmutableSet.Builder reactant = ImmutableSet.builder(); + private Optional> difficulty; + + GoalBuilder(ResourceLocation id) { + this.id = id; + } + + public GoalBuilder sub(String key, BingoSub sub) { + this.subs.put(key, sub); + return this; + } + + public GoalBuilder criterion(String key, Criterion criterion) { + return criterion(key, criterion, subber -> { + }); + } + + public GoalBuilder criterion(String key, Criterion criterion, Consumer subber) { + JsonSubber json = new JsonSubber(Criterion.CODEC.encodeStart(JSON_OPS.get(), criterion).getOrThrow()); + subber.accept(json); + this.criteria.put(key, new Dynamic<>(JsonOps.INSTANCE, json.json())); + return this; + } + + public GoalBuilder requirements(AdvancementRequirements requirements) { + this.requirements = Optional.of(requirements); + return this; + } + + public GoalBuilder requirements(AdvancementRequirements.Strategy strategy) { + this.requirementsStrategy = strategy; + return this; + } + + public GoalBuilder progress(ProgressTracker progress) { + this.progress = progress; + return this; + } + + public GoalBuilder progress(String criterion) { + return progress(CriterionProgressTracker.unscaled(criterion)); + } + + public GoalBuilder requiredCount(int requiredCount) { + this.requiredCount = BingoCodecs.EMPTY_DYNAMIC.createInt(requiredCount); + return this; + } + + public GoalBuilder requiredCount(BingoSub requiredCountSub) { + this.requiredCount = BingoUtil.toDynamic(BingoSub.INNER_CODEC, requiredCountSub); + return this; + } + + @SafeVarargs + public final GoalBuilder tags(ResourceKey... tags) { + this.tags.add(tags); + return this; + } + + public GoalBuilder name(@Translatable(prefix = "bingo.goal.") String name) { + return this.name(Component.translatable("bingo.goal." + name)); + } + + public GoalBuilder name(Component name) { + return this.name(name, subber -> { + }); + } + + public GoalBuilder name(Component name, Consumer subber) { + JsonSubber json = new JsonSubber(ComponentSerialization.CODEC.encodeStart(JSON_OPS.get(), name).getOrThrow()); + subber.accept(json); + this.name = Optional.of(new Dynamic<>(JsonOps.INSTANCE, json.json())); + return this; + } + + public GoalBuilder tooltip(@Translatable(prefix = "bingo.goal.", suffix = ".tooltip") String tooltip) { + return this.tooltip(Component.translatable("bingo.goal." + tooltip + ".tooltip")); + } + + public GoalBuilder tooltip(Component tooltip) { + return this.tooltip(tooltip, subber -> { + }); + } + + public GoalBuilder tooltip(Component tooltip, Consumer subber) { + JsonSubber json = new JsonSubber(ComponentSerialization.CODEC.encodeStart(JSON_OPS.get(), tooltip).getOrThrow()); + subber.accept(json); + this.tooltip = new Dynamic<>(JsonOps.INSTANCE, json.json()); + return this; + } + + public GoalBuilder tooltipIcon(ResourceLocation tooltipIcon) { + this.tooltipIcon = Optional.of(tooltipIcon); + return this; + } + + public GoalBuilder icon(Object icon) { + return icon(icon, subber -> { + }); + } + + public GoalBuilder icon(Object icon, Consumer subber) { + return icon(GoalIcon.infer(icon), subber); + } + + public GoalBuilder icon(Block icon, ItemLike fallback) { + return icon(icon, fallback, subber -> { + }); + } + + public GoalBuilder icon(Block icon, ItemLike fallback, Consumer subber) { + return icon(BlockIcon.ofBlockAndItem(icon, fallback), subber); + } + + public GoalBuilder icon(GoalIcon icon) { + return icon(icon, subber -> { + }); + } + + public GoalBuilder icon(GoalIcon icon, Consumer subber) { + JsonSubber jsonSubber = new JsonSubber(GoalIcon.CODEC.encodeStart(JSON_OPS.get(), icon).getOrThrow()); + subber.accept(jsonSubber); + this.icon = new Dynamic<>(JsonOps.INSTANCE, jsonSubber.json()); + return this; + } + + public GoalBuilder infrequency(int infrequency) { + this.infrequency = OptionalInt.of(infrequency); + return this; + } + + public GoalBuilder setAntisynergy(String... antisynergy) { + this.antisynergy = ImmutableSet.builderWithExpectedSize(antisynergy.length); + return this.antisynergy(antisynergy); + } + + public GoalBuilder antisynergy(String... antisynergy) { + this.antisynergy.add(antisynergy); + return this; + } + + public GoalBuilder catalyst(String... catalyst) { + this.catalyst.add(catalyst); + return this; + } + + public GoalBuilder reactant(String... reactant) { + this.reactant.add(reactant); + return this; + } + + public GoalBuilder difficulty(ResourceKey difficulty) { + this.difficulty = Optional.of(difficulty); + return this; + } + + public GoalHolder build(HolderLookup.Provider registries) { + final Map> criteria = this.criteria.build(); + return new GoalHolder(id, new BingoGoal( + subs.buildOrThrow(), + criteria, + requirements.or(() -> Optional.of(requirementsStrategy.create(criteria.keySet()))), + progress, + requiredCount, + HolderSet.direct(registries.lookupOrThrow(BingoRegistries.TAG)::getOrThrow, tags.build()), + name.orElseThrow(() -> new IllegalStateException("Bingo goal name has not been set")), + tooltip, + tooltipIcon, + icon, + infrequency, + antisynergy.build(), + catalyst.build(), + reactant.build(), + registries.lookupOrThrow(BingoRegistries.DIFFICULTY).getOrThrow( + difficulty.orElseThrow(() -> new IllegalStateException("Bingo goal difficulty has not been set")) + ), + registries.lookupOrThrow(Registries.TRIGGER_TYPE) + )); + } +} diff --git a/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalHolder.java b/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalHolder.java new file mode 100644 index 00000000..80144db7 --- /dev/null +++ b/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalHolder.java @@ -0,0 +1,50 @@ +package io.github.gaming32.bingo.data.goal; + +import com.mojang.serialization.Dynamic; +import io.github.gaming32.bingo.game.ActiveGoal; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.HoverEvent; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; + +import java.util.Map; +import java.util.Optional; + +public record GoalHolder(ResourceLocation id, BingoGoal goal) { + public ActiveGoal build(RandomSource rand) { + final Map> subs = goal.buildSubs(rand); + final Optional tooltip = goal.buildTooltip(subs, rand); + final MutableComponent name = goal.buildName(subs, rand); + tooltip.ifPresent(t -> name.withStyle(s -> s + .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, t)) + )); + return new ActiveGoal( + id, name, + tooltip, + goal.getTooltipIcon(), + goal.buildIcon(subs, rand), + goal.buildCriteria(subs, rand), + goal.buildRequiredCount(subs, rand), + Optional.of(goal.getDifficulty()), + goal.getRequirements(), + goal.getSpecialType(), + goal.getProgress() + ); + } + + @Override + public String toString() { + return id.toString(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof GoalHolder h && id.equals(h.id); + } + + @Override + public int hashCode() { + return id.hashCode(); + } +} diff --git a/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalManager.java b/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalManager.java new file mode 100644 index 00000000..fcc3e4f4 --- /dev/null +++ b/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalManager.java @@ -0,0 +1,71 @@ +package io.github.gaming32.bingo.data.goal; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import io.github.gaming32.bingo.Bingo; +import io.github.gaming32.bingo.util.ResourceLocations; +import net.minecraft.core.HolderLookup; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.packs.resources.ResourceManager; +import net.minecraft.server.packs.resources.SimpleJsonResourceReloadListener; +import net.minecraft.util.profiling.ProfilerFiller; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class GoalManager extends SimpleJsonResourceReloadListener { + public static final ResourceLocation ID = ResourceLocations.bingo("goals"); + + private static Map goals = Map.of(); + private static Map> goalsByDifficulty = Map.of(); + + public GoalManager(HolderLookup.Provider registries) { + super(registries, BingoGoal.CODEC, "bingo/goal"); + } + + public static Set getGoalIds() { + return goals.keySet(); + } + + @Nullable + public static GoalHolder getGoal(ResourceLocation id) { + return goals.get(id); + } + + public static List getGoalsByDifficulty(int difficulty) { + if (difficulty < 0) { + throw new IllegalArgumentException("Difficulties < 0 aren't allowed"); + } + return goalsByDifficulty.getOrDefault(difficulty, List.of()); + } + + @NotNull + @Override + public String getName() { + return ID.toString(); + } + + @Override + protected void apply(Map goals, ResourceManager resourceManager, ProfilerFiller profiler) { + final ImmutableMap.Builder result = ImmutableMap.builder(); + final Map> byDifficulty = new HashMap<>(); + for (final var entry : goals.entrySet()) { + final var goal = entry.getValue(); + final GoalHolder holder = new GoalHolder(entry.getKey(), goal); + result.put(holder.id(), holder); + byDifficulty.computeIfAbsent(goal.getDifficulty().value().number(), k -> ImmutableList.builder()).add(holder); + } + GoalManager.goals = result.build(); + GoalManager.goalsByDifficulty = byDifficulty.entrySet() + .stream() + .collect(ImmutableMap.toImmutableMap( + Map.Entry::getKey, + e -> e.getValue().build() + )); + Bingo.LOGGER.info("Loaded {} bingo goals", GoalManager.goals.size()); + } +} diff --git a/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalSubstitutionSystem.java b/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalSubstitutionSystem.java new file mode 100644 index 00000000..f046f2df --- /dev/null +++ b/common/src/main/java/io/github/gaming32/bingo/data/goal/GoalSubstitutionSystem.java @@ -0,0 +1,43 @@ +package io.github.gaming32.bingo.data.goal; + +import com.google.common.collect.ImmutableMap; +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Dynamic; +import io.github.gaming32.bingo.data.subs.BingoSub; +import io.github.gaming32.bingo.util.BingoUtil; +import net.minecraft.util.RandomSource; + +import java.util.Map; + +public class GoalSubstitutionSystem { + private static final String TYPE_FIELD = "bingo_type"; + + public static Dynamic performSubstitutions( + Dynamic value, + Map> referable, + RandomSource rand + ) { + final var asList = value.asStreamOpt(); + if (asList.result().isPresent()) { + return value.createList( + asList.result().get().map(d -> performSubstitutions(d, referable, rand).convert(d.getOps())) + ); + } + + if (value.get(TYPE_FIELD).result().isPresent()) { + return BingoUtil.fromDynamic(BingoSub.INNER_CODEC, value).substitute(referable, rand); + } + + final var asMap = value.asMapOpt(); + if (asMap.result().isPresent()) { + return value.createMap(asMap.result().get() + .collect(ImmutableMap.toImmutableMap( + Pair::getFirst, + e -> performSubstitutions(e.getSecond(), referable, rand).convert(e.getSecond().getOps()) + )) + ); + } + + return value; + } +} diff --git a/common/src/main/java/io/github/gaming32/bingo/data/progresstrackers/CriterionProgressTracker.java b/common/src/main/java/io/github/gaming32/bingo/data/progresstrackers/CriterionProgressTracker.java index 36705d68..e8cd139a 100644 --- a/common/src/main/java/io/github/gaming32/bingo/data/progresstrackers/CriterionProgressTracker.java +++ b/common/src/main/java/io/github/gaming32/bingo/data/progresstrackers/CriterionProgressTracker.java @@ -4,7 +4,7 @@ import com.mojang.serialization.DataResult; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import io.github.gaming32.bingo.data.BingoGoal; +import io.github.gaming32.bingo.data.goal.BingoGoal; import io.github.gaming32.bingo.game.ActiveGoal; import io.github.gaming32.bingo.game.BingoGame; import net.minecraft.server.level.ServerPlayer; diff --git a/common/src/main/java/io/github/gaming32/bingo/data/progresstrackers/ProgressTracker.java b/common/src/main/java/io/github/gaming32/bingo/data/progresstrackers/ProgressTracker.java index 6c307512..153c0401 100644 --- a/common/src/main/java/io/github/gaming32/bingo/data/progresstrackers/ProgressTracker.java +++ b/common/src/main/java/io/github/gaming32/bingo/data/progresstrackers/ProgressTracker.java @@ -2,7 +2,7 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; -import io.github.gaming32.bingo.data.BingoGoal; +import io.github.gaming32.bingo.data.goal.BingoGoal; import io.github.gaming32.bingo.game.ActiveGoal; import io.github.gaming32.bingo.game.BingoGame; import io.github.gaming32.bingo.game.GoalProgress; diff --git a/common/src/main/java/io/github/gaming32/bingo/data/subs/WrapBingoSub.java b/common/src/main/java/io/github/gaming32/bingo/data/subs/WrapBingoSub.java index 90deeeac..27a6369e 100644 --- a/common/src/main/java/io/github/gaming32/bingo/data/subs/WrapBingoSub.java +++ b/common/src/main/java/io/github/gaming32/bingo/data/subs/WrapBingoSub.java @@ -5,8 +5,8 @@ import com.mojang.serialization.Dynamic; import com.mojang.serialization.JsonOps; import com.mojang.serialization.MapCodec; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.JsonSubber; +import io.github.gaming32.bingo.data.goal.GoalSubstitutionSystem; import net.minecraft.Util; import net.minecraft.util.RandomSource; @@ -24,7 +24,7 @@ public WrapBingoSub(JsonElement value, Consumer subber) { @Override public Dynamic substitute(Map> referable, RandomSource rand) { - return BingoGoal.performSubstitutions(value, referable, rand); + return GoalSubstitutionSystem.performSubstitutions(value, referable, rand); } @Override diff --git a/common/src/main/java/io/github/gaming32/bingo/game/BingoBoard.java b/common/src/main/java/io/github/gaming32/bingo/game/BingoBoard.java index 318db14f..67cf68b4 100644 --- a/common/src/main/java/io/github/gaming32/bingo/game/BingoBoard.java +++ b/common/src/main/java/io/github/gaming32/bingo/game/BingoBoard.java @@ -3,9 +3,10 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; import io.github.gaming32.bingo.data.BingoDifficulty; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoRegistries; import io.github.gaming32.bingo.data.BingoTag; +import io.github.gaming32.bingo.data.goal.GoalHolder; +import io.github.gaming32.bingo.data.goal.GoalManager; import io.github.gaming32.bingo.util.BingoCodecs; import io.github.gaming32.bingo.util.BingoUtil; import io.github.gaming32.bingo.util.ResourceLocations; @@ -81,14 +82,14 @@ public static BingoBoard generate( int difficulty, int teamCount, RandomSource rand, - Predicate isAllowedGoal, - List requiredGoals, + Predicate isAllowedGoal, + List requiredGoals, HolderSet excludedTags, boolean allowsClientRequired, HolderLookup.Provider registries ) { final BingoBoard board = new BingoBoard(size); - final BingoGoal.GoalHolder[] generatedSheet = generateGoals( + final GoalHolder[] generatedSheet = generateGoals( registries.lookupOrThrow(BingoRegistries.DIFFICULTY), size, difficulty, @@ -115,19 +116,19 @@ public static BingoBoard generate( return board; } - public static BingoGoal.GoalHolder[] generateGoals( + public static GoalHolder[] generateGoals( HolderLookup difficultyLookup, int size, int difficulty, RandomSource rand, - Predicate isAllowedGoal, - List requiredGoals, + Predicate isAllowedGoal, + List requiredGoals, HolderSet excludedTags, boolean allowsClientRequired ) { - final Queue requiredGoalQueue = new ArrayDeque<>(requiredGoals); + final Queue requiredGoalQueue = new ArrayDeque<>(requiredGoals); - final BingoGoal.GoalHolder[] generatedSheet = new BingoGoal.GoalHolder[size * size]; + final GoalHolder[] generatedSheet = new GoalHolder[size * size]; final var difficulties = BingoDifficulty.getNumbers(difficultyLookup); final int[] difficultyLayout = generateDifficulty(difficulties, size, difficulty, rand); @@ -149,10 +150,10 @@ public static BingoGoal.GoalHolder[] generateGoals( throw new IllegalArgumentException("No goals with difficulty " + difficultyLayout[i] + " or easier"); } - List possibleGoals = BingoGoal.getGoalsByDifficulty(difficultyLayout[i] = difficultiesToTry.next()); + List possibleGoals = GoalManager.getGoalsByDifficulty(difficultyLayout[i] = difficultiesToTry.next()); int failSafe = 0; - BingoGoal.GoalHolder goal; + GoalHolder goal; goalGen: while (true) { @@ -168,11 +169,11 @@ public static BingoGoal.GoalHolder[] generateGoals( throw new IllegalArgumentException("No valid board layout was found for the specified size and difficulty"); } - possibleGoals = BingoGoal.getGoalsByDifficulty(difficultyLayout[i] = difficultiesToTry.next()); + possibleGoals = GoalManager.getGoalsByDifficulty(difficultyLayout[i] = difficultiesToTry.next()); failSafe = 1; } - final BingoGoal.GoalHolder goalCandidate = possibleGoals.get(rand.nextInt(possibleGoals.size())); + final GoalHolder goalCandidate = possibleGoals.get(rand.nextInt(possibleGoals.size())); if (!isAllowedGoal.test(goalCandidate)) { continue; diff --git a/common/src/main/java/io/github/gaming32/bingo/game/mode/BingoGameMode.java b/common/src/main/java/io/github/gaming32/bingo/game/mode/BingoGameMode.java index 066593d6..e97391ee 100644 --- a/common/src/main/java/io/github/gaming32/bingo/game/mode/BingoGameMode.java +++ b/common/src/main/java/io/github/gaming32/bingo/game/mode/BingoGameMode.java @@ -2,8 +2,8 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.serialization.Codec; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoRegistries; +import io.github.gaming32.bingo.data.goal.GoalHolder; import io.github.gaming32.bingo.game.BingoBoard; import io.github.gaming32.bingo.platform.registry.DeferredRegister; import io.github.gaming32.bingo.platform.registry.RegistryBuilder; @@ -38,7 +38,7 @@ default CommandSyntaxException checkAllowedConfig(GameConfig config) { boolean canGetGoal(BingoBoard board, int index, BingoBoard.Teams team, boolean isNever); - default boolean isGoalAllowed(BingoGoal.GoalHolder goal) { + default boolean isGoalAllowed(GoalHolder goal) { return true; } diff --git a/common/src/main/java/io/github/gaming32/bingo/game/mode/BlackoutGameMode.java b/common/src/main/java/io/github/gaming32/bingo/game/mode/BlackoutGameMode.java index 680ca3eb..62bb702c 100644 --- a/common/src/main/java/io/github/gaming32/bingo/game/mode/BlackoutGameMode.java +++ b/common/src/main/java/io/github/gaming32/bingo/game/mode/BlackoutGameMode.java @@ -1,7 +1,7 @@ package io.github.gaming32.bingo.game.mode; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoTag; +import io.github.gaming32.bingo.data.goal.GoalHolder; import io.github.gaming32.bingo.game.BingoBoard; import org.jetbrains.annotations.NotNull; @@ -34,7 +34,7 @@ public boolean canGetGoal(BingoBoard board, int index, BingoBoard.Teams team, bo } @Override - public boolean isGoalAllowed(BingoGoal.GoalHolder goal) { + public boolean isGoalAllowed(GoalHolder goal) { return goal.goal().getTags().stream().allMatch(g -> g.value().specialType() == BingoTag.SpecialType.NONE); } } diff --git a/common/src/main/java/io/github/gaming32/bingo/game/mode/LockoutGameMode.java b/common/src/main/java/io/github/gaming32/bingo/game/mode/LockoutGameMode.java index 04a8a646..ab2b8ba7 100644 --- a/common/src/main/java/io/github/gaming32/bingo/game/mode/LockoutGameMode.java +++ b/common/src/main/java/io/github/gaming32/bingo/game/mode/LockoutGameMode.java @@ -3,8 +3,8 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import io.github.gaming32.bingo.Bingo; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoTag; +import io.github.gaming32.bingo.data.goal.GoalHolder; import io.github.gaming32.bingo.game.BingoBoard; import net.minecraft.ChatFormatting; import net.minecraft.world.scores.PlayerTeam; @@ -95,7 +95,7 @@ public boolean canGetGoal(BingoBoard board, int index, BingoBoard.Teams team, bo } @Override - public boolean isGoalAllowed(BingoGoal.GoalHolder goal) { + public boolean isGoalAllowed(GoalHolder goal) { return goal.goal().getTags().stream().allMatch(g -> g.value().specialType() == BingoTag.SpecialType.NONE); } diff --git a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/BingoGoalProvider.java b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/BingoGoalProvider.java index 31fb5171..652eb896 100644 --- a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/BingoGoalProvider.java +++ b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/BingoGoalProvider.java @@ -2,7 +2,8 @@ import com.google.gson.JsonElement; import com.mojang.serialization.DynamicOps; -import io.github.gaming32.bingo.data.BingoGoal; +import io.github.gaming32.bingo.data.goal.BingoGoal; +import io.github.gaming32.bingo.data.goal.GoalBuilder; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; import net.fabricmc.fabric.api.datagen.v1.provider.FabricCodecDataProvider; import net.minecraft.core.HolderLookup; @@ -35,14 +36,14 @@ public String getName() { @Override protected void configure(BiConsumer adder, HolderLookup.Provider registries) { - final DynamicOps oldOps = BingoGoal.Builder.JSON_OPS.get(); + final DynamicOps oldOps = GoalBuilder.JSON_OPS.get(); try { - BingoGoal.Builder.JSON_OPS.set(registries.createSerializationContext(oldOps)); + GoalBuilder.JSON_OPS.set(registries.createSerializationContext(oldOps)); for (final GoalProviderProvider provider : PROVIDERS) { provider.create(adder, registries).addGoals(); } } finally { - BingoGoal.Builder.JSON_OPS.set(oldOps); + GoalBuilder.JSON_OPS.set(oldOps); } } diff --git a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/DifficultyGoalProvider.java b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/DifficultyGoalProvider.java index 3caa221b..3e67e44e 100644 --- a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/DifficultyGoalProvider.java +++ b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/DifficultyGoalProvider.java @@ -4,9 +4,11 @@ import com.google.common.collect.ImmutableList; import io.github.gaming32.bingo.conditions.BlockPatternCondition; import io.github.gaming32.bingo.data.BingoDifficulty; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoTags; import io.github.gaming32.bingo.data.JsonSubber; +import io.github.gaming32.bingo.data.goal.BingoGoal; +import io.github.gaming32.bingo.data.goal.GoalBuilder; +import io.github.gaming32.bingo.data.goal.GoalHolder; import io.github.gaming32.bingo.data.icons.CycleIcon; import io.github.gaming32.bingo.data.icons.GoalIcon; import io.github.gaming32.bingo.data.icons.ItemIcon; @@ -84,8 +86,8 @@ protected DifficultyGoalProvider( this.registries = registries; } - protected final void addGoal(BingoGoal.Builder goal) { - BingoGoal.GoalHolder builtGoal = goal.difficulty(difficulty).build(registries); + protected final void addGoal(GoalBuilder goal) { + GoalHolder builtGoal = goal.difficulty(difficulty).build(registries); if (!builtGoal.id().getPath().startsWith(prefix)) { throw new IllegalArgumentException("Goal ID does not start with " + prefix); } @@ -98,32 +100,32 @@ protected final ResourceLocation id(String path) { return ResourceLocations.bingo(prefix + path); } - protected static BingoGoal.Builder obtainItemGoal(ResourceLocation id, HolderLookup items, ResourceKey item) { + protected static GoalBuilder obtainItemGoal(ResourceLocation id, HolderLookup items, ResourceKey item) { return obtainItemGoal(id, items, items.getOrThrow(item).value()); } @SuppressWarnings("deprecation") - protected static BingoGoal.Builder obtainItemGoal(ResourceLocation id, HolderLookup items, ItemLike item) { + protected static GoalBuilder obtainItemGoal(ResourceLocation id, HolderLookup items, ItemLike item) { return obtainItemGoal(id, items, item, ItemPredicate.Builder.item().of(items, item)) .antisynergy(item.asItem().builtInRegistryHolder().key().location().getPath()) .name(item.asItem().getName()); } - protected static BingoGoal.Builder obtainItemGoal(ResourceLocation id, HolderLookup items, ItemLike icon, ItemPredicate.Builder... oneOfThese) { + protected static GoalBuilder obtainItemGoal(ResourceLocation id, HolderLookup items, ItemLike icon, ItemPredicate.Builder... oneOfThese) { return obtainItemGoal(id, items, ItemIcon.ofItem(icon), oneOfThese); } - protected static BingoGoal.Builder obtainItemGoal(ResourceLocation id, HolderLookup items, ItemStack icon, ItemPredicate.Builder... oneOfThese) { + protected static GoalBuilder obtainItemGoal(ResourceLocation id, HolderLookup items, ItemStack icon, ItemPredicate.Builder... oneOfThese) { return obtainItemGoal(id, items, new ItemIcon(icon), oneOfThese); } - protected static BingoGoal.Builder obtainItemGoal( + protected static GoalBuilder obtainItemGoal( ResourceLocation id, @SuppressWarnings("unused") HolderLookup items, // Unused, but present for consistency GoalIcon icon, ItemPredicate.Builder... oneOfThese ) { - BingoGoal.Builder builder = BingoGoal.builder(id); + GoalBuilder builder = BingoGoal.builder(id); if (oneOfThese.length == 1) { builder.criterion("obtain", TotalCountInventoryChangeTrigger.builder().items(oneOfThese[0].build()).build()) .progress("obtain"); @@ -138,12 +140,12 @@ protected static BingoGoal.Builder obtainItemGoal( .icon(icon); } - protected static BingoGoal.Builder obtainItemGoal(ResourceLocation id, HolderLookup items, ResourceKey item, int minCount, int maxCount) { + protected static GoalBuilder obtainItemGoal(ResourceLocation id, HolderLookup items, ResourceKey item, int minCount, int maxCount) { return obtainItemGoal(id, items, items.getOrThrow(item).value(), minCount, maxCount); } @SuppressWarnings("deprecation") - protected static BingoGoal.Builder obtainItemGoal(ResourceLocation id, HolderLookup items, ItemLike item, int minCount, int maxCount) { + protected static GoalBuilder obtainItemGoal(ResourceLocation id, HolderLookup items, ItemLike item, int minCount, int maxCount) { final var realItem = item.asItem(); final Consumer subFunction = minCount == maxCount ? subber -> {} @@ -153,7 +155,7 @@ protected static BingoGoal.Builder obtainItemGoal(ResourceLocation id, HolderLoo .name(Component.translatable("bingo.count", minCount, realItem.getName()), subFunction); } - protected static BingoGoal.Builder obtainItemGoal(ResourceLocation id, ItemLike icon, ItemPredicate.Builder item, int minCount, int maxCount) { + protected static GoalBuilder obtainItemGoal(ResourceLocation id, ItemLike icon, ItemPredicate.Builder item, int minCount, int maxCount) { if (minCount == maxCount) { return BingoGoal.builder(id) .criterion("obtain", TotalCountInventoryChangeTrigger.builder().items(item.withCount(MinMaxBounds.Ints.exactly(minCount)).build()).build()) @@ -171,7 +173,7 @@ protected static BingoGoal.Builder obtainItemGoal(ResourceLocation id, ItemLike .icon(icon, subber -> subber.sub("item.count", "count")); } - protected static BingoGoal.Builder obtainSomeItemsFromTag( + protected static GoalBuilder obtainSomeItemsFromTag( ResourceLocation id, TagKey tag, @Translatable String translationKey, int minCount, int maxCount ) { @@ -196,7 +198,7 @@ protected static BingoGoal.Builder obtainSomeItemsFromTag( .icon(new ItemTagCycleIcon(tag), subber -> subber.sub("+count", "count")); } - protected BingoGoal.Builder obtainAllItemsFromTag(TagKey tag, @Translatable(prefix = "bingo.goal.all_somethings.") String what) { + protected GoalBuilder obtainAllItemsFromTag(TagKey tag, @Translatable(prefix = "bingo.goal.all_somethings.") String what) { return BingoGoal.builder(id("all_" + what)) .criterion("obtain", HasSomeItemsFromTagTrigger.builder().tag(tag).requiresAll().build()) .progress("obtain") @@ -206,7 +208,7 @@ protected BingoGoal.Builder obtainAllItemsFromTag(TagKey tag, @Translatabl .icon(new ItemTagCycleIcon(tag)); } - protected static BingoGoal.Builder obtainSomeEdibleItems(ResourceLocation id, int minCount, int maxCount) { + protected static GoalBuilder obtainSomeEdibleItems(ResourceLocation id, int minCount, int maxCount) { if (minCount == maxCount) { return BingoGoal.builder(id) .criterion("obtain", HasSomeFoodItemsTrigger.builder().requiredCount(minCount).build()) @@ -232,7 +234,7 @@ protected static BingoGoal.Builder obtainSomeEdibleItems(ResourceLocation id, in .icon(new ItemTagCycleIcon(ConventionalItemTags.FOODS), subber -> subber.sub("+count", "count")); } - protected static BingoGoal.Builder obtainLevelsGoal(ResourceLocation id, int minLevels, int maxLevels) { + protected static GoalBuilder obtainLevelsGoal(ResourceLocation id, int minLevels, int maxLevels) { return BingoGoal.builder(id) .sub("count", BingoSub.random(minLevels, maxLevels)) .criterion("obtain", ExperienceChangeTrigger.builder().levels(MinMaxBounds.Ints.atLeast(0)).build(), @@ -244,7 +246,7 @@ protected static BingoGoal.Builder obtainLevelsGoal(ResourceLocation id, int min .antisynergy("levels"); } - protected static BingoGoal.Builder crouchDistanceGoal(ResourceLocation id, int minDistance, int maxDistance) { + protected static GoalBuilder crouchDistanceGoal(ResourceLocation id, int minDistance, int maxDistance) { return BingoGoal.builder(id) .sub("distance", BingoSub.random(minDistance, maxDistance)) .criterion( @@ -270,7 +272,7 @@ protected static BingoGoal.Builder crouchDistanceGoal(ResourceLocation id, int m .icon(Items.LEATHER_BOOTS, subber -> subber.sub("item.count", "distance")); } - protected static BingoGoal.Builder bedRowGoal(ResourceLocation id, int minCount, int maxCount) { + protected static GoalBuilder bedRowGoal(ResourceLocation id, int minCount, int maxCount) { if (minCount == maxCount) { return BingoGoal.builder(id) .criterion("obtain", BedRowTrigger.create(minCount)) @@ -290,13 +292,13 @@ protected static BingoGoal.Builder bedRowGoal(ResourceLocation id, int minCount, .tags(BingoTags.BUILD, BingoTags.COLOR, BingoTags.OVERWORLD); } - protected static BingoGoal.Builder mineralPillarGoal(ResourceLocation id, TagKey tag) { + protected static GoalBuilder mineralPillarGoal(ResourceLocation id, TagKey tag) { return BingoGoal.builder(id) .criterion("pillar", MineralPillarTrigger.pillar(tag)) .tags(BingoTags.BUILD); } - protected BingoGoal.Builder blockCubeGoal(ResourceLocation id, Object icon, TagKey blockTag, Component tagName) { + protected GoalBuilder blockCubeGoal(ResourceLocation id, Object icon, TagKey blockTag, Component tagName) { final var blocks = registries.lookupOrThrow(Registries.BLOCK); return BingoGoal.builder(id) .sub("width", BingoSub.random(2, 4)) diff --git a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/EasyGoalProvider.java b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/EasyGoalProvider.java index 470449e8..edc9928b 100644 --- a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/EasyGoalProvider.java +++ b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/EasyGoalProvider.java @@ -11,8 +11,9 @@ import io.github.gaming32.bingo.conditions.ToolIsEnchantedCondition; import io.github.gaming32.bingo.conditions.VillagerOwnershipCondition; import io.github.gaming32.bingo.data.BingoDifficulties; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoTags; +import io.github.gaming32.bingo.data.goal.BingoGoal; +import io.github.gaming32.bingo.data.goal.GoalBuilder; import io.github.gaming32.bingo.data.icons.BlockIcon; import io.github.gaming32.bingo.data.icons.CycleIcon; import io.github.gaming32.bingo.data.icons.EffectIcon; @@ -1053,8 +1054,8 @@ ItemSubPredicates.STORED_ENCHANTMENTS, createAnyStoredEnchantmentsRequirement() .icon(Items.BUNDLE)); } - private BingoGoal.Builder eatEntireCake() { - BingoGoal.Builder builder = BingoGoal.builder(id("eat_entire_cake")); + private GoalBuilder eatEntireCake() { + GoalBuilder builder = BingoGoal.builder(id("eat_entire_cake")); for (int level = 0; level < 7; level++) { LootItemCondition block; if (level == 6) { diff --git a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/HardGoalProvider.java b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/HardGoalProvider.java index d97d0bf0..4f02b25d 100644 --- a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/HardGoalProvider.java +++ b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/HardGoalProvider.java @@ -4,8 +4,8 @@ import io.github.gaming32.bingo.conditions.PillarCondition; import io.github.gaming32.bingo.conditions.StairwayToHeavenCondition; import io.github.gaming32.bingo.data.BingoDifficulties; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoTags; +import io.github.gaming32.bingo.data.goal.BingoGoal; import io.github.gaming32.bingo.data.icons.BlockIcon; import io.github.gaming32.bingo.data.icons.CycleIcon; import io.github.gaming32.bingo.data.icons.EntityIcon; diff --git a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/MediumGoalProvider.java b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/MediumGoalProvider.java index d8cb70b9..d1b8491b 100644 --- a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/MediumGoalProvider.java +++ b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/MediumGoalProvider.java @@ -8,8 +8,9 @@ import io.github.gaming32.bingo.conditions.OneByOneHoleCondition; import io.github.gaming32.bingo.conditions.WearingDifferentArmorCondition; import io.github.gaming32.bingo.data.BingoDifficulties; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoTags; +import io.github.gaming32.bingo.data.goal.BingoGoal; +import io.github.gaming32.bingo.data.goal.GoalBuilder; import io.github.gaming32.bingo.data.icons.BlockIcon; import io.github.gaming32.bingo.data.icons.CycleIcon; import io.github.gaming32.bingo.data.icons.EntityIcon; @@ -877,9 +878,9 @@ public void addGoals() { } @SafeVarargs - private BingoGoal.Builder potionGoal(String id, HolderLookup items, Holder... potions) { + private GoalBuilder potionGoal(String id, HolderLookup items, Holder... potions) { ItemStack potionItem = PotionContents.createItemStack(Items.POTION, potions[0]); - BingoGoal.Builder builder = obtainItemGoal( + GoalBuilder builder = obtainItemGoal( id(id), items, potionItem, diff --git a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/VeryEasyGoalProvider.java b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/VeryEasyGoalProvider.java index 02c57091..45f3b70c 100644 --- a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/VeryEasyGoalProvider.java +++ b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/VeryEasyGoalProvider.java @@ -1,8 +1,8 @@ package io.github.gaming32.bingo.fabric.datagen.goal; import io.github.gaming32.bingo.data.BingoDifficulties; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoTags; +import io.github.gaming32.bingo.data.goal.BingoGoal; import io.github.gaming32.bingo.data.icons.CycleIcon; import io.github.gaming32.bingo.data.icons.ItemIcon; import io.github.gaming32.bingo.data.icons.ItemTagCycleIcon; diff --git a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/VeryHardGoalProvider.java b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/VeryHardGoalProvider.java index c820b037..7ec185dc 100644 --- a/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/VeryHardGoalProvider.java +++ b/fabric/src/main/java/io/github/gaming32/bingo/fabric/datagen/goal/VeryHardGoalProvider.java @@ -4,8 +4,9 @@ import com.google.common.collect.ImmutableSortedSet; import io.github.gaming32.bingo.conditions.HasOnlyBeenDamagedByCondition; import io.github.gaming32.bingo.data.BingoDifficulties; -import io.github.gaming32.bingo.data.BingoGoal; import io.github.gaming32.bingo.data.BingoTags; +import io.github.gaming32.bingo.data.goal.BingoGoal; +import io.github.gaming32.bingo.data.goal.GoalBuilder; import io.github.gaming32.bingo.data.icons.CycleIcon; import io.github.gaming32.bingo.data.icons.EntityIcon; import io.github.gaming32.bingo.data.icons.InstrumentCycleIcon; @@ -340,7 +341,7 @@ public void addGoals() { } @SuppressWarnings("deprecation") - private BingoGoal.Builder obtainAllGoatHorns() { + private GoalBuilder obtainAllGoatHorns() { final var items = registries.lookupOrThrow(Registries.ITEM); final var sortedInstruments = registries.lookupOrThrow(Registries.INSTRUMENT) @@ -349,7 +350,7 @@ private BingoGoal.Builder obtainAllGoatHorns() { Comparator.comparing(e -> e.key().location()) )); - final BingoGoal.Builder builder = BingoGoal.builder(id("all_goat_horns")); + final GoalBuilder builder = BingoGoal.builder(id("all_goat_horns")); for (final var instrument : sortedInstruments) { final var location = instrument.key().location(); builder.criterion(