geforkt von Mirrors/FastAsyncWorldEdit
Dieser Commit ist enthalten in:
Ursprung
29a364865d
Commit
36ede1b27d
@ -49,7 +49,7 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
|
||||
public BlockMaterial getMaterial(BlockType blockType) {
|
||||
Material type = BukkitAdapter.adapt(blockType);
|
||||
if (type == null) {
|
||||
type = Material.AIR;
|
||||
return new PassthroughBlockMaterial(null);
|
||||
}
|
||||
return materialMap.computeIfAbsent(type, m -> new BukkitBlockMaterial(BukkitBlockRegistry.super.getMaterial(blockType), m));
|
||||
}
|
||||
|
@ -123,6 +123,7 @@ public class WorldEditPlugin extends JavaPlugin implements TabCompleter {
|
||||
}
|
||||
|
||||
public WorldEditPlugin(JavaPluginLoader loader, PluginDescriptionFile desc, File dataFolder, File jarFile) {
|
||||
super(loader, desc, dataFolder, jarFile);
|
||||
init();
|
||||
}
|
||||
|
||||
|
@ -69,8 +69,13 @@ public abstract class FaweParser<T> extends InputParser<T> {
|
||||
switch (c) {
|
||||
case ',':
|
||||
case '&':
|
||||
inputs.add(toParse.substring(last, i));
|
||||
String result = toParse.substring(last, i);
|
||||
if (!result.isEmpty()) {
|
||||
inputs.add(result);
|
||||
and.add(c == '&');
|
||||
} else {
|
||||
throw new InputParseException("Invalid dangling character " + c);
|
||||
}
|
||||
last = i + 1;
|
||||
continue outer;
|
||||
default:
|
||||
|
@ -2519,6 +2519,18 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||
*/
|
||||
public int makePumpkinPatches(final Vector position, final int apothem) {
|
||||
return makePumpkinPatches(position, apothem, 0.02);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes pumpkin patches randomly in an area around the given position.
|
||||
*
|
||||
* @param position the base position
|
||||
* @param apothem the apothem of the (square) area
|
||||
* @return number of patches created
|
||||
* @throws MaxChangedBlocksException thrown if too many blocks are changed
|
||||
*/
|
||||
public int makePumpkinPatches(final Vector position, final int apothem, double density) {
|
||||
// We want to generate pumpkins
|
||||
final GardenPatchGenerator generator = new GardenPatchGenerator(EditSession.this);
|
||||
generator.setPlant(GardenPatchGenerator.getPumpkinPattern());
|
||||
@ -2526,7 +2538,6 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
// In a region of the given radius
|
||||
final FlatRegion region = new CuboidRegion(EditSession.this.getWorld(), // Causes clamping of Y range
|
||||
position.add(-apothem, -5, -apothem), position.add(apothem, 10, apothem));
|
||||
final double density = 0.02;
|
||||
|
||||
final GroundFunction ground = new GroundFunction(new ExistingBlockMask(EditSession.this), generator);
|
||||
final LayerVisitor visitor = new LayerVisitor(region, minimumBlockY(region), maximumBlockY(region), ground);
|
||||
|
@ -26,6 +26,7 @@ import com.sk89q.worldedit.registry.state.PropertyGroup;
|
||||
import com.sk89q.worldedit.registry.state.PropertyKey;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
import jdk.nashorn.internal.ir.Block;
|
||||
|
||||
import java.util.EnumMap;
|
||||
@ -45,8 +46,70 @@ public class BlockType {
|
||||
return centralTopLimit(type.getDefaultState());
|
||||
}
|
||||
|
||||
public static double centralBottomLimit(BlockStateHolder block) {
|
||||
checkNotNull(block);
|
||||
BlockTypes type = block.getBlockType();
|
||||
switch (type) {
|
||||
case CREEPER_WALL_HEAD:
|
||||
case DRAGON_WALL_HEAD:
|
||||
case PLAYER_WALL_HEAD:
|
||||
case ZOMBIE_WALL_HEAD: return 0.25;
|
||||
case ACACIA_SLAB:
|
||||
case BIRCH_SLAB:
|
||||
case BRICK_SLAB:
|
||||
case COBBLESTONE_SLAB:
|
||||
case DARK_OAK_SLAB:
|
||||
case DARK_PRISMARINE_SLAB:
|
||||
case JUNGLE_SLAB:
|
||||
case NETHER_BRICK_SLAB:
|
||||
case OAK_SLAB:
|
||||
case PETRIFIED_OAK_SLAB:
|
||||
case PRISMARINE_BRICK_SLAB:
|
||||
case PRISMARINE_SLAB:
|
||||
case PURPUR_SLAB:
|
||||
case QUARTZ_SLAB:
|
||||
case RED_SANDSTONE_SLAB:
|
||||
case SANDSTONE_SLAB:
|
||||
case SPRUCE_SLAB:
|
||||
case STONE_BRICK_SLAB:
|
||||
case STONE_SLAB: {
|
||||
String state = (String) block.getState(PropertyKey.TYPE);
|
||||
if (state == null) return 0;
|
||||
switch (state) {
|
||||
case "double":
|
||||
case "bottom":
|
||||
return 0;
|
||||
case "top":
|
||||
return 0.5;
|
||||
}
|
||||
}
|
||||
case ACACIA_TRAPDOOR:
|
||||
case BIRCH_TRAPDOOR:
|
||||
case DARK_OAK_TRAPDOOR:
|
||||
case IRON_TRAPDOOR:
|
||||
case JUNGLE_TRAPDOOR:
|
||||
case OAK_TRAPDOOR:
|
||||
case SPRUCE_TRAPDOOR:
|
||||
if (block.getState(PropertyKey.OPEN) == Boolean.TRUE) {
|
||||
return 1;
|
||||
} else if ("bottom".equals(block.getState(PropertyKey.HALF))) {
|
||||
return 0.8125;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
case ACACIA_FENCE_GATE:
|
||||
case BIRCH_FENCE_GATE:
|
||||
case DARK_OAK_FENCE_GATE:
|
||||
case JUNGLE_FENCE_GATE:
|
||||
case OAK_FENCE_GATE:
|
||||
case SPRUCE_FENCE_GATE: return block.getState(PropertyKey.OPEN) == Boolean.TRUE ? 1 : 0;
|
||||
default:
|
||||
if (type.getMaterial().isMovementBlocker()) return 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO FIXME use registry
|
||||
* Returns the y offset a player falls to when falling onto the top of a block at xp+0.5/zp+0.5.
|
||||
*
|
||||
* @param block the block
|
||||
@ -54,7 +117,8 @@ public class BlockType {
|
||||
*/
|
||||
public static double centralTopLimit(BlockStateHolder block) {
|
||||
checkNotNull(block);
|
||||
switch (block.getBlockType().getTypeEnum()) {
|
||||
BlockTypes type = block.getBlockType();
|
||||
switch (type) {
|
||||
case BLACK_BED:
|
||||
case BLUE_BED:
|
||||
case BROWN_BED:
|
||||
@ -111,7 +175,17 @@ public class BlockType {
|
||||
case SANDSTONE_SLAB:
|
||||
case SPRUCE_SLAB:
|
||||
case STONE_BRICK_SLAB:
|
||||
case STONE_SLAB: return 0.5;
|
||||
case STONE_SLAB: {
|
||||
String state = (String) block.getState(PropertyKey.TYPE);
|
||||
if (state == null) return 0.5;
|
||||
switch (state) {
|
||||
case "bottom":
|
||||
return 0.5;
|
||||
case "top":
|
||||
case "double":
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
case LILY_PAD: return 0.015625;
|
||||
case REPEATER: return 0.125;
|
||||
case SOUL_SAND: return 0.875;
|
||||
@ -142,7 +216,12 @@ public class BlockType {
|
||||
case OAK_FENCE_GATE:
|
||||
case SPRUCE_FENCE_GATE: return block.getState(PropertyKey.OPEN) == Boolean.TRUE ? 0 : 1.5;
|
||||
default:
|
||||
return PropertyGroup.LEVEL.get(block);
|
||||
if (type.hasProperty(PropertyKey.LAYERS)) {
|
||||
return PropertyGroup.LEVEL.get(block) * 0.0625;
|
||||
}
|
||||
if (!type.getMaterial().isMovementBlocker()) return 0;
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -284,20 +284,20 @@ public class GenerationCommands extends MethodCommands {
|
||||
public void forestGen(Player player, LocalSession session, EditSession editSession, @Optional("10") int size, @Optional("tree") TreeType type, @Optional("5") double density) throws WorldEditException, ParameterException {
|
||||
density = density / 100;
|
||||
int affected = editSession.makeForest(session.getPlacementPosition(player), size, density, type);
|
||||
player.print(affected + " trees created.");
|
||||
player.print(BBC.getPrefix() + affected + " trees created.");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = {"pumpkins"},
|
||||
usage = "[size]",
|
||||
usage = "[size=10] [density=0.02]",
|
||||
desc = "Generate pumpkin patches",
|
||||
min = 0,
|
||||
max = 1
|
||||
max = 2
|
||||
)
|
||||
@CommandPermissions("worldedit.generation.pumpkins")
|
||||
@Logging(POSITION)
|
||||
public void pumpkins(Player player, LocalSession session, EditSession editSession, @Optional("10") int apothem) throws WorldEditException, ParameterException {
|
||||
int affected = editSession.makePumpkinPatches(session.getPlacementPosition(player), apothem);
|
||||
public void pumpkins(Player player, LocalSession session, EditSession editSession, @Optional("10") int apothem, @Optional("0.02") double density) throws WorldEditException, ParameterException {
|
||||
int affected = editSession.makePumpkinPatches(session.getPlacementPosition(player), apothem, density);
|
||||
BBC.COMMAND_PUMPKIN.send(player, affected);
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ import com.sk89q.worldedit.PlayerDirection;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.blocks.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
@ -157,36 +158,47 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
||||
final int z = pos.getBlockZ();
|
||||
final Extent world = pos.getExtent();
|
||||
|
||||
byte free = 0;
|
||||
byte spots = 0;
|
||||
int maxY = world.getMaxY();
|
||||
if (y >= maxY) return false;
|
||||
|
||||
while (y <= world.getMaximumPoint().getY() + 2) {
|
||||
if (!world.getBlock(new Vector(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) {
|
||||
++free;
|
||||
BlockMaterial initialMaterial = world.getBlockType(new Vector(x, y, z)).getMaterial();
|
||||
|
||||
boolean lastState = initialMaterial.isMovementBlocker() && initialMaterial.isFullCube();
|
||||
|
||||
double height = 1.85;
|
||||
double freeStart = -1;
|
||||
|
||||
for (int level = y + 1; level <= maxY + 2; level++) {
|
||||
BlockState state;
|
||||
if (level >= maxY) state = BlockTypes.VOID_AIR.getDefaultState();
|
||||
else state = world.getBlock(new Vector(x, level, z));
|
||||
BlockTypes type = state.getBlockType();
|
||||
BlockMaterial material = type.getMaterial();
|
||||
|
||||
if (!material.isFullCube() || !material.isMovementBlocker()) {
|
||||
if (!lastState) {
|
||||
lastState = BlockType.centralBottomLimit(state) != 1;
|
||||
continue;
|
||||
}
|
||||
if (freeStart == -1) {
|
||||
freeStart = level + BlockType.centralTopLimit(state);
|
||||
} else {
|
||||
free = 0;
|
||||
}
|
||||
|
||||
if (free == 2) {
|
||||
++spots;
|
||||
if (spots == 2) {
|
||||
final Vector platform = new Vector(x, y - 2, z);
|
||||
final BlockStateHolder block = world.getBlock(platform);
|
||||
final com.sk89q.worldedit.world.block.BlockType type = block.getBlockType();
|
||||
|
||||
// Don't get put in lava!
|
||||
if (type == BlockTypes.LAVA) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setPosition(platform.add(0.5, BlockType.centralTopLimit(block), 0.5));
|
||||
double bottomLimit = BlockType.centralBottomLimit(state);
|
||||
double space = level + bottomLimit - freeStart;
|
||||
if (space >= height) {
|
||||
setPosition(new Vector(x + 0.5, freeStart, z + 0.5));
|
||||
return true;
|
||||
}
|
||||
// Not enough room, reset the free position
|
||||
if (bottomLimit != 1) {
|
||||
freeStart = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
freeStart = -1;
|
||||
lastState = true;
|
||||
}
|
||||
|
||||
++y;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -194,48 +206,52 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
|
||||
public boolean descendLevel() {
|
||||
final Location pos = getBlockIn();
|
||||
final int x = pos.getBlockX();
|
||||
int y = Math.max(0, pos.getBlockY() - 1);
|
||||
int y = Math.max(0, pos.getBlockY());
|
||||
final int z = pos.getBlockZ();
|
||||
final Extent world = pos.getExtent();
|
||||
|
||||
byte free = 0;
|
||||
BlockMaterial initialMaterial = world.getBlockType(new Vector(x, y, z)).getMaterial();
|
||||
|
||||
while (y >= 1) {
|
||||
if (!world.getBlock(new Vector(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) {
|
||||
++free;
|
||||
} else {
|
||||
free = 0;
|
||||
}
|
||||
boolean lastState = initialMaterial.isMovementBlocker() && initialMaterial.isFullCube();
|
||||
|
||||
if (free == 2) {
|
||||
// So we've found a spot, but we have to drop the player
|
||||
// lightly and also check to see if there's something to
|
||||
// stand upon
|
||||
while (y >= 0) {
|
||||
final Vector platform = new Vector(x, y, z);
|
||||
final BlockStateHolder block = world.getBlock(platform);
|
||||
final com.sk89q.worldedit.world.block.BlockTypes type = block.getBlockType();
|
||||
double height = 1.85;
|
||||
double freeEnd = -1;
|
||||
|
||||
// Don't want to end up in lava
|
||||
switch (type) {
|
||||
case AIR:
|
||||
case CAVE_AIR:
|
||||
case VOID_AIR:
|
||||
case LAVA:
|
||||
--y;
|
||||
int maxY = world.getMaxY();
|
||||
if (y <= 2) return false;
|
||||
|
||||
for (int level = y + 1; level > 0; level--) {
|
||||
BlockState state;
|
||||
if (level >= maxY) state = BlockTypes.VOID_AIR.getDefaultState();
|
||||
else state = world.getBlock(new Vector(x, level, z));
|
||||
BlockTypes type = state.getBlockType();
|
||||
BlockMaterial material = type.getMaterial();
|
||||
|
||||
if (!material.isFullCube() || !material.isMovementBlocker()) {
|
||||
if (!lastState) {
|
||||
lastState = BlockType.centralTopLimit(state) != 0;
|
||||
continue;
|
||||
default:
|
||||
// Found a block!
|
||||
setPosition(platform.add(0.5, BlockType.centralTopLimit(block), 0.5));
|
||||
}
|
||||
if (freeEnd == -1) {
|
||||
freeEnd = level + BlockType.centralBottomLimit(state);
|
||||
} else {
|
||||
double topLimit = BlockType.centralTopLimit(state);
|
||||
double freeStart = level + topLimit;
|
||||
double space = freeEnd - freeStart;
|
||||
if (space >= height) {
|
||||
setPosition(new Vector(x + 0.5, freeStart, z + 0.5));
|
||||
return true;
|
||||
}
|
||||
// Not enough room, reset the free position
|
||||
if (topLimit != 0) {
|
||||
freeEnd = -1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
--y;
|
||||
} else {
|
||||
lastState = true;
|
||||
freeEnd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -745,6 +745,7 @@ public enum BlockTypes implements BlockType {
|
||||
try {
|
||||
ReflectionUtils.setFailsafeFieldValue(BlockTypes.class.getDeclaredField("settings"), this, new Settings(this, id, internalId));
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@ -987,7 +988,8 @@ public enum BlockTypes implements BlockType {
|
||||
try {
|
||||
BlockStateHolder block = LegacyMapper.getInstance().getBlockFromLegacy(input);
|
||||
if (block != null) return (BlockTypes) block.getBlockType();
|
||||
} catch (NumberFormatException e) {}
|
||||
} catch (NumberFormatException e) {
|
||||
} catch (IndexOutOfBoundsException e) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -144,9 +144,9 @@ public class BundledBlockData {
|
||||
}
|
||||
|
||||
public static class BlockEntry {
|
||||
private String id;
|
||||
public String id;
|
||||
public String localizedName;
|
||||
private SimpleBlockMaterial material = new SimpleBlockMaterial();
|
||||
public SimpleBlockMaterial material = new SimpleBlockMaterial();
|
||||
}
|
||||
|
||||
}
|
@ -21,7 +21,7 @@ package com.sk89q.worldedit.world.registry;
|
||||
|
||||
import com.sk89q.worldedit.blocks.BlockMaterial;
|
||||
|
||||
class SimpleBlockMaterial implements BlockMaterial {
|
||||
public class SimpleBlockMaterial implements BlockMaterial {
|
||||
|
||||
private boolean isAir;
|
||||
private boolean fullCube;
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren