2014-12-28 17:22:53 +01:00
package com.massivecraft.factions.cmd ;
2015-01-12 21:53:36 +01:00
import java.util.HashSet ;
import java.util.Set ;
2015-01-02 11:32:27 +01:00
import com.massivecraft.factions.Factions ;
2014-12-28 17:22:53 +01:00
import com.massivecraft.factions.Perm ;
import com.massivecraft.factions.Rel ;
2015-10-21 19:35:41 +02:00
import com.massivecraft.factions.cmd.type.TypeFaction ;
import com.massivecraft.factions.cmd.type.TypeMPlayer ;
import com.massivecraft.factions.cmd.type.TypeRank ;
2014-12-28 17:22:53 +01:00
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 ;
2015-01-12 21:53:36 +01:00
import com.massivecraft.factions.event.EventFactionsMembershipChange ;
import com.massivecraft.factions.event.EventFactionsMembershipChange.MembershipChangeReason ;
2015-01-02 11:32:27 +01:00
import com.massivecraft.factions.event.EventFactionsRankChange ;
2015-02-12 12:00:55 +01:00
import com.massivecraft.massivecore.MassiveException ;
2014-12-28 17:22:53 +01:00
import com.massivecraft.massivecore.cmd.req.ReqHasPerm ;
import com.massivecraft.massivecore.util.Txt ;
public class CmdFactionsRank extends FactionsCommand
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
2015-01-02 11:32:27 +01:00
// The rank required to do any rank changes.
2014-12-28 17:22:53 +01:00
final static Rel rankReq = Rel . OFFICER ;
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
2014-12-30 10:01:54 +01:00
// These fields are set upon perform() and unset afterwards.
2014-12-28 17:22:53 +01:00
2014-12-30 10:01:54 +01:00
// Target
2014-12-28 17:22:53 +01:00
private Faction targetFaction = null ;
private MPlayer target = null ;
2015-01-12 21:53:36 +01:00
// End faction (the faction they are changed to)
private Faction endFaction = null ;
private boolean factionChange = false ;
// Ranks
2015-01-02 11:32:27 +01:00
private Rel senderRank = null ;
private Rel targetRank = null ;
2014-12-28 17:22:53 +01:00
private Rel rank = null ;
2015-05-06 17:04:35 +02:00
// This one is permanent
2015-10-21 19:35:41 +02:00
private TypeRank rankReader = new TypeRank ( ) ;
2015-05-06 17:04:35 +02:00
2014-12-28 17:22:53 +01:00
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public CmdFactionsRank ( )
{
// Aliases
2015-01-02 11:32:27 +01:00
this . addAliases ( " rank " ) ;
2014-12-28 17:22:53 +01:00
2015-10-21 19:35:41 +02:00
// Parameters
this . addParameter ( TypeMPlayer . get ( ) , " player " ) ;
this . addParameter ( rankReader , " action " , " show " ) ;
this . addParameter ( TypeFaction . get ( ) , " faction " , " their " ) ;
2014-12-28 17:22:53 +01:00
// Requirements
this . addRequirements ( ReqHasPerm . get ( Perm . RANK . node ) ) ;
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
2015-02-12 12:00:55 +01:00
public void perform ( ) throws MassiveException
2014-12-28 17:22:53 +01:00
{
2015-01-12 21:53:36 +01:00
// This sets target and much other.
this . registerFields ( ) ;
2014-12-28 17:22:53 +01:00
2014-12-30 10:01:54 +01:00
// Sometimes we just want to show the rank.
if ( ! this . argIsSet ( 1 ) )
2014-12-28 17:22:53 +01:00
{
2015-01-12 21:53:36 +01:00
if ( ! Perm . RANK_SHOW . has ( sender , true ) ) return ;
2014-12-30 10:01:54 +01:00
this . showRank ( ) ;
2014-12-28 17:22:53 +01:00
return ;
}
2015-01-02 11:32:27 +01:00
// Permission check.
2015-01-12 21:53:36 +01:00
if ( ! Perm . RANK_ACTION . has ( sender , true ) ) return ;
2014-12-28 17:22:53 +01:00
2014-12-30 10:01:54 +01:00
// Is the player allowed or not. Method can be found later down.
2015-01-12 21:53:36 +01:00
this . ensureAllowed ( ) ;
if ( factionChange )
{
this . changeFaction ( ) ;
2014-12-28 17:22:53 +01:00
}
// Does the change make sense.
2015-01-12 21:53:36 +01:00
this . ensureMakesSense ( ) ;
2014-12-28 17:22:53 +01:00
2015-01-12 21:53:36 +01:00
// Event
2015-01-02 11:32:27 +01:00
EventFactionsRankChange event = new EventFactionsRankChange ( sender , target , rank ) ;
event . run ( ) ;
if ( event . isCancelled ( ) ) return ;
rank = event . getNewRank ( ) ;
2014-12-28 17:22:53 +01:00
2015-01-02 11:32:27 +01:00
// Change the rank.
2014-12-30 10:01:54 +01:00
this . changeRank ( ) ;
2014-12-28 17:22:53 +01:00
}
2015-01-12 21:53:36 +01:00
2014-12-30 10:01:54 +01:00
// This is always run after performing a MassiveCommand.
2014-12-28 17:22:53 +01:00
@Override
2015-10-21 19:35:41 +02:00
public void senderFields ( boolean set )
2014-12-28 17:22:53 +01:00
{
2015-10-21 19:35:41 +02:00
super . senderFields ( set ) ;
if ( ! set )
{
this . unregisterFields ( ) ;
}
2014-12-28 17:22:53 +01:00
}
// -------------------------------------------- //
2015-01-12 21:53:36 +01:00
// PRIVATE: REGISTER & UNREGISTER
2014-12-28 17:22:53 +01:00
// -------------------------------------------- //
2015-01-12 21:53:36 +01:00
private void registerFields ( ) throws MassiveException
2014-12-28 17:22:53 +01:00
{
2015-01-02 11:32:27 +01:00
// Getting the target and faction.
2015-05-06 17:04:35 +02:00
target = this . readArg ( msender ) ;
2014-12-28 17:22:53 +01:00
targetFaction = target . getFaction ( ) ;
2015-05-06 17:04:35 +02:00
// Ranks
senderRank = msender . getRole ( ) ;
targetRank = target . getRole ( ) ;
2014-12-28 17:22:53 +01:00
// Rank if any passed.
if ( this . argIsSet ( 1 ) )
{
2015-05-06 17:04:35 +02:00
this . rankReader . setStartRank ( targetRank ) ;
rank = this . readArg ( ) ;
2014-12-28 17:22:53 +01:00
}
2015-01-12 21:53:36 +01:00
// Changing peoples faction.
2015-05-06 17:04:35 +02:00
endFaction = this . readArgAt ( 2 , targetFaction ) ;
2015-01-12 21:53:36 +01:00
factionChange = ( endFaction ! = targetFaction ) ;
2015-05-06 17:04:35 +02:00
2014-12-28 17:22:53 +01:00
}
private void unregisterFields ( )
{
targetFaction = null ;
target = null ;
2015-01-02 11:32:27 +01:00
senderRank = null ;
targetRank = null ;
2014-12-28 17:22:53 +01:00
rank = null ;
}
2015-01-12 21:53:36 +01:00
// -------------------------------------------- //
// PRIVATE: ENSURE
// -------------------------------------------- //
private void ensureAllowed ( ) throws MassiveException
2014-12-28 17:22:53 +01:00
{
2015-01-02 11:32:27 +01:00
// People with permission don't follow the normal rules.
2015-01-12 21:53:36 +01:00
if ( msender . isUsingAdminMode ( ) ) return ;
2014-12-28 17:22:53 +01:00
2015-01-02 11:32:27 +01:00
// If somone gets the leadership of wilderness (Which has happened before).
// We can at least try to limit their powers.
2015-01-12 21:53:36 +01:00
if ( endFaction . isNone ( ) )
2014-12-28 17:22:53 +01:00
{
2015-01-12 21:53:36 +01:00
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. " ) ;
2014-12-28 17:22:53 +01:00
}
if ( targetFaction ! = msenderFaction )
{
2015-01-02 11:32:27 +01:00
// Don't change ranks outside of your faction.
2015-01-12 21:53:36 +01:00
throw new MassiveException ( ) . addMsg ( " %s <b>is not in the same faction as you. " , target . describeTo ( msender , true ) ) ;
2014-12-28 17:22:53 +01:00
}
2015-01-12 21:53:36 +01:00
if ( factionChange )
2014-12-28 17:22:53 +01:00
{
2015-01-12 21:53:36 +01:00
// Don't change peoples faction
throw new MassiveException ( ) . addMsg ( " <b>You can't change %s's <b>faction. " , target . describeTo ( msender ) ) ;
2014-12-28 17:22:53 +01:00
}
2015-01-02 11:32:27 +01:00
if ( senderRank . isLessThan ( rankReq ) )
2014-12-28 17:22:53 +01:00
{
2015-01-02 11:32:27 +01:00
// You need a specific rank to change ranks.
2015-01-12 21:53:36 +01:00
throw new MassiveException ( ) . addMsg ( " <b>You must be <h>%s <b>or higher to change ranks. " , Txt . getNicedEnum ( rankReq ) . toLowerCase ( ) ) ;
2014-12-28 17:22:53 +01:00
}
// The following two if statements could be merged.
// But isn't for the sake of nicer error messages.
2015-01-02 11:32:27 +01:00
if ( senderRank = = targetRank )
2014-12-28 17:22:53 +01:00
{
2015-01-02 11:32:27 +01:00
// You can't change someones rank if it is equal to yours.
2015-01-12 21:53:36 +01:00
throw new MassiveException ( ) . addMsg ( " <h>%s <b>can't manage eachother. " , Txt . getNicedEnum ( rankReq ) + " s " ) ;
2014-12-28 17:22:53 +01:00
}
2015-01-02 11:32:27 +01:00
if ( senderRank . isLessThan ( targetRank ) )
2014-12-28 17:22:53 +01:00
{
2015-01-02 11:32:27 +01:00
// You can't change someones rank if it is higher than yours.
2015-01-12 21:53:36 +01:00
throw new MassiveException ( ) . addMsg ( " <b>You can't manage people of higher rank. " ) ;
2014-12-28 17:22:53 +01:00
}
2015-01-12 21:53:36 +01:00
// The following two if statements could be merged.
// But isn't for the sake of nicer error messages.
if ( senderRank = = rank & & senderRank ! = Rel . LEADER )
2014-12-28 17:22:53 +01:00
{
2015-01-12 21:53:36 +01:00
// 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. " ) ;
2014-12-28 17:22:53 +01:00
}
2015-01-12 21:53:36 +01:00
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 ( ) ) ;
}
2014-12-28 17:22:53 +01:00
}
2015-01-12 21:53:36 +01:00
// -------------------------------------------- //
// PRIVATE: SHOW
// -------------------------------------------- //
private void showRank ( )
2014-12-28 17:22:53 +01:00
{
2015-01-12 21:53:36 +01:00
// 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 ( ) )
2014-12-28 17:22:53 +01:00
{
2015-01-12 21:53:36 +01:00
// Wilderness aka none doesn't use ranks
msg ( " %s <i>%s factionless " , targetName , isAre ) ;
2014-12-28 17:22:53 +01:00
}
2015-01-12 21:53:36 +01:00
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 ( ) ;
2014-12-28 17:22:53 +01:00
2015-01-12 21:53:36 +01:00
// 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 )
2014-12-28 17:22:53 +01:00
{
2015-01-12 21:53:36 +01:00
recipient . msg ( " %s <i>was moved from <i>%s to <i>%s<i>. " , target . describeTo ( recipient ) , targetFaction . describeTo ( recipient ) , endFaction . describeTo ( recipient ) ) ;
2014-12-28 17:22:53 +01:00
}
2015-01-12 21:53:36 +01:00
// Derplog
if ( MConf . get ( ) . logFactionJoin )
2014-12-28 17:22:53 +01:00
{
2015-01-12 21:53:36 +01:00
Factions . get ( ) . log ( Txt . parse ( " %s moved %s from %s to %s. " , msender . getName ( ) , target . getName ( ) , targetFaction . getName ( ) , endFaction . getName ( ) ) ) ;
2014-12-28 17:22:53 +01:00
}
2014-12-30 10:01:54 +01:00
2015-01-12 21:53:36 +01:00
// Now we don't need the old values.
targetFaction = target . getFaction ( ) ;
targetRank = target . getRole ( ) ;
senderRank = msender . getRole ( ) ; // In case they changed their own rank
2014-12-28 17:22:53 +01:00
}
2015-01-12 21:53:36 +01:00
// -------------------------------------------- //
// PRIVATE: CHANGE RANK
// -------------------------------------------- //
private void changeRank ( ) throws MassiveException
2014-12-28 17:22:53 +01:00
{
2014-12-30 10:01:54 +01:00
// In case of leadership change, we do special things not done in other rank changes.
2014-12-28 17:22:53 +01:00
if ( rank = = Rel . LEADER )
{
2014-12-30 10:01:54 +01:00
this . changeRankLeader ( ) ;
2014-12-28 17:22:53 +01:00
}
else
{
2014-12-30 10:01:54 +01:00
this . changeRankOther ( ) ;
2014-12-28 17:22:53 +01:00
}
}
private void changeRankLeader ( )
{
2015-01-02 11:32:27 +01:00
// If there is a current leader. Demote & inform them.
2014-12-28 17:22:53 +01:00
MPlayer targetFactionCurrentLeader = targetFaction . getLeader ( ) ;
if ( targetFactionCurrentLeader ! = null )
{
2015-01-02 11:32:27 +01:00
// Inform & demote the old leader.
2014-12-28 17:22:53 +01:00
targetFactionCurrentLeader . setRole ( Rel . OFFICER ) ;
2014-12-30 10:01:54 +01:00
if ( targetFactionCurrentLeader ! = msender )
{
2015-01-02 11:32:27 +01:00
// They kinda know if they fired the command themself.
2014-12-28 17:22:53 +01:00
targetFactionCurrentLeader . msg ( " <i>You have been demoted from the position of faction leader by %s<i>. " , msender . describeTo ( targetFactionCurrentLeader , true ) ) ;
2014-12-30 10:01:54 +01:00
}
2014-12-28 17:22:53 +01:00
}
2015-01-12 21:53:36 +01:00
// Promote the new leader.
2014-12-28 17:22:53 +01:00
target . setRole ( Rel . LEADER ) ;
2015-01-12 21:53:36 +01:00
// Inform everyone, this includes sender and target.
2015-01-02 11:32:27 +01:00
for ( MPlayer recipient : MPlayerColl . get ( ) . getAllOnline ( ) )
2014-12-28 17:22:53 +01:00
{
2015-01-02 11:32:27 +01:00
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 ) ) ;
2014-12-28 17:22:53 +01:00
}
}
2015-01-12 21:53:36 +01:00
private void changeRankOther ( ) throws MassiveException
2014-12-28 17:22:53 +01:00
{
2015-01-12 21:53:36 +01:00
// 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?
2015-01-02 11:32:27 +01:00
{
2015-01-12 21:53:36 +01:00
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. " ) ;
}
2015-01-02 11:32:27 +01:00
}
2015-01-12 21:53:36 +01:00
// Create recipients
Set < MPlayer > recipients = new HashSet < MPlayer > ( ) ;
recipients . addAll ( targetFaction . getMPlayers ( ) ) ;
recipients . add ( msender ) ;
2014-12-30 10:01:54 +01:00
2014-12-28 17:22:53 +01:00
// Were they demoted or promoted?
2015-01-02 11:32:27 +01:00
String change = ( rank . isLessThan ( targetRank ) ? " demoted " : " promoted " ) ;
2014-12-30 10:01:54 +01:00
// The rank will be set before the msg, so they have the appropriate prefix.
2014-12-28 17:22:53 +01:00
target . setRole ( rank ) ;
2015-01-02 11:32:27 +01:00
String oldRankName = Txt . getNicedEnum ( targetRank ) . toLowerCase ( ) ;
2014-12-28 17:22:53 +01:00
String rankName = Txt . getNicedEnum ( rank ) . toLowerCase ( ) ;
2015-01-02 11:32:27 +01:00
2015-01-12 21:53:36 +01:00
// Send message
2015-01-02 11:32:27 +01:00
for ( MPlayer recipient : recipients )
{
String targetName = target . describeTo ( recipient , true ) ;
2015-01-12 21:53:36 +01:00
String wasWere = ( recipient = = target ) ? " were " : " was " ;
2015-01-02 11:32:27 +01:00
recipient . msg ( " %s<i> %s %s from %s to <h>%s <i>in %s<i>. " , targetName , wasWere , change , oldRankName , rankName , targetFaction . describeTo ( msender ) ) ;
}
2014-12-28 17:22:53 +01:00
}
2015-01-12 21:53:36 +01:00
2014-12-30 10:01:54 +01:00
}