mirror of https://github.com/webbukkit/dynmap.git
250 lines
7.0 KiB
Java
250 lines
7.0 KiB
Java
|
package org.dynmap.forge_1_20;
|
||
|
/**
|
||
|
* Forge specific implementation of DynmapWorld
|
||
|
*/
|
||
|
import java.util.List;
|
||
|
|
||
|
import net.minecraft.world.level.ServerLevelAccessor;
|
||
|
import net.minecraft.world.level.border.WorldBorder;
|
||
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||
|
import net.minecraft.core.BlockPos;
|
||
|
import net.minecraft.resources.ResourceKey;
|
||
|
import net.minecraft.server.level.ServerLevel;
|
||
|
import net.minecraft.world.level.Level;
|
||
|
import net.minecraft.world.level.LightLayer;
|
||
|
|
||
|
import org.dynmap.DynmapChunk;
|
||
|
import org.dynmap.DynmapLocation;
|
||
|
import org.dynmap.DynmapWorld;
|
||
|
import org.dynmap.utils.MapChunkCache;
|
||
|
import org.dynmap.utils.Polygon;
|
||
|
|
||
|
public class ForgeWorld extends DynmapWorld
|
||
|
{
|
||
|
private ServerLevelAccessor world;
|
||
|
private final boolean skylight;
|
||
|
private final boolean isnether;
|
||
|
private final boolean istheend;
|
||
|
private final String env;
|
||
|
private DynmapLocation spawnloc = new DynmapLocation();
|
||
|
private static int maxWorldHeight = 320; // Maximum allows world height
|
||
|
|
||
|
public static int getMaxWorldHeight() {
|
||
|
return maxWorldHeight;
|
||
|
}
|
||
|
public static void setMaxWorldHeight(int h) {
|
||
|
maxWorldHeight = h;
|
||
|
}
|
||
|
|
||
|
public static String getWorldName(ServerLevelAccessor w) {
|
||
|
ResourceKey<Level> rk = w.getLevel().dimension();
|
||
|
String id = rk.location().getNamespace() + "_" + rk.location().getPath();
|
||
|
if (id.equals("minecraft_overworld")) { // Overworld?
|
||
|
return w.getLevel().serverLevelData.getLevelName();
|
||
|
}
|
||
|
else if (id.equals("minecraft_the_end")) {
|
||
|
return "DIM1";
|
||
|
}
|
||
|
else if (id.equals("minecraft_the_nether")) {
|
||
|
return "DIM-1";
|
||
|
}
|
||
|
else {
|
||
|
return id;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void updateWorld(ServerLevelAccessor w) {
|
||
|
this.updateWorldHeights(w.getLevel().getHeight(), w.getLevel().dimensionType().minY(), w.getLevel().getSeaLevel());
|
||
|
}
|
||
|
|
||
|
public ForgeWorld(ServerLevelAccessor w)
|
||
|
{
|
||
|
this(getWorldName(w),
|
||
|
w.getLevel().getHeight(),
|
||
|
w.getLevel().getSeaLevel(),
|
||
|
w.getLevel().dimension() == Level.NETHER,
|
||
|
w.getLevel().dimension() == Level.END,
|
||
|
getWorldName(w),
|
||
|
w.getLevel().dimensionType().minY());
|
||
|
setWorldLoaded(w);
|
||
|
}
|
||
|
public ForgeWorld(String name, int height, int sealevel, boolean nether, boolean the_end, String deftitle, int miny)
|
||
|
{
|
||
|
super(name, (height > maxWorldHeight)?maxWorldHeight:height, sealevel, miny);
|
||
|
world = null;
|
||
|
setTitle(deftitle);
|
||
|
isnether = nether;
|
||
|
istheend = the_end;
|
||
|
skylight = !(isnether || istheend);
|
||
|
|
||
|
if (isnether)
|
||
|
{
|
||
|
env = "nether";
|
||
|
}
|
||
|
else if (istheend)
|
||
|
{
|
||
|
env = "the_end";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
env = "normal";
|
||
|
}
|
||
|
//Log.info(getName() + ": skylight=" + skylight + ", height=" + this.worldheight + ", isnether=" + isnether + ", istheend=" + istheend);
|
||
|
}
|
||
|
/* Test if world is nether */
|
||
|
@Override
|
||
|
public boolean isNether()
|
||
|
{
|
||
|
return isnether;
|
||
|
}
|
||
|
public boolean isTheEnd()
|
||
|
{
|
||
|
return istheend;
|
||
|
}
|
||
|
/* Get world spawn location */
|
||
|
@Override
|
||
|
public DynmapLocation getSpawnLocation()
|
||
|
{
|
||
|
if(world != null) {
|
||
|
BlockPos p = world.getLevel().getSharedSpawnPos();
|
||
|
spawnloc.x = p.getX();
|
||
|
spawnloc.y = p.getY();
|
||
|
spawnloc.z = p.getZ();
|
||
|
spawnloc.world = this.getName();
|
||
|
}
|
||
|
return spawnloc;
|
||
|
}
|
||
|
/* Get world time */
|
||
|
@Override
|
||
|
public long getTime()
|
||
|
{
|
||
|
if(world != null)
|
||
|
return world.getLevel().getDayTime();
|
||
|
else
|
||
|
return -1;
|
||
|
}
|
||
|
/* World is storming */
|
||
|
@Override
|
||
|
public boolean hasStorm()
|
||
|
{
|
||
|
if(world != null)
|
||
|
return world.getLevel().isRaining();
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
/* World is thundering */
|
||
|
@Override
|
||
|
public boolean isThundering()
|
||
|
{
|
||
|
if(world != null)
|
||
|
return world.getLevel().isThundering();
|
||
|
else
|
||
|
return false;
|
||
|
}
|
||
|
/* World is loaded */
|
||
|
@Override
|
||
|
public boolean isLoaded()
|
||
|
{
|
||
|
return (world != null);
|
||
|
}
|
||
|
/* Set world to unloaded */
|
||
|
@Override
|
||
|
public void setWorldUnloaded()
|
||
|
{
|
||
|
getSpawnLocation();
|
||
|
world = null;
|
||
|
}
|
||
|
/* Set world to loaded */
|
||
|
public void setWorldLoaded(ServerLevelAccessor w) {
|
||
|
world = w;
|
||
|
this.sealevel = w.getLevel().getSeaLevel(); // Read actual current sealevel from world
|
||
|
// Update lighting table
|
||
|
for (int i = 0; i < 16; i++) {
|
||
|
// Algorithm based on LightmapTextureManager.getBrightness()
|
||
|
// We can't call that method because it's client-only.
|
||
|
// This means the code below can stop being correct if Mojang ever
|
||
|
// updates the curve; in that case we should reflect the changes.
|
||
|
float value = (float) i / 15.0f;
|
||
|
float brightness = value / (4.0f - 3.0f * value);
|
||
|
this.setBrightnessTableEntry(i, brightness);
|
||
|
//Log.info(getName() + ": light " + i + " = " + light);
|
||
|
}
|
||
|
}
|
||
|
/* Get light level of block */
|
||
|
@Override
|
||
|
public int getLightLevel(int x, int y, int z)
|
||
|
{
|
||
|
if(world != null)
|
||
|
return world.getLevel().getLightEngine().getRawBrightness(new BlockPos(x, y, z), 0);
|
||
|
else
|
||
|
return -1;
|
||
|
}
|
||
|
/* Get highest Y coord of given location */
|
||
|
@Override
|
||
|
public int getHighestBlockYAt(int x, int z)
|
||
|
{
|
||
|
if(world != null) {
|
||
|
return world.getLevel().getChunk(x >> 4, z >> 4).getHeight(Heightmap.Types.MOTION_BLOCKING, x & 15, z & 15);
|
||
|
}
|
||
|
else
|
||
|
return -1;
|
||
|
}
|
||
|
/* Test if sky light level is requestable */
|
||
|
@Override
|
||
|
public boolean canGetSkyLightLevel()
|
||
|
{
|
||
|
return skylight;
|
||
|
}
|
||
|
/* Return sky light level */
|
||
|
@Override
|
||
|
public int getSkyLightLevel(int x, int y, int z)
|
||
|
{
|
||
|
if(world != null) {
|
||
|
return world.getLevel().getBrightness(LightLayer.SKY, new BlockPos(x, y, z));
|
||
|
}
|
||
|
else
|
||
|
return -1;
|
||
|
}
|
||
|
/**
|
||
|
* Get world environment ID (lower case - normal, the_end, nether)
|
||
|
*/
|
||
|
@Override
|
||
|
public String getEnvironment()
|
||
|
{
|
||
|
return env;
|
||
|
}
|
||
|
/**
|
||
|
* Get map chunk cache for world
|
||
|
*/
|
||
|
@Override
|
||
|
public MapChunkCache getChunkCache(List<DynmapChunk> chunks)
|
||
|
{
|
||
|
if (world != null) {
|
||
|
ForgeMapChunkCache c = new ForgeMapChunkCache(DynmapPlugin.plugin.sscache);
|
||
|
c.setChunks(this, chunks);
|
||
|
return c;
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
public ServerLevel getWorld()
|
||
|
{
|
||
|
return world.getLevel();
|
||
|
}
|
||
|
@Override
|
||
|
public Polygon getWorldBorder() {
|
||
|
if (world != null) {
|
||
|
WorldBorder wb = world.getWorldBorder();
|
||
|
if ((wb != null) && (wb.getSize() < 5.9E7)) {
|
||
|
Polygon p = new Polygon();
|
||
|
p.addVertex(wb.getMinX(), wb.getMinZ());
|
||
|
p.addVertex(wb.getMinX(), wb.getMaxZ());
|
||
|
p.addVertex(wb.getMaxX(), wb.getMaxZ());
|
||
|
p.addVertex(wb.getMaxX(), wb.getMinZ());
|
||
|
return p;
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
}
|