diff --git a/core/src/main/java/com/nisovin/magicspells/events/MagicSpellsExplosionPrimeEvent.java b/core/src/main/java/com/nisovin/magicspells/events/MagicSpellsExplosionPrimeEvent.java deleted file mode 100644 index d3b281ac0..000000000 --- a/core/src/main/java/com/nisovin/magicspells/events/MagicSpellsExplosionPrimeEvent.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.nisovin.magicspells.events; - -import org.bukkit.entity.Explosive; -import org.bukkit.event.entity.ExplosionPrimeEvent; - -public class MagicSpellsExplosionPrimeEvent extends ExplosionPrimeEvent implements IMagicSpellsCompatEvent { - - public MagicSpellsExplosionPrimeEvent(Explosive explosive) { - super(explosive); - // TODO Auto-generated constructor stub - } - -} diff --git a/core/src/main/java/com/nisovin/magicspells/events/PortalEnterEvent.java b/core/src/main/java/com/nisovin/magicspells/events/PortalEnterEvent.java index 0ca545e34..75d1060cc 100644 --- a/core/src/main/java/com/nisovin/magicspells/events/PortalEnterEvent.java +++ b/core/src/main/java/com/nisovin/magicspells/events/PortalEnterEvent.java @@ -1,53 +1,17 @@ package com.nisovin.magicspells.events; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; +import org.bukkit.Location; import org.bukkit.entity.LivingEntity; -import org.jetbrains.annotations.NotNull; - import com.nisovin.magicspells.spells.instant.PortalSpell; /** - * This event is fired whenever an entity enters a portal from PortalSpell. + * This event is fired whenever an entity enters a portal from {@link PortalSpell}. */ -public class PortalEnterEvent extends Event { - - private static final HandlerList handlers = new HandlerList(); - - private final LivingEntity entity; - - private final PortalSpell portalSpell; - - public PortalEnterEvent(LivingEntity entity, PortalSpell portalSpell) { - this.entity = entity; - this.portalSpell = portalSpell; - } - - /** - * Gets the entity who entered the portal - * @return the entity - */ - public LivingEntity getEntity() { - return entity; - } - - /** - * Gets the portal spell - * @return the spell - */ - public PortalSpell getPortalSpell() { - return portalSpell; - } - - @NotNull - @Override - public HandlerList getHandlers() { - return handlers; - } +public class PortalEnterEvent extends PortalEvent { - public static HandlerList getHandlerList() { - return handlers; + public PortalEnterEvent(LivingEntity entity, Location destination, PortalSpell portalSpell) { + super(entity, destination, portalSpell); } } diff --git a/core/src/main/java/com/nisovin/magicspells/events/PortalEvent.java b/core/src/main/java/com/nisovin/magicspells/events/PortalEvent.java new file mode 100644 index 000000000..b9f7f8beb --- /dev/null +++ b/core/src/main/java/com/nisovin/magicspells/events/PortalEvent.java @@ -0,0 +1,84 @@ +package com.nisovin.magicspells.events; + +import org.bukkit.Location; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.entity.LivingEntity; + +import org.jetbrains.annotations.NotNull; + +import com.nisovin.magicspells.spells.instant.PortalSpell; + +/** + * {@link PortalSpell} + */ +public class PortalEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + private Location destination; + private final LivingEntity entity; + private final PortalSpell portalSpell; + + private boolean cancelled = false; + + public PortalEvent(LivingEntity entity, Location destination, PortalSpell portalSpell) { + this.entity = entity; + this.destination = destination; + this.portalSpell = portalSpell; + } + + /** + * Gets the entity who entered the portal + * @return the entity + */ + public LivingEntity getEntity() { + return entity; + } + + /** + * Gets a clone of the portal destination + * @return location + */ + public Location getDestination() { + return destination.clone(); + } + + /** + * Set the portal destination for this event + * @param destination new destination + */ + public void setDestination(Location destination) { + this.destination = destination; + } + + /** + * Gets the portal spell + * @return the spell + */ + public PortalSpell getPortalSpell() { + return portalSpell; + } + + @NotNull + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + cancelled = cancel; + } + +} diff --git a/core/src/main/java/com/nisovin/magicspells/events/PortalLeaveEvent.java b/core/src/main/java/com/nisovin/magicspells/events/PortalLeaveEvent.java index 600a60979..1c6508bc7 100644 --- a/core/src/main/java/com/nisovin/magicspells/events/PortalLeaveEvent.java +++ b/core/src/main/java/com/nisovin/magicspells/events/PortalLeaveEvent.java @@ -1,53 +1,17 @@ package com.nisovin.magicspells.events; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; +import org.bukkit.Location; import org.bukkit.entity.LivingEntity; -import org.jetbrains.annotations.NotNull; - import com.nisovin.magicspells.spells.instant.PortalSpell; /** - * This event is fired whenever an entity leaves a portal from PortalSpell. + * This event is fired whenever an entity leaves a portal from {@link PortalSpell}. */ -public class PortalLeaveEvent extends Event { - - private static final HandlerList handlers = new HandlerList(); - - private final LivingEntity entity; - - private final PortalSpell portalSpell; - - public PortalLeaveEvent(LivingEntity entity, PortalSpell portalSpell) { - this.entity = entity; - this.portalSpell = portalSpell; - } - - /** - * Gets the entity who left the portal - * @return the entity - */ - public LivingEntity getEntity() { - return entity; - } - - /** - * Gets the portal spell - * @return the spell - */ - public PortalSpell getPortalSpell() { - return portalSpell; - } - - @NotNull - @Override - public HandlerList getHandlers() { - return handlers; - } +public class PortalLeaveEvent extends PortalEvent { - public static HandlerList getHandlerList() { - return handlers; + public PortalLeaveEvent(LivingEntity entity, Location destination, PortalSpell portalSpell) { + super(entity, destination, portalSpell); } } diff --git a/core/src/main/java/com/nisovin/magicspells/events/SpellTargetEvent.java b/core/src/main/java/com/nisovin/magicspells/events/SpellTargetEvent.java index 13f033b6d..7a0745000 100644 --- a/core/src/main/java/com/nisovin/magicspells/events/SpellTargetEvent.java +++ b/core/src/main/java/com/nisovin/magicspells/events/SpellTargetEvent.java @@ -23,6 +23,7 @@ public SpellTargetEvent(Spell spell, SpellData spellData) { this.spellData = spellData; } + public SpellTargetEvent(Spell spell, SpellData spellData, LivingEntity target) { this(spell, spellData.target(target)); } diff --git a/core/src/main/java/com/nisovin/magicspells/listeners/MagicSpellListener.java b/core/src/main/java/com/nisovin/magicspells/listeners/MagicSpellListener.java index e918a2863..c630537d7 100644 --- a/core/src/main/java/com/nisovin/magicspells/listeners/MagicSpellListener.java +++ b/core/src/main/java/com/nisovin/magicspells/listeners/MagicSpellListener.java @@ -1,8 +1,6 @@ package com.nisovin.magicspells.listeners; -import org.bukkit.GameMode; import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.bukkit.entity.ArmorStand; import org.bukkit.event.EventHandler; @@ -26,13 +24,12 @@ public class MagicSpellListener implements Listener { @EventHandler public void onSpellTarget(SpellTargetEvent event) { - // Check if target has noTarget permission / spectator gamemode / is in noMagicZone / is an invisible marker armorstand + // Check if target has noTarget permission / is in noMagicZone / is an invisible marker armorstand LivingEntity target = event.getTarget(); Spell spell = event.getSpell(); if (target == null) return; if (Perm.NO_TARGET.has(target)) event.setCancelled(true); - if (target instanceof Player && ((Player) target).getGameMode() == GameMode.SPECTATOR) event.setCancelled(true); if (spell != null && noMagicZoneManager != null && noMagicZoneManager.willFizzle(target, spell)) event.setCancelled(true); if (isMSEntity(target)) event.setCancelled(true); if (target instanceof ArmorStand && target.isInvisible() && ((ArmorStand) target).isMarker()) event.setCancelled(true); diff --git a/core/src/main/java/com/nisovin/magicspells/spells/PassiveSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/PassiveSpell.java index 93087f0f2..7ffceb560 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/PassiveSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/PassiveSpell.java @@ -282,7 +282,7 @@ private boolean activateSpells(SpellData data) { if (data.hasTarget()) { SpellTargetEvent targetEvent = new SpellTargetEvent(this, data); - if (!targetEvent.callEvent()) { + if (!validTargetList.canTarget(data.caster(), data.target()) || !targetEvent.callEvent()) { MagicSpells.debug(3, " Target cancelled (TE)"); disabled = false; diff --git a/core/src/main/java/com/nisovin/magicspells/spells/instant/BeamSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/instant/BeamSpell.java index 2db4ccc49..0b3048b82 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/instant/BeamSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/instant/BeamSpell.java @@ -258,7 +258,7 @@ public CastResult castAtEntityFromLocation(SpellData data) { //check entities in the beam range for (LivingEntity e : loc.getNearbyLivingEntities(hitRadius, verticalHitRadius)) { if (!e.isValid() || immune.contains(e)) continue; - if (validTargetList != null && !validTargetList.canTarget(data.caster(), e)) continue; + if (!validTargetList.canTarget(data.caster(), e)) continue; SpellTargetEvent event = new SpellTargetEvent(this, locData, e); if (!event.callEvent()) continue; diff --git a/core/src/main/java/com/nisovin/magicspells/spells/instant/BlockBeamSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/instant/BlockBeamSpell.java index c859edad7..3568d0ade 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/instant/BlockBeamSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/instant/BlockBeamSpell.java @@ -299,7 +299,7 @@ public CastResult castAtEntityFromLocation(SpellData data) { //check entities in the beam range for (LivingEntity e : loc.getNearbyLivingEntities(hitRadius, verticalHitRadius)) { if (!e.isValid() || immune.contains(e)) continue; - if (validTargetList != null && !validTargetList.canTarget(data.caster(), e)) continue; + if (!validTargetList.canTarget(data.caster(), e)) continue; SpellTargetEvent event = new SpellTargetEvent(this, locData, e); if (!event.callEvent()) continue; diff --git a/core/src/main/java/com/nisovin/magicspells/spells/instant/DowseSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/instant/DowseSpell.java index 09a473c15..a26ecbe3a 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/instant/DowseSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/instant/DowseSpell.java @@ -145,18 +145,18 @@ else if (radius > 0 && caster.getLocation().distanceSquared(foundEntity.getLocat } if (!ordered.isEmpty()) { for (NearbyEntity ne : ordered) { - if (ne.entity instanceof LivingEntity le) { - SpellTargetEvent event = new SpellTargetEvent(this, data, le); - EventUtil.call(event); - if (!event.isCancelled()) { - foundEntity = event.getTarget(); - data = event.getSpellData(); - break; - } - } else { + if (!(ne.entity instanceof LivingEntity le)) { foundEntity = ne.entity; break; } + + if (!validTargetList.canTarget(caster, le)) continue; + SpellTargetEvent event = new SpellTargetEvent(this, data, le); + EventUtil.call(event); + if (event.isCancelled()) continue; + foundEntity = event.getTarget(); + data = event.getSpellData(); + break; } } } diff --git a/core/src/main/java/com/nisovin/magicspells/spells/instant/PortalSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/instant/PortalSpell.java index e4802ffb4..5984a2d32 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/instant/PortalSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/instant/PortalSpell.java @@ -18,6 +18,8 @@ import com.nisovin.magicspells.MagicSpells; import com.nisovin.magicspells.spells.InstantSpell; import com.nisovin.magicspells.util.config.ConfigData; +import com.nisovin.magicspells.events.PortalEnterEvent; +import com.nisovin.magicspells.events.PortalLeaveEvent; import com.nisovin.magicspells.events.SpellTargetEvent; import com.nisovin.magicspells.spelleffects.EffectPosition; @@ -318,14 +320,22 @@ private void onMove(PlayerMoveEvent event) { // Enters start portal if (checkHitbox(event.getTo(), startPortal)) { if (!checkTeleport(pl, startPortal)) return; - teleport(endPortal.portalLocation().clone(), pl, event); + + PortalEnterEvent portalEvent = new PortalEnterEvent(pl, endPortal.portalLocation(), PortalSpell.this); + if (!portalEvent.callEvent()) return; + + teleport(portalEvent.getDestination(), pl, event); return; } // Enters end portal if (allowReturn && checkHitbox(event.getTo(), endPortal)) { if (!checkTeleport(pl, endPortal)) return; - teleport(startPortal.portalLocation().clone(), pl, event); + + PortalLeaveEvent portalEvent = new PortalLeaveEvent(pl, startPortal.portalLocation(), PortalSpell.this); + if (!portalEvent.callEvent()) return; + + teleport(portalEvent.getDestination(), pl, event); } } diff --git a/core/src/main/java/com/nisovin/magicspells/spells/passive/PortalEnterListener.java b/core/src/main/java/com/nisovin/magicspells/spells/passive/PortalEnterListener.java new file mode 100644 index 000000000..7f80d8598 --- /dev/null +++ b/core/src/main/java/com/nisovin/magicspells/spells/passive/PortalEnterListener.java @@ -0,0 +1,38 @@ +package com.nisovin.magicspells.spells.passive; + +import org.bukkit.event.EventHandler; +import org.bukkit.entity.LivingEntity; + +import org.jetbrains.annotations.NotNull; + +import com.nisovin.magicspells.util.Name; + +import com.nisovin.magicspells.util.SpellFilter; +import com.nisovin.magicspells.events.PortalEnterEvent; +import com.nisovin.magicspells.spells.passive.util.PassiveListener; + +@Name("portalenter") +public class PortalEnterListener extends PassiveListener { + + private SpellFilter filter; + + @Override + public void initialize(@NotNull String var) { + if (var.isEmpty()) return; + filter = SpellFilter.fromString(var); + } + + @EventHandler + public void onEnter(PortalEnterEvent event) { + if (!isCancelStateOk(event.isCancelled())) return; + + LivingEntity entity = event.getEntity(); + if (!canTrigger(entity)) return; + + if (filter != null && !filter.check(event.getPortalSpell())) return; + + boolean casted = passiveSpell.activate(entity); + if (cancelDefaultAction(casted)) event.setCancelled(true); + } + +} diff --git a/core/src/main/java/com/nisovin/magicspells/spells/passive/PortalLeaveListener.java b/core/src/main/java/com/nisovin/magicspells/spells/passive/PortalLeaveListener.java new file mode 100644 index 000000000..7c1a6d211 --- /dev/null +++ b/core/src/main/java/com/nisovin/magicspells/spells/passive/PortalLeaveListener.java @@ -0,0 +1,38 @@ +package com.nisovin.magicspells.spells.passive; + +import org.bukkit.event.EventHandler; +import org.bukkit.entity.LivingEntity; + +import org.jetbrains.annotations.NotNull; + +import com.nisovin.magicspells.util.Name; + +import com.nisovin.magicspells.util.SpellFilter; +import com.nisovin.magicspells.events.PortalLeaveEvent; +import com.nisovin.magicspells.spells.passive.util.PassiveListener; + +@Name("portalleave") +public class PortalLeaveListener extends PassiveListener { + + private SpellFilter filter; + + @Override + public void initialize(@NotNull String var) { + if (var.isEmpty()) return; + filter = SpellFilter.fromString(var); + } + + @EventHandler + public void onLeave(PortalLeaveEvent event) { + if (!isCancelStateOk(event.isCancelled())) return; + + LivingEntity entity = event.getEntity(); + if (!canTrigger(entity)) return; + + if (filter != null && !filter.check(event.getPortalSpell())) return; + + boolean casted = passiveSpell.activate(entity); + if (cancelDefaultAction(casted)) event.setCancelled(true); + } + +} diff --git a/core/src/main/java/com/nisovin/magicspells/spells/targeted/CarpetSpell.java b/core/src/main/java/com/nisovin/magicspells/spells/targeted/CarpetSpell.java index 1e648dfa2..ac4ee2d46 100644 --- a/core/src/main/java/com/nisovin/magicspells/spells/targeted/CarpetSpell.java +++ b/core/src/main/java/com/nisovin/magicspells/spells/targeted/CarpetSpell.java @@ -1,15 +1,12 @@ package com.nisovin.magicspells.spells.targeted; -import java.util.Map; -import java.util.List; -import java.util.HashMap; -import java.util.ArrayList; +import java.util.*; +import java.util.Map.Entry; -import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Location; import org.bukkit.block.Block; -import org.bukkit.entity.Player; +import org.bukkit.entity.LivingEntity; import com.nisovin.magicspells.util.*; import com.nisovin.magicspells.Subspell; @@ -73,8 +70,8 @@ public void initialize() { public void turnOff() { super.turnOff(); - for (Block block : blocks.keySet()) { - block.setType(Material.AIR); + for (Entry entry : blocks.entrySet()) { + entry.getKey().setType(entry.getValue().air()); } blocks.clear(); if (checker != null) checker.stop(); @@ -151,9 +148,9 @@ private CastResult layCarpet(SpellData data) { if (!b.getType().isAir() && !b.getRelative(0, -1, 0).getType().isSolid()) continue; + blocks.put(b, new CarpetData(data, material, b.getType(), removeOnTouch)); b.setType(material, false); blockList.add(b); - blocks.put(b, new CarpetData(data, material, b.getType(), removeOnTouch)); Location subLoc = b.getLocation().add(0.5, 0, 0.5); playSpellEffects(EffectPosition.TARGET, subLoc, data.location(subLoc)); @@ -190,26 +187,24 @@ private TouchChecker() { @Override public void run() { - if (blocks.isEmpty()) return; - for (Player player : Bukkit.getOnlinePlayers()) { - - Block b = player.getLocation().getBlock(); - CarpetData data = blocks.get(b); - - if (data == null) continue; - if (player.equals(data.data.caster())) continue; - if (!data.material.equals(b.getType())) continue; - - if (data.removeOnTouch) { - b.setType(data.air); - blocks.remove(b); - } - - if (spellOnTouch != null) { - SpellTargetEvent event = new SpellTargetEvent(CarpetSpell.this, data.data, player); - if (!event.callEvent()) continue; - - spellOnTouch.subcast(event.getSpellData()); + for (Entry entry : new HashSet<>(blocks.entrySet())) { + Block block = entry.getKey(); + CarpetData carpetData = entry.getValue(); + for (LivingEntity target : block.getLocation().add(0.5, 1.5, 0.5).getNearbyLivingEntities(0.5)) { + if (!carpetData.material.equals(block.getType())) continue; + if (!validTargetList.canTarget(carpetData.data.caster(), target)) continue; + + if (carpetData.removeOnTouch) { + block.setType(carpetData.air); + blocks.remove(block); + } + + if (spellOnTouch != null) { + SpellTargetEvent event = new SpellTargetEvent(CarpetSpell.this, carpetData.data, target); + if (!event.callEvent()) continue; + + spellOnTouch.subcast(event.getSpellData()); + } } } } diff --git a/core/src/main/java/com/nisovin/magicspells/util/ValidTargetList.java b/core/src/main/java/com/nisovin/magicspells/util/ValidTargetList.java index 8b464849e..32aa61ea4 100644 --- a/core/src/main/java/com/nisovin/magicspells/util/ValidTargetList.java +++ b/core/src/main/java/com/nisovin/magicspells/util/ValidTargetList.java @@ -144,11 +144,9 @@ public boolean canTarget(LivingEntity caster, Entity target, boolean targetPlaye if (!(target instanceof LivingEntity) && !targetNonLivingEntities) return false; boolean targetIsPlayer = target instanceof Player; + if (target.equals(caster)) return targetSelf; if (targetIsPlayer && !gameModes.contains(((Player) target).getGameMode())) return false; - if (targetSelf && target.equals(caster)) return true; - if (!targetSelf && target.equals(caster)) return false; - if (!targetInvisibles && targetIsPlayer && caster instanceof Player player && !player.canSee((Player) target)) return false; if (targetPlayers && targetIsPlayer) return true; if (targetNonPlayers && !targetIsPlayer) return true; diff --git a/core/src/main/java/com/nisovin/magicspells/util/managers/PassiveManager.java b/core/src/main/java/com/nisovin/magicspells/util/managers/PassiveManager.java index 7801c919f..e63635f97 100644 --- a/core/src/main/java/com/nisovin/magicspells/util/managers/PassiveManager.java +++ b/core/src/main/java/com/nisovin/magicspells/util/managers/PassiveManager.java @@ -136,6 +136,8 @@ private void initialize() { addListener(PlayerAnimationListener.class); addListener(PlayerMoveListener.class); addListener(PlayerMoveToBlockListener.class); + addListener(PortalEnterListener.class); + addListener(PortalLeaveListener.class); addListener(PotionEffectListener.class); addListener(PrepareEnchantListener.class); addListener(QuitListener.class);