use of com.fastasyncworldedit.core.registry.state.PropertyKey in project FastAsyncWorldEdit by IntellectualSites.
the class BlockTransformExtent method transformState.
private static int transformState(BlockState state, Transform transform) {
int newMaskedId = state.getInternalId();
BlockType type = state.getBlockType();
// Rotate North, East, South, West
if (type.hasProperty(PropertyKey.NORTH) && type.hasProperty(PropertyKey.EAST) && type.hasProperty(PropertyKey.SOUTH) && type.hasProperty(PropertyKey.WEST)) {
BlockState tmp = state;
for (Map.Entry<Direction, PropertyKey> entry : directionMap.entrySet()) {
Direction newDir = findClosest(transform.apply(entry.getKey().toVector()), Flag.CARDINAL);
if (newDir != null) {
Object dirState = state.getState(entry.getValue());
tmp = tmp.with(directionMap.get(newDir), dirState);
}
}
newMaskedId = tmp.getInternalId();
}
// True if relying on two different "directions" for the result, e.g. stairs with both facing and shape
for (AbstractProperty property : (List<AbstractProperty<?>>) type.getProperties()) {
if (isDirectional(property)) {
long[] directions = getDirections(property);
if (directions != null) {
int oldIndex = property.getIndex(state.getInternalId());
if (oldIndex >= directions.length) {
if (Settings.settings().ENABLED_COMPONENTS.DEBUG) {
LOGGER.warn(String.format("Index outside direction array length found for block:{%s} property:{%s}", state.getBlockType().getId(), property.getName()));
}
continue;
}
Integer newIndex = getNewStateIndex(transform, directions, oldIndex);
if (newIndex != null) {
newMaskedId = property.modifyIndex(newMaskedId, newIndex);
}
}
}
}
return newMaskedId;
}
use of com.fastasyncworldedit.core.registry.state.PropertyKey in project FastAsyncWorldEdit by IntellectualSites.
the class BlockTransformExtent method getDirections.
private static long[] getDirections(AbstractProperty property) {
if (property instanceof DirectionalProperty) {
DirectionalProperty directional = (DirectionalProperty) property;
return adapt(directional.getValues().toArray(new Direction[0]));
} else {
List values = property.getValues();
PropertyKey key = property.getKey();
switch(key.getName().toLowerCase()) {
case "half":
{
return adapt(UP, DOWN);
}
case "type":
{
return adapt(combine(UP), combine(DOWN), 0L);
}
case "rotation":
{
List<Direction> directions = new ArrayList<>();
for (Object value : values) {
directions.add(Direction.fromRotationIndex((Integer) value).get());
}
return adapt(directions.toArray(new Direction[0]));
}
case "axis":
{
switch(property.getValues().size()) {
case 3:
return adapt(combine(EAST, WEST), combine(UP, DOWN), combine(SOUTH, NORTH));
case 2:
return adapt(combine(EAST, WEST), combine(SOUTH, NORTH));
default:
LOGGER.error("Invalid {} {}", property.getName(), property.getValues());
return null;
}
}
case "facing":
{
List<Direction> directions = new ArrayList<>();
for (Object value : values) {
directions.add(Direction.valueOf(value.toString().toUpperCase(Locale.ROOT)));
}
return adapt(directions.toArray(new Direction[0]));
}
case "face":
{
if (values.size() == 3) {
return adapt(combine(UP), combine(NORTH, EAST, SOUTH, WEST), combine(DOWN));
}
return null;
}
case "hinge":
{
return adapt(combine(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST), combine(NORTHEAST, NORTHWEST, SOUTHEAST, SOUTHWEST));
}
case "shape":
{
if (values.contains("left")) {
return adapt(combine(EAST, WEST), combine(NORTH, SOUTH));
}
if (values.contains("straight")) {
ArrayList<Long> result = new ArrayList<>();
for (Object value : values) {
// [straight, inner_left, inner_right, outer_left, outer_right]
switch(value.toString()) {
case "straight":
result.add(combine(NORTH, EAST, SOUTH, WEST));
continue;
case "inner_left":
result.add(orIndex(combine(NORTHEAST, NORTHWEST, SOUTHWEST, SOUTHEAST), property.getIndexFor("outer_right"), property.getIndexFor("outer_left")));
continue;
case "inner_right":
result.add(orIndex(combine(NORTHEAST, NORTHWEST, SOUTHWEST, SOUTHEAST), property.getIndexFor("outer_right"), property.getIndexFor("outer_left")));
continue;
case "outer_left":
result.add(orIndex(combine(NORTHEAST, NORTHWEST, SOUTHWEST, SOUTHEAST), property.getIndexFor("inner_left"), property.getIndexFor("inner_right")));
continue;
case "outer_right":
result.add(orIndex(combine(NORTHEAST, NORTHWEST, SOUTHWEST, SOUTHEAST), property.getIndexFor("inner_left"), property.getIndexFor("inner_right")));
continue;
default:
LOGGER.warn("Unknown direction {}", value);
result.add(0L);
}
}
return adapt(result.toArray(new Long[0]));
} else {
List<Long> directions = new ArrayList<>();
for (Object value : values) {
switch(value.toString()) {
case "north_south":
directions.add(combine(NORTH, SOUTH));
break;
case "east_west":
directions.add(combine(EAST, WEST));
break;
case "ascending_east":
directions.add(combine(ASCENDING_EAST));
break;
case "ascending_west":
directions.add(combine(ASCENDING_WEST));
break;
case "ascending_north":
directions.add(combine(ASCENDING_NORTH));
break;
case "ascending_south":
directions.add(combine(ASCENDING_SOUTH));
break;
case "south_east":
directions.add(combine(SOUTHEAST));
break;
case "south_west":
directions.add(combine(SOUTHWEST));
break;
case "north_west":
directions.add(combine(NORTHWEST));
break;
case "north_east":
directions.add(combine(NORTHEAST));
break;
default:
LOGGER.warn("Unknown direction {}", value);
directions.add(0L);
}
}
return adapt(directions.toArray(new Long[0]));
}
}
}
}
return null;
}
use of com.fastasyncworldedit.core.registry.state.PropertyKey in project FastAsyncWorldEdit by IntellectualSites.
the class BlockState method get.
/**
* Returns a temporary BlockState for a given type and string.
*
* <p>It's faster if a BlockType is provided compared to parsing the string.</p>
*
* @param type BlockType e.g., BlockTypes.STONE (or null)
* @param state String e.g., minecraft:water[level=4]
* @return BlockState
*/
public static BlockState get(@Nullable BlockType type, String state, BlockState defaultState) throws InputParseException {
int propStrStart = state.indexOf('[');
if (type == null) {
CharSequence key;
if (propStrStart == -1) {
key = state;
} else {
MutableCharSequence charSequence = MutableCharSequence.getTemporal();
charSequence.setString(state);
charSequence.setSubstring(0, propStrStart);
key = charSequence;
}
type = BlockTypes.get(key);
if (type == null) {
String input = key.toString();
throw new SuggestInputParseException("Does not match a valid block type: " + input, input, () -> Stream.of(BlockTypesCache.values).map(BlockType::getId).filter(id -> StringMan.blockStateMatches(input, id)).sorted(StringMan.blockStateComparator(input)).collect(Collectors.toList()));
}
}
if (propStrStart == -1) {
return type.getDefaultState();
}
List<? extends Property<?>> propList = type.getProperties();
if (state.charAt(state.length() - 1) != ']') {
state = state + "]";
}
MutableCharSequence charSequence = MutableCharSequence.getTemporal();
charSequence.setString(state);
if (propList.size() == 1) {
AbstractProperty<?> property = (AbstractProperty<?>) propList.get(0);
String name = property.getName();
charSequence.setSubstring(propStrStart + name.length() + 2, state.length() - 1);
int index = charSequence.length() <= 0 ? -1 : property.getIndexFor(charSequence);
if (index != -1) {
return type.withPropertyId(index);
}
}
int stateId;
if (defaultState != null) {
stateId = defaultState.getInternalId();
} else {
stateId = type.getDefaultState().getInternalId();
}
int length = state.length();
AbstractProperty<?> property = null;
int last = propStrStart + 1;
for (int i = last; i < length; i++) {
char c = state.charAt(i);
switch(c) {
case ']':
case ',':
{
charSequence.setSubstring(last, i);
if (property != null) {
int index = property.getIndexFor(charSequence);
if (index == -1) {
throw SuggestInputParseException.of(charSequence.toString(), (List<Object>) property.getValues());
}
stateId = property.modifyIndex(stateId, index);
} else {
// suggest
PropertyKey key = PropertyKey.getByName(charSequence);
if (key == null || !type.hasProperty(key)) {
// Suggest property
String input = charSequence.toString();
BlockType finalType = type;
throw new SuggestInputParseException("Invalid property " + key + ":" + input + " for type " + type, input, () -> finalType.getProperties().stream().map(Property::getName).filter(p -> StringMan.blockStateMatches(input, p)).sorted(StringMan.blockStateComparator(input)).collect(Collectors.toList()));
} else {
throw new SuggestInputParseException("No operator for " + state, "", () -> Collections.singletonList("="));
}
}
property = null;
last = i + 1;
break;
}
case '=':
{
charSequence.setSubstring(last, i);
property = (AbstractProperty) type.getPropertyMap().get(charSequence);
last = i + 1;
break;
}
default:
continue;
}
}
return type.withPropertyId(stateId >> BlockTypesCache.BIT_OFFSET);
}
use of com.fastasyncworldedit.core.registry.state.PropertyKey in project FastAsyncWorldEdit by IntellectualSites.
the class BlockState method withProperties.
public <V> BlockState withProperties(final BlockState other) {
BlockType ot = other.getBlockType();
if (ot == blockType) {
return other;
}
if (ot.getProperties().isEmpty() || blockType.getProperties().isEmpty()) {
return this;
}
BlockState newState = this;
for (Property<?> prop : ot.getProperties()) {
PropertyKey key = prop.getKey();
if (blockType.hasProperty(key)) {
newState = newState.with(key, other.getState(key));
}
}
return newState;
}
Aggregations