Added restrictions

This commit is contained in:
2022-09-25 23:34:43 +02:00
parent 8409d1cc7d
commit b5468b1fe9
43 changed files with 305 additions and 62 deletions

View File

@ -1,6 +1,7 @@
package eu.mhsl.minenet.minigames.instance.game;
import eu.mhsl.minenet.minigames.instance.MineNetInstance;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.GameFactory;
import eu.mhsl.minenet.minigames.util.CommonEventHandles;
import eu.mhsl.minenet.minigames.instance.Spawnable;
import eu.mhsl.minenet.minigames.instance.room.Room;
@ -50,6 +51,13 @@ public abstract class Game extends MineNetInstance implements Spawnable {
.addListener(ItemDropEvent.class, this::onItemDrop);
}
public static Game initialize(GameFactory factory, Player owner) {
Game game = factory.manufacture(factory.configuration() != null ? factory.configuration().getAll() : null);
Room.getRoom(owner).moveMembersToGame(game);
game.load();
return game;
}
/**
* Load and start countdown
*/

View File

@ -1,26 +1,46 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config;
import eu.mhsl.minenet.minigames.instance.game.Game;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.IRestriction;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.Restriction;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.RestrictionData;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.RestrictionHandler;
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.sound.Sound;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.entity.Player;
import net.minestom.server.event.instance.AddEntityToInstanceEvent;
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.sound.SoundEvent;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class GameConfigurationInventory extends InteractableInventory {
private final Map<Integer, Option<?>> map = new HashMap<>();
public GameConfigurationInventory(GameFactory factory) {
final private Room room;
final private GameFactory factory;
public GameConfigurationInventory(Room room, GameFactory factory) {
super(InventoryType.CHEST_5_ROW, factory.name());
this.room = room;
this.factory = factory;
room.eventNode()
.addListener(AddEntityToInstanceEvent.class, addEntityToInstanceEvent -> {
System.out.println("UPDATE");
updatePlayButton();
});
ConfigManager config = factory.configuration();
setClickableItem(
@ -39,20 +59,7 @@ public class GameConfigurationInventory extends InteractableInventory {
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
);
updatePlayButton();
for(int i = 9; i <= 17; i++) {
setDummyItem(Material.BLACK_STAINED_GLASS_PANE, i);
@ -92,4 +99,44 @@ public class GameConfigurationInventory extends InteractableInventory {
update();
}
private void updatePlayButton() {
RestrictionHandler restrictionHandler = factory.globalRestrictions();
RestrictionData restrictionData = new RestrictionData(room);
if(restrictionHandler.canPlay(restrictionData)) {
setClickableItem(
ItemStack.builder(restrictionHandler.getWarnings(restrictionData).size() > 0 ? Material.YELLOW_WOOL : Material.GREEN_WOOL)
.displayName(Component.text("Start", NamedTextColor.GREEN))
.lore(restrictionHandler.getWarnings(restrictionData).stream().map(Component::text).collect(Collectors.toList()))
.build(),
8,
itemClick -> {
Game.initialize(factory, itemClick.getPlayer());
},
true
);
} else {
setClickableItem(
ItemStack.builder(Material.RED_WOOL)
.displayName(Component.text("Bedinungen nicht erfült", NamedTextColor.RED))
.lore(
restrictionHandler.getRestrictions()
.stream()
.filter(iRestriction -> iRestriction.calculate(restrictionData).getType().equals(Restriction.Type.FAIL))
.map(iRestriction -> Component.text(iRestriction.calculate(restrictionData).getName()))
.collect(Collectors.toList()))
.build(),
8,
itemClick -> {
itemClick.getPlayer().playSound(Sound.sound(SoundEvent.ENTITY_SILVERFISH_DEATH, Sound.Source.AMBIENT, 1f, 1f));
},
false
);
}
}
}

View File

@ -1,6 +1,7 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config;
import eu.mhsl.minenet.minigames.instance.game.minigame.Minigame;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.RestrictionHandler;
import net.kyori.adventure.text.Component;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.Material;
@ -12,23 +13,31 @@ import java.util.Map;
public interface GameFactory {
Component name();
ConfigManager configuration();
default RestrictionHandler globalRestrictions() {
return new RestrictionHandler();
}
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

@ -1,5 +1,6 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.RestrictionHandler;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
@ -7,10 +8,10 @@ import net.minestom.server.item.Material;
import java.util.List;
public abstract class Option<T> {
private RestrictionHandler restrictionHandler;
private final Material item;
private final String name;
private final String id;
protected T currentValue;
private final List<T> options;
private int pointer = 0;
@ -24,6 +25,15 @@ public abstract class Option<T> {
currentValue = options.get(0);
}
public void setRestrictionHandler(RestrictionHandler restrictionHandler) {
this.restrictionHandler = restrictionHandler;
}
public RestrictionHandler getRestrictionHandler() {
return restrictionHandler;
}
public ItemStack getNext() {
if(++pointer >= options.size()) pointer = 0;
currentValue = options.get(pointer);

View File

@ -1,4 +1,4 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config.options;
package eu.mhsl.minenet.minigames.instance.game.minigame.config.common;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.Option;
import net.minestom.server.item.Material;

View File

@ -1,11 +1,13 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config.options;
package eu.mhsl.minenet.minigames.instance.game.minigame.config.common;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.Option;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.RestrictionHandler;
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,6 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction;
public interface IRestriction {
Restriction calculate(RestrictionData data);
}

View File

@ -0,0 +1,43 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction;
public class Restriction {
final private String name;
final private String description;
final private String warnMessage;
final private Type type;
public Restriction(String name, String description, String warnMessage, Type type) {
this.name = name;
this.description = description;
this.warnMessage = warnMessage;
this.type = type;
if(this.warnMessage == null && this.type.equals(Type.WARN)) {
throw new IllegalStateException("warnMessage cannot be null when RestrictionType is WARN");
}
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String getWarnMessage() {
return warnMessage;
}
public Type getType() {
return type;
}
public enum Type {
OK,
WARN,
FAIL,
}
}

View File

@ -0,0 +1,16 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction;
import eu.mhsl.minenet.minigames.instance.MineNetInstance;
import eu.mhsl.minenet.minigames.instance.room.Room;
public class RestrictionData {
final private Room instance;
public RestrictionData(Room instance) {
this.instance = instance;
}
public MineNetInstance getInstance() {
return instance;
}
}

View File

@ -0,0 +1,42 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
public class RestrictionHandler {
private List<IRestriction> restrictions = new ArrayList<>();
public RestrictionHandler(IRestriction... restrictions) {
this.restrictions = List.of(restrictions);
}
public RestrictionHandler() {
}
public RestrictionHandler addRestriction(IRestriction IRestriction) {
this.restrictions.add(IRestriction);
return this;
}
public List<IRestriction> getRestrictions() {
return restrictions;
}
public boolean canPlay(RestrictionData data) {
return this.restrictions.stream()
.anyMatch(iRestriction -> !iRestriction.calculate(data).getType().equals(Restriction.Type.OK));
}
public List<String> getWarnings(RestrictionData data) {
List<String> warnings = new ArrayList<>();
for (IRestriction r : this.restrictions) {
Restriction calculated = r.calculate(data);
if(!calculated.getType().equals(Restriction.Type.WARN)) continue;
warnings.add(calculated.getWarnMessage());
}
return warnings;
}
}

View File

@ -0,0 +1,24 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.common;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.IRestriction;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.Restriction;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.RestrictionData;
import kotlin.Result;
public class MaximalPlayeramountRestriction implements IRestriction {
final private int max;
public MaximalPlayeramountRestriction(int max) {
this.max = max;
}
@Override
public Restriction calculate(RestrictionData data) {
return new Restriction(
"Maxplayers",
"Maximale spieleranzahl",
null,
data.getInstance().getPlayers().size() > this.max ? Restriction.Type.FAIL : Restriction.Type.OK
);
}
}

View File

@ -0,0 +1,23 @@
package eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.common;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.IRestriction;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.Restriction;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.RestrictionData;
public class MinimalPlayeramountRestriction implements IRestriction {
final int min;
public MinimalPlayeramountRestriction(int min) {
this.min = min;
}
@Override
public Restriction calculate(RestrictionData data) {
return new Restriction(
"Minimal players",
"Minimal amount of players needed",
null,
data.getInstance().getPlayers().size() < min ? Restriction.Type.FAIL : Restriction.Type.OK
);
}
}

View File

@ -4,7 +4,7 @@ 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 eu.mhsl.minenet.minigames.instance.game.minigame.config.common.NumericOption;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.Material;

View File

@ -4,7 +4,7 @@ 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 eu.mhsl.minenet.minigames.instance.game.minigame.config.common.NumericOption;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.Material;

View File

@ -4,6 +4,9 @@ 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.restriction.RestrictionHandler;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.common.MaximalPlayeramountRestriction;
import eu.mhsl.minenet.minigames.instance.game.minigame.config.restriction.common.MinimalPlayeramountRestriction;
import net.kyori.adventure.text.Component;
import net.minestom.server.item.Material;
@ -20,6 +23,13 @@ public class StickFightFactory implements GameFactory {
return null;
}
@Override
public RestrictionHandler globalRestrictions() {
return new RestrictionHandler()
.addRestriction(new MinimalPlayeramountRestriction(2))
.addRestriction(new MaximalPlayeramountRestriction(4));
}
@Override
public Minigame manufacture(Map<String, Option<?>> configuration) {
return new Stickfight();

View File

@ -44,6 +44,6 @@ public class GameSelector extends InteractableEntity {
return;
}
playerEntityInteractEvent.getPlayer().openInventory(new MinigameTypeSelectInventory());
playerEntityInteractEvent.getPlayer().openInventory(new MinigameTypeSelectInventory(room));
}
}

View File

@ -4,6 +4,7 @@ import eu.mhsl.minenet.minigames.instance.game.GameList;
import eu.mhsl.minenet.minigames.instance.game.GameType;
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.instance.room.Room;
import eu.mhsl.minenet.minigames.shared.inventory.InteractableInventory;
import net.kyori.adventure.text.Component;
import net.minestom.server.inventory.InventoryType;
@ -12,8 +13,10 @@ import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
public class MinigameTypeSelectInventory extends InteractableInventory {
public MinigameTypeSelectInventory() {
final private Room room;
public MinigameTypeSelectInventory(Room room) {
super(InventoryType.CHEST_6_ROW, Component.text("MineNet Servernetzwerk"));
this.room = room;
int typeCount = 0;
for (GameType type : GameType.values()) {
@ -54,7 +57,7 @@ public class MinigameTypeSelectInventory extends InteractableInventory {
.meta(metaBuilder -> metaBuilder.hideFlag(ItemHideFlag.HIDE_ATTRIBUTES))
.build(),
gameCount,
itemClick -> itemClick.getPlayer().openInventory(new GameConfigurationInventory(gameFactory))
itemClick -> itemClick.getPlayer().openInventory(new GameConfigurationInventory(room, gameFactory))
);
gameCount++;
}

View File

@ -105,4 +105,3 @@ public class Languages {
}
}
}