From 2e19aabfa17acf57e88f66662e64f91ee66a14d1 Mon Sep 17 00:00:00 2001 From: Ty Sayers Date: Mon, 1 Jun 2015 12:25:20 -0400 Subject: [PATCH] Convert damage system to custom Mineplex damage events to enable legendary abilities. Fix NPE and hanging issue on ServerData's serialization adapter. Finalize item generation logic for instantiating CustomItem's based on specified random distribution of types, attribute counts, etc. Fix several Legendary bugs discovered during testing. Clean left-over template documentation and further clarify ambiguous methods. Add proper updating logic for custom items to track internal stats in hidden json lore. Add safe-logout system to prevent combat logging and enable players to safely log after a designated amount of time. Tweak WindBlade's flight speed to a more natural value. --- .../gameplay/safelog/LoggingManager.java | 251 ++++++++++++++++++ .../clans/gameplay/safelog/LogoutData.java | 46 ++++ .../clans/gameplay/safelog/QuitCommand.java | 62 +++++ .../mineplex/game/clans/items/CustomItem.java | 28 +- .../game/clans/items/GearManager.java | 224 +++++++++++++--- .../game/clans/items/ItemListener.java | 17 +- .../mineplex/game/clans/items/ItemType.java | 18 ++ .../mineplex/game/clans/items/PlayerGear.java | 31 ++- .../clans/items/attributes/ItemAttribute.java | 5 +- .../items/attributes/armor/LavaAttribute.java | 3 +- .../attributes/armor/PaddedAttribute.java | 3 +- .../attributes/armor/ProtectionAttribute.java | 1 - .../attributes/armor/ReductionAttribute.java | 13 +- .../attributes/armor/ReinforcedAttribute.java | 1 - .../attributes/armor/SlantedAttribute.java | 1 - .../weapon/ConqueringAttribute.java | 5 +- .../attributes/weapon/DamageAttribute.java | 7 +- .../attributes/weapon/FlamingAttribute.java | 5 +- .../attributes/weapon/FrostedAttribute.java | 11 +- .../attributes/weapon/HasteAttribute.java | 9 +- .../attributes/weapon/JaggedAttribute.java | 5 +- .../attributes/weapon/SharpAttribute.java | 5 +- .../attributes/weapon/VampiricAttribute.java | 26 +- .../clans/items/commands/GearCommand.java | 30 +-- .../clans/items/generation/WeightSet.java | 41 ++- .../items/legendaries/AlligatorsTooth.java | 9 +- .../items/legendaries/GiantsBroadsword.java | 12 +- .../clans/items/legendaries/HyperBlade.java | 19 +- .../items/legendaries/LegendaryItem.java | 22 +- .../items/legendaries/MagneticBlade.java | 36 ++- .../clans/items/legendaries/MeteorBow.java | 2 + .../clans/items/legendaries/WindBlade.java | 2 +- .../game/core/damage/CustomDamageEvent.java | 4 + .../RuntimeTypeAdapterFactory.java | 42 +-- 34 files changed, 819 insertions(+), 177 deletions(-) create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/LoggingManager.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/LogoutData.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/QuitCommand.java create mode 100644 Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemType.java diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/LoggingManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/LoggingManager.java new file mode 100644 index 000000000..52ba6fc3c --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/LoggingManager.java @@ -0,0 +1,251 @@ +package mineplex.game.clans.gameplay.safelog; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import mineplex.core.MiniPlugin; +import mineplex.minecraft.game.core.combat.event.CombatDeathEvent; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import mineplex.minecraft.game.core.damage.DamageManager; +import mineplex.core.itemstack.ItemStackFactory; +import mineplex.core.recharge.Recharge; +import mineplex.core.updater.event.UpdateEvent; +import mineplex.core.updater.UpdateType; +import mineplex.core.blockrestore.BlockRestore; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilEvent; +import mineplex.core.common.util.UtilGear; +import mineplex.core.common.util.UtilInv; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilEvent.ActionType; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.items.commands.GearCommand; + +import org.bukkit.ChatColor; +import org.bukkit.Color; +import org.bukkit.Effect; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.block.Biome; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockIgniteEvent.IgniteCause; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent.DamageCause; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerBucketFillEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.LeatherArmorMeta; +import org.bukkit.plugin.java.JavaPlugin; + +public class LoggingManager extends MiniPlugin +{ + public static final double SAFE_LOG_RANGE = 32d; + public static final int LOGOUT_DURATION = 10000; // Duration of safe-log (in milliseconds) + public static final long REJOIN_TIME = 60000; + + //Track Offline Players + private HashMap _logouts = new HashMap(); + + public LoggingManager(JavaPlugin plugin) + { + super("Logout Manager", plugin); + + _logouts = new HashMap(); + } + + private Set getNearbyHostilePlayers(Location location, double radius) + { + Set nearbyPlayers = new HashSet(); + + for (Player player : location.getWorld().getPlayers()) + { + double radiusSquared = radius * radius; + + if (player.getLocation().distanceSquared(location) <= radiusSquared) // TODO: Check to see if they're in a clan? + { + nearbyPlayers.add(player); + } + } + + return nearbyPlayers; + } + + public void onPlayerQuit(Player player) + { + LogoutData logoutData = _logouts.remove(player); + + boolean isSafeLog = logoutData != null && logoutData.hasSafeLogout() && !player.isDead(); + + if (!isSafeLog && getNearbyHostilePlayers(player.getLocation(), 32d).size() == 1) // No other players within 32 blocks + { + isSafeLog = true; + } + + // TODO: Check to see if player was attacked or attacked another player within last 15 seconds and set isSafeLog=false... + if (!isSafeLog) + { + onCombatLog(player); + } + } + + public void onPlayerJoin(Player player) + { + // TODO: Check to see if the player has a combat-log bot in place + // and if so, remove/un-use it as they have logged back in. + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) + { + onPlayerQuit(event.getPlayer()); + } + + @EventHandler + public void onPlayerKicked(PlayerKickEvent event) + { + onPlayerQuit(event.getPlayer()); + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) + { + onPlayerJoin(event.getPlayer()); + } + + @EventHandler + public void onUpdate(UpdateEvent event) + { + if (event.getType() == UpdateType.TICK) + tick(); + } + + @Override + public void addCommands() + { + addCommand(new QuitCommand(this)); + } + + private LogoutData getLogoutData(Player player) + { + return _logouts.get(player.getName()); + } + + public LogoutData insertLogoutData(Player player, long duration) + { + LogoutData data = new LogoutData(player, duration); + _logouts.put(player.getName(), data); + + return data; + } + + public LogoutData insertLogoutData(Player player) + { + return insertLogoutData(player, LOGOUT_DURATION); + } + + public boolean hasLogoutData(Player player) + { + return getLogoutData(player) != null; + } + + /** + * Tick the internal logic of this manager and update it's state. + * Intended to be ticked/updated every in-game tick. + */ + private void tick() + { + for (String playerName : _logouts.keySet()) + { + LogoutData data = _logouts.get(playerName); + + if (data.isOnline()) + { + double distance = data.getDistanceTravelled(); + + if (distance >= SAFE_LOG_RANGE) + { + cancelSafeLog(data.getPlayer()); + } + else if (data.hasSafeLogout()) + { + // TODO: Log out player safely. + } + } + else + { + _logouts.remove(playerName); + } + } + } + + private void cancelSafeLog(Player player) + { + _logouts.remove(player.getName()); + // TODO: Notify player that safe-log was cancelled + } + + public void onCombatLog(Player player) + { + UtilInv.drop(player, true); // Drop player's inventory belongigs to ground + } + + @EventHandler(ignoreCancelled = true) + public void onPlayerInteract(PlayerInteractEvent event) + { + Player player = event.getPlayer(); + + if (hasLogoutData(player)) + { + cancelSafeLog(player); + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onEntityDamaged(EntityDamageByEntityEvent event) + { + Entity victim = event.getEntity(); + + if (victim instanceof Player) + { + Player player = (Player) victim; + + if (hasLogoutData(player)) + { + cancelSafeLog(player); + } + } + } + + @EventHandler(ignoreCancelled = true) + public void onItemPickup(PlayerPickupItemEvent event) + { + if (hasLogoutData(event.getPlayer())) + { + event.setCancelled(true); // Prevent players that are safe-logging from picking up items. + } + } + +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/LogoutData.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/LogoutData.java new file mode 100644 index 000000000..5f311f35a --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/LogoutData.java @@ -0,0 +1,46 @@ +package mineplex.game.clans.gameplay.safelog; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +public class LogoutData +{ + + private String _playerName; + public Player getPlayer() { return Bukkit.getPlayer(_playerName); } + + private long _endTime; + public boolean hasSafeLogout() { return System.currentTimeMillis() >= _endTime; } + + private long _startTime; + + private Location _location; + public Location getLocation() { return _location; } + + public LogoutData(Player player, long duration) + { + _startTime = System.currentTimeMillis(); + _endTime = _startTime + duration; + _location = player.getLocation(); + _playerName = player.getName(); + } + + public boolean isOnline() + { + Player player = getPlayer(); + return player != null && player.isOnline(); + } + + public double getDistanceTravelled() + { + if (isOnline()) + { + Player player = getPlayer(); + + return player.getLocation().distance(_location); + } + + return -1d; + } +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/QuitCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/QuitCommand.java new file mode 100644 index 000000000..6b0d144c6 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/gameplay/safelog/QuitCommand.java @@ -0,0 +1,62 @@ +package mineplex.game.clans.gameplay.safelog; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.Chunk; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import mineplex.core.command.CommandBase; +import mineplex.core.common.Rank; +import mineplex.core.common.util.C; +import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilInput; +import mineplex.core.common.util.UtilMath; +import mineplex.core.common.util.UtilPlayer; +import mineplex.core.common.util.UtilServer; +import mineplex.core.common.util.UtilTime; +import mineplex.core.common.util.UtilTime.TimeUnit; +import mineplex.core.common.util.UtilWorld; +import mineplex.core.recharge.Recharge; +import mineplex.game.clans.clans.ClanInfo; +import mineplex.game.clans.clans.ClanRole; +import mineplex.game.clans.clans.ClansManager; +import mineplex.game.clans.clans.ClansUtility.ClanRelation; +import mineplex.game.clans.clans.ClientClan; +import mineplex.game.clans.items.CustomItem; +import mineplex.game.clans.items.GearManager; +import mineplex.game.clans.items.attributes.weapon.FlamingAttribute; +import mineplex.game.clans.items.attributes.weapon.FrostedAttribute; +import mineplex.game.clans.items.attributes.weapon.SharpAttribute; +import mineplex.game.clans.items.legendaries.LegendaryItem; +import mineplex.game.clans.items.legendaries.WindBlade; + +public class QuitCommand extends CommandBase +{ + + private LoggingManager _loggingManager; + + public QuitCommand(LoggingManager plugin) + { + super(plugin, Rank.ALL, "quit", "log", "logout"); + + _loggingManager = plugin; + } + + @Override + public void Execute(Player caller, String[] args) + { + if (_loggingManager.hasLogoutData(caller)) + { + UtilPlayer.message(caller, F.main("SafeLog", "You are already safe-logging!")); + } + else + { + _loggingManager.insertLogoutData(caller); + UtilPlayer.message(caller, F.main("SafeLog", "Successfully initiated safe-log!")); + } + } +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/CustomItem.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/CustomItem.java index f8bc27309..7933da3ea 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/CustomItem.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/CustomItem.java @@ -7,6 +7,7 @@ import java.util.Set; import java.util.UUID; import mineplex.game.clans.items.attributes.ItemAttribute; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; import org.bukkit.Material; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -32,7 +33,7 @@ public class CustomItem private ItemAttribute _suffix; public void setSuffix(ItemAttribute attribute) { _suffix = attribute; } - private String _displayName; + protected String _displayName; private String _description; private Material _material; @@ -117,6 +118,11 @@ public class CustomItem return item; } + public ItemStack toItemStack() + { + return toItemStack(1); + } + public void onInteract(PlayerInteractEvent event) { System.out.println("Triggered interact!"); @@ -126,7 +132,7 @@ public class CustomItem } } - public void onAttack(EntityDamageByEntityEvent event) + public void onAttack(CustomDamageEvent event) { System.out.println("Triggered attack!"); for (ItemAttribute attribute : getAttributes()) @@ -135,7 +141,7 @@ public class CustomItem } } - public void onAttacked(EntityDamageByEntityEvent event) + public void onAttacked(CustomDamageEvent event) { System.out.println("Triggered damage!"); for (ItemAttribute attribute : getAttributes()) @@ -182,4 +188,20 @@ public class CustomItem item.setItemMeta(meta); } + + public void addAttribute(ItemAttribute attribute) + { + if (_superPrefix == null) + { + _superPrefix = attribute; + } + else if (_prefix == null) + { + _prefix = attribute; + } + else if (_suffix == null) + { + _suffix = attribute; + } + } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/GearManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/GearManager.java index 30ce2a183..b3979bee9 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/GearManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/GearManager.java @@ -1,8 +1,12 @@ package mineplex.game.clans.items; +import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Random; +import java.util.Set; import mineplex.core.MiniPlugin; import mineplex.core.account.CoreClientManager; @@ -14,14 +18,12 @@ import mineplex.core.portal.TransferHandler; import mineplex.core.portal.Commands.SendCommand; import mineplex.core.portal.Commands.ServerCommand; import mineplex.game.clans.items.attributes.ItemAttribute; -import mineplex.game.clans.items.attributes.weapon.FlamingAttribute; -import mineplex.game.clans.items.attributes.weapon.FrostedAttribute; -import mineplex.game.clans.items.attributes.weapon.SharpAttribute; +import mineplex.game.clans.items.attributes.weapon.*; +import mineplex.game.clans.items.attributes.armor.*; import mineplex.game.clans.items.commands.GearCommand; import mineplex.game.clans.items.generation.Weight; import mineplex.game.clans.items.generation.WeightSet; -import mineplex.game.clans.items.legendaries.AlligatorsTooth; -import mineplex.game.clans.items.legendaries.WindBlade; +import mineplex.game.clans.items.legendaries.*; import mineplex.game.clans.items.smelting.SmeltingListener; import mineplex.serverdata.Region; import mineplex.serverdata.Utility; @@ -31,8 +33,11 @@ import mineplex.serverdata.serialization.RuntimeTypeAdapterFactory; import mineplex.serverdata.servers.ServerManager; import net.minecraft.server.v1_7_R4.Packet; import net.minecraft.server.v1_7_R4.PacketPlayOutSetSlot; +import net.minecraft.util.com.google.common.collect.Sets; import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -47,17 +52,31 @@ import com.google.gson.GsonBuilder; * @author MrTwiggy * */ -public class GearManager extends MiniPlugin implements IPacketHandler +public class GearManager extends MiniPlugin implements IPacketHandler, Runnable { private static final String ITEM_SERIALIZATION_TAG = "-JSON-"; + private static Random random = new Random(); + private static Gson _gson; private static GearManager _instance; // Singleton instance - private Map playerGears; // Mapping of player names (key) to cached gear set (value). + private Map _playerGears; // Mapping of player names (key) to cached gear set (value). private WeightSet _attributeWeights; // Weightings for randomly selecting number of attributes (1, 2, 3) - private WeightSet _itemWeights; // Weightings for randomly selecting item type (legendary/rare) - private WeightSet _gearWeights; // Weightings for randomly selecting gear type (armour/weapon) - private static Gson _gson; + private WeightSet _typeWeights; // Weightings for randomly selecting item type (legendary/weapon/armour/bow) + + // Legendary generation + private WeightSet> _legendaryWeights; + + // Weapon generation + private WeightSet _weaponTypes; + + // Armour generation + private WeightSet _armourTypes; + + // Attribute generation + private WeightSet> _weaponAttributes; + private WeightSet> _armourAttributes; + private WeightSet> _bowAttributes; public GearManager(JavaPlugin plugin, PacketHandler packetHandler) { @@ -65,37 +84,77 @@ public class GearManager extends MiniPlugin implements IPacketHandler _instance = this; - playerGears = new HashMap(); + _playerGears = new HashMap(); // TODO: Introduce configurable non-hardcoded values for generation weights? - _attributeWeights = new WeightSet(new Weight(3, 3), new Weight(20, 2), new Weight(77, 1)); - _itemWeights = new WeightSet(new Weight(90, true), new Weight(10, false)); - _itemWeights = new WeightSet(new Weight(50, true), new Weight(50, false)); + _attributeWeights = new WeightSet(new Weight(3, 3), new Weight(20, 2), new Weight(77, 1), new Weight(80, 0)); + _typeWeights = new WeightSet(new Weight(1000, ItemType.LEGENDARY), + new Weight(45, ItemType.ARMOUR), + new Weight(22, ItemType.WEAPON), + new Weight(22, ItemType.BOW)); - System.out.println("-Testting-testing"); - System.out.println(Utility.currentTimeSeconds()); + // Weapon-based attributes + _weaponAttributes = new WeightSet>(FrostedAttribute.class, SharpAttribute.class, + JaggedAttribute.class, HasteAttribute.class, FlamingAttribute.class, ConqueringAttribute.class); + + // Armour-based attributes + _armourAttributes = new WeightSet>(SlantedAttribute.class, ReinforcedAttribute.class, + ProtectionAttribute.class, PaddedAttribute.class, LavaAttribute.class); + + // Bow-based attributes + //_bowAttributes = new WeightSet>(); // TODO: Add in bow-attributes + + // Weapon material types + _weaponTypes = new WeightSet(Material.DIAMOND_SWORD, Material.GOLD_SWORD, Material.IRON_SWORD, Material.STONE_SWORD, + Material.DIAMOND_AXE, Material.GOLD_AXE, Material.IRON_AXE, Material.STONE_AXE); + + // Armour material types + _armourTypes = new WeightSet(Material.DIAMOND_HELMET, Material.DIAMOND_CHESTPLATE, Material.DIAMOND_LEGGINGS, Material.DIAMOND_BOOTS, + Material.IRON_HELMET, Material.IRON_CHESTPLATE, Material.IRON_LEGGINGS, Material.IRON_BOOTS, + Material.GOLD_HELMET, Material.GOLD_CHESTPLATE, Material.GOLD_LEGGINGS, Material.GOLD_BOOTS); + + // TODO: Initialize list of attributes and types + + // Initialize various LegendaryItem types + _legendaryWeights = new WeightSet>(AlligatorsTooth.class, WindBlade.class, + GiantsBroadsword.class, HyperBlade.class, MagneticBlade.class); + // TODO: Add rest of legendaries, find better way? // Register listeners UtilServer.getServer().getPluginManager().registerEvents(new ItemListener(), getPlugin()); UtilServer.getServer().getPluginManager().registerEvents(new SmeltingListener(), getPlugin()); - // adding all different container classes with their flag - RuntimeTypeAdapterFactory typeFactory = RuntimeTypeAdapterFactory - .of(ItemAttribute.class, "AttributeType") - .registerSubtype(SharpAttribute.class) - .registerSubtype(FrostedAttribute.class) - .registerSubtype(FlamingAttribute.class); // TODO: Register all item attributes automatically + // Initialize attribute types factory for JSON handling of polymorphism. + RuntimeTypeAdapterFactory attributeFactory = RuntimeTypeAdapterFactory + .of(ItemAttribute.class); + for (Class attributeType : _armourAttributes.elements()) + { + attributeFactory.registerSubtype(attributeType); + } + for (Class attributeType : _weaponAttributes.elements()) + { + attributeFactory.registerSubtype(attributeType); + } + + // Initialize legendary item type factory for JSON handling of polymorphism. RuntimeTypeAdapterFactory customItemType = RuntimeTypeAdapterFactory - .of(CustomItem.class, "ItemType") - .registerSubtype(AlligatorsTooth.class) - .registerSubtype(WindBlade.class); // TODO: Register all legendary weapons automatically + .of(CustomItem.class); + customItemType.registerSubtype(CustomItem.class); + customItemType.registerSubtype(LegendaryItem.class); + for (Class itemType : _legendaryWeights.elements()) + { + customItemType.registerSubtype(itemType); + } - GsonBuilder builder = new GsonBuilder(); - builder.registerTypeAdapterFactory(typeFactory); - builder.registerTypeAdapterFactory(customItemType); - _gson = builder.create(); + // Build GSON instance off factories for future serialization of items. + _gson = new GsonBuilder() + .registerTypeAdapterFactory(attributeFactory) + .registerTypeAdapterFactory(customItemType) + .create(); packetHandler.addPacketHandler(this); + + plugin.getServer().getScheduler().runTaskTimer(plugin, this, 1l, 1l); } @Override @@ -104,6 +163,18 @@ public class GearManager extends MiniPlugin implements IPacketHandler addCommand(new GearCommand(this)); } + /** + * Tick & update internal logic for {@link GearManager}. Called once per tick. + */ + @Override + public void run() + { + for (PlayerGear gear : _playerGears.values()) + { + gear.update(); + } + } + /** * @param player - the player whose {@link PlayerGear} set is to be fetched. * @return the cached or newly instantiated {@link PlayerGear} associated with {@code player}. @@ -111,24 +182,81 @@ public class GearManager extends MiniPlugin implements IPacketHandler public PlayerGear getPlayerGear(Player player) { String playerName = player.getName(); - if (!playerGears.containsKey(playerName)) + if (!_playerGears.containsKey(playerName)) { PlayerGear gear = new PlayerGear(playerName); - playerGears.put(playerName, gear); + _playerGears.put(playerName, gear); } - return playerGears.get(playerName); + return _playerGears.get(playerName); } public CustomItem generateItem() { int attributeCount = _attributeWeights.generateRandom(); - boolean isLegendary = _itemWeights.generateRandom(); - boolean isArmour = _gearWeights.generateRandom(); + ItemType itemType = _typeWeights.generateRandom(); - // TODO: Generate custom item randomly using generated values above + System.out.println("Generating item of type " + itemType.toString() + " with attribute count of " + attributeCount); + CustomItem item = generateItem(itemType); + System.out.println("Generated item!"); + + if (itemType != ItemType.LEGENDARY) // Only non-legendaries have attributes + { + for (ItemAttribute attribute : generateAttributes(itemType, attributeCount)) + { + item.addAttribute(attribute); + } + // Add up to attributeCount attributes + } + + return item; + } + + private CustomItem generateItem(ItemType itemType) + { + switch(itemType) + { + case LEGENDARY: // Legendary weapon + Class legendaryClass = _legendaryWeights.generateRandom(); + System.out.println("Legendary: " + legendaryClass.getName()); + return instantiate(legendaryClass); + case WEAPON: // Sword or axe + return new CustomItem(_weaponTypes.generateRandom()); + case ARMOUR: // Helmet, chestplate, leggings, or boots + return new CustomItem(_armourTypes.generateRandom()); + case BOW: // A bow + return new CustomItem(Material.BOW); + default: + return null;// Never reached, yet required for compilation purposes. + } + } + + private Set generateAttributes(ItemType type, int count) + { + Set attributes = new HashSet(); - return null; + for (int i = 0; i < count; i++) + { + switch (type) + { + case ARMOUR: + attributes.add(instantiate(_armourAttributes.generateRandom())); + break; + case WEAPON: + attributes.add(instantiate(_weaponAttributes.generateRandom())); + break; + default: + break; + } + } + + return attributes; + } + + public void spawnItem(Location location) + { + CustomItem item = generateItem(); + location.getWorld().dropItem(location, item.toItemStack()); } public static CustomItem parseItem(ItemStack item) @@ -158,7 +286,7 @@ public class GearManager extends MiniPlugin implements IPacketHandler { if (i % 40 == 39) { - serialization += "\n"; + serialization += "\n"; // TODO: Remove this temporary fix to hiding player lore } serialization += tempSeri.charAt(i); @@ -167,6 +295,22 @@ public class GearManager extends MiniPlugin implements IPacketHandler return serialization; } + /** + * @param type - the class-type of the object to be instantiated. (must have zero-argument constructor) + * @return a newly instantiated instance of {@code type} class-type. Instantied with zero argument constructor. + */ + private static T instantiate(Class type) + { + try + { + return type.newInstance(); + } + catch (Exception e) + { + return null; + } + } + private static String getItemSerialization(ItemStack item) { if (item == null || item.getItemMeta() == null @@ -214,12 +358,11 @@ public class GearManager extends MiniPlugin implements IPacketHandler public static String serialize(CustomItem customItem) { - return _gson.toJson(customItem); + return _gson.toJson(customItem, CustomItem.class); } public static CustomItem deserialize(String serialization) { - System.out.println("Serialization: " + serialization); return _gson.fromJson(serialization, CustomItem.class); } @@ -241,7 +384,8 @@ public class GearManager extends MiniPlugin implements IPacketHandler System.out.println("Item slot packet!"); PacketPlayOutSetSlot slotPacket = (PacketPlayOutSetSlot) packet; - + // TODO: Modify spigot build so that slotPacket's itemstack lore can be modified + // to 'hide' json-encoded lore from players. } } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemListener.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemListener.java index 521974557..d54b217d1 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemListener.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemListener.java @@ -1,5 +1,7 @@ package mineplex.game.clans.items; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -50,21 +52,22 @@ public class ItemListener implements Listener * @param event */ @EventHandler - public void onPlayerAttack(EntityDamageByEntityEvent event) + public void onPlayerAttack(CustomDamageEvent event) { + Player damager = event.GetDamagerPlayer(true); + Player damagee = event.GetDamageePlayer(); + // Trigger custom gear effects for attacker - if (event.getDamager() instanceof Player) + if (damager != null) { - Player attacker = (Player) event.getDamager(); - PlayerGear attackerGear = getGear(attacker); + PlayerGear attackerGear = getGear(damager); attackerGear.onAttack(event); } // Trigger custom gear effects for defender - if (event.getEntity() instanceof Player) + if (damagee != null) { - Player defender = (Player) event.getEntity(); - PlayerGear defenderGear = getGear(defender); + PlayerGear defenderGear = getGear(damagee); defenderGear.onAttacked(event); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemType.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemType.java new file mode 100644 index 000000000..ed32a8115 --- /dev/null +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/ItemType.java @@ -0,0 +1,18 @@ +package mineplex.game.clans.items; + +import com.google.common.collect.Sets; + +import mineplex.game.clans.items.generation.WeightSet; +import mineplex.game.clans.items.legendaries.AlligatorsTooth; +import mineplex.game.clans.items.legendaries.WindBlade; + +public enum ItemType +{ + LEGENDARY, + + ARMOUR, + + WEAPON, + + BOW; +} diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/PlayerGear.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/PlayerGear.java index 1ae4319ba..25191f7b6 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/PlayerGear.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/PlayerGear.java @@ -3,6 +3,9 @@ package mineplex.game.clans.items; import java.util.HashSet; import java.util.Set; +import mineplex.game.clans.items.legendaries.LegendaryItem; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -36,6 +39,30 @@ public class PlayerGear { _playerName = playerName; } + + /** + * Tick & update internal logic for the PlayerGear and required custom items that are + * equipped. + */ + public void update() + { + if (isOnline()) + { + CustomItem item = getWeapon(); + + if (item != null && item instanceof LegendaryItem) + { + LegendaryItem legendary = (LegendaryItem) item; + legendary.update(getPlayer()); + } + } + } + + public boolean isOnline() + { + Player player = getPlayer(); + return player != null && player.isOnline(); + } /** * @return the {@link Player} that owns this gear set. @@ -69,7 +96,7 @@ public class PlayerGear * Trigger on-attack events for the set of equipped {@link CustomItem}s in gear set. * @param event - the triggering on-attack event */ - public void onAttack(EntityDamageByEntityEvent event) + public void onAttack(CustomDamageEvent event) { for (CustomItem item : getGear()) { @@ -81,7 +108,7 @@ public class PlayerGear * Trigger attacked events for the set of equipped {@link CustomItem}s in gear set. * @param event - the triggering attacked event */ - public void onAttacked(EntityDamageByEntityEvent event) + public void onAttacked(CustomDamageEvent event) { for (CustomItem item : getGear()) { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/ItemAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/ItemAttribute.java index bf9443f7a..540918364 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/ItemAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/ItemAttribute.java @@ -1,6 +1,7 @@ package mineplex.game.clans.items.attributes; import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.player.PlayerInteractEvent; @@ -30,12 +31,12 @@ public abstract class ItemAttribute // Implementation left to subclasses. } - public void onAttack(EntityDamageByEntityEvent event) + public void onAttack(CustomDamageEvent event) { // Implementation left to subclasses. } - public void onAttacked(EntityDamageByEntityEvent event) + public void onAttacked(CustomDamageEvent event) { // Implementation left to subclasses. } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/LavaAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/LavaAttribute.java index 4e8f8dc1a..12e76c9a0 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/LavaAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/LavaAttribute.java @@ -6,8 +6,7 @@ import mineplex.game.clans.items.attributes.ItemAttribute; import mineplex.game.clans.items.generation.ValueDistribution; public class LavaAttribute extends PercentReductionAttribute -{ - // TODO: Replace with your generators +{ private static ValueDistribution reductionGen = generateDistribution(0.2d, 1.0d); // Value generator for heal amount private static ReductionConfig lavaConfig = new ReductionConfig(DamageCause.FIRE, DamageCause.LAVA, DamageCause.FIRE_TICK); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/PaddedAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/PaddedAttribute.java index 5c255a918..f3a4458a9 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/PaddedAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/PaddedAttribute.java @@ -6,8 +6,7 @@ import mineplex.game.clans.items.attributes.ItemAttribute; import mineplex.game.clans.items.generation.ValueDistribution; public class PaddedAttribute extends FlatReductionAttribute -{ - // TODO: Replace with your generators +{ private static ValueDistribution reductionGen = generateDistribution(1.0d, 4.0d); private static ReductionConfig config = new ReductionConfig(DamageCause.FALL); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ProtectionAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ProtectionAttribute.java index 8903beb8a..ec97366ec 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ProtectionAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ProtectionAttribute.java @@ -9,7 +9,6 @@ import mineplex.game.clans.items.generation.ValueDistribution; // A.K.A Conquering for Armor public class ProtectionAttribute extends FlatReductionAttribute { - // TODO: Replace with your generators private static ValueDistribution reductionGen = generateDistribution(1.0d, 4.0d); private static ReductionConfig config = new ReductionConfig(EntityType.values()); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReductionAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReductionAttribute.java index 897adb14b..e9227cadb 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReductionAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReductionAttribute.java @@ -10,6 +10,7 @@ import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import mineplex.game.clans.items.attributes.ItemAttribute; import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; public abstract class ReductionAttribute extends ItemAttribute { @@ -22,18 +23,16 @@ public abstract class ReductionAttribute extends ItemAttribute } @Override - public void onAttacked(EntityDamageByEntityEvent event) + public void onAttacked(CustomDamageEvent event) { - DamageCause cause = event.getCause(); - Entity attacker = event.getDamager(); + DamageCause cause = event.GetCause(); + Entity attacker = event.GetDamagerEntity(true); if (_config.reducesDamage(cause, attacker)) { - double damage = event.getDamage(); + double damage = event.GetDamage(); double reduction = getDamageReduction(damage); - double reducedDamage = Math.max(0, damage - reduction); - - event.setDamage(reducedDamage); + event.AddMod("Reduction Armor", reduction); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReinforcedAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReinforcedAttribute.java index 09cc76b99..36f385e73 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReinforcedAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/ReinforcedAttribute.java @@ -6,7 +6,6 @@ import mineplex.game.clans.items.generation.ValueDistribution; public class ReinforcedAttribute extends FlatReductionAttribute { - // TODO: Replace with your generators private static ValueDistribution reductionGen = generateDistribution(0.5d, 1.0d); private static ReductionConfig config = new ReductionConfig(DamageCause.ENTITY_ATTACK); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/SlantedAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/SlantedAttribute.java index 0618e473d..b1bcfffe7 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/SlantedAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/armor/SlantedAttribute.java @@ -7,7 +7,6 @@ import mineplex.game.clans.items.generation.ValueDistribution; public class SlantedAttribute extends FlatReductionAttribute { - // TODO: Replace with your generators private static ValueDistribution reductionGen = generateDistribution(0.5d, 1.5d); private static ReductionConfig config = new ReductionConfig(DamageCause.PROJECTILE); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/ConqueringAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/ConqueringAttribute.java index c3b57c04b..1ab6a9c2b 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/ConqueringAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/ConqueringAttribute.java @@ -7,8 +7,7 @@ import org.bukkit.entity.Player; public class ConqueringAttribute extends DamageAttribute { - // TODO: Replace with your generators - private static ValueDistribution damageGen = generateDistribution(1.0d, 6.0d); // Value generator for heal amount + private static ValueDistribution damageGen = generateDistribution(1.0d, 6.0d); public ConqueringAttribute() { @@ -18,7 +17,7 @@ public class ConqueringAttribute extends DamageAttribute @Override public String getDisplayName() { - return "Conquering"; // TODO: Fill in name + return "Conquering"; } @Override diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/DamageAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/DamageAttribute.java index 301008ca0..3848efeff 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/DamageAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/DamageAttribute.java @@ -2,6 +2,7 @@ package mineplex.game.clans.items.attributes.weapon; import mineplex.game.clans.items.attributes.ItemAttribute; import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; import org.bukkit.entity.Entity; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -17,11 +18,11 @@ public abstract class DamageAttribute extends ItemAttribute } @Override - public void onAttack(EntityDamageByEntityEvent event) + public void onAttack(CustomDamageEvent event) { - if (grantBonusDamage(event.getEntity())) + if (grantBonusDamage(event.GetDamageeEntity())) { - event.setDamage(event.getDamage() + _bonusDamage); + event.AddMod("Damage Attribute", _bonusDamage); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FlamingAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FlamingAttribute.java index c3b0f088d..61e48715d 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FlamingAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FlamingAttribute.java @@ -6,9 +6,8 @@ import org.bukkit.entity.Entity; public class FlamingAttribute extends AttackAttribute { - // TODO: Replace with your generators - private static ValueDistribution attackGen = generateDistribution(2, 4); // Value generator for heal amount - private static ValueDistribution fireGen = generateDistribution(60, 120); // Value generator for heal amount + private static ValueDistribution attackGen = generateDistribution(2, 4); + private static ValueDistribution fireGen = generateDistribution(60, 120); private int _fireDuration; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FrostedAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FrostedAttribute.java index aa4484b4f..6109b9cee 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FrostedAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/FrostedAttribute.java @@ -2,6 +2,7 @@ package mineplex.game.clans.items.attributes.weapon; import mineplex.game.clans.items.attributes.ItemAttribute; import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -44,13 +45,13 @@ public class FrostedAttribute extends ItemAttribute } @Override - public void onAttacked(EntityDamageByEntityEvent event) + public void onAttacked(CustomDamageEvent event) { - if (event.getDamager() instanceof Player) + Player damager = event.GetDamagerPlayer(true); + + if (damager != null) { - Player player = (Player) event.getDamager(); - - player.addPotionEffect(generateSlowEffect()); // Slow attacking player + damager.addPotionEffect(generateSlowEffect()); // Slow attacking player } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/HasteAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/HasteAttribute.java index c694957cc..0c2cd3adf 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/HasteAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/HasteAttribute.java @@ -10,10 +10,9 @@ import org.bukkit.util.Vector; public class HasteAttribute extends AttackAttribute { - // TODO: Replace with your generators - private static ValueDistribution attackGen = generateDistribution(2, 4); // Value generator for heal amount - private static ValueDistribution speedGen = generateDistribution(0, 2); // Value generator for heal amount - private static ValueDistribution durationGen = generateDistribution(60, 120); // Value generator for heal amount + private static ValueDistribution attackGen = generateDistribution(2, 4); + private static ValueDistribution speedGen = generateDistribution(0, 2); + private static ValueDistribution durationGen = generateDistribution(60, 120); private int _speedAmount; private int _speedDuration; @@ -29,7 +28,7 @@ public class HasteAttribute extends AttackAttribute @Override public String getDisplayName() { - return "Haste"; // TODO: Fill in name + return "Haste"; } @Override diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/JaggedAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/JaggedAttribute.java index 0b9fcbc74..3794c8b0a 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/JaggedAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/JaggedAttribute.java @@ -7,8 +7,7 @@ import org.bukkit.util.Vector; public class JaggedAttribute extends AttackAttribute { - // TODO: Replace with your generators - private static ValueDistribution attackGen = generateDistribution(2, 4); // Value generator for heal amount + private static ValueDistribution attackGen = generateDistribution(2, 4); public JaggedAttribute() { @@ -18,7 +17,7 @@ public class JaggedAttribute extends AttackAttribute @Override public String getDisplayName() { - return "Jagged"; // TODO: Fill in name + return "Jagged"; } @Override diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SharpAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SharpAttribute.java index 9413b79a6..48c2c285b 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SharpAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/SharpAttribute.java @@ -6,8 +6,7 @@ import org.bukkit.entity.Entity; public class SharpAttribute extends DamageAttribute { - // TODO: Replace with your generators - private static ValueDistribution damageGen = generateDistribution(0.5d, 1.5d); // Value generator for heal amount\ + private static ValueDistribution damageGen = generateDistribution(0.5d, 1.5d); public SharpAttribute() { @@ -17,7 +16,7 @@ public class SharpAttribute extends DamageAttribute @Override public String getDisplayName() { - return "Sharp"; // TODO: Fill in name + return "Sharp"; } @Override diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/VampiricAttribute.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/VampiricAttribute.java index 0bca99aaf..2cfe356fe 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/VampiricAttribute.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/attributes/weapon/VampiricAttribute.java @@ -2,14 +2,14 @@ package mineplex.game.clans.items.attributes.weapon; import mineplex.game.clans.items.attributes.ItemAttribute; import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageByEntityEvent; public class VampiricAttribute extends ItemAttribute { - // TODO: Replace with your generators - private static ValueDistribution healGen = generateDistribution(4, 12); // Value generator for heal amount + private static ValueDistribution healGen = generateDistribution(4, 12); private int _healPercent; @@ -21,7 +21,7 @@ public class VampiricAttribute extends ItemAttribute @Override public String getDisplayName() { - return "Vampiric"; // TODO: Fill in name + return "Vampiric"; } @Override @@ -31,17 +31,17 @@ public class VampiricAttribute extends ItemAttribute } @Override - public void onAttack(EntityDamageByEntityEvent event) + public void onAttack(CustomDamageEvent event) { - if (event.getDamager() instanceof Player) - { - Player attacker = (Player) event.getDamager(); - - double damage = event.getDamage(); - double healAmount = damage * (_healPercent / 100d); - double currentHealth = attacker.getHealth(); - attacker.setHealth(currentHealth + healAmount); - } + Player damager = event.GetDamagerPlayer(true); + + double damage = event.GetDamage(); + double healAmount = damage * (_healPercent / 100d); + heal(damager, healAmount); } + private void heal(Player player, double healAmount) + { + player.setHealth(player.getHealth() + healAmount); + } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/commands/GearCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/commands/GearCommand.java index 3c22d4b79..7729093e2 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/commands/GearCommand.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/commands/GearCommand.java @@ -8,6 +8,7 @@ import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.util.Vector; import mineplex.core.command.CommandBase; import mineplex.core.common.Rank; @@ -36,9 +37,13 @@ import mineplex.game.clans.items.legendaries.WindBlade; public class GearCommand extends CommandBase { + + private GearManager _gearManager; + public GearCommand(GearManager plugin) { super(plugin, Rank.ALL, "gear", "custom-gear"); + _gearManager = plugin; } @Override @@ -46,31 +51,16 @@ public class GearCommand extends CommandBase { UtilPlayer.message(caller, F.main("Gear", "Opening custom gear GUI!")); - if (caller.getItemInHand() != null && caller.getItemInHand().getType() != Material.AIR) + if (args == null || args.length == 0) { - ItemStack item = caller.getItemInHand(); - ItemMeta meta = item.getItemMeta(); - List lore = meta.getLore(); - lore.set(0, "Test"); - meta.setLore(lore); - item.setItemMeta(meta); - System.out.println("aaaaaaa"); - return; + Vector direction = caller.getLocation().getDirection().normalize(); + _gearManager.spawnItem(caller.getEyeLocation().add(direction)); } else { - LegendaryItem legendary = new WindBlade(); - caller.setItemInHand(legendary.toItemStack(1)); - return; + Vector direction = caller.getLocation().getDirection().normalize(); + _gearManager.spawnItem(caller.getEyeLocation().add(direction)); } - - /*CustomItem customItem = new CustomItem(); - customItem.setPrefix(new FrostedAttribute()); - customItem.setSuperPrefix(new SharpAttribute()); - customItem.setSuffix(new FlamingAttribute()); - ItemStack sword = customItem.toItemStack(1); - caller.setItemInHand(sword);*/ - // TODO: Open custom gear GUI here } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/generation/WeightSet.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/generation/WeightSet.java index 80c402c84..68ee5f5ab 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/generation/WeightSet.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/generation/WeightSet.java @@ -1,5 +1,6 @@ package mineplex.game.clans.items.generation; +import java.util.Collection; import java.util.HashSet; import java.util.Random; import java.util.Set; @@ -11,10 +12,15 @@ public class WeightSet private Set> _weights; + private WeightSet() + { + _weights = new HashSet>(); + } + @SafeVarargs public WeightSet(Weight... weights) { - _weights = new HashSet>(); + this(); for (Weight weight : weights) { @@ -22,6 +28,27 @@ public class WeightSet } } + @SafeVarargs + public WeightSet(T... elements) + { + this(); + + for (T element : elements) + { + _weights.add(new Weight(1, element)); // Constant weight of 1 means all elements are equally likely + } + } + + public WeightSet(Collection elements) + { + this(); + + for (T element : elements) + { + _weights.add(new Weight(1, element)); // Constant weight of 1 means all elements are equally likely + } + } + private int getTotalWeight() { int total = 0; @@ -52,4 +79,16 @@ public class WeightSet // Should never reach here. return null; } + + public Set elements() + { + Set elements = new HashSet(); + + for (Weight weight : _weights) + { + elements.add(weight.getValue()); + } + + return elements; + } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/AlligatorsTooth.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/AlligatorsTooth.java index 3ce29f6a6..e43868f99 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/AlligatorsTooth.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/AlligatorsTooth.java @@ -2,6 +2,7 @@ package mineplex.game.clans.items.legendaries; import mineplex.game.clans.items.attributes.ItemAttribute; import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -35,12 +36,12 @@ public class AlligatorsTooth extends LegendaryItem } @Override - public void onAttack(EntityDamageByEntityEvent event, Player wielder) + public void onAttack(CustomDamageEvent event, Player wielder) { if (isInWater(wielder)) { - double newDamage = event.getDamage() + _damageBonus; - event.setDamage(newDamage); + event.AddMod("Alligators Tooth", _damageBonus); + event.AddKnockback("Alligators Tooth", 0.5d); } super.onAttack(event); @@ -55,6 +56,6 @@ public class AlligatorsTooth extends LegendaryItem private boolean isInWater(Player player) { - return true; // TODO: Determine whether player is submerged in water + return player.getLocation().getBlock().isLiquid(); } } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/GiantsBroadsword.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/GiantsBroadsword.java index 9df21fdee..2835846cb 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/GiantsBroadsword.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/GiantsBroadsword.java @@ -3,6 +3,8 @@ package mineplex.game.clans.items.legendaries; import java.util.HashSet; import java.util.Set; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -27,15 +29,11 @@ public class GiantsBroadsword extends LegendaryItem } @Override - public void onAttack(EntityDamageByEntityEvent event, Player wielder) + public void onAttack(CustomDamageEvent event, Player wielder) { - // TODO: Buff knockback and damage values (What are specific values?) - // Chiss: Make 'em up - double bonusDamage = 2.0d; // Too much? - event.setDamage(event.getDamage() + bonusDamage); - - // TODO: Apply knockback bonus using previous Clans Custom combat events + event.AddMod("Giants Bonus", bonusDamage); + event.AddKnockback("Giants Sword", 0.5d); } private void buffPlayer(Player player) diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/HyperBlade.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/HyperBlade.java index b7584c0ef..92e103bb3 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/HyperBlade.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/HyperBlade.java @@ -1,7 +1,9 @@ package mineplex.game.clans.items.legendaries; import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.potion.PotionEffect; @@ -9,16 +11,22 @@ import org.bukkit.potion.PotionEffectType; public class HyperBlade extends LegendaryItem { + public static final long ATTACK_RATE_DURATION = 100; private static ValueDistribution amountGen = generateDistribution(0, 3); // [1, 4] speed amount private static ValueDistribution durationGen = generateDistribution(80, 320); // [4, 16] seconds speed duration private int _speedAmount; private int _speedDuration; + private long _lastAttack; + public long timeSinceLastAttack() { return System.currentTimeMillis() - _lastAttack; } + public HyperBlade() { + super("Hyper Blade", "Increased attack speed!", Material.STICK); _speedAmount = amountGen.generateIntValue(); _speedDuration = durationGen.generateIntValue(); + _lastAttack = 0; } @Override @@ -31,15 +39,20 @@ public class HyperBlade extends LegendaryItem } @Override - public void onAttack(EntityDamageByEntityEvent event, Player wielder) + public void onAttack(CustomDamageEvent event, Player wielder) { - // TODO: Reduce after-attack cooldown against players to 100ms (instead of 400ms) + if (timeSinceLastAttack() >= ATTACK_RATE_DURATION) + { + event.SetIgnoreRate(true); + log("Ignoring rate!"); + } } private void buffPlayer(Player wielder) { // Give player speed buff - wielder.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, _speedAmount, _speedDuration)); + wielder.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, _speedDuration, _speedAmount)); + log("Buffing"); } private boolean canBuff() diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/LegendaryItem.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/LegendaryItem.java index 60db32a47..3257e5811 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/LegendaryItem.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/LegendaryItem.java @@ -8,6 +8,7 @@ import org.bukkit.event.player.PlayerInteractEvent; import mineplex.game.clans.items.CustomItem; import mineplex.game.clans.items.generation.ValueDistribution; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; public class LegendaryItem extends CustomItem { @@ -17,12 +18,6 @@ public class LegendaryItem extends CustomItem private long _lastBlock; // Timestamp of last block from wielder public long timeSinceLastBlock() { return System.currentTimeMillis() - _lastBlock; } - - public LegendaryItem() - { - this(null, null, null); // TODO: Never used, just to skip base implementation for testing. - } - public LegendaryItem(String name, String description, Material material) { super(name, description, material); @@ -35,19 +30,17 @@ public class LegendaryItem extends CustomItem // Leave implementation to potential subtypes } - public void onAttack(EntityDamageByEntityEvent event, Player wielder) + public void onAttack(CustomDamageEvent event, Player wielder) { // Leave implementation to potential subtypes } @Override - public void onAttack(EntityDamageByEntityEvent event) + public void onAttack(CustomDamageEvent event) { - if (event.getDamager() instanceof Player) + if (event.GetDamagerPlayer(true) != null) { - Player wielder = (Player) event.getDamager(); - - onAttack(event, wielder); + onAttack(event, event.GetDamagerPlayer(true)); } super.onAttack(event); @@ -70,6 +63,11 @@ public class LegendaryItem extends CustomItem return timeSinceLastBlock() <= BLOCK_COOLDOWN; } + protected void log(String message) + { + System.out.println("[Custom Item - " + _displayName + "] " + message); + } + /** * @param minValue - the minimum value for attribute value range * @param maxValue - the maximum value for attribute value range diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MagneticBlade.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MagneticBlade.java index 5f7fca155..7934f5de2 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MagneticBlade.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MagneticBlade.java @@ -1,14 +1,24 @@ package mineplex.game.clans.items.legendaries; +import mineplex.core.common.util.UtilAction; +import mineplex.core.common.util.UtilAlg; +import mineplex.core.common.util.UtilMath; +import mineplex.minecraft.game.core.damage.CustomDamageEvent; + +import org.bukkit.Location; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.util.Vector; public class MagneticBlade extends LegendaryItem { + public static final double PULL_RANGE = 10d; + public MagneticBlade() { - + super("Magnetic Blade", "Pull enemies closer with special abilities!", Material.STICK); } @Override @@ -21,14 +31,32 @@ public class MagneticBlade extends LegendaryItem } @Override - public void onAttack(EntityDamageByEntityEvent event, Player wielder) + public void onAttack(CustomDamageEvent event, Player wielder) { + event.AddKnockback("Magnetic Blade", -0.5d); // Pull players with negative knockback + log("Negative knockback!"); // TODO: Apply negative knockback with [???] velocity/power to victims of attacks } private void pullPlayers(Player player) - { - // TODO: Grab all players in line of sight and pull towards player with ??? velocity + { + log("Pulling players!"); + Vector direction = player.getLocation().getDirection().normalize().multiply(10.0d); + Location target = player.getEyeLocation().add(direction); + + double targetDistance = player.getLocation().distance(target); + + for (Player other : player.getWorld().getPlayers()) + { + double otherDistance = player.getLocation().distance(other.getLocation()); + double otherTargetDistance = target.distance(other.getLocation()); + + // If player is in-front of us and within pulling range + if (otherTargetDistance < targetDistance && otherDistance <= PULL_RANGE) + { + UtilAction.velocity(other, UtilAlg.getTrajectory(other, player), 0.3, false, 0, 0, 1, true); + } + } } private boolean canPull() diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MeteorBow.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MeteorBow.java index 67c00cfe3..6bc437489 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MeteorBow.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/MeteorBow.java @@ -3,6 +3,7 @@ package mineplex.game.clans.items.legendaries; import mineplex.game.clans.items.attributes.ItemAttribute; import mineplex.game.clans.items.generation.ValueDistribution; +import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -15,6 +16,7 @@ public class MeteorBow extends LegendaryItem public MeteorBow() { + super("Meteor Bow", "Shoot explosive arrows!", Material.BOW); _flightTime = 0; } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/WindBlade.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/WindBlade.java index c8d38f700..47fd1bee3 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/WindBlade.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/items/legendaries/WindBlade.java @@ -12,7 +12,7 @@ import org.bukkit.util.Vector; public class WindBlade extends LegendaryItem { - public static final double FLIGHT_VELOCITY = 0.25d; + public static final double FLIGHT_VELOCITY = 0.75d; public static final int MAX_FLIGHT_TIME = 80; // Max flight of 80 ticks private long _flightTime; // Time (in ticks) since last touching ground and flying diff --git a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/damage/CustomDamageEvent.java b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/damage/CustomDamageEvent.java index e7b460fe3..9b008c6b1 100644 --- a/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/damage/CustomDamageEvent.java +++ b/Plugins/Mineplex.Minecraft.Game.Core/src/mineplex/minecraft/game/core/damage/CustomDamageEvent.java @@ -91,6 +91,10 @@ public class CustomDamageEvent extends Event implements Cancellable _damageMult.add(new DamageChange(source, reason, mod, useAttackName)); } + public void AddMod(String source, double mod) + { + AddMod(source, new String(), mod, false); + } public void AddMod(String source, String reason, double mod, boolean useAttackName) { diff --git a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/serialization/RuntimeTypeAdapterFactory.java b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/serialization/RuntimeTypeAdapterFactory.java index 33dc2239e..afb7f04a7 100644 --- a/Plugins/Mineplex.ServerData/src/mineplex/serverdata/serialization/RuntimeTypeAdapterFactory.java +++ b/Plugins/Mineplex.ServerData/src/mineplex/serverdata/serialization/RuntimeTypeAdapterFactory.java @@ -215,25 +215,29 @@ public final class RuntimeTypeAdapterFactory implements TypeAdapterFactory { } @Override public void write(JsonWriter out, R value) throws IOException { - Class srcType = value.getClass(); - String label = subtypeToLabel.get(srcType); - @SuppressWarnings("unchecked") // registration requires that subtype extends T - TypeAdapter delegate = (TypeAdapter) subtypeToDelegate.get(srcType); - if (delegate == null) { - throw new JsonParseException("cannot serialize " + srcType.getName() - + "; did you forget to register a subtype?"); - } - JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject(); - if (jsonObject.has(typeFieldName)) { - throw new JsonParseException("cannot serialize " + srcType.getName() - + " because it already defines a field named " + typeFieldName); - } - JsonObject clone = new JsonObject(); - clone.add(typeFieldName, new JsonPrimitive(label)); - for (Map.Entry e : jsonObject.entrySet()) { - clone.add(e.getKey(), e.getValue()); - } - Streams.write(clone, out); + if(value!=null) { + Class srcType = value.getClass(); + String label = subtypeToLabel.get(srcType); + @SuppressWarnings("unchecked") // registration requires that subtype extends T + TypeAdapter delegate = (TypeAdapter) subtypeToDelegate.get(srcType); + if (delegate == null) { + throw new JsonParseException("cannot serialize " + srcType.getName() + + "; did you forget to register a subtype?"); + } + JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject(); + if (jsonObject.has(typeFieldName)) { + throw new JsonParseException("cannot serialize " + srcType.getName() + + " because it already defines a field named " + typeFieldName); + } + JsonObject clone = new JsonObject(); + clone.add(typeFieldName, new JsonPrimitive(label)); + for (Map.Entry e : jsonObject.entrySet()) { + clone.add(e.getKey(), e.getValue()); + } + Streams.write(clone, out); + }else{ + out.nullValue(); + } } }; }