Add initial MultiTick implementation Signed-off-by: yoyosource <yoyosource@nidido.de>
Dieser Commit ist enthalten in:
Ursprung
1af342d2c3
Commit
d09c4970a0
@ -20,16 +20,16 @@
|
||||
package de.steamwar.bausystem.features.simulator.preview;
|
||||
|
||||
import de.steamwar.bausystem.features.simulator.TNTData;
|
||||
import de.steamwar.bausystem.features.simulator.preview.Simulator;
|
||||
import de.steamwar.bausystem.shared.Pair;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Simulator15 implements Simulator {
|
||||
|
||||
@Override
|
||||
public PreviewRecord run(Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> toCalculate) {
|
||||
return null;
|
||||
public void run(Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> toCalculate, Consumer<PreviewRecord> consumer) {
|
||||
consumer.accept(null);
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,9 @@ public class Explosion {
|
||||
int z = TNT.floor(o);
|
||||
|
||||
Material material = Simulator19.getBlockType(x, y, z);
|
||||
h -= (material.getBlastResistance() + 0.3F) * 0.3F;
|
||||
if (!material.isAir()) {
|
||||
h -= (material.getBlastResistance() + 0.3F) * 0.3F;
|
||||
}
|
||||
if (WATER_LOGABLE.contains(material)) {
|
||||
Waterlogged waterlogged = (Waterlogged) Simulator19.getBlockData(x, y, z);
|
||||
if (waterlogged.isWaterlogged()) {
|
||||
|
@ -32,6 +32,7 @@ import org.bukkit.util.VoxelShape;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Simulator19 implements Simulator {
|
||||
|
||||
@ -60,11 +61,9 @@ public class Simulator19 implements Simulator {
|
||||
private static final Map<Pos, VoxelShape> COLLISION_DATA_MAP = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public synchronized PreviewRecord run(Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> toCalculate) {
|
||||
public void run(Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> toCalculate, Consumer<PreviewRecord> consumer) { // TODO: Implement multi tick calculation max 40 ms per tick
|
||||
if (toCalculate == null) return;
|
||||
PreviewRecord previewRecord = new PreviewRecord();
|
||||
if (toCalculate == null) {
|
||||
return previewRecord;
|
||||
}
|
||||
int currentTick = 0;
|
||||
|
||||
Map<TNT, Record.TNTRecord> recordMap = new HashMap<>();
|
||||
@ -118,7 +117,7 @@ public class Simulator19 implements Simulator {
|
||||
accessed = 0;
|
||||
cacheMisses = 0;
|
||||
aired = 0;
|
||||
return previewRecord;
|
||||
consumer.accept(previewRecord);
|
||||
}
|
||||
|
||||
public static Material getBlockType(int x, int y, int z) { // Get BlockType of Chunk Data array?
|
||||
|
@ -24,11 +24,12 @@ import de.steamwar.bausystem.shared.Pair;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Simulator20 implements Simulator {
|
||||
|
||||
@Override
|
||||
public PreviewRecord run(Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> toCalculate) {
|
||||
return null;
|
||||
public void run(Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> toCalculate, Consumer<PreviewRecord> consumer) {
|
||||
consumer.accept(null);
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import de.steamwar.bausystem.utils.RayTraceUtils;
|
||||
import de.steamwar.entity.REntity;
|
||||
import de.steamwar.entity.REntityServer;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TNTPrimed;
|
||||
@ -58,6 +59,7 @@ public class TNTSimulator {
|
||||
|
||||
private List<SimulatorElement> tntElementList = new ArrayList<>();
|
||||
|
||||
private boolean currentlyCalculating = false;
|
||||
private PreviewRecord previewRecord = null;
|
||||
|
||||
public TNTSimulator() {
|
||||
@ -120,21 +122,36 @@ public class TNTSimulator {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasPreview(Player player) {
|
||||
return previewRecord != null && previewRecord.has(player);
|
||||
}
|
||||
|
||||
public void calcPreview(boolean force) {
|
||||
if (!force && previewRecord == null) {
|
||||
return;
|
||||
}
|
||||
if (currentlyCalculating) return;
|
||||
currentlyCalculating = true;
|
||||
|
||||
PreviewRecord newRecord = Simulator.impl.run(locations());
|
||||
PreviewRecord oldRecord = previewRecord;
|
||||
previewRecord = newRecord;
|
||||
if (newRecord == null) return;
|
||||
if (oldRecord != null) {
|
||||
oldRecord.getPlayers().forEach(player -> {
|
||||
oldRecord.hide(player);
|
||||
newRecord.show(player);
|
||||
});
|
||||
}
|
||||
Simulator.impl.run(locations(true), newRecord -> {
|
||||
boolean recalculate = currentlyCalculating;
|
||||
currentlyCalculating = false;
|
||||
|
||||
PreviewRecord oldRecord = previewRecord;
|
||||
previewRecord = newRecord;
|
||||
if (newRecord == null) return;
|
||||
if (oldRecord != null) {
|
||||
oldRecord.getPlayers().forEach(player -> {
|
||||
oldRecord.hide(player);
|
||||
newRecord.show(player);
|
||||
});
|
||||
}
|
||||
if (recalculate) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
calcPreview(force);
|
||||
}, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public List<REntity> getEntities() {
|
||||
@ -239,10 +256,10 @@ public class TNTSimulator {
|
||||
TNTElementGUI.open(player, tntElement, null);
|
||||
}
|
||||
|
||||
public Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> locations() {
|
||||
public Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> locations(boolean allowFrozen) {
|
||||
Map<Integer, Map<Integer, Set<Pair<TNTData, Integer>>>> result = new HashMap<>();
|
||||
for (SimulatorElement element : tntElementList) {
|
||||
if (element.locations(result)) {
|
||||
if (element.locations(result) && !allowFrozen) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -267,7 +284,7 @@ public class TNTSimulator {
|
||||
|
||||
public void start(Player p) {
|
||||
Region region = Region.getRegion(p.getLocation());
|
||||
Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> result = locations();
|
||||
Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> result = locations(false);
|
||||
if (result == null) {
|
||||
BauSystem.MESSAGE.send("SIMULATOR_REGION_FROZEN", p);
|
||||
return;
|
||||
|
@ -19,14 +19,19 @@
|
||||
|
||||
package de.steamwar.bausystem.features.simulator;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection;
|
||||
import com.comphenix.tinyprotocol.TinyProtocol;
|
||||
import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.bausystem.features.simulator.gui.SimulatorSelectionGUI;
|
||||
import de.steamwar.bausystem.region.Region;
|
||||
import de.steamwar.bausystem.shared.Pair;
|
||||
import de.steamwar.bausystem.utils.ItemUtils;
|
||||
import de.steamwar.bausystem.utils.PlayerMovementWrapper;
|
||||
import de.steamwar.bausystem.utils.RayTraceUtils;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -39,6 +44,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@Linked
|
||||
public class TNTSimulatorListener implements Listener {
|
||||
@ -71,6 +77,25 @@ public class TNTSimulatorListener implements Listener {
|
||||
return RayTraceUtils.traceREntity(player, to, simulator.getEntities());
|
||||
}
|
||||
|
||||
private static final Class<?> position = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPosition");
|
||||
private static final Class<?> positionLook = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInFlying$PacketPlayInPositionLook");
|
||||
|
||||
{
|
||||
BiFunction<Player, Object, Object> positionSetter = (player, o) -> {
|
||||
if (player.getGameMode() == GameMode.SPECTATOR) return o;
|
||||
TNTSimulator tntSimulator = currentSimulator.get(player);
|
||||
if (tntSimulator == null) return o;
|
||||
if (!tntSimulator.hasPreview(player)) return o;
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
PlayerMovementWrapper.impl.setPosition(player, o);
|
||||
}, 0L);
|
||||
return null;
|
||||
};
|
||||
|
||||
TinyProtocol.instance.addFilter(position, positionSetter);
|
||||
TinyProtocol.instance.addFilter(positionLook, positionSetter);
|
||||
}
|
||||
|
||||
private void hideShow(Player player, Pair<TNTSimulator, Boolean> simulatorPair) {
|
||||
TNTSimulator simulator = simulatorPair.getKey();
|
||||
TNTSimulator tntSimulator = currentSimulator.remove(player);
|
||||
|
@ -59,14 +59,13 @@ public class PreviewRecord {
|
||||
p.sendBlockChange(vector.toLocation(player.getWorld()), AIR_BLOCK_DATA);
|
||||
});
|
||||
ShowModeParameter showModeParameter = new ShowModeParameter();
|
||||
showModeParameter.enableInterpolateY();
|
||||
showModeParameter.enableInterpolateXZ();
|
||||
showModeParameter.enableWater();
|
||||
showModeParameter.enableCount();
|
||||
showModeParameter.setTntPositionMaterial(Material.RED_STAINED_GLASS);
|
||||
showModeParameter.setUpdatePositionMaterial(Material.WHITE_STAINED_GLASS);
|
||||
showModeParameter.setExplosePositionMaterial(Material.RED_WOOL);
|
||||
return new EntityShowMode(p, showModeParameter, 10);
|
||||
showModeParameter.setTntPositionMaterial(Material.WHITE_STAINED_GLASS);
|
||||
showModeParameter.setExplosePositionMaterial(Material.RED_STAINED_GLASS);
|
||||
EntityShowMode entityShowMode = new EntityShowMode(p, showModeParameter, 10);
|
||||
record.getTnt().forEach(tntRecord -> tntRecord.getPositions().forEach(entityShowMode::show));
|
||||
return entityShowMode;
|
||||
});
|
||||
}
|
||||
|
||||
@ -81,4 +80,8 @@ public class PreviewRecord {
|
||||
}
|
||||
return showModeMap.isEmpty();
|
||||
}
|
||||
|
||||
public boolean has(Player player) {
|
||||
return showModeMap.containsKey(player);
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,10 @@ import de.steamwar.core.VersionDependent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface Simulator {
|
||||
Simulator impl = VersionDependent.getVersionImpl(BauSystem.getInstance());
|
||||
|
||||
PreviewRecord run(Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> toCalculate);
|
||||
void run(Pair<Integer, Map<Integer, List<List<Pair<TNTData, Integer>>>>> toCalculate, Consumer<PreviewRecord> finished);
|
||||
}
|
||||
|
@ -200,14 +200,11 @@ public class TNTElement implements SimulatorElement {
|
||||
if (disabled) return false;
|
||||
Location location = getPosition().toLocation(SimulatorStorage.WORLD);
|
||||
Region thisRegion = Region.getRegion(location);
|
||||
if (thisRegion.getFlagStorage().get(Flag.FREEZE) == FreezeMode.ACTIVE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
result.computeIfAbsent(getTickOffset(), ignore -> new HashMap<>())
|
||||
.computeIfAbsent(OrderUtils.order(order), ignore -> new HashSet<>())
|
||||
.add(new Pair<>(new TNTData(location, fuseTicks, xVelocity, yVelocity, zVelocity), count));
|
||||
return false;
|
||||
return thisRegion.getFlagStorage().get(Flag.FREEZE) == FreezeMode.ACTIVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -149,12 +149,13 @@ public class TNTGroup implements SimulatorElement {
|
||||
@Override
|
||||
public boolean locations(Map<Integer, Map<Integer, Set<Pair<TNTData, Integer>>>> result) {
|
||||
if (disabled) return false;
|
||||
boolean frozen = false;
|
||||
for (TNTElement element : elements) {
|
||||
if (element.locations(result)) {
|
||||
return true;
|
||||
frozen = true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return frozen;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -118,7 +118,7 @@ public class XrayCommand extends SWCommand implements Listener, ScoreboardElemen
|
||||
if (hidden.containsKey(region) && hidden.get(region).contains(player)) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
PlayerMovementWrapper.impl.setPosition(player, o);
|
||||
}, 1L);
|
||||
}, 0L);
|
||||
return null;
|
||||
}
|
||||
return o;
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren