Arrows Stopping in Techhider Blocks #208
@ -80,7 +80,6 @@ public class Config {
|
||||
public static final int ArenaMaxX;
|
||||
public static final int ArenaMaxZ;
|
||||
public static final boolean GroundWalkable;
|
||||
public static final int ArrowTechhiderCollision;
|
||||
|
||||
//schematic parameter
|
||||
public static final boolean RanksEnabled;
|
||||
@ -189,7 +188,6 @@ public class Config {
|
||||
double teamBlueSpawnOffsetX = worldconfig.getDouble("Arena.SpawnOffset.x");
|
||||
double teamBlueSpawnOffsetY = worldconfig.getDouble("Arena.SpawnOffset.y");
|
||||
double teamBlueSpawnOffsetZ = worldconfig.getDouble("Arena.SpawnOffset.z");
|
||||
ArrowTechhiderCollision = config.getInt("Times.ArrowTechhiderCollision");
|
||||
|
||||
RanksEnabled = config.getBoolean("Schematic.RanksEnabled");
|
||||
SchematicType = de.steamwar.sql.SchematicType.fromDB(config.getString("Schematic.SchematicType"));
|
||||
|
@ -24,48 +24,43 @@ import de.steamwar.fightsystem.FightSystem;
|
||||
import de.steamwar.fightsystem.states.FightState;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.entity.AbstractArrow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Arrow;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ArrowStopper extends BasicListener {
|
||||
|
||||
private BukkitTask task;
|
||||
|
||||
private static final HashMap<Entity, Location> LAST_LOCATION = new HashMap<>();
|
||||
private static final Vector NULL_VECTOR = new Vector(0, 0, 0);
|
||||
|
||||
public ArrowStopper() {
|
||||
super(Config.ArrowTechhiderCollision != 0 ? EnumSet.of(FightState.RUNNING) : EnumSet.noneOf(FightState.class));
|
||||
super(Config.TechhiderActive ? EnumSet.of(FightState.RUNNING) : EnumSet.noneOf(FightState.class));
|
||||
}
|
||||
|
||||
Lixfel
hat
Die Init-Methode kann gestrichen werden und alles in den Konstruktor (der dann Public wird) übernommen werden. Konstruktor wäre dann super(Config.ArrowTechhiderCollision != 0 ? EnumSet.of(RUNNING), EnumSet.empty()); Die Init-Methode kann gestrichen werden und alles in den Konstruktor (der dann Public wird) übernommen werden. Konstruktor wäre dann super(Config.ArrowTechhiderCollision != 0 ? EnumSet.of(RUNNING), EnumSet.empty());
|
||||
private void run() {
|
||||
Iterator<Map.Entry<Entity, Location>> iterator = LAST_LOCATION.entrySet().iterator();
|
||||
Iterator<Arrow> iterator = Bukkit.getWorlds().get(0).getEntitiesByClass(Arrow.class).iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Lixfel
hat
BasicListener übernimmt im Konstruktor schon das Registrieren als StateDependent BasicListener übernimmt im Konstruktor schon das Registrieren als StateDependent
|
||||
Map.Entry<Entity, Location> e = iterator.next();
|
||||
Entity entity = e.getKey();
|
||||
if(checkBlocks(entity.getLocation().getBlock(), e.getValue().getBlock())){
|
||||
entity.remove();
|
||||
Arrow arrow = iterator.next();
|
||||
if(isValidEntity(arrow))
|
||||
continue;
|
||||
|
||||
Location prevLocation = arrow.getLocation().toVector().subtract(arrow.getVelocity()).toLocation(arrow.getWorld());
|
||||
if(arrow.getTicksLived() == 0)
|
||||
prevLocation = ((Player) arrow.getShooter()).getEyeLocation();
|
||||
if(checkBlocks(arrow.getLocation().getBlock(), prevLocation.getBlock())) {
|
||||
Lixfel
hat
Das dürfte nichts bringen, da der Iterator eigens auf einem für diese Aufgabe erstellter ArrayList läuft. Die Zeile drüber reicht schon vollkommen aus, um den Pfeil zu entfernen. Das dürfte nichts bringen, da der Iterator eigens auf einem für diese Aufgabe erstellter ArrayList läuft. Die Zeile drüber reicht schon vollkommen aus, um den Pfeil zu entfernen.
|
||||
arrow.remove();
|
||||
Lixfel
hat
Das müsste aus meiner Java-Erfahrung heraus auf jeden fall eine ConcurrentModificationException werfen Das müsste aus meiner Java-Erfahrung heraus auf jeden fall eine ConcurrentModificationException werfen
|
||||
iterator.remove();
|
||||
Lixfel
hat
Da musst du iterator.remove() verwenden. Da musst du iterator.remove() verwenden.
|
||||
} else {
|
||||
if(isValidEntity(entity, e)) {
|
||||
iterator.remove();
|
||||
}else {
|
||||
LAST_LOCATION.replace(e.getKey(), e.getKey().getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Lixfel
hat
Die Verschachtelung kann man evtl. durch eine else if-Konstruktion ersetzen. Die Verschachtelung kann man evtl. durch eine else if-Konstruktion ersetzen.
|
||||
|
||||
Lixfel
hat
Ebenfalls. Nutze einen Iterator. Ebenfalls. Nutze einen Iterator.
|
||||
@EventHandler()
|
||||
public void onEntityShootBow(EntityShootBowEvent event) {
|
||||
LAST_LOCATION.put(event.getProjectile(), event.getEntity().getEyeLocation());
|
||||
}
|
||||
|
||||
@Override
|
||||
Lixfel
hat
Auch hier wieder: Iterator benutzen. Auch hier wieder: Iterator benutzen.
|
||||
public void enable() {
|
||||
super.enable();
|
||||
Lixfel
hat
Ich denke, dass du auch hier den Iterator benutzen musst, weiß aber gerade nicht, ob eine Änderung da überhaupt vorgesehen ist. Ich denke, dass du auch hier den Iterator benutzen musst, weiß aber gerade nicht, ob eine Änderung da überhaupt vorgesehen ist.
|
||||
@ -76,7 +71,6 @@ public class ArrowStopper extends BasicListener {
|
||||
public void disable() {
|
||||
super.disable();
|
||||
task.cancel();
|
||||
LAST_LOCATION.clear();
|
||||
}
|
||||
|
||||
private boolean checkBlocks(Block start, Block end) {
|
||||
@ -113,9 +107,12 @@ public class ArrowStopper extends BasicListener {
|
||||
return Config.HiddenBlockTags.contains(block.getType().name());
|
||||
}
|
||||
|
||||
private boolean isValidEntity(Entity entity, Map.Entry<Entity, Location> entry) {
|
||||
return entity.getTicksLived() > Config.ArrowTechhiderCollision ||
|
||||
((AbstractArrow) entity).isInBlock() ||
|
||||
entity.getLocation().equals(entry.getValue());
|
||||
private boolean isValidEntity(Arrow entity) {
|
||||
boolean teamFrom = entity.getVelocity().getZ() > 0;
|
||||
boolean overMid = entity.getLocation().getZ() > Config.SpecSpawn.getZ();
|
||||
boolean otherSide = teamFrom == overMid;
|
||||
return otherSide ||
|
||||
entity.isInBlock() ||
|
||||
entity.getVelocity().equals(NULL_VECTOR);
|
||||
}
|
||||
}
|
||||
|
Statt der (aufwändigen) Verwaltung von LAST_LOCATIONS wäre es wsl. eleganter, mit entity.getVelocity() / 20 zu arbeiten. Das dürfte einiges an Verwaltungsaufwand sparen. Man könnte dann wsl. in run auch mit world.getEntitiesWithClass() arbeiten.
?, entity.getVelocity() gibt einen Vektor zurück, welchen man nicht einfach durch 20 teilen kann
.divide?
braucht einen Vektor
Du brauchst ja sowieso nur die einzelnen Komponenten, also teile doch einfach die durch 20....