SteamWar/FightSystem
Archiviert
13
1

Merge pull request 'Arrows Stopping in Techhider Blocks' (#208) from arrow-in-techhider into master

Reviewed-by: Lixfel <lixfel@steamwar.de>
Dieser Commit ist enthalten in:
Lixfel 2021-01-02 09:20:41 +01:00
Commit ea596d724a
2 geänderte Dateien mit 113 neuen und 4 gelöschten Zeilen

Datei anzeigen

@ -32,10 +32,7 @@ import de.steamwar.fightsystem.record.RecordSystem;
import de.steamwar.fightsystem.record.Recorder;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.fightsystem.utils.EnterHandler;
import de.steamwar.fightsystem.utils.FightScoreboard;
import de.steamwar.fightsystem.utils.FightStatistics;
import de.steamwar.fightsystem.utils.TechHider;
import de.steamwar.fightsystem.utils.*;
import de.steamwar.fightsystem.winconditions.*;
import de.steamwar.sql.EventFight;
import de.steamwar.sql.Schematic;
@ -103,6 +100,7 @@ public class FightSystem extends JavaPlugin {
new GameplayListener();
new PersonalKitCreator();
new ScoreboardListener();
new ArrowStopper();
if(Core.getVersion() > 8)
new VersionDependentListener();

Datei anzeigen

@ -0,0 +1,111 @@
/*
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.listener;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.states.FightState;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.projectiles.ProjectileSource;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import java.util.EnumSet;
public class ArrowStopper extends BasicListener {
private BukkitTask task;
private static final Vector NULL_VECTOR = new Vector(0, 0, 0);
private static final BlockFace[] BLOCK_FACES = {BlockFace.UP, BlockFace.DOWN, BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH};
public ArrowStopper() {
super(Config.TechhiderActive ? EnumSet.of(FightState.RUNNING) : EnumSet.noneOf(FightState.class));
}
private void run() {
for (Arrow arrow : Bukkit.getWorlds().get(0).getEntitiesByClass(Arrow.class)) {
if (invalidEntity(arrow))
continue;
Location prevLocation = arrow.getLocation().toVector().subtract(arrow.getVelocity()).toLocation(arrow.getWorld());
if (arrow.getTicksLived() == 0){
ProjectileSource projSource = arrow.getShooter();
if(projSource instanceof Player)
prevLocation = ((Player) arrow.getShooter()).getEyeLocation();
else
continue;
}
if (checkBlocks(arrow.getLocation().getBlock(), prevLocation.getBlock())) {
arrow.remove();
}
}
}
@Override
public void enable() {
super.enable();
task = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), this::run, 1, 1);
}
@Override
public void disable() {
super.disable();
task.cancel();
}
private boolean checkBlocks(Block start, Block end) {
Block cursor = start;
while (!cursor.getLocation().equals(end.getLocation())) {
BlockFace nearest = BlockFace.SELF;
double nearestDistance = cursor.getLocation().distance(end.getLocation());
for (BlockFace face : BLOCK_FACES) {
Block relative = cursor.getRelative(face);
double distance = relative.getLocation().distance(end.getLocation());
if(distance < nearestDistance) {
nearestDistance = distance;
nearest = face;
}
}
cursor = cursor.getRelative(nearest);
if(checkBlock(cursor))
return true;
}
return false;
}
private boolean checkBlock(Block block) {
return Config.HiddenBlockTags.contains(block.getType().name());
}
private boolean invalidEntity(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);
}
}