Rethinking power calculation some.

This commit is contained in:
Olof Larsson 2013-04-23 12:14:36 +02:00
parent 6b7312bcf8
commit 3c60f75bbd
15 changed files with 283 additions and 414 deletions

View File

@ -51,8 +51,6 @@ permissions:
factions.officer.any: {description: give or revoke officer rights for any player in any faction} factions.officer.any: {description: give or revoke officer rights for any player in any faction}
factions.open: {description: switch if invitation is required to join} factions.open: {description: switch if invitation is required to join}
factions.perm: {description: change faction permissions} factions.perm: {description: change faction permissions}
factions.power: {description: show player power info}
factions.power.any: {description: view an other players power level}
factions.powerboost: {description: apply permanent power bonus/penalty to specified player or faction} factions.powerboost: {description: apply permanent power bonus/penalty to specified player or faction}
factions.promote: {description: promote lesser members in your faction} factions.promote: {description: promote lesser members in your faction}
factions.relation: {description: set relation wish to another faction} factions.relation: {description: set relation wish to another faction}
@ -145,8 +143,6 @@ permissions:
factions.money.*: true factions.money.*: true
factions.open: true factions.open: true
factions.perm: true factions.perm: true
factions.power: true
factions.power.any: true
factions.promote: true factions.promote: true
factions.relation: true factions.relation: true
factions.seechunk: true factions.seechunk: true

View File

@ -80,6 +80,7 @@ public class ConfServer extends SimpleConfig
// ASSORTED // ASSORTED
// -------------------------------------------- // // -------------------------------------------- //
// TODO: Should this be based on a permission node lookup map?
public static double territoryShieldFactor = 0.3; public static double territoryShieldFactor = 0.3;
// for claimed areas where further faction-member ownership can be defined // for claimed areas where further faction-member ownership can be defined

View File

@ -33,7 +33,8 @@ import com.massivecraft.factions.listeners.FactionsListenerExploit;
import com.massivecraft.factions.listeners.FactionsListenerMain; import com.massivecraft.factions.listeners.FactionsListenerMain;
import com.massivecraft.factions.listeners.TodoFactionsPlayerListener; import com.massivecraft.factions.listeners.TodoFactionsPlayerListener;
import com.massivecraft.factions.task.AutoLeaveTask; import com.massivecraft.factions.task.AutoLeaveTask;
import com.massivecraft.factions.task.EconLandRewardTask; import com.massivecraft.factions.task.EconRewardTask;
import com.massivecraft.factions.task.PowerUpdateTask;
import com.massivecraft.mcore.MPlugin; import com.massivecraft.mcore.MPlugin;
import com.massivecraft.mcore.usys.Aspect; import com.massivecraft.mcore.usys.Aspect;
@ -128,8 +129,9 @@ public class Factions extends MPlugin
getServer().getPluginManager().registerEvents(this.playerListener, this); getServer().getPluginManager().registerEvents(this.playerListener, this);
// Schedule recurring non-tps-dependent tasks // Schedule recurring non-tps-dependent tasks
PowerUpdateTask.get().schedule(this);
AutoLeaveTask.get().schedule(this); AutoLeaveTask.get().schedule(this);
EconLandRewardTask.get().schedule(this); EconRewardTask.get().schedule(this);
// Register built in chat modifiers // Register built in chat modifiers
ChatModifierLc.get().register(); ChatModifierLc.get().register();

View File

@ -52,8 +52,6 @@ public enum Perm
OFFICER_ANY("officer.any"), OFFICER_ANY("officer.any"),
OPEN("open"), OPEN("open"),
PERM("perm"), PERM("perm"),
POWER("power"),
POWER_ANY("power.any"),
POWERBOOST("powerboost"), POWERBOOST("powerboost"),
PROMOTE("promote"), PROMOTE("promote"),
RELATION("relation"), RELATION("relation"),

View File

@ -31,7 +31,6 @@ public class CmdFactions extends FCommand
public CmdFactionsMoney cmdFactionsMoney = new CmdFactionsMoney(); public CmdFactionsMoney cmdFactionsMoney = new CmdFactionsMoney();
public CmdFactionsOpen cmdFactionsOpen = new CmdFactionsOpen(); public CmdFactionsOpen cmdFactionsOpen = new CmdFactionsOpen();
public CmdFactionsPerm cmdFactionsPerm = new CmdFactionsPerm(); public CmdFactionsPerm cmdFactionsPerm = new CmdFactionsPerm();
public CmdFactionsPower cmdFactionsPower = new CmdFactionsPower();
public CmdFactionsPowerBoost cmdFactionsPowerBoost = new CmdFactionsPowerBoost(); public CmdFactionsPowerBoost cmdFactionsPowerBoost = new CmdFactionsPowerBoost();
public CmdFactionsPromote cmdFactionsPromote = new CmdFactionsPromote(); public CmdFactionsPromote cmdFactionsPromote = new CmdFactionsPromote();
public CmdFactionsRelationAlly cmdFactionsRelationAlly = new CmdFactionsRelationAlly(); public CmdFactionsRelationAlly cmdFactionsRelationAlly = new CmdFactionsRelationAlly();
@ -62,7 +61,6 @@ public class CmdFactions extends FCommand
this.addSubCommand(HelpCommand.get()); this.addSubCommand(HelpCommand.get());
this.addSubCommand(this.cmdFactionsList); this.addSubCommand(this.cmdFactionsList);
this.addSubCommand(this.cmdFactionsShow); this.addSubCommand(this.cmdFactionsShow);
this.addSubCommand(this.cmdFactionsPower);
this.addSubCommand(this.cmdFactionsJoin); this.addSubCommand(this.cmdFactionsJoin);
this.addSubCommand(this.cmdFactionsLeave); this.addSubCommand(this.cmdFactionsLeave);
this.addSubCommand(this.cmdFactionsHome); this.addSubCommand(this.cmdFactionsHome);

View File

@ -1,33 +0,0 @@
package com.massivecraft.factions.cmd;
import com.massivecraft.factions.Perm;
import com.massivecraft.factions.cmd.arg.ARUPlayer;
import com.massivecraft.factions.entity.UPlayer;
import com.massivecraft.mcore.cmd.req.ReqHasPerm;
public class CmdFactionsPower extends FCommand
{
public CmdFactionsPower()
{
this.addAliases("power", "pow");
this.addOptionalArg("player", "you");
this.addRequirements(ReqHasPerm.get(Perm.POWER.node));
}
@Override
public void perform()
{
UPlayer target = this.arg(0, ARUPlayer.getStartAny(fme), fme);
if (target == null) return;
if (target != fme && ! Perm.POWER_ANY.has(sender, true)) return;
double powerBoost = target.getPowerBoost();
String boost = (powerBoost == 0.0) ? "" : (powerBoost > 0.0 ? " (bonus: " : " (penalty: ") + powerBoost + ")";
msg("%s<a> - Power / Maxpower: <i>%d / %d %s", target.describeTo(fme, true), target.getPowerRounded(), target.getPowerMaxRounded(), boost);
}
}

View File

@ -2,9 +2,7 @@ package com.massivecraft.factions.cmd;
import com.massivecraft.factions.Factions; import com.massivecraft.factions.Factions;
import com.massivecraft.factions.Perm; import com.massivecraft.factions.Perm;
import com.massivecraft.factions.cmd.arg.ARUPlayer;
import com.massivecraft.factions.cmd.arg.ARFaction; import com.massivecraft.factions.cmd.arg.ARFaction;
import com.massivecraft.factions.entity.UPlayer;
import com.massivecraft.factions.entity.Faction; import com.massivecraft.factions.entity.Faction;
import com.massivecraft.mcore.cmd.arg.ARDouble; import com.massivecraft.mcore.cmd.arg.ARDouble;
import com.massivecraft.mcore.cmd.req.ReqHasPerm; import com.massivecraft.mcore.cmd.req.ReqHasPerm;
@ -15,9 +13,8 @@ public class CmdFactionsPowerBoost extends FCommand
{ {
this.addAliases("powerboost"); this.addAliases("powerboost");
this.addRequiredArg("p|f|player|faction"); this.addRequiredArg("faction");
this.addRequiredArg("name"); this.addRequiredArg("amount");
this.addRequiredArg("#");
this.addRequirements(ReqHasPerm.get(Perm.POWERBOOST.node)); this.addRequirements(ReqHasPerm.get(Perm.POWERBOOST.node));
} }
@ -25,42 +22,17 @@ public class CmdFactionsPowerBoost extends FCommand
@Override @Override
public void perform() public void perform()
{ {
String type = this.arg(0).toLowerCase(); Faction faction = this.arg(0, ARFaction.get(fme));
boolean doPlayer = true; if (faction == null) return;
if (type.equals("f") || type.equals("faction"))
{
doPlayer = false;
}
else if (!type.equals("p") && !type.equals("player"))
{
msg("<b>You must specify \"p\" or \"player\" to target a player or \"f\" or \"faction\" to target a faction.");
msg("<b>ex. /f powerboost p SomePlayer 0.5 -or- /f powerboost f SomeFaction -5");
return;
}
Double targetPower = this.arg(2, ARDouble.get()); Double amount = this.arg(1, ARDouble.get());
if (targetPower == null) return; if (amount == null) return;
String target; faction.setPowerBoost(amount);
if (doPlayer) msg("<i>"+faction.getTag()+" now has a power bonus/penalty of "+amount+" to min and max power levels.");
{
UPlayer targetPlayer = this.arg(1, ARUPlayer.getStartAny(sender)); // TODO: Inconsistent. Why is there no boolean to toggle this logging of?
if (targetPlayer == null) return; Factions.get().log(fme.getName()+" has set the power bonus/penalty for "+faction.getTag()+" to "+amount+".");
targetPlayer.setPowerBoost(targetPower);
target = "Player \""+targetPlayer.getName()+"\"";
}
else
{
Faction targetFaction = this.arg(1, ARFaction.get(sender));
if (targetFaction == null) return;
targetFaction.setPowerBoost(targetPower);
target = "Faction \""+targetFaction.getTag()+"\"";
}
msg("<i>"+target+" now has a power bonus/penalty of "+targetPower+" to min and max power levels.");
Factions.get().log(fme.getName()+" has set the power bonus/penalty for "+target+" to "+targetPower+".");
} }
} }

View File

@ -646,44 +646,25 @@ public class Faction extends Entity<Faction> implements EconomyParticipator
public double getPower() public double getPower()
{ {
if (this.getFlag(FFlag.INFPOWER)) if (this.getFlag(FFlag.INFPOWER)) return 999999;
{
return 999999;
}
double ret = 0; double ret = 0;
for (UPlayer uplayer : this.getUPlayers()) for (UPlayer uplayer : this.getUPlayers())
{ {
ret += uplayer.getPower(); ret += uplayer.getPower();
} }
ret += this.getPowerBoost();
if (UConf.get(this).powerFactionMax > 0 && ret > UConf.get(this).powerFactionMax) ret = Math.min(ret, this.getPowerMax());
{ ret = Math.max(ret, 0);
ret = UConf.get(this).powerFactionMax;
}
return ret + this.getPowerBoost(); return ret;
} }
public double getPowerMax() public double getPowerMax()
{ {
if (this.getFlag(FFlag.INFPOWER)) if (this.getFlag(FFlag.INFPOWER)) return 999999;
{ return UConf.get(this).powerFactionMax + this.getPowerBoost();
return 999999;
}
double ret = 0;
for (UPlayer uplayer : this.getUPlayers())
{
ret += uplayer.getPowerMax();
}
if (UConf.get(this).powerFactionMax > 0 && ret > UConf.get(this).powerFactionMax)
{
ret = UConf.get(this).powerFactionMax;
}
return ret + this.getPowerBoost();
} }
public int getPowerRounded() public int getPowerRounded()

View File

@ -1,13 +1,20 @@
package com.massivecraft.factions.entity; package com.massivecraft.factions.entity;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.permissions.PermissionDefault;
import com.massivecraft.mcore.store.Entity; import com.massivecraft.mcore.store.Entity;
import com.massivecraft.mcore.util.MUtil;
import com.massivecraft.mcore.util.PermUtil;
import com.massivecraft.mcore.util.TimeUnit;
public class MConf extends Entity<MConf> public class MConf extends Entity<MConf>
{ {
@ -19,27 +26,73 @@ public class MConf extends Entity<MConf>
public static MConf get() { return i; } public static MConf get() { return i; }
// -------------------------------------------- // // -------------------------------------------- //
// COLORS // OVERRIDE: ENTITY
// -------------------------------------------- // // -------------------------------------------- //
public ChatColor colorMember = ChatColor.GREEN; @Override
public ChatColor colorAlly = ChatColor.DARK_PURPLE; public MConf load(MConf that)
public ChatColor colorTruce = ChatColor.LIGHT_PURPLE; {
public ChatColor colorNeutral = ChatColor.WHITE; super.load(that);
public ChatColor colorEnemy = ChatColor.RED;
this.upsertPowerPerms();
public ChatColor colorNoPVP = ChatColor.GOLD;
public ChatColor colorFriendlyFire = ChatColor.DARK_RED; return this;
//public ChatColor colorWilderness = ChatColor.DARK_GREEN; }
// -------------------------------------------- // // -------------------------------------------- //
// PREFIXES // POWER
// -------------------------------------------- // // -------------------------------------------- //
public String prefixLeader = "**"; public long powerTaskMillis = TimeUnit.MILLIS_PER_MINUTE;
public String prefixOfficer = "*";
public String prefixMember = "+"; public Map<String, Double> permToPowerMax = MUtil.map(
public String prefixRecruit = "-"; "factions.power.max.50", 50.0,
"factions.power.max.40", 40.0,
"factions.power.max.30", 30.0,
"factions.power.max.20", 20.0,
"factions.power.max.10", 10.0,
"factions.power.max.default", 10.0
);
public Map<String, Double> permToPowerMin = MUtil.map(
"factions.power.min.50", 50.0,
"factions.power.min.40", 40.0,
"factions.power.min.30", 30.0,
"factions.power.min.20", 20.0,
"factions.power.min.10", 10.0,
"factions.power.min.default", 10.0
);
public Map<String, Double> permToPowerHour = MUtil.map(
"factions.power.hour.50", 50.0,
"factions.power.hour.40", 40.0,
"factions.power.hour.30", 30.0,
"factions.power.hour.20", 20.0,
"factions.power.hour.10", 10.0,
"factions.power.hour.4", 4.0,
"factions.power.hour.2", 2.0,
"factions.power.hour.default", 2.0
);
public Map<String, Double> permToPowerDeath = MUtil.map(
"factions.power.death.0", 0.0,
"factions.power.death.-2", -2.0,
"factions.power.death.default", -2.0
);
public void upsertPowerPerms()
{
List<String> names = new ArrayList<String>();
names.addAll(this.permToPowerMax.keySet());
names.addAll(this.permToPowerMin.keySet());
names.addAll(this.permToPowerHour.keySet());
names.addAll(this.permToPowerDeath.keySet());
for (String name : names)
{
PermUtil.get(true, true, name, name, PermissionDefault.FALSE);
}
}
// -------------------------------------------- // // -------------------------------------------- //
// CHAT // CHAT
@ -77,27 +130,27 @@ public class MConf extends Entity<MConf>
public Set<String> herochatAlliesWorlds = new HashSet<String>(); public Set<String> herochatAlliesWorlds = new HashSet<String>();
// -------------------------------------------- // // -------------------------------------------- //
// LOGGING // COLORS
// -------------------------------------------- // // -------------------------------------------- //
public boolean logFactionCreate = true; public ChatColor colorMember = ChatColor.GREEN;
public boolean logFactionDisband = true; public ChatColor colorAlly = ChatColor.DARK_PURPLE;
public boolean logFactionJoin = true; public ChatColor colorTruce = ChatColor.LIGHT_PURPLE;
public boolean logFactionKick = true; public ChatColor colorNeutral = ChatColor.WHITE;
public boolean logFactionLeave = true; public ChatColor colorEnemy = ChatColor.RED;
public boolean logLandClaims = true;
public boolean logLandUnclaims = true; public ChatColor colorNoPVP = ChatColor.GOLD;
public boolean logMoneyTransactions = true; public ChatColor colorFriendlyFire = ChatColor.DARK_RED;
public boolean logPlayerCommands = true; //public ChatColor colorWilderness = ChatColor.DARK_GREEN;
// -------------------------------------------- // // -------------------------------------------- //
// EXPLOITS // PREFIXES
// -------------------------------------------- // // -------------------------------------------- //
public boolean handleExploitObsidianGenerators = true; public String prefixLeader = "**";
public boolean handleExploitEnderPearlClipping = true; public String prefixOfficer = "*";
public boolean handleExploitInteractionSpam = true; public String prefixMember = "+";
public boolean handleExploitTNTWaterlog = false; public String prefixRecruit = "-";
// -------------------------------------------- // // -------------------------------------------- //
// DERPY OVERRIDES // DERPY OVERRIDES
@ -113,5 +166,28 @@ public class MConf extends Entity<MConf>
public Set<String> worldsNoClaiming = new LinkedHashSet<String>(); public Set<String> worldsNoClaiming = new LinkedHashSet<String>();
public Set<String> worldsNoPowerLoss = new LinkedHashSet<String>(); public Set<String> worldsNoPowerLoss = new LinkedHashSet<String>();
public Set<String> worldsIgnorePvP = new LinkedHashSet<String>(); public Set<String> worldsIgnorePvP = new LinkedHashSet<String>();
// -------------------------------------------- //
// EXPLOITS
// -------------------------------------------- //
public boolean handleExploitObsidianGenerators = true;
public boolean handleExploitEnderPearlClipping = true;
public boolean handleExploitInteractionSpam = true;
public boolean handleExploitTNTWaterlog = false;
// -------------------------------------------- //
// LOGGING
// -------------------------------------------- //
public boolean logFactionCreate = true;
public boolean logFactionDisband = true;
public boolean logFactionJoin = true;
public boolean logFactionKick = true;
public boolean logFactionLeave = true;
public boolean logLandClaims = true;
public boolean logLandUnclaims = true;
public boolean logMoneyTransactions = true;
public boolean logPlayerCommands = true;
} }

View File

@ -47,25 +47,11 @@ public class UConf extends Entity<UConf>
// POWER // POWER
// -------------------------------------------- // // -------------------------------------------- //
public double powerMax = 10.0; // TODO: Group default values together?
public double powerMin = -10.0;
public double powerStarting = 10.0; // New players start out with this power level
public double powerPerDeath = -4.0; // A death makes you lose 4 power public double powerPlayerDefault = 0.0;
public double powerPerHourOnline = 10.0; public double powerFactionMax = 1000.0;
public double powerPerHourOffline = 0.0;
// players will no longer lose power from being offline once their power drops to this amount or less
public double powerLimitGainOnline = 10.0;
public double powerLimitGainOffline = 0.0;
public double powerLimitLossOnline = -10.0;
public double powerLimitLossOffline = 0.0;
public boolean scaleNegativePower = false; // Power regeneration rate increase as power decreases
public double scaleNegativeDivisor = 40.0; // Divisor for inverse power regeneration curve
public double powerFactionMax = 0.0; // if greater than 0, the cap on how much power a faction can have (additional power from players beyond that will act as a "buffer" of sorts)
// -------------------------------------------- // // -------------------------------------------- //
// DENY COMMANDS // DENY COMMANDS

View File

@ -18,8 +18,6 @@ import com.massivecraft.factions.RelationParticipator;
import com.massivecraft.factions.event.FactionsEventLandClaim; import com.massivecraft.factions.event.FactionsEventLandClaim;
import com.massivecraft.factions.event.FactionsEventMembershipChange; import com.massivecraft.factions.event.FactionsEventMembershipChange;
import com.massivecraft.factions.event.FactionsEventMembershipChange.MembershipChangeReason; import com.massivecraft.factions.event.FactionsEventMembershipChange.MembershipChangeReason;
import com.massivecraft.factions.event.FactionsEventPowerChange;
import com.massivecraft.factions.event.FactionsEventPowerChange.PowerChangeReason;
import com.massivecraft.factions.integration.Econ; import com.massivecraft.factions.integration.Econ;
import com.massivecraft.factions.integration.LWCFeatures; import com.massivecraft.factions.integration.LWCFeatures;
import com.massivecraft.factions.integration.Worldguard; import com.massivecraft.factions.integration.Worldguard;
@ -28,8 +26,6 @@ import com.massivecraft.mcore.mixin.Mixin;
import com.massivecraft.mcore.money.Money; import com.massivecraft.mcore.money.Money;
import com.massivecraft.mcore.ps.PS; import com.massivecraft.mcore.ps.PS;
import com.massivecraft.mcore.store.SenderEntity; import com.massivecraft.mcore.store.SenderEntity;
import com.massivecraft.mcore.util.MUtil;
import com.massivecraft.mcore.util.TimeUnit;
import com.massivecraft.mcore.util.Txt; import com.massivecraft.mcore.util.Txt;
@ -54,10 +50,7 @@ public class UPlayer extends SenderEntity<UPlayer> implements EconomyParticipato
this.setFactionId(that.factionId); this.setFactionId(that.factionId);
this.setRole(that.role); this.setRole(that.role);
this.setTitle(that.title); this.setTitle(that.title);
this.setPowerBoost(that.powerBoost); this.setPower(that.power);
this.power = that.power;
this.lastPowerUpdateTime = that.lastPowerUpdateTime;
return this; return this;
} }
@ -65,14 +58,13 @@ public class UPlayer extends SenderEntity<UPlayer> implements EconomyParticipato
@Override @Override
public boolean isDefault() public boolean isDefault()
{ {
// TODO: What if I incorporated the "default" word into the system?
// Rename?: hasFaction --> isFactionDefault
if (this.hasFaction()) return false; if (this.hasFaction()) return false;
// Role means nothing without a faction.
// Note: we do not check role or title here since they mean nothing without a faction. // Title means nothing without a faction.
if (this.getPowerRounded() != (int) Math.round(UConf.get(this).powerPlayerDefault)) return false;
// TODO: This line looks obnoxious, investigate it.
if (this.getPowerRounded() != this.getPowerMaxRounded() && this.getPowerRounded() != (int) Math.round(UConf.get(this).powerStarting)) return false;
if (this.hasPowerBoost()) return false;
return true; return true;
} }
@ -84,38 +76,30 @@ public class UPlayer extends SenderEntity<UPlayer> implements EconomyParticipato
// Each field has it's own section further down since just the getter and setter logic takes up quite some place. // Each field has it's own section further down since just the getter and setter logic takes up quite some place.
// This is a foreign key. // This is a foreign key.
// A players always belongs to a faction. // Each player belong to a faction.
// If null the player belongs to the no-faction faction called Wilderness. // Null means default which is the no-faction faction called Wilderness.
private String factionId = null; private String factionId = null;
// What role does the player have in the faction? // What role does the player have in the faction?
// The default value here is MEMBER since that one would be one of the most common ones and our goal is to save database space. // Null means default which is the default value for the universe.
// A note to self is that we can not change it from member to anything else just because we feel like it, that would corrupt database content.
private Rel role = null; private Rel role = null;
// What title does the player have in the faction? // What title does the player have in the faction?
// The title is just for fun. It's completely meaningless. // The title is just for fun. It's not connected to any game mechanic.
// The default case is no title since it's what you start with and also the most common case. // The default case is no title since it's what you start with and also the most common case.
// The player title is similar to the faction description. // The player title is similar to the faction description.
// //
// Question: Can the title contain chat colors? // Question: Can the title contain chat colors?
// Answer: Yes but in such case the policy is that they already must be parsed using Txt.parse. // Answer: Yes but in such case the policy is that they already must be parsed using Txt.parse.
// If they contain markup it should not be parsed in case we coded the system correctly. // If the title contains raw markup, such as "<white>" instead of "§f" it will not be parsed and "<white>" will be displayed.
private String title = null; private String title = null;
// Player usually do not have a powerboost. It defaults to 0. // Each player has an individual power level.
// The powerBoost is a custom increase/decrease to default and maximum power. // The power level for online players is occasionally updated by a recurring task and the power should stay the same for offline players.
// Note that player powerBoost and faction powerBoost are very similar. // For that reason the value is to be considered correct when you pick it. Do not call the power update method.
private Double powerBoost = null; // Null means default which is the default value for the universe.
// This field contains the last calculated value of the players power.
// The power calculation is lazy which means that the power is calculated first when you try to view the value.
private Double power = null; private Double power = null;
// This is the timestamp for the last calculation of the power.
// The value is used for the lazy calculation described above.
private long lastPowerUpdateTime = System.currentTimeMillis();
// -------------------------------------------- // // -------------------------------------------- //
// FIELDS: RAW TRANSIENT // FIELDS: RAW TRANSIENT
// -------------------------------------------- // // -------------------------------------------- //
@ -142,16 +126,9 @@ public class UPlayer extends SenderEntity<UPlayer> implements EconomyParticipato
public String getAccountId() { return this.getId(); } public String getAccountId() { return this.getId(); }
// -------------------------------------------- // // -------------------------------------------- //
// CONSTRUCT // CORE UTILITIES
// -------------------------------------------- // // -------------------------------------------- //
// GSON need this noarg constructor.
public UPlayer()
{
this.resetFactionData();
//this.power = ConfServer.powerStarting;
}
public void resetFactionData() public void resetFactionData()
{ {
// The default neutral faction // The default neutral faction
@ -162,6 +139,37 @@ public class UPlayer extends SenderEntity<UPlayer> implements EconomyParticipato
this.autoClaimFor = null; this.autoClaimFor = null;
} }
/*
public boolean isPresent(boolean requireFetchable)
{
if (!this.isOnline()) return false;
if (requireFetchable)
{
}
else
{
}
PS ps = Mixin.getSenderPs(this.getId());
if (ps == null) return false;
String psUniverse = Factions.get().getMultiverse().getUniverseForWorldName(ps.getWorld());
if (!psUniverse.equals(this.getUniverse())) return false;
if (!requireFetchable) return true;
Player player = this.getPlayer();
if (player == null) return false;
if (player.isDead()) return false;
return true;
}
*/
// -------------------------------------------- // // -------------------------------------------- //
// FIELD: factionId // FIELD: factionId
// -------------------------------------------- // // -------------------------------------------- //
@ -281,49 +289,6 @@ public class UPlayer extends SenderEntity<UPlayer> implements EconomyParticipato
this.changed(); this.changed();
} }
// -------------------------------------------- //
// FIELD: powerBoost
// -------------------------------------------- //
public double getPowerBoost()
{
Double ret = this.powerBoost;
if (ret == null) ret = 0D;
return ret;
}
public void setPowerBoost(Double powerBoost)
{
if (powerBoost == null || powerBoost == 0)
{
powerBoost = null;
}
this.powerBoost = powerBoost;
this.changed();
}
public boolean hasPowerBoost()
{
return this.getPowerBoost() != 0D;
}
// -------------------------------------------- //
// FIELD: lastPowerUpdateTime
// -------------------------------------------- //
// RAW
public long getLastPowerUpdateTime()
{
return this.lastPowerUpdateTime;
}
public void setLastPowerUpdateTime(long lastPowerUpdateTime)
{
this.lastPowerUpdateTime = lastPowerUpdateTime;
this.changed();
}
// -------------------------------------------- // // -------------------------------------------- //
// FIELD: power // FIELD: power
// -------------------------------------------- // // -------------------------------------------- //
@ -332,144 +297,24 @@ public class UPlayer extends SenderEntity<UPlayer> implements EconomyParticipato
public double getPower() public double getPower()
{ {
this.recalculatePower();
Double ret = this.power; Double ret = this.power;
if (ret == null) ret = UConf.get(this).powerStarting; if (ret == null) ret = UConf.get(this).powerPlayerDefault;
return ret; return ret;
} }
public void setPower(double power) public void setPower(Double power)
{ {
this.setPower(power, System.currentTimeMillis()); if (power == null || power == UConf.get(this).powerPlayerDefault)
} {
this.power = null;
public void setPower(double power, long now) }
{ else
power = Math.min(power, this.getPowerMax()); {
power = Math.max(power, this.getPowerMin()); this.power = power;
}
// Nochange
if (MUtil.equals(this.power, Double.valueOf(power))) return;
this.power = power;
this.setLastPowerUpdateTime(now);
this.changed(); this.changed();
} }
public double getPowerMax()
{
return UConf.get(this).powerMax + this.getPowerBoost();
}
public double getPowerMin()
{
return UConf.get(this).powerMin + this.getPowerBoost();
}
public void recalculatePower()
{
this.recalculatePower(this.isOnline());
}
private static final transient long POWER_RECALCULATION_MINIMUM_WAIT_MILLIS = 10 * TimeUnit.MILLIS_PER_SECOND;
public void recalculatePower(boolean online)
{
// Is the player really on this server?
// We use the sender ps mixin to fetch the current player location.
// If the PS is null it's OK. We assume the player is here if we do not know.
PS ps = Mixin.getSenderPs(this.getId());
if (ps != null && !ps.isWorldLoadedOnThisServer()) return;
// Get the now
long now = System.currentTimeMillis();
// We will only update if a certain amount of time has passed.
if (this.getLastPowerUpdateTime() + POWER_RECALCULATION_MINIMUM_WAIT_MILLIS >= now) return;
// Calculate millis passed
long millisPassed = now - this.getLastPowerUpdateTime();
// Note that we updated
this.setLastPowerUpdateTime(now);
// We consider dead players and players in other universes offline.
if (online)
{
Player thisPlayer = this.getPlayer();
online = (thisPlayer != null && !thisPlayer.isDead() && UPlayer.get(thisPlayer) == this);
}
// Cache and prepare
UConf uconf = UConf.get(this);
double powerCurrent;
if (this.power != null)
{
powerCurrent = this.power;
}
else
{
powerCurrent = uconf.powerStarting;
}
// Depending on online state pick the config values
double powerPerHour = online ? uconf.powerPerHourOnline : uconf.powerPerHourOffline;
double powerLimitGain = online ? uconf.powerLimitGainOnline : uconf.powerLimitGainOffline;
double powerLimitLoss = online ? uconf.powerLimitLossOnline : uconf.powerLimitLossOffline;
// Apply the negative divisor thingy
if (uconf.scaleNegativePower && powerCurrent < 0)
{
powerPerHour += (Math.sqrt(Math.abs(powerCurrent)) * Math.abs(powerCurrent)) / uconf.scaleNegativeDivisor;
}
// Calculate delta and target
double powerDelta = powerPerHour * millisPassed / TimeUnit.MILLIS_PER_HOUR;
double powerTarget = powerCurrent + powerDelta;
// Check Gain and Loss limits
if (powerDelta >= 0)
{
// Gain
if (powerTarget > powerLimitGain)
{
if (powerCurrent > powerLimitGain)
{
// Did already cross --> Just freeze
powerTarget = powerCurrent;
}
else
{
// Crossing right now --> Snap to limit
powerTarget = powerLimitGain;
}
}
}
else
{
// Loss
if (powerTarget < powerLimitLoss)
{
if (powerCurrent < powerLimitLoss)
{
// Did already cross --> Just freeze
powerTarget = powerCurrent;
}
else
{
// Crossing right now --> Snap to limit
powerTarget = powerLimitLoss;
}
}
}
FactionsEventPowerChange event = new FactionsEventPowerChange(null, this, PowerChangeReason.TIME, powerTarget);
event.run();
if (event.isCancelled()) return;
powerTarget = event.getNewPower();
this.setPower(powerTarget, now);
}
// FINER // FINER
public int getPowerRounded() public int getPowerRounded()
@ -477,16 +322,6 @@ public class UPlayer extends SenderEntity<UPlayer> implements EconomyParticipato
return (int) Math.round(this.getPower()); return (int) Math.round(this.getPower());
} }
public int getPowerMaxRounded()
{
return (int) Math.round(this.getPowerMax());
}
public int getPowerMinRounded()
{
return (int) Math.round(this.getPowerMin());
}
// -------------------------------------------- // // -------------------------------------------- //
// TITLE, NAME, FACTION TAG AND CHAT // TITLE, NAME, FACTION TAG AND CHAT
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -59,6 +59,7 @@ import com.massivecraft.factions.event.FactionsEventPowerChange.PowerChangeReaso
import com.massivecraft.factions.util.VisualizeUtil; import com.massivecraft.factions.util.VisualizeUtil;
import com.massivecraft.mcore.ps.PS; import com.massivecraft.mcore.ps.PS;
import com.massivecraft.mcore.util.MUtil; import com.massivecraft.mcore.util.MUtil;
import com.massivecraft.mcore.util.PermUtil;
import com.massivecraft.mcore.util.Txt; import com.massivecraft.mcore.util.Txt;
public class FactionsListenerMain implements Listener public class FactionsListenerMain implements Listener
@ -106,18 +107,26 @@ public class FactionsListenerMain implements Listener
return; return;
} }
// ... Event ... // ... alter the power ...
double newPower = uplayer.getPower() + UConf.get(uplayer).powerPerDeath; double maxPower = PermUtil.pickFirstVal(player, MConf.get().permToPowerMax);
double minPower = PermUtil.pickFirstVal(player, MConf.get().permToPowerMin);
double deathPower = PermUtil.pickFirstVal(player, MConf.get().permToPowerDeath);
double oldPower = uplayer.getPower();
double newPower = oldPower + deathPower;
newPower = Math.max(newPower, minPower);
newPower = Math.min(newPower, maxPower);
FactionsEventPowerChange powerChangeEvent = new FactionsEventPowerChange(null, uplayer, PowerChangeReason.DEATH, newPower); FactionsEventPowerChange powerChangeEvent = new FactionsEventPowerChange(null, uplayer, PowerChangeReason.DEATH, newPower);
powerChangeEvent.run(); powerChangeEvent.run();
if (powerChangeEvent.isCancelled()) return; if (powerChangeEvent.isCancelled()) return;
newPower = powerChangeEvent.getNewPower(); newPower = powerChangeEvent.getNewPower();
// ... alter the power ...
uplayer.setPower(newPower); uplayer.setPower(newPower);
// ... and inform the player. // ... and inform the player.
uplayer.msg("<i>Your power is now <h>%d / %d", uplayer.getPowerRounded(), uplayer.getPowerMaxRounded()); // TODO: A progress bar here would be epic :)
uplayer.msg("<i>Your power is now <h>%.2f / %.2f", newPower, maxPower);
} }
// -------------------------------------------- // // -------------------------------------------- //
@ -578,7 +587,6 @@ public class FactionsListenerMain implements Listener
event.setCancelled(true); event.setCancelled(true);
} }
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockBuild(BlockPistonExtendEvent event) public void blockBuild(BlockPistonExtendEvent event)

View File

@ -10,7 +10,6 @@ import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerBucketEmptyEvent; import org.bukkit.event.player.PlayerBucketEmptyEvent;
import org.bukkit.event.player.PlayerBucketFillEvent; import org.bukkit.event.player.PlayerBucketFillEvent;
import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import com.massivecraft.factions.Const; import com.massivecraft.factions.Const;
@ -21,7 +20,6 @@ import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.UPlayer; import com.massivecraft.factions.entity.UPlayer;
import com.massivecraft.factions.entity.MConf; import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.UPlayerColls; import com.massivecraft.factions.entity.UPlayerColls;
import com.massivecraft.mcore.event.MCorePlayerLeaveEvent;
import com.massivecraft.mcore.ps.PS; import com.massivecraft.mcore.ps.PS;
import com.massivecraft.mcore.util.MUtil; import com.massivecraft.mcore.util.MUtil;
import com.massivecraft.mcore.util.Txt; import com.massivecraft.mcore.util.Txt;
@ -29,30 +27,9 @@ import com.massivecraft.mcore.util.Txt;
public class TodoFactionsPlayerListener implements Listener public class TodoFactionsPlayerListener implements Listener
{ {
@EventHandler(priority = EventPriority.NORMAL) // -------------------------------------------- //
public void onPlayerJoin(PlayerJoinEvent event) // TERRITORY INFO MESSAGES
{ // -------------------------------------------- //
// If a player is joining the server ...
Player player = event.getPlayer();
UPlayer uplayer = UPlayer.get(player);
// ... recalculate their power as if they were offline since last recalculation.
uplayer.recalculatePower(false);
// TODO: What about the other universes?
// TODO: Track world --> world travel as logging on and off.
}
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerLeave(MCorePlayerLeaveEvent event)
{
Player player = event.getPlayer();
UPlayer uplayer = UPlayer.get(player);
// Recalculate the power before the player leaves.
// This is required since we recalculate as if the player were offline when they log back in.
// TODO: When I setup universes I must do this for all universe instance of the player that logs off!
uplayer.recalculatePower(true);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerMove(PlayerMoveEvent event) public void onPlayerMove(PlayerMoveEvent event)
@ -105,6 +82,10 @@ public class TodoFactionsPlayerListener implements Listener
} }
} }
// -------------------------------------------- //
// ASSORTED BUILD AND INTERACT
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onPlayerInteract(PlayerInteractEvent event) public void onPlayerInteract(PlayerInteractEvent event)
{ {

View File

@ -6,14 +6,14 @@ import com.massivecraft.factions.entity.FactionColls;
import com.massivecraft.mcore.ModuloRepeatTask; import com.massivecraft.mcore.ModuloRepeatTask;
import com.massivecraft.mcore.util.TimeUnit; import com.massivecraft.mcore.util.TimeUnit;
public class EconLandRewardTask extends ModuloRepeatTask public class EconRewardTask extends ModuloRepeatTask
{ {
// -------------------------------------------- // // -------------------------------------------- //
// INSTANCE & CONSTRUCT // INSTANCE & CONSTRUCT
// -------------------------------------------- // // -------------------------------------------- //
private static EconLandRewardTask i = new EconLandRewardTask(); private static EconRewardTask i = new EconRewardTask();
public static EconLandRewardTask get() { return i; } public static EconRewardTask get() { return i; }
// -------------------------------------------- // // -------------------------------------------- //
// OVERRIDE: MODULO REPEAT TASK // OVERRIDE: MODULO REPEAT TASK

View File

@ -0,0 +1,68 @@
package com.massivecraft.factions.task;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.UPlayer;
import com.massivecraft.factions.event.FactionsEventPowerChange;
import com.massivecraft.factions.event.FactionsEventPowerChange.PowerChangeReason;
import com.massivecraft.mcore.ModuloRepeatTask;
import com.massivecraft.mcore.util.PermUtil;
import com.massivecraft.mcore.util.TimeUnit;
public class PowerUpdateTask extends ModuloRepeatTask
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static PowerUpdateTask i = new PowerUpdateTask();
public static PowerUpdateTask get() { return i; }
// -------------------------------------------- //
// OVERRIDE: MODULO REPEAT TASK
// -------------------------------------------- //
@Override
public long getDelayMillis()
{
return MConf.get().powerTaskMillis;
}
@Override
public void setDelayMillis(long delayMillis)
{
MConf.get().powerTaskMillis = delayMillis;
}
@Override
public void invoke()
{
long millis = this.getDelayMillis();
for (Player player : Bukkit.getOnlinePlayers())
{
if (player.isDead()) continue;
double maxPower = PermUtil.pickFirstVal(player, MConf.get().permToPowerMax);
double minPower = PermUtil.pickFirstVal(player, MConf.get().permToPowerMin);
double hourPower = PermUtil.pickFirstVal(player, MConf.get().permToPowerHour);
UPlayer uplayer = UPlayer.get(player);
double oldPower = uplayer.getPower();
double newPower = oldPower + hourPower * millis / TimeUnit.MILLIS_PER_HOUR;
newPower = Math.max(newPower, minPower);
newPower = Math.min(newPower, maxPower);
FactionsEventPowerChange event = new FactionsEventPowerChange(null, uplayer, PowerChangeReason.TIME, newPower);
event.run();
if (event.isCancelled()) continue;
newPower = event.getNewPower();
uplayer.setPower(newPower);
}
}
}