diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java index 40732d54..a2162612 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/TraceCommand.java @@ -28,13 +28,16 @@ import de.steamwar.bausystem.features.tracer.show.Record; import de.steamwar.bausystem.features.tracer.show.*; import de.steamwar.bausystem.features.tracer.show.mode.BlockShowMode; import de.steamwar.bausystem.features.tracer.show.mode.ParticleShowMode; +import de.steamwar.bausystem.features.tracer.show.mode.RawEntityShowMode; import de.steamwar.bausystem.features.tracer.show.mode.TraceEntityShowMode; import de.steamwar.bausystem.linkage.LinkageType; import de.steamwar.bausystem.linkage.Linked; +import de.steamwar.bausystem.shared.ShowMode; import de.steamwar.bausystem.utils.ListChatView; import de.steamwar.command.SWCommand; import de.steamwar.command.SWCommandUtils; import de.steamwar.command.TypeMapper; +import lombok.AllArgsConstructor; import lombok.NonNull; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; @@ -46,6 +49,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.BiFunction; @Linked(LinkageType.COMMAND) public class TraceCommand extends SWCommand { @@ -313,10 +317,19 @@ public class TraceCommand extends SWCommand { internalShow(p, ShowModeType.PARTICLE, showModeParameterTypes); } + @Register({"show", "raw"}) + public void rawShowEntityCommand(Player p, ShowModeParameterType... showModeParameterTypes) { + internalShow(p, ShowModeType.RAW_ENTITY, showModeParameterTypes); + } + + @AllArgsConstructor private enum ShowModeType { - ENTITY, - PARTICLE, - BLOCK + ENTITY(TraceEntityShowMode::new), + RAW_ENTITY(RawEntityShowMode::new), + PARTICLE(ParticleShowMode::new), + BLOCK(BlockShowMode::new); + + private BiFunction> showModeBiFunction; } private void internalShow(Player p, @NonNull ShowModeType showModeType, ShowModeParameterType... showModeParameterTypes) { @@ -325,20 +338,7 @@ public class TraceCommand extends SWCommand { for (ShowModeParameterType showModeParameterType : showModeParameterTypes) { showModeParameterType.getShowModeParameterConsumer().accept(showModeParameter); } - switch (showModeType) { - case BLOCK: - TraceShowManager.show(p, new BlockShowMode(p, showModeParameter)); - break; - case PARTICLE: - TraceShowManager.show(p, new ParticleShowMode(p, showModeParameter)); - break; - case ENTITY: - TraceShowManager.show(p, new TraceEntityShowMode(p, showModeParameter)); - break; - default: - BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW_UNKNOWN", p); - return; - } + TraceShowManager.show(p, showModeType.showModeBiFunction.apply(p, showModeParameter)); BauSystem.MESSAGE.send("TRACE_MESSAGE_SHOW", p); } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/FactoredEntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/FactoredEntityShowMode.java new file mode 100644 index 00000000..ed03c9d8 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/FactoredEntityShowMode.java @@ -0,0 +1,129 @@ +/* + * 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 . + */ + +package de.steamwar.bausystem.features.tracer.show.mode; + +import de.steamwar.bausystem.features.tracer.AbstractTraceEntity; +import de.steamwar.bausystem.features.tracer.TNTPosition; +import de.steamwar.bausystem.features.tracer.TNTTracer_15; +import de.steamwar.bausystem.features.tracer.show.ShowModeParameter; +import de.steamwar.bausystem.shared.RoundedPosition; +import de.steamwar.bausystem.shared.ShowMode; +import de.steamwar.core.VersionedCallable; +import org.bukkit.entity.Player; +import org.bukkit.util.Consumer; +import org.bukkit.util.Vector; + +import java.util.HashMap; +import java.util.Map; + +public abstract class FactoredEntityShowMode implements ShowMode { + + private int factor; + + protected final Player player; + protected final ShowModeParameter showModeParameter; + + private final Map tntEntityMap = new HashMap<>(); + private final Map updateEntityMap = new HashMap<>(); + + protected FactoredEntityShowMode(Player player, ShowModeParameter showModeParameter, int factor) { + this.player = player; + this.showModeParameter = showModeParameter; + this.factor = factor; + } + + @Override + public void show(TNTPosition position) { + if (showModeParameter.isExplodeOnly()) { + if (!position.isExploded()) { + return; + } + RoundedPosition roundedPosition = new RoundedPosition(position, factor); + AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); + entity.display(player, position.isExploded()); + return; + } + if (!showModeParameter.isWater() && position.isExploded() && checkWater(position.getLocation())) { + // Basic + for (TNTPosition pos : position.getRecord().getPositions()) { + RoundedPosition roundedPosition = new RoundedPosition(pos, factor); + tntEntityMap.computeIfPresent(roundedPosition, (p, tnt) -> { + return tnt.hide(player, false) ? null : tnt; + }); + } + // Advanced + for (TNTPosition pos : position.getRecord().getPositions()) { + applyOnPosition(pos, updatePointPosition -> { + updateEntityMap.computeIfPresent(new RoundedPosition(updatePointPosition, factor), (p, point) -> { + return point.hide(player, false) ? null : point; + }); + }); + } + return; + } + + RoundedPosition roundedPosition = new RoundedPosition(position, factor); + AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); + entity.display(player, position.isExploded()); + + applyOnPosition(position, updatePointPosition -> { + updateEntityMap.computeIfAbsent(new RoundedPosition(updatePointPosition, factor), pos -> { + return createEntity(player, updatePointPosition, false); + }).display(player, false); + }); + } + + private boolean checkWater(Vector position) { + return VersionedCallable.call(new VersionedCallable<>(() -> TNTTracer_15.inWater(player.getWorld(), position), 15)); + } + + public static AbstractTraceEntity createEntity(Player player, Vector position, boolean tnt) { + return VersionedCallable.call(new VersionedCallable<>(() -> TNTTracer_15.create(player.getWorld(), position, tnt), 15)); + } + + private void applyOnPosition(TNTPosition position, Consumer function) { + if (position.getPreviousLocation() == null) return; + + if (showModeParameter.isInterpolate_Y()) { + Vector updatePointY = position.getPreviousLocation().clone().setY(position.getLocation().getY()); + if (!position.getLocation().equals(updatePointY)) { + function.accept(updatePointY); + } + } + + if (showModeParameter.isInterpolate_XZ()) { + Vector movement = position.getLocation().clone().subtract(position.getPreviousLocation()); + Vector updatePointXZ = Math.abs(movement.getX()) > Math.abs(movement.getZ()) + ? position.getLocation().clone().setZ(position.getPreviousLocation().getZ()) + : position.getLocation().clone().setX(position.getPreviousLocation().getX()); + if (!position.getLocation().equals(updatePointXZ)) { + function.accept(updatePointXZ); + } + } + } + + @Override + public void hide() { + tntEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); + tntEntityMap.clear(); + updateEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); + updateEntityMap.clear(); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/RawEntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/RawEntityShowMode.java new file mode 100644 index 00000000..98e4c6d8 --- /dev/null +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/RawEntityShowMode.java @@ -0,0 +1,32 @@ +/* + * + * This file is a part of the SteamWar software. + * + * Copyright (C) 2020 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 . + * / + */ + +package de.steamwar.bausystem.features.tracer.show.mode; + +import de.steamwar.bausystem.features.tracer.show.ShowModeParameter; +import org.bukkit.entity.Player; + +public class RawEntityShowMode extends FactoredEntityShowMode { + + public RawEntityShowMode(Player player, ShowModeParameter showModeParameter) { + super(player, showModeParameter, 1000000); + } +} diff --git a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/TraceEntityShowMode.java b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/TraceEntityShowMode.java index 6e7801ac..a5decb5c 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/TraceEntityShowMode.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/features/tracer/show/mode/TraceEntityShowMode.java @@ -21,108 +21,12 @@ package de.steamwar.bausystem.features.tracer.show.mode; -import de.steamwar.bausystem.features.tracer.AbstractTraceEntity; -import de.steamwar.bausystem.features.tracer.TNTPosition; -import de.steamwar.bausystem.features.tracer.TNTTracer_15; import de.steamwar.bausystem.features.tracer.show.ShowModeParameter; -import de.steamwar.bausystem.shared.RoundedPosition; -import de.steamwar.bausystem.shared.ShowMode; -import de.steamwar.core.VersionedCallable; import org.bukkit.entity.Player; -import org.bukkit.util.Consumer; -import org.bukkit.util.Vector; -import java.util.HashMap; -import java.util.Map; - -public class TraceEntityShowMode implements ShowMode { - - protected final Player player; - protected final ShowModeParameter showModeParameter; - - private final Map tntEntityMap = new HashMap<>(); - private final Map updateEntityMap = new HashMap<>(); +public class TraceEntityShowMode extends FactoredEntityShowMode { public TraceEntityShowMode(Player player, ShowModeParameter showModeParameter) { - this.player = player; - this.showModeParameter = showModeParameter; - } - - @Override - public void show(TNTPosition position) { - if (showModeParameter.isExplodeOnly()) { - if (!position.isExploded()) { - return; - } - RoundedPosition roundedPosition = new RoundedPosition(position); - AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); - entity.display(player, position.isExploded()); - return; - } - if (!showModeParameter.isWater() && position.isExploded() && checkWater(position.getLocation())) { - // Basic - for (TNTPosition pos : position.getRecord().getPositions()) { - RoundedPosition roundedPosition = new RoundedPosition(pos); - tntEntityMap.computeIfPresent(roundedPosition, (p, tnt) -> { - return tnt.hide(player, false) ? null : tnt; - }); - } - // Advanced - for (TNTPosition pos : position.getRecord().getPositions()) { - applyOnPosition(pos, updatePointPosition -> { - updateEntityMap.computeIfPresent(new RoundedPosition(updatePointPosition), (p, point) -> { - return point.hide(player, false) ? null : point; - }); - }); - } - return; - } - - RoundedPosition roundedPosition = new RoundedPosition(position); - AbstractTraceEntity entity = tntEntityMap.computeIfAbsent(roundedPosition, pos -> createEntity(player, position.getLocation(), true)); - entity.display(player, position.isExploded()); - - applyOnPosition(position, updatePointPosition -> { - updateEntityMap.computeIfAbsent(new RoundedPosition(updatePointPosition), pos -> { - return createEntity(player, updatePointPosition, false); - }).display(player, false); - }); - } - - private boolean checkWater(Vector position) { - return VersionedCallable.call(new VersionedCallable<>(() -> TNTTracer_15.inWater(player.getWorld(), position), 15)); - } - - public static AbstractTraceEntity createEntity(Player player, Vector position, boolean tnt) { - return VersionedCallable.call(new VersionedCallable<>(() -> TNTTracer_15.create(player.getWorld(), position, tnt), 15)); - } - - private void applyOnPosition(TNTPosition position, Consumer function) { - if (position.getPreviousLocation() == null) return; - - if (showModeParameter.isInterpolate_Y()) { - Vector updatePointY = position.getPreviousLocation().clone().setY(position.getLocation().getY()); - if (!position.getLocation().equals(updatePointY)) { - function.accept(updatePointY); - } - } - - if (showModeParameter.isInterpolate_XZ()) { - Vector movement = position.getLocation().clone().subtract(position.getPreviousLocation()); - Vector updatePointXZ = Math.abs(movement.getX()) > Math.abs(movement.getZ()) - ? position.getLocation().clone().setZ(position.getPreviousLocation().getZ()) - : position.getLocation().clone().setX(position.getPreviousLocation().getX()); - if (!position.getLocation().equals(updatePointXZ)) { - function.accept(updatePointXZ); - } - } - } - - @Override - public void hide() { - tntEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); - tntEntityMap.clear(); - updateEntityMap.forEach((roundedPosition, abstractTraceEntity) -> abstractTraceEntity.hide(player, true)); - updateEntityMap.clear(); + super(player, showModeParameter, 10); } } diff --git a/BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java b/BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java index 55e791d3..c803bb9a 100644 --- a/BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java +++ b/BauSystem_Main/src/de/steamwar/bausystem/shared/RoundedPosition.java @@ -35,16 +35,30 @@ public class RoundedPosition { this(position.getLocation().getX(), position.getLocation().getY(), position.getLocation().getZ()); } + public RoundedPosition(Position position, int factor) { + this(position.getLocation().getX(), position.getLocation().getY(), position.getLocation().getZ(), factor); + } + public RoundedPosition(Vector vector) { this(vector.getX(), vector.getY(), vector.getZ()); } + public RoundedPosition(Vector vector, int factor) { + this(vector.getX(), vector.getY(), vector.getZ(), factor); + } + public RoundedPosition(double x, double y, double z) { this.x = (int) (x * factor); this.y = (int) (y * factor); this.z = (int) (z * factor); } + public RoundedPosition(double x, double y, double z, int factor) { + this.x = (int) (x * factor); + this.y = (int) (y * factor); + this.z = (int) (z * factor); + } + @Override public boolean equals(Object o) { if (this == o) return true;