WIP for team invites.

This commit is contained in:
tastybento 2024-01-04 17:16:36 +09:00
parent de28bae47d
commit f290a2c65a
5 changed files with 213 additions and 4 deletions

View File

@ -78,6 +78,8 @@ public class IslandTeamCommand extends CompositeCommand {
private IslandTeamInviteRejectCommand rejectCommand;
private IslandTeamInviteCommand inviteCommand;
public IslandTeamCommand(CompositeCommand parent) {
super(parent, "team");
inviteMap = new HashMap<>();
@ -89,7 +91,7 @@ public class IslandTeamCommand extends CompositeCommand {
setOnlyPlayer(true);
setDescription("commands.island.team.description");
// Register commands
new IslandTeamInviteCommand(this);
inviteCommand = new IslandTeamInviteCommand(this);
leaveCommand = new IslandTeamLeaveCommand(this);
setOwnerCommand = new IslandTeamSetownerCommand(this);
kickCommand = new IslandTeamKickCommand(this);
@ -164,13 +166,31 @@ public class IslandTeamCommand extends CompositeCommand {
panelBuilder.registerTypeBuilder("MEMBER", this::createMemberButton);
panelBuilder.registerTypeBuilder("INVITED", this::createInvitedButton);
panelBuilder.registerTypeBuilder("RANK", this::createRankButton);
//panelBuilder.registerTypeBuilder("KICK", this::createKickButton);
panelBuilder.registerTypeBuilder("INVITE", this::createInviteButton);
border = panelBuilder.getPanelTemplate().border();
background = panelBuilder.getPanelTemplate().background();
// Register unknown type builder.
panelBuilder.build();
}
private PanelItem createInviteButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) {
if (island == null || !user.hasPermission(this.inviteCommand.getPermission())
|| island.getRank(user) < island.getRankCommand(this.getLabel() + " invite")) {
return this.getBlankBorder();
}
PanelItemBuilder builder = new PanelItemBuilder();
builder.icon(Material.PLAYER_HEAD);
builder.name(user.getTranslation("commands.island.team.gui.buttons.invite.name"));
builder.clickHandler((panel, user, clickType, clickSlot) -> {
if (clickType.equals(ClickType.LEFT)) {
user.closeInventory();
this.inviteCommand.build(user);
}
return true;
});
return builder.build();
}
private PanelItem createRankButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) {
// If there is no island, the do not show this icon
if (island == null) {

View File

@ -1,11 +1,15 @@
package world.bentobox.bentobox.api.commands.island.team;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.commands.CompositeCommand;
@ -13,6 +17,12 @@ import world.bentobox.bentobox.api.commands.island.team.Invite.Type;
import world.bentobox.bentobox.api.events.IslandBaseEvent;
import world.bentobox.bentobox.api.events.team.TeamEvent;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.TemplatedPanel;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.panels.builders.TemplatedPanelBuilder;
import world.bentobox.bentobox.api.panels.reader.ItemTemplateRecord;
import world.bentobox.bentobox.api.panels.reader.PanelTemplateRecord.TemplateItem;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.IslandsManager;
@ -24,6 +34,9 @@ public class IslandTeamInviteCommand extends CompositeCommand {
private final IslandTeamCommand itc;
private @Nullable User invitedPlayer;
private @Nullable TemplateItem border;
private @Nullable TemplateItem background;
private User user;
public IslandTeamInviteCommand(IslandTeamCommand parent) {
super(parent, "invite");
@ -36,6 +49,8 @@ public class IslandTeamInviteCommand extends CompositeCommand {
setOnlyPlayer(true);
setDescription("commands.island.team.invite.description");
setConfigurableRankCommand();
// Panels
getPlugin().saveResource("panels/team_invite_panel.yml", true);
}
@ -65,6 +80,7 @@ public class IslandTeamInviteCommand extends CompositeCommand {
Type inviteType = getInviteType(playerUUID);
if (inviteType != null) {
// TODO: send to team command to present invite
String name = getPlayers().getName(playerUUID);
switch (inviteType) {
case COOP -> user.sendMessage("commands.island.team.invite.name-has-invited-you.coop", TextVariables.NAME, name);
@ -73,7 +89,7 @@ public class IslandTeamInviteCommand extends CompositeCommand {
}
return true;
}
build(user);
showHelp(this, user);
return false;
}
@ -204,4 +220,60 @@ public class IslandTeamInviteCommand extends CompositeCommand {
return Optional.of(Util.tabLimit(options, lastArg));
}
public void build(User user) {
this.user = user;
// Start building panel.
TemplatedPanelBuilder panelBuilder = new TemplatedPanelBuilder();
panelBuilder.user(user);
panelBuilder.world(user.getWorld());
panelBuilder.template("team_panel", new File(getPlugin().getDataFolder(), "panels"));
panelBuilder.parameters("[name]", user.getName(), "[display_name]", user.getDisplayName());
panelBuilder.registerTypeBuilder("PROSPECT", this::createProspectButton);
//panelBuilder.registerTypeBuilder("INVITED", this::createInvitedButton);
//panelBuilder.registerTypeBuilder("RANK", this::createRankButton);
//panelBuilder.registerTypeBuilder("INVITE", this::createInviteButton);
border = panelBuilder.getPanelTemplate().border();
background = panelBuilder.getPanelTemplate().background();
// Register unknown type builder.
panelBuilder.build();
}
/**
* Create member button panel item.
*
* @param template the template
* @param slot the slot
* @return the panel item
*/
private PanelItem createProspectButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot slot) {
// Player issuing the command must have an island
Island island = getIslands().getPrimaryIsland(getWorld(), user.getUniqueId());
if (island == null) {
return this.getBlankBackground();
}
// TODO: THERE"S A BUG HERE
return user.getWorld().getPlayers().stream()
.filter(player -> !getIslands().inTeam(getWorld(), player.getUniqueId())).skip(slot.slot() - 1)
.limit(1L)
.findFirst().map(this::getProspect).orElse(this.getBlankBackground());
}
private PanelItem getProspect(Player player) {
return new PanelItemBuilder().icon(player.getName()).build();
}
private PanelItem getBlankBorder() {
return new PanelItemBuilder().icon(Objects.requireNonNullElse(border.icon(), new ItemStack(Material.BARRIER)))
.name((Objects.requireNonNullElse(border.title(), ""))).build();
}
private PanelItem getBlankBackground() {
return new PanelItemBuilder()
.icon(Objects.requireNonNullElse(background.icon(), new ItemStack(Material.BARRIER)))
.name((Objects.requireNonNullElse(background.title(), ""))).build();
}
}

View File

@ -623,9 +623,12 @@ commands:
name: "Rank Filter"
description: "&a Click to cycle ranks"
invitation: "Invitation"
invite:
name: "Invite player"
tips:
LEFT:
name: "&b Left Click"
invite: "&a to invite a player"
RIGHT:
name: "&b Right Click"
SHIFT_RIGHT:
@ -704,6 +707,21 @@ commands:
to-accept-or-reject: '&a Do /[label] team accept to accept, or /[label] team
reject to reject'
you-will-lose-your-island: '&c WARNING! You will lose your island if you accept!'
gui:
titles:
team-invite-panel: "Invite Players"
tips:
LEFT:
name: "&b Left Click"
invite: |
&a to invite a player
&a to join your team
RIGHT:
name: "&b Right Click"
coop: "&a to coop player"
SHIFT_LEFT:
name: "&b Shift Left Click"
trust: "&a to trust a player"
errors:
cannot-invite-self: '&c You cannot invite yourself!'
cooldown: '&c You cannot invite that person for another [number] seconds.'

View File

@ -0,0 +1,90 @@
# Name of panel used for indentification in the code - must be the same name as the filename.
team_panel:
# Title of the panel shown to the user. This is a reference and the reference will be translatable in the locale file
title: commands.island.team.invite.gui.titles.team-invite-panel
# The type of panel to show. Options are INVENTORY, HOPPER, DROPPER. INVENTORY is that standard chest inventory and
# the others refer to the inventories shown for those items.
type: INVENTORY
# The background of the panel. These items will be shown if other items are not there. STAINED_GLASS_PANEs give a good effect.
background:
icon: BLACK_STAINED_GLASS_PANE
# Each item may have text applied to it, but usually for background items, nothing is shown.
title: "&b&r" # Empty text. This is using the Bukkit chat color coding with &'s.
border:
# The border of each panel may be shown as a different item.
# It can be used to provide a contrast to items in the panel.
icon: BLUE_STAINED_GLASS_PANE
title: "&b&r" # Empty text
# This tag indicates which rows in the panel must be shown. The panel will be sized vertically accordingly. This does not include the borders.
# This can be a list and rows must be between 1 and 6, if used.
force-shown: []
# The content section contains details of each item/button in the panel. The numbers indicate the rows and then then columns of each item.
content:
# Row number
2:
2: prospect_button
3: prospect_button
4: prospect_button
5: prospect_button
6: prospect_button
7: prospect_button
8: prospect_button
3:
2: prospect_button
3: prospect_button
4: prospect_button
5: prospect_button
6: prospect_button
7: prospect_button
8: prospect_button
4:
2: prospect_button
3: prospect_button
4: prospect_button
5: prospect_button
6: prospect_button
7: prospect_button
8: prospect_button
5:
2: prospect_button
3: prospect_button
4: prospect_button
5: prospect_button
6: prospect_button
7: prospect_button
8: prospect_button
6:
2: prospect_button
3: prospect_button
4: prospect_button
5: prospect_button
6: prospect_button
7: prospect_button
8: prospect_button
# This is where reusable buttons are defined.
reusable:
# This is the name of the button that is referenced
prospect_button:
# If the icon for a button is not defined, it defaults to AIR and so effectively will not be shown.
# icons are usually not defined if the icon is going to be dynamically set in the panel, e.g. in this case the material will vary
#icon: STONE
title: commands.island.team.invite.gui.buttons.member.name
description: commands.island.team.invite.gui.buttons.member.description
data:
type: PROSPECT
# Actions cover what happens if the button is clicked or the mouse is moved over it. There can be multiple actions possible for different
# click-types.
actions:
# Each action has an arbitrary descriptive name to define it.
invite:
# The click-type is the same as the bukkit {@link org.bukkit.event.inventory.ClickType}. UNKNOWN is the default.
click-type: LEFT
# tooltip is a locale reference that will be translated for the user and shown when they hover over the button.
tooltip: commands.island.team.invite.gui.tips.LEFT.invite
coop:
click-type: RIGHT
tooltip: commands.island.team.invite.gui.tips.RIGHT.coop
trust:
click-type: SHIFT_LEFT
tooltip: commands.island.team.invite.gui.tips.SHIFT_LEFT.trust

View File

@ -13,7 +13,7 @@ team_panel:
border:
# The border of each panel may be shown as a different item.
# It can be used to provide a contrast to items in the panel.
icon: BLACK_STAINED_GLASS_PANE
icon: BLUE_STAINED_GLASS_PANE
title: "&b&r" # Empty text
# This tag indicates which rows in the panel must be shown. The panel will be sized vertically accordingly. This does not include the borders.
# This can be a list and rows must be between 1 and 6, if used.
@ -61,6 +61,15 @@ team_panel:
reject:
click-type: SHIFT_RIGHT
tooltip: commands.island.team.gui.tips.SHIFT_RIGHT.reject
7:
# Invite button
data:
type: INVITE
name: commands.island.team.gui.buttons.invite
actions:
invite:
click-type: LEFT
tooltip: commands.island.team.gui.tips.LEFT.invite
2:
2: member_button
3: member_button