diff --git a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/Settings.java b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/Settings.java index aae45d2..dfec693 100644 --- a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/Settings.java +++ b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/Settings.java @@ -38,7 +38,8 @@ public class Settings extends Appliance { BorderWarning, LocatorBar, InfoBars, - CoordinateDisplay + CoordinateDisplay, + Bloodmoon } public static Settings instance() { diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/Bloodmoon.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/Bloodmoon.java index be62263..ea58d30 100644 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/Bloodmoon.java +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/Bloodmoon.java @@ -1,75 +1,80 @@ package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon; +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Settings; import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.commands.BloodmoonCommand; +import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener.BloodmoonEntityDamageListener; import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener.BloodmoonMonsterDeathListener; import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener.BloodmoonPlayerJoinListener; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; import org.bukkit.Material; -import org.bukkit.boss.BarColor; -import org.bukkit.boss.BarFlag; -import org.bukkit.boss.BarStyle; -import org.bukkit.boss.BossBar; +import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ThreadLocalRandom; public class Bloodmoon extends Appliance { // für alle Dimensionen? einstellbar machen? - public final Map affectedMobEffectMap = Map.of( - EntityType.ZOMBIE, new PotionEffect[]{ - new PotionEffect(PotionEffectType.WITHER, 7 * 20, 1) - }, - EntityType.SKELETON, new PotionEffect[]{ - new PotionEffect(PotionEffectType.SLOWNESS, (int) (3.5 * 20), 1) - }, - EntityType.SPIDER, new PotionEffect[]{ - new PotionEffect(PotionEffectType.POISON, 4 * 20, 1), - new PotionEffect(PotionEffectType.NAUSEA, 6 * 20, 10) - }, - EntityType.CREEPER, new PotionEffect[]{ - new LightningPotionEffect() - }, - EntityType.HUSK, new PotionEffect[]{ - new PotionEffect(PotionEffectType.WITHER, 7 * 20, 1) - }, - EntityType.DROWNED, new PotionEffect[]{ - new PotionEffect(PotionEffectType.WITHER, 7 * 20, 1) - }, - EntityType.WITCH, new PotionEffect[]{}, - EntityType.ZOMBIE_VILLAGER, new PotionEffect[]{ - new PotionEffect(PotionEffectType.WITHER, 7 * 20, 1) - }, - EntityType.PHANTOM, new PotionEffect[]{ - new PotionEffect(PotionEffectType.LEVITATION, (int) (1.5 * 20), 3) - }, - EntityType.ENDERMAN, new PotionEffect[]{ - new PotionEffect(PotionEffectType.SLOWNESS, (int) (2.5 * 20), 2) - } + public final Map> affectedMobEffectMap = Map.of( + EntityType.ZOMBIE, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.WITHER, 7, 1) + ), + EntityType.SKELETON, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.SLOWNESS, 3.5, 1) + ), + EntityType.SPIDER, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.POISON, 4, 1), + new MobEffect.PotionMobEffect(PotionEffectType.NAUSEA, 6, 10) + ), + EntityType.CREEPER, Set.of( + new MobEffect.LightningMobEffect() + ), + EntityType.HUSK, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.WITHER, 7, 1) + ), + EntityType.DROWNED, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.WITHER, 7, 1) + ), + EntityType.WITCH, Set.of(), + EntityType.ZOMBIE_VILLAGER, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.WITHER, 7, 1) + ), + EntityType.PHANTOM, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.LEVITATION, 1.5, 3) + ), + EntityType.ENDERMAN, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.SLOWNESS, 2.5, 2) + ) ); public final int expMultiplier = 4; public final boolean lightningsActive = true; + public final double mobDamageMultipier = 2; + public final double mobHealthMultiplier = 3; private boolean isActive = false; - private final BossBar bossBar = Bukkit.createBossBar( - "Bloodmoon", - BarColor.RED, - BarStyle.SEGMENTED_12, - BarFlag.CREATE_FOG, - BarFlag.DARKEN_SKY + private final BossBar bossBar = BossBar.bossBar( + Component.text("Blutmond", NamedTextColor.DARK_RED), + 1f, + BossBar.Color.RED, + BossBar.Overlay.NOTCHED_12, + Set.of(BossBar.Flag.CREATE_WORLD_FOG, BossBar.Flag.DARKEN_SCREEN) ); - private final int bloodMoonLegth = 12000; + private final int bloodmoonLegth = 12000; + private final int bloodmoonStartTime = 12000; private final int daysBetweenBloodmoons = 1; private final int minBonusDrops = 1; private final int maxBonusDrops = 4; @@ -81,22 +86,40 @@ public class Bloodmoon extends Appliance { new ItemStack(Material.GOLD_BLOCK, 1), 2 ); + @Override + public void onEnable() { + Settings.instance().declareSetting(BloodmoonSetting.class); + } + public boolean bloodmoonIsActive() { return this.isActive; } public void startBloodmoon() { this.isActive = true; - Bukkit.getOnlinePlayers().forEach(player -> this.bossBar.addPlayer(player)); + Bukkit.getOnlinePlayers().forEach(this::addPlayerToBossBar); } public void stopBloodmoon() { this.isActive = false; - this.bossBar.removeAll(); + Bukkit.getOnlinePlayers().forEach(player -> player.hideBossBar(this.bossBar)); } - public void addPlayerToBossBar(Player p) { - this.bossBar.addPlayer(p); + public void addPlayerToBossBar(Player player) { + if(!this.getBloodmoonSetting(player)) return; + player.showBossBar(this.bossBar); + } + + public boolean isAffectedMob(Entity entity) { + return this.affectedMobEffectMap.containsKey(entity.getType()); + } + + public boolean getBloodmoonSetting(Player player) { + return Settings.instance().getSetting( + player, + Settings.Key.Bloodmoon, + Boolean.class + ); } public List getRandomBonusDrops() { @@ -123,7 +146,8 @@ public class Bloodmoon extends Appliance { protected @NotNull List listeners() { return List.of( new BloodmoonMonsterDeathListener(), - new BloodmoonPlayerJoinListener() + new BloodmoonPlayerJoinListener(), + new BloodmoonEntityDamageListener() ); } diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/BloodmoonSetting.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/BloodmoonSetting.java new file mode 100644 index 0000000..d0b43aa --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/BloodmoonSetting.java @@ -0,0 +1,46 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon; + +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.CategorizedSetting; +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.SettingCategory; +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Settings; +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.datatypes.BoolSetting; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +public class BloodmoonSetting extends BoolSetting implements CategorizedSetting { + public BloodmoonSetting() { + super(Settings.Key.Bloodmoon); + } + + @Override + public SettingCategory category() { + return SettingCategory.Misc; + } + + @Override + protected String title() { + return "Blutmond"; + } + + @Override + protected String description() { + return "Kämpfe während dem Blutmond mit stärkeren Monstern, um mit besseren Drops belohnt zu werden."; + } + + @Override + protected Material icon() { + return Material.CLOCK; + } + + @Override + protected Boolean defaultValue() { + return false; + } + + // TODO: only change when bloodmoon is not active + @Override + protected void change(Player player, ClickType clickType) { + super.change(player, clickType); + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/LightningPotionEffect.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/LightningPotionEffect.java deleted file mode 100644 index 297f74c..0000000 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/LightningPotionEffect.java +++ /dev/null @@ -1,10 +0,0 @@ -package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon; - -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -public class LightningPotionEffect extends PotionEffect { - public LightningPotionEffect() { - super(PotionEffectType.SLOWNESS, 0, 0); - } -} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/MobEffect.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/MobEffect.java new file mode 100644 index 0000000..c84ce63 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/MobEffect.java @@ -0,0 +1,29 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon; + +import net.kyori.adventure.util.Ticks; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public abstract class MobEffect { + public abstract void apply(Player p); + + public static class PotionMobEffect extends MobEffect { + private final PotionEffect effect; + public PotionMobEffect(PotionEffectType type, double seconds, int amplifier) { + this.effect = new PotionEffect(type, (int) (seconds * Ticks.TICKS_PER_SECOND), amplifier); + } + + @Override + public void apply(Player p) { + p.addPotionEffect(this.effect); + } + } + + public static class LightningMobEffect extends MobEffect { + @Override + public void apply(Player p) { + p.getWorld().strikeLightning(p.getLocation()); + } + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonEntityDamageListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonEntityDamageListener.java index ac2c619..3923340 100644 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonEntityDamageListener.java +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonEntityDamageListener.java @@ -4,6 +4,7 @@ import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.Bloodmoon; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; import org.bukkit.entity.Projectile; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -20,6 +21,15 @@ public class BloodmoonEntityDamageListener extends ApplianceListener if(!(damagerEntity instanceof LivingEntity damager && event.getEntity() instanceof LivingEntity receiver)) return; if(event.getFinalDamage() == 0) return; - // TODO: damage increase / reduction and effects + if(this.getAppliance().isAffectedMob(damager) && receiver instanceof Player player) { + if(!this.getAppliance().getBloodmoonSetting(player)) return; + event.setDamage(event.getDamage() * this.getAppliance().mobDamageMultipier); + this.getAppliance().affectedMobEffectMap.get(damager.getType()).forEach(mobEffect -> mobEffect.apply(player)); + return; + } + if(this.getAppliance().isAffectedMob(receiver) && damager instanceof Player player) { + if(!this.getAppliance().getBloodmoonSetting(player)) return; + event.setDamage(event.getDamage() / this.getAppliance().mobHealthMultiplier); + } } } diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonMonsterDeathListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonMonsterDeathListener.java index 6ff70cd..e6dce3e 100644 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonMonsterDeathListener.java +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonMonsterDeathListener.java @@ -3,6 +3,7 @@ package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.list import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.Bloodmoon; import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDeathEvent; @@ -10,11 +11,13 @@ public class BloodmoonMonsterDeathListener extends ApplianceListener @EventHandler public void onMonsterDeath(EntityDeathEvent event) { if(!this.getAppliance().bloodmoonIsActive()) return; + if(!(event.getDamageSource().getCausingEntity() instanceof Player player)) return; + if(!this.getAppliance().getBloodmoonSetting(player)) return; LivingEntity entity = event.getEntity(); - if(!this.getAppliance().affectedMobEffectMap.containsKey(entity.getType())) return; + if(!this.getAppliance().isAffectedMob(entity)) return; event.setDroppedExp(event.getDroppedExp() * this.getAppliance().expMultiplier); event.getDrops().addAll(this.getAppliance().getRandomBonusDrops()); - if(this.getAppliance().lightningsActive) event.getEntity().getWorld().strikeLightningEffect(event.getEntity().getLocation()); + if(this.getAppliance().lightningsActive) entity.getWorld().strikeLightningEffect(entity.getLocation()); } }