added hordes, disabled setting when bloodmoon is active

This commit is contained in:
2025-10-19 18:45:55 +02:00
parent e14c87c2fb
commit d70b025502
3 changed files with 63 additions and 8 deletions

View File

@@ -1,6 +1,7 @@
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.Main;
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;
@@ -11,6 +12,7 @@ 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.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
@@ -20,10 +22,7 @@ import org.bukkit.inventory.ItemStack;
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.*;
import java.util.concurrent.ThreadLocalRandom;
public class Bloodmoon extends Appliance {
@@ -61,7 +60,6 @@ public class Bloodmoon extends Appliance {
)
);
public final int expMultiplier = 4;
public final boolean lightningsActive = true;
public final double mobDamageMultipier = 2;
public final double mobHealthMultiplier = 3;
@@ -73,6 +71,17 @@ public class Bloodmoon extends Appliance {
BossBar.Overlay.NOTCHED_12,
Set.of(BossBar.Flag.CREATE_WORLD_FOG, BossBar.Flag.DARKEN_SCREEN)
);
private final boolean hordesEnabled = true;
private final int hordeSpawnRateTicks = 800;
private final int hordeSpawnRateVariationTicks = 100;
private final int hordeMinPopulation = 3;
private final int hordeMaxPopulation = 10;
private final int hordeSpawnDistance = 10;
private final List<EntityType> hordeMobList = List.of(
EntityType.ZOMBIE,
EntityType.SKELETON,
EntityType.SPIDER
);
private final int bloodmoonLegth = 12000;
private final int bloodmoonStartTime = 12000;
private final int daysBetweenBloodmoons = 1;
@@ -98,6 +107,23 @@ public class Bloodmoon extends Appliance {
public void startBloodmoon() {
this.isActive = true;
Bukkit.getOnlinePlayers().forEach(this::addPlayerToBossBar);
this.startHordeSpawning(this.getRandomHordeSpawnDelay());
}
private int getRandomHordeSpawnDelay() {
return this.hordeSpawnRateTicks + ThreadLocalRandom.current().nextInt(-this.hordeSpawnRateVariationTicks, this.hordeSpawnRateVariationTicks);
}
private void startHordeSpawning(int delay) {
Bukkit.getScheduler().runTaskLater(
Main.instance(),
() -> {
if(!this.bloodmoonIsActive()) return;
this.spawnRandomHorde();
this.startHordeSpawning(this.getRandomHordeSpawnDelay());
},
delay
);
}
public void stopBloodmoon() {
@@ -131,6 +157,20 @@ public class Bloodmoon extends Appliance {
return result;
}
public void spawnRandomHorde() {
if(Bukkit.getOnlinePlayers().isEmpty()) return;
if(!this.hordesEnabled) return;
List<? extends Player> onlinePlayerList = Bukkit.getOnlinePlayers().stream()
.filter(this::getBloodmoonSetting)
.toList();
ThreadLocalRandom random = ThreadLocalRandom.current();
Player player = onlinePlayerList.get(random.nextInt(onlinePlayerList.size()));
EntityType hordeEntityType = this.hordeMobList.get(random.nextInt(this.hordeMobList.size()));
int hordeSize = random.nextInt(this.hordeMinPopulation, this.hordeMaxPopulation + 1);
this.spawnHorde(player, hordeSize, hordeEntityType);
Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(Component.text("Eine Horde ist bei %s gespawnt.".formatted(player.getName()), NamedTextColor.RED)));
}
private ItemStack getRandomBonusDrop() {
int totalWeight = this.bonusDropWeightMap.values().stream().mapToInt(value -> value).sum();
int randomInt = ThreadLocalRandom.current().nextInt(0, totalWeight + 1);
@@ -142,6 +182,20 @@ public class Bloodmoon extends Appliance {
return null;
}
private void spawnHorde(Player player, int size, EntityType type) {
for(int i = 0; i < size; i++) {
double spawnRadiant = ThreadLocalRandom.current().nextDouble(0, 2*Math.PI);
Location mobSpawnLocation = player.getLocation().clone().add(
Math.sin(spawnRadiant)*this.hordeSpawnDistance,
0,
Math.cos(spawnRadiant)*this.hordeSpawnDistance
);
mobSpawnLocation.setY(player.getWorld().getHighestBlockYAt(mobSpawnLocation) + 1);
player.getWorld().spawnEntity(mobSpawnLocation, type);
player.getWorld().strikeLightningEffect(mobSpawnLocation);
}
}
@Override
protected @NotNull List<Listener> listeners() {
return List.of(

View File

@@ -4,6 +4,7 @@ import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Categor
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 eu.mhsl.craftattack.spawn.core.Main;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
@@ -25,7 +26,7 @@ public class BloodmoonSetting extends BoolSetting implements CategorizedSetting
@Override
protected String description() {
return "Kämpfe während dem Blutmond mit stärkeren Monstern, um mit besseren Drops belohnt zu werden.";
return "Kämpfe während dem Blutmond mit stärkeren Monstern mit besseren Drops. Kann nicht während dem Blutmond geändert werden!";
}
@Override
@@ -38,9 +39,9 @@ public class BloodmoonSetting extends BoolSetting implements CategorizedSetting
return false;
}
// TODO: only change when bloodmoon is not active
@Override
protected void change(Player player, ClickType clickType) {
if(Main.instance().getAppliance(Bloodmoon.class).bloodmoonIsActive()) return;
super.change(player, clickType);
}
}

View File

@@ -18,6 +18,6 @@ public class BloodmoonMonsterDeathListener extends ApplianceListener<Bloodmoon>
event.setDroppedExp(event.getDroppedExp() * this.getAppliance().expMultiplier);
event.getDrops().addAll(this.getAppliance().getRandomBonusDrops());
if(this.getAppliance().lightningsActive) entity.getWorld().strikeLightningEffect(entity.getLocation());
entity.getWorld().strikeLightningEffect(entity.getLocation());
}
}