diff --git a/src/com/massivecraft/factions/Board.java b/src/com/massivecraft/factions/Board.java new file mode 100644 index 00000000..6f07e793 --- /dev/null +++ b/src/com/massivecraft/factions/Board.java @@ -0,0 +1,287 @@ +package com.massivecraft.factions; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentSkipListMap; + +import org.bukkit.ChatColor; + +import com.massivecraft.factions.iface.RelationParticipator; +import com.massivecraft.factions.integration.LWCFeatures; +import com.massivecraft.factions.util.AsciiCompass; +import com.massivecraft.mcore.ps.PS; +import com.massivecraft.mcore.store.Entity; +import com.massivecraft.mcore.util.Txt; + +public class Board extends Entity +{ + // -------------------------------------------- // + // META + // -------------------------------------------- // + + public static Board get(Object oid) + { + return BoardColl.get().get(oid); + } + + // -------------------------------------------- // + // OVERRIDE + // -------------------------------------------- // + + @Override + public Board load(Board that) + { + this.map = that.map; + + return this; + } + + @Override + public boolean isDefault() + { + if (this.map == null) return true; + if (this.map.isEmpty()) return true; + return false; + } + + // -------------------------------------------- // + // FIELDS + // -------------------------------------------- // + + // TODO: Make TerritoryAccess immutable! + private ConcurrentSkipListMap map = new ConcurrentSkipListMap(); + + // -------------------------------------------- // + // GET + // -------------------------------------------- // + + public TerritoryAccess getTerritoryAccessAt(PS ps) + { + ps = ps.getChunkCoords(true); + TerritoryAccess ret = this.map.get(ps); + if (ret == null) ret = new TerritoryAccess("0"); + return ret; + } + + public Faction getFactionAt(PS ps) + { + return this.getTerritoryAccessAt(ps).getHostFaction(); + } + + // -------------------------------------------- // + // SET + // -------------------------------------------- // + + public void setTerritoryAccessAt(PS ps, TerritoryAccess territoryAccess) + { + ps = ps.getChunkCoords(true); + + if (territoryAccess == null || (territoryAccess.getHostFactionId().equals("0") && territoryAccess.isDefault())) + { + // TODO: Listen to an event instead! + // And this is probably the place where the event should be triggered! + if (ConfServer.onUnclaimResetLwcLocks && LWCFeatures.getEnabled()) + { + LWCFeatures.clearAllChests(ps); + } + + this.map.remove(ps); + } + else + { + this.map.put(ps, territoryAccess); + } + + this.changed(); + } + + public void setFactionAt(PS ps, Faction faction) + { + TerritoryAccess territoryAccess = null; + if (faction != null) + { + territoryAccess = new TerritoryAccess(faction.getId()); + } + this.setTerritoryAccessAt(ps, territoryAccess); + } + + // -------------------------------------------- // + // REMOVE + // -------------------------------------------- // + + public void removeAt(PS ps) + { + this.setTerritoryAccessAt(ps, null); + } + + public void removeAll(String factionId) + { + for (Entry entry : this.map.entrySet()) + { + TerritoryAccess territoryAccess = entry.getValue(); + if ( ! territoryAccess.getHostFactionId().equals(factionId)) continue; + + PS ps = entry.getKey(); + this.removeAt(ps); + } + } + + // Removes orphaned foreign keys + public void clean() + { + for (Entry entry : this.map.entrySet()) + { + TerritoryAccess territoryAccess = entry.getValue(); + if (FactionColl.i.exists(territoryAccess.getHostFactionId())) continue; + + PS ps = entry.getKey(); + this.removeAt(ps); + + Factions.get().log("Board cleaner removed "+territoryAccess.getHostFactionId()+" from "+entry.getKey()); + } + } + + // -------------------------------------------- // + // COUNT + // -------------------------------------------- // + + public int getCount(String factionId) + { + int ret = 0; + for (TerritoryAccess territoryAccess : this.map.values()) + { + if(territoryAccess.getHostFactionId().equals(factionId)) ret += 1; + } + return ret; + } + + public int getCount(Faction faction) + { + return this.getCount(faction.getId()); + } + + // -------------------------------------------- // + // NEARBY DETECTION + // -------------------------------------------- // + + // Is this coord NOT completely surrounded by coords claimed by the same faction? + // Simpler: Is there any nearby coord with a faction other than the faction here? + public boolean isBorderPs(PS ps) + { + PS nearby = null; + Faction faction = this.getFactionAt(ps); + + nearby = ps.withChunkX(ps.getChunkX() +1); + if (faction != this.getFactionAt(nearby)) return true; + + nearby = ps.withChunkX(ps.getChunkX() -1); + if (faction != this.getFactionAt(nearby)) return true; + + nearby = ps.withChunkZ(ps.getChunkZ() +1); + if (faction != this.getFactionAt(nearby)) return true; + + nearby = ps.withChunkZ(ps.getChunkZ() -1); + if (faction != this.getFactionAt(nearby)) return true; + + return false; + } + + // Is this coord connected to any coord claimed by the specified faction? + public boolean isConnectedPs(PS ps, Faction faction) + { + PS nearby = null; + + nearby = ps.withChunkX(ps.getChunkX() +1); + if (faction == this.getFactionAt(nearby)) return true; + + nearby = ps.withChunkX(ps.getChunkX() -1); + if (faction == this.getFactionAt(nearby)) return true; + + nearby = ps.withChunkZ(ps.getChunkZ() +1); + if (faction == this.getFactionAt(nearby)) return true; + + nearby = ps.withChunkZ(ps.getChunkZ() -1); + if (faction == this.getFactionAt(nearby)) return true; + + return false; + } + + // -------------------------------------------- // + // MAP GENERATION + // -------------------------------------------- // + + public ArrayList getMap(RelationParticipator observer, PS centerPs, double inDegrees) + { + centerPs = centerPs.getChunkCoords(true); + + ArrayList ret = new ArrayList(); + Faction centerFaction = this.getFactionAt(centerPs); + + ret.add(Txt.titleize("("+centerPs.getChunkX() + "," + centerPs.getChunkZ()+") "+centerFaction.getTag(observer))); + + int halfWidth = Const.MAP_WIDTH / 2; + int halfHeight = Const.MAP_HEIGHT / 2; + + PS topLeftPs = centerPs.plusChunkCoords(-halfWidth, -halfHeight); + + int width = halfWidth * 2 + 1; + int height = halfHeight * 2 + 1; + + //Make room for the list of tags + height--; + + Map fList = new HashMap(); + int chrIdx = 0; + + // For each row + for (int dz = 0; dz < height; dz++) + { + // Draw and add that row + String row = ""; + for (int dx = 0; dx < width; dx++) + { + if(dx == halfWidth && dz == halfHeight) + { + row += ChatColor.AQUA+"+"; + continue; + } + + PS herePs = topLeftPs.plusChunkCoords(dx, dz); + Faction hereFaction = this.getFactionAt(herePs); + if (hereFaction.isNone()) + { + row += ChatColor.GRAY+"-"; + } + else + { + if (!fList.containsKey(hereFaction)) + fList.put(hereFaction, Const.MAP_KEY_CHARS[chrIdx++]); + char fchar = fList.get(hereFaction); + row += hereFaction.getColorTo(observer) + "" + fchar; + } + } + ret.add(row); + } + + // Get the compass + ArrayList asciiCompass = AsciiCompass.getAsciiCompass(inDegrees, ChatColor.RED, Txt.parse("")); + + // Add the compass + ret.set(1, asciiCompass.get(0)+ret.get(1).substring(3*3)); + ret.set(2, asciiCompass.get(1)+ret.get(2).substring(3*3)); + ret.set(3, asciiCompass.get(2)+ret.get(3).substring(3*3)); + + String fRow = ""; + for (Faction keyfaction : fList.keySet()) + { + fRow += ""+keyfaction.getColorTo(observer) + fList.get(keyfaction) + ": " + keyfaction.getTag() + " "; + } + fRow = fRow.trim(); + ret.add(fRow); + + return ret; + } + +} diff --git a/src/com/massivecraft/factions/BoardColl.java b/src/com/massivecraft/factions/BoardColl.java new file mode 100644 index 00000000..d212bf0a --- /dev/null +++ b/src/com/massivecraft/factions/BoardColl.java @@ -0,0 +1,19 @@ +package com.massivecraft.factions; + +import com.massivecraft.mcore.store.Coll; +import com.massivecraft.mcore.store.MStore; + +public class BoardColl extends Coll +{ + // -------------------------------------------- // + // INSTANCE & CONSTRUCT + // -------------------------------------------- // + + private static BoardColl i = new BoardColl(); + public static BoardColl get() { return i; } + private BoardColl() + { + super(MStore.getDb(ConfServer.dburi), Factions.get(), "ai", Const.COLLECTION_BASENAME_BOARD, Board.class, String.class, true); + } + +} diff --git a/src/com/massivecraft/factions/BoardOld.java b/src/com/massivecraft/factions/BoardOld.java index 72540259..240f23b3 100644 --- a/src/com/massivecraft/factions/BoardOld.java +++ b/src/com/massivecraft/factions/BoardOld.java @@ -26,9 +26,9 @@ public class BoardOld private static transient File file = new File(Factions.get().getDataFolder(), "board.json"); private static transient HashMap flocationIds = new HashMap(); - //----------------------------------------------// - // Get and Set - //----------------------------------------------// + // -------------------------------------------- // + // GET AND SET + // -------------------------------------------- // public static String getIdAt(FLocation flocation) { if ( ! flocationIds.containsKey(flocation)) return "0"; @@ -118,9 +118,9 @@ public class BoardOld } - //----------------------------------------------// - // Cleaner. Remove orphaned foreign keys - //----------------------------------------------// + // -------------------------------------------- // + // CLEANER. REMOVE ORPHANED FOREIGN KEYS + // -------------------------------------------- // public static void clean() { @@ -136,11 +136,11 @@ public class BoardOld iter.remove(); } } - } + } - //----------------------------------------------// - // Coord count - //----------------------------------------------// + // -------------------------------------------- // + // COORD COUNT + // -------------------------------------------- // public static int getFactionCoordCount(String factionId) { @@ -175,9 +175,9 @@ public class BoardOld return ret; } - //----------------------------------------------// - // Map generation - //----------------------------------------------// + // -------------------------------------------- // + // MAP GENERATION + // -------------------------------------------- // /** * The map is relative to a coord and a faction diff --git a/src/com/massivecraft/factions/ConfServer.java b/src/com/massivecraft/factions/ConfServer.java index 72a3d262..c8338a4a 100644 --- a/src/com/massivecraft/factions/ConfServer.java +++ b/src/com/massivecraft/factions/ConfServer.java @@ -21,7 +21,8 @@ public class ConfServer extends SimpleConfig // FIELDS // -------------------------------------------- // - public final static List baseCommandAliases = MUtil.list("f"); + public static List baseCommandAliases = MUtil.list("f"); + public static String dburi = "default"; // Colors public static ChatColor colorMember = ChatColor.GREEN; diff --git a/src/com/massivecraft/factions/integration/LWCFeatures.java b/src/com/massivecraft/factions/integration/LWCFeatures.java index 9887e6a1..f4418b20 100644 --- a/src/com/massivecraft/factions/integration/LWCFeatures.java +++ b/src/com/massivecraft/factions/integration/LWCFeatures.java @@ -18,6 +18,7 @@ import com.massivecraft.factions.FLocation; import com.massivecraft.factions.FPlayerColl; import com.massivecraft.factions.Faction; import com.massivecraft.factions.Factions; +import com.massivecraft.mcore.ps.PS; public class LWCFeatures { @@ -63,15 +64,22 @@ public class LWCFeatures } } - public static void clearAllChests(FLocation flocation) + public static void clearAllChests(PS ps) { - Location location = new Location(Bukkit.getWorld(flocation.getWorldName()), flocation.getX() * 16, 5, flocation.getZ() * 16); - if (location.getWorld() == null) return; // world not loaded or something? cancel out to prevent error - Chunk chunk = location.getChunk(); + Chunk chunk = null; + try + { + chunk = ps.asBukkitChunk(true); + } + catch (Exception e) + { + return; + } + BlockState[] blocks = chunk.getTileEntities(); List chests = new LinkedList(); - for(int x = 0; x < blocks.length; x++) + for (int x = 0; x < blocks.length; x++) { if(blocks[x].getType() == Material.CHEST) { @@ -79,11 +87,11 @@ public class LWCFeatures } } - for(int x = 0; x < chests.size(); x++) + for (int x = 0; x < chests.size(); x++) { if(lwc.findProtection(chests.get(x)) != null) { - lwc.findProtection(chests.get(x)).remove(); + lwc.findProtection(chests.get(x)).remove(); } } }