First commit

This commit is contained in:
Tastybento 2017-11-25 18:17:16 -08:00
commit 38a98043d5
15 changed files with 1681 additions and 0 deletions

1
README.md Normal file
View File

@ -0,0 +1 @@
# addon-challenges

305
config.yml Normal file
View File

@ -0,0 +1,305 @@
# This file lists the values for various blocks that are used to calculate the
# island level. Level = total of all blocks in island boundary / 100.
# Players with the permission askyblock.island.multiplier.# will have their blocks
# multiplied in value by that amount.
# Underwater block multiplier
# If blocks are below sea-level, they can have a higher value. e.g. 2x
# Promotes under-water development if there is a sea. Value can be fractional.
underwater: 1.0
# Value of one island level. Default 100. Minimum value is 1.
levelcost: 100
# Cooldown between level requests in seconds
levelwait: 60
# Death penalty
# How many block values a player will lose per death.
# Default value of 100 means that for every death, the player will lose 1 level (if levelcost is 100)
# Set to zero to not use this feature
deathpenalty: 100
# Sum team deaths - if true, all the teams deaths are summed
# If false, only the leader's deaths counts
sumteamdeaths: false
# Max deaths
# If player dies more than this, it doesn't count anymore
# Stops players from getting into an impossible situation
maxdeaths: 10
# Reset deaths on island reset
islandresetdeathreset: true
# Reset deaths on team join
teamjoindeathreset: true
# This section lists the limits for any particular block. Blocks over this amount
# are not counted.
# Format:
# MATERIAL: limit or MATERIAL:DATA: limit.
# If DATA is used, there MUST be a corresponding block:data value in the blocks list.
# For example, if you limit Jungle Logs LOG:3, then there must be a value for LOG:3
# in the blocks section. If there is not, then LOG:3 would have no value.
limits:
COBBLESTONE: 10000
NETHERRACK: 1000
#LOG:3: 10
# This section lists the value of a block. Value must be an integer.
# Any blocks not listed will have a value of zero.
# Format is MATERIAL: value or MATERIAL:DATA: value.
blocks:
ACACIA_DOOR: 1
ACACIA_STAIRS: 1
ACACIA_FENCE: 1
ACACIA_FENCE_GATE: 1
ACACIA_STAIRS: 2
ACTIVATOR_RAIL: 10
AIR: 0
ANVIL: 10
ARMOR_STAND: 2
BANNER: 2
BEACON: 100
BED_BLOCK: 1
BEDROCK: 0
BEETROOT_BLOCK: 1
BIRCH_DOOR: 1
BIRCH_FENCE: 1
BIRCH_FENCE_GATE: 1
BIRCH_WOOD_STAIRS: 1
BLACK_GLAZED_TERRACOTTA: 1
BLACK_SHULKER_BOX: 1
BLUE_GLAZED_TERRACOTTA: 1
BLUE_SHULKER_BOX: 1
BOAT: 2
BOAT_ACACIA: 2
BOAT_BIRCH: 2
BOAT_DARK_OAK: 2
BOAT_JUNGLE: 2
BOAT_SPRUCE: 2
BONE_BLOCK: 1
BOOKSHELF: 5
BREWING_STAND: 20
BRICK: 5
BRICK_STAIRS: 5
BROWN_GLAZED_TERRACOTTA: 1
BROWN_SHULKER_BOX: 1
BURNING_FURNACE: 10
CACTUS: 1
CAKE_BLOCK: 1
CARPET: 1
CAULDRON: 10
CHEST: 2
CHORUS_FLOWER: 1
CHORUS_PLANT: 1
CLAY: 2
COAL_BLOCK: 9
COAL_ORE: 0
COBBLE_WALL: 1
COBBLESTONE: 1
COBBLESTONE_STAIRS: 1
COCOA: 1
CONCRETE: 1
CONCRETE_POWDER: 1
CYAN_GLAZED_TERRACOTTA: 1
CYAN_SHULKER_BOX: 1
DARK_OAK_DOOR: 1
DARK_OAK_FENCE: 1
DARK_OAK_FENCE_GATE: 1
DARK_OAK_STAIRS: 1
DAYLIGHT_DETECTOR: 10
DAYLIGHT_DETECTOR_INVERTED: 10
DEAD_BUSH: 1
DETECTOR_RAIL: 10
DIAMOND_BLOCK: 300
DIODE: 5
DIODE_BLOCK_OFF: 5
DIODE_BLOCK_ON: 5
DIRT: 2
DISPENSER: 5
DOUBLE_PLANT: 2
DOUBLE_STEP: 1
DOUBLE_STONE_SLAB2: 1
DRAGON_EGG: 150
DROPPER: 5
EMERALD_BLOCK: 150
EMERALD_ORE: 0
ENCHANTMENT_TABLE: 150
END_BRICKS: 2
ENDER_CHEST: 150
ENDER_PORTAL_FRAME: 0
ENDER_PORTAL: 0
ENDER_STONE: 2
EXPLOSIVE_MINECART: 10
FENCE: 1
FENCE_GATE: 1
FIRE: 0
FLOWER_POT: 5
FROSTED_ICE: 1
FURNACE: 10
GLASS: 2
GLOWSTONE: 1
GOLD_BLOCK: 150
GOLD_ORE: 0
GRASS: 5
GRASS_PATH: 5
GRAY_GLAZED_TERRACOTTA: 1
GRAY_SHULKER_BOX: 1
GRAVEL: 1
GREEN_GLAZED_TERRACOTTA: 1
GREEN_SHULKER_BOX: 1
HARD_CLAY: 2
HAY_BLOCK: 2
HOPPER: 10
HOPPER_MINECART: 20
HUGE_MUSHROOM_1: 1
HUGE_MUSHROOM_2: 1
ICE: 5
IRON_BLOCK: 10
IRON_DOOR_BLOCK: 5
IRON_FENCE: 5
IRON_ORE: 0
IRON_PLATE: 5
IRON_TRAPDOOR: 1
ITEM_FRAME: 2
JACK_O_LANTERN: 1
JUKEBOX: 10
JUNGLE_DOOR: 1
JUNGLE_FENCE: 1
JUNGLE_FENCE_GATE: 1
JUNGLE_WOOD_STAIRS: 1
LADDER: 1
LAPIS_BLOCK: 10
LAPIS_ORE: 0
LAVA: 0
LEAVES_2: 1
LEAVES: 1
LEVER: 1
LIGHT_BLUE_GLAZED_TERRACOTTA: 1
LIGHT_BLUE_SHULKER_BOX: 1
LIME_GLAZED_TERRACOTTA: 1
LIME_SHULKER_BOX: 1
LOG: 1
#Other log types - examples
#LOG:3: 2
LOG_2: 1
LONG_GRASS: 1
MAGENTA_GLAZED_TERRACOTTA: 1
MAGENTA_SHULKER_BOX: 1
MAGMA: 1
MELON_BLOCK: 1
MELON_STEM: 1
MINECART: 10
MOB_SPAWNER: 0
MOSSY_COBBLESTONE: 2
MYCEL: 5
NETHER_BRICK: 2
NETHER_BRICK_STAIRS: 2
NETHER_FENCE: 2
NETHER_STALK: 1
NETHER_WART_BLOCK: 2
NETHERRACK: 1
NOTE_BLOCK: 10
OBSERVER: 1
OBSIDIAN: 10
ORANGE_GLAZED_TERRACOTTA: 1
ORANGE_SHULKER_BOX: 1
PACKED_ICE: 5
PAINTING: 2
PINK_GLAZED_TERRACOTTA: 1
PINK_SHULKER_BOX: 1
PISTON_BASE: 2
PISTON_STICKY_BASE: 2
PORTAL: 0
POWERED_MINECART: 10
POWERED_RAIL: 10
PRISMARINE: 10
PUMPKIN_STEM: 1
PUMPKIN: 1
PURPLE_GLAZED_TERRACOTTA: 1
PURPLE_SHULKER_BOX: 1
PURPUR_BLOCK: 1
PURPUR_DOUBLE_SLAB: 1
PURPUR_PILLAR: 1
PURPUR_SLAB: 1
PURPUR_STAIRS: 1
QUARTZ_BLOCK: 1
QUARTZ_ORE: 0
QUARTZ_STAIRS: 1
QUARTZ: 1
RAILS: 1
RED_GLAZED_TERRACOTTA: 1
RED_MUSHROOM: 1
RED_NETHER_BRICK: 2
RED_ROSE: 1
RED_SANDSTONE: 1
RED_SANDSTONE_STAIRS: 1
RED_SHULKER_BOX: 1
REDSTONE_BLOCK: 10
REDSTONE_COMPARATOR_OFF: 10
REDSTONE_COMPARATOR_ON: 10
REDSTONE_COMPARATOR: 10
REDSTONE_LAMP_OFF: 10
REDSTONE_LAMP_ON: 10
REDSTONE_ORE: 0
REDSTONE_TORCH_OFF: 5
REDSTONE_TORCH_ON: 5
REDSTONE_WIRE: 1
SAND: 1
SANDSTONE: 1
SANDSTONE_STAIRS: 1
SEA_LANTERN: 1
SIGN_POST: 1
SILVER_GLAZED_TERRACOTTA: 1
SILVER_SHULKER_BOX: 1
SKULL: 10
SLIME_BLOCK: 10
SMOOTH_BRICK: 2
SMOOTH_STAIRS: 2
SNOW_BLOCK: 1
SOIL: 2
SOUL_SAND: 2
SPONGE: 10
SPRUCE_DOOR: 1
SPRUCE_FENCE: 1
SPRUCE_FENCE_GATE: 1
SPRUCE_WOOD_STAIRS: 1
STAINED_CLAY: 2
STAINED_GLASS: 2
STAINED_GLASS_PANE: 1
STATIONARY_LAVA: 0
STATIONARY_WATER: 0
STEP: 1
STONE: 1
STONE_BUTTON: 1
STONE_PLATE: 2
STORAGE_MINECART: 10
SUGAR_CANE_BLOCK: 1
THIN_GLASS: 1
TNT: 5
TORCH: 2
TRAP_DOOR: 5
TRAPPED_CHEST: 10
TRIPWIRE_HOOK: 2
TRIPWIRE: 2
VINE: 1
WALL_SIGN: 1
WATER_LILY: 5
WEB: 10
WHEAT: 1
WHITE_GLAZED_TERRACOTTA: 1
WHITE_SHULKER_BOX: 1
WOOD: 1
WOOD_BUTTON: 1
WOOD_DOOR: 1
WOOD_DOUBLE_STEP: 1
WOOD_PLATE: 1
WOOD_STAIRS: 1
WOOD_STEP: 1
WOODEN_DOOR: 1
WOOL: 1
WORKBENCH: 1
YELLOW_FLOWER: 1
YELLOW_GLAZED_TERRACOTTA: 1
YELLOW_SHULKER_BOX: 1

8
locales/bsb_en_US.yml Executable file
View File

@ -0,0 +1,8 @@
###########################################################################################
# This is a YML file. Be careful when editing. Check your edits in a YAML checker like #
# the one at http://yaml-online-parser.appspot.com #
###########################################################################################
### Credits ###
# Tastybento: maintainer

22
plugin.yml Executable file
View File

@ -0,0 +1,22 @@
name: BSkyBlock-Challenges
main: bskyblock.addin.challenges.Challenges
version: 0.1
authors: [tastybento]
depend: [BSkyBlock]
commands:
challenges:
description: Game challenges
aliases: [c, challenge]
usage: |
/challenges
permissions:
bskyblock.island.challenges:
description: Let the player use the /challenges command
default: true
bskyblock.admin.challenges:
description: Access challenge admin commands
default: op

63
pom.xml Normal file
View File

@ -0,0 +1,63 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<sourceDirectory>src</sourceDirectory>
<defaultGoal>clean package install</defaultGoal>
<resources>
<resource>
<targetPath>.</targetPath>
<filtering>true</filtering>
<directory>${basedir}</directory>
<includes>
<include>*.yml</include>
</includes>
</resource>
<resource>
<targetPath>locales</targetPath>
<filtering>false</filtering>
<directory>${basedir}/locales</directory>
<includes>
<include>*.yml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>us.tastybento</groupId>
<artifactId>bskyblock</artifactId>
<version>LATEST</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<artifactId>Challenges</artifactId>
<groupId>bskyblock.addons</groupId>
</project>

View File

@ -0,0 +1,36 @@
package bskyblock.addin.challenges;
import java.util.logging.Logger;
import org.bukkit.command.CommandSender;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.config.BSBLocale;
import us.tastybento.bskyblock.util.Util;
/**
* Makes code look nicer
* @author ben
*
*/
public abstract class AddonHelper {
protected final Challenges plugin;
protected final BSkyBlock bSkyBlock;
public AddonHelper(Challenges plugin) {
this.plugin = plugin;
this.bSkyBlock = BSkyBlock.getPlugin();
}
public final Logger getLogger() {
return plugin.getLogger();
}
public final void sendMessage(CommandSender sender, String message) {
Util.sendMessage(sender, message);
}
public final BSBLocale getLocale(CommandSender sender) {
return plugin.getLocale(sender);
}
}

View File

@ -0,0 +1,94 @@
package bskyblock.addin.challenges;
import java.util.UUID;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;
import bskyblock.addin.challenges.commands.ChallengesCommand;
import bskyblock.addin.challenges.config.LocaleManager;
import bskyblock.addin.challenges.config.PluginConfig;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.config.BSBLocale;
import us.tastybento.bskyblock.database.BSBDatabase;
import us.tastybento.bskyblock.database.flatfile.FlatFileDatabase;
/**
* Addin to BSkyBlock that enables challenges
* @author tastybento
*
*/
public class Challenges extends JavaPlugin {
private static final boolean DEBUG = true;
// The BSkyBlock plugin instance.
private BSkyBlock bSkyBlock;
// Locale manager for this plugin
private LocaleManager localeManager;
// The BSkyBlock database object
private BSBDatabase database;
private ChallengesManager manager;
private FlatFileDatabase flatFile;
@SuppressWarnings("unchecked")
@Override
public void onEnable() {
// Load the plugin's config
new PluginConfig(this);
// Get the BSkyBlock plugin. This will be available because this plugin depends on it in plugin.yml.
bSkyBlock = BSkyBlock.getPlugin();
// Check if it is enabled - it might be loaded, but not enabled.
if (bSkyBlock == null || !bSkyBlock.isEnabled()) {
this.setEnabled(false);
return;
}
// Local locales
localeManager = new LocaleManager(this);
// Challenges Manager
manager = new ChallengesManager(this);
// Register commands
new ChallengesCommand(this);
// Register Listener
getServer().getPluginManager().registerEvents(manager, this);
// Done
}
@Override
public void onDisable(){
if (manager != null)
manager.save(false);
}
/**
* Get the locale for this player
* @param sender
* @return Locale object for sender
*/
public BSBLocale getLocale(CommandSender sender) {
return localeManager.getLocale(sender);
}
/**
* Get the locale for this UUID
* @param uuid
* @return Locale object for UUID
*/
public BSBLocale getLocale(UUID uuid) {
return localeManager.getLocale(uuid);
}
public ChallengesManager getManager() {
return manager;
}
}

View File

@ -0,0 +1,257 @@
package bskyblock.addin.challenges;
import java.beans.IntrospectionException;
import java.lang.reflect.InvocationTargetException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import bskyblock.addin.challenges.database.object.ChallengesDO;
import bskyblock.addin.challenges.database.object.LevelsDO;
import bskyblock.addin.challenges.panel.Panel;
import bskyblock.addin.challenges.panel.Panel.PanelBuilder;
import bskyblock.addin.challenges.panel.Panel.PanelItem;
import us.tastybento.bskyblock.database.flatfile.FlatFileDatabase;
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
import us.tastybento.bskyblock.util.Util;
public class ChallengesManager implements Listener {
private static final boolean DEBUG = false;
private Challenges plugin;
private HashMap<UUID, Panel> challengePanels;
private AbstractDatabaseHandler<ChallengesDO> chHandler;
private HashMap<String,ChallengesDO> challenges;
private AbstractDatabaseHandler<LevelsDO> lvHandler;
private HashMap<String,LevelsDO> levels;
@SuppressWarnings("unchecked")
public ChallengesManager(Challenges plugin){
this.plugin = plugin;
// Set up the database handler to store and retrieve Challenges
chHandler = (AbstractDatabaseHandler<ChallengesDO>) new FlatFileDatabase().getHandler(plugin, ChallengesDO.class);
lvHandler = (AbstractDatabaseHandler<LevelsDO>) new FlatFileDatabase().getHandler(plugin, LevelsDO.class);
challenges = new HashMap<>();
levels = new HashMap<>();
challengePanels = new HashMap<>();
load();
}
public AbstractDatabaseHandler<ChallengesDO> getHandler() {
return chHandler;
}
/**
* Clear and reload all challenges
*/
public void load() {
levels.clear();
try {
for (LevelsDO level : lvHandler.loadObjects()) {
levels.put(level.getUniqueId(), level);
}
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | SecurityException | ClassNotFoundException | IntrospectionException
| SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
challenges.clear();
try {
for (ChallengesDO challenge : chHandler.loadObjects()) {
challenges.put(challenge.getUniqueId(), challenge);
}
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | SecurityException | ClassNotFoundException | IntrospectionException
| SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Save to the database
* @param async - if true, saving will be done async
*/
public void save(boolean async){
if(async){
Runnable save = () -> {
int index = 1;
for(ChallengesDO challenge : challenges.values()){
plugin.getLogger().info("DEBUG: saving challenges async " + index++);
try {
chHandler.saveObject(challenge);
} catch (Exception e) {
e.printStackTrace();
}
}
};
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, save);
} else {
int index = 1;
for(ChallengesDO challenge : challenges.values()){
plugin.getLogger().info("DEBUG: saving challenges sync " + index++);
try {
chHandler.saveObject(challenge);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
// Metrics-related methods //
public void shutdown(){
save(false);
challenges.clear();
}
/**
* Create a challenge from the inventory contents
* @param contents
*/
public void createChallenge(Player player, String name) {
// Get the main icon
ItemStack icon = player.getInventory().getItemInOffHand();
if (icon == null || icon.getType().equals(Material.AIR)) {
Util.sendMessage(player, "Icon will be paper");
icon = new ItemStack(Material.PAPER);
}
icon.setAmount(1);
ItemMeta meta = icon.getItemMeta();
meta.setDisplayName(name);
List<String> lore = new ArrayList<>();
lore.add("Required items:");
List<ItemStack> inv = Arrays.asList(player.getInventory().getStorageContents());
List<ItemStack> contents = new ArrayList<>();
for (ItemStack item : inv) {
if (item != null && !item.getType().equals(Material.AIR)) {
contents.add(item);
lore.add(item.getType() + " x " + item.getAmount());
}
}
if (lore.size() == 1) {
lore.add("No items");
}
meta.setDisplayName(name);
meta.setLore(lore);
icon.setItemMeta(meta);
ChallengesDO newChallenge = new ChallengesDO();
newChallenge.setRequiredItems(contents);
newChallenge.setUniqueId(name);
newChallenge.setIcon(icon);
if (chHandler.objectExits(name)) {
Util.sendMessage(player, ChatColor.RED + "Challenge already exists! Use /c replace <name>");
return;
}
try {
chHandler.saveObject(newChallenge);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException
| InstantiationException | NoSuchMethodException | IntrospectionException | SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Util.sendMessage(player, ChatColor.RED + "Challenge creation failed! " + e.getMessage());
return;
}
Util.sendMessage(player, "Challenge accepted!");
challenges.put(newChallenge.getUniqueId(), newChallenge);
}
public Inventory getChallenges(Player player) {
// TODO build the panel that is customized to the player
// Build panel
PanelBuilder panelBuilder = Panel.builder(plugin)
.name(plugin.getLocale(player).get("challenges.guiTitle"));
for (ChallengesDO challenge: challenges.values()) {
plugin.getLogger().info("Adding challenge " + challenge.getUniqueId());
PanelItem item = Panel.panelItemBuilder()
.setIcon(challenge.getIcon())
.setName(challenge.getFriendlyName().isEmpty() ? challenge.getUniqueId() : challenge.getFriendlyName())
.setDescription(challenge.getDescription())
.setSlot(challenge.getSlot())
.build();
plugin.getLogger().info("requested slot" + item.getSlot());
panelBuilder.addItem(item);
}
Panel panel = panelBuilder.build();
challengePanels.put(player.getUniqueId(), panel);
plugin.getLogger().info("DEBUG: added inv " + challengePanels.size());
return panel.getPanel();
}
@EventHandler(priority = EventPriority.LOWEST)
public void onInventoryClick(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked(); // The player that
// clicked the item
UUID playerUUID = player.getUniqueId();
Inventory inventory = event.getInventory(); // The inventory that was
// clicked in
// Check this is the right panel
if (inventory.getName() == null || !inventory.getName().equals(plugin.getLocale(player).get("challenges.guiTitle"))) {
return;
}
event.setCancelled(true);
if (!event.getClick().equals(ClickType.LEFT)) {
inventory.clear();
player.closeInventory();
player.updateInventory();
return;
}
int slot = event.getRawSlot();
if (slot == -999) {
inventory.clear();
player.closeInventory();
event.setCancelled(true);
return;
}
// TODO: Deal with the clicking
}
@EventHandler(priority = EventPriority.LOWEST)
public void onInventoryClose(InventoryCloseEvent event) {
challengePanels.remove(event.getPlayer().getUniqueId());
plugin.getLogger().info("DEBUG: removing inv " + challengePanels.size());
}
/**
* Clean up the hashmap should the player open up another inventory
* @param event
*/
@EventHandler(priority = EventPriority.LOWEST)
public void onInventoryOpen(InventoryOpenEvent event) {
Player player = (Player) event.getPlayer();
UUID playerUUID = player.getUniqueId();
Inventory inventory = event.getInventory(); // The inventory that was
if (inventory.getName() == null || !inventory.getName().equals(plugin.getLocale(player).get("challenges.guiTitle"))) {
challengePanels.remove(playerUUID);
plugin.getLogger().info("DEBUG: removing inv " + challengePanels.size());
}
}
@EventHandler(priority = EventPriority.NORMAL)
public void onLogOut(PlayerQuitEvent event) {
challengePanels.remove(event.getPlayer().getUniqueId());
plugin.getLogger().info("DEBUG: removing inv " + challengePanels.size());
}
}

View File

@ -0,0 +1,86 @@
package bskyblock.addin.challenges.commands;
import java.util.Set;
import java.util.UUID;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import bskyblock.addin.challenges.Challenges;
import us.tastybento.bskyblock.api.commands.AbstractCommand;
import us.tastybento.bskyblock.api.commands.ArgumentHandler;
import us.tastybento.bskyblock.api.commands.CanUseResp;
import us.tastybento.bskyblock.config.Settings;
import us.tastybento.bskyblock.util.VaultHelper;
public class ChallengesCommand extends AbstractCommand implements Listener {
private static final String CHALLENGE_COMMAND = "challenges";
private Challenges plugin;
public ChallengesCommand(Challenges plugin) {
super(CHALLENGE_COMMAND, new String[]{"c", "challenge"}, true);
plugin.getCommand(CHALLENGE_COMMAND).setExecutor(this);
plugin.getCommand(CHALLENGE_COMMAND).setTabCompleter(this);
this.plugin = plugin;
}
@Override
public CanUseResp canUse(CommandSender sender) {
if (!(sender instanceof Player)) {
return new CanUseResp(getLocale(sender).get("general.errors.use-in-game"));
}
// Basic permission check to use /challenges
if (!VaultHelper.hasPerm(player, Settings.PERMPREFIX + "island.challenges")) {
return new CanUseResp(getLocale(sender).get("general.errors.no-permission"));
}
return new CanUseResp(true);
}
@Override
public void execute(CommandSender sender, String[] args) {
// Open up the challenges GUI
if (isPlayer) {
player.openInventory(plugin.getManager().getChallenges(player));
} else {
// TODO
}
}
@Override
public void setup() {
addArgument(new ArgumentHandler(label) {
@Override
public CanUseResp canUse(CommandSender sender) {
return new CanUseResp(true);
}
@Override
public void execute(CommandSender sender, String[] args) {
// Create a copy of items in the player's main inventory
Player player = (Player)sender;
String name = UUID.randomUUID().toString();
if (args.length > 0) {
name = args[0];
}
plugin.getManager().createChallenge(player, name);
}
@Override
public Set<String> tabComplete(CommandSender sender, String[] args) {
return null;
}
@Override
public String[] usage(CommandSender sender) {
return new String[] {null, "Make a challenge from the items in your inventory"};
}
}.alias("make"));
}
}

View File

@ -0,0 +1,28 @@
package bskyblock.addin.challenges.config;
import java.util.UUID;
import bskyblock.addin.challenges.Challenges;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.config.AbstractLocaleManager;
import us.tastybento.bskyblock.config.BSBLocale;
import us.tastybento.bskyblock.config.Settings;
public class LocaleManager extends AbstractLocaleManager {
public LocaleManager(Challenges plugin) {
super(plugin);
}
@Override
public BSBLocale getLocale(UUID player) {
//getLogger().info("DEBUG: " + player);
//getLogger().info("DEBUG: " + getPlayers() == null ? "Players is null":"Players in not null");
//getLogger().info("DEBUG: " + getPlayers().getPlayer(player));
//getLogger().info("DEBUG: " + getPlayers().getPlayer(player).getLocale());
String locale = BSkyBlock.getPlugin().getPlayers().getPlayer(player).getLocale();
if(locale.isEmpty() || !getLocales().containsKey(locale)) return getLocales().get(Settings.defaultLanguage);
return getLocales().get(locale);
}
}

View File

@ -0,0 +1,95 @@
package bskyblock.addin.challenges.config;
import java.util.HashMap;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Material;
import org.bukkit.material.MaterialData;
import bskyblock.addin.challenges.Challenges;
public class PluginConfig {
private static final boolean DEBUG = false;
/**
* Loads the various settings from the config.yml file into the plugin
*/
public PluginConfig(Challenges plugin) {
plugin.saveDefaultConfig();
// Island level cool down time
Settings.levelWait = plugin.getConfig().getInt("levelwait", 60);
if (Settings.levelWait < 0) {
Settings.levelWait = 0;
}
// Get the under water multiplier
Settings.deathpenalty = plugin.getConfig().getInt("deathpenalty", 0);
Settings.sumTeamDeaths = plugin.getConfig().getBoolean("sumteamdeaths");
Settings.maxDeaths = plugin.getConfig().getInt("maxdeaths", 10);
Settings.islandResetDeathReset = plugin.getConfig().getBoolean("islandresetdeathreset", true);
Settings.teamJoinDeathReset = plugin.getConfig().getBoolean("teamjoindeathreset", true);
Settings.underWaterMultiplier = plugin.getConfig().getDouble("underwater", 1D);
Settings.levelCost = plugin.getConfig().getInt("levelcost", 100);
if (Settings.levelCost < 1) {
Settings.levelCost = 1;
plugin.getLogger().warning("levelcost in blockvalues.yml cannot be less than 1. Setting to 1.");
}
Settings.blockLimits = new HashMap<MaterialData, Integer>();
if (plugin.getConfig().isSet("limits")) {
for (String material : plugin.getConfig().getConfigurationSection("limits").getKeys(false)) {
try {
String[] split = material.split(":");
byte data = 0;
if (split.length>1) {
data = Byte.valueOf(split[1]);
}
Material mat;
if (StringUtils.isNumeric(split[0])) {
mat = Material.getMaterial(Integer.parseInt(split[0]));
} else {
mat = Material.valueOf(split[0].toUpperCase());
}
MaterialData materialData = new MaterialData(mat);
materialData.setData(data);
Settings.blockLimits.put(materialData, plugin.getConfig().getInt("limits." + material, 0));
if (DEBUG) {
plugin.getLogger().info("Maximum number of " + materialData + " will be " + Settings.blockLimits.get(materialData));
}
} catch (Exception e) {
plugin.getLogger().warning("Unknown material (" + material + ") in blockvalues.yml Limits section. Skipping...");
}
}
}
Settings.blockValues = new HashMap<MaterialData, Integer>();
if (plugin.getConfig().isSet("blocks")) {
for (String material : plugin.getConfig().getConfigurationSection("blocks").getKeys(false)) {
try {
String[] split = material.split(":");
byte data = 0;
if (split.length>1) {
data = Byte.valueOf(split[1]);
}
MaterialData materialData = null;
if (StringUtils.isNumeric(split[0])) {
materialData = new MaterialData(Integer.parseInt(split[0]));
} else {
materialData = new MaterialData(Material.valueOf(split[0].toUpperCase()));
}
materialData.setData(data);
Settings.blockValues.put(materialData, plugin.getConfig().getInt("blocks." + material, 0));
if (DEBUG) {
plugin.getLogger().info(materialData.toString() + " value = " + Settings.blockValues.get(materialData));
}
} catch (Exception e) {
// e.printStackTrace();
plugin.getLogger().warning("Unknown material (" + material + ") in blockvalues.yml blocks section. Skipping...");
}
}
} else {
plugin.getLogger().severe("No block values in blockvalues.yml! All island levels will be zero!");
}
// All done
}
}

View File

@ -0,0 +1,22 @@
package bskyblock.addin.challenges.config;
import java.util.HashMap;
import org.bukkit.material.MaterialData;
public class Settings {
public static boolean sumTeamDeaths;
public static int seaHeight;
public static HashMap<MaterialData, Integer> blockLimits;
public static HashMap<MaterialData, Integer> blockValues;
public static double underWaterMultiplier;
public static int deathpenalty;
public static long levelCost;
public static Object defaultLanguage;
public static int levelWait;
public static int maxDeaths;
public static boolean islandResetDeathReset;
public static boolean teamJoinDeathReset;
}

View File

@ -0,0 +1,401 @@
package bskyblock.addin.challenges.database.object;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import us.tastybento.bskyblock.database.objects.DataObject;
public class ChallengesDO extends DataObject {
enum ChallengeType {
/**
* This challenge only shows and icon in the GUI and doesn't do anything.
*/
ICON,
/**
* The player must have the items on them.
*/
INVENTORY,
/**
* The island level has to be equal or over this amount. Only works if there's an island level plugin installed.
*/
LEVEL,
/**
* Items or required entities have to be within x blocks of the player.
*/
SURROUNDING
}
/**
* Type of challenge
*/
private ChallengeType challengeType;
/**
* Whether this challenge is deployed or not
*/
private boolean deployed;
/**
* Description of the challenge. Will become the lore on the icon. Can include color codes.
*/
private String description = "";
/**
* Experience point reward
*/
private long expReward;
/**
* This challenge can be completed at any time
*/
private boolean freeChallenge;
/**
* Name of the icon and challenge. May include color codes.
*/
private String friendlyName = "";
/**
* The icon in the GUI for this challenge
*/
private ItemStack icon = new ItemStack(Material.PAPER);
/**
* The challenge level, e.g. Novice, Expert, etc.
* Levels are completed in order
*/
private String level = "Novice";
/**
* Maximum number of times the challenge can be repeated
*/
private long maxTimes = 1;
/**
* Money reward
*/
private long moneyReward;
/**
* If true, the challenge will disappear from the GUI when completed
*/
private boolean removeWhenCompleted;
/**
* True if the challenge is repeatable
*/
private boolean repeatable;
/**
* Repeat exp award
*/
private long repeatExpReward;
/**
* Reward items for repeating the challenge
*/
private List<ItemStack> repeatItemReward = new ArrayList<>();
/**
* Repeat money award
*/
private long repeatMoneyReward;
/**
* Commands to run when challenge is repeated
*/
private List<String> repeatrewardcommands = new ArrayList<>();
/**
* Description of the repeat rewards. If blank, it will be autogenerated.
*/
private String repeatRewardText = "";
/**
* Minimum amount of player experience
*/
private long reqExp;
/**
* Require level for this challenge.
*/
private long reqIslandlevel;
/**
* Minimum amount of money required
*/
private long reqMoney;
/**
* The required permissions to see this challenge
*/
private Set<String> reqPerms = new HashSet<>();
/**
* The items that must be in the inventory to complete the challenge.
*/
private List<ItemStack> requiredItems = new ArrayList<>();
/**
* Commands to run when the player completes the challenge for the first time
*/
private List<String> rewardCommands = new ArrayList<>();
/**
* List of items the player will receive first time
*/
private List<ItemStack> rewardItems = new ArrayList<>();
/**
* If this is blank, the reward text will be auto-generated, otherwise this will be used.
*/
private String rewardText = "";
/**
* The number of blocks around the player to search for items on an island
*/
private int searchRadius = 10;
/**
* Inventory slot where this challenge should be placed. 0 to 49.
*
*/
private int slot;
/**
* Take the required items from the player
*/
private boolean takeItems = true;
/**
* Take the money from the player
*/
private boolean takeMoney = false;
/**
* Unique name of the challenge
*/
private String uniqueId = "";
public ChallengeType getChallengeType() {
return challengeType;
}
public String getDescription() {
return description;
}
public long getExpReward() {
return expReward;
}
public String getFriendlyName() {
return friendlyName;
}
public ItemStack getIcon() {
return icon;
}
public String getLevel() {
return level;
}
public long getMaxTimes() {
return maxTimes;
}
public long getMoneyReward() {
return moneyReward;
}
public long getRepeatExpReward() {
return repeatExpReward;
}
public List<ItemStack> getRepeatItemReward() {
return repeatItemReward;
}
public long getRepeatMoneyReward() {
return repeatMoneyReward;
}
public List<String> getRepeatrewardcommands() {
return repeatrewardcommands;
}
public String getRepeatRewardText() {
return repeatRewardText;
}
public long getReqExp() {
return reqExp;
}
public long getReqIslandlevel() {
return reqIslandlevel;
}
public long getReqMoney() {
return reqMoney;
}
public Set<String> getReqPerms() {
return reqPerms;
}
public List<ItemStack> getRequiredItems() {
return requiredItems;
}
public List<String> getRewardCommands() {
return rewardCommands;
}
public List<ItemStack> getRewardItems() {
return rewardItems;
}
public String getRewardText() {
return rewardText;
}
public int getSearchRadius() {
return searchRadius;
}
public int getSlot() {
return slot;
}
@Override
public String getUniqueId() {
return uniqueId;
}
public boolean isDeployed() {
return deployed;
}
public boolean isFreeChallenge() {
return freeChallenge;
}
public boolean isRemoveWhenCompleted() {
return removeWhenCompleted;
}
public boolean isRepeatable() {
return repeatable;
}
public boolean isTakeItems() {
return takeItems;
}
public boolean isTakeMoney() {
return takeMoney;
}
public void setChallengeType(ChallengeType challengeType) {
this.challengeType = challengeType;
}
public void setDeployed(boolean deployed) {
this.deployed = deployed;
}
public void setDescription(String description) {
this.description = description;
}
public void setExpReward(long expReward) {
this.expReward = expReward;
}
public void setFreeChallenge(boolean freeChallenge) {
this.freeChallenge = freeChallenge;
}
public void setFriendlyName(String friendlyName) {
this.friendlyName = friendlyName;
}
public void setIcon(ItemStack icon) {
this.icon = icon;
}
public void setLevel(String level) {
this.level = level;
}
public void setMaxTimes(long maxTimes) {
this.maxTimes = maxTimes;
}
public void setMoneyReward(long moneyReward) {
this.moneyReward = moneyReward;
}
public void setRemoveWhenCompleted(boolean removeWhenCompleted) {
this.removeWhenCompleted = removeWhenCompleted;
}
public void setRepeatable(boolean repeatable) {
this.repeatable = repeatable;
}
public void setRepeatExpReward(long repeatExpReward) {
this.repeatExpReward = repeatExpReward;
}
public void setRepeatItemReward(List<ItemStack> repeatItemReward) {
this.repeatItemReward = repeatItemReward;
}
public void setRepeatMoneyReward(long repeatMoneyReward) {
this.repeatMoneyReward = repeatMoneyReward;
}
public void setRepeatrewardcommands(List<String> repeatrewardcommands) {
this.repeatrewardcommands = repeatrewardcommands;
}
public void setRepeatRewardText(String repeatRewardText) {
this.repeatRewardText = repeatRewardText;
}
public void setReqExp(long reqExp) {
this.reqExp = reqExp;
}
public void setReqIslandlevel(long reqIslandlevel) {
this.reqIslandlevel = reqIslandlevel;
}
public void setReqMoney(long reqMoney) {
this.reqMoney = reqMoney;
}
public void setReqPerms(Set<String> reqPerms) {
this.reqPerms = reqPerms;
}
public void setRequiredItems(List<ItemStack> requiredItems) {
this.requiredItems = requiredItems;
}
public void setRewardCommands(List<String> rewardCommands) {
this.rewardCommands = rewardCommands;
}
public void setRewardItems(List<ItemStack> rewardItems) {
this.rewardItems = rewardItems;
}
public void setRewardText(String rewardText) {
this.rewardText = rewardText;
}
public void setSearchRadius(int searchRadius) {
this.searchRadius = searchRadius;
}
public void setSlot(int slot) {
this.slot = slot;
}
public void setTakeItems(boolean takeItems) {
this.takeItems = takeItems;
}
public void setTakeMoney(boolean takeMoney) {
this.takeMoney = takeMoney;
}
@Override
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
}
}

View File

@ -0,0 +1,61 @@
package bskyblock.addin.challenges.database.object;
import java.util.ArrayList;
import java.util.List;
import us.tastybento.bskyblock.database.objects.DataObject;
public class LevelsDO extends DataObject {
/**
* A friendly name for the level. If blank, level name is used.
*/
private String friendlyName = "";
/**
* Commands to run when this level is completed
*/
private List<String> rewardCommands = new ArrayList<>();
/**
* Level name
*/
private String uniqueId = "";
/**
* The number of undone challenges that can be left on this level before unlocking next level
*/
private int waiveramount = 1;
public String getFriendlyName() {
return friendlyName;
}
public List<String> getRewardCommands() {
return rewardCommands;
}
@Override
public String getUniqueId() {
return uniqueId;
}
public int getWaiveramount() {
return waiveramount;
}
public void setFriendlyName(String friendlyName) {
this.friendlyName = friendlyName;
}
public void setRewardCommands(List<String> rewardCommands) {
this.rewardCommands = rewardCommands;
}
@Override
public void setUniqueId(String uniqueId) {
this.uniqueId = uniqueId;
}
public void setWaiveramount(int waiveramount) {
this.waiveramount = waiveramount;
}
}

View File

@ -0,0 +1,202 @@
package bskyblock.addin.challenges.panel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
public class Panel {
private final Inventory gui;
private final TreeMap<Integer, PanelItem> panelItems;
public Panel(Plugin plugin, String name, TreeMap<Integer, PanelItem> panelItems) {
// Generate gui
this.panelItems = panelItems;
// Create the panel
if (panelItems.lastKey() > 0) {
// Make sure size is a multiple of 9
int size = panelItems.lastKey() + 8;
size -= (size % 9);
gui = Bukkit.createInventory(null, size, name);
// Fill the inventory and return
for (Entry<Integer, PanelItem> en: panelItems.entrySet()) {
gui.setItem(en.getKey(), en.getValue().getIcon());
}
} else {
gui = Bukkit.createInventory(null, 9, name);
}
}
public TreeMap<Integer, PanelItem> getPanelItems() {
return panelItems;
}
public Inventory getPanel() {
return gui;
}
public static PanelBuilder builder(Plugin plugin) {
return new PanelBuilder(plugin);
}
public static class PanelBuilder {
private TreeMap<Integer,PanelItem> panelItems = new TreeMap<>();
private String name;
private Plugin plugin;
public PanelBuilder(Plugin plugin) {
this.plugin = plugin;
}
public PanelBuilder addItem(PanelItem item) {
// Fit into slots. Handle duplicates
int index = item.getSlot();
while (panelItems.containsKey(index) || index == 49) {
index++;
};
panelItems.put(index, item);
Bukkit.getLogger().info("DEBUG: added to slot " + index);
return this;
}
public PanelBuilder name(String name) {
this.name = name;
return this;
}
public Panel build() {
return new Panel(plugin, name, panelItems);
}
}
public static PanelItemBuilder panelItemBuilder() {
return new PanelItemBuilder();
}
public static class PanelItem {
private final Integer slot;
// The current index of the icon
private int index = 0;
// There is a list of icons for every toggle option
private final List<ItemStack> icon;
public PanelItem(ItemStack icon, String description, String name, Integer slot, List<String> toggleItems, boolean glow) {
this.slot = slot;
List<ItemStack> result = new ArrayList<>();
if (toggleItems.isEmpty()) {
// Create the icon
ItemMeta meta = icon.getItemMeta();
meta.setDisplayName(name);
meta.setLore(chop(description));
// Set flags to neaten up the view
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
meta.addItemFlags(ItemFlag.HIDE_DESTROYS);
meta.addItemFlags(ItemFlag.HIDE_PLACED_ON);
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
if (glow) {
meta.addEnchant(Enchantment.ARROW_DAMAGE, 0, true);
}
icon.setItemMeta(meta);
result.add(icon);
} else {
for (int i = 0; i < toggleItems.size(); i++) {
// Create the icon(s)
ItemMeta meta = icon.getItemMeta();
meta.setDisplayName(name);
List<String> desc = chop(description);
desc.addAll(chop(toggleItems.get(i)));
meta.setLore(desc);
// Set flags to neaten up the view
meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
meta.addItemFlags(ItemFlag.HIDE_DESTROYS);
meta.addItemFlags(ItemFlag.HIDE_PLACED_ON);
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
if (glow) {
meta.addEnchant(Enchantment.ARROW_DAMAGE, 0, true);
}
icon.setItemMeta(meta);
result.add(icon);
}
}
this.icon = result;
}
public ItemStack getIcon() {
return icon.get(index);
}
public ItemStack toggleIcon() {
if (icon.size() < (index + 1)) {
index++;
} else {
index = 0;
}
return icon.get(index);
}
public Integer getSlot() {
return slot;
}
}
public static class PanelItemBuilder {
private ItemStack icon;
private String description;
private String name;
private Integer slot;
private List<String> toggleItems = new ArrayList<>();
private boolean glow;
public PanelItemBuilder setIcon(ItemStack icon) {
this.icon = icon;
return this;
}
public PanelItemBuilder setDescription(String description) {
this.description = description;
return this;
}
public PanelItemBuilder setName(String name) {
this.name = name;
return this;
}
public PanelItemBuilder setSlot(Integer slot) {
this.slot = slot;
return this;
}
public PanelItemBuilder setToggleItems(List<String> toggleItems) {
this.toggleItems = toggleItems;
return this;
}
public PanelItemBuilder setGlow(boolean glow) {
this.glow = glow;
return this;
}
public PanelItem build() {
return new PanelItem(icon, description, name, slot, toggleItems, glow);
}
}
private static List<String> chop(String longLine) {
longLine = ChatColor.translateAlternateColorCodes('&', longLine);
// Split pip character requires escaping it
String[] split = longLine.split("\\|");
return new ArrayList<String>(Arrays.asList(split));
}
}