343 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			343 lines
		
	
	
	
		
			15 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.server.commands;
 | |
| 
 | |
| import com.mojang.brigadier.CommandDispatcher;
 | |
| import com.mojang.brigadier.arguments.DoubleArgumentType;
 | |
| import com.mojang.brigadier.exceptions.CommandSyntaxException;
 | |
| import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
 | |
| import com.mojang.brigadier.exceptions.Dynamic3CommandExceptionType;
 | |
| import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
 | |
| import java.util.stream.Stream;
 | |
| import net.minecraft.commands.CommandBuildContext;
 | |
| import net.minecraft.commands.CommandSourceStack;
 | |
| import net.minecraft.commands.Commands;
 | |
| import net.minecraft.commands.SharedSuggestionProvider;
 | |
| import net.minecraft.commands.arguments.EntityArgument;
 | |
| import net.minecraft.commands.arguments.ResourceArgument;
 | |
| import net.minecraft.commands.arguments.ResourceLocationArgument;
 | |
| import net.minecraft.core.Holder;
 | |
| import net.minecraft.core.registries.Registries;
 | |
| import net.minecraft.network.chat.Component;
 | |
| import net.minecraft.resources.ResourceLocation;
 | |
| import net.minecraft.world.entity.Entity;
 | |
| import net.minecraft.world.entity.LivingEntity;
 | |
| import net.minecraft.world.entity.ai.attributes.Attribute;
 | |
| import net.minecraft.world.entity.ai.attributes.AttributeInstance;
 | |
| import net.minecraft.world.entity.ai.attributes.AttributeMap;
 | |
| import net.minecraft.world.entity.ai.attributes.AttributeModifier;
 | |
| 
 | |
| public class AttributeCommand {
 | |
| 	private static final DynamicCommandExceptionType ERROR_NOT_LIVING_ENTITY = new DynamicCommandExceptionType(
 | |
| 		object -> Component.translatableEscape("commands.attribute.failed.entity", object)
 | |
| 	);
 | |
| 	private static final Dynamic2CommandExceptionType ERROR_NO_SUCH_ATTRIBUTE = new Dynamic2CommandExceptionType(
 | |
| 		(object, object2) -> Component.translatableEscape("commands.attribute.failed.no_attribute", object, object2)
 | |
| 	);
 | |
| 	private static final Dynamic3CommandExceptionType ERROR_NO_SUCH_MODIFIER = new Dynamic3CommandExceptionType(
 | |
| 		(object, object2, object3) -> Component.translatableEscape("commands.attribute.failed.no_modifier", object2, object, object3)
 | |
| 	);
 | |
| 	private static final Dynamic3CommandExceptionType ERROR_MODIFIER_ALREADY_PRESENT = new Dynamic3CommandExceptionType(
 | |
| 		(object, object2, object3) -> Component.translatableEscape("commands.attribute.failed.modifier_already_present", object3, object2, object)
 | |
| 	);
 | |
| 
 | |
| 	public static void register(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext context) {
 | |
| 		dispatcher.register(
 | |
| 			Commands.literal("attribute")
 | |
| 				.requires(Commands.hasPermission(2))
 | |
| 				.then(
 | |
| 					Commands.argument("target", EntityArgument.entity())
 | |
| 						.then(
 | |
| 							Commands.argument("attribute", ResourceArgument.resource(context, Registries.ATTRIBUTE))
 | |
| 								.then(
 | |
| 									Commands.literal("get")
 | |
| 										.executes(
 | |
| 											commandContext -> getAttributeValue(
 | |
| 												commandContext.getSource(), EntityArgument.getEntity(commandContext, "target"), ResourceArgument.getAttribute(commandContext, "attribute"), 1.0
 | |
| 											)
 | |
| 										)
 | |
| 										.then(
 | |
| 											Commands.argument("scale", DoubleArgumentType.doubleArg())
 | |
| 												.executes(
 | |
| 													commandContext -> getAttributeValue(
 | |
| 														commandContext.getSource(),
 | |
| 														EntityArgument.getEntity(commandContext, "target"),
 | |
| 														ResourceArgument.getAttribute(commandContext, "attribute"),
 | |
| 														DoubleArgumentType.getDouble(commandContext, "scale")
 | |
| 													)
 | |
| 												)
 | |
| 										)
 | |
| 								)
 | |
| 								.then(
 | |
| 									Commands.literal("base")
 | |
| 										.then(
 | |
| 											Commands.literal("set")
 | |
| 												.then(
 | |
| 													Commands.argument("value", DoubleArgumentType.doubleArg())
 | |
| 														.executes(
 | |
| 															commandContext -> setAttributeBase(
 | |
| 																commandContext.getSource(),
 | |
| 																EntityArgument.getEntity(commandContext, "target"),
 | |
| 																ResourceArgument.getAttribute(commandContext, "attribute"),
 | |
| 																DoubleArgumentType.getDouble(commandContext, "value")
 | |
| 															)
 | |
| 														)
 | |
| 												)
 | |
| 										)
 | |
| 										.then(
 | |
| 											Commands.literal("get")
 | |
| 												.executes(
 | |
| 													commandContext -> getAttributeBase(
 | |
| 														commandContext.getSource(), EntityArgument.getEntity(commandContext, "target"), ResourceArgument.getAttribute(commandContext, "attribute"), 1.0
 | |
| 													)
 | |
| 												)
 | |
| 												.then(
 | |
| 													Commands.argument("scale", DoubleArgumentType.doubleArg())
 | |
| 														.executes(
 | |
| 															commandContext -> getAttributeBase(
 | |
| 																commandContext.getSource(),
 | |
| 																EntityArgument.getEntity(commandContext, "target"),
 | |
| 																ResourceArgument.getAttribute(commandContext, "attribute"),
 | |
| 																DoubleArgumentType.getDouble(commandContext, "scale")
 | |
| 															)
 | |
| 														)
 | |
| 												)
 | |
| 										)
 | |
| 										.then(
 | |
| 											Commands.literal("reset")
 | |
| 												.executes(
 | |
| 													commandContext -> resetAttributeBase(
 | |
| 														commandContext.getSource(), EntityArgument.getEntity(commandContext, "target"), ResourceArgument.getAttribute(commandContext, "attribute")
 | |
| 													)
 | |
| 												)
 | |
| 										)
 | |
| 								)
 | |
| 								.then(
 | |
| 									Commands.literal("modifier")
 | |
| 										.then(
 | |
| 											Commands.literal("add")
 | |
| 												.then(
 | |
| 													Commands.argument("id", ResourceLocationArgument.id())
 | |
| 														.then(
 | |
| 															Commands.argument("value", DoubleArgumentType.doubleArg())
 | |
| 																.then(
 | |
| 																	Commands.literal("add_value")
 | |
| 																		.executes(
 | |
| 																			commandContext -> addModifier(
 | |
| 																				commandContext.getSource(),
 | |
| 																				EntityArgument.getEntity(commandContext, "target"),
 | |
| 																				ResourceArgument.getAttribute(commandContext, "attribute"),
 | |
| 																				ResourceLocationArgument.getId(commandContext, "id"),
 | |
| 																				DoubleArgumentType.getDouble(commandContext, "value"),
 | |
| 																				AttributeModifier.Operation.ADD_VALUE
 | |
| 																			)
 | |
| 																		)
 | |
| 																)
 | |
| 																.then(
 | |
| 																	Commands.literal("add_multiplied_base")
 | |
| 																		.executes(
 | |
| 																			commandContext -> addModifier(
 | |
| 																				commandContext.getSource(),
 | |
| 																				EntityArgument.getEntity(commandContext, "target"),
 | |
| 																				ResourceArgument.getAttribute(commandContext, "attribute"),
 | |
| 																				ResourceLocationArgument.getId(commandContext, "id"),
 | |
| 																				DoubleArgumentType.getDouble(commandContext, "value"),
 | |
| 																				AttributeModifier.Operation.ADD_MULTIPLIED_BASE
 | |
| 																			)
 | |
| 																		)
 | |
| 																)
 | |
| 																.then(
 | |
| 																	Commands.literal("add_multiplied_total")
 | |
| 																		.executes(
 | |
| 																			commandContext -> addModifier(
 | |
| 																				commandContext.getSource(),
 | |
| 																				EntityArgument.getEntity(commandContext, "target"),
 | |
| 																				ResourceArgument.getAttribute(commandContext, "attribute"),
 | |
| 																				ResourceLocationArgument.getId(commandContext, "id"),
 | |
| 																				DoubleArgumentType.getDouble(commandContext, "value"),
 | |
| 																				AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL
 | |
| 																			)
 | |
| 																		)
 | |
| 																)
 | |
| 														)
 | |
| 												)
 | |
| 										)
 | |
| 										.then(
 | |
| 											Commands.literal("remove")
 | |
| 												.then(
 | |
| 													Commands.argument("id", ResourceLocationArgument.id())
 | |
| 														.suggests(
 | |
| 															(commandContext, suggestionsBuilder) -> SharedSuggestionProvider.suggestResource(
 | |
| 																getAttributeModifiers(EntityArgument.getEntity(commandContext, "target"), ResourceArgument.getAttribute(commandContext, "attribute")),
 | |
| 																suggestionsBuilder
 | |
| 															)
 | |
| 														)
 | |
| 														.executes(
 | |
| 															commandContext -> removeModifier(
 | |
| 																commandContext.getSource(),
 | |
| 																EntityArgument.getEntity(commandContext, "target"),
 | |
| 																ResourceArgument.getAttribute(commandContext, "attribute"),
 | |
| 																ResourceLocationArgument.getId(commandContext, "id")
 | |
| 															)
 | |
| 														)
 | |
| 												)
 | |
| 										)
 | |
| 										.then(
 | |
| 											Commands.literal("value")
 | |
| 												.then(
 | |
| 													Commands.literal("get")
 | |
| 														.then(
 | |
| 															Commands.argument("id", ResourceLocationArgument.id())
 | |
| 																.suggests(
 | |
| 																	(commandContext, suggestionsBuilder) -> SharedSuggestionProvider.suggestResource(
 | |
| 																		getAttributeModifiers(EntityArgument.getEntity(commandContext, "target"), ResourceArgument.getAttribute(commandContext, "attribute")),
 | |
| 																		suggestionsBuilder
 | |
| 																	)
 | |
| 																)
 | |
| 																.executes(
 | |
| 																	commandContext -> getAttributeModifier(
 | |
| 																		commandContext.getSource(),
 | |
| 																		EntityArgument.getEntity(commandContext, "target"),
 | |
| 																		ResourceArgument.getAttribute(commandContext, "attribute"),
 | |
| 																		ResourceLocationArgument.getId(commandContext, "id"),
 | |
| 																		1.0
 | |
| 																	)
 | |
| 																)
 | |
| 																.then(
 | |
| 																	Commands.argument("scale", DoubleArgumentType.doubleArg())
 | |
| 																		.executes(
 | |
| 																			commandContext -> getAttributeModifier(
 | |
| 																				commandContext.getSource(),
 | |
| 																				EntityArgument.getEntity(commandContext, "target"),
 | |
| 																				ResourceArgument.getAttribute(commandContext, "attribute"),
 | |
| 																				ResourceLocationArgument.getId(commandContext, "id"),
 | |
| 																				DoubleArgumentType.getDouble(commandContext, "scale")
 | |
| 																			)
 | |
| 																		)
 | |
| 																)
 | |
| 														)
 | |
| 												)
 | |
| 										)
 | |
| 								)
 | |
| 						)
 | |
| 				)
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	private static AttributeInstance getAttributeInstance(Entity entity, Holder<Attribute> attribute) throws CommandSyntaxException {
 | |
| 		AttributeInstance attributeInstance = getLivingEntity(entity).getAttributes().getInstance(attribute);
 | |
| 		if (attributeInstance == null) {
 | |
| 			throw ERROR_NO_SUCH_ATTRIBUTE.create(entity.getName(), getAttributeDescription(attribute));
 | |
| 		} else {
 | |
| 			return attributeInstance;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static LivingEntity getLivingEntity(Entity target) throws CommandSyntaxException {
 | |
| 		if (!(target instanceof LivingEntity)) {
 | |
| 			throw ERROR_NOT_LIVING_ENTITY.create(target.getName());
 | |
| 		} else {
 | |
| 			return (LivingEntity)target;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static LivingEntity getEntityWithAttribute(Entity entity, Holder<Attribute> attribute) throws CommandSyntaxException {
 | |
| 		LivingEntity livingEntity = getLivingEntity(entity);
 | |
| 		if (!livingEntity.getAttributes().hasAttribute(attribute)) {
 | |
| 			throw ERROR_NO_SUCH_ATTRIBUTE.create(entity.getName(), getAttributeDescription(attribute));
 | |
| 		} else {
 | |
| 			return livingEntity;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static int getAttributeValue(CommandSourceStack source, Entity entity, Holder<Attribute> attribute, double scale) throws CommandSyntaxException {
 | |
| 		LivingEntity livingEntity = getEntityWithAttribute(entity, attribute);
 | |
| 		double d = livingEntity.getAttributeValue(attribute);
 | |
| 		source.sendSuccess(() -> Component.translatable("commands.attribute.value.get.success", getAttributeDescription(attribute), entity.getName(), d), false);
 | |
| 		return (int)(d * scale);
 | |
| 	}
 | |
| 
 | |
| 	private static int getAttributeBase(CommandSourceStack source, Entity entity, Holder<Attribute> attribute, double scale) throws CommandSyntaxException {
 | |
| 		LivingEntity livingEntity = getEntityWithAttribute(entity, attribute);
 | |
| 		double d = livingEntity.getAttributeBaseValue(attribute);
 | |
| 		source.sendSuccess(() -> Component.translatable("commands.attribute.base_value.get.success", getAttributeDescription(attribute), entity.getName(), d), false);
 | |
| 		return (int)(d * scale);
 | |
| 	}
 | |
| 
 | |
| 	private static int getAttributeModifier(CommandSourceStack source, Entity entity, Holder<Attribute> attribute, ResourceLocation id, double scale) throws CommandSyntaxException {
 | |
| 		LivingEntity livingEntity = getEntityWithAttribute(entity, attribute);
 | |
| 		AttributeMap attributeMap = livingEntity.getAttributes();
 | |
| 		if (!attributeMap.hasModifier(attribute, id)) {
 | |
| 			throw ERROR_NO_SUCH_MODIFIER.create(entity.getName(), getAttributeDescription(attribute), id);
 | |
| 		} else {
 | |
| 			double d = attributeMap.getModifierValue(attribute, id);
 | |
| 			source.sendSuccess(
 | |
| 				() -> Component.translatable(
 | |
| 					"commands.attribute.modifier.value.get.success", Component.translationArg(id), getAttributeDescription(attribute), entity.getName(), d
 | |
| 				),
 | |
| 				false
 | |
| 			);
 | |
| 			return (int)(d * scale);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static Stream<ResourceLocation> getAttributeModifiers(Entity entity, Holder<Attribute> attribute) throws CommandSyntaxException {
 | |
| 		AttributeInstance attributeInstance = getAttributeInstance(entity, attribute);
 | |
| 		return attributeInstance.getModifiers().stream().map(AttributeModifier::id);
 | |
| 	}
 | |
| 
 | |
| 	private static int setAttributeBase(CommandSourceStack source, Entity entity, Holder<Attribute> attribute, double value) throws CommandSyntaxException {
 | |
| 		getAttributeInstance(entity, attribute).setBaseValue(value);
 | |
| 		source.sendSuccess(
 | |
| 			() -> Component.translatable("commands.attribute.base_value.set.success", getAttributeDescription(attribute), entity.getName(), value), false
 | |
| 		);
 | |
| 		return 1;
 | |
| 	}
 | |
| 
 | |
| 	private static int resetAttributeBase(CommandSourceStack source, Entity entity, Holder<Attribute> attribute) throws CommandSyntaxException {
 | |
| 		LivingEntity livingEntity = getLivingEntity(entity);
 | |
| 		if (!livingEntity.getAttributes().resetBaseValue(attribute)) {
 | |
| 			throw ERROR_NO_SUCH_ATTRIBUTE.create(entity.getName(), getAttributeDescription(attribute));
 | |
| 		} else {
 | |
| 			double d = livingEntity.getAttributeBaseValue(attribute);
 | |
| 			source.sendSuccess(
 | |
| 				() -> Component.translatable("commands.attribute.base_value.reset.success", getAttributeDescription(attribute), entity.getName(), d), false
 | |
| 			);
 | |
| 			return 1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static int addModifier(
 | |
| 		CommandSourceStack source, Entity entity, Holder<Attribute> attribute, ResourceLocation id, double amount, AttributeModifier.Operation operation
 | |
| 	) throws CommandSyntaxException {
 | |
| 		AttributeInstance attributeInstance = getAttributeInstance(entity, attribute);
 | |
| 		AttributeModifier attributeModifier = new AttributeModifier(id, amount, operation);
 | |
| 		if (attributeInstance.hasModifier(id)) {
 | |
| 			throw ERROR_MODIFIER_ALREADY_PRESENT.create(entity.getName(), getAttributeDescription(attribute), id);
 | |
| 		} else {
 | |
| 			attributeInstance.addPermanentModifier(attributeModifier);
 | |
| 			source.sendSuccess(
 | |
| 				() -> Component.translatable("commands.attribute.modifier.add.success", Component.translationArg(id), getAttributeDescription(attribute), entity.getName()),
 | |
| 				false
 | |
| 			);
 | |
| 			return 1;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static int removeModifier(CommandSourceStack source, Entity entity, Holder<Attribute> attribute, ResourceLocation id) throws CommandSyntaxException {
 | |
| 		AttributeInstance attributeInstance = getAttributeInstance(entity, attribute);
 | |
| 		if (attributeInstance.removeModifier(id)) {
 | |
| 			source.sendSuccess(
 | |
| 				() -> Component.translatable(
 | |
| 					"commands.attribute.modifier.remove.success", Component.translationArg(id), getAttributeDescription(attribute), entity.getName()
 | |
| 				),
 | |
| 				false
 | |
| 			);
 | |
| 			return 1;
 | |
| 		} else {
 | |
| 			throw ERROR_NO_SUCH_MODIFIER.create(entity.getName(), getAttributeDescription(attribute), id);
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	private static Component getAttributeDescription(Holder<Attribute> attribute) {
 | |
| 		return Component.translatable(attribute.value().getDescriptionId());
 | |
| 	}
 | |
| }
 |