Merge branch 'feature/gem-hunters' into develop

This commit is contained in:
cnr 2017-02-25 00:40:05 -06:00
commit 699845d6d7
126 changed files with 11261 additions and 1042 deletions

View File

@ -1,40 +1,40 @@
<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>
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>
<parent>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-parent</artifactId>
<version>dev-SNAPSHOT</version>
</parent>
<parent>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-parent</artifactId>
<version>dev-SNAPSHOT</version>
</parent>
<artifactId>mineplex-core-common</artifactId>
<artifactId>mineplex-core-common</artifactId>
<dependencies>
<dependency>
<groupId>com.mineplex</groupId>
<artifactId>spigot</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-serverdata</artifactId>
<version>dev-SNAPSHOT</version>
</dependency>
</dependencies>
<dependencies>
<dependency>
<groupId>com.mineplex</groupId>
<artifactId>spigot</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-serverdata</artifactId>
<version>dev-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory/>
<includes>
<include>ascii.png</include>
</includes>
</resource>
</resources>
</build>
<build>
<resources>
<resource>
<directory />
<includes>
<include>ascii.png</include>
</includes>
</resource>
</resources>
</build>
</project>

View File

@ -4,18 +4,9 @@ import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import net.minecraft.server.v1_8_R3.BlockPosition;
import net.minecraft.server.v1_8_R3.Blocks;
import net.minecraft.server.v1_8_R3.IBlockData;
import net.minecraft.server.v1_8_R3.Item;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MinecraftKey;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.TileEntityFlowerPot;
import net.minecraft.server.v1_8_R3.WorldServer;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.SkullType;
@ -41,8 +32,18 @@ import org.bukkit.material.Bed;
import com.mojang.authlib.GameProfile;
import mineplex.core.common.Pair;
import mineplex.core.common.block.MultiBlockUpdaterAgent;
import mineplex.core.common.skin.SkinData;
import net.minecraft.server.v1_8_R3.BlockPosition;
import net.minecraft.server.v1_8_R3.Blocks;
import net.minecraft.server.v1_8_R3.IBlockData;
import net.minecraft.server.v1_8_R3.Item;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.MinecraftKey;
import net.minecraft.server.v1_8_R3.NBTTagCompound;
import net.minecraft.server.v1_8_R3.TileEntityFlowerPot;
import net.minecraft.server.v1_8_R3.WorldServer;
public class UtilBlock
{
@ -1670,4 +1671,38 @@ public class UtilBlock
return null;
}
/**
* Returns a {@link Set} containing all the relevant data regarding beacon construction.
* Useful for adding them to block restore.
*
* @param surface
* The Location of the glass coloured block (at surface level). The beacon is placed one block below this.
* @param glassData
* The colour data value of glass that colours the beacon
*/
public static Set<Pair<Location, Pair<Material, Byte>>> getBeaconBlocks(Location surface, byte glassData)
{
Set<Pair<Location, Pair<Material, Byte>>> blocks = new HashSet<>();
for (int x = -1; x <= 1; x++)
{
for (int z = -1; z <= 1; z++)
{
blocks.add(Pair.create(surface.clone().add(x, -3, z), Pair.create(Material.IRON_BLOCK, (byte) 0)));
if (x == 0 && z == 0)
{
continue;
}
blocks.add(Pair.create(surface.clone().add(x, -1, z), Pair.create(Material.QUARTZ_BLOCK, (byte) 0)));
}
}
blocks.add(Pair.create(surface.clone().add(0, -2, 0), Pair.create(Material.BEACON, (byte) 0)));
blocks.add(Pair.create(surface.clone().add(0, -1, 0), Pair.create(Material.STAINED_GLASS, glassData)));
return blocks;
}
}

View File

@ -447,6 +447,21 @@ public class UtilInv
return false;
}
public static boolean hasSpace(Player player, int slots)
{
int slotsFree = 0;
for (int slot = 0; slot < player.getInventory().getSize(); slot++)
{
if (player.getInventory().getItem(slot) == null)
{
slotsFree++;
}
}
return slotsFree >= slots;
}
public static void give(Player player, Material material)
{

View File

@ -12,7 +12,6 @@ import com.google.common.collect.ImmutableSet;
import mineplex.core.MiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.bonuses.BonusManager;
import mineplex.core.common.Rank;
import mineplex.core.powerplayclub.PowerPlayClubRepository;
@ -44,11 +43,11 @@ public class BetaWhitelist extends MiniPlugin
private final CoreClientManager _clientManager;
private final PowerPlayClubRepository _powerPlayClubRepository;
public BetaWhitelist(BonusManager manager)
public BetaWhitelist(CoreClientManager clientManager, PowerPlayClubRepository powerPlayRepository)
{
super("Beta Whitelist");
_clientManager = manager.getClientManager();
_powerPlayClubRepository = manager.getPowerPlayClubRepository();
_clientManager = clientManager;
_powerPlayClubRepository = powerPlayRepository;
}
@EventHandler
@ -56,7 +55,7 @@ public class BetaWhitelist extends MiniPlugin
{
Player player = event.getPlayer();
Rank rank = _clientManager.Get(player).GetRank(true);
if ((rank != Rank.MAPDEV && rank != Rank.MAPLEAD && rank.has(Rank.TWITCH) // If this player is Twitch+ (and not a builder),
if ((rank != Rank.MAPDEV && rank != Rank.MAPLEAD && rank.has(Rank.ETERNAL) // If this player is Eternal+ (and not a builder),
|| _powerPlayClubRepository.getCachedData(player).isSubscribed()) // a PPC subscriber,
|| EXTRA_PLAYERS.contains(player.getUniqueId())) // or explicitly whitelisted,
{

View File

@ -18,22 +18,23 @@ import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilMath;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@ReflectivelyCreateMiniPlugin
public class BlockRestore extends MiniPlugin
{
private HashMap<Block, BlockRestoreData> _blocks = new HashMap<Block, BlockRestoreData>();
private LinkedList<BlockRestoreMap> _restoreMaps;
public BlockRestore(JavaPlugin plugin)
private BlockRestore()
{
super("Block Restore", plugin);
super("Block Restore");
_restoreMaps = new LinkedList<BlockRestoreMap>();
}

View File

@ -1,47 +1,47 @@
package mineplex.core.communities.commands;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.communities.Community;
import mineplex.core.communities.Community.PrivacySetting;
import mineplex.core.communities.CommunityManager;
public class CommunityJoinCommand extends CommandBase<CommunityManager>
{
public CommunityJoinCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "join");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.help("/com join <community>", "Joins a community that is open or you have been invited to", Rank.ALL, ChatColor.AQUA));
return;
}
Community c = Plugin.getLoadedCommunity(args[0]);
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (c.getMembers().containsKey(caller.getUniqueId()))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are already in " + F.name(c.getName()) + "!"));
return;
}
if (c.getPrivacySetting() != PrivacySetting.OPEN && !Plugin.Get(caller).Invites.contains(c.getId()))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are have not been invited to " + F.name(c.getName()) + "!"));
return;
}
Plugin.handleJoin(caller, c, Plugin.Get(caller).Invites.contains(c.getId()));
}
package mineplex.core.communities.commands;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.communities.Community;
import mineplex.core.communities.Community.PrivacySetting;
import mineplex.core.communities.CommunityManager;
public class CommunityJoinCommand extends CommandBase<CommunityManager>
{
public CommunityJoinCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "join");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.help("/com join <community>", "Joins a community that is open or you have been invited to", Rank.ALL, ChatColor.AQUA));
return;
}
Community c = Plugin.getLoadedCommunity(args[0]);
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (c.getMembers().containsKey(caller.getUniqueId()))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are already in " + F.name(c.getName()) + "!"));
return;
}
if (c.getPrivacySetting() != PrivacySetting.OPEN && !Plugin.Get(caller).Invites.contains(c.getId()))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are have not been invited to " + F.name(c.getName()) + "!"));
return;
}
Plugin.handleJoin(caller, c, Plugin.Get(caller).Invites.contains(c.getId()));
}
}

View File

@ -1,50 +1,50 @@
package mineplex.core.communities.commands;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.communities.Community;
import mineplex.core.communities.CommunityManager;
import mineplex.core.communities.CommunityMemberInfo;
import mineplex.core.communities.CommunityRole;
import mineplex.core.personalServer.PersonalServerManager;
public class CommunityMCSCommand extends CommandBase<CommunityManager>
{
public CommunityMCSCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "mcs");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.help("/com mcs <community>", "Opens the Mineplex Community Server of a community you manage", Rank.ALL, ChatColor.AQUA));
return;
}
Community c = Plugin.getLoadedCommunity(args[0]);
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (c.getMembers().getOrDefault(caller.getUniqueId(), new CommunityMemberInfo(caller.getName(), caller.getUniqueId(), -1, CommunityRole.MEMBER, -1L)).Role.ordinal() > CommunityRole.COLEADER.ordinal())
{
if (!Managers.get(CoreClientManager.class).Get(caller).GetRank().has(Rank.ADMIN))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are not a co-leader of " + F.name(c.getName()) + "!"));
return;
}
}
Managers.get(PersonalServerManager.class).hostCommunityServer(caller, c);
}
package mineplex.core.communities.commands;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.communities.Community;
import mineplex.core.communities.CommunityManager;
import mineplex.core.communities.CommunityMemberInfo;
import mineplex.core.communities.CommunityRole;
import mineplex.core.personalServer.PersonalServerManager;
public class CommunityMCSCommand extends CommandBase<CommunityManager>
{
public CommunityMCSCommand(CommunityManager plugin)
{
super(plugin, Rank.ALL, "mcs");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 1)
{
UtilPlayer.message(caller, F.help("/com mcs <community>", "Opens the Mineplex Community Server of a community you manage", Rank.ALL, ChatColor.AQUA));
return;
}
Community c = Plugin.getLoadedCommunity(args[0]);
if (c == null)
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "That community was not found!"));
return;
}
if (c.getMembers().getOrDefault(caller.getUniqueId(), new CommunityMemberInfo(caller.getName(), caller.getUniqueId(), -1, CommunityRole.MEMBER, -1L)).Role.ordinal() > CommunityRole.COLEADER.ordinal())
{
if (!Managers.get(CoreClientManager.class).Get(caller).GetRank().has(Rank.ADMIN))
{
UtilPlayer.message(caller, F.main(Plugin.getName(), "You are not a co-leader of " + F.name(c.getName()) + "!"));
return;
}
}
Managers.get(PersonalServerManager.class).hostCommunityServer(caller, c);
}
}

View File

@ -1,50 +1,50 @@
package mineplex.core.communities.mcs;
import org.bukkit.Material;
import mineplex.core.common.util.C;
public enum MCSTheme
{
CANDYLAND(1, C.cPurple + "Candyland", Material.COOKIE, 1000, "Lobby_MPS_Candyland.zip")
;
private final int _id;
private final String _displayName, _file;
private final Material _displayType;
private final int _cost;
private MCSTheme(int id, String displayName, Material displayType, int cost, String file)
{
_id = id;
_displayName = displayName;
_displayType = displayType;
_cost = cost;
_file = file;
}
public int getId()
{
return _id;
}
public String getDisplayName()
{
return _displayName;
}
public Material getDisplayType()
{
return _displayType;
}
public int getCost()
{
return _cost;
}
public String getFile()
{
return _file;
}
package mineplex.core.communities.mcs;
import org.bukkit.Material;
import mineplex.core.common.util.C;
public enum MCSTheme
{
CANDYLAND(1, C.cPurple + "Candyland", Material.COOKIE, 1000, "Lobby_MPS_Candyland.zip")
;
private final int _id;
private final String _displayName, _file;
private final Material _displayType;
private final int _cost;
private MCSTheme(int id, String displayName, Material displayType, int cost, String file)
{
_id = id;
_displayName = displayName;
_displayType = displayType;
_cost = cost;
_file = file;
}
public int getId()
{
return _id;
}
public String getDisplayName()
{
return _displayName;
}
public Material getDisplayType()
{
return _displayType;
}
public int getCost()
{
return _cost;
}
public String getFile()
{
return _file;
}
}

View File

@ -1,26 +1,26 @@
package mineplex.core.communities.redis;
import mineplex.core.communities.CommunityManager;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.PlayerJoinCommand;
import mineplex.serverdata.commands.ServerCommand;
public class PlayerJoinHandler implements CommandCallback
{
private CommunityManager _communityManager;
public PlayerJoinHandler(CommunityManager communityManager)
{
_communityManager = communityManager;
}
@Override
public void run(ServerCommand command)
{
if (command instanceof PlayerJoinCommand)
{
PlayerJoinCommand joinCommand = (PlayerJoinCommand)command;
//_communityManager.updateAllMemberData(UUID.fromString(joinCommand.getUuid()), joinCommand.getName());
}
}
package mineplex.core.communities.redis;
import mineplex.core.communities.CommunityManager;
import mineplex.serverdata.commands.CommandCallback;
import mineplex.serverdata.commands.PlayerJoinCommand;
import mineplex.serverdata.commands.ServerCommand;
public class PlayerJoinHandler implements CommandCallback
{
private CommunityManager _communityManager;
public PlayerJoinHandler(CommunityManager communityManager)
{
_communityManager = communityManager;
}
@Override
public void run(ServerCommand command)
{
if (command instanceof PlayerJoinCommand)
{
PlayerJoinCommand joinCommand = (PlayerJoinCommand)command;
//_communityManager.updateAllMemberData(UUID.fromString(joinCommand.getUuid()), joinCommand.getName());
}
}
}

View File

@ -242,6 +242,11 @@ public class CosmeticManager extends MiniPlugin
{
return _boosterManager;
}
public void displayUI(Player player)
{
_shop.attemptShopOpen(player);
}
public void disableTeamArmor()
{

View File

@ -1,21 +1,21 @@
package mineplex.core.cosmetic.ui.button.open;
import org.bukkit.entity.Player;
import mineplex.core.cosmetic.ui.page.Menu;
import mineplex.core.cosmetic.ui.page.TauntPage;
import mineplex.core.gadget.types.Gadget;
public class OpenTaunts extends OpenPageButton
{
public OpenTaunts(Menu menu, Gadget active)
{
super(menu, active);
}
@Override
protected void leftClick(Player player)
{
getMenu().getShop().openPageForPlayer(player, new TauntPage(getMenu().getPlugin(), getMenu().getShop(), getMenu().getClientManager(), getMenu().getDonationManager(), "Taunts", player));
}
package mineplex.core.cosmetic.ui.button.open;
import org.bukkit.entity.Player;
import mineplex.core.cosmetic.ui.page.Menu;
import mineplex.core.cosmetic.ui.page.TauntPage;
import mineplex.core.gadget.types.Gadget;
public class OpenTaunts extends OpenPageButton
{
public OpenTaunts(Menu menu, Gadget active)
{
super(menu, active);
}
@Override
protected void leftClick(Player player)
{
getMenu().getShop().openPageForPlayer(player, new TauntPage(getMenu().getPlugin(), getMenu().getShop(), getMenu().getClientManager(), getMenu().getDonationManager(), "Taunts", player));
}
}

View File

@ -1,57 +1,57 @@
package mineplex.core.cosmetic.ui.page;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.C;
import mineplex.core.cosmetic.CosmeticManager;
import mineplex.core.cosmetic.ui.CosmeticShop;
import mineplex.core.donation.DonationManager;
import mineplex.core.gadget.types.Gadget;
import mineplex.core.gadget.types.GadgetType;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.item.ShopItem;
public class TauntPage extends GadgetPage
{
public TauntPage(CosmeticManager plugin, CosmeticShop shop, CoreClientManager clientManager, DonationManager donationManager, String name,
Player player)
{
super(plugin, shop, clientManager, donationManager, name, player);
}
@Override
protected void buildPage()
{
int slot = 10;
List<Gadget> list = getPlugin().getGadgetManager().getGadgets(GadgetType.TAUNT);
if(list != null)
for (Gadget gadget : list)
{
addGadget(gadget, slot);
if (getPlugin().getGadgetManager().getActive(getPlayer(), GadgetType.TAUNT) == gadget)
addGlow(slot);
slot++;
if (slot == 26)
slot += 2;
}
addButton(4, new ShopItem(Material.BED, C.cGray + " \u21FD Go Back", new String[]{}, 1, false), new IButton()
{
public void onClick(Player player, ClickType clickType)
{
getShop().openPageForPlayer(getPlayer(), new Menu(getPlugin(), getShop(), getClientManager(), getDonationManager(), player));
}
});
}
}
package mineplex.core.cosmetic.ui.page;
import java.util.List;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.C;
import mineplex.core.cosmetic.CosmeticManager;
import mineplex.core.cosmetic.ui.CosmeticShop;
import mineplex.core.donation.DonationManager;
import mineplex.core.gadget.types.Gadget;
import mineplex.core.gadget.types.GadgetType;
import mineplex.core.shop.item.IButton;
import mineplex.core.shop.item.ShopItem;
public class TauntPage extends GadgetPage
{
public TauntPage(CosmeticManager plugin, CosmeticShop shop, CoreClientManager clientManager, DonationManager donationManager, String name,
Player player)
{
super(plugin, shop, clientManager, donationManager, name, player);
}
@Override
protected void buildPage()
{
int slot = 10;
List<Gadget> list = getPlugin().getGadgetManager().getGadgets(GadgetType.TAUNT);
if(list != null)
for (Gadget gadget : list)
{
addGadget(gadget, slot);
if (getPlugin().getGadgetManager().getActive(getPlayer(), GadgetType.TAUNT) == gadget)
addGlow(slot);
slot++;
if (slot == 26)
slot += 2;
}
addButton(4, new ShopItem(Material.BED, C.cGray + " \u21FD Go Back", new String[]{}, 1, false), new IButton()
{
public void onClick(Player player, ClickType clickType)
{
getShop().openPageForPlayer(getPlayer(), new Menu(getPlugin(), getShop(), getClientManager(), getDonationManager(), player));
}
});
}
}

View File

@ -86,6 +86,8 @@ import mineplex.core.gadget.gadgets.doublejump.titan.DoubleJumpTitan;
import mineplex.core.gadget.gadgets.doublejump.vampire.DoubleJumpBlood;
import mineplex.core.gadget.gadgets.doublejump.wisdom.DoubleJumpEnchant;
import mineplex.core.gadget.gadgets.gamemodifiers.GameModifierType;
import mineplex.core.gadget.gadgets.gamemodifiers.gemhunters.GameModifierMount;
import mineplex.core.gadget.gadgets.gamemodifiers.gemhunters.MountType;
import mineplex.core.gadget.gadgets.gamemodifiers.kits.KitGameModifier;
import mineplex.core.gadget.gadgets.gamemodifiers.kits.KitModifier;
import mineplex.core.gadget.gadgets.gamemodifiers.kits.KitModifierType;
@ -558,6 +560,12 @@ public class GadgetManager extends MiniPlugin
addGadget(new EternalTaunt(this));
addGadget(new BlowAKissTaunt(this));
// Gem Hunters Mounts
for (MountType mount : MountType.values())
{
addGadget(new GameModifierMount(this, mount));
}
for (GadgetType gadgetType : GadgetType.values())
{
if (!_gadgets.containsKey(gadgetType))

View File

@ -1,106 +1,106 @@
package mineplex.core.gadget.event;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import mineplex.core.common.util.UtilTime;
import mineplex.core.gadget.gadgets.taunts.GameType;
public class TauntCommandEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Player _player;
private boolean _gameInProgress;
private boolean _alive;
private boolean _spectator;
private long _lastPvp;
private TauntState _state = TauntState.NONE;
private GameType _gameType;
public TauntCommandEvent(Player player, boolean gameInProgress, boolean alive, boolean spectator, long lastPvp, GameType gameType)
{
_player = player;
_gameInProgress = gameInProgress;
_alive = alive;
_spectator = spectator;
_lastPvp = lastPvp;
_gameType = gameType;
}
public Player getPlayer()
{
return _player;
}
public boolean isGameInProgress()
{
return _gameInProgress;
}
public boolean isAlive()
{
return _alive;
}
public boolean isSpectator()
{
return _spectator;
}
public boolean isInPvp(long cooldown)
{
return !UtilTime.elapsed(_lastPvp, cooldown);
}
public TauntState getState()
{
return _state;
}
public GameType getGameType()
{
return _gameType;
}
public void setState(TauntState state)
{
_state = state;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
public enum TauntState
{
NONE(""),
NO_TAUNT("You have no active taunts!"),
NOT_IN_GAME("You are not in a game!"),
NOT_ALIVE("You are not playing the game!"),
SPECTATOR("You can't run this as a spectator!"),
PVP("You can't run this while in pvp!"),
GAME_DISABLED("Taunts are disabled in this game!");
private String _message;
TauntState(String message)
{
_message = message;
}
public String getMessage()
{
return _message;
}
}
}
package mineplex.core.gadget.event;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import mineplex.core.common.util.UtilTime;
import mineplex.core.gadget.gadgets.taunts.GameType;
public class TauntCommandEvent extends Event
{
private static final HandlerList handlers = new HandlerList();
private Player _player;
private boolean _gameInProgress;
private boolean _alive;
private boolean _spectator;
private long _lastPvp;
private TauntState _state = TauntState.NONE;
private GameType _gameType;
public TauntCommandEvent(Player player, boolean gameInProgress, boolean alive, boolean spectator, long lastPvp, GameType gameType)
{
_player = player;
_gameInProgress = gameInProgress;
_alive = alive;
_spectator = spectator;
_lastPvp = lastPvp;
_gameType = gameType;
}
public Player getPlayer()
{
return _player;
}
public boolean isGameInProgress()
{
return _gameInProgress;
}
public boolean isAlive()
{
return _alive;
}
public boolean isSpectator()
{
return _spectator;
}
public boolean isInPvp(long cooldown)
{
return !UtilTime.elapsed(_lastPvp, cooldown);
}
public TauntState getState()
{
return _state;
}
public GameType getGameType()
{
return _gameType;
}
public void setState(TauntState state)
{
_state = state;
}
public HandlerList getHandlers()
{
return handlers;
}
public static HandlerList getHandlerList()
{
return handlers;
}
public enum TauntState
{
NONE(""),
NO_TAUNT("You have no active taunts!"),
NOT_IN_GAME("You are not in a game!"),
NOT_ALIVE("You are not playing the game!"),
SPECTATOR("You can't run this as a spectator!"),
PVP("You can't run this while in pvp!"),
GAME_DISABLED("Taunts are disabled in this game!");
private String _message;
TauntState(String message)
{
_message = message;
}
public String getMessage()
{
return _message;
}
}
}

View File

@ -19,7 +19,11 @@ public enum GameModifierType
MineStrike("MineStrike", new String[]{"Apply custom gun models and skin to use ingame"}, Material.TNT, 0),
SurvivalGames("Survival Games", new String[]{"Placeholder"}, Material.DIAMOND_SWORD, 0, true),
Bridges("Bridges", new String[]{"Placeholder"}, Material.IRON_PICKAXE, 0, true);
Bridges("Bridges", new String[]{"Placeholder"}, Material.IRON_PICKAXE, 0, true),
GemHunters("Gem Hunters", new String[] { "" }, Material.EMERALD, 0)
;
private String _name;
private List<String> _desc;

View File

@ -0,0 +1,23 @@
package mineplex.core.gadget.gadgets.gamemodifiers.gemhunters;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.gamemodifiers.GameModifierType;
import mineplex.core.gadget.types.GameModifierGadget;
public class GameModifierMount extends GameModifierGadget
{
private final MountType _mountType;
public GameModifierMount(GadgetManager manager, MountType mountType)
{
super(manager, GameModifierType.GemHunters, mountType.getName() + " Mount", mountType.getDescription(), -2, mountType.getMaterial(), mountType.getData(), false);
_mountType = mountType;
}
public final MountType getMountType()
{
return _mountType;
}
}

View File

@ -0,0 +1,53 @@
package mineplex.core.gadget.gadgets.gamemodifiers.gemhunters;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
public enum MountType
{
SKELETON(EntityType.HORSE, Material.BONE, (byte) 0, "Skeleton Horse", "Spooky")
;
private final EntityType _entityType;
private final Material _material;
private final byte _data;
private final String _name;
private final String[] _description;
private MountType(EntityType entityType, Material material, byte data, String name, String... description)
{
_entityType = entityType;
_material = material;
_data = data;
_name = name;
_description = description;
}
public final EntityType getEntityType()
{
return _entityType;
}
public final Material getMaterial()
{
return _material;
}
public byte getData()
{
return _data;
}
public final String getName()
{
return _name;
}
public final String[] getDescription()
{
return _description;
}
}

View File

@ -1,147 +1,147 @@
package mineplex.core.gadget.gadgets.taunts;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.FireworkEffect;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.util.Vector;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilText;
import mineplex.core.disguise.disguises.DisguiseSkeleton;
import mineplex.core.events.EnableArcadeSpawnEvent;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.morph.managers.UtilMorph;
import mineplex.core.gadget.types.TauntGadget;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
public class EternalTaunt extends TauntGadget
{
private static final int COOLDOWN = 30000;
private static final int PVP_COOLDOWN = 10000;
private Map<UUID, List<Item>> _clocks = new HashMap<>();
public EternalTaunt(GadgetManager manager)
{
super(manager, "Eternal Taunt", UtilText.splitLinesToArray(new String[]{C.cGray + "Although the Eternal has been around forever, he waited too long for a worthy opponent and he turned to bones.",
"",
C.cWhite + "Use /taunt in game to show how long you've been waiting.",
C.cRed + "Cannot be used while in PvP!"}, LineFormat.LORE),
-15, Material.WATCH, (byte) 0);
setCanPlayWithPvp(false);
setPvpCooldown(PVP_COOLDOWN);
setShouldPlay(true);
setEventType(UpdateType.FAST);
addDisabledGames(GameType.SMASH, GameType.SMASHTEAMS, GameType.SMASHDOMINATION);
}
@Override
public void onStart(Player player)
{
if (!Recharge.Instance.use(player, getName(), COOLDOWN, true, false, "Cosmetics"))
return;
UtilFirework.playFirework(player.getLocation(), FireworkEffect.builder().with(FireworkEffect.Type.BALL_LARGE).withColor(Color.fromRGB(255, 175, 175)).withFade(Color.RED).build());
_clocks.put(player.getUniqueId(), new ArrayList<>());
Bukkit.broadcastMessage(F.main("Taunt", F.name(player.getName()) + " waited so long they turned to bones."));
DisguiseSkeleton disguiseSkeleton = new DisguiseSkeleton(player);
UtilMorph.disguise(player, disguiseSkeleton, Manager);
}
@Override
public void onPlay(Player player)
{
if (!_clocks.containsKey(player.getUniqueId()))
return;
int i = getPlayerTicks(player);
EnableArcadeSpawnEvent enableArcadeSpawnEvent = new EnableArcadeSpawnEvent(true);
Bukkit.getPluginManager().callEvent(enableArcadeSpawnEvent);
Item clock = player.getWorld().dropItem(player.getLocation().add(0.5, 1.5, 0.5),
ItemStackFactory.Instance.CreateStack(Material.WATCH, (byte) 0, 1, " " + i));
enableArcadeSpawnEvent = new EnableArcadeSpawnEvent(false);
Bukkit.getPluginManager().callEvent(enableArcadeSpawnEvent);
Vector vel = new Vector(Math.sin(i * 9/5d), 0, Math.cos(i * 9/5d));
UtilAction.velocity(clock, vel, Math.abs(Math.sin(i * 12/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 12/3000d))*0.6, 1, false);
_clocks.get(player.getUniqueId()).add(clock);
if (_clocks.get(player.getUniqueId()).size() >= 5)
{
_clocks.get(player.getUniqueId()).get(0).remove();
_clocks.get(player.getUniqueId()).remove(0);
}
if (i % 2 == 0)
player.playSound(player.getLocation(), Sound.CLICK, 1f, 1f);
else
player.playSound(player.getLocation(), Sound.CLICK, 0.5f, 0.5f);
if (i >= 15)
{
finish(player);
}
}
@Override
public void onFinish(Player player)
{
UtilMorph.undisguise(player, Manager.getDisguiseManager());
if (_clocks.containsKey(player.getUniqueId()))
{
_clocks.get(player.getUniqueId()).forEach(c -> c.remove());
_clocks.get(player.getUniqueId()).clear();
_clocks.remove(player.getUniqueId());
}
}
@EventHandler
public void titanOwner(PlayerJoinEvent event)
{
if (Manager.getClientManager().Get(event.getPlayer()).GetRank().has(Rank.ETERNAL))
{
Manager.getDonationManager().Get(event.getPlayer()).addOwnedUnknownSalesPackage(getName());
}
}
@EventHandler
public void onClockPickup(PlayerPickupItemEvent event)
{
for (List<Item> clocks : _clocks.values())
{
for (Item item : clocks)
{
if (event.getItem().equals(item))
event.setCancelled(true);
}
}
}
}
package mineplex.core.gadget.gadgets.taunts;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.FireworkEffect;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.util.Vector;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.LineFormat;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilText;
import mineplex.core.disguise.disguises.DisguiseSkeleton;
import mineplex.core.events.EnableArcadeSpawnEvent;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.morph.managers.UtilMorph;
import mineplex.core.gadget.types.TauntGadget;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
public class EternalTaunt extends TauntGadget
{
private static final int COOLDOWN = 30000;
private static final int PVP_COOLDOWN = 10000;
private Map<UUID, List<Item>> _clocks = new HashMap<>();
public EternalTaunt(GadgetManager manager)
{
super(manager, "Eternal Taunt", UtilText.splitLinesToArray(new String[]{C.cGray + "Although the Eternal has been around forever, he waited too long for a worthy opponent and he turned to bones.",
"",
C.cWhite + "Use /taunt in game to show how long you've been waiting.",
C.cRed + "Cannot be used while in PvP!"}, LineFormat.LORE),
-15, Material.WATCH, (byte) 0);
setCanPlayWithPvp(false);
setPvpCooldown(PVP_COOLDOWN);
setShouldPlay(true);
setEventType(UpdateType.FAST);
addDisabledGames(GameType.SMASH, GameType.SMASHTEAMS, GameType.SMASHDOMINATION);
}
@Override
public void onStart(Player player)
{
if (!Recharge.Instance.use(player, getName(), COOLDOWN, true, false, "Cosmetics"))
return;
UtilFirework.playFirework(player.getLocation(), FireworkEffect.builder().with(FireworkEffect.Type.BALL_LARGE).withColor(Color.fromRGB(255, 175, 175)).withFade(Color.RED).build());
_clocks.put(player.getUniqueId(), new ArrayList<>());
Bukkit.broadcastMessage(F.main("Taunt", F.name(player.getName()) + " waited so long they turned to bones."));
DisguiseSkeleton disguiseSkeleton = new DisguiseSkeleton(player);
UtilMorph.disguise(player, disguiseSkeleton, Manager);
}
@Override
public void onPlay(Player player)
{
if (!_clocks.containsKey(player.getUniqueId()))
return;
int i = getPlayerTicks(player);
EnableArcadeSpawnEvent enableArcadeSpawnEvent = new EnableArcadeSpawnEvent(true);
Bukkit.getPluginManager().callEvent(enableArcadeSpawnEvent);
Item clock = player.getWorld().dropItem(player.getLocation().add(0.5, 1.5, 0.5),
ItemStackFactory.Instance.CreateStack(Material.WATCH, (byte) 0, 1, " " + i));
enableArcadeSpawnEvent = new EnableArcadeSpawnEvent(false);
Bukkit.getPluginManager().callEvent(enableArcadeSpawnEvent);
Vector vel = new Vector(Math.sin(i * 9/5d), 0, Math.cos(i * 9/5d));
UtilAction.velocity(clock, vel, Math.abs(Math.sin(i * 12/3000d)), false, 0, 0.2 + Math.abs(Math.cos(i * 12/3000d))*0.6, 1, false);
_clocks.get(player.getUniqueId()).add(clock);
if (_clocks.get(player.getUniqueId()).size() >= 5)
{
_clocks.get(player.getUniqueId()).get(0).remove();
_clocks.get(player.getUniqueId()).remove(0);
}
if (i % 2 == 0)
player.playSound(player.getLocation(), Sound.CLICK, 1f, 1f);
else
player.playSound(player.getLocation(), Sound.CLICK, 0.5f, 0.5f);
if (i >= 15)
{
finish(player);
}
}
@Override
public void onFinish(Player player)
{
UtilMorph.undisguise(player, Manager.getDisguiseManager());
if (_clocks.containsKey(player.getUniqueId()))
{
_clocks.get(player.getUniqueId()).forEach(c -> c.remove());
_clocks.get(player.getUniqueId()).clear();
_clocks.remove(player.getUniqueId());
}
}
@EventHandler
public void titanOwner(PlayerJoinEvent event)
{
if (Manager.getClientManager().Get(event.getPlayer()).GetRank().has(Rank.ETERNAL))
{
Manager.getDonationManager().Get(event.getPlayer()).addOwnedUnknownSalesPackage(getName());
}
}
@EventHandler
public void onClockPickup(PlayerPickupItemEvent event)
{
for (List<Item> clocks : _clocks.values())
{
for (Item item : clocks)
{
if (event.getItem().equals(item))
event.setCancelled(true);
}
}
}
}

View File

@ -1,84 +1,84 @@
package mineplex.core.gadget.gadgets.taunts;
public enum GameType
{
BACONBRAWL,
BARBARIANS,
BASKETBALL,
BOSSBATTLES,
BRIDGE,
CASTLESIEGE,
CHAMPIONSCTF,
CHAMPIONSDOMINATE,
CHAMPIONSTDM,
CHRISTMAS,
DEATHTAG,
DRAGONESCAPE,
DRAGONESCAPETEAMS,
DRAGONRIDERS,
DRAGONS,
DRAGONSTEAMS,
DRAW,
ELYTRARINGS,
EVOLUTION,
GRAVITY,
HALLOWEEN,
HALLOWEEN2016,
HIDESEEK,
HOLEINTHEWALL,
HORSE,
LOBBERS,
MICRO,
MILKCOW,
MINESTRIKE,
BAWKBAWKBATTLES,
MINECRAFTLEAGUE,
OLDMINEWARE,
PAINTBALL,
QUIVER,
QUIVERPAYLOAD,
QUIVERTEAMS,
RUNNER,
SEARCHANDDESTROY,
SHEEP,
TYPEWARS,
SMASH,
SMASHDOMINATION,
SMASHTEAMS,
SNAKE,
SNEAKYASSASSINS,
SNOWFIGHT,
SPEEDBUILDERS,
SPLEEF,
SPLEEFTEAMS,
SQUIDSHOOTER,
STACKER,
SURVIVALGAMES,
SURVIVALGAMESTEAMS,
TUG,
TURFWARS,
UHC,
UHCSOLO,
UHCSOLOSPEED,
UHCTEAMSSPEED,
WITHERASSAULT,
WIZARDS,
ZOMBIESURVIVAL,
BUILD,
BUILDMAVERICKS,
CARDS,
SKYWARS,
SKYWARSTEAMS,
MONSTERMAZE,
MONSTERLEAGUE,
GLADIATORS,
SKYFALL,
SKYFALLTEAMS,
BOUNCYBALLS,
VALENTINES,
EVENT,
BRAWL,
NONE
}
package mineplex.core.gadget.gadgets.taunts;
public enum GameType
{
BACONBRAWL,
BARBARIANS,
BASKETBALL,
BOSSBATTLES,
BRIDGE,
CASTLESIEGE,
CHAMPIONSCTF,
CHAMPIONSDOMINATE,
CHAMPIONSTDM,
CHRISTMAS,
DEATHTAG,
DRAGONESCAPE,
DRAGONESCAPETEAMS,
DRAGONRIDERS,
DRAGONS,
DRAGONSTEAMS,
DRAW,
ELYTRARINGS,
EVOLUTION,
GRAVITY,
HALLOWEEN,
HALLOWEEN2016,
HIDESEEK,
HOLEINTHEWALL,
HORSE,
LOBBERS,
MICRO,
MILKCOW,
MINESTRIKE,
BAWKBAWKBATTLES,
MINECRAFTLEAGUE,
OLDMINEWARE,
PAINTBALL,
QUIVER,
QUIVERPAYLOAD,
QUIVERTEAMS,
RUNNER,
SEARCHANDDESTROY,
SHEEP,
TYPEWARS,
SMASH,
SMASHDOMINATION,
SMASHTEAMS,
SNAKE,
SNEAKYASSASSINS,
SNOWFIGHT,
SPEEDBUILDERS,
SPLEEF,
SPLEEFTEAMS,
SQUIDSHOOTER,
STACKER,
SURVIVALGAMES,
SURVIVALGAMESTEAMS,
TUG,
TURFWARS,
UHC,
UHCSOLO,
UHCSOLOSPEED,
UHCTEAMSSPEED,
WITHERASSAULT,
WIZARDS,
ZOMBIESURVIVAL,
BUILD,
BUILDMAVERICKS,
CARDS,
SKYWARS,
SKYWARSTEAMS,
MONSTERMAZE,
MONSTERLEAGUE,
GLADIATORS,
SKYFALL,
SKYFALLTEAMS,
BOUNCYBALLS,
VALENTINES,
EVENT,
BRAWL,
NONE
}

View File

@ -1,162 +1,162 @@
package mineplex.core.gadget.types;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.taunts.GameType;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
/**
* Handles Taunts
*/
public abstract class TauntGadget extends Gadget
{
/** Sets if this specific taunt can be used while in PvP */
private boolean _canPlayWithPvp = false;
/** Sets the cooldown for pvp */
private long _pvpCooldown = 0;
/** Sets if this taunt needs to run on updates */
private boolean _shouldPlay = false;
/** Sets when the taunt will run, if set above */
private UpdateType _updateType = UpdateType.TICK;
/** List of games where this item is disabled */
private List<GameType> _disabledGames = new ArrayList<>();
/** The ticks that passed since the player started the effect */
private Map<UUID, Integer> _ticksPerPlayer = new HashMap<>();
/**
* @param manager The normal GadgetManager
* @param name The name of the item
* @param desc The lore/description of the item
* @param cost The cost of the item
* @param mat The display material of the item
* @param data The display data of the item
* @param alternativeSalesPackageNames Possible alternative names for this package
*/
public TauntGadget(GadgetManager manager, String name, String[] desc, int cost, Material mat, byte data,
String... alternativeSalesPackageNames)
{
super(manager, GadgetType.TAUNT, name, desc, cost, mat, data, 1, alternativeSalesPackageNames);
}
/**
* @param manager The normal GadgetManager
* @param name The name of the item
* @param desc The lore/description of the item
* @param cost The cost of the item
* @param mat The display material of the item
* @param data The display data of the item
* @param yearMonth The year and month of this item, if it is a PPC item
* @param alternativeSalesPackageNames Possible alternative names for this package
*/
public TauntGadget(GadgetManager manager, String name, String[] desc, int cost, Material mat, byte data,
YearMonth yearMonth, String... alternativeSalesPackageNames)
{
super(manager, GadgetType.TAUNT, name, desc, cost, mat, data, yearMonth, 1, alternativeSalesPackageNames);
}
@Override
public void disableCustom(Player player, boolean message)
{
finish(player);
}
public void start(Player player)
{
onStart(player);
_ticksPerPlayer.put(player.getUniqueId(), 0);
}
public abstract void onStart(Player player);
public void play(Player player)
{
onPlay(player);
int ticks = getPlayerTicks(player) + 1;
_ticksPerPlayer.put(player.getUniqueId(), ticks);
}
public abstract void onPlay(Player player);
public void finish(Player player)
{
onFinish(player);
_ticksPerPlayer.remove(player.getUniqueId());
}
public abstract void onFinish(Player player);
public void setCanPlayWithPvp(boolean canPlayWithPvp)
{
_canPlayWithPvp = canPlayWithPvp;
}
public void setPvpCooldown(long pvpCooldown)
{
_pvpCooldown = pvpCooldown;
}
public void setShouldPlay(boolean shouldPlay)
{
_shouldPlay = shouldPlay;
}
public void setEventType(UpdateType updateType)
{
_updateType = updateType;
}
public void addDisabledGames(GameType... disabledGames)
{
_disabledGames.addAll(Arrays.asList(disabledGames));
}
public boolean canPlayWithPvp()
{
return _canPlayWithPvp;
}
public boolean isGameDisabled(GameType gameType)
{
return _disabledGames.contains(gameType);
}
public long getPvpCooldown()
{
return _pvpCooldown;
}
public int getPlayerTicks(Player player)
{
return (_ticksPerPlayer.containsKey(player.getUniqueId())) ? _ticksPerPlayer.get(player.getUniqueId()) : -1;
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (!_shouldPlay)
return;
if (event.getType() != _updateType)
return;
for (Player player : getActive())
{
if (_ticksPerPlayer.containsKey(player.getUniqueId()))
play(player);
}
}
}
package mineplex.core.gadget.types;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.taunts.GameType;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
/**
* Handles Taunts
*/
public abstract class TauntGadget extends Gadget
{
/** Sets if this specific taunt can be used while in PvP */
private boolean _canPlayWithPvp = false;
/** Sets the cooldown for pvp */
private long _pvpCooldown = 0;
/** Sets if this taunt needs to run on updates */
private boolean _shouldPlay = false;
/** Sets when the taunt will run, if set above */
private UpdateType _updateType = UpdateType.TICK;
/** List of games where this item is disabled */
private List<GameType> _disabledGames = new ArrayList<>();
/** The ticks that passed since the player started the effect */
private Map<UUID, Integer> _ticksPerPlayer = new HashMap<>();
/**
* @param manager The normal GadgetManager
* @param name The name of the item
* @param desc The lore/description of the item
* @param cost The cost of the item
* @param mat The display material of the item
* @param data The display data of the item
* @param alternativeSalesPackageNames Possible alternative names for this package
*/
public TauntGadget(GadgetManager manager, String name, String[] desc, int cost, Material mat, byte data,
String... alternativeSalesPackageNames)
{
super(manager, GadgetType.TAUNT, name, desc, cost, mat, data, 1, alternativeSalesPackageNames);
}
/**
* @param manager The normal GadgetManager
* @param name The name of the item
* @param desc The lore/description of the item
* @param cost The cost of the item
* @param mat The display material of the item
* @param data The display data of the item
* @param yearMonth The year and month of this item, if it is a PPC item
* @param alternativeSalesPackageNames Possible alternative names for this package
*/
public TauntGadget(GadgetManager manager, String name, String[] desc, int cost, Material mat, byte data,
YearMonth yearMonth, String... alternativeSalesPackageNames)
{
super(manager, GadgetType.TAUNT, name, desc, cost, mat, data, yearMonth, 1, alternativeSalesPackageNames);
}
@Override
public void disableCustom(Player player, boolean message)
{
finish(player);
}
public void start(Player player)
{
onStart(player);
_ticksPerPlayer.put(player.getUniqueId(), 0);
}
public abstract void onStart(Player player);
public void play(Player player)
{
onPlay(player);
int ticks = getPlayerTicks(player) + 1;
_ticksPerPlayer.put(player.getUniqueId(), ticks);
}
public abstract void onPlay(Player player);
public void finish(Player player)
{
onFinish(player);
_ticksPerPlayer.remove(player.getUniqueId());
}
public abstract void onFinish(Player player);
public void setCanPlayWithPvp(boolean canPlayWithPvp)
{
_canPlayWithPvp = canPlayWithPvp;
}
public void setPvpCooldown(long pvpCooldown)
{
_pvpCooldown = pvpCooldown;
}
public void setShouldPlay(boolean shouldPlay)
{
_shouldPlay = shouldPlay;
}
public void setEventType(UpdateType updateType)
{
_updateType = updateType;
}
public void addDisabledGames(GameType... disabledGames)
{
_disabledGames.addAll(Arrays.asList(disabledGames));
}
public boolean canPlayWithPvp()
{
return _canPlayWithPvp;
}
public boolean isGameDisabled(GameType gameType)
{
return _disabledGames.contains(gameType);
}
public long getPvpCooldown()
{
return _pvpCooldown;
}
public int getPlayerTicks(Player player)
{
return (_ticksPerPlayer.containsKey(player.getUniqueId())) ? _ticksPerPlayer.get(player.getUniqueId()) : -1;
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (!_shouldPlay)
return;
if (event.getType() != _updateType)
return;
for (Player player : getActive())
{
if (_ticksPerPlayer.containsKey(player.getUniqueId()))
play(player);
}
}
}

View File

@ -0,0 +1,81 @@
package mineplex.core.google;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
@ReflectivelyCreateMiniPlugin
public class GoogleSheetsManager extends MiniPlugin
{
private static final File DATA_STORE_DIR = new File(".." + File.separatorChar + ".." + File.separatorChar + "update" + File.separatorChar + "files");
private GoogleSheetsManager()
{
super("Google Sheets");
}
public Map<String, List<List<String>>> getSheetData(String name)
{
return getSheetData(new File(DATA_STORE_DIR + File.separator + name + ".json"));
}
public Map<String, List<List<String>>> getSheetData(File file)
{
if (!file.exists())
{
return null;
}
Map<String, List<List<String>>> valuesMap = new HashMap<>();
try
{
JsonParser parser = new JsonParser();
JsonElement data = parser.parse(new FileReader(file));
JsonArray parent = data.getAsJsonObject().getAsJsonArray("data");
for (int i = 0; i < parent.size(); i++)
{
JsonObject sheet = parent.get(i).getAsJsonObject();
String name = sheet.get("name").getAsString();
JsonArray values = sheet.getAsJsonArray("values");
List<List<String>> valuesList = new ArrayList<>(values.size());
for (int j = 0; j < values.size(); j++)
{
List<String> list = new ArrayList<>();
Iterator<JsonElement> iterator = values.get(j).getAsJsonArray().iterator();
while (iterator.hasNext())
{
String value = iterator.next().getAsString();
list.add(value);
}
valuesList.add(list);
}
valuesMap.put(name, valuesList);
}
}
catch (FileNotFoundException e)
{
}
return valuesMap;
}
}

View File

@ -0,0 +1,8 @@
package mineplex.core.google;
public interface SheetObjectDeserialiser<T>
{
public T deserialise(String[] values) throws ArrayIndexOutOfBoundsException;
}

View File

@ -53,6 +53,7 @@ public class ItemBuilder
private int _amount;
private Color _color;
private short _data;
private short _durability;
private final HashMap<Enchantment, Integer> _enchants = new HashMap<Enchantment, Integer>();
private final List<String> _lore = new ArrayList<String>();
private Material _mat;
@ -90,6 +91,7 @@ public class ItemBuilder
_itemFlags.addAll(meta.getItemFlags());
_unbreakable = meta.spigot().isUnbreakable();
_durability = item.getDurability();
}
}
@ -108,6 +110,7 @@ public class ItemBuilder
_mat = mat;
_amount = amount;
_data = data;
_durability = 0;
}
public ItemBuilder(Material mat, short data)
@ -115,6 +118,13 @@ public class ItemBuilder
this(mat, 1, data);
}
public ItemBuilder setDurability(short durability)
{
_durability = durability;
return this;
}
public HashSet<ItemFlag> getItemFlags()
{
return _itemFlags;
@ -278,7 +288,8 @@ public class ItemBuilder
item.addUnsafeEnchantments(_enchants);
if (_glow) item.addEnchantment(UtilInv.getDullEnchantment(), 1);
if (_durability != 0) item.setDurability(_durability);
return item;
}
@ -298,7 +309,8 @@ public class ItemBuilder
newBuilder.setColor(_color);
// newBuilder.potion = potion;
newBuilder.setDurability(_durability);
return newBuilder;
}

View File

@ -1,52 +1,52 @@
package mineplex.core.particleeffects;
import java.awt.Color;
import org.bukkit.Location;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.particles.ColoredParticle;
import mineplex.core.common.util.particles.DustSpellColor;
public class LineEffect extends Effect
{
private int _particles = 100;
private Color _color;
private int _count = 0;
private Vector _vector;
private Location _fixedLoc;
public LineEffect(JavaPlugin plugin, Location location, Location target, Color color)
{
super(-1, new EffectLocation(location), plugin);
setTargetLocation(new EffectLocation(target));
_color = color;
}
@Override
public void runEffect()
{
Location location = _effectLocation.getFixedLocation().clone().add(0, 1, 0);
if (_vector == null)
{
Location targetLoc = getTargetLocation().getFixedLocation().clone();
Vector link = targetLoc.toVector().subtract(location.toVector());
float length = (float) link.length();
link.normalize();
Vector vector = link.multiply(length / _particles);
_vector = vector;
_fixedLoc = location.clone().subtract(_vector);
}
ColoredParticle coloredParticle = new ColoredParticle(UtilParticle.ParticleType.RED_DUST,
new DustSpellColor(_color), _effectLocation.getLocation().clone());
_fixedLoc.add(_vector);
if (_count == _particles)
{
stop();
}
}
}
package mineplex.core.particleeffects;
import java.awt.Color;
import org.bukkit.Location;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.particles.ColoredParticle;
import mineplex.core.common.util.particles.DustSpellColor;
public class LineEffect extends Effect
{
private int _particles = 100;
private Color _color;
private int _count = 0;
private Vector _vector;
private Location _fixedLoc;
public LineEffect(JavaPlugin plugin, Location location, Location target, Color color)
{
super(-1, new EffectLocation(location), plugin);
setTargetLocation(new EffectLocation(target));
_color = color;
}
@Override
public void runEffect()
{
Location location = _effectLocation.getFixedLocation().clone().add(0, 1, 0);
if (_vector == null)
{
Location targetLoc = getTargetLocation().getFixedLocation().clone();
Vector link = targetLoc.toVector().subtract(location.toVector());
float length = (float) link.length();
link.normalize();
Vector vector = link.multiply(length / _particles);
_vector = vector;
_fixedLoc = location.clone().subtract(_vector);
}
ColoredParticle coloredParticle = new ColoredParticle(UtilParticle.ParticleType.RED_DUST,
new DustSpellColor(_color), _effectLocation.getLocation().clone());
_fixedLoc.add(_vector);
if (_count == _particles)
{
stop();
}
}
}

View File

@ -12,7 +12,12 @@ public enum GenericServer
/**
* The Clans Hubs, such as ClansHub-1
*/
CLANS_HUB("ClansHub");
CLANS_HUB("ClansHub"),
/**
* The Beta Hubs, such as BetaHub-1
*/
BETA_HUB("BetaHub"),
;
private final String _name;

View File

@ -3,28 +3,29 @@ package mineplex.core.sponsorbranding;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;
import javax.imageio.ImageIO;
import mineplex.core.MiniPlugin;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
/**
*
* Manager for creating billboards with branding logos
*/
@ReflectivelyCreateMiniPlugin
public class BrandingManager extends MiniPlugin
{
private ConcurrentHashMap<Integer, BrandingPost> _posts = new ConcurrentHashMap<Integer, BrandingPost>();
private ConcurrentHashMap<String, BufferedImage> _imgCache = new ConcurrentHashMap<String, BufferedImage>();
public BrandingManager(JavaPlugin plugin)
private BrandingManager()
{
super("Branding Manager", plugin);
super("Branding Manager");
}
private BufferedImage getImage(String fileName)
@ -56,6 +57,28 @@ public class BrandingManager extends MiniPlugin
return image;
}
private BufferedImage getImage(URL url)
{
if (_imgCache.containsKey(url.toString()))
{
return _imgCache.get(url.toString());
}
BufferedImage image = null;
try
{
image = ImageIO.read(url);
_imgCache.put(url.toString(), image);
}
catch (IOException e)
{
e.printStackTrace();
}
return image;
}
/**
* Generates a billboard with a stored logo
* @param location The center of the billboard
@ -75,6 +98,22 @@ public class BrandingManager extends MiniPlugin
_posts.put(_posts.size(), bp);
}
public void createPost(Location location, BlockFace facing, URL url)
{
BufferedImage image = getImage(url);
if (image == null)
{
System.out.println("ERROR! Invalid image url!");
return;
}
BrandingPost brandingPost = new BrandingPost(location, facing, image);
brandingPost.spawn();
// Umm why not use a List?
_posts.put(_posts.size(), brandingPost);
}
/**
* Clears away all existing billboards
*/

View File

@ -68,6 +68,8 @@ public class BrandingPost
int width = (int) Math.ceil(_img.getWidth() / 128);
int height = (int) Math.ceil(_img.getHeight() / 128);
Bukkit.broadcastMessage("width=" + width + " height=" + height);
switch (_facing)
{
case EAST:
@ -160,6 +162,7 @@ public class BrandingPost
ItemStack item = getMapItem(x, y, _img);
i.setItem(item);
Bukkit.broadcastMessage(x + " <- X Y -> " + y);
_ents.add(i);
}
}

View File

@ -1,35 +1,35 @@
package mineplex.core.treasure.gui;
import org.bukkit.inventory.ItemStack;
import mineplex.core.treasure.TreasureType;
public class TreasurePageItem
{
private final ItemStack _item;
private final int _count;
private final TreasureType _treasureType;
public TreasurePageItem(ItemStack item, int count, TreasureType treasureType)
{
_item = item;
_count = count;
_treasureType = treasureType;
}
public ItemStack getItem()
{
return _item;
}
public int getCount()
{
return _count;
}
public TreasureType getTreasureType()
{
return _treasureType;
}
}
package mineplex.core.treasure.gui;
import org.bukkit.inventory.ItemStack;
import mineplex.core.treasure.TreasureType;
public class TreasurePageItem
{
private final ItemStack _item;
private final int _count;
private final TreasureType _treasureType;
public TreasurePageItem(ItemStack item, int count, TreasureType treasureType)
{
_item = item;
_count = count;
_treasureType = treasureType;
}
public ItemStack getItem()
{
return _item;
}
public int getCount()
{
return _count;
}
public TreasureType getTreasureType()
{
return _treasureType;
}
}

View File

@ -1,32 +1,32 @@
package mineplex.core.treasure.gui.pages;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.shop.item.IButton;
import mineplex.core.treasure.gui.TreasurePage;
public class NextPageButton implements IButton
{
private TreasurePage _treasurePage;
private Player _player;
public NextPageButton(TreasurePage treasurePage, Player player)
{
_treasurePage = treasurePage;
_player = player;
}
@Override
public void onClick(Player player, ClickType clickType)
{
if (_player != player)
return;
player.closeInventory();
TreasurePage nextPage = new TreasurePage(_treasurePage.getTreasureManager(), _treasurePage.getTreasureShop(), _treasurePage.getTreasureLocation(),
_treasurePage.getClientManager(), _treasurePage.getDonationManager(), _treasurePage.getInventoryManager(),
_treasurePage.getGadgetManager(), _player, _treasurePage.getActualPage() + 1);
_treasurePage.getTreasureShop().openPageForPlayer(player, nextPage);
}
}
package mineplex.core.treasure.gui.pages;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.shop.item.IButton;
import mineplex.core.treasure.gui.TreasurePage;
public class NextPageButton implements IButton
{
private TreasurePage _treasurePage;
private Player _player;
public NextPageButton(TreasurePage treasurePage, Player player)
{
_treasurePage = treasurePage;
_player = player;
}
@Override
public void onClick(Player player, ClickType clickType)
{
if (_player != player)
return;
player.closeInventory();
TreasurePage nextPage = new TreasurePage(_treasurePage.getTreasureManager(), _treasurePage.getTreasureShop(), _treasurePage.getTreasureLocation(),
_treasurePage.getClientManager(), _treasurePage.getDonationManager(), _treasurePage.getInventoryManager(),
_treasurePage.getGadgetManager(), _player, _treasurePage.getActualPage() + 1);
_treasurePage.getTreasureShop().openPageForPlayer(player, nextPage);
}
}

View File

@ -1,33 +1,33 @@
package mineplex.core.treasure.gui.pages;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.shop.item.IButton;
import mineplex.core.treasure.gui.TreasurePage;
public class PreviousPageButton implements IButton
{
private TreasurePage _treasurePage;
private Player _player;
public PreviousPageButton(TreasurePage treasurePage, Player player)
{
_treasurePage = treasurePage;
_player = player;
}
@Override
public void onClick(Player player, ClickType clickType)
{
if (_player != player)
return;
player.closeInventory();
TreasurePage previousPage = new TreasurePage(_treasurePage.getTreasureManager(), _treasurePage.getTreasureShop(), _treasurePage.getTreasureLocation(),
_treasurePage.getClientManager(), _treasurePage.getDonationManager(), _treasurePage.getInventoryManager(),
_treasurePage.getGadgetManager(), _player, _treasurePage.getActualPage() - 1);
_treasurePage.getTreasureShop().openPageForPlayer(player, previousPage);
}
}
package mineplex.core.treasure.gui.pages;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import mineplex.core.shop.item.IButton;
import mineplex.core.treasure.gui.TreasurePage;
public class PreviousPageButton implements IButton
{
private TreasurePage _treasurePage;
private Player _player;
public PreviousPageButton(TreasurePage treasurePage, Player player)
{
_treasurePage = treasurePage;
_player = player;
}
@Override
public void onClick(Player player, ClickType clickType)
{
if (_player != player)
return;
player.closeInventory();
TreasurePage previousPage = new TreasurePage(_treasurePage.getTreasureManager(), _treasurePage.getTreasureShop(), _treasurePage.getTreasureLocation(),
_treasurePage.getClientManager(), _treasurePage.getDonationManager(), _treasurePage.getInventoryManager(),
_treasurePage.getGadgetManager(), _player, _treasurePage.getActualPage() - 1);
_treasurePage.getTreasureShop().openPageForPlayer(player, previousPage);
}
}

View File

@ -185,7 +185,7 @@ public class TwoFactorAuth extends MiniClientPlugin<TwoFactorData>
player.sendMessage(F.main("2FA", "Setting up two-factor authentication."));
}
@EventHandler
//@EventHandler
public void onJoin(PlayerJoinEvent event)
{
Player player = event.getPlayer();

View File

@ -223,7 +223,7 @@ public class Clans extends JavaPlugin
}
}
BlockRestore blockRestore = new BlockRestore(this);
BlockRestore blockRestore = require(BlockRestore.class);
IgnoreManager ignoreManager = new IgnoreManager(this, _clientManager, preferenceManager, portal);

View File

@ -4,7 +4,6 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.common.Constants;
import mineplex.core.CustomTagFix;
import mineplex.core.PacketsInteractionFix;
import mineplex.core.account.CoreClientManager;
@ -72,14 +71,18 @@ import static mineplex.core.Managers.require;
*/
public class ClansHub extends JavaPlugin
{
private String WEB_CONFIG = "webServer";
@Override
public void onEnable()
{
Bukkit.setSpawnRadius(0);
getConfig().addDefault(Constants.WEB_CONFIG_KEY, Constants.WEB_ADDRESS);
getConfig().set(Constants.WEB_CONFIG_KEY, getConfig().getString(Constants.WEB_CONFIG_KEY));
getConfig().addDefault(WEB_CONFIG, "http://accounts.mineplex.com/");
getConfig().set(WEB_CONFIG, getConfig().getString(WEB_CONFIG));
saveConfig();
String webServerAddress = getConfig().getString(WEB_CONFIG);
//Logger.initialize(this);
//Velocity Fix
@ -96,7 +99,7 @@ public class ClansHub extends JavaPlugin
Recharge.Initialize(this);
VisibilityManager.Initialize(this); Give.Initialize(this);
Punish punish = new Punish(this, clientManager);
BlockRestore blockRestore = new BlockRestore(this);
BlockRestore blockRestore = require(BlockRestore.class);
DonationManager donationManager = require(DonationManager.class);
ServerConfiguration serverConfiguration = new ServerConfiguration(this, clientManager);

View File

@ -117,7 +117,7 @@ public class Hub extends JavaPlugin implements IRelation
Recharge.Initialize(this);
VisibilityManager.Initialize(this); Give.Initialize(this);
Punish punish = new Punish(this, clientManager);
BlockRestore blockRestore = new BlockRestore(this);
BlockRestore blockRestore = require(BlockRestore.class);
DonationManager donationManager = require(DonationManager.class);
ServerConfiguration serverConfiguration = new ServerConfiguration(this, clientManager);
@ -226,7 +226,7 @@ public class Hub extends JavaPlugin implements IRelation
//Updates
getServer().getScheduler().scheduleSyncRepeatingTask(this, new Updater(this), 1, 1);
BrandingManager brandingManager = new BrandingManager(this);
BrandingManager brandingManager = require(BrandingManager.class);
new BillboardManager(this, brandingManager);
require(TrackManager.class);

View File

@ -4,9 +4,6 @@ import mineplex.core.MiniPlugin;
import mineplex.core.common.events.ServerShutdownEvent;
import mineplex.core.sponsorbranding.BrandingManager;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.ItemFrame;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;

View File

@ -1,20 +1,20 @@
package mineplex.staffServer.salespackage.salespackages;
import org.bukkit.entity.Player;
import mineplex.staffServer.salespackage.SalesPackageManager;
public class MinestrikeChest extends SalesPackageBase
{
public MinestrikeChest(SalesPackageManager manager)
{
super(manager, "1 Minestrike Chest");
}
public void displayToAgent(Player agent, String playerName)
{
addButton(agent, "/sales item " + playerName + " 1 Item Minestrike Chest", "Give 1 Minestrike Chest.");
agent.sendMessage(" ");
addBackButton(agent, playerName);
}
package mineplex.staffServer.salespackage.salespackages;
import org.bukkit.entity.Player;
import mineplex.staffServer.salespackage.SalesPackageManager;
public class MinestrikeChest extends SalesPackageBase
{
public MinestrikeChest(SalesPackageManager manager)
{
super(manager, "1 Minestrike Chest");
}
public void displayToAgent(Player agent, String playerName)
{
addButton(agent, "/sales item " + playerName + " 1 Item Minestrike Chest", "Give 1 Minestrike Chest.");
agent.sendMessage(" ");
addBackButton(agent, playerName);
}
}

View File

@ -162,7 +162,7 @@ public class Arcade extends JavaPlugin
new SnapshotPlugin(this, snapshotManager, _clientManager);
new ReportPlugin(this, reportManager);
BlockRestore blockRestore = new BlockRestore(this);
BlockRestore blockRestore = require(BlockRestore.class);
ProjectileManager projectileManager = new ProjectileManager(this);
HologramManager hologramManager = new HologramManager(this, packetHandler);

View File

@ -288,7 +288,7 @@ public class ArcadeManager extends MiniPlugin implements IRelation
_conditionManager = new SkillConditionManager(plugin);
_brandingManager = new BrandingManager(plugin);
_brandingManager = require(BrandingManager.class);
_boosterManager = boosterManager;

View File

@ -1,51 +1,51 @@
package nautilus.game.arcade.command;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.gadget.event.TauntCommandEvent;
import mineplex.core.gadget.gadgets.taunts.GameType;
import mineplex.minecraft.game.core.combat.CombatManager;
import nautilus.game.arcade.ArcadeManager;
import nautilus.game.arcade.game.Game;
public class TauntCommand extends CommandBase<ArcadeManager>
{
private ArcadeManager _arcadeManager;
public TauntCommand(ArcadeManager manager)
{
super(manager, Rank.ALL, "taunt");
_arcadeManager = manager;
}
@Override
public void Execute(Player player, String[] args)
{
boolean pvp = false;
CombatManager combatManager = Managers.get(CombatManager.class);
if (combatManager != null)
{
pvp = UtilTime.elapsed(combatManager.Get(player).GetLastCombatEngaged(), 5000 * 60);
}
Game game = _arcadeManager.GetGame();
GameType gameType = GameType.NONE;
if (game != null)
{
gameType = GameType.valueOf(game.GetType().toString().toUpperCase());
}
TauntCommandEvent event = new TauntCommandEvent(player, _arcadeManager.isGameInProgress(),
_arcadeManager.GetGame().IsAlive(player), UtilPlayer.isSpectator(player), combatManager.Get(player).GetLastCombatEngaged(),
gameType);
Bukkit.getPluginManager().callEvent(event);
}
}
package nautilus.game.arcade.command;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.gadget.event.TauntCommandEvent;
import mineplex.core.gadget.gadgets.taunts.GameType;
import mineplex.minecraft.game.core.combat.CombatManager;
import nautilus.game.arcade.ArcadeManager;
import nautilus.game.arcade.game.Game;
public class TauntCommand extends CommandBase<ArcadeManager>
{
private ArcadeManager _arcadeManager;
public TauntCommand(ArcadeManager manager)
{
super(manager, Rank.ALL, "taunt");
_arcadeManager = manager;
}
@Override
public void Execute(Player player, String[] args)
{
boolean pvp = false;
CombatManager combatManager = Managers.get(CombatManager.class);
if (combatManager != null)
{
pvp = UtilTime.elapsed(combatManager.Get(player).GetLastCombatEngaged(), 5000 * 60);
}
Game game = _arcadeManager.GetGame();
GameType gameType = GameType.NONE;
if (game != null)
{
gameType = GameType.valueOf(game.GetType().toString().toUpperCase());
}
TauntCommandEvent event = new TauntCommandEvent(player, _arcadeManager.isGameInProgress(),
_arcadeManager.GetGame().IsAlive(player), UtilPlayer.isSpectator(player), combatManager.Get(player).GetLastCombatEngaged(),
gameType);
Bukkit.getPluginManager().callEvent(event);
}
}

View File

@ -328,7 +328,7 @@ public class PvP extends JavaPlugin implements IPlugin, Listener
public BlockRestore GetBlockRestore()
{
if (_blockRestore == null)
_blockRestore = new BlockRestore(this);
_blockRestore = require(BlockRestore.class);
return _blockRestore;
}

View File

@ -118,7 +118,7 @@ public class Hub extends JavaPlugin
Chat chat = new Chat(this, incognito, _clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName());
new MessageManager(this, incognito, _clientManager, preferenceManager, ignoreManager, punish, friendManager, chat);
BlockRestore blockRestore = new BlockRestore(this);
BlockRestore blockRestore = require(BlockRestore.class);
ProjectileManager projectileManager = new ProjectileManager(this);
HologramManager hologramManager = new HologramManager(this, packetHandler);

View File

@ -0,0 +1,5 @@
name: GemHunters
main: mineplex.gemhunters.GemHunters
version: 0.1
commands:
playwire:

View File

@ -0,0 +1,27 @@
<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>
<parent>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-plugin</artifactId>
<version>dev-SNAPSHOT</version>
<relativePath>../plugin.xml</relativePath>
</parent>
<name>GemHunters</name>
<artifactId>mineplex-game-gemhunters</artifactId>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mineplex-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mineplex-minecraft-game-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,308 @@
package mineplex.gemhunters;
import net.minecraft.server.v1_8_R3.MinecraftServer;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.SpigotConfig;
import mineplex.core.CustomTagFix;
import mineplex.core.FoodDupeFix;
import mineplex.core.TimingsFix;
import mineplex.core.account.CoreClientManager;
import mineplex.core.achievement.AchievementManager;
import mineplex.core.antihack.AntiHack;
import mineplex.core.beta.BetaWhitelist;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.boosters.BoosterManager;
import mineplex.core.chat.Chat;
import mineplex.core.command.CommandCenter;
import mineplex.core.common.Constants;
import mineplex.core.common.events.ServerShutdownEvent;
import mineplex.core.communities.CommunityManager;
import mineplex.core.cosmetic.CosmeticManager;
import mineplex.core.creature.Creature;
import mineplex.core.delayedtask.DelayedTask;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.donation.DonationManager;
import mineplex.core.elo.EloManager;
import mineplex.core.explosion.Explosion;
import mineplex.core.friend.FriendManager;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.give.Give;
import mineplex.core.hologram.HologramManager;
import mineplex.core.ignore.IgnoreManager;
import mineplex.core.incognito.IncognitoManager;
import mineplex.core.inventory.InventoryManager;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.core.memory.MemoryFix;
import mineplex.core.menu.MenuManager;
import mineplex.core.message.MessageManager;
import mineplex.core.monitor.LagMeter;
import mineplex.core.mount.MountManager;
import mineplex.core.npc.NpcManager;
import mineplex.core.packethandler.PacketHandler;
import mineplex.core.party.PartyManager;
import mineplex.core.pet.PetManager;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Portal;
import mineplex.core.powerplayclub.PowerPlayClubRepository;
import mineplex.core.preferences.PreferencesManager;
import mineplex.core.projectile.ProjectileManager;
import mineplex.core.punish.Punish;
import mineplex.core.recharge.Recharge;
import mineplex.core.serverConfig.ServerConfiguration;
import mineplex.core.stats.StatsManager;
import mineplex.core.status.ServerStatusManager;
import mineplex.core.teleport.Teleport;
import mineplex.core.thank.ThankManager;
import mineplex.core.twofactor.TwoFactorAuth;
import mineplex.core.updater.FileUpdater;
import mineplex.core.updater.Updater;
import mineplex.core.visibility.VisibilityManager;
import mineplex.gemhunters.beta.BetaModule;
import mineplex.gemhunters.bounties.BountyModule;
import mineplex.gemhunters.chat.ChatModule;
import mineplex.gemhunters.death.DeathModule;
import mineplex.gemhunters.death.npc.NPCManager;
import mineplex.gemhunters.economy.CashOutModule;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.loot.InventoryModule;
import mineplex.gemhunters.loot.LootModule;
import mineplex.gemhunters.map.ItemMapModule;
import mineplex.gemhunters.mount.MountModule;
import mineplex.gemhunters.quest.QuestModule;
import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.scoreboard.ScoreboardModule;
import mineplex.gemhunters.shop.ShopModule;
import mineplex.gemhunters.spawn.SpawnModule;
import mineplex.gemhunters.supplydrop.SupplyDropModule;
import mineplex.gemhunters.world.DebugListeners;
import mineplex.gemhunters.world.TimeCycle;
import mineplex.gemhunters.world.UndergroundMobs;
import mineplex.gemhunters.world.WorldListeners;
import mineplex.gemhunters.worldevent.WorldEventModule;
import mineplex.minecraft.game.core.combat.CombatManager;
import mineplex.minecraft.game.core.condition.ConditionManager;
import mineplex.minecraft.game.core.damage.DamageManager;
import static mineplex.core.Managers.require;
/**
* Gem Hunters main class <br>
*
* TODO make documentation and a nice header
*
* @author Sam
*/
public class GemHunters extends JavaPlugin
{
@Override
public void onEnable()
{
// Load configuration
getConfig().addDefault(Constants.WEB_CONFIG_KEY, Constants.WEB_ADDRESS);
getConfig().set(Constants.WEB_CONFIG_KEY, getConfig().getString(Constants.WEB_CONFIG_KEY));
saveConfig();
// Load core modules
CommandCenter.Initialize(this);
// Client Manager
CoreClientManager clientManager = new CoreClientManager(this);
// Donation Manager
DonationManager donationManager = require(DonationManager.class);
// Command Centre
CommandCenter.Instance.setClientManager(clientManager);
// Timings
require(TimingsFix.class);
// ItemStacks
ItemStackFactory.Initialize(this, false);
// Delayed Tasks
DelayedTask.Initialize(this);
// Recharge
Recharge.Initialize(this);
// Visibility
VisibilityManager.Initialize(this);
// Give
Give.Initialize(this);
// Server config
ServerConfiguration serverConfig = new ServerConfiguration(this, clientManager);
// Teleport
new Teleport(this, clientManager);
// Packets
PacketHandler packetHandler = require(PacketHandler.class);
// Vanish
IncognitoManager incognito = new IncognitoManager(this, clientManager, packetHandler);
// Preferences
PreferencesManager preferenceManager = new PreferencesManager(this, incognito, clientManager);
// Why do these depend on each other... :(
incognito.setPreferencesManager(preferenceManager);
// Server Status
ServerStatusManager serverStatusManager = new ServerStatusManager(this, clientManager, new LagMeter(this, clientManager));
// Portal
Portal portal = new Portal();
// File Updater
new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.BETA_HUB);
// Punish
Punish punish = new Punish(this, clientManager);
// Disguises
DisguiseManager disguiseManager = require(DisguiseManager.class);
// Creatures
Creature creature = new Creature(this);
// The old classic Damage Manager
new DamageManager(this, new CombatManager(this), new NpcManager(this, creature), disguiseManager, new ConditionManager(this));
// GWEN
require(AntiHack.class);
// Block Restore
BlockRestore blockRestore = require(BlockRestore.class);
// Ignoring
IgnoreManager ignoreManager = new IgnoreManager(this, clientManager, preferenceManager, portal);
// Statistics
StatsManager statsManager = new StatsManager(this, clientManager);
// Elo
EloManager eloManager = new EloManager(this, clientManager);
// Achievements
AchievementManager achievementManager = new AchievementManager(statsManager, clientManager, donationManager, incognito, eloManager);
// Chat/Messaging
Chat chat = new Chat(this, incognito, clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName());
new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, new FriendManager(this, clientManager, preferenceManager, portal), chat);
// Parties
new PartyManager();
// Communities
new CommunityManager(this, clientManager);
// Fixes
new MemoryFix(this);
new FoodDupeFix(this);
// Explosions
Explosion explosion = new Explosion(this, blockRestore);
explosion.SetDebris(true);
explosion.SetTemporaryDebris(false);
// Inventories
InventoryManager inventoryManager = new InventoryManager(this, clientManager);
// Reports
// SnapshotManager snapshotManager = new SnapshotManager(this, new
// SnapshotRepository(serverStatusManager.getCurrentServerName(),
// getLogger()));
// new SnapshotPlugin(this, snapshotManager, clientManager);
// new ReportPlugin(this, new ReportManager(this, snapshotManager,
// clientManager, incognito, punish, serverStatusManager.getRegion(),
// serverStatusManager.getCurrentServerName(), 1));
// Tag fix
new CustomTagFix(this, packetHandler);
// Holograms
HologramManager hologramManager = new HologramManager(this, packetHandler);
// Menus
new MenuManager(this);
// Gadgets, used for mounts, lots of managers for something really small
// :(
MountManager mountManager = new MountManager(this, clientManager, donationManager, blockRestore, disguiseManager);
PetManager petManager = new PetManager(this, clientManager, donationManager, inventoryManager, disguiseManager, creature, blockRestore);
ProjectileManager projectileManager = new ProjectileManager(this);
GadgetManager gadgetManager = new GadgetManager(this, clientManager, donationManager, inventoryManager, mountManager, petManager, preferenceManager, disguiseManager, blockRestore, projectileManager, achievementManager, packetHandler, hologramManager, incognito);
ThankManager thankManager = new ThankManager(this, clientManager, donationManager);
BoosterManager boosterManager = new BoosterManager(this, null, clientManager, donationManager, inventoryManager, thankManager);
CosmeticManager cosmeticManager = new CosmeticManager(this, clientManager, donationManager, inventoryManager, gadgetManager, mountManager, petManager, null, boosterManager);
cosmeticManager.setActive(false);
// Now we finally get to enable the Gem Hunters modules
// Though if any other module needs one of these it will be generated in
// order, however they are all here just for good measure.s
require(BetaModule.class);
//require(DebugModule.class);
require(BountyModule.class);
require(CashOutModule.class);
require(ChatModule.class);
require(DeathModule.class);
require(EconomyModule.class);
require(InventoryModule.class);
require(LootModule.class);
require(ItemMapModule.class);
require(MountModule.class);
require(QuestModule.class);
require(SafezoneModule.class);
require(ScoreboardModule.class);
require(SpawnModule.class);
require(ShopModule.class);
require(SupplyDropModule.class);
require(WorldEventModule.class);
// An arbitrary collection of world listeners such as block place/break,
// interact events etc...
new WorldListeners(this);
new TimeCycle(this);
new UndergroundMobs(this);
new DebugListeners(this);
// Combat npc
new NPCManager(hologramManager);
// UpdateEvent!!!
new Updater(this);
// Disable spigot's item merging
for (World world : getServer().getWorlds())
{
((CraftWorld) world).getHandle().spigotConfig.itemMerge = 0;
}
// Turn off the server's debugging
MinecraftServer.getServer().getPropertyManager().setProperty("debug", false);
SpigotConfig.debug = false;
// Two-factor auth
require(TwoFactorAuth.class);
// beta whitelist
new BetaWhitelist(clientManager, new PowerPlayClubRepository(this, clientManager, donationManager));
}
@Override
public void onDisable()
{
getServer().getPluginManager().callEvent(new ServerShutdownEvent(this));
}
}

View File

@ -0,0 +1,49 @@
package mineplex.gemhunters.beta;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
@ReflectivelyCreateMiniPlugin
public class BetaModule extends MiniPlugin
{
private static final String[] ANNOUCEMENTS = {
"Please remember this game is an early access BETA and all bugs should be reported at mineplex.com/forums/m/11929946/viewforum/8006500 .",
"Thank you for playing Gem Hunters!",
"Many more features are being added over the coming days!",
"Players in your party show up on your map!",
"Safezones are marked as green areas on your map!",
"Players that have super valuable items show up on your map!"
};
private int _lastIndex;
private BetaModule()
{
super("Beta");
}
@EventHandler
public void annouce(UpdateEvent event)
{
if (event.getType() != UpdateType.MIN_01)
{
return;
}
Bukkit.broadcastMessage(F.main(C.cRedB + "BETA", C.cYellow + ANNOUCEMENTS[_lastIndex]));
if (++_lastIndex == ANNOUCEMENTS.length)
{
_lastIndex = 0;
}
}
}

View File

@ -0,0 +1,36 @@
package mineplex.gemhunters.bounties;
import java.util.UUID;
import org.bukkit.entity.Player;
public class Bounty
{
private UUID _target;
private UUID _setter;
private int _amount;
public Bounty(Player target, Player setter, int amount)
{
_target = target.getUniqueId();
_setter = setter.getUniqueId();
_amount = amount;
}
public UUID getTarget()
{
return _target;
}
public UUID getSetter()
{
return _setter;
}
public int getAmount()
{
return _amount;
}
}

View File

@ -0,0 +1,46 @@
package mineplex.gemhunters.bounties;
import java.net.MalformedURLException;
import java.net.URL;
import org.bukkit.block.BlockFace;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.sponsorbranding.BrandingManager;
@ReflectivelyCreateMiniPlugin
public class BountyModule extends MiniPlugin
{
private final BrandingManager _brandingManager;
private BountyModule()
{
super("Bounty");
_brandingManager = require(BrandingManager.class);
}
//@EventHandler
public void test(PlayerCommandPreprocessEvent event)
{
if (!event.getMessage().startsWith("/want"))
{
return;
}
try
{
event.setCancelled(true);
_brandingManager.createPost(event.getPlayer().getLocation(), BlockFace.SOUTH, new URL("http://minotar.net/helm/Moppletop.png"));
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,75 @@
package mineplex.gemhunters.chat;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.account.CoreClientManager;
import mineplex.core.chat.Chat;
import mineplex.core.common.Rank;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
/**
* This module handles player chat.
*/
@ReflectivelyCreateMiniPlugin
public class ChatModule extends MiniPlugin
{
private final CoreClientManager _clientManager;
private final Chat _chat;
private ChatModule()
{
super("Chat");
_clientManager = require(CoreClientManager.class);
_chat = require(Chat.class);
}
@EventHandler(priority = EventPriority.LOWEST)
public void playerJoin(PlayerJoinEvent event)
{
event.setJoinMessage(F.sys("Join", event.getPlayer().getName()));
}
@EventHandler(priority = EventPriority.LOWEST)
public void playerQuit(PlayerQuitEvent event)
{
event.setQuitMessage(F.sys("Quit", event.getPlayer().getName()));
}
@EventHandler(priority = EventPriority.HIGHEST)
public void chat(AsyncPlayerChatEvent event)
{
// Checks if the player has been muted/chat is silenced etc...
if (event.isCancelled())
{
return;
}
Player player = event.getPlayer();
String playerName = player.getName();
Rank rank = _clientManager.Get(player).getRealOrDisguisedRank();
String rankString = rank == Rank.ALL ? "" : rank.getTag(true, true);
// Create a message that follows the rest of the network's chat format
String message = (rankString + " " + C.cYellow + playerName + " " + C.cWhite + _chat.getFilteredMessage(player, event.getMessage())).trim();
// We will handle the broadcast
event.setCancelled(true);
for (Player other : event.getRecipients())
{
other.sendMessage(message);
}
}
}

View File

@ -0,0 +1,198 @@
package mineplex.gemhunters.death;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import com.google.common.collect.Sets;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.core.visibility.VisibilityManager;
import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent;
import mineplex.gemhunters.spawn.SpawnModule;
/**
* This module handles anything to do with a players death
*/
@ReflectivelyCreateMiniPlugin
public class DeathModule extends MiniPlugin
{
// Some items like the cash out item (and for some reason players drop
// bones?) don't need to be dropped to avoid duplication.
private static final Set<Material> DISALLOWED_DROPS = Sets.newHashSet(Material.EMERALD, Material.MAP, Material.BONE, Material.STAINED_GLASS_PANE);
private static final int DEATH_ANIMATION_TIME = 7000;
private static final int DEATH_ANIMATION_COUNTDOWN = 2000;
private final SpawnModule _spawn;
private final Map<UUID, Long> _toRemove;
private DeathModule()
{
super("Death");
_spawn = require(SpawnModule.class);
_toRemove = new HashMap<>();
}
@EventHandler
public void join(PlayerJoinEvent event)
{
PlayerCustomRespawnEvent event2 = new PlayerCustomRespawnEvent(event.getPlayer());
UtilServer.CallEvent(event2);
}
@EventHandler
public void death(PlayerDeathEvent event)
{
Player player = event.getEntity();
// Stop the player dieing
player.setHealth(20);
player.setFoodLevel(20);
player.setExhaustion(0);
startAnimation(player);
_toRemove.put(player.getUniqueId(), System.currentTimeMillis());
}
@EventHandler
public void itemSpawn(ItemSpawnEvent event)
{
if (DISALLOWED_DROPS.contains(event.getEntity().getItemStack().getType()))
{
event.setCancelled(true);
}
}
@EventHandler
public void updateAnimations(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
Iterator<UUID> iterator = _toRemove.keySet().iterator();
while (iterator.hasNext())
{
UUID key = iterator.next();
Player player = UtilPlayer.searchExact(key);
if (player == null)
{
iterator.remove();
continue;
}
long start = _toRemove.get(key);
long end = start + DEATH_ANIMATION_TIME + 1000;
if (UtilTime.elapsed(start, DEATH_ANIMATION_TIME))
{
stopAnimation(player);
_toRemove.remove(key);
continue;
}
else if (UtilTime.elapsed(start, DEATH_ANIMATION_COUNTDOWN))
{
UtilTextMiddle.display(C.cRedB + "YOU DIED", String.valueOf((int) (end - System.currentTimeMillis()) / 1000), 0, 20, 0, player);
}
}
}
public void startAnimation(Player player)
{
UtilTextMiddle.display(C.cRedB + "YOU DIED", "Respawning shortly", 0, 60, 0, player);
VisibilityManager.Instance.setVisibility(player, false, UtilServer.getPlayers());
((CraftPlayer) player).getHandle().spectating = true;
player.setAllowFlight(true);
player.setFlying(true);
player.setGameMode(GameMode.CREATIVE);
}
public void stopAnimation(Player player)
{
UtilTextMiddle.display(C.cGreenB + "RESPAWNED", "", 0, 20, 20, player);
VisibilityManager.Instance.setVisibility(player, true, UtilServer.getPlayers());
((CraftPlayer) player).getHandle().spectating = false;
player.setFlying(false);
player.setAllowFlight(false);
player.setGameMode(GameMode.SURVIVAL);
_spawn.teleportToSpawn(player);
PlayerCustomRespawnEvent event = new PlayerCustomRespawnEvent(player);
UtilServer.CallEvent(event);
}
@EventHandler
public void itemPickup(PlayerPickupItemEvent event)
{
if (_toRemove.containsKey(event.getPlayer().getUniqueId()))
{
event.setCancelled(true);
}
}
@EventHandler
public void blockBreak(BlockBreakEvent event)
{
if (_toRemove.containsKey(event.getPlayer().getUniqueId()))
{
event.setCancelled(true);
}
}
@EventHandler
public void blockPlace(BlockPlaceEvent event)
{
if (_toRemove.containsKey(event.getPlayer().getUniqueId()))
{
event.setCancelled(true);
}
}
@EventHandler
public void inventory(InventoryClickEvent event)
{
if (_toRemove.containsKey(event.getWhoClicked().getUniqueId()))
{
event.setCancelled(true);
}
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
_toRemove.remove(event.getPlayer().getUniqueId());
}
}

View File

@ -0,0 +1,27 @@
package mineplex.gemhunters.death.event;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class PlayerCustomRespawnEvent extends PlayerEvent
{
private static final HandlerList HANDLERS = new HandlerList();
public PlayerCustomRespawnEvent(Player who)
{
super(who);
}
public HandlerList getHandlers()
{
return HANDLERS;
}
public static HandlerList getHandlerList()
{
return HANDLERS;
}
}

View File

@ -0,0 +1,238 @@
package mineplex.gemhunters.death.npc;
import java.io.File;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Skeleton;
import org.bukkit.metadata.FixedMetadataValue;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.disguise.disguises.DisguisePlayer;
import mineplex.core.hologram.Hologram;
import mineplex.core.hologram.HologramManager;
public class CombatLogNPC
{
public final static EntityType NPC_TYPE = EntityType.VILLAGER;
private PlayerInfo _playerInfo;
private Hologram _hologram;
private DisguiseManager _disguiseManager;
private long _spawnDate;
private final long _endingTime;
private double _spawnHealth;
private boolean _creative;
private LivingEntity _npc;
private ArmorStand _stand;
private CraftLivingEntity _lastDamager;
public int getEntityId()
{
return _npc.getEntityId();
}
public CombatLogNPC(Player player, DisguiseManager disguiseManager, HologramManager hologramManager, boolean wasCreative)
{
_playerInfo = new PlayerInfo(player);
_creative = wasCreative;
_disguiseManager = disguiseManager;
_hologram = new Hologram(hologramManager, player.getEyeLocation().add(0, 1, 0), C.cYellow + UtilTime.MakeStr(NPCManager.COMBAT_LOG_DURATION) + C.cWhite + " Seconds left before despawn");
_spawnDate = 0;
_endingTime = System.currentTimeMillis() + NPCManager.COMBAT_LOG_DURATION;
_spawnHealth = player.getHealth();
_hologram.start();
}
/**
* Called when the {@code _npc} associated with this CombatLogNPC is killed
* and thus drops all the owner's items.
*/
public void onDeath(CraftLivingEntity killer)
{
Location location = _npc.getLocation();
World world = location.getWorld();
File file = new File(world.getWorldFolder(), String.format("playerdata/%s.dat", _playerInfo.getPlayerUuid()));
file.delete(); // Delete the player's .dat file so they will join with
// empty inventory/respawn on next login
if (killer != null)
{
String killerName = "Unknown";
if (killer instanceof CraftPlayer)
{
killerName = ((CraftPlayer) killer).getName();
}
else
{
killerName = UtilEnt.getName(killer);
}
// try
// {
// DataOutputStream stream = new DataOutputStream(new FileOutputStream(_userDataPath + String.format("DEATH_%s.dat", _playerInfo.getPlayerUuid())));
//
// stream.writeLong(System.currentTimeMillis());
// stream.writeInt(killerName.length());
// stream.writeBytes(killerName);
//
// stream.close();
// }
// catch (IOException e)
// {
// System.out.println(String.format("FATAL ERROR while trying to create player death lock for %s, meaning %s will not be informed that they died next time they log in.", _playerInfo.getPlayerName(), _playerInfo.getPlayerName()));
// }
UtilServer.broadcast(F.main("Death", F.elem(_playerInfo.getPlayerName()) + " was killed by " + F.elem(killerName) + " while combat logged."));
}
_playerInfo.dropItems(location);
_disguiseManager.undisguise(_npc);
}
public void update()
{
_hologram.setText("Quitting in " + UtilTime.MakeStr(Math.max(_endingTime - System.currentTimeMillis(), 0)));
}
/**
* @return true, if the {@code _npc} associated with this CombatLogNPC is
* alive, false otherwise.
*/
public boolean isAlive()
{
return _npc != null && !_npc.isDead();
}
/**
* @return the amount of time (in milliseconds) that this npc has been alive
* an spawned in.
*/
public long getAliveDuation()
{
return System.currentTimeMillis() - _spawnDate;
}
public void spawn()
{
if (_npc != null) despawn();
_npc = spawnNpc(getPlayer());
_spawnDate = System.currentTimeMillis();
}
public void despawn()
{
System.out.println("Despawning");
if (_npc != null)
{
if (_stand != null)
{
_stand.setPassenger(null);
_stand.remove();
_stand = null;
}
_npc.remove();
_npc = null;
_hologram.stop();
_hologram = null;
}
}
public void remove()
{
if (_hologram != null)
{
_hologram.stop();
_hologram = null;
}
}
public PlayerInfo getPlayerInfo()
{
return _playerInfo;
}
public Player getPlayer()
{
return _playerInfo.getPlayer();
}
public boolean matchesPlayer(Player player)
{
return _playerInfo.getPlayerName().equalsIgnoreCase(player.getName());
}
private LivingEntity spawnNpc(Player player)
{
Location spawnLoc = player.getLocation();
Skeleton skel = player.getWorld().spawn(spawnLoc, Skeleton.class);
skel.setMetadata("CombatLogNPC", new FixedMetadataValue(UtilServer.getPlugin(), player.getUniqueId().toString()));
skel.teleport(spawnLoc);
skel.setHealth(_spawnHealth);
UtilEnt.vegetate(skel);
UtilEnt.silence(skel, true);
skel.getEquipment().setHelmet(player.getInventory().getHelmet());
skel.getEquipment().setChestplate(player.getInventory().getChestplate());
skel.getEquipment().setLeggings(player.getInventory().getLeggings());
skel.getEquipment().setBoots(player.getInventory().getBoots());
skel.getEquipment().setItemInHand(player.getItemInHand());
// Get in range
List<Player> inRange = UtilPlayer.getNearby(spawnLoc, 75d);
// Disguise
DisguisePlayer disguise = new DisguisePlayer(skel, ((CraftPlayer) player).getHandle().getProfile());
_disguiseManager.disguise(disguise, attempted -> inRange.contains(attempted));
if (!UtilEnt.isGrounded(player))
{
ArmorStand stand = player.getWorld().spawn(spawnLoc.clone().subtract(0,1,0), ArmorStand.class);
stand.setVisible(false);
stand.setPassenger(skel);
stand.setGravity(false);
_stand = stand;
}
return skel;
}
public boolean wasCreative()
{
return _creative;
}
public CraftLivingEntity getLastDamager()
{
return _lastDamager;
}
public void setLastDamager(CraftLivingEntity damager)
{
_lastDamager = damager;
}
}

View File

@ -0,0 +1,262 @@
package mineplex.gemhunters.death.npc;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Sound;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftLivingEntity;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityCombustEvent;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.metadata.FixedMetadataValue;
import mineplex.core.MiniPlugin;
import mineplex.core.disguise.DisguiseManager;
import mineplex.core.hologram.HologramManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.economy.PlayerCashOutCompleteEvent;
import mineplex.minecraft.game.core.damage.CustomDamageEvent;
public class NPCManager extends MiniPlugin
{
public static final long COMBAT_LOG_DURATION = 30000;
private static NPCManager _instance;
public static NPCManager getInstance()
{
return _instance;
}
private Set<CombatLogNPC> _logoutNpcs;
private Set<Integer> _toKillIds;
private Set<UUID> _cashedOutPreventNPCs = new HashSet<>();
private HologramManager _hologramManager;
public NPCManager(HologramManager hologramManager)
{
super("NPC Manager");
_instance = this;
_logoutNpcs = new HashSet<>();
_toKillIds = new HashSet<>();
_hologramManager = hologramManager;
}
@EventHandler
public void onCashOut(PlayerCashOutCompleteEvent event)
{
_cashedOutPreventNPCs.add(event.getPlayer().getUniqueId());
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
NPCManager.getInstance().spawnLogoutNpc(event.getPlayer());
}
@Override
public void disable()
{
log("Killing logout npcs");
// Despawn/kill all combat log NPCs on server shutdown
for (CombatLogNPC npc : _logoutNpcs)
{
npc.despawn();
}
_logoutNpcs.clear();
}
public void spawnLogoutNpc(Player player)
{
if (!_cashedOutPreventNPCs.remove(player.getUniqueId()) && !hasLogoutNpc(player))
{
CombatLogNPC npc = new CombatLogNPC(player, require(DisguiseManager.class), _hologramManager, player.getGameMode().equals(GameMode.CREATIVE));
npc.spawn();
_logoutNpcs.add(npc);
log(String.format("Spawned combat log NPC for %s!", player.getName()));
}
}
@EventHandler
public void killNpcs(PlayerJoinEvent event)
{
for (LivingEntity entity : Bukkit.getWorlds().get(0).getLivingEntities())
{
if (entity.hasMetadata("CombatLogNPC") && ((FixedMetadataValue) entity.getMetadata("CombatLogNPC").get(0)).asString().equals(event.getPlayer().getUniqueId().toString()))
{
entity.remove();
}
}
}
public void despawnLogoutNpc(Player player)
{
CombatLogNPC npc = getLogoutNpc(player);
if (npc != null)
{
_toKillIds.add(npc.getEntityId());
npc.despawn();
_logoutNpcs.remove(npc);
log(String.format("Despawned combat log NPC for %s!", player.getName()));
}
}
public boolean hasLogoutNpc(Player player)
{
return getLogoutNpc(player) != null;
}
public CombatLogNPC getLogoutNpc(Player player)
{
for (CombatLogNPC logoutNpc : _logoutNpcs)
{
if (logoutNpc.matchesPlayer(player))
{
return logoutNpc;
}
}
return null;
}
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event)
{
for (Entity entity : event.getChunk().getEntities())
{
for (CombatLogNPC npc : _logoutNpcs)
{
if (entity.getEntityId() == npc.getEntityId())
{
event.setCancelled(true);
break;
}
}
}
}
@EventHandler(ignoreCancelled = true)
public void onEntityDeath(EntityDeathEvent event)
{
CombatLogNPC logoutNpc = getLogoutNpc(event.getEntity());
if (logoutNpc != null)
{
logoutNpc.onDeath(logoutNpc.getLastDamager());
event.getDrops().clear(); // Clear the entity's item drops. Manually
// drops combat log items earlier
}
}
@EventHandler(ignoreCancelled = true)
public void onEntityDamaged(CustomDamageEvent event)
{
CombatLogNPC logoutNpc = getLogoutNpc(event.GetDamageeEntity());
if (logoutNpc != null && event.GetDamagerEntity(true) != null)
{
if (logoutNpc.wasCreative())
{
event.SetCancelled("Cannot hurt creative player");
return;
}
if (event.GetDamagerPlayer(true) != null)
{
event.GetDamagerPlayer(true).playSound(event.GetDamagerPlayer(true).getLocation(), Sound.HURT_FLESH, 1, 1);
}
logoutNpc.setLastDamager(((CraftLivingEntity) event.GetDamagerEntity(true)));
event.SetKnockback(false);
}
}
@EventHandler
public void onEntityIgnite(EntityCombustEvent event)
{
if (isLogoutNpc(event.getEntity()))
{
event.setCancelled(true);
}
}
@EventHandler
public void onUpdate(UpdateEvent event)
{
if (event.getType() == UpdateType.FASTER)
{
for (CombatLogNPC npc : _logoutNpcs)
{
npc.update();
}
}
if (event.getType() == UpdateType.SEC)
{
Iterator<CombatLogNPC> iterator = _logoutNpcs.iterator();
while (iterator.hasNext())
{
CombatLogNPC npc = iterator.next();
if (Bukkit.getPlayer(npc.getPlayerInfo().getPlayerName()) != null)
{
System.out.println("{NPCMANAGER} ORIGINAL PLAYER ALIVE AND DESPAWNING");
npc.despawn();
iterator.remove();
}
else if (!npc.isAlive())
{
System.out.println("{NPCMANAGER} NOT ALIVE AND REMOVING");
npc.remove();
iterator.remove();
}
else if (npc.getAliveDuation() > COMBAT_LOG_DURATION)
{
System.out.println("{NPCMANAGER} DESPAWNING");
npc.despawn();
iterator.remove();
}
}
}
}
private boolean isLogoutNpc(Entity entity)
{
return getLogoutNpc(entity) != null;
}
private CombatLogNPC getLogoutNpc(Entity entity)
{
return getLogoutNpc(entity.getEntityId());
}
private CombatLogNPC getLogoutNpc(int entityId)
{
for (CombatLogNPC npc : _logoutNpcs)
{
if (npc.getEntityId() == entityId)
{
return npc;
}
}
return null;
}
}

View File

@ -0,0 +1,92 @@
package mineplex.gemhunters.death.npc;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import mineplex.gemhunters.loot.InventoryModule;
public class PlayerInfo
{
private String _playerName;
private UUID _playerUuid;
private ItemStack[] _armor;
private List<ItemStack> _items;
private Location _location;
public PlayerInfo(Player player)
{
_playerName = player.getName();
_playerUuid = player.getUniqueId();
_armor = player.getInventory().getArmorContents();
_items = fetchItems(player.getInventory());
_location = player.getLocation();
}
public void dropItems(Location location)
{
World world = location.getWorld();
for (ItemStack item : _items)
{
world.dropItemNaturally(location, item);
}
}
public void restore()
{
Player player = getPlayer();
player.getInventory().clear();
player.getInventory().setArmorContents(_armor);
player.getInventory().addItem(_items.toArray(new ItemStack[0]));
player.teleport(_location);
}
public String getPlayerName()
{
return _playerName;
}
public UUID getUniqueId()
{
return _playerUuid;
}
public String getPlayerUuid()
{
return _playerUuid.toString();
}
public Player getPlayer()
{
return Bukkit.getPlayerExact(_playerName);
}
private List<ItemStack> fetchItems(PlayerInventory inventory)
{
List<ItemStack> items = new ArrayList<>();
addItems(items, inventory.getContents());
return items;
}
private void addItems(List<ItemStack> items, ItemStack[] itemsToAdd)
{
for (ItemStack item : itemsToAdd)
{
if (item != null && item.getType() != Material.AIR && !item.isSimilar(InventoryModule.LOCKED))
{
items.add(item);
}
}
}
}

View File

@ -0,0 +1,276 @@
package mineplex.gemhunters.economy;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.donation.DonationManager;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Intent;
import mineplex.core.portal.Portal;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent;
@ReflectivelyCreateMiniPlugin
public class CashOutModule extends MiniPlugin
{
private static final DecimalFormat ARMOUR_STAND_FORMAT = new DecimalFormat("0.0");
private static final ItemStack CASH_OUT_ITEM = new ItemBuilder(Material.EMERALD).setTitle(C.cGreen + "Cash Out").addLore("", C.cGray + "Click to begin the process to cash out.", C.cGray + "Cashing out saves your current loot.").build();
private static final int CASH_OUT_COOLDOWN = 10000;
private static final int CASH_OUT_MAX_MOVE_DISTANCE_SQUARED = 4;
private final DonationManager _donation;
private final Map<UUID, CashOutSession> _sessions;
public CashOutModule()
{
super("Cash Out");
_donation = require(DonationManager.class);
_sessions = new HashMap<>();
}
@EventHandler
public void teleportIn(PlayerTeleportIntoMapEvent event)
{
if (event.isCancelled())
{
return;
}
event.getPlayer().getInventory().setItem(7, CASH_OUT_ITEM);
}
@EventHandler
public void playerInteract(PlayerInteractEvent event)
{
if (!UtilEvent.isAction(event, ActionType.R))
{
return;
}
Player player = event.getPlayer();
ItemStack itemStack = player.getItemInHand();
if (itemStack == null)
{
return;
}
if (!itemStack.isSimilar(CASH_OUT_ITEM))
{
return;
}
attemptCashOut(player);
}
@EventHandler
public void itemDrop(PlayerDropItemEvent event)
{
if (event.getItemDrop().getItemStack().isSimilar(CASH_OUT_ITEM))
{
event.getPlayer().sendMessage(F.main("Game", "You cannot drop the " + F.item("Cash Out Item") + "."));
event.setCancelled(true);
}
}
@EventHandler
public void inventoryClick(InventoryClickEvent event)
{
ItemStack itemStack = event.getCurrentItem();
if (itemStack == null)
{
return;
}
if (!itemStack.isSimilar(CASH_OUT_ITEM))
{
return;
}
event.setCancelled(true);
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
}
@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
Iterator<UUID> iterator = _sessions.keySet().iterator();
while (iterator.hasNext())
{
UUID key = iterator.next();
Player player = UtilPlayer.searchExact(key);
CashOutSession session = _sessions.get(key);
double current = session.getCurrent();
ArmorStand stand = session.getArmourStand();
String standName = ARMOUR_STAND_FORMAT.format(current);
if (player == null)
{
session.endSession();
iterator.remove();
continue;
}
UtilTextMiddle.display(C.cGreen + standName, UtilTextMiddle.progress((float) (1 - current / session.getMax())), 0, 10, 0, player);
stand.setCustomName(standName + " seconds");
session.setCurrent(current - 0.05);
if (session.getCurrent() <= 0)
{
PlayerCashOutCompleteEvent completeEvent = new PlayerCashOutCompleteEvent(player);
UtilServer.CallEvent(completeEvent);
_donation.rewardCurrencyUntilSuccess(GlobalCurrency.GEM, player, "Earned", completeEvent.getGems());
session.endSession();
iterator.remove();
Portal.getInstance().sendPlayerToGenericServer(player, GenericServer.BETA_HUB, Intent.FORCE_TRANSFER);
}
}
}
@EventHandler
public void updateMove(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
{
return;
}
for (UUID key : _sessions.keySet())
{
Player player = UtilPlayer.searchExact(key);
CashOutSession session = _sessions.get(key);
if (session.getLocation().distanceSquared(player.getLocation()) > CASH_OUT_MAX_MOVE_DISTANCE_SQUARED)
{
cancelCashOut(player, "You moved!");
}
}
}
@EventHandler
public void entityDamage(EntityDamageEvent event)
{
if (!(event.getEntity() instanceof Player))
{
return;
}
Player player = (Player) event.getEntity();
if (isCashingOut(player))
{
cancelCashOut(player, "You took damage!");
}
}
@EventHandler
public void entityAttack(EntityDamageByEntityEvent event)
{
if (!(event.getDamager() instanceof Player) || event.getEntity() instanceof ArmorStand)
{
return;
}
Player player = (Player) event.getDamager();
if (isCashingOut(player))
{
cancelCashOut(player, "You attacked a player!");
}
}
public void attemptCashOut(Player player)
{
UUID key = player.getUniqueId();
if (_sessions.containsKey(key))
{
player.sendMessage(F.main("Game", "You are already cashing out."));
return;
}
if (!Recharge.Instance.use(player, "Cash Out", CASH_OUT_COOLDOWN, true, false))
{
return;
}
// Test time
_sessions.put(key, new CashOutSession(player, 10));
}
public void cancelCashOut(Player player, String message)
{
UUID key = player.getUniqueId();
CashOutSession session = _sessions.get(key);
player.sendMessage(F.main("Game", message + " Your cash out has been cancelled."));
session.endSession();
_sessions.remove(key);
}
public boolean isCashingOut(Player player)
{
return getCashOutSession(player) != null;
}
public CashOutSession getCashOutSession(Player player)
{
for (UUID key : _sessions.keySet())
{
if (key.equals(player.getUniqueId()))
{
return _sessions.get(key);
}
}
return null;
}
}

View File

@ -0,0 +1,58 @@
package mineplex.gemhunters.economy;
import org.bukkit.Location;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
public class CashOutSession
{
private double _current;
private double _max;
private ArmorStand _stand;
private Location _location;
public CashOutSession(Player player, double max)
{
_current = max;
_max = max;
_stand = player.getWorld().spawn(player.getLocation().add(0, 0.5, 0), ArmorStand.class);
_stand.setCustomNameVisible(true);
_stand.setVisible(false);
_stand.setGravity(false);
_location = player.getLocation();
}
public void endSession()
{
_stand.remove();
}
public void setCurrent(double current)
{
_current = current;
}
public double getCurrent()
{
return _current;
}
public double getMax()
{
return _max;
}
public ArmorStand getArmourStand()
{
return _stand;
}
public Location getLocation()
{
return _location;
}
}

View File

@ -0,0 +1,110 @@
package mineplex.gemhunters.economy;
import java.util.UUID;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.PlayerDeathEvent;
import mineplex.core.MiniClientPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F;
import mineplex.core.donation.DonationManager;
import mineplex.core.donation.Donor;
import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent;
import mineplex.gemhunters.economy.command.GiveGemsCommand;
import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent;
@ReflectivelyCreateMiniPlugin
public class EconomyModule extends MiniClientPlugin<Integer>
{
private static final float GEM_KILL_FACTOR = 0.5F;
private static final int GEM_START_COST = 100;
private final DonationManager _donation;
public EconomyModule()
{
super("Economy");
_donation = require(DonationManager.class);
}
@Override
public void addCommands()
{
addCommand(new GiveGemsCommand(this));
}
@EventHandler
public void respawn(PlayerCustomRespawnEvent event)
{
addToStore(event.getPlayer(), null, GEM_START_COST);
}
@EventHandler
public void teleportIn(PlayerTeleportIntoMapEvent event)
{
Player player = event.getPlayer();
Donor donor = _donation.Get(event.getPlayer());
if (donor.getBalance(GlobalCurrency.GEM) >= GEM_START_COST)
{
_donation.purchaseUnknownSalesPackage(player, "Gem Hunters Access", GlobalCurrency.GEM, GEM_START_COST, false, null);
}
}
@EventHandler
public void death(PlayerDeathEvent event)
{
Player player = event.getEntity();
Entity killer = event.getEntity().getKiller();
int oldGems = getGems(player);
if (killer instanceof Player)
{
Player killerPlayer = (Player) killer;
int newGems = (int) (oldGems * GEM_KILL_FACTOR);
addToStore(killerPlayer, "Killing " + F.name(player.getName()), newGems);
}
removeFromStore(player, oldGems);
}
@EventHandler
public void cashOut(PlayerCashOutCompleteEvent event)
{
event.incrementGems(getGems(event.getPlayer()));
}
public void addToStore(Player player, String reason, int gems)
{
Set(player, Get(player) + gems);
if (reason != null)
{
player.sendMessage(F.main(_moduleName, "+" + F.currency(GlobalCurrency.GEM, gems) + " (" + reason + ")."));
}
}
public void removeFromStore(Player player, int gems)
{
addToStore(player, null, -gems);
}
public int getGems(Player player)
{
return Get(player);
}
@Override
protected Integer addPlayer(UUID uuid)
{
return 0;
}
}

View File

@ -0,0 +1,44 @@
package mineplex.gemhunters.economy;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class PlayerCashOutCompleteEvent extends PlayerEvent
{
private static final HandlerList HANDLERS = new HandlerList();
private int _gems;
public PlayerCashOutCompleteEvent(Player player)
{
super(player);
}
public void incrementGems(int gems)
{
_gems += gems;
}
public void setGems(int gems)
{
_gems = gems;
}
public int getGems()
{
return _gems;
}
public HandlerList getHandlers()
{
return HANDLERS;
}
public static HandlerList getHandlerList()
{
return HANDLERS;
}
}

View File

@ -0,0 +1,47 @@
package mineplex.gemhunters.economy.command;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilPlayer;
import mineplex.gemhunters.economy.EconomyModule;
public class GiveGemsCommand extends CommandBase<EconomyModule>
{
public GiveGemsCommand(EconomyModule plugin)
{
super(plugin, Rank.ADMIN, "givegems");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length < 2)
{
caller.sendMessage(F.help("/" + _aliasUsed + " <player> <amount>", "Adds an amount of gems to a player's gems earned.", Rank.ADMIN));
return;
}
Player target = UtilPlayer.searchOnline(caller, args[0], true);
if (target == null)
{
return;
}
try
{
int amount = Integer.parseInt(args[1]);
Plugin.addToStore(target, "Given by " + F.name(caller.getName()), amount);
}
catch (NumberFormatException e)
{
caller.sendMessage(F.main(Plugin.getName(), "That is not a number."));
}
}
}

View File

@ -0,0 +1,107 @@
package mineplex.gemhunters.loot;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Material;
public class ChestProperties
{
private final String _name;
private final Material _blockMaterial;
private final String _dataKey;
private final int _minAmount;
private final int _maxAmount;
private final int _maxChestPerLoc;
private final int _spawnRate;
private final int _expireRate;
private final int _spawnRadius;
private final int _maxActive;
private final Map<Integer, Integer> _spawnedIndexes;
private long _lastSpawn;
public ChestProperties(String name, Material blockMaterial, String dataKey, int minAmount, int maxAmount, int maxChestPerLoc, int spawnRate, int expireRate, int spawnRadius, int maxActive)
{
_name = name;
_blockMaterial = blockMaterial;
_dataKey = dataKey;
_minAmount = minAmount;
_maxAmount = maxAmount;
_maxChestPerLoc = maxChestPerLoc;
_spawnRate = spawnRate;
_expireRate = expireRate;
_spawnRadius = spawnRadius;
_maxActive = maxActive;
_spawnedIndexes = new HashMap<>();
setLastSpawn();
}
public final String getName()
{
return _name;
}
public final Material getBlockMaterial()
{
return _blockMaterial;
}
public final String getDataKey()
{
return _dataKey;
}
public final int getMinAmount()
{
return _minAmount;
}
public final int getMaxAmount()
{
return _maxAmount;
}
public final int getMaxChestPerLocation()
{
return _maxChestPerLoc;
}
public final int getSpawnRate()
{
return _spawnRate;
}
public final int getExpireRate()
{
return _expireRate;
}
public final int getSpawnRadius()
{
return _spawnRadius;
}
public final int getMaxActive()
{
return _maxActive;
}
public final Map<Integer, Integer> getSpawnIndexes()
{
return _spawnedIndexes;
}
public void setLastSpawn()
{
_lastSpawn = System.currentTimeMillis();
}
public long getLastSpawn()
{
return _lastSpawn;
}
}

View File

@ -0,0 +1,133 @@
package mineplex.gemhunters.loot;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilInv;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent;
@ReflectivelyCreateMiniPlugin
public class InventoryModule extends MiniPlugin
{
public static final ItemStack LOCKED = new ItemBuilder(Material.STAINED_GLASS_PANE, (byte) 15).setTitle(C.cGray + "Locked").build();
private static final int START_INDEX = 9;
private static final String ITEM_METADATA = "UNLOCKER";
private final LootModule _loot;
private final Map<UUID, Integer> _slotsUnlocked;
private InventoryModule()
{
super("Unlocker");
_loot = require(LootModule.class);
_slotsUnlocked = new HashMap<>();
}
@EventHandler
public void respawn(PlayerCustomRespawnEvent event)
{
Player player = event.getPlayer();
Inventory inv = player.getInventory();
_slotsUnlocked.put(player.getUniqueId(), 0);
for (int i = START_INDEX; i < inv.getSize(); i++)
{
inv.setItem(i, LOCKED);
}
}
@EventHandler
public void quit(PlayerQuitEvent event)
{
_slotsUnlocked.remove(event.getPlayer().getUniqueId());
}
@EventHandler
public void inventoryClick(InventoryClickEvent event)
{
Player player = (Player) event.getWhoClicked();
if (event.getClickedInventory() == null || event.getCurrentItem() == null)
{
return;
}
if (event.getCurrentItem().isSimilar(LOCKED))
{
event.setCancelled(true);
player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0.6F);
}
}
@EventHandler
public void interact(PlayerInteractEvent event)
{
if (!UtilEvent.isAction(event, ActionType.R))
{
return;
}
Player player = event.getPlayer();
ItemStack itemStack = player.getItemInHand();
if (itemStack == null)
{
return;
}
LootItem lootItem = _loot.fromItemStack(itemStack);
if (lootItem == null || lootItem.getMetadata() == null || !lootItem.getMetadata().equals(ITEM_METADATA))
{
return;
}
player.setItemInHand(UtilInv.decrement(itemStack));
unlockSlots(player, itemStack.getType() == Material.CHEST ? 9 : 18);
}
public void unlockSlots(Player player, int slots)
{
Inventory inv = player.getInventory();
UUID key = player.getUniqueId();
int start = START_INDEX + _slotsUnlocked.get(key);
int end = Math.min(inv.getSize(), start + slots);
int delta = end - start;
//DebugModule.getInstance().d("start=" + start);
//DebugModule.getInstance().d("end=" + end);
//DebugModule.getInstance().d("delta=" + delta);
for (int i = start; i < end; i++)
{
inv.setItem(i, null);
}
player.sendMessage(F.main(_moduleName, "You unlocked an additional " + F.count(String.valueOf(delta)) + " slots of your inventory!"));
_slotsUnlocked.put(key, _slotsUnlocked.get(key) + slots);
}
}

View File

@ -0,0 +1,90 @@
package mineplex.gemhunters.loot;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.UtilMath;
/**
* Represents an item that can be contained in a chest inside the Gem Hunters
* world.
*/
public class LootItem
{
private final ItemStack _itemStack;
private final int _minAmount;
private final int _maxAmount;
private final double _probability;
private final String _metadata;
public LootItem(ItemStack itemStack, int minAmount, int maxAmount, double probability, String metadata)
{
_itemStack = itemStack;
_minAmount = minAmount;
_maxAmount = maxAmount;
_probability = probability;
_metadata = metadata;
}
/**
* Returns the Minecraft {@link ItemStack} bound to this
* {@link LootItem}.<br>
* The {@link ItemStack} returned will have an amount/size between the
* minAmount and maxAmount integers (set within the constuctor's parameters)
* inclusively.
*
* @return
*/
public ItemStack getItemStack()
{
_itemStack.setAmount(_minAmount + UtilMath.r(_maxAmount - _minAmount + 1));
return _itemStack;
}
/**
* The minimum amount or size an {@link ItemStack} of this {@link LootItem}
* can have.
*
* @return
*/
public int getMinAmount()
{
return _minAmount;
}
/**
* The maximum amount or size an {@link ItemStack} of this {@link LootItem}
* can have.
*
* @return
*/
public int getMaxAmount()
{
return _maxAmount;
}
/**
* The double value of the item's probability of being chosen to when
* picking an individual chest's loot.
*
* @return
*/
public double getProbability()
{
return _probability;
}
/**
* Any metadata bound to a {@link LootItem}. Useful for determining if an
* item has a particular <i>skill</i> or <i>ability</i> attached to it which
* you can use in code.
*
* @return
*/
public String getMetadata()
{
return _metadata;
}
}

View File

@ -0,0 +1,662 @@
package mineplex.gemhunters.loot;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.Chest;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilInv;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.google.GoogleSheetsManager;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.economy.PlayerCashOutCompleteEvent;
import mineplex.gemhunters.loot.command.SpawnChestCommand;
import mineplex.gemhunters.loot.command.UpdateLootCommand;
import mineplex.gemhunters.loot.deserialisers.ChestPropertiesDeserialiser;
import mineplex.gemhunters.loot.deserialisers.LootItemDeserialiser;
import mineplex.gemhunters.loot.event.PlayerChestOpenEvent;
import mineplex.gemhunters.loot.rewards.LootChestReward;
import mineplex.gemhunters.loot.rewards.LootGadgetReward;
import mineplex.gemhunters.loot.rewards.LootItemReward;
import mineplex.gemhunters.loot.rewards.LootRankReward;
import mineplex.gemhunters.loot.rewards.LootShardReward;
import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent;
import mineplex.gemhunters.util.SlackSheetsBot;
import mineplex.gemhunters.world.WorldDataModule;
@ReflectivelyCreateMiniPlugin
public class LootModule extends MiniPlugin
{
private static final String SHEET_FILE_NAME = "GEM_HUNTERS_CHESTS";
private static final String CHEST_MASTER_SHEET_NAME = "CHEST_MASTER";
private static final long CHEST_DESPAWN_TIME_OPENED = TimeUnit.SECONDS.toMillis(15);
private static final float CHESTS_ON_START_FACTOR = 0.333F;
private static final int MAX_SEARCH_ATTEMPTS = 40;
private static final int MAX_CHEST_CHECK_DISTANCE_SQUARED = 4;
private static final LootItemDeserialiser DESERIALISER = new LootItemDeserialiser();
private static final ChestPropertiesDeserialiser CHEST_DESERIALISER = new ChestPropertiesDeserialiser();
private static final ItemStack[] SPAWN_ITEMS = {
new ItemStack(Material.WOOD_SWORD),
new ItemStack(Material.APPLE, 3),
};
private static final String GEM_METADATA = "GEM";
private final EconomyModule _economy;
private final GoogleSheetsManager _sheets;
private final SafezoneModule _safezone;
private final WorldDataModule _worldData;
private final Map<String, Set<LootItem>> _chestLoot;
private final Map<String, ChestProperties> _chestProperties;
private final Set<SpawnedChest> _spawnedChest;
private final Set<LootItemReward> _itemRewards;
private final Set<UUID> _shownPlayers;
private LootModule()
{
super("Loot");
_economy = require(EconomyModule.class);
_sheets = require(GoogleSheetsManager.class);
_safezone = require(SafezoneModule.class);
_worldData = require(WorldDataModule.class);
_chestLoot = new HashMap<>();
_chestProperties = new HashMap<>();
_spawnedChest = new HashSet<>();
_itemRewards = new HashSet<>();
_shownPlayers = new HashSet<>();
runSyncLater(() -> {
updateChestLoot();
// Spawn some chests
for (String key : _chestProperties.keySet())
{
int max = _chestProperties.get(key).getMaxActive();
for (int i = 0; i < max * CHESTS_ON_START_FACTOR; i++)
{
addSpawnedChest(key, true);
}
}
}, 20);
}
@Override
public void addCommands()
{
addCommand(new UpdateLootCommand(this));
addCommand(new SpawnChestCommand(this));
}
@EventHandler
public void updateSpawnChests(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
// Despawn opened chests
Iterator<SpawnedChest> iterator = _spawnedChest.iterator();
while (iterator.hasNext())
{
SpawnedChest chest = iterator.next();
ChestProperties properties = chest.getProperties();
if (chest.isOpened() && UtilTime.elapsed(chest.getOpenedAt(), CHEST_DESPAWN_TIME_OPENED) || UtilTime.elapsed(chest.getSpawnedAt(), properties.getExpireRate()))
{
if (chest.getID() != -1)
{
properties.getSpawnIndexes().put(chest.getID(), properties.getSpawnIndexes().get(chest.getID()) - 1);
}
Block block = chest.getLocation().getBlock();
if (block.getState() instanceof Chest)
{
((Chest) block.getState()).getBlockInventory().clear();
}
block.getWorld().playEffect(chest.getLocation(), Effect.STEP_SOUND, block.getType());
block.setType(Material.AIR);
iterator.remove();
}
}
// Spawn new chests
for (String key : _chestProperties.keySet())
{
addSpawnedChest(key, false);
}
}
public boolean isSuitable(Block block)
{
Block up = block.getRelative(BlockFace.UP);
Block down = block.getRelative(BlockFace.DOWN);
if (block.getType() != Material.AIR || up.getType() != Material.AIR || down.getType() == Material.AIR || UtilBlock.liquid(down) || UtilBlock.liquid(up) || UtilBlock.liquid(block) || _safezone.isInSafeZone(block.getLocation()))
{
return false;
}
return true;
}
public void updateChestLoot()
{
log("Updating chest loot");
Map<String, List<List<String>>> map = _sheets.getSheetData(SHEET_FILE_NAME);
for (String key : map.keySet())
{
if (key.equals(CHEST_MASTER_SHEET_NAME))
{
int row = 0;
for (List<String> rows : map.get(key))
{
row++;
try
{
ChestProperties properties = CHEST_DESERIALISER.deserialise(rows.toArray(new String[0]));
_chestProperties.put(properties.getDataKey(), properties);
}
catch (Exception e)
{
if (row != 1)
{
SlackSheetsBot.reportParsingError(e, "Chest Loot", key, row);
}
continue;
}
}
continue;
}
Set<LootItem> items = new HashSet<>();
int row = 0;
for (List<String> rows : map.get(key))
{
row++;
try
{
items.add(DESERIALISER.deserialise(rows.toArray(new String[0])));
}
catch (Exception e)
{
if (row != 1)
{
SlackSheetsBot.reportParsingError(e, "Chest Loot", key, row);
}
continue;
}
}
_chestLoot.put(key, items);
}
log("Finished updating chest loot");
}
public void addSpawnedChest(String key, boolean force)
{
if (key.equals("PURPLE") && Bukkit.getOnlinePlayers().size() < 10)
{
return;
}
List<Location> locations = _worldData.getDataLocation(key);
ChestProperties properties = _chestProperties.get(key);
if (!force && !UtilTime.elapsed(properties.getLastSpawn(), properties.getSpawnRate()))
{
return;
}
properties.setLastSpawn();
// Only spawn more chests if we need to
int max = properties.getMaxActive();
int spawned = 0;
for (SpawnedChest chest : _spawnedChest)
{
if (chest.getProperties().getDataKey().equals(key))
{
spawned++;
}
}
// If there are too many chests of this type we can ignore it
if (spawned > max)
{
return;
}
if (locations.isEmpty())
{
return;
}
Map<Integer, Integer> spawnedIndexes = properties.getSpawnIndexes();
Location randomLocation = null;
boolean found = false;
int attempts = 0;
int index = -1;
while (index == -1 || !found && attempts < MAX_SEARCH_ATTEMPTS)
{
attempts++;
index = UtilMath.r(locations.size());
if (spawnedIndexes.getOrDefault(index, 0) >= properties.getMaxChestPerLocation())
{
continue;
}
}
if (index == -1)
{
return;
}
spawnedIndexes.put(index, spawnedIndexes.getOrDefault(index, 0) + 1);
randomLocation = locations.get(index);
int placeRadius = properties.getSpawnRadius();
Location chestToPlace = UtilAlg.getRandomLocation(randomLocation, placeRadius, 0, placeRadius);
Block block = chestToPlace.getBlock();
attempts = 0;
boolean suitable = false;
while (!suitable && attempts < MAX_SEARCH_ATTEMPTS)
{
chestToPlace = UtilAlg.getRandomLocation(randomLocation, placeRadius, 0, placeRadius);
block = chestToPlace.getBlock();
suitable = isSuitable(block);
attempts++;
}
if (!suitable)
{
return;
}
//DebugModule.getInstance().d("Spawned at " + UtilWorld.blockToStrClean(block) + " with key=" + key + " and index=" + index + " and max=" + spawned + "/" + max);
_spawnedChest.add(new SpawnedChest(chestToPlace, properties, index));
block.setType(properties.getBlockMaterial());
}
public void addSpawnedChest(Location location, String colour)
{
_spawnedChest.add(new SpawnedChest(location, _chestProperties.get(colour), -1));
}
public void fillChest(Player player, Block block, String key)
{
Set<Integer> used = new HashSet<>();
Set<LootItem> items = _chestLoot.get(key);
ChestProperties properties = _chestProperties.get(key);
Inventory inventory = null;
if (block.getType() == Material.ENDER_CHEST)
{
inventory = player.getEnderChest();
}
else
{
BlockState state = block.getState();
Chest chest = (Chest) state;
inventory = chest.getBlockInventory();
}
inventory.clear();
for (int i = 0; i < UtilMath.rRange(properties.getMinAmount(), properties.getMaxAmount()); i++)
{
LootItem lootItem = getRandomItem(items);
ItemStack itemStack = lootItem.getItemStack();
int index = getFreeIndex(inventory.getSize(), used);
inventory.setItem(index, itemStack);
}
}
public LootItem getRandomItem(Set<LootItem> items)
{
double totalWeight = 0;
for (LootItem item : items)
{
totalWeight += item.getProbability();
}
double select = Math.random() * totalWeight;
for (LootItem item : items)
{
if ((select -= item.getProbability()) <= 0)
{
return item;
}
}
return null;
}
private int getFreeIndex(int endIndex, Set<Integer> used)
{
int index = -1;
while (index == -1 || used.contains(index))
{
index = UtilMath.r(endIndex);
}
used.add(index);
return index;
}
public LootItem fromItemStack(ItemStack itemStack)
{
if (itemStack == null)
{
return null;
}
for (Set<LootItem> items : _chestLoot.values())
{
for (LootItem item : items)
{
if (item.getItemStack().isSimilar(itemStack))
{
return item;
}
}
}
return null;
}
public boolean hasChestBeenOpened(Location location)
{
for (SpawnedChest chest : _spawnedChest)
{
if (chest.getLocation().distanceSquared(location) < MAX_CHEST_CHECK_DISTANCE_SQUARED && chest.isOpened())
{
return true;
}
}
return false;
}
@EventHandler
public void chestOpen(PlayerInteractEvent event)
{
if (event.isCancelled() || !UtilEvent.isAction(event, ActionType.R_BLOCK))
{
return;
}
Player player = event.getPlayer();
Block block = event.getClickedBlock();
if (block.getType() != Material.CHEST && block.getType() != Material.ENDER_CHEST)
{
return;
}
if (hasChestBeenOpened(block.getLocation()))
{
return;
}
String key = null;
for (SpawnedChest chest : _spawnedChest)
{
if (UtilMath.offsetSquared(chest.getLocation(), block.getLocation()) < MAX_CHEST_CHECK_DISTANCE_SQUARED)
{
key = chest.getProperties().getDataKey();
chest.setOpened();
break;
}
}
if (key == null)
{
event.setCancelled(true);
return;
}
PlayerChestOpenEvent openEvent = new PlayerChestOpenEvent(player, block, _chestProperties.get(key));
UtilServer.CallEvent(openEvent);
if (openEvent.isCancelled())
{
event.setCancelled(true);
return;
}
fillChest(player, block, key);
}
@EventHandler
public void inventoryClick(InventoryClickEvent event)
{
if (event.getClickedInventory() == null)
{
return;
}
ItemStack itemStack = event.getCurrentItem();
if (itemStack == null)
{
return;
}
handleRewardItem((Player) event.getWhoClicked(), itemStack);
}
@EventHandler
public void pickupItem(PlayerPickupItemEvent event)
{
if (event.getItem() == null)
{
return;
}
handleRewardItem(event.getPlayer(), event.getItem().getItemStack());
}
public void handleRewardItem(Player player, ItemStack itemStack)
{
LootItem lootItem = fromItemStack(itemStack);
if (lootItem == null || lootItem.getMetadata() == null)
{
return;
}
LootItemReward reward = null;
for (LootItemReward storedReward : _itemRewards)
{
if (storedReward.getItemStack().isSimilar(itemStack))
{
reward = storedReward;
}
}
if (reward == null)
{
String[] metadataSplit = lootItem.getMetadata().split(" ");
String key = metadataSplit[0];
String[] values = new String[metadataSplit.length - 1];
for (int i = 1; i < metadataSplit.length; i++)
{
values[i - 1] = metadataSplit[i];
}
switch (key)
{
case "RANK_UPGRADE":
reward = new LootRankReward(itemStack);
break;
case "SHARD":
reward = new LootShardReward(Integer.parseInt(values[0]) * 1000, itemStack, Integer.parseInt(values[1]));
break;
case "CHEST":
reward = new LootChestReward(Integer.parseInt(values[0]) * 1000, itemStack, values[1], Integer.parseInt(values[2]));
break;
case "GADGET":
String gadget = "";
for (int i = 1; i < values.length; i++)
{
gadget += values[i] + " ";
}
reward = new LootGadgetReward(Integer.parseInt(values[0]) * 1000, itemStack, gadget.trim());
break;
default:
return;
}
_itemRewards.add(reward);
}
reward.collectItem(player);
}
@EventHandler
public void gemClick(PlayerInteractEvent event)
{
if (!UtilEvent.isAction(event, ActionType.R))
{
return;
}
Player player = event.getPlayer();
ItemStack itemStack = player.getItemInHand();
if (itemStack == null)
{
return;
}
LootItem lootItem = fromItemStack(itemStack);
if (lootItem == null || lootItem.getMetadata() == null || !lootItem.getMetadata().startsWith(GEM_METADATA))
{
return;
}
player.setItemInHand(UtilInv.decrement(itemStack));
int amount = Integer.parseInt(lootItem.getMetadata().split(" ")[1]);
_economy.addToStore(player, "Gem Item", amount);
}
@EventHandler
public void mapUpdate(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
_shownPlayers.clear();
for (Player player : Bukkit.getOnlinePlayers())
{
UUID key = player.getUniqueId();
for (LootItemReward itemReward : _itemRewards)
{
if (itemReward.getPlayer().equals(player))
{
_shownPlayers.add(key);
break;
}
}
}
}
@EventHandler
public void mapTeleport(PlayerTeleportIntoMapEvent event)
{
event.getPlayer().getInventory().addItem(SPAWN_ITEMS);
}
@EventHandler
public void cashOutComplete(PlayerCashOutCompleteEvent event)
{
Player player = event.getPlayer();
Iterator<LootItemReward> iterator = _itemRewards.iterator();
while (iterator.hasNext())
{
LootItemReward reward = iterator.next();
if (player.equals(reward.getPlayer()))
{
reward.success();
iterator.remove();
}
}
}
public final Set<UUID> getShownPlayers()
{
return _shownPlayers;
}
}

View File

@ -0,0 +1,59 @@
package mineplex.gemhunters.loot;
import org.bukkit.Location;
public class SpawnedChest
{
private Location _location;
private ChestProperties _properties;
private int _id;
private long _spawnedAt;
private long _openedAt;
public SpawnedChest(Location location, ChestProperties properties, int id)
{
_location = location;
_properties =properties;
_id = id;
_spawnedAt = System.currentTimeMillis();
_openedAt = 0;
}
public void setOpened()
{
_openedAt = System.currentTimeMillis();
}
public Location getLocation()
{
return _location;
}
public ChestProperties getProperties()
{
return _properties;
}
public int getID()
{
return _id;
}
public long getSpawnedAt()
{
return _spawnedAt;
}
public long getOpenedAt()
{
return _openedAt;
}
public boolean isOpened()
{
return _openedAt != 0;
}
}

View File

@ -0,0 +1,47 @@
package mineplex.gemhunters.loot.command;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.gemhunters.loot.LootModule;
public class SpawnChestCommand extends CommandBase<LootModule>
{
public SpawnChestCommand(LootModule plugin)
{
super(plugin, Rank.ADMIN, "spawnchest");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length == 0)
{
caller.sendMessage(F.help("/" + _aliasUsed + " <colour>", "Spawns a chest at your location.", GetRequiredRank()));
return;
}
String colour = args[0].toUpperCase();
try
{
DyeColor.valueOf(colour);
}
catch (IllegalArgumentException e)
{
caller.sendMessage(F.main(Plugin.getName(), "That is not a valid colour."));
return;
}
caller.sendMessage(F.main(Plugin.getName(), "Spawned a " + colour + " chest at your location."));
caller.getLocation().getBlock().setType(Material.CHEST);
Plugin.addSpawnedChest(caller.getLocation(), colour);
}
}

View File

@ -0,0 +1,33 @@
package mineplex.gemhunters.loot.command;
import org.bukkit.entity.Player;
import mineplex.core.command.CommandBase;
import mineplex.core.common.Rank;
import mineplex.core.common.util.F;
import mineplex.gemhunters.loot.LootModule;
/**
* An ADMIN command that allows users to retrieve the latest data from the
* google sheet and update all locally cached loot tables.
*/
public class UpdateLootCommand extends CommandBase<LootModule>
{
public UpdateLootCommand(LootModule plugin)
{
super(plugin, Rank.ADMIN, "updateloot");
}
@Override
public void Execute(Player caller, String[] args)
{
if (args.length > 1)
{
// TODO send redis message
}
caller.sendMessage(F.main(Plugin.getName(), "This command is currently disabled due to development issues."));
}
}

View File

@ -0,0 +1,43 @@
package mineplex.gemhunters.loot.deserialisers;
import org.bukkit.Material;
import mineplex.core.google.SheetObjectDeserialiser;
import mineplex.gemhunters.loot.ChestProperties;
public class ChestPropertiesDeserialiser implements SheetObjectDeserialiser<ChestProperties>
{
@Override
public ChestProperties deserialise(String[] values) throws ArrayIndexOutOfBoundsException
{
String name = values[0];
Material blockMaterial = Material.valueOf(values[1]);
String dataKey = values[2];
int minAmount = 1;
int maxAmount = 1;
String[] numbers = values[3].split("-");
if (numbers.length != 2)
{
minAmount = Integer.parseInt(String.valueOf(values[3]));
maxAmount = minAmount;
}
else
{
minAmount = Integer.parseInt(numbers[0]);
maxAmount = Integer.parseInt(numbers[1]);
}
int spawnRate = Integer.parseInt(values[4]);
int expireRate = Integer.parseInt(values[5]);
int maxChestsPerLoc = Integer.parseInt(values[6]);
int spawnRadius = Integer.parseInt(values[7]);
int maxActive = Integer.parseInt(values[8]);
return new ChestProperties(name, blockMaterial, dataKey, minAmount, maxAmount, maxChestsPerLoc, spawnRate, expireRate, spawnRadius, maxActive);
}
}

View File

@ -0,0 +1,100 @@
package mineplex.gemhunters.loot.deserialisers;
import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import mineplex.core.google.SheetObjectDeserialiser;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.gemhunters.loot.LootItem;
import net.md_5.bungee.api.ChatColor;
/**
* This is a {@link LootItem} deserialiser for Google Sheet interpretation.<br>
* <br>
* Arguments should follow the form:<br>
* <ul>
* <li>Material</li>
* <li>Material Data</li>
* <li>Max Durability</li>
* <li>Amount</li>
* <li>Item Name <i>(optional)</i></li>
* <li>Item Lore <i>(optional) each line separated by colons</i></li>
* <li>Enchantments <i>(optional) Has a NAME:LEVEL format with multiple
* enchantments being separated by commas</i></li>
* <li>Probability</li>
* <li>Metadata <i>(optional)</i></li>
* </ul>
* Thus derserialise is guaranteed to have at least 8 strings passed in.<br>
* If an illegal argument is passed in, derserialise will throw an exception,
* these should be handled by the caller.
*
* @see SheetObjectDeserialiser
*/
public class LootItemDeserialiser implements SheetObjectDeserialiser<LootItem>
{
@Override
public LootItem deserialise(String[] values) throws ArrayIndexOutOfBoundsException, IllegalArgumentException, NumberFormatException
{
Material material = Material.valueOf(values[0]);
byte data = values[1].equals("") ? 0 : Byte.parseByte(values[1]);
int minAmount = 1;
int maxAmount = 1;
short durability = values[2].equals("") ? 0 : Short.valueOf(values[3]);
String[] numbers = values[3].split("-");
if (numbers.length != 2)
{
minAmount = Integer.parseInt(values[3].equals("") ? "1" : values[3]);
maxAmount = minAmount;
}
else
{
minAmount = Integer.parseInt(numbers[0]);
maxAmount = Integer.parseInt(numbers[1]);
}
ItemBuilder builder = new ItemBuilder(material, data);
builder.setDurability(durability);
String title = ChatColor.translateAlternateColorCodes('&', values[4]);
builder.setTitle(title);
if (!values[5].equals(""))
{
String[] lore = values[5].split(":");
String[] colouredLore = new String[lore.length];
int loreIndex = 0;
for (String line : lore)
{
colouredLore[loreIndex++] = ChatColor.translateAlternateColorCodes('&', line);
}
builder.setLore(colouredLore);
}
String[] enchants = String.valueOf(values[6]).split(",");
for (String enchant : enchants)
{
String[] enchantData = enchant.split(":");
if (enchantData.length < 2)
{
continue;
}
builder.addEnchantment(Enchantment.getByName(enchantData[0]), Integer.parseInt(enchantData[1]));
}
double proability = Double.parseDouble(values[7]);
String metadata = values.length > 8 ? values[8] : null;
return new LootItem(builder.build(), minAmount, maxAmount, proability, metadata);
}
}

View File

@ -0,0 +1,60 @@
package mineplex.gemhunters.loot.event;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import mineplex.gemhunters.loot.ChestProperties;
public class PlayerChestOpenEvent extends PlayerEvent implements Cancellable
{
private static final HandlerList HANDLERS = new HandlerList();
private boolean _cancel;
private final Block _block;
private final ChestProperties _properties;
public PlayerChestOpenEvent(Player who, Block block, ChestProperties properties)
{
super(who);
_block = block;
_properties = properties;
}
public Block getChest()
{
return _block;
}
public ChestProperties getProperties()
{
return _properties;
}
public HandlerList getHandlers()
{
return HANDLERS;
}
public static HandlerList getHandlerList()
{
return HANDLERS;
}
@Override
public boolean isCancelled()
{
return _cancel;
}
@Override
public void setCancelled(boolean cancel)
{
_cancel = cancel;
}
}

View File

@ -0,0 +1,52 @@
package mineplex.gemhunters.loot.rewards;
import org.bukkit.inventory.ItemStack;
import mineplex.core.Managers;
import mineplex.core.common.util.Callback;
import mineplex.core.inventory.InventoryManager;
public class LootChestReward extends LootItemReward
{
private final InventoryManager _inventory;
private final String _chestName;
private final int _amount;
public LootChestReward(long cashOutDelay, ItemStack itemStack, String chestName, int amount)
{
super(chestName + " Chest", cashOutDelay, itemStack);
_inventory = Managers.require(InventoryManager.class);
_chestName = chestName;
_amount = amount;
}
@Override
public void onCollectItem()
{
}
@Override
public void onSuccessful()
{
_inventory.addItemToInventory(new Callback<Boolean>()
{
@Override
public void run(Boolean success)
{
//DebugModule.getInstance().d("Success= " + success);
}
}, _player, _chestName + " Chest", _amount);
}
@Override
public void onDeath()
{
}
}

View File

@ -0,0 +1,54 @@
package mineplex.gemhunters.loot.rewards;
import org.bukkit.inventory.ItemStack;
import mineplex.core.Managers;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.donation.DonationManager;
import mineplex.core.donation.Donor;
public class LootGadgetReward extends LootItemReward
{
private final DonationManager _donation;
private final String _gadget;
public LootGadgetReward(long cashOutDelay, ItemStack itemStack, String gadget)
{
super(gadget, cashOutDelay, itemStack);
_donation = Managers.require(DonationManager.class);
_gadget = gadget;
}
@Override
public void onCollectItem()
{
}
@Override
public void onSuccessful()
{
Donor donor = _donation.Get(_player);
if (donor.ownsUnknownSalesPackage(_gadget))
{
//DebugModule.getInstance().d("Shard duplicate");
_donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", (int) (500 + 1000 * Math.random()));
}
else
{
//DebugModule.getInstance().d("Adding gadget");
_donation.purchaseUnknownSalesPackage(_player, _gadget, GlobalCurrency.TREASURE_SHARD, 0, true, null);
}
}
@Override
public void onDeath()
{
}
}

View File

@ -0,0 +1,94 @@
package mineplex.gemhunters.loot.rewards;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime;
import mineplex.core.recharge.Recharge;
public abstract class LootItemReward
{
private String _name;
private long _firstItemPickup;
private long _cashOutDelay;
protected Player _player;
private ItemStack _itemStack;
public LootItemReward(String name, long cashOutDelay, ItemStack itemStack)
{
_name = name;
_firstItemPickup = 0;
_cashOutDelay = cashOutDelay;
_itemStack = itemStack;
}
public abstract void onCollectItem();
public abstract void onSuccessful();
public abstract void onDeath();
public final void collectItem(Player player)
{
if (player.equals(_player))
{
return;
}
if (_firstItemPickup == 0)
{
String title = C.cYellow + player.getName();
String subtitle = C.cGray + "Collected a " + F.elem(_name) + " reward. Killing them will drop it!";
String chatMessage = F.main("Game", title + " " + subtitle + " They will not be able to quit out of the game for " + F.time(UtilTime.MakeStr(_cashOutDelay) + "."));
UtilTextMiddle.display(title, subtitle, 20, 60, 20, UtilServer.getPlayers());
UtilServer.broadcast(chatMessage);
_firstItemPickup = System.currentTimeMillis();
}
else
{
String message = F.main("Game", F.name(player.getName()) + " now has the " + F.elem(_name) + " reward!");
UtilServer.broadcast(message);
}
Recharge.Instance.useForce(player, "Cash Out", _cashOutDelay, false);
_player = player;
onCollectItem();
}
public final void success()
{
//DebugModule.getInstance().d("Success");
onSuccessful();
}
public final void death(PlayerDeathEvent event)
{
}
public boolean isFirstPickup()
{
return _firstItemPickup == 0;
}
public Player getPlayer()
{
return _player;
}
public ItemStack getItemStack()
{
return _itemStack;
}
}

View File

@ -0,0 +1,85 @@
package mineplex.gemhunters.loot.rewards;
import java.util.concurrent.TimeUnit;
import org.bukkit.inventory.ItemStack;
import mineplex.core.Managers;
import mineplex.core.account.CoreClient;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.Rank;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F;
import mineplex.core.donation.DonationManager;
public class LootRankReward extends LootItemReward
{
private static final long CASH_OUT_DELAY = TimeUnit.MINUTES.toMillis(15);
private static final int CONSOLATION_PRICE = 10000;
private final CoreClientManager _clientManager;
private final DonationManager _donation;
public LootRankReward(ItemStack itemStack)
{
super("Rank", CASH_OUT_DELAY, itemStack);
_clientManager = Managers.require(CoreClientManager.class);
_donation = Managers.require(DonationManager.class);
}
@Override
public void onCollectItem()
{
}
@Override
public void onSuccessful()
{
CoreClient client = _clientManager.Get(_player);
Rank rank = client.GetRank();
Rank newRank = null;
// I could have done this so it runs off the order of the Rank enum,
// however knowing some people that might get changed so I'm just going
// to hard code what you get.
switch (rank)
{
case ALL:
newRank = Rank.ULTRA;
break;
case ULTRA:
newRank = Rank.HERO;
break;
case HERO:
newRank = Rank.LEGEND;
break;
case LEGEND:
newRank = Rank.TITAN;
break;
case TITAN:
newRank = Rank.ETERNAL;
break;
default:
break;
}
// A suitable rank could not be found.
if (newRank == null)
{
_player.sendMessage(F.main("Loot", "Since you already have eternal ( You are lucky :) ). So instead you can have " + CONSOLATION_PRICE + " shards."));
_donation.Get(_player).addBalance(GlobalCurrency.TREASURE_SHARD, CONSOLATION_PRICE);
return;
}
client.SetRank(newRank, false);
_clientManager.getRepository().saveRank(null, _player.getName(), _player.getUniqueId(), newRank, true);
}
@Override
public void onDeath()
{
}
}

View File

@ -0,0 +1,42 @@
package mineplex.gemhunters.loot.rewards;
import org.bukkit.inventory.ItemStack;
import mineplex.core.Managers;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.donation.DonationManager;
public class LootShardReward extends LootItemReward
{
private final DonationManager _donation;
private final int _amount;
public LootShardReward(long cashOutDelay, ItemStack itemStack, int amount)
{
super("Shard", cashOutDelay, itemStack);
_donation = Managers.require(DonationManager.class);
_amount = amount;
}
@Override
public void onCollectItem()
{
}
@Override
public void onSuccessful()
{
_donation.rewardCurrencyUntilSuccess(GlobalCurrency.TREASURE_SHARD, _player, "Earned", _amount);
}
@Override
public void onDeath()
{
}
}

View File

@ -0,0 +1,977 @@
package mineplex.gemhunters.map;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map.Entry;
import org.apache.commons.io.FileUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_8_R3.CraftChunk;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.util.LongHash;
import org.bukkit.craftbukkit.v1_8_R3.util.LongObjectHashMap;
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.entity.ItemSpawnEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import com.google.common.collect.HashMultiset;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multisets;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilInv;
import mineplex.core.common.util.UtilItem;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextBottom;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilTime.TimeUnit;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.portal.events.ServerTransferEvent;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.death.event.PlayerCustomRespawnEvent;
import net.minecraft.server.v1_8_R3.Block;
import net.minecraft.server.v1_8_R3.BlockPosition;
import net.minecraft.server.v1_8_R3.Blocks;
import net.minecraft.server.v1_8_R3.Chunk;
import net.minecraft.server.v1_8_R3.ChunkProviderServer;
import net.minecraft.server.v1_8_R3.ChunkRegionLoader;
import net.minecraft.server.v1_8_R3.IBlockData;
import net.minecraft.server.v1_8_R3.MaterialMapColor;
import net.minecraft.server.v1_8_R3.PersistentCollection;
import net.minecraft.server.v1_8_R3.WorldServer;
/**
* <b>All item map code was adapted from Clans.</b><br>
*/
@ReflectivelyCreateMiniPlugin
public class ItemMapModule extends MiniPlugin
{
// Every BLOCK_SCAN_INTERVAL we add as a new region to scan
private static final int BLOCK_SCAN_INTERVAL = 16 * 3;
// 1536 is the width of the entire world from one borderland to the other
private static final int HALF_WORLD_SIZE = 768;
// This slot is where the Clans Map will go by default
private static final int CLANS_MAP_SLOT = 8;
private static final String[] ZOOM_INFO;
static
{
ZOOM_INFO = new String[4];
for (int zoomLevel = 0; zoomLevel <= 3; zoomLevel++)
{
StringBuilder progressBar = new StringBuilder(C.cBlue);
boolean colorChange = false;
for (int i = 2; i >= 0; i--)
{
if (!colorChange && i < zoomLevel)
{
progressBar.append(C.cGray);
colorChange = true;
}
char c;
switch (i)
{
case 0:
c = '█';
break;
case 1:
c = '▆';
break;
default:
c = '▄';
break;
}
for (int a = 0; a < 4; a++)
{
progressBar.append(c);
}
if (i > 0)
{
progressBar.append(" ");
}
}
ZOOM_INFO[zoomLevel] = progressBar.toString();
}
}
private Comparator<Entry<Integer, Integer>> _comparator;
private int[][] _heightMap = new int[(HALF_WORLD_SIZE * 2) + 16][];
private HashMap<Integer, Byte[][]> _map = new HashMap<Integer, Byte[][]>();
private short _mapId = -1;
private HashMap<String, MapInfo> _mapInfo = new HashMap<String, MapInfo>();
private HashMap<Integer, Integer> _scale = new HashMap<Integer, Integer>();
// Use LinkedList because operations are either add(Entry) which is O(1) and remove(0) which is O(1) on LinkedList but O(n) on ArrayList
private LinkedList<Entry<Integer, Integer>> _scanList = new LinkedList<Entry<Integer, Integer>>();
private World _world;
private WorldServer _nmsWorld;
private ChunkProviderServer _chunkProviderServer;
private ChunkRegionLoader _chunkRegionLoader;
private ItemMapModule()
{
super("ItemMapManager");
_comparator = (o1, o2) ->
{
// Render the places outside the map first to speed up visual errors fixing
int outsideMap = Boolean.compare(o1.getValue() < -HALF_WORLD_SIZE, o2.getValue() < -HALF_WORLD_SIZE);
if (outsideMap != 0)
{
return -outsideMap;
}
double dist1 = 0;
double dist2 = 0;
for (Player player : UtilServer.getPlayers())
{
dist1 += getDistance(o1, player.getLocation().getX(), player.getLocation().getZ());
dist2 += getDistance(o2, player.getLocation().getX(), player.getLocation().getZ());
}
if (dist1 != dist2)
{
return Double.compare(dist1, dist2);
}
dist1 = getDistance(o1, 0, 0);
dist2 = getDistance(o2, 0, 0);
return Double.compare(dist1, dist2);
};
_scale.put(0, 1);
// _scale.put(1, 2);
_scale.put(1, 4);
_scale.put(2, 8);
_scale.put(3, 13);
// _scale.put(5, 16);
for (Entry<Integer, Integer> entry : _scale.entrySet())
{
int size = (HALF_WORLD_SIZE * 2) / entry.getValue();
Byte[][] bytes = new Byte[size][];
for (int i = 0; i < size; i++)
{
bytes[i] = new Byte[size];
}
_map.put(entry.getKey(), bytes);
}
for (int i = 0; i < _heightMap.length; i++)
{
_heightMap[i] = new int[_heightMap.length];
}
_world = Bukkit.getWorld("world");
try
{
Field chunkLoader = ChunkProviderServer.class.getDeclaredField("chunkLoader");
chunkLoader.setAccessible(true);
_nmsWorld = ((CraftWorld) _world).getHandle();
_chunkProviderServer = _nmsWorld.chunkProviderServer;
_chunkRegionLoader = (ChunkRegionLoader) chunkLoader.get(_chunkProviderServer);
if (_chunkRegionLoader == null)
{
throw new RuntimeException("Did not expect null chunkLoader");
}
}
catch (ReflectiveOperationException e)
{
throw new RuntimeException("Could not reflectively access ChunkRegionLoader", e);
}
try
{
File file = new File("world/gem_hunters_map_id");
File foundFile = null;
for (File f : new File("world/data").listFiles())
{
if (f.getName().startsWith("map_"))
{
foundFile = f;
break;
}
}
if (foundFile == null)
{
PersistentCollection collection = ((CraftWorld) _world).getHandle().worldMaps;
Field f = collection.getClass().getDeclaredField("d");
f.setAccessible(true);
((HashMap) f.get(collection)).put("map", (short) 0);
}
if (file.exists())
{
BufferedReader br = new BufferedReader(new FileReader(file));
_mapId = Short.parseShort(br.readLine());
br.close();
if (foundFile == null)
{
_mapId = -1;
file.delete();
}
else
{
for (int i = _mapId; i <= _mapId + 100; i++)
{
File file1 = new File("world/data/map_" + i + ".dat");
if (!file1.exists())
{
FileUtils.copyFile(foundFile, file1);
}
setupRenderer(Bukkit.getMap((short) i));
}
}
}
if (_mapId < 0)
{
MapView view = Bukkit.createMap(_world);
_mapId = view.getId();
setupRenderer(view);
for (int i = 0; i < 100; i++)
{
setupRenderer(Bukkit.createMap(_world));// Ensures the following 100 maps are unused
}
file.createNewFile();
PrintWriter writer = new PrintWriter(file, "UTF-8");
writer.print(_mapId);
writer.close();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
rebuildScan();
initialScan();
}
private void initialScan()
{
System.out.println("Beginning initial scan. There are " + _scanList.size() + " regions to scan");
// How many regions before logging an update (Currently set to every 20%)
int logPer = _scanList.size() / 5;
while (!_scanList.isEmpty())
{
Entry<Integer, Integer> entry = _scanList.remove(0);
if (_scanList.size() % logPer == 0)
{
System.out.println("Running initial render... " + _scanList.size() + " sections to go");
}
int startingX = entry.getKey();
int startingZ = entry.getValue();
boolean outsideMap = startingZ < -HALF_WORLD_SIZE;
scanWorldMap(startingX, startingZ, !outsideMap, true);
if (outsideMap)
{
continue;
}
for (int scale = 1; scale < _scale.size(); scale++)
{
if (scale == 3)
continue;
drawWorldScale(scale, startingX, startingZ);
colorWorldHeight(scale, startingX, startingZ);
}
colorWorldHeight(0, startingX, startingZ);
}
for (int x = -HALF_WORLD_SIZE; x < HALF_WORLD_SIZE; x += BLOCK_SCAN_INTERVAL)
{
for (int z = -HALF_WORLD_SIZE; z < HALF_WORLD_SIZE; z += BLOCK_SCAN_INTERVAL)
{
drawWorldScale(3, x, z);
colorWorldHeight(3, x, z);
}
}
System.out.println("Finished first map scan and render");
}
private void setupRenderer(MapView view)
{
for (MapRenderer renderer : view.getRenderers())
{
view.removeRenderer(renderer);
}
view.addRenderer(new ItemMapRenderer());
}
/**
* Get the center of the map.
*/
public int calcMapCenter(int zoom, int cord)
{
int mapSize = HALF_WORLD_SIZE / zoom; // This is how large the map is in pixels
int mapCord = cord / zoom; // This is pixels from true center of map, not held map
int fDiff = mapSize - -mapCord;
int sDiff = mapSize - mapCord;
double chunkBlock = cord & 0xF;
cord -= chunkBlock;
chunkBlock /= zoom;
/*if ((fDiff < 64 || sDiff < 64) && (Math.abs(fDiff - sDiff) > 1))
{
cord += (fDiff > sDiff ? Math.floor(chunkBlock) : Math.ceil(chunkBlock));
}
else*/
{
cord += (int) Math.floor(chunkBlock) * zoom;
}
while ((fDiff < 64 || sDiff < 64) && (Math.abs(fDiff - sDiff) > 1))
{
int change = (fDiff > sDiff ? -zoom : zoom);
cord += change;
mapCord = cord / zoom;
fDiff = mapSize - -mapCord;
sDiff = mapSize - mapCord;
}
return cord;
}
private void colorWorldHeight(int scale, int startingX, int startingZ)
{
Byte[][] map = _map.get(scale);
int zoom = getZoom(scale);
for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom)
{
double d0 = 0;
// Prevents ugly lines for the first line of Z
for (int addX = 0; addX < zoom; addX++)
{
for (int addZ = 0; addZ < zoom; addZ++)
{
int hX = x + addX + HALF_WORLD_SIZE;
int hZ = (startingZ - zoom) + addZ + HALF_WORLD_SIZE;
if (hX >= HALF_WORLD_SIZE * 2 || hZ >= HALF_WORLD_SIZE * 2)
{
continue;
}
d0 += _heightMap[hX + 16][hZ + 16] / (zoom * zoom);
}
}
for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom)
{
// Water depth colors not included
double d1 = 0;
for (int addX = 0; addX < zoom; addX++)
{
for (int addZ = 0; addZ < zoom; addZ++)
{
int hX = x + addX + HALF_WORLD_SIZE;
int hZ = z + addZ + HALF_WORLD_SIZE;
if (hX >= HALF_WORLD_SIZE * 2 || hZ >= HALF_WORLD_SIZE * 2)
{
continue;
}
d1 += _heightMap[hX + 16][hZ + 16] / (zoom * zoom);
}
}
double d2 = (d1 - d0) * 4.0D / (zoom + 4) + ((x + z & 0x1) - 0.5D) * 0.4D;
byte b0 = 1;
d0 = d1;
if (d2 > 0.6D)
{
b0 = 2;
}
else if (d2 > 1.2D)
{
b0 = 3;
}
else if (d2 < -0.6D)
{
b0 = 0;
}
int origColor = map[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] - 1;
/*if (color < 4)
{
d2 = waterDepth * 0.1D + (k1 + j2 & 0x1) * 0.2D;
b0 = 1;
if (d2 < 0.5D)
{
b0 = 2;
}
if (d2 > 0.9D)
{
b0 = 0;
}
}*/
byte color = (byte) (origColor + b0);
if((color <= -113 || color >= 0) && color <= 127)
{
map[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] = color;
}
else
{
// System.out.println(String.format("Tried to set color to %s in colorWorldHeight scale: %s, sx: %s, sz: %s, x: %s, z: %s, zoom: %s",
// color, scale, startingX, startingZ, x, z, zoom));
}
}
}
}
private void drawWorldScale(int scale, int startingX, int startingZ)
{
Byte[][] first = _map.get(0);
Byte[][] second = _map.get(scale);
int zoom = getZoom(scale);
for (int x = startingX; x < startingX + BLOCK_SCAN_INTERVAL; x += zoom)
{
for (int z = startingZ; z < startingZ + BLOCK_SCAN_INTERVAL; z += zoom)
{
HashMultiset<Byte> hashmultiset = HashMultiset.create();
for (int addX = 0; addX < zoom; addX++)
{
for (int addZ = 0; addZ < zoom; addZ++)
{
int pX = x + addX + HALF_WORLD_SIZE;
int pZ = z + addZ + HALF_WORLD_SIZE;
if (pX >= first.length || pZ >= first.length)
{
continue;
}
Byte b = first[pX][pZ];
hashmultiset.add(b);
}
}
Byte color;
try
{
color = Iterables.getFirst(Multisets.copyHighestCountFirst(hashmultiset), (byte) 0);
}
catch (Exception e)
{
color = (byte) 0;
}
second[(x + HALF_WORLD_SIZE) / zoom][(z + HALF_WORLD_SIZE) / zoom] = color;
}
}
}
@EventHandler
public void dropItem(ItemSpawnEvent event)
{
if (isItemClansMap(event.getEntity().getItemStack()))
event.getEntity().remove();
}
public void removeMap(Player player)
{
for (int slot = 0; slot < player.getInventory().getSize(); slot++)
{
if (isItemClansMap(player.getInventory().getItem(slot)))
player.getInventory().setItem(slot, null);
}
}
private double getDistance(double x1, double z1, double x2, double z2)
{
x1 = (x1 - x2);
z1 = (z1 - z2);
return (x1 * x1) + (z1 * z1);
}
private double getDistance(Entry<Integer, Integer> entry, double x1, double z1)
{
return getDistance(x1, z1, entry.getKey() + (BLOCK_SCAN_INTERVAL / 2), entry.getValue() + (BLOCK_SCAN_INTERVAL / 2));
}
public Byte[][] getMap(int scale)
{
return _map.get(scale);
}
public MapInfo getMap(Player player)
{
return _mapInfo.get(player.getName());
}
public int getMapSize()
{
return HALF_WORLD_SIZE;
}
public int getZoom(int scale)
{
return _scale.get(scale);
}
//fixme So what appears to happen is that after you die, if your map is is the same then the map is frozen
@EventHandler
public void onDeath(PlayerDeathEvent event)
{
MapInfo info = getMap(event.getEntity());
info.setMap(Math.min(_mapId + 100, info.getMap() + 1));
}
@EventHandler
public void onHotbarMove(PlayerItemHeldEvent event)
{
Player player = event.getPlayer();
if (!isItemClansMap(player.getInventory().getItem(event.getNewSlot())))
return;
showZoom(player, getMap(player));
}
@EventHandler
public void onInteract(PlayerInteractEvent event)
{
if (event.getAction() == Action.PHYSICAL)
return;
if (!isItemClansMap(event.getItem()))
return;
event.setCancelled(true);
Player player = event.getPlayer();
MapInfo info = getMap(player);
boolean zoomIn = UtilEvent.isAction(event, ActionType.L);
if (!_scale.containsKey(info.getScale() + (zoomIn ? -1 : 1)))
{
return;
}
if (!info.canZoom())
{
long remainingTime = (info.getZoomCooldown() + 2500) - System.currentTimeMillis();
UtilPlayer.message(
player,
F.main("Recharge",
"You cannot use " + F.skill("Map Zoom") + " for "
+ F.time(UtilTime.convertString((remainingTime), 1, TimeUnit.FIT)) + "."));
return;
}
info.addZoom();
if (zoomIn)
{
int newScale = info.getScale() - 1;
Location loc = player.getLocation();
int zoom = getZoom(newScale);
info.setInfo(newScale, calcMapCenter(zoom, loc.getBlockX()), calcMapCenter(zoom, loc.getBlockZ()));
}
else
{
int newScale = info.getScale() + 1;
Location loc = player.getLocation();
int zoom = getZoom(newScale);
info.setInfo(newScale, calcMapCenter(zoom, loc.getBlockX()), calcMapCenter(zoom, loc.getBlockZ()));
}
showZoom(player, info);
}
@EventHandler
public void teleportIn(PlayerCustomRespawnEvent event)
{
MapInfo info = new MapInfo(_mapId);
Player player = event.getPlayer();
Location loc = player.getLocation();
int zoom = getZoom(1);
info.setInfo(1, calcMapCenter(zoom, loc.getBlockX()), calcMapCenter(zoom, loc.getBlockZ()));
_mapInfo.put(player.getName(), info);
setMap(player);
}
@EventHandler
public void onWorldChange(PlayerTeleportEvent event)
{
if (event.getFrom().getWorld() != event.getTo().getWorld() && event.getTo().getWorld().equals("world"))
{
runSyncLater(new Runnable()
{
@Override
public void run()
{
setMap(event.getPlayer());
}
}, 20);
}
}
@EventHandler
public void onQuit(PlayerQuitEvent event)
{
_mapInfo.remove(event.getPlayer().getName());
}
//@EventHandler
public void onServerTransfer(ServerTransferEvent event)
{
Player p = event.getPlayer();
p.sendMessage(C.cDRed + C.Bold + "WARNING!");
p.sendMessage(C.cYellow + "There's a bug where switching servers will freeze the Clans Map!");
p.sendMessage(C.cYellow + "If you want to play on Clans again, rejoin the Mineplex server!");
}
private void rebuildScan()
{
for (int x = -HALF_WORLD_SIZE; x < HALF_WORLD_SIZE; x += BLOCK_SCAN_INTERVAL)
{
for (int z = -HALF_WORLD_SIZE - 16; z < HALF_WORLD_SIZE; z += (z < -HALF_WORLD_SIZE ? 16 : BLOCK_SCAN_INTERVAL))
{
_scanList.add(new HashMap.SimpleEntry<>(x, z));
}
}
Collections.sort(_scanList, _comparator);
}
@EventHandler
public void recenterMap(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
for (Player player : Bukkit.getOnlinePlayers())
{
MapInfo info = getMap(player);
if (info == null || info.getScale() >= 3)
{
continue;
}
Location l = player.getLocation();
int zoom = getZoom(info.getScale());
double mapX = (l.getX() - info.getX()) / zoom;
double mapZ = (l.getZ() - info.getZ()) / zoom;
if (Math.abs(mapX) > 22 || Math.abs(mapZ) > 22)
{
int newX = calcMapCenter(zoom, l.getBlockX());
int newZ = calcMapCenter(zoom, l.getBlockZ());
if (Math.abs(mapX) > 22 ? newX != info.getX() : newZ != info.getZ())
{
info.setInfo(newX, newZ);
}
}
}
}
@EventHandler
public void renderMap(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
return;
if (_scanList.isEmpty() && UtilServer.getPlayers().length > 0)
{
rebuildScan();
}
if (_scanList.size() % 20 == 0)
{
Collections.sort(_scanList, _comparator);
}
if (_scanList.isEmpty())
{
return;
}
Entry<Integer, Integer> entry = _scanList.remove(0);
int startingX = entry.getKey();
int startingZ = entry.getValue();
boolean outsideMap = startingZ < -HALF_WORLD_SIZE;
scanWorldMap(startingX, startingZ, !outsideMap, false);
if (outsideMap)
return;
for (int scale = 1; scale < _scale.size(); scale++)
{
drawWorldScale(scale, startingX, startingZ);
colorWorldHeight(scale, startingX, startingZ);
}
colorWorldHeight(0, startingX, startingZ);
}
// Let's not create hundreds of thousands of BlockPositions
// Single thread = should be thread safe
private BlockPosition.MutableBlockPosition _blockPosition = new BlockPosition.MutableBlockPosition();
// Maps the cached chunks which were loaded from disk to save IO operations
private LongObjectHashMap<Chunk> _chunkCache = new LongObjectHashMap<>();
/*
* Remove the cached chunks when the real chunks are loaded in
*/
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void LoadChunk(ChunkLoadEvent event)
{
_chunkCache.remove(LongHash.toLong(event.getChunk().getX(), event.getChunk().getZ()));
}
/*
* Given a particular coordinate, this method will scan up to BLOCK_SCAN_INTERVAL and record the color of ever 16th block
* If a chunk has not been loaded, the following steps will be taken:
* * Attempt to load the chunk from disk.
* * If the chunk could not be loaded, generate it froms scratch
* Otherwise, the loaded chunk will be used
*/
public void scanWorldMap(int startingX, int startingZ, boolean setColors, boolean isFirstScan)
{
Byte[][] map = _map.get(0);
for (int beginX = startingX; beginX < startingX + BLOCK_SCAN_INTERVAL; beginX += 16)
{
for (int beginZ = startingZ - (startingZ > -HALF_WORLD_SIZE ? 16 : 0); beginZ < startingZ
+ (setColors ? BLOCK_SCAN_INTERVAL : 16); beginZ += 16)
{
int chunkX = beginX / 16;
int chunkZ = beginZ / 16;
net.minecraft.server.v1_8_R3.Chunk nmsChunk = _chunkProviderServer.getChunkIfLoaded(chunkX, chunkZ);
if (nmsChunk == null)
{
long key = LongHash.toLong(chunkX, chunkZ);
nmsChunk = _chunkCache.get(key);
if (nmsChunk == null)
{
if (!isFirstScan)
{
continue;
}
try
{
Object[] data = _chunkRegionLoader.loadChunk(_nmsWorld, chunkX, chunkZ);
if (data == null)
{
// Something is wrong with the chunk
System.out.println("Chunk is not generated or missing level/block data. Regenerating (" + chunkX + "," + chunkZ + ")");
nmsChunk = ((CraftChunk) _world.getChunkAt(chunkX, chunkZ)).getHandle();
}
else
{
nmsChunk = (net.minecraft.server.v1_8_R3.Chunk) data[0];
}
}
catch (IOException e)
{
throw new RuntimeException("Chunk is corrupt or not readable!", e);
}
_chunkCache.put(key, nmsChunk);
}
}
if (!nmsChunk.isEmpty())
{
for (int x = beginX; x < beginX + 16; x++)
{
for (int z = beginZ; z < beginZ + 16; z++)
{
int color = 0;
int k3 = x & 0xF;
int l3 = z & 0xF;
int l4 = nmsChunk.b(k3, l3) + 1;
IBlockData iblockdata = Blocks.AIR.getBlockData();
if (l4 > 1)
{
do
{
l4--;
_blockPosition.c(k3, l4, l3);
iblockdata = nmsChunk.getBlockData(_blockPosition);
}
while (iblockdata.getBlock().g(iblockdata) == MaterialMapColor.b && (l4 > 0));
if ((l4 > 0) && (iblockdata.getBlock().getMaterial().isLiquid()))
{
int j5 = l4 - 1;
Block block1;
do
{
_blockPosition.c(k3, j5--, l3);
block1 = nmsChunk.getType(_blockPosition);
}
while ((j5 > 0) && (block1.getMaterial().isLiquid()));
}
}
_heightMap[x + HALF_WORLD_SIZE + 16][z + HALF_WORLD_SIZE + 16] = l4;
if (setColors)
{
//color = block.f(i5).M;
_blockPosition.c(k3, l4, l3);
IBlockData data = nmsChunk.getBlockData(_blockPosition);
color = data.getBlock().g(data).M;
color = (byte) ((color * 4) + 1);
}
if (setColors && beginZ >= startingZ)
{
map[x + HALF_WORLD_SIZE][z + HALF_WORLD_SIZE] = (byte) color;
}
}
}
}
}
}
}
public void setMap(Player player)
{
for (ItemStack item : UtilInv.getItems(player))
{
if (isItemClansMap(item))
{
return;
}
}
ItemStack item = new ItemBuilder(Material.MAP, 1, (short) getMap(player).getMap()).setTitle(C.cGreen + "World Map").build();
int slot = CLANS_MAP_SLOT;
ItemStack mapSlot = player.getInventory().getItem(slot);
if (mapSlot != null && mapSlot.getType() != Material.AIR)
{
slot = player.getInventory().firstEmpty();
}
if (slot >= 0)
{
player.getInventory().setItem(slot, item);
}
}
/*
* Displays the action bar to a player given their zoom level. Implementation may change
*/
private void showZoom(Player player, MapInfo info)
{
UtilTextBottom.display(ZOOM_INFO[info.getScale()], player);
}
/*
* Check whether an {@link ItemStack} is also a Clans Map
*
* @param itemStack The {@link ItemStack} to check
* @returns Whether the {@link ItemStack} is also a Clans Map
*/
private boolean isItemClansMap(ItemStack itemStack)
{
return UtilItem.matchesMaterial(itemStack, Material.MAP)
&& itemStack.getDurability() >= _mapId
&& itemStack.getDurability() <= _mapId + 100;
}
}

View File

@ -0,0 +1,294 @@
package mineplex.gemhunters.map;
import java.awt.Color;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.map.MapCanvas;
import org.bukkit.map.MapCursor;
import org.bukkit.map.MapCursorCollection;
import org.bukkit.map.MapPalette;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import mineplex.core.Managers;
import mineplex.core.common.util.UtilTime;
import mineplex.core.party.Party;
import mineplex.core.party.PartyManager;
import mineplex.gemhunters.loot.LootModule;
import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.supplydrop.SupplyDrop;
import mineplex.gemhunters.supplydrop.SupplyDropModule;
import mineplex.gemhunters.worldevent.WorldEvent;
import mineplex.gemhunters.worldevent.WorldEventModule;
/**
* <b>All item map code was adapted from Clans.</b><br>
*/
public class ItemMapRenderer extends MapRenderer
{
private static final int RENDER_COOLDOWN = 10000;
private static final int STANDARD_Y = 70;
private final ItemMapModule _itemMap;
private final LootModule _loot;
private final SafezoneModule _safezone;
private final SupplyDropModule _supply;
private final WorldEventModule _worldEvent;
private final PartyManager _party;
public ItemMapRenderer()
{
super(true);
_itemMap = Managers.require(ItemMapModule.class);
_loot = Managers.require(LootModule.class);
_safezone = Managers.require(SafezoneModule.class);
_supply = Managers.require(SupplyDropModule.class);
_worldEvent = Managers.require(WorldEventModule.class);
_party = Managers.require(PartyManager.class);
}
@Override
public void render(MapView mapView, MapCanvas canvas, Player player)
{
try
{
renderNormalMap(mapView, canvas, player);
}
catch (Throwable t)
{
System.out.println("Error while rendering map");
t.printStackTrace();
}
}
private void renderNormalMap(MapView mapView, MapCanvas canvas, Player player)
{
MapInfo info = _itemMap.getMap(player);
if (info == null)
{
return;
}
int scale = info.getScale();
int zoom = _itemMap.getZoom(scale);
Byte[][] map = _itemMap.getMap(scale);
int centerX = info.getX() / zoom;
int centerZ = info.getZ() / zoom;
// We have this cooldown to squeeze out every single bit of performance
// from the server.
if (UtilTime.elapsed(info.getLastRendered(), RENDER_COOLDOWN))
{
info.setLastRendered();
for (int mapX = 0; mapX < 128; mapX++)
{
for (int mapZ = 0; mapZ < 128; mapZ++)
{
int blockX = centerX + (mapX - 64);
int blockZ = centerZ + (mapZ - 64);
int pixelX = blockX + (map.length / 2);
int pixelZ = blockZ + (map.length / 2);
Byte color;
if (!(pixelX < 0 || pixelZ < 0 || pixelX >= map.length || pixelZ >= map.length) && map[pixelX][pixelZ] != null)
{
color = map[pixelX][pixelZ];
blockX *= zoom;
blockZ *= zoom;
Location location = new Location(mapView.getWorld(), blockX, STANDARD_Y, blockZ);
boolean safezone = _safezone.isInSafeZone(location);
if (safezone)
{
boolean colorAll = scale > 0;
Color areaColor = Color.GREEN;
if (areaColor != null)
{
if (!((color <= -113 || color >= 0) && color <= 127))
{
color = (byte) 0;
System.out.println(String.format("Tried to draw invalid color %s, player: %s, mapX: %s, mapZ: %s", color, player.getName(), mapX, mapZ));
}
else
{
// int chunkBX = blockX & 0xF;
// int chunkBZ = blockZ & 0xF;
// Border
if (
_safezone.isInSafeZone(new Location(mapView.getWorld(), blockX - 1, STANDARD_Y, blockZ)) ||
_safezone.isInSafeZone(new Location(mapView.getWorld(), blockX, STANDARD_Y, blockZ - 1)) ||
_safezone.isInSafeZone(new Location(mapView.getWorld(), blockX + 16, STANDARD_Y, blockZ)) ||
_safezone.isInSafeZone(new Location(mapView.getWorld(), blockX, STANDARD_Y, blockZ + 1)))
{
Color cColor = MapPalette.getColor(color);
double clans = colorAll ? 1 : 0.8;
double base = 1 - clans;
int r = (int) ((cColor.getRed() * base) + (areaColor.getRed() * clans));
int b = (int) ((cColor.getBlue() * base) + (areaColor.getBlue() * clans));
int g = (int) ((cColor.getGreen() * base) + (areaColor.getGreen() * clans));
color = MapPalette.matchColor(r, g, b);
}
// Inside
else
{
Color cColor = MapPalette.getColor(color);
double clans = 0.065;
// Stripes
//boolean checker = (mapX + (mapZ % 4)) % 4 == 0;
double base = 1 - clans;
int r = (int) ((cColor.getRed() * base) + (areaColor.getRed() * clans));
int b = (int) ((cColor.getBlue() * base) + (areaColor.getBlue() * clans));
int g = (int) ((cColor.getGreen() * base) + (areaColor.getGreen() * clans));
color = MapPalette.matchColor(r, g, b);
}
}
}
}
}
else
{
color = (byte) 0;
}
canvas.setPixel(mapX, mapZ, color);
}
}
}
if (info.isSendMap())
{
player.sendMap(mapView);
}
MapCursorCollection cursors = canvas.getCursors();
while (cursors.size() > 0)
{
cursors.removeCursor(cursors.getCursor(0));
}
for (WorldEvent event : _worldEvent.getActiveEvents())
{
if (!event.isInProgress())
{
continue;
}
Location point = event.getCurrentLocation();
double mapX = (point.getX() - info.getX()) / zoom;
double mapZ = (point.getZ() - info.getZ()) / zoom;
// To make these appear at the edges of the map, just change it from
// 64 to something like 128 for double the map size
if (mapX > -64 && mapX < 64 && mapZ > -64 && mapZ < 64)
{
byte b0 = (byte) (int) Math.min(127, (double) (mapX * 2.0F) + 0.5D);
byte b1 = (byte) (int) Math.max(-127, (double) (mapZ * 2.0F) + 0.5D);
byte cursorType = 5; // http://i.imgur.com/wpH6PT8.png
// Those are byte 5 and 6
byte rotation = (byte) ((int) Math.floor(System.currentTimeMillis() / 1000D) % 16);
MapCursor cursor = new MapCursor(b0, b1, rotation, cursorType, true);
cursors.addCursor(cursor);
}
}
SupplyDrop supplyDrop = _supply.getActive();
if (_supply.isActive())
{
Location point = supplyDrop.getCurrentLocation();
double mapX = (point.getX() - info.getX()) / zoom;
double mapZ = (point.getZ() - info.getZ()) / zoom;
// To make these appear at the edges of the map, just change it from
// 64 to something like 128 for double the map size
if (mapX > -64 && mapX < 64 && mapZ > -64 && mapZ < 64)
{
byte b0 = (byte) (int) Math.min(127, (double) (mapX * 2.0F) + 0.5D);
byte b1 = (byte) (int) Math.max(-127, (double) (mapZ * 2.0F) + 0.5D);
byte cursorType = 4; // http://i.imgur.com/wpH6PT8.png
// Those are byte 5 and 6
byte rotation = (byte) ((int) Math.floor(System.currentTimeMillis() / 1000D) % 16);
MapCursor cursor = new MapCursor(b0, b1, rotation, cursorType, true);
cursors.addCursor(cursor);
}
}
Party party = _party.getPartyByPlayer(player);
Set<UUID> shownPlayers = _loot.getShownPlayers();
for (Player other : Bukkit.getOnlinePlayers())
{
if (player.canSee(other) && other.isValid())
{
Location l = other.getLocation();
double mapX = (l.getX() - info.getX()) / zoom;
double mapZ = (l.getZ() - info.getZ()) / zoom;
if (mapX > -64 && mapX < 64 && mapZ > -64 && mapZ < 64)
{
MapCursor.Type cursorDisplay = null;
if (player.equals(other))
{
cursorDisplay = MapCursor.Type.WHITE_POINTER;
}
else if (shownPlayers.contains(other.getUniqueId()))
{
cursorDisplay = MapCursor.Type.BLUE_POINTER;
}
else if (party != null && party.isMember(other))
{
cursorDisplay = MapCursor.Type.GREEN_POINTER;
}
if (cursorDisplay == null)
{
continue;
}
byte b0 = (byte) (int) Math.min(127, (double) (mapX * 2.0F) + 0.5D);
byte b1 = (byte) (int) Math.max(-127, (double) (mapZ * 2.0F) + 0.5D);
byte rotation = (byte) (int) ((l.getYaw() * 16D) / 360D);
MapCursor cursor = new MapCursor(b0, b1, (byte) (rotation & 0xF), cursorDisplay.getValue(), true);
cursors.addCursor(cursor);
}
}
}
}
}

View File

@ -0,0 +1,124 @@
package mineplex.gemhunters.map;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import mineplex.core.common.util.UtilTime;
public class MapInfo
{
private int _scale;
private int _centerX;
private int _centerZ;
private long _lastRendered;
private boolean _sendMap;
private List<Long> _lastZooms = new ArrayList<Long>();
private int _mapId;
public MapInfo(int newId)
{
_mapId = newId;
}
public int getMap()
{
return _mapId;
}
public void setMap(int newId)
{
_mapId = newId;
}
public boolean canZoom()
{
Iterator<Long> itel = _lastZooms.iterator();
while (itel.hasNext())
{
long lastZoomed = itel.next();
if (UtilTime.elapsed(lastZoomed, 2500))
{
itel.remove();
}
}
return _lastZooms.size() < 3;
}
public void addZoom()
{
_lastZooms.add(System.currentTimeMillis());
}
public long getZoomCooldown()
{
long cooldown = 0;
for (long zoomCooldown : _lastZooms)
{
if (cooldown == 0 || zoomCooldown < cooldown)
{
cooldown = zoomCooldown;
}
}
return cooldown;
}
public long getLastRendered()
{
return _lastRendered;
}
public void setLastRendered()
{
_lastRendered = System.currentTimeMillis();
}
public void setInfo(int scale, int x, int z)
{
_lastRendered = 0;
_scale = scale;
_centerX = x;
_centerZ = z;
_sendMap = true;
}
public void setInfo(int x, int z)
{
_lastRendered = 0;
_centerX = x;
_centerZ = z;
_sendMap = true;
}
public boolean isSendMap()
{
if (_sendMap)
{
_sendMap = false;
return true;
}
return false;
}
public int getX()
{
return _centerX;
}
public int getZ()
{
return _centerZ;
}
public int getScale()
{
return _scale;
}
}

View File

@ -0,0 +1,37 @@
package mineplex.gemhunters.mount;
import org.bukkit.entity.LivingEntity;
import mineplex.core.gadget.gadgets.gamemodifiers.gemhunters.MountType;
public class MountData
{
private MountType _mountType;
private LivingEntity _entity;
public MountData()
{
}
public void setMountType(MountType mountType)
{
_mountType = mountType;
}
public MountType getMountType()
{
return _mountType;
}
public void setEntity(LivingEntity entity)
{
_entity = entity;
}
public LivingEntity getEntity()
{
return _entity;
}
}

View File

@ -0,0 +1,157 @@
package mineplex.gemhunters.mount;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Horse;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Tameable;
import org.bukkit.entity.Horse.Color;
import org.bukkit.entity.Horse.Style;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import mineplex.core.MiniClientPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilEvent;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.gamemodifiers.GameModifierType;
import mineplex.core.gadget.gadgets.gamemodifiers.gemhunters.GameModifierMount;
import mineplex.core.gadget.gadgets.gamemodifiers.gemhunters.MountType;
import mineplex.core.recharge.Recharge;
import mineplex.gemhunters.loot.LootItem;
import mineplex.gemhunters.loot.LootModule;
@ReflectivelyCreateMiniPlugin
public class MountModule extends MiniClientPlugin<MountData>
{
private static final String ITEM_METADATA = "MOUNT";
private final LootModule _loot;
private final GadgetManager _gadget;
private MountModule()
{
super("Mount");
_loot = require(LootModule.class);
_gadget = require(GadgetManager.class);
}
@Override
protected MountData addPlayer(UUID uuid)
{
return new MountData();
}
@EventHandler
public void playerInteract(PlayerInteractEvent event)
{
if (!UtilEvent.isAction(event, ActionType.R))
{
return;
}
Player player = event.getPlayer();
ItemStack itemStack = player.getItemInHand();
if (itemStack == null)
{
return;
}
LootItem lootItem = _loot.fromItemStack(itemStack);
if (lootItem == null || lootItem.getMetadata() == null || !lootItem.getMetadata().startsWith(ITEM_METADATA))
{
return;
}
int cooldown = Integer.parseInt(lootItem.getMetadata().split(" ")[1]) * 1000;
if (!Recharge.Instance.use(player, _moduleName, cooldown, true, true))
{
return;
}
spawnMount(player);
}
public void spawnMount(Player player)
{
GameModifierMount mount = ((GameModifierMount) _gadget.getActiveGameModifier(player, GameModifierType.GemHunters, g -> g != null));
MountType mountType = null;
if (mount != null)
{
mountType = mount.getMountType();
}
player.sendMessage(F.main(_moduleName, "Mounts are currently disabled."));
//spawnMount(player, mountType);
}
public void spawnMount(Player player, MountType mountType)
{
MountData data = Get(player);
LivingEntity entity = data.getEntity();
EntityType entityType = mountType == null ? EntityType.HORSE : mountType.getEntityType();
despawnMount(player);
entity = (LivingEntity) player.getWorld().spawnEntity(player.getLocation().add(0, 1, 0), entityType);
if (entity instanceof Tameable)
{
Tameable tameable = (Tameable) entity;
tameable.setOwner(player);
}
if (entity instanceof Horse)
{
Horse horse = (Horse) entity;
horse.setAdult();
horse.setAgeLock(true);
horse.setColor(Color.BROWN);
horse.setStyle(Style.NONE);
horse.setMaxDomestication(1);
horse.setJumpStrength(1);
horse.getInventory().setSaddle(new ItemStack(Material.SADDLE));
}
entity.setCustomName(player.getName() + "\'s Mount");
entity.setCustomNameVisible(true);
entity.setCanPickupItems(false);
entity.setHealth(1);
entity.setMaxHealth(1);
entity.setPassenger(player);
data.setEntity(entity);
data.setMountType(mountType);
}
public void despawnMount(Player player)
{
MountData data = Get(player);
LivingEntity entity = data.getEntity();
if (entity != null)
{
entity.remove();
}
}
public boolean isActive(Player player)
{
return Get(player).getEntity() != null;
}
}

View File

@ -0,0 +1,6 @@
package mineplex.gemhunters.mount.event;
public class MountSpawnEvent
{
}

View File

@ -0,0 +1,146 @@
package mineplex.gemhunters.quest;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerQuitEvent;
import mineplex.core.Managers;
import mineplex.core.account.CoreClientManager;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilServer;
import mineplex.core.donation.DonationManager;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.world.WorldDataModule;
public abstract class Quest implements Listener
{
private final int _id;
private final String _name;
private final String _description;
private final int _startCost;
private final int _completeReward;
protected final QuestModule _quest;
protected final CoreClientManager _clientManager;
protected final DonationManager _donation;
protected final EconomyModule _economy;
protected final WorldDataModule _worldData;
private final Map<UUID, Integer> _counter;
public Quest(int id, String name, String description, int startCost, int completeReward)
{
_id = id;
_name = name;
_description = description;
_startCost = startCost;
_completeReward = completeReward;
_quest = Managers.require(QuestModule.class);
_clientManager = Managers.require(CoreClientManager.class);
_donation = Managers.require(DonationManager.class);
_economy = Managers.require(EconomyModule.class);
_worldData = Managers.require(WorldDataModule.class);
_counter = new HashMap<>();
UtilServer.getServer().getPluginManager().registerEvents(this, UtilServer.getPlugin());
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
remove(event.getPlayer());
}
public void transfer(Player from, Player to)
{
// If the player has already been progressing this quest and is
// further than the other don't bother transferring their data.
if (get(to) >= get(from))
{
return;
}
set(to, get(from));
}
public void set(Player player, int amount)
{
_counter.put(player.getUniqueId(), amount);
}
public int get(Player player)
{
return _counter.getOrDefault(player.getUniqueId(), 0);
}
public int getAndIncrement(Player player, int amount)
{
int newAmount = get(player) + amount;
_counter.put(player.getUniqueId(), newAmount);
_quest.updateQuestItem(this, player);
return newAmount;
}
public void remove(Player player)
{
_counter.remove(player.getUniqueId());
}
public void onStart(Player player)
{
_economy.removeFromStore(player, _startCost);
}
public void onReward(Player player)
{
_economy.addToStore(player, "Completing " + F.elem(_name), _completeReward);
remove(player);
_quest.completeQuest(this, player);
}
public boolean isActive(Player player)
{
return _quest.isActive(this, player);
}
public abstract float getProgress(Player player);
public int getGoal()
{
return 1;
}
public final int getId()
{
return _id;
}
public final String getName()
{
return _name;
}
public final String getDescription()
{
return _description;
}
public final int getStartCost()
{
return _startCost;
}
public final int getCompleteReward()
{
return _completeReward;
}
}

View File

@ -0,0 +1,406 @@
package mineplex.gemhunters.quest;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.metadata.FixedMetadataValue;
import mineplex.core.MiniClientPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilItem;
import mineplex.core.common.util.UtilItem.ItemAttribute;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.menu.Menu;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.quest.types.ChestOpenerQuest;
import mineplex.gemhunters.quest.types.SamitoDQuest;
import mineplex.gemhunters.world.WorldDataModule;
import net.md_5.bungee.api.ChatColor;
@ReflectivelyCreateMiniPlugin
public class QuestModule extends MiniClientPlugin<QuestPlayerData>
{
private static final int MAX_QUESTS = 5;
private static final long RESET_QUESTS_TIME = TimeUnit.MINUTES.toMillis(15);
private static final Material MATERIAL = Material.PAPER;
private static final String ITEM_METADATA = "quest";
private final Quest[] _quests = {
new ChestOpenerQuest(0, "Chest Opener", 100, 250, 5),
new ChestOpenerQuest(1, "Grand Chest Opener", 200, 500, 20),
new ChestOpenerQuest(2, "Superior Chest Opener", 500, 750, 40),
new SamitoDQuest(3, "Give to the Homeless", "Donate " + F.count(String.valueOf(10)) + " gems to the Hobo.", 100, 300, 10)
};
private final WorldDataModule _worldData;
private QuestModule()
{
super("Quest");
_worldData = require(WorldDataModule.class);
Menu<?> menu = new QuestUI(this);
runSyncLater(() ->
{
for (Location location : _worldData.getCustomLocation("QUEST_NPC"))
{
new QuestNPC(this, location, menu);
}
}, 20);
}
@Override
protected QuestPlayerData addPlayer(UUID uuid)
{
return new QuestPlayerData();
}
@EventHandler
public void playerJoin(PlayerJoinEvent event)
{
updateQuests(event.getPlayer());
}
//@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.SLOW)
{
return;
}
for (Player player : Bukkit.getOnlinePlayers())
{
QuestPlayerData playerData = Get(player);
if (!UtilTime.elapsed(playerData.getLastClear(), RESET_QUESTS_TIME))
{
continue;
}
player.sendMessage(F.main(C.cYellowB + "Quest Master", "I have " + F.count(String.valueOf(MAX_QUESTS)) + " new quests for you! Come and see me to start them!"));
playerData.clear();
updateQuests(player);
}
}
@EventHandler
public void pickupItem(PlayerPickupItemEvent event)
{
if (event.isCancelled())
{
return;
}
Item item = event.getItem();
Player player = event.getPlayer();
Quest quest = fromItemStack(event.getItem().getItemStack());
if (quest == null)
{
return;
}
if (!item.hasMetadata(ITEM_METADATA))
{
return;
}
if (!Recharge.Instance.use(event.getPlayer(), "Quest Pickup " + quest.getId(), 2000, false, false))
{
event.setCancelled(true);
return;
}
boolean able = startQuest(quest, player);
if (!able)
{
event.setCancelled(true);
}
else
{
UUID owner = UUID.fromString(item.getMetadata(ITEM_METADATA).get(0).asString());
Player other = UtilPlayer.searchExact(owner);
/*
* Noting here that when a player leaves their quest progress is removed.
* However that means that if a new player picks up their quest item we
* run into a problem where that will be null. Thus the progress on that
* quest is lost.
* More complications are added when a player quits out and their NPC is
* there instead until they finally really really quit out.
* This is one massive headache in order to keep quests alive while not
* running into some serious memory leaks.
* Furthermore the time complications of this project mean that there isn't
* enough time right now to implement this (however a enough time for me
* to type this lengthy comment about it). So in true style I'm cutting
* corners and saying that if a player quits out then don't allow other
* players to be able to pickup the quest.
*/
if (other == null)
{
event.setCancelled(true);
return;
}
}
}
@EventHandler
public void dropItem(PlayerDropItemEvent event)
{
if (event.isCancelled())
{
return;
}
Player player = event.getPlayer();
Quest quest = fromItemStack(event.getItemDrop().getItemStack());
if (quest == null)
{
return;
}
cancelQuest(quest, player);
handleDroppedQuest(event.getItemDrop(), player);
}
public void handleDroppedQuest(Item item, Player player)
{
item.setMetadata(ITEM_METADATA, new FixedMetadataValue(_plugin, player.getUniqueId().toString()));
}
public void updateQuests(Player player)
{
QuestPlayerData playerData = Get(player);
List<Integer> quests = playerData.getPossibleQuests();
for (int i = 0; i < MAX_QUESTS; i++)
{
Quest quest = getRandomQuest(playerData, player);
if (quest == null)
{
player.sendMessage(F.main(_moduleName, "It seems that there was some trouble finding you a new quest. Please try again later."));
return;
}
quests.add(quest.getId());
}
}
public boolean startQuest(Quest quest, Player player)
{
if (isActive(quest, player))
{
player.sendMessage(F.main(_moduleName, "You have already accepted that quest."));
return false;
}
else if (isComplete(quest, player))
{
player.sendMessage(F.main(_moduleName, "You have already completed that quest."));
return false;
}
player.sendMessage(F.main(_moduleName, "Started " + F.name(quest.getName()) + "."));
QuestPlayerData playerData = Get(player);
playerData.getActiveQuests().add(quest.getId());
updateQuestItem(quest, player);
return true;
}
public void completeQuest(Quest quest, Player player)
{
if (!isActive(quest, player))
{
player.sendMessage(F.main(_moduleName, "This quest is not active for you."));
return;
}
player.sendMessage(F.main(_moduleName, "Completed " + F.name(quest.getName()) + "."));
QuestPlayerData playerData = Get(player);
playerData.getActiveQuests().remove(Integer.valueOf(quest.getId()));
playerData.getCompletedQuests().add(quest.getId());
updateQuestItem(quest, player);
}
public void cancelQuest(Quest quest, Player player)
{
if (!isActive(quest, player))
{
player.sendMessage(F.main(_moduleName, "This quest is not active for you."));
return;
}
player.sendMessage(F.main(_moduleName, "Dropped " + F.name(quest.getName()) + "."));
QuestPlayerData playerData = Get(player);
playerData.getActiveQuests().remove(Integer.valueOf(quest.getId()));
}
public Quest getRandomQuest(QuestPlayerData playerData, Player player)
{
int attempts = 0;
while (attempts < _quests.length * 2)
{
attempts++;
int index = UtilMath.r(_quests.length);
Quest quest = _quests[index];
if (isActive(quest, player) || isPossible(quest, player))
{
continue;
}
return quest;
}
return null;
}
public ItemStack getItemStack(Quest quest, Player player, boolean npc, boolean hasSpace)
{
ItemBuilder builder = new ItemBuilder(MATERIAL);
builder.setTitle(C.cGreen + quest.getName());
builder.addLore(C.blankLine, quest.getDescription(), C.blankLine);
boolean active = isActive(quest, player);
boolean complete = isComplete(quest, player);
if (npc)
{
if (active)
{
builder.setGlow(true);
builder.addLore(C.cRed + "You have already started this quest!");
}
else if (complete)
{
builder.addLore(C.cRed + "You have already completed this quest!");
}
else if (hasSpace)
{
builder.addLore(C.cGreen + "Click to start this quest!");
}
else
{
builder.addLore(C.cRed + "You do not have enough space in your inventory!");
}
}
else
{
builder.addLore(UtilTextMiddle.progress(quest.getProgress(player)) + C.mBody + " [" + C.cGreen + quest.get(player) + C.mBody + "/" + C.cGreen + quest.getGoal() + C.mBody + "]");
}
return builder.build();
}
public Quest fromItemStack(ItemStack itemStack)
{
Material material = itemStack.getType();
ItemMeta meta = itemStack.getItemMeta();
if (material != MATERIAL || meta == null || !meta.hasLore())
{
return null;
}
String name = ChatColor.stripColor(meta.getDisplayName());
for (Quest quest : _quests)
{
if (!quest.getName().equals(name))
{
continue;
}
return quest;
}
return null;
}
public void updateQuestItem(Quest quest, Player player)
{
ItemStack itemStack = getItemStack(quest, player, false, true);
for (ItemStack items : player.getInventory().getContents())
{
if (UtilItem.isSimilar(itemStack, items, ItemAttribute.MATERIAL, ItemAttribute.NAME, ItemAttribute.DATA))
{
player.getInventory().remove(items);
}
}
if (isActive(quest, player))
{
player.getInventory().addItem(itemStack);
}
}
public boolean isPossible(Quest quest, Player player)
{
return Get(player).getPossibleQuests().contains(quest.getId());
}
public boolean isActive(Quest quest, Player player)
{
return Get(player).getActiveQuests().contains(quest.getId());
}
public boolean isComplete(Quest quest, Player player)
{
return Get(player).getCompletedQuests().contains(quest.getId());
}
public Quest getFromId(int id)
{
for (Quest quest : _quests)
{
if (quest.getId() == id)
{
return quest;
}
}
return null;
}
}

View File

@ -0,0 +1,45 @@
package mineplex.gemhunters.quest;
import org.bukkit.Location;
import org.bukkit.entity.Villager;
import org.bukkit.entity.Villager.Profession;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.menu.Menu;
import mineplex.gemhunters.util.SimpleNPC;
public class QuestNPC extends SimpleNPC
{
private Menu<?> _questMenu;
public QuestNPC(QuestModule quest, Location spawn, Menu<?> menu)
{
super(quest.getPlugin(), spawn, Villager.class, C.cYellowB + "Quest Master", null);
_questMenu = menu;
Villager villager = (Villager) _entity;
villager.setProfession(Profession.LIBRARIAN);
}
@Override
@EventHandler
public void npcClick(PlayerInteractEntityEvent event)
{
if (!event.getRightClicked().equals(_entity))
{
return;
}
event.setCancelled(true);
event.getPlayer().sendMessage(F.main("Quest", "The Quest Master is currently disabled but will be avaiable to all players shortly."));
//_questMenu.open(event.getPlayer());/
}
}

View File

@ -0,0 +1,52 @@
package mineplex.gemhunters.quest;
import java.util.ArrayList;
import java.util.List;
public class QuestPlayerData
{
private final List<Integer> _possibleQuests;
private final List<Integer> _activeQuests;
private final List<Integer> _completedQuests;
private long _lastClear;
public QuestPlayerData()
{
_possibleQuests = new ArrayList<>();
_activeQuests = new ArrayList<>();
_completedQuests = new ArrayList<>();
_lastClear = System.currentTimeMillis();
}
public void clear()
{
_possibleQuests.clear();
_completedQuests.clear();
_lastClear = System.currentTimeMillis();
}
public List<Integer> getPossibleQuests()
{
return _possibleQuests;
}
public List<Integer> getActiveQuests()
{
return _activeQuests;
}
public List<Integer> getCompletedQuests()
{
return _completedQuests;
}
public long getLastClear()
{
return _lastClear;
}
}

View File

@ -0,0 +1,60 @@
package mineplex.gemhunters.quest;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import mineplex.core.common.util.UtilInv;
import mineplex.core.common.util.UtilUI;
import mineplex.core.menu.Button;
import mineplex.core.menu.Menu;
public class QuestUI extends Menu<QuestModule>
{
public QuestUI(QuestModule plugin)
{
super("Quest Master", plugin);
}
@Override
protected Button[] setUp(Player player)
{
Button[] buttons = new Button[21];
QuestPlayerData playerData = getPlugin().Get(player);
int i = 0;
int[] slots = UtilUI.getIndicesFor(playerData.getPossibleQuests().size(), 1);
for (Integer id : playerData.getPossibleQuests())
{
Quest quest = getPlugin().getFromId(id);
ItemStack itemStack = getPlugin().getItemStack(quest, player, true, UtilInv.hasSpace(player, 1));
buttons[slots[i++]] = new QuestSelectButton(getPlugin(), itemStack, quest);
}
return buttons;
}
public class QuestSelectButton extends Button<QuestModule>
{
private final Quest _quest;
public QuestSelectButton(QuestModule plugin, ItemStack itemStack, Quest quest)
{
super(itemStack, plugin);
_quest = quest;
}
@Override
public void onClick(Player player, ClickType clickType)
{
getPlugin().startQuest(_quest, player);
resetAndUpdate();
}
}
}

View File

@ -0,0 +1,53 @@
package mineplex.gemhunters.quest.types;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import mineplex.core.common.util.F;
import mineplex.gemhunters.loot.event.PlayerChestOpenEvent;
import mineplex.gemhunters.quest.Quest;
public class ChestOpenerQuest extends Quest
{
private final int _goal;
public ChestOpenerQuest(int id, String name, int startCost, int completeReward, int goal)
{
super(id, name, "Open " + F.count(String.valueOf(goal)) + " Chests.", startCost, completeReward);
_goal = goal;
}
@Override
public float getProgress(Player player)
{
return (float) get(player) / (float) _goal;
}
@Override
public int getGoal()
{
return _goal;
}
@EventHandler
public void chestOpen(PlayerChestOpenEvent event)
{
//DebugModule.getInstance().d(event.getEventName());
Player player = event.getPlayer();
if (!isActive(player))
{
return;
}
int amount = getAndIncrement(player, 1);
if (amount >= _goal)
{
onReward(player);
}
}
}

View File

@ -0,0 +1,82 @@
package mineplex.gemhunters.quest.types;
import org.bukkit.Color;
import org.bukkit.FireworkEffect.Type;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerInteractEvent;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilMath;
import mineplex.gemhunters.quest.Quest;
public class SamitoDQuest extends Quest
{
private static final String NPC_NAME = "Hobo";
private static final String[] REACTIONS = {
"Well hello there folks and welcome... to... my... youtube channel",
"WILLIAMMMMMMM",
"ALEXXXXXXXXXX",
"CHISS",
"Rods and Gaps",
"Hit him with that w-tap",
"You're the one who wanted to bring out bows young man"
};
private final Location _pot;
private final int _gemsToDonate;
public SamitoDQuest(int id, String name, String description, int startCost, int completeReward, int gemsToDonate)
{
super(id, name, description, startCost, completeReward);
_pot = _worldData.getCustomLocation("QUEST_SAM").get(0);
_pot.getBlock().setType(Material.FLOWER_POT);
_gemsToDonate = gemsToDonate;
}
@Override
public float getProgress(Player player)
{
return 0;
}
@EventHandler
public void onInteract(PlayerInteractEvent event)
{
Player player = event.getPlayer();
if (event.isCancelled() || !isActive(player))
{
return;
}
Block block = event.getClickedBlock();
if (block == null)
{
return;
}
if (UtilMath.offsetSquared(block.getLocation(), _pot) < 4)
{
if (_economy.getGems(player) < _gemsToDonate)
{
player.sendMessage(F.main(NPC_NAME, "Awww come on man, even alex has more gems than you."));
return;
}
player.sendMessage(F.main(NPC_NAME, REACTIONS[UtilMath.random.nextInt(REACTIONS.length)]));
_economy.removeFromStore(player, _gemsToDonate);
UtilFirework.playFirework(_pot, Type.BURST, Color.GREEN, true, false);
onReward(player);
}
}
}

View File

@ -0,0 +1,216 @@
package mineplex.gemhunters.safezone;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.world.WorldDataModule;
@ReflectivelyCreateMiniPlugin
public class SafezoneModule extends MiniPlugin
{
private static final String SAFEZONE_DATA_PREFIX = "SAFEZONE";
private static final String SAFEZONE_DATA_IGNORE = "IGNORE";
private final WorldDataModule _worldData;
private final Map<UUID, String> _currentSafezone;
private SafezoneModule()
{
super("Safezone");
_worldData = require(WorldDataModule.class);
_currentSafezone = new HashMap<>();
}
@EventHandler
public void updateSafeZone(UpdateEvent event)
{
if (event.getType() != UpdateType.FAST)
{
return;
}
for (Player player : UtilServer.getPlayers())
{
UUID key = player.getUniqueId();
String oldSafezone = _currentSafezone.get(key);
boolean isInOldSafezone = oldSafezone != null;
String newSafezone = getSafezone(player.getLocation());
boolean isInNewSafezone = newSafezone != null;
// null -> not null
if (!isInOldSafezone && isInNewSafezone)
{
if (!newSafezone.contains(SAFEZONE_DATA_IGNORE))
{
UtilTextMiddle.display("", C.cYellow + "Entering " + newSafezone, 10, 40, 10, player);
}
_currentSafezone.put(key, newSafezone);
}
// not null -> null
else if (isInOldSafezone && !isInNewSafezone)
{
if (!oldSafezone.contains(SAFEZONE_DATA_IGNORE))
{
UtilTextMiddle.display("", C.cYellow + "Leaving " + oldSafezone, 10, 40, 10, player);
}
_currentSafezone.put(key, null);
}
}
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
Player player = event.getPlayer();
_currentSafezone.remove(player.getUniqueId());
}
@EventHandler
public void entityDamage(EntityDamageEvent event)
{
if (!(event.getEntity() instanceof Player))
{
return;
}
Player player = (Player) event.getEntity();
if (isInSafeZone(player.getLocation()))
{
event.setCancelled(true);
}
}
@EventHandler
public void entityAttack(EntityDamageByEntityEvent event)
{
// Handle people shooting arrows at people outside a safezone
if (event.getDamager() instanceof Projectile)
{
Projectile projectile = (Projectile) event.getDamager();
if (projectile.getShooter() instanceof LivingEntity)
{
LivingEntity entity = (LivingEntity) projectile.getShooter();
if (isInSafeZone(entity.getLocation()))
{
event.setCancelled(true);
return;
}
}
}
if (!(event.getDamager() instanceof Player))
{
return;
}
Player player = (Player) event.getDamager();
if (isInSafeZone(player.getLocation()))
{
event.setCancelled(true);
}
}
@EventHandler
public void hungerChange(FoodLevelChangeEvent event)
{
if (isInSafeZone(event.getEntity().getLocation()) && event.getEntity() instanceof Player)
{
Player player = (Player) event.getEntity();
if (player.getFoodLevel() < event.getFoodLevel())
{
return;
}
event.setCancelled(true);
}
}
public boolean isInSafeZone(Location location)
{
return getSafezone(location) != null;
}
public boolean isInSafeZone(Location location, String safezone)
{
if (safezone == null)
{
return false;
}
List<Location> bounds = _worldData.getCustomLocation(SAFEZONE_DATA_PREFIX + " " + safezone);
if (bounds == null || bounds.size() != 2)
{
log("Error regarding safezone bounds for region " + safezone + " there are " + bounds.size() + " points instead of 2. Ignoring this safezone!");
return false;
}
return UtilAlg.inBoundingBox(location, bounds.get(0), bounds.get(1));
}
public String getSafezone(Location location)
{
Map<String, List<Location>> customLocations = _worldData.getAllCustomLocations();
for (String key : customLocations.keySet())
{
if (!key.startsWith(SAFEZONE_DATA_PREFIX))
{
continue;
}
List<Location> bounds = customLocations.get(key);
if (bounds.size() != 2)
{
log("Error regarding safezone bounds for region " + key + " there are " + bounds.size() + " points instead of 2. Ignoring this safezone!");
continue;
}
if (UtilAlg.inBoundingBox(location, bounds.get(0), bounds.get(1)))
{
String name = "";
String[] split = key.split(" ");
for (int i = 1; i < split.length; i++)
{
name += split[i] + " ";
}
return name.trim();
}
}
return null;
}
}

View File

@ -0,0 +1,78 @@
package mineplex.gemhunters.scoreboard;
import org.bukkit.entity.Player;
import mineplex.core.Managers;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilTime;
import mineplex.core.scoreboard.WritableMineplexScoreboard;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.supplydrop.SupplyDropModule;
import mineplex.gemhunters.worldevent.WorldEvent;
import mineplex.gemhunters.worldevent.WorldEventModule;
public class GemHuntersScoreboard extends WritableMineplexScoreboard
{
private final EconomyModule _economy;
private final WorldEventModule _worldEvent;
private final SupplyDropModule _supplyDrop;
public GemHuntersScoreboard(Player player)
{
super(player);
_economy = Managers.require(EconomyModule.class);
_worldEvent = Managers.require(WorldEventModule.class);
_supplyDrop = Managers.require(SupplyDropModule.class);
}
public void writeContent(Player player)
{
writeNewLine();
write(C.cGreenB + "Gems Earned");
write(String.valueOf(_economy.getGems(player)));
writeNewLine();
write(C.cGoldB + "Supply Drop");
if (_supplyDrop.isActive())
{
write(_supplyDrop.getActive().getName() + " - " + (int) UtilMath.offset(player.getLocation(), _supplyDrop.getActive().getChestLocation()) + "m");
}
else
{
write(UtilTime.MakeStr(_supplyDrop.getLastSupplyDrop() + _supplyDrop.getSequenceTimer() - System.currentTimeMillis()));
}
writeNewLine();
write(C.cYellowB + "World Event");
if (!_worldEvent.isEventActive())
{
write(UtilTime.MakeStr(_worldEvent.getLastEventComplete() + _worldEvent.getEventTimer() - System.currentTimeMillis()));
}
else
{
for (WorldEvent event : _worldEvent.getActiveEvents())
{
write(event.getEventType().getName() + " (" + event.getEventState().getName() + ")");
}
}
writeNewLine();
}
public String getSuffix(Player perspective, Player subject)
{
return C.cGray + " " + perspective.getName();
}
public int getUndernameScore(Player player)
{
return _economy.getGems(player);
}
}

View File

@ -0,0 +1,204 @@
package mineplex.gemhunters.scoreboard;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Score;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.economy.EconomyModule;
@ReflectivelyCreateMiniPlugin
public class ScoreboardModule extends MiniPlugin
{
private static final String PRIMARY_COLOUR = C.cGreenB;
private static final String SECONDARY_COLOUR = C.cWhiteB;
private static final String TRANSITION_COLOUR = C.cDGreenB;
private static final String SCOREBOARD_TITLE = " GEM HUNTERS ";
private final EconomyModule _economy;
private final Map<UUID, GemHuntersScoreboard> _scoreboards;
private int _shineIndex;
private boolean _shineDirection = true;
public ScoreboardModule()
{
super("Scoreboard");
_economy = require(EconomyModule.class);
_scoreboards = new HashMap<>();
}
@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() == UpdateType.FAST)
{
for (UUID key : _scoreboards.keySet())
{
GemHuntersScoreboard scoreboard = _scoreboards.get(key);
Player player = UtilPlayer.searchExact(key);
scoreboard.writeContent(player);
scoreboard.draw();
}
}
else if (event.getType() == UpdateType.FASTEST)
{
updateTitles();
}
}
@EventHandler
public void playerJoin(PlayerJoinEvent event)
{
createPlayerScoreboard(event.getPlayer());
}
@EventHandler
public void playerQuit(PlayerQuitEvent event)
{
Player player = event.getPlayer();
for (GemHuntersScoreboard scoreboard : _scoreboards.values())
{
scoreboard.getHandle().getTeam(player.getName()).unregister();
}
_scoreboards.remove(player.getUniqueId());
}
@EventHandler
public void updateGemsCounter(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC_08)
{
return;
}
for (Player player : Bukkit.getOnlinePlayers())
{
int gems = _economy.getGems(player);
for (GemHuntersScoreboard scoreboard : _scoreboards.values())
{
Objective objective = scoreboard.getHandle().getObjective(DisplaySlot.BELOW_NAME);
Score score = objective.getScore(player.getName());
if (score.getScore() == gems)
{
continue;
}
score.setScore(gems);
}
}
}
public void createPlayerScoreboard(Player player)
{
if (!_scoreboards.containsKey(player.getUniqueId()))
{
GemHuntersScoreboard scoreboard = new GemHuntersScoreboard(player);
Scoreboard handle = scoreboard.getHandle();
_scoreboards.put(player.getUniqueId(), scoreboard);
// Gem Counter Undername
Objective gemCounter = handle.registerNewObjective("Gems", "Gems");
gemCounter.setDisplaySlot(DisplaySlot.BELOW_NAME);
for (GemHuntersScoreboard other : _scoreboards.values())
{
// Set the other player's name tag for the player joining
Player otherPlayer = other.getOwner();
Team team = handle.registerNewTeam(otherPlayer.getName());
team.setPrefix(C.cYellow);
//team.setSuffix(scoreboard.getSuffix(player, otherPlayer));
team.addEntry(otherPlayer.getName());
if (player.equals(otherPlayer))
{
continue;
}
// Set the player that is joining
Scoreboard otherHandle = other.getHandle();
Team otherTeam = otherHandle.registerNewTeam(player.getName());
otherTeam.setPrefix(C.cYellow);
//otherTeam.setSuffix(other.getSuffix(other.getOwner(), player));
otherTeam.addEntry(player.getName());
}
player.setScoreboard(scoreboard.getHandle());
}
}
public void updateTitles()
{
String out = (_shineDirection ? PRIMARY_COLOUR : SECONDARY_COLOUR);
for (int i = 0; i < SCOREBOARD_TITLE.length(); i++)
{
char c = SCOREBOARD_TITLE.charAt(i);
if (_shineDirection)
{
if (i == _shineIndex)
{
out += TRANSITION_COLOUR;
}
else if (i == _shineIndex + 1)
{
out += SECONDARY_COLOUR;
}
}
else
{
if (i == _shineIndex)
{
out += TRANSITION_COLOUR;
}
else if (i == _shineIndex + 1)
{
out += PRIMARY_COLOUR;
}
}
out += c;
}
for (GemHuntersScoreboard scoreboard : _scoreboards.values())
{
scoreboard.setSidebarName(out);
}
_shineIndex++;
if (_shineIndex == SCOREBOARD_TITLE.length() * 2)
{
_shineIndex = 0;
_shineDirection = !_shineDirection;
}
}
}

View File

@ -0,0 +1,261 @@
package mineplex.gemhunters.shop;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilTime;
import mineplex.core.google.GoogleSheetsManager;
import mineplex.core.google.SheetObjectDeserialiser;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.loot.deserialisers.LootItemDeserialiser;
import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.shop.deserialisers.VillagerPropertiesDeserialiser;
import mineplex.gemhunters.util.SlackSheetsBot;
import mineplex.gemhunters.world.WorldDataModule;
@ReflectivelyCreateMiniPlugin
public class ShopModule extends MiniPlugin
{
private static final String SHEET_FILE_NAME = "GEM_HUNTERS_SHOP";
private static final String VILLAGER_MASTER_SHEET_NAME = "VILLAGER_MASTER";
private static final VillagerPropertiesDeserialiser VILLAGER_PROPERTIES_DESERIALISER = new VillagerPropertiesDeserialiser();
private static final LootItemDeserialiser DESERIALISER = new LootItemDeserialiser();
private static final SheetObjectDeserialiser<Integer> COST_DESERIALISER = new SheetObjectDeserialiser<Integer>()
{
@Override
public Integer deserialise(String[] values) throws ArrayIndexOutOfBoundsException, NumberFormatException
{
return Integer.parseInt(values[10]);
}
};
private static final int MINIMUM_ITEMS = 1;
private static final int MAXIMUM_ITEMS = 5;
private static final String[] NAMES = {
"Andrew", "Jon", "Bob", "Sam", "Ronan", "Alex", "Joe", "Emma", "Giovani", "Dean", "Josh", "Geoffrey", "Parker", "Spencer", "Luke", "Peter", "William", "Connor"
};
private final GoogleSheetsManager _sheets;
private final SafezoneModule _safezone;
private final WorldDataModule _worldData;
private final Map<String, Set<TradeableItem>> _trades;
private final Map<String, VillagerProperties> _properties;
private final List<TraderNPC> _npcs;
private final Map<String, Set<Integer>> _spawnedIndexes;
private ShopModule()
{
super("Shop");
_sheets = require(GoogleSheetsManager.class);
_safezone = require(SafezoneModule.class);
_worldData = require(WorldDataModule.class);
_trades = new HashMap<>();
_properties = new HashMap<>();
_npcs = new ArrayList<>();
_spawnedIndexes = new HashMap<>();
runSyncLater(() -> updateVillagerTrades(), 20);
}
public void updateVillagerTrades()
{
log("Updating villager trades");
Map<String, List<List<String>>> map = _sheets.getSheetData(SHEET_FILE_NAME);
for (String key : map.keySet())
{
if (key.equals(VILLAGER_MASTER_SHEET_NAME))
{
int row = 0;
for (List<String> rows : map.get(key))
{
row++;
try
{
VillagerProperties properties = VILLAGER_PROPERTIES_DESERIALISER.deserialise(rows.toArray(new String[0]));
_properties.put(properties.getDataKey(), properties);
}
catch (Exception e)
{
if (row != 1)
{
SlackSheetsBot.reportParsingError(e, "Villager Trades", key, row);
}
continue;
}
}
continue;
}
Set<TradeableItem> items = new HashSet<>();
int row = 0;
for (List<String> rows : map.get(key))
{
row++;
try
{
String[] values = rows.toArray(new String[0]);
items.add(new TradeableItem(DESERIALISER.deserialise(values), COST_DESERIALISER.deserialise(values)));
}
catch (Exception e)
{
if (row != 1)
{
SlackSheetsBot.reportParsingError(e, "Villager Trades", key, row);
}
continue;
}
}
_trades.put(key, items);
}
log("Finished updating villager trades");
}
@EventHandler
public void updateSpawnedVillagers(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
Iterator<TraderNPC> iterator = _npcs.iterator();
while (iterator.hasNext())
{
TraderNPC npc = iterator.next();
int expireTime = npc.getProperties().getExpireRate();
if (expireTime > 0 && UtilTime.elapsed(npc.getSpawnedAt(), expireTime))
{
npc.getEntity().remove();
iterator.remove();
}
}
for (String key : _properties.keySet())
{
List<Location> locations = _worldData.getSpawnLocation(capitalise(key));
VillagerProperties properties = _properties.get(key);
if (!UtilTime.elapsed(properties.getLastSpawn(), properties.getSpawnRate()))
{
continue;
}
properties.setLastSpawn();
// Only spawn more chests if we need to
int max = properties.getMax();
int spawned = 0;
for (TraderNPC npc : _npcs)
{
if (npc.getProperties().getDataKey().equals(key))
{
spawned++;
}
}
// If there are too many chests of this type we can ignore it
if (spawned > max)
{
continue;
}
Set<Integer> usedIndexes = _spawnedIndexes.get(key);
if (usedIndexes == null)
{
_spawnedIndexes.put(key, new HashSet<>());
usedIndexes = _spawnedIndexes.get(key);
}
if (locations.size() == usedIndexes.size())
{
continue;
}
int index = getFreeIndex(locations.size(), usedIndexes);
if (index == -1)
{
return;
}
Location randomLocation = locations.get(index);
randomLocation.setYaw(UtilMath.r(360));
usedIndexes.add(index);
//DebugModule.getInstance().d("Trader at " + UtilWorld.locToStrClean(randomLocation) + " with key=" + key + " and index=" + index + " and max=" + spawned + "/" + max);
_npcs.add(new TraderNPC(_plugin, randomLocation, Villager.class, NAMES[UtilMath.r(NAMES.length)], _safezone.isInSafeZone(randomLocation), properties, getRandomItemSet(_trades.get(key))));
}
}
private int getFreeIndex(int endIndex, Set<Integer> used)
{
int index = -1;
while (index == -1 || used.contains(index))
{
index = UtilMath.r(endIndex);
}
used.add(index);
return index;
}
private Set<TradeableItem> getRandomItemSet(Set<TradeableItem> items)
{
int size = UtilMath.rRange(MINIMUM_ITEMS, MAXIMUM_ITEMS);
Set<TradeableItem> items2 = new HashSet<>(size);
for (int i = 0; i < size; i++)
{
items2.add(UtilAlg.Random(items));
}
return items2;
}
private final String capitalise(String s)
{
String right = s.toLowerCase().substring(1);
char left = Character.toUpperCase(s.charAt(0));
return left + right;
}
}

View File

@ -0,0 +1,27 @@
package mineplex.gemhunters.shop;
import mineplex.gemhunters.loot.LootItem;
public class TradeableItem
{
private final LootItem _item;
private final int _cost;
public TradeableItem(LootItem item, int cost)
{
_item = item;
_cost = cost;
}
public LootItem getLootItem()
{
return _item;
}
public int getCost()
{
return _cost;
}
}

View File

@ -0,0 +1,158 @@
package mineplex.gemhunters.shop;
import java.util.List;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import mineplex.core.Managers;
import mineplex.core.common.currency.GlobalCurrency;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilInv;
import mineplex.core.itemstack.ItemBuilder;
import mineplex.core.itemstack.ItemStackFactory;
import mineplex.gemhunters.economy.EconomyModule;
import mineplex.gemhunters.util.SimpleNPC;
public class TraderNPC extends SimpleNPC
{
private final EconomyModule _economy;
private final VillagerProperties _properties;
private final Set<TradeableItem> _selling;
private final Inventory _inv;
private final long _spawnedAt;
public TraderNPC(JavaPlugin plugin, Location spawn, Class<? extends LivingEntity> type, String name, boolean vegetated, VillagerProperties properties, Set<TradeableItem> selling)
{
super(plugin, spawn, type, name, null, vegetated);
_economy = Managers.require(EconomyModule.class);
_properties = properties;
_selling = selling;
_inv = plugin.getServer().createInventory(null, 9, name);
_spawnedAt = System.currentTimeMillis();
int index = 1;
for (TradeableItem item : _selling)
{
ItemStack itemStack = new ItemBuilder(item.getLootItem().getItemStack()).addLore("Cost: " + F.currency(GlobalCurrency.GEM, item.getCost())).build();
_inv.setItem(index++, itemStack);
}
}
@Override
@EventHandler
public void npcClick(PlayerInteractEntityEvent event)
{
super.npcClick(event);
if (event.getRightClicked().equals(_entity))
{
event.setCancelled(true);
event.getPlayer().openInventory(_inv);
}
}
@EventHandler
public void inventoryClick(InventoryClickEvent event)
{
if (event.getInventory() == null)
{
return;
}
if (!event.getInventory().equals(_inv))
{
return;
}
event.setCancelled(true);
ItemStack itemStack = event.getCurrentItem();
if (itemStack == null)
{
return;
}
Player player = (Player) event.getWhoClicked();
int gems = _economy.getGems(player);
int cost = fromItemStack(itemStack);
if (cost == 0)
{
return;
}
if (cost > gems)
{
player.sendMessage(F.main(_entity.getCustomName(), "I'm sorry you don't have enough gems to purchase this."));
player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0.6F);
return;
}
if (!UtilInv.HasSpace(player, itemStack.getType(), itemStack.getAmount()))
{
player.sendMessage(F.main(_entity.getCustomName(), "I'm sorry you don't have enough space to hold that."));
player.playSound(player.getLocation(), Sound.ITEM_BREAK, 1, 0.6F);
return;
}
_economy.removeFromStore(player, cost);
// Remove cost lore
ItemBuilder builder = new ItemBuilder(itemStack);
List<String> lore = builder.getLore();
lore.remove(lore.size() - 1);
builder.setLore(lore.toArray(new String[0]));
itemStack = builder.build();
String itemName = ItemStackFactory.Instance.GetName(itemStack, true);
player.sendMessage(F.main(_entity.getCustomName(), "Purchased " + F.elem(itemName) + "!"));
player.playSound(player.getLocation(), Sound.NOTE_PLING, 1, 1.2F);
player.getInventory().addItem(itemStack);
}
public int fromItemStack(ItemStack itemStack)
{
for (TradeableItem item : _selling)
{
ItemStack itemStack2 = item.getLootItem().getItemStack();
if (itemStack.getType() == itemStack2.getType())
{
return item.getCost();
}
}
return 0;
}
public final VillagerProperties getProperties()
{
return _properties;
}
public final long getSpawnedAt()
{
return _spawnedAt;
}
}

View File

@ -0,0 +1,59 @@
package mineplex.gemhunters.shop;
public class VillagerProperties
{
private final String _name;
private final String _dataKey;
private final int _spawnRate;
private final int _expireRate;
private final int _max;
private long _lastSpawn;
public VillagerProperties(String name, String dataKey, int spawnRate, int expireRate, int max)
{
_name = name;
_dataKey = dataKey;
_spawnRate = spawnRate;
_expireRate = expireRate;
_max = max;
setLastSpawn();
}
public final String getName()
{
return _name;
}
public final String getDataKey()
{
return _dataKey;
}
public final int getSpawnRate()
{
return _spawnRate;
}
public final int getExpireRate()
{
return _expireRate;
}
public final int getMax()
{
return _max;
}
public void setLastSpawn()
{
_lastSpawn = System.currentTimeMillis();
}
public long getLastSpawn()
{
return _lastSpawn;
}
}

View File

@ -0,0 +1,23 @@
package mineplex.gemhunters.shop.deserialisers;
import mineplex.core.google.SheetObjectDeserialiser;
import mineplex.gemhunters.shop.VillagerProperties;
public class VillagerPropertiesDeserialiser implements SheetObjectDeserialiser<VillagerProperties>
{
@Override
public VillagerProperties deserialise(String[] values) throws ArrayIndexOutOfBoundsException
{
String name = values[0];
String dataKey = values[1];
int spawnRate = Integer.parseInt(values[4]);
int expireRate = Integer.parseInt(values[5]);
int max = Integer.parseInt(values[7]);
return new VillagerProperties(name, dataKey, spawnRate, expireRate, max);
}
}

View File

@ -0,0 +1,226 @@
package mineplex.gemhunters.spawn;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.WorldBorder;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scheduler.BukkitRunnable;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.portal.GenericServer;
import mineplex.core.portal.Intent;
import mineplex.core.portal.Portal;
import mineplex.gemhunters.death.npc.CombatLogNPC;
import mineplex.gemhunters.death.npc.NPCManager;
import mineplex.gemhunters.death.npc.PlayerInfo;
import mineplex.gemhunters.safezone.SafezoneModule;
import mineplex.gemhunters.spawn.event.PlayerTeleportIntoMapEvent;
import mineplex.gemhunters.util.ColouredTextAnimation;
import mineplex.gemhunters.util.SimpleNPC;
import mineplex.gemhunters.world.WorldDataModule;
@ReflectivelyCreateMiniPlugin
public class SpawnModule extends MiniPlugin
{
public static final int WORLD_BORDER_RADIUS = 1024;
private static final int MAX_SPAWNING_Y = 73;
private static final int MIN_PLAYER_DISTANCE_SQUARED = 6400;
private final SafezoneModule _safezone;
private final WorldDataModule _worldData;
private Location _spawn;
private Location _center;
private boolean _npcsSpawned;
private SpawnModule()
{
super("Spawn");
_safezone = require(SafezoneModule.class);
_worldData = require(WorldDataModule.class);
}
@EventHandler(priority = EventPriority.LOWEST)
public void playerJoin(PlayerJoinEvent event)
{
if (_spawn == null || _center == null)
{
_spawn = _worldData.getCustomLocation("PLAYER_SPAWN").get(0);
_center = new Location(_worldData.World, 0, 64, 0);
}
Player player = event.getPlayer();
NPCManager npcManager = NPCManager.getInstance();
if (npcManager.hasLogoutNpc(player))
{
CombatLogNPC npc = npcManager.getLogoutNpc(player);
PlayerInfo info = npc.getPlayerInfo();
info.restore();
return;
}
player.teleport(_spawn);
player.setFoodLevel(20);
player.setExhaustion(0);
player.getInventory().clear();
player.getInventory().setArmorContents(null);
player.updateInventory();
if (_npcsSpawned)
{
return;
}
WorldBorder border = _spawn.getWorld().getWorldBorder();
border.setCenter(_spawn);
border.setSize(WORLD_BORDER_RADIUS * 2);
_npcsSpawned = true;
{
Location location = _worldData.getCustomLocation("TELEPORT_NPC").get(0);
location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, _spawn)));
new SimpleNPC(_plugin, location, Villager.class, C.cDRed + "! " + C.cRedB + "Enter The World" + C.cDRed + " !", clicker -> {
Location toTeleport = getRandomLocation();
if (toTeleport == null)
{
clicker.sendMessage(F.main(_moduleName, "A suitable teleport location could not be found. Please try again in a few seconds."));
return;
}
PlayerTeleportIntoMapEvent teleportEvent = new PlayerTeleportIntoMapEvent(clicker, toTeleport);
UtilServer.CallEvent(teleportEvent);
if (teleportEvent.isCancelled())
{
clicker.sendMessage(F.main(_moduleName, "Something went wrong there, sorry. Please try again in a few seconds."));
return;
}
clicker.teleport(toTeleport);
clicker.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 4 * 20, 9));
clicker.addPotionEffect(new PotionEffect(PotionEffectType.DAMAGE_RESISTANCE, 4 * 20, 9));
ColouredTextAnimation animation = new ColouredTextAnimation("GEM HUNTERS", C.cGoldB + "M ", C.cGoldB + " M", new String[] { C.cDGreenB, C.cGreenB, C.cWhiteB });
runSyncTimer(new BukkitRunnable()
{
@Override
public void run()
{
if (animation.displayAsTitle(clicker))
{
cancel();
}
}
}, 10, 4);
});
}
{
Location location = _worldData.getCustomLocation("RETURN_TO_HUB").get(0);
location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, _spawn)));
new SimpleNPC(_plugin, location, Villager.class, C.cGoldB + "Return To Hub", clicker -> {
Portal.getInstance().sendPlayerToGenericServer(clicker, GenericServer.BETA_HUB, Intent.PLAYER_REQUEST);
});
}
{
Location location = _worldData.getCustomLocation("TUTORIAL").get(0);
location.setYaw(UtilAlg.GetYaw(UtilAlg.getTrajectory(location, _spawn)));
new SimpleNPC(_plugin, location, Villager.class, C.cGoldB + "Tutorial", clicker -> {
clicker.sendMessage(F.main(_moduleName, "A tutorial will be coming soon."));
});
}
}
public void teleportToSpawn(Player player)
{
player.teleport(_spawn);
}
public boolean isSuitable(Block block)
{
Block up = block.getRelative(BlockFace.UP);
Block down = block.getRelative(BlockFace.DOWN);
if (block.getType() != Material.AIR || down.getType() == Material.AIR || UtilBlock.liquid(down) || UtilBlock.liquid(up) || UtilBlock.liquid(block) || _safezone.isInSafeZone(block.getLocation()) || block.getLocation().getBlockY() > MAX_SPAWNING_Y)
{
return false;
}
for (Player player : Bukkit.getOnlinePlayers())
{
if (_safezone.isInSafeZone(player.getLocation()))
{
continue;
}
if (UtilMath.offsetSquared(player.getLocation(), block.getLocation()) < MIN_PLAYER_DISTANCE_SQUARED)
{
return false;
}
}
return true;
}
public Location getRandomLocation()
{
int attempts = 0;
double range = WORLD_BORDER_RADIUS * 0.5;
while (attempts < 100)
{
Location possible = UtilBlock.getHighest(_worldData.World, UtilAlg.getRandomLocation(_center, range)).getLocation();
if (isSuitable(possible.getBlock()))
{
return possible.add(0, 1, 0);
}
attempts++;
}
return null;
}
public Location getCenter()
{
return _center;
}
}

View File

@ -0,0 +1,56 @@
package mineplex.gemhunters.spawn.event;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
public class PlayerTeleportIntoMapEvent extends PlayerEvent implements Cancellable
{
private static final HandlerList HANDLERS = new HandlerList();
private boolean _cancel;
private Location _to;
public PlayerTeleportIntoMapEvent(Player who, Location to)
{
super(who);
_to = to;
}
public void setTo(Location to)
{
_to = to;
}
public Location getTo()
{
return _to;
}
public HandlerList getHandlers()
{
return HANDLERS;
}
public static HandlerList getHandlerList()
{
return HANDLERS;
}
@Override
public boolean isCancelled()
{
return _cancel;
}
@Override
public void setCancelled(boolean cancel)
{
_cancel = cancel;
}
}

View File

@ -0,0 +1,225 @@
package mineplex.gemhunters.supplydrop;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.DyeColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.FallingBlock;
import org.bukkit.util.BlockVector;
import mineplex.core.common.block.schematic.Schematic;
import mineplex.core.common.block.schematic.SchematicData;
import mineplex.core.common.block.schematic.UtilSchematic;
import mineplex.core.common.util.UtilFirework;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilShapes;
/**
* Represents an instance of a Supply Drop. <br>
* A supply drop consists of a helicopter flying through the map from a one
* location to another. Upon reaching it's destination it will drop a loot chest
* which players can then fight over. <br>
* The helicopter will then fly away towards a despawning location. <br>
* <br>
* The helicopter will be made up of a collection of blocks that are moved along
* a linear path. The look of this helicopter is saved in the map and is stored
* in internal memory on startup. <br>
* <br>
* The blades of the helicopter rotate, this is done within this class. <br>
* <br>
* {@link SupplyDropModule} handles when and where these supply drops will
* spawn.
*/
public class SupplyDrop
{
private static final String SCHEMATIC_PATH = ".." + File.separator + ".." + File.separator + "update" + File.separator + "files" + File.separator + "Helicopter.schematic";
private static final int BLADE_LENGTH = 7;
private final String _name;
private Location _destination;
private Location _despawn;
private Location _current;
private Location _blade;
private Schematic _schematic;
private Set<Block> _lastHelicopter;
private Set<Block> _bladeBlocks;
private boolean _diagonal;
public SupplyDrop(String name, Location spawn, Location destination, Location despawn)
{
_name = name;
_destination = destination.clone();
_despawn = despawn.clone();
_current = spawn.clone().add(-2, 0, 0);
try
{
_schematic = UtilSchematic.loadSchematic(new File(SCHEMATIC_PATH));
}
catch (IOException e)
{
e.printStackTrace();
return;
}
_lastHelicopter = new HashSet<>(100);
_bladeBlocks = new HashSet<>(20);
_diagonal = false;
}
public boolean advancePath()
{
boolean done = moveHelicopter();
if (!done)
{
rotateBlades();
}
_current.add(0, 0, 1);
return done;
}
public boolean moveHelicopter()
{
_current.getChunk().load();
for (Block block : _lastHelicopter)
{
block.setType(Material.AIR);
}
_lastHelicopter.clear();
if (_blade != null)
{
if (UtilMath.offset2d(_blade, _destination) < 1)
{
spawnLootChest();
}
else if (UtilMath.offset2d(_blade, _despawn) < 1)
{
for (Block block : _bladeBlocks)
{
block.setType(Material.AIR);
}
return true;
}
}
SchematicData data = _schematic.paste(_current, true);
_blade = data.getDataLocationMap().getIronLocations(DyeColor.RED).get(0);
for (BlockVector vector : data.getBlocks())
{
Location location = _current.add(vector);
_lastHelicopter.add(location.getBlock());
_current.subtract(vector);
}
return false;
}
public void rotateBlades()
{
_diagonal = !_diagonal;
for (Block block : _bladeBlocks)
{
block.setType(Material.AIR);
}
_bladeBlocks.clear();
if (_diagonal)
{
for (int x = -1; x <= 1; x += 2)
{
for (int z = -1; z <= 1; z += 2)
{
for (Location location : UtilShapes.getLinesLimitedPoints(_blade, _blade.clone().add(x * BLADE_LENGTH, 0, z * BLADE_LENGTH), BLADE_LENGTH))
{
Block block = location.getBlock();
_bladeBlocks.add(block);
block.setType(Material.STEP);
}
}
}
}
else
{
for (int x = -1; x <= 1; x += 2)
{
for (Location location : UtilShapes.getLinesLimitedPoints(_blade, _blade.clone().add(x * BLADE_LENGTH, 0, 0), BLADE_LENGTH))
{
Block block = location.getBlock();
_bladeBlocks.add(block);
block.setType(Material.STEP);
}
}
for (int z = -1; z <= 1; z += 2)
{
for (Location location : UtilShapes.getLinesLimitedPoints(_blade, _blade.clone().add(0, 0, z * BLADE_LENGTH), BLADE_LENGTH))
{
Block block = location.getBlock();
_bladeBlocks.add(block);
block.setType(Material.STEP);
}
}
}
}
public void stop()
{
for (Block block : _bladeBlocks)
{
block.setType(Material.AIR);
}
for (Block block : _lastHelicopter)
{
block.setType(Material.AIR);
}
}
public void spawnLootChest()
{
FallingBlock fallingBlock = _blade.getWorld().spawnFallingBlock(_blade.clone().subtract(0, 10, 0), Material.WOOD, (byte) 0);
fallingBlock.setHurtEntities(false);
fallingBlock.setDropItem(false);
UtilFirework.playFirework(fallingBlock.getLocation().add(0.5, 1, 0.5), UtilFirework.getRandomFireworkEffect(false, 2, 1));
}
public final String getName()
{
return _name;
}
public final Location getCurrentLocation()
{
return _current;
}
public final Location getChestLocation()
{
return _destination;
}
}

View File

@ -0,0 +1,223 @@
package mineplex.gemhunters.supplydrop;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.FallingBlock;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.ItemSpawnEvent;
import mineplex.core.MiniPlugin;
import mineplex.core.ReflectivelyCreateMiniPlugin;
import mineplex.core.blockrestore.BlockRestore;
import mineplex.core.common.Pair;
import mineplex.core.common.util.C;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.UtilTextMiddle;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.UtilWorld;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import mineplex.gemhunters.loot.LootModule;
import mineplex.gemhunters.supplydrop.command.SupplyDropCommand;
import mineplex.gemhunters.world.WorldDataModule;
@ReflectivelyCreateMiniPlugin
public class SupplyDropModule extends MiniPlugin
{
private static final long SEQUENCE_TIMER = TimeUnit.MINUTES.toMillis(15);
private static final String CHEST_COLOUR = "RED";
private static final String LOCATION_DATA = "SUPPLY_DROP";
private final BlockRestore _blockRestore;
private final LootModule _loot;
private final WorldDataModule _worldData;
private final Set<Block> _beaconBlocks;
private String[] _locationKeys;
private SupplyDrop _current;
private long _lastSupplyDrop;
private SupplyDropModule()
{
super("Supply Drop");
_blockRestore = require(BlockRestore.class);
_loot = require(LootModule.class);
_worldData = require(WorldDataModule.class);
_beaconBlocks = new HashSet<>();
_lastSupplyDrop = System.currentTimeMillis();
}
@Override
public void addCommands()
{
addCommand(new SupplyDropCommand(this));
}
@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.SEC)
{
return;
}
if (isActive())
{
if (_current.advancePath())
{
stopSequence();
}
}
else if (UtilTime.elapsed(_lastSupplyDrop, SEQUENCE_TIMER))
{
startSequence();
}
}
@EventHandler
public void itemSpawn(ItemSpawnEvent event)
{
// The Helicopter has a door. This stops it dropping items when it
// moves.
if (event.getEntity().getItemStack().getType() == Material.IRON_DOOR)
{
event.setCancelled(true);
}
}
@EventHandler
public void fallingBlockChange(EntityChangeBlockEvent event)
{
if (event.getEntity() instanceof FallingBlock && event.getTo() == Material.WOOD && isActive() && UtilMath.offsetSquared(_current.getChestLocation(), event.getBlock().getLocation()) < 4)
{
Block block = event.getBlock();
block.setType(Material.CHEST);
// Add location that the chest will appear at into the spawned
// chests list so that LootModule can populate it with loot.
_loot.addSpawnedChest(block.getLocation(), CHEST_COLOUR);
// Remove beacon
for (Block beacon : _beaconBlocks)
{
_blockRestore.restore(beacon);
}
_beaconBlocks.clear();
event.setCancelled(true);
}
}
public void startSequence(String locationKey)
{
Location spawn = _worldData.getCustomLocation(LOCATION_DATA + " " + locationKey + " Start").get(0);
Location destination = _worldData.getCustomLocation(LOCATION_DATA + " " + locationKey + " Chest").get(0);
Location despawn = _worldData.getCustomLocation(LOCATION_DATA + " " + locationKey + " End").get(0);
// Construct a beacon
for (Pair<Location, Pair<Material, Byte>> pair : UtilBlock.getBeaconBlocks(destination, (byte) 0))
{
// Look it's like a maze
_beaconBlocks.add(pair.getLeft().getBlock());
_blockRestore.add(pair.getLeft().getBlock(), pair.getRight().getLeft().getId(), pair.getRight().getRight(), Long.MAX_VALUE);
}
// Inform the masses
UtilTextMiddle.display(C.cYellow + locationKey, C.cGray + "A Supply Drop is spawning!", 10, 40, 10);
UtilServer.broadcast(F.main(_moduleName, "A Supply Drop is spawning at " + F.elem(locationKey) + " - " + C.cYellow + UtilWorld.locToStrClean(destination)));
_lastSupplyDrop = System.currentTimeMillis();
_current = new SupplyDrop(locationKey, spawn, destination, despawn);
}
public void startSequence()
{
startSequence(getLocationKeys()[UtilMath.r(getLocationKeys().length)]);
}
public void stopSequence()
{
// Remove beacon (only needed incase the command was executed)
for (Block block : _beaconBlocks)
{
_blockRestore.restore(block);
}
_beaconBlocks.clear();
_current.stop();
_current = null;
}
public boolean isActive()
{
return _current != null;
}
public SupplyDrop getActive()
{
return _current;
}
public long getLastSupplyDrop()
{
return _lastSupplyDrop;
}
public long getSequenceTimer()
{
return SEQUENCE_TIMER;
}
public String[] getLocationKeys()
{
if (_locationKeys == null)
{
List<String> supplyDropKeys = new ArrayList<>();
for (String key : _worldData.getAllCustomLocations().keySet())
{
if (key.startsWith(LOCATION_DATA))
{
String[] split = key.split(" ");
String nameKey = "";
for (int i = 1; i < split.length - 1; i++)
{
nameKey += split[i] + " ";
}
nameKey = nameKey.trim();
if (!supplyDropKeys.contains(nameKey))
{
supplyDropKeys.add(nameKey);
}
}
}
_locationKeys = supplyDropKeys.toArray(new String[0]);
}
return _locationKeys;
}
}

Some files were not shown because too many files have changed in this diff Show More