forked from SteamWar/SteamWar
267 lines
7.8 KiB
Java
267 lines
7.8 KiB
Java
/*
|
|
* This file is a part of the SteamWar software.
|
|
*
|
|
* Copyright (C) 2025 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.bausystem.world;
|
|
|
|
import de.steamwar.bausystem.BauSystem;
|
|
import de.steamwar.bausystem.FlatteningWrapper;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.EventHandler;
|
|
import org.bukkit.event.HandlerList;
|
|
import org.bukkit.event.Listener;
|
|
import org.bukkit.event.block.Action;
|
|
import org.bukkit.event.block.BlockPlaceEvent;
|
|
import org.bukkit.event.player.PlayerInteractEvent;
|
|
import org.bukkit.event.player.PlayerQuitEvent;
|
|
import org.bukkit.scheduler.BukkitTask;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.LinkedList;
|
|
import java.util.ListIterator;
|
|
import java.util.Map;
|
|
|
|
public class AutoLoader extends AbstractAutoLoader implements Listener {
|
|
|
|
private static final Map<Player, AutoLoader> players = new HashMap<>();
|
|
|
|
public static AutoLoader getLoader(Player player){
|
|
if(!players.containsKey(player))
|
|
return new AutoLoader(player);
|
|
return players.get(player);
|
|
}
|
|
|
|
public static boolean hasLoader(Player player){
|
|
return players.containsKey(player);
|
|
}
|
|
|
|
private final Player player;
|
|
private final BukkitTask task;
|
|
|
|
private final LinkedList<LoaderAction> actions = new LinkedList<>();
|
|
private int ticksBetweenShots = 80;
|
|
private int ticksBetweenBlocks = 1;
|
|
|
|
private int lastActivation;
|
|
private int waitTicks;
|
|
private ListIterator<LoaderAction> lastAction;
|
|
private boolean setup;
|
|
private Location lastLocation;
|
|
|
|
private AutoLoader(Player player){
|
|
this.player = player;
|
|
Bukkit.getPluginManager().registerEvents(this, BauSystem.getPlugin());
|
|
task = Bukkit.getScheduler().runTaskTimer(BauSystem.getPlugin(), this::run, 1, 1);
|
|
players.put(player, this);
|
|
player.sendMessage(BauSystem.PREFIX + "§7Schieße bitte einmal die Kanone ab");
|
|
player.sendMessage(BauSystem.PREFIX + "§7Und starte anschließend den AutoLader mit §8/§eloader start");
|
|
setup();
|
|
}
|
|
|
|
public void setup(){
|
|
print("§aAutoLader im Setup-Modus", false);
|
|
setup = true;
|
|
waitTicks = 0;
|
|
lastActivation = 0;
|
|
}
|
|
|
|
public void start(){
|
|
if(actions.isEmpty()){
|
|
print("§cKeine Aktion vorhanden", false);
|
|
return;
|
|
}
|
|
|
|
if(!setup){
|
|
print("§cAutoLader läuft bereits", false);
|
|
return;
|
|
}
|
|
|
|
setup = false;
|
|
waitTicks = 0;
|
|
lastActivation = 0;
|
|
lastAction = actions.listIterator();
|
|
print("§aAutoLader gestartet", false);
|
|
}
|
|
|
|
public void stop(){
|
|
print("§cAutoLader gestoppt", false);
|
|
players.remove(player);
|
|
HandlerList.unregisterAll(this);
|
|
if(task != null)
|
|
task.cancel();
|
|
}
|
|
|
|
public void undo(){
|
|
if(actions.isEmpty()){
|
|
print("§cKeine Aktion vorhanden", false);
|
|
return;
|
|
}
|
|
|
|
actions.removeLast();
|
|
print("§aUndo erfolgreich", true);
|
|
}
|
|
|
|
public void wait(int time){
|
|
if(time < 1){
|
|
print("§cDie Wartezeit ist zu klein", false);
|
|
return;
|
|
}
|
|
|
|
print("§aSchusswartezeit §e" + time + " §aTicks§8, zuvor " + ticksBetweenShots, false);
|
|
ticksBetweenShots = time;
|
|
}
|
|
|
|
public void blockWait(int time){
|
|
if(time < 1){
|
|
print("§cDie Wartezeit ist zu klein", false);
|
|
return;
|
|
}
|
|
|
|
print("§aSetzwartezeit §e" + time + " §aTicks§8, zuvor " + ticksBetweenBlocks, false);
|
|
ticksBetweenBlocks = time;
|
|
}
|
|
|
|
public int getTicksBetweenShots() {
|
|
return ticksBetweenShots;
|
|
}
|
|
|
|
public int getTicksBetweenBlocks() {
|
|
return ticksBetweenBlocks;
|
|
}
|
|
|
|
public boolean isSetup() {
|
|
return setup;
|
|
}
|
|
|
|
@EventHandler
|
|
public void onBlockPlace(BlockPlaceEvent event){
|
|
if(!setup || !event.getPlayer().equals(player))
|
|
return;
|
|
if(event.getBlock().getType() != Material.TNT)
|
|
return;
|
|
|
|
new TNTPlaceAction(this, event.getBlock().getLocation());
|
|
print("§eTNT platziert", true);
|
|
}
|
|
|
|
//BlockRedstoneEvent?
|
|
@EventHandler
|
|
public void onPlayerInteract(PlayerInteractEvent event){
|
|
if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.PHYSICAL)
|
|
return;
|
|
if (event.getClickedBlock().getType() == Material.OBSERVER)
|
|
return;
|
|
if (event.getPlayer().isSneaking())
|
|
return;
|
|
|
|
if (!setup || !event.getPlayer().equals(player))
|
|
return;
|
|
|
|
Detoloader detoloader = FlatteningWrapper.impl.onPlayerInteractLoader(event);
|
|
if (detoloader == null || detoloader.getActivation() < 0) return;
|
|
|
|
if (lastLocation != null && lastLocation.distance(event.getClickedBlock().getLocation()) <= 1) return;
|
|
|
|
if (detoloader.useActive) {
|
|
new AbstractAutoLoader.RedstoneActivation(this, event.getClickedBlock().getLocation()
|
|
, detoloader.getActivation() == 0 ? getLastActivation() : detoloader.getActivation()
|
|
, detoloader.isActive());
|
|
} else {
|
|
new AbstractAutoLoader.TemporaryActivation(this, event.getClickedBlock().getLocation()
|
|
, detoloader.getActivation());
|
|
}
|
|
print(detoloader.addBack ? "§e" + detoloader.getBlock() + " betätigt" :
|
|
detoloader.getBlock(), detoloader.addBack);
|
|
lastLocation = event.getClickedBlock().getLocation();
|
|
}
|
|
|
|
@EventHandler
|
|
public void onLeave(PlayerQuitEvent event){
|
|
if(!event.getPlayer().equals(player))
|
|
return;
|
|
stop();
|
|
}
|
|
|
|
private void run(){
|
|
lastActivation++;
|
|
if(setup)
|
|
return;
|
|
while(lastActivation >= waitTicks){
|
|
lastActivation = 0;
|
|
|
|
LoaderAction action = lastAction.next();
|
|
if(action.perform()){
|
|
waitTicks = action.ticks();
|
|
}else{
|
|
waitTicks = 1;
|
|
lastAction.previous();
|
|
}
|
|
|
|
if(!lastAction.hasNext()){
|
|
lastAction = actions.listIterator();
|
|
waitTicks = ticksBetweenShots;
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
Player getPlayer() {
|
|
return player;
|
|
}
|
|
|
|
@Override
|
|
boolean setRedstone(Location location, boolean active){
|
|
return FlatteningWrapper.impl.setRedstone(location, active);
|
|
}
|
|
|
|
@Override
|
|
LinkedList<LoaderAction> getActions() {
|
|
return actions;
|
|
}
|
|
|
|
@Override
|
|
void resetLastActivation() {
|
|
lastActivation = 0;
|
|
}
|
|
|
|
@Override
|
|
int getLastActivation() {
|
|
return lastActivation;
|
|
}
|
|
|
|
class TNTPlaceAction extends AbstractAutoLoader.LoaderAction {
|
|
|
|
TNTPlaceAction(AbstractAutoLoader loader, Location location){
|
|
super(loader, location);
|
|
}
|
|
|
|
@Override
|
|
public boolean perform() {
|
|
return FlatteningWrapper.impl.tntPlaceActionPerform(location);
|
|
}
|
|
|
|
@Override
|
|
int ticks(){
|
|
return ticksBetweenBlocks;
|
|
}
|
|
}
|
|
}
|