mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2025-06-25 02:04:44 +02:00
Chat / Merge blocks placer / generator
This commit is contained in:
@ -20,7 +20,6 @@ apply plugin: 'com.github.johnrengelman.shadow'
|
||||
dependencies {
|
||||
compile project(':Core')
|
||||
compile 'org.spongepowered:spongeapi:5.0.0-SNAPSHOT'
|
||||
//compile 'org.mcstats.sponge:metrics:R8-SNAPSHOT'
|
||||
}
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
@ -20,7 +20,6 @@ import com.intellectualcrafters.plot.util.EconHandler;
|
||||
import com.intellectualcrafters.plot.util.EventUtil;
|
||||
import com.intellectualcrafters.plot.util.InventoryUtil;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.PlotQueue;
|
||||
import com.intellectualcrafters.plot.util.SchematicHandler;
|
||||
import com.intellectualcrafters.plot.util.SetupUtils;
|
||||
import com.intellectualcrafters.plot.util.StringMan;
|
||||
@ -28,6 +27,7 @@ import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandler;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandlerImplementation;
|
||||
import com.intellectualcrafters.plot.util.WorldUtil;
|
||||
import com.intellectualcrafters.plot.util.block.QueueProvider;
|
||||
import com.intellectualcrafters.plot.uuid.UUIDWrapper;
|
||||
import com.plotsquared.sponge.generator.SpongePlotGenerator;
|
||||
import com.plotsquared.sponge.listener.ChunkProcessor;
|
||||
@ -47,11 +47,17 @@ import com.plotsquared.sponge.util.SpongeSetupUtils;
|
||||
import com.plotsquared.sponge.util.SpongeTaskManager;
|
||||
import com.plotsquared.sponge.util.SpongeTitleManager;
|
||||
import com.plotsquared.sponge.util.SpongeUtil;
|
||||
import com.plotsquared.sponge.util.block.FastQueue;
|
||||
import com.plotsquared.sponge.util.block.SlowQueue;
|
||||
import com.plotsquared.sponge.util.block.SpongeLocalQueue;
|
||||
import com.plotsquared.sponge.uuid.SpongeLowerOfflineUUIDWrapper;
|
||||
import com.plotsquared.sponge.uuid.SpongeOnlineUUIDWrapper;
|
||||
import com.plotsquared.sponge.uuid.SpongeUUIDHandler;
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
import org.slf4j.Logger;
|
||||
import org.spongepowered.api.Game;
|
||||
import org.spongepowered.api.Server;
|
||||
@ -63,20 +69,11 @@ import org.spongepowered.api.event.game.state.GameAboutToStartServerEvent;
|
||||
import org.spongepowered.api.plugin.Plugin;
|
||||
import org.spongepowered.api.plugin.PluginContainer;
|
||||
import org.spongepowered.api.profile.GameProfileManager;
|
||||
import org.spongepowered.api.world.Chunk;
|
||||
import org.spongepowered.api.world.World;
|
||||
import org.spongepowered.api.world.gen.GenerationPopulator;
|
||||
import org.spongepowered.api.world.gen.WorldGenerator;
|
||||
import org.spongepowered.api.world.gen.WorldGeneratorModifier;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Plugin(id = "plotsquared", name = "PlotSquared", description = "Easy, yet powerful Plot World generation and management.",
|
||||
url = "https://github.com/IntellectualSites/PlotSquared", version = "3.3.3")
|
||||
public class SpongeMain implements IPlotMain {
|
||||
@ -364,14 +361,9 @@ public class SpongeMain implements IPlotMain {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotQueue<Chunk> initPlotQueue() {
|
||||
try {
|
||||
MainUtil.canSendChunk = true;
|
||||
return new FastQueue();
|
||||
} catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new SlowQueue();
|
||||
public QueueProvider initBlockQueue() {
|
||||
MainUtil.canSendChunk = true;
|
||||
return QueueProvider.of(SpongeLocalQueue.class, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,19 +2,17 @@ package com.plotsquared.sponge.generator;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.intellectualcrafters.plot.generator.AugmentedUtils;
|
||||
import com.intellectualcrafters.plot.object.LazyResult;
|
||||
import com.intellectualcrafters.plot.util.PlotChunk;
|
||||
import com.intellectualcrafters.plot.util.SetQueue;
|
||||
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.util.block.DelegateLocalBlockQueue;
|
||||
import com.plotsquared.sponge.util.SpongeUtil;
|
||||
import java.util.List;
|
||||
import org.spongepowered.api.block.BlockState;
|
||||
import org.spongepowered.api.world.World;
|
||||
import org.spongepowered.api.world.extent.ImmutableBiomeArea;
|
||||
import org.spongepowered.api.world.extent.MutableBlockVolume;
|
||||
import org.spongepowered.api.world.gen.GenerationPopulator;
|
||||
import org.spongepowered.api.world.gen.WorldGenerator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SpongeAugmentedGenerator implements GenerationPopulator {
|
||||
|
||||
private static SpongeAugmentedGenerator generator;
|
||||
@ -43,38 +41,28 @@ public class SpongeAugmentedGenerator implements GenerationPopulator {
|
||||
int bz = min.getZ();
|
||||
int cx = bx >> 4;
|
||||
int cz = bz >> 4;
|
||||
AugmentedUtils.generate(world.getName(), cx, cz, new LazyResult<PlotChunk<?>>() {
|
||||
AugmentedUtils.generate(world.getName(), cx, cz, new DelegateLocalBlockQueue(null) {
|
||||
@Override
|
||||
public PlotChunk<?> create() {
|
||||
ChunkWrapper wrap = SetQueue.IMP.new ChunkWrapper(world.getName(), cx, cz);
|
||||
return new PlotChunk<ChunkWrapper>(wrap) {
|
||||
@Override
|
||||
public ChunkWrapper getChunkAbs() {
|
||||
return getChunkWrapper();
|
||||
}
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, byte data) {
|
||||
terrain.setBlock(bx + x, y, bz + z, SpongeUtil.getBlockState(id, data));
|
||||
}
|
||||
@Override
|
||||
public void setBiome(int x, int z, int biome) {
|
||||
// TODO FIXME
|
||||
}
|
||||
@Override
|
||||
public PlotChunk clone() {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED YET");
|
||||
}
|
||||
@Override
|
||||
public PlotChunk shallowClone() {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED YET");
|
||||
}
|
||||
@Override
|
||||
public void addToQueue() {}
|
||||
@Override
|
||||
public void flush(boolean fixLighting) {}
|
||||
};
|
||||
public boolean setBlock(int x, int y, int z, int id, int data) {
|
||||
terrain.setBlock(bx + x, y, bz + z, SpongeUtil.getBlockState(id, data));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotBlock getBlock(int x, int y, int z) {
|
||||
BlockState block = terrain.getBlock(bx + x, y, bz + z);
|
||||
return block == null ? PlotBlock.get(0, 0) : SpongeUtil.getPlotBlock(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int z, String biome) {
|
||||
return false; // TODO ?
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWorld() {
|
||||
return world.getName();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,19 +1,17 @@
|
||||
package com.plotsquared.sponge.generator;
|
||||
|
||||
import org.spongepowered.api.world.World;
|
||||
import org.spongepowered.api.world.extent.ImmutableBiomeArea;
|
||||
import org.spongepowered.api.world.extent.MutableBlockVolume;
|
||||
import org.spongepowered.api.world.gen.GenerationPopulator;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.generator.IndependentPlotGenerator;
|
||||
import com.intellectualcrafters.plot.object.ChunkWrapper;
|
||||
import com.intellectualcrafters.plot.object.PlotArea;
|
||||
import com.intellectualcrafters.plot.object.PseudoRandom;
|
||||
import com.intellectualcrafters.plot.util.ChunkManager;
|
||||
import com.intellectualcrafters.plot.util.SetQueue;
|
||||
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
|
||||
import com.plotsquared.sponge.util.block.GenChunk;
|
||||
import org.spongepowered.api.world.World;
|
||||
import org.spongepowered.api.world.extent.ImmutableBiomeArea;
|
||||
import org.spongepowered.api.world.extent.MutableBlockVolume;
|
||||
import org.spongepowered.api.world.gen.GenerationPopulator;
|
||||
|
||||
public class SpongeTerrainGen implements GenerationPopulator {
|
||||
|
||||
@ -36,7 +34,7 @@ public class SpongeTerrainGen implements GenerationPopulator {
|
||||
Vector3i min = terrain.getBlockMin();
|
||||
int cx = min.getX() >> 4;
|
||||
int cz = min.getZ() >> 4;
|
||||
ChunkWrapper wrap = SetQueue.IMP.new ChunkWrapper(worldname, cx, cz);
|
||||
ChunkWrapper wrap = new ChunkWrapper(worldname, cx, cz);
|
||||
// Create the result object
|
||||
GenChunk result = new GenChunk(terrain, null, wrap);
|
||||
// Catch any exceptions
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.plotsquared.sponge.util;
|
||||
|
||||
import com.intellectualcrafters.plot.config.Settings;
|
||||
import com.intellectualcrafters.plot.object.ConsolePlayer;
|
||||
import com.intellectualcrafters.plot.object.PlotMessage;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
@ -139,7 +140,7 @@ public class SpongeChatManager extends ChatManager<Text.Builder> {
|
||||
|
||||
@Override
|
||||
public void send(PlotMessage plotMessage, PlotPlayer player) {
|
||||
if (player instanceof ConsolePlayer) {
|
||||
if (player instanceof ConsolePlayer || !Settings.Chat.INTERACTIVE) {
|
||||
player.sendMessage(plotMessage.$(this).build().toPlain());
|
||||
} else {
|
||||
((SpongePlayer) player).player.sendMessage(plotMessage.$(this).build());
|
||||
|
@ -1,60 +1,12 @@
|
||||
package com.plotsquared.sponge.util;
|
||||
|
||||
import com.intellectualcrafters.plot.generator.HybridUtils;
|
||||
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.object.RegionWrapper;
|
||||
import com.intellectualcrafters.plot.object.RunnableVal;
|
||||
import org.spongepowered.api.block.BlockState;
|
||||
import org.spongepowered.api.block.BlockTypes;
|
||||
import org.spongepowered.api.world.World;
|
||||
import com.intellectualcrafters.plot.util.expiry.PlotAnalysis;
|
||||
|
||||
public class SpongeHybridUtils extends HybridUtils {
|
||||
|
||||
@Override
|
||||
public int checkModified(String worldName, int x1, int x2, int y1, int y2, int z1, int z2, PlotBlock[] blocks) {
|
||||
World world = SpongeUtil.getWorld(worldName);
|
||||
int count = 0;
|
||||
for (int y = y1; y <= y2; y++) {
|
||||
for (int x = x1; x <= x2; x++) {
|
||||
for (int z = z1; z <= z2; z++) {
|
||||
BlockState state = world.getBlock(x, y, z);
|
||||
PlotBlock block = SpongeUtil.getPlotBlock(state);
|
||||
boolean same = false;
|
||||
for (PlotBlock p : blocks) {
|
||||
if (block.id == p.id) {
|
||||
same = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!same) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get_ey(String worldName, int sx, int ex, int sz, int ez, int sy) {
|
||||
World world = SpongeUtil.getWorld(worldName);
|
||||
int ey = sy;
|
||||
for (int x = sx; x <= ex; x++) {
|
||||
for (int z = sz; z <= ez; z++) {
|
||||
for (int y = sy; y < 256; y++) {
|
||||
if (y > ey) {
|
||||
BlockState state = world.getBlock(x, y, z);
|
||||
if (state.getType() != BlockTypes.AIR) {
|
||||
ey = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ey;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void analyzeRegion(String world, RegionWrapper region, RunnableVal<PlotAnalysis> whenDone) {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED YET");
|
||||
|
@ -1,246 +0,0 @@
|
||||
package com.plotsquared.sponge.util.block;
|
||||
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.PlotChunk;
|
||||
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
|
||||
import com.plotsquared.sponge.util.SpongeUtil;
|
||||
import org.spongepowered.api.world.Chunk;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class FastChunk extends PlotChunk<Chunk> {
|
||||
|
||||
public char[][] ids;
|
||||
public short[] count;
|
||||
public short[] air;
|
||||
public short[] relight;
|
||||
public int[][] biomes;
|
||||
public Chunk chunk;
|
||||
|
||||
public FastChunk(ChunkWrapper chunk) {
|
||||
super(chunk);
|
||||
this.ids = new char[16][];
|
||||
this.count = new short[16];
|
||||
this.air = new short[16];
|
||||
this.relight = new short[16];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunkAbs() {
|
||||
ChunkWrapper loc = getChunkWrapper();
|
||||
return SpongeUtil.getWorld(loc.world).getChunk(loc.x, 0, loc.z).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunk() {
|
||||
if (this.chunk == null) {
|
||||
ChunkWrapper cl = getChunkWrapper();
|
||||
this.chunk = SpongeUtil.getWorld(cl.world).getChunk(cl.x, 0, cl.z).get();
|
||||
}
|
||||
return this.chunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChunkWrapper(ChunkWrapper loc) {
|
||||
super.setChunkWrapper(loc);
|
||||
this.chunk = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of block changes in a specified section.
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public int getCount(int i) {
|
||||
return this.count[i];
|
||||
}
|
||||
|
||||
public int getAir(int i) {
|
||||
return this.air[i];
|
||||
}
|
||||
|
||||
public void setCount(int i, short value) {
|
||||
this.count[i] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of block changes in a specified section.
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public int getRelight(int i) {
|
||||
return this.relight[i];
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
int total = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
total += this.count[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public int getTotalRelight() {
|
||||
if (getTotalCount() == 0) {
|
||||
Arrays.fill(this.count, (short) 1);
|
||||
Arrays.fill(this.relight, Short.MAX_VALUE);
|
||||
return Short.MAX_VALUE;
|
||||
}
|
||||
int total = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
total += this.relight[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the raw data for a section.
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public char[] getIdArray(int i) {
|
||||
return this.ids[i];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, byte data) {
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
int j = MainUtil.CACHE_J[y][x][z];
|
||||
char[] vs = this.ids[i];
|
||||
if (vs == null) {
|
||||
vs = this.ids[i] = new char[4096];
|
||||
this.count[i]++;
|
||||
} else if (vs[j] == 0) {
|
||||
this.count[i]++;
|
||||
}
|
||||
switch (id) {
|
||||
case 0:
|
||||
this.air[i]++;
|
||||
vs[j] = (char) 1;
|
||||
return;
|
||||
case 10:
|
||||
case 11:
|
||||
case 39:
|
||||
case 40:
|
||||
case 51:
|
||||
case 74:
|
||||
case 89:
|
||||
case 122:
|
||||
case 124:
|
||||
case 138:
|
||||
case 169:
|
||||
this.relight[i]++;
|
||||
case 2:
|
||||
case 4:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 30:
|
||||
case 32:
|
||||
case 37:
|
||||
case 41:
|
||||
case 42:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
case 48:
|
||||
case 49:
|
||||
case 55:
|
||||
case 56:
|
||||
case 57:
|
||||
case 58:
|
||||
case 60:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 73:
|
||||
case 78:
|
||||
case 79:
|
||||
case 80:
|
||||
case 81:
|
||||
case 82:
|
||||
case 83:
|
||||
case 85:
|
||||
case 87:
|
||||
case 88:
|
||||
case 101:
|
||||
case 102:
|
||||
case 103:
|
||||
case 110:
|
||||
case 112:
|
||||
case 113:
|
||||
case 121:
|
||||
case 129:
|
||||
case 133:
|
||||
case 165:
|
||||
case 166:
|
||||
case 170:
|
||||
case 172:
|
||||
case 173:
|
||||
case 174:
|
||||
case 181:
|
||||
case 182:
|
||||
case 188:
|
||||
case 189:
|
||||
case 190:
|
||||
case 191:
|
||||
case 192:
|
||||
vs[j] = (char) (id << 4);
|
||||
return;
|
||||
case 130:
|
||||
case 76:
|
||||
case 62:
|
||||
this.relight[i]++;
|
||||
case 54:
|
||||
case 146:
|
||||
case 61:
|
||||
case 65:
|
||||
case 68:
|
||||
case 50:
|
||||
if (data < 2) {
|
||||
data = 2;
|
||||
}
|
||||
default:
|
||||
vs[j] = (char) ((id << 4) + data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotChunk clone() {
|
||||
FastChunk toReturn = new FastChunk(getChunkWrapper());
|
||||
toReturn.air = this.air.clone();
|
||||
toReturn.count = this.count.clone();
|
||||
toReturn.relight = this.relight.clone();
|
||||
toReturn.ids = new char[this.ids.length][];
|
||||
for (int i = 0; i < this.ids.length; i++) {
|
||||
char[] matrix = this.ids[i];
|
||||
if (matrix != null) {
|
||||
toReturn.ids[i] = new char[matrix.length];
|
||||
System.arraycopy(matrix, 0, toReturn.ids[i], 0, matrix.length);
|
||||
}
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotChunk shallowClone() {
|
||||
FastChunk toReturn = new FastChunk(getChunkWrapper());
|
||||
toReturn.air = this.air;
|
||||
toReturn.count = this.count;
|
||||
toReturn.relight = this.relight;
|
||||
toReturn.ids = this.ids;
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, int biome) {
|
||||
if (this.biomes == null) {
|
||||
this.biomes = new int[16][16];
|
||||
}
|
||||
this.biomes[x][z] = biome;
|
||||
}
|
||||
}
|
@ -1,326 +0,0 @@
|
||||
package com.plotsquared.sponge.util.block;
|
||||
|
||||
import com.intellectualcrafters.plot.object.ChunkLoc;
|
||||
import com.intellectualcrafters.plot.object.PseudoRandom;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.PlotChunk;
|
||||
import com.intellectualcrafters.plot.util.SetQueue;
|
||||
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.plotsquared.sponge.util.SpongeUtil;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ClassInheritanceMultiMap;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.chunk.BlockStateContainer;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
import org.spongepowered.api.world.Chunk;
|
||||
import org.spongepowered.api.world.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
public class FastQueue extends SlowQueue {
|
||||
|
||||
public final SendChunk chunkSender;
|
||||
public final HashMap<ChunkWrapper, Chunk> toUpdate = new HashMap<>();
|
||||
|
||||
public FastQueue() throws RuntimeException {
|
||||
TaskManager.runTaskRepeat(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (FastQueue.this.toUpdate.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
int count = 0;
|
||||
ArrayList<Chunk> chunks = new ArrayList<>();
|
||||
Iterator<Entry<ChunkWrapper, Chunk>> i = FastQueue.this.toUpdate.entrySet().iterator();
|
||||
while (i.hasNext() && (count < 128)) {
|
||||
chunks.add(i.next().getValue());
|
||||
i.remove();
|
||||
count++;
|
||||
}
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
update(chunks);
|
||||
}
|
||||
}, 1);
|
||||
this.chunkSender = new SendChunk();
|
||||
MainUtil.initCache();
|
||||
}
|
||||
|
||||
public void update(Collection<Chunk> chunks) {
|
||||
if (chunks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (!MainUtil.canSendChunk) {
|
||||
for (Chunk chunk : chunks) {
|
||||
chunk.unloadChunk();
|
||||
chunk.loadChunk(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.chunkSender.sendChunk(chunks);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
MainUtil.canSendChunk = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be overridden by any specialized queues.
|
||||
* @param plotChunk
|
||||
*/
|
||||
@Override
|
||||
public void execute(PlotChunk<Chunk> plotChunk) {
|
||||
FastChunk fs = (FastChunk) plotChunk;
|
||||
Chunk spongeChunk = plotChunk.getChunk();
|
||||
net.minecraft.world.World nmsWorld = (net.minecraft.world.World) spongeChunk.getWorld();
|
||||
ChunkWrapper wrapper = plotChunk.getChunkWrapper();
|
||||
if (!this.toUpdate.containsKey(wrapper)) {
|
||||
this.toUpdate.put(wrapper, spongeChunk);
|
||||
}
|
||||
spongeChunk.loadChunk(true);
|
||||
try {
|
||||
boolean flag = !nmsWorld.provider.getHasNoSky();
|
||||
// Sections
|
||||
net.minecraft.world.chunk.Chunk nmsChunk = (net.minecraft.world.chunk.Chunk) spongeChunk;
|
||||
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||
Map<BlockPos, TileEntity> tiles = nmsChunk.getTileEntityMap();
|
||||
ClassInheritanceMultiMap<Entity>[] entities = nmsChunk.getEntityLists();
|
||||
// Trim tiles
|
||||
Set<Entry<BlockPos, TileEntity>> entryset = tiles.entrySet();
|
||||
Iterator<Entry<BlockPos, TileEntity>> iterator = entryset.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Entry<BlockPos, TileEntity> tile = iterator.next();
|
||||
BlockPos pos = tile.getKey();
|
||||
int lx = pos.getX() & 15;
|
||||
int ly = pos.getY();
|
||||
int lz = pos.getZ() & 15;
|
||||
int j = MainUtil.CACHE_I[ly][lx][lz];
|
||||
int k = MainUtil.CACHE_J[ly][lx][lz];
|
||||
char[] array = fs.getIdArray(j);
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
if (array[k] != 0) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
// Trim entities
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if ((entities[i] != null) && (fs.getCount(i) >= 4096)) {
|
||||
entities[i].clear();
|
||||
}
|
||||
}
|
||||
// Efficiently merge sections
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
if (fs.getCount(j) == 0) {
|
||||
continue;
|
||||
}
|
||||
char[] newArray = fs.getIdArray(j);
|
||||
if (newArray == null) {
|
||||
continue;
|
||||
}
|
||||
ExtendedBlockStorage section = sections[j];
|
||||
if ((section == null) || (fs.getCount(j) >= 4096)) {
|
||||
section = new ExtendedBlockStorage(j << 4, flag);
|
||||
//section.setData(newArray); //todo
|
||||
sections[j] = section;
|
||||
continue;
|
||||
}
|
||||
BlockStateContainer currentArray = section.getData();
|
||||
boolean fill = true;
|
||||
for (int k = 0; k < newArray.length; k++) {
|
||||
char n = newArray[k];
|
||||
switch (n) {
|
||||
case 0:
|
||||
fill = false;
|
||||
continue;
|
||||
case 1:
|
||||
fill = false;
|
||||
//currentArray[k] = 0; //todo
|
||||
continue;
|
||||
default:
|
||||
//currentArray[k] = n; //todo
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (fill) {
|
||||
fs.setCount(j, Short.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
// Clear
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
int[][] biomes = fs.biomes;
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
spongeChunk.setBiome(x, z, SpongeUtil.getBiome(biome));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be overridden by any specialized queues.
|
||||
* @param wrap
|
||||
*/
|
||||
@Override
|
||||
public PlotChunk<Chunk> getChunk(ChunkWrapper wrap) {
|
||||
return new FastChunk(wrap);
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be overridden by any specialized queues.
|
||||
* @param pc
|
||||
*/
|
||||
@Override
|
||||
public boolean fixLighting(PlotChunk<Chunk> pc, boolean fixAll) {
|
||||
try {
|
||||
FastChunk bc = (FastChunk) pc;
|
||||
Chunk spongeChunk = bc.getChunk();
|
||||
net.minecraft.world.chunk.Chunk nmsChunk = (net.minecraft.world.chunk.Chunk) spongeChunk;
|
||||
if (!spongeChunk.isLoaded()) {
|
||||
if (!spongeChunk.loadChunk(false)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
spongeChunk.unloadChunk();
|
||||
spongeChunk.loadChunk(false);
|
||||
}
|
||||
// TODO load adjacent chunks
|
||||
nmsChunk.generateSkylightMap();
|
||||
if (bc.getTotalRelight() == 0 && !fixAll) {
|
||||
return true;
|
||||
}
|
||||
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||
net.minecraft.world.World nmsWorld = nmsChunk.getWorld();
|
||||
|
||||
int X = pc.getX() << 4;
|
||||
int Z = pc.getZ() << 4;
|
||||
|
||||
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
ExtendedBlockStorage section = sections[j];
|
||||
if (section == null) {
|
||||
continue;
|
||||
}
|
||||
if ((bc.getRelight(j) == 0 && !fixAll) || bc.getCount(j) == 0 || (bc.getCount(j) >= 4096 && bc.getAir(j) == 0)) {
|
||||
continue;
|
||||
}
|
||||
BlockStateContainer array = section.getData();
|
||||
int l = PseudoRandom.random.random(2);
|
||||
for (int k = 0; k < array.getSerializedSize(); k++) {
|
||||
int i = 0;
|
||||
//i = array[k]; //todo
|
||||
if (i < 16) {
|
||||
continue;
|
||||
}
|
||||
short id = (short) (i >> 4);
|
||||
switch (id) { // Lighting
|
||||
default:
|
||||
if (!fixAll) {
|
||||
continue;
|
||||
}
|
||||
if ((k & 1) == l) {
|
||||
l = 1 - l;
|
||||
continue;
|
||||
}
|
||||
case 10:
|
||||
case 11:
|
||||
case 39:
|
||||
case 40:
|
||||
case 50:
|
||||
case 51:
|
||||
case 62:
|
||||
case 74:
|
||||
case 76:
|
||||
case 89:
|
||||
case 122:
|
||||
case 124:
|
||||
case 130:
|
||||
case 138:
|
||||
case 169:
|
||||
int x = MainUtil.x_loc[j][k];
|
||||
int y = MainUtil.y_loc[j][k];
|
||||
int z = MainUtil.z_loc[j][k];
|
||||
if (isSurrounded(sections, x, y, z)) {
|
||||
continue;
|
||||
}
|
||||
BlockPos pos = new BlockPos(X + x, y, Z + z);
|
||||
nmsWorld.checkLight(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isSurrounded(ExtendedBlockStorage[] sections, int x, int y, int z) {
|
||||
return isSolid(getId(sections, x, y + 1, z))
|
||||
&& isSolid(getId(sections, x + 1, y - 1, z))
|
||||
&& isSolid(getId(sections, x - 1, y, z))
|
||||
&& isSolid(getId(sections, x, y, z + 1))
|
||||
&& isSolid(getId(sections, x, y, z - 1));
|
||||
}
|
||||
|
||||
public boolean isSolid(int i) {
|
||||
//return i != 0 && Block.getBlockById(i).isOpaqueCube();
|
||||
throw new UnsupportedOperationException("Unsupported");
|
||||
}
|
||||
|
||||
public int getId(ExtendedBlockStorage[] sections, int x, int y, int z) {
|
||||
if (x < 0 || x > 15 || z < 0 || z > 15) {
|
||||
return 1;
|
||||
}
|
||||
if (y < 0 || y > 255) {
|
||||
return 1;
|
||||
}
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
ExtendedBlockStorage section = sections[i];
|
||||
if (section == null) {
|
||||
return 0;
|
||||
}
|
||||
BlockStateContainer array = section.getData();
|
||||
int j = MainUtil.CACHE_J[y][x][z];
|
||||
//return array[j] >> 4; //todo: fix for 1.9.4
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be overridden by any specialized queues.
|
||||
* @param world
|
||||
* @param locations
|
||||
*/
|
||||
@Override
|
||||
public void sendChunk(String world, Collection<ChunkLoc> locations) {
|
||||
World spongeWorld = SpongeUtil.getWorld(world);
|
||||
for (ChunkLoc loc : locations) {
|
||||
ChunkWrapper wrapper = SetQueue.IMP.new ChunkWrapper(world, loc.x, loc.z);
|
||||
if (!this.toUpdate.containsKey(wrapper)) {
|
||||
this.toUpdate.put(wrapper, spongeWorld.getChunk(loc.x, 0, loc.z).get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,58 +1,88 @@
|
||||
package com.plotsquared.sponge.util.block;
|
||||
|
||||
import com.intellectualcrafters.plot.util.PlotChunk;
|
||||
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
|
||||
import com.intellectualcrafters.plot.object.ChunkWrapper;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.util.block.ScopedLocalBlockQueue;
|
||||
import com.plotsquared.sponge.util.SpongeUtil;
|
||||
import org.spongepowered.api.world.Chunk;
|
||||
import org.spongepowered.api.world.biome.BiomeType;
|
||||
import org.spongepowered.api.world.extent.MutableBiomeArea;
|
||||
import org.spongepowered.api.world.extent.MutableBlockVolume;
|
||||
|
||||
public class GenChunk extends PlotChunk<Chunk> {
|
||||
public class GenChunk extends ScopedLocalBlockQueue {
|
||||
|
||||
private final MutableBlockVolume terrain;
|
||||
private final MutableBiomeArea biome;
|
||||
private final int bz;
|
||||
private final int bx;
|
||||
private final String world;
|
||||
|
||||
public boolean modified = false;
|
||||
|
||||
public GenChunk(MutableBlockVolume terrain, MutableBiomeArea biome, ChunkWrapper wrap) {
|
||||
super(wrap);
|
||||
super(null, new Location(null, 0, 0, 0), new Location(null, 15, 255, 15));
|
||||
this.bx = wrap.x << 4;
|
||||
this.bz = wrap.z << 4;
|
||||
this.terrain = terrain;
|
||||
this.biome = biome;
|
||||
this.world = wrap.world;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Chunk getChunkAbs() {
|
||||
ChunkWrapper wrap = getChunkWrapper();
|
||||
return SpongeUtil.getWorld(wrap.world).getChunk(wrap.x << 4, 0, wrap.z << 4).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, int biome) {
|
||||
if (this.biome != null) {
|
||||
this.biome.setBiome(this.bx + x, this.bz + z, SpongeUtil.getBiome(biome));
|
||||
public void fillBiome(String biomeName) {
|
||||
if (this.biome == null) {
|
||||
return;
|
||||
}
|
||||
BiomeType biome = SpongeUtil.getBiome(biomeName.toUpperCase());
|
||||
for (int x = 0; x <= 15; x++) {
|
||||
for (int z = 0; z < 15; z++) {
|
||||
this.biome.setBiome(this.bx + x, this.bz + z, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, byte data) {
|
||||
public boolean setBiome(int x, int z, String biomeName) {
|
||||
modified = true;
|
||||
BiomeType biome = SpongeUtil.getBiome(biomeName.toUpperCase());
|
||||
this.biome.setBiome(this.bx + x, this.bz + z, biome);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, int id, int data) {
|
||||
modified = true;
|
||||
this.terrain.setBlock(this.bx + x, y, this.bz + z, SpongeUtil.getBlockState(id, data));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChunkWrapper(ChunkWrapper loc) {
|
||||
super.setChunkWrapper(loc);
|
||||
public PlotBlock getBlock(int x, int y, int z) {
|
||||
return SpongeUtil.getPlotBlock(this.terrain.getBlock(this.bx + x, y, this.bz + z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotChunk clone() {
|
||||
public String getWorld() {
|
||||
return this.world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getMax() {
|
||||
return new Location(getWorld(), 15 + bx, 255, 15 + bz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Location getMin() {
|
||||
return new Location(getWorld(), bx, 0, bz);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public GenChunk clone() {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED YET");
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotChunk shallowClone() {
|
||||
public GenChunk shallowClone() {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED YET");
|
||||
}
|
||||
}
|
||||
|
@ -1,108 +0,0 @@
|
||||
package com.plotsquared.sponge.util.block;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.object.ChunkLoc;
|
||||
import com.intellectualcrafters.plot.object.Location;
|
||||
import com.intellectualcrafters.plot.object.Plot;
|
||||
import com.intellectualcrafters.plot.object.PlotPlayer;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.intellectualcrafters.plot.util.UUIDHandler;
|
||||
import com.plotsquared.sponge.object.SpongePlayer;
|
||||
import com.plotsquared.sponge.util.SpongeUtil;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
import net.minecraft.network.play.server.SPacketChunkData;
|
||||
import org.spongepowered.api.entity.living.player.Player;
|
||||
import org.spongepowered.api.world.Chunk;
|
||||
import org.spongepowered.api.world.World;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* An utility that can be used to send chunks, rather than using bukkit code to do so (uses heavy NMS)
|
||||
*
|
||||
|
||||
*/
|
||||
public class SendChunk {
|
||||
|
||||
public void sendChunk(Collection<Chunk> input) {
|
||||
HashSet<Chunk> chunks = new HashSet<Chunk>(input);
|
||||
HashMap<String, ArrayList<Chunk>> map = new HashMap<>();
|
||||
for (Chunk chunk : chunks) {
|
||||
String world = chunk.getWorld().getName();
|
||||
ArrayList<Chunk> list = map.get(world);
|
||||
if (list == null) {
|
||||
list = new ArrayList<>();
|
||||
map.put(world, list);
|
||||
}
|
||||
list.add(chunk);
|
||||
((net.minecraft.world.chunk.Chunk) chunk).generateSkylightMap();
|
||||
}
|
||||
for (Entry<String, PlotPlayer> entry : UUIDHandler.getPlayers().entrySet()) {
|
||||
PlotPlayer pp = entry.getValue();
|
||||
Plot plot = pp.getCurrentPlot();
|
||||
Location loc = null;
|
||||
String world;
|
||||
if (plot != null) {
|
||||
world = plot.getArea().worldname;
|
||||
} else {
|
||||
loc = pp.getLocation();
|
||||
world = loc.getWorld();
|
||||
}
|
||||
ArrayList<Chunk> list = map.get(world);
|
||||
if (list == null) {
|
||||
continue;
|
||||
}
|
||||
if (loc == null) {
|
||||
loc = pp.getLocation();
|
||||
}
|
||||
int cx = loc.getX() >> 4;
|
||||
int cz = loc.getZ() >> 4;
|
||||
Player player = ((SpongePlayer) pp).player;
|
||||
int view = player.getViewDistance();
|
||||
EntityPlayer nmsPlayer = (EntityPlayer) player;
|
||||
if (!(nmsPlayer instanceof EntityPlayerMP)) {
|
||||
PS.debug("Cannot send chunk change to: " + pp.getName());
|
||||
return;
|
||||
}
|
||||
EntityPlayerMP nmsPlayerMP = (EntityPlayerMP) nmsPlayer;
|
||||
for (Chunk chunk : list) {
|
||||
Vector3i min = chunk.getBlockMin();
|
||||
int dx = Math.abs(cx - (min.getX() >> 4));
|
||||
int dz = Math.abs(cz - (min.getZ() >> 4));
|
||||
if ((dx > view) || (dz > view)) {
|
||||
continue;
|
||||
}
|
||||
chunks.remove(chunk);
|
||||
NetHandlerPlayServer con = nmsPlayerMP.connection;
|
||||
net.minecraft.world.chunk.Chunk nmsChunk = (net.minecraft.world.chunk.Chunk) chunk;
|
||||
SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65535);
|
||||
con.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
for (Chunk chunk : chunks) {
|
||||
TaskManager.runTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
chunk.unloadChunk();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void sendChunk(String worldName, List<ChunkLoc> chunkLocations) {
|
||||
World spongeWorld = SpongeUtil.getWorld(worldName);
|
||||
ArrayList<Chunk> chunks = new ArrayList<>();
|
||||
for (ChunkLoc loc : chunkLocations) {
|
||||
chunks.add(spongeWorld.getChunk(loc.x, 0, loc.z).get());
|
||||
}
|
||||
sendChunk(chunks);
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package com.plotsquared.sponge.util.block;
|
||||
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.PlotChunk;
|
||||
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
|
||||
import com.plotsquared.sponge.util.SpongeUtil;
|
||||
import org.spongepowered.api.world.Chunk;
|
||||
|
||||
public class SlowChunk extends PlotChunk<Chunk> {
|
||||
|
||||
public PlotBlock[][] result = new PlotBlock[16][];
|
||||
public int[][] biomes;
|
||||
private PlotBlock lastBlock;
|
||||
|
||||
public SlowChunk(ChunkWrapper chunk) {
|
||||
super(chunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunkAbs() {
|
||||
ChunkWrapper loc = getChunkWrapper();
|
||||
return SpongeUtil.getWorld(loc.world).getChunk(loc.x << 4, 0, loc.z << 4).get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, int biome) {
|
||||
if (this.biomes == null) {
|
||||
this.biomes = new int[16][16];
|
||||
}
|
||||
this.biomes[x][z] = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, byte data) {
|
||||
if (this.result[y >> 4] == null) {
|
||||
this.result[y >> 4] = new PlotBlock[4096];
|
||||
}
|
||||
if (id == this.lastBlock.id && data == this.lastBlock.data) {
|
||||
this.result[MainUtil.CACHE_I[x][y][z]][MainUtil.CACHE_J[x][y][z]] = this.lastBlock;
|
||||
} else {
|
||||
this.result[MainUtil.CACHE_I[x][y][z]][MainUtil.CACHE_J[x][y][z]] = PlotBlock.get((short) id, data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotChunk clone() {
|
||||
SlowChunk toReturn = new SlowChunk(getChunkWrapper());
|
||||
for (int i = 0; i < this.result.length; i++) {
|
||||
PlotBlock[] matrix = this.result[i];
|
||||
if (matrix != null) {
|
||||
toReturn.result[i] = new PlotBlock[matrix.length];
|
||||
System.arraycopy(matrix, 0, toReturn.result[i], 0, matrix.length);
|
||||
}
|
||||
}
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotChunk shallowClone() {
|
||||
SlowChunk toReturn = new SlowChunk(getChunkWrapper());
|
||||
toReturn.result = this.result;
|
||||
return toReturn;
|
||||
}
|
||||
}
|
@ -1,226 +0,0 @@
|
||||
package com.plotsquared.sponge.util.block;
|
||||
|
||||
import com.flowpowered.math.vector.Vector3i;
|
||||
import com.intellectualcrafters.plot.PS;
|
||||
import com.intellectualcrafters.plot.object.ChunkLoc;
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.PlotChunk;
|
||||
import com.intellectualcrafters.plot.util.PlotQueue;
|
||||
import com.intellectualcrafters.plot.util.SetQueue;
|
||||
import com.intellectualcrafters.plot.util.SetQueue.ChunkWrapper;
|
||||
import com.plotsquared.sponge.util.SpongeUtil;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraft.world.gen.ChunkProviderServer;
|
||||
import org.spongepowered.api.block.BlockState;
|
||||
import org.spongepowered.api.world.Chunk;
|
||||
import org.spongepowered.api.world.World;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class SlowQueue implements PlotQueue<Chunk> {
|
||||
|
||||
private final ConcurrentHashMap<ChunkWrapper, PlotChunk<Chunk>> blocks = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public boolean setBlock(String world, int x, int y, int z, short id, byte data) {
|
||||
if (y > 255 || y < 0) {
|
||||
return false;
|
||||
}
|
||||
ChunkWrapper wrap = SetQueue.IMP.new ChunkWrapper(world, x >> 4, z >> 4);
|
||||
x = x & 15;
|
||||
z = z & 15;
|
||||
PlotChunk<Chunk> result = this.blocks.get(wrap);
|
||||
if (result == null) {
|
||||
result = getChunk(wrap);
|
||||
result.setBlock(x, y, z, id, data);
|
||||
PlotChunk<Chunk> previous = this.blocks.put(wrap, result);
|
||||
if (previous == null) {
|
||||
return true;
|
||||
}
|
||||
this.blocks.put(wrap, previous);
|
||||
result = previous;
|
||||
}
|
||||
result.setBlock(x, y, z, id, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChunk(PlotChunk<Chunk> chunk) {
|
||||
this.blocks.put(chunk.getChunkWrapper(), chunk);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotChunk<Chunk> next() {
|
||||
if (!PS.get().isMainThread(Thread.currentThread())) {
|
||||
throw new IllegalStateException("Must be called from main thread!");
|
||||
}
|
||||
try {
|
||||
if (this.blocks.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
Iterator<Entry<ChunkWrapper, PlotChunk<Chunk>>> iter = this.blocks.entrySet().iterator();
|
||||
PlotChunk<Chunk> toReturn = iter.next().getValue();
|
||||
if (SetQueue.IMP.isWaiting()) {
|
||||
return null;
|
||||
}
|
||||
iter.remove();
|
||||
execute(toReturn);
|
||||
fixLighting(toReturn, true);
|
||||
return toReturn;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotChunk<Chunk> next(ChunkWrapper wrap, boolean fixLighting) {
|
||||
if (!PS.get().isMainThread(Thread.currentThread())) {
|
||||
throw new IllegalStateException("Must be called from main thread!");
|
||||
}
|
||||
try {
|
||||
if (this.blocks.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
PlotChunk<Chunk> toReturn = this.blocks.remove(wrap);
|
||||
if (toReturn == null) {
|
||||
return null;
|
||||
}
|
||||
execute(toReturn);
|
||||
fixLighting(toReturn, fixLighting);
|
||||
return toReturn;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.blocks.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void regenerateChunk(String world, ChunkLoc loc) {
|
||||
World spongeWorld = SpongeUtil.getWorld(world);
|
||||
net.minecraft.world.World nmsWorld = (net.minecraft.world.World) spongeWorld;
|
||||
Optional<Chunk> chunkOpt = spongeWorld.getChunk(loc.x, 0, loc.z);
|
||||
if (chunkOpt.isPresent()) {
|
||||
try {
|
||||
Chunk spongeChunk = chunkOpt.get();
|
||||
IChunkProvider provider = nmsWorld.getChunkProvider();
|
||||
if (!(provider instanceof ChunkProviderServer)) {
|
||||
PS.debug("Not valid world generator for: " + world);
|
||||
}
|
||||
/* ChunkProviderServer chunkServer = (ChunkProviderServer) provider;
|
||||
IChunkProvider chunkProvider = chunkServer.serverChunkGenerator;
|
||||
|
||||
long pos = ChunkCoordIntPair.chunkXZ2Int(loc.x, loc.z);
|
||||
net.minecraft.world.chunk.Chunk mcChunk = (net.minecraft.world.chunk.Chunk) spongeChunk;
|
||||
if (chunkServer.chunkExists(loc.x, loc.z)) {
|
||||
mcChunk = chunkServer.loadChunk(loc.x, loc.z);
|
||||
mcChunk.onChunkUnload();
|
||||
}
|
||||
Field fieldDroppedChunksSet;
|
||||
try {
|
||||
fieldDroppedChunksSet = chunkServer.getClass().getField("droppedChunksSet");
|
||||
} catch (Throwable t) {
|
||||
fieldDroppedChunksSet = ReflectionUtils.findField(chunkServer.getClass(), Set.class);
|
||||
}
|
||||
Set<Long> set = (Set<Long>) fieldDroppedChunksSet.get(chunkServer);
|
||||
set.remove(pos);
|
||||
ReflectionUtils.findField(chunkServer.getClass(),)
|
||||
chunkServer.id2ChunkMap.remove(pos);
|
||||
mcChunk = chunkProvider.provideChunk(loc.x, loc.z);
|
||||
chunkServer.id2ChunkMap.add(pos, mcChunk);
|
||||
chunkServer.loadedChunks.add(mcChunk);
|
||||
if (mcChunk != null) {
|
||||
mcChunk.onChunkLoad();
|
||||
mcChunk.populateChunk(chunkProvider, chunkProvider, loc.x, loc.z);
|
||||
SetQueue.IMP.queue.sendChunk(world, Arrays.asList(loc));
|
||||
}
|
||||
else {
|
||||
PS.debug("CHUNK IS NULL!?");
|
||||
}*/
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be overriden by any specialized queues.
|
||||
* @param plotChunk
|
||||
*/
|
||||
public void execute(PlotChunk<Chunk> plotChunk) {
|
||||
SlowChunk sc = (SlowChunk) plotChunk;
|
||||
Chunk chunk = plotChunk.getChunk();
|
||||
chunk.loadChunk(true);
|
||||
Vector3i min = chunk.getBlockMin();
|
||||
int bx = min.getX();
|
||||
int bz = min.getZ();
|
||||
for (int i = 0; i < sc.result.length; i++) {
|
||||
PlotBlock[] result2 = sc.result[i];
|
||||
if (result2 == null) {
|
||||
continue;
|
||||
}
|
||||
for (int j = 0; j < 4096; j++) {
|
||||
int x = MainUtil.x_loc[i][j];
|
||||
int y = MainUtil.y_loc[i][j];
|
||||
int z = MainUtil.z_loc[i][j];
|
||||
PlotBlock newBlock = result2[j];
|
||||
BlockState state = SpongeUtil.getBlockState(newBlock.id, newBlock.data);
|
||||
chunk.setBlock(bx + x, y, bz + z, state, false);
|
||||
}
|
||||
}
|
||||
int[][] biomes = sc.biomes;
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
chunk.setBiome(bx + x, bz + z, SpongeUtil.getBiome(biome));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be overriden by any specialized queues.
|
||||
* @param wrap
|
||||
*/
|
||||
@Override
|
||||
public PlotChunk<Chunk> getChunk(ChunkWrapper wrap) {
|
||||
return new SlowChunk(wrap);
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be overriden by any specialized queues.
|
||||
* @param fixAll
|
||||
*/
|
||||
@Override
|
||||
public boolean fixLighting(PlotChunk<Chunk> chunk, boolean fixAll) {
|
||||
// Do nothing
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be overriden by any specialized queues.
|
||||
* @param locs
|
||||
*/
|
||||
@Override
|
||||
public void sendChunk(String world, Collection<ChunkLoc> locs) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
@ -0,0 +1,500 @@
|
||||
package com.plotsquared.sponge.util.block;
|
||||
|
||||
import com.intellectualcrafters.plot.object.PlotBlock;
|
||||
import com.intellectualcrafters.plot.object.PseudoRandom;
|
||||
import com.intellectualcrafters.plot.util.MainUtil;
|
||||
import com.intellectualcrafters.plot.util.StringMan;
|
||||
import com.intellectualcrafters.plot.util.TaskManager;
|
||||
import com.intellectualcrafters.plot.util.block.BasicLocalBlockQueue;
|
||||
import com.plotsquared.sponge.util.SpongeUtil;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityTracker;
|
||||
import net.minecraft.entity.EntityTrackerEntry;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.network.play.server.SPacketChunkData;
|
||||
import net.minecraft.network.play.server.SPacketDestroyEntities;
|
||||
import net.minecraft.server.management.PlayerChunkMap;
|
||||
import net.minecraft.util.ClassInheritanceMultiMap;
|
||||
import net.minecraft.util.IntHashMap;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
|
||||
import org.spongepowered.api.block.BlockState;
|
||||
import org.spongepowered.api.block.BlockTypes;
|
||||
import org.spongepowered.api.world.World;
|
||||
import org.spongepowered.api.world.biome.BiomeType;
|
||||
import org.spongepowered.api.world.extent.UnmodifiableBlockVolume;
|
||||
import org.spongepowered.api.world.extent.worker.MutableBlockVolumeWorker;
|
||||
import org.spongepowered.api.world.extent.worker.procedure.BlockVolumeMapper;
|
||||
|
||||
public class SpongeLocalQueue extends BasicLocalBlockQueue<char[]> {
|
||||
|
||||
public SpongeLocalQueue(String world) {
|
||||
super(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalChunk<char[]> getLocalChunk(int x, int z) {
|
||||
return new CharLocalChunk_Sponge(this, x, z) {
|
||||
// Custom stuff?
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void optimize() {
|
||||
|
||||
}
|
||||
|
||||
public World getSpongeWorld() {
|
||||
return SpongeUtil.getWorld(getWorld());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlotBlock getBlock(int x, int y, int z) {
|
||||
|
||||
World worldObj = getSpongeWorld();
|
||||
BlockState block = worldObj.getBlock(x, y, z);
|
||||
if (block == null) {
|
||||
return PlotBlock.get(0, 0);
|
||||
}
|
||||
return SpongeUtil.getPlotBlock(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(int x, int z) {
|
||||
World world = getSpongeWorld();
|
||||
Chunk nmsChunk = ((net.minecraft.world.World) world).getChunkProvider().provideChunk(x, z);
|
||||
if (nmsChunk == null || !nmsChunk.isLoaded()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ChunkPos pos = nmsChunk.getChunkCoordIntPair();
|
||||
WorldServer w = (WorldServer) nmsChunk.getWorld();
|
||||
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||
if (!chunkMap.contains(x, z)) {
|
||||
return;
|
||||
}
|
||||
EntityTracker tracker = w.getEntityTracker();
|
||||
HashSet<EntityPlayerMP> players = new HashSet<>();
|
||||
for (EntityPlayer player : w.playerEntities) {
|
||||
if (player instanceof EntityPlayerMP) {
|
||||
if (chunkMap.isPlayerWatchingChunk((EntityPlayerMP) player, x, z)) {
|
||||
players.add((EntityPlayerMP) player);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (players.size() == 0) {
|
||||
return;
|
||||
}
|
||||
HashSet<EntityTrackerEntry> entities = new HashSet<>();
|
||||
ClassInheritanceMultiMap<Entity>[] entitieSlices = nmsChunk.getEntityLists();
|
||||
IntHashMap<EntityTrackerEntry> entries = null;
|
||||
for (Field field : tracker.getClass().getDeclaredFields()) {
|
||||
if (field.getType() == IntHashMap.class) {
|
||||
field.setAccessible(true);
|
||||
entries = (IntHashMap<EntityTrackerEntry>) field.get(tracker);
|
||||
}
|
||||
}
|
||||
for (ClassInheritanceMultiMap<Entity> slice : entitieSlices) {
|
||||
if (slice == null) {
|
||||
continue;
|
||||
}
|
||||
for (Entity ent : slice) {
|
||||
EntityTrackerEntry entry = entries != null ? entries.lookup(ent.getEntityId()) : null;
|
||||
if (entry == null) {
|
||||
continue;
|
||||
}
|
||||
entities.add(entry);
|
||||
SPacketDestroyEntities packet = new SPacketDestroyEntities(ent.getEntityId());
|
||||
for (EntityPlayerMP player : players) {
|
||||
player.connection.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Send chunks
|
||||
SPacketChunkData packet = new SPacketChunkData(nmsChunk, 65535);
|
||||
for (EntityPlayerMP player : players) {
|
||||
player.connection.sendPacket(packet);
|
||||
}
|
||||
// send ents
|
||||
for (EntityTrackerEntry entry : entities) {
|
||||
try {
|
||||
TaskManager.IMP.taskLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (EntityPlayerMP player : players) {
|
||||
if (entry.isVisibleTo(player)) {
|
||||
entry.removeFromTrackedPlayers(player);
|
||||
if (entry.getTrackedEntity() != player) {
|
||||
entry.updatePlayerEntity(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 2);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fixChunkLighting(int x, int z) {
|
||||
Chunk nmsChunk = getChunk(getSpongeWorld(), x, z);
|
||||
nmsChunk.generateSkylightMap();
|
||||
}
|
||||
|
||||
public class CharLocalChunk_Sponge extends CharLocalChunk {
|
||||
public short[] count;
|
||||
public short[] air;
|
||||
public short[] relight;
|
||||
|
||||
public CharLocalChunk_Sponge(BasicLocalBlockQueue parent, int x, int z) {
|
||||
super(parent, x, z);
|
||||
this.count = new short[16];
|
||||
this.air = new short[16];
|
||||
this.relight = new short[16];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, int id, int data) {
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
int j = MainUtil.CACHE_J[y][x][z];
|
||||
char[] vs = this.blocks[i];
|
||||
if (vs == null) {
|
||||
vs = this.blocks[i] = new char[4096];
|
||||
this.count[i]++;
|
||||
} else if (vs[j] == 0) {
|
||||
this.count[i]++;
|
||||
}
|
||||
switch (id) {
|
||||
case 0:
|
||||
this.air[i]++;
|
||||
vs[j] = (char) 1;
|
||||
return;
|
||||
case 10:
|
||||
case 11:
|
||||
case 39:
|
||||
case 40:
|
||||
case 51:
|
||||
case 74:
|
||||
case 89:
|
||||
case 122:
|
||||
case 124:
|
||||
case 138:
|
||||
case 169:
|
||||
this.relight[i]++;
|
||||
case 2:
|
||||
case 4:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 30:
|
||||
case 32:
|
||||
case 37:
|
||||
case 41:
|
||||
case 42:
|
||||
case 45:
|
||||
case 46:
|
||||
case 47:
|
||||
case 48:
|
||||
case 49:
|
||||
case 55:
|
||||
case 56:
|
||||
case 57:
|
||||
case 58:
|
||||
case 60:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 73:
|
||||
case 78:
|
||||
case 79:
|
||||
case 80:
|
||||
case 81:
|
||||
case 82:
|
||||
case 83:
|
||||
case 85:
|
||||
case 87:
|
||||
case 88:
|
||||
case 101:
|
||||
case 102:
|
||||
case 103:
|
||||
case 110:
|
||||
case 112:
|
||||
case 113:
|
||||
case 121:
|
||||
case 129:
|
||||
case 133:
|
||||
case 165:
|
||||
case 166:
|
||||
case 170:
|
||||
case 172:
|
||||
case 173:
|
||||
case 174:
|
||||
case 181:
|
||||
case 182:
|
||||
case 188:
|
||||
case 189:
|
||||
case 190:
|
||||
case 191:
|
||||
case 192:
|
||||
vs[j] = (char) (id << 4);
|
||||
return;
|
||||
case 130:
|
||||
case 76:
|
||||
case 62:
|
||||
this.relight[i]++;
|
||||
case 54:
|
||||
case 146:
|
||||
case 61:
|
||||
case 65:
|
||||
case 68:
|
||||
case 50:
|
||||
if (data < 2) {
|
||||
data = 2;
|
||||
}
|
||||
default:
|
||||
vs[j] = (char) ((id << 4) + data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public char[] getIdArray(int i) {
|
||||
return this.blocks[i];
|
||||
}
|
||||
|
||||
public int getCount(int i) {
|
||||
return this.count[i];
|
||||
}
|
||||
|
||||
public int getAir(int i) {
|
||||
return this.air[i];
|
||||
}
|
||||
|
||||
public void setCount(int i, short value) {
|
||||
this.count[i] = value;
|
||||
}
|
||||
|
||||
public int getRelight(int i) {
|
||||
return this.relight[i];
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
int total = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
total += this.count[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public int getTotalRelight() {
|
||||
if (getTotalCount() == 0) {
|
||||
Arrays.fill(this.count, (short) 1);
|
||||
Arrays.fill(this.relight, Short.MAX_VALUE);
|
||||
return Short.MAX_VALUE;
|
||||
}
|
||||
int total = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
total += this.relight[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSurrounded(char[][] sections, int x, int y, int z) {
|
||||
return isSolid(getId(sections, x, y + 1, z))
|
||||
&& isSolid(getId(sections, x + 1, y - 1, z))
|
||||
&& isSolid(getId(sections, x - 1, y, z))
|
||||
&& isSolid(getId(sections, x, y, z + 1))
|
||||
&& isSolid(getId(sections, x, y, z - 1));
|
||||
}
|
||||
|
||||
public boolean isSolid(int i) {
|
||||
return i != 0 && Block.getBlockById(i).isVisuallyOpaque();
|
||||
}
|
||||
|
||||
public int getId(char[][] sections, int x, int y, int z) {
|
||||
if (x < 0 || x > 15 || z < 0 || z > 15) {
|
||||
return 1;
|
||||
}
|
||||
if (y < 0 || y > 255) {
|
||||
return 1;
|
||||
}
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
char[] section = sections[i];
|
||||
if (section == null) {
|
||||
return 0;
|
||||
}
|
||||
int j = MainUtil.CACHE_I[y][x][z];
|
||||
int combined = section[j];
|
||||
return combined >> 4;
|
||||
}
|
||||
|
||||
public boolean fixLighting(CharLocalChunk_Sponge bc, Chunk nmsChunk) {
|
||||
try {
|
||||
if (!nmsChunk.isLoaded()) {
|
||||
return false;
|
||||
}
|
||||
ExtendedBlockStorage[] sections = nmsChunk.getBlockStorageArray();
|
||||
nmsChunk.generateSkylightMap();
|
||||
net.minecraft.world.World nmsWorld = nmsChunk.getWorld();
|
||||
|
||||
int X = bc.getX() << 4;
|
||||
int Z = bc.getZ() << 4;
|
||||
|
||||
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(0, 0, 0);
|
||||
for (int j = 0; j < sections.length; j++) {
|
||||
ExtendedBlockStorage section = sections[j];
|
||||
if (section == null) {
|
||||
continue;
|
||||
}
|
||||
if ((bc.getCount(j) == 0) || ((bc.getCount(j) >= 4096) && (bc.getAir(j) == 0)) || bc.getAir(j) == 4096) {
|
||||
continue;
|
||||
}
|
||||
char[] array = bc.getIdArray(j);
|
||||
if (array != null) {
|
||||
int l = PseudoRandom.random.random(2);
|
||||
for (int k = 0; k < array.length; k++) {
|
||||
int i = array[k];
|
||||
if (i < 16) {
|
||||
continue;
|
||||
}
|
||||
short id = (short) (i >> 4);
|
||||
switch (id) { // Lighting
|
||||
default:
|
||||
if ((k & 1) == l) {
|
||||
l = 1 - l;
|
||||
continue;
|
||||
}
|
||||
case 10:
|
||||
case 11:
|
||||
case 39:
|
||||
case 40:
|
||||
case 50:
|
||||
case 51:
|
||||
case 62:
|
||||
case 74:
|
||||
case 76:
|
||||
case 89:
|
||||
case 122:
|
||||
case 124:
|
||||
case 130:
|
||||
case 138:
|
||||
case 169:
|
||||
int x = MainUtil.x_loc[j][k];
|
||||
int y = MainUtil.y_loc[j][k];
|
||||
int z = MainUtil.z_loc[j][k];
|
||||
if (isSurrounded(bc.blocks, x, y, z)) {
|
||||
continue;
|
||||
}
|
||||
pos.setPos(X + x, y, Z + z);
|
||||
nmsWorld.checkLight(pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void regenChunk(int x, int z) {
|
||||
World worldObj = getSpongeWorld();
|
||||
throw new UnsupportedOperationException("NOT SUPPORTED");
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setComponents(LocalChunk<char[]> lc) {
|
||||
setBlocks(lc);
|
||||
setBiomes(lc);
|
||||
}
|
||||
|
||||
public Chunk getChunk(World world, int x, int z) {
|
||||
net.minecraft.world.chunk.Chunk chunk = ((net.minecraft.world.World) world).getChunkProvider().provideChunk(x, z);
|
||||
if (chunk != null && !chunk.isLoaded()) {
|
||||
chunk.onChunkLoad();
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
private BlockState AIR = BlockTypes.AIR.getDefaultState();
|
||||
|
||||
public void setBlocks(LocalChunk<char[]> lc) {
|
||||
World worldObj = getSpongeWorld();
|
||||
org.spongepowered.api.world.Chunk spongeChunk = (org.spongepowered.api.world.Chunk) getChunk(worldObj, lc.getX(), lc.getZ());
|
||||
char[][] ids = ((CharLocalChunk) lc).blocks;
|
||||
MutableBlockVolumeWorker<? extends org.spongepowered.api.world.Chunk> blockWorker = spongeChunk.getBlockWorker();
|
||||
blockWorker.map(new BlockVolumeMapper() {
|
||||
@Override
|
||||
public BlockState map(UnmodifiableBlockVolume volume, int xx, int y, int zz) {
|
||||
int x = xx & 15;
|
||||
int z = zz & 15;
|
||||
int i = MainUtil.CACHE_I[y][x][z];
|
||||
char[] array = ids[i];
|
||||
if (array == null) {
|
||||
return null;
|
||||
}
|
||||
int combinedId = array[MainUtil.CACHE_J[y][x][z]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
return AIR;
|
||||
default:
|
||||
int id = combinedId >> 4;
|
||||
Block block = Block.getBlockById(id);
|
||||
int data = combinedId & 0xf;
|
||||
IBlockState ibd;
|
||||
if (data != 0) {
|
||||
ibd = block.getStateFromMeta(data);
|
||||
} else {
|
||||
ibd = block.getDefaultState();
|
||||
}
|
||||
return (BlockState) ibd;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setBiomes(LocalChunk<char[]> lc) {
|
||||
if (lc.biomes != null) {
|
||||
World worldObj = getSpongeWorld();
|
||||
int bx = lc.getX() << 4;
|
||||
int bz = lc.getX() << 4;
|
||||
String last = null;
|
||||
BiomeType biome = null;
|
||||
for (int x = 0; x < lc.biomes.length; x++) {
|
||||
String[] biomes2 = lc.biomes[x];
|
||||
if (biomes2 != null) {
|
||||
for (int y = 0; y < biomes2.length; y++) {
|
||||
String biomeStr = biomes2[y];
|
||||
if (biomeStr != null) {
|
||||
if (last == null || !StringMan.isEqual(last, biomeStr)) {
|
||||
biome = SpongeUtil.getBiome(biomeStr.toUpperCase());
|
||||
}
|
||||
worldObj.setBiome(bx, bz, biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user