Splits Gate into Gate, GateLayout and GateHandler, and creates a new portal package with portal related classes

This commit is contained in:
Kristian Knarvik 2021-02-22 17:01:47 +01:00
parent c422cb9ea9
commit fb70b8bc75
30 changed files with 749 additions and 324 deletions

View File

@ -202,9 +202,12 @@ public class BlockLocation extends Location {
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) return true; if (this == obj) {
if (obj == null) return false; return true;
if (getClass() != obj.getClass()) return false; }
if (obj == null || getClass() != obj.getClass()) {
return false;
}
BlockLocation blockLocation = (BlockLocation) obj; BlockLocation blockLocation = (BlockLocation) obj;

View File

@ -4,9 +4,9 @@ package net.knarcraft.stargate;
* This stores a block location as a vector relative to a position * This stores a block location as a vector relative to a position
* *
* <p>A relative block vector stores a vector relative to some origin. The origin in this plugin is usually the * <p>A relative block vector stores a vector relative to some origin. The origin in this plugin is usually the
* top-left block of a gate. The right is therefore the distance from the top-left corner towards the top-right corner. * top-left block of a gate (top-left when looking at the side with the sign). The right is therefore the distance
* Depth is the distance from the top-left corner to the bottom-left corner. Distance is the distance outward from the * from the top-left corner towards the top-right corner. Depth is the distance from the top-left corner to the
* gate.</p> * bottom-left corner. Distance is the distance outward from the gate.</p>
*/ */
public class RelativeBlockVector { public class RelativeBlockVector {
@ -56,12 +56,15 @@ public class RelativeBlockVector {
@Override @Override
public String toString() { public String toString() {
return String.format("right = %d, depth = %d, distance = %d", right, depth, distance); return String.format("(right = %d, depth = %d, distance = %d)", right, depth, distance);
} }
@Override @Override
public boolean equals(Object other) { public boolean equals(Object other) {
if (!(other instanceof RelativeBlockVector)) { if (other == this) {
return true;
}
if (other == null || this.getClass() != other.getClass()) {
return false; return false;
} }
RelativeBlockVector otherVector = (RelativeBlockVector) other; RelativeBlockVector otherVector = (RelativeBlockVector) other;

View File

@ -10,6 +10,11 @@ import net.knarcraft.stargate.listener.PlayerEventsListener;
import net.knarcraft.stargate.listener.PluginEventListener; import net.knarcraft.stargate.listener.PluginEventListener;
import net.knarcraft.stargate.listener.VehicleEventListener; import net.knarcraft.stargate.listener.VehicleEventListener;
import net.knarcraft.stargate.listener.WorldEventListener; import net.knarcraft.stargate.listener.WorldEventListener;
import net.knarcraft.stargate.portal.Gate;
import net.knarcraft.stargate.portal.GateHandler;
import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.portal.PortalHandler;
import net.knarcraft.stargate.portal.PortalOption;
import net.knarcraft.stargate.thread.BlockPopulatorThread; import net.knarcraft.stargate.thread.BlockPopulatorThread;
import net.knarcraft.stargate.thread.StarGateThread; import net.knarcraft.stargate.thread.StarGateThread;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -561,8 +566,8 @@ public class Stargate extends JavaPlugin {
} }
} }
getServer().getScheduler().scheduleSyncRepeatingTask(this, new StarGateThread(), 0L, 100L); getServer().getScheduler().runTaskTimer(this, new StarGateThread(), 0L, 100L);
getServer().getScheduler().scheduleSyncRepeatingTask(this, new BlockPopulatorThread(), 0L, 1L); getServer().getScheduler().runTaskTimer(this, new BlockPopulatorThread(), 0L, 100L);
this.registerCommands(); this.registerCommands();
} }
@ -626,8 +631,8 @@ public class Stargate extends JavaPlugin {
} }
public void loadGates() { public void loadGates() {
Gate.loadGates(gateFolder); GateHandler.loadGates(gateFolder);
log.info(Stargate.getString("prefix") + "Loaded " + Gate.getGateCount() + " gate layouts"); log.info(Stargate.getString("prefix") + "Loaded " + GateHandler.getGateCount() + " gate layouts");
} }
public void loadAllPortals() { public void loadAllPortals() {
@ -688,7 +693,7 @@ public class Stargate extends JavaPlugin {
openList.clear(); openList.clear();
managedWorlds.clear(); managedWorlds.clear();
PortalHandler.clearGates(); PortalHandler.clearGates();
Gate.clearGates(); GateHandler.clearGates();
// Store the old Bungee enabled value // Store the old Bungee enabled value
boolean oldEnableBungee = enableBungee; boolean oldEnableBungee = enableBungee;

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.event; package net.knarcraft.stargate.event;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.event; package net.knarcraft.stargate.event;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.event; package net.knarcraft.stargate.event;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.event; package net.knarcraft.stargate.event;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.event; package net.knarcraft.stargate.event;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.event; package net.knarcraft.stargate.event;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.event; package net.knarcraft.stargate.event;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import org.bukkit.event.Cancellable; import org.bukkit.event.Cancellable;
import org.bukkit.event.Event; import org.bukkit.event.Event;

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.event; package net.knarcraft.stargate.event;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.event; package net.knarcraft.stargate.event;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
/** /**

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.event; package net.knarcraft.stargate.event;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;

View File

@ -1,7 +1,7 @@
package net.knarcraft.stargate.listener; package net.knarcraft.stargate.listener;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.portal.PortalHandler;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.event.StargateDestroyEvent; import net.knarcraft.stargate.event.StargateDestroyEvent;
import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EconomyHelper;

View File

@ -1,7 +1,7 @@
package net.knarcraft.stargate.listener; package net.knarcraft.stargate.listener;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.portal.PortalHandler;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;

View File

@ -1,8 +1,8 @@
package net.knarcraft.stargate.listener; package net.knarcraft.stargate.listener;
import net.knarcraft.stargate.BlockLocation; import net.knarcraft.stargate.BlockLocation;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.portal.PortalHandler;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.utility.BungeeHelper; import net.knarcraft.stargate.utility.BungeeHelper;
import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EconomyHelper;

View File

@ -1,7 +1,7 @@
package net.knarcraft.stargate.listener; package net.knarcraft.stargate.listener;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.portal.PortalHandler;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EconomyHelper;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.listener; package net.knarcraft.stargate.listener;
import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.portal.PortalHandler;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;

View File

@ -0,0 +1,300 @@
package net.knarcraft.stargate.portal;
import net.knarcraft.stargate.BlockLocation;
import net.knarcraft.stargate.EconomyHandler;
import net.knarcraft.stargate.Stargate;
import org.bukkit.Material;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
/**
* A gate describes the physical structure of a stargate
*
* <p>While the portal class represents a portal in space, the Gate class represents the physical gate/portal entrance.</p>
*/
public class Gate {
private final String filename;
private final GateLayout layout;
private final HashMap<Character, Material> types;
//Gate materials
private Material portalOpenBlock;
private Material portalClosedBlock;
private Material portalButton;
// Economy information
private int useCost;
private int createCost;
private int destroyCost;
private boolean toOwner;
/**
* Instantiates a new gate
*
* @param filename <p>The name of the gate which equal the name of the file</p>
* @param layout <p>The character layout defined in the gate file</p>
* @param types <p>The block types the different layout characters represent</p>
* @param portalOpenBlock <p>The material to set the non-frame to when the portal is open</p>
* @param portalClosedBlock <p>The material to set the non-frame to when the portal is closed</p>
* @param portalButton <p>The material to use for the portal button</p>
* @param useCost <p>The cost of using a portal with this gate layout (-1 to disable)</p>
* @param createCost <p>The cost of creating a portal with this gate layout (-1 to disable)</p>
* @param destroyCost <p>The cost of destroying a portal with this gate layout (-1 to disable)</p>
* @param toOwner <p>Whether any payment should go to the owner of the gate, as opposed to just disappearing</p>
*/
public Gate(String filename, GateLayout layout, HashMap<Character, Material> types, Material portalOpenBlock,
Material portalClosedBlock, Material portalButton, int useCost, int createCost, int destroyCost,
boolean toOwner) {
this.filename = filename;
this.layout = layout;
this.types = types;
this.portalOpenBlock = portalOpenBlock;
this.portalClosedBlock = portalClosedBlock;
this.portalButton = portalButton;
this.useCost = useCost;
this.createCost = createCost;
this.destroyCost = destroyCost;
this.toOwner = toOwner;
}
/**
* Gets the layout of this gate
*
* @return <p>The layout of this gate</p>
*/
public GateLayout getLayout() {
return layout;
}
/**
* Gets the material types each layout character represents
*
* @return <p>The material types each layout character represents</p>
*/
public HashMap<Character, Material> getTypes() {
return types;
}
public Material getControlBlock() {
return types.get('-');
}
public String getFilename() {
return filename;
}
public Material getPortalOpenBlock() {
return portalOpenBlock;
}
public void setPortalOpenBlock(Material type) {
portalOpenBlock = type;
}
public Material getPortalClosedBlock() {
return portalClosedBlock;
}
public void setPortalClosedBlock(Material type) {
portalClosedBlock = type;
}
public Material getPortalButton() {
return portalButton;
}
public int getUseCost() {
if (useCost < 0) return EconomyHandler.useCost;
return useCost;
}
public Integer getCreateCost() {
if (createCost < 0) return EconomyHandler.createCost;
return createCost;
}
public Integer getDestroyCost() {
if (destroyCost < 0) return EconomyHandler.destroyCost;
return destroyCost;
}
public Boolean getToOwner() {
return toOwner;
}
public boolean matches(BlockLocation topLeft, int modX, int modZ) {
return matches(topLeft, modX, modZ, false);
}
public boolean matches(BlockLocation topLeft, int modX, int modZ, boolean onCreate) {
HashMap<Character, Material> portalTypes = new HashMap<>(types);
Character[][] layout = this.layout.getLayout();
for (int y = 0; y < layout.length; y++) {
for (int x = 0; x < layout[y].length; x++) {
Character key = layout[y][x];
if (key.equals(GateHandler.getEntranceCharacter()) || key.equals(GateHandler.getExitCharacter())) {
if (Stargate.ignoreEntrance) {
continue;
}
Material type = topLeft.modRelative(x, y, 0, modX, 1, modZ).getType();
// Ignore entrance if it's air and we're creating a new gate
if (onCreate && type == Material.AIR) {
continue;
}
if (type != portalClosedBlock && type != portalOpenBlock) {
Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type);
return false;
}
} else if (!key.equals(GateHandler.getAnythingCharacter())) {
Material id = portalTypes.get(key);
if (id == null) {
portalTypes.put(key, topLeft.modRelative(x, y, 0, modX, 1, modZ).getType());
} else if (topLeft.modRelative(x, y, 0, modX, 1, modZ).getType() != id) {
Stargate.debug("Gate::Matches", "Block Type Mismatch: " + topLeft.modRelative(x, y, 0, modX, 1, modZ).getType() + " != " + id);
return false;
}
}
}
}
return true;
}
/**
* Saves this gate to a file
*
* <p>This method will save the gate to its filename in the given folder.</p>
*
* @param gateFolder <p>The folder to save the gate file in</p>
*/
public void save(String gateFolder) {
try {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(gateFolder + filename));
writeConfig(bufferedWriter, "portal-open", portalOpenBlock.name());
writeConfig(bufferedWriter, "portal-closed", portalClosedBlock.name());
writeConfig(bufferedWriter, "button", portalButton.name());
//Save the values necessary for economy
saveEconomyValues(bufferedWriter);
//Store type material type to use for frame blocks
saveFrameBlockTypes(bufferedWriter);
bufferedWriter.newLine();
//Save the layout
layout.save(bufferedWriter);
bufferedWriter.close();
} catch (IOException ex) {
Stargate.log.log(Level.SEVERE, "Could not save Gate " + filename + " - " + ex.getMessage());
}
}
/**
* Saves current economy related values using a buffered writer
*
* @param bufferedWriter <p>The buffered writer to write to</p>
* * @throws IOException <p>If unable to write to the buffered writer</p>
*/
private void saveEconomyValues(BufferedWriter bufferedWriter) throws IOException {
if (useCost != -1) {
writeConfig(bufferedWriter, "usecost", useCost);
}
if (createCost != -1) {
writeConfig(bufferedWriter, "createcost", createCost);
}
if (destroyCost != -1) {
writeConfig(bufferedWriter, "destroycost", destroyCost);
}
writeConfig(bufferedWriter, "toowner", toOwner);
}
/**
* Saves the types of blocks used for the gate frame/border using a buffered writer
*
* @param bufferedWriter <p>The buffered writer to write to</p>
* @throws IOException <p>If unable to write to the buffered writer</p>
*/
private void saveFrameBlockTypes(BufferedWriter bufferedWriter) throws IOException {
for (Map.Entry<Character, Material> entry : types.entrySet()) {
Character type = entry.getKey();
Material value = entry.getValue();
// Skip control values
if (type.equals(GateHandler.getAnythingCharacter()) ||
type.equals(GateHandler.getEntranceCharacter()) ||
type.equals(GateHandler.getExitCharacter())) {
continue;
}
bufferedWriter.append(type);
bufferedWriter.append('=');
if (value != null) {
bufferedWriter.append(value.toString());
}
bufferedWriter.newLine();
}
}
/**
* Writes an integer to a config
*
* @param bufferedWriter <p>The buffered writer to write the config to</p>
* @param key <p>The config key to save</p>
* @param value <p>The value of the config key</p>
* @throws IOException <p>If unable to write to the buffered writer</p>
*/
private void writeConfig(BufferedWriter bufferedWriter, String key, int value) throws IOException {
writeConfig(bufferedWriter, "%s=%d", key, value);
}
/**
* Writes a boolean to a config
*
* @param bufferedWriter <p>The buffered writer to write the config to</p>
* @param key <p>The config key to save</p>
* @param value <p>The value of the config key</p>
* @throws IOException <p>If unable to write to the buffered writer</p>
*/
private void writeConfig(BufferedWriter bufferedWriter, String key, boolean value) throws IOException {
writeConfig(bufferedWriter, "%s=%b", key, value);
}
/**
* Writes a string to a config
*
* @param bufferedWriter <p>The buffered writer to write the config to</p>
* @param key <p>The config key to save</p>
* @param value <p>The value of the config key</p>
* @throws IOException <p>If unable to write to the buffered writer</p>
*/
private void writeConfig(BufferedWriter bufferedWriter, String key, String value) throws IOException {
writeConfig(bufferedWriter, "%s=%s", key, value);
}
/**
* Writes a formatted string to a buffered writer
*
* @param bufferedWriter <p>The buffered writer to write the formatted string to</p>
* @param format <p>The format to use</p>
* @param key <p>The config key to save</p>
* @param value <p>The config value to save</p>
* @throws IOException <p>If unable to write to the buffered writer</p>
*/
private void writeConfig(BufferedWriter bufferedWriter, String format, String key, Object value) throws IOException {
bufferedWriter.append(String.format(format, key, value));
bufferedWriter.newLine();
}
}

View File

@ -1,54 +1,56 @@
package net.knarcraft.stargate; package net.knarcraft.stargate.portal;
import net.knarcraft.stargate.EconomyHandler;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.utility.MaterialHelper; import net.knarcraft.stargate.utility.MaterialHelper;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import java.io.BufferedWriter;
import java.io.File; import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Scanner; import java.util.Scanner;
import java.util.logging.Level; import java.util.logging.Level;
public class Gate { public class GateHandler {
private static final Character ANYTHING = ' '; private static final Character ANYTHING = ' ';
private static final Character ENTRANCE = '.'; private static final Character ENTRANCE = '.';
private static final Character EXIT = '*'; private static final Character EXIT = '*';
private static Material defaultPortalBlockOpen = Material.NETHER_PORTAL;
private static Material defaultPortalBlockClosed = Material.AIR;
private static Material defaultButton = Material.STONE_BUTTON;
private static final HashMap<String, Gate> gates = new HashMap<>(); private static final HashMap<String, Gate> gates = new HashMap<>();
private static final HashMap<Material, List<Gate>> controlBlocks = new HashMap<>(); private static final HashMap<Material, List<Gate>> controlBlocks = new HashMap<>();
private static final HashSet<Material> frameBlocks = new HashSet<>(); private static final HashSet<Material> frameBlocks = new HashSet<>();
private final String filename; private GateHandler() {
private final Character[][] layout;
private final HashMap<Character, Material> types;
private final HashMap<RelativeBlockVector, Integer> exits = new HashMap<>();
private RelativeBlockVector[] entrances = new RelativeBlockVector[0];
private RelativeBlockVector[] border = new RelativeBlockVector[0];
private RelativeBlockVector[] controls = new RelativeBlockVector[0];
private RelativeBlockVector exitBlock = null;
private Material portalBlockOpen = Material.NETHER_PORTAL;
private Material portalBlockClosed = Material.AIR;
private Material button = Material.STONE_BUTTON;
// Economy information }
private int useCost = -1;
private int createCost = -1;
private int destroyCost = -1;
private boolean toOwner = false;
public Gate(String filename, Character[][] layout, HashMap<Character, Material> types) { /**
this.filename = filename; * Gets the character used for blocks that are not part of the gate
this.layout = layout; *
this.types = types; * @return <p>The character used for blocks that are not part of the gate</p>
*/
public static Character getAnythingCharacter() {
return ANYTHING;
}
populateCoordinates(); /**
* Gets the character used for defining the entrance
*
* @return <p>The character used for defining the entrance</p>
*/
public static Character getEntranceCharacter() {
return ENTRANCE;
}
public static Character getExitCharacter() {
return EXIT;
} }
public static void registerGate(Gate gate) { public static void registerGate(Gate gate) {
@ -64,17 +66,11 @@ public class Gate {
} }
public static Gate loadGate(File file) { public static Gate loadGate(File file) {
Scanner scanner = null; try (Scanner scanner = new Scanner(file)) {
try {
scanner = new Scanner(file);
return loadGate(file.getName(), file.getParent(), scanner); return loadGate(file.getName(), file.getParent(), scanner);
} catch (Exception ex) { } catch (Exception ex) {
Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage()); Stargate.log.log(Level.SEVERE, "Could not load Gate " + file.getName() + " - " + ex.getMessage());
return null; return null;
} finally {
if (scanner != null) {
scanner.close();
}
} }
} }
@ -144,6 +140,7 @@ public class Gate {
Character[][] layout = new Character[design.size()][cols]; Character[][] layout = new Character[design.size()][cols];
//y = relative line number of layout file
for (int y = 0; y < design.size(); y++) { for (int y = 0; y < design.size(); y++) {
List<Character> row = design.get(y); List<Character> row = design.get(y);
Character[] result = new Character[cols]; Character[] result = new Character[cols];
@ -159,22 +156,25 @@ public class Gate {
layout[y] = result; layout[y] = result;
} }
Gate gate = new Gate(fileName, layout, types); Material portalOpenBlock = readConfig(config, fileName, "portal-open", defaultPortalBlockOpen);
Material portalClosedBlock = readConfig(config, fileName, "portal-closed", defaultPortalBlockClosed);
Material portalButton = readConfig(config, fileName, "button", defaultButton);
int useCost = readConfig(config, fileName, "usecost", -1);
int createCost = readConfig(config, fileName, "createcost", -1);
int destroyCost = readConfig(config, fileName, "destroycost", -1);
boolean toOwner = (config.containsKey("toowner") ? Boolean.valueOf(config.get("toowner")) : EconomyHandler.toOwner);
gate.portalBlockOpen = readConfig(config, fileName, "portal-open", gate.portalBlockOpen); Gate gate = new Gate(fileName, new GateLayout(layout), types, portalOpenBlock, portalClosedBlock, portalButton, useCost,
gate.portalBlockClosed = readConfig(config, fileName, "portal-closed", gate.portalBlockClosed); createCost, destroyCost, toOwner);
gate.button = readConfig(config, fileName, "button", gate.button);
gate.useCost = readConfig(config, fileName, "usecost", -1);
gate.destroyCost = readConfig(config, fileName, "destroycost", -1);
gate.createCost = readConfig(config, fileName, "createcost", -1);
gate.toOwner = (config.containsKey("toowner") ? Boolean.valueOf(config.get("toowner")) : EconomyHandler.toOwner);
if (gate.getControls().length != 2) {
if (gate.getLayout().getControls().length != 2) {
Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gates must have exactly 2 control points."); Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gates must have exactly 2 control points.");
return null; return null;
} }
if (!MaterialHelper.isButtonCompatible(gate.button)) { if (!MaterialHelper.isButtonCompatible(gate.getPortalButton())) {
Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gate button must be a type of button."); Stargate.log.log(Level.SEVERE, "Could not load Gate " + fileName + " - Gate button must be a type of button.");
return null; return null;
} }
@ -341,227 +341,4 @@ public class Gate {
frameBlocks.clear(); frameBlocks.clear();
} }
private void populateCoordinates() {
List<RelativeBlockVector> entranceList = new ArrayList<>();
List<RelativeBlockVector> borderList = new ArrayList<>();
List<RelativeBlockVector> controlList = new ArrayList<>();
RelativeBlockVector[] relativeExits = new RelativeBlockVector[layout[0].length];
int[] exitDepths = new int[layout[0].length];
RelativeBlockVector lastExit = null;
for (int y = 0; y < layout.length; y++) {
for (int x = 0; x < layout[y].length; x++) {
Character key = layout[y][x];
if (key.equals('-')) {
controlList.add(new RelativeBlockVector(x, y, 0));
}
if (key.equals(ENTRANCE) || key.equals(EXIT)) {
entranceList.add(new RelativeBlockVector(x, y, 0));
exitDepths[x] = y;
if (key.equals(EXIT)) {
this.exitBlock = new RelativeBlockVector(x, y, 0);
}
} else if (!key.equals(ANYTHING)) {
borderList.add(new RelativeBlockVector(x, y, 0));
}
}
}
for (int x = 0; x < exitDepths.length; x++) {
relativeExits[x] = new RelativeBlockVector(x, exitDepths[x], 0);
}
for (int x = relativeExits.length - 1; x >= 0; x--) {
if (relativeExits[x] != null) {
lastExit = relativeExits[x];
} else {
relativeExits[x] = lastExit;
}
if (exitDepths[x] > 0) this.exits.put(relativeExits[x], x);
}
this.entrances = entranceList.toArray(this.entrances);
this.border = borderList.toArray(this.border);
this.controls = controlList.toArray(this.controls);
}
public void save(String gateFolder) {
try {
BufferedWriter bw = new BufferedWriter(new FileWriter(gateFolder + filename));
writeConfig(bw, "portal-open", portalBlockOpen.name());
writeConfig(bw, "portal-closed", portalBlockClosed.name());
writeConfig(bw, "button", button.name());
if (useCost != -1)
writeConfig(bw, "usecost", useCost);
if (createCost != -1)
writeConfig(bw, "createcost", createCost);
if (destroyCost != -1)
writeConfig(bw, "destroycost", destroyCost);
writeConfig(bw, "toowner", toOwner);
for (Map.Entry<Character, Material> entry : types.entrySet()) {
Character type = entry.getKey();
Material value = entry.getValue();
// Skip control values
if (type.equals(ANYTHING) || type.equals(ENTRANCE) || type.equals(EXIT)) {
continue;
}
bw.append(type);
bw.append('=');
if (value != null) {
bw.append(value.toString());
}
bw.newLine();
}
bw.newLine();
for (Character[] aLayout : layout) {
for (Character symbol : aLayout) {
bw.append(symbol);
}
bw.newLine();
}
bw.close();
} catch (IOException ex) {
Stargate.log.log(Level.SEVERE, "Could not save Gate " + filename + " - " + ex.getMessage());
}
}
private void writeConfig(BufferedWriter bw, String key, int value) throws IOException {
bw.append(String.format("%s=%d", key, value));
bw.newLine();
}
private void writeConfig(BufferedWriter bw, String key, boolean value) throws IOException {
bw.append(String.format("%s=%b", key, value));
bw.newLine();
}
private void writeConfig(BufferedWriter bw, String key, String value) throws IOException {
bw.append(String.format("%s=%s", key, value));
bw.newLine();
}
public Character[][] getLayout() {
return layout;
}
public HashMap<Character, Material> getTypes() {
return types;
}
public RelativeBlockVector[] getEntrances() {
return entrances;
}
public RelativeBlockVector[] getBorder() {
return border;
}
public RelativeBlockVector[] getControls() {
return controls;
}
public HashMap<RelativeBlockVector, Integer> getExits() {
return exits;
}
public RelativeBlockVector getExit() {
return exitBlock;
}
public Material getControlBlock() {
return types.get('-');
}
public String getFilename() {
return filename;
}
public Material getPortalBlockOpen() {
return portalBlockOpen;
}
public void setPortalBlockOpen(Material type) {
portalBlockOpen = type;
}
public Material getPortalBlockClosed() {
return portalBlockClosed;
}
public void setPortalBlockClosed(Material type) {
portalBlockClosed = type;
}
public Material getButton() {
return button;
}
public int getUseCost() {
if (useCost < 0) return EconomyHandler.useCost;
return useCost;
}
public Integer getCreateCost() {
if (createCost < 0) return EconomyHandler.createCost;
return createCost;
}
public Integer getDestroyCost() {
if (destroyCost < 0) return EconomyHandler.destroyCost;
return destroyCost;
}
public Boolean getToOwner() {
return toOwner;
}
public boolean matches(BlockLocation topLeft, int modX, int modZ) {
return matches(topLeft, modX, modZ, false);
}
public boolean matches(BlockLocation topLeft, int modX, int modZ, boolean onCreate) {
HashMap<Character, Material> portalTypes = new HashMap<>(types);
for (int y = 0; y < layout.length; y++) {
for (int x = 0; x < layout[y].length; x++) {
Character key = layout[y][x];
if (key.equals(ENTRANCE) || key.equals(EXIT)) {
if (Stargate.ignoreEntrance) {
continue;
}
Material type = topLeft.modRelative(x, y, 0, modX, 1, modZ).getType();
// Ignore entrance if it's air and we're creating a new gate
if (onCreate && type == Material.AIR) {
continue;
}
if (type != portalBlockClosed && type != portalBlockOpen) {
Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type);
return false;
}
} else if (!key.equals(ANYTHING)) {
Material id = portalTypes.get(key);
if (id == null) {
portalTypes.put(key, topLeft.modRelative(x, y, 0, modX, 1, modZ).getType());
} else if (topLeft.modRelative(x, y, 0, modX, 1, modZ).getType() != id) {
Stargate.debug("Gate::Matches", "Block Type Mismatch: " + topLeft.modRelative(x, y, 0, modX, 1, modZ).getType() + " != " + id);
return false;
}
}
}
}
return true;
}
} }

View File

@ -0,0 +1,202 @@
package net.knarcraft.stargate.portal;
import net.knarcraft.stargate.RelativeBlockVector;
import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* The gate layout describes where every part of the gate should be
*
* <p>The gate layout parses a layout described by a Character matrix and stores the different parts of the gate as
* relative block vectors.</p>
*/
public class GateLayout {
private Character [][] layout;
private final HashMap<RelativeBlockVector, Integer> exits = new HashMap<>();
private RelativeBlockVector[] entrances = new RelativeBlockVector[0];
private RelativeBlockVector[] border = new RelativeBlockVector[0];
private RelativeBlockVector[] controls = new RelativeBlockVector[0];
private RelativeBlockVector exitBlock = null;
/**
* Instantiates a new gate layout
*
* @param layout <p>A character array describing the layout</p>
*/
public GateLayout(Character[][] layout) {
this.layout = layout;
readLayout();
}
/**
* Gets the character array describing this layout
*
* @return <p>The character array describing this layout</p>
*/
public Character[][] getLayout() {
return this.layout;
}
/**
* Gets the locations of entrances for this gate
*
* @return <p>The locations of entrances for this gate</p>
*/
public RelativeBlockVector[] getEntrances() {
return entrances;
}
/**
* Gets the locations of border blocks for the gate described by this layout
*
* <p>A border block is basically any block of the frame. In terms of the nether gate, the border blocks are every
* block of the gate that's not air when the gate is closed. The sign and button are not border blocks.</p>
*
* @return <p>The locations of border blocks for this gate</p>
*/
public RelativeBlockVector[] getBorder() {
return border;
}
/**
* Gets the exit block defined in the layout
*
* @return <p>The exit block defined in the layout</p>
*/
public RelativeBlockVector getExit() {
return exitBlock;
}
/**
* Gets other possible exits of the gate
*
* @return <p>Other possible gate exits</p>
*/
public HashMap<RelativeBlockVector, Integer> getExits() {
return exits;
}
/**
* Gets the locations of the control blocks for this gate
*
* <p>The control blocks are the blocks where a sign can be placed to create a portal.</p>
*
* @return <p>The locations of the control blocks for this gate</p>
*/
public RelativeBlockVector[] getControls() {
return controls;
}
/**
* Saves the gate layout using a buffered writer
*
* @param bufferedWriter <p>The buffered writer to write to</p>
* @throws IOException <p>If unable to write to the buffered writer</p>
*/
public void save(BufferedWriter bufferedWriter) throws IOException {
for (Character[] line : this.layout) {
for (Character symbol : line) {
bufferedWriter.append(symbol);
}
bufferedWriter.newLine();
}
}
/**
* Reads the gate layout to relative block vectors
*/
private void readLayout() {
List<RelativeBlockVector> entranceList = new ArrayList<>();
List<RelativeBlockVector> borderList = new ArrayList<>();
List<RelativeBlockVector> controlList = new ArrayList<>();
RelativeBlockVector[] relativeExits = new RelativeBlockVector[layout[0].length];
RelativeBlockVector lastExit = null;
int[] exitDepths = readLayout(controlList, entranceList, borderList);
//Generate other possible exits
for (int x = 0; x < exitDepths.length; x++) {
relativeExits[x] = new RelativeBlockVector(x, exitDepths[x], 0);
}
//Add non-null exits to the exits list
for (int x = relativeExits.length - 1; x >= 0; x--) {
if (relativeExits[x] != null) {
lastExit = relativeExits[x];
} else {
relativeExits[x] = lastExit;
}
if (exitDepths[x] > 0) {
this.exits.put(relativeExits[x], x);
}
}
this.entrances = entranceList.toArray(this.entrances);
this.border = borderList.toArray(this.border);
this.controls = controlList.toArray(this.controls);
}
/**
* Reads the given layout matrix, filling in the given lists of relative block vectors
*
* @param controlList <p>The list of control blocks to save to</p>
* @param entranceList <p>The list of entrances to save to</p>
* @param borderList <p>The list of border blocks to save to</p>
* @return <p>A list of depths of possible extra exits</p>
*/
private int[] readLayout(List<RelativeBlockVector> controlList, List<RelativeBlockVector> entranceList,
List<RelativeBlockVector> borderList) {
//Store the depth/line of each
int[] exitDepths = new int[layout[0].length];
int lineCount = layout.length;
for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) {
int rowSize = layout[lineIndex].length;
for (int rowIndex = 0; rowIndex < rowSize; rowIndex++) {
Character key = layout[lineIndex][rowIndex];
parseLayoutCharacter(key, rowIndex, lineIndex, exitDepths, controlList, entranceList, borderList);
}
}
return exitDepths;
}
/**
* Parses one character of the layout
*
* @param key <p>The character read</p>
* @param rowIndex <p>The row of the read character</p>
* @param lineIndex <p>The line of the read character</p>
* @param exitDepths <p>The list of exit depths to save to</p>
* @param controlList <p>The list of control blocks to save to</p>
* @param entranceList <p>The list of entrances to save to</p>
* @param borderList <p>The list of border blocks to save to</p>
*/
private void parseLayoutCharacter(Character key, int rowIndex, int lineIndex, int[] exitDepths,
List<RelativeBlockVector> controlList, List<RelativeBlockVector> entranceList,
List<RelativeBlockVector> borderList) {
//Add control blocks
if (key.equals('-')) {
controlList.add(new RelativeBlockVector(rowIndex, lineIndex, 0));
}
if (key.equals(GateHandler.getEntranceCharacter()) || key.equals(GateHandler.getExitCharacter())) {
//Register entrances
entranceList.add(new RelativeBlockVector(rowIndex, lineIndex, 0));
//Find the lowest exit block at a given x position
exitDepths[rowIndex] = lineIndex;
//Register exit
if (key.equals(GateHandler.getExitCharacter())) {
this.exitBlock = new RelativeBlockVector(rowIndex, lineIndex, 0);
}
} else if (!key.equals(GateHandler.getAnythingCharacter())) {
//Add border
borderList.add(new RelativeBlockVector(rowIndex, lineIndex, 0));
}
}
}

View File

@ -1,5 +1,10 @@
package net.knarcraft.stargate; package net.knarcraft.stargate.portal;
import net.knarcraft.stargate.BlockLocation;
import net.knarcraft.stargate.BloxPopulator;
import net.knarcraft.stargate.EconomyHandler;
import net.knarcraft.stargate.RelativeBlockVector;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.event.StargateActivateEvent; import net.knarcraft.stargate.event.StargateActivateEvent;
import net.knarcraft.stargate.event.StargateCloseEvent; import net.knarcraft.stargate.event.StargateCloseEvent;
import net.knarcraft.stargate.event.StargateDeactivateEvent; import net.knarcraft.stargate.event.StargateDeactivateEvent;
@ -317,7 +322,7 @@ public class Portal {
public BlockLocation[] getEntrances() { public BlockLocation[] getEntrances() {
if (entrances == null) { if (entrances == null) {
RelativeBlockVector[] space = gate.getEntrances(); RelativeBlockVector[] space = gate.getLayout().getEntrances();
entrances = new BlockLocation[space.length]; entrances = new BlockLocation[space.length];
int i = 0; int i = 0;
@ -330,7 +335,7 @@ public class Portal {
public BlockLocation[] getFrame() { public BlockLocation[] getFrame() {
if (frame == null) { if (frame == null) {
RelativeBlockVector[] border = gate.getBorder(); RelativeBlockVector[] border = gate.getLayout().getBorder();
frame = new BlockLocation[border.length]; frame = new BlockLocation[border.length];
int i = 0; int i = 0;
@ -371,7 +376,7 @@ public class Portal {
if (isOpen() && !force) return false; if (isOpen() && !force) return false;
Material openType = gate.getPortalBlockOpen(); Material openType = gate.getPortalOpenBlock();
Axis ax = openType == Material.NETHER_PORTAL ? rot : null; Axis ax = openType == Material.NETHER_PORTAL ? rot : null;
for (BlockLocation inside : getEntrances()) { for (BlockLocation inside : getEntrances()) {
Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, openType, ax)); Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, openType, ax));
@ -409,7 +414,7 @@ public class Portal {
if (isAlwaysOn() && !force) return; // Only close always-open if forced if (isAlwaysOn() && !force) return; // Only close always-open if forced
// Close this gate, then the dest gate. // Close this gate, then the dest gate.
Material closedType = gate.getPortalBlockClosed(); Material closedType = gate.getPortalClosedBlock();
for (BlockLocation inside : getEntrances()) { for (BlockLocation inside : getEntrances()) {
Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, closedType)); Stargate.blockPopulatorQueue.add(new BloxPopulator(inside, closedType));
} }
@ -455,7 +460,7 @@ public class Portal {
} }
public boolean isPowered() { public boolean isPowered() {
RelativeBlockVector[] controls = gate.getControls(); RelativeBlockVector[] controls = gate.getLayout().getControls();
for (RelativeBlockVector vector : controls) { for (RelativeBlockVector vector : controls) {
BlockData data = getBlockAt(vector).getBlock().getBlockData(); BlockData data = getBlockAt(vector).getBlock().getBlockData();
@ -583,8 +588,8 @@ public class Portal {
public Location getExit(Entity entity, Location traveller) { public Location getExit(Entity entity, Location traveller) {
Location exitLocation = null; Location exitLocation = null;
// Check if the gate has an exit block // Check if the gate has an exit block
if (gate.getExit() != null) { if (gate.getLayout().getExit() != null) {
BlockLocation exit = getBlockAt(gate.getExit()); BlockLocation exit = getBlockAt(gate.getLayout().getExit());
int back = (isBackwards()) ? -1 : 1; int back = (isBackwards()) ? -1 : 1;
double entitySize = Math.ceil((float) Math.max(entity.getBoundingBox().getWidthX(), entity.getBoundingBox().getWidthZ())); double entitySize = Math.ceil((float) Math.max(entity.getBoundingBox().getWidthX(), entity.getBoundingBox().getWidthZ()));
exitLocation = exit.modRelativeLoc(0D, 0D, entitySize, traveller.getYaw(), traveller.getPitch(), modX * back, 1, modZ * back); exitLocation = exit.modRelativeLoc(0D, 0D, entitySize, traveller.getYaw(), traveller.getPitch(), modX * back, 1, modZ * back);
@ -657,7 +662,7 @@ public class Portal {
if (!Stargate.verifyPortals) { if (!Stargate.verifyPortals) {
return true; return true;
} }
for (RelativeBlockVector control : gate.getControls()) { for (RelativeBlockVector control : gate.getLayout().getControls()) {
verified = verified && getBlockAt(control).getBlock().getType().equals(gate.getControlBlock()); verified = verified && getBlockAt(control).getBlock().getType().equals(gate.getControlBlock());
} }
return verified; return verified;

View File

@ -1,5 +1,9 @@
package net.knarcraft.stargate; package net.knarcraft.stargate.portal;
import net.knarcraft.stargate.BlockLocation;
import net.knarcraft.stargate.RelativeBlockVector;
import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.TwoTuple;
import net.knarcraft.stargate.event.StargateCreateEvent; import net.knarcraft.stargate.event.StargateCreateEvent;
import net.knarcraft.stargate.utility.EconomyHelper; import net.knarcraft.stargate.utility.EconomyHelper;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -38,6 +42,10 @@ public class PortalHandler {
// A list of Bungee gates // A list of Bungee gates
private static final Map<String, Portal> bungeePortals = new HashMap<>(); private static final Map<String, Portal> bungeePortals = new HashMap<>();
private PortalHandler() {
}
public static List<String> getNetwork(String network) { public static List<String> getNetwork(String network) {
return allPortalsNet.get(network.toLowerCase()); return allPortalsNet.get(network.toLowerCase());
} }
@ -208,7 +216,7 @@ public class PortalHandler {
return null; return null;
} }
if (Gate.getGatesByControlBlock(idParent).length == 0) { if (GateHandler.getGatesByControlBlock(idParent).length == 0) {
return null; return null;
} }
@ -250,7 +258,7 @@ public class PortalHandler {
buttonFacing = BlockFace.SOUTH; buttonFacing = BlockFace.SOUTH;
} }
Gate[] possibleGates = Gate.getGatesByControlBlock(idParent); Gate[] possibleGates = GateHandler.getGatesByControlBlock(idParent);
Gate gate = null; Gate gate = null;
RelativeBlockVector buttonVector = null; RelativeBlockVector buttonVector = null;
@ -258,7 +266,7 @@ public class PortalHandler {
if (gate != null || buttonVector != null) { if (gate != null || buttonVector != null) {
break; break;
} }
RelativeBlockVector[] vectors = possibility.getControls(); RelativeBlockVector[] vectors = possibility.getLayout().getControls();
RelativeBlockVector otherControl = null; RelativeBlockVector otherControl = null;
for (RelativeBlockVector vector : vectors) { for (RelativeBlockVector vector : vectors) {
@ -357,7 +365,7 @@ public class PortalHandler {
} }
// Bleh, gotta check to make sure none of this gate belongs to another gate. Boo slow. // Bleh, gotta check to make sure none of this gate belongs to another gate. Boo slow.
for (RelativeBlockVector v : gate.getBorder()) { for (RelativeBlockVector v : gate.getLayout().getBorder()) {
BlockLocation b = topLeft.modRelative(v.getRight(), v.getDepth(), v.getDistance(), modX, 1, modZ); BlockLocation b = topLeft.modRelative(v.getRight(), v.getDepth(), v.getDistance(), modX, 1, modZ);
if (getByBlock(b.getBlock()) != null) { if (getByBlock(b.getBlock()) != null) {
Stargate.debug("createPortal", "Gate conflicts with existing gate"); Stargate.debug("createPortal", "Gate conflicts with existing gate");
@ -427,7 +435,7 @@ public class PortalHandler {
// No button on an always-open gate. // No button on an always-open gate.
if (!portalOptions.get(PortalOption.ALWAYS_ON)) { if (!portalOptions.get(PortalOption.ALWAYS_ON)) {
button = topLeft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ); button = topLeft.modRelative(buttonVector.getRight(), buttonVector.getDepth(), buttonVector.getDistance() + 1, modX, 1, modZ);
Directional buttonData = (Directional) Bukkit.createBlockData(gate.getButton()); Directional buttonData = (Directional) Bukkit.createBlockData(gate.getPortalButton());
buttonData.setFacing(buttonFacing); buttonData.setFacing(buttonFacing);
button.getBlock().setBlockData(buttonData); button.getBlock().setBlockData(buttonData);
portal.setButton(button); portal.setButton(button);
@ -447,7 +455,7 @@ public class PortalHandler {
// Set the inside of the gate to its closed material // Set the inside of the gate to its closed material
} else { } else {
for (BlockLocation inside : portal.getEntrances()) { for (BlockLocation inside : portal.getEntrances()) {
inside.setType(portal.getGate().getPortalBlockClosed()); inside.setType(portal.getGate().getPortalClosedBlock());
} }
} }
@ -813,7 +821,7 @@ public class PortalHandler {
int modZ = Integer.parseInt(portalData[4]); int modZ = Integer.parseInt(portalData[4]);
float rotX = Float.parseFloat(portalData[5]); float rotX = Float.parseFloat(portalData[5]);
BlockLocation topLeft = new BlockLocation(world, portalData[6]); BlockLocation topLeft = new BlockLocation(world, portalData[6]);
Gate gate = Gate.getGateByName(portalData[7]); Gate gate = GateHandler.getGateByName(portalData[7]);
if (gate == null) { if (gate == null) {
Stargate.log.info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex + Stargate.log.info(Stargate.getString("prefix") + "Gate layout on line " + lineIndex +
" does not exist [" + portalData[7] + "]"); " does not exist [" + portalData[7] + "]");
@ -907,7 +915,7 @@ public class PortalHandler {
*/ */
private static void destroyInvalidStarGate(Portal portal) { private static void destroyInvalidStarGate(Portal portal) {
// DEBUG // DEBUG
for (RelativeBlockVector control : portal.getGate().getControls()) { for (RelativeBlockVector control : portal.getGate().getLayout().getControls()) {
if (!portal.getBlockAt(control).getBlock().getType().equals(portal.getGate().getControlBlock())) { if (!portal.getBlockAt(control).getBlock().getType().equals(portal.getGate().getControlBlock())) {
Stargate.debug("loadAllGates", "Control Block Type == " + portal.getBlockAt(control).getBlock().getType().name()); Stargate.debug("loadAllGates", "Control Block Type == " + portal.getBlockAt(control).getBlock().getType().name());
} }

View File

@ -1,4 +1,4 @@
package net.knarcraft.stargate; package net.knarcraft.stargate.portal;
public enum PortalOption { public enum PortalOption {

View File

@ -1,6 +1,6 @@
package net.knarcraft.stargate.thread; package net.knarcraft.stargate.thread;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import java.util.Iterator; import java.util.Iterator;

View File

@ -1,7 +1,7 @@
package net.knarcraft.stargate.utility; package net.knarcraft.stargate.utility;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.PortalHandler; import net.knarcraft.stargate.portal.PortalHandler;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -20,6 +20,10 @@ public final class BungeeHelper {
private final static String bungeeChannel = "BungeeCord"; private final static String bungeeChannel = "BungeeCord";
private final static String teleportMessageDelimiter = "#@#"; private final static String teleportMessageDelimiter = "#@#";
private BungeeHelper() {
}
/** /**
* Sends a plugin message to BungeeCord allowing the target server to catch it * Sends a plugin message to BungeeCord allowing the target server to catch it
* *

View File

@ -1,11 +1,15 @@
package net.knarcraft.stargate.utility; package net.knarcraft.stargate.utility;
import net.knarcraft.stargate.EconomyHandler; import net.knarcraft.stargate.EconomyHandler;
import net.knarcraft.stargate.Portal; import net.knarcraft.stargate.portal.Portal;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
public class EconomyHelper { public final class EconomyHelper {
private EconomyHelper() {
}
/** /**
* Tries to make the given user pay the teleport fee * Tries to make the given user pay the teleport fee

View File

@ -8,6 +8,10 @@ import org.bukkit.Tag;
*/ */
public final class MaterialHelper { public final class MaterialHelper {
private MaterialHelper() {
}
/** /**
* Checks whether the given material is a dead or alive wall coral * Checks whether the given material is a dead or alive wall coral
* *

View File

@ -3,6 +3,7 @@ package net.knarcraft.stargate;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
public class RelativeBlockVectorTest { public class RelativeBlockVectorTest {
@ -14,4 +15,18 @@ public class RelativeBlockVectorTest {
assertEquals(23, relativeBlockVector.getDistance()); assertEquals(23, relativeBlockVector.getDistance());
} }
@Test
public void equalsTest() {
RelativeBlockVector vector1 = new RelativeBlockVector(56, 34, 76);
RelativeBlockVector vector2 = new RelativeBlockVector(56, 34, 76);
assertEquals(vector1, vector2);
}
@Test
public void notEqualsTest() {
RelativeBlockVector vector1 = new RelativeBlockVector(456, 78, 234);
RelativeBlockVector vector2 = new RelativeBlockVector(56, 34, 76);
assertNotEquals(vector1, vector2);
}
} }

View File

@ -0,0 +1,95 @@
package net.knarcraft.stargate.portal;
import be.seeseemelk.mockbukkit.ServerMock;
import be.seeseemelk.mockbukkit.WorldMock;
import net.knarcraft.stargate.RelativeBlockVector;
import net.knarcraft.stargate.Stargate;
import org.bukkit.Material;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import be.seeseemelk.mockbukkit.MockBukkit;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class GateLayoutTest {
private static GateLayout layout;
@BeforeAll
public static void setUp() {
ServerMock server = MockBukkit.mock();
server.addWorld(new WorldMock(Material.DIRT, 5));
MockBukkit.load(Stargate.class);
layout = GateHandler.getGateByName("nethergate.gate").getLayout();
}
@Test
public void gateLayoutExitTest() {
assertEquals(new RelativeBlockVector(1, 3, 0), layout.getExit());
}
@Test
public void gateLayoutExitsTest() {
List<RelativeBlockVector> expected = new ArrayList<>();
expected.add(new RelativeBlockVector(1, 3, 0));
expected.add(new RelativeBlockVector(2, 3, 0));
Set<RelativeBlockVector> exits = layout.getExits().keySet();
exits.forEach((blockVector) -> assertTrue(expected.contains(blockVector)));
}
@Test
public void gateLayoutBorderTest() {
List<RelativeBlockVector> expected = new ArrayList<>();
expected.add(new RelativeBlockVector(1, 0, 0));
expected.add(new RelativeBlockVector(2, 0, 0));
expected.add(new RelativeBlockVector(0, 1, 0));
expected.add(new RelativeBlockVector(0, 2, 0));
expected.add(new RelativeBlockVector(0, 3, 0));
expected.add(new RelativeBlockVector(1, 4, 0));
expected.add(new RelativeBlockVector(2, 4, 0));
expected.add(new RelativeBlockVector(3, 1, 0));
expected.add(new RelativeBlockVector(3, 2, 0));
expected.add(new RelativeBlockVector(3, 3, 0));
RelativeBlockVector[] borderBlocks = layout.getBorder();
for (RelativeBlockVector blockVector : borderBlocks) {
assertTrue(expected.contains(blockVector));
}
}
@Test
public void gateLayoutControlsTest() {
List<RelativeBlockVector> expected = new ArrayList<>();
expected.add(new RelativeBlockVector(0, 2, 0));
expected.add(new RelativeBlockVector(3, 2, 0));
RelativeBlockVector[] controlBlocks = layout.getControls();
for (RelativeBlockVector blockVector : controlBlocks) {
assertTrue(expected.contains(blockVector));
}
}
@Test
public void gateLayoutEntrancesTest() {
List<RelativeBlockVector> expected = new ArrayList<>();
expected.add(new RelativeBlockVector(1, 1, 0));
expected.add(new RelativeBlockVector(2, 1, 0));
expected.add(new RelativeBlockVector(1, 2, 0));
expected.add(new RelativeBlockVector(2, 2, 0));
expected.add(new RelativeBlockVector(1, 3, 0));
expected.add(new RelativeBlockVector(2, 3, 0));
RelativeBlockVector[] controlBlocks = layout.getEntrances();
for (RelativeBlockVector blockVector : controlBlocks) {
assertTrue(expected.contains(blockVector));
}
}
}