Added the Hero Ivy

This commit is contained in:
Sam 2017-08-14 16:57:44 +01:00
parent 456f959a8d
commit 9300af8370
7 changed files with 608 additions and 7 deletions

View File

@ -6,7 +6,6 @@ import java.util.HashMap;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.Material;
import mineplex.core.common.block.schematic.Schematic;
import mineplex.core.common.block.schematic.SchematicData;
@ -15,7 +14,6 @@ import mineplex.core.common.util.C;
import mineplex.core.gadget.GadgetManager;
import mineplex.core.gadget.gadgets.gamemodifiers.GameCosmeticCategory;
import mineplex.core.gadget.types.GameModifierGadget;
import mineplex.core.itemstack.ItemStackFactory;
public class EmblemGadget extends GameModifierGadget
{
@ -57,7 +55,6 @@ public class EmblemGadget extends GameModifierGadget
}
}
private final EmblemType _type;
private final Schematic _schematic;
public EmblemGadget(GadgetManager manager, GameCosmeticCategory category, EmblemType type)
@ -70,11 +67,9 @@ public class EmblemGadget extends GameModifierGadget
super(manager, category, type.getName(), new String[] {
C.cGray + "Changed your displayed Emblem",
C.cGray + "to " + type.getName() + ".",
}, cost, Material.GLASS, (byte) 0);
}, cost, type.getMaterial(), type.getMaterialData());
_type = type;
_schematic = SCHEMATICS.get(type.getSchematic());
setDisplayItem(ItemStackFactory.Instance.CreateStack(type.getMaterial(), type.getMaterialData()));
}
public SchematicData buildAt(Location location, boolean inverse)

View File

@ -61,6 +61,7 @@ import nautilus.game.arcade.game.games.moba.kit.dana.HeroDana;
import nautilus.game.arcade.game.games.moba.kit.devon.HeroDevon;
import nautilus.game.arcade.game.games.moba.kit.hattori.HeroHattori;
import nautilus.game.arcade.game.games.moba.kit.hp.HPManager;
import nautilus.game.arcade.game.games.moba.kit.ivy.HeroIvy;
import nautilus.game.arcade.game.games.moba.kit.larissa.HeroLarissa;
import nautilus.game.arcade.game.games.moba.kit.rowena.HeroRowena;
import nautilus.game.arcade.game.games.moba.minion.MinionManager;
@ -125,6 +126,7 @@ public class Moba extends TeamGame
new HeroLarissa(Manager),
new HeroBardolf(Manager),
new HeroRowena(Manager),
new HeroIvy(Manager),
new HeroBob(Manager)
};

View File

@ -0,0 +1,25 @@
package nautilus.game.arcade.game.games.moba.kit.ivy;
import mineplex.core.common.skin.SkinData;
import nautilus.game.arcade.ArcadeManager;
import nautilus.game.arcade.game.games.moba.MobaRole;
import nautilus.game.arcade.game.games.moba.kit.HeroKit;
import nautilus.game.arcade.game.games.moba.kit.common.SkillSword;
import nautilus.game.arcade.kit.Perk;
public class HeroIvy extends HeroKit
{
private static final Perk[] PERKS = {
new SkillSword(0),
new SkillHook(1),
new SkillFloralLeap(2),
new SkillBoxingRing(3)
};
public HeroIvy(ArcadeManager manager)
{
super(manager, "Ivy", PERKS, MobaRole.WARRIOR, SkinData.SANTA, 20);
}
}

View File

@ -0,0 +1,173 @@
package nautilus.game.arcade.game.games.moba.kit.ivy;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.bukkit.ChatColor;
import org.bukkit.Effect;
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.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.common.util.F;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilPlayer;
import mineplex.core.common.util.UtilTime;
import mineplex.core.recharge.Recharge;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import nautilus.game.arcade.game.games.moba.Moba;
import nautilus.game.arcade.game.games.moba.buff.BuffManager;
import nautilus.game.arcade.game.games.moba.buff.buffs.BuffRooting;
import nautilus.game.arcade.game.games.moba.kit.HeroSkill;
public class SkillBoxingRing extends HeroSkill
{
private static final String[] DESCRIPTION = {
"Creates a wall of thorns that damages",
"and roots any players that are contained",
"inside."
};
private static final ItemStack SKILL_ITEM = new ItemStack(Material.NETHER_STAR);
private static final long DURATION = TimeUnit.SECONDS.toMillis(5);
private static final int BLOCK_RADIUS = 3;
private static final PotionEffect BUFF = new PotionEffect(PotionEffectType.REGENERATION, 60, 1, false, false);
private static final long DEBUFF_DURATION = TimeUnit.SECONDS.toMillis(2);
private static final int DAMAGE = 2;
private final Set<BoxingRingData> _data = new HashSet<>();
public SkillBoxingRing(int slot)
{
super("Thorn Wall", DESCRIPTION, SKILL_ITEM, slot, ActionType.ANY);
setCooldown(45000);
setDropItemActivate(true);
}
@EventHandler
public void interact(PlayerInteractEvent event)
{
if (!isSkillItem(event))
{
return;
}
Player player = event.getPlayer();
if (!UtilEnt.isGrounded(player))
{
player.sendMessage(F.main("Game", "You cannot use " + F.skill(GetName()) + " while airborne."));
return;
}
Location location = player.getLocation().subtract(0, 1, 0);
byte colour = (byte) (Manager.GetGame().GetTeam(player).GetColor() == ChatColor.RED ? 14 : 11);
// // Double Plants work by the bottom block having a data value, in this case 4, the top part of the plant has
// // a data value of 8, this tells the client to render the top of the part of the block located below itself.
// byte bottomFlower = 4;
// byte topFlower = 8;
location.getWorld().playEffect(location, Effect.STEP_SOUND, Material.STAINED_CLAY, colour);
for (Block block : getSquareBlocks(location, BLOCK_RADIUS, false))
{
Manager.GetBlockRestore().add(block, Material.STAINED_CLAY.getId(), colour, DURATION + UtilMath.rRange(-500, 500));
}
// for (Block block : getSquareBlocks(location, BLOCK_RADIUS, true))
// {
// Manager.GetBlockRestore().add(block, Material.GRASS.getId(), (byte) 0, DURATION + 500 + UtilMath.r(250));
// }
location.add(0, 1, 0);
for (Block block : getSquareBlocks(location, BLOCK_RADIUS, true))
{
Manager.GetBlockRestore().add(block, Material.RED_ROSE.getId(), (byte) 0, DURATION + UtilMath.r(500));
block.getWorld().playEffect(block.getLocation().add(0.5, 0.5, 0.5), Effect.STEP_SOUND, Material.RED_ROSE);
// long duration = DURATION + UtilMath.r(250);
// Manager.GetBlockRestore().add(block, Material.DOUBLE_PLANT.getId(), bottomFlower, duration);
// Manager.GetBlockRestore().add(block, Material.DOUBLE_PLANT.getId(), topFlower, duration);
}
_data.add(new BoxingRingData(player));
useSkill(player);
}
private List<Block> getSquareBlocks(Location center, int radius, boolean border)
{
return UtilBlock.getInBoundingBox(center.clone().subtract(radius, 0, radius), center.clone().add(radius, 0, radius), false, false, border, false);
}
@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.FASTER)
{
return;
}
_data.removeIf(data ->
{
Player player = data.Owner;
Location location = data.Center;
if (!player.isOnline() || UtilTime.elapsed(data.Start, DURATION))
{
return true;
}
Moba host = (Moba) Manager.GetGame();
BuffManager buffManager = host.getBuffManager();
for (Player nearby : UtilPlayer.getNearby(location, BLOCK_RADIUS))
{
if (isTeamDamage(player, nearby))
{
nearby.addPotionEffect(BUFF);
}
else if (Recharge.Instance.use(nearby, GetName() + " Rooting", 2000, false, false))
{
buffManager.apply(new BuffRooting(host, nearby, DEBUFF_DURATION));
}
else if (Recharge.Instance.use(nearby, GetName() + " Damage", 900, false, false))
{
Manager.GetDamage().NewDamageEvent(nearby, player, null, DamageCause.CUSTOM, DAMAGE, false, true, false, player.getName(), GetName());
}
}
return false;
});
}
private class BoxingRingData
{
Player Owner;
Location Center;
long Start;
BoxingRingData(Player owner)
{
Owner = owner;
Center = owner.getLocation();
Start = System.currentTimeMillis();
}
}
}

View File

@ -0,0 +1,247 @@
package nautilus.game.arcade.game.games.moba.kit.ivy;
import java.awt.*;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import mineplex.core.common.Pair;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilBlock;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilParticle.ViewDist;
import mineplex.core.common.util.UtilTime;
import mineplex.core.common.util.particles.ColoredParticle;
import mineplex.core.common.util.particles.DustSpellColor;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import nautilus.game.arcade.game.games.moba.kit.HeroSkill;
public class SkillFloralLeap extends HeroSkill
{
private static final String[] DESCRIPTION = {
"Leap up into the air.",
"Landing creates a bed of flowers",
"that damage and slow enemy players."
};
private static final ItemStack SKILL_ITEM = new ItemStack(Material.FEATHER);
private static final DustSpellColor[] COLOURS = {
new DustSpellColor(Color.RED),
new DustSpellColor(Color.GREEN),
new DustSpellColor(Color.MAGENTA)
};
private static final long DURATION = TimeUnit.SECONDS.toMillis(5);
private static final int BLOCK_RADIUS = 5;
private static final PotionEffect DEBUFF = new PotionEffect(PotionEffectType.SLOW, 50, 2, false, false);
private static final int DAMAGE = 2;
private final Set<FlowerBedData> _data = new HashSet<>();
public SkillFloralLeap(int slot)
{
super("Floral Leap", DESCRIPTION, SKILL_ITEM, slot, ActionType.ANY);
setCooldown(11000);
setSneakActivate(true);
}
@EventHandler
public void interact(PlayerInteractEvent event)
{
if (!isSkillItem(event))
{
return;
}
Player player = event.getPlayer();
useSkill(player);
}
@EventHandler
public void toggleSneak(PlayerToggleSneakEvent event)
{
if (!isSkillSneak(event))
{
return;
}
Player player = event.getPlayer();
useSkill(player);
}
@Override
public void useSkill(Player player)
{
super.useSkill(player);
Vector direction = player.getLocation().getDirection();
direction.setY(1.2);
UtilAction.velocity(player, direction);
_data.add(new FlowerBedData(player));
UtilParticle.PlayParticleToAll(ParticleType.CLOUD, player.getLocation().add(0, 1, 0), 0.5F, 0.5F, 0.5F, 0.1F, 20, ViewDist.LONG);
player.getWorld().playSound(player.getLocation(), Sound.DIG_GRASS, 1, 1);
}
@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
_data.removeIf(data ->
{
Player player = data.Owner;
if (player == null || !player.isOnline())
{
return true;
}
// Has landed
if (data.Active)
{
if (UtilTime.elapsed(data.Start, DURATION))
{
return true;
}
else if (!UtilTime.elapsed(data.LastDamage, 1000))
{
return false;
}
data.LastDamage = System.currentTimeMillis();
for (LivingEntity nearby : UtilEnt.getInRadius(data.Center, BLOCK_RADIUS).keySet())
{
if (isTeamDamage(player, nearby))
{
continue;
}
nearby.addPotionEffect(DEBUFF);
Manager.GetDamage().NewDamageEvent(nearby, player, null, DamageCause.CUSTOM, DAMAGE, false, true, false, player.getName(), GetName());
}
}
// Has just landed
else if (UtilTime.elapsed(data.Leap, 500) && UtilEnt.isGrounded(player))
{
Location location = player.getLocation();
data.Active = true;
data.Center = location;
data.Start = System.currentTimeMillis();
for (Block block : UtilBlock.getInRadius(location, BLOCK_RADIUS).keySet())
{
if (block.getType() != Material.AIR || UtilBlock.airFoliage(block.getRelative(BlockFace.DOWN)))
{
continue;
}
Pair<Material, Byte> flower = getRandomFlower();
Manager.GetBlockRestore().add(block, flower.getLeft().getId(), flower.getRight(), DURATION + (UtilMath.rRange(-500, 500)));
if (Math.random() > 0.7)
{
block.getWorld().playEffect(block.getLocation().add(0.5, 0.5, 0.5), Effect.STEP_SOUND, flower.getLeft());
}
}
}
// Hasn't landed
else
{
Location location = player.getLocation();
for (int i = 0; i < 2; i++)
{
for (DustSpellColor colour : COLOURS)
{
new ColoredParticle(ParticleType.RED_DUST, colour, UtilAlg.getRandomLocation(location, 0.3, 0, 0.3))
.display(ViewDist.LONG);
}
}
}
return false;
});
}
@EventHandler
public void blockPhysics(BlockPhysicsEvent event)
{
if (event.getChangedType() == Material.LONG_GRASS || event.getChangedType() == Material.RED_ROSE)
{
event.setCancelled(true);
}
}
@EventHandler
public void playerDeath(PlayerDeathEvent event)
{
_data.removeIf(data -> data.Owner.equals(event.getEntity()));
}
private Pair<Material, Byte> getRandomFlower()
{
double random = Math.random();
if (random > 0.6)
{
return Pair.create(Material.LONG_GRASS, (byte) 1);
}
else
{
return Pair.create(Material.RED_ROSE, (byte) (UtilMath.r(8) + 1));
}
}
private class FlowerBedData
{
Player Owner;
long Leap;
boolean Active;
Location Center;
long Start;
long LastDamage;
FlowerBedData(Player owner)
{
Owner = owner;
Leap = System.currentTimeMillis();
}
}
}

View File

@ -0,0 +1,159 @@
package nautilus.game.arcade.game.games.moba.kit.ivy;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import mineplex.core.common.util.UtilAction;
import mineplex.core.common.util.UtilAlg;
import mineplex.core.common.util.UtilEnt;
import mineplex.core.common.util.UtilEvent.ActionType;
import mineplex.core.common.util.UtilMath;
import mineplex.core.common.util.UtilParticle.ParticleType;
import mineplex.core.common.util.UtilServer;
import mineplex.core.common.util.particles.effects.LineParticle;
import mineplex.core.updater.UpdateType;
import mineplex.core.updater.event.UpdateEvent;
import nautilus.game.arcade.game.games.moba.kit.HeroSkill;
public class SkillHook extends HeroSkill
{
private static final String[] DESCRIPTION = {
"Fire out a particle beam. Hooking players",
"and pulling them towards you."
};
private static final ItemStack SKILL_ITEM = new ItemStack(Material.VINE);
private static final int RANGE = 7;
private static final int DAMAGE_PLAYER = 4;
private static final int DAMAGE_MINION = 6;
private static final PotionEffect DEBUFF = new PotionEffect(PotionEffectType.SLOW, 60, 2, false, false);
private final Set<HookData> _data = new HashSet<>();
public SkillHook(int slot)
{
super("Vine Pull", DESCRIPTION, SKILL_ITEM, slot, ActionType.ANY);
setCooldown(10000);
}
@EventHandler
public void interact(PlayerInteractEvent event)
{
if (!isSkillItem(event))
{
return;
}
Player player = event.getPlayer();
LineParticle lineParticle = new LineParticle(player.getEyeLocation(), player.getLocation().getDirection(), 0.25, RANGE, ParticleType.HAPPY_VILLAGER, UtilServer.getPlayers());
_data.add(new HookData(player, lineParticle));
useSkill(player);
}
@EventHandler
public void update(UpdateEvent event)
{
if (event.getType() != UpdateType.TICK)
{
return;
}
_data.removeIf(data ->
{
Player player = data.Owner;
LineParticle leash = data.Leash;
if (player == null || !player.isOnline())
{
return true;
}
for (int i = 0; i < 4; i++)
{
if (leash.update())
{
return true;
}
if (data.Target == null)
{
for (LivingEntity nearby : UtilEnt.getInRadius(leash.getLastLocation().subtract(0, 1.2, 0), 1).keySet())
{
if (isTeamDamage(player, nearby))
{
continue;
}
if (nearby instanceof Player)
{
data.Target = (Player) nearby;
UtilAction.zeroVelocity(nearby);
Manager.GetDamage().NewDamageEvent(nearby, player, null, DamageCause.CUSTOM, DAMAGE_PLAYER, false, false, false, player.getName(), GetName());
}
else
{
Manager.GetDamage().NewDamageEvent(nearby, player, null, DamageCause.CUSTOM, DAMAGE_MINION, true, false, false, player.getName(), GetName());
}
}
}
else
{
Player target = data.Target;
if (!target.isOnline())
{
return true;
}
if (UtilMath.offset2dSquared(target.getLocation(), player.getLocation()) < 4)
{
UtilAction.zeroVelocity(target);
target.addPotionEffect(DEBUFF);
return true;
}
UtilAction.velocity(target, UtilAlg.getTrajectory(target, player).setY(data.First ? 0 : 0.3));
data.First = true;
}
}
return false;
});
}
@EventHandler
public void playerDeath(PlayerDeathEvent event)
{
_data.removeIf(data -> data.Owner.equals(event.getEntity()) || data.Target.equals(event.getEntity()));
}
private class HookData
{
Player Owner;
LineParticle Leash;
Player Target;
boolean First;
HookData(Player owner, LineParticle leash)
{
Owner = owner;
Leash = leash;
}
}
}

View File

@ -65,7 +65,7 @@ public class MobaMap implements Listener
Location location = schematicSpawns.get(index++);
Vector direction = UtilAlg.getTrajectory(location, _host.GetSpectatorLocation());
gadget.buildAt(location, direction.getZ() > 0);
gadget.buildAt(location, direction.getZ() < 0);
}
}
}