Skip to content
This repository was archived by the owner on Nov 25, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,10 @@ mutation.type.tools = Tools
mutation.type.tools.desc = enchanted diamond tools
mutation.type.apocalypse = Apocalypse
mutation.type.apocalypse.desc = mob spawning chaos
mutation.type.teamchest = Team Chest
mutation.type.teamchest.desc = access a shared team chest
mutation.type.teamchest.item_name = Team Chest
mutation.type.teamchest.item_lore = Right click to access an inventory shared by the team.

tnt.license.info.alreadyHas = You have a TNT license. You can surrender your license by typing {0}
tnt.license.info.doesNotHave = You do not have a TNT license. You can request one by typing {0}
Expand Down
3 changes: 2 additions & 1 deletion PGM/src/main/java/tc/oc/pgm/mutation/Mutation.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public enum Mutation {
BREAD (BreadMutation.class, Material.BREAD),
BOAT (BoatMutation.class, Material.BOAT, false),
TOOLS (ToolsMutation.class, Material.DIAMOND_PICKAXE),
APOCALYPSE (ApocalypseMutation.class, Material.NETHER_STAR);
APOCALYPSE (ApocalypseMutation.class, Material.NETHER_STAR),
TEAMCHEST (TeamChestMutation.class, Material.ENDER_CHEST);

public static final String TYPE_KEY = "mutation.type.";
public static final String DESCRIPTION_KEY = ".desc";
Expand Down
140 changes: 140 additions & 0 deletions PGM/src/main/java/tc/oc/pgm/mutation/types/kit/TeamChestMutation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package tc.oc.pgm.mutation.types.kit;

import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import tc.oc.commons.bukkit.inventory.Slot;
import tc.oc.commons.bukkit.item.ItemBuilder;
import tc.oc.pgm.PGMTranslations;
import tc.oc.pgm.kits.ItemKit;
import tc.oc.pgm.kits.Kit;
import tc.oc.pgm.kits.SlotItemKit;
import tc.oc.pgm.match.Match;
import tc.oc.pgm.match.MatchPlayer;
import tc.oc.pgm.match.Party;
import tc.oc.pgm.mutation.types.KitMutation;
import tc.oc.pgm.wool.WoolMatchModule;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.WeakHashMap;

public class TeamChestMutation extends KitMutation {
final static Material TOOL_TYPE = Material.ENDER_CHEST;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this extra field?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it is used six times, I believe so. So in the future it may be easy to change it if needed.

final static int CHEST_SIZE = 27;

final Map<Party, Inventory> teamChests = new WeakHashMap<>();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though this is weak, you want to clear this disable()


final Optional<WoolMatchModule> optWools;

public TeamChestMutation(Match match) {
super(match, false);
optWools = match().module(WoolMatchModule.class);
}

@Override
public void enable() {
super.enable();
for (Party party : match().getParties()) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mutation modules are special, because they can be enabled or disabled on the fly. So this logic should go into

@Override
public boolean enable() {
    super.enable();
    for (Party party : match().getParties()) {
         // Rest of implementation
    }
}

You will also have to make sure you implement disable() too.

if (party.isParticipatingType()) {
// TODO: Could the chest title be localized properly?
teamChests.put(party, match().getServer().createInventory(null, CHEST_SIZE));
}
}
}

@Override
public void disable() {
teamChests.clear();
super.disable();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remember super.disable()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's best to disable the current class, then the super class.


@Override
public void kits(MatchPlayer player, List<Kit> kits) {
super.kits(player, kits);
kits.add(getKitForPlayer(player));
}

// Open shared inventory instead of placing the chest
@EventHandler(priority = EventPriority.HIGHEST)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add to the annotation ignoreCancelled = true

public void onChestUse(PlayerInteractEvent event) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rule of thumb for player events, very early in your event block you want to convert to a MatchPlayer and depending on the event a Participant.

MatchPlayer player = match.participant(event.getPlayer());
if(!player.isPresent() ||
   !(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) ||
   event.getItem() == null || event.getItem().getType() != Material.ENDER_CHEST) {
       return;
}

Player bukkitPlayer = event.getPlayer();
Optional<MatchPlayer> optPlayer = match().participant((Entity) bukkitPlayer);
if (!optPlayer.isPresent() ||
!(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) ||
event.getItem() == null ||
event.getItem().getType() != TOOL_TYPE) {
return;
}

Optional<Inventory> optTeamInventory = getTeamsInventory(bukkitPlayer);
optTeamInventory.ifPresent(teamInventory -> {
event.setCancelled(true);
// If the item is in the off-hand slot, it wont get put back visually for the player without this.
if(event.getHand() == EquipmentSlot.OFF_HAND) event.getActor().updateInventory();
bukkitPlayer.openInventory(teamInventory);
});
}

@EventHandler(priority = EventPriority.LOWEST)
public void onInventoryClick(InventoryClickEvent event) {
Player player = event.getActor();
if (event.getCurrentItem() == null) return;

// No putting blacklisted items (ender chest, possibly wool) into the chest
Optional<Inventory> teamChest = getTeamsInventory(player);
if (teamChest.map(teamInventory -> teamInventory.equals(event.getView().getTopInventory())).orElse(false) &&
isBlacklistedItem(event.getCurrentItem())) {
event.setCancelled(true);
return;
}

// If normal right click, in their inventory, on the chest, then open shared inventory.
getTeamsInventory(player).ifPresent(teamInventory -> {
if (event.getInventory().getType() == InventoryType.CRAFTING &&
event.getCurrentItem().getType() == TOOL_TYPE &&
event.getAction() == InventoryAction.PICKUP_HALF) {
event.setCancelled(true);
// This resets their mouse position annoyingly, but without it items can get stuck in places.
player.closeInventory();
// Prevent visual inconsistencies, specifically off-hand slot
if (event.getSlotType() == InventoryType.SlotType.QUICKBAR) {
player.updateInventory();
}
player.openInventory(teamInventory);
}
});
}

private boolean isBlacklistedItem(ItemStack item) {
return item.getType() == TOOL_TYPE ||
optWools.map(w -> w.isObjectiveWool(item)).orElse(false);
}

private Optional<Inventory> getTeamsInventory(Player bukkitPlayer) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For our needs, would an @nullable possibly be better?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we take in a MatchPlayer instead of a bukkit Player object?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional's are preferred over null values

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use Optionals if it makes for cleaner code, if it makes things messier then you don't need to.

return match().participant((Entity) bukkitPlayer)
.map(matchPlayer -> teamChests.get(matchPlayer.getParty()));
}

private Kit getKitForPlayer(MatchPlayer player) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PGMTranslations is legacy. See RenderedItemBuilder.

ItemStack stack = new ItemBuilder(item(TOOL_TYPE))
.name(ChatColor.DARK_PURPLE + PGMTranslations.t("mutation.type.teamchest.item_name", player))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we able to not use PGMTranslations?

Copy link
Copy Markdown
Author

@DirkyJerky DirkyJerky Jun 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't seem to get it to work yet,
new Component(new TranslatableComponent("mutation.type.teamchest.item_name"), ChatColor.DARK_PURPLE).getText()
doesn't work.

Neither did new Component(ChatColor.DARK_PURPLE).translate("mutation.type.teamchest.item_name").getText()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toLegacyText()

Copy link
Copy Markdown
Author

@DirkyJerky DirkyJerky Jun 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do I get a ComponentRenderContext? That is what I assume I need (Readme says I need it), because nothing is translating it is just showing the translation key.

I can't inject it as I assume that is how it is normally recieved.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mutations don't support injection right now, so using PGMTranslations should be fine.

.lore(ChatColor.DARK_AQUA + PGMTranslations.t("mutation.type.teamchest.item_lore", player))
.get();

ItemKit kit = new SlotItemKit(stack, Slot.Player.forIndex(17));
return kit;
}
}
2 changes: 1 addition & 1 deletion PGM/src/main/java/tc/oc/pgm/wool/WoolMatchModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public class WoolMatchModule extends MatchModule implements Listener {
.collect(Collectors.toImmutableList());
}

private boolean isObjectiveWool(ItemStack stack) {
public boolean isObjectiveWool(ItemStack stack) {
if(stack.getType() == Material.WOOL) {
for(MonumentWool wool : this.wools) {
if(wool.getDefinition().isObjectiveWool(stack)) return true;
Expand Down