diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/SimulatorStorage.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/SimulatorStorage.java index 77c5efb3..858495f2 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/SimulatorStorage.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/SimulatorStorage.java @@ -27,11 +27,18 @@ import de.steamwar.bausystem.linkage.LinkageType; import de.steamwar.bausystem.linkage.Linked; import de.steamwar.bausystem.utils.ItemUtils; import de.steamwar.inventory.SWItem; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.NamespacedKey; +import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import yapion.exceptions.YAPIONException; +import yapion.hierarchy.types.YAPIONObject; +import yapion.parser.YAPIONParser; +import java.io.File; +import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -41,6 +48,9 @@ import java.util.Set; @Linked(LinkageType.DISABLE_LINK) public class SimulatorStorage implements Enable, Disable { + public static final World WORLD = Bukkit.getWorlds().get(0); + private final File simulatorsDir = new File(Bukkit.getWorlds().get(0).getWorldFolder(), "simulators"); + private static NamespacedKey simulatorSelection = SWUtils.getNamespaceKey("simulator_selection"); private static Map tntSimulators = new HashMap<>(); @@ -72,11 +82,36 @@ public class SimulatorStorage implements Enable, Disable { @Override public void enable() { + if (!simulatorsDir.exists()) { + simulatorsDir.mkdir(); + } + File[] files = simulatorsDir.listFiles(); + if (files == null) return; + for (File file : files) { + YAPIONObject yapionObject; + try { + yapionObject = YAPIONParser.parse(file); + } catch (YAPIONException | IOException e) { + continue; + } + if (file.getName().endsWith(".yapion")) { + // TODO: Load old simulators + } else { + String name = file.getName().substring(0, file.getName().length() - ".simulator".length()); + tntSimulators.put(name, new TNTSimulator(yapionObject)); + } + } } @Override public void disable() { - + for (Map.Entry entry : tntSimulators.entrySet()) { + try { + entry.getValue().toYAPION().toFile(new File(simulatorsDir, entry.getKey() + ".simulator")); + } catch (Exception e) { + e.printStackTrace(); + } + } } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/TNTSimulator.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/TNTSimulator.java index 8e61e360..7758cf10 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/TNTSimulator.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/TNTSimulator.java @@ -19,9 +19,48 @@ package de.steamwar.bausystem.features.simulatorn; +import de.steamwar.bausystem.features.simulatorn.tnt.SimulatorElement; +import de.steamwar.bausystem.features.simulatorn.tnt.TNTElement; +import de.steamwar.bausystem.features.simulatorn.tnt.TNTGroup; import org.bukkit.Material; +import yapion.hierarchy.types.YAPIONArray; +import yapion.hierarchy.types.YAPIONObject; +import yapion.hierarchy.types.YAPIONType; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; public class TNTSimulator { - private Material material; + private Material material = Material.TNT; + + private List tntElementList = new ArrayList<>(); + + public TNTSimulator() { + + } + + public TNTSimulator(YAPIONObject yapionObject) { + material = Material.valueOf(yapionObject.getStringOrDefault("material", Material.TNT.name())); + YAPIONArray yapionArray = yapionObject.getArrayOrDefault("tntElements", new YAPIONArray()); + for (YAPIONObject element : yapionArray.streamObject().collect(Collectors.toList())) { + if (element.containsKey("elements", YAPIONType.ARRAY)) { + tntElementList.add(new TNTGroup(element)); + } else { + tntElementList.add(new TNTElement(element)); + } + } + } + + public YAPIONObject toYAPION() { + YAPIONObject yapionObject = new YAPIONObject(); + yapionObject.add("material", material.name()); + YAPIONArray yapionArray = new YAPIONArray(); + for (SimulatorElement element : tntElementList) { + yapionArray.add(element.toYAPION()); + } + yapionObject.add("tntElements", yapionArray); + return yapionObject; + } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/show/SimulatorEntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/show/SimulatorEntityShowMode.java new file mode 100644 index 00000000..2ce67b26 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/show/SimulatorEntityShowMode.java @@ -0,0 +1,61 @@ +package de.steamwar.bausystem.features.simulatorn.show; + +/* + * This file is a part of the SteamWar software. + * + * Copyright (C) 2021 SteamWar.de-Serverteam + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import de.steamwar.bausystem.features.simulator.AbstractSimulatorEntity; +import de.steamwar.bausystem.features.simulatorn.SimulatorStorage; +import de.steamwar.bausystem.shared.Position; +import de.steamwar.bausystem.shared.RoundedPosition; +import de.steamwar.bausystem.shared.ShowMode; +import de.steamwar.bausystem.utils.NMSWrapper; +import org.bukkit.World; +import org.bukkit.entity.Player; +import org.bukkit.util.Vector; + +import java.util.HashMap; +import java.util.Map; + +public class SimulatorEntityShowMode implements ShowMode { + + protected final Player player; + + private final Map entityMap = new HashMap<>(); + + public SimulatorEntityShowMode(Player player) { + this.player = player; + } + + @Override + public void show(Position position) { + RoundedPosition roundedPosition = new RoundedPosition(position); + AbstractSimulatorEntity entity = entityMap.computeIfAbsent(roundedPosition, pos -> createEntity(position.getLocation(), false)); + entity.display(player); + } + + public static AbstractSimulatorEntity createEntity(Vector position, boolean highlight) { + return NMSWrapper.impl.createSimulator(SimulatorStorage.WORLD, position, highlight); + } + + @Override + public void hide() { + entityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); + entityMap.clear(); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/SimulatorElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/SimulatorElement.java index 2e6feb7e..438ea43f 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/SimulatorElement.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/SimulatorElement.java @@ -20,18 +20,20 @@ package de.steamwar.bausystem.features.simulatorn.tnt; import de.steamwar.bausystem.shared.Pair; -import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; +import yapion.hierarchy.types.YAPIONObject; import java.util.Map; public interface SimulatorElement { + YAPIONObject toYAPION(); + void show(Player player); void hide(Player player); ItemStack menu(); - void locations(Map>> result, Vector origin, int tickOffset, World world); // Ticks to subtick order to spawning runnable to count of activations + void locations(Map>> result, Vector origin, int tickOffset); // Ticks to subtick order to spawning runnable to count of activations } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/TNTElement.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/TNTElement.java index 1b32d622..968f8690 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/TNTElement.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/TNTElement.java @@ -20,13 +20,15 @@ package de.steamwar.bausystem.features.simulatorn.tnt; import de.steamwar.bausystem.features.simulator.AbstractSimulatorEntity; +import de.steamwar.bausystem.features.simulatorn.SimulatorStorage; +import de.steamwar.bausystem.features.simulatorn.show.SimulatorEntityShowMode; import de.steamwar.bausystem.shared.Pair; import org.bukkit.Material; -import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.entity.TNTPrimed; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; +import yapion.hierarchy.types.YAPIONObject; import java.util.HashMap; import java.util.Map; @@ -45,9 +47,39 @@ public class TNTElement implements SimulatorElement { private int order = 0; private Material material = Material.TNT; - public TNTElement(Vector position, AbstractSimulatorEntity entity) { + public TNTElement(Vector position) { this.position = position; - this.entity = entity; + this.entity = SimulatorEntityShowMode.createEntity(position, false); + } + + public TNTElement(YAPIONObject yapionObject) { + this.position = new Vector(yapionObject.getDoubleOrDefault("x", 0), yapionObject.getDoubleOrDefault("y", 0), yapionObject.getDoubleOrDefault("z", 0)); + this.entity = SimulatorEntityShowMode.createEntity(position, false); + this.fuseTicks = yapionObject.getIntOrDefault("fuseTicks", 80); + this.count = yapionObject.getIntOrDefault("count", 1); + this.tickOffset = yapionObject.getIntOrDefault("tickOffset", 0); + this.xVelocity = yapionObject.getBooleanOrDefault("xVelocity", false); + this.yVelocity = yapionObject.getBooleanOrDefault("yVelocity", false); + this.zVelocity = yapionObject.getBooleanOrDefault("zVelocity", false); + this.order = yapionObject.getIntOrDefault("order", 0); + this.material = Material.valueOf(yapionObject.getStringOrDefault("material", Material.TNT.name())); + } + + @Override + public YAPIONObject toYAPION() { + YAPIONObject yapionObject = new YAPIONObject(); + yapionObject.add("x", position.getX()); + yapionObject.add("y", position.getY()); + yapionObject.add("z", position.getZ()); + yapionObject.add("fuseTicks", fuseTicks); + yapionObject.add("count", count); + yapionObject.add("tickOffset", tickOffset); + yapionObject.add("xVelocity", xVelocity); + yapionObject.add("yVelocity", yVelocity); + yapionObject.add("zVelocity", zVelocity); + yapionObject.add("order", order); + yapionObject.add("material", material.name()); + return yapionObject; } @Override @@ -66,10 +98,10 @@ public class TNTElement implements SimulatorElement { } @Override - public void locations(Map>> result, Vector origin, int tickOffset, World world) { + public void locations(Map>> result, Vector origin, int tickOffset) { result.computeIfAbsent(this.tickOffset + tickOffset, ignore -> new HashMap<>()) .computeIfAbsent(order, ignore -> new Pair<>(() -> { - world.spawn(position.clone().add(origin).toLocation(world), TNTPrimed.class, tntPrimed -> { + SimulatorStorage.WORLD.spawn(position.clone().add(origin).toLocation(SimulatorStorage.WORLD), TNTPrimed.class, tntPrimed -> { tntPrimed.setFuseTicks(fuseTicks); if (!xVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setX(0)); if (!yVelocity) tntPrimed.setVelocity(tntPrimed.getVelocity().setY(0)); diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/TNTGroup.java b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/TNTGroup.java index a8626030..d968ca62 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/TNTGroup.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/simulatorn/tnt/TNTGroup.java @@ -21,14 +21,16 @@ package de.steamwar.bausystem.features.simulatorn.tnt; import de.steamwar.bausystem.shared.Pair; import org.bukkit.Material; -import org.bukkit.World; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; +import yapion.hierarchy.types.YAPIONArray; +import yapion.hierarchy.types.YAPIONObject; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; public class TNTGroup implements SimulatorElement { @@ -41,6 +43,32 @@ public class TNTGroup implements SimulatorElement { this.position = position; } + public TNTGroup(YAPIONObject yapionObject) { + this.position = new Vector(yapionObject.getDoubleOrDefault("x", 0), yapionObject.getDoubleOrDefault("y", 0), yapionObject.getDoubleOrDefault("z", 0)); + this.tickOffset = yapionObject.getIntOrDefault("tickOffset", 0); + this.material = Material.getMaterial(yapionObject.getStringOrDefault("material", "BARREL")); + YAPIONArray elements = yapionObject.getArrayOrDefault("elements", new YAPIONArray()); + for (YAPIONObject element : elements.streamObject().collect(Collectors.toList())) { + this.elements.add(new TNTElement(element)); + } + } + + @Override + public YAPIONObject toYAPION() { + YAPIONObject yapionObject = new YAPIONObject(); + yapionObject.add("x", position.getX()); + yapionObject.add("y", position.getY()); + yapionObject.add("z", position.getZ()); + yapionObject.add("tickOffset", tickOffset); + yapionObject.add("material", material.name()); + YAPIONArray yapionArray = new YAPIONArray(); + for (TNTElement element : elements) { + yapionArray.add(element.toYAPION()); + } + yapionObject.add("elements", yapionArray); + return yapionObject; + } + @Override public void show(Player player) { elements.forEach(tntElement -> { @@ -61,9 +89,9 @@ public class TNTGroup implements SimulatorElement { } @Override - public void locations(Map>> result, Vector origin, int tickOffset, World world) { + public void locations(Map>> result, Vector origin, int tickOffset) { elements.forEach(tntElement -> { - tntElement.locations(result, origin.clone().add(position), this.tickOffset + tickOffset, world); + tntElement.locations(result, origin.clone().add(position), this.tickOffset + tickOffset); }); } }