From 7feb23ce0e709d9816ae19a6ee4e12a3e84e1ac8 Mon Sep 17 00:00:00 2001 From: YocyCraft Date: Wed, 18 Dec 2024 02:28:06 +0800 Subject: [PATCH 1/8] Add Datagen for mod added damage types Add new damage type: lost in time --- .../assets/anvilcraft/lang/en_ud.json | 3 +- .../assets/anvilcraft/lang/en_us.json | 3 +- .../data/anvilcraft/damage_type/laser.json | 0 .../anvilcraft/damage_type/lost_in_time.json | 5 + .../tags/damage_type/bypasses_armor.json | 8 + .../tags/damage_type/bypasses_resistance.json | 8 + .../tags/damage_type/no_knockback.json | 8 + .../neoforge/tags/damage_type/is_magic.json | 8 + .../api/anvil/impl/TimeWarpBehavior.java | 225 +++++++++--------- .../anvilcraft/data/AnvilCraftDatagen.java | 7 +- .../dubhe/anvilcraft/data/lang/OtherLang.java | 3 +- .../data/provider/ModDamageTypeProvider.java | 36 +++ .../provider/ModDamageTypeTagProvider.java | 29 +++ .../dubhe/anvilcraft/init/ModDamageTypes.java | 11 + .../anvilcraft/mixin/DamageSourcesMixin.java | 8 + 15 files changed, 247 insertions(+), 115 deletions(-) rename src/{main => generated}/resources/data/anvilcraft/damage_type/laser.json (100%) create mode 100644 src/generated/resources/data/anvilcraft/damage_type/lost_in_time.json create mode 100644 src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json create mode 100644 src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json create mode 100644 src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json create mode 100644 src/generated/resources/data/neoforge/tags/damage_type/is_magic.json create mode 100644 src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeProvider.java create mode 100644 src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeTagProvider.java diff --git a/src/generated/resources/assets/anvilcraft/lang/en_ud.json b/src/generated/resources/assets/anvilcraft/lang/en_ud.json index f9a753400..356647a52 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_ud.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_ud.json @@ -263,7 +263,8 @@ "config.waila.plugin_anvilcraft": "ʇɟɐɹƆ ןıʌuⱯ", "config.waila.plugin_anvilcraft.power_provider": "ɹǝʍoԀ ʇɟɐɹƆ ןıʌuⱯ", "config.waila.plugin_anvilcraft.warning_percent": "pןoɥsǝɹɥ⟘ buıuɹɐM", - "death.attack.anvilcraft.laser": "˙ɹǝsɐן ʎq pǝɔɹǝıd sɐʍ %1$s", + "death.attack.anvilcraft.laser": "ɹǝsɐן ʎq pǝɔɹǝıd sɐʍ %1$s", + "death.attack.anvilcraft.lost_in_time": "ǝɯıʇ ɟo ɹǝʌıɹ ǝɥʇ uı ʇsoן sɐʍ %1$s", "enchantment.anvilcraft.beheading": "buıpɐǝɥǝᗺ", "enchantment.anvilcraft.felling": "buıןןǝℲ", "enchantment.anvilcraft.harvest": "ʇsǝʌɹɐH", diff --git a/src/generated/resources/assets/anvilcraft/lang/en_us.json b/src/generated/resources/assets/anvilcraft/lang/en_us.json index 6a59bc548..050f338f0 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_us.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_us.json @@ -263,7 +263,8 @@ "config.waila.plugin_anvilcraft": "Anvil Craft", "config.waila.plugin_anvilcraft.power_provider": "Anvil Craft Power", "config.waila.plugin_anvilcraft.warning_percent": "Warning Threshold", - "death.attack.anvilcraft.laser": "%1$s was pierced by laser.", + "death.attack.anvilcraft.laser": "%1$s was pierced by laser", + "death.attack.anvilcraft.lost_in_time": "%1$s was lost in the river of time", "enchantment.anvilcraft.beheading": "Beheading", "enchantment.anvilcraft.felling": "Felling", "enchantment.anvilcraft.harvest": "Harvest", diff --git a/src/main/resources/data/anvilcraft/damage_type/laser.json b/src/generated/resources/data/anvilcraft/damage_type/laser.json similarity index 100% rename from src/main/resources/data/anvilcraft/damage_type/laser.json rename to src/generated/resources/data/anvilcraft/damage_type/laser.json diff --git a/src/generated/resources/data/anvilcraft/damage_type/lost_in_time.json b/src/generated/resources/data/anvilcraft/damage_type/lost_in_time.json new file mode 100644 index 000000000..e38707aff --- /dev/null +++ b/src/generated/resources/data/anvilcraft/damage_type/lost_in_time.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "anvilcraft.lost_in_time", + "scaling": "when_caused_by_living_non_player" +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json new file mode 100644 index 000000000..0ccc6bb9c --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "anvilcraft:lost_in_time", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json new file mode 100644 index 000000000..0ccc6bb9c --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "anvilcraft:lost_in_time", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json b/src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json new file mode 100644 index 000000000..0ccc6bb9c --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "anvilcraft:lost_in_time", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json b/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json new file mode 100644 index 000000000..0ccc6bb9c --- /dev/null +++ b/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "anvilcraft:lost_in_time", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java b/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java index 9858f7eea..d69484e4b 100644 --- a/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java +++ b/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java @@ -5,6 +5,7 @@ import dev.dubhe.anvilcraft.block.CorruptedBeaconBlock; import dev.dubhe.anvilcraft.init.ModBlocks; import dev.dubhe.anvilcraft.init.ModComponents; +import dev.dubhe.anvilcraft.init.ModDamageTypes; import dev.dubhe.anvilcraft.init.ModRecipeTypes; import dev.dubhe.anvilcraft.item.HasMobBlockItem; import dev.dubhe.anvilcraft.recipe.ChanceItemStack; @@ -17,6 +18,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.Item; @@ -44,124 +46,125 @@ public boolean handle( float fallDistance, AnvilFallOnLandEvent event) { BlockState belowState = level.getBlockState(hitBlockPos.below()); - if (belowState.is(ModBlocks.CORRUPTED_BEACON) && belowState.getValue(CorruptedBeaconBlock.LIT)) { - Map items = level.getEntitiesOfClass(ItemEntity.class, new AABB(hitBlockPos)) - .stream() - .map(it -> Map.entry(it, it.getItem())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + if (!belowState.is(ModBlocks.CORRUPTED_BEACON) || !belowState.getValue(CorruptedBeaconBlock.LIT)) return false; - if (items.values().stream().anyMatch(it -> it.is(ModBlocks.RESIN_BLOCK.asItem()))) { - items.entrySet().stream() - .filter(it -> it.getValue().is(ModBlocks.RESIN_BLOCK.asItem())) - .map(it -> { - ItemStack itemStack = it.getValue(); - Entity entity = HasMobBlockItem.getMobFromItem(level, itemStack); - if (entity == null) { - return Map.entry(it.getKey(), new ItemStack(ModBlocks.AMBER_BLOCK)); - } - ItemStack result = new ItemStack( - entity.getType().getCategory() == MobCategory.MONSTER - && level.getRandom().nextFloat() <= 0.05 - ? ModBlocks.RESENTFUL_AMBER_BLOCK.asItem() - : ModBlocks.MOB_AMBER_BLOCK.asItem() - ); - HasMobBlockItem.SavedEntity savedEntity = itemStack.getComponents().get(ModComponents.SAVED_ENTITY); - result.set(ModComponents.SAVED_ENTITY, savedEntity); - return Map.entry(it.getKey(), result); - }) - .forEach(it -> { - ItemEntity old = it.getKey(); - ItemEntity itemEntity = new ItemEntity( - old.level(), - old.getX(), - old.getY(), - old.getZ(), - it.getValue() - ); - old.discard(); - old.level().addFreshEntity(itemEntity); - }); - return true; - } - TimeWarpRecipe.Input input = new TimeWarpRecipe.Input(items.values().stream().toList(), hitBlockState); - Optional> recipeOptional = level.getRecipeManager() - .getRecipeFor(ModRecipeTypes.TIME_WARP_TYPE.get(), input, level); - if (recipeOptional.isPresent()) { - RecipeHolder recipe = recipeOptional.get(); - int times = recipe.value().getMaxCraftTime(input); - Object2IntMap results = new Object2IntOpenHashMap<>(); - LootContext context; - if (level instanceof ServerLevel serverLevel) { - context = RecipeUtil.emptyLootContext(serverLevel); - } else { - return false; - } - for (int i = 0; i < times; i++) { - for (Ingredient ingredient : recipe.value().getIngredients()) { - for (ItemStack stack : items.values()) { - if (ingredient.test(stack)) { - stack.shrink(1); - break; - } - } + level.getEntitiesOfClass(LivingEntity.class, new AABB(hitBlockPos), LivingEntity::isAlive) + .forEach(it -> it.hurt(ModDamageTypes.lostInTime(level), Float.MAX_VALUE)); + + Map items = level.getEntitiesOfClass(ItemEntity.class, new AABB(hitBlockPos)) + .stream() + .map(it -> Map.entry(it, it.getItem())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + if (items.values().stream().anyMatch(it -> it.is(ModBlocks.RESIN_BLOCK.asItem()))) { + items.entrySet().stream() + .filter(it -> it.getValue().is(ModBlocks.RESIN_BLOCK.asItem())) + .map(it -> { + ItemStack itemStack = it.getValue(); + Entity entity = HasMobBlockItem.getMobFromItem(level, itemStack); + if (entity == null) { + return Map.entry(it.getKey(), new ItemStack(ModBlocks.AMBER_BLOCK)); } - for (ChanceItemStack stack : recipe.value().getResults()) { - int amount = stack.getStack().getCount() * stack.getAmount().getInt(context); - results.mergeInt(stack.getStack().getItem(), amount, Integer::sum); + ItemStack result = new ItemStack( + entity.getType().getCategory() == MobCategory.MONSTER + && level.getRandom().nextFloat() <= 0.05 + ? ModBlocks.RESENTFUL_AMBER_BLOCK.asItem() + : ModBlocks.MOB_AMBER_BLOCK.asItem() + ); + HasMobBlockItem.SavedEntity savedEntity = itemStack.getComponents().get(ModComponents.SAVED_ENTITY); + result.set(ModComponents.SAVED_ENTITY, savedEntity); + return Map.entry(it.getKey(), result); + }) + .forEach(it -> { + ItemEntity old = it.getKey(); + ItemEntity itemEntity = new ItemEntity( + old.level(), + old.getX(), + old.getY(), + old.getZ(), + it.getValue() + ); + old.discard(); + old.level().addFreshEntity(itemEntity); + }); + return true; + } + TimeWarpRecipe.Input input = new TimeWarpRecipe.Input(items.values().stream().toList(), hitBlockState); + Optional> recipeOptional = level.getRecipeManager() + .getRecipeFor(ModRecipeTypes.TIME_WARP_TYPE.get(), input, level); + if (recipeOptional.isEmpty()) return false; + RecipeHolder recipe = recipeOptional.get(); + int times = recipe.value().getMaxCraftTime(input); + Object2IntMap results = new Object2IntOpenHashMap<>(); + LootContext context; + if (level instanceof ServerLevel serverLevel) { + context = RecipeUtil.emptyLootContext(serverLevel); + } else { + return false; + } + for (int i = 0; i < times; i++) { + for (Ingredient ingredient : recipe.value().getIngredients()) { + for (ItemStack stack : items.values()) { + if (ingredient.test(stack)) { + stack.shrink(1); + break; } } - AnvilUtil.dropItems( - results.object2IntEntrySet().stream() - .map(entry -> new ItemStack(entry.getKey(), entry.getIntValue())) - .toList(), - level, - hitBlockPos.getCenter() - ); - if (recipe.value().isFromWater()) { - level.setBlockAndUpdate(hitBlockPos, recipe.value().getCauldron().defaultBlockState()); - } else { - if (recipe.value().isConsumeFluid()) { - if (hitBlockState.hasProperty(LayeredCauldronBlock.LEVEL)) { - int cauldronLevel = hitBlockState.getValue(LayeredCauldronBlock.LEVEL); - cauldronLevel -= Math.max(recipe.value().getRequiredFluidLevel(), 1); - if (cauldronLevel <= 0) { - level.setBlockAndUpdate(hitBlockPos, Blocks.CAULDRON.defaultBlockState()); - } else { - level.setBlockAndUpdate( - hitBlockPos, - hitBlockState.setValue(LayeredCauldronBlock.LEVEL, cauldronLevel) - ); - } - } else { - level.setBlockAndUpdate(hitBlockPos, Blocks.CAULDRON.defaultBlockState()); - } - } - if (recipe.value().isProduceFluid()) { - if (hitBlockState.hasProperty(LayeredCauldronBlock.LEVEL)) { - int cauldronLevel = hitBlockState.getValue(LayeredCauldronBlock.LEVEL); - cauldronLevel++; - level.setBlockAndUpdate( - hitBlockPos, - hitBlockState.setValue(LayeredCauldronBlock.LEVEL, cauldronLevel) - ); - } else { - level.setBlockAndUpdate( - hitBlockPos, - recipe.value().getCauldron().defaultBlockState() - ); - } + } + for (ChanceItemStack stack : recipe.value().getResults()) { + int amount = stack.getStack().getCount() * stack.getAmount().getInt(context); + results.mergeInt(stack.getStack().getItem(), amount, Integer::sum); + } + } + AnvilUtil.dropItems( + results.object2IntEntrySet().stream() + .map(entry -> new ItemStack(entry.getKey(), entry.getIntValue())) + .toList(), + level, + hitBlockPos.getCenter() + ); + if (recipe.value().isFromWater()) { + level.setBlockAndUpdate(hitBlockPos, recipe.value().getCauldron().defaultBlockState()); + } else { + if (recipe.value().isConsumeFluid()) { + if (hitBlockState.hasProperty(LayeredCauldronBlock.LEVEL)) { + int cauldronLevel = hitBlockState.getValue(LayeredCauldronBlock.LEVEL); + cauldronLevel -= Math.max(recipe.value().getRequiredFluidLevel(), 1); + if (cauldronLevel <= 0) { + level.setBlockAndUpdate(hitBlockPos, Blocks.CAULDRON.defaultBlockState()); + } else { + level.setBlockAndUpdate( + hitBlockPos, + hitBlockState.setValue(LayeredCauldronBlock.LEVEL, cauldronLevel) + ); } + } else { + level.setBlockAndUpdate(hitBlockPos, Blocks.CAULDRON.defaultBlockState()); + } + } + if (recipe.value().isProduceFluid()) { + if (hitBlockState.hasProperty(LayeredCauldronBlock.LEVEL)) { + int cauldronLevel = hitBlockState.getValue(LayeredCauldronBlock.LEVEL); + cauldronLevel++; + level.setBlockAndUpdate( + hitBlockPos, + hitBlockState.setValue(LayeredCauldronBlock.LEVEL, cauldronLevel) + ); + } else { + level.setBlockAndUpdate( + hitBlockPos, + recipe.value().getCauldron().defaultBlockState() + ); } - items.forEach((k, v) -> { - if (v.isEmpty()) { - k.discard(); - return; - } - k.setItem(v.copy()); - }); - return true; } } - return false; + items.forEach((k, v) -> { + if (v.isEmpty()) { + k.discard(); + return; + } + k.setItem(v.copy()); + }); + return true; } } diff --git a/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java b/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java index 4a721943c..b17384aed 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java @@ -3,6 +3,8 @@ import dev.dubhe.anvilcraft.AnvilCraft; import dev.dubhe.anvilcraft.data.advancement.AdvancementHandler; import dev.dubhe.anvilcraft.data.lang.LangHandler; +import dev.dubhe.anvilcraft.data.provider.ModDamageTypeProvider; +import dev.dubhe.anvilcraft.data.provider.ModDamageTypeTagProvider; import dev.dubhe.anvilcraft.data.provider.ModLootTableProvider; import dev.dubhe.anvilcraft.data.provider.ModPoiTagProvider; import dev.dubhe.anvilcraft.data.provider.ModRegistryProvider; @@ -43,7 +45,10 @@ public static void gatherData(GatherDataEvent event) { generator.addProvider(event.includeServer(), new ModRegistryProvider(packOutput, lookupProvider)); generator.addProvider(event.includeServer(), new ModLootTableProvider(packOutput, lookupProvider)); generator.addProvider( - event.includeServer(), new ModPoiTagProvider(packOutput, lookupProvider, existingFileHelper)); + event.includeServer(), new ModPoiTagProvider(packOutput, lookupProvider, existingFileHelper)); + generator.addProvider(event.includeServer(), new ModDamageTypeProvider(packOutput, lookupProvider)); + generator.addProvider( + event.includeServer(), new ModDamageTypeTagProvider(packOutput, lookupProvider, existingFileHelper)); } /** diff --git a/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java b/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java index 7778862df..c7f099c85 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java @@ -35,6 +35,7 @@ public static void init(@NotNull RegistrateLangProvider provider) { provider.add("enchantment.anvilcraft.beheading", "Beheading"); provider.add("enchantment.anvilcraft.felling", "Felling"); provider.add("enchantment.anvilcraft.harvest", "Harvest"); - provider.add("death.attack.anvilcraft.laser", "%1$s was pierced by laser."); + provider.add("death.attack.anvilcraft.laser", "%1$s was pierced by laser"); + provider.add("death.attack.anvilcraft.lost_in_time", "%1$s was lost in the river of time"); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeProvider.java b/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeProvider.java new file mode 100644 index 000000000..28cb4aa08 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeProvider.java @@ -0,0 +1,36 @@ +package dev.dubhe.anvilcraft.data.provider; + +import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.init.ModDamageTypes; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.RegistrySetBuilder; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.PackOutput; +import net.minecraft.data.worldgen.BootstrapContext; +import net.minecraft.world.damagesource.DamageEffects; +import net.minecraft.world.damagesource.DamageType; +import net.neoforged.neoforge.common.data.DatapackBuiltinEntriesProvider; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; +import java.util.concurrent.CompletableFuture; + +public class ModDamageTypeProvider extends DatapackBuiltinEntriesProvider { + private static final RegistrySetBuilder BUILDER = new RegistrySetBuilder() + .add(Registries.DAMAGE_TYPE, ModDamageTypeProvider::bootstrap); + + public static void bootstrap(BootstrapContext ctx) { + ctx.register(ModDamageTypes.LASER, new DamageType("anvilcraft.laser", 0.1f, DamageEffects.BURNING)); + ctx.register(ModDamageTypes.LOST_IN_TIME, new DamageType("anvilcraft.lost_in_time", 0.1f)); + } + + public ModDamageTypeProvider(PackOutput output, CompletableFuture registries) { + super(output, registries, BUILDER, Set.of(AnvilCraft.MOD_ID)); + } + + @Override + @NotNull + public String getName() { + return "AnvilCraft's Damage Type data"; + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeTagProvider.java b/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeTagProvider.java new file mode 100644 index 000000000..94a5e294d --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeTagProvider.java @@ -0,0 +1,29 @@ +package dev.dubhe.anvilcraft.data.provider; + +import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.init.ModDamageTypes; +import net.minecraft.core.HolderLookup; +import net.minecraft.data.PackOutput; +import net.minecraft.data.tags.DamageTypeTagsProvider; +import net.minecraft.tags.DamageTypeTags; +import net.neoforged.neoforge.common.Tags; +import net.neoforged.neoforge.common.data.ExistingFileHelper; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.concurrent.CompletableFuture; + +public class ModDamageTypeTagProvider extends DamageTypeTagsProvider { + + public ModDamageTypeTagProvider(PackOutput output, CompletableFuture lookupProvider, @Nullable ExistingFileHelper existingFileHelper) { + super(output, lookupProvider, AnvilCraft.MOD_ID, existingFileHelper); + } + + @Override + protected void addTags(@NotNull HolderLookup.Provider pProvider) { + this.tag(DamageTypeTags.BYPASSES_ARMOR).addOptional(ModDamageTypes.LOST_IN_TIME.location()); + this.tag(DamageTypeTags.BYPASSES_RESISTANCE).addOptional(ModDamageTypes.LOST_IN_TIME.location()); + this.tag(DamageTypeTags.NO_KNOCKBACK).addOptional(ModDamageTypes.LOST_IN_TIME.location()); + this.tag(Tags.DamageTypes.IS_MAGIC).addOptional(ModDamageTypes.LOST_IN_TIME.location()); + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/init/ModDamageTypes.java b/src/main/java/dev/dubhe/anvilcraft/init/ModDamageTypes.java index a1e501f92..672c28aa2 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/ModDamageTypes.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/ModDamageTypes.java @@ -4,6 +4,7 @@ import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.damagesource.DamageSources; import net.minecraft.world.damagesource.DamageType; import net.minecraft.world.level.Level; @@ -12,12 +13,22 @@ public class ModDamageTypes { Registries.DAMAGE_TYPE, AnvilCraft.of("laser") ); + public static final ResourceKey LOST_IN_TIME = ResourceKey.create( + Registries.DAMAGE_TYPE, + AnvilCraft.of("lost_in_time") + ); public static DamageSource laser(Level level) { return ((DamageSourceExtra) level.damageSources()).laser(); } + public static DamageSource lostInTime(Level level) { + return ((DamageSourceExtra) level.damageSources()).lostInTime(); + } + + public interface DamageSourceExtra { DamageSource laser(); + DamageSource lostInTime(); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/DamageSourcesMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/DamageSourcesMixin.java index a08c96f21..2aa864f7a 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/DamageSourcesMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/DamageSourcesMixin.java @@ -19,6 +19,8 @@ public abstract class DamageSourcesMixin implements ModDamageTypes.DamageSourceE @Unique private DamageSource anvilCraft$laser; + @Unique + private DamageSource anvilCraft$lostInTime; @Inject( method = "", @@ -26,10 +28,16 @@ public abstract class DamageSourcesMixin implements ModDamageTypes.DamageSourceE ) void initModDamageSources(RegistryAccess registry, CallbackInfo ci){ anvilCraft$laser = this.source(ModDamageTypes.LASER); + anvilCraft$lostInTime = this.source(ModDamageTypes.LOST_IN_TIME); } @Override public DamageSource laser() { return anvilCraft$laser; } + + @Override + public DamageSource lostInTime(){ + return anvilCraft$lostInTime; + } } From 8f41c835b2a4a8dcab5bdd82eedbb6234669ce19 Mon Sep 17 00:00:00 2001 From: Gugle Date: Wed, 18 Dec 2024 12:21:16 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=B9=BB=E7=81=B5?= =?UTF-8?q?=E9=93=81=E7=A0=A7=E8=A7=A6=E5=8F=91=E6=96=B9=E5=BC=8F=E4=B8=BA?= =?UTF-8?q?=E7=A3=81=E9=93=81=E4=B8=8B=E9=99=8D=E6=B2=BF=E8=A7=A6=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/dev/dubhe/anvilcraft/AnvilCraft.java | 20 +++++++++---------- .../dubhe/anvilcraft/block/MagnetBlock.java | 4 ++-- .../anvilcraft/block/SpectralAnvilBlock.java | 12 ++++++----- .../entity/FallingSpectralBlockEntity.java | 8 ++++---- .../anvilcraft/mixin/HopperBlockMixin.java | 4 +++- .../EmbChunkBuilderMeshingTaskMixin.java | 5 +++-- .../SodiumChunkBuilderMeshingTaskMixin.java | 2 +- .../dev/dubhe/anvilcraft/util/MagnetUtil.java | 17 ++++++++++++++++ 8 files changed, 46 insertions(+), 26 deletions(-) create mode 100644 src/main/java/dev/dubhe/anvilcraft/util/MagnetUtil.java diff --git a/src/main/java/dev/dubhe/anvilcraft/AnvilCraft.java b/src/main/java/dev/dubhe/anvilcraft/AnvilCraft.java index ac37d4b2a..6683c7e47 100644 --- a/src/main/java/dev/dubhe/anvilcraft/AnvilCraft.java +++ b/src/main/java/dev/dubhe/anvilcraft/AnvilCraft.java @@ -34,7 +34,6 @@ import net.minecraft.util.Unit; import net.minecraft.world.item.crafting.RecipeManager; import net.neoforged.bus.api.IEventBus; -import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.Mod; import net.neoforged.fml.event.lifecycle.FMLLoadCompleteEvent; import net.neoforged.neoforge.common.NeoForge; @@ -65,9 +64,8 @@ public class AnvilCraft { .getConfig(); public static final Registrate REGISTRATE = Registrate.create(MOD_ID); - private final Logger logger = LoggerFactory.getLogger("AnvilCraft"); - public AnvilCraft(IEventBus modEventBus, ModContainer container) { + public AnvilCraft(IEventBus modEventBus) { ModItemGroups.register(modEventBus); ModBlocks.register(); ModFluids.register(modEventBus); @@ -90,11 +88,11 @@ public AnvilCraft(IEventBus modEventBus, ModContainer container) { AnvilCraftDatagen.init(); registerEvents(modEventBus); - logger.info("Ciallo~(∠・ω< )⌒★"); - logger.info("let's 0721!"); + LOGGER.info("Ciallo~(∠・ω< )⌒★"); + LOGGER.info("let's 0721!"); } - private static void registerEvents(IEventBus eventBus) { + private static void registerEvents(@NotNull IEventBus eventBus) { NeoForge.EVENT_BUS.addListener(AnvilCraft::registerCommand); NeoForge.EVENT_BUS.addListener(AnvilCraft::addReloadListeners); NeoForge.EVENT_BUS.addListener(AnvilCraft::addItemTooltips); @@ -112,16 +110,16 @@ public static void registerCommand(@NotNull RegisterCommandsEvent event) { ModCommands.register(event.getDispatcher()); } - public static void registerPayload(RegisterPayloadHandlersEvent event) { + public static void registerPayload(@NotNull RegisterPayloadHandlersEvent event) { PayloadRegistrar registrar = event.registrar("1"); ModNetworks.init(registrar); } - public static void addItemTooltips(ItemTooltipEvent event) { + public static void addItemTooltips(@NotNull ItemTooltipEvent event) { ItemTooltipManager.addTooltip(event.getItemStack(), event.getToolTip()); } - public static void addReloadListeners(AddReloadListenerEvent event) { + public static void addReloadListeners(@NotNull AddReloadListenerEvent event) { RecipeManager recipeManager = event.getServerResources().getRecipeManager(); event.addListener( ( @@ -136,7 +134,7 @@ public static void addReloadListeners(AddReloadListenerEvent event) { ); } - public static void loadComplete(FMLLoadCompleteEvent event) { + public static void loadComplete(@NotNull FMLLoadCompleteEvent event) { event.enqueueWork(() -> { ModInteractionMap.initInteractionMap(); if (Util.isLoaded("theoneprobe")) { @@ -146,7 +144,7 @@ public static void loadComplete(FMLLoadCompleteEvent event) { }); } - public static void packSetup(AddPackFindersEvent event) { + public static void packSetup(@NotNull AddPackFindersEvent event) { event.addPackFinders( of("resourcepacks/transparent_cauldron"), PackType.CLIENT_RESOURCES, diff --git a/src/main/java/dev/dubhe/anvilcraft/block/MagnetBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/MagnetBlock.java index d74af1122..d518526b4 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/MagnetBlock.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/MagnetBlock.java @@ -81,7 +81,7 @@ public void neighborChanged( if (bl) { level.scheduleTick(pos, this, 4); } else { - level.setBlock(pos, state.cycle(LIT), 2); + level.setBlockAndUpdate(pos, state.cycle(LIT)); } } } @@ -156,7 +156,7 @@ public void tick( BlockPos pos, RandomSource random) { if (state.getValue(LIT) && !level.hasNeighborSignal(pos)) { - level.setBlock(pos, state.cycle(LIT), 2); + level.setBlockAndUpdate(pos, state.cycle(LIT)); } } } diff --git a/src/main/java/dev/dubhe/anvilcraft/block/SpectralAnvilBlock.java b/src/main/java/dev/dubhe/anvilcraft/block/SpectralAnvilBlock.java index 2c19728b5..89dd9744a 100644 --- a/src/main/java/dev/dubhe/anvilcraft/block/SpectralAnvilBlock.java +++ b/src/main/java/dev/dubhe/anvilcraft/block/SpectralAnvilBlock.java @@ -3,6 +3,7 @@ import dev.dubhe.anvilcraft.api.hammer.IHammerRemovable; import dev.dubhe.anvilcraft.entity.FallingSpectralBlockEntity; +import dev.dubhe.anvilcraft.util.MagnetUtil; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; @@ -56,7 +57,8 @@ public class SpectralAnvilBlock extends Block implements IHammerRemovable { public SpectralAnvilBlock(Properties properties) { super(properties); this.registerDefaultState( - this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(POWERED, false)); + this.stateDefinition.any().setValue(FACING, Direction.NORTH).setValue(POWERED, false) + ); } @Override @@ -141,13 +143,13 @@ public void neighborChanged( BlockPos neighborPos, boolean movedByPiston ) { - boolean hasNeighborSignal = level.hasNeighborSignal(pos); + boolean hasNeighborSignal = MagnetUtil.hasMagnetism(level, pos); boolean currentPowered = state.getValue(POWERED); if (hasNeighborSignal && !currentPowered) { - level.scheduleTick(pos, this, 4); - level.setBlock(pos, state.setValue(POWERED, Boolean.TRUE), 2); + level.setBlockAndUpdate(pos, state.setValue(POWERED, true)); } else if (!hasNeighborSignal && currentPowered) { - level.setBlock(pos, state.setValue(POWERED, Boolean.FALSE), 2); + level.scheduleTick(pos, this, 4); + level.setBlockAndUpdate(pos, state.setValue(POWERED, false)); } } } diff --git a/src/main/java/dev/dubhe/anvilcraft/entity/FallingSpectralBlockEntity.java b/src/main/java/dev/dubhe/anvilcraft/entity/FallingSpectralBlockEntity.java index 002724d64..11a00da28 100644 --- a/src/main/java/dev/dubhe/anvilcraft/entity/FallingSpectralBlockEntity.java +++ b/src/main/java/dev/dubhe/anvilcraft/entity/FallingSpectralBlockEntity.java @@ -148,8 +148,7 @@ public boolean causeFallDamage(float fallDistance, float multiplier, DamageSourc if (dist < 0) { return false; } - Predicate predicate = - EntitySelector.NO_CREATIVE_OR_SPECTATOR.and(EntitySelector.LIVING_ENTITY_STILL_ALIVE); + Predicate predicate = EntitySelector.NO_CREATIVE_OR_SPECTATOR.and(EntitySelector.LIVING_ENTITY_STILL_ALIVE); float f = (float) Math.min(Mth.floor((float) dist * 2), 40); this.level().getEntities(this, this.getBoundingBox(), predicate).forEach(entity -> entity.hurt(source, f)); boolean isAnvil = this.blockState.is(BlockTags.ANVIL); @@ -177,8 +176,9 @@ protected static boolean shouldIgnoreBlockInMovement(BlockState blockState) { /** * 落下幻灵实体 */ - public static FallingSpectralBlockEntity fall( - Level level, BlockPos pos, BlockState blockState, boolean updateBlock, boolean isGhostEntity) { + public static @NotNull FallingSpectralBlockEntity fall( + Level level, BlockPos pos, BlockState blockState, boolean updateBlock, boolean isGhostEntity + ) { FallingSpectralBlockEntity fallingBlockEntity = new FallingSpectralBlockEntity( level, (double) pos.getX() + 0.5, diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/HopperBlockMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/HopperBlockMixin.java index a7ce90d12..25739cb86 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/HopperBlockMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/HopperBlockMixin.java @@ -17,17 +17,19 @@ import org.spongepowered.asm.mixin.Shadow; @Mixin(HopperBlock.class) -public class HopperBlockMixin implements IHammerChangeable { +abstract class HopperBlockMixin implements IHammerChangeable { @Shadow @Final public static DirectionProperty FACING; @Override + @SuppressWarnings("AddedMixinMembersNamePattern") public boolean change(Player player, BlockPos blockPos, @NotNull Level level, ItemStack anvilHammer) { return level.setBlockAndUpdate(blockPos, level.getBlockState(blockPos).cycle(FACING)); } @Override + @SuppressWarnings("AddedMixinMembersNamePattern") public @Nullable Property getChangeableProperty(BlockState blockState) { return FACING; } diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/compat/EmbChunkBuilderMeshingTaskMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/compat/EmbChunkBuilderMeshingTaskMixin.java index f81bfc39f..19af659e0 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/compat/EmbChunkBuilderMeshingTaskMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/compat/EmbChunkBuilderMeshingTaskMixin.java @@ -9,11 +9,12 @@ import org.embeddedt.embeddium.impl.render.chunk.compile.ChunkBuildBuffers; import org.embeddedt.embeddium.impl.render.chunk.compile.pipeline.BlockRenderer; import org.embeddedt.embeddium.impl.render.chunk.compile.tasks.ChunkBuilderMeshingTask; +import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @Mixin(ChunkBuilderMeshingTask.class) -public class EmbChunkBuilderMeshingTaskMixin { +abstract class EmbChunkBuilderMeshingTaskMixin { @WrapOperation( method = "execute(Lorg/embeddedt/embeddium/impl/render/chunk/compile/ChunkBuildContext;Lorg/embeddedt/embeddium/impl/util/task/CancellationToken;)Lorg/embeddedt/embeddium/impl/render/chunk/compile/ChunkBuildOutput;", at = @At( @@ -23,7 +24,7 @@ public class EmbChunkBuilderMeshingTaskMixin { ) void skipBlock( BlockRenderer instance, - BlockRenderContext context, + @NotNull BlockRenderContext context, ChunkBuildBuffers consumer, Operation original ) { diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/compat/SodiumChunkBuilderMeshingTaskMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/compat/SodiumChunkBuilderMeshingTaskMixin.java index b9b23bf93..14d1f934a 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/compat/SodiumChunkBuilderMeshingTaskMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/compat/SodiumChunkBuilderMeshingTaskMixin.java @@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.At; @Mixin(ChunkBuilderMeshingTask.class) -public class SodiumChunkBuilderMeshingTaskMixin { +abstract class SodiumChunkBuilderMeshingTaskMixin { @WrapOperation( method = "execute(Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/ChunkBuildContext;Lnet/caffeinemc/mods/sodium/client/util/task/CancellationToken;)Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/ChunkBuildOutput;", at = @At( diff --git a/src/main/java/dev/dubhe/anvilcraft/util/MagnetUtil.java b/src/main/java/dev/dubhe/anvilcraft/util/MagnetUtil.java new file mode 100644 index 000000000..1bc179a94 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/util/MagnetUtil.java @@ -0,0 +1,17 @@ +package dev.dubhe.anvilcraft.util; + +import dev.dubhe.anvilcraft.block.MagnetBlock; +import dev.dubhe.anvilcraft.init.ModBlockTags; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.NotNull; + +public abstract class MagnetUtil { + public static boolean hasMagnetism(@NotNull Level level, @NotNull BlockPos pos) { + BlockState state = level.getBlockState(pos.above()); + return (state.is(ModBlockTags.MAGNET) || state.getBlock() instanceof MagnetBlock) + && state.hasProperty(MagnetBlock.LIT) + && !state.getValue(MagnetBlock.LIT); + } +} From ac4cc92d7bd9f4761433fea04f6751ec14f3ff2e Mon Sep 17 00:00:00 2001 From: YocyCraft Date: Wed, 18 Dec 2024 12:22:34 +0800 Subject: [PATCH 3/8] Add particle for lost in time damage Resolve conflict with Curtain mod. Fixed #1338 --- .../api/anvil/impl/TimeWarpBehavior.java | 23 +++++++++++++++++-- .../anvilcraft/mixin/ItemEntityMixin.java | 21 ++++++++++------- .../forge/PistonMovingBlockEntityMixin.java | 18 --------------- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java b/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java index d69484e4b..c2cbbf1fa 100644 --- a/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java +++ b/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java @@ -16,6 +16,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; @@ -31,12 +32,16 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; public class TimeWarpBehavior implements IAnvilBehavior { + public static final int SOUL_PARTICLE_COUNT = 3; + @SuppressWarnings("DuplicatedCode") @Override public boolean handle( @@ -48,8 +53,22 @@ public boolean handle( BlockState belowState = level.getBlockState(hitBlockPos.below()); if (!belowState.is(ModBlocks.CORRUPTED_BEACON) || !belowState.getValue(CorruptedBeaconBlock.LIT)) return false; - level.getEntitiesOfClass(LivingEntity.class, new AABB(hitBlockPos), LivingEntity::isAlive) - .forEach(it -> it.hurt(ModDamageTypes.lostInTime(level), Float.MAX_VALUE)); + List damagedEntities = level.getEntitiesOfClass( + LivingEntity.class, + new AABB(hitBlockPos), + LivingEntity::isAlive); + if(!damagedEntities.isEmpty()){ + damagedEntities.forEach(it -> it.hurt(ModDamageTypes.lostInTime(level), Float.MAX_VALUE)); + if(level instanceof ServerLevel serverLevel && damagedEntities.stream().anyMatch(LivingEntity::isDeadOrDying)){ + Vec3 particleCenter = hitBlockPos.above().getCenter(); + serverLevel.sendParticles(ParticleTypes.SOUL, + particleCenter.x, + particleCenter.y, + particleCenter.z, + SOUL_PARTICLE_COUNT, + 0.4, 0.4, 0.4, 0.01); + } + } Map items = level.getEntitiesOfClass(ItemEntity.class, new AABB(hitBlockPos)) .stream() diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/ItemEntityMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/ItemEntityMixin.java index db55061fe..278935d7f 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/ItemEntityMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/ItemEntityMixin.java @@ -1,6 +1,5 @@ package dev.dubhe.anvilcraft.mixin; -import dev.dubhe.anvilcraft.AnvilCraft; import dev.dubhe.anvilcraft.block.HollowMagnetBlock; import dev.dubhe.anvilcraft.init.ModBlockTags; import dev.dubhe.anvilcraft.init.ModBlocks; @@ -8,7 +7,6 @@ import dev.dubhe.anvilcraft.init.ModItems; import dev.dubhe.anvilcraft.item.IFireReforging; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.DamageTypeTags; import net.minecraft.util.Mth; @@ -17,6 +15,7 @@ import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.phys.AABB; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @@ -25,7 +24,6 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; -import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; import net.neoforged.neoforge.event.EventHooks; import org.jetbrains.annotations.NotNull; @@ -63,10 +61,10 @@ abstract class ItemEntityMixin extends Entity { protected abstract void setUnderwaterMovement(); @Shadow - public abstract boolean isMergable(); + protected abstract boolean isMergable(); @Shadow - public abstract void mergeWithNeighbours(); + protected abstract void mergeWithNeighbours(); @Shadow private int pickupDelay; @@ -173,7 +171,7 @@ private void slidingRailProgress(CallbackInfoReturnable cir) { // 以下是中子锭运动相关mixin @Inject(method = "tick", at = @At("HEAD"), cancellable = true) - private void neutroniumTick(CallbackInfo ci){ + private void anvilcraft$neutroniumTick(CallbackInfo ci){ ItemStack item = this.getItem(); if (!item.is(ModItems.NEUTRONIUM_INGOT)) return; if (item.onEntityItemUpdate((ItemEntity) (Object) this)) { @@ -211,7 +209,7 @@ private void neutroniumTick(CallbackInfo ci){ this.applyGravity(); this.noPhysics = false; if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > (double)1.0E-5F || (this.tickCount + this.getId()) % 4 == 0) { - this.neutroniumMove(MoverType.SELF, this.getDeltaMovement()); + this.anvilCraft$neutroniumMove(MoverType.SELF, this.getDeltaMovement()); float f = 0.98F; if (this.onGround()) { BlockPos groundPos = this.getBlockPosBelowThatAffectsMyMovement(); @@ -252,8 +250,15 @@ private void neutroniumTick(CallbackInfo ci){ ci.cancel(); } + @Override + @NotNull + public PushReaction getPistonPushReaction(){ + if(this.getItem().is(ModItems.NEUTRONIUM_INGOT)) return PushReaction.IGNORE; + return super.getPistonPushReaction(); + } + @Unique - private void neutroniumMove(MoverType moverType, Vec3 motion) { + private void anvilCraft$neutroniumMove(MoverType moverType, Vec3 motion) { this.level().getProfiler().push("move"); //代替原版move方法中的collide调用 diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/forge/PistonMovingBlockEntityMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/forge/PistonMovingBlockEntityMixin.java index b1e59381f..5e38a260a 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/forge/PistonMovingBlockEntityMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/forge/PistonMovingBlockEntityMixin.java @@ -1,15 +1,11 @@ package dev.dubhe.anvilcraft.mixin.forge; import dev.dubhe.anvilcraft.block.ResinBlock; -import dev.dubhe.anvilcraft.init.ModItems; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.SlimeBlock; import net.minecraft.world.level.block.piston.PistonMovingBlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.PushReaction; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; @@ -31,18 +27,4 @@ private static boolean isElastic(@NotNull BlockState instance) { return block instanceof SlimeBlock || block instanceof ResinBlock; } - @Redirect( - method = "moveCollidedEntities", - at = @At( - value = "INVOKE", - remap = false, - target = "Lnet/minecraft/world/entity/Entity;getPistonPushReaction()Lnet/minecraft/world/level/material/PushReaction;" - ) - ) - private static PushReaction cancelPistonPushForNeutronium(Entity entity) { - if (entity instanceof ItemEntity itemEntity && itemEntity.getItem().is(ModItems.NEUTRONIUM_INGOT.get())) { - return PushReaction.IGNORE; - } - return entity.getPistonPushReaction(); - } } From 8366540c37039d942ba8937f3b77ab9f4ee617cc Mon Sep 17 00:00:00 2001 From: Gugle Date: Wed, 18 Dec 2024 12:29:08 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=93=81=E7=A0=A7?= =?UTF-8?q?=E7=A9=BF=E8=BF=87=E6=9C=AB=E5=9C=B0=E9=97=A8=E6=97=B6=E6=88=90?= =?UTF-8?q?=E5=8A=9F=E5=8F=98=E5=8C=96=E4=B8=BA=E5=B9=BB=E7=81=B5=E9=93=81?= =?UTF-8?q?=E7=A0=A7=E7=9A=84=E6=A6=82=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../anvilcraft/mixin/EndPortalBlockMixin.java | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/EndPortalBlockMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/EndPortalBlockMixin.java index acd25ec4b..f2ad53649 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/EndPortalBlockMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/EndPortalBlockMixin.java @@ -8,6 +8,7 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.item.FallingBlockEntity; import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.EndPortalBlock; import net.minecraft.world.level.block.Portal; import net.minecraft.world.level.block.state.BlockState; @@ -20,21 +21,36 @@ @Mixin(EndPortalBlock.class) abstract class EndPortalBlockMixin { @Inject( - method = "entityInside", - at = - @At( - value = "INVOKE", - target = - "Lnet/minecraft/world/entity/Entity;setAsInsidePortal(Lnet/minecraft/world/level/block/Portal;Lnet/minecraft/core/BlockPos;)V"), - cancellable = true) + method = "entityInside", + at = + @At( + value = "INVOKE", + target = + "Lnet/minecraft/world/entity/Entity;setAsInsidePortal(Lnet/minecraft/world/level/block/Portal;Lnet/minecraft/core/BlockPos;)V"), + cancellable = true) private void fallBlockEntityInside( - BlockState pState, Level pLevel, BlockPos pPos, Entity pEntity, CallbackInfo ci) { + BlockState pState, Level pLevel, BlockPos pPos, Entity pEntity, CallbackInfo ci) { if (pEntity instanceof FallingBlockEntity fallingBlockEntity - && !fallingBlockEntity.blockState.is(ModBlockTags.END_PORTAL_UNABLE_CHANGE)) { + && !fallingBlockEntity.blockState.is(ModBlockTags.END_PORTAL_UNABLE_CHANGE)) { + fallingBlockEntity.blockState = ModBlocks.END_DUST.getDefaultState(); + anvil: if (fallingBlockEntity.blockState.is(BlockTags.ANVIL)) { + double rand = pLevel.random.nextDouble(); + if (fallingBlockEntity.blockState.is(Blocks.DAMAGED_ANVIL) && rand >= 0.01) { + break anvil; + } else if (fallingBlockEntity.blockState.is(Blocks.CHIPPED_ANVIL) && rand >= 0.02) { + break anvil; + } else if (fallingBlockEntity.blockState.is(Blocks.ANVIL) && rand >= 0.03) { + break anvil; + } else if (fallingBlockEntity.blockState.is(ModBlocks.ROYAL_ANVIL) && rand >= 0.5) { + break anvil; + } else if (fallingBlockEntity.blockState.is(ModBlocks.EMBER_ANVIL)) { + fallingBlockEntity.blockState = ModBlocks.SPECTRAL_ANVIL.getDefaultState(); + break anvil; + } else if (rand >= 0.03) { + break anvil; + } fallingBlockEntity.blockState = ModBlocks.SPECTRAL_ANVIL.getDefaultState(); - } else { - fallingBlockEntity.blockState = ModBlocks.END_DUST.getDefaultState(); } fallingBlockEntity.setAsInsidePortal((Portal) this, pPos); ci.cancel(); From 6c9474d8e1954a785e33290e2c90f25dc19821d1 Mon Sep 17 00:00:00 2001 From: YocyCraft Date: Wed, 18 Dec 2024 02:28:06 +0800 Subject: [PATCH 5/8] Add Datagen for mod added damage types Add new damage type: lost in time --- .../assets/anvilcraft/lang/en_ud.json | 3 +- .../assets/anvilcraft/lang/en_us.json | 3 +- .../data/anvilcraft/damage_type/laser.json | 0 .../anvilcraft/damage_type/lost_in_time.json | 5 + .../tags/damage_type/bypasses_armor.json | 8 + .../tags/damage_type/bypasses_resistance.json | 8 + .../tags/damage_type/no_knockback.json | 8 + .../neoforge/tags/damage_type/is_magic.json | 8 + .../api/anvil/impl/TimeWarpBehavior.java | 225 +++++++++--------- .../dubhe/anvilcraft/data/lang/OtherLang.java | 3 +- .../data/provider/ModDamageTypeProvider.java | 36 +++ .../provider/ModDamageTypeTagProvider.java | 29 +++ .../dubhe/anvilcraft/init/ModDamageTypes.java | 11 + .../anvilcraft/mixin/DamageSourcesMixin.java | 8 + 14 files changed, 241 insertions(+), 114 deletions(-) rename src/{main => generated}/resources/data/anvilcraft/damage_type/laser.json (100%) create mode 100644 src/generated/resources/data/anvilcraft/damage_type/lost_in_time.json create mode 100644 src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json create mode 100644 src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json create mode 100644 src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json create mode 100644 src/generated/resources/data/neoforge/tags/damage_type/is_magic.json create mode 100644 src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeProvider.java create mode 100644 src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeTagProvider.java diff --git a/src/generated/resources/assets/anvilcraft/lang/en_ud.json b/src/generated/resources/assets/anvilcraft/lang/en_ud.json index 219d1d4e7..45ab04892 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_ud.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_ud.json @@ -263,7 +263,8 @@ "config.waila.plugin_anvilcraft": "ʇɟɐɹƆ ןıʌuⱯ", "config.waila.plugin_anvilcraft.power_provider": "ɹǝʍoԀ ʇɟɐɹƆ ןıʌuⱯ", "config.waila.plugin_anvilcraft.warning_percent": "pןoɥsǝɹɥ⟘ buıuɹɐM", - "death.attack.anvilcraft.laser": "˙ɹǝsɐן ʎq pǝɔɹǝıd sɐʍ %1$s", + "death.attack.anvilcraft.laser": "ɹǝsɐן ʎq pǝɔɹǝıd sɐʍ %1$s", + "death.attack.anvilcraft.lost_in_time": "ǝɯıʇ ɟo ɹǝʌıɹ ǝɥʇ uı ʇsoן sɐʍ %1$s", "enchantment.anvilcraft.beheading": "buıpɐǝɥǝᗺ", "enchantment.anvilcraft.felling": "buıןןǝℲ", "enchantment.anvilcraft.harvest": "ʇsǝʌɹɐH", diff --git a/src/generated/resources/assets/anvilcraft/lang/en_us.json b/src/generated/resources/assets/anvilcraft/lang/en_us.json index 05dc3d6b3..7be4c1ae0 100644 --- a/src/generated/resources/assets/anvilcraft/lang/en_us.json +++ b/src/generated/resources/assets/anvilcraft/lang/en_us.json @@ -263,7 +263,8 @@ "config.waila.plugin_anvilcraft": "Anvil Craft", "config.waila.plugin_anvilcraft.power_provider": "Anvil Craft Power", "config.waila.plugin_anvilcraft.warning_percent": "Warning Threshold", - "death.attack.anvilcraft.laser": "%1$s was pierced by laser.", + "death.attack.anvilcraft.laser": "%1$s was pierced by laser", + "death.attack.anvilcraft.lost_in_time": "%1$s was lost in the river of time", "enchantment.anvilcraft.beheading": "Beheading", "enchantment.anvilcraft.felling": "Felling", "enchantment.anvilcraft.harvest": "Harvest", diff --git a/src/main/resources/data/anvilcraft/damage_type/laser.json b/src/generated/resources/data/anvilcraft/damage_type/laser.json similarity index 100% rename from src/main/resources/data/anvilcraft/damage_type/laser.json rename to src/generated/resources/data/anvilcraft/damage_type/laser.json diff --git a/src/generated/resources/data/anvilcraft/damage_type/lost_in_time.json b/src/generated/resources/data/anvilcraft/damage_type/lost_in_time.json new file mode 100644 index 000000000..e38707aff --- /dev/null +++ b/src/generated/resources/data/anvilcraft/damage_type/lost_in_time.json @@ -0,0 +1,5 @@ +{ + "exhaustion": 0.1, + "message_id": "anvilcraft.lost_in_time", + "scaling": "when_caused_by_living_non_player" +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json new file mode 100644 index 000000000..0ccc6bb9c --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_armor.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "anvilcraft:lost_in_time", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json new file mode 100644 index 000000000..0ccc6bb9c --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/damage_type/bypasses_resistance.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "anvilcraft:lost_in_time", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json b/src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json new file mode 100644 index 000000000..0ccc6bb9c --- /dev/null +++ b/src/generated/resources/data/minecraft/tags/damage_type/no_knockback.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "anvilcraft:lost_in_time", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json b/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json new file mode 100644 index 000000000..0ccc6bb9c --- /dev/null +++ b/src/generated/resources/data/neoforge/tags/damage_type/is_magic.json @@ -0,0 +1,8 @@ +{ + "values": [ + { + "id": "anvilcraft:lost_in_time", + "required": false + } + ] +} \ No newline at end of file diff --git a/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java b/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java index 9858f7eea..d69484e4b 100644 --- a/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java +++ b/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java @@ -5,6 +5,7 @@ import dev.dubhe.anvilcraft.block.CorruptedBeaconBlock; import dev.dubhe.anvilcraft.init.ModBlocks; import dev.dubhe.anvilcraft.init.ModComponents; +import dev.dubhe.anvilcraft.init.ModDamageTypes; import dev.dubhe.anvilcraft.init.ModRecipeTypes; import dev.dubhe.anvilcraft.item.HasMobBlockItem; import dev.dubhe.anvilcraft.recipe.ChanceItemStack; @@ -17,6 +18,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.MobCategory; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.item.Item; @@ -44,124 +46,125 @@ public boolean handle( float fallDistance, AnvilFallOnLandEvent event) { BlockState belowState = level.getBlockState(hitBlockPos.below()); - if (belowState.is(ModBlocks.CORRUPTED_BEACON) && belowState.getValue(CorruptedBeaconBlock.LIT)) { - Map items = level.getEntitiesOfClass(ItemEntity.class, new AABB(hitBlockPos)) - .stream() - .map(it -> Map.entry(it, it.getItem())) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + if (!belowState.is(ModBlocks.CORRUPTED_BEACON) || !belowState.getValue(CorruptedBeaconBlock.LIT)) return false; - if (items.values().stream().anyMatch(it -> it.is(ModBlocks.RESIN_BLOCK.asItem()))) { - items.entrySet().stream() - .filter(it -> it.getValue().is(ModBlocks.RESIN_BLOCK.asItem())) - .map(it -> { - ItemStack itemStack = it.getValue(); - Entity entity = HasMobBlockItem.getMobFromItem(level, itemStack); - if (entity == null) { - return Map.entry(it.getKey(), new ItemStack(ModBlocks.AMBER_BLOCK)); - } - ItemStack result = new ItemStack( - entity.getType().getCategory() == MobCategory.MONSTER - && level.getRandom().nextFloat() <= 0.05 - ? ModBlocks.RESENTFUL_AMBER_BLOCK.asItem() - : ModBlocks.MOB_AMBER_BLOCK.asItem() - ); - HasMobBlockItem.SavedEntity savedEntity = itemStack.getComponents().get(ModComponents.SAVED_ENTITY); - result.set(ModComponents.SAVED_ENTITY, savedEntity); - return Map.entry(it.getKey(), result); - }) - .forEach(it -> { - ItemEntity old = it.getKey(); - ItemEntity itemEntity = new ItemEntity( - old.level(), - old.getX(), - old.getY(), - old.getZ(), - it.getValue() - ); - old.discard(); - old.level().addFreshEntity(itemEntity); - }); - return true; - } - TimeWarpRecipe.Input input = new TimeWarpRecipe.Input(items.values().stream().toList(), hitBlockState); - Optional> recipeOptional = level.getRecipeManager() - .getRecipeFor(ModRecipeTypes.TIME_WARP_TYPE.get(), input, level); - if (recipeOptional.isPresent()) { - RecipeHolder recipe = recipeOptional.get(); - int times = recipe.value().getMaxCraftTime(input); - Object2IntMap results = new Object2IntOpenHashMap<>(); - LootContext context; - if (level instanceof ServerLevel serverLevel) { - context = RecipeUtil.emptyLootContext(serverLevel); - } else { - return false; - } - for (int i = 0; i < times; i++) { - for (Ingredient ingredient : recipe.value().getIngredients()) { - for (ItemStack stack : items.values()) { - if (ingredient.test(stack)) { - stack.shrink(1); - break; - } - } + level.getEntitiesOfClass(LivingEntity.class, new AABB(hitBlockPos), LivingEntity::isAlive) + .forEach(it -> it.hurt(ModDamageTypes.lostInTime(level), Float.MAX_VALUE)); + + Map items = level.getEntitiesOfClass(ItemEntity.class, new AABB(hitBlockPos)) + .stream() + .map(it -> Map.entry(it, it.getItem())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + if (items.values().stream().anyMatch(it -> it.is(ModBlocks.RESIN_BLOCK.asItem()))) { + items.entrySet().stream() + .filter(it -> it.getValue().is(ModBlocks.RESIN_BLOCK.asItem())) + .map(it -> { + ItemStack itemStack = it.getValue(); + Entity entity = HasMobBlockItem.getMobFromItem(level, itemStack); + if (entity == null) { + return Map.entry(it.getKey(), new ItemStack(ModBlocks.AMBER_BLOCK)); } - for (ChanceItemStack stack : recipe.value().getResults()) { - int amount = stack.getStack().getCount() * stack.getAmount().getInt(context); - results.mergeInt(stack.getStack().getItem(), amount, Integer::sum); + ItemStack result = new ItemStack( + entity.getType().getCategory() == MobCategory.MONSTER + && level.getRandom().nextFloat() <= 0.05 + ? ModBlocks.RESENTFUL_AMBER_BLOCK.asItem() + : ModBlocks.MOB_AMBER_BLOCK.asItem() + ); + HasMobBlockItem.SavedEntity savedEntity = itemStack.getComponents().get(ModComponents.SAVED_ENTITY); + result.set(ModComponents.SAVED_ENTITY, savedEntity); + return Map.entry(it.getKey(), result); + }) + .forEach(it -> { + ItemEntity old = it.getKey(); + ItemEntity itemEntity = new ItemEntity( + old.level(), + old.getX(), + old.getY(), + old.getZ(), + it.getValue() + ); + old.discard(); + old.level().addFreshEntity(itemEntity); + }); + return true; + } + TimeWarpRecipe.Input input = new TimeWarpRecipe.Input(items.values().stream().toList(), hitBlockState); + Optional> recipeOptional = level.getRecipeManager() + .getRecipeFor(ModRecipeTypes.TIME_WARP_TYPE.get(), input, level); + if (recipeOptional.isEmpty()) return false; + RecipeHolder recipe = recipeOptional.get(); + int times = recipe.value().getMaxCraftTime(input); + Object2IntMap results = new Object2IntOpenHashMap<>(); + LootContext context; + if (level instanceof ServerLevel serverLevel) { + context = RecipeUtil.emptyLootContext(serverLevel); + } else { + return false; + } + for (int i = 0; i < times; i++) { + for (Ingredient ingredient : recipe.value().getIngredients()) { + for (ItemStack stack : items.values()) { + if (ingredient.test(stack)) { + stack.shrink(1); + break; } } - AnvilUtil.dropItems( - results.object2IntEntrySet().stream() - .map(entry -> new ItemStack(entry.getKey(), entry.getIntValue())) - .toList(), - level, - hitBlockPos.getCenter() - ); - if (recipe.value().isFromWater()) { - level.setBlockAndUpdate(hitBlockPos, recipe.value().getCauldron().defaultBlockState()); - } else { - if (recipe.value().isConsumeFluid()) { - if (hitBlockState.hasProperty(LayeredCauldronBlock.LEVEL)) { - int cauldronLevel = hitBlockState.getValue(LayeredCauldronBlock.LEVEL); - cauldronLevel -= Math.max(recipe.value().getRequiredFluidLevel(), 1); - if (cauldronLevel <= 0) { - level.setBlockAndUpdate(hitBlockPos, Blocks.CAULDRON.defaultBlockState()); - } else { - level.setBlockAndUpdate( - hitBlockPos, - hitBlockState.setValue(LayeredCauldronBlock.LEVEL, cauldronLevel) - ); - } - } else { - level.setBlockAndUpdate(hitBlockPos, Blocks.CAULDRON.defaultBlockState()); - } - } - if (recipe.value().isProduceFluid()) { - if (hitBlockState.hasProperty(LayeredCauldronBlock.LEVEL)) { - int cauldronLevel = hitBlockState.getValue(LayeredCauldronBlock.LEVEL); - cauldronLevel++; - level.setBlockAndUpdate( - hitBlockPos, - hitBlockState.setValue(LayeredCauldronBlock.LEVEL, cauldronLevel) - ); - } else { - level.setBlockAndUpdate( - hitBlockPos, - recipe.value().getCauldron().defaultBlockState() - ); - } + } + for (ChanceItemStack stack : recipe.value().getResults()) { + int amount = stack.getStack().getCount() * stack.getAmount().getInt(context); + results.mergeInt(stack.getStack().getItem(), amount, Integer::sum); + } + } + AnvilUtil.dropItems( + results.object2IntEntrySet().stream() + .map(entry -> new ItemStack(entry.getKey(), entry.getIntValue())) + .toList(), + level, + hitBlockPos.getCenter() + ); + if (recipe.value().isFromWater()) { + level.setBlockAndUpdate(hitBlockPos, recipe.value().getCauldron().defaultBlockState()); + } else { + if (recipe.value().isConsumeFluid()) { + if (hitBlockState.hasProperty(LayeredCauldronBlock.LEVEL)) { + int cauldronLevel = hitBlockState.getValue(LayeredCauldronBlock.LEVEL); + cauldronLevel -= Math.max(recipe.value().getRequiredFluidLevel(), 1); + if (cauldronLevel <= 0) { + level.setBlockAndUpdate(hitBlockPos, Blocks.CAULDRON.defaultBlockState()); + } else { + level.setBlockAndUpdate( + hitBlockPos, + hitBlockState.setValue(LayeredCauldronBlock.LEVEL, cauldronLevel) + ); } + } else { + level.setBlockAndUpdate(hitBlockPos, Blocks.CAULDRON.defaultBlockState()); + } + } + if (recipe.value().isProduceFluid()) { + if (hitBlockState.hasProperty(LayeredCauldronBlock.LEVEL)) { + int cauldronLevel = hitBlockState.getValue(LayeredCauldronBlock.LEVEL); + cauldronLevel++; + level.setBlockAndUpdate( + hitBlockPos, + hitBlockState.setValue(LayeredCauldronBlock.LEVEL, cauldronLevel) + ); + } else { + level.setBlockAndUpdate( + hitBlockPos, + recipe.value().getCauldron().defaultBlockState() + ); } - items.forEach((k, v) -> { - if (v.isEmpty()) { - k.discard(); - return; - } - k.setItem(v.copy()); - }); - return true; } } - return false; + items.forEach((k, v) -> { + if (v.isEmpty()) { + k.discard(); + return; + } + k.setItem(v.copy()); + }); + return true; } } diff --git a/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java b/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java index 7778862df..c7f099c85 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/lang/OtherLang.java @@ -35,6 +35,7 @@ public static void init(@NotNull RegistrateLangProvider provider) { provider.add("enchantment.anvilcraft.beheading", "Beheading"); provider.add("enchantment.anvilcraft.felling", "Felling"); provider.add("enchantment.anvilcraft.harvest", "Harvest"); - provider.add("death.attack.anvilcraft.laser", "%1$s was pierced by laser."); + provider.add("death.attack.anvilcraft.laser", "%1$s was pierced by laser"); + provider.add("death.attack.anvilcraft.lost_in_time", "%1$s was lost in the river of time"); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeProvider.java b/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeProvider.java new file mode 100644 index 000000000..28cb4aa08 --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeProvider.java @@ -0,0 +1,36 @@ +package dev.dubhe.anvilcraft.data.provider; + +import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.init.ModDamageTypes; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.RegistrySetBuilder; +import net.minecraft.core.registries.Registries; +import net.minecraft.data.PackOutput; +import net.minecraft.data.worldgen.BootstrapContext; +import net.minecraft.world.damagesource.DamageEffects; +import net.minecraft.world.damagesource.DamageType; +import net.neoforged.neoforge.common.data.DatapackBuiltinEntriesProvider; +import org.jetbrains.annotations.NotNull; + +import java.util.Set; +import java.util.concurrent.CompletableFuture; + +public class ModDamageTypeProvider extends DatapackBuiltinEntriesProvider { + private static final RegistrySetBuilder BUILDER = new RegistrySetBuilder() + .add(Registries.DAMAGE_TYPE, ModDamageTypeProvider::bootstrap); + + public static void bootstrap(BootstrapContext ctx) { + ctx.register(ModDamageTypes.LASER, new DamageType("anvilcraft.laser", 0.1f, DamageEffects.BURNING)); + ctx.register(ModDamageTypes.LOST_IN_TIME, new DamageType("anvilcraft.lost_in_time", 0.1f)); + } + + public ModDamageTypeProvider(PackOutput output, CompletableFuture registries) { + super(output, registries, BUILDER, Set.of(AnvilCraft.MOD_ID)); + } + + @Override + @NotNull + public String getName() { + return "AnvilCraft's Damage Type data"; + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeTagProvider.java b/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeTagProvider.java new file mode 100644 index 000000000..94a5e294d --- /dev/null +++ b/src/main/java/dev/dubhe/anvilcraft/data/provider/ModDamageTypeTagProvider.java @@ -0,0 +1,29 @@ +package dev.dubhe.anvilcraft.data.provider; + +import dev.dubhe.anvilcraft.AnvilCraft; +import dev.dubhe.anvilcraft.init.ModDamageTypes; +import net.minecraft.core.HolderLookup; +import net.minecraft.data.PackOutput; +import net.minecraft.data.tags.DamageTypeTagsProvider; +import net.minecraft.tags.DamageTypeTags; +import net.neoforged.neoforge.common.Tags; +import net.neoforged.neoforge.common.data.ExistingFileHelper; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.concurrent.CompletableFuture; + +public class ModDamageTypeTagProvider extends DamageTypeTagsProvider { + + public ModDamageTypeTagProvider(PackOutput output, CompletableFuture lookupProvider, @Nullable ExistingFileHelper existingFileHelper) { + super(output, lookupProvider, AnvilCraft.MOD_ID, existingFileHelper); + } + + @Override + protected void addTags(@NotNull HolderLookup.Provider pProvider) { + this.tag(DamageTypeTags.BYPASSES_ARMOR).addOptional(ModDamageTypes.LOST_IN_TIME.location()); + this.tag(DamageTypeTags.BYPASSES_RESISTANCE).addOptional(ModDamageTypes.LOST_IN_TIME.location()); + this.tag(DamageTypeTags.NO_KNOCKBACK).addOptional(ModDamageTypes.LOST_IN_TIME.location()); + this.tag(Tags.DamageTypes.IS_MAGIC).addOptional(ModDamageTypes.LOST_IN_TIME.location()); + } +} diff --git a/src/main/java/dev/dubhe/anvilcraft/init/ModDamageTypes.java b/src/main/java/dev/dubhe/anvilcraft/init/ModDamageTypes.java index a1e501f92..672c28aa2 100644 --- a/src/main/java/dev/dubhe/anvilcraft/init/ModDamageTypes.java +++ b/src/main/java/dev/dubhe/anvilcraft/init/ModDamageTypes.java @@ -4,6 +4,7 @@ import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.damagesource.DamageSources; import net.minecraft.world.damagesource.DamageType; import net.minecraft.world.level.Level; @@ -12,12 +13,22 @@ public class ModDamageTypes { Registries.DAMAGE_TYPE, AnvilCraft.of("laser") ); + public static final ResourceKey LOST_IN_TIME = ResourceKey.create( + Registries.DAMAGE_TYPE, + AnvilCraft.of("lost_in_time") + ); public static DamageSource laser(Level level) { return ((DamageSourceExtra) level.damageSources()).laser(); } + public static DamageSource lostInTime(Level level) { + return ((DamageSourceExtra) level.damageSources()).lostInTime(); + } + + public interface DamageSourceExtra { DamageSource laser(); + DamageSource lostInTime(); } } diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/DamageSourcesMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/DamageSourcesMixin.java index a08c96f21..2aa864f7a 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/DamageSourcesMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/DamageSourcesMixin.java @@ -19,6 +19,8 @@ public abstract class DamageSourcesMixin implements ModDamageTypes.DamageSourceE @Unique private DamageSource anvilCraft$laser; + @Unique + private DamageSource anvilCraft$lostInTime; @Inject( method = "", @@ -26,10 +28,16 @@ public abstract class DamageSourcesMixin implements ModDamageTypes.DamageSourceE ) void initModDamageSources(RegistryAccess registry, CallbackInfo ci){ anvilCraft$laser = this.source(ModDamageTypes.LASER); + anvilCraft$lostInTime = this.source(ModDamageTypes.LOST_IN_TIME); } @Override public DamageSource laser() { return anvilCraft$laser; } + + @Override + public DamageSource lostInTime(){ + return anvilCraft$lostInTime; + } } From b56302ea024734d36e123bc453a41e6e3dabb77c Mon Sep 17 00:00:00 2001 From: YocyCraft Date: Wed, 18 Dec 2024 12:22:34 +0800 Subject: [PATCH 6/8] Add particle for lost in time damage Resolve conflict with Curtain mod. Fixed #1338 --- .../api/anvil/impl/TimeWarpBehavior.java | 23 +++++++++++++++++-- .../anvilcraft/mixin/ItemEntityMixin.java | 21 ++++++++++------- .../forge/PistonMovingBlockEntityMixin.java | 18 --------------- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java b/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java index d69484e4b..c2cbbf1fa 100644 --- a/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java +++ b/src/main/java/dev/dubhe/anvilcraft/api/anvil/impl/TimeWarpBehavior.java @@ -16,6 +16,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntMap; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; @@ -31,12 +32,16 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.storage.loot.LootContext; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; public class TimeWarpBehavior implements IAnvilBehavior { + public static final int SOUL_PARTICLE_COUNT = 3; + @SuppressWarnings("DuplicatedCode") @Override public boolean handle( @@ -48,8 +53,22 @@ public boolean handle( BlockState belowState = level.getBlockState(hitBlockPos.below()); if (!belowState.is(ModBlocks.CORRUPTED_BEACON) || !belowState.getValue(CorruptedBeaconBlock.LIT)) return false; - level.getEntitiesOfClass(LivingEntity.class, new AABB(hitBlockPos), LivingEntity::isAlive) - .forEach(it -> it.hurt(ModDamageTypes.lostInTime(level), Float.MAX_VALUE)); + List damagedEntities = level.getEntitiesOfClass( + LivingEntity.class, + new AABB(hitBlockPos), + LivingEntity::isAlive); + if(!damagedEntities.isEmpty()){ + damagedEntities.forEach(it -> it.hurt(ModDamageTypes.lostInTime(level), Float.MAX_VALUE)); + if(level instanceof ServerLevel serverLevel && damagedEntities.stream().anyMatch(LivingEntity::isDeadOrDying)){ + Vec3 particleCenter = hitBlockPos.above().getCenter(); + serverLevel.sendParticles(ParticleTypes.SOUL, + particleCenter.x, + particleCenter.y, + particleCenter.z, + SOUL_PARTICLE_COUNT, + 0.4, 0.4, 0.4, 0.01); + } + } Map items = level.getEntitiesOfClass(ItemEntity.class, new AABB(hitBlockPos)) .stream() diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/ItemEntityMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/ItemEntityMixin.java index db55061fe..278935d7f 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/ItemEntityMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/ItemEntityMixin.java @@ -1,6 +1,5 @@ package dev.dubhe.anvilcraft.mixin; -import dev.dubhe.anvilcraft.AnvilCraft; import dev.dubhe.anvilcraft.block.HollowMagnetBlock; import dev.dubhe.anvilcraft.init.ModBlockTags; import dev.dubhe.anvilcraft.init.ModBlocks; @@ -8,7 +7,6 @@ import dev.dubhe.anvilcraft.init.ModItems; import dev.dubhe.anvilcraft.item.IFireReforging; import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; import net.minecraft.server.level.ServerPlayer; import net.minecraft.tags.DamageTypeTags; import net.minecraft.util.Mth; @@ -17,6 +15,7 @@ import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.phys.AABB; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @@ -25,7 +24,6 @@ import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; -import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; import net.neoforged.neoforge.event.EventHooks; import org.jetbrains.annotations.NotNull; @@ -63,10 +61,10 @@ abstract class ItemEntityMixin extends Entity { protected abstract void setUnderwaterMovement(); @Shadow - public abstract boolean isMergable(); + protected abstract boolean isMergable(); @Shadow - public abstract void mergeWithNeighbours(); + protected abstract void mergeWithNeighbours(); @Shadow private int pickupDelay; @@ -173,7 +171,7 @@ private void slidingRailProgress(CallbackInfoReturnable cir) { // 以下是中子锭运动相关mixin @Inject(method = "tick", at = @At("HEAD"), cancellable = true) - private void neutroniumTick(CallbackInfo ci){ + private void anvilcraft$neutroniumTick(CallbackInfo ci){ ItemStack item = this.getItem(); if (!item.is(ModItems.NEUTRONIUM_INGOT)) return; if (item.onEntityItemUpdate((ItemEntity) (Object) this)) { @@ -211,7 +209,7 @@ private void neutroniumTick(CallbackInfo ci){ this.applyGravity(); this.noPhysics = false; if (!this.onGround() || this.getDeltaMovement().horizontalDistanceSqr() > (double)1.0E-5F || (this.tickCount + this.getId()) % 4 == 0) { - this.neutroniumMove(MoverType.SELF, this.getDeltaMovement()); + this.anvilCraft$neutroniumMove(MoverType.SELF, this.getDeltaMovement()); float f = 0.98F; if (this.onGround()) { BlockPos groundPos = this.getBlockPosBelowThatAffectsMyMovement(); @@ -252,8 +250,15 @@ private void neutroniumTick(CallbackInfo ci){ ci.cancel(); } + @Override + @NotNull + public PushReaction getPistonPushReaction(){ + if(this.getItem().is(ModItems.NEUTRONIUM_INGOT)) return PushReaction.IGNORE; + return super.getPistonPushReaction(); + } + @Unique - private void neutroniumMove(MoverType moverType, Vec3 motion) { + private void anvilCraft$neutroniumMove(MoverType moverType, Vec3 motion) { this.level().getProfiler().push("move"); //代替原版move方法中的collide调用 diff --git a/src/main/java/dev/dubhe/anvilcraft/mixin/forge/PistonMovingBlockEntityMixin.java b/src/main/java/dev/dubhe/anvilcraft/mixin/forge/PistonMovingBlockEntityMixin.java index b1e59381f..5e38a260a 100644 --- a/src/main/java/dev/dubhe/anvilcraft/mixin/forge/PistonMovingBlockEntityMixin.java +++ b/src/main/java/dev/dubhe/anvilcraft/mixin/forge/PistonMovingBlockEntityMixin.java @@ -1,15 +1,11 @@ package dev.dubhe.anvilcraft.mixin.forge; import dev.dubhe.anvilcraft.block.ResinBlock; -import dev.dubhe.anvilcraft.init.ModItems; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.SlimeBlock; import net.minecraft.world.level.block.piston.PistonMovingBlockEntity; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.PushReaction; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; @@ -31,18 +27,4 @@ private static boolean isElastic(@NotNull BlockState instance) { return block instanceof SlimeBlock || block instanceof ResinBlock; } - @Redirect( - method = "moveCollidedEntities", - at = @At( - value = "INVOKE", - remap = false, - target = "Lnet/minecraft/world/entity/Entity;getPistonPushReaction()Lnet/minecraft/world/level/material/PushReaction;" - ) - ) - private static PushReaction cancelPistonPushForNeutronium(Entity entity) { - if (entity instanceof ItemEntity itemEntity && itemEntity.getItem().is(ModItems.NEUTRONIUM_INGOT.get())) { - return PushReaction.IGNORE; - } - return entity.getPistonPushReaction(); - } } From ce20e2fc496d242abb5d97236f8c1fabcf5573a0 Mon Sep 17 00:00:00 2001 From: YocyCraft Date: Wed, 18 Dec 2024 12:39:04 +0800 Subject: [PATCH 7/8] Resolved merge conflict --- .../java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java b/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java index 807a2bab5..6bc9e6f1a 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java @@ -3,6 +3,8 @@ import dev.dubhe.anvilcraft.AnvilCraft; import dev.dubhe.anvilcraft.data.advancement.AdvancementHandler; import dev.dubhe.anvilcraft.data.lang.LangHandler; +import dev.dubhe.anvilcraft.data.provider.ModDamageTypeProvider; +import dev.dubhe.anvilcraft.data.provider.ModDamageTypeTagProvider; import dev.dubhe.anvilcraft.data.provider.ModFurnaceFuelProvider; import dev.dubhe.anvilcraft.data.provider.ModLootTableProvider; import dev.dubhe.anvilcraft.data.provider.ModPoiTagProvider; @@ -46,6 +48,9 @@ public static void gatherData(GatherDataEvent event) { generator.addProvider( event.includeServer(), new ModPoiTagProvider(packOutput, lookupProvider, existingFileHelper)); generator.addProvider(event.includeServer(), new ModFurnaceFuelProvider(packOutput, lookupProvider)); + generator.addProvider(event.includeServer(), new ModDamageTypeProvider(packOutput, lookupProvider)); + generator.addProvider( + event.includeServer(), new ModDamageTypeTagProvider(packOutput, lookupProvider, existingFileHelper)); } /** From 94ddc84ce6c9657de4fb517edc71a085638002f2 Mon Sep 17 00:00:00 2001 From: YocyCraft Date: Wed, 18 Dec 2024 12:40:13 +0800 Subject: [PATCH 8/8] Resolved merge conflict again --- src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java b/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java index b17384aed..18c6ae3c3 100644 --- a/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java +++ b/src/main/java/dev/dubhe/anvilcraft/data/AnvilCraftDatagen.java @@ -5,6 +5,7 @@ import dev.dubhe.anvilcraft.data.lang.LangHandler; import dev.dubhe.anvilcraft.data.provider.ModDamageTypeProvider; import dev.dubhe.anvilcraft.data.provider.ModDamageTypeTagProvider; +import dev.dubhe.anvilcraft.data.provider.ModFurnaceFuelProvider; import dev.dubhe.anvilcraft.data.provider.ModLootTableProvider; import dev.dubhe.anvilcraft.data.provider.ModPoiTagProvider; import dev.dubhe.anvilcraft.data.provider.ModRegistryProvider; @@ -46,6 +47,7 @@ public static void gatherData(GatherDataEvent event) { generator.addProvider(event.includeServer(), new ModLootTableProvider(packOutput, lookupProvider)); generator.addProvider( event.includeServer(), new ModPoiTagProvider(packOutput, lookupProvider, existingFileHelper)); + generator.addProvider(event.includeServer(), new ModFurnaceFuelProvider(packOutput, lookupProvider)); generator.addProvider(event.includeServer(), new ModDamageTypeProvider(packOutput, lookupProvider)); generator.addProvider( event.includeServer(), new ModDamageTypeTagProvider(packOutput, lookupProvider, existingFileHelper));