Adds missing comments to Gate and changes the matches function from n^2 to n execution time

This commit is contained in:
Kristian Knarvik 2021-02-22 20:25:07 +01:00
parent 279ea9d8f0
commit e665a49f03

View File

@ -1,8 +1,9 @@
package net.knarcraft.stargate.portal; package net.knarcraft.stargate.portal;
import net.knarcraft.stargate.BlockLocation; import net.knarcraft.stargate.BlockLocation;
import net.knarcraft.stargate.EconomyHandler; import net.knarcraft.stargate.RelativeBlockVector;
import net.knarcraft.stargate.Stargate; import net.knarcraft.stargate.Stargate;
import net.knarcraft.stargate.utility.EconomyHandler;
import org.bukkit.Material; import org.bukkit.Material;
import java.io.BufferedWriter; import java.io.BufferedWriter;
@ -81,70 +82,174 @@ public class Gate {
return types; return types;
} }
/**
* Gets the material type used for this gate's control blocks
*
* @return <p>The material type used for control blocks</p>
*/
public Material getControlBlock() { public Material getControlBlock() {
return types.get('-'); return types.get(GateHandler.getControlBlockCharacter());
} }
/**
* Gets the filename of this gate
*
* @return <p>The filename of this gate</p>
*/
public String getFilename() { public String getFilename() {
return filename; return filename;
} }
/**
* Gets the block type to use for the opening when a portal using this gate is open
*
* @return <p>The block type to use for the opening when open</p>
*/
public Material getPortalOpenBlock() { public Material getPortalOpenBlock() {
return portalOpenBlock; return portalOpenBlock;
} }
/**
* Sets the block to use for the opening when a portal using this gate is open
*
* @param type <p>The block type to use for the opening when open</p>
*/
public void setPortalOpenBlock(Material type) { public void setPortalOpenBlock(Material type) {
portalOpenBlock = type; portalOpenBlock = type;
} }
/**
* Gets the block type to use for the opening when a portal using this gate is closed
*
* @return <p>The block type to use for the opening when closed</p>
*/
public Material getPortalClosedBlock() { public Material getPortalClosedBlock() {
return portalClosedBlock; return portalClosedBlock;
} }
/**
* Sets the block type to use for the opening when a portal using this gate is closed
*
* @param type <p>The block type to use for the opening when closed</p>
*/
public void setPortalClosedBlock(Material type) { public void setPortalClosedBlock(Material type) {
portalClosedBlock = type; portalClosedBlock = type;
} }
/**
* Gets the material to use for a portal's button if using this gate type
*
* @return <p>The material to use for a portal's button if using this gate type</p>
*/
public Material getPortalButton() { public Material getPortalButton() {
return portalButton; return portalButton;
} }
/**
* Gets the cost of using a portal with this gate
*
* @return <p>The cost of using a portal with this gate</p>
*/
public int getUseCost() { public int getUseCost() {
if (useCost < 0) return EconomyHandler.useCost; return useCost < 0 ? EconomyHandler.getUseCost() : useCost;
return useCost;
} }
/**
* Gets the cost of creating a portal with this gate
*
* @return <p>The cost of creating a portal with this gate</p>
*/
public Integer getCreateCost() { public Integer getCreateCost() {
if (createCost < 0) return EconomyHandler.createCost; return createCost < 0 ? EconomyHandler.getCreateCost() : createCost;
return createCost;
} }
/**
* Gets the cost of destroying a portal with this gate
*
* @return <p>The cost of destroying a portal with this gate</p>
*/
public Integer getDestroyCost() { public Integer getDestroyCost() {
if (destroyCost < 0) return EconomyHandler.destroyCost; if (destroyCost < 0) return EconomyHandler.getDestroyCost();
return destroyCost; return destroyCost;
} }
/**
* Gets whether portal payments go to this portal's owner
*
* @return <p>Whether portal payments go to the owner</p>
*/
public Boolean getToOwner() { public Boolean getToOwner() {
return toOwner; return toOwner;
} }
/**
* Checks whether a portal's gate matches this gate type
*
* @param topLeft <p>The top-left block of the portal's gate</p>
* @param modX <p>The x modifier used</p>
* @param modZ <p>The z modifier used</p>
* @return <p>True if this gate matches the portal</p>
*/
public boolean matches(BlockLocation topLeft, int modX, int modZ) { public boolean matches(BlockLocation topLeft, int modX, int modZ) {
return matches(topLeft, modX, modZ, false); return matches(topLeft, modX, modZ, false);
} }
/**
* Checks whether a portal's gate matches this gate type
*
* @param topLeft <p>The top-left block of the portal's gate</p>
* @param modX <p>The x modifier used</p>
* @param modZ <p>The z modifier used</p>
* @param onCreate <p>Whether this is used in the context of creating a new gate</p>
* @return <p>True if this gate matches the portal</p>
*/
public boolean matches(BlockLocation topLeft, int modX, int modZ, boolean onCreate) { public boolean matches(BlockLocation topLeft, int modX, int modZ, boolean onCreate) {
HashMap<Character, Material> portalTypes = new HashMap<>(types); return verifyGateEntrancesMatch(topLeft, modX, modZ, onCreate) && verifyGateBorderMatches(topLeft, modX, modZ);
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(); /**
* Verifies that all border blocks of a portal gate matches this gate type
*
* @param topLeft <p>The top-left block of the portal</p>
* @param modX <p>The x modifier used</p>
* @param modZ <p>The z modifier used</p>
* @return <p>True if all border blocks of the gate match the layout</p>
*/
private boolean verifyGateBorderMatches(BlockLocation topLeft, int modX, int modZ) {
Map<Character, Material> portalTypes = new HashMap<>(types);
for (RelativeBlockVector borderVector : layout.getBorder()) {
int rowIndex = borderVector.getRight();
int lineIndex = borderVector.getDepth();
Character key = layout.getLayout()[lineIndex][rowIndex];
Material materialInLayout = portalTypes.get(key);
Material materialAtLocation = getBlockAt(topLeft, borderVector, modX, modZ).getType();
if (materialInLayout == null) {
portalTypes.put(key, materialAtLocation);
} else if (materialAtLocation != materialInLayout) {
Stargate.debug("Gate::Matches", String.format("Block Type Mismatch: %s != %s",
materialAtLocation, materialInLayout));
return false;
}
}
return true;
}
/**
* Verifies that all entrances of a portal gate matches this gate type
*
* @param topLeft <p>The top-left block of this portal</p>
* @param modX <p>The x modifier used</p>
* @param modZ <p>The z modifier used</p>
* @param onCreate <p>Whether this is used in the context of creating a new gate</p>
* @return <p>Whether this is used in the context of creating a new gate</p>
*/
private boolean verifyGateEntrancesMatch(BlockLocation topLeft, int modX, int modZ, boolean onCreate) {
if (Stargate.ignoreEntrance) {
return true;
}
for (RelativeBlockVector entranceVector : layout.getEntrances()) {
Material type = getBlockAt(topLeft, entranceVector, modX, modZ).getType();
// Ignore entrance if it's air and we're creating a new gate // Ignore entrance if it's air and we're creating a new gate
if (onCreate && type == Material.AIR) { if (onCreate && type == Material.AIR) {
@ -155,19 +260,18 @@ public class Gate {
Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type); Stargate.debug("Gate::Matches", "Entrance/Exit Material Mismatch: " + type);
return false; 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;
} }
return true; /**
* Gets the block at a relative block vector location
*
* @param vector <p>The relative block vector</p>
* @return <p>The block at the given relative position</p>
*/
private BlockLocation getBlockAt(BlockLocation topLeft, RelativeBlockVector vector, int modX, int modZ) {
return topLeft.modRelative(vector.getRight(), vector.getDepth(), vector.getDistance(), modX, 1, modZ);
} }
/** /**