12
1

Meteor #324

Zusammengeführt
Lixfel hat 24 Commits von Meteor nach master 2022-02-11 22:48:17 +01:00 zusammengeführt
8 geänderte Dateien mit 310 neuen und 21 gelöschten Zeilen

Datei anzeigen

@ -108,6 +108,7 @@ WinConditions: # defaults to none if missing
# - PUMPKIN_TECH_KO
# - HELLS_BELLS
# - METEOR
WinConditionParams:
# The time of any of the timeout win conditions in seconds

Datei anzeigen

@ -22,6 +22,7 @@ package de.steamwar.fightsystem;
import de.steamwar.fightsystem.commands.*;
import de.steamwar.fightsystem.countdown.*;
import de.steamwar.fightsystem.event.HellsBells;
import de.steamwar.fightsystem.event.Meteor;
import de.steamwar.fightsystem.fight.Fight;
import de.steamwar.fightsystem.fight.FightTeam;
import de.steamwar.fightsystem.fight.FightWorld;
@ -109,6 +110,7 @@ public class FightSystem extends JavaPlugin {
new WinconditionPercentTimeout();
new HellsBells();
new Meteor();
new NoPlayersOnlineCountdown();
new PreSchemCountdown();

Datei anzeigen

@ -203,6 +203,29 @@ BAR_WATER={0}
# Winconditions
HELLS_BELLS_COUNTDOWN=bis die Bomben fallen
HELLS_BELLS_START_1=§c!!Achtung!! Bomber im Anflug, noch ca. eine Minute bis zur Ankunft.
HELLS_BELLS_START_2=§cBomber im Anflug, ca. eine Minute bis zur Ankunft.
HELLS_BELLS_START_3=§cBomber auf dem Radar gesichtet, geschätzte Ankunftszeit: eine Minute.
HELLS_BELLS_START_4=§cUnbekanntes Flugobjekt gesichtet, trifft in ca. einer Minute ein.
HELLS_BELLS_START_5=§cFlugobjekt gesichtet. Ankunft in ca. einer Minute.
HELLS_BELLS_START_6=§cBomber erschienen, Ankunft ca. eine Minute.
HELLS_BELLS_SWAP_1=§aDie Bomben fallen nun schneller.
HELLS_BELLS_SWAP_2=§aMehr Bomber im Anflug.
HELLS_BELLS_SWAP_3=§aZusätzliche Bomber gesichtet.
HELLS_BELLS_SWAP_4=§aDas Bombardement scheint sich zu erhöhen.
METEOR_COUNTDOWN=bis es Meteore regnet
METEOR_START_1=§cEin Meteorschauer wurden am Himmel entdeckt
METEOR_START_2=§cSternschnuppen sind diesen Fight 100% wahrscheinlicher
METEOR_START_3=§cEs wurden Meteoriten am Himmel entdeckt, begeben sie sich umgehend in Sicherheit!
METEOR_START_4=§cDer Untergang steht nahe! Die Meteoriten werden uns in etwa einer Minute treffen.
METEOR_START_5=§fNEWS §cHeute Nachmittag wird es gröbere Meteoriten Schauer geben!
METEOR_START_6=§cNoch fliegende Airships sind dem Absturz geweiht.
METEOR_SWAP_1=§aEs hört nicht auf, die Meteoriten scheinen mehr zu werden.
METEOR_SWAP_2=§aDas war erst der Anfang, die Meteoriten kommen immer schneller und machen mehr Schaden.
METEOR_SWAP_3=§aEs scheint als würde es nicht aufhören, die Meteoriten kommen nur schneller!
METEOR_SWAP_4=§aEin weiterer Schauer ist entdeckt worden, begebt euch in Sicherheit!
TECHKO_COUNTDOWN=bis {0} §7einen Schuss abgegeben haben muss
WIN_FIGHTLEADER=§7Kampfleiterentscheidung

Datei anzeigen

@ -22,6 +22,7 @@ package de.steamwar.fightsystem.event;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.countdown.Countdown;
import de.steamwar.fightsystem.record.GlobalRecorder;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.fightsystem.utils.Message;
@ -33,6 +34,8 @@ import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.scheduler.BukkitTask;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
@ -50,11 +53,23 @@ public class HellsBells {
private HellsBellsCountdown currentCountdown;
private BukkitTask currentDropping;
private final List<String> startMessages = Arrays.asList("HELLS_BELLS_START_1", "HELLS_BELLS_START_2",
"HELLS_BELLS_START_3", "HELLS_BELLS_START_4", "HELLS_BELLS_START_5", "HELLS_BELLS_START_6");
private final List<String> stateSwapMessages = Arrays.asList("HELLS_BELLS_SWAP_1", "HELLS_BELLS_SWAP_2",
"HELLS_BELLS_SWAP_3", "HELLS_BELLS_SWAP_4");
public void startCountdown() {
if (current == State.PRE) {
if (current == HellsBells.State.PRE || current == HellsBells.State.FIRST) {
String startMessage = startMessages.get(random.nextInt(startMessages.size()));
GlobalRecorder.getInstance().system(startMessage);
FightSystem.getMessage().broadcast(startMessage);
current = current.getNext();
} else if (current != State.LAST && currentDrops >= current.SWITCH_AFTER) {
} else if (current != HellsBells.State.LAST && currentDrops >= current.SWITCH_AFTER) {
String stateSwapMessage = stateSwapMessages.get(random.nextInt(stateSwapMessages.size()));
GlobalRecorder.getInstance().system(stateSwapMessage);
FightSystem.getMessage().broadcast(stateSwapMessage);
currentDrops = 0;
current = current.getNext();
}
currentDrops++;
@ -137,23 +152,6 @@ public class HellsBells {
}
}
private static class Point {
private final int x;
private final int y;
private final int z;
public Point(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
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
}
}
private enum State {
PRE(60, 80, 1),

Datei anzeigen

@ -0,0 +1,219 @@
/*
Veraltet
Review

Fehlender License-Header

Fehlender License-Header
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.event;
import de.steamwar.fightsystem.Config;
import de.steamwar.fightsystem.FightSystem;
import de.steamwar.fightsystem.countdown.Countdown;
import de.steamwar.fightsystem.record.GlobalRecorder;
import de.steamwar.fightsystem.states.FightState;
import de.steamwar.fightsystem.states.StateDependent;
import de.steamwar.fightsystem.states.StateDependentListener;
import de.steamwar.fightsystem.utils.Message;
import de.steamwar.fightsystem.utils.SWSound;
import de.steamwar.fightsystem.winconditions.Winconditions;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.LargeFireball;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
public class Meteor implements Listener {
public static final Random random = new Random();
private final Vector vector = new Vector(0, -1, 0);
private final World world = Bukkit.getWorlds().get(0);
private final int xLength = Config.RedExtendRegion.getMaxX() - Config.RedExtendRegion.getMinX();
private final int zLength = Config.RedExtendRegion.getMaxZ() - Config.RedExtendRegion.getMinZ();
private Meteor.State current = Meteor.State.PRE;
private int currentDrops = 0;
private Meteor.MeteorCountdown currentCountdown;
private final AtomicInteger amount = new AtomicInteger(0);
private BukkitTask currentDropping;
private final List<String> startMessages = Arrays.asList("METEOR_START_1", "METEOR_START_2", "METEOR_START_3", "METEOR_START_4", "METEOR_START_5", "METEOR_START_6");
Veraltet
Review

Warum hier ein TNT Spawnen und nicht einfach die Explosionsstärke des Fireballs hochdrehen?

Warum hier ein TNT Spawnen und nicht einfach die Explosionsstärke des Fireballs hochdrehen?
Veraltet
Review

Damit Wasser mit weggeht? Das geht nur bei TNT Schaden weg, und ich weiß nicht ob es so gut ist (für Feuerbälle) dies zu erweitern.

Damit Wasser mit weggeht? Das geht nur bei TNT Schaden weg, und ich weiß nicht ob es so gut ist (für Feuerbälle) dies zu erweitern.
Veraltet
Review
Das ist FUD. Der WaterRemover schert sich nicht darum, ob es Feuerball oder TNT ist: https://steamwar.de/devlabs/SteamWar/FightSystem/src/branch/master/FightSystem_Core/src/de/steamwar/fightsystem/listener/WaterRemover.java
Veraltet
Review

Aber wenn ich einfach eine Explosion mache, macht er es nicht weg, dass war es nämlich vorher. Werden nicht auch die beiden arten von Explosionen, anders berechnet intern, muss ich mir mal angucken.

Aber wenn ich einfach eine Explosion mache, macht er es nicht weg, dass war es nämlich vorher. Werden nicht auch die beiden arten von Explosionen, anders berechnet intern, muss ich mir mal angucken.
Veraltet
Review

Es macht einen Unterschied, ob du einen Fireball oder einen Large_Fireball (o.ä.) spawnst. Der eine ist ein Dispenser-Fireball, der andere ein Ghast-/MissileWars-Fireball!

Es macht einen Unterschied, ob du einen Fireball oder einen Large_Fireball (o.ä.) spawnst. Der eine ist ein Dispenser-Fireball, der andere ein Ghast-/MissileWars-Fireball!
private final List<String> stateSwapMessages = Arrays.asList("METEOR_SWAP_1", "METEOR_SWAP_2", "METEOR_SWAP_3", "METEOR_SWAP_4");
public void startCountdown() {
if (current == Meteor.State.PRE || current == Meteor.State.FIRST) {
String startMessage = startMessages.get(random.nextInt(startMessages.size()));
GlobalRecorder.getInstance().system(startMessage);
FightSystem.getMessage().broadcast(startMessage);
current = current.getNext();
} else if (current != Meteor.State.LAST && currentDrops >= current.SWITCH_AFTER) {
String stateSwapMessage = stateSwapMessages.get(random.nextInt(stateSwapMessages.size()));
GlobalRecorder.getInstance().system(stateSwapMessage);
FightSystem.getMessage().broadcast(stateSwapMessage);
currentDrops = 0;
current = current.getNext();
}
currentDrops++;
currentCountdown = new Meteor.MeteorCountdown(current.MIN_TIME + random.nextInt(current.MAX_TIME - current.MIN_TIME));
currentCountdown.enable();
}
//@EventHandler
public void explode(ProjectileHitEvent event) {
if (event.getEntity() instanceof Fireball) {
TNTPrimed tnt = world.spawn(event.getEntity().getLocation(), TNTPrimed.class);
tnt.setVelocity(new Vector(0, 0, 0));
tnt.setFuseTicks(0);
tnt.setYield(((Fireball) event.getEntity()).getYield());
event.getEntity().remove();
}
}
public void drop() {
int randomAmount = current.minAmount + random.nextInt(current.maxAmount - current.minAmount);
if (amount.get() > 0) {
amount.set(amount.get() + randomAmount);
return;
}
amount.set(randomAmount);
currentDropping = Bukkit.getScheduler().runTaskTimer(FightSystem.getPlugin(), () -> {
int xOffset = getStart(xLength);
int zOffset = getStart(zLength);
int yOffset = getHeightStart();
Point redStart = new Point(Config.RedExtendRegion.getMinX() + xOffset, Config.RedExtendRegion.getMaxY() + yOffset, Config.RedExtendRegion.getMaxZ() - zOffset);
Point blueStart = new Point(Config.BlueExtendRegion.getMinX() + xOffset, Config.BlueExtendRegion.getMaxY() + yOffset, Config.BlueExtendRegion.getMinZ() + zOffset);
vector.setX(random.nextDouble() - 0.5);
vector.setZ(random.nextDouble() - 0.5);
LargeFireball fireballRed = world.spawn(redStart.toLocation(world), LargeFireball.class);
fireballRed.setDirection(vector);
fireballRed.setBounce(false);
fireballRed.setIsIncendiary(false);
fireballRed.setYield(current.explosionSize);
LargeFireball fireballBlue = world.spawn(blueStart.toLocation(world), LargeFireball.class);
vector.setZ(vector.getZ() * -1);
fireballBlue.setDirection(vector);
fireballBlue.setBounce(false);
fireballBlue.setIsIncendiary(false);
fireballBlue.setYield(current.explosionSize);
if (amount.decrementAndGet() <= 0) {
currentDropping.cancel();
}
}, 0L, 4L);
}
private int getStart(int regionSize) {
double randomNumber = (random.nextDouble() - random.nextDouble()) / 2 + 0.5;
Lixfel markierte diese Unterhaltung als gelöst
Review

Du instanzierst den Countdown nur an einer Stelle und brauchst sonst nie Spezialfunktionalität - kannst du eigentlich zu einer Lambda-Klasse verkürzen/einfachen.

Du instanzierst den Countdown nur an einer Stelle und brauchst sonst nie Spezialfunktionalität - kannst du eigentlich zu einer Lambda-Klasse verkürzen/einfachen.
Review

das ist einfach so aus HellsBells übernommen.

das ist einfach so aus HellsBells übernommen.
Bukkit.getLogger().log(Level.INFO, "Calculated Start: " + (int) (randomNumber * (regionSize - 1)));
return Math.max(Math.min((int) (randomNumber * (regionSize - 1)), regionSize - 1), 0);
}
private int getHeightStart() {
return 5 + random.nextInt(15);
}
public Meteor() {
new StateDependentListener(Winconditions.METEOR, FightState.Running, this);
new StateDependent(Winconditions.METEOR, FightState.Running) {
@Override
Lixfel markierte diese Unterhaltung als gelöst
Review

Gibts die Klasse nicht schon in HellsBells?

Gibts die Klasse nicht schon in HellsBells?
Review

Vermutlich schon.

Vermutlich schon.
public void enable() {
startCountdown();
}
@Override
public void disable() {
currentCountdown.disable();
}
}.register();
}
private class MeteorCountdown extends Countdown {
public MeteorCountdown(int time) {
super(time, new Message("METEOR_COUNTDOWN"), SWSound.BLOCK_NOTE_BASS, true);
}
Lixfel markierte diese Unterhaltung als gelöst
Review

Auch nicht genau so in HellsBells?

Auch nicht genau so in HellsBells?
Review

Die Klasse schon, sie hat nur andere Werte! Vllt könnte man sich da eine kleine lineare State Machine ausdenken, welche das gleiche Macht.

Die Klasse schon, sie hat nur andere Werte! Vllt könnte man sich da eine kleine lineare State Machine ausdenken, welche das gleiche Macht.
@Override
public void countdownFinished() {
drop();
startCountdown();
}
}
private enum State {
PRE(60, 80, 1, 0, 0, 0),
FIRST(25, 35, 6, 2, 3, 6),
SECOND(20, 30, 7, 4, 4, 8),
THIRD(15, 25, 7, 4, 5, 10),
FOURTH(10, 20, 8, 6, 7, 14),
LAST(5, 10, 0, 6, 9, 18);
State(int minTime, int maxTime, int switchAfter, int explosionSize, int minAmount, int maxAmount) {
this.MIN_TIME = minTime;
this.MAX_TIME = maxTime;
this.SWITCH_AFTER = switchAfter;
this.explosionSize = explosionSize;
this.minAmount = minAmount;
this.maxAmount = maxAmount;
}
private final int MIN_TIME; //NOSONAR
private final int MAX_TIME; //NOSONAR
private final int SWITCH_AFTER; //NOSONAR
private final int explosionSize; //NOSONAR
private final int minAmount;
private final int maxAmount;
public Meteor.State getNext() {
switch (this) {
case PRE:
return FIRST;
case FIRST:
return SECOND;
case SECOND:
return THIRD;
case THIRD:
return FOURTH;
case FOURTH:
case LAST:
return LAST;
default:
return PRE;
}
}
}
}

Datei anzeigen

@ -0,0 +1,44 @@
/*
* 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.event;
import org.bukkit.Location;
import org.bukkit.World;
class Point {
private final int x;
private final int y;
private final int z;
public Point(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public Location toLocation(World world) {
return new Location(world, this.x, this.y, this.z); //NOSONAR
}
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
}
}

Datei anzeigen

@ -29,6 +29,7 @@ import de.steamwar.fightsystem.utils.Message;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityExplodeEvent;
@ -105,7 +106,7 @@ public class PercentWincondition extends Wincondition implements PrintableWincon
@EventHandler
public void onEntityExplode(EntityExplodeEvent event) {
if (explosionFilter.getAsBoolean() || !team.getExtendRegion().inRegion(event.getEntity().getLocation())) {
if (event.getEntityType() == EntityType.FIREBALL || explosionFilter.getAsBoolean() || !team.getExtendRegion().inRegion(event.getEntity().getLocation())) {
return;
}

Datei anzeigen

@ -36,5 +36,6 @@ public enum Winconditions {
WATER_TECH_KO,
PUMPKIN_TECH_KO,
HELLS_BELLS
HELLS_BELLS,
METEOR
}