package net.minecraft.server.commands; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import net.minecraft.commands.CommandBuildContext; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; import net.minecraft.commands.arguments.CompoundTagArgument; import net.minecraft.commands.arguments.ResourceArgument; import net.minecraft.commands.arguments.coordinates.Vec3Argument; import net.minecraft.commands.synchronization.SuggestionProviders; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder.Reference; import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.Mob; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; public class SummonCommand { private static final SimpleCommandExceptionType ERROR_FAILED = new SimpleCommandExceptionType(Component.translatable("commands.summon.failed")); private static final SimpleCommandExceptionType ERROR_DUPLICATE_UUID = new SimpleCommandExceptionType(Component.translatable("commands.summon.failed.uuid")); private static final SimpleCommandExceptionType INVALID_POSITION = new SimpleCommandExceptionType(Component.translatable("commands.summon.invalidPosition")); public static void register(CommandDispatcher dispatcher, CommandBuildContext context) { dispatcher.register( Commands.literal("summon") .requires(commandSourceStack -> commandSourceStack.hasPermission(2)) .then( Commands.argument("entity", ResourceArgument.resource(context, Registries.ENTITY_TYPE)) .suggests(SuggestionProviders.SUMMONABLE_ENTITIES) .executes( commandContext -> spawnEntity( commandContext.getSource(), ResourceArgument.getSummonableEntityType(commandContext, "entity"), commandContext.getSource().getPosition(), new CompoundTag(), true ) ) .then( Commands.argument("pos", Vec3Argument.vec3()) .executes( commandContext -> spawnEntity( commandContext.getSource(), ResourceArgument.getSummonableEntityType(commandContext, "entity"), Vec3Argument.getVec3(commandContext, "pos"), new CompoundTag(), true ) ) .then( Commands.argument("nbt", CompoundTagArgument.compoundTag()) .executes( commandContext -> spawnEntity( commandContext.getSource(), ResourceArgument.getSummonableEntityType(commandContext, "entity"), Vec3Argument.getVec3(commandContext, "pos"), CompoundTagArgument.getCompoundTag(commandContext, "nbt"), false ) ) ) ) ) ); } public static Entity createEntity(CommandSourceStack source, Reference> type, Vec3 pos, CompoundTag tag, boolean randomizeProperties) throws CommandSyntaxException { BlockPos blockPos = BlockPos.containing(pos); if (!Level.isInSpawnableBounds(blockPos)) { throw INVALID_POSITION.create(); } else { CompoundTag compoundTag = tag.copy(); compoundTag.putString("id", type.key().location().toString()); ServerLevel serverLevel = source.getLevel(); Entity entity = EntityType.loadEntityRecursive(compoundTag, serverLevel, EntitySpawnReason.COMMAND, entityx -> { entityx.snapTo(pos.x, pos.y, pos.z, entityx.getYRot(), entityx.getXRot()); return entityx; }); if (entity == null) { throw ERROR_FAILED.create(); } else { if (randomizeProperties && entity instanceof Mob) { ((Mob)entity).finalizeSpawn(source.getLevel(), source.getLevel().getCurrentDifficultyAt(entity.blockPosition()), EntitySpawnReason.COMMAND, null); } if (!serverLevel.tryAddFreshEntityWithPassengers(entity)) { throw ERROR_DUPLICATE_UUID.create(); } else { return entity; } } } } private static int spawnEntity(CommandSourceStack source, Reference> type, Vec3 pos, CompoundTag tag, boolean randomizeProperties) throws CommandSyntaxException { Entity entity = createEntity(source, type, pos, tag, randomizeProperties); source.sendSuccess(() -> Component.translatable("commands.summon.success", entity.getDisplayName()), true); return 1; } }