Meteor #324
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
219
FightSystem_Core/src/de/steamwar/fightsystem/event/Meteor.java
Normale Datei
@ -0,0 +1,219 @@
|
||||
/*
|
||||
|
||||
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");
|
||||
Lixfel
hat
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?
YoyoNow
hat
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.
Lixfel
hat
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 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
YoyoNow
hat
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.
Lixfel
hat
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
Lixfel
hat
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.
YoyoNow
hat
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
Lixfel
hat
Gibts die Klasse nicht schon in HellsBells? Gibts die Klasse nicht schon in HellsBells?
YoyoNow
hat
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
Lixfel
hat
Auch nicht genau so in HellsBells? Auch nicht genau so in HellsBells?
YoyoNow
hat
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
44
FightSystem_Core/src/de/steamwar/fightsystem/event/Point.java
Normale Datei
@ -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
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -36,5 +36,6 @@ public enum Winconditions {
|
||||
WATER_TECH_KO,
|
||||
PUMPKIN_TECH_KO,
|
||||
|
||||
HELLS_BELLS
|
||||
HELLS_BELLS,
|
||||
METEOR
|
||||
}
|
||||
|
Fehlender License-Header