Skip to content

Commit

Permalink
Add reset repair cost functionality and filters
Browse files Browse the repository at this point in the history
  • Loading branch information
mschae23 committed Apr 24, 2024
1 parent 46c1cbd commit d2b3341
Show file tree
Hide file tree
Showing 26 changed files with 606 additions and 125 deletions.
8 changes: 4 additions & 4 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ org.gradle.jvmargs=-Xmx1G

# Fabric Properties
# check these on https://fabricmc.net/versions.html
minecraft_version=1.20.5-rc3
yarn_mappings=1.20.5-rc3+build.1
minecraft_version=1.20.5
yarn_mappings=1.20.5+build.1
loader_version=0.15.10

# Mod Properties
mod_version = 3.1.3
mod_version = 3.2.0
maven_group = de.mschae23.minecraft.mod
archives_base_name = grind-enchantments

# Dependencies
fabric_api_version=0.97.5+1.20.5
fabric_api_version=0.97.6+1.20.5
codec_config_api_version=2.0.0+1.20.5-rc3
tax_free_levels_version=loom-SNAPSHOT

Expand Down
24 changes: 5 additions & 19 deletions src/main/java/de/mschae23/grindenchantments/GrindEnchantments.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,41 +23,27 @@
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.ItemEnchantmentsComponent;
import net.minecraft.component.type.LoreComponent;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import de.mschae23.grindenchantments.config.DedicatedServerConfig;
import de.mschae23.grindenchantments.config.FilterConfig;
import de.mschae23.grindenchantments.cost.CostFunction;
import de.mschae23.grindenchantments.item.GrindEnchantmentsDataComponent;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;

public class GrindEnchantments {
public static int getLevelCost(ItemStack stack, CostFunction costFunction, boolean allowCurses, RegistryWrapper.WrapperLookup wrapperLookup) {
public static int getLevelCost(ItemStack stack, CostFunction costFunction, FilterConfig filter, RegistryWrapper.WrapperLookup wrapperLookup) {
ItemEnchantmentsComponent enchantments = EnchantmentHelper.getEnchantments(stack);
double cost = costFunction.getCost(enchantments, allowCurses, wrapperLookup);
double cost = costFunction.getCost(enchantments, filter, wrapperLookup);

return (int) Math.ceil(cost);
}

public static Object2IntMap<RegistryEntry<Enchantment>> getEnchantments(ItemStack stack, boolean allowCurses) {
Object2IntMap<RegistryEntry<Enchantment>> enchantments = new Object2IntOpenHashMap<>(EnchantmentHelper.getEnchantments(stack).enchantments);

if (!allowCurses) {
// Don't transfer curses if it isn't enabled in the config
for (RegistryEntry<Enchantment> entry : enchantments.keySet()) {
if (entry.value().isCursed()) {
enchantments.removeInt(entry);
}
}
}

return enchantments;
public static ItemEnchantmentsComponent getEnchantments(ItemStack stack, FilterConfig filter) {
return filter.filter(EnchantmentHelper.getEnchantments(stack));
}

public static ItemStack addLevelCostComponent(ItemStack stack, IntSupplier cost, boolean canTakeItem, DedicatedServerConfig config) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@
import de.mschae23.config.api.ModConfig;
import com.mojang.serialization.Codec;
import com.mojang.serialization.JsonOps;
import de.mschae23.grindenchantments.config.GrindEnchantmentsV2Config;
import de.mschae23.grindenchantments.config.GrindEnchantmentsV3Config;
import de.mschae23.grindenchantments.config.v1.GrindEnchantmentsV1Config;
import de.mschae23.grindenchantments.config.v2.GrindEnchantmentsV2Config;
import de.mschae23.grindenchantments.cost.CostFunctionType;
import de.mschae23.grindenchantments.event.ApplyLevelCostEvent;
import de.mschae23.grindenchantments.event.GrindstoneEvents;
import de.mschae23.grindenchantments.impl.DisenchantOperation;
import de.mschae23.grindenchantments.impl.MoveOperation;
import de.mschae23.grindenchantments.impl.ResetRepairCostOperation;
import de.mschae23.grindenchantments.item.GrindEnchantmentsDataComponent;
import de.mschae23.grindenchantments.registry.GrindEnchantmentsRegistries;
import io.github.fourmisain.taxfreelevels.TaxFreeLevels;
Expand All @@ -50,11 +52,11 @@ public class GrindEnchantmentsMod implements ModInitializer {

public static final Path CONFIG_PATH = Paths.get(MODID + ".json");

private static final GrindEnchantmentsV2Config LATEST_CONFIG_DEFAULT = GrindEnchantmentsV2Config.DEFAULT;
private static final GrindEnchantmentsV3Config LATEST_CONFIG_DEFAULT = GrindEnchantmentsV3Config.DEFAULT;
private static final int LATEST_CONFIG_VERSION = LATEST_CONFIG_DEFAULT.version();
private static final Codec<ModConfig<GrindEnchantmentsV2Config>> CONFIG_CODEC = ModConfig.createCodec(LATEST_CONFIG_VERSION, GrindEnchantmentsMod::getConfigType);
private static final Codec<ModConfig<GrindEnchantmentsV3Config>> CONFIG_CODEC = ModConfig.createCodec(LATEST_CONFIG_VERSION, GrindEnchantmentsMod::getConfigType);

private static GrindEnchantmentsV2Config CONFIG = LATEST_CONFIG_DEFAULT;
private static GrindEnchantmentsV3Config CONFIG = LATEST_CONFIG_DEFAULT;

@Override
public void onInitialize() {
Expand All @@ -70,9 +72,11 @@ public void onInitialize() {

DisenchantOperation disenchant = new DisenchantOperation();
MoveOperation move = new MoveOperation();
ResetRepairCostOperation resetRepairCost = new ResetRepairCostOperation();

GrindstoneEvents.registerAll(disenchant);
GrindstoneEvents.registerAll(move);
GrindstoneEvents.registerAll(resetRepairCost);

ApplyLevelCostEvent.EVENT.register(ApplyLevelCostEvent.DEFAULT, (cost, player) -> {
player.addExperienceLevels(-cost);
Expand All @@ -89,15 +93,15 @@ public void onInitialize() {
}

@SuppressWarnings("deprecation")
private static ModConfig.Type<GrindEnchantmentsV2Config, ?> getConfigType(int version) {
//noinspection SwitchStatementWithTooFewBranches
private static ModConfig.Type<GrindEnchantmentsV3Config, ?> getConfigType(int version) {
return new ModConfig.Type<>(version, switch (version) {
case 1 -> GrindEnchantmentsV1Config.TYPE_CODEC;
default -> GrindEnchantmentsV2Config.TYPE_CODEC;
case 2 -> GrindEnchantmentsV2Config.TYPE_CODEC;
default -> GrindEnchantmentsV3Config.TYPE_CODEC;
});
}

public static GrindEnchantmentsV2Config getConfig() {
public static GrindEnchantmentsV3Config getConfig() {
return CONFIG;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import de.mschae23.grindenchantments.cost.CostFunction;
import de.mschae23.grindenchantments.cost.CountMinPowerCostFunction;
import de.mschae23.grindenchantments.cost.FilterCostFunction;
import de.mschae23.grindenchantments.cost.TransformCostFunction;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
Expand All @@ -33,5 +34,5 @@ public record DisenchantConfig(boolean enabled, boolean consumeItem, CostFunctio
).apply(instance, instance.stable(DisenchantConfig::new)));

public static final DisenchantConfig DEFAULT = new DisenchantConfig(true, false,
new TransformCostFunction(new CountMinPowerCostFunction(), 0.3, 8.0));
new FilterCostFunction(new TransformCostFunction(new CountMinPowerCostFunction(), 0.3, 8.0)));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2024 mschae23
*
* This file is part of Grind enchantments.
*
* Grind enchantments is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package de.mschae23.grindenchantments.config;

import net.minecraft.util.StringIdentifiable;
import com.mojang.serialization.Codec;

public enum FilterAction implements StringIdentifiable {
ALLOW("allow"),
IGNORE("ignore"),
DENY("deny");

public static final Codec<FilterAction> CODEC = StringIdentifiable.createCodec(FilterAction::values);
public static final Codec<FilterAction> NON_IGNORE_CODEC = StringIdentifiable.createCodec(() -> new FilterAction[] { ALLOW, DENY, });

private final String name;

FilterAction(String name) {
this.name = name;
}

@Override
public String asString() {
return this.name;
}
}
119 changes: 119 additions & 0 deletions src/main/java/de/mschae23/grindenchantments/config/FilterConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright (C) 2024 mschae23
*
* This file is part of Grind enchantments.
*
* Grind enchantments is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package de.mschae23.grindenchantments.config;

import net.minecraft.component.type.ItemEnchantmentsComponent;
import net.minecraft.enchantment.Enchantment;
import net.minecraft.item.Item;
import net.minecraft.registry.RegistryCodecs;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.entry.RegistryEntryList;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;

public record FilterConfig(boolean enabled, ItemConfig item, EnchantmentConfig enchantment, FilterAction curses) {
public static final Codec<FilterConfig> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.BOOL.fieldOf("enabled").forGetter(FilterConfig::enabled),
ItemConfig.CODEC.fieldOf("item").forGetter(FilterConfig::item),
EnchantmentConfig.CODEC.fieldOf("enchantment").forGetter(FilterConfig::enchantment),
FilterAction.CODEC.fieldOf("cursed_enchantments").forGetter(FilterConfig::curses)
).apply(instance, instance.stable(FilterConfig::new)));

public static final FilterConfig DEFAULT = new FilterConfig(true, ItemConfig.DEFAULT, EnchantmentConfig.DEFAULT, FilterAction.IGNORE);

public ItemEnchantmentsComponent filter(ItemEnchantmentsComponent enchantments) {
if (!this.enabled) {
return enchantments;
}

ItemEnchantmentsComponent.Builder builder = new ItemEnchantmentsComponent.Builder(enchantments);

if (this.curses == FilterAction.DENY) {
for (RegistryEntry<Enchantment> entry : builder.getEnchantments()) {
if (entry.value().isCursed()) {
return ItemEnchantmentsComponent.DEFAULT;
}
}
}

if (this.enchantment.action == FilterAction.DENY) {
for (RegistryEntry<Enchantment> entry : builder.getEnchantments()) {
if (this.enchantment.enchantments.contains(entry)) {
return ItemEnchantmentsComponent.DEFAULT;
}
}
}

builder.remove(enchantment ->
((this.curses == FilterAction.IGNORE) && enchantment.value().isCursed())
|| ((this.enchantment.action == FilterAction.IGNORE) == this.enchantment.enchantments.contains(enchantment)));

return builder.build();
}

public ItemEnchantmentsComponent filterReversed(ItemEnchantmentsComponent enchantments) {
if (!this.enabled) {
return ItemEnchantmentsComponent.DEFAULT;
}

ItemEnchantmentsComponent.Builder builder = new ItemEnchantmentsComponent.Builder(enchantments);

if (this.curses == FilterAction.DENY) {
for (RegistryEntry<Enchantment> entry : builder.getEnchantments()) {
if (entry.value().isCursed()) {
return ItemEnchantmentsComponent.DEFAULT;
}
}
}

if (this.enchantment.action == FilterAction.DENY) {
for (RegistryEntry<Enchantment> entry : builder.getEnchantments()) {
if (this.enchantment.enchantments.contains(entry)) {
return ItemEnchantmentsComponent.DEFAULT;
}
}
}

builder.remove(enchantment ->
((this.curses == FilterAction.ALLOW) || !enchantment.value().isCursed())
&& ((this.enchantment.action == FilterAction.ALLOW) == this.enchantment.enchantments.contains(enchantment)));

return builder.build();
}

public record ItemConfig(RegistryEntryList<Item> items, FilterAction action) {
public static final Codec<ItemConfig> CODEC = RecordCodecBuilder.create(instance -> instance.group(
RegistryCodecs.entryList(RegistryKeys.ITEM).fieldOf("enchantments").forGetter(ItemConfig::items),
FilterAction.NON_IGNORE_CODEC.fieldOf("action").forGetter(ItemConfig::action)
).apply(instance, instance.stable(ItemConfig::new)));

public static final ItemConfig DEFAULT = new ItemConfig(RegistryEntryList.empty(), FilterAction.DENY);
}

public record EnchantmentConfig(RegistryEntryList<Enchantment> enchantments, FilterAction action) {
public static final Codec<EnchantmentConfig> CODEC = RecordCodecBuilder.create(instance -> instance.group(
RegistryCodecs.entryList(RegistryKeys.ENCHANTMENT).fieldOf("enchantments").forGetter(EnchantmentConfig::enchantments),
FilterAction.CODEC.fieldOf("action").forGetter(EnchantmentConfig::action)
).apply(instance, instance.stable(EnchantmentConfig::new)));

public static final EnchantmentConfig DEFAULT = new EnchantmentConfig(RegistryEntryList.empty(), FilterAction.IGNORE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2024 mschae23
*
* This file is part of Grind enchantments.
*
* Grind enchantments is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package de.mschae23.grindenchantments.config;

import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import de.mschae23.config.api.ModConfig;

public record GrindEnchantmentsV3Config(DisenchantConfig disenchant, MoveConfig move, ResetRepairCostConfig resetRepairCost,
FilterConfig filter,
DedicatedServerConfig dedicatedServerConfig, ClientConfig clientConfig) implements ModConfig<GrindEnchantmentsV3Config> {
public static final MapCodec<GrindEnchantmentsV3Config> TYPE_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group(
DisenchantConfig.CODEC.fieldOf("disenchant_to_book").forGetter(GrindEnchantmentsV3Config::disenchant),
MoveConfig.CODEC.fieldOf("move_enchantments").forGetter(GrindEnchantmentsV3Config::move),
ResetRepairCostConfig.CODEC.fieldOf("reset_repair_cost").forGetter(GrindEnchantmentsV3Config::resetRepairCost),
FilterConfig.CODEC.fieldOf("filter").forGetter(GrindEnchantmentsV3Config::filter),
DedicatedServerConfig.CODEC.orElse(DedicatedServerConfig.DEFAULT).fieldOf("dedicated_server_options").forGetter(GrindEnchantmentsV3Config::dedicatedServerConfig),
ClientConfig.CODEC.fieldOf("client_options").forGetter(GrindEnchantmentsV3Config::clientConfig)
).apply(instance, instance.stable(GrindEnchantmentsV3Config::new)));

public static final ModConfig.Type<GrindEnchantmentsV3Config, GrindEnchantmentsV3Config> TYPE = new ModConfig.Type<>(3, TYPE_CODEC);

public static final GrindEnchantmentsV3Config DEFAULT =
new GrindEnchantmentsV3Config(DisenchantConfig.DEFAULT, MoveConfig.DEFAULT, ResetRepairCostConfig.DEFAULT, FilterConfig.DEFAULT, DedicatedServerConfig.DEFAULT, ClientConfig.DEFAULT);

@Override
public Type<GrindEnchantmentsV3Config, ?> type() {
return TYPE;
}

@Override
public GrindEnchantmentsV3Config latest() {
return this;
}

@Override
public boolean shouldUpdate() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import de.mschae23.grindenchantments.cost.CostFunction;
import de.mschae23.grindenchantments.cost.CountLevelsCostFunction;
import de.mschae23.grindenchantments.cost.FilterCostFunction;
import de.mschae23.grindenchantments.cost.TransformCostFunction;
import de.mschae23.grindenchantments.cost.FirstEnchantmentCostFunction;
import com.mojang.serialization.Codec;
Expand All @@ -33,5 +34,6 @@ public record MoveConfig(boolean enabled, CostFunction costFunction) {
).apply(instance, instance.stable(MoveConfig::new)));

public static final MoveConfig DEFAULT = new MoveConfig(true,
new TransformCostFunction(new FirstEnchantmentCostFunction(new CountLevelsCostFunction(3.0, 8.0)), 0.5, 0.5));
new FilterCostFunction(new FirstEnchantmentCostFunction(new TransformCostFunction(
new CountLevelsCostFunction(3.0, 8.0), 0.5, 0.5))));
}
Loading

0 comments on commit d2b3341

Please sign in to comment.