Add MissileWars module

This commit is contained in:
2024-08-04 23:09:23 +02:00
parent ca143f2412
commit 391b8c3854
58 changed files with 4305 additions and 0 deletions
@@ -0,0 +1,84 @@
/*
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.misslewars.items;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import de.steamwar.misslewars.MissileWars;
import de.steamwar.misslewars.scripts.ScriptedItem;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Objects;
public class CustomItem extends SpecialItem {
private ScriptedItem scriptedItem;
public CustomItem(ScriptedItem scriptedItem) {
this.scriptedItem = scriptedItem;
}
@Override
public ItemStack getItem() {
return scriptedItem.getItemStack();
}
@Override
public boolean handleUse(Player p) {
return scriptedItem.execute(ScriptedItem.EventType.onClick, p, p.getLocation());
}
@Override
public void handleThrow(Entity e) {
scriptedItem.execute(ScriptedItem.EventType.onThrow, e, e.getLocation());
}
@Override
public void handleHit(Entity e, Location l) {
scriptedItem.execute(ScriptedItem.EventType.onHit, e, l);
}
public static void init() {
File itemsFolder = new File(MissileWars.getPlugin().getDataFolder(), "items");
if (!itemsFolder.exists() || !itemsFolder.canRead() || !itemsFolder.isDirectory()) throw new SecurityException("Items could not be loaded");
for (File itemFile : Objects.requireNonNull(itemsFolder.listFiles())) {
if (!itemFile.canRead() || !itemFile.isFile()) continue;
try {
JsonObject jsonObject = new JsonParser().parse(new FileReader(itemFile)).getAsJsonObject();
new CustomItem(new ScriptedItem(jsonObject));
} catch (JsonSyntaxException | IOException e) {
e.printStackTrace();
throw new SecurityException("Item JSON error " + itemFile, e);
}
}
}
public ScriptedItem getScriptedItem() {
return scriptedItem;
}
}
@@ -0,0 +1,135 @@
/*
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.misslewars.items;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
import com.sk89q.worldedit.function.mask.BlockTypeMask;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockTypes;
import de.steamwar.misslewars.MissileWars;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class Missile extends SpecialItem {
private static final World world = new BukkitWorld(Bukkit.getWorlds().get(0));
private final Clipboard clipboard;
private final ItemStack item;
private Missile(File missileFile) {
String[] strings = missileFile.getName().split("\\.");
String name = strings[0];
String material = strings[1];
if (!material.endsWith("_SPAWN_EGG")) material += "_SPAWN_EGG";
Material itemType = Material.valueOf(material);
ClipboardFormat format = ClipboardFormats.findByFile(missileFile);
try {
assert format != null;
clipboard = format.getReader(new FileInputStream(missileFile)).read();
} catch (IOException e) {
throw new SecurityException("Corrupt missile");
}
List<String> lore = new ArrayList<>();
lore(lore, strings, 2, "§7Speed");
lore(lore, strings, 3, "§7Size");
EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1);
BlockTypeMask blockTypeMask = new BlockTypeMask(clipboard, BlockTypes.TNT);
lore.add("§7TNT §8: §e" + e.countBlocks(clipboard.getRegion(), blockTypeMask));
item = createItem(itemType, "§c" + name, 1, lore);
}
private void lore(List<String> lore, String[] args, int index, String tag) {
if (args.length > index) {
lore.add(tag + " §8: §e" + Integer.parseInt(args[index]) + "§8/§77");
} else {
lore.add(tag + " §8: §e0§8/§77");
}
}
@Override
public ItemStack getItem() {
return item;
}
@Override
public boolean handleUse(Player p) {
BlockVector3 dimensions = clipboard.getDimensions();
Location location = p.getLocation();
BlockVector3 v = BlockVector3.ZERO;
BlockVector3 offset = clipboard.getRegion().getMinimumPoint().subtract(clipboard.getOrigin());
AffineTransform aT = new AffineTransform();
double yaw = (p.getLocation().getYaw() + 360f) % 360;
if (yaw > 45 && yaw <= 135) aT = aT.rotateY(270);
else if (yaw > 135 && yaw <= 225) aT = aT.rotateY(180);
else if (yaw > 225 && yaw <= 315) aT = aT.rotateY(90);
v = v.subtract(dimensions.getX()/2, dimensions.getY() + 2, -2).subtract(offset);
v = aT.apply(v.toVector3()).toBlockPoint();
v = v.add(location.getBlockX(), location.getBlockY(), location.getBlockZ());
EditSession e = WorldEdit.getInstance().getEditSessionFactory().getEditSession(world, -1);
ClipboardHolder ch = new ClipboardHolder(clipboard);
ch.setTransform(aT);
Operations.completeBlindly(ch.createPaste(e).to(v).ignoreAirBlocks(true).build());
e.flushSession();
return true;
}
@Override
public boolean isMissile() {
return true;
}
public static void init() {
File missileFolder = new File(MissileWars.getPlugin().getDataFolder(), "missiles");
if (!missileFolder.exists() || !missileFolder.canRead() || !missileFolder.isDirectory()) throw new SecurityException("Missiles could not be loaded");
for (File missileFile : Objects.requireNonNull(missileFolder.listFiles())) {
if (!missileFile.canRead() || !missileFile.isFile()) continue;
if (!missileFile.getName().endsWith(".schem")) continue;
new Missile(missileFile);
}
}
}
@@ -0,0 +1,132 @@
/*
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.misslewars.items;
import de.steamwar.misslewars.Config;
import net.md_5.bungee.api.ChatMessageType;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.potion.PotionEffectType;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public abstract class SpecialItem {
private static final Random random = new Random();
private static double count = 0;
private static int consecutiveSupportItems = 0;
private static List<SpecialItem> supportItems = new ArrayList<>();
private static List<SpecialItem> missileItems = new ArrayList<>();
SpecialItem() {
if (this.isMissile()) missileItems.add(this);
else supportItems.add(this);
}
private String materialName = null;
public abstract ItemStack getItem();
public abstract boolean handleUse(Player p);
public void handleThrow(Entity e) {}
public void handleHit(Entity e, Location l) {}
public boolean isMissile() {
return false;
}
public ItemStack createItem(Material material, String name, int amount, List<String> lore) {
ItemStack item = new ItemStack(material, amount);
ItemMeta meta = item.getItemMeta();
assert meta != null;
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
meta.setLore(lore);
meta.setDisplayName(name);
item.setItemMeta(meta);
return item;
}
public static boolean handleUse(ItemStack item, Player player) {
if (player.hasPotionEffect(PotionEffectType.LEVITATION)) {
player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText("§cDu kannst dieses Item derzeit nicht nutzen!"));
return false;
}
return handleUse(item, player, missileItems) || handleUse(item, player, supportItems);
}
private static boolean handleUse(ItemStack item, Player player, List<SpecialItem> items) {
for (SpecialItem specialItem : items)
if (item.isSimilar(specialItem.getItem())) return specialItem.handleUse(player);
return false;
}
public static void handleThrow(ProjectileLaunchEvent e) {
String name = e.getEntity().getClass().getName().toLowerCase();
for (SpecialItem specialItem : supportItems) {
if (specialItem.materialName == null)
specialItem.materialName = specialItem.getItem().getType().name().toLowerCase();
if (name.contains(specialItem.materialName))
specialItem.handleThrow(e.getEntity());
}
}
public static void handleHit(ProjectileHitEvent e) {
String name = e.getEntity().getClass().getName().toLowerCase();
Location location = null;
if (e.getHitEntity() != null) location = e.getHitEntity().getLocation();
else if (e.getHitBlock() != null) location = e.getHitBlock().getLocation();
if (location == null) return;
for (SpecialItem specialItem : supportItems) {
if (name.contains(((CustomItem) specialItem).getScriptedItem().getEntityName())) {
specialItem.handleHit(e.getEntity(), location);
}
}
}
public static ItemStack getRandomItem() {
if (Config.MissileChance == 0 || consecutiveSupportItems > 1) {
consecutiveSupportItems = 0;
return supportItems.get(random.nextInt(supportItems.size())).getItem();
}
if (Config.MissileChance == 1) {
return missileItems.get(random.nextInt(missileItems.size())).getItem();
}
double missileChance = Config.MissileChance + count * 0.1;
if (random.nextDouble() > missileChance) {
count += Config.MissileChance;
consecutiveSupportItems++;
return supportItems.get(random.nextInt(supportItems.size())).getItem();
} else {
count -= 1 - Config.MissileChance;
return missileItems.get(random.nextInt(missileItems.size())).getItem();
}
}
}