initial commit
This commit is contained in:
		
							
								
								
									
										59
									
								
								src/main/java/eu/mhsl/minenet/minestom/pve/Lobby.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/main/java/eu/mhsl/minenet/minestom/pve/Lobby.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
package eu.mhsl.minenet.minestom.pve;
 | 
			
		||||
 | 
			
		||||
import net.kyori.adventure.sound.Sound;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.title.Title;
 | 
			
		||||
import net.minestom.server.MinecraftServer;
 | 
			
		||||
import net.minestom.server.entity.Entity;
 | 
			
		||||
import net.minestom.server.entity.Player;
 | 
			
		||||
import net.minestom.server.event.EventNode;
 | 
			
		||||
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
 | 
			
		||||
import net.minestom.server.event.item.ItemDropEvent;
 | 
			
		||||
import net.minestom.server.event.player.*;
 | 
			
		||||
import net.minestom.server.event.trait.InstanceEvent;
 | 
			
		||||
import net.minestom.server.instance.InstanceContainer;
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.util.FullbrightDimension;
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.util.PaneGenerator;
 | 
			
		||||
import net.minestom.server.instance.block.Block;
 | 
			
		||||
import net.minestom.server.sound.SoundEvent;
 | 
			
		||||
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
public final class Lobby extends InstanceContainer {
 | 
			
		||||
 | 
			
		||||
    public static final Lobby INSTANCE = new Lobby();
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        MinecraftServer.getInstanceManager().registerInstance(INSTANCE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Lobby() {
 | 
			
		||||
        super(UUID.randomUUID(), FullbrightDimension.INSTANCE);
 | 
			
		||||
        setGenerator(new PaneGenerator(Block.GOLD_BLOCK));
 | 
			
		||||
        setTimeRate(0);
 | 
			
		||||
        setTime(18000);
 | 
			
		||||
 | 
			
		||||
        EventNode<InstanceEvent> events = eventNode();
 | 
			
		||||
 | 
			
		||||
        events.addListener(AddEntityToInstanceEvent.class, addEntityToInstanceEvent -> {
 | 
			
		||||
            final Entity entity = addEntityToInstanceEvent.getEntity();
 | 
			
		||||
            if(!(entity instanceof Player p)) return;
 | 
			
		||||
 | 
			
		||||
            if(p.getInstance() != null) {
 | 
			
		||||
                p.scheduler().scheduleNextTick(() -> p.sendMessage("BACK TO LOBBY"));
 | 
			
		||||
            } else {
 | 
			
		||||
                p.scheduler().scheduleNextTick(() -> p.sendMessage("NEW TO LOBBY"));
 | 
			
		||||
                //p.playSound(Sound.sound(SoundEvent.MUSIC_END, Sound.Source.MASTER, 1f, 1f));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        events.addListener(ItemDropEvent.class, itemDropEvent -> {
 | 
			
		||||
            itemDropEvent.setCancelled(true);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        events.addListener(PlayerBlockBreakEvent.class, playerBlockBreakEvent -> {
 | 
			
		||||
            playerBlockBreakEvent.setCancelled(true);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										107
									
								
								src/main/java/eu/mhsl/minenet/minestom/pve/Main.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/main/java/eu/mhsl/minenet/minestom/pve/Main.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
package eu.mhsl.minenet.minestom.pve;
 | 
			
		||||
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.command.PlayCommand;
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.command.StopCommand;
 | 
			
		||||
import net.kyori.adventure.sound.Sound;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.format.NamedTextColor;
 | 
			
		||||
import net.minestom.server.MinecraftServer;
 | 
			
		||||
import net.minestom.server.adventure.audience.Audiences;
 | 
			
		||||
import net.minestom.server.command.CommandManager;
 | 
			
		||||
import net.minestom.server.coordinate.Pos;
 | 
			
		||||
import net.minestom.server.entity.GameMode;
 | 
			
		||||
import net.minestom.server.entity.Player;
 | 
			
		||||
import net.minestom.server.entity.PlayerSkin;
 | 
			
		||||
import net.minestom.server.event.GlobalEventHandler;
 | 
			
		||||
import net.minestom.server.event.player.PlayerChatEvent;
 | 
			
		||||
import net.minestom.server.event.player.PlayerLoginEvent;
 | 
			
		||||
import net.minestom.server.event.player.PlayerSpawnEvent;
 | 
			
		||||
import net.minestom.server.event.server.ServerTickMonitorEvent;
 | 
			
		||||
import net.minestom.server.extras.lan.OpenToLAN;
 | 
			
		||||
import net.minestom.server.instance.InstanceContainer;
 | 
			
		||||
import net.minestom.server.instance.InstanceManager;
 | 
			
		||||
import net.minestom.server.instance.block.Block;
 | 
			
		||||
import net.minestom.server.monitoring.TickMonitor;
 | 
			
		||||
import net.minestom.server.potion.Potion;
 | 
			
		||||
import net.minestom.server.potion.PotionEffect;
 | 
			
		||||
import net.minestom.server.sound.SoundEvent;
 | 
			
		||||
import net.minestom.server.timer.TaskSchedule;
 | 
			
		||||
import net.minestom.server.utils.MathUtils;
 | 
			
		||||
import net.minestom.server.world.Difficulty;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicReference;
 | 
			
		||||
 | 
			
		||||
public class Main {
 | 
			
		||||
    public static void main(String[] args) {
 | 
			
		||||
        MinecraftServer server = MinecraftServer.init();
 | 
			
		||||
        CommandManager commands = MinecraftServer.getCommandManager();
 | 
			
		||||
        InstanceManager instances = MinecraftServer.getInstanceManager();
 | 
			
		||||
        GlobalEventHandler events = MinecraftServer.getGlobalEventHandler();
 | 
			
		||||
 | 
			
		||||
        MinecraftServer.setBrandName("minenet");
 | 
			
		||||
        MinecraftServer.setCompressionThreshold(0);
 | 
			
		||||
        MinecraftServer.setTerminalEnabled(true);
 | 
			
		||||
        MinecraftServer.setDifficulty(Difficulty.NORMAL);
 | 
			
		||||
 | 
			
		||||
        events.addListener(PlayerLoginEvent.class, playerLoginEvent -> {
 | 
			
		||||
            final Player p = playerLoginEvent.getPlayer();
 | 
			
		||||
 | 
			
		||||
            playerLoginEvent.setSpawningInstance(Lobby.INSTANCE);
 | 
			
		||||
 | 
			
		||||
            if(!p.getName().toString().equals("MineTec")) p.setReducedDebugScreenInformation(true); //TODO remove condition
 | 
			
		||||
            p.setRespawnPoint(new Pos(0,5,0));
 | 
			
		||||
            p.setGameMode(GameMode.CREATIVE);
 | 
			
		||||
            p.setEnableRespawnScreen(false);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        events.addListener(PlayerChatEvent.class, chatEvent -> {
 | 
			
		||||
            chatEvent.setChatFormat((event) -> Component.text(event.getEntity().getUsername())
 | 
			
		||||
                    .append(Component.text(" | ", NamedTextColor.DARK_GRAY)
 | 
			
		||||
                            .append(Component.text(event.getMessage(), NamedTextColor.WHITE))));
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        events.addListener(PlayerSpawnEvent.class, playerSpawnEvent -> {
 | 
			
		||||
            playerSpawnEvent.getPlayer().addEffect(new Potion(PotionEffect.BLINDNESS, (byte) 1, 30));
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        commands.register(new PlayCommand());
 | 
			
		||||
        commands.register(new StopCommand());
 | 
			
		||||
 | 
			
		||||
        AtomicReference<TickMonitor> lastTick = new AtomicReference<>();
 | 
			
		||||
        events.addListener(ServerTickMonitorEvent.class, event -> {
 | 
			
		||||
            final TickMonitor monitor = event.getTickMonitor();
 | 
			
		||||
            lastTick.set(monitor);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        MinecraftServer.getSchedulerManager().scheduleTask(() -> {
 | 
			
		||||
            Collection<Player> players = MinecraftServer.getConnectionManager().getOnlinePlayers();
 | 
			
		||||
            if (players.isEmpty()) return;
 | 
			
		||||
 | 
			
		||||
            for(Player p : players) {
 | 
			
		||||
                p.refreshCommands(); //TODO this is a dumb idea
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            final Runtime runtime = Runtime.getRuntime();
 | 
			
		||||
            final TickMonitor tickMonitor = lastTick.get();
 | 
			
		||||
            final long ramUsage = (runtime.totalMemory() - runtime.freeMemory()) / 1024 / 1024;
 | 
			
		||||
 | 
			
		||||
            final Component header = Component.newline()
 | 
			
		||||
                    .append(Component.newline()).append(Component.text("Players: " + players.size()))
 | 
			
		||||
                    .append(Component.newline()).append(Component.newline())
 | 
			
		||||
                    .append(Component.text("RAM: " + ramUsage + " MB", NamedTextColor.GRAY).append(Component.newline())
 | 
			
		||||
                    .append(Component.text("TICK: " + MathUtils.round(tickMonitor.getTickTime(), 2) + "ms", NamedTextColor.GRAY))).append(Component.newline())
 | 
			
		||||
                    .append(Component.text("LOAD: " + MathUtils.round(tickMonitor.getTickTime()*2, 1) + "%", NamedTextColor.GRAY))
 | 
			
		||||
                    .append(Component.newline());
 | 
			
		||||
 | 
			
		||||
            final Component footer = Component.text("");
 | 
			
		||||
 | 
			
		||||
            Audiences.players().sendPlayerListHeaderAndFooter(header, footer);
 | 
			
		||||
 | 
			
		||||
        }, TaskSchedule.tick(20), TaskSchedule.tick(20));
 | 
			
		||||
 | 
			
		||||
        OpenToLAN.open();
 | 
			
		||||
        server.start("0.0.0.0", 25565);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										129
									
								
								src/main/java/eu/mhsl/minenet/minestom/pve/arena/Arena.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								src/main/java/eu/mhsl/minenet/minestom/pve/arena/Arena.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,129 @@
 | 
			
		||||
package eu.mhsl.minenet.minestom.pve.arena;
 | 
			
		||||
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.Lobby;
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.arena.mob.Zombie;
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.util.FullbrightDimension;
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.util.PaneGenerator;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.format.NamedTextColor;
 | 
			
		||||
import net.minestom.server.MinecraftServer;
 | 
			
		||||
import net.minestom.server.coordinate.Point;
 | 
			
		||||
import net.minestom.server.coordinate.Pos;
 | 
			
		||||
import net.minestom.server.coordinate.Vec;
 | 
			
		||||
import net.minestom.server.entity.*;
 | 
			
		||||
import net.minestom.server.entity.ai.EntityAIGroup;
 | 
			
		||||
import net.minestom.server.entity.ai.EntityAIGroupBuilder;
 | 
			
		||||
import net.minestom.server.entity.ai.goal.DoNothingGoal;
 | 
			
		||||
import net.minestom.server.entity.ai.goal.FollowTargetGoal;
 | 
			
		||||
import net.minestom.server.entity.ai.goal.RandomLookAroundGoal;
 | 
			
		||||
import net.minestom.server.entity.ai.goal.RandomStrollGoal;
 | 
			
		||||
import net.minestom.server.entity.ai.target.ClosestEntityTarget;
 | 
			
		||||
import net.minestom.server.entity.damage.DamageType;
 | 
			
		||||
import net.minestom.server.event.entity.EntityAttackEvent;
 | 
			
		||||
import net.minestom.server.event.entity.EntityDamageEvent;
 | 
			
		||||
import net.minestom.server.event.entity.EntityDeathEvent;
 | 
			
		||||
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
 | 
			
		||||
import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent;
 | 
			
		||||
import net.minestom.server.instance.InstanceContainer;
 | 
			
		||||
import net.minestom.server.instance.block.Block;
 | 
			
		||||
import net.minestom.server.item.ItemStack;
 | 
			
		||||
import net.minestom.server.item.Material;
 | 
			
		||||
import net.minestom.server.potion.Potion;
 | 
			
		||||
import net.minestom.server.potion.PotionEffect;
 | 
			
		||||
import net.minestom.server.sound.SoundEvent;
 | 
			
		||||
import net.minestom.server.timer.Task;
 | 
			
		||||
import net.minestom.server.timer.TaskSchedule;
 | 
			
		||||
import net.minestom.server.world.DimensionType;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.concurrent.CompletableFuture;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
import java.util.function.Predicate;
 | 
			
		||||
 | 
			
		||||
public class Arena extends InstanceContainer {
 | 
			
		||||
    private UUID arenaId;
 | 
			
		||||
    private Task spawner;
 | 
			
		||||
    private boolean isRunning = false;
 | 
			
		||||
    public Arena(UUID arenaId) {
 | 
			
		||||
        super(arenaId, FullbrightDimension.INSTANCE);
 | 
			
		||||
 | 
			
		||||
        this.arenaId = arenaId;
 | 
			
		||||
 | 
			
		||||
        MinecraftServer.getInstanceManager().registerInstance(this);
 | 
			
		||||
        ArenaManager.add(this);
 | 
			
		||||
 | 
			
		||||
        this.setGenerator(new PaneGenerator(Block.STONE));
 | 
			
		||||
 | 
			
		||||
        eventNode().addListener(AddEntityToInstanceEvent.class, addEntityToInstanceEvent -> {
 | 
			
		||||
            if(addEntityToInstanceEvent.getEntity() instanceof Player) start();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        eventNode().addListener(RemoveEntityFromInstanceEvent.class, removeEntityFromInstanceEvent -> {
 | 
			
		||||
           if(!(removeEntityFromInstanceEvent.getEntity() instanceof Player)) return;
 | 
			
		||||
           if(this.getPlayers().size() > 1) return;
 | 
			
		||||
 | 
			
		||||
           stop();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        eventNode().addListener(EntityAttackEvent.class, entityAttackEvent -> {
 | 
			
		||||
            //Player attacks Mob
 | 
			
		||||
            if(!(entityAttackEvent.getEntity() instanceof Player)) return;
 | 
			
		||||
            sendMessage(Component.text("EntityAttackEvent " + System.currentTimeMillis()));
 | 
			
		||||
 | 
			
		||||
            Player attacker = (Player) entityAttackEvent.getEntity();
 | 
			
		||||
            LivingEntity target = (LivingEntity) entityAttackEvent.getTarget();
 | 
			
		||||
 | 
			
		||||
            target.damage(DamageType.fromPlayer(attacker), 20);
 | 
			
		||||
 | 
			
		||||
            double knockbackX = Math.sin(attacker.getPosition().yaw() * (Math.PI / 180));
 | 
			
		||||
            double knockbackZ = -Math.cos(attacker.getPosition().yaw() * (Math.PI / 180));
 | 
			
		||||
 | 
			
		||||
            entityAttackEvent.getTarget().takeKnockback(
 | 
			
		||||
                    0.5f,
 | 
			
		||||
                    knockbackX,
 | 
			
		||||
                    knockbackZ
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            scheduler().scheduleNextTick(() -> {
 | 
			
		||||
                if(target.isDead()) {
 | 
			
		||||
                    target.takeKnockback(
 | 
			
		||||
                            1f,
 | 
			
		||||
                            knockbackX,
 | 
			
		||||
                            knockbackZ
 | 
			
		||||
                    );
 | 
			
		||||
                } else
 | 
			
		||||
                    target.setVelocity(new Vec(0, 10, 0));
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void stop() {
 | 
			
		||||
        this.spawner.cancel();
 | 
			
		||||
 | 
			
		||||
        if(this.getPlayers().size() > 1) {
 | 
			
		||||
            for(Player p : this.getPlayers()) {
 | 
			
		||||
                p.sendMessage(Component.text("instance stopped"));
 | 
			
		||||
                p.setInstance(Lobby.INSTANCE);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        MinecraftServer.getSchedulerManager().scheduleNextTick(() -> {
 | 
			
		||||
            MinecraftServer.getInstanceManager().unregisterInstance(this);
 | 
			
		||||
            System.out.println("Stopped arena " + arenaId);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void start() {
 | 
			
		||||
        if(isRunning) return;
 | 
			
		||||
        isRunning = true;
 | 
			
		||||
 | 
			
		||||
        this.spawner = scheduler().scheduleTask(() -> {
 | 
			
		||||
            if(this.getEntities().size() > 100) return;
 | 
			
		||||
            new Zombie().setInstance(this, new Pos(0, 5, 0));
 | 
			
		||||
        }, TaskSchedule.seconds(1), TaskSchedule.seconds(1));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,29 @@
 | 
			
		||||
package eu.mhsl.minenet.minestom.pve.arena;
 | 
			
		||||
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicReferenceArray;
 | 
			
		||||
 | 
			
		||||
public class ArenaManager {
 | 
			
		||||
    private static List<Arena> ARENAS = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
    public static void add(@NotNull Arena arena) {
 | 
			
		||||
        ARENAS.add(arena);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void remove(@NotNull Arena arena) {
 | 
			
		||||
        ARENAS.remove(arena);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static List<Arena> get() {
 | 
			
		||||
        return ARENAS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void stopAll() {
 | 
			
		||||
        for(Arena arena : ARENAS) {
 | 
			
		||||
            arena.stop();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										126
									
								
								src/main/java/eu/mhsl/minenet/minestom/pve/arena/ArenaMob.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								src/main/java/eu/mhsl/minenet/minestom/pve/arena/ArenaMob.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,126 @@
 | 
			
		||||
package eu.mhsl.minenet.minestom.pve.arena;
 | 
			
		||||
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.format.NamedTextColor;
 | 
			
		||||
import net.minestom.server.MinecraftServer;
 | 
			
		||||
import net.minestom.server.coordinate.Pos;
 | 
			
		||||
import net.minestom.server.entity.EntityCreature;
 | 
			
		||||
import net.minestom.server.entity.EntityType;
 | 
			
		||||
import net.minestom.server.entity.LivingEntity;
 | 
			
		||||
import net.minestom.server.entity.Player;
 | 
			
		||||
import net.minestom.server.entity.ai.EntityAIGroupBuilder;
 | 
			
		||||
import net.minestom.server.entity.ai.goal.MeleeAttackGoal;
 | 
			
		||||
import net.minestom.server.entity.ai.goal.RandomLookAroundGoal;
 | 
			
		||||
import net.minestom.server.entity.ai.goal.RandomStrollGoal;
 | 
			
		||||
import net.minestom.server.entity.ai.target.ClosestEntityTarget;
 | 
			
		||||
import net.minestom.server.entity.damage.DamageType;
 | 
			
		||||
import net.minestom.server.event.entity.EntityAttackEvent;
 | 
			
		||||
import net.minestom.server.event.entity.EntityDamageEvent;
 | 
			
		||||
import net.minestom.server.event.entity.EntityDeathEvent;
 | 
			
		||||
import net.minestom.server.event.entity.EntitySpawnEvent;
 | 
			
		||||
import net.minestom.server.item.ItemStack;
 | 
			
		||||
import net.minestom.server.item.Material;
 | 
			
		||||
import net.minestom.server.particle.Particle;
 | 
			
		||||
import net.minestom.server.particle.ParticleCreator;
 | 
			
		||||
import net.minestom.server.potion.Potion;
 | 
			
		||||
import net.minestom.server.potion.PotionEffect;
 | 
			
		||||
import net.minestom.server.sound.SoundEvent;
 | 
			
		||||
import net.minestom.server.timer.TaskSchedule;
 | 
			
		||||
import net.minestom.server.utils.time.TimeUnit;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public class ArenaMob extends EntityCreature {
 | 
			
		||||
    public ArenaMob(@NotNull EntityType entityType) {
 | 
			
		||||
        super(entityType);
 | 
			
		||||
 | 
			
		||||
        setCustomName(generateHealthBar(getMaxHealth(), getHealth()));
 | 
			
		||||
        setCustomNameVisible(true);
 | 
			
		||||
        setRemovalAnimationDelay(3500);
 | 
			
		||||
 | 
			
		||||
        addAIGroup(
 | 
			
		||||
                new EntityAIGroupBuilder()
 | 
			
		||||
                        .addGoalSelector(new MeleeAttackGoal(this, 1.2, 20, TimeUnit.SERVER_TICK))
 | 
			
		||||
                        .addTargetSelector(new ClosestEntityTarget(this, 32, Player.class))
 | 
			
		||||
                        .addGoalSelector(new RandomLookAroundGoal(this, 30))
 | 
			
		||||
                        .addGoalSelector(new RandomStrollGoal(this, 5))
 | 
			
		||||
                        .build()
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        eventNode().addListener(EntitySpawnEvent.class, entitySpawnEvent -> {
 | 
			
		||||
            Pos position = entitySpawnEvent.getEntity().getPosition();
 | 
			
		||||
            if(entitySpawnEvent.getEntity() == this) ParticleCreator.createParticlePacket(Particle.FIREWORK,
 | 
			
		||||
                    position.x(),
 | 
			
		||||
                    position.y(),
 | 
			
		||||
                    position.z(),
 | 
			
		||||
                    (float) position.sub(1).x(),
 | 
			
		||||
                    (float) position.sub(1).y(),
 | 
			
		||||
                    (float) position.sub(1).z(),
 | 
			
		||||
                    10);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        eventNode().addListener(EntityAttackEvent.class, entityAttackEvent -> {
 | 
			
		||||
            //Mob attacks Player
 | 
			
		||||
            if(entityAttackEvent.getEntity() instanceof Player) return;
 | 
			
		||||
 | 
			
		||||
            instance.sendMessage(Component.text("EntityAttackEvent " + System.currentTimeMillis()));
 | 
			
		||||
            entityAttackEvent.getTarget().takeKnockback(
 | 
			
		||||
                    0.2f,
 | 
			
		||||
                    Math.sin(entityAttackEvent.getEntity().getPosition().yaw() * (Math.PI / 180)),
 | 
			
		||||
                    -Math.cos(entityAttackEvent.getEntity().getPosition().yaw() * (Math.PI / 180))
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            ((LivingEntity) entityAttackEvent.getTarget()).damage(DamageType.fromEntity(entityAttackEvent.getEntity()), 1);
 | 
			
		||||
 | 
			
		||||
            ((EntityCreature) entityAttackEvent.getEntity()).swingMainHand();
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        eventNode().addListener(EntityDamageEvent.class, entityDamageEvent -> {
 | 
			
		||||
            instance.sendMessage(Component.text("EntityDamageEvent " + System.currentTimeMillis()));
 | 
			
		||||
 | 
			
		||||
            entityDamageEvent.setSound(SoundEvent.BLOCK_AMETHYST_BLOCK_STEP);
 | 
			
		||||
 | 
			
		||||
            setCustomName(generateHealthBar(getMaxHealth(), getHealth()));
 | 
			
		||||
            lookAt(new Pos(0,0,0));
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        eventNode().addListener(EntityDeathEvent.class, entityDeathEvent -> {
 | 
			
		||||
            instance.sendMessage(Component.text("EntityDeathEvent " + System.currentTimeMillis()));
 | 
			
		||||
 | 
			
		||||
            setCustomNameVisible(false);
 | 
			
		||||
            setCustomName(null);
 | 
			
		||||
 | 
			
		||||
            scheduler().scheduleTask(() -> {
 | 
			
		||||
                teleport(getPosition().sub(0, 0.1, 0));
 | 
			
		||||
            }, TaskSchedule.seconds(3), TaskSchedule.stop());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    private static final int BLOCK_LENGTH = 6;
 | 
			
		||||
 | 
			
		||||
    private static final List<String> CHARACTERS = List.of(
 | 
			
		||||
            "", "▏", "▎", "▍",
 | 
			
		||||
            "▌", "▋", "▊", "▉"
 | 
			
		||||
    );
 | 
			
		||||
    private static final String FULL_BLOCK_CHAR = "█";
 | 
			
		||||
    private static @NotNull Component generateHealthBar(float maxHealth, float currentHealth) {
 | 
			
		||||
        // Converts the health percentage into a number from 0-{blockLength} -- only 0 if the mob's health is 0
 | 
			
		||||
        final double charHealth = (currentHealth / maxHealth) * BLOCK_LENGTH;
 | 
			
		||||
        return Component.text()
 | 
			
		||||
                .append(Component.text(
 | 
			
		||||
                        FULL_BLOCK_CHAR.repeat((int) Math.floor(charHealth)),
 | 
			
		||||
                        NamedTextColor.DARK_RED
 | 
			
		||||
                )).append(Component.text(CHARACTERS.get((int) Math.round(
 | 
			
		||||
                        (charHealth - Math.floor(charHealth)) // number from 0-1
 | 
			
		||||
                                * (CHARACTERS.size() - 1) // indexes start at 0
 | 
			
		||||
                )), NamedTextColor.GOLD))
 | 
			
		||||
                .build();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,19 @@
 | 
			
		||||
package eu.mhsl.minenet.minestom.pve.arena.mob;
 | 
			
		||||
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.arena.ArenaMob;
 | 
			
		||||
import net.minestom.server.entity.EntityCreature;
 | 
			
		||||
import net.minestom.server.entity.EntityType;
 | 
			
		||||
import net.minestom.server.entity.Player;
 | 
			
		||||
import net.minestom.server.item.ItemStack;
 | 
			
		||||
import net.minestom.server.item.Material;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
public class Zombie extends ArenaMob {
 | 
			
		||||
    public Zombie() {
 | 
			
		||||
        super(EntityType.ZOMBIE);
 | 
			
		||||
 | 
			
		||||
        setItemInHand(Player.Hand.MAIN, ItemStack.builder(Material.TNT).build());
 | 
			
		||||
        setItemInHand(Player.Hand.OFF, ItemStack.builder(Material.FLINT_AND_STEEL).build());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,31 @@
 | 
			
		||||
package eu.mhsl.minenet.minestom.pve.command;
 | 
			
		||||
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.arena.Arena;
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.arena.ArenaManager;
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.util.CommandConditions;
 | 
			
		||||
import kotlin.reflect.jvm.internal.impl.metadata.ProtoBuf;
 | 
			
		||||
import kotlin.reflect.jvm.internal.impl.protobuf.MessageLite;
 | 
			
		||||
import net.minestom.server.MinecraftServer;
 | 
			
		||||
import net.minestom.server.command.builder.Command;
 | 
			
		||||
import net.minestom.server.command.builder.condition.CommandCondition;
 | 
			
		||||
import net.minestom.server.entity.Player;
 | 
			
		||||
import net.minestom.server.potion.Potion;
 | 
			
		||||
import net.minestom.server.potion.PotionEffect;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
 | 
			
		||||
public class PlayCommand extends Command {
 | 
			
		||||
    public PlayCommand() {
 | 
			
		||||
        super("start");
 | 
			
		||||
        setCondition(CommandConditions::lobbyOnly);
 | 
			
		||||
 | 
			
		||||
        setDefaultExecutor((sender, context) -> {
 | 
			
		||||
 | 
			
		||||
            if(sender instanceof Player p) {
 | 
			
		||||
                Arena arena = new Arena(p.getUuid());
 | 
			
		||||
                p.setInstance(arena);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,22 @@
 | 
			
		||||
package eu.mhsl.minenet.minestom.pve.command;
 | 
			
		||||
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.Lobby;
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.arena.ArenaManager;
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.util.CommandConditions;
 | 
			
		||||
import net.minestom.server.MinecraftServer;
 | 
			
		||||
import net.minestom.server.command.builder.Command;
 | 
			
		||||
import net.minestom.server.entity.Player;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
public class StopCommand extends Command {
 | 
			
		||||
    public StopCommand() {
 | 
			
		||||
        super("stop");
 | 
			
		||||
        setCondition(CommandConditions::arenaOnly);
 | 
			
		||||
 | 
			
		||||
        setDefaultExecutor(((sender, context) -> {
 | 
			
		||||
            final Player p = (Player) sender;
 | 
			
		||||
            p.setInstance(Lobby.INSTANCE);
 | 
			
		||||
            p.setHealth(p.getMaxHealth());
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,21 @@
 | 
			
		||||
package eu.mhsl.minenet.minestom.pve.util;
 | 
			
		||||
 | 
			
		||||
import eu.mhsl.minenet.minestom.pve.Lobby;
 | 
			
		||||
import net.minestom.server.command.CommandSender;
 | 
			
		||||
import net.minestom.server.entity.Player;
 | 
			
		||||
import net.minestom.server.instance.Instance;
 | 
			
		||||
import net.minestom.server.instance.InstanceContainer;
 | 
			
		||||
 | 
			
		||||
public class CommandConditions {
 | 
			
		||||
    public static boolean lobbyOnly(CommandSender sender, String arguments) {
 | 
			
		||||
        if(!(sender instanceof Player p)) return false;
 | 
			
		||||
        Instance instance = p.getInstance();
 | 
			
		||||
        return instance == null || instance == Lobby.INSTANCE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean arenaOnly(CommandSender sender, String arguments) {
 | 
			
		||||
        if(!(sender instanceof Player p)) return false;
 | 
			
		||||
        final Instance instance = p.getInstance();
 | 
			
		||||
        return instance != null && instance != Lobby.INSTANCE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,15 @@
 | 
			
		||||
package eu.mhsl.minenet.minestom.pve.util;
 | 
			
		||||
 | 
			
		||||
import net.minestom.server.MinecraftServer;
 | 
			
		||||
import net.minestom.server.utils.NamespaceID;
 | 
			
		||||
import net.minestom.server.world.DimensionType;
 | 
			
		||||
 | 
			
		||||
public class FullbrightDimension {
 | 
			
		||||
    public static final DimensionType INSTANCE = DimensionType.builder(NamespaceID.from("arena:default"))
 | 
			
		||||
            .ambientLight(2f)
 | 
			
		||||
            .build();
 | 
			
		||||
 | 
			
		||||
    static {
 | 
			
		||||
        MinecraftServer.getDimensionTypeManager().addDimension(INSTANCE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,24 @@
 | 
			
		||||
package eu.mhsl.minenet.minestom.pve.util;
 | 
			
		||||
 | 
			
		||||
import net.minestom.server.instance.block.Block;
 | 
			
		||||
import net.minestom.server.instance.generator.GenerationUnit;
 | 
			
		||||
import net.minestom.server.instance.generator.Generator;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
 | 
			
		||||
public class PaneGenerator implements Generator {
 | 
			
		||||
    private Block block;
 | 
			
		||||
    public PaneGenerator(Block block) {
 | 
			
		||||
        this.block = block;
 | 
			
		||||
    }
 | 
			
		||||
    @Override
 | 
			
		||||
    public void generate(@NotNull GenerationUnit unit) {
 | 
			
		||||
        unit.modifier().fillHeight(0, 5, block);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void generateAll(@NotNull Collection<@NotNull GenerationUnit> units) {
 | 
			
		||||
        Generator.super.generateAll(units);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user