First try at a tax system

This hasn't been tested. This is a tax system where Factions can tax their players. Later it should be extended do that servers can tax factions based on how much land they have claimed. We start of with this simpler system to make sure that can be tested in real-life environments before we go ahead with the more full fledged system.
This commit is contained in:
Magnus Ulf
2019-07-15 07:55:12 +02:00
parent 193a4acc83
commit 35c38ce4b8
13 changed files with 416 additions and 93 deletions

View File

@@ -11,6 +11,8 @@ import com.massivecraft.factions.predicate.PredicateCommandSenderFaction;
import com.massivecraft.factions.predicate.PredicateMPlayerRank;
import com.massivecraft.factions.util.MiscUtil;
import com.massivecraft.factions.util.RelationUtil;
import com.massivecraft.massivecore.Couple;
import com.massivecraft.massivecore.Identified;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.collections.MassiveMap;
import com.massivecraft.massivecore.collections.MassiveMapDef;
@@ -38,6 +40,7 @@ import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -158,8 +161,13 @@ public class Faction extends Entity<Faction> implements FactionsParticipator, MP
// Null means default.
private MassiveMapDef<String, Boolean> flags = new MassiveMapDef<>();
private Map<String, Set<String>> perms = this.createNewPermMap();
// What is the base tax on members of the faction?
// Specific taxes on ranks or players.
public static String IDENTIFIER_TAX_BASE = "base";
private Map<String, Double> tax = new MassiveMap<>();
// -------------------------------------------- //
// FIELD: id
@@ -944,6 +952,62 @@ public class Faction extends Entity<Faction> implements FactionsParticipator, MP
return MPermColl.get().getFixed(permId) != null;
}
// -------------------------------------------- //
// FIELD: tax
// -------------------------------------------- //
// RAW
public Map<String, Double> getTax() { return this.tax; }
// FINER GET
public Double getTaxFor(String id)
{
if (id == null) throw new NullPointerException("id");
return this.tax.get(id);
}
public Double getTaxFor(Identified identified)
{
if (identified == null) throw new NullPointerException("identified");
return this.getTaxFor(identified.getId());
}
public double getTaxForPlayer(MPlayer mplayer)
{
return getTaxAndReasonForPlayer(mplayer).map(Entry::getValue).orElse(0D);
}
public Optional<Entry<String, Double>> getTaxAndReasonForPlayer(MPlayer mplayer)
{
if (mplayer == null) throw new NullPointerException("mplayer");
if (mplayer.getFaction() != this) throw new IllegalArgumentException("Player " + mplayer.getId() + " not in " + this.getId());
Double ret = null;
ret = this.getTaxFor(mplayer);
if (ret != null) return Optional.of(new Couple<>(mplayer.getId(), ret));
ret = this.getTaxFor(mplayer.getRank());
if (ret != null) return Optional.of(new Couple<>(mplayer.getRank().getId(), ret));
ret = this.getTaxFor(IDENTIFIER_TAX_BASE);
if (ret != null) return Optional.of(new Couple<>(IDENTIFIER_TAX_BASE, ret));
return Optional.empty();
}
// FINER SET
public Double setTaxFor(String id, Double value)
{
return this.tax.put(id, value);
}
public Double setTaxFor(Identified identified, Double value)
{
return this.setTaxFor(identified.getId(), value);
}
// -------------------------------------------- //
// OVERRIDE: RelationParticipator
// -------------------------------------------- //

View File

@@ -2,7 +2,6 @@ package com.massivecraft.factions.entity;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.Rel;
import com.massivecraft.factions.integration.Econ;
import com.massivecraft.factions.util.MiscUtil;
import com.massivecraft.massivecore.collections.MassiveMap;
import com.massivecraft.massivecore.store.Coll;
@@ -165,48 +164,9 @@ public class FactionColl extends Coll<Faction>
}
// -------------------------------------------- //
// LAND REWARD
// NAME
// -------------------------------------------- //
public void econLandRewardRoutine()
{
// If econ is enabled ...
if (!Econ.isEnabled()) return;
// ... and the land reward is non zero ...
double econLandReward = MConf.get().econLandReward;
if (econLandReward == 0.0) return;
// ... log initiation ...
Factions.get().log("Running econLandRewardRoutine...");
MFlag flagPeaceful = MFlag.getFlagPeaceful();
// ... and for each faction ...
for (Faction faction : this.getAll())
{
// ... get the land count ...
int landCount = faction.getLandCount();
// ... and if the faction isn't peaceful and has land ...
if (landCount == 0 || faction.getFlag(flagPeaceful)) continue;
// ... get the faction's members ...
List<MPlayer> players = faction.getMPlayers();
// ... calculate the reward ...
int playerCount = players.size();
double reward = econLandReward * landCount / playerCount;
// ... and grant the reward.
String description = String.format("own %s faction land divided among %s members", landCount, playerCount);
for (MPlayer player : players)
{
Econ.modifyMoney(player, reward, description);
}
}
}
@Override
public Faction getByName(String name)
{

View File

@@ -30,7 +30,7 @@ public class MConf extends Entity<MConf>
// -------------------------------------------- //
// META
// -------------------------------------------- //
protected static transient MConf i;
public static MConf get() { return i; }
@@ -487,7 +487,36 @@ public class MConf extends Entity<MConf>
public boolean logFactionLeave = true;
public boolean logLandClaims = true;
public boolean logMoneyTransactions = true;
// -------------------------------------------- //
// TAX
// -------------------------------------------- //
// Should the tax system be enabled?
public boolean taxEnabled = false;
// How much can you tax a player?
public double taxPlayerMinimum = -10;
public double taxPlayerMaximum = 10;
// How much should Factions be taxed?
//public double taxUpkeepBase = 0;
//public double taxUpkeepPerChunk = 1;
// When is a player inactive?
public int taxInactiveDays = 3;
// When the last run time was (in unix time)
// 0 means never
public long taxTaskLastMillis = 0;
// Tax run when?
// 0 means at midnight UTC it can be offset by a certain millis
public long taxTaskInvocationOffsetMillis = 0;
// How often should the task be run?
public long taxTaskPeriodMillis = TimeUnit.MILLIS_PER_DAY;
// -------------------------------------------- //
// ENUMERATIONS
// -------------------------------------------- //
@@ -574,10 +603,6 @@ public class MConf extends Entity<MConf>
// This requires that you have the external plugin called "Vault" installed.
public boolean econEnabled = true;
// A money reward per chunk. This reward is divided among the players in the faction.
// You set the time inbetween each reward almost at the top of this config file. (taskEconLandRewardMinutes)
public double econLandReward = 0.00;
// When paying a cost you may specify an account that should receive the money here.
// Per default "" the money is just destroyed.
public String econUniverseAccount = "";

View File

@@ -36,6 +36,7 @@ public class MFlag extends Entity<MFlag> implements Prioritized, Registerable, N
public final static transient String ID_PEACEFUL = "peaceful";
public final static transient String ID_INFPOWER = "infpower";
public final static transient String ID_FLY = "fly";
public final static transient String ID_TAXKICK = "taxkick";
public final static transient int PRIORITY_OPEN = 1_000;
public final static transient int PRIORITY_MONSTERS = 2_000;
@@ -53,6 +54,7 @@ public class MFlag extends Entity<MFlag> implements Prioritized, Registerable, N
public final static transient int PRIORITY_PEACEFUL = 14_000;
public final static transient int PRIORITY_INFPOWER = 15_000;
public final static transient int PRIORITY_FLY = 16_000;
public final static transient int PRIORITY_TAXKICK = 17_000;
// -------------------------------------------- //
// META: CORE
@@ -93,6 +95,7 @@ public class MFlag extends Entity<MFlag> implements Prioritized, Registerable, N
getFlagPeaceful();
getFlagInfpower();
getFlagFly();
getFlagTaxKick();
}
public static MFlag getFlagOpen() { return getCreative(PRIORITY_OPEN, ID_OPEN, ID_OPEN, "Can the faction be joined without an invite?", "Anyone can join. No invite required.", "An invite is required to join.", false, true, true); }
@@ -111,6 +114,7 @@ public class MFlag extends Entity<MFlag> implements Prioritized, Registerable, N
public static MFlag getFlagPeaceful() { return getCreative(PRIORITY_PEACEFUL, ID_PEACEFUL, ID_PEACEFUL, "Is the faction in truce with everyone?", "The faction is in truce with everyone.", "The faction relations work as usual.", false, false, true); }
public static MFlag getFlagInfpower() { return getCreative(PRIORITY_INFPOWER, ID_INFPOWER, ID_INFPOWER, "Does the faction have infinite power?", "The faction has infinite power.", "The faction power works as usual.", false, false, true); }
public static MFlag getFlagFly() { return getCreative(PRIORITY_FLY, ID_FLY, ID_FLY, "Is flying allowed for members in faction territory?", "Members can fly in faction territory.", "Members can not fly in faction territory.", false, false, true); }
public static MFlag getFlagTaxKick() { return getCreative(PRIORITY_TAXKICK, ID_TAXKICK, ID_TAXKICK, "Are players kicked for not paying taxes?", "Members are kicked for not paying taxes.", "Members are not kicked for not paying taxes.", false, true, true); }
public static MFlag getCreative(int priority, String id, String name, String desc, String descYes, String descNo, boolean standard, boolean editable, boolean visible)
{

View File

@@ -56,9 +56,10 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
public final static transient String ID_WITHDRAW = "withdraw";
public final static transient String ID_TERRITORY = "territory";
public final static transient String ID_ACCESS = "access";
public final static transient String ID_VOTE = "VOTE";
public final static transient String ID_VOTE = "VOTE"; // Why is this capitalised? Can that be easily changed?
public final static transient String ID_CREATEVOTE = "createvote";
public final static transient String ID_CLAIMNEAR = "claimnear";
public final static transient String ID_TAX = "tax";
public final static transient String ID_REL = "rel";
public final static transient String ID_DISBAND = "disband";
public final static transient String ID_FLAGS = "flags";
@@ -87,6 +88,7 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
public final static transient int PRIORITY_VOTE = 18200;
public final static transient int PRIORITY_CREATEVOTE = 18600;
public final static transient int PRIORITY_CLAIMNEAR = 19000;
public final static transient int PRIORITY_TAX = 19500;
public final static transient int PRIORITY_REL = 20000;
public final static transient int PRIORITY_DISBAND = 21000;
public final static transient int PRIORITY_FLAGS = 22000;
@@ -139,6 +141,7 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
getPermVote();
getPermCreateVote();
getPermClaimnear();
getPermTax();
getPermRel();
getPermDisband();
getPermFlags();
@@ -168,6 +171,7 @@ public class MPerm extends Entity<MPerm> implements Prioritized, Registerable, N
public static MPerm getPermVote() { return getCreative(PRIORITY_VOTE, ID_VOTE, ID_VOTE, "vote", MUtil.set("LEADER", "OFFICER", "MEMBER", "RECRUIT"), false, true, true); }
public static MPerm getPermCreateVote() { return getCreative(PRIORITY_CREATEVOTE, ID_CREATEVOTE, ID_CREATEVOTE, "manage votes", MUtil.set("LEADER", "OFFICER"), false, true, true); }
public static MPerm getPermClaimnear() { return getCreative(PRIORITY_CLAIMNEAR, ID_CLAIMNEAR, ID_CLAIMNEAR, "claim nearby", MUtil.set("LEADER", "OFFICER", "MEMBER", "RECRUIT", "ALLY"), false, false, false); } // non editable, non visible.
public static MPerm getPermTax() { return getCreative(PRIORITY_TAX, ID_TAX, ID_TAX, "set taxes", MUtil.set("LEADER"), false, true, true); }
public static MPerm getPermRel() { return getCreative(PRIORITY_REL, ID_REL, ID_REL, "change relations", MUtil.set("LEADER", "OFFICER"), false, true, true); }
public static MPerm getPermDisband() { return getCreative(PRIORITY_DISBAND, ID_DISBAND, ID_DISBAND, "disband the faction", MUtil.set("LEADER"), false, true, true); }
public static MPerm getPermFlags() { return getCreative(PRIORITY_FLAGS, ID_FLAGS, ID_FLAGS, "manage flags", MUtil.set("LEADER"), false, true, true); }