mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-05 20:36:42 +00:00
Copy paste/merge FAWE classes to this WorldEdit fork
- so certain people can look at the diff and complain about my sloppy code :( Signed-off-by: Jesse Boyd <jessepaleg@gmail.com>
This commit is contained in:
@ -22,20 +22,23 @@ package com.sk89q.worldedit.world;
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
/**
|
||||
* An abstract implementation of {@link World}.
|
||||
@ -62,9 +65,7 @@ public abstract class AbstractWorld implements World {
|
||||
|
||||
@Override
|
||||
public Mask createLiquidMask() {
|
||||
return new BlockMask(this,
|
||||
BlockTypes.LAVA.getDefaultState().toFuzzy(),
|
||||
BlockTypes.WATER.getDefaultState().toFuzzy());
|
||||
return new BlockTypeMask(this, BlockTypes.LAVA, BlockTypes.WATER);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -91,6 +92,11 @@ public abstract class AbstractWorld implements World {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getLazyBlock(Vector position) {
|
||||
return new BaseBlock(getBlock(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean queueBlockBreakEffect(Platform server, Vector position, BlockType blockType, double priority) {
|
||||
if (taskId == -1) {
|
||||
@ -140,7 +146,7 @@ public abstract class AbstractWorld implements World {
|
||||
}
|
||||
|
||||
public void play() {
|
||||
playEffect(position, 2001, blockType.getLegacyId());
|
||||
playEffect(position, 2001, blockType.getLegacyCombinedId() >> 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -148,5 +154,4 @@ public abstract class AbstractWorld implements World {
|
||||
return Double.compare(priority, other != null ? other.priority : 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -24,17 +24,19 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.blocks.LazyBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.weather.WeatherType;
|
||||
|
||||
import java.util.Collections;
|
||||
@ -50,7 +52,7 @@ public class NullWorld extends AbstractWorld {
|
||||
|
||||
private static final NullWorld INSTANCE = new NullWorld();
|
||||
|
||||
protected NullWorld() {
|
||||
public NullWorld() {
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -124,9 +126,14 @@ public class NullWorld extends AbstractWorld {
|
||||
return BlockTypes.AIR.getDefaultState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyBlock getLazyBlock(Vector position) {
|
||||
return new LazyBlock(getBlock(position), this, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock getFullBlock(Vector position) {
|
||||
return getBlock(position).toBaseBlock();
|
||||
return new BaseBlock(getBlock(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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 Lesser General default 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 Lesser General default License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General default License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.world;
|
||||
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.function.mask.BlockTypeMask;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.world.block.*;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.function.mask.BlockMask;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.world.weather.WeatherType;
|
||||
import com.sk89q.worldedit.world.weather.WeatherTypes;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* An abstract implementation of {@link World}.
|
||||
*/
|
||||
public interface SimpleWorld extends World {
|
||||
@Override
|
||||
default boolean useItem(Vector position, BaseItem item, Direction face) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean setBlock(Vector position, BlockStateHolder block, boolean notifyAndLight) throws WorldEditException {
|
||||
return setBlock(position, block);
|
||||
}
|
||||
|
||||
@Override
|
||||
default BlockState getFullBlock(Vector position) {
|
||||
return getLazyBlock(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean setBlock(Vector pt, BlockStateHolder block) throws WorldEditException;
|
||||
|
||||
@Override
|
||||
default int getMaxY() {
|
||||
return getMaximumPoint().getBlockY();
|
||||
}
|
||||
|
||||
@Override
|
||||
default Mask createLiquidMask() {
|
||||
return new BlockTypeMask(this, BlockTypes.LAVA, BlockTypes.WATER);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void dropItem(Vector pt, BaseItemStack item, int times) {
|
||||
for (int i = 0; i < times; ++i) {
|
||||
dropItem(pt, item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
default void checkLoadedChunk(Vector pt) {
|
||||
}
|
||||
|
||||
@Override
|
||||
default void fixAfterFastMode(Iterable<BlockVector2D> chunks) {
|
||||
}
|
||||
|
||||
@Override
|
||||
default void fixLighting(Iterable<BlockVector2D> chunks) {
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean playEffect(Vector position, int type, int data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean queueBlockBreakEffect(Platform server, Vector position, BlockType blockType, double priority) {
|
||||
SetQueue.IMP.addTask(() -> playEffect(position, 2001, blockType.getLegacyCombinedId() >> 4));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
default Vector getMinimumPoint() {
|
||||
return new Vector(-30000000, 0, -30000000);
|
||||
}
|
||||
|
||||
@Override
|
||||
default Vector getMaximumPoint() {
|
||||
return new Vector(30000000, 255, 30000000);
|
||||
}
|
||||
|
||||
@Override
|
||||
default @Nullable Operation commit() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
default boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, Vector position) throws MaxChangedBlocksException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
default void simulateBlockMine(Vector position) {
|
||||
try {
|
||||
setBlock(position, BlockTypes.AIR.getDefaultState());
|
||||
} catch (WorldEditException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
default WeatherType getWeather() {
|
||||
return WeatherTypes.CLEAR;
|
||||
}
|
||||
|
||||
@Override
|
||||
default long getRemainingWeatherDuration() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
default void setWeather(WeatherType weatherType) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
default void setWeather(WeatherType weatherType, long duration) {
|
||||
|
||||
}
|
||||
}
|
@ -26,14 +26,15 @@ import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.extension.platform.Platform;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Direction;
|
||||
import com.sk89q.worldedit.util.TreeGenerator;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.weather.WeatherType;
|
||||
|
||||
/**
|
||||
|
@ -19,11 +19,16 @@
|
||||
|
||||
package com.sk89q.worldedit.world.biome;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Link;
|
||||
import com.sk89q.worldedit.command.BiomeCommands;
|
||||
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Basic storage object to represent a given biome.
|
||||
*/
|
||||
@Link(clazz = BiomeCommands.class, value = "biomelist")
|
||||
public class BaseBiome {
|
||||
|
||||
private int id;
|
||||
@ -79,4 +84,9 @@ public class BaseBiome {
|
||||
public int hashCode() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public static Class<?> inject() {
|
||||
return BaseBiome.class;
|
||||
}
|
||||
}
|
||||
|
@ -19,13 +19,13 @@
|
||||
|
||||
package com.sk89q.worldedit.world.biome;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.sk89q.worldedit.world.registry.BiomeRegistry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Returns the name of a biome using a given {@code BiomeRegistry}.
|
||||
*/
|
||||
|
@ -1,211 +0,0 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.world.block;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a mutable "snapshot" of a block.
|
||||
*
|
||||
* <p>An instance of this block contains all the information needed to
|
||||
* accurately reproduce the block, provided that the instance was
|
||||
* made correctly. In some implementations, it may not be possible to get a
|
||||
* snapshot of blocks correctly, so, for example, the NBT data for a block
|
||||
* may be missing.</p>
|
||||
*
|
||||
* <p>A peculiar detail of this class is that it accepts {@code -1} as a
|
||||
* valid data value. This is due to legacy reasons: WorldEdit uses -1
|
||||
* as a "wildcard" block value, even though a {@link Mask} would be
|
||||
* more appropriate.</p>
|
||||
*/
|
||||
public class BaseBlock implements BlockStateHolder<BaseBlock>, TileEntityBlock {
|
||||
|
||||
private BlockState blockState;
|
||||
@Nullable private CompoundTag nbtData;
|
||||
|
||||
/**
|
||||
* Construct a block with a state.
|
||||
*
|
||||
* @param blockState The blockstate
|
||||
*/
|
||||
protected BaseBlock(BlockState blockState) {
|
||||
this.blockState = blockState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a block with the given ID, data value and NBT data structure.
|
||||
*
|
||||
* @param state The block state
|
||||
* @param nbtData NBT data, which must be provided
|
||||
*/
|
||||
protected BaseBlock(BlockState state, CompoundTag nbtData) {
|
||||
checkNotNull(nbtData);
|
||||
this.blockState = state;
|
||||
this.nbtData = nbtData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a clone of another block.
|
||||
*
|
||||
* @param other the other block
|
||||
*/
|
||||
public BaseBlock(BaseBlock other) {
|
||||
this(other.toImmutableState(), other.getNbtData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a map of state to statevalue
|
||||
*
|
||||
* @return The state map
|
||||
*/
|
||||
@Override
|
||||
public Map<Property<?>, Object> getStates() {
|
||||
return this.blockState.getStates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockType getBlockType() {
|
||||
return this.blockState.getBlockType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> BaseBlock with(Property<V> property, V value) {
|
||||
return new BaseBlock(this.blockState.with(property, value), getNbtData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the State for this Block.
|
||||
*
|
||||
* @param property The state to get the value for
|
||||
* @return The state value
|
||||
*/
|
||||
@Override
|
||||
public <V> V getState(Property<V> property) {
|
||||
return this.blockState.getState(property);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNbtData() {
|
||||
return getNbtData() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNbtId() {
|
||||
CompoundTag nbtData = getNbtData();
|
||||
if (nbtData == null) {
|
||||
return "";
|
||||
}
|
||||
Tag idTag = nbtData.getValue().get("id");
|
||||
if (idTag instanceof StringTag) {
|
||||
return ((StringTag) idTag).getValue();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CompoundTag getNbtData() {
|
||||
return this.nbtData;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNbtData(@Nullable CompoundTag nbtData) {
|
||||
throw new UnsupportedOperationException("This class is immutable.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the type ID and data value are equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof BaseBlock)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final BaseBlock otherBlock = (BaseBlock) o;
|
||||
|
||||
return this.toImmutableState().equals(otherBlock.toImmutableState()) && Objects.equals(getNbtData(), otherBlock.getNbtData());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the type is the same, and if the matched states are the same.
|
||||
*
|
||||
* @param o other block
|
||||
* @return true if equal
|
||||
*/
|
||||
@Override
|
||||
public boolean equalsFuzzy(BlockStateHolder o) {
|
||||
return this.toImmutableState().equalsFuzzy(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState toImmutableState() {
|
||||
return this.blockState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock toBaseBlock() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock toBaseBlock(CompoundTag compoundTag) {
|
||||
if (compoundTag == null) {
|
||||
return this.blockState.toBaseBlock();
|
||||
} else if (compoundTag == this.nbtData) {
|
||||
return this;
|
||||
} else {
|
||||
return new BaseBlock(this.blockState, compoundTag);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int ret = toImmutableState().hashCode() << 3;
|
||||
if (hasNbtData()) {
|
||||
ret += getNbtData().hashCode();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
// if (getNbtData() != null) { // TODO Maybe make some JSON serialiser to make this not awful.
|
||||
// return blockState.getAsString() + " {" + String.valueOf(getNbtData()) + "}";
|
||||
// } else {
|
||||
return blockState.getAsString();
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
@ -19,24 +19,25 @@
|
||||
|
||||
package com.sk89q.worldedit.world.block;
|
||||
|
||||
import com.google.common.collect.ArrayTable;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.boydti.fawe.object.string.MutableCharSequence;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Table;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.SingleBlockStateMask;
|
||||
import com.sk89q.worldedit.function.pattern.FawePattern;
|
||||
import com.sk89q.worldedit.registry.state.AbstractProperty;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.*;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* An immutable class that represents the state a block can be in.
|
||||
@ -44,130 +45,252 @@ import java.util.Set;
|
||||
@SuppressWarnings("unchecked")
|
||||
public class BlockState implements BlockStateHolder<BlockState> {
|
||||
|
||||
private final BlockType blockType;
|
||||
private final Map<Property<?>, Object> values;
|
||||
private final boolean fuzzy;
|
||||
private final int internalId;
|
||||
|
||||
private BaseBlock emptyBaseBlock;
|
||||
|
||||
// Neighbouring state table.
|
||||
private Table<Property<?>, Object, BlockState> states;
|
||||
|
||||
private BlockState(BlockType blockType) {
|
||||
this.blockType = blockType;
|
||||
this.values = new LinkedHashMap<>();
|
||||
this.emptyBaseBlock = new BaseBlock(this);
|
||||
this.fuzzy = false;
|
||||
// TODO FIXME have field for BlockType & propertyId (to avoid all the bit shifting / masking)
|
||||
protected BlockState(int internalId) {
|
||||
this.internalId = internalId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a fuzzy BlockState. This can be used for partial matching.
|
||||
*
|
||||
* @param blockType The block type
|
||||
* @param values The block state values
|
||||
* Returns a temporary BlockState for a given internal id
|
||||
* @param combinedId
|
||||
* @deprecated magic number
|
||||
* @return BlockState
|
||||
*/
|
||||
private BlockState(BlockType blockType, Map<Property<?>, Object> values) {
|
||||
this.blockType = blockType;
|
||||
this.values = values;
|
||||
this.fuzzy = true;
|
||||
@Deprecated
|
||||
public static BlockState get(int combinedId) {
|
||||
return BlockTypes.getFromStateId(combinedId).withStateId(combinedId);
|
||||
}
|
||||
|
||||
static Map<Map<Property<?>, Object>, BlockState> generateStateMap(BlockType blockType) {
|
||||
Map<Map<Property<?>, Object>, BlockState> stateMap = new LinkedHashMap<>();
|
||||
List<? extends Property> properties = blockType.getProperties();
|
||||
/**
|
||||
* Returns a temporary BlockState for a given type and string
|
||||
* @param state String e.g. minecraft:water[level=4]
|
||||
* @return BlockState
|
||||
*/
|
||||
public static BlockState get(String state) {
|
||||
return get(null, state);
|
||||
}
|
||||
|
||||
if (!properties.isEmpty()) {
|
||||
List<List<Object>> separatedValues = Lists.newArrayList();
|
||||
for (Property prop : properties) {
|
||||
List<Object> vals = Lists.newArrayList();
|
||||
vals.addAll(prop.getValues());
|
||||
separatedValues.add(vals);
|
||||
/**
|
||||
* Returns a temporary BlockState for a given type and string
|
||||
* - It's faster if a BlockType is provided compared to parsing the string
|
||||
* @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) {
|
||||
return get(type, state, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a temporary BlockState for a given type and string
|
||||
* - It's faster if a BlockType is provided compared to parsing the string
|
||||
* @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, int propId) {
|
||||
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;
|
||||
}
|
||||
List<List<Object>> valueLists = Lists.cartesianProduct(separatedValues);
|
||||
for (List<Object> valueList : valueLists) {
|
||||
Map<Property<?>, Object> valueMap = Maps.newTreeMap(Comparator.comparing(Property::getName));
|
||||
BlockState stateMaker = new BlockState(blockType);
|
||||
for (int i = 0; i < valueList.size(); i++) {
|
||||
Property<?> property = properties.get(i);
|
||||
Object value = valueList.get(i);
|
||||
valueMap.put(property, value);
|
||||
stateMaker.setState(property, value);
|
||||
type = BlockTypes.get(key);
|
||||
}
|
||||
if (propStrStart == -1) {
|
||||
return type.getDefaultState();
|
||||
}
|
||||
|
||||
List<? extends Property> propList = type.getProperties();
|
||||
|
||||
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);
|
||||
|
||||
return type.withPropertyId(property.getIndexFor(charSequence));
|
||||
}
|
||||
|
||||
int stateId = type.getInternalId() + (propId << BlockTypes.BIT_OFFSET);
|
||||
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);
|
||||
int index = property.getIndexFor(charSequence);
|
||||
stateId = property.modifyIndex(stateId, index);
|
||||
last = i + 1;
|
||||
break;
|
||||
}
|
||||
stateMap.put(valueMap, stateMaker);
|
||||
case '=': {
|
||||
charSequence.setSubstring(last, i);
|
||||
property = (AbstractProperty) type.getPropertyMap().get(charSequence);
|
||||
last = i + 1;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (stateMap.isEmpty()) {
|
||||
// No properties.
|
||||
stateMap.put(new LinkedHashMap<>(), new BlockState(blockType));
|
||||
}
|
||||
|
||||
for (BlockState state : stateMap.values()) {
|
||||
state.populate(stateMap);
|
||||
}
|
||||
|
||||
return stateMap;
|
||||
}
|
||||
|
||||
private void populate(Map<Map<Property<?>, Object>, BlockState> stateMap) {
|
||||
final Table<Property<?>, Object, BlockState> states = HashBasedTable.create();
|
||||
|
||||
for(final Map.Entry<Property<?>, Object> entry : this.values.entrySet()) {
|
||||
final Property property = entry.getKey();
|
||||
|
||||
property.getValues().forEach(value -> {
|
||||
if(value != entry.getValue()) {
|
||||
BlockState modifiedState = stateMap.get(this.withValue(property, value));
|
||||
if (modifiedState != null) {
|
||||
states.put(property, value, modifiedState);
|
||||
} else {
|
||||
System.out.println(stateMap);
|
||||
WorldEdit.logger.warning("Found a null state at " + this.withValue(property, value));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.states = states.isEmpty() ? states : ArrayTable.create(states);
|
||||
}
|
||||
|
||||
private <V> Map<Property<?>, Object> withValue(final Property<V> property, final V value) {
|
||||
final Map<Property<?>, Object> values = Maps.newHashMap(this.values);
|
||||
values.put(property, value);
|
||||
return values;
|
||||
return type.withPropertyId(stateId >> BlockTypes.BIT_OFFSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockType getBlockType() {
|
||||
return this.blockType;
|
||||
public BlockState withPropertyId(int propertyId) {
|
||||
return getBlockType().withPropertyId(propertyId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mask toMask(Extent extent) {
|
||||
return new SingleBlockStateMask(extent, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Extent extent, Vector get, Vector set) throws WorldEditException {
|
||||
return extent.setBlock(set, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState apply(Vector position) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getInternalId() {
|
||||
return this.internalId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNbtData() {
|
||||
return getNbtData() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNbtId() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public CompoundTag getNbtData() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNbtData(@Nullable CompoundTag nbtData) {
|
||||
throw new UnsupportedOperationException("This class is immutable.");
|
||||
}
|
||||
|
||||
/**
|
||||
* The internal id with no type information
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
@Override
|
||||
public final int getInternalPropertiesId() {
|
||||
return this.getInternalId() >> BlockTypes.BIT_OFFSET;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final BlockTypes getBlockType() {
|
||||
return BlockTypes.get(this.getInternalId() & BlockTypes.BIT_MASK);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public final int getInternalBlockTypeId() {
|
||||
return this.getInternalId() & BlockTypes.BIT_MASK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> BlockState with(final Property<V> property, final V value) {
|
||||
if (fuzzy) {
|
||||
return setState(property, value);
|
||||
} else {
|
||||
BlockState result = states.get(property, value);
|
||||
return result == null ? this : result;
|
||||
try {
|
||||
int newState = ((AbstractProperty) property).modify(this.getInternalId(), value);
|
||||
return newState != this.getInternalId() ? new BlockState(newState) : this;
|
||||
} catch (ClassCastException e) {
|
||||
throw new IllegalArgumentException("Property not found: " + property);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> V getState(final Property<V> property) {
|
||||
return (V) this.values.get(property);
|
||||
public <V> BlockState with(final PropertyKey property, final V value) {
|
||||
try {
|
||||
int newState = ((AbstractProperty) getBlockType().getProperty(property)).modify(this.getInternalId(), value);
|
||||
return newState != this.getInternalId() ? new BlockState(newState) : this;
|
||||
} catch (ClassCastException e) {
|
||||
throw new IllegalArgumentException("Property not found: " + property);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<Property<?>, Object> getStates() {
|
||||
return Collections.unmodifiableMap(this.values);
|
||||
public final <V> V getState(final Property<V> property) {
|
||||
try {
|
||||
AbstractProperty ap = (AbstractProperty) property;
|
||||
return (V) ap.getValue(this.getInternalId());
|
||||
} catch (ClassCastException e) {
|
||||
throw new IllegalArgumentException("Property not found: " + property);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public final <V> V getState(final PropertyKey key) {
|
||||
return getState(getBlockType().getProperty(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public final Map<Property<?>, Object> getStates() {
|
||||
BlockType type = this.getBlockType();
|
||||
// Lazily initialize the map
|
||||
Map<? extends Property, Object> map = Maps.asMap(type.getPropertiesSet(), (Function<Property, Object>) input -> getState(input));
|
||||
return (Map<Property<?>, Object>) map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated, use masks - not try to this fuzzy/non fuzzy state nonsense
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public BlockState toFuzzy() {
|
||||
return new BlockState(this.getBlockType(), new HashMap<>());
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getInternalId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this == obj;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean equalsFuzzy(BlockStateHolder o) {
|
||||
try {
|
||||
return o.getInternalId() == this.getInternalId();
|
||||
} catch (ClassCastException e) {
|
||||
// Shouldn't happen unless something modifies WorldEdit
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!getBlockType().equals(o.getBlockType())) {
|
||||
return false;
|
||||
}
|
||||
@ -201,38 +324,37 @@ public class BlockState implements BlockStateHolder<BlockState> {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock toBaseBlock() {
|
||||
if (this.fuzzy) {
|
||||
throw new IllegalArgumentException("Can't create a BaseBlock from a fuzzy BlockState!");
|
||||
}
|
||||
return this.emptyBaseBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseBlock toBaseBlock(CompoundTag compoundTag) {
|
||||
if (compoundTag == null) {
|
||||
return toBaseBlock();
|
||||
}
|
||||
return new BaseBlock(this, compoundTag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method used for creating the initial BlockState.
|
||||
*
|
||||
* Sets a value. DO NOT USE THIS.
|
||||
*
|
||||
* @param property The state
|
||||
* @param value The value
|
||||
* @return The blockstate, for chaining
|
||||
*/
|
||||
private BlockState setState(final Property<?> property, final Object value) {
|
||||
this.values.put(property, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getAsString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -19,23 +19,58 @@
|
||||
|
||||
package com.sk89q.worldedit.world.block;
|
||||
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.blocks.TileEntityBlock;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.pattern.FawePattern;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public interface BlockStateHolder<T extends BlockStateHolder> {
|
||||
public interface BlockStateHolder<T extends BlockStateHolder> extends FawePattern, TileEntityBlock {
|
||||
|
||||
/**
|
||||
* Get the block type
|
||||
*
|
||||
* @return The type
|
||||
*/
|
||||
BlockType getBlockType();
|
||||
BlockTypes getBlockType();
|
||||
|
||||
/**
|
||||
* Returns a BlockState with the given state and value applied.
|
||||
* Magic number (legacy uses)
|
||||
* @param propertyId
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
BlockStateHolder withPropertyId(int propertyId);
|
||||
|
||||
/**
|
||||
* Get combined id (legacy uses)
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
int getInternalId();
|
||||
|
||||
/**
|
||||
* Get type id (legacy uses)
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
int getInternalBlockTypeId();
|
||||
|
||||
/**
|
||||
* Get the block data (legacy uses)
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
int getInternalPropertiesId();
|
||||
|
||||
Mask toMask(Extent extent);
|
||||
|
||||
/**
|
||||
* Returns a BlockStateHolder with the given state and value applied.
|
||||
*
|
||||
* @param property The state
|
||||
* @param value The value
|
||||
@ -43,6 +78,15 @@ public interface BlockStateHolder<T extends BlockStateHolder> {
|
||||
*/
|
||||
<V> T with(final Property<V> property, final V value);
|
||||
|
||||
/**
|
||||
* Returns a BlockStateHolder with the given state and value applied.
|
||||
*
|
||||
* @param property The property key
|
||||
* @param value The value
|
||||
* @return The modified state, or same if could not be applied
|
||||
*/
|
||||
<V> BlockStateHolder with(final PropertyKey property, final V value);
|
||||
|
||||
/**
|
||||
* Gets the value at the given state
|
||||
*
|
||||
@ -51,6 +95,14 @@ public interface BlockStateHolder<T extends BlockStateHolder> {
|
||||
*/
|
||||
<V> V getState(Property<V> property);
|
||||
|
||||
/**
|
||||
* Gets the value at the given state
|
||||
*
|
||||
* @param property The state
|
||||
* @return The value
|
||||
*/
|
||||
<V> V getState(final PropertyKey property);
|
||||
|
||||
/**
|
||||
* Gets an immutable collection of the states.
|
||||
*
|
||||
@ -59,35 +111,20 @@ public interface BlockStateHolder<T extends BlockStateHolder> {
|
||||
Map<Property<?>, Object> getStates();
|
||||
|
||||
/**
|
||||
* Checks if the type is the same, and if the matched states are the same.
|
||||
*
|
||||
* @deprecated use masks - not try to this fuzzy/non fuzzy state nonsense
|
||||
* @param o other block
|
||||
* @return true if equal
|
||||
*/
|
||||
@Deprecated
|
||||
boolean equalsFuzzy(BlockStateHolder o);
|
||||
|
||||
/**
|
||||
* Returns an immutable {@link BlockState} from this BlockStateHolder.
|
||||
* Returns an immutable BlockStateHolder from this BlockStateHolder.
|
||||
*
|
||||
* @return A BlockState
|
||||
*/
|
||||
BlockState toImmutableState();
|
||||
|
||||
/**
|
||||
* Gets a {@link BaseBlock} from this BlockStateHolder.
|
||||
*
|
||||
* @return The BaseBlock
|
||||
*/
|
||||
BaseBlock toBaseBlock();
|
||||
|
||||
/**
|
||||
* Gets a {@link BaseBlock} from this BlockStateHolder.
|
||||
*
|
||||
* @param compoundTag The NBT Data to apply
|
||||
* @return The BaseBlock
|
||||
*/
|
||||
BaseBlock toBaseBlock(CompoundTag compoundTag);
|
||||
|
||||
default String getAsString() {
|
||||
if (getStates().isEmpty()) {
|
||||
return this.getBlockType().getId();
|
||||
|
@ -0,0 +1,5 @@
|
||||
package com.sk89q.worldedit.world.block;
|
||||
|
||||
public class BlockStateRegistry {
|
||||
|
||||
}
|
@ -19,48 +19,45 @@
|
||||
|
||||
package com.sk89q.worldedit.world.block;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||
import com.sk89q.worldedit.extension.platform.Capability;
|
||||
import com.sk89q.worldedit.registry.NamespacedRegistry;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.mask.Mask;
|
||||
import com.sk89q.worldedit.function.mask.SingleBlockTypeMask;
|
||||
import com.sk89q.worldedit.function.pattern.FawePattern;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
public interface BlockType extends FawePattern, Comparable<BlockTypes> {
|
||||
|
||||
public class BlockType {
|
||||
|
||||
public static final NamespacedRegistry<BlockType> REGISTRY = new NamespacedRegistry<>("block type");
|
||||
|
||||
private String id;
|
||||
private BlockState defaultState;
|
||||
private Map<String, ? extends Property> properties;
|
||||
private BlockMaterial blockMaterial;
|
||||
|
||||
public BlockType(String id) {
|
||||
this(id, null);
|
||||
default BlockTypes getTypeEnum() {
|
||||
return (BlockTypes) this;
|
||||
}
|
||||
|
||||
public BlockType(String id, Function<BlockState, BlockState> values) {
|
||||
// If it has no namespace, assume minecraft.
|
||||
if (!id.contains(":")) {
|
||||
id = "minecraft:" + id;
|
||||
}
|
||||
this.id = id;
|
||||
this.defaultState = new ArrayList<>(BlockState.generateStateMap(this).values()).get(0);
|
||||
if (values != null) {
|
||||
this.defaultState = values.apply(this.defaultState);
|
||||
}
|
||||
@Deprecated
|
||||
int getMaxStateId();
|
||||
|
||||
@Override
|
||||
default boolean apply(Extent extent, Vector get, Vector set) throws WorldEditException {
|
||||
return extent.setBlock(set, this.getDefaultState());
|
||||
}
|
||||
|
||||
@Override
|
||||
default BlockStateHolder apply(Vector position) {
|
||||
return this.getDefaultState();
|
||||
}
|
||||
|
||||
default Mask toMask(Extent extent) {
|
||||
return new SingleBlockTypeMask(extent, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,17 +65,15 @@ public class BlockType {
|
||||
*
|
||||
* @return The id
|
||||
*/
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Gets the name of this block, or the ID if the name cannot be found.
|
||||
*
|
||||
* @return The name, or ID
|
||||
*/
|
||||
public String getName() {
|
||||
BundledBlockData.BlockEntry entry = BundledBlockData.getInstance().findById(this.id);
|
||||
default String getName() {
|
||||
BundledBlockData.BlockEntry entry = BundledBlockData.getInstance().findById(this.getId());
|
||||
if (entry == null) {
|
||||
return getId();
|
||||
} else {
|
||||
@ -86,27 +81,30 @@ public class BlockType {
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
default BlockState withPropertyId(int internalPropertiesId) {
|
||||
if (internalPropertiesId == 0) return getDefaultState();
|
||||
return BlockState.get(getInternalId() + (internalPropertiesId << BlockTypes.BIT_OFFSET));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the properties of this BlockType in a key->property mapping.
|
||||
*
|
||||
* @return The properties map
|
||||
*/
|
||||
public Map<String, ? extends Property> getPropertyMap() {
|
||||
if (properties == null) {
|
||||
properties = ImmutableMap.copyOf(WorldEdit.getInstance().getPlatformManager()
|
||||
.queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getProperties(this));
|
||||
}
|
||||
return this.properties;
|
||||
}
|
||||
@Deprecated
|
||||
Map<String, ? extends Property> getPropertyMap();
|
||||
|
||||
/**
|
||||
* Gets the properties of this BlockType.
|
||||
*
|
||||
* @return the properties
|
||||
*/
|
||||
public List<? extends Property> getProperties() {
|
||||
return ImmutableList.copyOf(this.getPropertyMap().values());
|
||||
}
|
||||
@Deprecated
|
||||
List<? extends Property> getProperties();
|
||||
|
||||
@Deprecated
|
||||
Set<? extends Property> getPropertiesSet();
|
||||
|
||||
/**
|
||||
* Gets a property by name.
|
||||
@ -114,25 +112,26 @@ public class BlockType {
|
||||
* @param name The name
|
||||
* @return The property
|
||||
*/
|
||||
public <V> Property<V> getProperty(String name) {
|
||||
return getPropertyMap().get(name);
|
||||
}
|
||||
@Deprecated
|
||||
<V> Property<V> getProperty(String name);
|
||||
|
||||
boolean hasProperty(PropertyKey key);
|
||||
|
||||
<V> Property<V> getProperty(PropertyKey key);
|
||||
|
||||
/**
|
||||
* Gets the default state of this block type.
|
||||
*
|
||||
* @return The default state
|
||||
*/
|
||||
public BlockState getDefaultState() {
|
||||
return this.defaultState;
|
||||
}
|
||||
BlockState getDefaultState();
|
||||
|
||||
/**
|
||||
* Gets whether this block type has an item representation.
|
||||
*
|
||||
* @return If it has an item
|
||||
*/
|
||||
public boolean hasItemType() {
|
||||
default boolean hasItemType() {
|
||||
return getItemType() != null;
|
||||
}
|
||||
|
||||
@ -142,46 +141,32 @@ public class BlockType {
|
||||
* @return The item representation
|
||||
*/
|
||||
@Nullable
|
||||
public ItemType getItemType() {
|
||||
return ItemTypes.get(this.id);
|
||||
}
|
||||
ItemType getItemType();
|
||||
|
||||
/**
|
||||
* Get the material for this BlockType.
|
||||
*
|
||||
* @return The material
|
||||
*/
|
||||
public BlockMaterial getMaterial() {
|
||||
if (this.blockMaterial == null) {
|
||||
this.blockMaterial = WorldEdit.getInstance().getPlatformManager().queryCapability(Capability.GAME_HOOKS).getRegistries().getBlockRegistry().getMaterial(this);
|
||||
}
|
||||
return this.blockMaterial;
|
||||
BlockMaterial getMaterial();
|
||||
|
||||
default int getLegacyCombinedId() {
|
||||
Integer combinedId = LegacyMapper.getInstance().getLegacyFromBlock(this);
|
||||
return combinedId == null ? 0 : combinedId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the legacy ID. Needed for legacy reasons.
|
||||
* The internal index of this type.
|
||||
*
|
||||
* DO NOT USE THIS.
|
||||
* This number is not necessarily consistent across restarts.
|
||||
*
|
||||
* @return legacy id or 0, if unknown
|
||||
* @return internal id
|
||||
*/
|
||||
@Deprecated
|
||||
public int getLegacyId() {
|
||||
int[] id = LegacyMapper.getInstance().getLegacyFromBlock(this.getDefaultState());
|
||||
if (id != null) {
|
||||
return id[0];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int getInternalId();
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.id.hashCode();
|
||||
}
|
||||
boolean equals(Object obj);
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof BlockType && this.id.equals(((BlockType) obj).id);
|
||||
}
|
||||
int hashCode();
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
package com.sk89q.worldedit.world.block;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class BlockTypeSwitch<T> implements Function<BlockType, T> {
|
||||
private final T[] tasks;
|
||||
protected BlockTypeSwitch(T[] tasks) {
|
||||
this.tasks = tasks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T apply(BlockType blockType) {
|
||||
return this.tasks[blockType.getInternalId()];
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package com.sk89q.worldedit.world.block;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class BlockTypeSwitchBuilder<T> {
|
||||
private final Object[] runnables;
|
||||
private T defaultTask;
|
||||
|
||||
public BlockTypeSwitchBuilder(T defaultTask) {
|
||||
this.runnables = new Object[BlockTypes.size()];
|
||||
this.defaultTask = defaultTask;
|
||||
}
|
||||
|
||||
public BlockTypeSwitchBuilder<T> add(BlockType type, T task) {
|
||||
this.runnables[type.getInternalId()] = task;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockTypeSwitchBuilder<T> add(Predicate<BlockType> predicate, T task) {
|
||||
for (BlockTypes type : BlockTypes.values) {
|
||||
if (predicate.test(type)) {
|
||||
this.runnables[type.getInternalId()] = task;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockTypeSwitchBuilder<T> setDefaultTask(T defaultTask) {
|
||||
this.defaultTask = defaultTask;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlockTypeSwitch<T> build() {
|
||||
for (int i = 0; i < runnables.length; i++) {
|
||||
if (runnables[i] == null) runnables[i] = defaultTask;
|
||||
}
|
||||
return new BlockTypeSwitch(runnables);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -28,10 +28,12 @@ import com.sk89q.jnbt.NBTUtils;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.DataException;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import com.sk89q.worldedit.world.storage.InvalidFormatException;
|
||||
|
||||
@ -262,7 +264,7 @@ public class AnvilChunk implements Chunk {
|
||||
BlockState state = LegacyMapper.getInstance().getBlockFromLegacy(id, data);
|
||||
CompoundTag tileEntity = getBlockTileEntity(position);
|
||||
|
||||
return state.toBaseBlock(tileEntity);
|
||||
return new BaseBlock(state, tileEntity);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,7 +20,8 @@
|
||||
package com.sk89q.worldedit.world.chunk;
|
||||
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.DataException;
|
||||
|
||||
/**
|
||||
|
@ -27,11 +27,13 @@ import com.sk89q.jnbt.NBTUtils;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.DataException;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
import com.sk89q.worldedit.world.storage.InvalidFormatException;
|
||||
|
||||
@ -154,7 +156,7 @@ public class OldChunk implements Chunk {
|
||||
|
||||
@Override
|
||||
public BaseBlock getBlock(Vector position) throws DataException {
|
||||
if(position.getBlockY() >= 128) BlockTypes.AIR.getDefaultState().toBaseBlock();
|
||||
if(position.getBlockY() >= 128) new BaseBlock(BlockTypes.AIR);
|
||||
int id, dataVal;
|
||||
|
||||
int x = position.getBlockX() - rootX * 16;
|
||||
@ -183,7 +185,7 @@ public class OldChunk implements Chunk {
|
||||
BlockState state = LegacyMapper.getInstance().getBlockFromLegacy(id, dataVal);
|
||||
CompoundTag tileEntity = getBlockTileEntity(position);
|
||||
|
||||
return state.toBaseBlock(tileEntity);
|
||||
return new BaseBlock(state, tileEntity);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,44 +19,29 @@
|
||||
|
||||
package com.sk89q.worldedit.world.item;
|
||||
|
||||
import com.sk89q.worldedit.registry.NamespacedRegistry;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.registry.BundledItemData;
|
||||
import com.sk89q.worldedit.world.registry.LegacyMapper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class ItemType {
|
||||
public interface ItemType {
|
||||
|
||||
public static final NamespacedRegistry<ItemType> REGISTRY = new NamespacedRegistry<>("item type");
|
||||
|
||||
private String id;
|
||||
|
||||
public ItemType(String id) {
|
||||
// If it has no namespace, assume minecraft.
|
||||
if (!id.contains(":")) {
|
||||
id = "minecraft:" + id;
|
||||
}
|
||||
this.id = id;
|
||||
default ItemTypes toEnum() {
|
||||
return (ItemTypes) this;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
String getId();
|
||||
|
||||
int getInternalId();
|
||||
|
||||
/**
|
||||
* Gets the name of this item, or the ID if the name cannot be found.
|
||||
*
|
||||
* @return The name, or ID
|
||||
*/
|
||||
public String getName() {
|
||||
BundledItemData.ItemEntry entry = BundledItemData.getInstance().findById(this.id);
|
||||
if (entry == null) {
|
||||
return getId();
|
||||
} else {
|
||||
return entry.localizedName;
|
||||
}
|
||||
}
|
||||
String getName();
|
||||
|
||||
|
||||
/**
|
||||
@ -64,7 +49,7 @@ public class ItemType {
|
||||
*
|
||||
* @return If it has a block
|
||||
*/
|
||||
public boolean hasBlockType() {
|
||||
default boolean hasBlockType() {
|
||||
return getBlockType() != null;
|
||||
}
|
||||
|
||||
@ -74,17 +59,11 @@ public class ItemType {
|
||||
* @return The block representation
|
||||
*/
|
||||
@Nullable
|
||||
public BlockType getBlockType() {
|
||||
return BlockTypes.get(this.id);
|
||||
default BlockType getBlockType() {
|
||||
return BlockTypes.get(getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof ItemType && this.id.equals(((ItemType) obj).id);
|
||||
default BaseItem getDefaultState() {
|
||||
return new BaseItem(this);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,9 +22,8 @@ package com.sk89q.worldedit.world.registry;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.biome.BiomeData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides information on biomes.
|
||||
|
@ -1,154 +0,0 @@
|
||||
/*
|
||||
* 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 Lesser 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 Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit.world.registry;
|
||||
|
||||
/**
|
||||
* Describes the material for a block.
|
||||
*/
|
||||
public interface BlockMaterial {
|
||||
|
||||
/**
|
||||
* Get whether this block is a full sized cube.
|
||||
*
|
||||
* @return the value of the test
|
||||
*/
|
||||
boolean isFullCube();
|
||||
|
||||
/**
|
||||
* Get whether this block is opaque.
|
||||
*
|
||||
* @return the value of the test
|
||||
*/
|
||||
boolean isOpaque();
|
||||
|
||||
/**
|
||||
* Get whether this block emits a Redstone signal.
|
||||
*
|
||||
* @return the value of the test
|
||||
*/
|
||||
boolean isPowerSource();
|
||||
|
||||
/**
|
||||
* Get whether this block is a liquid.
|
||||
*
|
||||
* @return the value of the test
|
||||
*/
|
||||
boolean isLiquid();
|
||||
|
||||
/**
|
||||
* Get whether this block is a solid.
|
||||
*
|
||||
* @return the value of the test
|
||||
*/
|
||||
boolean isSolid();
|
||||
|
||||
/**
|
||||
* Get the hardness factor for this block.
|
||||
*
|
||||
* @return the hardness factor
|
||||
*/
|
||||
float getHardness();
|
||||
|
||||
/**
|
||||
* Get the resistance factor for this block.
|
||||
*
|
||||
* @return the resistance factor
|
||||
*/
|
||||
float getResistance();
|
||||
|
||||
/**
|
||||
* Get the slipperiness factor for this block.
|
||||
*
|
||||
* @return the slipperiness factor
|
||||
*/
|
||||
float getSlipperiness();
|
||||
|
||||
/**
|
||||
* Get the light value for this block.
|
||||
*
|
||||
* @return the light value
|
||||
*/
|
||||
int getLightValue();
|
||||
|
||||
/**
|
||||
* Get whether this block breaks when it is pushed by a piston.
|
||||
*
|
||||
* @return true if the block breaks
|
||||
*/
|
||||
boolean isFragileWhenPushed();
|
||||
|
||||
/**
|
||||
* Get whether this block can be pushed by a piston.
|
||||
*
|
||||
* @return true if the block cannot be pushed
|
||||
*/
|
||||
boolean isUnpushable();
|
||||
|
||||
/**
|
||||
* Get whether this block is ticked randomly.
|
||||
*
|
||||
* @return true if this block is ticked randomly
|
||||
*/
|
||||
boolean isTicksRandomly();
|
||||
|
||||
/**
|
||||
* Get whether this block prevents movement.
|
||||
*
|
||||
* @return true if this block blocks movement
|
||||
*/
|
||||
boolean isMovementBlocker();
|
||||
|
||||
/**
|
||||
* Get whether this block will burn.
|
||||
*
|
||||
* @return true if this block will burn
|
||||
*/
|
||||
boolean isBurnable();
|
||||
|
||||
/**
|
||||
* Get whether this block needs to be broken by a tool for maximum
|
||||
* speed.
|
||||
*
|
||||
* @return true if a tool is required
|
||||
*/
|
||||
boolean isToolRequired();
|
||||
|
||||
/**
|
||||
* Get whether this block is replaced when a block is placed over it
|
||||
* (for example, tall grass).
|
||||
*
|
||||
* @return true if the block is replaced
|
||||
*/
|
||||
boolean isReplacedDuringPlacement();
|
||||
|
||||
/**
|
||||
* Get whether this block is translucent.
|
||||
*
|
||||
* @return true if the block is translucent
|
||||
*/
|
||||
boolean isTranslucent();
|
||||
|
||||
/**
|
||||
* Gets whether the block has a container (Item container)
|
||||
*
|
||||
* @return If it has a container
|
||||
*/
|
||||
boolean hasContainer();
|
||||
}
|
@ -19,9 +19,13 @@
|
||||
|
||||
package com.sk89q.worldedit.world.registry;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@ -48,4 +52,11 @@ public interface BlockRegistry {
|
||||
*/
|
||||
Map<String, ? extends Property> getProperties(BlockType blockType);
|
||||
|
||||
|
||||
/**
|
||||
* Register all blocks
|
||||
*/
|
||||
default Collection<String> registerBlocks() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||
import com.sk89q.worldedit.util.gson.VectorAdapter;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -136,4 +137,4 @@ public class BundledBlockData {
|
||||
private SimpleBlockMaterial material = new SimpleBlockMaterial();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.world.registry;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
|
||||
@ -45,4 +46,4 @@ public class BundledBlockRegistry implements BlockRegistry {
|
||||
return Collections.emptyMap(); // Oof
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -24,6 +24,8 @@ import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* A item registry that uses {@link BundledItemRegistry} to serve information
|
||||
@ -37,4 +39,9 @@ public class BundledItemRegistry implements ItemRegistry {
|
||||
ItemType itemType = ItemTypes.get(id);
|
||||
return itemType == null ? null : new BaseItem(itemType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> registerItems() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ package com.sk89q.worldedit.world.registry;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
public interface ItemRegistry {
|
||||
|
||||
@ -34,4 +36,11 @@ public interface ItemRegistry {
|
||||
@Nullable
|
||||
BaseItem createFromId(String id);
|
||||
|
||||
/**
|
||||
* Register all items
|
||||
*/
|
||||
default Collection<String> registerItems() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,24 +19,27 @@
|
||||
|
||||
package com.sk89q.worldedit.world.registry;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.io.Resources;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.util.gson.VectorAdapter;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import com.sk89q.worldedit.world.item.ItemType;
|
||||
import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||
import com.sk89q.worldedit.util.gson.VectorAdapter;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@ -48,10 +51,10 @@ public class LegacyMapper {
|
||||
private static final Logger log = Logger.getLogger(LegacyMapper.class.getCanonicalName());
|
||||
private static LegacyMapper INSTANCE;
|
||||
|
||||
private Multimap<String, BlockState> stringToBlockMap = HashMultimap.create();
|
||||
private Multimap<BlockState, String> blockToStringMap = HashMultimap.create();
|
||||
private Multimap<String, ItemType> stringToItemMap = HashMultimap.create();
|
||||
private Multimap<ItemType, String> itemToStringMap = HashMultimap.create();
|
||||
private final Int2ObjectArrayMap<Integer> blockStateToLegacyId4Data = new Int2ObjectArrayMap<>();
|
||||
private final Int2ObjectArrayMap<Integer> extraId4DataToStateId = new Int2ObjectArrayMap<>();
|
||||
private final int[] blockArr = new int[4096];
|
||||
private final BiMap<Integer, ItemTypes> itemMap = HashBiMap.create();
|
||||
|
||||
/**
|
||||
* Create a new instance.
|
||||
@ -60,6 +63,7 @@ public class LegacyMapper {
|
||||
try {
|
||||
loadFromResource();
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
log.log(Level.WARNING, "Failed to load the built-in legacy id registry", e);
|
||||
}
|
||||
}
|
||||
@ -77,8 +81,8 @@ public class LegacyMapper {
|
||||
if (url == null) {
|
||||
throw new IOException("Could not find legacy.json");
|
||||
}
|
||||
String data = Resources.toString(url, Charset.defaultCharset());
|
||||
LegacyDataFile dataFile = gson.fromJson(data, new TypeToken<LegacyDataFile>() {}.getType());
|
||||
String source = Resources.toString(url, Charset.defaultCharset());
|
||||
LegacyDataFile dataFile = gson.fromJson(source, new TypeToken<LegacyDataFile>() {}.getType());
|
||||
|
||||
ParserContext parserContext = new ParserContext();
|
||||
parserContext.setPreferringWildcard(false);
|
||||
@ -87,65 +91,114 @@ public class LegacyMapper {
|
||||
|
||||
for (Map.Entry<String, String> blockEntry : dataFile.blocks.entrySet()) {
|
||||
try {
|
||||
String id = blockEntry.getKey();
|
||||
BlockState state = WorldEdit.getInstance().getBlockFactory().parseFromInput(blockEntry.getValue(), parserContext).toImmutableState();
|
||||
blockToStringMap.put(state, id);
|
||||
stringToBlockMap.put(id, state);
|
||||
BlockStateHolder blockState = BlockState.get(null, blockEntry.getValue());
|
||||
BlockTypes type = blockState.getBlockType();
|
||||
if (type.hasProperty(PropertyKey.WATERLOGGED)) {
|
||||
blockState = blockState.with(PropertyKey.WATERLOGGED, false);
|
||||
}
|
||||
int combinedId = getCombinedId(blockEntry.getKey());
|
||||
blockArr[combinedId] = blockState.getInternalId();
|
||||
|
||||
blockStateToLegacyId4Data.put(blockState.getInternalId(), (Integer) combinedId);
|
||||
blockStateToLegacyId4Data.putIfAbsent(blockState.getInternalBlockTypeId(), combinedId);
|
||||
} catch (Exception e) {
|
||||
log.warning("Unknown block: " + blockEntry.getValue());
|
||||
log.fine("Unknown block: " + blockEntry.getValue());
|
||||
}
|
||||
}
|
||||
for (int id = 0; id < 256; id++) {
|
||||
int combinedId = id << 4;
|
||||
int base = blockArr[combinedId];
|
||||
if (base != 0) {
|
||||
for (int data = 0; data < 16; data++, combinedId++) {
|
||||
if (blockArr[combinedId] == 0) blockArr[combinedId] = base;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> itemEntry : dataFile.items.entrySet()) {
|
||||
try {
|
||||
String id = itemEntry.getKey();
|
||||
ItemType type = ItemTypes.get(itemEntry.getValue());
|
||||
itemToStringMap.put(type, id);
|
||||
stringToItemMap.put(id, type);
|
||||
itemMap.put(getCombinedId(itemEntry.getKey()), ItemTypes.get(itemEntry.getValue()));
|
||||
} catch (Exception e) {
|
||||
log.warning("Unknown item: " + itemEntry.getValue());
|
||||
log.fine("Unknown item: " + itemEntry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemType getItemFromLegacy(int legacyId) {
|
||||
return getItemFromLegacy(legacyId, 0);
|
||||
private int getCombinedId(String input) {
|
||||
String[] split = input.split(":");
|
||||
return (Integer.parseInt(split[0]) << 4) + (split.length == 2 ? Integer.parseInt(split[1]) : 0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ItemType getItemFromLegacy(int legacyId, int data) {
|
||||
return stringToItemMap.get(legacyId + ":" + data).stream().findFirst().orElse(null);
|
||||
public ItemTypes getItemFromLegacy(int legacyId) {
|
||||
return itemMap.get(legacyId << 4);
|
||||
}
|
||||
|
||||
public ItemTypes getItemFromLegacy(String input) {
|
||||
if (input.startsWith("minecraft:")) input = input.substring(10);
|
||||
return itemMap.get(getCombinedId(input));
|
||||
}
|
||||
|
||||
public BlockState getBlockFromLegacy(String input) {
|
||||
if (input.startsWith("minecraft:")) input = input.substring(10);
|
||||
return BlockState.get(blockArr[getCombinedId(input)]);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public int[] getLegacyFromItem(ItemType itemType) {
|
||||
if (!itemToStringMap.containsKey(itemType)) {
|
||||
return null;
|
||||
} else {
|
||||
String value = itemToStringMap.get(itemType).stream().findFirst().get();
|
||||
return Arrays.stream(value.split(":")).mapToInt(Integer::parseInt).toArray();
|
||||
}
|
||||
public ItemTypes getItemFromLegacy(int legacyId, int data) {
|
||||
return itemMap.get((legacyId << 4) + data);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getLegacyFromItem(ItemType itemType) {
|
||||
return itemMap.inverse().get(itemType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BlockState getBlockFromLegacy(int legacyId) {
|
||||
return getBlockFromLegacy(legacyId, 0);
|
||||
return getBlock(legacyId << 4);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BlockState getBlockFromLegacyCombinedId(int combinedId) {
|
||||
return getBlock(combinedId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public BlockState getBlockFromLegacy(int legacyId, int data) {
|
||||
return stringToBlockMap.get(legacyId + ":" + data).stream().findFirst().orElse(null);
|
||||
return getBlock((legacyId << 4) + data);
|
||||
}
|
||||
|
||||
private BlockState getBlock(int combinedId) {
|
||||
if (combinedId < blockArr.length) {
|
||||
return BlockState.get(blockArr[combinedId]);
|
||||
}
|
||||
Integer extra = extraId4DataToStateId.get(combinedId);
|
||||
if (extra == null) {
|
||||
extra = extraId4DataToStateId.get(combinedId & 0xFF0);
|
||||
}
|
||||
if (extra != null) {
|
||||
return BlockState.get(extra);
|
||||
}
|
||||
return BlockTypes.AIR.getDefaultState();
|
||||
}
|
||||
|
||||
public void register(int id, int data, BlockStateHolder state) {
|
||||
int combinedId = ((id << 4) + data);
|
||||
extraId4DataToStateId.put((int) combinedId, (Integer) state.getInternalId());
|
||||
blockStateToLegacyId4Data.putIfAbsent(state.getInternalId(), combinedId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public int[] getLegacyFromBlock(BlockState blockState) {
|
||||
if (!blockToStringMap.containsKey(blockState)) {
|
||||
return null;
|
||||
} else {
|
||||
String value = blockToStringMap.get(blockState).stream().findFirst().get();
|
||||
return Arrays.stream(value.split(":")).mapToInt(Integer::parseInt).toArray();
|
||||
}
|
||||
public Integer getLegacyFromBlock(BlockState blockState) {
|
||||
Integer result = blockStateToLegacyId4Data.get(blockState.getInternalId());
|
||||
if (result == null) result = blockStateToLegacyId4Data.get(blockState.getInternalBlockTypeId());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getLegacyFromBlock(BlockType type) {
|
||||
return blockStateToLegacyId4Data.get(type.getDefaultState());
|
||||
}
|
||||
|
||||
public static LegacyMapper getInstance() {
|
||||
|
@ -22,11 +22,10 @@ package com.sk89q.worldedit.world.registry;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.biome.BiomeData;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A biome registry that knows nothing.
|
||||
*/
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
package com.sk89q.worldedit.world.registry;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class PassthroughBlockMaterial implements BlockMaterial {
|
||||
@ -29,6 +31,15 @@ public class PassthroughBlockMaterial implements BlockMaterial {
|
||||
this.blockMaterial = material;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAir() {
|
||||
if (blockMaterial == null) {
|
||||
return false;
|
||||
} else {
|
||||
return blockMaterial.isAir();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullCube() {
|
||||
if (blockMaterial == null) {
|
||||
@ -110,6 +121,15 @@ public class PassthroughBlockMaterial implements BlockMaterial {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightOpacity() {
|
||||
if (blockMaterial == null) {
|
||||
return 0;
|
||||
} else {
|
||||
return blockMaterial.getLightOpacity();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFragileWhenPushed() {
|
||||
if (blockMaterial == null) {
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
package com.sk89q.worldedit.world.registry;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||
|
||||
class SimpleBlockMaterial implements BlockMaterial {
|
||||
|
||||
private boolean fullCube;
|
||||
@ -39,6 +41,26 @@ class SimpleBlockMaterial implements BlockMaterial {
|
||||
private boolean replacedDuringPlacement;
|
||||
private boolean isTranslucent;
|
||||
private boolean hasContainer;
|
||||
private int lightOpacity;
|
||||
private boolean isAir;
|
||||
|
||||
@Override
|
||||
public boolean isAir() {
|
||||
return isAir;
|
||||
}
|
||||
|
||||
public void setAir(boolean air) {
|
||||
isAir = air;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightOpacity() {
|
||||
return lightOpacity;
|
||||
}
|
||||
|
||||
public void setLightOpacity(int lightOpacity) {
|
||||
this.lightOpacity = lightOpacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFullCube() {
|
||||
|
@ -22,14 +22,7 @@
|
||||
package com.sk89q.worldedit.world.snapshot;
|
||||
|
||||
import com.sk89q.worldedit.world.DataException;
|
||||
import com.sk89q.worldedit.world.storage.ChunkStore;
|
||||
import com.sk89q.worldedit.world.storage.FileLegacyChunkStore;
|
||||
import com.sk89q.worldedit.world.storage.FileMcRegionChunkStore;
|
||||
import com.sk89q.worldedit.world.storage.TrueZipLegacyChunkStore;
|
||||
import com.sk89q.worldedit.world.storage.TrueZipMcRegionChunkStore;
|
||||
import com.sk89q.worldedit.world.storage.ZippedLegacyChunkStore;
|
||||
import com.sk89q.worldedit.world.storage.ZippedMcRegionChunkStore;
|
||||
|
||||
import com.sk89q.worldedit.world.storage.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
|
@ -19,11 +19,10 @@
|
||||
|
||||
package com.sk89q.worldedit.world.snapshot;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.util.Calendar;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A name parser attempts to make sense of a filename for a snapshot.
|
||||
*/
|
||||
|
@ -23,6 +23,7 @@ package com.sk89q.worldedit.world.snapshot;
|
||||
|
||||
import com.sk89q.worldedit.world.storage.MissingWorldException;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.util.ArrayList;
|
||||
@ -30,8 +31,6 @@ import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A repository contains zero or more snapshots.
|
||||
*/
|
||||
|
@ -24,13 +24,15 @@ import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.world.DataException;
|
||||
import com.sk89q.worldedit.world.chunk.Chunk;
|
||||
import com.sk89q.worldedit.world.storage.ChunkStore;
|
||||
import com.sk89q.worldedit.world.storage.MissingChunkException;
|
||||
import com.sk89q.worldedit.world.storage.MissingWorldException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -22,7 +22,7 @@ package com.sk89q.worldedit.world.storage;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.*;
|
||||
import com.sk89q.worldedit.world.DataException;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
|
@ -19,12 +19,12 @@
|
||||
|
||||
package com.sk89q.worldedit.world.storage;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Utility methods for working with NBT data used in Minecraft.
|
||||
*/
|
||||
|
@ -24,11 +24,11 @@ import com.sk89q.worldedit.world.DataException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* Represents the chunk store used by Minecraft alpha but zipped.
|
||||
|
@ -26,11 +26,11 @@ import com.sk89q.worldedit.world.DataException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Enumeration;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipException;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.Enumeration;
|
||||
|
||||
/**
|
||||
* Represents the chunk store used by Minecraft alpha but zipped.
|
||||
|
Reference in New Issue
Block a user