12
1

Arrows Stopping in Techhider Blocks #208

Manuell gemergt
Lixfel hat 17 Commits von arrow-in-techhider nach master 2021-01-02 09:20:42 +01:00 zusammengeführt
3 geänderte Dateien mit 19 neuen und 106 gelöschten Zeilen
Nur Änderungen aus Commit e431b1323c werden angezeigt - Alle Commits anzeigen

Datei anzeigen

@ -1,31 +0,0 @@
/*
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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.utils;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_14_R1.block.CraftBlock;
public class ArrowStopper_14 {
private ArrowStopper_14(){}
static int blockToId(Block block){
return net.minecraft.server.v1_14_R1.Block.REGISTRY_ID.getId(((CraftBlock)block).getNMS());
}
}

Datei anzeigen

@ -1,31 +0,0 @@
/*
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 <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.utils;
import org.bukkit.block.Block;
public class ArrowStopper_8 {
private ArrowStopper_8(){}
@SuppressWarnings("deprecation")
static int blockToId(Block block){
return block.getTypeId();
}
}

Datei anzeigen

@ -17,34 +17,33 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.fightsystem.utils;
package de.steamwar.fightsystem.listener;
import de.steamwar.core.Core;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.AbstractArrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.HandlerList;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.player.PlayerPickupArrowEvent;
import org.bukkit.scheduler.BukkitTask;
import java.util.*;
public class ArrowStopper implements StateDependent, Listener {
public class ArrowStopper extends BasicListener {
private BukkitTask task;
Veraltet
Review

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.

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.
Veraltet
Review

?, entity.getVelocity() gibt einen Vektor zurück, welchen man nicht einfach durch 20 teilen kann

?, entity.getVelocity() gibt einen Vektor zurück, welchen man nicht einfach durch 20 teilen kann
Veraltet
Review

.divide?

.divide?
Veraltet
Review

braucht einen Vektor

braucht einen Vektor
Veraltet
Review

Du brauchst ja sowieso nur die einzelnen Komponenten, also teile doch einfach die durch 20....

Du brauchst ja sowieso nur die einzelnen Komponenten, also teile doch einfach die durch 20....
private static final HashMap<Entity, Location> LAST_LOCATION = new HashMap<>();
ArrowStopper() {
super(EnumSet.of(FightState.RUNNING));
}
Veraltet
Review

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());
public static void init() {
if(Config.ArrowTechhiderCollision == 0)
return;
Veraltet
Review

BasicListener übernimmt im Konstruktor schon das Registrieren als StateDependent

BasicListener übernimmt im Konstruktor schon das Registrieren als StateDependent
@ -52,16 +51,18 @@ public class ArrowStopper implements StateDependent, Listener {
}
private void run() {
Collection<Entity> arrows = Bukkit.getWorlds().get(0).getEntitiesByClasses(AbstractArrow.class);
if(arrows.isEmpty())
return;
for (Map.Entry<Entity, Location> e : LAST_LOCATION.entrySet()) {
if(checkBlocks(e.getKey().getLocation().getBlock(), e.getValue().getBlock()))
e.getKey().remove();
Entity entity = e.getKey();
if(checkBlocks(entity.getLocation().getBlock(), e.getValue().getBlock())){
entity.remove();
Veraltet
Review

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.
LAST_LOCATION.remove(entity);
Veraltet
Review

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
}
Veraltet
Review

Da musst du iterator.remove() verwenden.

Da musst du iterator.remove() verwenden.
else {
if(e.getKey().getTicksLived() <= Config.ArrowTechhiderCollision ||
!((AbstractArrow) e.getKey()).isInBlock()) {
LAST_LOCATION.put(e.getKey(), e.getKey().getLocation());
if(entity.getTicksLived() > Config.ArrowTechhiderCollision ||
((AbstractArrow) entity).isInBlock() || entity.getLocation().equals(e.getValue())) {
Veraltet
Review

Die Verschachtelung kann man evtl. durch eine else if-Konstruktion ersetzen.

Die Verschachtelung kann man evtl. durch eine else if-Konstruktion ersetzen.
LAST_LOCATION.remove(entity);
Veraltet
Review

Ebenfalls. Nutze einen Iterator.

Ebenfalls. Nutze einen Iterator.
}else {
Veraltet
Review

Auch hier wieder: Iterator benutzen.

Auch hier wieder: Iterator benutzen.
LAST_LOCATION.replace(e.getKey(), e.getKey().getLocation());
}
Veraltet
Review

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.
}
}
@ -69,46 +70,20 @@ public class ArrowStopper implements StateDependent, Listener {
@EventHandler()
public void onEntityShootBow(EntityShootBowEvent event) {
if(!(event.getEntity() instanceof Player))
return;
LAST_LOCATION.put(event.getProjectile(), event.getEntity().getEyeLocation());
}
@EventHandler
public void onPlayerPickupArrow(PlayerPickupArrowEvent event) {
LAST_LOCATION.remove(event.getArrow());
}
@Override
public Set<FightState> enabled() {
return EnumSet.of(FightState.RUNNING);
}
@Override
public void enable() {
Bukkit.getPluginManager().registerEvents(this, FightSystem.getPlugin());
super.enable();
task = Bukkit.getScheduler().runTaskTimerAsynchronously(FightSystem.getPlugin(), this::run, 1, 1);
}
Veraltet
Review

Das kannst du nicht Asynchron machen (es dauert 50ms+, bis du einen Chunk für Blockabfragen bekommst), das produziert hier nur Threads.

Das kannst du nicht Asynchron machen (es dauert 50ms+, bis du einen Chunk für Blockabfragen bekommst), das produziert hier nur Threads.
@Override
public void disable() {
Review

Ok, wenn ich jetzt richtig verstanden habe, was diese Funktion macht, dann tut sie linear zwischen den Blöcken interpolieren? Ich meine, das ist zwar nicht die korrekte Minecraft-Berechnungsreihenfolge, soll mir aber auch recht sein.

Ok, wenn ich jetzt richtig verstanden habe, was diese Funktion macht, dann tut sie linear zwischen den Blöcken interpolieren? Ich meine, das ist zwar nicht die korrekte Minecraft-Berechnungsreihenfolge, soll mir aber auch recht sein.
super.disable();
task.cancel();
LAST_LOCATION.clear();
HandlerList.unregisterAll(this);
}
private static int blockToId(Block block){
switch(Core.getVersion()){
case 8:
case 9:
case 10:
case 12:
return ArrowStopper_8.blockToId(block);
case 14:
case 15:
default:
return ArrowStopper_14.blockToId(block);
}
}
private boolean checkBlocks(Block start, Block end) {
@ -142,6 +117,6 @@ public class ArrowStopper implements StateDependent, Listener {
}
private boolean checkBlock(Block block) {
return Config.HiddenBlocks.contains(blockToId(block));
return Config.HiddenBlockTags.contains(block.getType().name());
}
}