Skip to content

Commit

Permalink
Merge pull request #857 from ZhuRuoLing/dev
Browse files Browse the repository at this point in the history
添加更多生物转化
  • Loading branch information
Gu-ZT authored Jun 8, 2024
2 parents ab6b77b + b857369 commit 251913a
Show file tree
Hide file tree
Showing 14 changed files with 392 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,28 @@
import dev.dubhe.anvilcraft.data.recipe.transform.MobTransformContainer;
import dev.dubhe.anvilcraft.init.ModBlockEntities;
import dev.dubhe.anvilcraft.init.ModRecipeTypes;

import java.util.Objects;

import lombok.Getter;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
import net.minecraft.server.commands.data.EntityDataAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BeaconBeamBlock;
Expand Down Expand Up @@ -185,28 +193,52 @@ public void setRemoved() {
super.setRemoved();
}

private static void tryTransformEntity(
Entity livingEntity,
BlockPos pos,
ServerLevel level,
RecipeManager manager
) {
MobTransformContainer container = new MobTransformContainer(level, pos, livingEntity);
var recipe = manager.getRecipeFor(ModRecipeTypes.MOB_TRANSFORM_RECIPE, container, level);
if (recipe.isEmpty()) return;
var entityType = recipe.get().result(level.random);
CompoundTag tag = new CompoundTag();
tag.putString("id", BuiltInRegistries.ENTITY_TYPE.getKey(entityType).toString());
Entity entity = EntityType.loadEntityRecursive(tag, level, (e) -> {
e.moveTo(
livingEntity.position().x,
livingEntity.position().y,
livingEntity.position().z,
e.getYRot(),
e.getXRot()
);
return e;
});
if (entity == null) return;
if (entity instanceof Mob mob) {
mob.finalizeSpawn(
level,
level.getCurrentDifficultyAt(entity.blockPosition()),
MobSpawnType.NATURAL,
null,
null
);
}
recipe.get().postProcess(livingEntity, entity);
livingEntity.remove(Entity.RemovalReason.DISCARDED);
level.tryAddFreshEntityWithPassengers(entity);
}

private static void affectEntities(@NotNull Level level, BlockPos pos) {
if (level.isClientSide) return;
AABB aabb = new AABB(pos).expandTowards(0.0, level.getHeight(), 0.0);
List<LivingEntity> list = level.getEntitiesOfClass(LivingEntity.class, aabb);
if (list.isEmpty()) return;
RecipeManager manager = Objects.requireNonNull(level.getServer()).getRecipeManager();
for (LivingEntity livingEntity : list) {
MobTransformContainer container = new MobTransformContainer(level, pos, livingEntity);
livingEntity.addEffect(new MobEffectInstance(MobEffects.WITHER, 120, 0, true, true));
var recipe = manager.getRecipeFor(ModRecipeTypes.MOB_TRANSFORM_RECIPE, container, level);
if (recipe.isEmpty()) continue;
var entityType = recipe.get().result(level.random);
Entity entity = entityType.create(level);
if (entity == null) continue;
entity.moveTo(livingEntity.position());
CompoundTag compoundTag = entity.saveWithoutId(new CompoundTag());
recipe.get().accept(compoundTag);
UUID uuid = entity.getUUID();
entity.load(compoundTag);
entity.setUUID(uuid);
livingEntity.remove(Entity.RemovalReason.DISCARDED);
level.addFreshEntity(entity);
tryTransformEntity(livingEntity, pos, (ServerLevel) level, manager);
}
}

Expand Down Expand Up @@ -270,6 +302,6 @@ public float[] getColor() {
@SuppressWarnings("unused")
public AABB getRenderBoundingBox() {
return new AABB(Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY,
Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import dev.dubhe.anvilcraft.data.recipe.transform.MobTransformRecipe;
import dev.dubhe.anvilcraft.data.recipe.transform.NumericTagValuePredicate;
import dev.dubhe.anvilcraft.data.recipe.transform.TagModification;
import dev.dubhe.anvilcraft.data.recipe.transform.TransformOptions;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.EntityType;

Expand Down Expand Up @@ -58,6 +59,21 @@ public static void init(RegistrateRecipeProvider provider) {
.result(EntityType.ZOMBIE_HORSE, 0.1)
.accept(provider);

MobTransformRecipe.builder("skeleton")
.input(EntityType.SKELETON)
.result(EntityType.STRAY, 0.8)
.result(EntityType.WITHER_SKELETON, 0.2)
.accept(provider);

MobTransformRecipe.builder("zombie")
.input(EntityType.ZOMBIE)
.result(EntityType.DROWNED, 0.45)
.result(EntityType.HUSK, 0.45)
.result(EntityType.GIANT, 0.1)
.option(TransformOptions.KEEP_INVENTORY)
.option(TransformOptions.REPLACE_ANVIL)
.accept(provider);

MobTransformRecipe.builder("silverfish")
.input(EntityType.SILVERFISH)
.result(EntityType.ENDERMITE, 1)
Expand All @@ -82,5 +98,8 @@ public static void init(RegistrateRecipeProvider provider) {
.value(tag);
})
.accept(provider);



}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.data.recipes.FinishedRecipe;
import net.minecraft.data.recipes.RecipeCategory;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.commands.data.EntityDataAccessor;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Recipe;
Expand All @@ -29,8 +31,11 @@
import javax.swing.text.html.Option;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;

import static net.minecraft.data.recipes.RecipeBuilder.ROOT_RECIPE_ADVANCEMENT;
Expand All @@ -47,7 +52,10 @@ public class MobTransformRecipe implements Recipe<MobTransformContainer> {
.forGetter(o -> java.util.Optional.ofNullable(o.tagPredicates)),
TagModification.CODEC.listOf()
.optionalFieldOf("tagModifications")
.forGetter(o -> java.util.Optional.ofNullable(o.tagModifications))
.forGetter(o -> java.util.Optional.ofNullable(o.tagModifications)),
TransformOptions.CODEC.listOf()
.optionalFieldOf("transformOptions")
.forGetter(o -> Optional.ofNullable(o.transformOptions))
).apply(ins, MobTransformRecipe::new));

private final ResourceLocation id;
Expand All @@ -59,6 +67,8 @@ public class MobTransformRecipe implements Recipe<MobTransformContainer> {
private List<NumericTagValuePredicate> tagPredicates;
@Getter
private List<TagModification> tagModifications;
@Getter
private List<TransformOptions> transformOptions;

/**
* 生物转化配方
Expand All @@ -68,13 +78,15 @@ public MobTransformRecipe(
ResourceLocation input,
List<TransformResult> results,
Optional<List<NumericTagValuePredicate>> tagPredicates,
Optional<List<TagModification>> tagModifications
Optional<List<TagModification>> tagModifications,
Optional<List<TransformOptions>> options
) {
this.id = id;
this.results = results;
this.input = BuiltInRegistries.ENTITY_TYPE.get(input);
this.tagPredicates = tagPredicates.orElseGet(ArrayList::new);
this.tagModifications = tagModifications.orElseGet(ArrayList::new);
transformOptions = options.orElseGet(ArrayList::new);
}

public MobTransformRecipe(ResourceLocation id) {
Expand All @@ -92,12 +104,19 @@ public boolean matches(@NotNull MobTransformContainer container, @NotNull Level
}

/**
* 修改生物nbt
* 对生物进行后处理
*/
public void accept(Tag tag) {
public void postProcess(Entity oldEntity, Entity entity) {
for (TransformOptions option : transformOptions) {
option.accept(oldEntity, entity);
}
CompoundTag compoundTag = entity.saveWithoutId(new CompoundTag());
for (TagModification tagModification : tagModifications) {
tagModification.accept(tag);
tagModification.accept(compoundTag);
}
UUID uuid = entity.getUUID();
entity.load(compoundTag);
entity.setUUID(uuid);
}

@Override
Expand Down Expand Up @@ -209,6 +228,7 @@ public static class Builder {
private RecipeCategory category = RecipeCategory.MISC;
private List<NumericTagValuePredicate> tagPredicates;
private List<TagModification> tagModifications;
private Set<TransformOptions> options;

Builder(ResourceLocation id) {
this.id = id;
Expand Down Expand Up @@ -260,6 +280,17 @@ public Builder tagModification(@NotNull Consumer<TagModification.Builder> predic
return this;
}

/**
* 生物转化额外选项
*/
public Builder option(TransformOptions option) {
if (options == null) {
options = new HashSet<>();
}
options.add(option);
return this;
}

/**
* 构造
*/
Expand All @@ -269,6 +300,9 @@ public MobTransformRecipe build() {
r.results = results;
r.tagPredicates = tagPredicates;
r.tagModifications = tagModifications;
if (options != null) {
r.transformOptions = new ArrayList<>(options);
}
return r;
}

Expand All @@ -291,5 +325,7 @@ public FinishedMobTransformRecipe finish() {
public void accept(Consumer<FinishedRecipe> provider) {
provider.accept(finish());
}


}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package dev.dubhe.anvilcraft.data.recipe.transform;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.mojang.serialization.Codec;
import com.mojang.serialization.JsonOps;
import dev.dubhe.anvilcraft.init.ModBlocks;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import org.jetbrains.annotations.NotNull;

public enum TransformOptions implements StringRepresentable {

KEEP_INVENTORY("keepInventory") {
@Override
public void accept(Entity oldEntity, Entity newEntity) {
if (newEntity instanceof LivingEntity n && oldEntity instanceof LivingEntity o) {
for (EquipmentSlot value : EquipmentSlot.values()) {
n.setItemSlot(value, o.getItemBySlot(value));
}
for (InteractionHand value : InteractionHand.values()) {
n.setItemInHand(value, o.getItemInHand(value));
}
}
}
},
REPLACE_ANVIL("replaceAnvil") {
@Override
public void accept(Entity oldEntity, Entity newEntity) {
if (newEntity instanceof LivingEntity n && oldEntity instanceof LivingEntity o) {
for (InteractionHand value : InteractionHand.values()) {
ItemStack itemStack = o.getItemInHand(value);
if (itemStack.is(Items.ANVIL)
|| itemStack.is(Items.CHIPPED_ANVIL)
|| itemStack.is(Items.DAMAGED_ANVIL)) {
o.setItemInHand(value, ModBlocks.HEAVY_IRON_BLOCK.asItem().getDefaultInstance());
n.setItemInHand(value, ModBlocks.HEAVY_IRON_BLOCK.asItem().getDefaultInstance());
}
}
}
}
};

public static final Codec<TransformOptions> CODEC = StringRepresentable.fromEnum(TransformOptions::values);
private final String name;

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

@Override
public @NotNull String getSerializedName() {
return name;
}

public abstract void accept(Entity oldEntity, Entity newEntity);

/**
*
*/
public static TransformOptions fromJson(JsonObject jsonObject) {
return CODEC.decode(JsonOps.INSTANCE, jsonObject)
.getOrThrow(false, s -> {
}).getFirst();
}

/**
*
*/
public JsonElement toJson() {
return CODEC.encodeStart(JsonOps.INSTANCE, this)
.getOrThrow(false, s -> {
});
}
}
Loading

0 comments on commit 251913a

Please sign in to comment.