Arrows Stopping in Techhider Blocks #208
@ -80,7 +80,6 @@ public class Config {
|
|||||||
public static final int ArenaMaxX;
|
public static final int ArenaMaxX;
|
||||||
public static final int ArenaMaxZ;
|
public static final int ArenaMaxZ;
|
||||||
public static final boolean GroundWalkable;
|
public static final boolean GroundWalkable;
|
||||||
public static final int ArrowTechhiderCollision;
|
|
||||||
|
|
||||||
//schematic parameter
|
//schematic parameter
|
||||||
public static final boolean RanksEnabled;
|
public static final boolean RanksEnabled;
|
||||||
@ -189,7 +188,6 @@ public class Config {
|
|||||||
double teamBlueSpawnOffsetX = worldconfig.getDouble("Arena.SpawnOffset.x");
|
double teamBlueSpawnOffsetX = worldconfig.getDouble("Arena.SpawnOffset.x");
|
||||||
double teamBlueSpawnOffsetY = worldconfig.getDouble("Arena.SpawnOffset.y");
|
double teamBlueSpawnOffsetY = worldconfig.getDouble("Arena.SpawnOffset.y");
|
||||||
double teamBlueSpawnOffsetZ = worldconfig.getDouble("Arena.SpawnOffset.z");
|
double teamBlueSpawnOffsetZ = worldconfig.getDouble("Arena.SpawnOffset.z");
|
||||||
ArrowTechhiderCollision = config.getInt("Times.ArrowTechhiderCollision");
|
|
||||||
|
|
||||||
RanksEnabled = config.getBoolean("Schematic.RanksEnabled");
|
RanksEnabled = config.getBoolean("Schematic.RanksEnabled");
|
||||||
SchematicType = de.steamwar.sql.SchematicType.fromDB(config.getString("Schematic.SchematicType"));
|
SchematicType = de.steamwar.sql.SchematicType.fromDB(config.getString("Schematic.SchematicType"));
|
||||||
|
@ -24,46 +24,41 @@ import de.steamwar.fightsystem.FightSystem;
|
|||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.entity.AbstractArrow;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Arrow;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.entity.EntityShootBowEvent;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ArrowStopper extends BasicListener {
|
public class ArrowStopper extends BasicListener {
|
||||||
|
|
||||||
private BukkitTask task;
|
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() {
|
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() {
|
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()) {
|
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();
|
Arrow arrow = iterator.next();
|
||||||
Entity entity = e.getKey();
|
if(isValidEntity(arrow))
|
||||||
if(checkBlocks(entity.getLocation().getBlock(), e.getValue().getBlock())){
|
continue;
|
||||||
entity.remove();
|
|
||||||
iterator.remove();
|
|
||||||
} else {
|
|
||||||
if(isValidEntity(entity, e)) {
|
|
||||||
iterator.remove();
|
|
||||||
}else {
|
|
||||||
LAST_LOCATION.replace(e.getKey(), e.getKey().getLocation());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler()
|
Location prevLocation = arrow.getLocation().toVector().subtract(arrow.getVelocity()).toLocation(arrow.getWorld());
|
||||||
public void onEntityShootBow(EntityShootBowEvent event) {
|
if(arrow.getTicksLived() == 0)
|
||||||
LAST_LOCATION.put(event.getProjectile(), event.getEntity().getEyeLocation());
|
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.
|
|||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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.
|
|||||||
@Override
|
@Override
|
||||||
Lixfel
hat
Auch hier wieder: Iterator benutzen. Auch hier wieder: Iterator benutzen.
|
|||||||
@ -76,7 +71,6 @@ public class ArrowStopper extends BasicListener {
|
|||||||
public void disable() {
|
public void disable() {
|
||||||
super.disable();
|
super.disable();
|
||||||
task.cancel();
|
task.cancel();
|
||||||
LAST_LOCATION.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkBlocks(Block start, Block end) {
|
private boolean checkBlocks(Block start, Block end) {
|
||||||
@ -113,9 +107,12 @@ public class ArrowStopper extends BasicListener {
|
|||||||
return Config.HiddenBlockTags.contains(block.getType().name());
|
return Config.HiddenBlockTags.contains(block.getType().name());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValidEntity(Entity entity, Map.Entry<Entity, Location> entry) {
|
private boolean isValidEntity(Arrow entity) {
|
||||||
return entity.getTicksLived() > Config.ArrowTechhiderCollision ||
|
boolean teamFrom = entity.getVelocity().getZ() > 0;
|
||||||
((AbstractArrow) entity).isInBlock() ||
|
boolean overMid = entity.getLocation().getZ() > Config.SpecSpawn.getZ();
|
||||||
entity.getLocation().equals(entry.getValue());
|
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....