Skip to content

Commit

Permalink
Adapt the position when switching between Overworld and Nether
Browse files Browse the repository at this point in the history
Closes #51
  • Loading branch information
piegamesde committed Jul 19, 2020
1 parent 55900c4 commit f2a04c9
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ public Integer call() {
WorldRegionFolder world;
CachedRegionFolder cached;
try {
world = WorldRegionFolder.load(inputRegion, renderer);
world = WorldRegionFolder.load(inputRegion, renderer, dimension == MinecraftDimension.NETHER);
cached = CachedRegionFolder.create(world, !force, output);
} catch (IOException e) {
log.error("Could not load region folder", e);
Expand Down Expand Up @@ -340,7 +340,7 @@ public Integer call() {
WorldRegionFolder world;
CachedRegionFolder cached;
try {
world = WorldRegionFolder.load(inputRegion, renderer);
world = WorldRegionFolder.load(inputRegion, renderer, folderSettings.dimension == MinecraftDimension.NETHER);
cached = CachedRegionFolder.create(world, !folderSettings.force, settings.outputDir.resolve(folderSettings.name));
} catch (IOException e) {
log.error("Could not load region folder", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ public abstract class RegionFolder {
*/
public abstract boolean needsCaching();

/**
* Whether this region folder represents a Nether dimension or not.
*/
public abstract boolean isNether();

/**
* This {@link RegionFolder} implementation will render region files using a {@link RegionRenderer}.
* Calling {@link #render(Vector2ic)} repeatedly on the same location will render the same image
Expand All @@ -140,6 +145,7 @@ public static class WorldRegionFolder extends RegionFolder {
protected final RegionRenderer renderer;
protected LevelMetadata pins;
protected final long timestamp;
protected final boolean isNether;

/**
* @param file
Expand All @@ -154,10 +160,11 @@ public static class WorldRegionFolder extends RegionFolder {
* @throws NullPointerException
* if any of the arguments is {@code null}
*/
public WorldRegionFolder(Map<Vector2ic, Path> files, RegionRenderer renderer) {
public WorldRegionFolder(Map<Vector2ic, Path> files, RegionRenderer renderer, boolean isNether) {
this.regions = Objects.requireNonNull(files);
this.renderer = Objects.requireNonNull(renderer);
this.timestamp = System.currentTimeMillis();
this.isNether = isNether;
}

@Override
Expand Down Expand Up @@ -197,6 +204,11 @@ public boolean needsCaching() {
return true;
}

@Override
public boolean isNether() {
return isNether;
}

@Override
public Optional<LevelMetadata> getPins() {
return Optional.ofNullable(pins);
Expand All @@ -220,7 +232,7 @@ public void setPins(LevelMetadata pins) {
* @see #load(Path, MinecraftDimension, RegionRenderer)
*/
public static WorldRegionFolder load(Path world, MinecraftDimension dimension, RegionRenderer renderer, boolean loadPins) throws IOException {
WorldRegionFolder folder = load(world.resolve(dimension.getRegionPath()), renderer);
WorldRegionFolder folder = load(world.resolve(dimension.getRegionPath()), renderer, dimension == MinecraftDimension.NETHER);
if (loadPins)
folder.setPins(LevelMetadata.loadFromWorld(world, dimension));
return folder;
Expand All @@ -238,7 +250,7 @@ public static WorldRegionFolder load(Path world, MinecraftDimension dimension, R
* {@code region} and is situated inside a Minecraft world, but this is not a hard
* requirement. It has to be a directory.
*/
public static WorldRegionFolder load(Path regionFolder, RegionRenderer renderer) throws IOException {
public static WorldRegionFolder load(Path regionFolder, RegionRenderer renderer, boolean isNether) throws IOException {
Map<Vector2ic, Path> files = new HashMap<>();
try (Stream<Path> stream = Files.list(regionFolder)) {
for (Path p : (Iterable<Path>) stream::iterator) {
Expand All @@ -247,7 +259,7 @@ public static WorldRegionFolder load(Path regionFolder, RegionRenderer renderer)
files.put(new Vector2i(Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2))), p);
}
}
return new WorldRegionFolder(files, renderer);
return new WorldRegionFolder(files, renderer, isNether);
}
}

Expand All @@ -268,6 +280,7 @@ public static abstract class SavedRegionFolder<T> extends RegionFolder {
protected final Map<Vector2ic, RegionHelper> regions;
protected final Optional<LevelMetadata> pins;
protected final long timestamp;
protected final boolean isNether;

/**
* Loads a json file that contains the information about all rendered files.
Expand All @@ -282,6 +295,7 @@ protected SavedRegionFolder(T file) throws IOException {
.stream().flatMap(Collection::stream)
.collect(Collectors.toMap(r -> new Vector2i(r.x, r.z), Function.identity()));
timestamp = helper.timestamp;
isNether = helper.isNether;
}

@Override
Expand Down Expand Up @@ -318,6 +332,11 @@ public long getTimestamp() {
return timestamp;
}

@Override
public boolean isNether() {
return isNether;
}

@Override
public Optional<LevelMetadata> getPins() {
return pins;
Expand Down Expand Up @@ -470,6 +489,11 @@ public long getTimestamp() {
return world.getTimestamp();
}

@Override
public boolean isNether() {
return world.isNether();
}

/**
* Remove all information about generated structures that are not in the set
*/
Expand Down Expand Up @@ -508,7 +532,7 @@ public void save() throws IOException {
synchronized (regions) {
try (Writer writer = new OutputStreamWriter(new GZIPOutputStream(Files.newOutputStream(basePath,
StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING), 8192, true))) {
GSON.toJson(new SavedRegionHelper(regions.values(), getPins().orElse(null), getTimestamp()), writer);
GSON.toJson(new SavedRegionHelper(regions.values(), getPins().orElse(null), getTimestamp(), isNether()), writer);
writer.flush();
}
}
Expand All @@ -534,11 +558,13 @@ static class SavedRegionHelper {
Collection<RegionHelper> regions;
LevelMetadata pins;
long timestamp;
boolean isNether;

public SavedRegionHelper(Collection<RegionHelper> regions, LevelMetadata pins, long timestamp) {
public SavedRegionHelper(Collection<RegionHelper> regions, LevelMetadata pins, long timestamp, boolean isNether) {
this.regions = regions;
this.pins = pins;
this.timestamp = timestamp;
this.isNether = isNether;
}

static class RegionHelper {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import org.controlsfx.control.textfield.AutoCompletionBinding;
import org.controlsfx.control.textfield.TextFields;
import org.controlsfx.dialog.ExceptionDialog;
import org.joml.Vector2d;
import org.joml.Vector2ic;

import com.google.common.collect.Streams;
Expand Down Expand Up @@ -339,11 +340,36 @@ public ListCell<HistoryItem> call(ListView<HistoryItem> param) {

renderer.regionFolder.bind(regionFolderCached);
renderer.regionFolder.addListener((observable, previous, val) -> {
/* Reload pins */
if (val != null)
this.pins.loadWorld(val.listRegions(), val.getPins().map(pins -> Pin.convertStatic(pins, backgroundThread, renderer.viewport)).orElse(
Collections.emptySet()));
else
this.pins.loadWorld(Collections.emptyList(), Collections.emptyList());

/*
* Change zoom factor for the nether. We're not using the normal zooming API because a transition
* animation is not desired while switching worlds. Also normally, zooming is done around the mouse
* cursor, but we need it around the world's origin. So we backup the translation beforehand and
* then do the necessary calculations manually.
*/
boolean wasNether = previous != null && previous.isNether();
boolean isNether = val != null && val.isNether();
final double DELTA_ZOOM = 3; /* = ln2(8) */
if (isNether && !wasNether) {
var translation = renderer.viewport.translationProperty.get();
var oldScale = renderer.viewport.scaleProperty.get();
renderer.viewport.zoomProperty.set(renderer.viewport.zoomProperty.get() + DELTA_ZOOM);
var newScale = renderer.viewport.scaleProperty.get();
renderer.viewport.translationProperty.set(translation.mul(oldScale / newScale, new Vector2d()));
}
if (wasNether && !isNether) {
var translation = renderer.viewport.translationProperty.get();
var oldScale = renderer.viewport.scaleProperty.get();
renderer.viewport.zoomProperty.set(renderer.viewport.zoomProperty.get() - DELTA_ZOOM);
var newScale = renderer.viewport.scaleProperty.get();
renderer.viewport.translationProperty.set(translation.mul(oldScale / newScale, new Vector2d()));
}
});
renderer.getChunkMetadata().addListener((MapChangeListener<Vector2ic, Map<Vector2ic, ChunkMetadata>>) change -> {
if (change.getValueAdded() != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public Region render(Vector2ic regionPos, RegionFile file) {

WorldRegionFolder localWorld = WorldRegionFolder.load(
Paths.get(URI.create(getClass().getResource("/BlockMapWorld/region").toString())),
renderer);
renderer, false);

{
File out1 = folder.newFolder();
Expand Down Expand Up @@ -112,7 +112,7 @@ public Region render(Vector2ic regionPos, RegionFile file) {

WorldRegionFolder localWorld = WorldRegionFolder.load(
Paths.get(URI.create(getClass().getResource("/BlockMapWorld/region").toString())),
renderer);
renderer, false);

File out1 = folder.newFolder();
CachedRegionFolder cachedWorld = CachedRegionFolder.create(localWorld, true, out1.toPath());
Expand Down

0 comments on commit f2a04c9

Please sign in to comment.