Refactored party system commands. Simplified logic and improved readability.
This commit is contained in:
@@ -18,55 +18,25 @@ import net.neoforged.neoforge.event.entity.player.AttackEntityEvent;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
/**
|
|
||||||
* Party/”comrade” handler.
|
|
||||||
*
|
|
||||||
* Commands:
|
|
||||||
* /comrade party create
|
|
||||||
* /comrade invite <player>
|
|
||||||
* /comrade accept <leader>
|
|
||||||
* /comrade remove <member>
|
|
||||||
* /comrade list
|
|
||||||
*
|
|
||||||
* Only the party “leader” can remove others. Invites must be accepted by the target.
|
|
||||||
* If you invite someone but you aren’t yet in a party, you automatically become leader of a new party.
|
|
||||||
*/
|
|
||||||
@EventBusSubscriber(
|
@EventBusSubscriber(
|
||||||
modid = Stalinium.MODID,
|
modid = Stalinium.MODID,
|
||||||
bus = EventBusSubscriber.Bus.GAME
|
bus = EventBusSubscriber.Bus.GAME
|
||||||
)
|
)
|
||||||
public class ComradeHandler {
|
public class ComradeHandler {
|
||||||
/** Maps each party leader → Party object. Only the leader’s UUID is the key. */
|
|
||||||
public static final Map<UUID, Party> PARTIES = new ConcurrentHashMap<>();
|
public static final Map<UUID, Party> PARTIES = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/** If player X has been invited by leader Y, pendingInvites maps X → Y. */
|
|
||||||
private static final Map<UUID, UUID> PENDING_INVITES = new ConcurrentHashMap<>();
|
private static final Map<UUID, UUID> PENDING_INVITES = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/** A small helper class to store party data. */
|
|
||||||
public static class Party {
|
public static class Party {
|
||||||
final UUID leader;
|
public final UUID leader;
|
||||||
public final Set<UUID> members = ConcurrentHashMap.newKeySet();
|
public final Set<UUID> members = ConcurrentHashMap.newKeySet();
|
||||||
|
public Party(UUID leader) {
|
||||||
Party(UUID leader) {
|
|
||||||
this.leader = leader;
|
this.leader = leader;
|
||||||
this.members.add(leader);
|
this.members.add(leader);
|
||||||
}
|
}
|
||||||
|
public boolean isMember(UUID u) { return members.contains(u); }
|
||||||
public boolean isMember(UUID uuid) {
|
public boolean isLeader(UUID u) { return leader.equals(u); }
|
||||||
return members.contains(uuid);
|
public void addMember(UUID u) { members.add(u); }
|
||||||
}
|
public void removeMember(UUID u) { members.remove(u); }
|
||||||
|
|
||||||
void addMember(UUID uuid) {
|
|
||||||
members.add(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeMember(UUID uuid) {
|
|
||||||
members.remove(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isLeader(UUID uuid) {
|
|
||||||
return leader.equals(uuid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<Party> findPartyOf(UUID uuid) {
|
public static Optional<Party> findPartyOf(UUID uuid) {
|
||||||
@@ -75,8 +45,8 @@ public class ComradeHandler {
|
|||||||
.findAny();
|
.findAny();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Optional<Party> findPartyByLeader(UUID leaderUuid) {
|
private static Optional<Party> findPartyByLeader(UUID leader) {
|
||||||
return Optional.ofNullable(PARTIES.get(leaderUuid));
|
return Optional.ofNullable(PARTIES.get(leader));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
@@ -87,73 +57,49 @@ public class ComradeHandler {
|
|||||||
.then(Commands.literal("create")
|
.then(Commands.literal("create")
|
||||||
.executes(ctx -> {
|
.executes(ctx -> {
|
||||||
ServerPlayer sender = ctx.getSource().getPlayerOrException();
|
ServerPlayer sender = ctx.getSource().getPlayerOrException();
|
||||||
UUID senderId = sender.getUUID();
|
UUID me = sender.getUUID();
|
||||||
|
if (findPartyOf(me).isPresent()) {
|
||||||
// If sender is already in a party, do nothing.
|
ctx.getSource().sendFailure(Component.literal("§eYou are already in a party."));
|
||||||
if (findPartyOf(senderId).isPresent()) {
|
|
||||||
ctx.getSource().sendFailure(
|
|
||||||
Component.literal("§eYou are already in a party.")
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Party newParty = new Party(senderId);
|
PARTIES.put(me, new Party(me));
|
||||||
PARTIES.put(senderId, newParty);
|
ctx.getSource().sendSuccess(() -> Component.literal("§aParty created. You are now the leader."), false);
|
||||||
ctx.getSource().sendSuccess(
|
|
||||||
() -> Component.literal("§aParty created. You are now the leader."),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
return 1;
|
return 1;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
|
||||||
.then(Commands.literal("invite")
|
.then(Commands.literal("invite")
|
||||||
.then(Commands.argument("player", EntityArgument.player())
|
.then(Commands.argument("player", EntityArgument.player())
|
||||||
.executes(ctx -> {
|
.executes(ctx -> {
|
||||||
ServerPlayer sender = ctx.getSource().getPlayerOrException();
|
ServerPlayer leader = ctx.getSource().getPlayerOrException();
|
||||||
ServerPlayer target = EntityArgument.getPlayer(ctx, "player");
|
ServerPlayer target = EntityArgument.getPlayer(ctx, "player");
|
||||||
UUID senderId = sender.getUUID();
|
UUID lid = leader.getUUID(), tid = target.getUUID();
|
||||||
UUID targetId = target.getUUID();
|
if (lid.equals(tid)) {
|
||||||
if (senderId.equals(targetId)) {
|
ctx.getSource().sendFailure(Component.literal("§eYou cannot invite yourself."));
|
||||||
ctx.getSource().sendFailure(
|
|
||||||
Component.literal("§eYou cannot invite yourself.")
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Optional<Party> senderPartyOpt = findPartyOf(senderId);
|
// ensure party exists & you are leader
|
||||||
if (senderPartyOpt.isPresent()) {
|
Party party = findPartyOf(lid).orElseGet(() -> {
|
||||||
Party party = senderPartyOpt.get();
|
Party auto = new Party(lid);
|
||||||
if (party.isMember(targetId)) {
|
PARTIES.put(lid, auto);
|
||||||
ctx.getSource().sendFailure(
|
ctx.getSource().sendSuccess(() -> Component.literal("§aNo existing party—one was created for you."), false);
|
||||||
Component.literal("§eThat player is already in your party.")
|
return auto;
|
||||||
);
|
});
|
||||||
|
if (!party.isLeader(lid)) {
|
||||||
|
ctx.getSource().sendFailure(Component.literal("§eOnly the party leader can invite."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
if (party.isMember(tid)) {
|
||||||
Party auto = new Party(senderId);
|
ctx.getSource().sendFailure(Component.literal("§eThat player is already in your party."));
|
||||||
PARTIES.put(senderId, auto);
|
|
||||||
senderPartyOpt = Optional.of(auto);
|
|
||||||
ctx.getSource().sendSuccess(
|
|
||||||
() -> Component.literal("§aNo party found, so one was automatically created. You are now leader."),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Party party = senderPartyOpt.get();
|
|
||||||
if (!party.isLeader(senderId)) {
|
|
||||||
ctx.getSource().sendFailure(
|
|
||||||
Component.literal("§eOnly the party leader can invite new comrades.")
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
PENDING_INVITES.put(targetId, senderId);
|
PENDING_INVITES.put(tid, lid);
|
||||||
target.sendSystemMessage(
|
target.sendSystemMessage(Component.literal(
|
||||||
Component.literal("§6" + sender.getName().getString()
|
"§6" + leader.getName().getString()
|
||||||
+ " §awants you to join their party. Type §e/comrade accept "
|
+ " §awants you to join their party! Type §e/comrade party accept "
|
||||||
+ sender.getName().getString() + " §ato accept.")
|
+ leader.getName().getString() + "§a."
|
||||||
);
|
));
|
||||||
ctx.getSource().sendSuccess(
|
ctx.getSource().sendSuccess(() ->
|
||||||
() -> Component.literal("§aInvitation sent to §6" + target.getName().getString() + "§a."),
|
Component.literal("§aInvitation sent to §6" + target.getName().getString()), false);
|
||||||
false
|
|
||||||
);
|
|
||||||
return 1;
|
return 1;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -161,36 +107,23 @@ public class ComradeHandler {
|
|||||||
.then(Commands.literal("accept")
|
.then(Commands.literal("accept")
|
||||||
.then(Commands.argument("leader", EntityArgument.player())
|
.then(Commands.argument("leader", EntityArgument.player())
|
||||||
.executes(ctx -> {
|
.executes(ctx -> {
|
||||||
ServerPlayer accepter = ctx.getSource().getPlayerOrException();
|
ServerPlayer you = ctx.getSource().getPlayerOrException();
|
||||||
ServerPlayer leader= EntityArgument.getPlayer(ctx,"leader");
|
ServerPlayer leader= EntityArgument.getPlayer(ctx,"leader");
|
||||||
UUID accepterId = accepter.getUUID();
|
UUID yid = you.getUUID(), lid = leader.getUUID();
|
||||||
UUID leaderId = leader.getUUID();
|
if (!Objects.equals(PENDING_INVITES.get(yid), lid)) {
|
||||||
UUID expected = PENDING_INVITES.get(accepterId);
|
ctx.getSource().sendFailure(Component.literal("§eNo invitation found from that leader."));
|
||||||
if (expected == null || !expected.equals(leaderId)) {
|
|
||||||
ctx.getSource().sendFailure(
|
|
||||||
Component.literal("§eNo invitation found from that leader.")
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Party party = findPartyByLeader(lid)
|
||||||
// Find (or create) the leader’s party:
|
|
||||||
Party party = findPartyByLeader(leaderId)
|
|
||||||
.orElseGet(() -> {
|
.orElseGet(() -> {
|
||||||
Party brandNew = new Party(leaderId);
|
Party p = new Party(lid);
|
||||||
PARTIES.put(leaderId, brandNew);
|
PARTIES.put(lid, p);
|
||||||
return brandNew;
|
return p;
|
||||||
});
|
});
|
||||||
|
party.addMember(yid);
|
||||||
// Add this player to that party:
|
PENDING_INVITES.remove(yid);
|
||||||
party.addMember(accepterId);
|
you.sendSystemMessage(Component.literal("§aYou joined §6" + leader.getName().getString() + "§a’s party."));
|
||||||
PENDING_INVITES.remove(accepterId);
|
leader.sendSystemMessage(Component.literal("§a" + you.getName().getString() + " §ais now your comrade."));
|
||||||
|
|
||||||
accepter.sendSystemMessage(
|
|
||||||
Component.literal("§aYou have joined §6" + leader.getName().getString() + "§a’s party.")
|
|
||||||
);
|
|
||||||
leader.sendSystemMessage(
|
|
||||||
Component.literal("§a" + accepter.getName().getString() + " §ais now your comrade.")
|
|
||||||
);
|
|
||||||
return 1;
|
return 1;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
@@ -198,113 +131,119 @@ public class ComradeHandler {
|
|||||||
.then(Commands.literal("remove")
|
.then(Commands.literal("remove")
|
||||||
.then(Commands.argument("player", EntityArgument.player())
|
.then(Commands.argument("player", EntityArgument.player())
|
||||||
.executes(ctx -> {
|
.executes(ctx -> {
|
||||||
ServerPlayer sender = ctx.getSource().getPlayerOrException();
|
ServerPlayer leader = ctx.getSource().getPlayerOrException();
|
||||||
ServerPlayer toRemove = EntityArgument.getPlayer(ctx, "player");
|
ServerPlayer target = EntityArgument.getPlayer(ctx,"player");
|
||||||
UUID senderId = sender.getUUID();
|
UUID lid = leader.getUUID(), tid = target.getUUID();
|
||||||
UUID removeId = toRemove.getUUID();
|
Optional<Party> opt = findPartyOf(lid);
|
||||||
Optional<Party> maybeParty = findPartyOf(senderId);
|
if (opt.isEmpty()) {
|
||||||
if (maybeParty.isEmpty()) {
|
ctx.getSource().sendFailure(Component.literal("§eYou have no party."));
|
||||||
ctx.getSource().sendFailure(
|
|
||||||
Component.literal("§eYou are not comrades with anyone.")
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Party party = maybeParty.get();
|
Party party = opt.get();
|
||||||
if (!party.isLeader(senderId)) {
|
if (!party.isLeader(lid)) {
|
||||||
ctx.getSource().sendFailure(
|
ctx.getSource().sendFailure(Component.literal("§eOnly the leader can remove."));
|
||||||
Component.literal("§eOnly the party leader may remove members.")
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (removeId.equals(senderId)) {
|
if (!party.isMember(tid)) {
|
||||||
ctx.getSource().sendFailure(
|
ctx.getSource().sendFailure(Component.literal("§eThat player is not in your party."));
|
||||||
Component.literal("§eYou cannot remove yourself from your own party.")
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!party.isMember(removeId)) {
|
party.removeMember(tid);
|
||||||
ctx.getSource().sendFailure(
|
target.sendSystemMessage(Component.literal(
|
||||||
Component.literal("§eThat player is not one of your comrades.")
|
"§cYou have been removed from §6" + leader.getName().getString() + "§c’s party."
|
||||||
);
|
));
|
||||||
|
ctx.getSource().sendSuccess(() ->
|
||||||
|
Component.literal("§aRemoved “" + target.getName().getString() + "”."), false);
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.then(Commands.literal("leave")
|
||||||
|
.executes(ctx -> {
|
||||||
|
ServerPlayer you = ctx.getSource().getPlayerOrException();
|
||||||
|
UUID youId = you.getUUID();
|
||||||
|
Optional<Party> opt = findPartyOf(youId);
|
||||||
|
if (opt.isEmpty()) {
|
||||||
|
ctx.getSource().sendFailure(Component.literal("§eYou are not in a party."));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Party party = opt.get();
|
||||||
party.removeMember(removeId);
|
if (party.isLeader(youId)) {
|
||||||
toRemove.sendSystemMessage(
|
ctx.getSource().sendFailure(Component.literal(
|
||||||
Component.literal("§cYou are no longer "
|
"§eYou are the leader — use /comrade party disband to tear it down."));
|
||||||
+ sender.getName().getString() + "'s comrade.")
|
return 0;
|
||||||
);
|
}
|
||||||
ctx.getSource().sendSuccess(
|
party.removeMember(youId);
|
||||||
() -> Component.literal("§a“" + toRemove.getName().getString()
|
you.sendSystemMessage(Component.literal("§cYou left the party."));
|
||||||
+ "” is no longer your comrade."),
|
MinecraftServer srv = ctx.getSource().getServer();
|
||||||
false
|
ServerPlayer leader = srv.getPlayerList().getPlayer(party.leader);
|
||||||
);
|
if (leader != null) {
|
||||||
if (party.members.size() == 1 && party.isLeader(senderId)) {
|
leader.sendSystemMessage(Component.literal(
|
||||||
PARTIES.remove(senderId);
|
"§e" + you.getName().getString() + " has left your party."));
|
||||||
sender.sendSystemMessage(
|
|
||||||
Component.literal("§6Your party was disbanded (no more members).")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
.then(Commands.literal("disband")
|
||||||
|
.executes(ctx -> {
|
||||||
|
ServerPlayer leader = ctx.getSource().getPlayerOrException();
|
||||||
|
UUID lid = leader.getUUID();
|
||||||
|
Optional<Party> opt = findPartyByLeader(lid);
|
||||||
|
if (opt.isEmpty()) {
|
||||||
|
ctx.getSource().sendFailure(Component.literal("§eYou are not leading any party."));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Party party = opt.get();
|
||||||
|
MinecraftServer srv = ctx.getSource().getServer();
|
||||||
|
party.members.forEach(m -> {
|
||||||
|
ServerPlayer p = srv.getPlayerList().getPlayer(m);
|
||||||
|
if (p != null) {
|
||||||
|
p.sendSystemMessage(Component.literal("§cYour party has been disbanded."));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
PENDING_INVITES.entrySet().removeIf(e -> e.getValue().equals(lid));
|
||||||
|
PARTIES.remove(lid);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
)
|
)
|
||||||
.then(Commands.literal("list")
|
.then(Commands.literal("list")
|
||||||
.executes(ctx -> {
|
.executes(ctx -> {
|
||||||
ServerPlayer sender = ctx.getSource().getPlayerOrException();
|
ServerPlayer you = ctx.getSource().getPlayerOrException();
|
||||||
UUID senderId = sender.getUUID();
|
UUID youId = you.getUUID();
|
||||||
Optional<Party> maybeParty = findPartyOf(senderId);
|
Optional<Party> opt = findPartyOf(youId);
|
||||||
if (maybeParty.isEmpty()) {
|
if (opt.isEmpty()) {
|
||||||
ctx.getSource().sendSuccess(
|
ctx.getSource().sendSuccess(() -> Component.literal("§eYou are not in a party."), false);
|
||||||
() -> Component.literal("§eYou are not in a party."),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Party party = maybeParty.get();
|
Party party = opt.get();
|
||||||
MinecraftServer server = ctx.getSource().getServer();
|
MinecraftServer srv = ctx.getSource().getServer();
|
||||||
List<String> displayNames = new ArrayList<>();
|
List<String> names = new ArrayList<>();
|
||||||
for (UUID memberUuid : party.members) {
|
for(UUID m : party.members){
|
||||||
ServerPlayer online = server.getPlayerList().getPlayer(memberUuid);
|
ServerPlayer p = srv.getPlayerList().getPlayer(m);
|
||||||
if (online != null) {
|
names.add(p != null ? p.getName().getString() : m.toString());
|
||||||
displayNames.add(online.getName().getString());
|
|
||||||
} else {
|
|
||||||
displayNames.add(memberUuid.toString());
|
|
||||||
}
|
}
|
||||||
}
|
String out = String.join(", ", names);
|
||||||
String joined = String.join(", ", displayNames);
|
ctx.getSource().sendSuccess(() -> Component.literal("§6Party: §f" + out), false);
|
||||||
ctx.getSource().sendSuccess(
|
|
||||||
() -> Component.literal("§6Party members: §f" + joined),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
return 1;
|
return 1;
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onPlayerAttackEntity(AttackEntityEvent event) {
|
public static void onPlayerAttackEntity(AttackEntityEvent event) {
|
||||||
LivingEntity source = event.getEntity();
|
LivingEntity src = event.getEntity();
|
||||||
if (source.level().isClientSide) return;
|
if (src.level().isClientSide || !(src instanceof Player)) return;
|
||||||
if (!(source instanceof Player)) return;
|
if (!(event.getTarget() instanceof ServerPlayer victim)) return;
|
||||||
|
UUID a = src.getUUID(), b = victim.getUUID();
|
||||||
if (event.getTarget() instanceof ServerPlayer targetPlayer) {
|
Optional<Party> opt = findPartyOf(a);
|
||||||
UUID sourceId = source.getUUID();
|
if (opt.isPresent() && opt.get().isMember(b)) {
|
||||||
UUID targetId = targetPlayer.getUUID();
|
|
||||||
|
|
||||||
// If both are in the same party, cancel damage:
|
|
||||||
Optional<Party> maybeParty = findPartyOf(sourceId);
|
|
||||||
if (maybeParty.isPresent()) {
|
|
||||||
Party party = maybeParty.get();
|
|
||||||
if (party.isMember(targetId)) {
|
|
||||||
event.setCanceled(true);
|
event.setCanceled(true);
|
||||||
source.sendSystemMessage(
|
src.sendSystemMessage(Component.literal(
|
||||||
Component.literal("§cYou cannot hurt your comrade “"
|
"§cYou cannot hurt your comrade “" + victim.getName().getString() + "”!"
|
||||||
+ targetPlayer.getName().getString() + "”!")
|
));
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user