<commit_before>package mytown.entities;

import com.google.common.collect.ImmutableList;
import mytown.api.interfaces.*;
import mytown.config.Config;
import mytown.core.Utils;
import mytown.core.utils.teleport.Teleport;
import mytown.entities.flag.Flag;
import mytown.entities.flag.FlagType;
import mytown.handlers.VisualsTickHandler;
import mytown.proxies.LocalizationProxy;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;

import java.util.*;

// TODO Implement TownType

/**
 * Defines a Town. A Town is made up of Residents, Ranks, Blocks, and Plots.
 *
 * @author <NAME>
 */
public class Town implements IHasResidents, IHasRanks, IHasBlocks, IHasPlots, IHasFlags, IHasBlockWhitelists, Comparable<Town> {
    private String name, oldName = null;

    public Town(String name) {
        setName(name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * Renames this current Town setting oldName to the previous name. You MUST set oldName to null after saving it in the Datasource
     */
    public void rename(String newName) {
        oldName = name;
        name = newName;
    }

    public String getOldName() {
        return oldName;
    }

    /**
     * Resets the oldName to null. You MUST call this after a name change in the Datasource!
     */
    public void resetOldName() {
        oldName = null;
    }


    @Override
    public String toString() {
        return String.format("Town: {Name: %s}", name);
    }

    /**
     * Returns the name that is currently used in the DB
     */
    public String getDBName() {
        if (getOldName() == null)
            return getName();
        else
            return getOldName();
    }

    /* ----- IHasResidents ----- */

    private Map<Resident, Rank> residents = new Hashtable<Resident, Rank>();

    public void addResident(Resident res, Rank rank) {
        residents.put(res, rank);
    }

    @Override
    public void addResident(Resident res) {
        addResident(res, defaultRank);
    }

    @Override
    public void removeResident(Resident res) {
        for (Iterator<Plot> it = plots.iterator(); it.hasNext(); ) {
            Plot plot = it.next();
            if (plot.hasOwner(res) && plot.getOwners().size() <= 1) {
                it.remove();
            }
        }
        residents.remove(res);
    }

    @Override
    public boolean hasResident(Resident res) {
        return res != null && residents.containsKey(res);
    }

    public boolean hasResident(String username) {
        for (Resident res : residents.keySet()) { // TODO Can this be made faster?
            if (res.getPlayerName().equals(username)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public ImmutableList<Resident> getResidents() {
        return ImmutableList.copyOf(residents.keySet());
    }

    /**
     * Returns the Rank the Resident is assigned to.
     */
    public Rank getResidentRank(Resident res) {
        return residents.get(res);
    }

    /**
     * Sets the given Residents Rank for this Town.
     *
     * @param res
     * @param rank
     */
    public void setResidentRank(Resident res, Rank rank) {
        if (residents.containsKey(res)) { // So a Resident is not accidentally added by setting the Rank of a non-resident
            residents.put(res, rank);
        }
    }

    /* ----- IHasRanks ----- */

    private List<Rank> ranks = new ArrayList<Rank>();
    private Rank defaultRank = null; // TODO Set default rank during creation?

    @Override
    public void addRank(Rank rank) {
        ranks.add(rank);
    }

    @Override
    public void removeRank(Rank rank) {
        ranks.remove(rank);
    }

    @Override
    public void setDefaultRank(Rank rank) {
        defaultRank = rank;
    }

    @Override
    public Rank getDefaultRank() {
        return defaultRank;
    }

    @Override
    public boolean hasRank(Rank rank) {
        return ranks.contains(rank);
    }

    @Override
    public boolean hasRankName(String rankName) {
        for (Rank r : ranks) {
            if (r.getName().equals(rankName))
                return true;
        }
        return false;
    }

    @Override
    public Rank getRank(String rankName) {
        for (Rank r : ranks) {
            if (r.getName().equals(rankName))
                return r;
        }
        return null;
    }

    @Override
    public boolean promoteResident(Resident res, Rank rank) {
        if (hasResident(res) && hasRank(rank)) {
            residents.remove(res);
            residents.put(res, rank);
            return true;
        }
        return false;
    }


    @Override
    public ImmutableList<Rank> getRanks() {
        return ImmutableList.copyOf(ranks);
    }

    /* ----- IHasBlocks ----- */

    protected Map<String, TownBlock> blocks = new Hashtable<String, TownBlock>();
    protected int extraBlocks = 0;

    @Override
    public void addBlock(TownBlock block) {
        blocks.put(block.getKey(), block);
    }

    @Override
    public void removeBlock(TownBlock block) {
        blocks.remove(block.getKey());
    }

    @Override
    public boolean hasBlock(TownBlock block) {
        return blocks.containsValue(block);
    }

    @Override
    public ImmutableList<TownBlock> getBlocks() {
        return ImmutableList.copyOf(blocks.values());
    }

    @Override
    public TownBlock getBlockAtCoords(int dim, int x, int z) {
        return blocks.get(String.format(TownBlock.keyFormat, dim, x, z));
    }

    @Override
    public int getExtraBlocks() {
        return extraBlocks;
    }

    @Override
    public void setExtraBlocks(int extra) {
        extraBlocks = extra < 0 ? 0 : extra;
    }

    @Override
    public int getMaxBlocks() { // TODO Cache this stuff?
        int maxBlocks = Config.blocksMayor + (Config.blocksResident * (residents.size() - 1)) + extraBlocks;

        for (Resident res : getResidents()) {
            maxBlocks += res.getExtraBlocks();
        }

        return maxBlocks;
    }

    public void showBorders(Resident caller) {
        if(caller.getPlayer() instanceof EntityPlayerMP)
            VisualsTickHandler.getInstance().markTownBorders(this, (EntityPlayerMP)caller.getPlayer());
    }

    public void hideBorders(Resident caller) {
        if(caller.getPlayer() instanceof EntityPlayerMP)
            VisualsTickHandler.getInstance().unmarkBlocksForTown((EntityPlayerMP) caller.getPlayer());
    }

    /* ----- IHasPlots ----- */

    private int maxPlots;
    private boolean isShowingPlots = false;

    public void setMaxPlots(int maxPlots) {
        this.maxPlots = maxPlots;
    }

    public int getMaxPlots() {
        return maxPlots;
    }

    /**
     * Returns plots owned by the player
     */
    public List<Plot> getPlotsOwned(Resident res) {
        List<Plot> list = new ArrayList<Plot>();
        for (Plot plot : plots) {
            if (plot.hasOwner(res))
                list.add(plot);
        }
        return list;
    }

    /**
     * Gets how many plots this resident is owner in
     */
    public int getAmountPlotsOwned(Resident res) {
        int x = 0;
        for (Plot plot : plots) {
            if (plot.hasOwner(res))
                x++;
        }
        return x;
    }

    /**
     * Returns if resident can make any more plots
     */
    public boolean canResidentMakePlot(Resident res) {
        return getAmountPlotsOwned(res) >= maxPlots && !residents.get(res).hasPermission("mytown.plot.unlimited");
    }

    private List<Plot> plots = new ArrayList<Plot>();

    @Override
    public void addPlot(Plot plot) {
        plots.add(plot);
    }

    @Override
    public void removePlot(Plot plot) {
        for (int x = plot.getStartChunkX(); x <= plot.getEndChunkX(); x++) {
            for (int z = plot.getStartChunkZ(); z <= plot.getEndChunkZ(); z++) {
                TownBlock b = getBlockAtCoords(plot.getDim(), x, z);
                if (b != null) {
                    b.removePlot(plot);
                }
            }
        }
        plots.remove(plot);
    }

    @Override
    public boolean hasPlot(Plot plot) {
        return plots.contains(plot);
    }

    @Override
    public ImmutableList<Plot> getPlots() {
        return ImmutableList.copyOf(plots);
    }

    @Override
    public Plot getPlotAtCoords(int dim, int x, int y, int z) {
        TownBlock b = getBlockAtCoords(dim, x >> 4, z >> 4);
        if (b != null) {
            return b.getPlotAtCoords(dim, x, y, z);
        }

        return null;
    }

    public Plot getPlotAtResident(Resident res) {
        return getPlotAtCoords(res.getPlayer().dimension, (int) res.getPlayer().posX, (int) res.getPlayer().posY, (int) res.getPlayer().posZ);
    }

    public void showPlots(Resident caller) {
        if(caller.getPlayer() instanceof EntityPlayerMP)
            for(Plot plot : plots) {
                VisualsTickHandler.getInstance().markPlotBorders(plot, (EntityPlayerMP)caller.getPlayer());
            }
    }

    public void hidePlots(Resident caller) {
        if(caller.getPlayer() instanceof EntityPlayerMP)
            VisualsTickHandler.getInstance().unmarkBlocksForPlots((EntityPlayerMP)caller.getPlayer());
    }

    /* ----- IHasFlags ------ */

    private List<Flag> flags = new ArrayList<Flag>();

    @Override
    public void addFlag(Flag flag) {
        flags.add(flag);
    }<commit_msg>Fixed getting plot at resident's position.<commit_after>package mytown.entities;

import com.google.common.collect.ImmutableList;
import mytown.MyTown;
import mytown.api.interfaces.*;
import mytown.config.Config;
import mytown.core.Utils;
import mytown.core.utils.teleport.Teleport;
import mytown.entities.flag.Flag;
import mytown.entities.flag.FlagType;
import mytown.handlers.VisualsTickHandler;
import mytown.proxies.LocalizationProxy;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;

import java.util.*;

// TODO Implement TownType

/**
 * Defines a Town. A Town is made up of Residents, Ranks, Blocks, and Plots.
 *
 * @author <NAME>
 */
public class Town implements IHasResidents, IHasRanks, IHasBlocks, IHasPlots, IHasFlags, IHasBlockWhitelists, Comparable<Town> {
    private String name, oldName = null;

    public Town(String name) {
        setName(name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * Renames this current Town setting oldName to the previous name. You MUST set oldName to null after saving it in the Datasource
     */
    public void rename(String newName) {
        oldName = name;
        name = newName;
    }

    public String getOldName() {
        return oldName;
    }

    /**
     * Resets the oldName to null. You MUST call this after a name change in the Datasource!
     */
    public void resetOldName() {
        oldName = null;
    }


    @Override
    public String toString() {
        return String.format("Town: {Name: %s}", name);
    }

    /**
     * Returns the name that is currently used in the DB
     */
    public String getDBName() {
        if (getOldName() == null)
            return getName();
        else
            return getOldName();
    }

    /* ----- IHasResidents ----- */

    private Map<Resident, Rank> residents = new Hashtable<Resident, Rank>();

    public void addResident(Resident res, Rank rank) {
        residents.put(res, rank);
    }

    @Override
    public void addResident(Resident res) {
        addResident(res, defaultRank);
    }

    @Override
    public void removeResident(Resident res) {
        for (Iterator<Plot> it = plots.iterator(); it.hasNext(); ) {
            Plot plot = it.next();
            if (plot.hasOwner(res) && plot.getOwners().size() <= 1) {
                it.remove();
            }
        }
        residents.remove(res);
    }

    @Override
    public boolean hasResident(Resident res) {
        return res != null && residents.containsKey(res);
    }

    public boolean hasResident(String username) {
        for (Resident res : residents.keySet()) { // TODO Can this be made faster?
            if (res.getPlayerName().equals(username)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public ImmutableList<Resident> getResidents() {
        return ImmutableList.copyOf(residents.keySet());
    }

    /**
     * Returns the Rank the Resident is assigned to.
     */
    public Rank getResidentRank(Resident res) {
        return residents.get(res);
    }

    /**
     * Sets the given Residents Rank for this Town.
     *
     * @param res
     * @param rank
     */
    public void setResidentRank(Resident res, Rank rank) {
        if (residents.containsKey(res)) { // So a Resident is not accidentally added by setting the Rank of a non-resident
            residents.put(res, rank);
        }
    }

    /* ----- IHasRanks ----- */

    private List<Rank> ranks = new ArrayList<Rank>();
    private Rank defaultRank = null; // TODO Set default rank during creation?

    @Override
    public void addRank(Rank rank) {
        ranks.add(rank);
    }

    @Override
    public void removeRank(Rank rank) {
        ranks.remove(rank);
    }

    @Override
    public void setDefaultRank(Rank rank) {
        defaultRank = rank;
    }

    @Override
    public Rank getDefaultRank() {
        return defaultRank;
    }

    @Override
    public boolean hasRank(Rank rank) {
        return ranks.contains(rank);
    }

    @Override
    public boolean hasRankName(String rankName) {
        for (Rank r : ranks) {
            if (r.getName().equals(rankName))
                return true;
        }
        return false;
    }

    @Override
    public Rank getRank(String rankName) {
        for (Rank r : ranks) {
            if (r.getName().equals(rankName))
                return r;
        }
        return null;
    }

    @Override
    public boolean promoteResident(Resident res, Rank rank) {
        if (hasResident(res) && hasRank(rank)) {
            residents.remove(res);
            residents.put(res, rank);
            return true;
        }
        return false;
    }


    @Override
    public ImmutableList<Rank> getRanks() {
        return ImmutableList.copyOf(ranks);
    }

    /* ----- IHasBlocks ----- */

    protected Map<String, TownBlock> blocks = new Hashtable<String, TownBlock>();
    protected int extraBlocks = 0;

    @Override
    public void addBlock(TownBlock block) {
        blocks.put(block.getKey(), block);
    }

    @Override
    public void removeBlock(TownBlock block) {
        blocks.remove(block.getKey());
    }

    @Override
    public boolean hasBlock(TownBlock block) {
        return blocks.containsValue(block);
    }

    @Override
    public ImmutableList<TownBlock> getBlocks() {
        return ImmutableList.copyOf(blocks.values());
    }

    @Override
    public TownBlock getBlockAtCoords(int dim, int x, int z) {
        return blocks.get(String.format(TownBlock.keyFormat, dim, x, z));
    }

    @Override
    public int getExtraBlocks() {
        return extraBlocks;
    }

    @Override
    public void setExtraBlocks(int extra) {
        extraBlocks = extra < 0 ? 0 : extra;
    }

    @Override
    public int getMaxBlocks() { // TODO Cache this stuff?
        int maxBlocks = Config.blocksMayor + (Config.blocksResident * (residents.size() - 1)) + extraBlocks;

        for (Resident res : getResidents()) {
            maxBlocks += res.getExtraBlocks();
        }

        return maxBlocks;
    }

    public void showBorders(Resident caller) {
        if(caller.getPlayer() instanceof EntityPlayerMP)
            VisualsTickHandler.getInstance().markTownBorders(this, (EntityPlayerMP)caller.getPlayer());
    }

    public void hideBorders(Resident caller) {
        if(caller.getPlayer() instanceof EntityPlayerMP)
            VisualsTickHandler.getInstance().unmarkBlocksForTown((EntityPlayerMP) caller.getPlayer());
    }

    /* ----- IHasPlots ----- */

    private int maxPlots;
    private boolean isShowingPlots = false;

    public void setMaxPlots(int maxPlots) {
        this.maxPlots = maxPlots;
    }

    public int getMaxPlots() {
        return maxPlots;
    }

    /**
     * Returns plots owned by the player
     */
    public List<Plot> getPlotsOwned(Resident res) {
        List<Plot> list = new ArrayList<Plot>();
        for (Plot plot : plots) {
            if (plot.hasOwner(res))
                list.add(plot);
        }
        return list;
    }

    /**
     * Gets how many plots this resident is owner in
     */
    public int getAmountPlotsOwned(Resident res) {
        int x = 0;
        for (Plot plot : plots) {
            if (plot.hasOwner(res))
                x++;
        }
        return x;
    }

    /**
     * Returns if resident can make any more plots
     */
    public boolean canResidentMakePlot(Resident res) {
        return getAmountPlotsOwned(res) >= maxPlots && !residents.get(res).hasPermission("mytown.plot.unlimited");
    }

    private List<Plot> plots = new ArrayList<Plot>();

    @Override
    public void addPlot(Plot plot) {
        plots.add(plot);
    }

    @Override
    public void removePlot(Plot plot) {
        for (int x = plot.getStartChunkX(); x <= plot.getEndChunkX(); x++) {
            for (int z = plot.getStartChunkZ(); z <= plot.getEndChunkZ(); z++) {
                TownBlock b = getBlockAtCoords(plot.getDim(), x, z);
                if (b != null) {
                    b.removePlot(plot);
                }
            }
        }
        plots.remove(plot);
    }

    @Override
    public boolean hasPlot(Plot plot) {
        return plots.contains(plot);
    }

    @Override
    public ImmutableList<Plot> getPlots() {
        return ImmutableList.copyOf(plots);
    }

    @Override
    public Plot getPlotAtCoords(int dim, int x, int y, int z) {
        TownBlock b = getBlockAtCoords(dim, x >> 4, z >> 4);
        if (b != null) {
            return b.getPlotAtCoords(dim, x, y, z);
        }

        return null;
    }

    public Plot getPlotAtResident(Resident res) {
        /*
        MyTown.instance.log.info("Floor: " + Math.floor(res.getPlayer().posX) + ", " + Math.floor(res.getPlayer().posY) + ", " + Math.floor(res.getPlayer().posZ));
        MyTown.instance.log.info("Ceil: " + Math.ceil(res.getPlayer().posX) + ", " + Math.ceil(res.getPlayer().posY) + ", " + Math.ceil(res.getPlayer().posZ));
        MyTown.instance.log.info("Pos: " + (int)res.getPlayer().posX + ", " + (int)res.getPlayer().posY + ", " + (int)res.getPlayer().posZ);
        */

        return getPlotAtCoords(res.getPlayer().dimension, (int) Math.floor(res.getPlayer().posX), (int) Math.floor(res.getPlayer().posY), (int) Math.floor(res.getPlayer().posZ));
    }

    public void showPlots(Resident caller) {
        if(caller.getPlayer() instanceof EntityPlayerMP)
            for(Plot plot : plots) {
                VisualsTickHandler.getInstance().markPlotBorders(plot, (EntityPlayerMP)caller.getPlayer());
            }
    }

    public void hidePlots(Resident caller) {
        if(caller.getPlayer() instanceof EntityPlayerMP)
            VisualsTickHandler.getInstance().unmarkBlocksForPlots((EntityPlayerMP)caller.getPlayer());
    }

    /* ----- IHasFlags ------ */

    private List<Flag> flags = new ArrayList<Flag>();

    @Override
    public void addFlag(Flag flag) {
        flags.add(flag);
    }
{'fraction_non_alphanumeric': 0.1153317378685269, 'fraction_numerical': 0.0008147054330668568, 'mean_word_length': 2.191938891597595, 'pattern_counts': {'":': 0, '<': 51, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7377760', 'n_tokens_mistral': 5936, 'n_tokens_neox': 5693, 'n_words': 1433}