Saber-Factions/src/main/java/com/massivecraft/factions/zcore/persist/MemoryBoard.java

380 lines
14 KiB
Java
Raw Normal View History

package com.massivecraft.factions.zcore.persist;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
2014-11-06 01:36:47 +01:00
import com.massivecraft.factions.*;
import com.massivecraft.factions.struct.Permission;
import com.massivecraft.factions.struct.Relation;
import com.massivecraft.factions.util.AsciiCompass;
import com.massivecraft.factions.util.LazyLocation;
2018-02-11 00:59:21 +01:00
import com.massivecraft.factions.zcore.util.TL;
import com.massivecraft.factions.zcore.util.TagReplacer;
import com.massivecraft.factions.zcore.util.TagUtil;
import mkremins.fanciful.FancyMessage;
import org.bukkit.ChatColor;
import org.bukkit.World;
import java.util.*;
import java.util.Map.Entry;
public abstract class MemoryBoard extends Board {
public class MemoryBoardMap extends HashMap<FLocation, String> {
2016-05-03 23:05:18 +02:00
private static final long serialVersionUID = -6689617828610585368L;
Multimap<String, FLocation> factionToLandMap = HashMultimap.create();
@Override
public String put(FLocation floc, String factionId) {
String previousValue = super.put(floc, factionId);
if (previousValue != null) {
factionToLandMap.remove(previousValue, floc);
}
factionToLandMap.put(factionId, floc);
return previousValue;
}
@Override
public String remove(Object key) {
String result = super.remove(key);
if (result != null) {
FLocation floc = (FLocation) key;
factionToLandMap.remove(result, floc);
}
return result;
}
@Override
public void clear() {
super.clear();
factionToLandMap.clear();
}
public int getOwnedLandCount(String factionId) {
return factionToLandMap.get(factionId).size();
}
public void removeFaction(String factionId) {
Collection<FLocation> flocations = factionToLandMap.removeAll(factionId);
for (FLocation floc : flocations) {
super.remove(floc);
}
}
}
public MemoryBoardMap flocationIds = new MemoryBoardMap();
//----------------------------------------------//
// Get and Set
//----------------------------------------------//
public String getIdAt(FLocation flocation) {
if (!flocationIds.containsKey(flocation)) {
return "0";
}
return flocationIds.get(flocation);
}
public Faction getFactionAt(FLocation flocation) {
return Factions.getInstance().getFactionById(getIdAt(flocation));
}
public void setIdAt(String id, FLocation flocation) {
clearOwnershipAt(flocation);
if (id.equals("0")) {
removeAt(flocation);
}
flocationIds.put(flocation, id);
}
public void setFactionAt(Faction faction, FLocation flocation) {
setIdAt(faction.getId(), flocation);
}
public void removeAt(FLocation flocation) {
Faction faction = getFactionAt(flocation);
Iterator<LazyLocation> it = faction.getWarps().values().iterator();
while (it.hasNext()) {
if (flocation.isInChunk(it.next().getLocation())) {
it.remove();
}
}
clearOwnershipAt(flocation);
flocationIds.remove(flocation);
}
public Set<FLocation> getAllClaims(String factionId) {
2017-12-19 11:18:13 +01:00
Set<FLocation> locs = new HashSet<>();
for (Entry<FLocation, String> entry : flocationIds.entrySet()) {
if (entry.getValue().equals(factionId)) {
locs.add(entry.getKey());
}
}
return locs;
}
public Set<FLocation> getAllClaims(Faction faction) {
return getAllClaims(faction.getId());
}
// not to be confused with claims, ownership referring to further member-specific ownership of a claim
public void clearOwnershipAt(FLocation flocation) {
Faction faction = getFactionAt(flocation);
if (faction != null && faction.isNormal()) {
faction.clearClaimOwnership(flocation);
}
}
public void unclaimAll(String factionId) {
Faction faction = Factions.getInstance().getFactionById(factionId);
if (faction != null && faction.isNormal()) {
faction.clearAllClaimOwnership();
faction.clearWarps();
}
clean(factionId);
}
public void unclaimAllInWorld(String factionId, World world) {
for (FLocation loc : getAllClaims(factionId)) {
if (loc.getWorldName().equals(world.getName())) {
removeAt(loc);
}
}
}
public void clean(String factionId) {
flocationIds.removeFaction(factionId);
}
// 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 isBorderLocation(FLocation flocation) {
Faction faction = getFactionAt(flocation);
FLocation a = flocation.getRelative(1, 0);
FLocation b = flocation.getRelative(-1, 0);
FLocation c = flocation.getRelative(0, 1);
FLocation d = flocation.getRelative(0, -1);
return faction != getFactionAt(a) || faction != getFactionAt(b) || faction != getFactionAt(c) || faction != getFactionAt(d);
}
// Is this coord connected to any coord claimed by the specified faction?
public boolean isConnectedLocation(FLocation flocation, Faction faction) {
FLocation a = flocation.getRelative(1, 0);
FLocation b = flocation.getRelative(-1, 0);
FLocation c = flocation.getRelative(0, 1);
FLocation d = flocation.getRelative(0, -1);
return faction == getFactionAt(a) || faction == getFactionAt(b) || faction == getFactionAt(c) || faction == getFactionAt(d);
}
/**
* Checks if there is another faction within a given radius other than Wilderness. Used for HCF feature that
* requires a 'buffer' between factions.
*
* @param flocation - center location.
* @param faction - faction checking for.
* @param radius - chunk radius to check.
* @return true if another Faction is within the radius, otherwise false.
*/
public boolean hasFactionWithin(FLocation flocation, Faction faction, int radius) {
for (int x = -radius; x <= radius; x++) {
for (int z = -radius; z <= radius; z++) {
if (x == 0 && z == 0) {
continue;
}
FLocation relative = flocation.getRelative(x, z);
Faction other = getFactionAt(relative);
if (other.isNormal() && other != faction) {
return true;
}
}
}
return false;
}
//----------------------------------------------//
// Cleaner. Remove orphaned foreign keys
//----------------------------------------------//
public void clean() {
Iterator<Entry<FLocation, String>> iter = flocationIds.entrySet().iterator();
while (iter.hasNext()) {
Entry<FLocation, String> entry = iter.next();
if (!Factions.getInstance().isValidFactionId(entry.getValue())) {
P.p.log("Board cleaner removed " + entry.getValue() + " from " + entry.getKey());
iter.remove();
}
}
}
//----------------------------------------------//
// Coord count
//----------------------------------------------//
public int getFactionCoordCount(String factionId) {
return flocationIds.getOwnedLandCount(factionId);
}
public int getFactionCoordCount(Faction faction) {
return getFactionCoordCount(faction.getId());
}
public int getFactionCoordCountInWorld(Faction faction, String worldName) {
String factionId = faction.getId();
int ret = 0;
2017-12-19 11:18:13 +01:00
for (Entry<FLocation, String> entry : flocationIds.entrySet()) {
if (entry.getValue().equals(factionId) && entry.getKey().getWorldName().equals(worldName)) {
ret += 1;
}
}
return ret;
}
//----------------------------------------------//
// Map generation
//----------------------------------------------//
/**
* The map is relative to a coord and a faction north is in the direction of decreasing x east is in the direction
* of decreasing z
*/
2018-02-11 00:59:21 +01:00
public ArrayList<FancyMessage> getMap(FPlayer fplayer, FLocation flocation, double inDegrees) {
Faction faction = fplayer.getFaction();
ArrayList<FancyMessage> ret = new ArrayList<>();
Faction factionLoc = getFactionAt(flocation);
2018-02-11 00:59:21 +01:00
ret.add(new FancyMessage(P.p.txt.titleize("(" + flocation.getCoordString() + ") " + factionLoc.getTag(fplayer))));
// Get the compass
ArrayList<String> asciiCompass = AsciiCompass.getAsciiCompass(inDegrees, ChatColor.RED, P.p.txt.parse("<a>"));
int halfWidth = Conf.mapWidth / 2;
// Use player's value for height
int halfHeight = fplayer.getMapHeight() / 2;
FLocation topLeft = flocation.getRelative(-halfWidth, -halfHeight);
int width = halfWidth * 2 + 1;
int height = halfHeight * 2 + 1;
if (Conf.showMapFactionKey) {
height--;
}
2017-12-19 11:18:13 +01:00
Map<String, Character> fList = new HashMap<>();
int chrIdx = 0;
// For each row
for (int dz = 0; dz < height; dz++) {
// Draw and add that row
2018-02-11 00:59:21 +01:00
FancyMessage row = new FancyMessage("");
2018-02-11 02:35:25 +01:00
if (dz < 3) {
row.then(asciiCompass.get(dz));
}
for (int dx = (dz < 3 ? 6 : 3); dx < width; dx++) {
if (dx == halfWidth && dz == halfHeight) {
row.then("+").color(ChatColor.AQUA).tooltip(TL.CLAIM_YOUAREHERE.toString());
} else {
FLocation flocationHere = topLeft.getRelative(dx, dz);
Faction factionHere = getFactionAt(flocationHere);
2018-02-11 00:59:21 +01:00
Relation relation = fplayer.getRelationTo(factionHere);
if (factionHere.isWilderness()) {
row.then("-") .color(ChatColor.GRAY);
// Check for claimat position and if so, let them claim at ;D
if (fplayer.getPlayer().hasPermission(Permission.CLAIMAT.node)) {
row.tooltip(TL.CLAIM_CLICK_TO_CLAIM.format(dx, dz))
.command(String.format("/f claimat %s %d %d", flocation.getWorldName(), dx, dz));
}
} else if (factionHere.isSafeZone()) {
2018-02-11 00:59:21 +01:00
row.then("+").color(Conf.colorPeaceful);
} else if (factionHere.isWarZone()) {
2018-02-11 00:59:21 +01:00
row.then("+").color(ChatColor.DARK_RED);
} else if (factionHere == faction || factionHere == factionLoc || relation.isAtLeast(Relation.ALLY) ||
(Conf.showNeutralFactionsOnMap && relation.equals(Relation.NEUTRAL)) ||
(Conf.showEnemyFactionsOnMap && relation.equals(Relation.ENEMY))) {
if (!fList.containsKey(factionHere.getTag())) {
fList.put(factionHere.getTag(), Conf.mapKeyChrs[Math.min(chrIdx++, Conf.mapKeyChrs.length - 1)]);
}
char tag = fList.get(factionHere.getTag());
2018-02-11 00:59:21 +01:00
row.then(String.valueOf(tag)).color(factionHere.getColorTo(faction)).tooltip(getToolTip(factionHere, fplayer));
} else {
2018-02-11 00:59:21 +01:00
row.then("-").color(ChatColor.GRAY);
}
}
}
2018-02-11 00:59:21 +01:00
ret.add(row);
}
// Add the faction key
if (Conf.showMapFactionKey) {
2018-02-11 00:59:21 +01:00
FancyMessage fRow = new FancyMessage("");
for (String key : fList.keySet()) {
2018-02-11 00:59:21 +01:00
fRow.then(String.format("%s: %s ", fList.get(key), key)).color(ChatColor.GRAY);
}
ret.add(fRow);
}
return ret;
}
private List<String> getToolTip(Faction faction, FPlayer to) {
List<String> ret = new ArrayList<>();
2018-02-11 01:57:18 +01:00
List<String> show = P.p.getConfig().getStringList("map");
2018-02-11 00:59:21 +01:00
if (!faction.isNormal()) {
String tag = faction.getTag(to);
// send header and that's all
String header = show.get(0);
if (TagReplacer.HEADER.contains(header)) {
ret.add(P.p.txt.titleize(tag));
} else {
ret.add(P.p.txt.parse(TagReplacer.FACTION.replace(header, tag)));
}
return ret; // we only show header for non-normal factions
}
for (String raw : show) {
// Hack to get rid of the extra underscores in title normally used to center tag
2018-02-11 01:04:05 +01:00
if (raw.contains("{header}")) {
2018-02-11 00:59:21 +01:00
raw = raw.replace("{header}", faction.getTag(to));
}
String parsed = TagUtil.parsePlain(faction, to, raw); // use relations
if (parsed == null) {
continue; // Due to minimal f show.
}
if (TagUtil.hasFancy(parsed)) {
List<FancyMessage> fancy = TagUtil.parseFancy(faction, to, parsed);
if (fancy != null) {
2018-02-11 01:04:05 +01:00
for (FancyMessage msg : fancy) {
ret.add((P.p.txt.parse(msg.toOldMessageFormat())));
2018-02-11 00:59:21 +01:00
}
}
continue;
}
if (!parsed.contains("{notFrozen}") && !parsed.contains("{notPermanent}")) {
if (parsed.contains("{ig}")) {
// replaces all variables with no home TL
parsed = parsed.substring(0, parsed.indexOf("{ig}")) + TL.COMMAND_SHOW_NOHOME.toString();
}
if (parsed.contains("%")) {
parsed = parsed.replaceAll("%", ""); // Just in case it got in there before we disallowed it.
}
ret.add(P.p.txt.parse(parsed));
}
}
return ret;
}
public abstract void convertFrom(MemoryBoard old);
}