New StateMachine, improved Height Classification
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Ursprung
b3c5186699
Commit
21ee580c0f
@ -55,6 +55,8 @@ import java.util.logging.Level;
|
|||||||
|
|
||||||
public abstract class AI {
|
public abstract class AI {
|
||||||
|
|
||||||
|
public static final double INTERACTION_RANGE = 5.0;
|
||||||
|
|
||||||
private static final Map<UUID, AI> ais = new HashMap<>();
|
private static final Map<UUID, AI> ais = new HashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
@ -204,12 +206,12 @@ public abstract class AI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void move(Vector pos) {
|
public void move(Vector pos) {
|
||||||
queue.add(new Action(2) {
|
queue.add(new Action(4) {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Location location = entity.getLocation();
|
Location location = entity.getLocation();
|
||||||
Location target = translate(pos, false);
|
Location target = translate(pos, false);
|
||||||
if(Math.abs(location.getX() - target.getX()) > 1.9 || Math.abs(location.getY() - target.getY()) > 1.9 || Math.abs(location.getZ() - target.getZ()) > 1.9) {
|
if(Math.abs(location.getX() - target.getX()) > 1.0 || Math.abs(location.getY() - target.getY()) > 1.5 || Math.abs(location.getZ() - target.getZ()) > 1.0) {
|
||||||
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> entity.getName() + ": Overdistance movement " + location.toVector() + " " + target.toVector());
|
FightSystem.getPlugin().getLogger().log(Level.INFO, () -> entity.getName() + ": Overdistance movement " + location.toVector() + " " + target.toVector());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -223,7 +225,7 @@ public abstract class AI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean interactionDistanceViolation(Location location) {
|
private boolean interactionDistanceViolation(Location location) {
|
||||||
return location.distance(entity.getEyeLocation()) > 5;
|
return location.distance(entity.getEyeLocation()) > INTERACTION_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void interact(Block block) {
|
private void interact(Block block) {
|
||||||
|
@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
package de.steamwar.fightsystem.ai;
|
package de.steamwar.fightsystem.ai;
|
||||||
|
|
||||||
import de.steamwar.entity.RArmorStand;
|
|
||||||
import de.steamwar.entity.REntityServer;
|
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.fight.FightTeam;
|
import de.steamwar.fightsystem.fight.FightTeam;
|
||||||
import de.steamwar.fightsystem.states.FightState;
|
import de.steamwar.fightsystem.states.FightState;
|
||||||
@ -29,15 +27,18 @@ import de.steamwar.sql.SteamwarUser;
|
|||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Function;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class LixfelAI extends AI {
|
public class LixfelAI extends AI {
|
||||||
|
|
||||||
private Random random;
|
private Random random;
|
||||||
|
|
||||||
private LixfelPathplanner pathplanner;
|
private LixfelPathplanner pathplanner;
|
||||||
private Action action;
|
private List<Vector> setup;
|
||||||
private REntityServer entityServer;
|
private long preRunningStart;
|
||||||
private RArmorStand entityMarker;
|
private List<TimedVector> timedStart;
|
||||||
|
private List<Cannon> cannons;
|
||||||
|
private Cannon currentCannon;
|
||||||
|
|
||||||
public LixfelAI(FightTeam team, String user) {
|
public LixfelAI(FightTeam team, String user) {
|
||||||
super(team, SteamwarUser.get(user));
|
super(team, SteamwarUser.get(user));
|
||||||
@ -52,220 +53,155 @@ public class LixfelAI extends AI {
|
|||||||
schem = publics.stream().filter(s -> s.getName().equals("TheUnderground")).findAny().orElse(schem);
|
schem = publics.stream().filter(s -> s.getName().equals("TheUnderground")).findAny().orElse(schem);
|
||||||
|
|
||||||
pathplanner = new LixfelPathplanner(schem);
|
pathplanner = new LixfelPathplanner(schem);
|
||||||
|
setup = new ArrayList<>(Collections.singletonList(new Vector(25, 15, 25)));
|
||||||
action = new BlockAction(Collections.emptyList(), Collections.singletonList(new Vector(25, 15, 25)),
|
timedStart = new ArrayList<>(Collections.singletonList(new TimedVector(420L, new Vector(21, 15, 24))));
|
||||||
new MoveToRangeAction(new Vector(21, 15, 24),
|
cannons = new ArrayList<>(Arrays.asList(
|
||||||
new FunctionAction(ai -> {
|
new Cannon(new Vector(11,25,11), 10,23,14, 12,23,14, 10,23,12, 12,23,12, 12,24,15, 10,24,14, 12,23,15, 12,24,14, 11,24,12, 10,24,15, 12,24,12, 10,23,15, 10,24,12),
|
||||||
setReady();
|
new Cannon(new Vector(39,25,11), 38,24,15, 38,23,12, 40,23,14, 40,24,12, 40,23,15, 40,24,14, 39,24,12, 38,23,14, 40,24,15, 40,23,12, 38,23,15, 38,24,12, 38,24,14),
|
||||||
return FightState.getFightState() == FightState.PRE_RUNNING;
|
new Cannon(new Vector(12,18,11), 13,17,15, 13,17,16, 13,18,16, 13,18,14, 14,18,14, 14,17,15, 14,17,16, 14,18,16, 13,17,14, 14,17,14, 13,18,15, 14,18,15),
|
||||||
},
|
new Cannon(new Vector(38,18,11), 37,18,14, 36,18,14, 36,17,15, 37,17,15, 37,18,15, 36,18,15, 36,17,14, 37,17,14, 36,17,16, 37,17,16, 36,18,16, 37,18,16),
|
||||||
new WaitAction(420,
|
new Cannon(new Vector(9,9,16), 10,11,17, 10,8,19, 10,8,17, 11,8,19, 11,8,15, 10,8,15, 12,8,15, 10,10,15, 12,7,19, 11,10,15, 12,8,19, 12,7,15, 11,7,15, 10,9,17, 11,9,19, 12,9,19, 10,9,19, 10,7,17, 11,7,19, 10,7,15, 10,7,19, 10,10,17, 12,9,15, 10,9,15, 11,9,15, 12,10,19, 11,10,19, 12,10,15, 10,6,17, 10,10,19),
|
||||||
new BlockAction(Collections.emptyList(), Collections.singletonList(new Vector(21, 15, 24)),
|
new Cannon(null, 23,5,9, 23,6,9, 23,7,9, 23,8,9),
|
||||||
new FunctionAction(ai -> FightState.getFightState() == FightState.RUNNING,
|
new Cannon(null, 27,5,9, 27,6,9, 27,7,9, 27,8,9)
|
||||||
new ChooseCannonAction(
|
));
|
||||||
new Cannon(new Vector(11,25,11), 10,23,14, 12,23,14, 10,23,12, 12,23,12, 12,24,15, 10,24,14, 12,23,15, 12,24,14, 11,24,12, 10,24,15, 12,24,12, 10,23,15, 10,24,12),
|
chooseCannon();
|
||||||
new Cannon(new Vector(39,25,11), 38,24,15, 38,23,12, 40,23,14, 40,24,12, 40,23,15, 40,24,14, 39,24,12, 38,23,14, 40,24,15, 40,23,12, 38,23,15, 38,24,12, 38,24,14),
|
|
||||||
new Cannon(new Vector(12,18,11), 13,17,15, 13,17,16, 13,18,16, 13,18,14, 14,18,14, 14,17,15, 14,17,16, 14,18,16, 13,17,14, 14,17,14, 13,18,15, 14,18,15),
|
|
||||||
new Cannon(new Vector(38,18,11), 37,18,14, 36,18,14, 36,17,15, 37,17,15, 37,18,15, 36,18,15, 36,17,14, 37,17,14, 36,17,16, 37,17,16, 36,18,16, 37,18,16),
|
|
||||||
new Cannon(new Vector(8,9,16), 10,11,17, 10,8,19, 10,8,17, 11,8,19, 11,8,15, 10,8,15, 12,8,15, 10,10,15, 12,7,19, 11,10,15, 12,8,19, 12,7,15, 11,7,15, 10,9,17, 11,9,19, 12,9,19, 10,9,19, 10,7,17, 11,7,19, 10,7,15, 10,7,19, 10,10,17, 12,9,15, 10,9,15, 11,9,15, 12,10,19, 11,10,19, 12,10,15, 10,6,17, 10,10,19),
|
|
||||||
new Cannon(null, 23,5,9, 23,6,9, 23,7,9, 23,8,9),
|
|
||||||
new Cannon(null, 27,5,9, 27,6,9, 27,7,9, 27,8,9)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
/*entityServer = new REntityServer();
|
|
||||||
Bukkit.getPluginManager().registerEvents(new Listener() {
|
|
||||||
@EventHandler
|
|
||||||
public void onJoin(PlayerJoinEvent e) {
|
|
||||||
entityServer.addPlayer(e.getPlayer());
|
|
||||||
}
|
|
||||||
}, FightSystem.getPlugin());
|
|
||||||
|
|
||||||
System.out.println(pathplanner.getWalkable().size());
|
|
||||||
for(Vector v : pathplanner.getWalkable()) {
|
|
||||||
RArmorStand armorStand = new RArmorStand(entityServer, translate(v, false), RArmorStand.Size.MARKER);
|
|
||||||
armorStand.setInvisible(true);
|
|
||||||
armorStand.setDisplayName("walkable");
|
|
||||||
}
|
|
||||||
entityMarker = new RArmorStand(entityServer, getEntity().getLocation(), RArmorStand.Size.MARKER);
|
|
||||||
entityMarker.setInvisible(true);
|
|
||||||
entityMarker.setDisplayName("position");*/
|
|
||||||
|
|
||||||
return schem;
|
return schem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void move(Vector pos) {
|
|
||||||
super.move(pos);
|
|
||||||
//entityMarker.move(getEntity().getLocation());
|
|
||||||
}
|
|
||||||
|
|
||||||
LixfelPathplanner getPathplanner() {
|
|
||||||
return pathplanner;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAction(Action action) {
|
|
||||||
this.action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void plan() {
|
protected void plan() {
|
||||||
action.plan(this);
|
switch (FightState.getFightState()) {
|
||||||
}
|
case POST_SCHEM_SETUP:
|
||||||
|
if(prepareSchem() && scanEnemy())
|
||||||
private abstract static class Action {
|
setReady();
|
||||||
private Action next;
|
break;
|
||||||
|
case PRE_RUNNING:
|
||||||
public Action(Action next) {
|
if(start() && scanEnemy())
|
||||||
this.next = next;
|
ensureInRange(currentCannon.tnt.keySet().iterator().next());
|
||||||
}
|
break;
|
||||||
|
case RUNNING:
|
||||||
public abstract void plan(LixfelAI ai);
|
while(currentCannon.shoot())
|
||||||
|
chooseCannon(); //TODO prevent endless loop
|
||||||
public void setNext(Action next) {
|
break;
|
||||||
this.next = next;
|
default:
|
||||||
}
|
break;
|
||||||
|
|
||||||
protected void next(LixfelAI ai) {
|
|
||||||
ai.setAction(next);
|
|
||||||
next.plan(ai);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FunctionAction extends Action {
|
private boolean prepareSchem() {
|
||||||
|
return doWith(setup, this::interact);
|
||||||
private final Function<LixfelAI, Boolean> action;
|
|
||||||
public FunctionAction(Function<LixfelAI, Boolean> action, Action followup) {
|
|
||||||
super(followup);
|
|
||||||
this.action = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void plan(LixfelAI ai) {
|
|
||||||
if(action.apply(ai))
|
|
||||||
next(ai);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class WaitAction extends Action {
|
private boolean scanEnemy() {
|
||||||
|
//TODO
|
||||||
private int remaining;
|
return true;
|
||||||
public WaitAction(int ticks, Action followup) {
|
|
||||||
super(followup);
|
|
||||||
this.remaining = ticks;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void plan(LixfelAI ai) {
|
|
||||||
if(--remaining == 0)
|
|
||||||
next(ai);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MoveToRangeAction extends Action {
|
private boolean start() {
|
||||||
|
if(preRunningStart == 0)
|
||||||
|
preRunningStart = Config.world.getFullTime();
|
||||||
|
|
||||||
private final Vector target;
|
if(timedStart.isEmpty())
|
||||||
public MoveToRangeAction(Vector target, Action next) {
|
return true;
|
||||||
super(next);
|
|
||||||
this.target = target;
|
long time = Config.world.getFullTime() - preRunningStart;
|
||||||
}
|
TimedVector vector = timedStart.get(0);
|
||||||
|
if(!ensureInRange(vector.vector))
|
||||||
public boolean inRange(LixfelAI ai) {
|
return false;
|
||||||
return new Vector(0, ai.getEntity().getEyeHeight(), 0).add(ai.getPosition()).distance(target) <= 5;
|
|
||||||
}
|
if(time >= vector.getTime()) {
|
||||||
|
interact(timedStart.remove(0).vector);
|
||||||
@Override
|
} else {
|
||||||
public void plan(LixfelAI ai) {
|
scanEnemy();
|
||||||
if(inRange(ai)) {
|
|
||||||
next(ai);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector position = ai.getPosition();
|
|
||||||
List<Vector> path = new ArrayList<>(ai.getPathplanner().planToRange(position, new Vector(0, -ai.getEntity().getEyeHeight(), 0).add(target), 5.0));
|
|
||||||
if(path.isEmpty())
|
|
||||||
path.add(new Vector(0, 1, 0).add(position));
|
|
||||||
|
|
||||||
ai.move(path.get(0));
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class BlockAction extends Action {
|
private void chooseCannon() {
|
||||||
private final List<Vector> tntToPlace;
|
currentCannon = cannons.get(random.nextInt(cannons.size()));
|
||||||
private final List<Vector> interactables;
|
|
||||||
|
|
||||||
public BlockAction(List<Vector> tntToPlace, List<Vector> interactables, Action followup) {
|
|
||||||
super(followup);
|
|
||||||
this.tntToPlace = new ArrayList<>(tntToPlace);
|
|
||||||
this.interactables = new ArrayList<>(interactables);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void plan(LixfelAI ai) {
|
|
||||||
if(!tntToPlace.isEmpty()) {
|
|
||||||
MoveToRangeAction move = new MoveToRangeAction(tntToPlace.get(0), this);
|
|
||||||
if(move.inRange(ai))
|
|
||||||
ai.setTNT(tntToPlace.remove(0));
|
|
||||||
else
|
|
||||||
move.plan(ai);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!interactables.isEmpty()) {
|
|
||||||
MoveToRangeAction move = new MoveToRangeAction(interactables.get(0), this);
|
|
||||||
if(move.inRange(ai))
|
|
||||||
ai.interact(interactables.remove(0));
|
|
||||||
else
|
|
||||||
move.plan(ai);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
next(ai);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ChooseCannonAction extends Action {
|
private boolean doWith(List<Vector> targets, Consumer<Vector> method) {
|
||||||
|
if(targets.isEmpty())
|
||||||
|
return true;
|
||||||
|
|
||||||
private final List<Cannon> cannons;
|
if(ensureInRange(targets.get(0)))
|
||||||
private final List<Cannon> shootingList = new ArrayList<>();
|
method.accept(targets.remove(0));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public ChooseCannonAction(Cannon... cannons) {
|
private boolean ensureInRange(Vector target) {
|
||||||
super(null);
|
Vector position = getPosition();
|
||||||
this.cannons = Arrays.asList(cannons);
|
boolean inRange = new Vector(0, getEntity().getEyeHeight(), 0).add(position).distance(target) <= 5;
|
||||||
Collections.shuffle(this.cannons);
|
if(inRange)
|
||||||
}
|
return true;
|
||||||
|
|
||||||
@Override
|
List<Vector> path = new ArrayList<>(pathplanner.planToRange(position, new Vector(0, -getEntity().getEyeHeight(), 0).add(target), 5.0));
|
||||||
public void plan(LixfelAI ai) {
|
if(path.isEmpty())
|
||||||
if(shootingList.isEmpty())
|
path.add(new Vector(0, 1, 0).add(position));
|
||||||
shootingList.addAll(cannons);
|
|
||||||
|
|
||||||
setNext(shootingList.remove(0).toAction(this));
|
move(path.get(0));
|
||||||
next(ai);
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Cannon {
|
private class Cannon {
|
||||||
private final Vector activator;
|
private final Vector activator;
|
||||||
private final List<Vector> tnt = new ArrayList<>();
|
private final Map<Vector, Boolean> tnt = new HashMap<>();
|
||||||
|
private long freeAt;
|
||||||
|
|
||||||
public Cannon(Vector activator, int... tntpos) {
|
public Cannon(Vector activator, int... tntpos) {
|
||||||
this.activator = activator;
|
this.activator = activator;
|
||||||
|
|
||||||
for(int i = 0; i < tntpos.length; i+=3) {
|
for(int i = 0; i < tntpos.length; i+=3) {
|
||||||
tnt.add(new Vector(tntpos[i], tntpos[i+1], tntpos[i+2]));
|
tnt.put(new Vector(tntpos[i], tntpos[i+1], tntpos[i+2]), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockAction toAction(Action next) {
|
public boolean shoot() {
|
||||||
return new BlockAction(tnt, activator == null ? Collections.emptyList() : Collections.singletonList(activator), next);
|
if(Config.world.getFullTime() < freeAt)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for(Map.Entry<Vector, Boolean> entry : tnt.entrySet()) {
|
||||||
|
if(!entry.getValue()) {
|
||||||
|
if(ensureInRange(entry.getKey())) {
|
||||||
|
setTNT(entry.getKey());
|
||||||
|
entry.setValue(true);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(activator != null) {
|
||||||
|
if(!ensureInRange(activator))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
interact(activator);
|
||||||
|
}
|
||||||
|
|
||||||
|
freeAt = Config.world.getFullTime() + 80;
|
||||||
|
for(Map.Entry<Vector, Boolean> entry : tnt.entrySet())
|
||||||
|
entry.setValue(false);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TimedVector {
|
||||||
|
private final long time;
|
||||||
|
private final Vector vector;
|
||||||
|
|
||||||
|
public TimedVector(long time, Vector vector) {
|
||||||
|
this.time = time;
|
||||||
|
this.vector = vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector getVector() {
|
||||||
|
return vector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,12 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
|||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
import com.sk89q.worldedit.math.BlockVector3;
|
import com.sk89q.worldedit.math.BlockVector3;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
|
||||||
import de.steamwar.fightsystem.Config;
|
import de.steamwar.fightsystem.Config;
|
||||||
import de.steamwar.fightsystem.utils.WorldeditWrapper;
|
import de.steamwar.fightsystem.utils.WorldeditWrapper;
|
||||||
import de.steamwar.sql.SchematicData;
|
import de.steamwar.sql.SchematicData;
|
||||||
import de.steamwar.sql.SchematicNode;
|
import de.steamwar.sql.SchematicNode;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Banner;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.type.*;
|
import org.bukkit.block.data.type.*;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
@ -40,11 +40,11 @@ import java.util.stream.Collectors;
|
|||||||
public class LixfelPathplanner {
|
public class LixfelPathplanner {
|
||||||
|
|
||||||
private static double blockHeight(Clipboard clipboard, BlockVector3 vector) {
|
private static double blockHeight(Clipboard clipboard, BlockVector3 vector) {
|
||||||
BaseBlock block = clipboard.getFullBlock(vector);
|
BlockData data = BukkitAdapter.adapt(clipboard.getFullBlock(vector));
|
||||||
if(block.getBlockType().getMaterial().isFullCube())
|
|
||||||
return 1.0;
|
|
||||||
BlockData data = BukkitAdapter.adapt(block);
|
|
||||||
Material material = data.getMaterial();
|
Material material = data.getMaterial();
|
||||||
|
if(material.isOccluding())
|
||||||
|
return 1.0;
|
||||||
|
|
||||||
if(material.isSolid()) {
|
if(material.isSolid()) {
|
||||||
if(material.isInteractable()) {
|
if(material.isInteractable()) {
|
||||||
if(data instanceof Stairs)
|
if(data instanceof Stairs)
|
||||||
@ -53,13 +53,17 @@ public class LixfelPathplanner {
|
|||||||
return 1.5;
|
return 1.5;
|
||||||
else if(data instanceof Bed)
|
else if(data instanceof Bed)
|
||||||
return 0.5625;
|
return 0.5625;
|
||||||
|
else if(data instanceof TrapDoor)
|
||||||
|
return -1.0;
|
||||||
} else {
|
} else {
|
||||||
if(data instanceof Slab)
|
if(data instanceof Slab)
|
||||||
return ((Slab)data).getType() == Slab.Type.BOTTOM ? 0.5 : 1.0;
|
return ((Slab)data).getType() == Slab.Type.BOTTOM ? 0.5 : 1.0;
|
||||||
else if(data instanceof Wall)
|
else if(data instanceof Wall)
|
||||||
return 1.5;
|
return 1.5;
|
||||||
else if(data instanceof GlassPane || material == Material.IRON_BARS)
|
else if(data instanceof Banner || material.name().endsWith("PRESSURE_PLATE"))
|
||||||
return 1.0;
|
return 0.0;
|
||||||
|
|
||||||
|
return 1.0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(material == Material.LADDER || material == Material.SCAFFOLDING)
|
if(material == Material.LADDER || material == Material.SCAFFOLDING)
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren