diff --git a/src/de/leafbla/meinkraft/roleplay/PlayerRole.java b/src/de/leafbla/meinkraft/roleplay/PlayerRole.java index 1517376..de6928b 100644 --- a/src/de/leafbla/meinkraft/roleplay/PlayerRole.java +++ b/src/de/leafbla/meinkraft/roleplay/PlayerRole.java @@ -1,12 +1,21 @@ package de.leafbla.meinkraft.roleplay; import de.leafbla.meinkraft.Main; +import de.leafbla.meinkraft.roleplay.wizard.ProjectileBlockHit; +import de.leafbla.meinkraft.roleplay.wizard.ProjectileEntityHit; +import de.leafbla.meinkraft.util.Pair; +import org.bukkit.Material; import org.bukkit.entity.Player; +import org.bukkit.entity.Snowball; + +import java.util.HashMap; +import java.util.Map; public abstract class PlayerRole { + protected final Map> projectiles = new HashMap<>(); protected final Player player; - protected final Main plugin; + public final Main plugin; private final Role role; public Player getPlayer() { @@ -27,5 +36,9 @@ public abstract class PlayerRole { public abstract void end(); - + public Snowball launchProjectile(Material material, ProjectileEntityHit entityHit, ProjectileBlockHit blockHit) { + Snowball snowball = Utils.launchProjectile(player, material); + this.projectiles.put(snowball.getEntityId(), new Pair<>(entityHit, blockHit)); + return snowball; + } } diff --git a/src/de/leafbla/meinkraft/roleplay/Utils.java b/src/de/leafbla/meinkraft/roleplay/Utils.java index fefd45a..f431e2e 100644 --- a/src/de/leafbla/meinkraft/roleplay/Utils.java +++ b/src/de/leafbla/meinkraft/roleplay/Utils.java @@ -6,6 +6,7 @@ import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack; import org.bukkit.entity.Player; import org.bukkit.entity.Snowball; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; public class Utils { @@ -18,4 +19,13 @@ public class Utils { public static Snowball launchProjectile(Player player, Material material) { return launchProjectile(player, new ItemStack(material)); } + + public static ItemStack namedItem(Material material, String name) { + ItemStack itemStack = new ItemStack(material); + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(name); + itemStack.setItemMeta(itemMeta); + return itemStack; + } + } diff --git a/src/de/leafbla/meinkraft/roleplay/bomber/BomberListener.java b/src/de/leafbla/meinkraft/roleplay/bomber/BomberListener.java index 142c42c..1690a32 100644 --- a/src/de/leafbla/meinkraft/roleplay/bomber/BomberListener.java +++ b/src/de/leafbla/meinkraft/roleplay/bomber/BomberListener.java @@ -31,7 +31,6 @@ public class BomberListener implements Listener { this.plugin = main; } - @EventHandler public void onPlace(BlockPlaceEvent event) { if (event.getBlockPlaced().getType() == Material.STONE_PRESSURE_PLATE) { mines.put(event.getBlockPlaced().getLocation(), event.getPlayer()); @@ -45,7 +44,6 @@ public class BomberListener implements Listener { } } - @EventHandler public void onPlace(PlayerInteractEvent event) { if (event.getAction() == Action.PHYSICAL) if (event.getClickedBlock().getType() == Material.STONE_PRESSURE_PLATE) { @@ -92,7 +90,6 @@ public class BomberListener implements Listener { Map grenades = new HashMap<>(); - @EventHandler public void onLand(ProjectileHitEvent event) { if (event.getEntity() instanceof Snowball) { Snowball ball = (Snowball) event.getEntity(); diff --git a/src/de/leafbla/meinkraft/roleplay/fighter/FighterRole.java b/src/de/leafbla/meinkraft/roleplay/fighter/FighterRole.java index a73f699..ab77377 100644 --- a/src/de/leafbla/meinkraft/roleplay/fighter/FighterRole.java +++ b/src/de/leafbla/meinkraft/roleplay/fighter/FighterRole.java @@ -26,8 +26,6 @@ public class FighterRole extends PlayerRole implements ManaAble { private int mana; private boolean powerfist; - BukkitRunnable refillMana; - public FighterRole(Main plugin, Player player) { super(plugin, player, Role.FIGHTER); } @@ -38,20 +36,12 @@ public class FighterRole extends PlayerRole implements ManaAble { this.player.setWalkSpeed(0.3f); this.powerfist = false; this.player.setGravity(true); - refillMana = new BukkitRunnable() { - @Override - public void run() { - addMana(1); - } - }; - refillMana.runTaskTimer(plugin, 0, 5); } @Override public void end() { player.setExp(0.5f); this.player.setWalkSpeed(0.2f); - refillMana.cancel(); } @Override diff --git a/src/de/leafbla/meinkraft/roleplay/ninja/NinjaListener.java b/src/de/leafbla/meinkraft/roleplay/ninja/NinjaListener.java index b652dec..b731ff3 100644 --- a/src/de/leafbla/meinkraft/roleplay/ninja/NinjaListener.java +++ b/src/de/leafbla/meinkraft/roleplay/ninja/NinjaListener.java @@ -1,126 +1,78 @@ package de.leafbla.meinkraft.roleplay.ninja; import de.leafbla.meinkraft.Main; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.Particle; -import org.bukkit.craftbukkit.v1_16_R2.entity.CraftSnowball; -import org.bukkit.craftbukkit.v1_16_R2.inventory.CraftItemStack; -import org.bukkit.entity.LivingEntity; +import de.leafbla.meinkraft.roleplay.Role; +import de.leafbla.meinkraft.roleplay.RoleListener; import org.bukkit.entity.Player; -import org.bukkit.entity.Snowball; import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.event.entity.*; import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.ShapedRecipe; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.potion.PotionEffect; +import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.potion.PotionEffectType; -import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.projectiles.ProjectileSource; -public class NinjaListener implements Listener { +public class NinjaListener extends RoleListener { private Main plugin; public NinjaListener(Main main) { + super(Role.NINJA, main); this.plugin = main; - addKnife(); - addDarts(); } - private void addDarts() { - ItemStack item = new ItemStack(Material.STICK); - ItemMeta im = item.getItemMeta(); - im.setDisplayName("Blowpipe"); - item.setItemMeta(im); - NamespacedKey key = new NamespacedKey(plugin, "blowpipe"); - ShapedRecipe recipe = new ShapedRecipe(key, item); - recipe.shape("D", "D"); - recipe.setIngredient('D', Material.DIRT); - Bukkit.addRecipe(recipe); + @EventHandler + public void onMove(PlayerMoveEvent event) { + Player player = event.getPlayer(); + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + role.onMove(event); } - private void addKnife() { - ItemStack item = new ItemStack(Material.IRON_INGOT); - ItemMeta im = item.getItemMeta(); - im.setDisplayName("Throwing Knife"); - item.setItemMeta(im); - NamespacedKey key = new NamespacedKey(plugin, "throwing_knife"); - ShapedRecipe recipe = new ShapedRecipe(key, item); - recipe.shape("DD", "DD"); - recipe.setIngredient('D', Material.DIRT); - Bukkit.addRecipe(recipe); - } + @EventHandler public void onInteract(PlayerInteractEvent event) { Player player = event.getPlayer(); - if (event.getAction().name().contains("RIGHT")) { - ItemStack knife = event.getPlayer().getInventory().getItemInMainHand(); - if (knife.getType() == Material.IRON_INGOT) { - ItemStack oneknife = knife.clone(); - oneknife.setAmount(1); - Snowball ball = player.launchProjectile(Snowball.class); - ball.setVelocity(ball.getVelocity().multiply(1.2)); - ball.setBounce(false); - ((CraftSnowball) ball).getHandle().setItem(CraftItemStack.asNMSCopy(oneknife)); - - int amt = knife.getAmount(); - knife.setAmount(amt - 1); - player.setItemInHand(knife); - } else if (knife.getType() == Material.STICK) { - ItemStack oneknife = new ItemStack(Material.FEATHER, 1); - Snowball ball = player.launchProjectile(Snowball.class); - ball.setVelocity(ball.getVelocity().multiply(3)); - ((CraftSnowball) ball).getHandle().setItem(CraftItemStack.asNMSCopy(oneknife)); - - int amt = knife.getAmount(); - flying = true; - new BukkitRunnable() { - int i = 0; - - @Override - public void run() { - if (flying) - ball.getWorld().spawnParticle(Particle.FLAME, ball.getLocation(), 0); - else - this.cancel(); - } - }.runTaskTimerAsynchronously(this.plugin, 0, 1); - //knife.setAmount(amt - 1); - //player.setItemInHand(knife); - } - } + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + role.onInteract(event); } - private boolean flying = false; + @EventHandler + public void onPoison(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player)) return; + Player player = (Player) event.getEntity(); + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + if (event.getCause() == EntityDamageEvent.DamageCause.POISON) + event.setCancelled(true); + } @EventHandler public void onLand(ProjectileHitEvent event) { - if (event.getEntity() instanceof Snowball) { - Snowball ball = (Snowball) event.getEntity(); - ItemStack item = - CraftItemStack.asBukkitCopy( - ((CraftSnowball) ball).getHandle().getItem() - ); - if (item.getType() == Material.IRON_INGOT) { - if (event.getHitEntity() == null) - event.getEntity().getWorld().dropItem(event.getEntity().getLocation(), item); - else { - if (event.getHitEntity() instanceof LivingEntity) - ((LivingEntity) event.getHitEntity()).damage(8); - } - } else if (item.getType() == Material.FEATHER) { - flying = false; - if (event.getHitEntity() != null) { - if (event.getHitEntity() instanceof LivingEntity) { - LivingEntity len = ((LivingEntity) event.getHitEntity()); - Bukkit.broadcastMessage(String.format("hit %s", len.getName())); - len.addPotionEffect(new PotionEffect(PotionEffectType.POISON, 5 * 20, 0, true, true)); - } - } - } - } + ProjectileSource shooter = event.getEntity().getShooter(); + if (!(shooter instanceof Player)) return; + Player player = (Player) shooter; + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + role.projectileHit(event); + } + + @EventHandler + public void onPoisonSoak(LingeringPotionSplashEvent event) { + ProjectileSource shooter = event.getEntity().getShooter(); + if (!(shooter instanceof Player)) return; + Player player = (Player) shooter; + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + role.lingeringPotionSplash(event); + } + + @EventHandler + public void onCloudApply(AreaEffectCloudApplyEvent event) { + ProjectileSource shooter = event.getEntity().getSource(); + if (!(shooter instanceof Player)) return; + Player player = (Player) shooter; + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + role.effectCloudApply(event); } } diff --git a/src/de/leafbla/meinkraft/roleplay/ninja/NinjaRole.java b/src/de/leafbla/meinkraft/roleplay/ninja/NinjaRole.java index ec0db51..67adba5 100644 --- a/src/de/leafbla/meinkraft/roleplay/ninja/NinjaRole.java +++ b/src/de/leafbla/meinkraft/roleplay/ninja/NinjaRole.java @@ -3,26 +3,234 @@ package de.leafbla.meinkraft.roleplay.ninja; import de.leafbla.meinkraft.Main; import de.leafbla.meinkraft.roleplay.PlayerRole; import de.leafbla.meinkraft.roleplay.Role; -import org.bukkit.entity.Player; +import de.leafbla.meinkraft.roleplay.Utils; +import de.leafbla.meinkraft.roleplay.wizard.ProjectileBlockHit; +import de.leafbla.meinkraft.roleplay.wizard.ProjectileEntityHit; +import org.bukkit.*; +import org.bukkit.entity.*; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.AreaEffectCloudApplyEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.LingeringPotionSplashEvent; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerMoveEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.ShapedRecipe; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.potion.PotionData; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.potion.PotionType; +import org.bukkit.projectiles.ProjectileSource; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.RayTraceResult; +import org.bukkit.util.Vector; + +import java.util.Date; +import java.util.Objects; public class NinjaRole extends PlayerRole { + private BukkitRunnable stealth; + private Date lastMove; + private final long STEALTHDELAY = 1000; + private boolean stealthed = false; + public NinjaRole(Main plugin, Player player) { super(plugin, player, Role.NINJA); } @Override public void start() { - + player.getInventory().addItem(Utils.namedItem(Material.STICK, "Blasrohr")); + player.getInventory().addItem(Utils.namedItem(Material.SLIME_BALL, "Lingering Poison Potion")); + player.getInventory().addItem(Utils.namedItem(Material.BONE, "Dash Attack")); + stealth = new BukkitRunnable() { + @Override + public void run() { + Date now = new Date(); + if (stealthed) { + player.removePotionEffect(PotionEffectType.INVISIBILITY); + player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 20 * 20, 0, false, false)); + } else { + if (now.getTime() - lastMove.getTime() > STEALTHDELAY) { + stealthed = true; + player.playSound(player.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1, 1); + player.removePotionEffect(PotionEffectType.INVISIBILITY); + player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, 20 * 20, 0, false, false)); + } + } + } + }; + stealth.runTaskTimer(plugin, 0, 10); + lastMove = new Date(); } @Override public void end() { - + stealth.cancel(); + player.removePotionEffect(PotionEffectType.INVISIBILITY); } - @Override - public Role getRole() { - return Role.NINJA; + public void onInteract(PlayerInteractEvent event) { + Player player = event.getPlayer(); + ItemStack inHand = player.getInventory().getItemInMainHand(); + if (inHand.getType() == Material.STICK) { + this.blasrohr(); + } else if (inHand.getType() == Material.SLIME_BALL) { + this.poisonCloud(); + } else if (inHand.getType() == Material.BONE) { + player.sendMessage("BONE"); + this.dash(); + } + } + + private void blasrohr() { + Snowball ball = this.launchProjectile(Material.ARROW, (event, projectile, target, shooter) -> { + if (!(target instanceof LivingEntity)) return; + LivingEntity livingEntity = (LivingEntity) target; + livingEntity.removePotionEffect(PotionEffectType.POISON); + livingEntity.addPotionEffect(new PotionEffect(PotionEffectType.POISON, 3 * 20, 0, true)); + }, (event, projectile, target, targetFace, shooter) -> { + + }); + ball.setVelocity(ball.getVelocity().multiply(2)); + } + + private void poisonCloud() { + ThrownPotion thownPotion = player.launchProjectile(ThrownPotion.class); + ItemStack lingeringPotion = new ItemStack(Material.LINGERING_POTION); + PotionMeta potionMeta = (PotionMeta) lingeringPotion.getItemMeta(); + potionMeta.setBasePotionData(new PotionData(PotionType.POISON, true, false)); + lingeringPotion.setItemMeta(potionMeta); + thownPotion.setItem(lingeringPotion); + } + + public void onMove(PlayerMoveEvent event) { + if (event.getFrom().getBlock().equals(event.getTo().getBlock())) return; // not really moved, huh? + this.lastMove = new Date(); + if (stealthed) { + player.setWalkSpeed(0.15f); + if (event.getPlayer().isSneaking()) return; + this.stealthed = false; + player.removePotionEffect(PotionEffectType.INVISIBILITY); + player.playSound(player.getLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1, 1); + } else { + player.setWalkSpeed(0.2f); + } + } + + final int DASHLENGTH = 7; + + public void dash() { + RayTraceResult blockTraceResult = player.getWorld().rayTraceBlocks(player.getEyeLocation(), player.getEyeLocation().getDirection(), DASHLENGTH); + RayTraceResult entityTraceResult = player.getWorld().rayTraceEntities(player.getEyeLocation(), player.getEyeLocation().getDirection(), DASHLENGTH, e -> (e instanceof LivingEntity) && (!e.equals(player))); + if (blockTraceResult != null && (blockTraceResult.getHitBlock() != null && entityTraceResult != null)) { + double blockDistance = blockTraceResult.getHitPosition().distance(player.getEyeLocation().toVector()); + double entityDistance = entityTraceResult.getHitPosition().distance(player.getEyeLocation().toVector()); + if (blockDistance < entityDistance) { + player.sendMessage("obstructed"); + return; + } + } + //player.sendMessage(String.format("e: %s, b: %s", entityTraceResult.getHitEntity(), entityTraceResult.getHitBlock())); + if (entityTraceResult == null) return; + Entity hit = entityTraceResult.getHitEntity(); + if (!(hit instanceof LivingEntity)) return; + LivingEntity entity = (LivingEntity) hit; + Location entityLocation = entity.getEyeLocation(); + entityLocation.setPitch(0); + Vector behindEntity = entityLocation.getDirection().normalize().multiply(-1); + Location newLocation = entity.getLocation().add(behindEntity); + Vector facingEntity = newLocation.toVector().subtract(entity.getLocation().toVector()).multiply(-1); + newLocation.setDirection(facingEntity); + player.teleport(newLocation); + player.attack(entity); + } + + public void projectileHit(ProjectileHitEvent event) { + assert Objects.equals(event.getEntity().getShooter(), player); + Projectile projectile = event.getEntity(); + if (this.projectiles.containsKey(projectile.getEntityId())) { + ProjectileBlockHit projectileBlockHit = this.projectiles.get(projectile.getEntityId()).getRight(); + ProjectileEntityHit projectileEntityHit = this.projectiles.get(projectile.getEntityId()).getLeft(); + if (event.getHitEntity() != null) { + projectileEntityHit.onHit(event, projectile, event.getHitEntity(), player); + } else if (event.getHitBlock() != null) { + Entity hitEntity = event.getHitEntity(); + projectileBlockHit.onHit(event, projectile, event.getHitBlock(), event.getHitBlockFace(), player); + } + this.projectiles.remove(projectile.getEntityId()); + } + } + + public void lingeringPotionSplash(LingeringPotionSplashEvent event) { + event.getAreaEffectCloud().setDuration(5 * 20); + } + + public void effectCloudApply(AreaEffectCloudApplyEvent event) { + event.setCancelled(true); + player.addPotionEffect(new PotionEffect(PotionEffectType.REGENERATION, 20, 0)); + } + + + + + @EventHandler + public void onMove(PlayerMoveEvent event) { + Player player = event.getPlayer(); + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + role.onMove(event); + } + + + @EventHandler + public void onInteract(PlayerInteractEvent event) { + Player player = event.getPlayer(); + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + role.onInteract(event); + } + + @EventHandler + public void onPoison(EntityDamageEvent event) { + if (!(event.getEntity() instanceof Player)) return; + Player player = (Player) event.getEntity(); + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + if (event.getCause() == EntityDamageEvent.DamageCause.POISON) + event.setCancelled(true); + } + + @EventHandler + public void onLand(ProjectileHitEvent event) { + ProjectileSource shooter = event.getEntity().getShooter(); + if (!(shooter instanceof Player)) return; + Player player = (Player) shooter; + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + role.projectileHit(event); + } + + @EventHandler + public void onPoisonSoak(LingeringPotionSplashEvent event) { + ProjectileSource shooter = event.getEntity().getShooter(); + if (!(shooter instanceof Player)) return; + Player player = (Player) shooter; + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + role.lingeringPotionSplash(event); + } + @EventHandler + public void onCloudApply(AreaEffectCloudApplyEvent event) { + ProjectileSource shooter = event.getEntity().getSource(); + if (!(shooter instanceof Player)) return; + Player player = (Player) shooter; + if (!this.matchesRole(player)) return; + NinjaRole role = this.getRole(player); + role.effectCloudApply(event); } } diff --git a/src/de/leafbla/meinkraft/roleplay/wizard/WizardListener.java b/src/de/leafbla/meinkraft/roleplay/wizard/WizardListener.java index 59373cd..1f47d90 100644 --- a/src/de/leafbla/meinkraft/roleplay/wizard/WizardListener.java +++ b/src/de/leafbla/meinkraft/roleplay/wizard/WizardListener.java @@ -18,6 +18,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerItemHeldEvent; +import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.meta.ItemMeta; @@ -25,6 +26,7 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.bukkit.projectiles.ProjectileSource; import org.bukkit.scheduler.BukkitRunnable; +import org.spigotmc.event.entity.EntityDismountEvent; public class WizardListener extends RoleListener { @@ -92,14 +94,11 @@ public class WizardListener extends RoleListener { @EventHandler public void onLand(ProjectileHitEvent event) { - Bukkit.getLogger().info("PHE"); ProjectileSource shooter = event.getEntity().getShooter(); if (!(shooter instanceof Player)) return; - Bukkit.getLogger().info("shooter was player"); Player player = (Player) shooter; if (!this.matchesRole(player)) return; WizardRole role = this.getRole(player); - Bukkit.getLogger().info("PHE"); role.projectileHit(event); //if (event.getEntity() instanceof Snowball) { // Snowball ball = (Snowball) event.getEntity(); diff --git a/src/de/leafbla/meinkraft/roleplay/wizard/WizardRole.java b/src/de/leafbla/meinkraft/roleplay/wizard/WizardRole.java index 86681a1..63faf3d 100644 --- a/src/de/leafbla/meinkraft/roleplay/wizard/WizardRole.java +++ b/src/de/leafbla/meinkraft/roleplay/wizard/WizardRole.java @@ -18,14 +18,15 @@ import org.bukkit.event.player.PlayerItemHeldEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.scheduler.BukkitRunnable; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; +import java.util.*; public class WizardRole extends PlayerRole implements ManaAble { - private final Map> projectiles = new HashMap<>(); + BukkitRunnable refillMana; + Set transmorphedPlayers = new HashSet<>(); + private int mana; public WizardRole(Main plugin, Player player) { @@ -51,31 +52,32 @@ public class WizardRole extends PlayerRole implements ManaAble { @Override public void start() { + setupInventory(); this.currentSpell = WizardSpell.values()[0]; - this.mana = 0; - } - - private ItemStack namedItem(Material material, String name) { - ItemStack itemStack = new ItemStack(material); - ItemMeta itemMeta = itemStack.getItemMeta(); - itemMeta.setDisplayName(name); - itemStack.setItemMeta(itemMeta); - return itemStack; + this.mana = 33; + refillMana = new BukkitRunnable() { + @Override + public void run() { + addMana(1); + } + }; + refillMana.runTaskTimer(plugin, 0, 5); } private void setupInventory() { ItemStack wand = new ItemStack(Material.STICK); player.getInventory().clear(); player.getInventory().setHeldItemSlot(0); - player.getInventory().addItem(namedItem(Material.STICK, "Wand")); + player.getInventory().addItem(Utils.namedItem(Material.STICK, "Wand")); for (WizardSpell wizardSpell : WizardSpell.values()) { - player.getInventory().addItem(namedItem(wizardSpell.getIcon(), wizardSpell.displayName())); + player.getInventory().addItem(Utils.namedItem(wizardSpell.getIcon(), wizardSpell.displayName())); } } @Override public void end() { + refillMana.cancel(); } @Override @@ -83,12 +85,6 @@ public class WizardRole extends PlayerRole implements ManaAble { return Role.WIZARD; } - public Snowball launchProjectile(Material material, ProjectileEntityHit entityHit, ProjectileBlockHit blockHit) { - Snowball snowball = Utils.launchProjectile(player, material); - this.projectiles.put(snowball.getEntityId(), new Pair<>(entityHit, blockHit)); - return snowball; - } - public void onInteract(PlayerInteractEvent event) { ItemStack itemStack = event.getPlayer().getInventory().getItemInMainHand(); if (itemStack.getType() != Material.STICK) return; @@ -129,7 +125,6 @@ public class WizardRole extends PlayerRole implements ManaAble { assert Objects.equals(event.getEntity().getShooter(), player); Projectile projectile = event.getEntity(); if (this.projectiles.containsKey(projectile.getEntityId())) { - Bukkit.getLogger().info("Known projectile"); ProjectileBlockHit projectileBlockHit = this.projectiles.get(projectile.getEntityId()).getRight(); ProjectileEntityHit projectileEntityHit = this.projectiles.get(projectile.getEntityId()).getLeft(); if (event.getHitEntity() != null) { diff --git a/src/de/leafbla/meinkraft/roleplay/wizard/WizardSpell.java b/src/de/leafbla/meinkraft/roleplay/wizard/WizardSpell.java index 55f3ad9..6944045 100644 --- a/src/de/leafbla/meinkraft/roleplay/wizard/WizardSpell.java +++ b/src/de/leafbla/meinkraft/roleplay/wizard/WizardSpell.java @@ -1,39 +1,122 @@ package de.leafbla.meinkraft.roleplay.wizard; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Chicken; +import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; enum WizardSpell { - PUFF_OF_MAGIC("Puff of Magic", Material.NETHER_STAR) { + PUFF_OF_MAGIC("Puff of Magic", Material.NETHER_STAR, 5) { @Override - void cast(WizardRole wizardRole) { + public void _cast(WizardRole wizardRole) { wizardRole.launchProjectile(Material.NETHER_STAR, (event, projectile, target, shooter) -> { if (!(target instanceof LivingEntity)) return; LivingEntity livingEntity = (LivingEntity) target; - livingEntity.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 5 * 20, 0)); - livingEntity.damage(2); + if (livingEntity.hasPotionEffect(PotionEffectType.GLOWING)) { + livingEntity.removePotionEffect(PotionEffectType.GLOWING); + livingEntity.damage(2); + livingEntity.setVelocity(livingEntity.getVelocity().add(projectile.getVelocity())); + } else { + livingEntity.addPotionEffect(new PotionEffect(PotionEffectType.GLOWING, 5 * 20, 0)); + livingEntity.damage(1); + } }, (event, projectile, target, targetFace, shooter) -> { - target.breakNaturally(); }); } }, - SPELL2("Fireball", Material.FIRE_CHARGE), - SPELL3("Something Something", Material.CLAY); + SPELL2("Fireball", Material.FIRE_CHARGE, 0), + SPELL3("Something Something", Material.CLAY, 0), + TRANSMORPH("Transmorgify", Material.FEATHER, 30) { + @Override + public void _cast(WizardRole wizardRole) { + wizardRole.launchProjectile(Material.FEATHER, + (event, projectile, target, shooter) -> { + if (!(target instanceof Player)) return; + if (target.equals(shooter)) return; + wizardRole.addMana(this.getManaCost()); + Player player = (Player) target; + GameMode previousGamemode = player.getGameMode(); + player.setGameMode(GameMode.SPECTATOR); + Chicken chicken = (Chicken) player.getWorld().spawnEntity(player.getLocation(), EntityType.CHICKEN); + int duration = 4 * 20; + chicken.setNoDamageTicks(duration); + + new BukkitRunnable() { + @Override + public void run() { + player.setSpectatorTarget(chicken); + player.playSound(player.getLocation(), Sound.ENTITY_CHICKEN_AMBIENT, 1, 1); + wizardRole.transmorphedPlayers.add(player); + } + }.runTask(wizardRole.plugin); + + BukkitRunnable undo = new BukkitRunnable() { + @Override + public void run() { + player.setSpectatorTarget(null); + player.setGameMode(previousGamemode); + chicken.remove(); + player.playSound(player.getLocation(), Sound.ENTITY_CHICKEN_DEATH, 1, 1); + wizardRole.transmorphedPlayers.remove(player); + } + }; + undo.runTaskLater(wizardRole.plugin, duration); + new BukkitRunnable() { + int time = 0; + + @Override + public void run() { + time += 2; + if (time >= duration) { + this.cancel(); + } + player.setSpectatorTarget(chicken); + } + }.runTaskTimer(wizardRole.plugin, 0, 2); + }, + (event, projectile, target, targetFace, shooter) -> { + }); + } + }; private final String displayName; private final Material icon; + private final int manaCost; - WizardSpell(String displayName, Material iconMaterial) { + WizardSpell(String displayName, Material iconMaterial, int manaCost) { this.displayName = displayName; this.icon = iconMaterial; + this.manaCost = manaCost; } - void cast(WizardRole wizardRole) { - wizardRole.getPlayer().sendMessage(String.format("§eCasting §6%s§e.", this.displayName)); + public int getManaCost() { + return this.manaCost; + } + + public void _cast(WizardRole wizardRole) { + } + + public void insufficientMana(WizardRole wizardRole) { + Player player = wizardRole.getPlayer(); + player.playSound(player.getLocation(), Sound.BLOCK_FIRE_EXTINGUISH, 1, 1); + } + + public void cast(WizardRole wizardRole) { + if (wizardRole.getMana() >= this.manaCost) { + wizardRole.addMana(-this.manaCost); + this._cast(wizardRole); + } else { + this.insufficientMana(wizardRole); + } } public String displayName() {