mirror of
https://github.com/EngineHub/WorldEdit.git
synced 2025-03-13 13:57:48 +08:00
Add a command to apply side effects (#1623)
* [WIP] Add a command to apply side effects * Fix checkstyle * Switch to the //update command, and add messages * The update command won't change in the future, remove that warning * Create a Function that applies side effects for easier API usage, and make gmasks apply to `//update` * Fixed `//update` not using the current side effect set * Fixed PR review notes * Fixed regression in last commit * smh why is it null * Update GeneralCommands.java * PR review * PR review * :( * :(
This commit is contained in:
parent
2c172197ac
commit
df71f3ae7d
@ -32,7 +32,12 @@ import com.sk89q.worldedit.command.util.WorldEditAsyncCommandBuilder;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.function.RegionMaskingFilter;
|
||||
import com.sk89q.worldedit.function.block.ApplySideEffect;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.visitor.RegionVisitor;
|
||||
import com.sk89q.worldedit.internal.command.CommandRegistrationHandler;
|
||||
import com.sk89q.worldedit.internal.command.CommandUtil;
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
@ -76,7 +81,7 @@ public class GeneralCommands {
|
||||
CommandManager commandManager,
|
||||
CommandManagerService commandManagerService,
|
||||
WorldEdit worldEdit) {
|
||||
// Collect the tool commands
|
||||
// Collect the commands
|
||||
CommandManager collect = commandManagerService.newCommandManager();
|
||||
|
||||
registration.register(
|
||||
@ -282,6 +287,29 @@ public class GeneralCommands {
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "/update",
|
||||
desc = "Apply side effects to your selection"
|
||||
)
|
||||
@CommandPermissions("worldedit.update")
|
||||
void update(Actor actor, LocalSession session, World injectedWorld,
|
||||
@Arg(desc = "The side effects", def = "")
|
||||
SideEffectSet sideEffectSet) throws WorldEditException {
|
||||
if (sideEffectSet == null) {
|
||||
// Use defaults if none supplied.
|
||||
sideEffectSet = SideEffectSet.defaults();
|
||||
}
|
||||
RegionFunction apply = new ApplySideEffect(injectedWorld, sideEffectSet);
|
||||
if (session.getMask() != null) {
|
||||
apply = new RegionMaskingFilter(session.getMask(), apply);
|
||||
}
|
||||
|
||||
RegionVisitor visitor = new RegionVisitor(session.getSelection(injectedWorld), apply);
|
||||
Operations.complete(visitor);
|
||||
|
||||
actor.printInfo(TranslatableComponent.of("worldedit.update"));
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "/reorder",
|
||||
desc = "Sets the reorder mode of WorldEdit"
|
||||
|
@ -21,6 +21,7 @@ package com.sk89q.worldedit.command.argument;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
@ -30,6 +31,8 @@ import org.enginehub.piston.converter.SuccessfulConversion;
|
||||
import org.enginehub.piston.inject.InjectedValueAccess;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.sk89q.worldedit.util.formatting.text.TextComponent.space;
|
||||
@ -40,20 +43,30 @@ public class CommaSeparatedValuesConverter<T> implements ArgumentConverter<T> {
|
||||
return wrapAndLimit(delegate, -1);
|
||||
}
|
||||
|
||||
public static <T> CommaSeparatedValuesConverter<T> wrapNoRepeats(ArgumentConverter<T> delegate) {
|
||||
return wrapAndLimitNoRepeats(delegate, -1);
|
||||
}
|
||||
|
||||
public static <T> CommaSeparatedValuesConverter<T> wrapAndLimit(ArgumentConverter<T> delegate, int maximum) {
|
||||
return new CommaSeparatedValuesConverter<>(delegate, maximum);
|
||||
return new CommaSeparatedValuesConverter<>(delegate, maximum, true);
|
||||
}
|
||||
|
||||
public static <T> CommaSeparatedValuesConverter<T> wrapAndLimitNoRepeats(ArgumentConverter<T> delegate, int maximum) {
|
||||
return new CommaSeparatedValuesConverter<>(delegate, maximum, false);
|
||||
}
|
||||
|
||||
private static final Splitter COMMA = Splitter.on(',');
|
||||
|
||||
private final ArgumentConverter<T> delegate;
|
||||
private final int maximum;
|
||||
private final boolean repeats;
|
||||
|
||||
private CommaSeparatedValuesConverter(ArgumentConverter<T> delegate, int maximum) {
|
||||
private CommaSeparatedValuesConverter(ArgumentConverter<T> delegate, int maximum, boolean repeats) {
|
||||
checkArgument(maximum == -1 || maximum > 1,
|
||||
"Maximum must be bigger than 1, or exactly -1");
|
||||
this.delegate = delegate;
|
||||
this.maximum = maximum;
|
||||
this.repeats = repeats;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -73,7 +86,17 @@ public class CommaSeparatedValuesConverter<T> implements ArgumentConverter<T> {
|
||||
public List<String> getSuggestions(String input, InjectedValueAccess context) {
|
||||
String lastInput = Iterables.getLast(COMMA.split(input), "");
|
||||
assert lastInput != null;
|
||||
return delegate.getSuggestions(lastInput, context);
|
||||
List<String> suggestions = delegate.getSuggestions(lastInput, context);
|
||||
if (input.contains(",")) {
|
||||
String prefix = input.substring(0, input.length() - lastInput.length());
|
||||
Set<String> entries = ImmutableSet.copyOf(COMMA.split(input));
|
||||
suggestions = suggestions
|
||||
.stream()
|
||||
.filter(suggestion -> repeats || !entries.contains(suggestion))
|
||||
.map(suggestion -> prefix + suggestion)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.command.argument;
|
||||
|
||||
import com.sk89q.worldedit.util.SideEffect;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.util.formatting.text.Component;
|
||||
import com.sk89q.worldedit.util.formatting.text.TextComponent;
|
||||
import org.enginehub.piston.CommandManager;
|
||||
import org.enginehub.piston.converter.ArgumentConverter;
|
||||
import org.enginehub.piston.converter.ConversionResult;
|
||||
import org.enginehub.piston.converter.FailedConversion;
|
||||
import org.enginehub.piston.converter.SuccessfulConversion;
|
||||
import org.enginehub.piston.inject.InjectedValueAccess;
|
||||
import org.enginehub.piston.inject.Key;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SideEffectSetConverter implements ArgumentConverter<SideEffectSet> {
|
||||
|
||||
public static void register(CommandManager commandManager) {
|
||||
ArgumentConverter<SideEffect> sideEffectConverter = commandManager.getConverter(Key.of(SideEffect.class))
|
||||
.orElseThrow(() -> new IllegalStateException("SideEffectSetConverter must be registered after SideEffectConverter"));
|
||||
commandManager.registerConverter(
|
||||
Key.of(SideEffectSet.class),
|
||||
new SideEffectSetConverter(CommaSeparatedValuesConverter.wrapNoRepeats(sideEffectConverter))
|
||||
);
|
||||
}
|
||||
|
||||
private final TextComponent choices = TextComponent.of("any side effects");
|
||||
private final CommaSeparatedValuesConverter<SideEffect> sideEffectConverter;
|
||||
|
||||
private SideEffectSetConverter(CommaSeparatedValuesConverter<SideEffect> sideEffectConverter) {
|
||||
this.sideEffectConverter = sideEffectConverter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component describeAcceptableArguments() {
|
||||
return choices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getSuggestions(String input, InjectedValueAccess context) {
|
||||
return sideEffectConverter.getSuggestions(input, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConversionResult<SideEffectSet> convert(String argument, InjectedValueAccess context) {
|
||||
try {
|
||||
ConversionResult<SideEffect> result = sideEffectConverter.convert(argument, context);
|
||||
if (result.isSuccessful()) {
|
||||
SideEffectSet set = SideEffectSet.none();
|
||||
for (SideEffect sideEffect : result.get()) {
|
||||
set = set.with(sideEffect, SideEffect.State.ON);
|
||||
}
|
||||
return SuccessfulConversion.fromSingle(set);
|
||||
} else {
|
||||
return result.failureAsAny();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return FailedConversion.from(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -81,6 +81,7 @@ import com.sk89q.worldedit.command.argument.OffsetConverter;
|
||||
import com.sk89q.worldedit.command.argument.RegionFactoryConverter;
|
||||
import com.sk89q.worldedit.command.argument.RegistryConverter;
|
||||
import com.sk89q.worldedit.command.argument.SideEffectConverter;
|
||||
import com.sk89q.worldedit.command.argument.SideEffectSetConverter;
|
||||
import com.sk89q.worldedit.command.argument.VectorConverter;
|
||||
import com.sk89q.worldedit.command.argument.WorldConverter;
|
||||
import com.sk89q.worldedit.command.argument.ZonedDateTimeConverter;
|
||||
@ -221,6 +222,7 @@ public final class PlatformCommandManager {
|
||||
RegionFactoryConverter.register(commandManager);
|
||||
WorldConverter.register(commandManager);
|
||||
SideEffectConverter.register(commandManager);
|
||||
SideEffectSetConverter.register(commandManager);
|
||||
HeightConverter.register(commandManager);
|
||||
OffsetConverter.register(worldEdit, commandManager);
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.function.block;
|
||||
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.SideEffectSet;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Applies the given side effect within a region.
|
||||
*/
|
||||
public class ApplySideEffect implements RegionFunction {
|
||||
|
||||
private final World world;
|
||||
private final SideEffectSet sideEffectSet;
|
||||
|
||||
public ApplySideEffect(World world, SideEffectSet sideEffectSet) {
|
||||
checkNotNull(world);
|
||||
checkNotNull(sideEffectSet);
|
||||
this.world = world;
|
||||
this.sideEffectSet = sideEffectSet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(BlockVector3 position) throws WorldEditException {
|
||||
world.applySideEffects(position, world.getBlock(position), sideEffectSet);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -29,6 +29,7 @@ public enum SideEffect {
|
||||
ENTITY_AI(State.OFF),
|
||||
EVENTS(State.OFF);
|
||||
|
||||
// TODO Make these components in WE8
|
||||
private final String displayName;
|
||||
private final String description;
|
||||
private final State defaultValue;
|
||||
@ -56,6 +57,7 @@ public enum SideEffect {
|
||||
ON,
|
||||
DELAYED;
|
||||
|
||||
// TODO Make this a component in WE8
|
||||
private final String displayName;
|
||||
|
||||
State() {
|
||||
|
@ -52,6 +52,7 @@
|
||||
"worldedit.perf.sideeffect.get": "Side effect \"{0}\" is set to {1}",
|
||||
"worldedit.perf.sideeffect.already-set": "Side effect \"{0}\" is already {1}",
|
||||
"worldedit.perf.sideeffect.set-all": "All side effects set to {0}",
|
||||
"worldedit.update": "Applied side effects to the selection.",
|
||||
"worldedit.reorder.current": "The reorder mode is {0}",
|
||||
"worldedit.reorder.set": "The reorder mode is now {0}",
|
||||
"worldedit.gmask.disabled": "Global mask disabled.",
|
||||
|
Loading…
x
Reference in New Issue
Block a user