mirror of
https://github.com/DRE2N/DungeonsXL.git
synced 2024-11-28 13:36:33 +01:00
Add donors addon module
This commit is contained in:
parent
75945ce8a6
commit
74a879212c
7
addon/README.md
Normal file
7
addon/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
## DungeonsXL Donors Addon
|
||||
|
||||
(C) 2020 Daniel Saukel, All Rights Reserved.
|
||||
|
||||
This module is a plugin with additional features made for donors.
|
||||
|
||||
The GNU LGPLv3 of the API and the GNU GPLv3 license of the other modules do not apply to this module.
|
32
addon/core/pom.xml
Normal file
32
addon/core/pom.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.erethon.dungeonsxl</groupId>
|
||||
<artifactId>dungeonsxl-addon-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
<parent>
|
||||
<groupId>de.erethon.dungeonsxl</groupId>
|
||||
<artifactId>dungeonsxl-addon</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<targetPath>.</targetPath>
|
||||
<filtering>true</filtering>
|
||||
<directory>src/main/resources/</directory>
|
||||
<includes>
|
||||
<include>plugin.yml</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot</artifactId>
|
||||
<version>${spigotVersion.latest}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Daniel Saukel
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
package de.erethon.dungeonsxxl;
|
||||
|
||||
import de.erethon.commons.compatibility.Internals;
|
||||
import de.erethon.commons.javaplugin.DREPlugin;
|
||||
import de.erethon.commons.javaplugin.DREPluginSettings;
|
||||
import de.erethon.dungeonsxl.DungeonsXL;
|
||||
import de.erethon.dungeonsxxl.requirement.*;
|
||||
import de.erethon.dungeonsxxl.sign.*;
|
||||
import de.erethon.dungeonsxxl.util.GlowUtil;
|
||||
|
||||
/**
|
||||
* @author Daniel Saukel
|
||||
*/
|
||||
public class DungeonsXXL extends DREPlugin {
|
||||
|
||||
private DungeonsXL dxl;
|
||||
private GlowUtil glowUtil;
|
||||
|
||||
public DungeonsXXL() {
|
||||
settings = DREPluginSettings.builder()
|
||||
.internals(Internals.v1_15_R1)
|
||||
.metrics(false)
|
||||
.spigotMCResourceId(-1)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
dxl = DungeonsXL.getInstance();
|
||||
glowUtil = new GlowUtil(this);
|
||||
|
||||
dxl.getRequirementRegistry().add("feeItems", FeeItemsRequirement.class);
|
||||
|
||||
dxl.getSignRegistry().add("Firework", FireworkSign.class);
|
||||
dxl.getSignRegistry().add("GlowingBlock", GlowingBlockSign.class);
|
||||
dxl.getSignRegistry().add("InteractWall", InteractWallSign.class);
|
||||
dxl.getSignRegistry().add("Particle", ParticleSign.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instance of this plugin.
|
||||
*
|
||||
* @return the instance of this plugin
|
||||
*/
|
||||
public static DungeonsXXL getInstance() {
|
||||
return (DungeonsXXL) DREPlugin.getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current {@link de.erethon.dungeonsxl.DungeonsXL} singleton.
|
||||
*
|
||||
* @return the current {@link de.erethon.dungeonsxl.DungeonsXL} singleton
|
||||
*/
|
||||
public DungeonsXL getDXL() {
|
||||
return dxl;
|
||||
}
|
||||
|
||||
/**
|
||||
* The loaded instance of GlowUtil.
|
||||
*
|
||||
* @return the loaded instance of GlowUtil
|
||||
*/
|
||||
public GlowUtil getGlowUtil() {
|
||||
return glowUtil;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Daniel Saukel
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
package de.erethon.dungeonsxxl.requirement;
|
||||
|
||||
import de.erethon.dungeonsxl.api.DungeonsAPI;
|
||||
import de.erethon.dungeonsxl.api.Requirement;
|
||||
import de.erethon.dungeonsxl.config.DMessage;
|
||||
import java.util.List;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
/**
|
||||
* @author Daniel Saukel
|
||||
*/
|
||||
public class FeeItemsRequirement implements Requirement {
|
||||
|
||||
private DungeonsAPI api;
|
||||
|
||||
private List<ItemStack> fee;
|
||||
|
||||
public FeeItemsRequirement(DungeonsAPI api) {
|
||||
this.api = api;
|
||||
}
|
||||
|
||||
public List<ItemStack> getFee() {
|
||||
return fee;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(ConfigurationSection config) {
|
||||
fee = api.getCaliburn().deserializeStackList(config, "feeItems");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(Player player) {
|
||||
for (ItemStack stack : fee) {
|
||||
if (!player.getInventory().containsAtLeast(stack, stack.getAmount())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseComponent[] getCheckMessage(Player player) {
|
||||
ComponentBuilder builder = new ComponentBuilder(DMessage.REQUIREMENT_FEE_ITEMS + ": ").color(ChatColor.GOLD);
|
||||
boolean first = true;
|
||||
for (ItemStack stack : fee) {
|
||||
String name = stack.getAmount() > 1 ? stack.getAmount() + " " : "" + api.getCaliburn().getExItem(stack).getName();
|
||||
ChatColor color = player.getInventory().containsAtLeast(stack, stack.getAmount()) ? ChatColor.GREEN : ChatColor.DARK_RED;
|
||||
if (!first) {
|
||||
builder.append(", ").color(ChatColor.WHITE);
|
||||
} else {
|
||||
first = false;
|
||||
}
|
||||
builder.append(name).color(color);
|
||||
}
|
||||
return builder.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void demand(Player player) {
|
||||
player.getInventory().removeItem(fee.toArray(new ItemStack[]{}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FeeItemsRequirement{items=" + fee + "}";
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Daniel Saukel
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
package de.erethon.dungeonsxxl.sign;
|
||||
|
||||
import de.erethon.dungeonsxl.api.DungeonsAPI;
|
||||
import de.erethon.dungeonsxl.api.sign.Button;
|
||||
import de.erethon.dungeonsxl.api.world.InstanceWorld;
|
||||
import de.erethon.dungeonsxl.player.DPermission;
|
||||
import de.erethon.dungeonsxxl.util.FireworkUtil;
|
||||
import org.bukkit.block.Sign;
|
||||
|
||||
/**
|
||||
* @author Daniel Saukel
|
||||
*/
|
||||
public class FireworkSign extends Button {
|
||||
|
||||
public FireworkSign(DungeonsAPI api, Sign sign, String[] lines, InstanceWorld instance) {
|
||||
super(api, sign, lines, instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Firework";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBuildPermission() {
|
||||
return DPermission.SIGN.getNode() + ".firework";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnDungeonInit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSetToAir() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push() {
|
||||
FireworkUtil.spawnRandom(getSign().getLocation());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Daniel Saukel
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
package de.erethon.dungeonsxxl.sign;
|
||||
|
||||
import de.erethon.commons.misc.BlockUtil;
|
||||
import de.erethon.commons.misc.EnumUtil;
|
||||
import de.erethon.dungeonsxl.api.DungeonsAPI;
|
||||
import de.erethon.dungeonsxl.api.sign.Rocker;
|
||||
import de.erethon.dungeonsxl.api.world.InstanceWorld;
|
||||
import de.erethon.dungeonsxl.player.DPermission;
|
||||
import de.erethon.dungeonsxl.world.DGameWorld;
|
||||
import de.erethon.dungeonsxxl.DungeonsXXL;
|
||||
import de.erethon.dungeonsxxl.world.block.GlowingBlock;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.block.Sign;
|
||||
|
||||
/**
|
||||
* Turns the attached block into a glowing block.
|
||||
*
|
||||
* @author Daniel Saukel
|
||||
*/
|
||||
public class GlowingBlockSign extends Rocker {
|
||||
|
||||
private ChatColor color = ChatColor.DARK_RED;
|
||||
private Double time;
|
||||
|
||||
private GlowingBlock glowingBlock;
|
||||
|
||||
public GlowingBlockSign(DungeonsAPI api, Sign sign, String[] lines, InstanceWorld instance) {
|
||||
super(api, sign, lines, instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the glowing block.
|
||||
*
|
||||
* @return the glowing block
|
||||
*/
|
||||
public GlowingBlock getGlowingBlock() {
|
||||
return glowingBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color of the glowing block or null if it is a rainbow block.
|
||||
*
|
||||
* @return the color of the glowing block or null if it is a rainbow block
|
||||
*/
|
||||
public ChatColor getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "GlowingBlock";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBuildPermission() {
|
||||
return DPermission.SIGN.getNode() + ".glowingblock";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnDungeonInit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSetToAir() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
if (getLine(1).equalsIgnoreCase("RAINBOW")) {
|
||||
color = null;
|
||||
} else {
|
||||
ChatColor color = EnumUtil.getEnumIgnoreCase(ChatColor.class, getLine(1));
|
||||
if (color != null) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
||||
try {
|
||||
time = Double.parseDouble(getLine(2));
|
||||
} catch (NumberFormatException exception) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void activate() {
|
||||
if (active) {
|
||||
return;
|
||||
}
|
||||
|
||||
((DGameWorld) getGameWorld()).addGameBlock(
|
||||
glowingBlock = new GlowingBlock(DungeonsXXL.getInstance(), BlockUtil.getAttachedBlock(getSign().getBlock()), color, time));
|
||||
active = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivate() {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
|
||||
glowingBlock.removeGlow();
|
||||
active = false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Daniel Saukel
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
package de.erethon.dungeonsxxl.sign;
|
||||
|
||||
import de.erethon.commons.misc.BlockUtil;
|
||||
import de.erethon.commons.misc.NumberUtil;
|
||||
import de.erethon.dungeonsxl.api.DungeonsAPI;
|
||||
import de.erethon.dungeonsxl.api.world.InstanceWorld;
|
||||
import de.erethon.dungeonsxl.player.DPermission;
|
||||
import de.erethon.dungeonsxl.sign.passive.InteractSign;
|
||||
import de.erethon.dungeonsxl.trigger.InteractTrigger;
|
||||
import de.erethon.dungeonsxl.world.DGameWorld;
|
||||
import org.bukkit.block.Sign;
|
||||
|
||||
/**
|
||||
* This sign adds an interact trigger to an attached block, like a "suspicious wall".
|
||||
*
|
||||
* @author Daniel Saukel
|
||||
*/
|
||||
public class InteractWallSign extends InteractSign {
|
||||
|
||||
public InteractWallSign(DungeonsAPI api, Sign sign, String[] lines, InstanceWorld instance) {
|
||||
super(api, sign, lines, instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "InteractWall";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBuildPermission() {
|
||||
return DPermission.SIGN.getNode() + ".interactwall";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnDungeonInit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtected() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSetToAir() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
InteractTrigger trigger = InteractTrigger.getOrCreate(NumberUtil.parseInt(getSign().getLine(1)),
|
||||
BlockUtil.getAttachedBlock(getSign().getBlock()), (DGameWorld) getGameWorld());
|
||||
if (trigger != null) {
|
||||
trigger.addListener(this);
|
||||
addTrigger(trigger);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Daniel Saukel
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
package de.erethon.dungeonsxxl.sign;
|
||||
|
||||
import de.erethon.commons.misc.EnumUtil;
|
||||
import de.erethon.commons.misc.NumberUtil;
|
||||
import de.erethon.dungeonsxl.api.DungeonsAPI;
|
||||
import de.erethon.dungeonsxl.api.sign.Button;
|
||||
import de.erethon.dungeonsxl.api.world.InstanceWorld;
|
||||
import de.erethon.dungeonsxl.player.DPermission;
|
||||
import org.bukkit.Particle;
|
||||
import org.bukkit.block.Sign;
|
||||
|
||||
/**
|
||||
* Spawns particles.
|
||||
*
|
||||
* @author Daniel Saukel
|
||||
*/
|
||||
public class ParticleSign extends Button {
|
||||
|
||||
private Particle particle;
|
||||
private int count;
|
||||
private double offsetX, offsetY, offsetZ;
|
||||
private double extra = 1;
|
||||
|
||||
public ParticleSign(DungeonsAPI api, Sign sign, String[] lines, InstanceWorld instance) {
|
||||
super(api, sign, lines, instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Particle";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBuildPermission() {
|
||||
return DPermission.SIGN.getNode() + ".particle";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnDungeonInit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isProtected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSetToAir() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() {
|
||||
particle = EnumUtil.getEnumIgnoreCase(Particle.class, getLine(1));
|
||||
if (particle == null) {
|
||||
markAsErroneous("Unknown particle type: " + getLine(1));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
String[] args = getLine(2).split(",");
|
||||
if (args.length == 1) {
|
||||
extra = NumberUtil.parseDouble(args[0], 1);
|
||||
} else if (args.length >= 3) {
|
||||
offsetX = NumberUtil.parseDouble(args[0], 0);
|
||||
offsetX = NumberUtil.parseDouble(args[1], 0);
|
||||
offsetX = NumberUtil.parseDouble(args[2], 0);
|
||||
if (args.length == 4) {
|
||||
extra = NumberUtil.parseDouble(args[3], 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push() {
|
||||
getSign().getWorld().spawnParticle(particle, getSign().getLocation(), count, offsetX, offsetY, offsetZ, extra);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Daniel Saukel
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
package de.erethon.dungeonsxxl.util;
|
||||
|
||||
import java.util.Random;
|
||||
import org.bukkit.Color;
|
||||
import static org.bukkit.Color.*;
|
||||
import org.bukkit.FireworkEffect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.inventory.meta.FireworkMeta;
|
||||
|
||||
/**
|
||||
* Util class for randomized fireworks.
|
||||
*
|
||||
* @author Daniel Saukel
|
||||
*/
|
||||
public class FireworkUtil {
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
private static final Color[] COLORS = {YELLOW, AQUA, BLACK, BLUE, FUCHSIA, GRAY, GREEN, LIME, MAROON, NAVY, OLIVE, ORANGE, PURPLE, RED, SILVER, TEAL, WHITE};
|
||||
|
||||
/**
|
||||
* Spawns a randomized firework.
|
||||
*
|
||||
* @param location the location where the firework is fired
|
||||
* @return the Firework
|
||||
*/
|
||||
public static Firework spawnRandom(Location location) {
|
||||
Firework firework = (Firework) location.getWorld().spawnEntity(location, EntityType.FIREWORK);
|
||||
FireworkMeta meta = firework.getFireworkMeta();
|
||||
Random r = new Random();
|
||||
int rt = r.nextInt(4) + 1;
|
||||
FireworkEffect.Type type = FireworkEffect.Type.BALL;
|
||||
if (rt == 1) {
|
||||
type = FireworkEffect.Type.BALL;
|
||||
}
|
||||
if (rt == 2) {
|
||||
type = FireworkEffect.Type.BALL_LARGE;
|
||||
}
|
||||
if (rt == 3) {
|
||||
type = FireworkEffect.Type.BURST;
|
||||
}
|
||||
if (rt == 4) {
|
||||
type = FireworkEffect.Type.CREEPER;
|
||||
}
|
||||
if (rt == 5) {
|
||||
type = FireworkEffect.Type.STAR;
|
||||
}
|
||||
FireworkEffect effect = FireworkEffect.builder().flicker(r.nextBoolean()).withColor(randomColor()).withFade(randomColor()).with(type).trail(r.nextBoolean()).build();
|
||||
meta.addEffect(effect);
|
||||
int rp = r.nextInt(2) + 1;
|
||||
meta.setPower(rp);
|
||||
firework.setFireworkMeta(meta);
|
||||
return firework;
|
||||
}
|
||||
|
||||
private static Color randomColor() {
|
||||
return COLORS[RANDOM.nextInt(COLORS.length - 1)];
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,380 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Daniel Saukel
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
package de.erethon.dungeonsxxl.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Random;
|
||||
import net.minecraft.server.v1_15_R1.EntityShulker;
|
||||
import net.minecraft.server.v1_15_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_15_R1.Packet;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutEntityDestroy;
|
||||
import net.minecraft.server.v1_15_R1.PacketPlayOutSpawnEntityLiving;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Shulker;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
import org.bukkit.scoreboard.Team;
|
||||
|
||||
/**
|
||||
* @author Daniel Saukel
|
||||
*/
|
||||
public class GlowUtil implements Listener {
|
||||
|
||||
private static final Random RANDOM = new Random();
|
||||
|
||||
private Map<ChatColor, Team> teams = new HashMap<>();
|
||||
private GlowData<org.bukkit.entity.Entity> glowingBlocks = new GlowData<>();
|
||||
private Map<Player, GlowData<net.minecraft.server.v1_15_R1.Entity>> playerGlows = new HashMap<>();
|
||||
private GlowRunnable runnable = new GlowRunnable();
|
||||
|
||||
public GlowUtil(Plugin plugin) {
|
||||
runnable.runTaskTimer(plugin, 0L, 2L);
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
private Team getTeam(ChatColor color) {
|
||||
if (!teams.containsKey(color)) {
|
||||
Team team = Bukkit.getScoreboardManager().getMainScoreboard().getTeam("DXL_" + color.getChar());
|
||||
if (team == null) {
|
||||
team = Bukkit.getScoreboardManager().getMainScoreboard().registerNewTeam("DXL_" + color.getChar());
|
||||
team.setColor(color);
|
||||
}
|
||||
teams.put(color, team);
|
||||
}
|
||||
return teams.get(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a colored glow effect to the block that is visible to all players.
|
||||
*
|
||||
* @param block the block
|
||||
* @param color the glow color
|
||||
* @return the spawned entity that provides the glow effect
|
||||
*/
|
||||
public org.bukkit.entity.Entity addBlockGlow(Block block, ChatColor color) {
|
||||
Shulker entity = block.getWorld().spawn(new Location(block.getWorld(), block.getX() + .5, block.getY(), block.getZ() + .5), Shulker.class);
|
||||
entity.setAI(false);
|
||||
entity.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 0), true);
|
||||
entity.setInvulnerable(true);
|
||||
addGlow(entity, color);
|
||||
glowingBlocks.put(block, entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a packet-level colored glow effect to the block that is only visible to certain players.
|
||||
*
|
||||
* @param block the block
|
||||
* @param color the glow color
|
||||
* @param players the players who can see the effect
|
||||
*/
|
||||
public void addBlockGlow(Block block, ChatColor color, Player... players) {
|
||||
EntityShulker entity = new EntityShulker(EntityTypes.SHULKER, ((CraftWorld) block.getWorld()).getHandle());
|
||||
entity.setLocation(block.getX() + .5, block.getY(), block.getZ() + .5, 0, 0);
|
||||
entity.setFlag(6, true);
|
||||
entity.setInvisible(true);
|
||||
for (Player player : players) {
|
||||
sendPacket(player, new PacketPlayOutSpawnEntityLiving(entity));
|
||||
if (playerGlows.get(player) == null) {
|
||||
playerGlows.put(player, new GlowData<>());
|
||||
}
|
||||
playerGlows.get(player).put(block, entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a rainbow colored glow effect to the block that is visible to all players.
|
||||
*
|
||||
* @param block the block
|
||||
* @return the spawned entity that provides the glow effect
|
||||
*/
|
||||
public org.bukkit.entity.Entity addRainbowBlockGlow(Block block) {
|
||||
return addRainbowBlockGlow(block, (Long) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a rainbow colored glow effect to the block that is visible to all players.
|
||||
* <p>
|
||||
* The task is cancelled automatically when the entity dies.
|
||||
*
|
||||
* @param block the block
|
||||
* @param cancelTime the time in milliseconds until the glow effect shall end; null = forever
|
||||
* @return the spawned entity that provides the glow effect
|
||||
*/
|
||||
public org.bukkit.entity.Entity addRainbowBlockGlow(Block block, Long cancelTime) {
|
||||
Shulker entity = block.getWorld().spawn(new Location(block.getWorld(), block.getX() + .5, block.getY(), block.getZ() + .5), Shulker.class);
|
||||
entity.setAI(false);
|
||||
entity.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, Integer.MAX_VALUE, 0), true);
|
||||
entity.setInvulnerable(true);
|
||||
glowingBlocks.put(block, entity);
|
||||
addRainbowGlow(entity, cancelTime);
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a packet-level rainbow colored glow effect to the block that is only visible to certain players.
|
||||
* <p>
|
||||
* Returns the repeating task that handles color changes.
|
||||
*
|
||||
* @param block the block
|
||||
* @param players
|
||||
*/
|
||||
public void addRainbowBlockGlow(Block block, Player... players) {
|
||||
addRainbowBlockGlow(block, null, players);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a packet-level rainbow colored glow effect to the block that is only visible to certain players.
|
||||
* <p>
|
||||
* Returns the repeating task that handles color changes.
|
||||
*
|
||||
* @param block the block
|
||||
* @param cancelTime the time in milliseconds until the glow effect shall end; null = forever
|
||||
* @param players
|
||||
*/
|
||||
public void addRainbowBlockGlow(Block block, Long cancelTime, Player... players) {
|
||||
EntityShulker entity = new EntityShulker(EntityTypes.SHULKER, ((CraftWorld) block.getWorld()).getHandle());
|
||||
entity.setLocation(block.getX() + .5, block.getY(), block.getZ() + .5, 0, 0);
|
||||
entity.setFlag(6, true);
|
||||
entity.setInvisible(true);
|
||||
for (Player player : players) {
|
||||
sendPacket(player, new PacketPlayOutSpawnEntityLiving(entity));
|
||||
if (playerGlows.get(player) == null) {
|
||||
playerGlows.put(player, new GlowData<>());
|
||||
}
|
||||
playerGlows.get(player).put(block, entity);
|
||||
}
|
||||
addRainbowGlow(entity, cancelTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the glow effect from a glowing block.
|
||||
*
|
||||
* @param block the block
|
||||
*/
|
||||
public void removeBlockGlow(Block block) {
|
||||
org.bukkit.entity.Entity bukkitEntity = glowingBlocks.get(block);
|
||||
if (bukkitEntity != null) {
|
||||
bukkitEntity.remove();
|
||||
glowingBlocks.remove(block);
|
||||
runnable.removeEntity(bukkitEntity);
|
||||
}
|
||||
|
||||
for (Entry<Player, GlowData<net.minecraft.server.v1_15_R1.Entity>> entry : playerGlows.entrySet()) {
|
||||
net.minecraft.server.v1_15_R1.Entity nmsEntity = entry.getValue().get(block);
|
||||
if (nmsEntity != null) {
|
||||
sendPacket(entry.getKey(), new PacketPlayOutEntityDestroy(nmsEntity.getId()));
|
||||
runnable.removeEntity(nmsEntity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a colored glow effect to an entity and handles its scoreboard team membership.
|
||||
*
|
||||
* @param entity a Bukkit Entity
|
||||
* @param color the glow color
|
||||
*/
|
||||
public void addGlow(org.bukkit.entity.Entity entity, ChatColor color) {
|
||||
getTeam(color).addEntry(asEntry(entity));
|
||||
entity.setGlowing(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a colored glow effect to an entity and handles its scoreboard team membership.
|
||||
*
|
||||
* @param entity an NMS Entity
|
||||
* @param color the glow color
|
||||
*/
|
||||
public void addGlow(net.minecraft.server.v1_15_R1.Entity entity, ChatColor color) {
|
||||
getTeam(color).addEntry(asEntry(entity));
|
||||
entity.setFlag(6, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a changing glow effect to an entity.
|
||||
*
|
||||
* @param entity an NMS Entity
|
||||
*/
|
||||
public void addRainbowGlow(org.bukkit.entity.Entity entity) {
|
||||
addRainbowGlow(entity, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a changing glow effect to an entity.
|
||||
*
|
||||
* @param entity an NMS Entity
|
||||
* @param cancelTime the time in milliseconds until the glow effect shall end; null = forever
|
||||
*/
|
||||
public void addRainbowGlow(org.bukkit.entity.Entity entity, Long cancelTime) {
|
||||
entity.setGlowing(true);
|
||||
runnable.addEntity(entity, cancelTime != null ? System.currentTimeMillis() + cancelTime : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a changing glow effect to an entity.
|
||||
*
|
||||
* @param entity an NMS Entity
|
||||
*/
|
||||
public void addRainbowGlow(net.minecraft.server.v1_15_R1.Entity entity) {
|
||||
addRainbowGlow(entity, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a changing glow effect to an entity.
|
||||
*
|
||||
* @param entity an NMS Entity
|
||||
* @param cancelTime the time in milliseconds until the glow effect shall end; null = forever
|
||||
*/
|
||||
public void addRainbowGlow(net.minecraft.server.v1_15_R1.Entity entity, Long cancelTime) {
|
||||
entity.setFlag(6, true);
|
||||
runnable.addEntity(entity, cancelTime != null ? System.currentTimeMillis() + cancelTime : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the glow effect from an entity and handles its scoreboard team membership.
|
||||
*
|
||||
* @param entity a Bukkit Entity
|
||||
*/
|
||||
public void removeGlow(org.bukkit.entity.Entity entity) {
|
||||
entity.setGlowing(false);
|
||||
teams.values().forEach(t -> t.removeEntry(asEntry(entity)));
|
||||
runnable.removeEntity(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the glow effect from an entity and handles its scoreboard team membership.
|
||||
*
|
||||
* @param entity an NMS Entity
|
||||
*/
|
||||
public void removeGlow(net.minecraft.server.v1_15_R1.Entity entity) {
|
||||
entity.setFlag(6, false);
|
||||
teams.values().forEach(t -> t.removeEntry(asEntry(entity)));
|
||||
runnable.removeEntity(entity);
|
||||
}
|
||||
|
||||
private static String asEntry(org.bukkit.entity.Entity entity) {
|
||||
return entity instanceof Player ? entity.getName() : entity.getUniqueId().toString();
|
||||
}
|
||||
|
||||
private static String asEntry(net.minecraft.server.v1_15_R1.Entity entity) {
|
||||
return entity instanceof Player ? entity.getName() : entity.getUniqueID().toString();
|
||||
}
|
||||
|
||||
private static void sendPacket(Player player, Packet<?> packet) {
|
||||
((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
removeBlockGlow(event.getBlock());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
playerGlows.remove(event.getPlayer());
|
||||
}
|
||||
|
||||
private class GlowRunnable extends BukkitRunnable {
|
||||
|
||||
private Map<Object, Long> entities = new HashMap<>();
|
||||
private ChatColor color;
|
||||
|
||||
private void addEntity(Object entity, Long cancelTime) {
|
||||
entities.put(entity, cancelTime);
|
||||
}
|
||||
|
||||
private void removeEntity(Object entity) {
|
||||
entities.remove(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
color = ChatColor.values()[RANDOM.nextInt(ChatColor.values().length - 1)];
|
||||
for (Entry<Object, Long> entry : entities.entrySet().toArray(new Entry[entities.size()])) {
|
||||
if (entry.getKey() instanceof org.bukkit.entity.Entity) {
|
||||
run((org.bukkit.entity.Entity) entry.getKey(), entry.getValue());
|
||||
} else if (entry.getKey() instanceof net.minecraft.server.v1_15_R1.Entity) {
|
||||
run((net.minecraft.server.v1_15_R1.Entity) entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void run(org.bukkit.entity.Entity entity, Long cancelTime) {
|
||||
getTeam(color).removeEntry(asEntry(entity));
|
||||
if ((cancelTime != null && System.currentTimeMillis() >= cancelTime) || entity.isDead()) {
|
||||
entities.remove(entity);
|
||||
glowingBlocks.remove(entity);
|
||||
if (!entity.isDead()) {
|
||||
entity.setGlowing(false);
|
||||
} else {
|
||||
entity.remove();
|
||||
}
|
||||
return;
|
||||
}
|
||||
getTeam(color).addEntry(asEntry(entity));
|
||||
}
|
||||
|
||||
private void run(net.minecraft.server.v1_15_R1.Entity entity, Long cancelTime) {
|
||||
getTeam(color).removeEntry(asEntry(entity));
|
||||
if (cancelTime != null && System.currentTimeMillis() >= cancelTime) {
|
||||
entities.remove(entity);
|
||||
for (Entry<Player, GlowData<net.minecraft.server.v1_15_R1.Entity>> entry : playerGlows.entrySet()) {
|
||||
if (!entry.getValue().glowingBlocks.containsValue(entity)) {
|
||||
continue;
|
||||
}
|
||||
Player player = entry.getKey();
|
||||
sendPacket(player, new PacketPlayOutEntityDestroy(entity.getId()));
|
||||
entry.getValue().remove(entity);
|
||||
}
|
||||
return;
|
||||
}
|
||||
getTeam(color).addEntry(asEntry(entity));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class GlowData<T> {
|
||||
|
||||
Map<Block, T> glowingBlocks = new HashMap<>();
|
||||
|
||||
T get(Block block) {
|
||||
return glowingBlocks.get(block);
|
||||
}
|
||||
|
||||
void remove(Block block) {
|
||||
glowingBlocks.remove(block);
|
||||
}
|
||||
|
||||
void remove(T entity) {
|
||||
for (Entry<Block, T> entry : glowingBlocks.entrySet().toArray(new Entry[glowingBlocks.size()])) {
|
||||
if (entry.getValue().equals(entity)) {
|
||||
glowingBlocks.remove(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void put(Block block, T entity) {
|
||||
glowingBlocks.put(block, entity);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Daniel Saukel
|
||||
*
|
||||
* All rights reserved.
|
||||
*/
|
||||
package de.erethon.dungeonsxxl.world.block;
|
||||
|
||||
import de.erethon.dungeonsxl.world.block.GameBlock;
|
||||
import de.erethon.dungeonsxxl.DungeonsXXL;
|
||||
import de.erethon.dungeonsxxl.util.GlowUtil;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
/**
|
||||
* @author Daniel Saukel
|
||||
*/
|
||||
public class GlowingBlock extends GameBlock {
|
||||
|
||||
private GlowUtil glowUtil;
|
||||
|
||||
public GlowingBlock(DungeonsXXL plugin, Block block, ChatColor color, Double time) {
|
||||
super(plugin.getDXL(), block);
|
||||
glowUtil = plugin.getGlowUtil();
|
||||
|
||||
Long millis;
|
||||
if (time != null) {
|
||||
millis = (long) (time * 1000);
|
||||
} else {
|
||||
millis = null;
|
||||
}
|
||||
|
||||
if (color != null) {
|
||||
glowUtil.addBlockGlow(block, color);
|
||||
if (millis != null) {
|
||||
new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
removeGlow();
|
||||
}
|
||||
}.runTaskLater(plugin, millis / 50);
|
||||
}
|
||||
} else {
|
||||
glowUtil.addRainbowBlockGlow(block, millis);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeGlow() {
|
||||
glowUtil.removeBlockGlow(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBreak(BlockBreakEvent event) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
7
addon/core/src/main/resources/plugin.yml
Normal file
7
addon/core/src/main/resources/plugin.yml
Normal file
@ -0,0 +1,7 @@
|
||||
name: DungeonsXXL
|
||||
main: de.erethon.dungeonsxxl.DungeonsXXL
|
||||
version: ${project.version}${buildNo}
|
||||
author: Daniel Saukel
|
||||
description: ${project.description}
|
||||
website: ${project.url}
|
||||
depend: [DungeonsXL]
|
37
addon/dist/pom.xml
vendored
Normal file
37
addon/dist/pom.xml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.erethon.dungeonsxl</groupId>
|
||||
<artifactId>dungeonsxl-addon-dist</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<packaging>jar</packaging>
|
||||
<parent>
|
||||
<groupId>de.erethon.dungeonsxl</groupId>
|
||||
<artifactId>dungeonsxl-addon</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<build>
|
||||
<finalName>${project.artifactId}-${project.version}${buildNo}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>de.erethon.dungeonsxl</groupId>
|
||||
<artifactId>dungeonsxl-addon-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
27
addon/pom.xml
Normal file
27
addon/pom.xml
Normal file
@ -0,0 +1,27 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>de.erethon.dungeonsxl</groupId>
|
||||
<artifactId>dungeonsxl-addon</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>DungeonsXXL</name>
|
||||
<url>https://dre2n.github.io</url>
|
||||
<description>Create BETTER custom dungeons and adventure maps with ease!</description>
|
||||
<parent>
|
||||
<groupId>de.erethon.dungeonsxl</groupId>
|
||||
<artifactId>dungeonsxl-parent</artifactId>
|
||||
<version>0.18-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modules>
|
||||
<module>core</module>
|
||||
<module>dist</module>
|
||||
</modules>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>de.erethon.dungeonsxl</groupId>
|
||||
<artifactId>dungeonsxl-dist</artifactId>
|
||||
<version>0.18-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -208,6 +208,7 @@ public enum DMessage implements Message {
|
||||
PLAYER_UNLIMITED_LIVES("player.unlimitedLives"),
|
||||
PLAYER_WAIT_FOR_OTHER_PLAYERS("player.waitForOtherPlayers"),
|
||||
REQUIREMENT_FEE("requirement.fee"),
|
||||
REQUIREMENT_FEE_ITEMS("requirement.feeItems"),
|
||||
REQUIREMENT_FEE_LEVEL("requirement.feeLevel"),
|
||||
REQUIREMENT_FEE_MONEY("requirement.feeMoney"),
|
||||
REQUIREMENT_FORBIDDEN_ITEMS("requirement.forbiddenItems"),
|
||||
|
@ -224,6 +224,7 @@ player:
|
||||
waitForOtherPlayers: "&6Waiting for team members..."
|
||||
requirement:
|
||||
fee: "&6You have been charged &4&v1 &6for entering the dungeon."
|
||||
feeItems: "Items"
|
||||
feeLevel: "Levels"
|
||||
feeMoney: "Money"
|
||||
forbiddenItems: "Forbidden items"
|
||||
|
@ -221,6 +221,7 @@ player:
|
||||
waitForOtherPlayers: "&6En attente des membres de l'équipe..."
|
||||
requirement:
|
||||
fee: "&6Vous avez été débité de &4&v1 &6pour entrer dans le donjon."
|
||||
feeItems: "Items"
|
||||
feeLevel: "Niveaux"
|
||||
feeMoney: "Argent"
|
||||
forbiddenItems: "Objets défendus"
|
||||
|
@ -221,6 +221,7 @@ player:
|
||||
waitForOtherPlayers: "&6Warte auf andere Gruppenmitglieder..."
|
||||
requirement:
|
||||
fee: "&6Du hast &4&v1 &6bezahlt, um den Dungeon zu betreten."
|
||||
feeItems: "Items"
|
||||
feeLevel: "Level"
|
||||
feeMoney: "Geld"
|
||||
forbiddenItems: "Verbotene Items"
|
||||
|
Loading…
Reference in New Issue
Block a user