Initial commit

This commit is contained in:
2022-09-17 10:49:36 +02:00
parent 1e8420a83e
commit 59a6e1c423
368 changed files with 26176 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
package eu.mhsl.minenet.minigames.instance;
import net.minestom.server.MinecraftServer;
import net.minestom.server.utils.NamespaceID;
import net.minestom.server.world.DimensionType;
/**
* Prebuilt dimensions
*/
public enum Dimension {
OVERWORLD(
DimensionType
.builder(NamespaceID.from("minenet:fullbright_overworld"))
.ambientLight(2.0f)
.build()
),
NETHER(
DimensionType
.builder(NamespaceID.from("minenet:fullbright_nether"))
.ambientLight(2.0f)
.effects("minecraft:the_nether")
.build()
),
THE_END(
DimensionType
.builder(NamespaceID.from("minenet:fullbright_end"))
.ambientLight(2.0f)
.effects("minecraft:the_end")
.build()
);
public final DimensionType DIMENSION;
Dimension(DimensionType dimType) {
this.DIMENSION = dimType;
MinecraftServer.getDimensionTypeManager().addDimension(this.DIMENSION);
}
}

View File

@@ -0,0 +1,7 @@
package eu.mhsl.minenet.minigames.instance;
import net.minestom.server.coordinate.Pos;
public interface Spawnable {
Pos getSpawn();
}

View File

@@ -0,0 +1,136 @@
package eu.mhsl.minenet.minigames.instance.game;
import eu.mhsl.minenet.minigames.util.CommonEventHandles;
import eu.mhsl.minenet.minigames.instance.Spawnable;
import eu.mhsl.minenet.minigames.instance.room.Room;
import io.github.bloepiloepi.pvp.config.PvPConfig;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.event.EventNode;
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent;
import net.minestom.server.event.item.ItemDropEvent;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.event.player.PlayerBlockPlaceEvent;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.event.trait.InstanceEvent;
import net.minestom.server.instance.InstanceContainer;
import net.minestom.server.timer.ExecutionType;
import net.minestom.server.timer.TaskSchedule;
import net.minestom.server.world.DimensionType;
import org.jetbrains.annotations.NotNull;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public abstract class Game extends InstanceContainer implements Spawnable {
protected boolean isRunning = false;
protected boolean isBeforeBeginning = true;
protected final Random rnd = new Random(); //TODO better way than ths?
public Game(DimensionType dimensionType) {
super(UUID.randomUUID(), dimensionType);
MinecraftServer.getInstanceManager().registerInstance(this);
eventNode()
.addListener(PlayerMoveEvent.class, this::onPlayerMove)
.addListener(PlayerBlockBreakEvent.class, this::onBlockBreak)
.addListener(PlayerBlockPlaceEvent.class, this::onBlockPlace)
.addListener(AddEntityToInstanceEvent.class, this::onJoin)
.addListener(RemoveEntityFromInstanceEvent.class, this::onLeave)
.addListener(ItemDropEvent.class, this::onItemDrop);
}
public void enablePvpConfig(PvPConfig config) {
//eventNode().addChild((EventNode<? extends InstanceEvent>) config.createNode());
}
/**
* Load and start countdown
*/
public void load() {
scheduler().submitTask(() -> {
CompletableFuture<Void> callback = new CompletableFuture<>();
this.onLoad(callback);
callback.whenComplete((unused, throwable) -> this.start());
return TaskSchedule.stop();
}, ExecutionType.ASYNC);
}
protected void start() {
isRunning = true;
isBeforeBeginning = false;
this.onStart();
}
public void stop() {
isRunning = false;
this.onStop();
this.unload();
}
public void unload() {
this.onUnload();
getPlayers().forEach(Room::setOwnRoom);
scheduler().scheduleTask(() -> {
System.out.println("stopping game instance " + this.uniqueId);
getPlayers().forEach(player -> player.kick("timeout"));
MinecraftServer.getInstanceManager().unregisterInstance(this);
}, TaskSchedule.seconds(10), TaskSchedule.stop());
}
protected void onLoad(CompletableFuture<Void> callback) {}
protected void onStart() {}
protected void onStop() {}
protected void onUnload() {}
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
}
protected void onBlockBreak(@NotNull PlayerBlockBreakEvent playerBlockBreakEvent) {
playerBlockBreakEvent.setCancelled(true);
}
protected void onBlockPlace(@NotNull PlayerBlockPlaceEvent playerBlockPlaceEvent) {
playerBlockPlaceEvent.setCancelled(true);
}
protected void onJoin(@NotNull AddEntityToInstanceEvent addEntityToInstanceEvent) {
}
/**
* Make sure when overriding to call checkAbandoned to insure no garbage instances
* @param removeEntityFromInstanceEvent
*/
protected void onLeave(@NotNull RemoveEntityFromInstanceEvent removeEntityFromInstanceEvent) {
this.checkAbandoned();
}
protected void onItemDrop(@NotNull ItemDropEvent itemDropEvent) {
CommonEventHandles.cancel(itemDropEvent);
}
protected void checkAbandoned() {
scheduleNextTick((instance) -> {
if(instance.getPlayers().size() == 0) this.unload();
});
}
public Pos getSpawn() {
return new Pos(0,50,0);
}
}

View File

@@ -0,0 +1,108 @@
package eu.mhsl.minenet.minigames.instance.game.minigame;
import eu.mhsl.minenet.minigames.instance.game.Game;
import eu.mhsl.minenet.minigames.message.Countdown;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import eu.mhsl.minenet.minigames.message.type.TitleMessage;
import eu.mhsl.minenet.minigames.score.Score;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.timer.ExecutionType;
import net.minestom.server.timer.TaskSchedule;
import net.minestom.server.world.DimensionType;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
public class Minigame extends Game {
private final String name;
private Score score = new Score(this);
private int timeLimit = 0;
private int timePlayed = 0;
private boolean preventExit = false;
public Minigame(DimensionType dimensionType, String gameName) {
super(dimensionType);
this.name = gameName;
}
public Score getScore() {
return this.score;
}
public String getName() {
return name;
}
public void setTimeLimit(int limit) {
this.timeLimit = limit;
}
@Override
public void load() {
super.load();
}
/**
* Displays countdown and starts the game
* When overriding make sure to call this::start after countdown!
*/
protected CompletableFuture<Void> countdownStart() {
return new Countdown(TitleMessage.class)
.countdown(Audience.audience(getPlayers()), 5, countdownModifier -> {
countdownModifier.message = new TitleMessage(Duration.ofMillis(300), Duration.ofMillis(700))
.subtitle(subtitleMessage -> {
subtitleMessage.appendStatic(Component.text("in ", NamedTextColor.DARK_GREEN))
.appendStatic(Component.text(countdownModifier.timeLeft, NamedTextColor.GREEN))
.appendStatic(Component.text(" seconds", NamedTextColor.DARK_GREEN));
});
});
}
@Override
protected void start() {
countdownStart().thenRun(() -> {
super.start();
if(timeLimit > 0) {
scheduler().submitTask(() -> {
System.out.println("Countdown running...");
if(!isRunning || timeLimit == 0) return TaskSchedule.stop();
if(timeLimit <= timePlayed) {
stop();
return TaskSchedule.stop();
}
int timeLeft = timeLimit - timePlayed;
switch (timeLeft) {
case 60, 30, 10, 5, 4, 3, 2, 1 ->
new ChatMessage(Icon.SCIENCE).appendStatic("Noch " + timeLeft + " Sekunden!").send(getPlayers());
}
timePlayed++;
return TaskSchedule.seconds(1);
}, ExecutionType.SYNC);
}
});
}
@Override
public void stop() {
isRunning = false;
this.onStop();
countdownUnload();
}
protected void countdownUnload() {
new TitleMessage(Duration.ofSeconds(1)).appendStatic("Finish").send(getPlayers());
scheduler().scheduleTask(this::unload, TaskSchedule.seconds(5), TaskSchedule.stop());
}
}

View File

@@ -0,0 +1,22 @@
package eu.mhsl.minenet.minigames.instance.game.minigame;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.minigame.types.deathcube.DeathcubeFactory;
import eu.mhsl.minenet.minigames.instance.game.minigame.types.minerun.MinerunFactory;
import eu.mhsl.minenet.minigames.instance.game.minigame.types.stickfight.StickFightFactory;
import eu.mhsl.minenet.minigames.instance.game.minigame.types.trafficlightrace.TrafficLightRaceFactory;
public enum MinigameType {
DEATHCUBE(new DeathcubeFactory()),
STICKFIGHT(new StickFightFactory()),
MINERUN(new MinerunFactory()),
TRAFFICLIGHTRACE(new TrafficLightRaceFactory());
private GameFactory factory;
MinigameType(GameFactory factory) {
this.factory = factory;
}
public GameFactory getFactory() {
return this.factory;
}
}

View File

@@ -0,0 +1,16 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config;
import java.util.ArrayList;
public class ConfigManager {
private final ArrayList<Option<?>> items = new ArrayList<>();
public ConfigManager addOption(Option option) {
items.add(option);
return this;
}
public ArrayList<Option<?>> getAll() {
return items;
}
}

View File

@@ -0,0 +1,95 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config;
import eu.mhsl.minenet.minigames.instance.game.Game;
import eu.mhsl.minenet.minigames.shared.inventory.InteractableInventory;
import eu.mhsl.minenet.minigames.util.TextUtil;
import eu.mhsl.minenet.minigames.instance.room.Room;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.entity.Player;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.inventory.condition.InventoryConditionResult;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import java.util.HashMap;
import java.util.Map;
public class GameConfigurationInventory extends InteractableInventory {
private final Map<Integer, Option<?>> map = new HashMap<>();
public GameConfigurationInventory(GameFactory factory) {
super(InventoryType.CHEST_5_ROW, factory.name());
ConfigManager config = factory.configuration();
setClickableItem(
ItemStack.builder(Material.RED_WOOL).displayName(Component.text("Abbrechen", NamedTextColor.RED)).build(),
0,
itemClick -> itemClick.getPlayer().closeInventory(),
true
);
setDummyItem(Material.BLACK_STAINED_GLASS_PANE,1);
setDummyItem(
ItemStack.builder(Material.NAME_TAG).displayName(factory.name()).build(),
4
);
setDummyItem(Material.BLACK_STAINED_GLASS_PANE,7);
setClickableItem(
ItemStack.builder(Material.GREEN_WOOL).displayName(Component.text("Start", NamedTextColor.GREEN)).build(),
8,
itemClick -> {
try {
Game game = factory.manufacture(config != null ? config.getAll() : null);
Room.getRoom(itemClick.getPlayer()).moveMembersToGame(game);
game.load();
} catch (Exception e) {
e.printStackTrace();
}
},
true
);
for(int i = 9; i <= 17; i++) {
setDummyItem(Material.BLACK_STAINED_GLASS_PANE, i);
}
if(config == null) {
setDummyItem(
ItemStack.builder(Material.BARRIER).displayName(Component.text("Keine Optionen")).lore(TextUtil.autoWrap("Für dieses Spiel sind keine Einstellungen verfügbar!")).build(),
31
);
return;
}
int pos = 18;
for(Option<?> item : config.getAll()) {
map.put(pos, item);
setDummyItem(
item.getCurrent(),
pos++
);
}
}
@Override
protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
inventoryConditionResult.setCancel(true);
if(!map.containsKey(slot)) return;
Option item = map.get(slot);
setDummyItem(
item.getNext(),
slot
);
update();
}
}

View File

@@ -0,0 +1,34 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config;
import eu.mhsl.minenet.minigames.instance.game.minigame.Minigame;
import net.kyori.adventure.text.Component;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.Material;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public interface GameFactory {
Component name();
ConfigManager configuration();
default Material symbol() {
return Material.GRASS_BLOCK;
};
default Component description() {
return Component.text("- Keine Beschreibung -");
};
Minigame manufacture(Map<String, Option<?>> configuration);
default Minigame manufacture(List<Option<?>> configuration) {
if(configuration == null) return manufacture();
Map<String, Option<?>> cnf = new HashMap<>();
configuration.forEach(option -> cnf.put(option.getId(), option));
return manufacture(cnf);
}
default Minigame manufacture() {
if(this.configuration() == null) return manufacture(List.of());
return manufacture(this.configuration().getAll());
}
}

View File

@@ -0,0 +1,51 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import java.util.List;
public abstract class Option<T> {
private final Material item;
private final String name;
private final String id;
protected T currentValue;
private final List<T> options;
private int pointer = 0;
public Option(String id, Material item, String name, List<T> options) {
this.id = id;
this.item = item;
this.name = name;
this.options = options;
currentValue = options.get(0);
}
public ItemStack getNext() {
if(++pointer >= options.size()) pointer = 0;
currentValue = options.get(pointer);
return getCurrent();
}
public ItemStack getCurrent() {
int amount = Integer.parseInt(options.get(pointer).toString());
return ItemStack.builder(item)
.displayName(Component.text(name).append(Component.text(" - ")).append(Component.text(amount)))
.build();
}
public int getAsInt() {
return Integer.parseInt(getAsString());
}
public String getAsString() {
return currentValue.toString();
}
public String getId() {
return id;
}
}

View File

@@ -0,0 +1,12 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config.options;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.Option;
import net.minestom.server.item.Material;
import java.util.List;
public class BoolOption extends Option<Boolean> {
public BoolOption(String id, Material item, String name) {
super(id, item, name, List.of(true, false));
}
}

View File

@@ -0,0 +1,12 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config.options;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.Option;
import net.minestom.server.item.Material;
import java.util.List;
public class NumericOption extends Option<Integer> {
public NumericOption(String id, Material item, String name, Integer... options) {
super(id, item, name, List.of(options));
}
}

View File

@@ -0,0 +1,57 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.types.deathcube;
import eu.mhsl.minenet.minigames.instance.game.minigame.Minigame;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.world.generator.BlockPallet;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularTerrainGenerator;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
class Deathcube extends Minigame {
int radius, height, percentage;
public Deathcube(int radius, int height, int percentage) {
super(Dimension.THE_END.DIMENSION, "Deathcube");
this.radius = radius;
this.height = height;
this.percentage = percentage;
this.setGenerator(new CircularTerrainGenerator(40, true));
}
@Override
protected void onLoad(CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = -radius; x <= radius; x++) {
for (int z = -radius; z <= radius; z++) {
if(new Pos(x, 0, z).distance(new Pos(0, 0, 0)) > radius) continue;
for (int y = 49; y < height; y++) {
if(super.rnd.nextInt(1, 100) <= percentage) {
batch.setBlock(x, y, z, BlockPallet.WOOD.rnd());
}
}
}
}
BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
super.onPlayerMove(playerMoveEvent);
if(isBeforeBeginning) if(playerMoveEvent.getNewPosition().y() > 51.5) playerMoveEvent.setCancelled(true);
if(playerMoveEvent.getNewPosition().y() > 100) getScore().addResult(playerMoveEvent.getPlayer());
}
@Override
public Pos getSpawn() {
return new Pos(0, 50, 30);
}
}

View File

@@ -0,0 +1,36 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.types.deathcube;
import eu.mhsl.minenet.minigames.instance.game.minigame.Minigame;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.Option;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.ConfigManager;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.options.NumericOption;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.Material;
import java.util.Map;
public class DeathcubeFactory implements GameFactory {
@Override
public Component name() {
return Component.text("Deathcube");
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, "Radius", 10, 30, 50, 100))
.addOption(new NumericOption("height", Material.SCAFFOLDING, "Height", 50, 100, 150, 200))
.addOption(new NumericOption("percentage", Material.COBWEB, "Percent of blocks", 5, 7, 9, 11, 13));
}
@Override
public Minigame manufacture(Map<String, Option<?>> configuration) {
return new Deathcube(configuration.get("radius").getAsInt(), configuration.get("height").getAsInt(), configuration.get("percentage").getAsInt());
}
@Override
public Material symbol() {
return Material.OAK_FENCE;
}
}

View File

@@ -0,0 +1,130 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.types.minerun;
import eu.mhsl.minenet.minigames.instance.game.minigame.Minigame;
import eu.mhsl.minenet.minigames.message.type.ActionBarMessage;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.util.Intersect;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.world.generator.BlockPallet;
import eu.mhsl.minenet.minigames.world.generator.terrain.SquareTerrainGenerator;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import net.minestom.server.instance.block.Block;
import net.minestom.server.sound.SoundEvent;
import org.jetbrains.annotations.NotNull;
import java.util.*;
import java.util.concurrent.CompletableFuture;
class Minerun extends Minigame {
private int minePercentage = 50;
private int width = 100;
private int length = 50;
private final int backRun = -5;
private final int preRun = 5;
private final int afterMines = 2;
private final int afterFinishLine = 10;
public Minerun(int width, int length, int minePercentage) {
super(Dimension.THE_END.DIMENSION, "Minerun");
setGenerator(new SquareTerrainGenerator(width, length + preRun + afterFinishLine, true));
this.width = width;
this.length = length;
this.minePercentage = minePercentage;
System.out.println(width + " " + length + " " + minePercentage);
}
@Override
protected void onLoad(CompletableFuture<Void> callback) {
int spawnToFinishLine = preRun + length + afterMines;
int spawnToEnd = spawnToFinishLine + afterFinishLine;
Random random = new Random();
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = 0; x <= width; x++) {
for(int z = preRun; z <= length + preRun; z++) {
if (random.nextInt(0, 100) < minePercentage) {
batch.setBlock(x, 50, z, BlockPallet.PRESSURE_PLATES.rnd());
}
}
}
Map<String, String> properties = new HashMap<>() {
{
put("west", "true");
put("east", "true");
}
};
for(int x = 0; x <= width; x++) {
batch.setBlock(x, 49, spawnToFinishLine, Block.GOLD_BLOCK);
batch.setBlock(x, 49, preRun, Block.GOLD_BLOCK);
batch.setBlock(x, 50, preRun, Block.OAK_FENCE.withProperties(properties));
}
BatchUtil.loadAndApplyBatch(batch, this, () -> {
callback.complete(null);
});
}
@Override
protected void onStart() {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for(int x = 0; x <= width; x++) {
batch.setBlock(x, 50, preRun, Block.AIR);
}
BatchUtil.loadAndApplyBatch(batch, this, () -> {
playSound(Sound.sound(SoundEvent.BLOCK_WOOD_BREAK, Sound.Source.BLOCK, 1f, 1f));
});
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
Player p = playerMoveEvent.getPlayer();
Pos middle = playerMoveEvent.getNewPosition();
if(middle.x() < 0 || middle.x() > width) { //player cannot go sidewards
playerMoveEvent.setCancelled(true);
new ActionBarMessage().appendStatic(Component.text("Please stay in line!", NamedTextColor.RED)).send(p);
}
if(!isRunning && middle.z() > preRun+0.5) { //player cannot go forward before game start
playerMoveEvent.setCancelled(true);
}
if(getScore().hasResult(p) && middle.z() < preRun + length + afterMines) { // player cannot go back
playerMoveEvent.setCancelled(true);
new ActionBarMessage().appendStatic(Component.text("You cannot go back on the Field!", NamedTextColor.RED)).send(p);
return;
}
if(Intersect.withPressurePlate(this, BlockPallet.PRESSURE_PLATES, middle)) { //Player died
p.setPose(Entity.Pose.DYING);
p.teleport(new Pos(p.getPosition().x(), getSpawn().y(), getSpawn().z()));
p.playSound(Sound.sound(SoundEvent.ENTITY_GENERIC_EXPLODE, Sound.Source.PLAYER, 1f, 1f));
}
if(middle.z() > preRun + length + afterMines) { // Player finished
getScore().addResult(p);
}
}
@Override
public Pos getSpawn() {
return new Pos(width/2, 50, 3);
}
}

View File

@@ -0,0 +1,42 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.types.minerun;
import eu.mhsl.minenet.minigames.instance.game.minigame.Minigame;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.ConfigManager;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.Option;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.options.NumericOption;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.Material;
import java.util.Map;
public class MinerunFactory implements GameFactory {
@Override
public Component name() {
return Component.text("Deathcube");
}
@Override
public ConfigManager configuration() {
return new ConfigManager()
.addOption(new NumericOption("width", Material.OAK_FENCE, "Width", 10, 30, 50, 100))
.addOption(new NumericOption("length", Material.ZOMBIE_HEAD, "Length", 50, 100, 150, 200))
.addOption(new NumericOption("percentage", Material.LIGHT_WEIGHTED_PRESSURE_PLATE, "Percent of mines", 30, 40, 50, 60, 70));
}
@Override
public Minigame manufacture(Map<String, Option<?>> configuration) {
System.out.println("Manufacture" + configuration.get("width").getAsInt());
return new Minerun(configuration.get("width").getAsInt(), configuration.get("length").getAsInt(), configuration.get("percentage").getAsInt());
}
@Override
public Material symbol() {
return Material.LIGHT_WEIGHTED_PRESSURE_PLATE;
}
@Override
public Component description() {
return Component.text("Weiche druckplatten aus");
}
}

View File

@@ -0,0 +1,32 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.types.stickfight;
import eu.mhsl.minenet.minigames.instance.game.minigame.Minigame;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.ConfigManager;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.Option;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.Material;
import java.util.Map;
public class StickFightFactory implements GameFactory {
@Override
public Component name() {
return Component.text("Stickfight");
}
@Override
public ConfigManager configuration() {
return null;
}
@Override
public Minigame manufacture(Map<String, Option<?>> configuration) {
return new Stickfight();
}
@Override
public Material symbol() {
return Material.STICK;
}
}

View File

@@ -0,0 +1,71 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.types.stickfight;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.game.minigame.Minigame;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.world.generator.terrain.CircularTerrainGenerator;
import eu.mhsl.minenet.minigames.world.generator.terrain.SquareTerrainGenerator;
import io.github.bloepiloepi.pvp.PvpExtension;
import io.github.bloepiloepi.pvp.config.*;
import io.github.bloepiloepi.pvp.events.FinalAttackEvent;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.event.EventNode;
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.event.trait.InstanceEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import net.minestom.server.instance.block.Block;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
public class Stickfight extends Minigame {
public Stickfight() {
super(Dimension.OVERWORLD.DIMENSION, "Stickfight");
eventNode().addChild(
PvPConfig.emptyBuilder()
.damage(DamageConfig.legacyBuilder().fallDamage(false))
.attack(AttackConfig.legacyBuilder().attackCooldown(true))
.build().createNode()
);
eventNode().addListener(FinalAttackEvent.class, finalAttackEvent -> {
finalAttackEvent.setBaseDamage(0);
((Player) finalAttackEvent.getTarget()).setHealth(20);
});
setGenerator(new CircularTerrainGenerator(20, false));
}
@Override
protected void onLoad(CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for (int z = -10; z <= 10; z++) {
batch.setBlock(0, 50, z, Block.SANDSTONE);
}
batch.setBlock(0, 50, 0, Block.GOLD_BLOCK);
BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
if(isBeforeBeginning) playerMoveEvent.setCancelled(true);
if(playerMoveEvent.getNewPosition().y() < 40) {
playerMoveEvent.getPlayer().teleport(new Pos(0, 51, 0));
}
}
@Override
protected void onJoin(@NotNull AddEntityToInstanceEvent addEntityToInstanceEvent) {
}
@Override
public Pos getSpawn() {
return new Pos(0.5, 51, 0.5);
}
}

View File

@@ -0,0 +1,29 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.types.trafficlightrace;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.timer.TaskSchedule;
import java.util.Random;
enum LightPhase {
RED(Material.RED_WOOL, 1000, 5000),
YELLOW(Material.YELLOW_WOOL, 1000, 2000),
GREEN(Material.GREEN_WOOL, 1000, 5000);
public final ItemStack item;
private final int minDuration;
private final int maxDuration;
private static final Random rnd = new Random();
LightPhase(Material material, int minDuration, int maxDuration) {
this.item = ItemStack.of(material);
this.minDuration = minDuration;
this.maxDuration = maxDuration;
}
public TaskSchedule taskScheduleRandomDuration() {
return TaskSchedule.millis(rnd.nextLong(minDuration, maxDuration));
}
}

View File

@@ -0,0 +1,69 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.types.trafficlightrace;
import eu.mhsl.minenet.minigames.instance.game.minigame.Minigame;
import eu.mhsl.minenet.minigames.util.BatchUtil;
import eu.mhsl.minenet.minigames.instance.Dimension;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.event.player.PlayerMoveEvent;
import net.minestom.server.instance.batch.AbsoluteBlockBatch;
import net.minestom.server.instance.block.Block;
import net.minestom.server.timer.ExecutionType;
import net.minestom.server.timer.TaskSchedule;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
class TrafficLightRace extends Minigame {
private LightPhase phase = LightPhase.RED;
private int phaseCounter = 1;
public TrafficLightRace() {
super(Dimension.THE_END.DIMENSION, "Ampelrennen");
}
@Override
protected void onLoad(CompletableFuture<Void> callback) {
AbsoluteBlockBatch batch = new AbsoluteBlockBatch();
for (int x = -10; x <= 10; x++) {
for (int z = 5; z <= 100; z++) {
batch.setBlock(x, 5, z, super.rnd.nextInt(0, 100) > 90 ? Block.SOUL_SAND : Block.BLACK_CONCRETE_POWDER);
}
}
BatchUtil.loadAndApplyBatch(batch, this, () -> callback.complete(null));
}
@Override
protected void onStart() {
scheduler().submitTask(() -> {
if(!super.isRunning) return TaskSchedule.stop();
phaseCounter++;
if(phaseCounter >= 4) phaseCounter = 0;
if(phaseCounter == 0) phase = LightPhase.RED;
if(phaseCounter == 1 || phaseCounter == 3) phase = LightPhase.YELLOW;
if(phaseCounter == 2) phase = LightPhase.GREEN;
getPlayers().forEach(player -> {
for(int i = 0; i < 9; i++) {
player.getInventory().setItemStack(i, phase.item);
}
});
return phase.taskScheduleRandomDuration();
}, ExecutionType.SYNC);
}
@Override
protected void onPlayerMove(@NotNull PlayerMoveEvent playerMoveEvent) {
super.onPlayerMove(playerMoveEvent);
if(playerMoveEvent.getNewPosition().z() > 110) stop();
if(phase.equals(LightPhase.RED) && playerMoveEvent.getNewPosition().z() > playerMoveEvent.getPlayer().getPosition().z()) {
playerMoveEvent.getPlayer().setVelocity(new Vec(0, 5, -10));
}
}
}

View File

@@ -0,0 +1,32 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.types.trafficlightrace;
import eu.mhsl.minenet.minigames.instance.game.minigame.Minigame;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.GameFactory;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.ConfigManager;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.Option;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.Material;
import java.util.Map;
public class TrafficLightRaceFactory implements GameFactory {
@Override
public Component name() {
return Component.text("TrafficLightRace");
}
@Override
public ConfigManager configuration() {
return null;
}
@Override
public Minigame manufacture(Map<String, Option<?>> configuration) {
return new TrafficLightRace();
}
@Override
public Material symbol() {
return Material.YELLOW_WOOL;
}
}

View File

@@ -0,0 +1,46 @@
package eu.mhsl.minenet.minigames.instance.hub;
import eu.mhsl.minenet.minigames.Resource;
import eu.mhsl.minenet.minigames.instance.hub.entity.RoomSelector;
import eu.mhsl.minenet.minigames.util.CommonEventHandles;
import eu.mhsl.minenet.minigames.instance.Spawnable;
import eu.mhsl.minenet.minigames.instance.Dimension;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.event.player.*;
import net.minestom.server.instance.AnvilLoader;
import net.minestom.server.instance.InstanceContainer;
import java.nio.file.Path;
import java.util.UUID;
public class HubInstance extends InstanceContainer implements Spawnable {
public static final HubInstance INSTANCE = new HubInstance();
static {
MinecraftServer.getInstanceManager().registerInstance(INSTANCE);
INSTANCE.setChunkLoader(new AnvilLoader(Resource.HUB_MAP.getPath()));
INSTANCE.eventNode()
.addListener(PlayerBlockBreakEvent.class, CommonEventHandles::cancel)
.addListener(PlayerBlockPlaceEvent.class, CommonEventHandles::cancel)
.addListener(PlayerBlockInteractEvent.class, CommonEventHandles::cancel);
new RoomSelector().setInstance(INSTANCE, new Pos(0.5, 11, 4.5));
}
private HubInstance() {
super(UUID.randomUUID(), Dimension.THE_END.DIMENSION);
setChunkLoader(new AnvilLoader(Path.of("maps/hub")));
setTime(18000);
setTimeRate(0);
}
@Override
public Pos getSpawn() {
return new Pos(0.5, 11, 0.5);
}
}

View File

@@ -0,0 +1,35 @@
package eu.mhsl.minenet.minigames.instance.hub.entity;
import eu.mhsl.minenet.minigames.instance.hub.inventory.HubInventory;
import eu.mhsl.minenet.minigames.shared.entity.InteractableEntity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.metadata.villager.AbstractVillagerMeta;
import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
import net.minestom.server.event.player.PlayerEntityInteractEvent;
import org.jetbrains.annotations.NotNull;
public class RoomSelector extends InteractableEntity {
final AbstractVillagerMeta abstractVillagerMeta;
public RoomSelector() {
super(EntityType.VILLAGER);
abstractVillagerMeta = (AbstractVillagerMeta) this.getEntityMeta();
}
@Override
public void onSpawn(@NotNull AddEntityToInstanceEvent addEntityToInstanceEvent) {
}
@Override
public void onAttack(@NotNull EntityAttackEvent entityAttackEvent) {
super.onAttack(entityAttackEvent);
abstractVillagerMeta.setHeadShakeTimer(20);
}
@Override
public void onInteract(@NotNull PlayerEntityInteractEvent playerEntityInteractEvent) {
playerEntityInteractEvent.getPlayer().openInventory(new HubInventory());
}
}

View File

@@ -0,0 +1,37 @@
package eu.mhsl.minenet.minigames.instance.hub.inventory;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.shared.inventory.InteractableInventory;
import net.kyori.adventure.text.Component;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemHideFlag;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
public class HubInventory extends InteractableInventory {
public HubInventory() {
super(InventoryType.CHEST_3_ROW, Component.text("MineNet Servernetzwerk"));
setClickableItem(
ItemStack
.builder(Material.WRITABLE_BOOK)
.displayName(Component.text("Create own room"))
.lore(Component.text("Create new empty room"))
.meta(metaBuilder -> metaBuilder.hideFlag(ItemHideFlag.HIDE_ATTRIBUTES))
.build(),
12,
itemClick -> Room.createRoom(itemClick.getPlayer()),
true
);
setClickableItem(
ItemStack
.builder(Material.KNOWLEDGE_BOOK)
.displayName(Component.text("Browse room"))
.lore(Component.text("Browse existing rooms"))
.build(),
14,
itemClick -> itemClick.getPlayer().openInventory(new JoinInventory())
);
}
}

View File

@@ -0,0 +1,70 @@
package eu.mhsl.minenet.minigames.instance.hub.inventory;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import eu.mhsl.minenet.minigames.shared.inventory.InteractableInventory;
import eu.mhsl.minenet.minigames.instance.hub.HubInstance;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerPacketEvent;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.inventory.condition.InventoryConditionResult;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import net.minestom.server.item.metadata.PlayerHeadMeta;
import net.minestom.server.network.packet.client.play.ClientNameItemPacket;
import java.util.Locale;
public class JoinInventory extends InteractableInventory {
private String typedText = "";
private final String prefix = "name:";
public JoinInventory() {
super(InventoryType.ANVIL, Component.text("Enter username"));
setClickableItem(
ItemStack.builder(Material.PLAYER_HEAD)
.displayName(Component.text(prefix))
.meta(PlayerHeadMeta.class, builder -> {
})
.build(),
0,
itemClick -> {}
);
HubInstance.INSTANCE.eventNode().addListener(PlayerPacketEvent.class, event -> {
if (event.getPacket() instanceof ClientNameItemPacket packet) {
typedText = packet.itemName();
}
});
}
@Override
protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
if(slot != 2) return;
inventoryConditionResult.setCancel(true);
player.closeInventory();
typedText = formatInput(typedText);
Room target = Room.getRoom(MinecraftServer.getConnectionManager().findPlayer(typedText));
if(target != null)
Room.setRoom(player, target);
else
new ChatMessage(Icon.ERROR).appendStatic("The room").quote(typedText).appendStatic("could not be found!").send(player);
}
private String formatInput(String raw) {
if(raw.startsWith(prefix)) {
raw = raw.split(prefix)[1];
}
return raw.toLowerCase(Locale.ROOT).trim();
}
}

View File

@@ -0,0 +1,123 @@
package eu.mhsl.minenet.minigames.instance.room;
import eu.mhsl.minenet.minigames.Resource;
import eu.mhsl.minenet.minigames.instance.game.Game;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import eu.mhsl.minenet.minigames.util.CommonEventHandles;
import eu.mhsl.minenet.minigames.util.MoveInstance;
import eu.mhsl.minenet.minigames.instance.Spawnable;
import eu.mhsl.minenet.minigames.instance.Dimension;
import eu.mhsl.minenet.minigames.instance.hub.HubInstance;
import eu.mhsl.minenet.minigames.instance.room.entity.GameSelector;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.event.player.PlayerDisconnectEvent;
import net.minestom.server.instance.AnvilLoader;
import net.minestom.server.instance.InstanceContainer;
import java.util.*;
import java.util.stream.Collectors;
public class Room extends InstanceContainer implements Spawnable {
private static final Map<Player, Room> rooms = new WeakHashMap<>();
public static Room createRoom(Player owner) {
System.out.println("Room created by " + owner.getUsername());
setRoom(owner, new Room(owner));
return getRoom(owner);
}
public static void deleteRoom(Room room) {
System.out.println("Room deleted");
rooms.values().removeAll(Collections.singleton(room)); // remove(room) would only remove the first one
room.getAllMembers().forEach(player -> MoveInstance.move(player, HubInstance.INSTANCE));
MoveInstance.forceCloseInstance(room);
}
public static Room getRoom(Player p) {
return rooms.get(p);
}
public static void setOwnRoom(Player p) {
setRoom(p, getRoom(p));
}
public static void setRoom(Player p, Room room) {
p.clearEffects();
p.clearTitle();
p.getInventory().clear();
rooms.put(p, room);
MoveInstance.move(p, room);
}
public static void unsetRoom(Player p) {
rooms.remove(p);
}
public static Set<Room> getAllRooms() {
return new HashSet<>(rooms.values());
}
private Player owner;
private Room(Player owner) {
super(UUID.randomUUID(), Dimension.THE_END.DIMENSION);
MinecraftServer.getInstanceManager().registerInstance(this);
setChunkLoader(new AnvilLoader(Resource.LOBBY_MAP.getPath()));
eventNode().addListener(PlayerBlockBreakEvent.class, CommonEventHandles::cancel);
setOwner(owner);
new GameSelector().setInstance(this, new Pos(0.5, 16, 9.5));
}
public Player getOwner() {
return owner;
}
private void setOwner(Player newOwner) {
this.owner = newOwner;
this.owner.eventNode().addListener(PlayerDisconnectEvent.class, playerDisconnectEvent -> {
System.out.println("Room Leader left room");
Player p = playerDisconnectEvent.getPlayer();
if(p != this.owner) return; // return if the current handling player is really the current owner
getAllMembers().stream()
.filter(player -> player != p) // exclude the current leaving owner
.findFirst() // find first user meeting the requirement
.ifPresentOrElse(
this::setOwner, // set the new owner
() -> Room.deleteRoom(Room.getRoom(p)) // or else delete the room (no players in the room)
);
Room.unsetRoom(p); // remove the player itself from the room
new ChatMessage(Icon.ERROR).appendStatic("The room leader left!").send(getAllMembers());
new ChatMessage(Icon.SCIENCE).appendStatic(this.owner.getUsername()).appendStatic(" is the new Leader!").send(getAllMembers().stream().filter(player -> player != this.owner).collect(Collectors.toSet()));
new ChatMessage(Icon.SUCCESS).appendStatic("You are now the leader.").send(this.owner);
});
}
public void moveMembersToGame(Game game) {
this.getAllMembers().forEach(player -> {
MoveInstance.move(player, game);
});
}
public Set<Player> getAllMembers() {
return rooms.keySet().stream()
.filter(player -> getRoom(player) == this)
.collect(Collectors.toSet());
}
@Override
public Pos getSpawn() {
return new Pos(0.5, 16, 0.5);
}
}

View File

@@ -0,0 +1,49 @@
package eu.mhsl.minenet.minigames.instance.room.entity;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.instance.room.inventory.MinigameTypeSelectInventory;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import eu.mhsl.minenet.minigames.shared.entity.InteractableEntity;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.metadata.villager.AbstractVillagerMeta;
import net.minestom.server.event.entity.EntityAttackEvent;
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
import net.minestom.server.event.player.PlayerEntityInteractEvent;
import org.jetbrains.annotations.NotNull;
public class GameSelector extends InteractableEntity {
final AbstractVillagerMeta abstractVillagerMeta;
public GameSelector() {
super(EntityType.VILLAGER);
abstractVillagerMeta = (AbstractVillagerMeta) this.getEntityMeta();
}
@Override
public void onSpawn(@NotNull AddEntityToInstanceEvent addEntityToInstanceEvent) {
}
@Override
public void onAttack(@NotNull EntityAttackEvent entityAttackEvent) {
super.onAttack(entityAttackEvent);
}
@Override
public void onInteract(@NotNull PlayerEntityInteractEvent playerEntityInteractEvent) {
Room room = (Room) instance;
if(playerEntityInteractEvent.getPlayer() != room.getOwner()) {
abstractVillagerMeta.setHeadShakeTimer(20);
new ChatMessage(Icon.ERROR).appendStatic("Only the room leader can start games!").indent(1).newLine()
.appendStatic("current leader: ").appendStatic(room.getOwner().getUsername())
.send(playerEntityInteractEvent.getPlayer());
return;
}
playerEntityInteractEvent.getPlayer().openInventory(new MinigameTypeSelectInventory());
}
}

View File

@@ -0,0 +1,11 @@
package eu.mhsl.minenet.minigames.instance.room.inventory;
import eu.mhsl.minenet.minigames.shared.inventory.InteractableInventory;
import net.kyori.adventure.text.Component;
import net.minestom.server.inventory.InventoryType;
public class BoardInventory extends InteractableInventory {
public BoardInventory() {
super(InventoryType.CHEST_3_ROW, Component.text("Brettspiele"));
}
}

View File

@@ -0,0 +1,64 @@
package eu.mhsl.minenet.minigames.instance.room.inventory;
import eu.mhsl.minenet.minigames.instance.game.minigame.MinigameType;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.GameConfigurationInventory;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.GameFactory;
import eu.mhsl.minenet.minigames.shared.inventory.InteractableInventory;
import net.kyori.adventure.text.Component;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemHideFlag;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
public class MinigameTypeSelectInventory extends InteractableInventory {
public MinigameTypeSelectInventory() {
super(InventoryType.CHEST_3_ROW, Component.text("MineNet Servernetzwerk"));
int i = 0;
for (MinigameType minigameType : MinigameType.values()) {
GameFactory gameFactory = minigameType.getFactory();
setClickableItem(
ItemStack.builder(gameFactory.symbol())
.displayName(gameFactory.name())
.lore(gameFactory.description())
.meta(metaBuilder -> metaBuilder.hideFlag(ItemHideFlag.HIDE_ATTRIBUTES))
.build(),
i,
itemClick -> itemClick.getPlayer().openInventory(new GameConfigurationInventory(gameFactory))
);
i++;
}
// setClickableItem(
// ItemStack
// .builder(Material.IRON_SWORD)
// .displayName(Component.text("PVP Spiele"))
// .lore(Component.text("Player versus Player"))
// .meta(metaBuilder -> metaBuilder.hideFlag(ItemHideFlag.HIDE_ATTRIBUTES))
// .build(),
// 11,
// itemClick -> itemClick.getPlayer().openInventory(new PvpInventory())
// );
//
// setClickableItem(
// ItemStack
// .builder(Material.ZOMBIE_HEAD)
// .displayName(Component.text("PVE Arenen"))
// .lore(Component.text("Player versus Entity"))
// .build(),
// 13,
// itemClick -> itemClick.getPlayer().openInventory(new PveInventory())
// );
//
// setClickableItem(
// ItemStack
// .builder(Material.BRICK_SLAB)
// .displayName(Component.text("Brettspiele"))
// .lore(Component.text("Bekannte Brettspieler aller Art"))
// .build(),
// 15,
// itemClick -> itemClick.getPlayer().openInventory(new BoardInventory())
// );
}
}

View File

@@ -0,0 +1,41 @@
package eu.mhsl.minenet.minigames.instance.room.inventory;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.GameConfigurationInventory;
import eu.mhsl.minenet.minigames.instance.game.minigame.types.minerun.MinerunFactory;
import eu.mhsl.minenet.minigames.shared.inventory.InteractableInventory;
import eu.mhsl.minenet.minigames.instance.game.minigame.types.deathcube.DeathcubeFactory;
import eu.mhsl.minenet.minigames.instance.game.minigame.types.trafficlightrace.TrafficLightRaceFactory;
import net.kyori.adventure.text.Component;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
public class PveInventory extends InteractableInventory {
public PveInventory() {
super(InventoryType.CHEST_3_ROW, Component.text("PVE"));
setClickableItem(
ItemStack.builder(Material.LIGHT_WEIGHTED_PRESSURE_PLATE).displayName(Component.text("Minerun")).lore(Component.text("Jump between ground mines to the finish")).build(),
0,
itemClick -> {
itemClick.getPlayer().openInventory(new GameConfigurationInventory(new MinerunFactory()));
}
);
setClickableItem(
ItemStack.builder(Material.YELLOW_WOOL).displayName(Component.text("Ampelrennen")).build(),
1,
itemClick -> {
itemClick.getPlayer().openInventory(new GameConfigurationInventory(new TrafficLightRaceFactory()));
}
);
setClickableItem(
ItemStack.builder(Material.RED_WOOL).displayName(Component.text("Deathcube")).build(),
2,
itemClick -> {
itemClick.getPlayer().openInventory(new GameConfigurationInventory(new DeathcubeFactory()));
}
);
}
}

View File

@@ -0,0 +1,27 @@
package eu.mhsl.minenet.minigames.instance.room.inventory;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.GameConfigurationInventory;
import eu.mhsl.minenet.minigames.instance.game.minigame.types.stickfight.StickFightFactory;
import eu.mhsl.minenet.minigames.shared.inventory.InteractableInventory;
import net.kyori.adventure.text.Component;
import net.minestom.server.entity.Player;
import net.minestom.server.inventory.InventoryType;
import net.minestom.server.inventory.click.ClickType;
import net.minestom.server.inventory.condition.InventoryConditionResult;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
public class PvpInventory extends InteractableInventory {
public PvpInventory() {
super(InventoryType.CHEST_6_ROW, Component.text("PVP"));
setClickableItem(ItemStack.of(Material.GOLD_INGOT), 4, itemClick -> {
itemClick.getPlayer().openInventory(new GameConfigurationInventory(new StickFightFactory()));
});
}
@Override
protected void onClick(Player player, int slot, ClickType clickType, InventoryConditionResult inventoryConditionResult) {
super.onClick(player, slot, clickType, inventoryConditionResult);
}
}