Add recruit role for factions

The recruit role's goal is to enable factions to invite new members without being afraid of getting griefed instantly.

Adds a configuration option "factionRankDefault" for default rank of newly joined faction members. By default this is RECRUIT, but it can be set to any supported rank.

Adds the /f promote and /f demote commands, which leaders and officers can use to increase or decrease the rank of a faction member by one level, up to officer, or down to recruit.
This version of the recruit feature preserves the /f officer command for backward compatibility.
This commit is contained in:
Justin Kaeser 2013-01-06 21:44:29 +01:00
parent 755a957b12
commit 4743c1821a
13 changed files with 208 additions and 31 deletions

View File

@ -129,6 +129,7 @@ permissions:
factions.cape.*: true
factions.claim: true
factions.deinvite: true
factions.demote: true
factions.description: true
factions.disband: true
factions.flag: true
@ -142,11 +143,11 @@ permissions:
factions.list: true
factions.map: true
factions.money.*: true
factions.officer: true
factions.open: true
factions.perm: true
factions.power: true
factions.power.any: true
factions.promote: true
factions.relation: true
factions.seechunk: true
factions.sethome: true
@ -155,4 +156,4 @@ permissions:
factions.title: true
factions.unclaim: true
factions.unclaimall: true
factions.version: true
factions.version: true

View File

@ -27,6 +27,7 @@ public class Conf
public static Map<FFlag, Boolean> factionFlagDefaults;
public static Map<FFlag, Boolean> factionFlagIsChangeable;
public static Map<FPerm, Set<Rel>> factionPermDefaults;
public static Rel factionRankDefault = Rel.RECRUIT;
// Power
public static double powerPlayerMax = 10.0;
@ -43,6 +44,8 @@ public class Conf
public static String prefixLeader = "**";
public static String prefixOfficer = "*";
public static String prefixMember = "+";
public static String prefixRecruit = "-";
public static int factionTagLengthMin = 3;
public static int factionTagLengthMax = 10;

View File

@ -136,15 +136,16 @@ public class FPlayer extends PlayerEntity implements EconomyParticipator
}
this.factionId = "0"; // The default neutral faction
this.role = Rel.MEMBER;
this.title = "";
this.autoClaimFor = null;
if (doSpoutUpdate)
{
SpoutFeatures.updateTitle(this, null);
SpoutFeatures.updateTitle(null, this);
SpoutFeatures.updateCape(this.getPlayer(), null);
SpoutFeatures.updateTitle(this, null);
SpoutFeatures.updateTitle(null, this);
SpoutFeatures.updateCape(this.getPlayer(), null);
}
}
@ -693,4 +694,4 @@ public class FPlayer extends PlayerEntity implements EconomyParticipator
{
this.sendMessage(P.p.txt.parse(str, args));
}
}
}

View File

@ -121,11 +121,11 @@ public class Factions extends EntityCollection<Faction>
//faction.setFlag(FFlag.LIGHTNING, true);
faction.setFlag(FFlag.ENDERGRIEF, true);
faction.setPermittedRelations(FPerm.BUILD, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.DOOR, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.CONTAINER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.BUTTON, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.LEVER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.BUILD, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.DOOR, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.CONTAINER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.BUTTON, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.LEVER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
}
public void setFlagsForSafeZone(Faction faction)
@ -144,11 +144,11 @@ public class Factions extends EntityCollection<Faction>
//faction.setFlag(FFlag.LIGHTNING, false);
faction.setFlag(FFlag.ENDERGRIEF, false);
faction.setPermittedRelations(FPerm.DOOR, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.CONTAINER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.BUTTON, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.LEVER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.TERRITORY, Rel.LEADER, Rel.OFFICER, Rel.MEMBER);
faction.setPermittedRelations(FPerm.DOOR, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.CONTAINER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.BUTTON, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.LEVER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.TERRITORY, Rel.LEADER, Rel.OFFICER, Rel.MEMBER);
}
public void setFlagsForWarZone(Faction faction)
@ -167,10 +167,10 @@ public class Factions extends EntityCollection<Faction>
//faction.setFlag(FFlag.LIGHTNING, true);
faction.setFlag(FFlag.ENDERGRIEF, true);
faction.setPermittedRelations(FPerm.DOOR, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.CONTAINER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.BUTTON, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.LEVER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.DOOR, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.CONTAINER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.BUTTON, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.LEVER, Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY, Rel.TRUCE, Rel.NEUTRAL, Rel.ENEMY);
faction.setPermittedRelations(FPerm.TERRITORY, Rel.LEADER, Rel.OFFICER, Rel.MEMBER);
}

View File

@ -0,0 +1,68 @@
package com.massivecraft.factions.cmd;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.struct.Permission;
import com.massivecraft.factions.struct.Rel;
public class CmdDemote extends FCommand
{
public CmdDemote()
{
super();
this.aliases.add("demote");
this.requiredArgs.add("player name");
//this.optionalArgs.put("", "");
this.permission = Permission.DEMOTE.node;
this.disableOnLock = true;
//To demote someone from member -> recruit you must be an officer.
//To demote someone from officer -> member you must be a leader.
//We'll handle this internally
senderMustBePlayer = true;
senderMustBeMember = false;
senderMustBeOfficer = false;
senderMustBeLeader = false;
}
@Override
public void perform()
{
FPlayer you = this.argAsBestFPlayerMatch(0);
if (you == null) return;
if (you.getFaction() != myFaction)
{
msg("%s<b> is not a member in your faction.", you.describeTo(fme, true));
return;
}
if (you == fme)
{
msg("<b>The target player mustn't be yourself.");
return;
}
if (you.getRole() == Rel.MEMBER)
{
if (!fme.getRole().isAtLeast(Rel.OFFICER)) {
msg("<b>You must be an officer to demote a member to recruit.");
return;
}
you.setRole(Rel.RECRUIT);
myFaction.msg("%s<i> was demoted to being a recruit in your faction.", you.describeTo(myFaction, true));
}
else if (you.getRole() == Rel.OFFICER)
{
if (!fme.getRole().isAtLeast(Rel.LEADER)) {
msg("<b>You must be the leader to demote an officer to member.");
return;
}
you.setRole(Rel.MEMBER);
myFaction.msg("%s<i> was demoted to being a member in your faction.", you.describeTo(myFaction, true));
}
}
}

View File

@ -103,6 +103,8 @@ public class CmdHelp extends FCommand
pageLines.add( p.cmdBase.cmdUnclaim.getUseageTemplate(true) );
pageLines.add( p.cmdBase.cmdUnclaimall.getUseageTemplate(true) );
pageLines.add( p.cmdBase.cmdKick.getUseageTemplate(true) );
pageLines.add( p.cmdBase.cmdPromote.getUseageTemplate(true) );
pageLines.add( p.cmdBase.cmdDemote.getUseageTemplate(true) );
pageLines.add( p.cmdBase.cmdOfficer.getUseageTemplate(true) );
pageLines.add( p.cmdBase.cmdLeader.getUseageTemplate(true) );
pageLines.add( p.cmdBase.cmdTitle.getUseageTemplate(true) );

View File

@ -3,9 +3,9 @@ package com.massivecraft.factions.cmd;
import org.bukkit.Bukkit;
import com.massivecraft.factions.Conf;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.FPlayers;
import com.massivecraft.factions.Faction;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.P;
import com.massivecraft.factions.event.FPlayerJoinEvent;
import com.massivecraft.factions.struct.Permission;
@ -87,15 +87,18 @@ public class CmdJoin extends FCommand
// then make 'em pay (if applicable)
if (samePlayer && ! payForCommand(Conf.econCostJoin, "to join a faction", "for joining a faction")) return;
fme.msg("<i>%s successfully joined %s.", fplayer.describeTo(fme, true), faction.getTag(fme));
fme.setRole(Conf.factionRankDefault); // They have just joined a faction, start them out on the lowest rank (default config).
if (!samePlayer)
fplayer.msg("<i>%s moved you into the faction %s.", fme.describeTo(fplayer, true), faction.getTag(fplayer));
faction.msg("<i>%s joined your faction.", fplayer.describeTo(faction, true));
fme.msg("<i>%s successfully joined %s.", fplayer.describeTo(fme, true), faction.getTag(fme));
fplayer.resetFactionData();
fplayer.setFaction(faction);
faction.deinvite(fplayer);
if (Conf.logFactionJoin)
{

View File

@ -0,0 +1,69 @@
package com.massivecraft.factions.cmd;
import com.massivecraft.factions.FPlayer;
import com.massivecraft.factions.struct.Permission;
import com.massivecraft.factions.struct.Rel;
public class CmdPromote extends FCommand
{
public CmdPromote()
{
super();
this.aliases.add("promote");
this.requiredArgs.add("player name");
//this.optionalArgs.put("", "");
this.permission = Permission.PROMOTE.node;
this.disableOnLock = true;
//To promote someone from recruit -> member you must be an officer.
//To promote someone from member -> officer you must be a leader.
//We'll handle this internally
senderMustBePlayer = true;
senderMustBeMember = false;
senderMustBeOfficer = false;
senderMustBeLeader = false;
}
@Override
public void perform()
{
FPlayer you = this.argAsBestFPlayerMatch(0);
if (you == null) return;
if (you.getFaction() != myFaction)
{
msg("%s<b> is not a member in your faction.", you.describeTo(fme, true));
return;
}
if (you == fme)
{
msg("<b>The target player mustn't be yourself.");
return;
}
if (you.getRole() == Rel.RECRUIT)
{
if (!fme.getRole().isAtLeast(Rel.OFFICER)) {
msg("<b>You must be an officer to promote someone to member.");
return;
}
you.setRole(Rel.MEMBER);
myFaction.msg("%s<i> was promoted to being a member of your faction.", you.describeTo(myFaction, true));
}
else if (you.getRole() == Rel.MEMBER)
{
if (!fme.getRole().isAtLeast(Rel.LEADER)) {
msg("<b>You must be the leader to promote someone to officer.");
return;
}
// Give
you.setRole(Rel.OFFICER);
myFaction.msg("%s<i> was promoted to being a officer in your faction.", you.describeTo(myFaction, true));
}
}
}

View File

@ -49,6 +49,7 @@ public class CmdShow extends FCommand
Collection<FPlayer> admins = faction.getFPlayersWhereRole(Rel.LEADER);
Collection<FPlayer> mods = faction.getFPlayersWhereRole(Rel.OFFICER);
Collection<FPlayer> normals = faction.getFPlayersWhereRole(Rel.MEMBER);
Collection<FPlayer> recruits = faction.getFPlayersWhereRole(Rel.RECRUIT);
msg(p.txt.titleize(faction.getTag(fme)));
msg("<a>Description: <i>%s", faction.getDescription());
@ -147,6 +148,17 @@ public class CmdShow extends FCommand
}
}
for (FPlayer follower : recruits)
{
if (follower.isOnline())
{
memberOnlineNames.add(follower.getNameAndTitle(fme));
}
else
{
memberOfflineNames.add(follower.getNameAndTitle(fme));
}
}
sendMessage(p.txt.parse("<a>Members online: ") + TextUtil.implode(memberOnlineNames, sepparator));
sendMessage(p.txt.parse("<a>Members offline: ") + TextUtil.implode(memberOfflineNames, sepparator));
}

View File

@ -16,6 +16,7 @@ public class FCmdRoot extends FCommand
public CmdConfig cmdConfig = new CmdConfig();
public CmdCreate cmdCreate = new CmdCreate();
public CmdDeinvite cmdDeinvite = new CmdDeinvite();
public CmdDemote cmdDemote = new CmdDemote();
public CmdDescription cmdDescription = new CmdDescription();
public CmdDisband cmdDisband = new CmdDisband();
public CmdFlag cmdFlag = new CmdFlag();
@ -33,6 +34,7 @@ public class FCmdRoot extends FCommand
public CmdPerm cmdPerm = new CmdPerm();
public CmdPower cmdPower = new CmdPower();
public CmdPowerBoost cmdPowerBoost = new CmdPowerBoost();
public CmdPromote cmdPromote = new CmdPromote();
public CmdRelationAlly cmdRelationAlly = new CmdRelationAlly();
public CmdRelationEnemy cmdRelationEnemy = new CmdRelationEnemy();
public CmdRelationNeutral cmdRelationNeutral = new CmdRelationNeutral();
@ -77,6 +79,7 @@ public class FCmdRoot extends FCommand
this.addSubCommand(this.cmdCreate);
this.addSubCommand(this.cmdSethome);
this.addSubCommand(this.cmdTag);
this.addSubCommand(this.cmdDemote);
this.addSubCommand(this.cmdDescription);
this.addSubCommand(this.cmdCape);
this.addSubCommand(this.cmdPerm);
@ -103,6 +106,7 @@ public class FCmdRoot extends FCommand
this.addSubCommand(this.cmdRelationTruce);
this.addSubCommand(this.cmdBypass);
this.addSubCommand(this.cmdPowerBoost);
this.addSubCommand(this.cmdPromote);
this.addSubCommand(this.cmdLock);
this.addSubCommand(this.cmdReload);
this.addSubCommand(this.cmdConfig);

View File

@ -24,11 +24,11 @@ import com.massivecraft.factions.iface.RelationParticipator;
*/
public enum FPerm
{
BUILD("build", "edit the terrain", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY),
BUILD("build", "edit the terrain", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY),
PAINBUILD("painbuild", "edit but take damage"),
DOOR("door", "use doors", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY),
BUTTON("button", "use stone buttons", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY),
LEVER("lever", "use levers", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.ALLY),
DOOR("door", "use doors", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY),
BUTTON("button", "use stone buttons", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY),
LEVER("lever", "use levers", Rel.LEADER, Rel.OFFICER, Rel.MEMBER, Rel.RECRUIT, Rel.ALLY),
CONTAINER("container", "use containers", Rel.LEADER, Rel.OFFICER, Rel.MEMBER),
INVITE("invite", "invite players", Rel.LEADER, Rel.OFFICER),
KICK("kick", "kick members", Rel.LEADER, Rel.OFFICER),

View File

@ -18,6 +18,7 @@ public enum Permission
CONFIG("config"),
CREATE("create"),
DEINVITE("deinvite"),
DEMOTE("demote"),
DESCRIPTION("description"),
DISBAND("disband"),
FLAG("flag"),
@ -49,6 +50,7 @@ public enum Permission
POWER("power"),
POWER_ANY("power.any"),
POWERBOOST("powerboost"),
PROMOTE("promote"),
RELATION("relation"),
RELOAD("reload"),
SAVE("save"),

View File

@ -6,9 +6,10 @@ import com.massivecraft.factions.Conf;
public enum Rel
{
LEADER (70, "your faction leader", "your faction leader", "", ""),
OFFICER (60, "an officer in your faction", "officers in your faction", "", ""),
MEMBER (50, "a member in your faction", "members in your faction", "your faction", "your factions"),
LEADER (80, "your faction leader", "your faction leader", "", ""),
OFFICER (70, "an officer in your faction", "officers in your faction", "", ""),
MEMBER (60, "a member in your faction", "members in your faction", "your faction", "your factions"),
RECRUIT (50, "a recruit in your faction", "recruits in your faction", "", ""),
ALLY (40, "an ally", "allies", "an allied faction", "allied factions"),
TRUCE (30, "someone in truce with you", "those in truce with you", "a faction in truce", "factions in truce"),
NEUTRAL (20, "someone neutral to you", "those neutral to you", "a neutral faction", "neutral factions"),
@ -64,6 +65,7 @@ public enum Rel
if (c == 'l') return LEADER;
if (c == 'o') return OFFICER;
if (c == 'm') return MEMBER;
if (c == 'r') return RECRUIT;
if (c == 'a') return ALLY;
if (c == 't') return TRUCE;
if (c == 'n') return NEUTRAL;
@ -93,7 +95,7 @@ public enum Rel
public ChatColor getColor()
{
if (this.isAtLeast(MEMBER))
if (this.isAtLeast(RECRUIT))
return Conf.colorMember;
else if (this == ALLY)
return Conf.colorAlly;
@ -117,6 +119,16 @@ public enum Rel
return Conf.prefixOfficer;
}
if (this == MEMBER)
{
return Conf.prefixMember;
}
if (this == RECRUIT)
{
return Conf.prefixRecruit;
}
return "";
}