HellsBells #275
@ -42,142 +42,90 @@ public class HellsBells {
|
||||
|
||||
public static final Random random = new Random();
|
||||
|
||||
private enum Direction {
|
||||
NORTH(0, 0, 1),
|
||||
SOUTH(0, 0, -1),
|
||||
EAST(1, 0, 0),
|
||||
WEST(-1, 0, 0);
|
||||
private final World world = Bukkit.getWorlds().get(0);
|
||||
|
||||
private final int xLength = Config.RedPasteRegion.getMaxX() - Config.RedPasteRegion.getMinX();
|
||||
private final int zLength = Config.RedPasteRegion.getMaxZ() - Config.RedPasteRegion.getMinZ();
|
||||
private State current = State.PRE;
|
||||
private int currentDrops = 0;
|
||||
private HellsBellsCountdown currentCountdown;
|
||||
private BukkitTask currentDropping;
|
||||
Lixfel
hat
Warum das nochmal extra vorhalten? In getRandom kann ja auch values() aufgerufen werden... Warum das nochmal extra vorhalten? In getRandom kann ja auch values() aufgerufen werden...
YoyoNow
hat
values() auf einem Enum erzeugt immer eine kopie der Enum Elemente intern, daher recht inefficient. values() auf einem Enum erzeugt immer eine kopie der Enum Elemente intern, daher recht inefficient.
Lixfel
hat
Ich finde, es ist ineffizienter, eine Kopie ständig im RAM zu halten, als alle x Minuten mal eine neue Kopie des 4! Elemente großen Array anzulegen. Ist zudem kürzer und einfacher, einfach neu zu kopieren. Ich finde, es ist ineffizienter, eine Kopie ständig im RAM zu halten, als alle x Minuten mal eine neue Kopie des 4! Elemente großen Array anzulegen. Ist zudem kürzer und einfacher, einfach neu zu kopieren.
|
||||
private final List<String> startMessages = Arrays.asList("§c!!Achtung!! Bomber im Anflug, noch ca. eine Minute bis zur Ankunft.",
|
||||
"§cBomber im Anflug, ca. eine Minute bis zur Ankunft.",
|
||||
"§cBomber auf dem Radar gesichtet, geschätzte Ankunftszeit: eine Minute.",
|
||||
"§cUnbekanntes Flugobjekt gesichtet, trifft in ca. einer Minute ein.",
|
||||
"§cFlugobjekt gesichtet. Ankunft in ca. einer Minute.",
|
||||
"§cBomber erschienen, Ankunft ca. eine Minute.");
|
||||
private final List<String> stateSwapMessages = Arrays.asList("§aDie Bomben fallen nun schneller.",
|
||||
"§aMehr Bomber im Anflug.",
|
||||
"§aZusätzliche Bomber gesichtet.",
|
||||
"§aDas Bombardement scheint sich zu erhöhen.");
|
||||
|
||||
static final Direction[] DIRECTIONS = values();
|
||||
|
||||
int dx;
|
||||
int dy;
|
||||
int dz;
|
||||
|
||||
Direction(int dx, int dy, int dz) {
|
||||
this.dx = dx;
|
||||
this.dy = dy;
|
||||
this.dz = dz;
|
||||
public void startCountdown() {
|
||||
if (current == State.PRE) {
|
||||
Bukkit.broadcastMessage(FightSystem.PREFIX + (startMessages.get(random.nextInt(startMessages.size()))));
|
||||
current = current.getNext();
|
||||
} else if (current != State.LAST && currentDrops >= current.SWITCH_AFTER) {
|
||||
Bukkit.broadcastMessage(FightSystem.PREFIX + (stateSwapMessages.get(random.nextInt(stateSwapMessages.size()))));
|
||||
currentDrops = 0;
|
||||
}
|
||||
|
||||
public static Direction getRandom() {
|
||||
return Direction.DIRECTIONS[random.nextInt(Direction.DIRECTIONS.length)];
|
||||
currentDrops++;
|
||||
currentCountdown = new HellsBellsCountdown(current.MIN_TIME + random.nextInt(current.MAX_TIME - current.MIN_TIME));
|
||||
currentCountdown.enable();
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
In der enable() ist sichergestellt, dass es noch nie ausgeführt wurde oder vorher die disable() ausgeführt wurde, die Überprüfung sollte demnach unnötig sein. In der enable() ist sichergestellt, dass es noch nie ausgeführt wurde oder vorher die disable() ausgeführt wurde, die Überprüfung sollte demnach unnötig sein.
|
||||
}
|
||||
|
||||
public void drop() {
|
||||
Direction direction = Direction.getRandom();
|
||||
|
||||
AtomicInteger length = new AtomicInteger(10 + random.nextInt(direction.getLength(zLength, xLength) - 10));
|
||||
int width = 5 + random.nextInt(5);
|
||||
int xOffset = getWidthStart(direction.getLength(xLength, zLength), direction.getLength(length.get(), width));
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Es ist garantiert, dass vor der disable() die enable() ausgeführt wurde. Es ist garantiert, dass vor der disable() die enable() ausgeführt wurde.
|
||||
int zOffset = getLengthStart(direction.getLength(zLength, xLength), direction.getLength(width, length.get()));
|
||||
int yOffset = getHeightStart();
|
||||
|
||||
Point redStart;
|
||||
Point blueStart;
|
||||
|
||||
if (direction.isNorthOrWest()) {
|
||||
redStart = new Point(Config.RedPasteRegion.getMaxX() - xOffset, Config.RedExtendRegion.getMaxY() + yOffset, Config.RedPasteRegion.getMaxZ() - zOffset);
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Diese Unterklasse scheint mir ziemlich unnötig, die Inhalte dieser Klasse sollten in die übergeordnete Klasse eingebaut werden können. Diese Unterklasse scheint mir ziemlich unnötig, die Inhalte dieser Klasse sollten in die übergeordnete Klasse eingebaut werden können.
|
||||
blueStart = new Point(Config.BluePasteRegion.getMinX() + xOffset, Config.BlueExtendRegion.getMaxY() + yOffset, Config.BluePasteRegion.getMinZ() + zOffset);
|
||||
} else {
|
||||
redStart = new Point(Config.RedPasteRegion.getMinX() + xOffset, Config.RedExtendRegion.getMaxY() + yOffset, Config.RedPasteRegion.getMinZ() + zOffset);
|
||||
blueStart = new Point(Config.BluePasteRegion.getMaxX() - xOffset, Config.BlueExtendRegion.getMaxY() + yOffset, Config.BluePasteRegion.getMaxZ() - zOffset);
|
||||
}
|
||||
|
||||
Zeanon markierte diese Unterhaltung als gelöst
Lixfel
hat
Das StateDependent sollte nur die Sachen (de-)aktivieren, nicht das ganze Behaviour innehaben. Um die Nestung zu verringern: Nimm den ganzen Code bis auf die Enable und Disable und bewege den in die HellsBells-Klasse. (Also die übergeordnete) Das StateDependent sollte nur die Sachen (de-)aktivieren, nicht das ganze Behaviour innehaben. Um die Nestung zu verringern: Nimm den ganzen Code bis auf die Enable und Disable und bewege den in die HellsBells-Klasse. (Also die übergeordnete)
|
||||
Direction other() {
|
||||
switch (this) {
|
||||
case NORTH:
|
||||
return EAST;
|
||||
case SOUTH:
|
||||
return WEST;
|
||||
case EAST:
|
||||
return NORTH;
|
||||
case WEST:
|
||||
return SOUTH;
|
||||
default:
|
||||
return this;
|
||||
currentDropping = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), () -> {
|
||||
for (int w = 0; w < width; w++) {
|
||||
if (direction.isNorthOrWest()) {
|
||||
world.spawnEntity(redStart.addAndToLocation(world, -1 * (direction.dx * length.get() + w * direction.other().dx), 0, -1 * (direction.dz * length.get() + w * direction.other().dz)), EntityType.PRIMED_TNT);
|
||||
|
||||
world.spawnEntity(blueStart.addAndToLocation(world, direction.dx * length.get() + w * direction.other().dx, 0, direction.dz * length.get() + w * direction.other().dz), EntityType.PRIMED_TNT);
|
||||
} else {
|
||||
world.spawnEntity(redStart.addAndToLocation(world, direction.dx * length.get() + w * direction.other().dx, 0, direction.dz * length.get() + w * direction.other().dz), EntityType.PRIMED_TNT);
|
||||
|
||||
world.spawnEntity(blueStart.addAndToLocation(world, -1 * (direction.dx * length.get() + w * direction.other().dx), 0, -1 * (direction.dz * length.get() + w * direction.other().dz)), EntityType.PRIMED_TNT);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (length.addAndGet(-2) <= 0) {
|
||||
currentDropping.cancel();
|
||||
}
|
||||
}, 0L, 4L);
|
||||
}
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
init() und terminate() lesen sich mir wie eine enable() und disable() eines StateDependent... init() und terminate() lesen sich mir wie eine enable() und disable() eines StateDependent...
|
||||
|
||||
Zeanon markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Wird der State NONE wirklich benötigt? Wird der State NONE wirklich benötigt?
|
||||
public int getLength(int length1, int length2) {
|
||||
return isNorthOrSouth() ? length1 : length2;
|
||||
}
|
||||
private int getLengthStart(int regionSize, int length) {
|
||||
return random.nextInt(regionSize - length);
|
||||
}
|
||||
|
||||
public boolean isNorthOrSouth() {
|
||||
return this == NORTH || this == SOUTH;
|
||||
}
|
||||
private int getWidthStart(int regionSize, int length) {
|
||||
return random.nextInt(regionSize - length);
|
||||
}
|
||||
|
||||
public boolean isNorthOrWest() {
|
||||
return this == NORTH || this == WEST;
|
||||
}
|
||||
private int getHeightStart() {
|
||||
return 5 + random.nextInt(15);
|
||||
}
|
||||
|
||||
public HellsBells() {
|
||||
new StateDependent(Winconditions.HELLS_BELLS, FightState.Running) {
|
||||
|
||||
private final World world = Bukkit.getWorlds().get(0);
|
||||
private final int xLength = Config.RedPasteRegion.getMaxX() - Config.RedPasteRegion.getMinX();
|
||||
private final int zLength = Config.RedPasteRegion.getMaxZ() - Config.RedPasteRegion.getMinZ();
|
||||
private State current = State.PRE;
|
||||
private int currentDrops = 0;
|
||||
private HellsBellsCountdown currentCountdown;
|
||||
private BukkitTask currentDropping;
|
||||
private final List<String> startMessages = Arrays.asList("§c!!Achtung!! Bomber im Anflug, noch ca. eine Minute bis zur Ankunft.",
|
||||
"§cBomber im Anflug, ca. eine Minute bis zur Ankunft.",
|
||||
"§cBomber auf dem Radar gesichtet, geschätzte Ankunftszeit: eine Minute.",
|
||||
"§cUnbekanntes Flugobjekt gesichtet, trifft in ca. einer Minute ein.",
|
||||
"§cFlugobjekt gesichtet. Ankunft in ca. einer Minute.",
|
||||
"§cBomber erschienen, Ankunft ca. eine Minute.");
|
||||
|
||||
public void startCountdown() {
|
||||
if (current == State.PRE) {
|
||||
Bukkit.broadcastMessage(FightSystem.PREFIX + (startMessages.get(random.nextInt(startMessages.size()))));
|
||||
current = current.getNext();
|
||||
} else if (current != State.LAST && currentDrops >= current.SWITCH_AFTER) {
|
||||
Bukkit.broadcastMessage(FightSystem.PREFIX + "§aDie Bomben fallen nun schneller.");
|
||||
currentDrops = 0;
|
||||
}
|
||||
|
||||
currentDrops++;
|
||||
currentCountdown = new HellsBellsCountdown(current.MIN_TIME + random.nextInt(current.MAX_TIME - current.MIN_TIME));
|
||||
currentCountdown.enable();
|
||||
}
|
||||
|
||||
public void drop() {
|
||||
Direction direction = Direction.getRandom();
|
||||
|
||||
AtomicInteger length = new AtomicInteger(10 + random.nextInt(direction.getLength(zLength, xLength) - 10));
|
||||
int width = 5 + random.nextInt(5);
|
||||
int xOffset = getWidthStart(direction.getLength(xLength, zLength), direction.getLength(length.get(), width));
|
||||
int zOffset = getLengthStart(direction.getLength(zLength, xLength), direction.getLength(width, length.get()));
|
||||
int yOffset = getHeightStart();
|
||||
|
||||
Point redStart = direction.isNorthOrWest() ? new Point(Config.RedPasteRegion.getMaxX() - xOffset, Config.RedExtendRegion.getMaxY() + yOffset, Config.RedPasteRegion.getMaxZ() - zOffset) : new Point(Config.RedPasteRegion.getMinX() + xOffset, Config.RedExtendRegion.getMaxY() + yOffset, Config.RedPasteRegion.getMinZ() + zOffset);
|
||||
Point blueStart = direction.isNorthOrWest() ? new Point(Config.BluePasteRegion.getMinX() + xOffset, Config.BlueExtendRegion.getMaxY() + yOffset, Config.BluePasteRegion.getMinZ() + zOffset) : new Point(Config.BluePasteRegion.getMaxX() - xOffset, Config.BlueExtendRegion.getMaxY() + yOffset, Config.BluePasteRegion.getMaxZ() - zOffset);
|
||||
|
||||
currentDropping = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), () -> {
|
||||
int factor = direction.isNorthOrWest() ? 1 : -1;
|
||||
for (int w = 0; w < width; w++) {
|
||||
world.spawnEntity(redStart.subtractAndToLocation(world, (direction.dx * length.get() + w * direction.other().dx) * factor, 0, (direction.dz * length.get() + w * direction.other().dz) * factor), EntityType.PRIMED_TNT);
|
||||
world.spawnEntity(blueStart.addAndToLocation(world, (direction.dx * length.get() + w * direction.other().dx) * factor, 0, (direction.dz * length.get() + w * direction.other().dz) * factor), EntityType.PRIMED_TNT);
|
||||
}
|
||||
if (length.addAndGet(-2) <= 0) {
|
||||
currentDropping.cancel();
|
||||
}
|
||||
}, 0L, 4L);
|
||||
}
|
||||
|
||||
private int getLengthStart(int regionSize, int length) {
|
||||
return random.nextInt(regionSize - length);
|
||||
}
|
||||
|
||||
private int getWidthStart(int regionSize, int length) {
|
||||
return random.nextInt(regionSize - length);
|
||||
}
|
||||
|
||||
private int getHeightStart() {
|
||||
return 5 + random.nextInt(15);
|
||||
}
|
||||
|
||||
class HellsBellsCountdown extends Countdown {
|
||||
|
||||
public HellsBellsCountdown(int time) {
|
||||
super(time, SWSound.BLOCK_NOTE_BASS, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String countdownCounting() {
|
||||
return "bis die Bomben fallen";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void countdownFinished() {
|
||||
drop();
|
||||
|
||||
startCountdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enable() {
|
||||
startCountdown();
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Gibt es nicht random.nextInt(MIN, MAX)? (kA) Gibt es nicht random.nextInt(MIN, MAX)? (kA)
YoyoNow
hat
Nein leider bietet die normale Random implementation dies nicht an. Nein leider bietet die normale Random implementation dies nicht an.
|
||||
@ -190,6 +138,25 @@ public class HellsBells {
|
||||
}.register();
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Diesen if-Block kann man denke ich vereinfachen, wenn man stattdessen in den Assignments mit dem conditional-Operator arbeitet ?:. Diesen if-Block kann man denke ich vereinfachen, wenn man stattdessen in den Assignments mit dem conditional-Operator arbeitet ?:.
|
||||
}
|
||||
|
||||
class HellsBellsCountdown extends Countdown {
|
||||
Lixfel
hat
Kann glaube noch private static sein. Kann glaube noch private static sein.
|
||||
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Könnte man statt diesen Ifs nicht einfach eine Methode in der Direction machen, die dann den passenden Wert zurückgibt? Könnte man statt diesen Ifs nicht einfach eine Methode in der Direction machen, die dann den passenden Wert zurückgibt?
|
||||
public HellsBellsCountdown(int time) {
|
||||
super(time, SWSound.BLOCK_NOTE_BASS, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String countdownCounting() {
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Auch hier müsste das zu einer Methode in Direction umwandelbar sein. Auch hier müsste das zu einer Methode in Direction umwandelbar sein.
Lixfel
hat
Stat dem If-Block mit Subtract and add: Alle Werte mit Stat dem If-Block mit Subtract and add: Alle Werte mit `int factor = direction.isNorthOrWest() ? 1 : -1;` multiplizieren.
|
||||
return "bis die Bomben fallen";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void countdownFinished() {
|
||||
drop();
|
||||
|
||||
startCountdown();
|
||||
YoyoNow markierte diese Unterhaltung als gelöst
Veraltet
Lixfel
hat
Üblicherweise verwenden wir eher Bukkit...getScheduler().runTaskTimer(Plugin, lambda-Methode, Zeit(en)) Üblicherweise verwenden wir eher Bukkit...getScheduler().runTaskTimer(Plugin, lambda-Methode, Zeit(en))
|
||||
}
|
||||
}
|
||||
|
||||
private static class Point {
|
||||
|
||||
private final int x;
|
||||
@ -205,10 +172,6 @@ public class HellsBells {
|
||||
public Location addAndToLocation(World world, int x, int y, int z) {
|
||||
return new Location(world, this.x + x, this.y + y, this.z + z); //NOSONAR
|
||||
}
|
||||
|
||||
public Location subtractAndToLocation(World world, int x, int y, int z) {
|
||||
return new Location(world, this.x - x, this.y - y, this.z - z); //NOSONAR
|
||||
}
|
||||
}
|
||||
|
||||
private enum State {
|
||||
@ -250,4 +213,53 @@ public class HellsBells {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum Direction {
|
||||
NORTH(0, 0, 1),
|
||||
SOUTH(0, 0, -1),
|
||||
EAST(1, 0, 0),
|
||||
WEST(-1, 0, 0);
|
||||
|
||||
|
||||
int dx;
|
||||
int dy;
|
||||
int dz;
|
||||
|
||||
Direction(int dx, int dy, int dz) {
|
||||
this.dx = dx;
|
||||
this.dy = dy;
|
||||
this.dz = dz;
|
||||
}
|
||||
|
||||
public static Direction getRandom() {
|
||||
return Direction.values()[random.nextInt(Direction.values().length)];
|
||||
}
|
||||
|
||||
Direction other() {
|
||||
switch (this) {
|
||||
case NORTH:
|
||||
return EAST;
|
||||
case SOUTH:
|
||||
return WEST;
|
||||
case EAST:
|
||||
return NORTH;
|
||||
case WEST:
|
||||
return SOUTH;
|
||||
default:
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public int getLength(int length1, int length2) {
|
||||
return isNorthOrSouth() ? length1 : length2;
|
||||
}
|
||||
|
||||
public boolean isNorthOrSouth() {
|
||||
return this == NORTH || this == SOUTH;
|
||||
}
|
||||
|
||||
public boolean isNorthOrWest() {
|
||||
return this == NORTH || this == WEST;
|
||||
}
|
||||
}
|
||||
}
|
Subklassen bitte nach dem Inhalt der Hauptklasse.