diff --git a/build.gradle b/build.gradle index 6588f7a..e3edc71 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,9 @@ group = mod_group_id repositories { mavenLocal() + maven { + url "https://cursemaven.com" + } } base { @@ -97,6 +100,7 @@ dependencies { // And its provides the option to then use net.minecraft as the group, and one of; client, server or joined as the module name, plus the game version as version. // For all intends and purposes: You can treat this dependency as if it is a normal library you would use. implementation "net.neoforged:neoforge:${neo_version}" + implementation "curse.maven:cloth-config-348521:5424576" // Example optional mod dependency with JEI // The JEI API is declared for compile time use, while the full JEI artifact is used at runtime diff --git a/gradle.properties b/gradle.properties index 5451ab1..0d330ce 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,18 +26,18 @@ loader_version_range=[4,) # The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63} # Must match the String constant located in the main mod class annotated with @Mod. -mod_id=examplemod +mod_id=thinkbeforedrop # The human-readable display name for the mod. -mod_name=Example Mod +mod_name=Think Before Drop # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. -mod_license=All Rights Reserved +mod_license=MIT # The mod version. See https://semver.org/ -mod_version=1.0.0 +mod_version=2.1 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html -mod_group_id=com.example.examplemod +mod_group_id=com.haoooozhang # The authors of the mod. This is a simple text string that is used for display purposes in the mod list. -mod_authors=YourNameHere, OtherNameHere +mod_authors=HaooooZhang, IAFEnvoy # The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. -mod_description=Example mod description.\nNewline characters can be used and will be replaced properly. +mod_description=Press Q twice before drop specific items diff --git a/src/main/java/com/example/examplemod/Config.java b/src/main/java/com/example/examplemod/Config.java deleted file mode 100644 index d70d1eb..0000000 --- a/src/main/java/com/example/examplemod/Config.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.example.examplemod; - -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.fml.event.config.ModConfigEvent; -import net.neoforged.neoforge.common.ModConfigSpec; - -// An example config class. This is not required, but it's a good idea to have one to keep your config organized. -// Demonstrates how to use Neo's config APIs -@EventBusSubscriber(modid = ExampleMod.MODID, bus = EventBusSubscriber.Bus.MOD) -public class Config -{ - private static final ModConfigSpec.Builder BUILDER = new ModConfigSpec.Builder(); - - private static final ModConfigSpec.BooleanValue LOG_DIRT_BLOCK = BUILDER - .comment("Whether to log the dirt block on common setup") - .define("logDirtBlock", true); - - private static final ModConfigSpec.IntValue MAGIC_NUMBER = BUILDER - .comment("A magic number") - .defineInRange("magicNumber", 42, 0, Integer.MAX_VALUE); - - public static final ModConfigSpec.ConfigValue MAGIC_NUMBER_INTRODUCTION = BUILDER - .comment("What you want the introduction message to be for the magic number") - .define("magicNumberIntroduction", "The magic number is... "); - - // a list of strings that are treated as resource locations for items - private static final ModConfigSpec.ConfigValue> ITEM_STRINGS = BUILDER - .comment("A list of items to log on common setup.") - .defineListAllowEmpty("items", List.of("minecraft:iron_ingot"), Config::validateItemName); - - static final ModConfigSpec SPEC = BUILDER.build(); - - public static boolean logDirtBlock; - public static int magicNumber; - public static String magicNumberIntroduction; - public static Set items; - - private static boolean validateItemName(final Object obj) - { - return obj instanceof String itemName && BuiltInRegistries.ITEM.containsKey(ResourceLocation.parse(itemName)); - } - - @SubscribeEvent - static void onLoad(final ModConfigEvent event) - { - logDirtBlock = LOG_DIRT_BLOCK.get(); - magicNumber = MAGIC_NUMBER.get(); - magicNumberIntroduction = MAGIC_NUMBER_INTRODUCTION.get(); - - // convert the list of strings into a set of items - items = ITEM_STRINGS.get().stream() - .map(itemName -> BuiltInRegistries.ITEM.get(ResourceLocation.parse(itemName))) - .collect(Collectors.toSet()); - } -} diff --git a/src/main/java/com/example/examplemod/ExampleMod.java b/src/main/java/com/example/examplemod/ExampleMod.java deleted file mode 100644 index 835a48d..0000000 --- a/src/main/java/com/example/examplemod/ExampleMod.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.example.examplemod; - -import org.slf4j.Logger; - -import com.mojang.logging.LogUtils; - -import net.minecraft.client.Minecraft; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.chat.Component; -import net.minecraft.world.food.FoodProperties; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.CreativeModeTabs; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Blocks; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.material.MapColor; -import net.neoforged.api.distmarker.Dist; -import net.neoforged.bus.api.IEventBus; -import net.neoforged.bus.api.SubscribeEvent; -import net.neoforged.fml.ModContainer; -import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.fml.common.Mod; -import net.neoforged.fml.config.ModConfig; -import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; -import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent; -import net.neoforged.neoforge.common.NeoForge; -import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent; -import net.neoforged.neoforge.event.server.ServerStartingEvent; -import net.neoforged.neoforge.registries.DeferredBlock; -import net.neoforged.neoforge.registries.DeferredHolder; -import net.neoforged.neoforge.registries.DeferredItem; -import net.neoforged.neoforge.registries.DeferredRegister; - -// The value here should match an entry in the META-INF/neoforge.mods.toml file -@Mod(ExampleMod.MODID) -public class ExampleMod -{ - // Define mod id in a common place for everything to reference - public static final String MODID = "examplemod"; - // Directly reference a slf4j logger - private static final Logger LOGGER = LogUtils.getLogger(); - // Create a Deferred Register to hold Blocks which will all be registered under the "examplemod" namespace - public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MODID); - // Create a Deferred Register to hold Items which will all be registered under the "examplemod" namespace - public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID); - // Create a Deferred Register to hold CreativeModeTabs which will all be registered under the "examplemod" namespace - public static final DeferredRegister CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MODID); - - // Creates a new Block with the id "examplemod:example_block", combining the namespace and path - public static final DeferredBlock EXAMPLE_BLOCK = BLOCKS.registerSimpleBlock("example_block", BlockBehaviour.Properties.of().mapColor(MapColor.STONE)); - // Creates a new BlockItem with the id "examplemod:example_block", combining the namespace and path - public static final DeferredItem EXAMPLE_BLOCK_ITEM = ITEMS.registerSimpleBlockItem("example_block", EXAMPLE_BLOCK); - - // Creates a new food item with the id "examplemod:example_id", nutrition 1 and saturation 2 - public static final DeferredItem EXAMPLE_ITEM = ITEMS.registerSimpleItem("example_item", new Item.Properties().food(new FoodProperties.Builder() - .alwaysEdible().nutrition(1).saturationModifier(2f).build())); - - // Creates a creative tab with the id "examplemod:example_tab" for the example item, that is placed after the combat tab - public static final DeferredHolder EXAMPLE_TAB = CREATIVE_MODE_TABS.register("example_tab", () -> CreativeModeTab.builder() - .title(Component.translatable("itemGroup.examplemod")) //The language key for the title of your CreativeModeTab - .withTabsBefore(CreativeModeTabs.COMBAT) - .icon(() -> EXAMPLE_ITEM.get().getDefaultInstance()) - .displayItems((parameters, output) -> { - output.accept(EXAMPLE_ITEM.get()); // Add the example item to the tab. For your own tabs, this method is preferred over the event - }).build()); - - // The constructor for the mod class is the first code that is run when your mod is loaded. - // FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically. - public ExampleMod(IEventBus modEventBus, ModContainer modContainer) - { - // Register the commonSetup method for modloading - modEventBus.addListener(this::commonSetup); - - // Register the Deferred Register to the mod event bus so blocks get registered - BLOCKS.register(modEventBus); - // Register the Deferred Register to the mod event bus so items get registered - ITEMS.register(modEventBus); - // Register the Deferred Register to the mod event bus so tabs get registered - CREATIVE_MODE_TABS.register(modEventBus); - - // Register ourselves for server and other game events we are interested in. - // Note that this is necessary if and only if we want *this* class (ExampleMod) to respond directly to events. - // Do not add this line if there are no @SubscribeEvent-annotated functions in this class, like onServerStarting() below. - NeoForge.EVENT_BUS.register(this); - - // Register the item to a creative tab - modEventBus.addListener(this::addCreative); - - // Register our mod's ModConfigSpec so that FML can create and load the config file for us - modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC); - } - - private void commonSetup(final FMLCommonSetupEvent event) - { - // Some common setup code - LOGGER.info("HELLO FROM COMMON SETUP"); - - if (Config.logDirtBlock) - LOGGER.info("DIRT BLOCK >> {}", BuiltInRegistries.BLOCK.getKey(Blocks.DIRT)); - - LOGGER.info(Config.magicNumberIntroduction + Config.magicNumber); - - Config.items.forEach((item) -> LOGGER.info("ITEM >> {}", item.toString())); - } - - // Add the example block item to the building blocks tab - private void addCreative(BuildCreativeModeTabContentsEvent event) - { - if (event.getTabKey() == CreativeModeTabs.BUILDING_BLOCKS) - event.accept(EXAMPLE_BLOCK_ITEM); - } - - // You can use SubscribeEvent and let the Event Bus discover methods to call - @SubscribeEvent - public void onServerStarting(ServerStartingEvent event) - { - // Do something when the server starts - LOGGER.info("HELLO from server starting"); - } - - // You can use EventBusSubscriber to automatically register all static methods in the class annotated with @SubscribeEvent - @EventBusSubscriber(modid = MODID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) - public static class ClientModEvents - { - @SubscribeEvent - public static void onClientSetup(FMLClientSetupEvent event) - { - // Some client setup code - LOGGER.info("HELLO FROM CLIENT SETUP"); - LOGGER.info("MINECRAFT NAME >> {}", Minecraft.getInstance().getUser().getName()); - } - } -} diff --git a/src/main/java/net/haoooozhang/thinkbeforedrop/DropManager.java b/src/main/java/net/haoooozhang/thinkbeforedrop/DropManager.java new file mode 100644 index 0000000..3411040 --- /dev/null +++ b/src/main/java/net/haoooozhang/thinkbeforedrop/DropManager.java @@ -0,0 +1,91 @@ +package net.haoooozhang.thinkbeforedrop; + +import me.shedaniel.autoconfig.AutoConfig; +import net.minecraft.core.component.DataComponents; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.*; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.ShulkerBoxBlock; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; + +@OnlyIn(Dist.CLIENT) +public class DropManager { + private static long lastDropTime = 0; + private static int lastSlot = -1; + private static boolean dropped = false; + + private static boolean shouldHandleDrop(ItemStack stack){ + ModConfig config = AutoConfig.getConfigHolder(ModConfig.class).getConfig(); + if (!config.configenable) return false; + Item item = stack.getItem(); + Block block = null; + if (item instanceof BlockItem) + block = ((BlockItem) item).getBlock(); + ResourceLocation location = Registries.ITEM.location();//有问题 + assert location != null; + String name = location.toString(); + if (config.internal.weapon) + if (item instanceof SwordItem || item instanceof BowItem || item instanceof CrossbowItem || item instanceof TridentItem || item instanceof ArrowItem) + return true; + if (config.internal.tool) + if (item instanceof AxeItem || item instanceof PickaxeItem || item instanceof ShovelItem || item instanceof HoeItem) + return true; + if (config.internal.shulkerBox) + if (block != null) + if (block instanceof ShulkerBoxBlock) + return true; + if (config.internal.armor) + if (item instanceof ArmorItem || item instanceof ElytraItem) + return true; + //ore todo + if (config.internal.disc) + if (item instanceof DiscFragmentItem || item.components().has(DataComponents.JUKEBOX_PLAYABLE)) + return true; + if (config.internal.uncommon) + if (item.components().has(DataComponents.RARITY) == Rarity.UNCOMMON) + return true; + if (config.internal.rare) + if (item.components().has(DataComponents.RARITY) == Rarity.RARE) + return true; + if (config.internal.epic) + if (item.components().has(DataComponents.RARITY) == Rarity.EPIC) + return true; + if (config.internal.enchanted) { + if (stack.isEnchanted()) + return true; + } + //hasNBT Todo + //hasComponent Todo + if (config.internal.enchantedBook) + if (item instanceof EnchantedBookItem) + return true; + if (config.internal.book) + if (item instanceof WritableBookItem || item instanceof WrittenBookItem) + return true; + return config.custom.customItems.contains(name); + } + public static boolean shouldThrow(ItemStack stack, int slot) { + ModConfig config = AutoConfig.getConfigHolder(ModConfig.class).getConfig(); + if (slot != lastSlot) { + lastDropTime = 0; + dropped = false; + } + if (!shouldHandleDrop(stack) || dropped) return true; + long now = System.currentTimeMillis(); + if (now - lastDropTime >= config.time.minSecond * 1000 && now - lastDropTime <= config.time.maxSecond * 1000) { + if (stack.getCount() != 1) + dropped = true; + lastDropTime = 0; + return true; + } + lastDropTime = now; + lastSlot = slot; + return false; + } + public static Component getWarningText() { + return Component.translatable("tbt.warning"); + } +} diff --git a/src/main/java/net/haoooozhang/thinkbeforedrop/ModConfig.java b/src/main/java/net/haoooozhang/thinkbeforedrop/ModConfig.java new file mode 100644 index 0000000..0317a78 --- /dev/null +++ b/src/main/java/net/haoooozhang/thinkbeforedrop/ModConfig.java @@ -0,0 +1,54 @@ +package net.haoooozhang.thinkbeforedrop; + +import me.shedaniel.autoconfig.ConfigData; +import me.shedaniel.autoconfig.annotation.Config; +import me.shedaniel.autoconfig.annotation.ConfigEntry; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; + +import java.util.ArrayList; +import java.util.List; + +@OnlyIn(Dist.CLIENT) +@Config(name = ThinkBeforeDrop.MODID) +public class ModConfig implements ConfigData { + public boolean configenable = true; + @ConfigEntry.Gui.CollapsibleObject + public Time time = new Time(); + @ConfigEntry.Gui.CollapsibleObject + public Internal internal = new Internal(); + @ConfigEntry.Gui.CollapsibleObject + public Custom custom = new Custom(); + + //设置两次按下Q的允许间隔 + @Config(name = "time") + public static class Time implements ConfigData { + public double minSecond = 0.5; + public double maxSecond = 5; + } + + //配置表 + @Config(name = "internal") + public static class Internal implements ConfigData { + public boolean weapon = false;//所有武器 + public boolean tool = false;//所有工具 + public boolean shulkerBox = false;//所有潜影盒 + public boolean armor = false;//所有装备 + public boolean ore = false;//所有矿石 + public boolean disc = false;//所有唱片 + public boolean uncommon = false;//所有黄名物品 + public boolean rare = false;//所有蓝名物品 + public boolean epic = false;//所有紫名物品 + public boolean enchanted = false;//所有有附魔的物品,包括物品有的附魔(只能指令拿到的那种) + public boolean hasNbt = false;//所有有特殊nbt的(不包括耐久、附魔惩罚等) + public boolean hasComponent = false;//有hasComponent + public boolean enchantedBook = false;//所有附魔书 + public boolean book = false;//所有成书 + } + + @Config(name = "custom") + public static class Custom implements ConfigData { + public List customItems = new ArrayList<>();//自定义,使用英文逗号分隔 + public List excludeItems = new ArrayList<>();//排除物品,使用英文逗号分隔 + } +} diff --git a/src/main/java/net/haoooozhang/thinkbeforedrop/ThinkBeforeDrop.java b/src/main/java/net/haoooozhang/thinkbeforedrop/ThinkBeforeDrop.java new file mode 100644 index 0000000..743cc9a --- /dev/null +++ b/src/main/java/net/haoooozhang/thinkbeforedrop/ThinkBeforeDrop.java @@ -0,0 +1,19 @@ +package net.haoooozhang.thinkbeforedrop; + +import com.mojang.logging.LogUtils; +import me.shedaniel.autoconfig.AutoConfig; +import me.shedaniel.autoconfig.serializer.GsonConfigSerializer; +import net.neoforged.fml.common.Mod; +import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import org.slf4j.Logger; + +@Mod(ThinkBeforeDrop.MODID) +public class ThinkBeforeDrop { + public static final String MODID = "thinkbeforedrop"; + private static final Logger LOGGER = LogUtils.getLogger(); + + private void doClientStuff(final FMLClientSetupEvent event){ + AutoConfig.register(net.haoooozhang.thinkbeforedrop.ModConfig.class, GsonConfigSerializer::new); + //ModLoadingContext.get().registerExtensionPoint(Gui.ConfigScreenFactory.class, () -> new ConfigGuiHandler.ConfigGuiFactory((client, screen) -> AutoConfig.getConfigScreen(ModConfig.class, screen).get())); + } +} diff --git a/src/main/java/net/haoooozhang/thinkbeforedrop/mixin/ClientPlayerEntityMixin.java b/src/main/java/net/haoooozhang/thinkbeforedrop/mixin/ClientPlayerEntityMixin.java new file mode 100644 index 0000000..45ee194 --- /dev/null +++ b/src/main/java/net/haoooozhang/thinkbeforedrop/mixin/ClientPlayerEntityMixin.java @@ -0,0 +1,37 @@ +package net.haoooozhang.thinkbeforedrop.mixin; + +import com.mojang.authlib.GameProfile; +import net.haoooozhang.thinkbeforedrop.DropManager; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.player.AbstractClientPlayer; +import net.minecraft.client.player.LocalPlayer; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@OnlyIn(Dist.CLIENT) +@Mixin(LocalPlayer.class) +public class ClientPlayerEntityMixin extends AbstractClientPlayer{ + @Shadow + @Final + protected Minecraft minecraft; + + public ClientPlayerEntityMixin(ClientLevel world, GameProfile profile){ + super(world, profile); + } + + @Inject(method = "dropSelectedItem(Z)Z", at = @At("HEAD"), cancellable = true) + public void beforeDropItem(boolean dropEntireStack, CallbackInfoReturnable cir){ + if (!DropManager.shouldThrow(this.getInventory().getSelected(), this.getInventory().selected)) { + assert minecraft.player != null; + minecraft.player.displayClientMessage(DropManager.getWarningText(), true); + cir.setReturnValue(false); + } + } +} diff --git a/src/main/resources/META-INF/neoforge.mods.toml b/src/main/resources/META-INF/neoforge.mods.toml index 1b9f6e9..5f07996 100644 --- a/src/main/resources/META-INF/neoforge.mods.toml +++ b/src/main/resources/META-INF/neoforge.mods.toml @@ -84,6 +84,12 @@ description='''${mod_description}''' versionRange="${minecraft_version_range}" ordering="NONE" side="BOTH" +[[dependencies."${mod_id}"]] +modId = "cloth-config" +mandatory = true +versionRange = "[0,)" +ordering = "NONE" +side = "BOTH" # Features are specific properties of the game environment, that you may want to declare you require. This example declares # that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't diff --git a/src/main/resources/assets/thinkbeforedrop/lang/en_us.json b/src/main/resources/assets/thinkbeforedrop/lang/en_us.json new file mode 100644 index 0000000..f4fc2da --- /dev/null +++ b/src/main/resources/assets/thinkbeforedrop/lang/en_us.json @@ -0,0 +1,25 @@ +{ + "tbt.warning": "Press Q again to confirm dropping !", + "text.autoconfig.thinkbeforedrop.title": "Think Before Drop Menu", + "text.autoconfig.thinkbeforedrop.option.enabled": "Enabled", + "text.autoconfig.thinkbeforedrop.option.time": "Time Settings", + "text.autoconfig.thinkbeforedrop.option.time.minSecond": "Minimum confirm seconds", + "text.autoconfig.thinkbeforedrop.option.time.maxSecond": "Maximum confirm seconds", + "text.autoconfig.thinkbeforedrop.option.internal": "Internal Filters", + "text.autoconfig.thinkbeforedrop.option.internal.weapon": "All weapons", + "text.autoconfig.thinkbeforedrop.option.internal.tool": "All tools", + "text.autoconfig.thinkbeforedrop.option.internal.shulkerBox": "All skulker boxes", + "text.autoconfig.thinkbeforedrop.option.internal.armor": "All armor", + "text.autoconfig.thinkbeforedrop.option.internal.ore": "All ores", + "text.autoconfig.thinkbeforedrop.option.internal.disc": "All music disc", + "text.autoconfig.thinkbeforedrop.option.internal.uncommon": "All uncommon items", + "text.autoconfig.thinkbeforedrop.option.internal.rare": "All rare items", + "text.autoconfig.thinkbeforedrop.option.internal.epic": "All epic items", + "text.autoconfig.thinkbeforedrop.option.internal.enchanted": "All enchanted items", + "text.autoconfig.thinkbeforedrop.option.internal.hasNbt": "All items with nbt", + "text.autoconfig.thinkbeforedrop.option.internal.enchantedBook": "All enchanted books", + "text.autoconfig.thinkbeforedrop.option.internal.book": "All books", + "text.autoconfig.thinkbeforedrop.option.custom": "Custom Filters", + "text.autoconfig.thinkbeforedrop.option.custom.customItems": "Custom items", + "text.autoconfig.thinkbeforedrop.option.custom.excludeItems": "Exclude items" +} \ No newline at end of file diff --git a/src/main/resources/assets/thinkbeforedrop/lang/zh_cn.json b/src/main/resources/assets/thinkbeforedrop/lang/zh_cn.json new file mode 100644 index 0000000..0733fb0 --- /dev/null +++ b/src/main/resources/assets/thinkbeforedrop/lang/zh_cn.json @@ -0,0 +1,25 @@ +{ + "tbt.warning": "再次按下Q以确认丢出此物品", + "text.autoconfig.thinkbeforedrop.title": "丢弃物品保护设置", + "text.autoconfig.thinkbeforedrop.option.enabled": "启用", + "text.autoconfig.thinkbeforedrop.option.time": "时间设置", + "text.autoconfig.thinkbeforedrop.option.time.minSecond": "最小确认时间(秒数)", + "text.autoconfig.thinkbeforedrop.option.time.maxSecond": "最大确认时间(秒数)", + "text.autoconfig.thinkbeforedrop.option.internal": "内置筛选器", + "text.autoconfig.thinkbeforedrop.option.internal.weapon": "所有武器", + "text.autoconfig.thinkbeforedrop.option.internal.tool": "所有工具", + "text.autoconfig.thinkbeforedrop.option.internal.shulkerBox": "所有潜影盒", + "text.autoconfig.thinkbeforedrop.option.internal.armor": "所有装备", + "text.autoconfig.thinkbeforedrop.option.internal.ore": "所有矿石", + "text.autoconfig.thinkbeforedrop.option.internal.disc": "所有唱片", + "text.autoconfig.thinkbeforedrop.option.internal.uncommon": "所有少见物品", + "text.autoconfig.thinkbeforedrop.option.internal.rare": "所有稀有物品", + "text.autoconfig.thinkbeforedrop.option.internal.epic": "所有史诗物品", + "text.autoconfig.thinkbeforedrop.option.internal.enchanted": "所有附魔物品", + "text.autoconfig.thinkbeforedrop.option.internal.hasNbt": "所有带特殊nbt的物品", + "text.autoconfig.thinkbeforedrop.option.internal.enchantedBook": "所有附魔书", + "text.autoconfig.thinkbeforedrop.option.internal.book": "所有书与笔和成书", + "text.autoconfig.thinkbeforedrop.option.custom": "自定义筛选器", + "text.autoconfig.thinkbeforedrop.option.custom.customItems": "自定义物品", + "text.autoconfig.thinkbeforedrop.option.custom.excludeItems": "排除物品" +} \ No newline at end of file diff --git a/src/main/resources/icon.png b/src/main/resources/icon.png new file mode 100644 index 0000000..cdcc1b0 Binary files /dev/null and b/src/main/resources/icon.png differ diff --git a/src/main/resources/pack.mcmeta b/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..1718811 --- /dev/null +++ b/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "Think Before Drop resources", + "pack_format": 10 + } +} \ No newline at end of file diff --git a/src/main/resources/thinkbeforedrop.mixins.json b/src/main/resources/thinkbeforedrop.mixins.json new file mode 100644 index 0000000..2abe44c --- /dev/null +++ b/src/main/resources/thinkbeforedrop.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.haoooozhang.thinkbeforedrop.mixin", + "compatibilityLevel": "JAVA_17", + "refmap": "thinkbeforedrop.refmap.json", + "client": [ + "ClientPlayerEntityMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file