develop-bloodmoon #10

Merged
MineTec merged 17 commits from develop-bloodmoon into master 2025-11-23 14:03:07 +00:00
6 changed files with 197 additions and 21 deletions
Showing only changes of commit 9433495a52 - Show all commits

View File

@@ -1,54 +1,136 @@
package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon; package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon;
import eu.mhsl.craftattack.spawn.core.appliance.Appliance; 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.BloodmoonMonsterDeathListener; import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener.BloodmoonMonsterDeathListener;
import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener.BloodmoonPlayerJoinListener;
import org.bukkit.Bukkit;
import org.bukkit.Material; 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.EntityType; import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Map;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
public class Bloodmoon extends Appliance { public class Bloodmoon extends Appliance {
// für alle Dimensionen? einstellbar machen? // für alle Dimensionen? einstellbar machen?
public final Set<EntityType> affectedMobs = Set.of( public final Map<EntityType, PotionEffect[]> affectedMobEffectMap = Map.of(
EntityType.ZOMBIE, EntityType.ZOMBIE, new PotionEffect[]{
EntityType.SKELETON, new PotionEffect(PotionEffectType.WITHER, 7 * 20, 1)
EntityType.SPIDER, },
EntityType.CREEPER, EntityType.SKELETON, new PotionEffect[]{
EntityType.HUSK, new PotionEffect(PotionEffectType.SLOWNESS, (int) (3.5 * 20), 1)
EntityType.DROWNED, },
Pupsi marked this conversation as resolved Outdated

?

?
EntityType.WITCH, EntityType.SPIDER, new PotionEffect[]{
EntityType.ZOMBIE_VILLAGER, new PotionEffect(PotionEffectType.POISON, 4 * 20, 1),
EntityType.PHANTOM, new PotionEffect(PotionEffectType.NAUSEA, 6 * 20, 10)
EntityType.ENDERMAN },
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)
Pupsi marked this conversation as resolved Outdated

stray?

stray?
},
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)
MineTec marked this conversation as resolved Outdated

wenn keine Effekte, wozu der Eintrag?

wenn keine Effekte, wozu der Eintrag?
Outdated
Review

Damit Hexen trotzdem mehr Schaden machen und mehr Leben haben.

Damit Hexen trotzdem mehr Schaden machen und mehr Leben haben.
}
); );
public final int expMultiplier = 4; public final int expMultiplier = 4;
public final boolean summonLightning = true; public final boolean lightningsActive = true;
private boolean isActive = false;
private final BossBar bossBar = Bukkit.createBossBar(
"Bloodmoon",
BarColor.RED,
BarStyle.SEGMENTED_12,
BarFlag.CREATE_FOG,
BarFlag.DARKEN_SKY
);
private final int bloodMoonLegth = 12000;
private final int daysBetweenBloodmoons = 1;
private final int minBonusDrops = 1; private final int minBonusDrops = 1;
private final int maxBonusDrops = 4; private final int maxBonusDrops = 4;
private final Map<ItemStack, Integer> bonusDropWeightMap = Map.of(
new ItemStack(Material.IRON_INGOT, 5), 10,
new ItemStack(Material.GOLD_INGOT, 2), 5,
new ItemStack(Material.DIAMOND, 1), 1,
new ItemStack(Material.IRON_BLOCK, 1), 5,
new ItemStack(Material.GOLD_BLOCK, 1), 2
);
public boolean bloodmoonIsActive() { public boolean bloodmoonIsActive() {
return true; return this.isActive;
} }
public Set<ItemStack> getRandomBonusDrops() { public void startBloodmoon() {
this.isActive = true;
Bukkit.getOnlinePlayers().forEach(player -> this.bossBar.addPlayer(player));
}
Pupsi marked this conversation as resolved Outdated

WeakHashMap implementierung verwenden

WeakHashMap implementierung verwenden
public void stopBloodmoon() {
this.isActive = false;
this.bossBar.removeAll();
}
public void addPlayerToBossBar(Player p) {
this.bossBar.addPlayer(p);
}
public List<ItemStack> getRandomBonusDrops() {
int itemCount = ThreadLocalRandom.current().nextInt(this.minBonusDrops, this.maxBonusDrops + 1); int itemCount = ThreadLocalRandom.current().nextInt(this.minBonusDrops, this.maxBonusDrops + 1);
return Set.of( List<ItemStack> result = new ArrayList<>();
new ItemStack(Material.DIAMOND_BLOCK, 2), for(int i = 0; i < itemCount; i++) {
new ItemStack(Material.IRON_BARS, 3) result.add(this.getRandomBonusDrop());
); }
return result;
}
private ItemStack getRandomBonusDrop() {
int totalWeight = this.bonusDropWeightMap.values().stream().mapToInt(value -> value).sum();
int randomInt = ThreadLocalRandom.current().nextInt(0, totalWeight + 1);
int cumulativeWeight = 0;
for(Map.Entry<ItemStack, Integer> entry : this.bonusDropWeightMap.entrySet()) {
cumulativeWeight += entry.getValue();
if(randomInt <= cumulativeWeight) return entry.getKey();
}
return null;
} }
@Override @Override
protected @NotNull List<Listener> listeners() { protected @NotNull List<Listener> listeners() {
return List.of( return List.of(
new BloodmoonMonsterDeathListener() new BloodmoonMonsterDeathListener(),
new BloodmoonPlayerJoinListener()
);
}
@Override
protected @NotNull List<ApplianceCommand<?>> commands() {
return List.of(
new BloodmoonCommand()
); );
} }
} }

View File

@@ -0,0 +1,10 @@
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);
}
}

View File

@@ -0,0 +1,44 @@
package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.commands;
import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.Bloodmoon;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class BloodmoonCommand extends ApplianceCommand<Bloodmoon> {
public BloodmoonCommand() {
super("bloodmoon");
}
@Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception {
if(args.length == 0) {
sender.sendMessage("Bloodmoon is currently " + (this.getAppliance().bloodmoonIsActive() ? "active." : "inactive."));
return;
}
switch(args[0]) {
case "start": {
this.getAppliance().startBloodmoon();
sender.sendMessage("Started bloodmoon.");
break;
}
case "stop": {
this.getAppliance().stopBloodmoon();
sender.sendMessage("Stopped bloodmoon.");
break;
}
default: throw new Error("No such option: '" + args[0] + "' !");
}
}
@Override
public @Nullable List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(args.length == 1) return List.of("start", "stop");
return null;
}
}

View File

@@ -0,0 +1,25 @@
package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener;
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.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
public class BloodmoonEntityDamageListener extends ApplianceListener<Bloodmoon> {
@EventHandler
public void onEntityDamage(EntityDamageByEntityEvent event) {
if(!this.getAppliance().bloodmoonIsActive()) return;
Entity damagerEntity = event.getDamager();
if(damagerEntity instanceof Projectile projectile) {
if(!(projectile.getShooter() instanceof Entity shooter)) return;
damagerEntity = shooter;
}
if(!(damagerEntity instanceof LivingEntity damager && event.getEntity() instanceof LivingEntity receiver)) return;
if(event.getFinalDamage() == 0) return;
// TODO: damage increase / reduction and effects
}
}

View File

@@ -11,9 +11,10 @@ public class BloodmoonMonsterDeathListener extends ApplianceListener<Bloodmoon>
public void onMonsterDeath(EntityDeathEvent event) { public void onMonsterDeath(EntityDeathEvent event) {
if(!this.getAppliance().bloodmoonIsActive()) return; if(!this.getAppliance().bloodmoonIsActive()) return;
LivingEntity entity = event.getEntity(); LivingEntity entity = event.getEntity();
if(!this.getAppliance().affectedMobs.contains(entity.getType())) return; if(!this.getAppliance().affectedMobEffectMap.containsKey(entity.getType())) return;
event.setDroppedExp(event.getDroppedExp() * this.getAppliance().expMultiplier); event.setDroppedExp(event.getDroppedExp() * this.getAppliance().expMultiplier);
event.getDrops().addAll(this.getAppliance().getRandomBonusDrops()); event.getDrops().addAll(this.getAppliance().getRandomBonusDrops());
if(this.getAppliance().lightningsActive) event.getEntity().getWorld().strikeLightningEffect(event.getEntity().getLocation());
} }
} }

View File

@@ -0,0 +1,14 @@
package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener;
import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.Bloodmoon;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
public class BloodmoonPlayerJoinListener extends ApplianceListener<Bloodmoon> {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
if(!this.getAppliance().bloodmoonIsActive()) return;
this.getAppliance().addPlayerToBossBar(event.getPlayer());
}
}