-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cb960d3
commit 60be8eb
Showing
11 changed files
with
754 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
112 changes: 112 additions & 0 deletions
112
cloud-bukkit/src/main/java/org/incendo/cloud/bukkit/parser/rotation/Angle.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// | ||
// MIT License | ||
// | ||
// Copyright (c) 2024 Incendo | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
// | ||
package org.incendo.cloud.bukkit.parser.rotation; | ||
|
||
import org.checkerframework.checker.nullness.qual.NonNull; | ||
|
||
/** | ||
* Represents an angle that can be applied to a reference angle. | ||
* | ||
* @since 2.0.0 | ||
*/ | ||
public final class Angle { | ||
|
||
private final float angle; | ||
private final boolean relative; | ||
|
||
private Angle( | ||
final float angle, | ||
final boolean relative | ||
) { | ||
this.angle = angle; | ||
this.relative = relative; | ||
} | ||
|
||
/** | ||
* Create a new angle object. | ||
* | ||
* @param angle angle | ||
* @param relative whether the angle is relative | ||
* @return Created angle instance. | ||
*/ | ||
public static @NonNull Angle of( | ||
final float angle, | ||
final boolean relative | ||
) { | ||
return new Angle(angle, relative); | ||
} | ||
|
||
/** | ||
* Returns the angle. | ||
* | ||
* @return angle | ||
*/ | ||
public float angle() { | ||
return this.angle; | ||
} | ||
|
||
/** | ||
* Returns if this angle is relative. | ||
* | ||
* @return whether the angle is relative | ||
*/ | ||
public boolean relative() { | ||
return this.relative; | ||
} | ||
|
||
/** | ||
* Applies this angle to a reference angle. | ||
* | ||
* @param angle the reference angle | ||
* @return the modified angle | ||
*/ | ||
public float apply(final float angle) { | ||
return this.relative ? this.angle + angle : this.angle; | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Angle that = (Angle) o; | ||
return Float.compare(this.angle, that.angle) == 0 && this.relative == that.relative; | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
int result = Float.hashCode(this.angle); | ||
result = 31 * result + Boolean.hashCode(this.relative); | ||
return result; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return String.format("Angle{angle=%s, relative=%s}", this.angle, this.relative); | ||
} | ||
|
||
} |
138 changes: 138 additions & 0 deletions
138
cloud-bukkit/src/main/java/org/incendo/cloud/bukkit/parser/rotation/AngleParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
// | ||
// MIT License | ||
// | ||
// Copyright (c) 2024 Incendo | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
// | ||
package org.incendo.cloud.bukkit.parser.rotation; | ||
|
||
import java.util.stream.Collectors; | ||
import org.apiguardian.api.API; | ||
import org.checkerframework.checker.nullness.qual.NonNull; | ||
import org.incendo.cloud.component.CommandComponent; | ||
import org.incendo.cloud.context.CommandContext; | ||
import org.incendo.cloud.context.CommandInput; | ||
import org.incendo.cloud.parser.ArgumentParseResult; | ||
import org.incendo.cloud.parser.ArgumentParser; | ||
import org.incendo.cloud.parser.ParserDescriptor; | ||
import org.incendo.cloud.parser.standard.FloatParser; | ||
import org.incendo.cloud.parser.standard.IntegerParser; | ||
import org.incendo.cloud.suggestion.BlockingSuggestionProvider; | ||
import org.incendo.cloud.type.range.Range; | ||
|
||
|
||
/** | ||
* Parser that parsers a {@link Angle} from two floats. | ||
* | ||
* @param <C> Command sender type | ||
* @since 2.0.0 | ||
*/ | ||
public final class AngleParser<C> implements ArgumentParser<C, Angle>, BlockingSuggestionProvider.Strings<C> { | ||
|
||
private static final Range<Integer> SUGGESTION_RANGE = Range.intRange(Integer.MIN_VALUE, Integer.MAX_VALUE); | ||
|
||
/** | ||
* Creates a new angle parser. | ||
* | ||
* @param <C> command sender type | ||
* @return the created parser | ||
* @since 2.0.0 | ||
*/ | ||
@API(status = API.Status.STABLE, since = "2.0.0") | ||
public static <C> @NonNull ParserDescriptor<C, Angle> angleParser() { | ||
return ParserDescriptor.of(new AngleParser<>(), Angle.class); | ||
} | ||
|
||
/** | ||
* Returns a {@link CommandComponent.Builder} using {@link #angleParser()} as the parser. | ||
* | ||
* @param <C> the command sender type | ||
* @return the component builder | ||
* @since 2.0.0 | ||
*/ | ||
@API(status = API.Status.STABLE, since = "2.0.0") | ||
public static <C> CommandComponent.@NonNull Builder<C, Angle> angleComponent() { | ||
return CommandComponent.<C, Angle>builder().parser(angleParser()); | ||
} | ||
|
||
@Override | ||
public @NonNull ArgumentParseResult<@NonNull Angle> parse( | ||
final @NonNull CommandContext<@NonNull C> commandContext, | ||
final @NonNull CommandInput commandInput | ||
) { | ||
final String input = commandInput.skipWhitespace().peekString(); | ||
|
||
final boolean relative; | ||
if (commandInput.peek() == '~') { | ||
relative = true; | ||
commandInput.moveCursor(1); | ||
} else { | ||
relative = false; | ||
} | ||
|
||
final float angle; | ||
try { | ||
final boolean empty = commandInput.peekString().isEmpty() || commandInput.peek() == ' '; | ||
angle = empty ? 0 : commandInput.readFloat(); | ||
|
||
// You can have a prefix without a number, in which case we wouldn't consume the | ||
// subsequent whitespace. We do it manually. | ||
if (commandInput.hasRemainingInput() && commandInput.peek() == ' ') { | ||
commandInput.read(); | ||
} | ||
} catch (final Exception e) { | ||
return ArgumentParseResult.failure(new FloatParser.FloatParseException( | ||
input, | ||
new FloatParser<>( | ||
FloatParser.DEFAULT_MINIMUM, | ||
FloatParser.DEFAULT_MAXIMUM | ||
), | ||
commandContext | ||
)); | ||
} | ||
|
||
return ArgumentParseResult.success( | ||
Angle.of( | ||
angle, | ||
relative | ||
) | ||
); | ||
} | ||
|
||
@Override | ||
public @NonNull Iterable<@NonNull String> stringSuggestions( | ||
final @NonNull CommandContext<C> commandContext, | ||
final @NonNull CommandInput input | ||
) { | ||
String prefix; | ||
if (input.hasRemainingInput() && input.peek() == '~') { | ||
prefix = "~"; | ||
input.moveCursor(1); | ||
} else { | ||
prefix = ""; | ||
} | ||
|
||
return IntegerParser.getSuggestions( | ||
SUGGESTION_RANGE, | ||
input | ||
).stream().map(string -> prefix + string).collect(Collectors.toList()); | ||
} | ||
|
||
} |
Oops, something went wrong.