Merge branch 'feature/gem-hunters' into develop
This commit is contained in:
commit
699845d6d7
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
{
|
||||
|
@ -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>();
|
||||
}
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
@ -242,6 +242,11 @@ public class CosmeticManager extends MiniPlugin
|
||||
{
|
||||
return _boosterManager;
|
||||
}
|
||||
|
||||
public void displayUI(Player player)
|
||||
{
|
||||
_shop.attemptShopOpen(player);
|
||||
}
|
||||
|
||||
public void disableTeamArmor()
|
||||
{
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package mineplex.core.google;
|
||||
|
||||
public interface SheetObjectDeserialiser<T>
|
||||
{
|
||||
|
||||
public T deserialise(String[] values) throws ArrayIndexOutOfBoundsException;
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
5
Plugins/mineplex-game-gemhunters/plugin.yml
Normal file
5
Plugins/mineplex-game-gemhunters/plugin.yml
Normal file
@ -0,0 +1,5 @@
|
||||
name: GemHunters
|
||||
main: mineplex.gemhunters.GemHunters
|
||||
version: 0.1
|
||||
commands:
|
||||
playwire:
|
27
Plugins/mineplex-game-gemhunters/pom.xml
Normal file
27
Plugins/mineplex-game-gemhunters/pom.xml
Normal 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>
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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."));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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."));
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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()
|
||||
{
|
||||
}
|
||||
}
|
@ -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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package mineplex.gemhunters.mount.event;
|
||||
|
||||
public class MountSpawnEvent
|
||||
{
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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());/
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user