Add donors addon module

This commit is contained in:
Daniel Saukel 2020-06-19 00:46:03 +02:00
parent 75945ce8a6
commit 74a879212c
19 changed files with 1105 additions and 0 deletions

7
addon/README.md Normal file
View 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
View 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>

View File

@ -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;
}
}

View File

@ -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 + "}";
}
}

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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)];
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}

View 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
View 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
View 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>

View File

@ -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"),

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -14,6 +14,7 @@
<module>bukkit_magicvalues</module>
<module>core</module>
<module>dist</module>
<module>addon</module>
</modules>
<properties>
<buildNo></buildNo>