404 lines
12 KiB
Java
404 lines
12 KiB
Java
package com.massivecraft.factions.cmd;
|
|
|
|
import java.util.HashSet;
|
|
import java.util.Set;
|
|
|
|
import com.massivecraft.factions.Factions;
|
|
import com.massivecraft.factions.Perm;
|
|
import com.massivecraft.factions.Rel;
|
|
import com.massivecraft.factions.cmd.type.TypeFaction;
|
|
import com.massivecraft.factions.cmd.type.TypeMPlayer;
|
|
import com.massivecraft.factions.cmd.type.TypeRank;
|
|
import com.massivecraft.factions.entity.Faction;
|
|
import com.massivecraft.factions.entity.MConf;
|
|
import com.massivecraft.factions.entity.MFlag;
|
|
import com.massivecraft.factions.entity.MPlayer;
|
|
import com.massivecraft.factions.entity.MPlayerColl;
|
|
import com.massivecraft.factions.event.EventFactionsMembershipChange;
|
|
import com.massivecraft.factions.event.EventFactionsMembershipChange.MembershipChangeReason;
|
|
import com.massivecraft.factions.event.EventFactionsRankChange;
|
|
import com.massivecraft.massivecore.MassiveException;
|
|
import com.massivecraft.massivecore.cmd.req.ReqHasPerm;
|
|
import com.massivecraft.massivecore.util.Txt;
|
|
|
|
public class CmdFactionsRank extends FactionsCommand
|
|
{
|
|
// -------------------------------------------- //
|
|
// CONSTANTS
|
|
// -------------------------------------------- //
|
|
|
|
// The rank required to do any rank changes.
|
|
final static Rel rankReq = Rel.OFFICER;
|
|
|
|
// -------------------------------------------- //
|
|
// FIELDS
|
|
// -------------------------------------------- //
|
|
// These fields are set upon perform() and unset afterwards.
|
|
|
|
// Target
|
|
private Faction targetFaction = null;
|
|
private MPlayer target = null;
|
|
|
|
// End faction (the faction they are changed to)
|
|
private Faction endFaction = null;
|
|
private boolean factionChange = false;
|
|
|
|
// Ranks
|
|
private Rel senderRank = null;
|
|
private Rel targetRank = null;
|
|
private Rel rank = null;
|
|
|
|
// This one is permanent
|
|
private TypeRank rankReader = new TypeRank();
|
|
|
|
// -------------------------------------------- //
|
|
// CONSTRUCT
|
|
// -------------------------------------------- //
|
|
|
|
public CmdFactionsRank()
|
|
{
|
|
// Aliases
|
|
this.addAliases("rank");
|
|
|
|
// Parameters
|
|
this.addParameter(TypeMPlayer.get(), "player");
|
|
this.addParameter(rankReader, "action", "show");
|
|
this.addParameter(TypeFaction.get(), "faction", "their");
|
|
|
|
// Requirements
|
|
this.addRequirements(ReqHasPerm.get(Perm.RANK.node));
|
|
}
|
|
|
|
// -------------------------------------------- //
|
|
// OVERRIDE
|
|
// -------------------------------------------- //
|
|
|
|
@Override
|
|
public void perform() throws MassiveException
|
|
{
|
|
// This sets target and much other.
|
|
this.registerFields();
|
|
|
|
// Sometimes we just want to show the rank.
|
|
if ( ! this.argIsSet(1))
|
|
{
|
|
if ( ! Perm.RANK_SHOW.has(sender, true)) return;
|
|
this.showRank();
|
|
return;
|
|
}
|
|
|
|
// Permission check.
|
|
if ( ! Perm.RANK_ACTION.has(sender, true)) return;
|
|
|
|
// Is the player allowed or not. Method can be found later down.
|
|
this.ensureAllowed();
|
|
|
|
if (factionChange)
|
|
{
|
|
this.changeFaction();
|
|
}
|
|
|
|
// Does the change make sense.
|
|
this.ensureMakesSense();
|
|
|
|
// Event
|
|
EventFactionsRankChange event = new EventFactionsRankChange(sender, target, rank);
|
|
event.run();
|
|
if (event.isCancelled()) return;
|
|
rank = event.getNewRank();
|
|
|
|
// Change the rank.
|
|
this.changeRank();
|
|
}
|
|
|
|
// This is always run after performing a MassiveCommand.
|
|
@Override
|
|
public void senderFields(boolean set)
|
|
{
|
|
super.senderFields(set);
|
|
|
|
if ( ! set)
|
|
{
|
|
this.unregisterFields();
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------- //
|
|
// PRIVATE: REGISTER & UNREGISTER
|
|
// -------------------------------------------- //
|
|
|
|
private void registerFields() throws MassiveException
|
|
{
|
|
// Getting the target and faction.
|
|
target = this.readArg(msender);
|
|
targetFaction = target.getFaction();
|
|
|
|
|
|
// Ranks
|
|
senderRank = msender.getRole();
|
|
targetRank = target.getRole();
|
|
|
|
// Rank if any passed.
|
|
if (this.argIsSet(1))
|
|
{
|
|
this.rankReader.setStartRank(targetRank);
|
|
rank = this.readArg();
|
|
}
|
|
|
|
// Changing peoples faction.
|
|
endFaction = this.readArgAt(2, targetFaction);
|
|
factionChange = (endFaction != targetFaction);
|
|
|
|
}
|
|
|
|
private void unregisterFields()
|
|
{
|
|
targetFaction = null;
|
|
target = null;
|
|
|
|
senderRank = null;
|
|
targetRank = null;
|
|
rank = null;
|
|
}
|
|
|
|
// -------------------------------------------- //
|
|
// PRIVATE: ENSURE
|
|
// -------------------------------------------- //
|
|
|
|
private void ensureAllowed() throws MassiveException
|
|
{
|
|
// People with permission don't follow the normal rules.
|
|
if (msender.isUsingAdminMode()) return;
|
|
|
|
// If somone gets the leadership of wilderness (Which has happened before).
|
|
// We can at least try to limit their powers.
|
|
if (endFaction.isNone())
|
|
{
|
|
throw new MassiveException().addMsg("%s <b>doesn't use ranks sorry :(", targetFaction.getName() );
|
|
}
|
|
|
|
if (target == msender)
|
|
{
|
|
// Don't change your own rank.
|
|
throw new MassiveException().addMsg("<b>The target player mustn't be yourself.");
|
|
}
|
|
|
|
if (targetFaction != msenderFaction)
|
|
{
|
|
// Don't change ranks outside of your faction.
|
|
throw new MassiveException().addMsg("%s <b>is not in the same faction as you.", target.describeTo(msender, true));
|
|
}
|
|
|
|
if (factionChange)
|
|
{
|
|
// Don't change peoples faction
|
|
throw new MassiveException().addMsg("<b>You can't change %s's <b>faction.", target.describeTo(msender));
|
|
}
|
|
|
|
if (senderRank.isLessThan(rankReq))
|
|
{
|
|
// You need a specific rank to change ranks.
|
|
throw new MassiveException().addMsg("<b>You must be <h>%s <b>or higher to change ranks.", Txt.getNicedEnum(rankReq).toLowerCase());
|
|
}
|
|
|
|
// The following two if statements could be merged.
|
|
// But isn't for the sake of nicer error messages.
|
|
if (senderRank == targetRank)
|
|
{
|
|
// You can't change someones rank if it is equal to yours.
|
|
throw new MassiveException().addMsg("<h>%s <b>can't manage eachother.", Txt.getNicedEnum(rankReq)+"s");
|
|
}
|
|
|
|
if (senderRank.isLessThan(targetRank))
|
|
{
|
|
// You can't change someones rank if it is higher than yours.
|
|
throw new MassiveException().addMsg("<b>You can't manage people of higher rank.");
|
|
}
|
|
|
|
// The following two if statements could be merged.
|
|
// But isn't for the sake of nicer error messages.
|
|
if (senderRank == rank && senderRank != Rel.LEADER)
|
|
{
|
|
// You can't set ranks equal to your own. Unless you are the leader.
|
|
throw new MassiveException().addMsg("<b>You can't set ranks equal to your own.");
|
|
}
|
|
|
|
if (senderRank.isLessThan(rank))
|
|
{
|
|
// You can't set ranks higher than your own.
|
|
throw new MassiveException().addMsg("<b>You can't set ranks higher than your own.");
|
|
}
|
|
}
|
|
|
|
private void ensureMakesSense() throws MassiveException
|
|
{
|
|
// Don't change their rank to something they already are.
|
|
if (target.getRole() == rank)
|
|
{
|
|
throw new MassiveException().addMsg("%s <b>is already %s<b>.", target.describeTo(msender), rank.getColor() + rank.getDescPlayerOne());
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------- //
|
|
// PRIVATE: SHOW
|
|
// -------------------------------------------- //
|
|
|
|
private void showRank()
|
|
{
|
|
// Damn you grammar, causing all these checks.
|
|
String targetName = target.describeTo(msender, true);
|
|
String isAre = (target == msender) ? "are" : "is"; // "you are" or "he is"
|
|
String theAan = (targetRank == Rel.LEADER) ? "the" : Txt.aan(targetRank.name()); // "a member", "an officer" or "the leader"
|
|
String rankName = Txt.getNicedEnum(targetRank).toLowerCase();
|
|
String ofIn = (targetRank == Rel.LEADER) ? "of" : "in"; // "member in" or "leader of"
|
|
String factionName = targetFaction.describeTo(msender, true);
|
|
if (targetFaction == msenderFaction)
|
|
{
|
|
// Having the "Y" in "Your faction" being uppercase in the middle of a sentence makes no sense.
|
|
factionName = factionName.toLowerCase();
|
|
}
|
|
if (targetFaction.isNone())
|
|
{
|
|
// Wilderness aka none doesn't use ranks
|
|
msg("%s <i>%s factionless", targetName, isAre);
|
|
}
|
|
else
|
|
{
|
|
// Derp is a member in Faction
|
|
msg("%s <i>%s %s <h>%s <i>%s %s<i>.", targetName, isAre, theAan, rankName, ofIn, factionName);
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------- //
|
|
// PRIVATE: CHANGE FACTION
|
|
// -------------------------------------------- //
|
|
|
|
private void changeFaction() throws MassiveException
|
|
{
|
|
// Don't change a leader to a new faction.
|
|
if (targetRank == Rel.LEADER)
|
|
{
|
|
throw new MassiveException().addMsg("<b>You cannot remove the present leader. Demote them first.");
|
|
}
|
|
|
|
// Event
|
|
EventFactionsMembershipChange membershipChangeEvent = new EventFactionsMembershipChange(sender, msender, endFaction, MembershipChangeReason.RANK);
|
|
membershipChangeEvent.run();
|
|
if (membershipChangeEvent.isCancelled()) throw new MassiveException();
|
|
|
|
// Apply
|
|
target.resetFactionData();
|
|
target.setFaction(endFaction);
|
|
|
|
// No longer invited.
|
|
endFaction.setInvited(target, false);
|
|
|
|
// Create recipients
|
|
Set<MPlayer> recipients = new HashSet<MPlayer>();
|
|
recipients.addAll(targetFaction.getMPlayersWhereOnline(true));
|
|
recipients.addAll(endFaction.getMPlayersWhereOnline(true));
|
|
recipients.add(msender);
|
|
|
|
// Send message
|
|
for (MPlayer recipient : recipients)
|
|
{
|
|
recipient.msg("%s <i>was moved from <i>%s to <i>%s<i>.", target.describeTo(recipient), targetFaction.describeTo(recipient), endFaction.describeTo(recipient));
|
|
}
|
|
|
|
// Derplog
|
|
if (MConf.get().logFactionJoin)
|
|
{
|
|
Factions.get().log(Txt.parse("%s moved %s from %s to %s.", msender.getName(), target.getName(), targetFaction.getName(), endFaction.getName()));
|
|
}
|
|
|
|
// Now we don't need the old values.
|
|
targetFaction = target.getFaction();
|
|
targetRank = target.getRole();
|
|
senderRank = msender.getRole(); // In case they changed their own rank
|
|
}
|
|
|
|
// -------------------------------------------- //
|
|
// PRIVATE: CHANGE RANK
|
|
// -------------------------------------------- //
|
|
|
|
private void changeRank() throws MassiveException
|
|
{
|
|
// In case of leadership change, we do special things not done in other rank changes.
|
|
if (rank == Rel.LEADER)
|
|
{
|
|
this.changeRankLeader();
|
|
}
|
|
else
|
|
{
|
|
this.changeRankOther();
|
|
}
|
|
}
|
|
|
|
private void changeRankLeader()
|
|
{
|
|
// If there is a current leader. Demote & inform them.
|
|
MPlayer targetFactionCurrentLeader = targetFaction.getLeader();
|
|
if (targetFactionCurrentLeader != null)
|
|
{
|
|
// Inform & demote the old leader.
|
|
targetFactionCurrentLeader.setRole(Rel.OFFICER);
|
|
if (targetFactionCurrentLeader != msender)
|
|
{
|
|
// They kinda know if they fired the command themself.
|
|
targetFactionCurrentLeader.msg("<i>You have been demoted from the position of faction leader by %s<i>.", msender.describeTo(targetFactionCurrentLeader, true));
|
|
}
|
|
}
|
|
|
|
// Promote the new leader.
|
|
target.setRole(Rel.LEADER);
|
|
|
|
// Inform everyone, this includes sender and target.
|
|
for (MPlayer recipient : MPlayerColl.get().getAllOnline())
|
|
{
|
|
String changerName = senderIsConsole ? "A server admin" : msender.describeTo(recipient);
|
|
recipient.msg("%s<i> gave %s<i> the leadership of %s<i>.", changerName, target.describeTo(recipient), targetFaction.describeTo(recipient));
|
|
}
|
|
}
|
|
|
|
private void changeRankOther() throws MassiveException
|
|
{
|
|
// If the target is currently the leader and faction isn't permanent a new leader should be promoted.
|
|
// Sometimes a bug occurs and multiple leaders exist. Then we should be able to demote without promoting new leader
|
|
if (targetRank == Rel.LEADER && ( ! MConf.get().permanentFactionsDisableLeaderPromotion || ! targetFaction.getFlag(MFlag.ID_PERMANENT)) && targetFaction.getMPlayersWhereRole(Rel.LEADER).size() == 1)
|
|
// This if statement is very long. Should I nest it for readability?
|
|
{
|
|
targetFaction.promoteNewLeader(); // This might disband the faction.
|
|
|
|
// So if the faction disbanded...
|
|
if (targetFaction.detached())
|
|
{
|
|
// ... we inform the sender.
|
|
target.resetFactionData();
|
|
throw new MassiveException().addMsg("<i>The target was a leader and got demoted. The faction disbanded and no rank was set.");
|
|
}
|
|
}
|
|
|
|
// Create recipients
|
|
Set<MPlayer> recipients = new HashSet<MPlayer>();
|
|
recipients.addAll(targetFaction.getMPlayers());
|
|
recipients.add(msender);
|
|
|
|
// Were they demoted or promoted?
|
|
String change = (rank.isLessThan(targetRank) ? "demoted" : "promoted");
|
|
|
|
// The rank will be set before the msg, so they have the appropriate prefix.
|
|
target.setRole(rank);
|
|
String oldRankName = Txt.getNicedEnum(targetRank).toLowerCase();
|
|
String rankName = Txt.getNicedEnum(rank).toLowerCase();
|
|
|
|
// Send message
|
|
for(MPlayer recipient : recipients)
|
|
{
|
|
String targetName = target.describeTo(recipient, true);
|
|
String wasWere = (recipient == target) ? "were" : "was";
|
|
recipient.msg("%s<i> %s %s from %s to <h>%s <i>in %s<i>.", targetName, wasWere, change, oldRankName, rankName, targetFaction.describeTo(msender));
|
|
}
|
|
}
|
|
|
|
}
|