Map changes

This commit is contained in:
Daniel Mills 2021-07-15 23:25:06 -04:00
parent 753b69726a
commit fff6e50702
4 changed files with 367 additions and 79 deletions

View File

@ -19,36 +19,48 @@
package com.volmit.iris.manager.gui;
import com.volmit.iris.Iris;
import com.volmit.iris.generator.IrisComplex;
import com.volmit.iris.generator.IrisEngine;
import com.volmit.iris.map.RenderType;
import com.volmit.iris.object.IrisBiome;
import com.volmit.iris.object.IrisRegion;
import com.volmit.iris.object.IrisRegistrant;
import com.volmit.iris.scaffold.engine.Engine;
import com.volmit.iris.scaffold.engine.IrisAccess;
import com.volmit.iris.scaffold.parallel.MultiBurst;
import com.volmit.iris.util.*;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.attribute.Attribute;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.MouseInputListener;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.BiFunction;
public class IrisVision extends JPanel implements MouseWheelListener, KeyListener, MouseMotionListener {
public class IrisVision extends JPanel implements MouseWheelListener, KeyListener, MouseMotionListener, MouseInputListener {
private static final long serialVersionUID = 2094606939770332040L;
private RenderType currentType = RenderType.BIOME;
private boolean help = true;
private boolean helpIgnored = false;
private boolean shift = false;
private Player player = null;
private boolean debug = false;
private boolean control = false;
private boolean eco = false;
private boolean lowtile = false;
private boolean follow = false;
private boolean alt = false;
private int posX = 0;
@ -63,6 +75,7 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
private int h = 0;
private double lx = 0;
private double lz = 0;
private KList<LivingEntity> lastEntities = new KList<>();
private double ox = 0;
private double oz = 0;
private double hx = 0;
@ -70,8 +83,10 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
private double oxp = 0;
private double ozp = 0;
private Engine engine;
private KMap<String, Long> notifications = new KMap<>();
double tfps = 240D;
int ltc = 3;
private ChronoLatch centities = new ChronoLatch(1000);
private final RollingSequence rs = new RollingSequence(512);
private final O<Integer> m = new O<>();
private int tid = 0;
@ -106,12 +121,14 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
return t;
});
private BufferedImage texture;
public IrisVision(JFrame frame) {
m.set(8);
rs.put(1);
addMouseWheelListener(this);
addMouseMotionListener(this);
addMouseListener(this);
frame.addKeyListener(this);
J.a(() -> {
J.sleep(10000);
@ -153,29 +170,114 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
return colorFunction.apply(wx, wz);
}
public void notify(String s)
{
notifications.put(s, M.ms() + 2500);
}
@Override
public void keyTyped(KeyEvent e) {
int currentMode = currentType.ordinal();
if (e.getKeyCode() == KeyEvent.VK_M) {
currentType = RenderType.values()[(currentMode+1) % RenderType.values().length];
dump();
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
shift = true;
}
if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
control = true;
}if (e.getKeyCode() == KeyEvent.VK_SEMICOLON) {
debug = true;
} if (e.getKeyCode() == KeyEvent.VK_SLASH) {
help = true;
helpIgnored = true;
} if (e.getKeyCode() == KeyEvent.VK_ALT) {
alt = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SEMICOLON) {
debug = false;
}
if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
shift = false;
}
if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
control = false;
}
if (e.getKeyCode() == KeyEvent.VK_SLASH) {
help = false;
helpIgnored = true;
} if (e.getKeyCode() == KeyEvent.VK_ALT) {
alt = false;
}
// Pushes
if (e.getKeyCode() == KeyEvent.VK_F) {
follow = !follow;
if(player != null && follow)
{
notify("Following " + player.getName() + ". Press F to disable");
}
else if(follow)
{
notify("Can't follow, no one is in the world");
follow = false;
}
else
{
notify("Follow Off");
}
return;
}
if (e.getKeyCode() == KeyEvent.VK_R) {
dump();
notify("Refreshing Chunks");
return;
}
if (e.getKeyCode() == KeyEvent.VK_P) {
lowtile = !lowtile;
dump();
notify("Rendering "+(lowtile ? "Low" : "High")+" Quality Tiles");
return;
}
if (e.getKeyCode() == KeyEvent.VK_E) {
eco = !eco;
dump();
notify("Using " + (eco ? "60" : "Uncapped") + " FPS Limit");
return;
}
if (e.getKeyCode() == KeyEvent.VK_EQUALS) {
mscale = mscale + ((0.044 * mscale) * -3);
mscale = Math.max(mscale, 0.00001);
dump();
return;
}
if (e.getKeyCode() == KeyEvent.VK_MINUS) {
mscale = mscale + ((0.044 * mscale) * 3);
mscale = Math.max(mscale, 0.00001);
dump();
return;
}
if (e.getKeyCode() == KeyEvent.VK_BACK_SLASH) {
mscale = 1D;
dump();
notify("Zoom Reset");
return;
}
int currentMode = currentType.ordinal();
for(RenderType i : RenderType.values())
{
@ -184,44 +286,16 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
{
currentType = i;
dump();
notify("Rendering " + Form.capitalizeWords(currentType.name().toLowerCase().replaceAll("\\Q_\\E", " ")));
return;
}
}
}
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
shift = true;
} else if (e.getKeyCode() == KeyEvent.VK_SEMICOLON) {
debug = true;
} else if (e.getKeyCode() == KeyEvent.VK_SLASH) {
help = true;
helpIgnored = true;
}else if (e.getKeyCode() == KeyEvent.VK_ALT) {
alt = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SEMICOLON) {
debug = false;
} else if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
shift = false;
} else if (e.getKeyCode() == KeyEvent.VK_SLASH) {
help = false;
helpIgnored = true;
}else if (e.getKeyCode() == KeyEvent.VK_ALT) {
alt = false;
}
if (e.getKeyCode() == KeyEvent.VK_F) {
Iris.info("FOLLOW TOGGLE");
follow = !follow;
if (e.getKeyCode() == KeyEvent.VK_M) {
currentType = RenderType.values()[(currentMode+1) % RenderType.values().length];
notify("Rendering " + Form.capitalizeWords(currentType.name().toLowerCase().replaceAll("\\Q_\\E", " ")));
dump();
}
}
@ -250,7 +324,7 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
e.submit(() ->
{
PrecisionStopwatch ps = PrecisionStopwatch.start();
BufferedImage b = renderer.render(x * mscale, z * mscale, div * mscale, div, currentType);
BufferedImage b = renderer.render(x * mscale, z * mscale, div * mscale, div / (lowtile ? 3 : 1), currentType);
rs.put(ps.getMilliseconds());
working.remove(key);
@ -304,41 +378,51 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
@Override
public void paint(Graphics gx) {
if (ox < oxp) {
velocity = Math.abs(ox - oxp) * 0.06;
velocity = Math.abs(ox - oxp) * 0.36;
oxp -= velocity;
}
if (ox > oxp) {
velocity = Math.abs(oxp - ox) * 0.06;
velocity = Math.abs(oxp - ox) * 0.36;
oxp += velocity;
}
if (oz < ozp) {
velocity = Math.abs(oz - ozp) * 0.06;
velocity = Math.abs(oz - ozp) * 0.36;
ozp -= velocity;
}
if (oz > ozp) {
velocity = Math.abs(ozp - oz) * 0.06;
velocity = Math.abs(ozp - oz) * 0.36;
ozp += velocity;
}
if (lx < hx) {
hx -= Math.abs(lx - hx) * 0.06;
hx -= Math.abs(lx - hx) * 0.36;
}
if (lx > hx) {
hx += Math.abs(hx - lx) * 0.06;
hx += Math.abs(hx - lx) * 0.36;
}
if (lz < hz) {
hz -= Math.abs(lz - hz) * 0.06;
hz -= Math.abs(lz - hz) * 0.36;
}
if (lz > hz) {
hz += Math.abs(hz - lz) * 0.06;
hz += Math.abs(hz - lz) * 0.36;
}
if(centities.flip())
{
J.s(() -> {
synchronized (lastEntities)
{
lastEntities.clear();
lastEntities.addAll(world.getEntitiesByClass(LivingEntity.class));
}
});
}
lowq = Math.max(Math.min((int)M.lerp(8, 28, velocity / 1000D), 28), 8);
PrecisionStopwatch p = PrecisionStopwatch.start();
Graphics2D g = (Graphics2D) gx;
@ -383,6 +467,7 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
}
}
hanleFollow();
renderOverlays(g);
if (!isVisible()) {
@ -399,12 +484,21 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
J.a(() ->
{
J.sleep(1);
J.sleep(eco ? 15 : 1);
repaint();
});
}
private void hanleFollow() {
if(follow && player != null)
{
animateTo(player.getLocation().getX(), player.getLocation().getZ());
}
}
private void renderOverlays(Graphics2D g) {
renderPlayer(g);
if(help)
{
renderOverlayHelp(g);
@ -415,8 +509,38 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
renderOverlayDebug(g);
}
renderHoverOverlay(g, shift);
renderOverlayLegend(g);
renderHoverOverlay(g, shift);
if(!notifications.isEmpty())
{
renderNotification(g);
}
}
private void renderOverlayLegend(Graphics2D g) {
KList<String> l = new KList<>();
l.add("Zoom: " + Form.pc(mscale, 0));
l.add("Blocks: " + Form.f((int)mscale * w) + " by " + Form.f((int)mscale * h));
l.add("BPP: " + Form.f(mscale, 1));
l.add("Render Mode: " + Form.capitalizeWords(currentType.name().toLowerCase().replaceAll("\\Q_\\E", " ")));
drawCardBR(g, l);
}
private void renderNotification(Graphics2D g) {
drawCardCB(g, notifications.k());
for(String i : notifications.k())
{
if(M.ms() > notifications.get(i))
{
notifications.remove(i);
}
}
}
private void renderPlayer(Graphics2D g) {
Player b = null;
for(Player i : world.getPlayers())
@ -425,35 +549,84 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
renderPosition(g, i.getLocation().getX(), i.getLocation().getZ());
}
if(follow && b != null)
synchronized (lastEntities)
{
animateTo(b.getLocation().getX(), b.getLocation().getZ());
drawCardTL(g, new KList<>("Following " + b.getName()));
double dist = Double.MAX_VALUE;
LivingEntity h = null;
for(LivingEntity i : lastEntities)
{
if(i instanceof Player)
{
continue;
}
renderMobPosition(g, i, i.getLocation().getX(), i.getLocation().getZ());
if(shift)
{
double d = i.getLocation().distanceSquared(new Location(i.getWorld(), getWorldX(hx), i.getLocation().getY(), getWorldZ(hz)));
if(d < dist)
{
dist = d;
h = i;
}
}
}
if(h != null && shift)
{
g.setColor(Color.red);
g.fillRoundRect((int)getScreenX(h.getLocation().getX()) - 10, (int)getScreenZ(h.getLocation().getZ()) - 10, 20, 20, 20, 20);
KList<String> k = new KList<>();
k.add(Form.capitalizeWords(h.getType().name().toLowerCase(Locale.ROOT).replaceAll("\\Q_\\E", " ")) + h.getEntityId());
k.add("Pos: " + h.getLocation().getBlockX() + ", " + h.getLocation().getBlockY() + ", " + h.getLocation().getBlockZ());
k.add("UUID: " + h.getUniqueId().toString());
k.add("HP: " + h.getHealth() + " / " + h.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue());
drawCardTR(g, k);
}
}
player = b;
}
private void animateTo(double wx, double wz) {
double sx = getScreenX(wx);
double sz = getScreenZ(wz);
double cx = getWorldX(getWidth()/2);
double cz = getWorldZ(getHeight()/2);
ox += (wx - cx) * 0.77;
oz += (wz - cz) * 0.77;
ox += (wx - cx);
oz += (wz - cz);
}
private void renderPosition(Graphics2D g, double x, double z)
{
g.setColor(Color.orange);
g.fillRoundRect((int)getScreenX(x) - 15, (int)getScreenZ(z) - 15, 30, 30, 15, 15);
g.setColor(Color.blue.brighter().brighter());
g.fillRoundRect((int)getScreenX(x) - 10, (int)getScreenZ(z) - 10, 20, 20, 10, 10);
if(texture != null)
{
g.drawImage(texture, (int)getScreenX(x), (int)getScreenZ(z), 66, 66, (img, infoflags, xx, xy, width, height) -> true);
}
else
{
g.setColor(Color.darkGray);
g.fillRoundRect((int)getScreenX(x) - 15, (int)getScreenZ(z) - 15, 30, 30, 15, 15);
g.setColor(Color.cyan.darker().darker());
g.fillRoundRect((int)getScreenX(x) - 10, (int)getScreenZ(z) - 10, 20, 20, 10, 10);
}
}
private void renderMobPosition(Graphics2D g, LivingEntity e, double x, double z)
{
g.setColor(Color.red.darker().darker());
g.fillRoundRect((int)getScreenX(x) - 2, (int)getScreenZ(z) - 2, 4, 4, 4, 4);
}
private void renderHoverOverlay(Graphics2D g, boolean detailed) {
IrisBiome biome = engine.getFramework().getComplex().getTrueBiomeStream().get(getWorldX(hx), getWorldZ(hz));
IrisRegion region = engine.getFramework().getComplex().getRegionStream().get(getWorldX(hx), getWorldZ(hz));
KList<String> l = new KList<>();
l.add(biome.getName());
l.add("Biome: " + biome.getName());
l.add("Region: " + region.getName() + "(" + region.getLoadKey() + ")");
if(detailed)
{
l.add("Block " + (int)getWorldX(hx) + ", " + (int)getWorldZ(hz));
@ -461,17 +634,16 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
l.add("Region " + (((int)getWorldX(hx)>>4)>>5) + ", " + (((int)getWorldZ(hz)>>4)>>5));
l.add("Key: " + biome.getLoadKey());
l.add("File: " + biome.getLoadFile());
l.add("Region: " + region.getName() + "(" + region.getLoadKey() + ")");
}
drawCardAt((float)hx, (float)hz, g, l);
drawCardAt((float)hx, (float)hz, 0, 0, g, l);
}
private void renderOverlayDebug(Graphics2D g) {
KList<String> l = new KList<>();
l.add("Velocity: " + velocity);
drawCardTL(g, l);
l.add("Velocity: " + (int)velocity);
l.add("Center Pos: " + Form.f((int)getWorldX(getWidth()/2)) + ", " + Form.f((int)getWorldZ(getHeight()/2)));
drawCardBL(g, l);
}
private void renderOverlayHelp(Graphics2D g) {
@ -480,7 +652,10 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
l.add("R to repaint the screen");
l.add("F to follow first player");
l.add("+/- to Change Zoom");
l.add("\\ to reset zoom to 1");
l.add("M to cycle render modes");
l.add("P to toggle Tile Quality Mode");
l.add("E to toggle Eco FPS Mode");
int ff = 0;
for (RenderType i : RenderType.values()) {
@ -489,18 +664,77 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
}
l.add("Shift for additional biome details (at cursor)");
l.add("Shift + Click to teleport to location");
l.add("Alt + Click to open biome in VSCode");
l.add("CTRL + Click to teleport to location");
l.add("ALT + Click to open biome in VSCode");
drawCardTL(g, l);
}
private void drawCardTL(Graphics2D g, KList<String> text)
{
drawCardAt(0, 0, g, text);
drawCardAt(0, 0, 0, 0, g, text);
}
private void drawCardAt(float x, float y, Graphics2D g, KList<String> text)
private void drawCardBR(Graphics2D g, KList<String> text)
{
drawCardAt(getWidth(), getHeight(), 1, 1, g, text);
}
private void drawCardBL(Graphics2D g, KList<String> text)
{
drawCardAt(0, getHeight(), 0, 1, g, text);
}
private void drawCardTR(Graphics2D g, KList<String> text)
{
drawCardAt(getWidth(), 0, 1, 0, g, text);
}
private void open()
{
IrisComplex complex = engine.getFramework().getComplex();
File r = null;
switch(currentType)
{
case BIOME, LAYER_LOAD, DECORATOR_LOAD, OBJECT_LOAD, HEIGHT -> r = complex.getTrueBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode();
case BIOME_LAND -> r = complex.getLandBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode();
case BIOME_SEA -> r = complex.getSeaBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode();
case REGION -> r = complex.getRegionStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode();
case CAVE_LAND -> r = complex.getCaveBiomeStream().get(getWorldX(hx), getWorldZ(hz)).openInVSCode();
}
notify("Opening " + r.getPath() + " in VSCode");
}
private void teleport()
{
J.s(() -> {
if(player != null)
{
double h = engine.getFramework().getComplex().getTrueHeightStream().get(getWorldX(hx), getWorldZ(hz));
player.teleport(new Location(player.getWorld(), getWorldX(hx), h, getWorldZ(hz)));
notify("Teleporting to " + Form.f((int)getWorldX(hx)) +", " + Form.f((int)h) + ", " + Form.f((int)getWorldZ(hz)));
}
else
{
notify("No player in world, can't teleport.");
}
});
}
private void drawCardCB(Graphics2D g, KList<String> text)
{
drawCardAt(getWidth()/2, getHeight(), 0.5, 1, g, text);
}
private void drawCardCT(Graphics2D g, KList<String> text)
{
drawCardAt(getWidth()/2, 0, 0.5, 0, g, text);
}
private void drawCardAt(float x, float y, double pushX, double pushZ, Graphics2D g, KList<String> text)
{
g.setFont(new Font("Hevetica", Font.BOLD, 16));
int h = 0;
int w = 0;
@ -513,18 +747,21 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
w += 28;
h += 28;
int cw = (int) ((w+26) * pushX);
int ch = (int) ((h+26) * pushZ);
g.setColor(Color.darkGray);
g.fillRect((int)x + 7 + 2, (int)y + 7 + 2, w + 7, h + 7); // Shadow
g.fillRect((int)x + 7 + 2-cw , (int)y + 7 + 2-ch, w + 7, h + 7); // Shadow
g.setColor(Color.gray);
g.fillRect((int)x + 7 + 1, (int)y + 7 + 1, w + 7, h + 7); // Shadow
g.fillRect((int)x + 7 + 1-cw, (int)y + 7 + 1-ch, w + 7, h + 7); // Shadow
g.setColor(Color.white);
g.fillRect((int)x + 7, (int)y + 7, w + 7, h + 7);
g.fillRect((int)x + 7-cw, (int)y + 7-ch, w + 7, h + 7);
g.setColor(Color.black);
int m = 0;
for(String i : text)
{
g.drawString(i, x + 14, y + 14 + (++m * g.getFontMetrics().getHeight()));
g.drawString(i, x + 14-cw, y + 14 -ch + (++m * g.getFontMetrics().getHeight()));
}
}
@ -541,6 +778,7 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
if (file != null) {
try {
nv.texture = ImageIO.read(file);
frame.setIconImage(ImageIO.read(file));
} catch (IOException e) {Iris.reportError(e);
@ -565,4 +803,37 @@ public class IrisVision extends JPanel implements MouseWheelListener, KeyListene
mscale = mscale + ((0.044 * mscale) * notches);
mscale = Math.max(mscale, 0.00001);
}
@Override
public void mouseClicked(MouseEvent e) {
if(control)
{
teleport();
}
else if(alt)
{
open();
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}

View File

@ -18,9 +18,11 @@
package com.volmit.iris.object;
import com.volmit.iris.Iris;
import com.volmit.iris.manager.IrisDataManager;
import lombok.Data;
import java.awt.*;
import java.io.File;
@Data
@ -30,4 +32,15 @@ public class IrisRegistrant {
private transient String loadKey;
private transient File loadFile;
public File openInVSCode()
{
try {
Desktop.getDesktop().open(getLoadFile());
} catch (Throwable e) {
Iris.reportError(e);
}
return getLoadFile();
}
}

View File

@ -43,7 +43,7 @@ public class HunkRegionSlice<T> {
private final String key;
private final KMap<ChunkPosition, Hunk<T>> loadedChunks;
private final KMap<ChunkPosition, Long> lastUse;
private final KList<ChunkPosition> save;
private final KSet<ChunkPosition> save;
private final int height;
public HunkRegionSlice(int height, Function3<Integer, Integer, Integer, Hunk<T>> factory, HunkIOAdapter<T> adapter, CompoundTag compound, String key) {
@ -53,7 +53,7 @@ public class HunkRegionSlice<T> {
this.factory = factory;
this.adapter = adapter;
this.compound = compound;
this.save = new KList<>();
this.save = new KSet<>();
this.key = key;
this.lastUse = new KMap<>();
}
@ -246,7 +246,7 @@ public class HunkRegionSlice<T> {
public Hunk<T> getRW(int x, int z) {
return lock.withResult(x, z, () -> {
save.addIfMissing(new ChunkPosition(x, z));
save.add(new ChunkPosition(x, z));
return get(x, z);
});
}

View File

@ -39,4 +39,8 @@ public class KSet<T> extends HashSet<T> {
public KSet(int initialCapacity) {
super(initialCapacity);
}
public KSet<T> copy() {
return new KSet<T>(this);
}
}