From 7b0dd73098547426327c7cb7db33e430feb5b2b6 Mon Sep 17 00:00:00 2001 From: Lilly <46890129+RainbowDashLabs@users.noreply.github.com> Date: Fri, 18 Aug 2023 13:59:19 +0200 Subject: [PATCH] First implementation of every default trigger --- .../configuration/Configuration.java | 2 +- .../bloodnight/mobs/DamageHandler.java | 75 ++++++++++ .../eldoria/bloodnight/mobs/MobSpawner.java | 2 + .../dispatcher/DefaultTriggerDispatcher.java | 42 ------ .../mobs/dispatcher/KillDispatcher.java | 42 ------ .../dispatcher/impl/DamageDispatcher.java | 78 ++++++++++ .../dispatcher/impl/ExplosionDispatcher.java | 27 ++++ .../dispatcher/impl/ProjectileDispatcher.java | 34 +++++ .../impl/StandardTriggerDispatcher.java | 51 +++++++ .../de/eldoria/bloodnight/util/MobTags.java | 135 ++++++++++++++++-- .../bloodnight/nodes/meta/DataType.java | 1 + .../eldoria/bloodnight/nodes/meta/Fields.java | 5 + .../impl/events/OnTargetChangeNode.java | 43 ++++++ .../trigger/impl/events/OnTeleportNode.java | 44 ++++++ .../events/damage/OnDamageByEntityNode.java | 48 +++++++ .../events/damage/OnDamageByPlayerNode.java | 48 +++++++ .../impl/events/damage/OnDamageNode.java | 50 +++++++ .../impl/events/{ => damage}/OnDeathNode.java | 7 +- .../trigger/impl/events/damage/OnHitNode.java | 47 ++++++ .../events/explosion/OnExplosionNode.java | 39 +++++ .../{ => explosion}/OnExplosionPrimeNode.java | 9 +- .../events/{ => kill}/OnEntityKillNode.java | 8 +- .../trigger/impl/events/kill/OnKillNode.java | 43 ++++++ .../events/{ => kill}/OnPlayerKillNode.java | 10 +- .../events/projectile/OnProjectileHit.java | 39 +++++ .../events/projectile/OnProjectileShoot.java | 41 ++++++ settings.gradle.kts | 1 + 27 files changed, 866 insertions(+), 105 deletions(-) create mode 100644 core/src/main/java/de/eldoria/bloodnight/mobs/DamageHandler.java delete mode 100644 core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/DefaultTriggerDispatcher.java delete mode 100644 core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/KillDispatcher.java create mode 100644 core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/DamageDispatcher.java create mode 100644 core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/ExplosionDispatcher.java create mode 100644 core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/ProjectileDispatcher.java create mode 100644 core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/StandardTriggerDispatcher.java create mode 100644 nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnTargetChangeNode.java create mode 100644 nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnTeleportNode.java create mode 100644 nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageByEntityNode.java create mode 100644 nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageByPlayerNode.java create mode 100644 nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageNode.java rename nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/{ => damage}/OnDeathNode.java (87%) create mode 100644 nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnHitNode.java create mode 100644 nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/explosion/OnExplosionNode.java rename nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/{ => explosion}/OnExplosionPrimeNode.java (83%) rename nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/{ => kill}/OnEntityKillNode.java (85%) create mode 100644 nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/kill/OnKillNode.java rename nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/{ => kill}/OnPlayerKillNode.java (82%) create mode 100644 nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/projectile/OnProjectileHit.java create mode 100644 nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/projectile/OnProjectileShoot.java diff --git a/core/src/main/java/de/eldoria/bloodnight/configuration/Configuration.java b/core/src/main/java/de/eldoria/bloodnight/configuration/Configuration.java index bd6c743..06ca8a6 100644 --- a/core/src/main/java/de/eldoria/bloodnight/configuration/Configuration.java +++ b/core/src/main/java/de/eldoria/bloodnight/configuration/Configuration.java @@ -16,7 +16,7 @@ public class Configuration extends JacksonConfig { // TODO: Register default mobs on creation public static final ConfigKey MOBS = ConfigKey.of("mobs", Path.of("mobs.yml"), MobRegistry.class, MobRegistry::new); - public static final ConfigKey ITEMS = ConfigKey.of("mobs", Path.of("mobs.yml"), ItemRegistry.class, ItemRegistry::new); + public static final ConfigKey ITEMS = ConfigKey.of("items", Path.of("items.yml"), ItemRegistry.class, ItemRegistry::new); public static final ConfigKey GLOBAL_DROPS = ConfigKey.of("Global Drops", Path.of("global_drops.yml"), GlobalDrops.class, GlobalDrops::defaultDrops); public Configuration(@NotNull Plugin plugin) { diff --git a/core/src/main/java/de/eldoria/bloodnight/mobs/DamageHandler.java b/core/src/main/java/de/eldoria/bloodnight/mobs/DamageHandler.java new file mode 100644 index 0000000..8427389 --- /dev/null +++ b/core/src/main/java/de/eldoria/bloodnight/mobs/DamageHandler.java @@ -0,0 +1,75 @@ +package de.eldoria.bloodnight.mobs; + +import de.eldoria.bloodnight.util.MobTags; +import org.bukkit.EntityEffect; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; + +import java.util.Optional; +import java.util.UUID; + +/** + * This class handles damage events for custom mobs with extensions. + * It listens for entity damage events and performs necessary actions based on the type of damage and the entity involved. + */ +public class DamageHandler implements Listener { + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) + public void onExtensionDamage(EntityDamageEvent event) { + if (MobTags.isExtension(event.getEntity())) handleExtensionDamage(event); + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) + public void onBaseDamage(EntityDamageEvent event) { + if (MobTags.isExtended(event.getEntity())) handleBaseDamage(event); + } + + private void handleExtensionDamage(EntityDamageEvent event) { + Entity entity = event.getEntity(); + Optional baseId = MobTags.getBase(entity); + if (baseId.isEmpty()) return; + if (!(entity instanceof LivingEntity extension)) return; + // Forward damage from extension over to base mob + if (!(entity.getServer().getEntity(baseId.get()) instanceof LivingEntity base)) return; + + if (event instanceof EntityDamageByEntityEvent byEntity) { + base.damage(event.getDamage(), byEntity.getDamager()); + } else { + base.damage(event.getDamage()); + } + event.setCancelled(true); + // Sync damage from base to extension + extension.setHealth(base.getHealth()); + entity.playEffect(EntityEffect.HURT); + } + + private void handleBaseDamage(EntityDamageEvent event) { + Entity entity = event.getEntity(); + Optional extensionId = MobTags.getExtension(entity); + if (!(entity instanceof LivingEntity base)) return; + + if (extensionId.isEmpty()) return; + if (!(entity.getServer().getEntity(extensionId.get()) instanceof LivingEntity extension)) return; + + // We assume that the damage won't change anymore + extension.setHealth(base.getHealth() - event.getFinalDamage()); + extension.playEffect(EntityEffect.HURT); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onEntityDeath(EntityDeathEvent event) { + var entity = event.getEntity(); + if (!MobTags.isCustomMob(entity)) return; + Optional extensionId = MobTags.getExtension(entity); + if (extensionId.isEmpty()) return; + // Kill extension when the base dies. + if (entity.getServer().getEntity(extensionId.get()) instanceof LivingEntity extension) { + extension.damage(extension.getHealth()); + } + } +} diff --git a/core/src/main/java/de/eldoria/bloodnight/mobs/MobSpawner.java b/core/src/main/java/de/eldoria/bloodnight/mobs/MobSpawner.java index 86e15c0..842a74b 100644 --- a/core/src/main/java/de/eldoria/bloodnight/mobs/MobSpawner.java +++ b/core/src/main/java/de/eldoria/bloodnight/mobs/MobSpawner.java @@ -38,7 +38,9 @@ void handleSpawnedMob(Entity entity) { List matching = configuration.mobs().getMatching(active, entity.getType()); if(matching.isEmpty()) return; if (worldSettings.mobSettings().spawning().spawnPercentage() < ThreadLocalRandom.current().nextInt(100)) return; + // TODO: This doesnt factor in the spawn percentage of matching active mobs itself. CustomMob customMob = matching.get(ThreadLocalRandom.current().nextInt(matching.size())); + // TODO Building the mob with changed attributes, equipment, extensions etc is missing. coordinator.register(entity, customMob); } diff --git a/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/DefaultTriggerDispatcher.java b/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/DefaultTriggerDispatcher.java deleted file mode 100644 index 2265f3c..0000000 --- a/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/DefaultTriggerDispatcher.java +++ /dev/null @@ -1,42 +0,0 @@ -package de.eldoria.bloodnight.mobs.dispatcher; - -import de.eldoria.bloodnight.mobs.MobCoordinator; -import de.eldoria.bloodnight.nodes.dispatching.TriggerData; -import de.eldoria.bloodnight.nodes.trigger.TriggerNode; -import de.eldoria.bloodnight.nodes.trigger.impl.events.OnDeathNode; -import de.eldoria.bloodnight.nodes.trigger.impl.events.OnExplosionPrimeNode; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityDamageByBlockEvent; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.event.entity.ExplosionPrimeEvent; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -/** - * This class listens to events, wraps their data into a {@link TriggerData} and trigger corresponding {@link TriggerNode}. - * This class only covers predefined trigger nodes. - * Custom nodes will need to create their own trigger dispatcher. - */ -public class DefaultTriggerDispatcher extends TriggerDispatcher { - - public DefaultTriggerDispatcher(MobCoordinator coordinator) { - super(coordinator); - } - - @EventHandler - public void onDeath(EntityDeathEvent event) { - trigger(event.getEntity(), TriggerData.forNode(OnDeathNode.class, event)); - } - - @EventHandler - public void onExplosionPrime(ExplosionPrimeEvent event) { - trigger(event.getEntity(), TriggerData.forNode(OnExplosionPrimeNode.class, event)); - } - -} diff --git a/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/KillDispatcher.java b/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/KillDispatcher.java deleted file mode 100644 index b6ffb61..0000000 --- a/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/KillDispatcher.java +++ /dev/null @@ -1,42 +0,0 @@ -package de.eldoria.bloodnight.mobs.dispatcher; - -import de.eldoria.bloodnight.mobs.MobCoordinator; -import de.eldoria.bloodnight.nodes.dispatching.TriggerData; -import de.eldoria.bloodnight.nodes.trigger.impl.events.OnDeathNode; -import de.eldoria.bloodnight.nodes.trigger.impl.events.OnEntityKillNode; -import de.eldoria.bloodnight.nodes.trigger.impl.events.OnPlayerKillNode; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDeathEvent; - -public class KillDispatcher extends TriggerDispatcher { - public KillDispatcher(MobCoordinator coordinator) { - super(coordinator); - } - - /** - * This handler is purely for observing dealt damage to entities to notice who killed it. - * - * @param event damage event - */ - @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) - public void onEntityDamageDelegate(EntityDamageByEntityEvent event) { - if (!(event.getEntity() instanceof LivingEntity living)) return; - // Check if entity will be killed. - if (event.getFinalDamage() >= living.getHealth()) { - if (event.getEntity() instanceof Player) { - trigger(event.getDamager(), TriggerData.forNode(OnPlayerKillNode.class, event)); - } else { - trigger(event.getDamager(), TriggerData.forNode(OnEntityKillNode.class, event)); - } - } - } - - @EventHandler - public void onEntityDeath(EntityDeathEvent event) { - trigger(event.getEntity(), TriggerData.forNode(OnDeathNode.class, event)); - } -} diff --git a/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/DamageDispatcher.java b/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/DamageDispatcher.java new file mode 100644 index 0000000..cc7408b --- /dev/null +++ b/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/DamageDispatcher.java @@ -0,0 +1,78 @@ +package de.eldoria.bloodnight.mobs.dispatcher.impl; + +import de.eldoria.bloodnight.mobs.MobCoordinator; +import de.eldoria.bloodnight.mobs.dispatcher.TriggerDispatcher; +import de.eldoria.bloodnight.nodes.dispatching.TriggerData; +import de.eldoria.bloodnight.nodes.trigger.impl.events.damage.OnDamageByEntityNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.damage.OnDamageByPlayerNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.damage.OnDamageNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.damage.OnDeathNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.damage.OnHitNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.kill.OnEntityKillNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.kill.OnKillNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.kill.OnPlayerKillNode; +import de.eldoria.bloodnight.util.MobTags; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; + +/** + * A {@link TriggerDispatcher} which only handles kills of entities + */ +public class DamageDispatcher extends TriggerDispatcher { + public DamageDispatcher(MobCoordinator coordinator) { + super(coordinator); + } + + /** + * This handler is purely for observing dealt damage to entities to notice who killed it. + * + * @param event damage event + */ + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) + public void onKill(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof LivingEntity living)) return; + // Check whether entity will be killed. + if (event.getFinalDamage() >= living.getHealth()) { + trigger(event.getDamager(), TriggerData.forNode(OnKillNode.class, event)); + if (event.getEntity() instanceof Player) { + trigger(event.getDamager(), TriggerData.forNode(OnPlayerKillNode.class, event)); + } else { + trigger(event.getDamager(), TriggerData.forNode(OnEntityKillNode.class, event)); + } + } + } + + @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGH) + public void onDamage(EntityDamageEvent event) { + // We do not care about non CustomMob damage here + if (!MobTags.isCustomMob(event.getEntity())) return; + // Damage to extensions is handled somewhere else + if (MobTags.isExtension(event.getEntity())) return; + + if (event instanceof EntityDamageByEntityEvent byEntity) { + if (byEntity.getDamager().getType() == EntityType.PLAYER) { + trigger(event.getEntity(), TriggerData.forNode(OnDamageByPlayerNode.class, byEntity)); + } else { + trigger(event.getEntity(), TriggerData.forNode(OnDamageByEntityNode.class, byEntity)); + } + } else { + trigger(event.getEntity(), TriggerData.forNode(OnDamageNode.class, event)); + } + } + + @EventHandler + public void onHit(EntityDamageByEntityEvent event) { + trigger(event.getDamager(), TriggerData.forNode(OnHitNode.class, event)); + } + + @EventHandler(priority = EventPriority.HIGH) + public void onEntityDeath(EntityDeathEvent event) { + trigger(event.getEntity(), TriggerData.forNode(OnDeathNode.class, event)); + } +} diff --git a/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/ExplosionDispatcher.java b/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/ExplosionDispatcher.java new file mode 100644 index 0000000..550625f --- /dev/null +++ b/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/ExplosionDispatcher.java @@ -0,0 +1,27 @@ +package de.eldoria.bloodnight.mobs.dispatcher.impl; + +import de.eldoria.bloodnight.mobs.MobCoordinator; +import de.eldoria.bloodnight.mobs.dispatcher.TriggerDispatcher; +import de.eldoria.bloodnight.nodes.dispatching.TriggerData; +import de.eldoria.bloodnight.nodes.trigger.impl.events.explosion.OnExplosionNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.explosion.OnExplosionPrimeNode; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.ExplosionPrimeEvent; + +public class ExplosionDispatcher extends TriggerDispatcher { + public ExplosionDispatcher(MobCoordinator coordinator) { + super(coordinator); + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onExplosionPrime(ExplosionPrimeEvent event) { + trigger(event.getEntity(), TriggerData.forNode(OnExplosionPrimeNode.class, event)); + } + + @EventHandler + public void onExplosionEvent(EntityExplodeEvent event) { + trigger(event.getEntity(), TriggerData.forNode(OnExplosionNode.class, event)); + } +} diff --git a/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/ProjectileDispatcher.java b/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/ProjectileDispatcher.java new file mode 100644 index 0000000..9418c23 --- /dev/null +++ b/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/ProjectileDispatcher.java @@ -0,0 +1,34 @@ +package de.eldoria.bloodnight.mobs.dispatcher.impl; + +import de.eldoria.bloodnight.mobs.MobCoordinator; +import de.eldoria.bloodnight.mobs.dispatcher.TriggerDispatcher; +import de.eldoria.bloodnight.nodes.dispatching.TriggerData; +import de.eldoria.bloodnight.nodes.trigger.impl.events.projectile.OnProjectileHit; +import de.eldoria.bloodnight.nodes.trigger.impl.events.projectile.OnProjectileShoot; +import de.eldoria.eldoutilities.entities.projectiles.ProjectileSender; +import de.eldoria.eldoutilities.entities.projectiles.ProjectileUtil; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.ProjectileHitEvent; +import org.bukkit.event.entity.ProjectileLaunchEvent; + +public class ProjectileDispatcher extends TriggerDispatcher { + public ProjectileDispatcher(MobCoordinator coordinator) { + super(coordinator); + } + + @EventHandler + public void onProjectileShoot(ProjectileLaunchEvent event) { + ProjectileSender projectileSource = ProjectileUtil.getProjectileSource(event.getEntity()); + if (projectileSource.isEntity()) { + trigger(projectileSource.getEntity(), TriggerData.forNode(OnProjectileShoot.class, event)); + } + } + + @EventHandler + public void onProjectileHit(ProjectileHitEvent event) { + ProjectileSender projectileSource = ProjectileUtil.getProjectileSource(event.getEntity()); + if (projectileSource.isEntity()) { + trigger(event.getEntity(), TriggerData.forNode(OnProjectileHit.class, event)); + } + } +} diff --git a/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/StandardTriggerDispatcher.java b/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/StandardTriggerDispatcher.java new file mode 100644 index 0000000..ae597ff --- /dev/null +++ b/core/src/main/java/de/eldoria/bloodnight/mobs/dispatcher/impl/StandardTriggerDispatcher.java @@ -0,0 +1,51 @@ +package de.eldoria.bloodnight.mobs.dispatcher.impl; + +import de.eldoria.bloodnight.mobs.MobCoordinator; +import de.eldoria.bloodnight.mobs.dispatcher.TriggerDispatcher; +import de.eldoria.bloodnight.nodes.dispatching.TriggerData; +import de.eldoria.bloodnight.nodes.trigger.TriggerNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.OnTargetChangeNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.OnTeleportNode; +import de.eldoria.bloodnight.util.MobTags; +import org.bukkit.entity.EntityType; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.entity.EntityTargetLivingEntityEvent; +import org.bukkit.event.entity.EntityTeleportEvent; + +/** + * This class listens to events, wraps their data into a {@link TriggerData} and trigger corresponding {@link TriggerNode}. + * This class only covers predefined trigger nodes. + * Custom nodes will need to create their own trigger dispatcher. + */ +public class StandardTriggerDispatcher extends TriggerDispatcher { + + public StandardTriggerDispatcher(MobCoordinator coordinator) { + super(coordinator); + } + + @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) + public void onTeleport(EntityTeleportEvent event) { + trigger(event.getEntity(), TriggerData.forNode(OnTeleportNode.class, event)); + } + + @EventHandler + public void onTargetEvent(EntityTargetLivingEntityEvent event) { + if (event.getTarget() != null && MobTags.isCustomMob(event.getTarget())) { + event.setCancelled(true); + return; + } + + if (!MobTags.isCustomMob(event.getEntity())) { + return; + } + + // Block that custom mobs target something else than players. + // Otherwise, they will probably kill each other. + if (event.getTarget() != null && event.getTarget().getType() != EntityType.PLAYER) { + event.setCancelled(true); + return; + } + trigger(event.getEntity(), TriggerData.forNode(OnTargetChangeNode.class, event)); + } +} diff --git a/core/src/main/java/de/eldoria/bloodnight/util/MobTags.java b/core/src/main/java/de/eldoria/bloodnight/util/MobTags.java index 9332e3f..3a90580 100644 --- a/core/src/main/java/de/eldoria/bloodnight/util/MobTags.java +++ b/core/src/main/java/de/eldoria/bloodnight/util/MobTags.java @@ -1,26 +1,143 @@ package de.eldoria.bloodnight.util; import de.eldoria.bloodnight.mob.CustomMob; +import de.eldoria.eldoutilities.utils.DataContainerUtil; import org.bukkit.NamespacedKey; import org.bukkit.entity.Entity; import org.bukkit.persistence.PersistentDataType; -public class MobTags { +import java.util.Optional; +import java.util.UUID; + +/** + * Utility class for managing tags related to custom mobs. + */ +public final class MobTags { + private static final String NAMESPACE = "bloodnight"; + + private MobTags() { + throw new UnsupportedOperationException("This is a utility class."); + } + + + private static NamespacedKey create(String key) { + return new NamespacedKey(NAMESPACE, key); + } + /** * Marks that an {@link Entity} is a {@link CustomMob}. - * This tag is solely for existence checks and should use a {@link PersistentDataType#BYTE}. - * The value of the byte doesn't matter. - * If this tag is set on the mob with the BYTE type, it is always considered a custom mob. + * This tag should use a {@link PersistentDataType#STRING} and save the {@link CustomMob#id()}. */ - public static final NamespacedKey CUSTOM_MOB = new NamespacedKey("bloodnight", "custom_mob"); + public static final NamespacedKey CUSTOM_MOB = create("custom_mob"); /** * Marks that a mob is an extension of a custom mob. - * This tag should use a {@link PersistentDataType#INTEGER} containing the {@link Entity#getEntityId()} of the entity that the mob has, that is extended. + * This tag should use a {@link PersistentDataType#STRING} containing the {@link Entity#getUniqueId()} of the entity that the mob has, that is extended. */ - public static final NamespacedKey EXTENDS = new NamespacedKey("bloodnight", "extends"); + public static final NamespacedKey EXTENDS = create("extends"); /** * Marks that a mob is extended and has another mob attached to it. - * This tag should use a {@link PersistentDataType#INTEGER} containing the {@link Entity#getEntityId()} of the entity that extends this mob. + * This tag should use a {@link PersistentDataType#STRING} containing the {@link Entity#getUniqueId()} of the entity that extends this mob. + */ + public static final NamespacedKey EXTENDED = create("extended"); + + /** + * Checks if the specified entity is a custom mob. + * + * @param entity the entity to check + * @return true if the entity is a custom mob, false otherwise + */ + public static boolean isCustomMob(Entity entity) { + return DataContainerUtil.hasKey(entity, CUSTOM_MOB, PersistentDataType.STRING); + } + + /** + * Retrieves the {@link CustomMob#id()} associated with the given entity. + * + * @param entity the entity to retrieve the custom mob ID from + * @return an optional containing the custom mob ID, or an empty optional if no custom mob ID is found + */ + public static Optional getCustomMobId(Entity entity) { + return DataContainerUtil.get(entity, CUSTOM_MOB, PersistentDataType.STRING); + } + + /** + * Determines if the given entity is an extension. + * + * @param entity the entity to check for an extension + * @return {@code true} if the entity has an extension, {@code false} otherwise + */ + public static boolean isExtension(Entity entity) { + return DataContainerUtil.hasKey(entity, EXTENDS, PersistentDataType.STRING); + } + + /** + * Checks if the given entity is extended. + * + * @param entity the entity to check + * @return true if the entity is extended, false otherwise + */ + public static boolean isExtended(Entity entity) { + return DataContainerUtil.hasKey(entity, EXTENDED, PersistentDataType.STRING); + } + + /** + * Marks an Entity as a custom mob by adding a unique identifier to its data. + * + * @param entity The Entity to mark as a custom mob. + */ + public static void markCustomMob(Entity entity) { + DataContainerUtil.putValue(entity, CUSTOM_MOB, PersistentDataType.STRING, entity.getUniqueId().toString()); + } + + /** + * Marks the given extension entity with the UUID of the base entity. + * + * @param extension The entity to mark as an extension. + * @param base The base entity that the extension is extending. + */ + public static void markExtension(Entity extension, Entity base) { + DataContainerUtil.putValue(extension, EXTENDS, PersistentDataType.STRING, base.getUniqueId().toString()); + } + + /** + * Marks the base entity with the extension entity. + * + * @param base The base entity to be marked. + * @param extension The extension entity to mark the base entity with. + */ + public static void markBase(Entity base, Entity extension) { + DataContainerUtil.putValue(base, EXTENDED, PersistentDataType.STRING, extension.getUniqueId().toString()); + } + + /** + * Marks an extended mob by establishing a connection between a base entity and an extension entity. + * + * @param base The base entity to be marked. + * @param extension The extension entity to be marked. + */ + public static void markExtendedMob(Entity base, Entity extension) { + markBase(base, extension); + markExtension(extension, base); + } + + /** + * Returns the extension of the given entity as an Optional UUID. + * + * @param entity The entity to retrieve the extension from + * @return An Optional instance containing the extension UUID if found, + * or an empty Optional if no extension is present + */ + public static Optional getExtension(Entity entity) { + return DataContainerUtil.get(entity, EXTENDED, PersistentDataType.STRING).map(UUID::fromString); + } + + /** + * Retrieves the base UUID for the given entity. + * + * @param entity the entity to retrieve the base UUID for + * @return an Optional containing the base UUID if it exists, otherwise an empty Optional */ - public static final NamespacedKey EXTENDED = new NamespacedKey("bloodnight", "extended"); + public static Optional getBase(Entity entity) { + return DataContainerUtil.get(entity, EXTENDS, PersistentDataType.STRING).map(UUID::fromString); + } } diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/meta/DataType.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/meta/DataType.java index db96ef6..d648761 100644 --- a/nodes/src/main/java/de/eldoria/bloodnight/nodes/meta/DataType.java +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/meta/DataType.java @@ -5,6 +5,7 @@ */ public enum DataType { ENTITY, + PROJECTILE(ENTITY), CANCELABLE_EVENT, INTEGER, NUMBER(INTEGER), diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/meta/Fields.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/meta/Fields.java index aa5a8e4..2b6e682 100644 --- a/nodes/src/main/java/de/eldoria/bloodnight/nodes/meta/Fields.java +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/meta/Fields.java @@ -32,6 +32,11 @@ public final class Fields { public static final String KILLED_ENTITY = "killed_entity"; public static final String DAMAGE_CAUSE = "damage_cause"; public static final String CANCELABLE_EVENT = "cancelable_event"; + public static final String PROJECTILE = "projectile"; + public static final String TARGET = "target"; + public static final String DAMAGE = "damage"; + public static final String FINAL_DAMAGE = "final_damage"; + private Fields() { throw new UnsupportedOperationException("This is a utility class."); } diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnTargetChangeNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnTargetChangeNode.java new file mode 100644 index 0000000..fc8af88 --- /dev/null +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnTargetChangeNode.java @@ -0,0 +1,43 @@ +package de.eldoria.bloodnight.nodes.trigger.impl.events; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import de.eldoria.bloodnight.nodes.annotations.Meta; +import de.eldoria.bloodnight.nodes.annotations.Output; +import de.eldoria.bloodnight.nodes.base.io.Edge; +import de.eldoria.bloodnight.nodes.base.io.EditorMeta; +import de.eldoria.bloodnight.nodes.base.io.OutputContainer; +import de.eldoria.bloodnight.nodes.meta.Categories; +import de.eldoria.bloodnight.nodes.meta.DataType; +import de.eldoria.bloodnight.nodes.meta.Fields; +import de.eldoria.bloodnight.nodes.trigger.base.CancelableEventTriggerNode; +import org.bukkit.event.entity.EntityTargetEvent; + +import java.util.Map; + +/** + * A trigger, that's called when an entity got killed by this mob. + */ +@Output(name = OnTargetChangeNode.Outputs.TARGET, type = DataType.ENTITY) +@Output(name = OnTargetChangeNode.Outputs.CANCELABLE_EVENT, type = DataType.CANCELABLE_EVENT) +@Meta(name = "On target change", description = "A trigger, that's called when an entity looses or gets a new target.", category = Categories.EVENT) +public class OnTargetChangeNode extends CancelableEventTriggerNode { + + @JsonCreator + public OnTargetChangeNode(@JsonProperty("input") Map input, @JsonProperty("meta") EditorMeta meta) { + super(input, meta); + } + + @Override + protected OutputContainer output(OutputContainer output) { + return super.output() + .set(Outputs.TARGET, event.getEntity()) + .set(Outputs.CANCELABLE_EVENT, event); + } + + public static class Outputs { + public static final String TARGET = Fields.TARGET; + public static final String CANCELABLE_EVENT = Fields.CANCELABLE_EVENT; + } +} + diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnTeleportNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnTeleportNode.java new file mode 100644 index 0000000..209a563 --- /dev/null +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnTeleportNode.java @@ -0,0 +1,44 @@ +package de.eldoria.bloodnight.nodes.trigger.impl.events; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import de.eldoria.bloodnight.nodes.annotations.Meta; +import de.eldoria.bloodnight.nodes.annotations.Output; +import de.eldoria.bloodnight.nodes.base.io.Edge; +import de.eldoria.bloodnight.nodes.base.io.EditorMeta; +import de.eldoria.bloodnight.nodes.base.io.OutputContainer; +import de.eldoria.bloodnight.nodes.meta.Categories; +import de.eldoria.bloodnight.nodes.meta.DataType; +import de.eldoria.bloodnight.nodes.meta.Fields; +import de.eldoria.bloodnight.nodes.trigger.base.CancelableEventTriggerNode; +import org.bukkit.event.entity.EntityTeleportEvent; + +import java.util.Map; + +/** + * A trigger, that's called when an entity ports to a new location + */ +@Output(name = OnTeleportNode.Outputs.FROM, type = DataType.LOCATION) +@Output(name = OnTeleportNode.Outputs.TO, type = DataType.LOCATION) +@Output(name = OnTeleportNode.Outputs.CANCELABLE_EVENT, type = DataType.CANCELABLE_EVENT) +@Meta(name = "On teleport", description = "A trigger, that's called when an entity ports to a new location", category = Categories.EVENT) +public class OnTeleportNode extends CancelableEventTriggerNode { + @JsonCreator + public OnTeleportNode(@JsonProperty("input") Map input, @JsonProperty("meta") EditorMeta meta) { + super(input, meta); + } + + @Override + protected OutputContainer output(OutputContainer output) { + return super.output() + .set(Outputs.FROM, event.getFrom()) + .set(Outputs.TO, event.getTo()); + } + + public static class Outputs { + public static final String FROM = Fields.FROM; + public static final String TO = Fields.TO; + public static final String CANCELABLE_EVENT = Fields.CANCELABLE_EVENT; + + } +} diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageByEntityNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageByEntityNode.java new file mode 100644 index 0000000..ef6812e --- /dev/null +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageByEntityNode.java @@ -0,0 +1,48 @@ +package de.eldoria.bloodnight.nodes.trigger.impl.events.damage; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import de.eldoria.bloodnight.nodes.annotations.Meta; +import de.eldoria.bloodnight.nodes.annotations.Output; +import de.eldoria.bloodnight.nodes.base.io.Edge; +import de.eldoria.bloodnight.nodes.base.io.EditorMeta; +import de.eldoria.bloodnight.nodes.base.io.OutputContainer; +import de.eldoria.bloodnight.nodes.meta.Categories; +import de.eldoria.bloodnight.nodes.meta.DataType; +import de.eldoria.bloodnight.nodes.meta.Fields; +import de.eldoria.bloodnight.nodes.trigger.base.CancelableEventTriggerNode; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import java.util.Map; + +/** + * A trigger, that's called when an entity got killed by this mob. + */ +@Output(name = OnDamageByEntityNode.Outputs.TARGET, type = DataType.PLAYER) +@Output(name = OnDamageByEntityNode.Outputs.DAMAGE, type = DataType.NUMBER) +@Output(name = OnDamageByEntityNode.Outputs.FINAL_DAMAGE, type = DataType.NUMBER) +@Output(name = OnDamageByEntityNode.Outputs.DAMAGE_CAUSE, type = DataType.DAMAGE_CAUSE) +@Meta(name = "On damage by entity", description = "A trigger, that's called when damaged was received from an entity.", category = Categories.EVENT) +public class OnDamageByEntityNode extends CancelableEventTriggerNode { + + @JsonCreator + public OnDamageByEntityNode(@JsonProperty("input") Map input, @JsonProperty("meta") EditorMeta meta) { + super(input, meta); + } + + @Override + protected OutputContainer output(OutputContainer output) { + return output.set(Outputs.TARGET, event.getEntity()) + .set(Outputs.DAMAGE, event.getDamage()) + .set(Outputs.FINAL_DAMAGE, event.getFinalDamage()) + .set(Outputs.DAMAGE_CAUSE, event.getCause()); + } + + public static class Outputs { + public static final String TARGET = Fields.TARGET; + public static final String DAMAGE = Fields.DAMAGE; + public static final String FINAL_DAMAGE = Fields.FINAL_DAMAGE; + public static final String DAMAGE_CAUSE = Fields.DAMAGE_CAUSE; + } +} + diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageByPlayerNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageByPlayerNode.java new file mode 100644 index 0000000..106ff6e --- /dev/null +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageByPlayerNode.java @@ -0,0 +1,48 @@ +package de.eldoria.bloodnight.nodes.trigger.impl.events.damage; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import de.eldoria.bloodnight.nodes.annotations.Meta; +import de.eldoria.bloodnight.nodes.annotations.Output; +import de.eldoria.bloodnight.nodes.base.io.Edge; +import de.eldoria.bloodnight.nodes.base.io.EditorMeta; +import de.eldoria.bloodnight.nodes.base.io.OutputContainer; +import de.eldoria.bloodnight.nodes.meta.Categories; +import de.eldoria.bloodnight.nodes.meta.DataType; +import de.eldoria.bloodnight.nodes.meta.Fields; +import de.eldoria.bloodnight.nodes.trigger.base.CancelableEventTriggerNode; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import java.util.Map; + +/** + * A trigger, that's called when a player got killed by this mob. + */ +@Output(name = OnDamageByPlayerNode.Outputs.TARGET, type = DataType.PLAYER) +@Output(name = OnDamageByPlayerNode.Outputs.DAMAGE, type = DataType.NUMBER) +@Output(name = OnDamageByPlayerNode.Outputs.FINAL_DAMAGE, type = DataType.NUMBER) +@Output(name = OnDamageByPlayerNode.Outputs.DAMAGE_CAUSE, type = DataType.DAMAGE_CAUSE) +@Meta(name = "On damage by player", description = "A trigger, that's called when damaged was received from a player.", category = Categories.EVENT) +public class OnDamageByPlayerNode extends CancelableEventTriggerNode { + + @JsonCreator + public OnDamageByPlayerNode(@JsonProperty("input") Map input, @JsonProperty("meta") EditorMeta meta) { + super(input, meta); + } + + @Override + protected OutputContainer output(OutputContainer output) { + return super.output().set(Outputs.TARGET, event.getEntity()) + .set(Outputs.DAMAGE, event.getDamage()) + .set(Outputs.FINAL_DAMAGE, event.getFinalDamage()) + .set(Outputs.DAMAGE_CAUSE, event.getCause()); + } + + public static class Outputs { + public static final String TARGET = Fields.TARGET; + public static final String DAMAGE = Fields.DAMAGE; + public static final String FINAL_DAMAGE = Fields.FINAL_DAMAGE; + public static final String DAMAGE_CAUSE = Fields.DAMAGE_CAUSE; + } +} + diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageNode.java new file mode 100644 index 0000000..2938c97 --- /dev/null +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDamageNode.java @@ -0,0 +1,50 @@ +package de.eldoria.bloodnight.nodes.trigger.impl.events.damage; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import de.eldoria.bloodnight.nodes.annotations.Meta; +import de.eldoria.bloodnight.nodes.annotations.Output; +import de.eldoria.bloodnight.nodes.base.io.Edge; +import de.eldoria.bloodnight.nodes.base.io.EditorMeta; +import de.eldoria.bloodnight.nodes.base.io.OutputContainer; +import de.eldoria.bloodnight.nodes.meta.Categories; +import de.eldoria.bloodnight.nodes.meta.DataType; +import de.eldoria.bloodnight.nodes.meta.Fields; +import de.eldoria.bloodnight.nodes.trigger.base.CancelableEventTriggerNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.kill.OnEntityKillNode; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; + +import java.util.Map; + +/** + * A trigger, that's called when an entity (including players) got killed by this mob. + */ +@Output(name = OnDamageNode.Outputs.TARGET, type = DataType.PLAYER) +@Output(name = OnDamageNode.Outputs.DAMAGE, type = DataType.NUMBER) +@Output(name = OnDamageNode.Outputs.FINAL_DAMAGE, type = DataType.NUMBER) +@Output(name = OnDamageNode.Outputs.DAMAGE_CAUSE, type = DataType.DAMAGE_CAUSE) +@Meta(name = "On damage", description = "A trigger, that's called when damaged was received.", category = Categories.EVENT) +public class OnDamageNode extends CancelableEventTriggerNode { + + @JsonCreator + public OnDamageNode(@JsonProperty("input") Map input, @JsonProperty("meta") EditorMeta meta) { + super(input, meta); + } + + @Override + protected OutputContainer output(OutputContainer output) { + return output.set(Outputs.TARGET, event.getEntity()) + .set(Outputs.DAMAGE, event.getDamage()) + .set(Outputs.FINAL_DAMAGE, event.getFinalDamage()) + .set(Outputs.DAMAGE_CAUSE, event.getCause()); + } + + public static class Outputs { + public static final String TARGET = Fields.TARGET; + public static final String DAMAGE = Fields.DAMAGE; + public static final String FINAL_DAMAGE = Fields.FINAL_DAMAGE; + public static final String DAMAGE_CAUSE = Fields.DAMAGE_CAUSE; + } +} + diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnDeathNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDeathNode.java similarity index 87% rename from nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnDeathNode.java rename to nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDeathNode.java index f291d0e..87fb02f 100644 --- a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnDeathNode.java +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnDeathNode.java @@ -1,4 +1,4 @@ -package de.eldoria.bloodnight.nodes.trigger.impl.events; +package de.eldoria.bloodnight.nodes.trigger.impl.events.damage; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -15,9 +15,12 @@ import java.util.Map; +/** + * A trigger, that's called when an entity dies. + */ @Output(name = OnDeathNode.Outputs.KILLER, type = DataType.PLAYER) @Output(name = OnDeathNode.Outputs.DAMAGE_CAUSE, type = DataType.DAMAGE_CAUSE) -@Meta(name = "On entity death", description = "A trigger, that's called when an entity dies.", category = Categories.EVENT) +@Meta(name = "On death", description = "A trigger, that's called when the mob dies.", category = Categories.EVENT) public class OnDeathNode extends TriggerNode { private EntityDeathEvent event; diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnHitNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnHitNode.java new file mode 100644 index 0000000..3bf6d72 --- /dev/null +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/damage/OnHitNode.java @@ -0,0 +1,47 @@ +package de.eldoria.bloodnight.nodes.trigger.impl.events.damage; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import de.eldoria.bloodnight.nodes.annotations.Meta; +import de.eldoria.bloodnight.nodes.annotations.Output; +import de.eldoria.bloodnight.nodes.base.io.Edge; +import de.eldoria.bloodnight.nodes.base.io.EditorMeta; +import de.eldoria.bloodnight.nodes.base.io.OutputContainer; +import de.eldoria.bloodnight.nodes.meta.Categories; +import de.eldoria.bloodnight.nodes.meta.DataType; +import de.eldoria.bloodnight.nodes.meta.Fields; +import de.eldoria.bloodnight.nodes.trigger.base.CancelableEventTriggerNode; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import java.util.Map; + +/** + * A trigger, that's called when an entity dies. + */ +@Output(name = OnHitNode.Outputs.TARGET, type = DataType.PLAYER) +@Output(name = OnHitNode.Outputs.DAMAGE, type = DataType.NUMBER) +@Output(name = OnHitNode.Outputs.FINAL_DAMAGE, type = DataType.NUMBER) +@Output(name = OnHitNode.Outputs.DAMAGE_CAUSE, type = DataType.DAMAGE_CAUSE) +@Meta(name = "On hit", description = "A trigger, that's called when another entity gets hit.", category = Categories.EVENT) +public class OnHitNode extends CancelableEventTriggerNode { + + @JsonCreator + public OnHitNode(@JsonProperty("input") Map input, @JsonProperty("meta") EditorMeta meta) { + super(input, meta); + } + + @Override + protected OutputContainer output(OutputContainer output) { + return output.set(Outputs.TARGET, event.getEntity()) + .set(Outputs.DAMAGE, event.getDamage()) + .set(Outputs.FINAL_DAMAGE, event.getFinalDamage()) + .set(Outputs.DAMAGE_CAUSE, event.getCause()); + } + + public static class Outputs { + public static final String TARGET = Fields.TARGET; + public static final String DAMAGE = Fields.DAMAGE; + public static final String FINAL_DAMAGE = Fields.FINAL_DAMAGE; + public static final String DAMAGE_CAUSE = Fields.DAMAGE_CAUSE; + } +} diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/explosion/OnExplosionNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/explosion/OnExplosionNode.java new file mode 100644 index 0000000..f4c1df6 --- /dev/null +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/explosion/OnExplosionNode.java @@ -0,0 +1,39 @@ +package de.eldoria.bloodnight.nodes.trigger.impl.events.explosion; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import de.eldoria.bloodnight.nodes.annotations.Meta; +import de.eldoria.bloodnight.nodes.annotations.Output; +import de.eldoria.bloodnight.nodes.base.io.Edge; +import de.eldoria.bloodnight.nodes.base.io.EditorMeta; +import de.eldoria.bloodnight.nodes.base.io.OutputContainer; +import de.eldoria.bloodnight.nodes.meta.Categories; +import de.eldoria.bloodnight.nodes.meta.DataType; +import de.eldoria.bloodnight.nodes.meta.Fields; +import de.eldoria.bloodnight.nodes.trigger.base.CancelableEventTriggerNode; +import org.bukkit.event.entity.EntityExplodeEvent; + +import java.util.Map; + +/** + * A trigger, that's called when an entity is exploding. + */ +@Output(name = OnExplosionNode.Outputs.CANCELABLE_EVENT, type = DataType.CANCELABLE_EVENT) +@Meta(name = "On explosion", description = "A trigger, that's called when an entity is exploding.", category = Categories.EVENT) +public class OnExplosionNode extends CancelableEventTriggerNode { + + @JsonCreator + public OnExplosionNode(@JsonProperty("input") Map input, @JsonProperty("meta") EditorMeta meta) { + super(input, meta); + } + + @Override + protected OutputContainer output(OutputContainer output) { + return super.output() + .set(Outputs.CANCELABLE_EVENT, event); + } + + public static class Outputs { + public static final String CANCELABLE_EVENT = Fields.CANCELABLE_EVENT; + } +} diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnExplosionPrimeNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/explosion/OnExplosionPrimeNode.java similarity index 83% rename from nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnExplosionPrimeNode.java rename to nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/explosion/OnExplosionPrimeNode.java index dc10f1c..627f3ee 100644 --- a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnExplosionPrimeNode.java +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/explosion/OnExplosionPrimeNode.java @@ -1,4 +1,4 @@ -package de.eldoria.bloodnight.nodes.trigger.impl.events; +package de.eldoria.bloodnight.nodes.trigger.impl.events.explosion; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -15,7 +15,9 @@ import java.util.Map; -@Output(name = OnExplosionPrimeNode.Outputs.KILLED_ENTITY, type = DataType.ENTITY) +/** + * A trigger, that's called when an entity decided to explode. + */ @Output(name = OnExplosionPrimeNode.Outputs.CANCELABLE_EVENT, type = DataType.CANCELABLE_EVENT) @Meta(name = "On explosion prime", description = "A trigger, that's called when an entity decided to explode.", category = Categories.EVENT) public class OnExplosionPrimeNode extends CancelableEventTriggerNode { @@ -28,11 +30,10 @@ public OnExplosionPrimeNode(@JsonProperty("input") Map input, @Jso @Override protected OutputContainer output(OutputContainer output) { return super.output() - .set(Outputs.KILLED_ENTITY, event.getEntity()); + .set(Outputs.CANCELABLE_EVENT, event); } public static class Outputs { - public static final String KILLED_ENTITY = Fields.KILLED_ENTITY; public static final String CANCELABLE_EVENT = Fields.CANCELABLE_EVENT; } } diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnEntityKillNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/kill/OnEntityKillNode.java similarity index 85% rename from nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnEntityKillNode.java rename to nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/kill/OnEntityKillNode.java index 6ca08bb..184f611 100644 --- a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnEntityKillNode.java +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/kill/OnEntityKillNode.java @@ -1,4 +1,4 @@ -package de.eldoria.bloodnight.nodes.trigger.impl.events; +package de.eldoria.bloodnight.nodes.trigger.impl.events.kill; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -15,6 +15,9 @@ import java.util.Map; +/** + * A trigger, that's called when an entity got killed by this mob. + */ @Output(name = OnEntityKillNode.Outputs.KILLED_ENTITY, type = DataType.ENTITY) @Output(name = OnEntityKillNode.Outputs.CANCELABLE_EVENT, type = DataType.CANCELABLE_EVENT) @Meta(name = "On entity kill", description = "A trigger, that's called when an entity got killed by this mob.", category = Categories.EVENT) @@ -28,7 +31,8 @@ public OnEntityKillNode(@JsonProperty("input") Map input, @JsonPro @Override protected OutputContainer output(OutputContainer output) { return super.output() - .set(Outputs.KILLED_ENTITY, event.getEntity()); + .set(Outputs.KILLED_ENTITY, event.getEntity()) + .set(OnPlayerKillNode.Outputs.CANCELABLE_EVENT, event); } public static class Outputs { diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/kill/OnKillNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/kill/OnKillNode.java new file mode 100644 index 0000000..c91477d --- /dev/null +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/kill/OnKillNode.java @@ -0,0 +1,43 @@ +package de.eldoria.bloodnight.nodes.trigger.impl.events.kill; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import de.eldoria.bloodnight.nodes.annotations.Meta; +import de.eldoria.bloodnight.nodes.annotations.Output; +import de.eldoria.bloodnight.nodes.base.io.Edge; +import de.eldoria.bloodnight.nodes.base.io.EditorMeta; +import de.eldoria.bloodnight.nodes.base.io.OutputContainer; +import de.eldoria.bloodnight.nodes.meta.Categories; +import de.eldoria.bloodnight.nodes.meta.DataType; +import de.eldoria.bloodnight.nodes.meta.Fields; +import de.eldoria.bloodnight.nodes.trigger.base.CancelableEventTriggerNode; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +import java.util.Map; + +/** + * A trigger, that's called when an entity (including players) got killed by this mob. + */ +@Output(name = OnKillNode.Outputs.KILLED_ENTITY, type = DataType.ENTITY) +@Output(name = OnKillNode.Outputs.CANCELABLE_EVENT, type = DataType.CANCELABLE_EVENT) +@Meta(name = "On any kill", description = "A trigger, that's called when an entity (including players) got killed by this mob.", category = Categories.EVENT) +public class OnKillNode extends CancelableEventTriggerNode { + + @JsonCreator + public OnKillNode(@JsonProperty("input") Map input, @JsonProperty("meta") EditorMeta meta) { + super(input, meta); + } + + @Override + protected OutputContainer output(OutputContainer output) { + return super.output() + .set(Outputs.KILLED_ENTITY, event.getEntity()) + .set(OnPlayerKillNode.Outputs.CANCELABLE_EVENT, event); + } + + public static class Outputs { + public static final String KILLED_ENTITY = Fields.KILLED_ENTITY; + public static final String CANCELABLE_EVENT = Fields.CANCELABLE_EVENT; + } +} + diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnPlayerKillNode.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/kill/OnPlayerKillNode.java similarity index 82% rename from nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnPlayerKillNode.java rename to nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/kill/OnPlayerKillNode.java index 6c06832..93beb10 100644 --- a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/OnPlayerKillNode.java +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/kill/OnPlayerKillNode.java @@ -1,4 +1,4 @@ -package de.eldoria.bloodnight.nodes.trigger.impl.events; +package de.eldoria.bloodnight.nodes.trigger.impl.events.kill; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -15,9 +15,12 @@ import java.util.Map; +/** + * A trigger, that's called when a player got killed by this mob. + */ @Output(name = OnPlayerKillNode.Outputs.KILLED_ENTITY, type = DataType.PLAYER) @Output(name = OnPlayerKillNode.Outputs.CANCELABLE_EVENT, type = DataType.CANCELABLE_EVENT) -@Meta(name = "On entity kill", description = "A trigger, that's called when a player got killed by this mob.", category = Categories.EVENT) +@Meta(name = "On player kill", description = "A trigger, that's called when a player got killed by this mob.", category = Categories.EVENT) public class OnPlayerKillNode extends CancelableEventTriggerNode { @JsonCreator @@ -28,7 +31,8 @@ public OnPlayerKillNode(@JsonProperty("input") Map input, @JsonPro @Override protected OutputContainer output(OutputContainer output) { return super.output() - .set(Outputs.KILLED_ENTITY, event.getEntity()); + .set(Outputs.KILLED_ENTITY, event.getEntity()) + .set(Outputs.CANCELABLE_EVENT, event); } public static class Outputs { diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/projectile/OnProjectileHit.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/projectile/OnProjectileHit.java new file mode 100644 index 0000000..6f083d7 --- /dev/null +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/projectile/OnProjectileHit.java @@ -0,0 +1,39 @@ +package de.eldoria.bloodnight.nodes.trigger.impl.events.projectile; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import de.eldoria.bloodnight.nodes.annotations.Meta; +import de.eldoria.bloodnight.nodes.annotations.Output; +import de.eldoria.bloodnight.nodes.base.io.Edge; +import de.eldoria.bloodnight.nodes.base.io.EditorMeta; +import de.eldoria.bloodnight.nodes.base.io.OutputContainer; +import de.eldoria.bloodnight.nodes.meta.Categories; +import de.eldoria.bloodnight.nodes.meta.DataType; +import de.eldoria.bloodnight.nodes.meta.Fields; +import de.eldoria.bloodnight.nodes.trigger.base.CancelableEventTriggerNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.OnTeleportNode; +import org.bukkit.event.entity.ProjectileHitEvent; + +import java.util.Map; + +@Output(name = OnProjectileHit.Outputs.PROJECTILE, type = DataType.PROJECTILE) +@Output(name = OnTeleportNode.Outputs.CANCELABLE_EVENT, type = DataType.CANCELABLE_EVENT) +@Meta(name = "On teleport", description = "A trigger, that's called when an projectile hits another entity", category = Categories.EVENT) +public class OnProjectileHit extends CancelableEventTriggerNode { + @JsonCreator + public OnProjectileHit(@JsonProperty("input") Map input, @JsonProperty("meta") EditorMeta meta) { + super(input, meta); + } + + @Override + protected OutputContainer output(OutputContainer output) { + return super.output(output) + .set(Outputs.PROJECTILE, event.getEntity()) + .set(Outputs.CANCELABLE_EVENT, event); + } + + public static class Outputs { + public static final String PROJECTILE = Fields.PROJECTILE; + public static final String CANCELABLE_EVENT = Fields.CANCELABLE_EVENT; + } +} diff --git a/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/projectile/OnProjectileShoot.java b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/projectile/OnProjectileShoot.java new file mode 100644 index 0000000..5203dbd --- /dev/null +++ b/nodes/src/main/java/de/eldoria/bloodnight/nodes/trigger/impl/events/projectile/OnProjectileShoot.java @@ -0,0 +1,41 @@ +package de.eldoria.bloodnight.nodes.trigger.impl.events.projectile; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import de.eldoria.bloodnight.nodes.annotations.Meta; +import de.eldoria.bloodnight.nodes.annotations.Output; +import de.eldoria.bloodnight.nodes.base.io.Edge; +import de.eldoria.bloodnight.nodes.base.io.EditorMeta; +import de.eldoria.bloodnight.nodes.base.io.OutputContainer; +import de.eldoria.bloodnight.nodes.meta.Categories; +import de.eldoria.bloodnight.nodes.meta.DataType; +import de.eldoria.bloodnight.nodes.meta.Fields; +import de.eldoria.bloodnight.nodes.trigger.base.CancelableEventTriggerNode; +import de.eldoria.bloodnight.nodes.trigger.impl.events.OnTeleportNode; +import org.bukkit.event.entity.ProjectileLaunchEvent; + +import java.util.Map; + +/** + * A trigger, that's called when an shoots a projectile + */ +@Output(name = OnProjectileShoot.Outputs.PROJECTILE, type = DataType.PROJECTILE) +@Meta(name = "On projectile shoot", description = "A trigger, that's called when an shoots a projectile", category = Categories.EVENT) +@Output(name = OnTeleportNode.Outputs.CANCELABLE_EVENT, type = DataType.CANCELABLE_EVENT) +public class OnProjectileShoot extends CancelableEventTriggerNode { + @JsonCreator + public OnProjectileShoot(@JsonProperty("input") Map input, @JsonProperty("meta") EditorMeta meta) { + super(input, meta); + } + + @Override + protected OutputContainer output(OutputContainer output) { + return super.output(output) + .set(Outputs.PROJECTILE, event.getEntity()); + } + + public static class Outputs { + public static final String PROJECTILE = Fields.PROJECTILE; + public static final String CANCELABLE_EVENT = Fields.CANCELABLE_EVENT; + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 5a82454..6030477 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,6 +16,7 @@ dependencyResolutionManagement { version("eldoutil", "2.0.1") library("eldoutil-items","de.eldoria.util", "items").versionRef("eldoutil") + library("eldoutil-items","de.eldoria.util", "entities").versionRef("eldoutil") library("eldoutil-jackson","de.eldoria.util", "jackson-configuration").versionRef("eldoutil") bundle("eldoria-utilities", listOf("eldoutil-items", "eldoutil-jackson"))