This commit is contained in:
Brandon 2023-02-11 01:37:12 +00:00
parent 079259d991
commit 6d65a797db
2681 changed files with 299076 additions and 0 deletions

70
Battle-Crates-main/.gitignore vendored Normal file
View File

@ -0,0 +1,70 @@
# Eclipse
/.classpath
/.project
/.settings
# Netbeans
/nbproject
# Fuck mauri!
/build.xml
# Maven
/target
/dependency-reduced-pom.xml
*/target
*/dependency-reduced-pom.xml
# Vim
.*.sw[a-p]
# Various other potential build files
/build
/bin
/dist
/manifest.mf
/MANIFEST.MF
/META-INF/MANIFEST.MF
git.properties
.ssh
key
commiter.sh
key.pub
dependency-reduced-pom.xml
# Mac Filesystem Dust
.DS_Store
# IntelliJ IDEA
*.iml
*.ipr
*.iws
.idea/
#Libraries jar files
libraries/*.jar
=======
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
out

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>rip.battle.crates</groupId>
<artifactId>BattleCrates</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>rip.battle.spigot</groupId>
<artifactId>battlespigot-server</artifactId>
<version>1.7.10-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>rip.battle.core</groupId>
<artifactId>bukkit</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>cc.stormworth.hcf</groupId>
<artifactId>hcf</artifactId>
<version>1.0.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,69 @@
package rip.battle.crates;
import cc.stormworth.core.util.command.rCommandHandler;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoDatabase;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.configuration.Configuration;
import org.bukkit.plugin.java.JavaPlugin;
import rip.battle.crates.airdrop.AirdropListener;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.listeners.CrateListener;
import rip.battle.crates.reward.RewardsListeners;
@Getter
public class Crates extends JavaPlugin {
@Getter private static Crates instance;
private MongoDatabase mongoDatabase;
@Override
public void onEnable() {
instance = this;
saveDefaultConfig();
loadMongo();
Crate.load();
Bukkit.getPluginManager().registerEvents(new CrateListener(), this);
Bukkit.getPluginManager().registerEvents(new RewardsListeners(), this);
Bukkit.getPluginManager().registerEvents(new AirdropListener(), this);
rCommandHandler.registerPackage(this, "rip.battle.crates.crate.commands");
rCommandHandler.registerPackage(this, "rip.battle.crates.reward.commands");
}
@Override
public void onDisable() {
Crate.getCrates().values().forEach(Crate::save);
}
private void loadMongo() {
Configuration configuration = getConfig();
if (configuration.getBoolean("mongo.authentication.enabled")) {
ServerAddress serverAddress =
new ServerAddress(
configuration.getString("mongo.host"), configuration.getInt("mongo.port"));
MongoCredential credential =
MongoCredential.createCredential(
configuration.getString("mongo.authentication.username"),
"admin",
configuration.getString("mongo.authentication.password").toCharArray());
mongoDatabase =
new MongoClient(serverAddress, credential, MongoClientOptions.builder().build())
.getDatabase(getConfig().getString("mongo.database"));
} else {
mongoDatabase =
new MongoClient(configuration.getString("mongo.host"), configuration.getInt("mongo.port"))
.getDatabase(getConfig().getString("mongo.database"));
}
}
}

View File

@ -0,0 +1,82 @@
package rip.battle.crates.airdrop;
import cc.stormworth.core.kt.util.ItemBuilder;
import cc.stormworth.core.util.trail.ParticleEffect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import rip.battle.crates.Crates;
import rip.battle.crates.crate.Crate;
import java.util.Arrays;
import java.util.List;
public class Airdrop extends Crate {
public Airdrop() {
super("Airdrop");
getCrates().put("Airdrop", this);
}
@Override
public List<String> getHologramsLines() {
return Arrays.asList(
getDisplayName() + " Airdrop",
"&7",
"&fLeft click &7for preview rewards",
"&7",
"&7&ostore.battle.rip");
}
@Override
public ItemStack generateKey() {
return new ItemBuilder(Material.CHEST)
.name("&6&lAirdrop")
.addToLore(
"&7Purchasable at &fstore.battle.rip&7.",
"",
"&ePlace this down to designate a &6&lLocation &efor the &6&lLoot&e!"
).build();
}
public void startAnimation(Block block, Player player) {
createFlameRings(block.getLocation().add(0, 0, 0.5));
block.setMetadata("airdrop", new FixedMetadataValue(Crates.getInstance(), true));
/*Dropper dropper = (Dropper) block.getState();
List<Reward> rewardList = new ArrayList<>(getRewards());
Collections.shuffle(rewardList);
int i = 0;
while (i <= 9) {
Reward randomReward = RandomUtils.getRandomReward(rewardList);
dropper.getInventory().setItem(i, randomReward.getItem());
if (!randomReward.getBroadcast().isEmpty()) {
randomReward.getBroadcast().forEach(line -> Bukkit.broadcastMessage(line.replace("{player}", player.getName())));
}
i++;
}*/
}
private void createFlameRings(Location location) {
double alpha = 0;
for (int count = 0; count < 50; count++) {
alpha += Math.PI / 16;
Location firstLocation = location.clone().add(Math.cos(alpha), Math.sin(alpha) + 1, Math.sin(alpha));
Location secondLocation = location.clone().add(Math.cos(alpha + Math.PI), Math.sin(alpha) + 1, Math.sin(alpha + Math.PI));
ParticleEffect.FLAME.display(0, 0, 0, 0, 10, firstLocation, 10);
ParticleEffect.FLAME.display(0, 0, 0, 0, 10, secondLocation, 10);
}
}
}

View File

@ -0,0 +1,246 @@
package rip.battle.crates.airdrop;
import cc.stormworth.core.util.chat.CC;
import cc.stormworth.core.util.general.LocationUtil;
import cc.stormworth.core.util.general.TaskUtil;
import cc.stormworth.hcf.Main;
import cc.stormworth.hcf.team.Team;
import cc.stormworth.hcf.team.claims.LandBoard;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.Skull;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftPlayer;
import org.bukkit.entity.FallingBlock;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.scheduler.BukkitRunnable;
import rip.battle.crates.Crates;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.reward.Reward;
import rip.battle.crates.utils.FireworkUtil;
import rip.battle.crates.utils.ItemUtils;
import rip.battle.crates.utils.RandomUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class AirdropListener implements Listener {
@EventHandler
public void onBlockPlaceEvent(BlockPlaceEvent event) {
Player player = event.getPlayer();
ItemStack item = event.getItemInHand();
if (!ItemUtils.isAirDrop(item)) {
return;
}
Airdrop airdrop = (Airdrop) Crate.getByName("Airdrop");
if (!airdrop.isEnable()) {
player.sendMessage(CC.translate("&cAirdrop is currently disabled."));
event.setCancelled(true);
player.playSound(player.getLocation(), Sound.ANVIL_BREAK, 1, 1);
return;
}
if (!player.isOp()) {
Team team = LandBoard.getInstance().getTeam(player.getLocation());
if (team != null && !team.isMember(player.getUniqueId())) {
player.sendMessage(CC.translate("&cYou can only put the &6&lAirdrop&c in your claim or in Wilderness."));
event.setCancelled(true);
return;
}
if (Main.getInstance().getServerHandler().isWarzone(player.getLocation())) {
player.sendMessage(CC.translate("&cYou cannot place an &6&lAirdrop&c in a Warzone."));
event.setCancelled(true);
return;
}
}
Location location = event.getBlock().getLocation().clone().add(0, 25, 0);
if (location.getBlock() != null && location.getBlock().getType() != Material.AIR) {
player.sendMessage(CC.translate("&cYou cannot place an &6&lAirdrop&c there."));
player.sendMessage(CC.translate("&cGo out in the open air to deploy the &6&lAirdrop&c."));
player.playSound(player.getLocation(), Sound.VILLAGER_NO, 1, 1);
event.setCancelled(true);
return;
}
FallingBlock block = player.getLocation().getWorld().spawnFallingBlock(
location,
Material.SNOW_BLOCK,
(byte) 3);
block.setMetadata("airdrop", new FixedMetadataValue(Crates.getInstance(), player.getName()));
event.setCancelled(true);
FireworkUtil.launchFirework(event.getBlock().getLocation());
ItemUtils.consume(player);
}
@EventHandler
public void onDeath(EntityChangeBlockEvent event) {
if (!(event.getEntity() instanceof FallingBlock)) {
return;
}
FallingBlock fallingBlock = (FallingBlock) event.getEntity();
if (!fallingBlock.hasMetadata("airdrop")) {
return;
}
Airdrop airdrop = (Airdrop) Crate.getByName("Airdrop");
Player player = Bukkit.getPlayer(fallingBlock.getMetadata("airdrop").get(0).asString());
fallingBlock.setDropItem(false);
Block block = event.getBlock();
new BukkitRunnable() {
@Override
public void run() {
block.setType(Material.SKULL);
block.setData((byte) 3);
Skull skull = (Skull) block.getState();
skull.setOwner("conhost");
skull.update();
}
}.runTaskLater(Crates.getInstance(), 2L);
for(Player online : Bukkit.getServer().getOnlinePlayers()) {
if(((CraftPlayer) online).getHandle().playerConnection.networkManager.getVersion() < 47){
new BukkitRunnable() {
@Override
public void run() {
online.sendBlockChange(block.getLocation(), Material.CHEST, (byte) 0);
}
}.runTaskLater(Crates.getInstance(), 2L);
}
}
block.setMetadata("airdrop", new FixedMetadataValue(Crates.getInstance(), player.getName()));
TaskUtil.runAsync(Crates.getInstance(), () -> airdrop.startAnimation(block, player));
}
/*@EventHandler
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
if (!(event.getEntity() instanceof FallingBlock)) {
return;
}
FallingBlock fallingBlock = (FallingBlock) event.getEntity();
if (!fallingBlock.hasMetadata("airdrop")) {
return;
}
Airdrop airdrop = (Airdrop) Crate.getByName("Airdrop");
Player player = Bukkit.getPlayer(fallingBlock.getMetadata("airdrop").get(0).asString());
Block block = event.getBlock();
block.setType(Material.DROPPER);
airdrop.startAnimation(block, player);
}*/
@EventHandler
public void onInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (event.getClickedBlock() == null) {
return;
}
Block block = event.getClickedBlock();
if (!block.hasMetadata("airdrop")) {
return;
}
event.setCancelled(true);
if(block.hasMetadata("airdropOpen")) return;
if (block.getType() != Material.DROPPER) {
Inventory inventory = Bukkit.createInventory(null, 9, "Airdrop");
List<Reward> rewardList = new ArrayList<>(Airdrop.getByName("Airdrop").getRewards());
Collections.shuffle(rewardList);
int i = 0;
while (i < 9) {
Reward randomReward = RandomUtils.getRandomReward(rewardList);
inventory.setItem(i, randomReward.getItem());
if (!randomReward.getBroadcast().isEmpty()) {
randomReward.getBroadcast().forEach(line -> Bukkit.broadcastMessage(line.replace("{player}", player.getName())));
}
i++;
}
player.openInventory(inventory);
}
block.setMetadata("airdropOpen", new FixedMetadataValue(Crates.getInstance(), true));
player.setMetadata("airdropOpen", new FixedMetadataValue(Crates.getInstance(), LocationUtil.parseLocation(block.getLocation())));
}
@EventHandler
public void onInventoryClose(InventoryCloseEvent event) {
Player player = (Player) event.getPlayer();
if (!player.hasMetadata("airdropOpen")) {
return;
}
if (!event.getInventory().getName().equals("Airdrop")) {
return;
}
Inventory inventory = event.getInventory();
for (int i = 0; i < inventory.getSize(); i++) {
ItemStack item = inventory.getItem(i);
if (item == null) {
continue;
}
player.getLocation().getWorld().dropItem(player.getLocation(), item);
}
Location location = LocationUtil.convertLocation(player.getMetadata("airdropOpen").get(0).asString());
Block block = location.getBlock();
block.setType(Material.AIR);
player.removeMetadata("airdropOpen", Crates.getInstance());
block.removeMetadata("airdrop", Crates.getInstance());
}
}

View File

@ -0,0 +1,419 @@
package rip.battle.crates.crate;
import cc.stormworth.core.CorePlugin;
import cc.stormworth.core.kt.util.ItemBuilder;
import cc.stormworth.core.util.chat.CC;
import cc.stormworth.core.util.general.LocationUtil;
import cc.stormworth.core.util.holograms.Hologram;
import cc.stormworth.core.util.holograms.Holograms;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.model.Filters;
import com.mongodb.client.model.ReplaceOptions;
import lombok.Getter;
import lombok.Setter;
import org.bson.Document;
import org.bukkit.*;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import rip.battle.crates.Crates;
import rip.battle.crates.airdrop.Airdrop;
import rip.battle.crates.misterybox.MysteryBox;
import rip.battle.crates.reward.Reward;
import rip.battle.crates.reward.RewardType;
import rip.battle.crates.supplydrop.SupplyDrop;
import rip.battle.crates.utils.ChatUtils;
import rip.battle.crates.utils.RandomUtils;
import java.util.*;
import java.util.stream.Collectors;
@Setter
@Getter
public class Crate {
private static final MongoCollection<Document> collection = Crates.getInstance().getMongoDatabase().getCollection("crates");
@Getter
private static final Map<String, Crate> crates = Maps.newHashMap();
private final String name;
private boolean enable;
private List<Reward> rewards = Lists.newArrayList();
private List<CratePlaceholder> placeholders = Lists.newArrayList();
private String displayName;
private ItemStack key;
private Sound openSound;
private int minimumReward = 1;
private int maximumReward = 2;
private Location chestLocation;
private final Map<Location, Hologram> holograms = Maps.newHashMap();
private final Inventory inventory;
public Crate(String name) {
this.name = name;
this.enable = true;
this.displayName = ChatColor.GOLD + name;
this.key = new ItemBuilder(Material.TRIPWIRE_HOOK).name(CC.translate(displayName + " Key")).build();
this.inventory = Bukkit.createInventory(null, 54, CC.translate("&eEdit Rewards of " + name));
if (!name.equalsIgnoreCase("Airdrop")) {
crates.put(name, this);
}
}
public void destroyHolograms() {
holograms.values().forEach(Hologram::destroy);
holograms.clear();
}
public List<String> getHologramsLines() {
return Arrays.asList(
displayName + " Crate",
"&7",
"&fLeft click&7 &7for preview rewards",
"&fRight click&7 to open",
"&7",
"&7&ostore.battle.rip");
}
public void sendHolograms() {
if (chestLocation == null) return;
double y = 0.50;
if (chestLocation.getBlock().getType() == Material.BEACON || chestLocation.getBlock().getType() == Material.ENDER_CHEST
|| chestLocation.getBlock().getType() == Material.ENDER_PORTAL || chestLocation.getBlock().getType() == Material.DROPPER) {
y = 0.90;
}
Location finalLocation = chestLocation.clone().add(0.50, y, 0.50);
Hologram hologram = Holograms.newHologram().at(finalLocation).addLines(getHologramsLines()).build();
hologram.send();
this.holograms.put(finalLocation, hologram);
}
public void createHologram(Location location) {
Location finalLocation = location.clone().add(0.50, 0.50, 0.50);
Hologram hologram = Holograms.newHologram().at(finalLocation).addLines(getHologramsLines()).build();
hologram.send();
this.holograms.put(finalLocation, hologram);
}
public static void load() {
Crate crate;
for (Document document : collection.find()) {
if (document.containsKey("type")) {
if (document.getString("type").equalsIgnoreCase("supplydrop")) {
crate = new SupplyDrop();
} else if (document.getString("type").equalsIgnoreCase("mysterybox")) {
crate = new MysteryBox(document.getString("name"));
} else if (document.getString("type").equalsIgnoreCase("airdrop")) {
crate = new Airdrop();
} else {
crate = new Crate(document.getString("name"));
}
} else {
crate = new Crate(document.getString("name"));
}
crate.setEnable(document.getBoolean("enable"));
crate.setDisplayName(document.getString("displayName"));
crate.setKey(CorePlugin.GSON.fromJson(document.getString("key"), ItemStack.class));
if (document.containsKey("openSound")) {
crate.setOpenSound(Sound.valueOf(document.getString("openSound")));
}
crate.setMinimumReward(document.getInteger("minimumReward"));
crate.setMaximumReward(document.getInteger("maximumReward"));
for (Document reward : document.getList("rewards", Document.class)) {
crate.getRewards().add(new Reward(reward));
}
for (Document placeholder : document.getList("placeholders", Document.class)) {
crate.getPlaceholders().add(new CratePlaceholder(placeholder));
}
if (crate instanceof MysteryBox) {
for (Document reward : document.getList("obligatoryrewards", Document.class)) {
((MysteryBox) crate).getObligatoryRewards().add(new Reward(reward));
}
}
if (document.containsKey("chestLocations")) {
for (String location : document.getList("chestLocations", String.class)) {
crate.setChestLocation(LocationUtil.convertLocation(location));
}
}
if (document.containsKey("chestLocation")) {
crate.setChestLocation(LocationUtil.convertLocation(document.getString("chestLocation")));
}
for (CratePlaceholder placeholder : crate.getPlaceholders()) {
crate.getInventory().setItem(placeholder.getSlot(), placeholder.getItem());
}
for (Reward reward : crate.getRewards()) {
crate.getInventory().setItem(reward.getSlot(), reward.getItem());
}
if (crate instanceof MysteryBox) {
for (Reward reward : ((MysteryBox) crate).getObligatoryRewards()) {
crate.getInventory().setItem(reward.getSlot(), reward.getItem());
}
}
crate.sendHolograms();
}
if (!crates.containsKey("Airdrop")) {
crates.put("Airdrop", new Airdrop());
}
if (!crates.containsKey("SupplyDrop")) {
crates.put("SupplyDrop", new SupplyDrop());
}
}
public void save() {
Document document = new Document();
document.append("name", name);
document.append("enable", enable);
document.append("displayName", displayName);
document.append("key", CorePlugin.GSON.toJson(key));
if (openSound != null) document.append("openSound", openSound.name());
document.append("minimumReward", minimumReward);
document.append("maximumReward", maximumReward);
document.append("rewards", rewards.stream().map(Reward::serialize).collect(Collectors.toList()));
document.append("placeholders", placeholders.stream().map(CratePlaceholder::serialize).collect(Collectors.toList()));
//document.append("chestLocations", chestLocations.stream().map(LocationUtil::parseLocation).collect(Collectors.toList()));
if (chestLocation != null) {
document.append("chestLocation", LocationUtil.parseLocation(chestLocation));
}
if (this instanceof MysteryBox) {
MysteryBox mysteryBox = (MysteryBox) this;
document.append("type", "mysteryBox");
document.append("obligatoryrewards", mysteryBox.getObligatoryRewards().stream().map(Reward::serialize).collect(Collectors.toList()));
} else if (this instanceof Airdrop) {
document.append("type", "airdrop");
} else if (this instanceof SupplyDrop) {
document.append("type", "supplydrop");
} else {
document.append("type", "crate");
}
collection.replaceOne(Filters.eq("name", name), document, new ReplaceOptions().upsert(true));
}
public static Crate getByLocation(Location location) {
for (Crate crate : crates.values()) {
if (crate.getChestLocation() != null && crate.getChestLocation().equals(location)) {
return crate;
}
}
return null;
}
public static Crate getByName(String name) {
return crates.get(name);
}
public ItemStack generateKey() {
if (getName().equalsIgnoreCase("Giftbox")) {
return new ItemBuilder(key.clone())
.name(CC.translate(displayName + " &7(Package) &a&l* CLICK *"))
.setLore(Lists.newArrayList(
"&7",
"&7You can preview this " + getDisplayName() + " Crate &7 rewards",
"&7By going to the overworld &aSpawn",
"&7",
ChatUtils.getFirstColor(getDisplayName()) + "Right Click &7to open the key",
"&7",
"&7Purchase additional keys at &f&nstore.battle.rip"
))
.build();
}
return new ItemBuilder(key.clone())
.name(CC.translate(displayName + " Key"))
.setLore(Lists.newArrayList(
"&7",
"&7You can preview this " + getDisplayName() + " Crate &7 rewards",
"&7By going to the overworld &aSpawn",
"&7",
ChatUtils.getFirstColor(getDisplayName()) + "Right Click &7to open the key",
ChatUtils.getFirstColor(getDisplayName()) + "Left Click &7to preview rewards",
"&7",
"&7Purchase additional keys at &f&nstore.battle.rip"
))
.build();
}
public static Crate getCrateByKey(ItemStack key) {
if (key == null) return null;
if (key.getItemMeta() == null) return null;
ItemMeta meta = key.getItemMeta();
if (meta.hasDisplayName() && meta.hasLore()) {
String name = meta.getDisplayName();
if (name.contains(CC.translate("&7(Package)"))) {
return Crate.getByName("Giftbox");
}
if (name.contains("Key")) {
name = name.replace(" Key", "");
String finalName = name;
return crates.values()
.stream()
.filter(crate -> crate.getDisplayName().equalsIgnoreCase(finalName))
.findFirst().orElse(null);
}
}
return null;
}
public void openCrate(Player player) {
if (!enable) {
player.sendMessage(CC.translate("&cThis crate is currently disabled"));
return;
}
if (getMaximumReward() == 0 || getRewards().isEmpty()) {
player.sendMessage(CC.translate("&cCrate " + getName() + " is empty, please contact an admin."));
return;
}
if (player.getInventory().firstEmpty() < 0) {
player.sendMessage(CC.translate("&cInventory Full."));
return;
}
int random = new Random().nextInt(getMaximumReward() - getMinimumReward() + 1) + getMinimumReward();
List<Reward> randomRewards = new ArrayList<>();
List<Reward> rewardList = new ArrayList<>(getRewards());
Collections.shuffle(rewardList);
for (int i = 0; i < random; i++) {
randomRewards.add(RandomUtils.getRandomReward(rewardList));
}
for (Reward reward : randomRewards) {
if (reward.getType() == RewardType.ITEMS) {
if (player.getInventory().firstEmpty() < 0) {
player.sendMessage(CC.translate("&cInventory Full."));
player.getWorld().dropItem(player.getLocation(), reward.getItem());
} else {
player.getInventory().addItem(reward.getItem());
}
} else {
List<String> commands = reward.getCommands();
for (String command : commands) {
if (command.contains("op")) {
continue;
}
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command.replace("%player%", player.getName()));
}
}
if (!reward.getBroadcast().isEmpty()) {
reward.getBroadcast().forEach(line -> Bukkit.broadcastMessage(line.replace("{player}", player.getName())));
}
}
if (randomRewards.size() == 0) { // if not found any reward
Reward reward = getRewards().get(new Random().nextInt(getRewards().size()));
if (reward.getType() == RewardType.ITEMS) {
if (player.getInventory().firstEmpty() < 0) {
player.sendMessage(CC.translate("&cInventory Full."));
player.getWorld().dropItem(player.getLocation(), reward.getItem());
} else {
player.getInventory().addItem(reward.getItem());
}
} else {
List<String> commands = reward.getCommands();
for (String command : commands) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command.replace("%player%", player.getName()));
}
}
if (!reward.getBroadcast().isEmpty()) {
reward.getBroadcast().forEach(line -> Bukkit.broadcastMessage(line.replace("{player}", player.getName())));
}
}
if (openSound != null) {
player.playSound(player.getLocation(), openSound, 1, 1);
}
player.sendMessage(CC.translate("&aYou have received " + randomRewards.size() + " reward(s)"));
consumeKey(player);
player.updateInventory();
}
public void openEditRewardsInventory(Player player) {
player.openInventory(inventory);
}
public void consumeKey(Player player) {
if (player.getItemInHand().getAmount() > 1) {
player.getItemInHand().setAmount(player.getItemInHand().getAmount() - 1);
} else {
player.setItemInHand(new ItemStack(Material.AIR));
}
}
public Reward getReward(int slot) {
return rewards.stream().filter(reward -> reward.getSlot() == slot).findFirst().orElse(null);
}
public CratePlaceholder getPlaceholder(int slot) {
return placeholders.stream().filter(reward -> reward.getSlot() == slot).findFirst().orElse(null);
}
public void delete() {
crates.remove(name);
destroyHolograms();
collection.deleteOne(Filters.eq("name", name));
}
public void removeHologram() {
holograms.forEach((loc, hologram) -> hologram.destroy());
}
}

View File

@ -0,0 +1,32 @@
package rip.battle.crates.crate;
import cc.stormworth.core.CorePlugin;
import cc.stormworth.core.kt.util.ItemBuilder;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.bson.Document;
import org.bukkit.inventory.ItemStack;
@Getter
@AllArgsConstructor
public class CratePlaceholder {
private ItemStack item;
private int slot;
public CratePlaceholder(Document document) {
this.item = CorePlugin.GSON.fromJson(document.getString("item"), ItemStack.class);
this.slot = document.getInteger("slot");
}
public ItemStack getPreview() {
return new ItemBuilder(item.clone())
.name(" ")
.build();
}
public Document serialize(){
return new Document("item", CorePlugin.GSON.toJson(item))
.append("slot", slot);
}
}

View File

@ -0,0 +1,286 @@
package rip.battle.crates.crate.commands;
import cc.stormworth.core.util.chat.CC;
import cc.stormworth.core.util.chat.Clickable;
import cc.stormworth.core.util.command.annotations.Command;
import cc.stormworth.core.util.command.annotations.Param;
import cc.stormworth.core.util.onedoteight.TitleBuilder;
import cc.stormworth.hcf.profile.HCFProfile;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.crates.airdrop.Airdrop;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.menus.CSGOOpenMenu;
import rip.battle.crates.crate.menus.CrateEditMenu;
import rip.battle.crates.crate.menus.CratePreviewMenu;
import rip.battle.crates.misterybox.MysteryBox;
public class CrateCommands {
@Command(names = {"crate", "cr", "crates", "mysterybox", "mb"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void help(Player player) {
player.sendMessage(CC.translate("&a&lCrates Help"));
player.sendMessage(CC.translate("&7- &e/crate create <name> &7- &aCreate a crate"));
player.sendMessage(CC.translate("&7- &e/mystery create <name> &7- &aCreate a mystery box"));
player.sendMessage("");
player.sendMessage(CC.translate("&7- &e/crate delete <name> &7- &aDelete a crate"));
player.sendMessage(CC.translate("&7- &e/crate list &7- &aList all crates"));
player.sendMessage(CC.translate("&7- &e/crate edit <name> &7- &aEdit a crate"));
player.sendMessage(CC.translate("&7- &e/crate preview <name> &7- &aPreview a crate"));
player.sendMessage(CC.translate("&7- &e/crate give <name> <amount> <target> &7- &aGive a crate key to player"));
player.sendMessage(CC.translate("&7- &e/reward &7- &aTo show help for rewards"));
player.sendMessage(CC.translate("&7- &e/airdrop give <target> <amount> &7- &aTo show help for rewards"));
}
@Command(names = {"airdrop"}, permission = "", hidden = true)
public static void airdrop(Player player) {
Airdrop airdrop = (Airdrop) Crate.getByName("Airdrop");
if (airdrop == null) {
player.sendMessage(CC.translate("&cairdrop with that name does not exist!"));
return;
}
new CratePreviewMenu(airdrop).openMenu(player);
}
@Command(names = {"crate create", "cr create", "crates create"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void create(Player player, @Param(name = "name") String name) {
if (Crate.getByName(name) != null) {
player.sendMessage(CC.translate("&cCrate with that name already exists!"));
return;
}
Crate crate = new Crate(name);
crate.save();
player.sendMessage(CC.translate("&aCrate &e" + name + "&a created!"));
}
@Command(names = {"mysterybox create", "mb create"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void mysterybox(Player player, @Param(name = "name") String name) {
if (Crate.getByName(name) != null) {
player.sendMessage(CC.translate("&cCrate with that name already exists!"));
return;
}
MysteryBox crate = new MysteryBox(name);
crate.save();
player.sendMessage(CC.translate("&aMystery &e" + name + "&a created!"));
}
@Command(names = {"crate delete", "cr delete", "crates delete", "crate remove", "cr remove", "crates remove"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void delete(Player player, @Param(name = "name") String name) {
Crate crate = Crate.getByName(name);
if (crate == null) {
player.sendMessage(CC.translate("&cCrate with that name does not exist!"));
return;
}
crate.delete();
player.sendMessage(CC.translate("&aCrate &e" + name + "&a deleted!"));
}
@Command(names = {"crate list", "cr list", "crates list", "mysterybox list", "mb list"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void list(Player player) {
player.sendMessage(CC.translate("&aCrates:"));
for (Crate crate : Crate.getCrates().values()) {
if (crate instanceof MysteryBox) {
player.sendMessage(CC.translate("&7- &e" + crate.getName() + " &7- &aMystery Box"));
} else if (crate instanceof Airdrop) {
player.sendMessage(CC.translate("&7- &e" + crate.getName() + " &7- &aAirdrop"));
} else {
player.sendMessage(CC.translate("&7- &e" + crate.getName() + " &7- &aCrate"));
}
}
}
@Command(names = {"crate edit", "cr edit", "crates edit", "mysterybox edit", "mb edit", "airdrop edit", "ad edit"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void edit(Player player, @Param(name = "name") String name) {
Crate crate = Crate.getByName(name);
if (crate == null) {
player.sendMessage(CC.translate("&cCrate with that name does not exist!"));
return;
}
new CrateEditMenu(crate).openMenu(player);
}
@Command(names = {"crate test"}, permission = "op", hidden = true)
public static void test(Player player, @Param(name = "name") String name) {
Crate crate = Crate.getByName(name);
if (crate == null) {
player.sendMessage(CC.translate("&cCrate with that name does not exist!"));
return;
}
new CSGOOpenMenu(crate).openMenu(player);
}
@Command(names = {"airdrop edit", "ad edit"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void airdropEdit(Player player) {
Crate crate = Crate.getByName("Airdrop");
if (crate == null) {
player.sendMessage(CC.translate("&cCrate with that name does not exist!"));
return;
}
new CrateEditMenu(crate).openMenu(player);
}
@Command(names = {"crate preview", "cr preview", "crates preview", "mysterybox preview", "mb preview"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void preview(Player player, @Param(name = "name") String name) {
Crate crate = Crate.getByName(name);
if (crate == null) {
player.sendMessage(CC.translate("&cCrate with that name does not exist!"));
return;
}
new CratePreviewMenu(crate).openMenu(player);
}
@Command(names = {"crate give", "cr give", "crates give", "mysterybox give", "mb give", "airdrop give", "ad give"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void give(CommandSender player, @Param(name = "name") String name,
@Param(name = "amount") int amount,
@Param(name = "target") Player target) {
Crate crate = Crate.getByName(name);
if (crate == null) {
player.sendMessage(CC.translate("&cCrate with that name does not exist!"));
return;
}
ItemStack item = crate.generateKey().clone();
item.setAmount(amount);
target.getInventory().addItem(item);
if (crate instanceof MysteryBox) {
player.sendMessage(CC.translate("&eYou have given x" + amount + " &6Mistery&e Keys to &6" + target.getName() + "&e!"));
} else if (crate instanceof Airdrop) {
player.sendMessage(CC.translate("&eYou have given x" + amount + " &6Airdrop&e to &6" + target.getName() + "&e!"));
} else {
player.sendMessage(CC.translate("&eYou have given x" + amount + " &6Crate Keys&e to &6" + target.getName() + "&e!"));
}
}
@Command(names = {"givekey", "crate givekey"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void give(CommandSender player,
@Param(name = "target") Player target,
@Param(name = "name") String name,
@Param(name = "amount") int amount) {
Crate crate = Crate.getByName(name);
if (crate == null) {
player.sendMessage(CC.translate("&cCrate with that name does not exist!"));
return;
}
ItemStack item = crate.generateKey().clone();
item.setAmount(amount);
if (target.getInventory().firstEmpty() == -1) {
target.sendMessage("");
target.sendMessage(CC.translate("&a&eYour inventory was &cfull&e."));
Clickable clickable = new Clickable("&a[Click here] &eto recover the items.",
"&a[Click here]",
"/reclaimitems");
clickable.sendToPlayer(target);
target.sendMessage("");
HCFProfile profile = HCFProfile.get(target);
profile.getNoReclaimedItems().add(Crate.getByName("Blood").generateKey());
return;
}
target.getInventory().addItem(item);
}
@Command(names = {"crate setchest", "cr setchest", "crates setchest", "mysterybox setchest", "mb setchest"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void setChest(Player player, @Param(name = "name") String name) {
Crate crate = Crate.getByName(name);
if (crate == null) {
player.sendMessage(CC.translate("&cCrate with that name does not exist!"));
return;
}
Block targetBlock = player.getTargetBlock(null, 4);
if (targetBlock == null) {
player.sendMessage(CC.translate("&cYou must be look a block."));
return;
}
Location location = targetBlock.getLocation();
if (crate.getChestLocation() != null && crate.getChestLocation().equals(location)) {
player.sendMessage(CC.translate("&cThere is another crate."));
return;
}
crate.createHologram(location);
crate.setChestLocation(location);
player.sendMessage(CC.translate("&aSuccessfully set chest location."));
}
@Command(names = {"keyall"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void keyall(CommandSender sender, @Param(name = "name") String name, @Param(name = "amount") int amount) {
Crate crate = Crate.getByName(name);
if (crate == null) {
sender.sendMessage(CC.translate("&cCrate with that name does not exist!"));
return;
}
for (Player target : Bukkit.getOnlinePlayers()) {
ItemStack item = crate.generateKey().clone();
item.setAmount(amount);
if (target.getInventory().firstEmpty() != -1) {
target.getInventory().addItem(item);
} else {
target.getWorld().dropItem(target.getLocation(), item);
}
TitleBuilder titleBuilder = new TitleBuilder(crate.getDisplayName() + " &areceived.",
"&eAmount: &f" + amount,
10, 20, 10);
titleBuilder.send(target);
}
sender.sendMessage(CC.translate("&eYou have given &6x" + amount + " " + crate.getName() + " &eto &6everybody&e."));
}
@Command(names = {"keyalldone"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void keyalldone(CommandSender sender) {
for (Player other : Bukkit.getOnlinePlayers()) {
TitleBuilder titleBuilder = new TitleBuilder("&4&lKeyall", "&7has finished.", 10, 20, 10);
titleBuilder.send(other);
}
}
@Command(names = {"create removechest", "cr removechest"}, permission = "PLATFORMADMINISTRATOR", hidden = true)
public static void removeLocation(CommandSender sender, @Param(name = "name") String name) {
Crate crate = Crate.getByName(name);
if (crate == null) {
sender.sendMessage(CC.translate("&cCrate with that name does not exist!"));
return;
}
crate.setChestLocation(null);
crate.removeHologram();
sender.sendMessage(CC.translate("&aSuccessfully removed chest location."));
}
}

View File

@ -0,0 +1,189 @@
package rip.battle.crates.crate.listeners;
import cc.stormworth.core.util.chat.CC;
import cc.stormworth.core.util.general.TaskUtil;
import com.google.common.collect.Lists;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import rip.battle.crates.Crates;
import rip.battle.crates.airdrop.Airdrop;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.CratePlaceholder;
import rip.battle.crates.crate.menus.CSGOOpenMenu;
import rip.battle.crates.crate.menus.CrateEditMenu;
import rip.battle.crates.crate.menus.CratePreviewMenu;
import rip.battle.crates.misterybox.MysteryBox;
import rip.battle.crates.reward.Reward;
import rip.battle.crates.supplydrop.SupplyDrop;
import rip.battle.crates.utils.RandomUtils;
import java.util.List;
public class CrateListener implements Listener {
@EventHandler
public void onInventoryClose(InventoryCloseEvent event) {
Player player = (Player) event.getPlayer();
Inventory inventory = event.getInventory();
if (player.hasMetadata("closeByRightClick")) {
player.removeMetadata("closeByRightClick", Crates.getInstance());
return;
}
if (inventory.getName().contains(CC.translate("&eEdit Rewards of "))) {
String name = inventory.getName().replace(CC.translate("&eEdit Rewards of "), "");
Crate crate = Crate.getByName(name);
if (crate == null) {
return;
}
List<CratePlaceholder> placeholders = Lists.newArrayList();
for (int i = 0; i < 54; i++) {
ItemStack item = inventory.getItem(i);
if (item == null || item.getType() == null) {
continue;
}
if (crate.getReward(i) != null) {
continue;
}
if (crate instanceof MysteryBox) {
MysteryBox box = (MysteryBox) crate;
if (box.getObligatoryReward(i) != null) {
continue;
}
}
placeholders.add(new CratePlaceholder(item, i));
}
crate.setPlaceholders(placeholders);
player.sendMessage(CC.translate("&aSuccessfully updated the rewards of &e" + name + "&a!"));
player.playSound(player.getLocation(), Sound.LEVEL_UP, 0.5F, 0.5F);
TaskUtil.runAsync(Crates.getInstance(), crate::save);
TaskUtil.runLater(Crates.getInstance(), () -> new CrateEditMenu(crate).openMenu(player),
2L);
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (Crate.getCrateByKey(player.getItemInHand()) instanceof Airdrop) {
player.sendMessage(CC.translate("&cTo use AirDrop you have to put the block on the ground."));
return;
}
if (Crate.getCrateByKey(player.getItemInHand()) instanceof SupplyDrop) {
return;
}
if (Crate.getCrateByKey(player.getItemInHand()) instanceof MysteryBox) {
MysteryBox box = (MysteryBox) Crate.getCrateByKey(player.getItemInHand());
box.openCrate(player);
return;
}
if (Crate.getCrateByKey(player.getItemInHand()) != null) {
Crate crate = Crate.getCrateByKey(player.getItemInHand());
if (crate.getName().equalsIgnoreCase("Giftbox")) {
crate.consumeKey(player);
if (player.isSneaking()) {
if (player.getInventory().firstEmpty() == -1) {
player.sendMessage(CC.translate("&cYour inventory is full!"));
return;
}
Reward reward = RandomUtils.getRandomReward(crate.getRewards());
player.getInventory().addItem(reward.getItem());
} else {
new CSGOOpenMenu(crate).openMenu(player);
}
return;
}
event.setCancelled(true);
if (event.getAction().name().contains("RIGHT_CLICK")) {
if (Crate.getCrateByKey(player.getItemInHand()) == crate) {
crate.openCrate(player);
return;
}
if (player.isSneaking() && player.getGameMode() == GameMode.CREATIVE && player.isOp()) {
new CrateEditMenu(crate).openMenu(player);
return;
}
new CratePreviewMenu(crate).openMenu(player);
}
if (event.getAction().name().contains("LEFT_CLICK")) {
if (player.isSneaking() && player.getGameMode() == GameMode.CREATIVE && player.isOp()) {
new CrateEditMenu(crate).openMenu(player);
return;
}
new CratePreviewMenu(crate).openMenu(player);
}
}
if (event.getClickedBlock() == null) return;
Location location = event.getClickedBlock().getLocation();
Crate crate = Crate.getByLocation(location);
if (crate == null) {
return;
}
event.setCancelled(true);
if (event.getAction().name().contains("RIGHT_CLICK")) {
if (Crate.getCrateByKey(player.getItemInHand()) == crate) {
crate.openCrate(player);
return;
}
if (player.isSneaking() && player.getGameMode() == GameMode.CREATIVE && player.isOp()) {
new CrateEditMenu(crate).openMenu(player);
return;
}
new CratePreviewMenu(crate).openMenu(player);
}
if (event.getAction().name().contains("LEFT_CLICK")) {
if (player.isSneaking() && player.getGameMode() == GameMode.CREATIVE && player.isOp()) {
new CrateEditMenu(crate).openMenu(player);
return;
}
new CratePreviewMenu(crate).openMenu(player);
}
}
}

View File

@ -0,0 +1,92 @@
package rip.battle.crates.crate.menus;
import cc.stormworth.core.kt.util.ItemBuilder;
import cc.stormworth.core.menu.Button;
import cc.stormworth.core.menu.Menu;
import com.google.common.collect.Maps;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.reward.Reward;
import rip.battle.crates.utils.RandomUtils;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class CSGOOpenMenu extends Menu {
private final Crate crate;
private final Reward randomReward;
private final List<Reward> rewards;
int time = 0;
private boolean claimed = false;
@Override
public String getTitle(Player player) {
return crate.getDisplayName() + " Crate";
}
public CSGOOpenMenu(Crate crate) {
this.crate = crate;
this.rewards = crate.getRewards();
randomReward = RandomUtils.getRandomReward(rewards);
Collections.shuffle(rewards);
setAutoUpdate(true);
setUpdateAfterClick(false);
}
@Override
public void onClose(Player player) {
if (!claimed) {
player.getInventory().addItem(randomReward.getItem());
player.updateInventory();
player.playSound(player.getLocation(), Sound.LEVEL_UP, 1.0F, 1.0F);
claimed = true;
}
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
Collections.rotate(rewards, 1);
for (int i = 0; i < 9; i++) {
buttons.put(buttons.size(), Button.fromItem(new ItemBuilder(Material.STAINED_GLASS_PANE).data((short) 0).build()));
}
for (int i = 0; i < 9; i++) {
buttons.put(buttons.size(), Button.fromItem(rewards.get(i).getItem()));
}
for (int i = 18; i < 27; i++) {
buttons.put(buttons.size(), Button.fromItem(new ItemBuilder(Material.STAINED_GLASS_PANE).data((short) 0).build()));
}
buttons.put(4, Button.fromItem(new ItemBuilder(Material.STAINED_GLASS_PANE).data((short) 5).build()));
buttons.put(22, Button.fromItem(new ItemBuilder(Material.STAINED_GLASS_PANE).data((short) 5).build()));
player.playSound(player.getLocation(), Sound.NOTE_STICKS, 1.0F, 1.0F);
Button button = buttons.get(13);
if (time == 25) {
if (button.getButtonItem(player).isSimilar(randomReward.getItem())) {
setAutoUpdate(false);
player.getInventory().addItem(randomReward.getItem());
player.updateInventory();
player.playSound(player.getLocation(), Sound.LEVEL_UP, 1.0F, 1.0F);
claimed = true;
}
} else {
time++;
}
return buttons;
}
}

View File

@ -0,0 +1,109 @@
package rip.battle.crates.crate.menus;
import cc.stormworth.core.kt.util.ItemBuilder;
import cc.stormworth.core.menu.Button;
import cc.stormworth.core.menu.Menu;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.prompt.CrateBroadCastPrompt;
import rip.battle.crates.crate.prompt.CrateEditLinePrompt;
import rip.battle.crates.reward.Reward;
import rip.battle.crates.reward.menus.RewardEditMenu;
import rip.battle.crates.utils.ChatUtils;
public class CrateBroadcastMenu extends Menu {
private final Crate crate;
private final Reward reward;
public CrateBroadcastMenu(Crate crate, Reward reward) {
this.crate = crate;
this.reward = reward;
setUpdateAfterClick(true);
}
@Override
public String getTitle(Player player) {
return "&eBroadcast Lines";
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
buttons.put(0, Button.fromItem(new ItemBuilder(Material.BED)
.name("&cGo Back").build(),
(other) -> new RewardEditMenu(reward, crate).openMenu(other)));
buttons.put(4, Button.fromItem(new ItemBuilder(Material.BOOK)
.name("&aAdd new lines").build(),
(other) -> ChatUtils.beginPrompt(other, new CrateBroadCastPrompt(crate, reward))));
buttons.put(8, Button.fromItem(new ItemBuilder(Material.JUKEBOX)
.name("&eClick to preview broadcast").build(),
(other) -> {
player.closeInventory();
LinkedList<String> lines = reward.getBroadcast();
if (lines.isEmpty()) {
other.sendMessage("&cNo broadcast lines set!");
}else{
lines.forEach(line -> other.sendMessage(line.replace("{player}", other.getName())));
}
}));
int i = 9;
int index = 0;
for (String line : reward.getBroadcast()) {
buttons.put(i++, new BroadcastLineButton(line, index++));
}
return buttons;
}
@RequiredArgsConstructor
public class BroadcastLineButton extends Button{
private final String line;
private final int index;
@Override
public String getName(Player player) {
return line;
}
@Override
public List<String> getDescription(Player player) {
return Lists.newArrayList(
"&fRight &7click to Delete this line",
"&fLeft &7click to Edit this line"
);
}
@Override
public Material getMaterial(Player player) {
return Material.PAPER;
}
@Override
public void clicked(Player player, int slot, ClickType clickType) {
if (clickType == ClickType.RIGHT) {
reward.getBroadcast().remove(line);
} else if (clickType == ClickType.LEFT) {
ChatUtils.beginPrompt(player, new CrateEditLinePrompt(crate, reward, index));
}
}
}
}

View File

@ -0,0 +1,52 @@
package rip.battle.crates.crate.menus;
import cc.stormworth.core.kt.util.ItemBuilder;
import cc.stormworth.core.menu.Button;
import cc.stormworth.core.menu.Menu;
import cc.stormworth.core.util.chat.CC;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import rip.battle.crates.crate.Crate;
import java.util.Map;
@RequiredArgsConstructor
public class CrateDeleteMenu extends Menu {
private final Crate crate;
@Override
public String getTitle(Player player) {
return "&cDelete Crate or chest";
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
buttons.put(0, Button.fromItem(new ItemBuilder(Material.BED)
.name("&cGo Back").build(),
(other) -> new CrateEditMenu(crate).openMenu(other)));
buttons.put(getSlot(3, 1), Button.fromItem(new ItemBuilder(Material.FLINT_AND_STEEL).name("&cDelete Crate").build(),
(other) -> {
other.closeInventory();
crate.delete();
}));
buttons.put(getSlot(5, 1),
Button.fromItem(new ItemBuilder(Material.CHEST)
.name("&cDelete Chest").build(), (other) -> {
crate.removeHologram();
crate.setChestLocation(null);
player.sendMessage(CC.translate("&aSuccessfully removed chest location."));
other.closeInventory();
}));
return buttons;
}
}

View File

@ -0,0 +1,190 @@
package rip.battle.crates.crate.menus;
import cc.stormworth.core.kt.util.ItemBuilder;
import cc.stormworth.core.menu.Button;
import cc.stormworth.core.menu.Menu;
import cc.stormworth.core.util.chat.CC;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.prompt.CrateKeyItemPrompt;
import rip.battle.crates.crate.prompt.CrateRenamePrompt;
import rip.battle.crates.utils.ChatUtils;
public class CrateEditMenu extends Menu {
private final Crate crate;
public CrateEditMenu(Crate crate) {
this.crate = crate;
setUpdateAfterClick(true);
}
@Override
public String getTitle(Player player) {
String name = "&eEditing &a" + crate.getDisplayName() + "&e...";
if(name.length() > 32) {
name = name.substring(0, 32);
}
return name;
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
buttons.put(getSlot(2, 1), Button.fromItem(
new ItemBuilder(Material.NAME_TAG).name("&6Change display name")
.addToLore(
"",
"&7Click to change displayname."
).build(),
(other) -> ChatUtils.beginPrompt(other, new CrateRenamePrompt(crate))));
buttons.put(getSlot(4, 1), Button.fromItem(
new ItemBuilder(Material.CHEST)
.name("&6Edit rewards")
.addToLore(
"",
"&7Click to edit the rewards for this crate."
).build(),
crate::openEditRewardsInventory));
buttons.put(getSlot(6, 1), Button.fromItem(
new ItemBuilder(crate.getKey().getType())
.data(crate.getKey().getDurability())
.name("&6Change key item")
.addToLore(
"",
"&7Click to change the key item for this crate."
).build(),
(other) -> ChatUtils.beginPrompt(other, new CrateKeyItemPrompt(crate))));
buttons.put(getSlot(4, 2), Button.fromItem(
new ItemBuilder(Material.JUKEBOX).name("&6Select open sound")
.addToLore(
"",
"&7Click to select the sound that plays when this crate is opened."
)
.build(),
(other) -> new SelectSoundMenu(crate).openMenu(player)));
buttons.put(getSlot(2, 3), new MinAmountButton());
buttons.put(getSlot(4, 3), Button.fromItem(
new ItemBuilder(crate.isEnable() ? Material.REDSTONE_TORCH_ON : Material.LEVER)
.name(crate.isEnable() ? "&cDisable crate" : "&aEnable crate")
.addToLore(
"",
"&7Click to " + (crate.isEnable() ? "disable" : "enable") + " this crate."
).build(),
(other) -> crate.setEnable(!crate.isEnable())
));
buttons.put(getSlot(6, 3), new MaxRewardsButton());
buttons.put(getSlot(5, 5), Button.fromItem(
new ItemBuilder(Material.FLINT_AND_STEEL).name("&4&lDelete crate")
.addToLore(
"",
"&4&lClick to delete this crate."
).build(), (other) -> new CrateDeleteMenu(crate).openMenu(other)));
buttons.put(getSlot(3, 5), Button.fromItem(
new ItemBuilder(Material.ENDER_CHEST).name("&6Preview rewards")
.addToLore(
"",
"&7Click to open preview menu of rewards for this crate."
)
.build(), (other) -> new CratePreviewMenu(crate).openMenu(other)));
return buttons;
}
public class MinAmountButton extends Button{
@Override
public String getName(Player player) {
return "&6Select Min rewards amount";
}
@Override
public List<String> getDescription(Player player) {
return Lists.newArrayList(
"&7Minimum amount of rewards to be given: &f" + crate.getMinimumReward(),
"",
"&fRight click &7to decrease",
"&fLeft click &7to increase",
""
);
}
@Override
public Material getMaterial(Player player) {
return Material.WOOD_BUTTON;
}
@Override
public void clicked(Player player, int slot, ClickType clickType) {
if(clickType == ClickType.RIGHT) {
if(crate.getMinimumReward() == 1) {
player.sendMessage(CC.translate("&cCrates with a minimum reward of 1 are not allowed."));
Button.playFail(player);
return;
}
crate.setMinimumReward(crate.getMinimumReward() - 1);
} else if(clickType == ClickType.LEFT) {
crate.setMinimumReward(crate.getMinimumReward() + 1);
}
}
}
public class MaxRewardsButton extends Button{
@Override
public String getName(Player player) {
return "&6Select Max rewards amount";
}
@Override
public List<String> getDescription(Player player) {
return Lists.newArrayList(
"&7Maximum amount of rewards to be given: &f" + crate.getMaximumReward(),
"",
"&fRight click &7to decrease",
"&fLeft click &7to increase",
""
);
}
@Override
public Material getMaterial(Player player) {
return Material.STONE_BUTTON;
}
@Override
public void clicked(Player player, int slot, ClickType clickType) {
if(clickType == ClickType.RIGHT) {
if(crate.getMaximumReward() <= crate.getMinimumReward()) {
player.sendMessage(CC.translate("&cMaximum reward must be greater than or equal to minimum reward."));
Button.playFail(player);
return;
}
crate.setMaximumReward(crate.getMaximumReward() - 1);
} else if(clickType == ClickType.LEFT) {
crate.setMaximumReward(crate.getMaximumReward() + 1);
}
}
}
}

View File

@ -0,0 +1,48 @@
package rip.battle.crates.crate.menus;
import cc.stormworth.core.menu.Button;
import cc.stormworth.core.menu.Menu;
import com.google.common.collect.Maps;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.entity.Player;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.CratePlaceholder;
import rip.battle.crates.misterybox.MysteryBox;
@RequiredArgsConstructor
public class CratePreviewMenu extends Menu {
private final Crate crate;
@Override
public String getTitle(Player player) {
String name = crate.getName();
if(name.length() > 32) {
name = name.substring(0, 32);
}
return ChatColor.GOLD + "Preview " + name;
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
for (CratePlaceholder placeholder : crate.getPlaceholders()) {
if (placeholder.getItem() != null) {
buttons.put(placeholder.getSlot(), Button.fromItem(placeholder.getPreview()));
}
}
crate.getRewards().forEach(reward -> buttons.put(reward.getSlot(), Button.fromItem(reward.getItem())));
if(crate instanceof MysteryBox) {
((MysteryBox) crate).getObligatoryRewards().forEach(reward -> buttons.put(reward.getSlot(), Button.fromItem(reward.getItem())));
}
return buttons;
}
}

View File

@ -0,0 +1,96 @@
package rip.battle.crates.crate.menus;
import cc.stormworth.core.kt.util.ItemBuilder;
import cc.stormworth.core.menu.Button;
import cc.stormworth.core.menu.Menu;
import cc.stormworth.core.menu.pagination.PaginatedMenu;
import cc.stormworth.core.util.chat.CC;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import rip.battle.crates.crate.Crate;
@RequiredArgsConstructor
public class SelectSoundMenu extends PaginatedMenu {
private final Crate crate;
@Override
public String getTitle(Player player) {
return "&6Select sound when open";
}
@Override
public String getPrePaginatedTitle(Player player) {
return "&6Select sound when open &f" + crate.getName();
}
@Override
public int getMaxItemsPerPage(Player player) {
return 27;
}
@Override
public Map<Integer, Button> getGlobalButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
buttons.put(4, Button.fromItem(new ItemBuilder(Material.BED).name("&cGo Back").build(),
(other) -> new CrateEditMenu(crate).openMenu(other)));
return buttons;
}
@Override
public Map<Integer, Button> getAllPagesButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
for (Sound sound : Sound.values()) {
buttons.put(buttons.size(), new SoundButton(sound));
}
return buttons;
}
@RequiredArgsConstructor
public class SoundButton extends Button{
private final Sound sound;
@Override
public String getName(Player player) {
return "&6" + sound.name();
}
@Override
public List<String> getDescription(Player player) {
return Lists.newArrayList(
"&fLeft click &6to Set sound",
"&fRight click &7to Play sound"
);
}
@Override
public Material getMaterial(Player player) {
return Material.JUKEBOX;
}
@Override
public void clicked(Player player, int slot, ClickType clickType) {
if(clickType == ClickType.LEFT){
player.playSound(player.getLocation(), sound, 1, 1);
crate.setOpenSound(sound);
player.sendMessage(CC.translate("&6Set sound to &f" + sound.name()));
new CrateEditMenu(crate).openMenu(player);
}else{
player.playSound(player.getLocation(), sound, 1, 1);
}
}
}
}

View File

@ -0,0 +1,49 @@
package rip.battle.crates.crate.prompt;
import cc.stormworth.core.util.chat.CC;
import java.util.LinkedList;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.menus.CrateBroadcastMenu;
import rip.battle.crates.reward.Reward;
public class CrateBroadCastPrompt extends StringPrompt {
private final Crate crate;
private final Reward reward;
private final LinkedList<String> lines;
public CrateBroadCastPrompt(Crate crate, Reward reward) {
this.reward = reward;
this.crate = crate;
this.lines = reward.getBroadcast();
}
@Override
public String getPromptText(ConversationContext context) {
return CC.translate("&7Enter a lines to broadcast when the crate is opened. "
+ "&7&oOr type &ccancel&7&o to cancel or type &aconfirm&7 to end: ");
}
@Override
public Prompt acceptInput(ConversationContext context, String input) {
Player player = (Player) context.getForWhom();
if (input.equalsIgnoreCase("cancel") || input.equalsIgnoreCase("confirm")) {
reward.setBroadcast(lines);
new CrateBroadcastMenu(crate, reward).openMenu(player);
return Prompt.END_OF_CONVERSATION;
}
lines.add(CC.translate(input.replace("{name}", crate.getDisplayName())));
player.sendMessage(CC.translate("&aAdded new broadcast line"));
return this;
}
}

View File

@ -0,0 +1,40 @@
package rip.battle.crates.crate.prompt;
import cc.stormworth.core.util.chat.CC;
import lombok.RequiredArgsConstructor;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.menus.CrateBroadcastMenu;
import rip.battle.crates.reward.Reward;
@RequiredArgsConstructor
public class CrateEditLinePrompt extends StringPrompt {
private final Crate crate;
private final Reward reward;
private final int index;
@Override
public String getPromptText(ConversationContext conversationContext) {
return CC.translate("&7Enter a text to modify the line number &6" + index + "&7. Or type &ccancel&7 to cancel.");
}
@Override
public Prompt acceptInput(ConversationContext context, String input) {
Player player = (Player) context.getForWhom();
if (input.equalsIgnoreCase("cancel")) {
new CrateBroadcastMenu(crate, reward).openMenu(player);
return Prompt.END_OF_CONVERSATION;
}
reward.getBroadcast().set(index, CC.translate(input.replace("{name}", crate.getDisplayName())));
new CrateBroadcastMenu(crate, reward).openMenu(player);
return Prompt.END_OF_CONVERSATION;
}
}

View File

@ -0,0 +1,48 @@
package rip.battle.crates.crate.prompt;
import cc.stormworth.core.util.chat.CC;
import lombok.RequiredArgsConstructor;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.menus.CrateEditMenu;
@RequiredArgsConstructor
public class CrateKeyItemPrompt extends StringPrompt {
private final Crate crate;
@Override
public String getPromptText(ConversationContext conversationContext) {
return CC.translate("&7Put item in your hand and type &6accept&7 to confirm. Or type &6cancel&7 to cancel.");
}
@Override
public Prompt acceptInput(ConversationContext context, String input) {
Player player = (Player) context.getForWhom();
if (input.equalsIgnoreCase("cancel")) {
player.sendMessage(CC.translate("&cCrate rename cancelled."));
new CrateEditMenu(crate).openMenu(player);
return Prompt.END_OF_CONVERSATION;
}
if(player.getItemInHand() == null) {
player.sendMessage(CC.translate("&cYou must have an item in your hand to select it."));
return this;
}
if (input.equalsIgnoreCase("accept")) {
crate.setKey(player.getItemInHand());
player.sendMessage(CC.translate("&aCrate key item set to &6" + player.getItemInHand().getType().name() + "&a."));
new CrateEditMenu(crate).openMenu(player);
return Prompt.END_OF_CONVERSATION;
}
return this;
}
}

View File

@ -0,0 +1,43 @@
package rip.battle.crates.crate.prompt;
import cc.stormworth.core.util.chat.CC;
import lombok.AllArgsConstructor;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.menus.CrateEditMenu;
@AllArgsConstructor
public class CrateRenamePrompt extends StringPrompt {
private final Crate crate;
@Override
public String getPromptText(ConversationContext conversationContext) {
return CC.translate("&7Enter a new display name for the crate: &6" + crate.getName() + "&7. Or type &6cancel&7 to cancel.");
}
@Override
public Prompt acceptInput(ConversationContext context, String input) {
Player player = (Player) context.getForWhom();
if (input.equalsIgnoreCase("cancel")) {
player.sendMessage(CC.translate("&cCrate rename cancelled."));
new CrateEditMenu(crate).openMenu(player);
return Prompt.END_OF_CONVERSATION;
}
crate.setDisplayName(CC.translate(input));
player.sendMessage(CC.translate("&aCrate displayname change to &6" + crate.getDisplayName() + "&a."));
crate.destroyHolograms();
crate.sendHolograms();
new CrateEditMenu(crate).openMenu(player);
return Prompt.END_OF_CONVERSATION;
}
}

View File

@ -0,0 +1,146 @@
package rip.battle.crates.misterybox;
import cc.stormworth.core.kt.util.ItemBuilder;
import cc.stormworth.core.util.chat.CC;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.reward.Reward;
import rip.battle.crates.reward.RewardType;
import rip.battle.crates.utils.ChatUtils;
import rip.battle.crates.utils.RandomUtils;
import java.util.*;
@Getter
@Setter
public class MysteryBox extends Crate {
private List<Reward> obligatoryRewards = Lists.newArrayList();
public MysteryBox(String name) {
super(name);
}
@Override
public List<String> getHologramsLines() {
return Arrays.asList(
getDisplayName() + " MisteryBox",
"&7",
"&fLeft click &7for preview rewards",
"&fRight click &7to open",
"&7",
"&7&ostore.battle.rip");
}
@Override
public ItemStack generateKey() {
return new ItemBuilder(getKey().clone())
.name(CC.translate(getDisplayName() + " Key"))
.setLore(Lists.newArrayList(
"&7",
"&7You can preview this " + getDisplayName() + " Crate &7 rewards",
"&7By going to the overworld &aSpawn",
"&7",
ChatUtils.getFirstColor(getDisplayName()) + "Right Click &7to open the key",
ChatUtils.getFirstColor(getDisplayName()) + "Left Click &7to preview rewards",
"&7",
"&7Purchase additional keys at &f&nstore.battle.rip"
))
.build();
}
@Override
public void openCrate(Player player) {
if (!isEnable()) {
player.sendMessage(CC.translate("&cThis misterybox is currently disabled"));
return;
}
if (getMaximumReward() == 0 || getRewards().isEmpty()) {
player.sendMessage(CC.translate("&cCrate " + getName() + " is empty, please contact an admin."));
return;
}
if (player.getInventory().firstEmpty() < 0) {
player.sendMessage(CC.translate("&cInventory Full."));
return;
}
int random = new Random().nextInt(getMaximumReward() - getMinimumReward() + 1) + getMinimumReward();
List<Reward> randomRewards = new ArrayList<>();
List<Reward> rewardList = new ArrayList<>(getRewards());
Collections.shuffle(rewardList);
for (int i = 0; i < random; i++) {
randomRewards.add(RandomUtils.getRandomReward(rewardList));
}
for (Reward reward : obligatoryRewards) {
if (reward.getType() == RewardType.ITEMS) {
if (player.getInventory().firstEmpty() < 0) {
player.sendMessage(CC.translate("&cInventory Full."));
player.getWorld().dropItem(player.getLocation(), reward.getItem());
} else {
player.getInventory().addItem(reward.getItem());
}
} else {
List<String> commands = reward.getCommands();
for (String command : commands) {
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command.replace("%player%", player.getName()));
}
}
if (!reward.getBroadcast().isEmpty()) {
reward.getBroadcast().forEach(line -> Bukkit.broadcastMessage(line.replace("{player}", player.getName())));
}
}
for (Reward reward : randomRewards) {
if (reward.getType() == RewardType.ITEMS) {
if (player.getInventory().firstEmpty() < 0) {
player.sendMessage(CC.translate("&cInventory Full."));
player.getWorld().dropItem(player.getLocation(), reward.getItem());
} else {
player.getInventory().addItem(reward.getItem());
}
} else {
List<String> commands = reward.getCommands();
for (String command : commands) {
if (command.contains("op")) {
continue;
}
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command.replace("%player%", player.getName()));
}
}
if (!reward.getBroadcast().isEmpty()) {
reward.getBroadcast().forEach(line -> Bukkit.broadcastMessage(line.replace("{player}", player.getName())));
}
}
if (getOpenSound() != null) {
player.playSound(player.getLocation(), getOpenSound(), 1, 1);
}
player.sendMessage(CC.translate("&aYou have received " + (randomRewards.size() + obligatoryRewards.size()) + " reward(s)"));
consumeKey(player);
player.updateInventory();
}
public Reward getObligatoryReward(int slot) {
return obligatoryRewards.stream().filter(reward -> reward.getSlot() == slot).findFirst().orElse(null);
}
}

View File

@ -0,0 +1,152 @@
package rip.battle.crates.reward;
import cc.stormworth.core.CorePlugin;
import cc.stormworth.core.kt.util.ItemBuilder;
import cc.stormworth.core.util.chat.CC;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.Setter;
import org.bson.Document;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import rip.battle.crates.utils.ItemUtils;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@Getter
@Setter
public class Reward {
private ItemStack item;
private double chance;
private int slot;
private RewardType type;
private List<String> commands;
private boolean obligatory;
private LinkedList<String> broadcast = Lists.newLinkedList();
public Reward(ItemStack item, double chance, int slot, RewardType type, List<String> commands, boolean obligatory) {
this.item = item;
if (this.item == null) {
this.item = new ItemStack(Material.AIR);
}
this.chance = chance;
this.slot = slot;
this.type = type;
this.commands = commands;
this.obligatory = obligatory;
if (this.chance > 1.0) {
this.chance = 1.0;
}
ItemUtils.removeRewardsLore(this.item);
}
public Reward(Document document) {
this.item = CorePlugin.GSON.fromJson(document.getString("item"), ItemStack.class);
this.slot = document.getInteger("slot");
if (document.get("chance") instanceof Double) {
this.chance = document.getDouble("chance");
} else if (document.get("chance") instanceof Integer) {
this.chance = Double.parseDouble(document.getInteger("chance").toString());
}
if (this.chance > 1.0) {
this.chance = 1.0;
}
if (document.containsKey("type")) {
this.type = RewardType.getByName(document.getString("type"));
} else {
this.type = RewardType.ITEMS;
}
if (document.containsKey("commands")) {
this.commands = document.getList("commands", String.class);
}
if (document.containsKey("broadcast")) {
setBroadcast(new LinkedList<>(document.getList("broadcast", String.class)));
}
}
public ItemStack getItem() {
if (this.item == null) {
return new ItemStack(Material.AIR);
}
ItemStack item = this.item.clone();
ItemUtils.removeRewardsLore(item);
return item;
}
public ItemStack getPreviewItem() {
List<String> lore = Lists.newArrayList();
lore.add("&0");
lore.add("&7Type: &e" + this.type.name());
lore.add("&0");
lore.add("&7Chance: &e" + this.chance + "%");
if (this.commands != null && !this.commands.isEmpty()) {
lore.add("&7Commands: &e");
for (String command : this.commands) {
lore.add(" &7- &f" + command);
}
}
lore.add("&0");
lore.add("&fRight Click &7to edit");
return new ItemBuilder(this.item.clone())
.addLoreList(CC.translate(lore)).build();
}
public ItemStack getPreviewObligatoryItem() {
List<String> lore = Lists.newArrayList();
lore.add("&0");
lore.add("&7Type: &e" + this.type.name());
lore.add("&0");
lore.add("&7Chance: &e" + this.chance + "%");
lore.add("&cObligatory");
if (this.commands != null && !this.commands.isEmpty()) {
lore.add("&7Commands: &e");
for (String command : this.commands) {
lore.add(" &7- &f" + command);
}
}
lore.add("&0");
lore.add("&fRight Click &7to edit");
return new ItemBuilder(this.item.clone())
.addLoreList(CC.translate(lore)).build();
}
public ItemStack getRealItem() {
return item;
}
public Document serialize() {
Document document = new Document();
document.append("item", CorePlugin.GSON.toJson(item));
document.append("slot", slot);
document.append("chance", chance);
document.append("type", type.name());
if (commands != null) {
document.append("commands", commands);
}
document.append("broadcast", new ArrayList<>(broadcast));
return document;
}
}

View File

@ -0,0 +1,17 @@
package rip.battle.crates.reward;
public enum RewardType {
COMMAND,
ITEMS;
public static RewardType getByName(String name) {
for (RewardType type : RewardType.values()) {
if (type.name().equalsIgnoreCase(name)) {
return type;
}
}
return null;
}
}

View File

@ -0,0 +1,221 @@
package rip.battle.crates.reward;
import cc.stormworth.core.util.chat.CC;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.metadata.FixedMetadataValue;
import rip.battle.crates.Crates;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.CratePlaceholder;
import rip.battle.crates.misterybox.MysteryBox;
import rip.battle.crates.reward.menus.RewardEditMenu;
import rip.battle.crates.utils.ItemUtils;
public class RewardsListeners implements Listener {
@EventHandler
public void onInventoryOpen(InventoryOpenEvent event) {
Inventory inventory = event.getInventory();
if (inventory.getName().contains(CC.translate("&eEdit Rewards of "))) {
String name = inventory.getName().replace(CC.translate("&eEdit Rewards of "), "");
Crate crate = Crate.getByName(name);
if (crate == null) {
return;
}
for (CratePlaceholder placeholder : crate.getPlaceholders()) {
if (placeholder.getItem() == null) {
crate.getPlaceholders().remove(placeholder);
continue;
}
inventory.setItem(placeholder.getSlot(), placeholder.getItem());
}
crate.getRewards().forEach(reward -> inventory.setItem(reward.getSlot(), reward.getPreviewItem()));
if (crate instanceof MysteryBox) {
MysteryBox box = (MysteryBox) crate;
box.getObligatoryRewards().forEach(reward -> inventory.setItem(reward.getSlot(), reward.getPreviewObligatoryItem()));
}
}
}
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
Inventory inventory = event.getInventory();
if (event.getClickedInventory() == null) {
return;
}
if (inventory.getName().contains(CC.translate("&eEdit Rewards of "))) {
String name = inventory.getName().replace(CC.translate("&eEdit Rewards of "), "");
Crate crate = Crate.getByName(name);
if (crate == null) {
return;
}
if (event.getClick() == ClickType.RIGHT) {
if (event.getClickedInventory() == player.getInventory()) {
return;
}
event.setCancelled(true);
if (crate instanceof MysteryBox) {
MysteryBox box = (MysteryBox) crate;
if (box.getObligatoryReward(event.getSlot()) != null) {
player.setMetadata("closeByRightClick", new FixedMetadataValue(Crates.getInstance(), true));
new RewardEditMenu(box.getObligatoryReward(event.getSlot()), crate).openMenu(player);
return;
}
}
if (crate.getReward(event.getSlot()) != null) {
player.setMetadata("closeByRightClick", new FixedMetadataValue(Crates.getInstance(), true));
new RewardEditMenu(crate.getReward(event.getSlot()), crate).openMenu(player);
} else if (crate.getPlaceholder(event.getSlot()) != null) {
CratePlaceholder placeholder = crate.getPlaceholder(event.getSlot());
Reward newReward = new Reward(placeholder.getItem().clone(), 100, placeholder.getSlot(), RewardType.ITEMS, null, false);
crate.getPlaceholders().remove(placeholder);
crate.getRewards().add(newReward);
player.setMetadata("closeByRightClick", new FixedMetadataValue(Crates.getInstance(), true));
new RewardEditMenu(newReward, crate).openMenu(player);
} else {
Reward newReward = new Reward(event.getCurrentItem(), 100, event.getSlot(), RewardType.ITEMS, null, false);
crate.getRewards().add(newReward);
player.setMetadata("closeByRightClick", new FixedMetadataValue(Crates.getInstance(), true));
new RewardEditMenu(newReward, crate).openMenu(player);
}
} else {
if (event.getClick() == ClickType.DROP || event.getClick() == ClickType.CONTROL_DROP) {
if (crate.getPlaceholder(event.getSlot()) != null) {
crate.getPlaceholders().remove(crate.getPlaceholder(event.getSlot()));
}
if (crate.getReward(event.getSlot()) != null) {
crate.getRewards().remove(crate.getReward(event.getSlot()));
}
if (crate instanceof MysteryBox) {
MysteryBox box = (MysteryBox) crate;
if (box.getObligatoryReward(event.getSlot()) != null) {
box.getObligatoryRewards().remove(box.getObligatoryReward(event.getSlot()));
}
}
} else if (event.getClick() == ClickType.SHIFT_LEFT) {
if (event.getClickedInventory() == player.getInventory()) {
if (ItemUtils.isReward(event.getCursor())) {
Reward reward = ItemUtils.getRewardByItem(event.getCurrentItem().clone(), inventory.firstEmpty());
if (reward != null) {
if (reward.isObligatory()) {
if (crate instanceof MysteryBox) {
MysteryBox box = (MysteryBox) crate;
box.getObligatoryRewards().add(reward);
return;
}
}
crate.getRewards().add(reward);
return;
}
}
crate.getPlaceholders().add(new CratePlaceholder(event.getCurrentItem().clone(), inventory.firstEmpty()));
} else {
if (crate.getPlaceholder(event.getSlot()) != null) {
crate.getPlaceholders().remove(crate.getPlaceholder(event.getSlot()));
}
if (crate.getReward(event.getSlot()) != null) {
crate.getRewards().remove(crate.getReward(event.getSlot()));
}
if (crate instanceof MysteryBox) {
MysteryBox box = (MysteryBox) crate;
if (box.getObligatoryReward(event.getSlot()) != null) {
box.getObligatoryRewards().remove(box.getObligatoryReward(event.getSlot()));
}
}
}
} else if (event.getClick() == ClickType.LEFT) {
if (event.getClickedInventory() == player.getInventory()) {
return;
}
if (event.getInventory().getItem(event.getSlot()) == null) {
if (ItemUtils.isReward(event.getCursor())) {
Reward reward = ItemUtils.getRewardByItem(event.getCursor().clone(), event.getSlot());
if (reward != null) {
if (reward.isObligatory()) {
if (crate instanceof MysteryBox) {
MysteryBox box = (MysteryBox) crate;
box.getObligatoryRewards().add(reward);
return;
}
}
crate.getRewards().add(reward);
return;
}
}
crate.getPlaceholders().add(new CratePlaceholder(event.getCursor().clone(), event.getSlot()));
} else {
if (crate.getPlaceholder(event.getSlot()) != null) {
crate.getPlaceholders().remove(crate.getPlaceholder(event.getSlot()));
}
if (crate.getReward(event.getSlot()) != null) {
crate.getRewards().remove(crate.getReward(event.getSlot()));
}
if (crate instanceof MysteryBox) {
MysteryBox box = (MysteryBox) crate;
if (box.getObligatoryReward(event.getSlot()) != null) {
box.getObligatoryRewards().remove(box.getObligatoryReward(event.getSlot()));
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,115 @@
package rip.battle.crates.reward.commands;
import cc.stormworth.core.util.chat.CC;
import cc.stormworth.core.util.command.annotations.Command;
import cc.stormworth.core.util.command.annotations.Param;
import com.google.common.collect.Lists;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.List;
public class RewardCommand {
@Command(names = {"reward"}, permission = "PLATFORMADMINISTRATOR")
public static void help(Player player) {
player.sendMessage(CC.translate("&a&lReward Help"));
player.sendMessage(CC.translate("&7- &e/reward setchance <chance> &7- &aSets the chance for the item in your hand"));
player.sendMessage(CC.translate("&7- &e/reward setobligatory &7- &aSets the item in your hand to be obligatory"));
player.sendMessage(CC.translate("&7- &e/reward addcommand <command> &7- &aAdds a command to the item in your hand"));
}
@Command(names = {"reward setchance"}, permission = "PLATFORMADMINISTRATOR")
public static void setChance(Player player, @Param(name = "chance") int chance) {
if (chance < 0 || chance > 100) {
player.sendMessage(CC.translate("&cChance must be between 0 and 100!"));
return;
}
ItemStack itemStack = player.getItemInHand();
if (itemStack == null) {
player.sendMessage(CC.translate("&cYou must be holding an item to set the chance!"));
return;
}
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
player.sendMessage(CC.translate("&cYou must be holding an item to set the chance!"));
return;
}
List<String> lore = meta.getLore();
if (lore == null) {
lore = Lists.newArrayList();
}
lore.add(0, CC.translate("&7Chance:&a " + chance));
meta.setLore(lore);
itemStack.setItemMeta(meta);
player.sendMessage(CC.translate("&aSuccessfully set chance for &e" + itemStack.getType().name() + " &ato &e" + chance + "%"));
}
@Command(names = {"reward setobligatory"}, permission = "PLATFORMADMINISTRATOR")
public static void setObligatory(Player player) {
ItemStack itemStack = player.getItemInHand();
if (itemStack == null) {
player.sendMessage(CC.translate("&cYou must be holding an item to set the chance!"));
return;
}
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
player.sendMessage(CC.translate("&cYou must be holding an item to set the chance!"));
return;
}
List<String> lore = meta.getLore();
if (lore == null) {
lore = Lists.newArrayList();
}
lore.add(0, CC.translate("&7Obligatory"));
meta.setLore(lore);
itemStack.setItemMeta(meta);
player.sendMessage(CC.translate("&aSuccessfully set obligatory for &e" + itemStack.getType().name()));
}
@Command(names = {"reward addcommand"}, permission = "PLATFORMADMINISTRATOR")
public static void setcommand(Player player, @Param(name = "command", wildcard = true) String command) {
ItemStack itemStack = player.getItemInHand();
if (itemStack == null) {
player.sendMessage(CC.translate("&cYou must be holding an item to set the chance!"));
return;
}
ItemMeta meta = itemStack.getItemMeta();
if (meta == null) {
player.sendMessage(CC.translate("&cYou must be holding an item to set the chance!"));
return;
}
List<String> lore = meta.getLore();
if (lore == null) {
lore = Lists.newArrayList();
}
lore.add(0, CC.translate("&7Command:&a " + command));
meta.setLore(lore);
itemStack.setItemMeta(meta);
player.sendMessage(CC.translate("&aSuccessfully added command for &e" + itemStack.getType().name()));
}
}

View File

@ -0,0 +1,113 @@
package rip.battle.crates.reward.menus;
import cc.stormworth.core.kt.util.ItemBuilder;
import cc.stormworth.core.menu.Button;
import cc.stormworth.core.menu.Menu;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.reward.Reward;
import rip.battle.crates.reward.RewardType;
import rip.battle.crates.reward.promt.RewardAddCommandPrompt;
import rip.battle.crates.utils.ChatUtils;
public class RewardCommandsMenu extends Menu {
private final Reward reward;
private final Crate crate;
public RewardCommandsMenu(Reward reward, Crate crate) {
this.reward = reward;
this.crate = crate;
setUpdateAfterClick(true);
}
@Override
public String getTitle(Player player) {
return ChatColor.GREEN + "Manage commands";
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
buttons.put(getSlot(0, 0), Button.fromItem(
new ItemBuilder(Material.BED)
.name("&cGo Back")
.addToLore(
"",
"&7Click to go back to the reward edit menu."
).build(),
(other) -> {
if(reward.getCommands().isEmpty()) {
reward.setType(RewardType.ITEMS);
}
new RewardEditMenu(reward, crate).openMenu(other);
}));
if(reward.getCommands().isEmpty()) {
buttons.put(getSlot(4, 0), Button.fromItem(
new ItemBuilder(Material.PAPER)
.name("&bAdd Command")
.addToLore(
"",
"&7Click add command to reward."
).build(),
(other) -> ChatUtils.beginPrompt(player, new RewardAddCommandPrompt(reward, crate, new RewardCommandsMenu(reward, crate)))));
}
int slot = 9;
for (String command : reward.getCommands()) {
buttons.put(slot, new CommandButton(command));
}
return buttons;
}
@RequiredArgsConstructor
public class CommandButton extends Button{
private final String command;
@Override
public String getName(Player player) {
return ChatColor.GOLD + command;
}
@Override
public List<String> getDescription(Player player) {
return Lists.newArrayList(
"",
"&fLeft Click to edit command",
"&fRight Click to remove command"
);
}
@Override
public Material getMaterial(Player player) {
return Material.PAPER;
}
@Override
public void clicked(Player player, int slot, ClickType clickType) {
reward.getCommands().remove(command);
if (clickType == ClickType.LEFT) {
ChatUtils.beginPrompt(player, new RewardAddCommandPrompt(reward, crate, new RewardCommandsMenu(reward, crate)));
} else if (clickType == ClickType.RIGHT) {
Button.playNeutral(player);
}
}
}
}

View File

@ -0,0 +1,143 @@
package rip.battle.crates.reward.menus;
import cc.stormworth.core.kt.util.ItemBuilder;
import cc.stormworth.core.menu.Button;
import cc.stormworth.core.menu.Menu;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import rip.battle.crates.Crates;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.crate.menus.CrateBroadcastMenu;
import rip.battle.crates.misterybox.MysteryBox;
import rip.battle.crates.reward.Reward;
import rip.battle.crates.reward.promt.RewardAddCommandPrompt;
import rip.battle.crates.reward.promt.RewardSetChancePrompt;
import rip.battle.crates.utils.ChatUtils;
@RequiredArgsConstructor
public class RewardEditMenu extends Menu {
private final Reward reward;
private final Crate crate;
@Override
public String getTitle(Player player) {
return "&eEditing reward...";
}
@Override
public int size(Map<Integer, Button> buttons) {
return 3 * 9;
}
@Override
public void onClose(Player player) {
if (player.hasMetadata("closeByRightClick")) {
player.removeMetadata("closeByRightClick", Crates.getInstance());
}
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
buttons.put(getSlot(0, 0), Button.fromItem(
new ItemBuilder(Material.BED)
.name("&cGo Back")
.addToLore(
"",
"&7Click to go back to the reward edit menu."
).build(),
(other) -> {
other.closeInventory();
crate.openEditRewardsInventory(other);
}));
buttons.put(getSlot(2, 1), Button.fromItem(
new ItemBuilder(Material.EXP_BOTTLE)
.name("&bSet Chance")
.addToLore(
"",
"&7Click to set the chance of this reward",
"",
"&7Current chance: &a" + reward.getChance() + "%"
).build(),
(other) -> ChatUtils.beginPrompt(other, new RewardSetChancePrompt(reward, crate))
));
if(crate instanceof MysteryBox){
MysteryBox box = (MysteryBox) crate;
buttons.put(getSlot(4, 1), Button.fromItem(
new ItemBuilder(Material.ANVIL)
.name(box.getObligatoryRewards().contains(reward) ? "&aObligatory" : "&cObligatory")
.addToLore(
"",
(box.getObligatoryRewards().contains(reward) ? "&cClick to unset" : "&aClick to set") + " &7as an obligatory reward"
).build(),
(other) -> {
if(box.getObligatoryRewards().contains(reward)){
box.getObligatoryRewards().remove(reward);
box.getRewards().add(reward);
}else{
box.getObligatoryRewards().add(reward);
box.getRewards().remove(reward);
}
Button.playNeutral(other);
}
));
}
buttons.put(getSlot(6, 1), new CommandButtons());
buttons.put(getSlot(4, 2),
Button.fromItem(new ItemBuilder(Material.PAPER)
.name("&6Broadcast Lines")
.addToLore("",
"&7Click to view broadcast lines").build(),
(other) -> new CrateBroadcastMenu(crate, reward).openMenu(other)));
return buttons;
}
public class CommandButtons extends Button{
@Override
public String getName(Player player) {
return "&bCommands";
}
@Override
public List<String> getDescription(Player player) {
return Lists.newArrayList(
"",
"&fLeft Click to add a command to this reward",
"&fRight Click to manage commands",
"",
"&7Current Commands: &a" + (reward.getCommands() == null
|| reward.getCommands().isEmpty() ? "None" : Arrays.toString(reward.getCommands().toArray()))
);
}
@Override
public Material getMaterial(Player player) {
return Material.BOOK;
}
@Override
public void clicked(Player player, int slot, ClickType clickType) {
if(clickType == ClickType.LEFT){
ChatUtils.beginPrompt(player, new RewardAddCommandPrompt(reward, crate, new RewardEditMenu(reward, crate)));
}else{
new RewardCommandsMenu(reward, crate).openMenu(player);
}
}
}
}

View File

@ -0,0 +1,50 @@
package rip.battle.crates.reward.promt;
import cc.stormworth.core.menu.Menu;
import cc.stormworth.core.util.chat.CC;
import lombok.RequiredArgsConstructor;
import net.minecraft.util.com.google.common.collect.Lists;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.reward.Reward;
import rip.battle.crates.reward.menus.RewardEditMenu;
import rip.battle.crates.reward.RewardType;
@RequiredArgsConstructor
public class RewardAddCommandPrompt extends StringPrompt {
private final Reward reward;
private final Crate crate;
private final Menu menu;
@Override
public String getPromptText(ConversationContext context) {
return CC.translate("&7Enter the command you want to add. Or type &6cancel&7 to go back.");
}
@Override
public Prompt acceptInput(ConversationContext context, String input) {
Player player = (Player) context.getForWhom();
if (input.equalsIgnoreCase("cancel")) {
new RewardEditMenu(reward, crate).openMenu(player);
return END_OF_CONVERSATION;
}
reward.setType(RewardType.COMMAND);
if(reward.getCommands() == null) {
reward.setCommands(Lists.newArrayList());
}
reward.getCommands().add(input);
menu.openMenu(player);
player.sendMessage(CC.translate("&aCommand &e" + input + "&e has been added to the reward."));
return END_OF_CONVERSATION;
}
}

View File

@ -0,0 +1,55 @@
package rip.battle.crates.reward.promt;
import cc.stormworth.core.util.chat.CC;
import lombok.RequiredArgsConstructor;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import rip.battle.crates.crate.Crate;
import rip.battle.crates.reward.Reward;
import rip.battle.crates.reward.menus.RewardEditMenu;
@RequiredArgsConstructor
public class RewardSetChancePrompt extends StringPrompt {
private final Reward reward;
private final Crate crate;
@Override
public String getPromptText(ConversationContext context) {
return CC.translate("&7Set the chance of this reward to be given. Or type &6cancel &7to go back.");
}
@Override
public Prompt acceptInput(ConversationContext context, String input) {
Player player = (Player) context.getForWhom();
if (input.equalsIgnoreCase("cancel")) {
new RewardEditMenu(reward, crate).openMenu(player);
return END_OF_CONVERSATION;
}
try {
double chance = Double.parseDouble(input);
if (chance < 0 || chance > 1.0) {
player.sendMessage(CC.translate("&cThe chance must be between 0 and 1.0."));
return this;
}
reward.setChance(chance);
player.sendMessage(CC.translate("&aThe chance of this reward is now &6" + chance + "&a%."));
new RewardEditMenu(reward, crate).openMenu(player);
} catch (NumberFormatException e) {
player.sendMessage(CC.translate("&cThe chance must be a number between 0 and 100."));
return this;
}
return END_OF_CONVERSATION;
}
}

View File

@ -0,0 +1,39 @@
package rip.battle.crates.supplydrop;
import cc.stormworth.core.kt.util.ItemBuilder;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import rip.battle.crates.crate.Crate;
import java.util.Arrays;
import java.util.List;
public class SupplyDrop extends Crate {
public SupplyDrop() {
super("SupplyDrop");
getCrates().put("SupplyDrop", this);
}
@Override
public List<String> getHologramsLines() {
return Arrays.asList(
getDisplayName() + " SupplyDrop",
"&7",
"&fLeft click &7for preview rewards",
"&7",
"&7&ostore.battle.rip");
}
@Override
public ItemStack generateKey() {
return new ItemBuilder(Material.DROPPER)
.name("&4&lSupplyDrop")
.addToLore(
"&7Purchasable at &fstore.battle.rip&7.",
""
).build();
}
}

View File

@ -0,0 +1,28 @@
package rip.battle.crates.utils;
import lombok.experimental.UtilityClass;
import org.bukkit.ChatColor;
import org.bukkit.conversations.ConversationFactory;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import rip.battle.crates.Crates;
@UtilityClass
public class ChatUtils {
public void beginPrompt(Player player, StringPrompt prompt) {
player.closeInventory();
player.beginConversation(
new ConversationFactory(Crates.getInstance())
.withFirstPrompt(prompt)
.withTimeout(60)
.withModality(false)
.withLocalEcho(false)
.buildConversation(player));
}
public String getFirstColor(String message) {
return ChatColor.translateAlternateColorCodes('&', message.substring(0, 2));
}
}

View File

@ -0,0 +1,114 @@
package rip.battle.crates.utils;
import org.bukkit.Color;
import org.bukkit.FireworkEffect;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_7_R4.entity.CraftFirework;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Firework;
import org.bukkit.inventory.meta.FireworkMeta;
import java.util.Random;
public class FireworkUtil {
public static void launchFirework(Location loc) {
Firework fw = (Firework) loc.getWorld().spawnEntity(loc, EntityType.FIREWORK);
FireworkMeta fwm = fw.getFireworkMeta();
Random random = RandomUtils.getRandom();
int randomInt = random.nextInt(4) + 1;
FireworkEffect.Type type;
if (randomInt == 1) {
type = FireworkEffect.Type.BALL;
} else if (randomInt == 2) {
type = FireworkEffect.Type.BALL_LARGE;
} else if (randomInt == 3) {
type = FireworkEffect.Type.BURST;
} else {
type = FireworkEffect.Type.STAR;
}
int r1i = random.nextInt(17) + 1;
int r2i = random.nextInt(17) + 1;
Color c1 = getColor(r1i);
Color c2 = getColor(r2i);
FireworkEffect effect = FireworkEffect.builder()
.flicker(random.nextBoolean())
.withColor(c1)
.withFade(c2).with(type).trail(random.nextBoolean()).build();
fwm.addEffect(effect);
fwm.setPower(3);
((CraftFirework) fw).getHandle().expectedLifespan = 5;
fw.setFireworkMeta(fwm);
}
public static Color getColor(int i) {
Color color = null;
switch (i) {
case 1:
color = Color.AQUA;
break;
case 2:
color = Color.BLACK;
break;
case 3:
color = Color.BLUE;
break;
case 4:
color = Color.FUCHSIA;
break;
case 5:
color = Color.GRAY;
break;
case 6:
color = Color.GREEN;
break;
case 7:
color = Color.LIME;
break;
case 8:
color = Color.MAROON;
break;
case 9:
color = Color.NAVY;
break;
case 10:
color = Color.OLIVE;
break;
case 11:
color = Color.ORANGE;
break;
case 12:
color = Color.PURPLE;
break;
case 13:
color = Color.RED;
break;
case 14:
color = Color.SILVER;
break;
case 15:
color = Color.TEAL;
break;
case 16:
color = Color.WHITE;
break;
case 17:
color = Color.YELLOW;
break;
default:
break;
}
return color;
}
}

View File

@ -0,0 +1,148 @@
package rip.battle.crates.utils;
import cc.stormworth.core.util.chat.CC;
import com.google.common.collect.Lists;
import lombok.experimental.UtilityClass;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import rip.battle.crates.reward.Reward;
import rip.battle.crates.reward.RewardType;
import java.util.List;
@UtilityClass
public class ItemUtils {
public boolean isReward(ItemStack item) {
if (item == null) return false;
if (!item.hasItemMeta()) return false;
if (!item.getItemMeta().hasLore()) return false;
return item.getItemMeta().getLore().stream().anyMatch(lore -> lore.contains(CC.translate("&7Type: &e")));
}
public void consume(Player player) {
ItemStack item = player.getInventory().getItemInHand();
if (item.getAmount() == 1) {
player.getInventory().remove(item);
} else {
item.setAmount(item.getAmount() - 1);
}
player.updateInventory();
}
public RewardType getRewardType(ItemStack item) {
if (!isReward(item)) return null;
for (String lore : item.getItemMeta().getLore()) {
if (lore.contains(CC.translate("&7Type: &e"))) {
return RewardType.getByName(ChatColor.stripColor(lore).replace(CC.translate("Type: "), "").toUpperCase());
}
}
return null;
}
public Reward getRewardByItem(ItemStack item, int slot) {
if (!isReward(item)) return null;
RewardType type = getRewardType(item);
if (type == null) return null;
double chance = getChance(item);
List<String> commands = Lists.newArrayList();
if (type == RewardType.COMMAND) {
commands.addAll(getCommands(item));
}
return new Reward(item, chance, slot, type, commands, isObligatory(item));
}
public void removeRewardsLore(ItemStack item) {
ItemMeta meta = item.getItemMeta();
if (meta == null) return;
List<String> lore = meta.getLore();
if (lore == null) return;
lore.removeIf(line -> line.contains(CC.translate("&7Type: &e")));
lore.removeIf(line -> line.contains(CC.translate("&7Chance: &e")));
lore.removeIf(line -> line.contains(CC.translate("&cObligatory")));
lore.removeIf(line -> line.contains(CC.translate("&7Commands: &e")));
lore.removeIf(line -> line.contains(CC.translate("&fRight Click &7to edit")));
lore.removeIf(line -> line.equalsIgnoreCase(CC.translate("&0")));
meta.setLore(lore);
item.setItemMeta(meta);
}
public double getChance(ItemStack item) {
if (!isReward(item)) return 0;
for (String lore : item.getItemMeta().getLore()) {
if (lore.contains(CC.translate("&7Chance: &e"))) {
return Double.parseDouble(ChatColor.stripColor(lore).replace(CC.translate("Chance: "), "").replace("%", ""));
}
}
return 0;
}
public boolean isObligatory(ItemStack item) {
if (item == null) return false;
if (!item.hasItemMeta()) return false;
if (!item.getItemMeta().hasLore()) return false;
return item.getItemMeta().getLore().stream().anyMatch(lore -> lore.contains(CC.translate("&cObligatory")));
}
public boolean isCommandType(ItemStack item) {
if (item == null) return false;
if (!item.hasItemMeta()) return false;
if (!item.getItemMeta().hasLore()) return false;
return item.getItemMeta().getLore().stream().anyMatch(lore -> lore.contains(CC.translate("&7Commands: &e")));
}
public List<String> getCommands(ItemStack item) {
if (!isCommandType(item)) return null;
List<String> commands = Lists.newArrayList();
for (String lore : item.getItemMeta().getLore()) {
if (lore.contains(CC.translate(" &7- &f"))) {
commands.add(ChatColor.stripColor(lore).replace(CC.translate(" - "), ""));
}
}
return commands;
}
public boolean isAirDrop(ItemStack item) {
if (item == null) return false;
if (!item.hasItemMeta()) return false;
if (!item.getItemMeta().hasLore()) return false;
if (item.getItemMeta().getDisplayName() == null) return false;
return item.getItemMeta().getDisplayName().equalsIgnoreCase(CC.translate("&6&lAirdrop"));
}
}

View File

@ -0,0 +1,45 @@
package rip.battle.crates.utils;
import lombok.Getter;
import lombok.experimental.UtilityClass;
import rip.battle.crates.reward.Reward;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
@UtilityClass
public class RandomUtils {
@Getter
private static final Random random = ThreadLocalRandom.current();
public double getDouble(double min, double max) {
return min + (max - min) * random.nextDouble();
}
public Reward getRandomReward(List<Reward> list) {
list.removeIf(reward -> reward.getChance() <= 0D);
if (list.isEmpty()) return null;
Reward reward = null;
double total = list.stream().mapToDouble(Reward::getChance).sum();
double index = getDouble(0D, total);
double countWeight = 0D;
for (Reward reward1 : list) {
countWeight += reward1.getChance();
if (countWeight >= index) {
reward = reward1;
break;
}
}
return reward;
}
}

View File

@ -0,0 +1,8 @@
mongo:
host: localhost
port: 27017
database: "battlerip"
authentication:
enabled: false
username: "admin"
password: "admin"

View File

@ -0,0 +1,6 @@
main: rip.battle.crates.Crates
name: Crates
version: 1.0.0
author: EnzoL_
depend:
- Core

70
BattleEntity-main/.gitignore vendored Normal file
View File

@ -0,0 +1,70 @@
# Eclipse
/.classpath
/.project
/.settings
# Netbeans
/nbproject
# Fuck mauri!
/build.xml
# Maven
/target
/dependency-reduced-pom.xml
*/target
*/dependency-reduced-pom.xml
# Vim
.*.sw[a-p]
# Various other potential build files
/build
/bin
/dist
/manifest.mf
/MANIFEST.MF
/META-INF/MANIFEST.MF
git.properties
.ssh
key
commiter.sh
key.pub
dependency-reduced-pom.xml
# Mac Filesystem Dust
.DS_Store
# IntelliJ IDEA
*.iml
*.ipr
*.iws
.idea/
#Libraries jar files
libraries/*.jar
=======
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
out

66
BattleEntity-main/pom.xml Normal file
View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>rip.battle.entity</groupId>
<artifactId>BattleEntity</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<finalName>BattleEntity</finalName>
</build>
<repositories>
<repository>
<id>viaversion-repo</id>
<url>https://repo.viaversion.com</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>rip.battle.spigot</groupId>
<artifactId>battle-server</artifactId>
<version>1.8.8-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<artifactId>BattleAPI</artifactId>
<groupId>cc.stormworth</groupId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<artifactId>BattleBukkit</artifactId>
<groupId>cc.stormworth</groupId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.viaversion</groupId>
<artifactId>viaversion-api</artifactId>
<version>LATEST</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,272 @@
package rip.battle.entity;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.server.v1_8_R3.PacketPlayOutAnimation;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityDestroy;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityStatus;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.utils.AngleUtils;
import rip.battle.entity.utils.PacketUtils;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@Getter @Setter
public abstract class Entity {
private static int ENTITY_ID = -1337;
private final int id;
private final UUID uuid;
private Location location;
private boolean initialized = false;
private boolean hidden = false;
private boolean persistent = true;
private boolean root = true;
private Set<UUID> currentWatchers = Sets.newHashSet();
private Set<UUID> hiddeFor = Sets.newHashSet();
private Set<String> commands = Sets.newHashSet();
private Consumer<Player> onLeftClick;
private Consumer<Player> onRightClick;
public Entity(Location location) {
this.id = nextId();
this.location = location;
this.uuid = UUID.randomUUID();
EntityManager.addEntity(this);
}
public abstract String getTypeName();
public void initializeData() {
this.initialized = true;
}
public void onDelete(){
destroyForCurrentWatchers();
EntityManager.removeEntity(this);
}
public void updateLocation(Location location) {
this.location = location;
getCurrentWatchersPlayers().forEach(this::sendRePositionPackets);
}
public Hologram getAttachedHologram(){ //Add HologramEntity
return null;
}
public boolean isVisible() {
return !hidden;
}
public boolean isVisibleTo(Player player) {
return !hidden && location.getWorld() == player.getWorld() && location.distance(player.getLocation()) <= 32.0 && !hiddeFor.contains(player.getUniqueId());
}
public void updateVisibility(boolean hidden){
boolean hasChanged = this.hidden != hidden;
this.hidden = hidden;
if(hasChanged){
if(hidden){
destroyForCurrentWatchers();
}else{
Bukkit.getOnlinePlayers().forEach(player -> {
if (!currentWatchers.contains(player.getUniqueId()) && isVisibleTo(player)) {
currentWatchers.add(player.getUniqueId());
}
});
spawnForCurrentWatchers();
}
}
if (getAttachedHologram() != null) {
getAttachedHologram().updateVisibility(hidden);
}
}
public void updateVisibilityFor(Player player, boolean hidden) {
boolean hasChanged = currentWatchers.contains(player.getUniqueId()) != hidden;
if(hasChanged){
if(hidden){
hiddeFor.add(player.getUniqueId());
currentWatchers.remove(player.getUniqueId());
}else{
currentWatchers.add(player.getUniqueId());
}
if(hidden) {
sendDestroyPackets(player);
}else {
sendSpawnPackets(player);
}
if (getAttachedHologram() != null) {
getAttachedHologram().updateVisibilityFor(player, hidden);
}
}
}
public void spawnForCurrentWatchers() {
getCurrentWatchersPlayers().stream().filter(this::isVisibleTo).forEach(this::sendSpawnPackets);
}
public void onLeftClick(Player player) {
if (!commands.isEmpty()) {
for (String command : commands) {
player.performCommand(command.replace("{player}", player.getName()));
}
}else if (onLeftClick != null) {
onLeftClick.accept(player);
}
}
public void onRightClick(Player player) {
if (onRightClick != null) {
onRightClick.accept(player);
}
}
public void spawn(){
Bukkit.getOnlinePlayers().forEach(player -> {
if(isVisibleTo(player)){
spawn(player);
}
});
}
public boolean isDamageable() {
return false;
}
public void spawn(Player player){
/*if (currentWatchers.contains(player.getUniqueId())) {
return;
}*/
currentWatchers.add(player.getUniqueId());
sendSpawnPackets(player);
sendUpdatePackets(player);
}
public void update(Player player){
if (!currentWatchers.contains(player.getUniqueId())) {
return;
}
sendUpdatePackets(player);
}
public void destroy(Player player) {
currentWatchers.remove(player.getUniqueId());
sendDestroyPackets(player);
}
public boolean hasAnyWatchers() {
return currentWatchers.size() > 0;
}
public List<Player> getCurrentWatchersPlayers() {
return currentWatchers.stream().map(Bukkit::getPlayer).filter(Objects::nonNull).collect(Collectors.toList());
}
public boolean isWatcher(Player player){
return currentWatchers.contains(player.getUniqueId());
}
public void updateForCurrentWatchers() {
for (Player player : getCurrentWatchersPlayers()) {
update(player);
}
}
public void destroyForCurrentWatchers() {
for (Player player : getCurrentWatchersPlayers()) {
sendDestroyPackets(player);
}
}
public void resendForCurrentWatchers() {
for (Player player : getCurrentWatchersPlayers()) {
destroy(player);
spawn(player);
}
}
public boolean isMultiPartEntity(){
return false;
}
public boolean isRootOfMultiPartEntity(){
return root;
}
public void sendSpawnPackets(Player player) {}
public void sendDestroyPackets(Player player) {
PacketUtils.sendPacket(player, new PacketPlayOutEntityDestroy(id));
}
public void sendUpdatePackets(Player player) {}
public void sendRePositionPackets(Player player) {
PacketPlayOutEntityTeleport playOutEntityTeleport = new PacketPlayOutEntityTeleport(
this.id,
(int) (this.location.getX() * 32.0D),
(int) (this.location.getY() * 32.0D),
(int) (this.location.getZ() * 32.0D),
AngleUtils.yawToBytes(location.getYaw()),
AngleUtils.yawToBytes(location.getPitch()),
false
);
PacketUtils.sendPacket(player, playOutEntityTeleport);
}
public void sendStatusPacket(byte status){
PacketPlayOutEntityStatus packet = new PacketPlayOutEntityStatus(id, status);
PacketUtils.sendPacket(getCurrentWatchersPlayers(), packet);
}
public void sendAnimationPacket(int animation){
PacketPlayOutAnimation packet = new PacketPlayOutAnimation(id, animation);
PacketUtils.sendPacket(getCurrentWatchersPlayers(), packet);
}
public static int nextId() {
return ENTITY_ID--;
}
}

View File

@ -0,0 +1,24 @@
package rip.battle.entity;
import com.google.common.collect.Maps;
import lombok.Getter;
import java.util.Map;
public class EntityManager {
@Getter private static final Map<Integer, Entity> entities = Maps.newHashMap();
public static void addEntity(Entity entity) {
entities.put(entity.getId(), entity);
}
public static void removeEntity(Entity entity) {
entities.remove(entity.getId());
}
public static Entity getEntity(int id) {
return entities.get(id);
}
}

View File

@ -0,0 +1,114 @@
package rip.battle.entity;
import cc.stormworth.core.api.BattleAPI;
import com.jonahseguin.drink.CommandService;
import com.jonahseguin.drink.Drink;
import com.jonahseguin.drink.command.DrinkCommandContainer;
import lombok.Getter;
import net.minecraft.server.v1_8_R3.PacketPlayInUseEntity;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.commands.HologramCommand;
import rip.battle.entity.hologram.commands.sub.*;
import rip.battle.entity.hologram.runnable.HologramUpdateRunnable;
import rip.battle.entity.listeners.PlayerListener;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.commands.NPCCommand;
import rip.battle.entity.npc.commands.sub.*;
import rip.battle.entity.packet.PacketEntityUseAdapter;
import rip.battle.entity.taks.RainbowTask;
import rip.battle.entity.task.EntityVisibilityRunnable;
import rip.battle.entity.tick.TickableEntity;
@Getter
public class EntityPlugin extends JavaPlugin {
private HologramManager hologramManager;
private NPCManager npcManager;
private BattleAPI battleAPI;
@Override
public void onEnable() {
registerManagers();
registerListeners();
registerCommands();
registerRunnables();
}
@Override
public void onDisable() {
hologramManager.saveHolograms();
npcManager.saveNPCs();
}
private void registerManagers(){
hologramManager = new HologramManager(this);
npcManager = new NPCManager(this);
battleAPI = BattleAPI.getBattleAPI(this);
}
private void registerRunnables(){
getServer().getScheduler().runTaskTimerAsynchronously(this, new HologramUpdateRunnable(hologramManager), 0L, 1L);
getServer().getScheduler().runTaskTimerAsynchronously(this, new RainbowTask(), 0L, 1L);
getServer().getScheduler().runTaskTimer(this, new EntityVisibilityRunnable(), 0L, 20L);
getServer().getScheduler().runTaskTimerAsynchronously(this, () -> {
for (Entity entity : EntityManager.getEntities().values()) {
if (entity instanceof TickableEntity){
TickableEntity livingEntity = (TickableEntity) entity;
livingEntity.tick();
}
}
}, 0L, 1L);
}
private void registerCommands(){
CommandService drink = Drink.get(this);
DrinkCommandContainer hologramContainer = drink.register(new HologramCommand(), "hologram");
hologramContainer.registerSub(new HologramCreateSubCommand(hologramManager));
hologramContainer.registerSub(new HologramDeleteSubCommand(hologramManager));
hologramContainer.registerSub(new HologramAddLineSubCommand(hologramManager));
hologramContainer.registerSub(new HologramAddItemLineSubCommand(hologramManager));
hologramContainer.registerSub(new HologramTeleportSubCommand(hologramManager));
hologramContainer.registerSub(new HologramMoveHereSubCommand(hologramManager));
hologramContainer.registerSub(new HologramSetLineSubCommand(hologramManager));
hologramContainer.registerSub(new HologramSetItemLineSubCommand(hologramManager));
hologramContainer.registerSub(new HologramListSubCommand(hologramManager));
hologramContainer.registerSub(new HologramRemoveLineSubCommand(hologramManager));
hologramContainer.registerSub(new HologramEditSubCommand(this, hologramManager));
DrinkCommandContainer npcContainer = drink.register(new NPCCommand(), "npc");
npcContainer.registerSub(new NPCCreateSubCommand(npcManager));
npcContainer.registerSub(new NPCDeleteSubCommand(npcManager));
npcContainer.registerSub(new NPCSetDisplaynameSubCommand(npcManager));
npcContainer.registerSub(new NPCSetSkinSubCommand(npcManager));
npcContainer.registerSub(new NPCSetArmorSubCommand(npcManager));
npcContainer.registerSub(new NPCAddItemLineSubCommand(npcManager));
npcContainer.registerSub(new NPCAddLineSubCommand(npcManager));
npcContainer.registerSub(new NPCMoveHereSubCommand(npcManager));
npcContainer.registerSub(new NPCTeleportSubCommand(npcManager));
npcContainer.registerSub(new NPCRemoveLineSubCommand(npcManager));
npcContainer.registerSub(new NPCSetLineSubCommand(npcManager));
npcContainer.registerSub(new NPCSetItemInHandSubCommand(npcManager));
npcContainer.registerSub(new NPCSetHelmetSubCommand(npcManager));
npcContainer.registerSub(new NPCSetChestPlateSubCommand(npcManager));
npcContainer.registerSub(new NPCSetLeggingsSubCommand(npcManager));
npcContainer.registerSub(new NPCSetBootsSubCommand(npcManager));
npcContainer.registerSub(new NPCListCommand(npcManager));
npcContainer.registerSub(new NPCEditSubCommand(this, npcManager));
drink.registerCommands();
}
private void registerListeners(){
battleAPI.registerAdapter(PacketPlayInUseEntity.class, new PacketEntityUseAdapter(this));
PluginManager pluginManager = getServer().getPluginManager();
pluginManager.registerEvents(new PlayerListener(), this);
}
}

View File

@ -0,0 +1,308 @@
package rip.battle.entity.hologram;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.Entity;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.hologram.lines.HologramLine;
import rip.battle.entity.hologram.lines.impl.ItemLine;
import rip.battle.entity.hologram.lines.impl.MultipleTextLine;
import rip.battle.entity.hologram.lines.impl.SupplierMultipleTextLine;
import rip.battle.entity.hologram.lines.impl.TextLine;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@Getter
public class CraftHologram implements Hologram {
private final List<HologramLine<?>> lines = Lists.newArrayList();
private Location location;
private final Set<UUID> currentWatchers = Sets.newHashSet();
private final Set<UUID> hiddenPlayers = Sets.newHashSet();
private boolean hidden;
private Entity parent;
private String name;
public CraftHologram(String name, String line, Location location) {
this.name = name;
this.location = location;
addLine(line);
}
public CraftHologram(String name, ItemStack line, Location location) {
this.name = name;
this.location = location;
addLine(line);
}
public CraftHologram(String name, Location location) {
this.location = location;
this.name = name;
}
public boolean isVisible() {
return !hidden;
}
public boolean isVisibleTo(Player player) {
return !hidden && location.getWorld() == player.getWorld() && location.distance(player.getLocation()) <= 32.0 && !hiddenPlayers.contains(player.getUniqueId());
}
@Override
public void destroy() {
onDelete();
}
@Override
public void spawn() {
Bukkit.getOnlinePlayers().forEach(player -> {
if (isVisibleTo(player)) {
lines.forEach(line -> line.spawn(player));
currentWatchers.add(player.getUniqueId());
}
});
}
public void spawnFor(Player player) {
lines.forEach(line -> line.spawn(player));
currentWatchers.add(player.getUniqueId());
}
public void updateVisibility(boolean hidden){
boolean hasChanged = this.hidden != hidden;
this.hidden = hidden;
if(hasChanged){
lines.forEach(line -> line.updateVisibility(hidden));
}
}
@Override
public void updateVisibilityFor(Player player, boolean hidden) {
boolean hasChanged = currentWatchers.contains(player.getUniqueId()) != hidden;
if(hasChanged){
if(hidden){
hiddenPlayers.add(player.getUniqueId());
currentWatchers.remove(player.getUniqueId());
}else{
currentWatchers.add(player.getUniqueId());
}
lines.forEach(line -> {
if (line.isVisibleTo(player)) {
line.sendSpawnPackets(player);
}else{
line.sendDestroyPackets(player);
}
});
}
}
public List<Player> getCurrentWatchersPlayers() {
return currentWatchers.stream().map(Bukkit::getPlayer).filter(Objects::nonNull).collect(Collectors.toList());
}
public boolean isWatcher(Player player){
return currentWatchers.contains(player.getUniqueId());
}
protected void updateForCurrentWatchers() {
lines.forEach(Entity::updateForCurrentWatchers);
}
public void onDelete() {
lines.forEach(HologramLine::onDelete);
lines.clear();
currentWatchers.clear();
}
public void updateLocation(Location location){
this.location = location;
synchronizeLocations();
}
public void addLine(HologramLine<?> line) {
getCurrentWatchersPlayers().forEach(line::spawn);
lines.add(line);
synchronizeLocations();
}
@Override
public void addLine(String text){
addLine(player -> text);
}
@Override
public void addLine(Function<CommandSender, String> line) {
addLine(line, null);
}
@Override
public void addLines(List<Function<CommandSender, String>> lines) {
lines.forEach(this::addLine);
}
@Override
public void addLines(Function<CommandSender, List<String>> lines) {
addLine(new MultipleTextLine(this, this.location.clone(), lines));
}
@Override
public void addSupplierLines(Function<CommandSender, Supplier<List<String>>> lines) {
addLine(new SupplierMultipleTextLine(this, this.location.clone(), lines));
}
@Override
public void addLine(Function<CommandSender, String> line, Consumer<Player> onClick) {
addLine(line, onClick, player -> true);
}
@Override
public void addLine(Function<CommandSender, String> line, Consumer<Player> onClick, Predicate<Player> shouldSend) {
addLine(new TextLine(this, this.location.clone().subtract(0, 0.25, 0), line, onClick, shouldSend));
}
@Override
public void addLine(ItemStack itemStack){
addLine(itemStack, null);
}
@Override
public void addLine(ItemStack line, Consumer<Player> onClick) {
addLine(line, onClick, player -> true);
}
@Override
public void addLine(ItemStack line, Consumer<Player> onClick, Predicate<Player> shouldSend) {
addLine(new ItemLine(this, this.location.clone().subtract(0, 0.25, 0), line, onClick, shouldSend));
}
@Override
public void setLine(int line, String text) {
setLine(line, player -> text);
}
@Override
public void setLine(int line, Function<CommandSender, String> text) {
setLine(line, text, null);
}
@Override
public void setLine(int line, Function<CommandSender, String> text, Consumer<Player> onClick) {
setLine(line, text, onClick, player -> true);
}
@Override
public void setLine(int line, Function<CommandSender, String> text, Consumer<Player> onClick, Predicate<Player> shouldSend) {
HologramLine<?> hologramLine = lines.get(line);
if(hologramLine instanceof TextLine){
TextLine textLine = (TextLine) hologramLine;
textLine.setText(text);
textLine.setOnLeftClick(onClick);
textLine.setShouldSend(shouldSend);
textLine.updateForCurrentWatchers();
}
}
@Override
public void setLine(int line, ItemStack itemStack) {
setLine(line, itemStack, null);
}
@Override
public void setLine(int line, ItemStack itemStack, Consumer<Player> onClick) {
setLine(line, itemStack, onClick, player -> true);
}
@Override
public void setLine(int line, ItemStack itemStack, Consumer<Player> onClick, Predicate<Player> shouldSend) {
HologramLine<?> hologramLine = lines.get(line);
if(hologramLine instanceof ItemLine){
ItemLine itemLine = (ItemLine) hologramLine;
itemLine.setItemStack(itemStack);
itemLine.setOnLeftClick(onClick);
itemLine.setShouldSend(shouldSend);
itemLine.updateForCurrentWatchers();
}
}
@Override
public void removeLine(HologramLine<?> line) {
lines.remove(line);
getCurrentWatchersPlayers().forEach(line::destroy);
}
@Override
public void removeLine(int index) {
removeLine(lines.remove(index));
}
@Override
public void teleport(Location location) {
updateLocation(location);
}
public void clearLines() {
getCurrentWatchersPlayers().forEach(player -> {
for (HologramLine<?> line : lines) {
line.sendDestroyPackets(player);
}
});
lines.clear();
}
protected void synchronizeLocations(){
Location startLocation = location.clone().add(0, lines.size() * 0.25, 0);
for (HologramLine<?> line : lines) {
if (line instanceof ItemLine){
startLocation.subtract(0, 0.25, 0);
line.updateLocation(startLocation.clone().add(0.0, 0.5, 0.0));
startLocation.subtract(0, 0.5, 0);
}if (line instanceof TextLine) {
line.updateLocation(startLocation.clone());
startLocation.subtract(0, 0.25, 0);
}else if (line instanceof MultipleTextLine){
MultipleTextLine multipleTextLine = (MultipleTextLine) line;
multipleTextLine.updateLocation(startLocation.clone().add(0, 0.25, 0));
startLocation.subtract(0, 0.25 * multipleTextLine.getLines().apply(Bukkit.getConsoleSender()).size(), 0);
}
}
}
public void setParent(Entity parent) {
this.parent = parent;
}
}

View File

@ -0,0 +1,133 @@
package rip.battle.entity.hologram;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.hologram.impl.UpdatableHologram;
import rip.battle.entity.hologram.lines.HologramLine;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
public class HologramBuilder {
private final Hologram hologram;
public HologramBuilder(String name, Location location, boolean updatable) {
if (updatable) {
hologram = new UpdatableHologram(name, location) {
@Override
public int getUpdateInterval() {
return 1;
}
};
} else {
hologram = new CraftHologram(name, location);
}
}
public HologramBuilder addLine(String line) {
hologram.addLine(line);
return this;
}
public HologramBuilder addLine(ItemStack line) {
hologram.addLine(line);
return this;
}
public HologramBuilder addLine(ItemStack line, Consumer<Player> onClick) {
hologram.addLine(line, onClick);
return this;
}
public HologramBuilder addLine(ItemStack line, Consumer<Player> onClick, Predicate<Player> shouldSend) {
hologram.addLine(line, onClick, shouldSend);
return this;
}
public HologramBuilder addLine(String line, Consumer<Player> onClick) {
hologram.addLine(player -> line, onClick);
return this;
}
public HologramBuilder addLine(String line, Consumer<Player> onClick, Predicate<Player> shouldSend) {
hologram.addLine(player -> line, onClick, shouldSend);
return this;
}
public HologramBuilder addLine(Function<CommandSender, String> line, Consumer<Player> onClick, Predicate<Player> shouldSend) {
hologram.addLine(line, onClick, shouldSend);
return this;
}
public HologramBuilder addLine(Function<CommandSender, String> line, Consumer<Player> onClick) {
hologram.addLine(line, onClick);
return this;
}
public HologramBuilder addLine(Function<CommandSender, String> line) {
hologram.addLine(line);
return this;
}
public HologramBuilder removeLine(int index) {
hologram.removeLine(index);
return this;
}
public HologramBuilder removeLine(HologramLine<?> line) {
hologram.removeLine(line);
return this;
}
public HologramBuilder addLines(String... lines) {
for (String line : lines) {
hologram.addLine(line);
}
return this;
}
public HologramBuilder addLines(ItemStack... lines) {
for (ItemStack line : lines) {
hologram.addLine(line);
}
return this;
}
@SafeVarargs
public final HologramBuilder addLines(Function<CommandSender, String>... lines) {
for (Function<CommandSender, String> line : lines) {
hologram.addLine(line);
}
return this;
}
public HologramBuilder hide() {
hologram.updateVisibility(true);
return this;
}
public HologramBuilder show() {
hologram.updateVisibility(false);
return this;
}
public HologramBuilder hideFor(Player player) {
hologram.updateVisibilityFor(player, true);
return this;
}
public HologramBuilder showFor(Player player) {
hologram.updateVisibilityFor(player, false);
return this;
}
public Hologram build() {
return hologram;
}
}

View File

@ -0,0 +1,122 @@
package rip.battle.entity.hologram;
import cc.stormworth.core.util.serialize.ItemStackAdapter;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import lombok.Getter;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.hologram.impl.UpdatableHologram;
import rip.battle.entity.hologram.serialization.HologramTypeAdapter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
public class HologramManager {
@Getter private final Map<String, Hologram> holograms = Maps.newHashMap();
private final EntityPlugin plugin;
public HologramManager(EntityPlugin plugin){
this.plugin = plugin;
loadHolograms();
}
public void loadHolograms(){
File file = new File(plugin.getDataFolder(), "holograms");
if (!file.exists()){
return;
}
Arrays.stream(file.listFiles()).forEach(file1 -> {
FileReader fileReader;
try {
fileReader = new FileReader(file1);
JsonElement jsonElement = new Gson().fromJson(fileReader, JsonElement.class);
System.out.println(jsonElement.toString());
Hologram hologram = HologramTypeAdapter.fromJson(jsonElement);
holograms.put(file1.getName().replace(".json", ""), hologram);
System.out.println("Loaded hologram " + file1.getName());
System.out.println("hologram " + ((CraftHologram)hologram).getLocation());
} catch (IOException e) {
e.printStackTrace();
}
});
}
public void saveHolograms(){
Gson gson = new GsonBuilder()
.registerTypeAdapter(ItemStack.class, new ItemStackAdapter())
.registerTypeAdapter(Hologram.class, new HologramTypeAdapter())
.enableComplexMapKeySerialization()
.setPrettyPrinting()
.create();
File file = new File(plugin.getDataFolder(), "holograms");
if (!file.exists())
file.mkdirs();
holograms.forEach((name, hologram) -> {
try {
FileWriter writer = new FileWriter(new File(plugin.getDataFolder(),
File.separator + "holograms" + File.separator + name + ".json"));
writer.write(gson.toJson(HologramTypeAdapter.toJson(hologram)));
System.out.println("Saved hologram " + name);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
});
}
public void addHologram(String name, Hologram hologram) {
this.holograms.put(name, hologram);
}
public void removeHologram(String name) {
Hologram hologram = this.holograms.remove(name);
if (hologram != null) {
hologram.destroy();
}
File file = new File(plugin.getDataFolder(), "holograms" + File.separator + name + ".json");
if (file.exists())
file.delete();
}
public Hologram getHologram(String name) {
return this.holograms.get(name);
}
public void createHologram(String name, Location location) {
Hologram hologram = new UpdatableHologram(name, location);
hologram.spawn();
addHologram(name, hologram);
}
}

View File

@ -0,0 +1,74 @@
package rip.battle.entity.hologram.api;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.hologram.lines.HologramLine;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public interface Hologram {
String getName();
List<HologramLine<?>> getLines();
void addLine(String line);
void addLine(Function<CommandSender, String> line);
void addLines(List<Function<CommandSender, String>> lines);
void addLines(Function<CommandSender, List<String>> lines);
void addSupplierLines(Function<CommandSender, Supplier<List<String>>> lines);
void addLine(Function<CommandSender, String> line, Consumer<Player> onClick);
void addLine(Function<CommandSender, String> line, Consumer<Player> onClick, Predicate<Player> shouldSend);
void addLine(ItemStack line);
void addLine(ItemStack line, Consumer<Player> onClick);
void addLine(ItemStack line, Consumer<Player> onClick, Predicate<Player> shouldSend);
void setLine(int line, String text);
void setLine(int line, Function<CommandSender, String> text);
void setLine(int line, Function<CommandSender, String> text, Consumer<Player> onClick);
void setLine(int line, Function<CommandSender, String> text, Consumer<Player> onClick, Predicate<Player> shouldSend);
void setLine(int line, ItemStack itemStack);
void setLine(int line, ItemStack itemStack, Consumer<Player> onClick);
void setLine(int line, ItemStack itemStack, Consumer<Player> onClick, Predicate<Player> shouldSend);
void removeLine(HologramLine<?> line);
void removeLine(int index);
void teleport(Location location);
Location getLocation();
boolean isVisible();
void updateVisibility(boolean hidden);
void updateVisibilityFor(Player player, boolean hidden);
boolean isVisibleTo(Player player);
void destroy();
void spawn();
}

View File

@ -0,0 +1,30 @@
package rip.battle.entity.hologram.commands;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Require;
import com.jonahseguin.drink.annotation.Sender;
import org.bukkit.entity.Player;
public class HologramCommand {
@Command(name = "", desc = "Allows you to manage your holograms", usage = "<subcommand>")
@Require("battle.entity.hologram")
public void hologram(@Sender Player player) {
player.sendMessage(CC.translate("&e&lHologram Commands"));
player.sendMessage(CC.translate("&e/hologram create <name> &7- &fAllows you to create a hologram."));
player.sendMessage(CC.translate("&e/hologram delete <name> &7- &fAllows you to delete a hologram."));
player.sendMessage(CC.translate("&e/hologram addline <name> <line> &7- &fAllows you to add a line to a hologram."));
player.sendMessage(CC.translate("&e/hologram setline <name> <number> <line> &7- &fAllows you to set a line on a hologram."));
player.sendMessage(CC.translate("&e/hologram additemline <name> &7- &fAllows you to add an item line to a hologram."));
player.sendMessage(CC.translate("&e/hologram setitemline <name> <number> <item> &7- &fAllows you to set an item line on a hologram."));
player.sendMessage(CC.translate("&e/hologram removeline <name> <number> &7- &fAllows you to remove a line from a hologram."));
player.sendMessage(CC.translate("&e/hologram teleport <name> &7- &fAllows you to teleport to a hologram."));
player.sendMessage(CC.translate("&e/hologram movehere <name> &7- &fAllows you to move a hologram to your location."));
player.sendMessage(CC.translate("&e/hologram list &7- &fAllows you to list all holograms."));
player.sendMessage(CC.translate("&e/hologram edit <name> &7- &fAllows you to edit a hologram."));
}
}

View File

@ -0,0 +1,35 @@
package rip.battle.entity.hologram.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.api.Hologram;
@RequiredArgsConstructor
public class HologramAddItemLineSubCommand {
private final HologramManager hologramManager;
@Command(name = "additemline", desc = "Allows you to add an item line to a hologram", usage = "<name> <item>")
public void addline(@Sender Player player, String name) {
Hologram hologram = hologramManager.getHologram(name);
if (hologram == null) {
player.sendMessage(CC.translate("&cA hologram with that name does not exist."));
return;
}
if (player.getItemInHand() == null) {
player.sendMessage(CC.translate("&cYou must be holding an item in your hand."));
return;
}
hologram.addLine(player.getItemInHand());
player.sendMessage(CC.translate("&aYou have added an item line to the hologram &e" + name + "&a."));
}
}

View File

@ -0,0 +1,31 @@
package rip.battle.entity.hologram.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import com.jonahseguin.drink.annotation.Text;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.api.Hologram;
@RequiredArgsConstructor
public class HologramAddLineSubCommand {
private final HologramManager hologramManager;
@Command(name = "addline", desc = "Allows you to add a line to a hologram", usage = "<name> <line>")
public void addline(@Sender Player player, String name, @Text String line) {
Hologram hologram = hologramManager.getHologram(name);
if (hologram == null) {
player.sendMessage(CC.translate("&cA hologram with that name does not exist."));
return;
}
hologram.addLine(line);
player.sendMessage(CC.translate("&aYou have added a line to the hologram &e" + name + "&a."));
}
}

View File

@ -0,0 +1,27 @@
package rip.battle.entity.hologram.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.HologramManager;
@RequiredArgsConstructor
public class HologramCreateSubCommand {
private final HologramManager hologramManager;
@Command(name = "create", desc = "Allows you to create a hologram", usage = "<name>")
public void create(@Sender Player player, String name) {
if (hologramManager.getHologram(name) != null) {
player.sendMessage(CC.translate("&cA hologram with that name already exists."));
return;
}
hologramManager.createHologram(name, player.getLocation());
player.sendMessage(CC.translate("&aYou have created a hologram with the name &e" + name + "&a."));
}
}

View File

@ -0,0 +1,29 @@
package rip.battle.entity.hologram.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.api.Hologram;
@RequiredArgsConstructor
public class HologramDeleteSubCommand {
private final HologramManager hologramManager;
@Command(name = "delete", desc = "Allows you to delete a hologram", usage = "<name>")
public void delete(@Sender Player player, String name) {
Hologram hologram = hologramManager.getHologram(name);
if (hologram == null) {
player.sendMessage(CC.translate("&cA hologram with that name does not exist."));
return;
}
hologramManager.removeHologram(name);
player.sendMessage(CC.translate("&aYou have deleted the hologram &e" + name + "&a."));
}
}

View File

@ -0,0 +1,32 @@
package rip.battle.entity.hologram.commands.sub;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.hologram.menu.HologramEditMenu;
@RequiredArgsConstructor
public class HologramEditSubCommand {
private final EntityPlugin plugin;
private final HologramManager hologramManager;
@Command(name = "edit", desc = "Edit a hologram")
public void edit(@Sender Player player, String name){
Hologram hologram = hologramManager.getHologram(name);
if (hologram == null){
player.sendMessage(ChatColor.RED + "Hologram not found.");
return;
}
new HologramEditMenu(plugin, hologram, null).open(player);
}
}

View File

@ -0,0 +1,43 @@
package rip.battle.entity.hologram.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.api.Hologram;
import java.util.Map;
@RequiredArgsConstructor
public class HologramListSubCommand {
private final HologramManager hologramManager;
@Command(name = "list", desc = "Allows you to list all holograms", aliases = {"l", "ls"})
public void list(@Sender Player player) {
Map<String, Hologram> holograms = hologramManager.getHolograms();
if (holograms.isEmpty()) {
player.sendMessage(CC.translate("&cThere are no holograms."));
return;
}
player.sendMessage(CC.translate("&aThere are &e" + holograms.size() + " &aholograms."));
holograms.forEach((name, hologram) -> {
ComponentBuilder builder = new ComponentBuilder(CC.translate("&e" + name + " &b[Click to teleport]"));
builder.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(CC.translate("&7Click to teleport")).create()));
builder.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/hologram tp " + name));
player.spigot().sendMessage(builder.create());
});
}
}

View File

@ -0,0 +1,30 @@
package rip.battle.entity.hologram.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.api.Hologram;
@RequiredArgsConstructor
public class HologramMoveHereSubCommand {
private final HologramManager hologramManager;
@Command(name = "movehere", desc = "Allows you to move a hologram to your location", usage = "<name>", aliases = {"move", "moveto", "teleporto", "s"})
public void movehere(@Sender Player player, String name) {
Hologram hologram = hologramManager.getHologram(name);
if (hologram == null) {
player.sendMessage(CC.translate("&cA hologram with that name does not exist."));
return;
}
hologram.teleport(player.getLocation());
player.sendMessage(CC.translate("&aYou have moved the hologram &e" + name + "&a to your location."));
}
}

View File

@ -0,0 +1,32 @@
package rip.battle.entity.hologram.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.api.Hologram;
@RequiredArgsConstructor
public class HologramRemoveLineSubCommand {
private final HologramManager hologramManager;
@Command(name = "removeline", desc = "Allows you to remove a line of a hologram", usage = "<name> <line>")
public void removeLine(@Sender Player player, String name, int line) {
Hologram hologram = hologramManager.getHologram(name);
if (hologram == null) {
player.sendMessage(CC.translate("&cA hologram with that name does not exist."));
return;
}
hologram.removeLine(line);
player.sendMessage(CC.translate("&aYou have removed a line of the hologram &e" + name + "&a."));
}
}

View File

@ -0,0 +1,38 @@
package rip.battle.entity.hologram.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.api.Hologram;
@RequiredArgsConstructor
public class HologramSetItemLineSubCommand {
private final HologramManager hologramManager;
@Command(name = "setitemline", desc = "Allows you to set a item line of a hologram", usage = "<name> <line>")
public void setItemLine(@Sender Player player, String name, int line) {
Hologram hologram = hologramManager.getHologram(name);
if (hologram == null) {
player.sendMessage(CC.translate("&cA hologram with that name does not exist."));
return;
}
ItemStack item = player.getItemInHand();
if (item == null) {
player.sendMessage(CC.translate("&cYou must be holding an item in your hand."));
return;
}
hologram.setLine(line, item);
player.sendMessage(CC.translate("&aYou have set a item line of the hologram &e" + name + "&a."));
}
}

View File

@ -0,0 +1,31 @@
package rip.battle.entity.hologram.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.api.Hologram;
@RequiredArgsConstructor
public class HologramSetLineSubCommand {
private final HologramManager hologramManager;
@Command(name = "setline", desc = "Allows you to set a line of a hologram", usage = "<name> <line> <text>")
public void setline(@Sender Player player, String name, int line, String text) {
Hologram hologram = hologramManager.getHologram(name);
if (hologram == null) {
player.sendMessage(CC.translate("&cA hologram with that name does not exist."));
return;
}
hologram.setLine(line, text);
player.sendMessage(CC.translate("&aYou have set a line of the hologram &e" + name + "&a."));
}
}

View File

@ -0,0 +1,30 @@
package rip.battle.entity.hologram.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.api.Hologram;
@RequiredArgsConstructor
public class HologramTeleportSubCommand {
private final HologramManager hologramManager;
@Command(name = "teleport", desc = "Allows you to teleport to a hologram", usage = "<name>", aliases = {"tp"})
public void teleport(@Sender Player player, String name) {
Hologram hologram = hologramManager.getHologram(name);
if (hologram == null) {
player.sendMessage(CC.translate("&cA hologram with that name does not exist."));
return;
}
player.teleport(hologram.getLocation());
player.sendMessage(CC.translate("&aYou have teleported to the hologram &e" + name + "&a."));
}
}

View File

@ -0,0 +1,40 @@
package rip.battle.entity.hologram.impl;
import lombok.Setter;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.hologram.CraftHologram;
import rip.battle.entity.hologram.lines.HologramLine;
@Setter
public class UpdatableHologram extends CraftHologram {
private long lastUpdate = System.currentTimeMillis();
public UpdatableHologram(String name, String line, Location location) {
super(name, line, location);
}
public UpdatableHologram(String name, ItemStack line, Location location) {
super(name, line, location);
}
public UpdatableHologram(String name, Location location) {
super(name, location);
}
public void update(Player player){
for (HologramLine<?> line : getLines()){
line.update(player);
}
}
public int getUpdateInterval(){
return 1;
}
public boolean canUpdate() {
return System.currentTimeMillis() - lastUpdate > getUpdateInterval();
}
}

View File

@ -0,0 +1,100 @@
package rip.battle.entity.hologram.lines;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.server.v1_8_R3.PacketPlayOutAttachEntity;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import rip.battle.entity.Entity;
import rip.battle.entity.hologram.CraftHologram;
import rip.battle.entity.utils.PacketUtils;
import java.util.function.Consumer;
import java.util.function.Predicate;
@Getter
@Setter
public abstract class HologramLine<T> extends Entity {
private final CraftHologram parent;
private Predicate<Player> shouldSend;
private final int supportEntityID = nextId();
public HologramLine(CraftHologram parent, Location location) {
this(parent, location, player -> true, null);
}
public HologramLine(CraftHologram parent, Location location, Predicate<Player> shouldSend) {
this(parent, location, shouldSend, null);
}
public HologramLine(CraftHologram parent, Location location, Consumer<Player> onClick) {
this(parent, location, player -> true, onClick);
}
public HologramLine(CraftHologram parent, Location location, Predicate<Player> shouldSend, Consumer<Player> onClick) {
super(location);
this.parent = parent;
this.shouldSend = shouldSend;
this.setOnLeftClick(onClick);
}
public boolean shouldSend(Player player) {
return shouldSend.test(player);
}
/*@Override
public void onLeftClick(Player player) {
player.sendMessage("You clicked a hologram line!");
}*/
@Override
public void spawn() {
super.spawn();
parent.getCurrentWatchers().addAll(getCurrentWatchers());
}
@Override
public void spawn(Player player) {
super.spawn(player);
parent.getCurrentWatchers().add(player.getUniqueId());
}
@Override
public void destroy(Player player) {
super.destroy(player);
parent.getCurrentWatchers().remove(player.getUniqueId());
}
public abstract T getLine(Player player);
public abstract void setLine(T line);
public void sendAttachPacket(Player player){
CraftHologram hologram = getParent();
if (hologram == null || hologram.getParent() == null)
return;
PacketUtils.sendPacket(player, new PacketPlayOutAttachEntity(0, supportEntityID, hologram.getParent().getId()));
}
@Override
public String getTypeName() {
return "Hologram_Line";
}
@Override
public boolean isRoot() {
return false;
}
@Override
public boolean isMultiPartEntity() {
return true;
}
}

View File

@ -0,0 +1,184 @@
package rip.battle.entity.hologram.lines.impl;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.hologram.CraftHologram;
import rip.battle.entity.hologram.lines.HologramLine;
import rip.battle.entity.utils.DataWatcherUtil;
import rip.battle.entity.utils.PacketUtils;
import rip.battle.entity.utils.PlayerUtil;
import java.util.Collections;
import java.util.function.Consumer;
import java.util.function.Predicate;
@Getter @Setter
public class ItemLine extends HologramLine<ItemStack> {
private ItemStack itemStack;
public ItemLine(CraftHologram parent, Location location, ItemStack itemStack) {
this(parent, location, itemStack, null);
}
public ItemLine(CraftHologram parent, Location location, ItemStack itemStack, Consumer<Player> onClick) {
this(parent, location, itemStack, onClick, player -> true);
}
public ItemLine(CraftHologram parent, Location location, ItemStack itemStack, Consumer<Player> onClick, Predicate<Player> shouldSend) {
super(parent, location, shouldSend, onClick);
this.itemStack = itemStack;
setPersistent(false);
}
@Override
public void sendSpawnPackets(Player player) {
boolean legacy = PlayerUtil.isLegacy(player);
PacketPlayOutSpawnEntity spawnPacket = new PacketPlayOutSpawnEntity(
getId(),
2,
(int) getLocation().getX(),
(int) getLocation().getY(),
(int) getLocation().getZ(),
0,
0
);
DataWatcher itemDataWatcher = DataWatcherUtil.createDataWatcher();
itemDataWatcher.a(0, (byte) 0);
itemDataWatcher.a(1, (short) 0);
itemDataWatcher.a(2, "");
itemDataWatcher.a(3, (byte) 0);
itemDataWatcher.a(4, (byte) 0);
itemDataWatcher.add(10, 5);
itemDataWatcher.watch(10, CraftItemStack.asNMSCopy(itemStack));
DataWatcherUtil.setFlag(itemDataWatcher, 5, false);
PacketPlayOutEntityMetadata metadataPacket = new PacketPlayOutEntityMetadata(getId(), itemDataWatcher, true);
DataWatcher armorStandDataWatcher = DataWatcherUtil.createDataWatcher();
if (!legacy) {
armorStandDataWatcher.a(0, (byte) 0);
armorStandDataWatcher.a(1, (short) 0);
armorStandDataWatcher.a(2, "");
armorStandDataWatcher.a(3, (byte) 0);
armorStandDataWatcher.a(4, (byte) 0);
DataWatcherUtil.setFlag(armorStandDataWatcher, 5, true);
armorStandDataWatcher.a(6, (float) 1);
armorStandDataWatcher.a(7, 0);
armorStandDataWatcher.a(8, (byte) 0);
armorStandDataWatcher.a(9, (byte) 0);
armorStandDataWatcher.a(10, (byte) 0);
DataWatcherUtil.setTypeFlag(armorStandDataWatcher, 10, 1, true);
DataWatcherUtil.setTypeFlag(armorStandDataWatcher, 10, 4, false);
DataWatcherUtil.setTypeFlag(armorStandDataWatcher, 10, 8, false);
DataWatcherUtil.setTypeFlag(armorStandDataWatcher, 10, 10, true);
armorStandDataWatcher.a(11, PacketUtils.ARMOR_STAND_HEAD_POSE);
armorStandDataWatcher.a(12, PacketUtils.ARMOR_STAND_BODY_POSE);
armorStandDataWatcher.a(13, PacketUtils.ARMOR_STAND_LEFT_ARM_POSE);
armorStandDataWatcher.a(14, PacketUtils.ARMOR_STAND_RIGHT_ARM_POSE);
armorStandDataWatcher.a(15, PacketUtils.ARMOR_STAND_LEFT_LEG_POSE);
armorStandDataWatcher.a(16, PacketUtils.ARMOR_STAND_RIGHT_LEG_POSE);
}
Packet<?> armorStandPacket;
if (legacy){
EntityWitherSkull skull = new EntityWitherSkull(((CraftWorld) getLocation().getWorld()).getHandle());
skull.d(getSupportEntityID());
skull.setLocation(getLocation().getX(), (getLocation().getY() + 1.5), getLocation().getZ(), 0.0f, 0.0f);
armorStandPacket = new PacketPlayOutSpawnEntity(skull, 66);
} else {
armorStandPacket = new PacketPlayOutSpawnEntityLiving(
getSupportEntityID(),
30,
MathHelper.floor(getLocation().getX() * 32.0D),
MathHelper.floor((getLocation().getY() + 0.15) * 32.0D),
MathHelper.floor(getLocation().getZ() * 32.0D),
armorStandDataWatcher
);
}
PacketPlayOutAttachEntity attachPacket = new PacketPlayOutAttachEntity(0, getId(), getSupportEntityID());
PacketUtils.sendPacket(player, spawnPacket);
PacketUtils.sendPacket(player, metadataPacket);
PacketUtils.sendPacket(player, armorStandPacket);
PacketUtils.sendPacket(player, attachPacket);
}
@Override
public void sendRePositionPackets(Player player){
PacketPlayOutEntityTeleport teleportPacket;
if (PlayerUtil.isLegacy(player)){
teleportPacket = new PacketPlayOutEntityTeleport(
getSupportEntityID(),
MathHelper.floor(getLocation().getX() * 32.0D),
MathHelper.floor((getLocation().getY() + 1.5) * 32.0D) ,
MathHelper.floor(getLocation().getZ() * 32.0D),
(byte) 0,
(byte) 0,
false
);
}else{
teleportPacket = new PacketPlayOutEntityTeleport(
getSupportEntityID(),
MathHelper.floor(getLocation().getX() * 32.0D),
MathHelper.floor((getLocation().getY() + 0.15) * 32.0D) ,
MathHelper.floor(getLocation().getZ() * 32.0D),
(byte) 0,
(byte) 0,
false
);
}
PacketUtils.sendPacket(player, teleportPacket);
}
@Override
public void sendUpdatePackets(Player player) {
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata();
packet.setEntityId(getId());
packet.setData(Collections.singletonList(new DataWatcher.WatchableObject(5, 10, CraftItemStack.asNMSCopy(itemStack))));
PacketUtils.sendPacket(player, packet);
}
@Override
public void sendDestroyPackets(Player player) {
PacketPlayOutEntityDestroy destroyPacket = new PacketPlayOutEntityDestroy(getId(), getSupportEntityID());
PacketUtils.sendPacket(player, destroyPacket);
super.sendDestroyPackets(player);
}
@Override
public ItemStack getLine(Player player) {
return itemStack;
}
@Override
public void setLine(ItemStack line) {
this.itemStack = line;
}
}

View File

@ -0,0 +1,105 @@
package rip.battle.entity.hologram.lines.impl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.Getter;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.CraftHologram;
import rip.battle.entity.hologram.lines.HologramLine;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
@Getter
public class MultipleTextLine extends HologramLine<List<String>> {
private Function<CommandSender, List<String>> lines;
private final Map<UUID, List<TextLine>> textLines = Maps.newHashMap();
public MultipleTextLine(CraftHologram parent, Location location, Function<CommandSender, List<String>> lines) {
super(parent, location);
this.lines = lines;
}
@Override
public List<String> getLine(Player player) {
return lines.apply(player);
}
@Override
public void setLine(List<String> line) {
this.lines = player -> line;
}
@Override
public void sendSpawnPackets(Player player) {
List<String> lines = getLine(player);
List<TextLine> textLines = this.textLines.get(player.getUniqueId());
Location location = getLocation().clone();
if (textLines == null) {
textLines = Lists.newArrayList();
}
for (String line : lines) {
TextLine textLine = new TextLine(getParent(), location.subtract(0, 0.25, 0), player1 -> line);
textLine.setMultiLine(true);
textLine.spawn(player);
textLines.add(textLine);
}
this.textLines.put(player.getUniqueId(), textLines);
}
@Override
public void updateLocation(Location location) {
setLocation(location);
for (List<TextLine> textLines : this.textLines.values()) {
Location locationCloned = getLocation().clone();
for (TextLine textLine : textLines) {
textLine.updateLocation(locationCloned.subtract(0, 0.25, 0));
}
}
}
@Override
public void sendDestroyPackets(Player player) {
List<TextLine> textLines = this.textLines.get(player.getUniqueId());
if (textLines == null) {
return;
}
for (TextLine textLine : textLines) {
textLine.sendDestroyPackets(player);
}
this.textLines.remove(player.getUniqueId());
}
@Override
public void sendUpdatePackets(Player player) {
List<TextLine> textLines = this.textLines.get(player.getUniqueId());
if (textLines == null) {
return;
}
for (TextLine textLine : textLines) {
textLine.sendUpdatePackets(player);
}
}
}

View File

@ -0,0 +1,104 @@
package rip.battle.entity.hologram.lines.impl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.CraftHologram;
import rip.battle.entity.hologram.lines.HologramLine;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Function;
import java.util.function.Supplier;
public class SupplierMultipleTextLine extends HologramLine<Supplier<List<String>>> {
private Function<CommandSender, Supplier<List<String>>> lines;
private final Map<UUID, List<TextLine>> textLines = Maps.newHashMap();
public SupplierMultipleTextLine(CraftHologram parent, Location location, Function<CommandSender, Supplier<List<String>>> lines) {
super(parent, location);
this.lines = lines;
}
@Override
public Supplier<List<String>> getLine(Player player) {
return lines.apply(player);
}
@Override
public void setLine(Supplier<List<String>> line) {
lines = player -> line;
}
@Override
public void sendSpawnPackets(Player player) {
List<String> lines = getLine(player).get();
List<TextLine> textLines = this.textLines.get(player.getUniqueId());
Location location = getLocation().clone();
if (textLines == null) {
textLines = Lists.newArrayList();
}
for (String line : lines) {
TextLine textLine = new TextLine(getParent(), location.subtract(0, 0.25, 0), player1 -> line);
textLine.setMultiLine(true);
textLine.spawn(player);
textLines.add(textLine);
}
this.textLines.put(player.getUniqueId(), textLines);
}
@Override
public void updateLocation(Location location) {
setLocation(location);
for (List<TextLine> textLines : this.textLines.values()) {
Location locationCloned = getLocation().clone();
for (TextLine textLine : textLines) {
textLine.updateLocation(locationCloned.subtract(0, 0.25, 0));
}
}
}
@Override
public void sendDestroyPackets(Player player) {
List<TextLine> textLines = this.textLines.get(player.getUniqueId());
if (textLines == null) {
return;
}
for (TextLine textLine : textLines) {
textLine.sendDestroyPackets(player);
}
this.textLines.remove(player.getUniqueId());
}
@Override
public void sendUpdatePackets(Player player) {
List<TextLine> textLines = this.textLines.get(player.getUniqueId());
if (textLines == null) {
return;
}
for (TextLine textLine : textLines) {
textLine.sendUpdatePackets(player);
}
}
}

View File

@ -0,0 +1,164 @@
package rip.battle.entity.hologram.lines.impl;
import cc.stormworth.core.util.chat.CC;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.v1_8_R3.CraftWorld;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.CraftHologram;
import rip.battle.entity.hologram.lines.HologramLine;
import rip.battle.entity.taks.RainbowTask;
import rip.battle.entity.utils.DataWatcherUtil;
import rip.battle.entity.utils.PacketUtils;
import rip.battle.entity.utils.PlayerUtil;
import java.util.Collections;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@Getter
@Setter
public class TextLine extends HologramLine<String> {
private Function<CommandSender, String> text;
private boolean multiLine = false;
public TextLine(CraftHologram parent, Location location, Function<CommandSender, String> text) {
this(parent, location, text, null);
}
public TextLine(CraftHologram parent, Location location, Function<CommandSender, String> text, Consumer<Player> onClick) {
this(parent, location, text, onClick, player -> true);
}
public TextLine(CraftHologram parent, Location location, Function<CommandSender, String> text, Consumer<Player> onClick, Predicate<Player> shouldSend) {
super(parent, location, shouldSend, onClick);
this.text = text;
setPersistent(false);
}
@Override
public String getLine(Player player) {
return text.apply(player);
}
@Override
public void setLine(String line) {
this.text = player -> line;
}
@Override
public void sendSpawnPackets(Player player) {
boolean legacy = PlayerUtil.isLegacy(player);
String text = processPlaceholders(getLine(player), player);
DataWatcher dataWatcher = DataWatcherUtil.createDataWatcher();
dataWatcher.a(0, (byte) 0);
dataWatcher.a(1, (short) 0);
dataWatcher.a(2, text);
dataWatcher.a(3, text.isEmpty() || text.equalsIgnoreCase("&7") || text.equalsIgnoreCase(" ") ? (byte) 0 : (byte) 1);
dataWatcher.a(4, (byte) 0);
if (legacy){
dataWatcher.a(16, (byte) -2);
}else{
DataWatcherUtil.setFlag(dataWatcher, 5, true);
dataWatcher.a(6, (float) 1);
dataWatcher.a(7, 0);
dataWatcher.a(8, (byte) 0);
dataWatcher.a(9, (byte) 0);
dataWatcher.a(10, (byte) 0);
DataWatcherUtil.setTypeFlag(dataWatcher, 10, 1, true);
DataWatcherUtil.setTypeFlag(dataWatcher, 10, 4, false);
DataWatcherUtil.setTypeFlag(dataWatcher, 10, 8, false);
DataWatcherUtil.setTypeFlag(dataWatcher, 10, 10, true);
dataWatcher.a(11, PacketUtils.ARMOR_STAND_HEAD_POSE);
dataWatcher.a(12, PacketUtils.ARMOR_STAND_BODY_POSE);
dataWatcher.a(13, PacketUtils.ARMOR_STAND_LEFT_ARM_POSE);
dataWatcher.a(14, PacketUtils.ARMOR_STAND_RIGHT_ARM_POSE);
dataWatcher.a(15, PacketUtils.ARMOR_STAND_LEFT_LEG_POSE);
dataWatcher.a(16, PacketUtils.ARMOR_STAND_RIGHT_LEG_POSE);
}
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(
getId(),
legacy ? 55 : 30,
MathHelper.floor(getLocation().getX() * 32.0D),
MathHelper.floor(getLocation().getY() * 32.0D),
MathHelper.floor(getLocation().getZ() * 32.0D),
dataWatcher
);
PacketUtils.sendPacket(player, packet);
if (legacy){
EntityWitherSkull skull = new EntityWitherSkull(((CraftWorld) getLocation().getWorld()).getHandle());
skull.d(getSupportEntityID());
skull.setLocation(getLocation().getX(), (getLocation().getY() + 3), getLocation().getZ(), 0.0f, 0.0f);
PacketUtils.sendPacket(player, new PacketPlayOutSpawnEntity(skull, 66));
PacketUtils.sendPacket(player, new PacketPlayOutAttachEntity(0, getId(), getSupportEntityID()));
}
}
@Override
public void sendUpdatePackets(Player player) {
String text = processPlaceholders(getLine(player), player);
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata();
packet.setEntityId(getId());
packet.setData(Collections.singletonList(new DataWatcher.WatchableObject(4, 2, text)));
PacketUtils.sendPacket(player, packet);
}
@Override
public void sendRePositionPackets(Player player) {
if (PlayerUtil.isLegacy(player)){
PacketPlayOutEntityTeleport packet = new PacketPlayOutEntityTeleport(
getSupportEntityID(),
MathHelper.floor(getLocation().getX() * 32.0D),
MathHelper.floor((getLocation().getY() + 3) * 32.0D),
MathHelper.floor(getLocation().getZ() * 32.0D),
(byte) 0,
(byte) 0,
false
);
PacketUtils.sendPacket(player, packet);
}else{
super.sendRePositionPackets(player);
}
}
@Override
public void sendDestroyPackets(Player player) {
PacketUtils.sendPacket(player, new PacketPlayOutEntityDestroy(getSupportEntityID()));
PacketUtils.sendPacket(player, new PacketPlayOutEntityDestroy(getId()));
}
public String processPlaceholders(String text, Player player) {
String textFormatted = text;
if (textFormatted == null) {
return null;
}
textFormatted = textFormatted.replace("{player}", player.getName());
textFormatted = textFormatted.replace("{player_displayname}", player.getDisplayName());
textFormatted = textFormatted.replace("{rainbow}", RainbowTask.getCurrentColor().toString());
return CC.translate(textFormatted);
}
}

View File

@ -0,0 +1,159 @@
package rip.battle.entity.hologram.menu;
import cc.stormworth.core.util.inventory.ItemBuilder;
import cc.stormworth.core.util.menu.Menu;
import cc.stormworth.core.util.menu.button.Button;
import cc.stormworth.core.util.menu.button.impl.PlaceholderButton;
import cc.stormworth.core.util.menu.impl.ConfirmationMenu;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.hologram.CraftHologram;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.npc.api.NPC;
import rip.battle.entity.npc.menu.NPCEditMenu;
import java.util.Map;
public class HologramEditMenu extends Menu {
private final Hologram hologram;
private final HologramManager hologramManager;
private final EntityPlugin plugin;
private final Menu back;
public HologramEditMenu(EntityPlugin plugin, Hologram hologram, Menu back) {
this.plugin = plugin;
this.hologramManager = plugin.getHologramManager();
this.hologram = hologram;
this.back = back;
}
@Override
public String getTitle(Player player) {
return "&bEditing Hologram &8" + hologram.getName();
}
@Override
public int getRows(Player player) {
return 3;
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
if (back != null){
buttons.put(0, new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
return new ItemBuilder(Material.BED).setName("&cBack").toItemStack();
}
@Override
public void onClick(Player player) {
back.open(player);
}
});
}
buttons.put(getSlot(1, 1), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.ENDER_PEARL);
builder.setName("&6Teleport");
builder.addLore(
"",
"&7Click to teleport to this hologram."
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
player.closeInventory();
player.teleport(hologram.getLocation());
}
});
buttons.put(getSlot(1, 4), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.BOOK);
builder.setName("&6Lines: " + hologram.getLines().size());
builder.addLore(
"",
"&7Click to manage lines on this hologram."
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
new HologramManageLinesMenu(plugin, hologram).open(player);
}
});
buttons.put(getSlot(1, 7), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.WOOL);
builder.setWoolColour(DyeColor.RED);
builder.setName("&4&lDELETE");
builder.addLore(
"",
"&7Click to delete this hologram."
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
new ConfirmationMenu("&4&lAre you sure?", (value) -> {
if (value){
CraftHologram craftHologram = (CraftHologram) hologram;
if (craftHologram.getParent() != null){
NPC npc = (NPC) craftHologram.getParent();
npc.setHologram(null);
hologram.destroy();
new NPCEditMenu(npc, plugin).open(player);
}else{
hologramManager.removeHologram(hologram.getName());
player.closeInventory();
}
}else {
new HologramEditMenu(plugin, hologram, null).open(player);
}
}, new PlaceholderButton(new ItemBuilder(Material.WOOL)
.setWoolColour(DyeColor.RED)
.setName("&4&lDeleting &c" + hologram.getName())
.toItemStack()))
.open(player);
}
});
return buttons;
}
}

View File

@ -0,0 +1,149 @@
package rip.battle.entity.hologram.menu;
import cc.stormworth.core.util.chat.CC;
import cc.stormworth.core.util.chat.ChatUtils;
import cc.stormworth.core.util.inventory.ItemBuilder;
import cc.stormworth.core.util.menu.Menu;
import cc.stormworth.core.util.menu.button.Button;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.hologram.CraftHologram;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.hologram.lines.HologramLine;
import rip.battle.entity.hologram.prompt.HologramAddItemLinePrompt;
import rip.battle.entity.hologram.prompt.HologramAddLinePrompt;
import rip.battle.entity.hologram.prompt.HologramEditLinePrompt;
import rip.battle.entity.npc.api.NPC;
import rip.battle.entity.npc.menu.NPCEditMenu;
import java.util.Map;
@RequiredArgsConstructor
public class HologramManageLinesMenu extends Menu {
private final EntityPlugin plugin;
private final Hologram hologram;
@Override
public String getTitle(Player player) {
return "&bEditing lines of &8" + hologram.getName();
}
@Override
public int getRows(Player player) {
return 3;
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
buttons.put(0, new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
return new ItemBuilder(Material.BED).setName("&cBack").toItemStack();
}
@Override
public void onClick(Player player) {
new HologramEditMenu(plugin, hologram, null).open(player);
}
});
buttons.put(getSlot(0, 3), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.BOOK);
builder.setName("&6Add line");
builder.addLore(
"",
"&7Click to add new line to this hologram."
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
ChatUtils.beginPrompt(player, new HologramAddLinePrompt(plugin, hologram), plugin);
}
});
buttons.put(getSlot(0, 5), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.DIAMOND_PICKAXE);
builder.setName("&6Add Item line");
builder.addLore(
"",
"&7Click to add new item line to this hologram."
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
ChatUtils.beginPrompt(player, new HologramAddItemLinePrompt(plugin, hologram), plugin);
}
});
int startSlot = 9;
for (HologramLine<?> line : hologram.getLines()) {
buttons.put(startSlot++, new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.PAPER);
builder.setName("&6" + line.getLine(player));
builder.addLore(
"",
"&7Click to edit this line.",
"&cShift click to remove this line."
);
return builder.toItemStack();
}
@Override
public void onClick(Player player, ClickType clickType) {
if (clickType.isShiftClick()) {
hologram.removeLine(line);
player.sendMessage(CC.translate("&aRemoved line &8" + line.getLine(player) + " &afrom hologram &8" + hologram.getName() + "&a."));
if (hologram.getLines().isEmpty()){
CraftHologram craftHologram = (CraftHologram) hologram;
if (craftHologram.getParent() != null){
NPC npc = (NPC) craftHologram.getParent();
npc.setHologram(null);
hologram.destroy();
new NPCEditMenu(npc, plugin).open(player);
}
}
} else {
ChatUtils.beginPrompt(player, new HologramEditLinePrompt(plugin, hologram, line), plugin);
}
}
});
}
return buttons;
}
}

View File

@ -0,0 +1,52 @@
package rip.battle.entity.hologram.prompt;
import cc.stormworth.core.util.chat.CC;
import lombok.RequiredArgsConstructor;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.hologram.menu.HologramManageLinesMenu;
@RequiredArgsConstructor
public class HologramAddItemLinePrompt extends StringPrompt {
private final EntityPlugin plugin;
private final Hologram hologram;
@Override
public String getPromptText(ConversationContext conversationContext) {
return CC.translate("&7Enter &aconfirm&7 to set your item in hand as the line or type &ccancel &7to cancel.");
}
@Override
public Prompt acceptInput(ConversationContext context, String input) {
Player player = (Player) context.getForWhom();
if (input.equalsIgnoreCase("cancel")) {
new HologramManageLinesMenu(plugin, hologram).open(player);
return Prompt.END_OF_CONVERSATION;
}
ItemStack itemStack = player.getItemInHand();
if (itemStack == null || itemStack.getType() == Material.AIR) {
player.sendMessage(CC.translate("&cYou must be holding an item to set it as a hologram line."));
player.playSound(player.getLocation(), Sound.NOTE_BASS, 1, 1);
return this;
}
hologram.addLine(itemStack);
player.sendMessage(CC.translate("&aAdded line to hologram."));
player.playSound(player.getLocation(), Sound.NOTE_PLING, 1, 1);
new HologramManageLinesMenu(plugin, hologram).open(player);
return Prompt.END_OF_CONVERSATION;
}
}

View File

@ -0,0 +1,42 @@
package rip.battle.entity.hologram.prompt;
import cc.stormworth.core.util.chat.CC;
import lombok.RequiredArgsConstructor;
import org.bukkit.Sound;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.hologram.menu.HologramManageLinesMenu;
@RequiredArgsConstructor
public class HologramAddLinePrompt extends StringPrompt {
private final EntityPlugin plugin;
private final Hologram hologram;
@Override
public String getPromptText(ConversationContext conversationContext) {
return CC.translate("&7Enter the text for the new line or type &ccancel &7to cancel.");
}
@Override
public Prompt acceptInput(ConversationContext context, String input) {
Player player = (Player) context.getForWhom();
if (input.equalsIgnoreCase("cancel")) {
new HologramManageLinesMenu(plugin, hologram).open(player);
return Prompt.END_OF_CONVERSATION;
}
hologram.addLine(input);
player.sendMessage(CC.translate("&aAdded line to hologram."));
player.playSound(player.getLocation(), Sound.NOTE_PLING, 1, 1);
new HologramManageLinesMenu(plugin, hologram).open(player);
return Prompt.END_OF_CONVERSATION;
}
}

View File

@ -0,0 +1,66 @@
package rip.battle.entity.hologram.prompt;
import cc.stormworth.core.util.chat.CC;
import lombok.RequiredArgsConstructor;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.hologram.lines.HologramLine;
import rip.battle.entity.hologram.lines.impl.ItemLine;
import rip.battle.entity.hologram.lines.impl.TextLine;
import rip.battle.entity.hologram.menu.HologramManageLinesMenu;
@RequiredArgsConstructor
public class HologramEditLinePrompt extends StringPrompt {
private final EntityPlugin plugin;
private final Hologram hologram;
private final HologramLine<?> line;
@Override
public String getPromptText(ConversationContext context) {
if (line instanceof ItemLine){
return CC.translate("&7Enter &aconfirm&7 to set item in hand as the item for this line or type &ccancel &7to cancel.");
}
return CC.translate("&7Enter the text for the line or type &ccancel &7to cancel.");
}
@Override
public Prompt acceptInput(ConversationContext context, String input) {
Player player = (Player) context.getForWhom();
if (input.equalsIgnoreCase("cancel")) {
new HologramManageLinesMenu(plugin, hologram).open(player);
return Prompt.END_OF_CONVERSATION;
}
if (line instanceof ItemLine){
if (input.equalsIgnoreCase("confirm")){
((ItemLine) line).setLine(player.getItemInHand());
line.updateForCurrentWatchers();
player.sendMessage(CC.translate("&aSet item in hand as the item for this line."));
new HologramManageLinesMenu(plugin, hologram).open(player);
return Prompt.END_OF_CONVERSATION;
}
}else{
TextLine textLine = (TextLine) line;
textLine.setLine(input);
textLine.updateForCurrentWatchers();
player.sendMessage(CC.translate("&aSet text for this line."));
new HologramManageLinesMenu(plugin, hologram).open(player);
return Prompt.END_OF_CONVERSATION;
}
return this;
}
}

View File

@ -0,0 +1,28 @@
package rip.battle.entity.hologram.runnable;
import lombok.RequiredArgsConstructor;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.hologram.impl.UpdatableHologram;
@RequiredArgsConstructor
public class HologramUpdateRunnable implements Runnable {
private final HologramManager hologramManager;
@Override
public void run() {
for (Hologram hologram : hologramManager.getHolograms().values()) {
if (hologram instanceof UpdatableHologram){
UpdatableHologram updatableHologram = (UpdatableHologram) hologram;
if (updatableHologram.canUpdate() && !updatableHologram.getLines().isEmpty()){
updatableHologram.getCurrentWatchersPlayers().forEach(updatableHologram::update);
updatableHologram.setLastUpdate(System.currentTimeMillis());
}
}
}
}
}

View File

@ -0,0 +1,92 @@
package rip.battle.entity.hologram.serialization;
import cc.stormworth.core.util.location.LocationUtils;
import cc.stormworth.core.util.serialize.ItemStackAdapter;
import com.google.gson.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import rip.battle.entity.hologram.CraftHologram;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.hologram.impl.UpdatableHologram;
import rip.battle.entity.hologram.lines.HologramLine;
import rip.battle.entity.hologram.lines.impl.ItemLine;
import rip.battle.entity.hologram.lines.impl.TextLine;
import java.lang.reflect.Type;
public class HologramTypeAdapter implements JsonDeserializer<Hologram>, JsonSerializer<Hologram> {
@Override
public Hologram deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
return fromJson(jsonElement);
}
@Override
public JsonElement serialize(Hologram hologram, Type type, JsonSerializationContext jsonSerializationContext) {
return toJson(hologram);
}
public static JsonObject toJson(Hologram hologram) {
if (hologram == null) {
return null;
}
JsonObject object = new JsonObject();
CraftHologram craftHologram = (CraftHologram) hologram;
object.addProperty("location", LocationUtils.serializeLocation(craftHologram.getLocation()));
object.addProperty("name", craftHologram.getName());
JsonArray lines = new JsonArray();
for (HologramLine<?> line : craftHologram.getLines()) {
JsonObject lineObject = new JsonObject();
if (line instanceof TextLine) {
lineObject.addProperty("text", ((TextLine) line).getText().apply(Bukkit.getConsoleSender()));
}else {
ItemLine itemLine = (ItemLine) line;
lineObject.add("item", ItemStackAdapter.serialize(itemLine.getItemStack()));
}
lines.add(lineObject);
}
object.add("lines", lines);
object.add("hidden", new JsonPrimitive(craftHologram.isHidden()));
return object;
}
public static Hologram fromJson(JsonElement jsonElement) {
if (jsonElement == null || !jsonElement.isJsonObject()) {
return null;
}
JsonObject jsonObject = jsonElement.getAsJsonObject();
Location location = LocationUtils.deserializeLocation(jsonObject.get("location").getAsString());
JsonArray lines = jsonObject.getAsJsonArray("lines");
String name = jsonObject.get("name").getAsString();
CraftHologram hologram = new UpdatableHologram(name, location);
for (JsonElement line : lines) {
JsonObject lineObject = line.getAsJsonObject();
if (lineObject.has("text")) {
hologram.addLine(lineObject.get("text").getAsString());
}else {
hologram.addLine(ItemStackAdapter.deserialize(lineObject.get("item")));
}
}
hologram.updateVisibility(jsonObject.get("hidden").getAsBoolean());
return hologram;
}
}

View File

@ -0,0 +1,26 @@
package rip.battle.entity.listeners;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import rip.battle.entity.Entity;
import rip.battle.entity.EntityManager;
import rip.battle.entity.hologram.CraftHologram;
import rip.battle.entity.hologram.HologramManager;
import rip.battle.entity.npc.NPCManager;
@RequiredArgsConstructor
public class PlayerListener implements Listener {
@EventHandler
public void onQuit(PlayerQuitEvent event){
Player player = event.getPlayer();
for (Entity entity : EntityManager.getEntities().values()){
entity.destroy(player);
}
}
}

View File

@ -0,0 +1,191 @@
package rip.battle.entity.living;
import cc.stormworth.core.util.TaskUtil;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.server.v1_8_R3.MathHelper;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityTeleport;
import net.minecraft.server.v1_8_R3.PacketPlayOutEntityVelocity;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.Vector;
import rip.battle.entity.Entity;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.living.events.LivingEntityDeathEvent;
import rip.battle.entity.tick.TickableEntity;
import rip.battle.entity.utils.AngleUtils;
import rip.battle.entity.utils.PacketUtils;
import rip.battle.spigot.Battle;
import rip.battle.spigot.knockback.KnockbackProfile;
@Getter @Setter
public abstract class LivingEntity extends Entity implements TickableEntity {
private double health = 20;
private double maxHealth = 20;
private boolean dead;
private boolean invulnerable;
private long lastDamage;
private boolean gravity = true;
private String customName;
private Vector velocity;
private boolean onGround;
public LivingEntity(Location location) {
super(location);
velocity = new Vector();
}
@Override
public void tick() {
if (gravity){
if (!getLocation().getBlock().getType().isSolid()) {
System.out.println("Falling");
setVelocity(getVelocity().clone().add(new Vector(0, -0.1, 0)));
onGround = false;
}else{
System.out.println("On ground");
onGround = true;
}
}
}
public void setVelocity(Vector vector) {
this.velocity = vector;
move(vector);
getCurrentWatchersPlayers().forEach(currentWatchersPlayer -> sendVelocityPacket(currentWatchersPlayer, vector));
}
public void sendVelocityPacket(Player player, Vector vector) {
PacketPlayOutEntityVelocity packet = new PacketPlayOutEntityVelocity(getId(), vector.getX(), vector.getY(), vector.getZ());
PacketUtils.sendPacket(player, packet);
}
public void move(Vector vector) {
Location to = getLocation().clone().add(vector);
if (to.getBlock().getRelative(0, 1, 0).getType().isSolid()) {
to.setY(to.getBlockY() + 1);
}
setLocation(to);
getCurrentWatchersPlayers().forEach(this::sendMovePacket);
}
public void sendMovePacket(Player player) {
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(
getId(),
MathHelper.floor(getLocation().getX() * 32.0D),
MathHelper.floor(getLocation().getY() * 32.0D),
MathHelper.floor(getLocation().getZ() * 32.0D),
AngleUtils.yawToBytes(getLocation().getYaw()),
AngleUtils.yawToBytes(getLocation().getPitch()),
true);
PacketUtils.sendPacket(player, teleportPacket);
velocity = new Vector();
}
@Override
public void onLeftClick(Player player) {
ItemStack hand = player.getItemInHand();
double damage = 1;
switch (hand.getType()){
case WOOD_SWORD:
case STONE_SWORD:
damage = 3.0;
break;
case IRON_SWORD:
damage = 4.0;
break;
case GOLD_SWORD:
damage = 5.0;
break;
case DIAMOND_SWORD:
damage = 6.0;
break;
}
//Change this xd
double finalDamage = damage;
TaskUtil.run(JavaPlugin.getPlugin(EntityPlugin.class), () -> {
damage(player, finalDamage);
});
}
public boolean damage(org.bukkit.entity.Entity entity, double damage){
if (invulnerable){
return false;
}
if (lastDamage + 500L > System.currentTimeMillis()){
return false;
}
if (dead){
return false;
}
health -= damage;
if (health <= 0){
onDeath(entity);
sendStatusPacket((byte) 3);
TaskUtil.runLater(JavaPlugin.getPlugin(EntityPlugin.class), () -> {
if (dead){
destroyForCurrentWatchers();
}
}, 40);
Bukkit.getPluginManager().callEvent(new LivingEntityDeathEvent(this, entity));
return true;
}
lastDamage = System.currentTimeMillis();
sendAnimationPacket(1);
KnockbackProfile profile = Battle.INSTANCE.getConfig().getCurrentKb();
setVelocity(new Vector(
(-MathHelper.sin(entity.getLocation().getYaw() * 3.1415927F / 180.0F) * profile.getHorizontal()),
profile.getVertical(),
(MathHelper.cos(entity.getLocation().getYaw() * 3.1415927F / 180.0F) * profile.getHorizontal())
));
return true;
}
public void onDeath(org.bukkit.entity.Entity entity){
dead = true;
}
public void setCustomName(String customName) {
this.customName = customName;
updateForCurrentWatchers();
}
public boolean isCollideWithBlock(Location to){
return to.getBlock().getType().isSolid();
}
}

View File

@ -0,0 +1,26 @@
package rip.battle.entity.living.events;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import rip.battle.entity.living.LivingEntity;
@RequiredArgsConstructor
@Getter
public class LivingEntityDeathEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private final LivingEntity entity;
private final org.bukkit.entity.Entity killer;
public static HandlerList getHandlerList() {
return handlers;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
}

View File

@ -0,0 +1,83 @@
package rip.battle.entity.living.impl;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import rip.battle.entity.living.LivingEntity;
import rip.battle.entity.utils.AngleUtils;
import rip.battle.entity.utils.DataWatcherUtil;
import rip.battle.entity.utils.PacketUtils;
import java.util.Collections;
@Setter @Getter
public class VillagerEntity extends LivingEntity {
public VillagerEntity(Location location) {
super(location);
}
@Override
public String getTypeName() {
return "Villager";
}
@Override
public void sendSpawnPackets(Player player) {
DataWatcher dataWatcher = DataWatcherUtil.createDataWatcher();
dataWatcher.a(0, (byte) 0);
dataWatcher.a(1, (short) 300);
dataWatcher.a(2, getCustomName() == null ? "" : getCustomName());
dataWatcher.a(3, (byte) 1);
dataWatcher.a(4, (byte) 1);
dataWatcher.a(6, (float) 1);
dataWatcher.a(10, (byte) 2);
dataWatcher.a(12, (byte) 0);
dataWatcher.a(16, 0);
PacketPlayOutSpawnEntityLiving spawnPacket = new PacketPlayOutSpawnEntityLiving(
getId(),
120,
MathHelper.floor(getLocation().getX() * 32.0D),
MathHelper.floor(getLocation().getY() * 32.0D),
MathHelper.floor(getLocation().getZ() * 32.0D),
dataWatcher);
PacketPlayOutEntity.PacketPlayOutEntityLook lookPacket = new PacketPlayOutEntity.PacketPlayOutEntityLook(
getId(),
AngleUtils.yawToBytes(getLocation().getYaw()),
AngleUtils.yawToBytes(getLocation().getPitch()),
true);
PacketPlayOutEntityHeadRotation headRotationPacket = new PacketPlayOutEntityHeadRotation(
getId(),
AngleUtils.yawToBytes(getLocation().getYaw()));
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(
getId(),
MathHelper.floor(getLocation().getX() * 32.0D),
MathHelper.floor(getLocation().getY() * 32.0D),
MathHelper.floor(getLocation().getZ() * 32.0D),
AngleUtils.yawToBytes(getLocation().getYaw()),
AngleUtils.yawToBytes(getLocation().getPitch()),
true);
PacketUtils.sendPacket(player, spawnPacket);
PacketUtils.sendPacket(player, lookPacket);
PacketUtils.sendPacket(player, headRotationPacket);
PacketUtils.sendPacket(player, teleportPacket);
}
@Override
public void sendUpdatePackets(Player player) {
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata();
packet.setEntityId(getId());
packet.setData(Collections.singletonList(new DataWatcher.WatchableObject(4, 2, getCustomName())));
PacketUtils.sendPacket(player, packet);
}
}

View File

@ -0,0 +1,196 @@
package rip.battle.entity.npc;
import cc.stormworth.core.util.UUIDUtils;
import cc.stormworth.core.util.skin.SkinTexture;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.NPC;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.hologram.api.Hologram;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
public class NPCBuilder {
public NPCEntity npc;
public NPCBuilder(String name, Location location) {
npc = new NPCEntity(name, location);
}
public NPCBuilder setSkin(SkinTexture skin) {
npc.setSkin(skin);
return this;
}
public NPCBuilder setSkin(Player player) {
npc.setSkin(SkinTexture.getPlayerTexture(player));
return this;
}
public NPCBuilder setSkin(String value, String signature) {
npc.setSkin(new SkinTexture(value, signature));
return this;
}
public NPCBuilder setSkin(String name) {
UUID uuid = Bukkit.getOfflinePlayer(name).getUniqueId();
if (uuid == null){
CompletableFuture<UUID> future = UUIDUtils.getUUIDFromMojang(name);
future.thenAccept(uuidFetch -> {
if (uuidFetch == null){
return;
}
CompletableFuture<SkinTexture> skinFuture = UUIDUtils.getSkinFromMojang(uuidFetch);
skinFuture.thenAccept(skinFetch -> {
if (skinFetch == null){
return;
}
npc.setSkin(skinFetch);
});
});
}else {
CompletableFuture<SkinTexture> skinFuture = UUIDUtils.getSkinFromMojang(uuid);
skinFuture.thenAccept(skinFetch -> {
if (skinFetch == null){
return;
}
npc.setSkin(skinFetch);
});
}
return this;
}
public NPCBuilder setDisplayName(String displayName) {
npc.setDisplayName(displayName);
return this;
}
public NPCBuilder setArmor(Player player) {
if (player.getInventory().getHelmet() != null) {
npc.setHelmet(player.getInventory().getHelmet());
}
if (player.getInventory().getChestplate() != null) {
npc.setChestplate(player.getInventory().getChestplate());
}
if (player.getInventory().getLeggings() != null) {
npc.setLeggings(player.getInventory().getLeggings());
}
if (player.getInventory().getBoots() != null) {
npc.setBoots(player.getInventory().getBoots());
}
return this;
}
public NPCBuilder setArmor(ItemStack[] armor){
npc.setArmor(armor);
return this;
}
public NPCBuilder setHelmet(ItemStack helmet) {
npc.setHelmet(helmet);
return this;
}
public NPCBuilder setChestplate(ItemStack chestplate) {
npc.setChestplate(chestplate);
return this;
}
public NPCBuilder setLeggings(ItemStack leggings) {
npc.setLeggings(leggings);
return this;
}
public NPCBuilder setBoots(ItemStack boots) {
npc.setBoots(boots);
return this;
}
public NPCBuilder setItemInHand(ItemStack itemInHand) {
npc.setItemInHand(itemInHand);
return this;
}
public NPCBuilder onInteract(Consumer<Player> consumer) {
npc.setOnLeftClick(consumer);
return this;
}
public NPCBuilder onAttack(Consumer<Player> consumer) {
npc.setOnRightClick(consumer);
return this;
}
public NPCBuilder setHologram(Hologram hologram) {
npc.setHologram(hologram);
return this;
}
public NPCBuilder setCommands(Set<String> commands) {
npc.setCommands(commands);
return this;
}
public NPCBuilder addCommand(String command) {
npc.getCommands().add(command);
return this;
}
public NPCBuilder removeCommand(String command) {
npc.getCommands().remove(command);
return this;
}
public NPCBuilder setMessages(List<String> messages) {
npc.setMessages(messages);
return this;
}
public NPCBuilder addMessage(String message) {
npc.getMessages().add(message);
return this;
}
public NPCBuilder removeMessage(String message) {
npc.getMessages().remove(message);
return this;
}
public NPCBuilder setMessage(int index, String message) {
npc.getMessages().set(index, message);
return this;
}
public NPCBuilder setOnRightClick(Consumer<Player> onRightClick) {
npc.setOnRightClick(onRightClick);
return this;
}
public NPCBuilder setOnLeftClick(Consumer<Player> onLeftClick) {
npc.setOnLeftClick(onLeftClick);
return this;
}
public NPCEntity build() {
return npc;
}
}

View File

@ -0,0 +1,467 @@
package rip.battle.entity.npc;
import cc.stormworth.core.util.TaskUtil;
import cc.stormworth.core.util.chat.CC;
import cc.stormworth.core.util.skin.SkinTexture;
import com.google.common.collect.Lists;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.server.v1_8_R3.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_8_R3.scoreboard.CraftScoreboard;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.plugin.java.JavaPlugin;
import rip.battle.entity.Entity;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.hologram.CraftHologram;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.npc.api.NPC;
import rip.battle.entity.utils.AngleUtils;
import rip.battle.entity.utils.DataWatcherUtil;
import rip.battle.entity.utils.PacketUtils;
import rip.battle.entity.utils.PlayerUtil;
import java.util.*;
@Getter @Setter
public class NPCEntity extends Entity implements NPC {
private final UUID uuid;
private String name;
private String displayName;
private GameProfile gameProfile;
private SkinTexture skin;
private CraftHologram hologram;
private boolean hidden;
private ItemStack itemInHand;
private ItemStack helmet;
private ItemStack chestplate;
private ItemStack leggings;
private ItemStack boots;
private List<String> messages = Lists.newArrayList();
private int supportEntityID;
public NPCEntity(String name, String displayName, Location location) {
super(location);
this.name = name;
this.displayName = CC.translate(displayName);
this.uuid = UUID.randomUUID();
this.gameProfile = new GameProfile(uuid, displayName);
}
public NPCEntity(String name, Location location) {
this(name, name, location);
}
@Override
public String getTypeName() {
return "NPC";
}
@Override
public Hologram getAttachedHologram() {
return hologram;
}
@Override
public void onRightClick(Player player) {
super.onRightClick(player);
if (!getCommands().isEmpty()){
getCommands().forEach(command -> player.performCommand(command.replace("%player%", player.getName())));
}
if (!messages.isEmpty()) {
messages.forEach(player::sendMessage);
}
}
@Override
public void sendSpawnPackets(Player player) {
DataWatcher dataWatcher = DataWatcherUtil.createNPCDataWatcher(this);
PacketPlayOutPlayerInfo addPlayerPacket = new PacketPlayOutPlayerInfo(
PacketPlayOutPlayerInfo.EnumPlayerInfoAction.ADD_PLAYER,
gameProfile,
0,
WorldSettings.EnumGamemode.SURVIVAL,
null);
PacketPlayOutPlayerInfo removePlayerPacket = new PacketPlayOutPlayerInfo(
PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER,
gameProfile,
0,
WorldSettings.EnumGamemode.SURVIVAL,
null);
PacketPlayOutNamedEntitySpawn spawnPacket = new PacketPlayOutNamedEntitySpawn(
getId(),
uuid,
MathHelper.floor(getLocation().getX() * 32.0),
MathHelper.floor(getLocation().getY() * 32.0),
MathHelper.floor(getLocation().getZ() * 32.0),
AngleUtils.yawToBytes(getLocation().getYaw()),
AngleUtils.yawToBytes(getLocation().getPitch()),
0,
dataWatcher
);
PacketPlayOutEntity.PacketPlayOutEntityLook lookPacket = new PacketPlayOutEntity.PacketPlayOutEntityLook(
getId(),
AngleUtils.yawToBytes(getLocation().getYaw()),
AngleUtils.yawToBytes(getLocation().getPitch()),
true
);
PacketPlayOutEntityHeadRotation headRotationPacket = new PacketPlayOutEntityHeadRotation(
getId(),
AngleUtils.yawToBytes(getLocation().getYaw())
);
PacketPlayOutEntityTeleport teleportPacket = new PacketPlayOutEntityTeleport(
getId(),
MathHelper.floor(getLocation().getX() * 32.0),
MathHelper.floor(getLocation().getY() * 32.0),
MathHelper.floor(getLocation().getZ() * 32.0),
AngleUtils.yawToBytes(getLocation().getYaw()),
AngleUtils.yawToBytes(getLocation().getPitch()),
true
);
PacketUtils.sendPacket(player, addPlayerPacket);
TaskUtil.runLater(JavaPlugin.getPlugin(EntityPlugin.class), () -> {
PacketUtils.sendPacket(player, spawnPacket);
if (itemInHand != null) {
PacketUtils.sendPacket(player, new PacketPlayOutEntityEquipment(getId(), 0, CraftItemStack.asNMSCopy(itemInHand)));
}
if (helmet != null) {
PacketUtils.sendPacket(player, new PacketPlayOutEntityEquipment(getId(), 4, CraftItemStack.asNMSCopy(helmet)));
}
if (chestplate != null) {
PacketUtils.sendPacket(player, new PacketPlayOutEntityEquipment(getId(), 3, CraftItemStack.asNMSCopy(chestplate)));
}
if (leggings != null) {
PacketUtils.sendPacket(player, new PacketPlayOutEntityEquipment(getId(), 2, CraftItemStack.asNMSCopy(leggings)));
}
if (boots != null) {
PacketUtils.sendPacket(player, new PacketPlayOutEntityEquipment(getId(), 1, CraftItemStack.asNMSCopy(boots)));
}
TaskUtil.runLater(JavaPlugin.getPlugin(EntityPlugin.class), () -> {
PacketUtils.sendPacket(player, lookPacket);
PacketUtils.sendPacket(player, headRotationPacket);
PacketUtils.sendPacket(player, teleportPacket);
PacketUtils.sendPacket(player, new PacketPlayOutAnimation(getId(), 0));
PacketUtils.sendPacket(player, removePlayerPacket);
if (hologram != null) {
hideNamePlate(player);
}
}, 4L);
if (hologram != null){
hologram.spawnFor(player);
}
}, 1L);
}
@Override
public void sendUpdatePackets(Player player) {
PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata();
packet.setEntityId(getId());
packet.setData(Collections.singletonList(new DataWatcher.WatchableObject(4, 2, displayName)));
PacketUtils.sendPacket(player, packet);
}
@Override
public void updateLocation(Location location) {
super.updateLocation(location);
if (hologram != null){
hologram.updateLocation(calculateHologramLocation());
}
getCurrentWatchersPlayers().forEach(player -> {
PacketUtils.sendPacket(player, new PacketPlayOutEntityHeadRotation(
getId(),
AngleUtils.yawToBytes(getLocation().getYaw())
));
PacketUtils.sendPacket(player, new PacketPlayOutAnimation(
getId(),
0
));
});
}
public Location calculateHologramLocation(){
return getLocation().clone().subtract(0, 0.2, 0);
}
public void setSkin(SkinTexture skin){
this.skin = skin;
if (skin != null) {
gameProfile = new GameProfile(uuid, displayName);
gameProfile.getProperties().put("textures", new Property("textures", skin.getValue(), skin.getSignature()));
}else {
gameProfile = new GameProfile(uuid, displayName);
gameProfile.getProperties().clear();
}
resendForCurrentWatchers();
}
@Override
public void destroy() {
onDelete();
}
@Override
public void onDelete() {
super.onDelete();
if (hologram != null){
hologram.destroy();
}
}
@Override
public void teleport(double x, double y, double z) {
teleport(new Location(getLocation().getWorld(), x, y, z, getLocation().getYaw(), getLocation().getPitch()));
}
@Override
public void teleport(double x, double y, double z, float yaw, float pitch) {
teleport(new Location(getLocation().getWorld(), x, y, z, yaw, pitch));
}
public void teleport(Location location) {
updateLocation(location);
}
@Override
public void teleport(Location location, float yaw, float pitch) {
Location newLocation = location.clone();
newLocation.setYaw(yaw);
newLocation.setPitch(pitch);
updateLocation(newLocation);
}
protected void updateTexture(SkinTexture skin){
this.skin = skin;
if (skin != null) {
gameProfile = new GameProfile(uuid, displayName);
gameProfile.getProperties().put("textures", new Property("textures", skin.getValue(), skin.getSignature()));
for (Player player : getCurrentWatchersPlayers()) {
destroy(player);
spawn(player);
}
}
}
public void updateItemInHand(ItemStack itemInHand) {
this.itemInHand = itemInHand;
for (Player player : getCurrentWatchersPlayers()){
PacketUtils.sendPacket(player, new PacketPlayOutEntityEquipment(getId(), 0, CraftItemStack.asNMSCopy(itemInHand == null ? new ItemStack(Material.AIR) : itemInHand)));
}
}
public void setHelmet(ItemStack helmet) {
this.helmet = helmet;
for (Player player : getCurrentWatchersPlayers()){
PacketUtils.sendPacket(player, new PacketPlayOutEntityEquipment(getId(), 4, CraftItemStack.asNMSCopy(helmet == null ? new ItemStack(Material.AIR) : helmet)));
}
}
public void setChestplate(ItemStack chestplate) {
this.chestplate = chestplate;
for (Player player : getCurrentWatchersPlayers()){
PacketUtils.sendPacket(player, new PacketPlayOutEntityEquipment(getId(), 3, CraftItemStack.asNMSCopy(chestplate == null ? new ItemStack(Material.AIR) : chestplate)));
}
}
public void setLeggings(ItemStack leggings) {
this.leggings = leggings;
for (Player player : getCurrentWatchersPlayers()){
PacketUtils.sendPacket(player, new PacketPlayOutEntityEquipment(getId(), 2, CraftItemStack.asNMSCopy(leggings == null ? new ItemStack(Material.AIR) : leggings)));
}
}
public void setBoots(ItemStack boots) {
this.boots = boots;
for (Player player : getCurrentWatchersPlayers()){
PacketUtils.sendPacket(player, new PacketPlayOutEntityEquipment(getId(), 1, CraftItemStack.asNMSCopy(boots == null ? new ItemStack(Material.AIR) : boots)));
}
}
public void setHologram(Hologram hologram) {
this.hologram = (CraftHologram) hologram;
if (hologram != null){
this.hologram.updateLocation(calculateHologramLocation());
((CraftHologram) hologram).setParent(this);
for (Player player : getCurrentWatchersPlayers()){
hideNamePlate(player);
this.hologram.spawnFor(player);
}
}else{
for (Player player : getCurrentWatchersPlayers()){
showNamePlate(player);
}
}
updateForCurrentWatchers();
}
protected void hideNamePlate(Player player){
if (PlayerUtil.isLegacy(player)){
if (supportEntityID == 0){
supportEntityID = nextId();
DataWatcher slimeDatawatcher = DataWatcherUtil.createDataWatcher();
slimeDatawatcher.a(0, (byte) 0);
slimeDatawatcher.a(1, (short) 0);
slimeDatawatcher.a(2, "");
slimeDatawatcher.a(3, (byte) 0);
slimeDatawatcher.a(4, (byte) 0);
slimeDatawatcher.a(16, (byte) -2);
PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(
supportEntityID,
55,
MathHelper.floor(getLocation().getX() * 32.0D),
MathHelper.floor(getLocation().getY() * 32.0D),
MathHelper.floor(getLocation().getZ() * 32.0D),
slimeDatawatcher
);
PacketUtils.sendPacket(player, packet);
}
PacketUtils.sendPacket(player, new PacketPlayOutAttachEntity(0, supportEntityID, getId()));
}else {
ScoreboardTeam team = new ScoreboardTeam(((CraftScoreboard) Bukkit.getScoreboardManager().getMainScoreboard()).getHandle(),
getDisplayName());
team.setNameTagVisibility(ScoreboardTeamBase.EnumNameTagVisibility.NEVER);
PacketUtils.sendPacket(player, new PacketPlayOutScoreboardTeam(team, 1));
PacketUtils.sendPacket(player, new PacketPlayOutScoreboardTeam(team, 0));
PacketUtils.sendPacket(player, new PacketPlayOutScoreboardTeam(team, new ArrayList<String>(){{add(getDisplayName());}}, 3));
}
}
protected void showNamePlate(Player player){
if (PlayerUtil.isLegacy(player)){
PacketUtils.sendPacket(player, new PacketPlayOutAttachEntity(0, supportEntityID, 0));
PacketUtils.sendPacket(player, new PacketPlayOutEntityDestroy(supportEntityID));
supportEntityID = 0;
}else {
ScoreboardTeam team = new ScoreboardTeam(((CraftScoreboard) Bukkit.getScoreboardManager().getMainScoreboard()).getHandle(),
getDisplayName());
team.setNameTagVisibility(ScoreboardTeamBase.EnumNameTagVisibility.ALWAYS);
PacketUtils.sendPacket(player, new PacketPlayOutScoreboardTeam(team, 1));
PacketUtils.sendPacket(player, new PacketPlayOutScoreboardTeam(team, 0));
PacketUtils.sendPacket(player, new PacketPlayOutScoreboardTeam(team, new ArrayList<String>(){{add(getDisplayName());}}, 3));
}
}
@Override
public void sendDestroyPackets(Player player) {
PacketUtils.sendPacket(player, new PacketPlayOutEntityDestroy(supportEntityID));
super.sendDestroyPackets(player);
}
@Override
public void setArmor(Player player) {
PlayerInventory inventory = player.getInventory();
setHelmet(inventory.getHelmet());
setChestplate(inventory.getChestplate());
setLeggings(inventory.getLeggings());
setBoots(inventory.getBoots());
}
@Override
public void setArmor(ItemStack[] armor) {
setHelmet(armor[3]);
setChestplate(armor[2]);
setLeggings(armor[1]);
setBoots(armor[0]);
}
@Override
public void setArmor(ItemStack helmet, ItemStack chestplate, ItemStack leggings, ItemStack boots) {
setHelmet(helmet);
setChestplate(chestplate);
setLeggings(leggings);
setBoots(boots);
}
@Override
public void setItemInHand(ItemStack itemInHand) {
this.itemInHand = itemInHand;
updateItemInHand(itemInHand);
}
@Override
public void setDisplayName(String displayName) {
this.displayName = CC.translate(displayName);
this.gameProfile = new GameProfile(uuid, CC.translate(displayName));
if (skin != null) {
gameProfile.getProperties().put("textures", new Property("textures", skin.getValue(), skin.getSignature()));
}
resendForCurrentWatchers();
}
}

View File

@ -0,0 +1,116 @@
package rip.battle.entity.npc;
import cc.stormworth.core.util.serialize.ItemStackAdapter;
import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import lombok.Getter;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.hologram.serialization.HologramTypeAdapter;
import rip.battle.entity.npc.api.NPC;
import rip.battle.entity.npc.serialization.NPCTypeAdapter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
@Getter
public class NPCManager {
private final Map<String, NPC> npcs = Maps.newHashMap();
private final EntityPlugin plugin;
public NPCManager(EntityPlugin plugin) {
this.plugin = plugin;
loadNPCs();
}
public void loadNPCs() {
File file = new File(plugin.getDataFolder(), "npcs");
if (!file.exists()){
return;
}
Arrays.stream(file.listFiles()).forEach(file1 -> {
FileReader fileReader;
try {
fileReader = new FileReader(file1);
JsonElement jsonElement = new Gson().fromJson(fileReader, JsonElement.class);
NPC npc = NPCTypeAdapter.fromJson(jsonElement);
npcs.put(file1.getName().replace(".json", ""), npc);
System.out.println("Loaded NPC: " + npc.getName());
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
});
}
public void saveNPCs(){
Gson gson = new GsonBuilder()
.registerTypeAdapter(ItemStack.class, new ItemStackAdapter())
.registerTypeAdapter(Hologram.class, new HologramTypeAdapter())
.enableComplexMapKeySerialization()
.setPrettyPrinting()
.create();
File file = new File(plugin.getDataFolder(), "npcs");
if (!file.exists())
file.mkdirs();
npcs.forEach((name, hologram) -> {
try {
FileWriter writer = new FileWriter(new File(plugin.getDataFolder(),
File.separator + "npcs" + File.separator + name + ".json"));
writer.write(gson.toJson(NPCTypeAdapter.toJson(hologram)));
System.out.println("Saved NPC: " + name);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
});
}
public void addNPC(NPC npc) {
npcs.put(npc.getName(), npc);
}
public void removeNPC(NPC npc) {
npc.destroy();
npcs.remove(npc.getName());
File file = new File(plugin.getDataFolder(), "npcs" + File.separator + npc.getName() + ".json");
if (file.exists())
file.delete();
}
public NPC getNPC(String name) {
return npcs.get(name);
}
public void createNPC(String name, Location location) {
NPC npc = new NPCEntity(name, location);
npc.spawn();
addNPC(npc);
}
}

View File

@ -0,0 +1,90 @@
package rip.battle.entity.npc.api;
import cc.stormworth.core.util.skin.SkinTexture;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.hologram.api.Hologram;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
public interface NPC {
String getName();
void setSkin(SkinTexture skin);
SkinTexture getSkin();
void destroy();
void destroy(Player player);
void spawn();
void spawn(Player player);
void updateVisibility(boolean hidden);
void updateVisibilityFor(Player player, boolean hidden);
boolean isVisible();
boolean isVisibleTo(Player player);
void teleport(double x, double y, double z);
void teleport(double x, double y, double z, float yaw, float pitch);
void teleport(Location location);
void teleport(Location location, float yaw, float pitch);
Location getLocation();
ItemStack getHelmet();
ItemStack getChestplate();
ItemStack getLeggings();
ItemStack getBoots();
ItemStack getItemInHand();
void setHelmet(ItemStack itemStack);
void setChestplate(ItemStack itemStack);
void setLeggings(ItemStack itemStack);
void setBoots(ItemStack itemStack);
void setItemInHand(ItemStack itemStack);
void setArmor(Player player);
void setArmor(ItemStack[] armor);
void setArmor(ItemStack helmet, ItemStack chestplate, ItemStack leggings, ItemStack boots);
void setDisplayName(String displayName);
String getDisplayName();
Hologram getHologram();
void setHologram(Hologram hologram);
void setMessages(List<String> messages);
List<String> getMessages();
Set<String> getCommands();
void setOnRightClick(Consumer<Player> onRightClick);
void setOnLeftClick(Consumer<Player> onLeftClick);
}

View File

@ -0,0 +1,33 @@
package rip.battle.entity.npc.commands;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import org.bukkit.entity.Player;
public class NPCCommand {
@Command(name = "", desc = "Allows you to manage your npc", usage = "<subcommand>")
public void npc(@Sender Player player) {
player.sendMessage(CC.translate("&e&lNPC Commands"));
player.sendMessage(CC.translate("&e/npc create <name> &7- &fCreates a npc with the given name."));
player.sendMessage(CC.translate("&e/npc remove <name> &7- &fRemoves a npc with the given name."));
player.sendMessage(CC.translate("&e/npc setline <name> <line> [text] &7- &fSets a line on a npc."));
player.sendMessage(CC.translate("&e/npc removeline <name> <line> &7- &fRemoves a line from a npc."));
player.sendMessage(CC.translate("&e/npc addline <name> <text> &7- &fAdds a line to a npc."));
player.sendMessage(CC.translate("&e/npc additemline <name> <item> &7- &fAdds a line with an item to a npc."));
player.sendMessage(CC.translate("&e/npc teleport <name> &7- &fTeleports you to a npc."));
player.sendMessage(CC.translate("&e/npc movehere <name> &7- &fSets the location of a npc."));
player.sendMessage(CC.translate("&e/npc setdisplayname <name> <displayname> &7- &fSets the display name of a npc."));
player.sendMessage(CC.translate("&e/npc setskin <name> <skin> &7- &fSets the skin of a npc."));
player.sendMessage(CC.translate("&e/npc setarmor <name> &7- &fSets your armor as the armor of a npc."));
player.sendMessage(CC.translate("&e/npc setitem <name> <slot> &7- &fSets your item in hand as the item in hand of a npc."));
player.sendMessage(CC.translate("&e/npc sethelmet <name> &7- &fSets your helmet as the helmet of a npc."));
player.sendMessage(CC.translate("&e/npc setchestplate <name> &7- &fSets your chestplate as the chestplate of a npc."));
player.sendMessage(CC.translate("&e/npc setleggings <name> &7- &fSets your leggings as the leggings of a npc."));
player.sendMessage(CC.translate("&e/npc setboots <name> &7- &fSets your boots as the boots of a npc."));
player.sendMessage(CC.translate("&e/npc list &7- &fLists all npcs."));
}
}

View File

@ -0,0 +1,46 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import com.jonahseguin.drink.annotation.Text;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.hologram.impl.UpdatableHologram;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCAddItemLineSubCommand {
private final NPCManager npcManager;
@Command(name = "additemline", desc = "Allows you to add a item line to a npc", usage = "<name>")
public void addLine(@Sender Player player, String name) {
NPC npc = npcManager.getNPC(name);
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
if (npc.getHologram() == null){
npc.setHologram(new UpdatableHologram(npc.getName() + "_hologram", npc.getLocation()));
}
ItemStack item = player.getItemInHand();
if (item == null) {
player.sendMessage(CC.translate("&cYou must be holding an item in your hand."));
return;
}
npc.getHologram().addLine(item);
player.sendMessage(CC.translate("&aYou have added a line to the npc &f" + name + "&a."));
}
}

View File

@ -0,0 +1,37 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import com.jonahseguin.drink.annotation.Text;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.impl.UpdatableHologram;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCAddLineSubCommand {
private final NPCManager npcManager;
@Command(name = "addline", desc = "Allows you to add a line to a npc", usage = "<name> <line>")
public void addLine(@Sender Player player, String name, @Text String line) {
NPC npc = npcManager.getNPC(name);
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
if (npc.getHologram() == null){
npc.setHologram(new UpdatableHologram(npc.getName() + "_hologram", npc.getLocation()));
}
npc.getHologram().addLine(line);
player.sendMessage(CC.translate("&aYou have added a line to the npc &f" + name + "&a."));
}
}

View File

@ -0,0 +1,27 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
@RequiredArgsConstructor
public class NPCCreateSubCommand {
private final NPCManager npcManager;
@Command(name = "create", desc = "Allows you to create a npc", usage = "<name>")
public void create(@Sender Player player, String name) {
if (npcManager.getNPC(name) != null) {
player.sendMessage(CC.translate("&cA npc with that name already exists."));
return;
}
npcManager.createNPC(name, player.getLocation());
player.sendMessage(CC.translate("&aYou have created a npc with the name &f" + name + "&a."));
}
}

View File

@ -0,0 +1,32 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCDeleteSubCommand {
private final NPCManager npcManager;
@Command(name = "delete", desc = "Allows you to delete a npc", usage = "<name>")
public void delete(@Sender Player player, String name) {
NPC npc = npcManager.getNPC(name);
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
npc.destroy();
npcManager.removeNPC(npc);
player.sendMessage(CC.translate("&aYou have deleted the npc &f" + name + "&a."));
}
}

View File

@ -0,0 +1,31 @@
package rip.battle.entity.npc.commands.sub;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
import rip.battle.entity.npc.menu.NPCEditMenu;
@RequiredArgsConstructor
public class NPCEditSubCommand {
private final EntityPlugin plugin;
private final NPCManager npcManager;
@Command(name = "edit", desc = "Edit an NPC")
public void edit(@Sender Player player, String name){
NPC npc = npcManager.getNPC(name);
if (npc == null){
player.sendMessage(ChatColor.RED + "NPC not found.");
return;
}
new NPCEditMenu(npc, plugin).open(player);
}
}

View File

@ -0,0 +1,43 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
import java.util.Map;
@RequiredArgsConstructor
public class NPCListCommand {
private final NPCManager npcManager;
@Command(name = "list", desc = "List all NPCs", usage = "/npc list", aliases = {"l", "ls"})
public void list(@Sender Player player){
Map<String, NPC> npcs = npcManager.getNpcs();
if (npcs.isEmpty()) {
player.sendMessage(CC.translate("&cThere are no npcs."));
return;
}
player.sendMessage(CC.translate("&aThere are &e" + npcs.size() + " &anpcs."));
npcs.forEach((name, npc) -> {
ComponentBuilder builder = new ComponentBuilder(CC.translate("&e" + name + " &b[Click to teleport]"));
builder.event(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ComponentBuilder(CC.translate("&7Click to teleport")).create()));
builder.event(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/npc tp " + name));
player.spigot().sendMessage(builder.create());
});
}
}

View File

@ -0,0 +1,30 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCMoveHereSubCommand {
private final NPCManager npcManager;
@Command(name = "movehere", desc = "Allows you to move a npc to your location", usage = "<name>", aliases = {"mh", "s", "teleporto", "teleporthere"})
public void moveHere(@Sender Player player, String name) {
NPC npc = npcManager.getNPC(name);
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
npc.teleport(player.getLocation());
player.sendMessage(CC.translate("&aYou have moved the npc &f" + name + "&a to your location."));
}
}

View File

@ -0,0 +1,49 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.hologram.api.Hologram;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCRemoveLineSubCommand {
private final NPCManager npcManager;
@Command(name = "removeline", desc = "Allows you to remove a line from a npc", usage = "<name> <line>")
public void removeLine(@Sender Player player, String name, int line) {
NPC npc = npcManager.getNPC(name);
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
Hologram hologram = npc.getHologram();
if (hologram == null) {
player.sendMessage(CC.translate("&cThis npc does not have a hologram."));
return;
}
if (line > hologram.getLines().size()) {
player.sendMessage(CC.translate("&cThis npc does not have a line with that index."));
return;
}
if (hologram.getLines().size() == 1) {
hologram.destroy();
npc.setHologram(null);
}else{
hologram.removeLine(line);
}
player.sendMessage(CC.translate("&aYou have removed the line &f" + line + " &afrom the npc &f" + name + "&a."));
}
}

View File

@ -0,0 +1,31 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCSetArmorSubCommand {
private final NPCManager npcManager;
@Command(name = "setarmor", desc = "Allows you to set the armor of a npc", usage = "<name>")
public void setArmor(@Sender Player player, String name) {
NPC npc = npcManager.getNPC(name);
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
npc.setArmor(player);
player.sendMessage(CC.translate("&aYou have set your armor to the npc &f" + name + "&a."));
}
}

View File

@ -0,0 +1,29 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCSetBootsSubCommand {
private final NPCManager npcManager;
@Command(name = "setboots", desc = "Sets the boots of a npc")
public void setBoots(@Sender Player player){
NPC npc = npcManager.getNPC(player.getName());
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
npc.setBoots(player.getInventory().getBoots());
player.sendMessage(CC.translate("&aYou have set the boots of the npc &f" + npc.getName() + "&a."));
}
}

View File

@ -0,0 +1,29 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCSetChestPlateSubCommand {
private final NPCManager npcManager;
@Command(name = "setchestplate", desc = "Sets the chestplate of a npc")
public void setBoots(@Sender Player player){
NPC npc = npcManager.getNPC(player.getName());
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
npc.setChestplate(player.getInventory().getChestplate());
player.sendMessage(CC.translate("&aYou have set the chestplate of the npc &f" + npc.getName() + "&a."));
}
}

View File

@ -0,0 +1,30 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCSetDisplaynameSubCommand {
private final NPCManager npcManager;
@Command(name = "setdisplayname", desc = "Allows you to set the display name of a npc", usage = "<name> <displayname>")
public void setDisplayname(@Sender Player player, String name, String displayName) {
NPC npc = npcManager.getNPC(name);
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
npc.setDisplayName(displayName);
player.sendMessage(CC.translate("&aYou have set the display name of the npc &f" + name + " &ato &f" + displayName + "&a."));
}
}

View File

@ -0,0 +1,30 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCSetHelmetSubCommand {
private final NPCManager npcManager;
@Command(name = "sethelmet", desc = "Sets the helmet of a npc")
public void setBoots(@Sender Player player){
NPC npc = npcManager.getNPC(player.getName());
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
npc.setHelmet(player.getInventory().getHelmet());
player.sendMessage(CC.translate("&aYou have set the helmet of the npc &f" + npc.getName() + "&a."));
}
}

View File

@ -0,0 +1,30 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCSetItemInHandSubCommand {
private final NPCManager npcManager;
@Command(name = "setitemhand", desc = "Sets the item in hand of a npc", aliases = "setitem")
public void setBoots(@Sender Player player){
NPC npc = npcManager.getNPC(player.getName());
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
npc.setItemInHand(player.getInventory().getItemInHand());
player.sendMessage(CC.translate("&aYou have set the item in hand of the npc &f" + npc.getName() + "&a."));
}
}

View File

@ -0,0 +1,30 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCSetLeggingsSubCommand {
private final NPCManager npcManager;
@Command(name = "setleggings", desc = "Sets the leggings of a npc")
public void setBoots(@Sender Player player){
NPC npc = npcManager.getNPC(player.getName());
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
npc.setLeggings(player.getInventory().getLeggings());
player.sendMessage(CC.translate("&aYou have set the leggings of the npc &f" + npc.getName() + "&a."));
}
}

View File

@ -0,0 +1,78 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.OptArg;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.hologram.lines.HologramLine;
import rip.battle.entity.hologram.lines.impl.ItemLine;
import rip.battle.entity.hologram.lines.impl.TextLine;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCSetLineSubCommand {
private final NPCManager npcManager;
public void setLine(@Sender Player player, String name, int line, @OptArg String text) {
NPC npc = npcManager.getNPC(name);
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
if (npc.getHologram() == null) {
player.sendMessage(CC.translate("&cThis npc does not have a hologram."));
return;
}
if (line > npc.getHologram().getLines().size()) {
player.sendMessage(CC.translate("&cThis npc does not have a line with that index."));
return;
}
HologramLine<?> hologramLine = npc.getHologram().getLines().get(line);
if (hologramLine instanceof ItemLine){
if (text != null){
player.sendMessage(CC.translate("&cYou cannot set the text of an item line."));
return;
}
ItemStack item = player.getItemInHand();
if (item == null){
player.sendMessage(CC.translate("&cYou must be holding an item to set the item line."));
return;
}
((ItemLine) hologramLine).setItemStack(item);
hologramLine.updateForCurrentWatchers();
player.sendMessage(CC.translate("&aYou have set the item line &f" + line + " &afor the npc &f" + name + "&a."));
}else {
if (text == null) {
player.sendMessage(CC.translate("&cYou must provide text to set the text line."));
return;
}
((TextLine) hologramLine).setText(other -> text);
TextLine textLine = (TextLine) hologramLine;
textLine.setLine(text);
hologramLine.updateForCurrentWatchers();
player.sendMessage(CC.translate("&aYou have set the line &f" + line + " &afor the npc &f" + name + "&a."));
}
}
}

View File

@ -0,0 +1,55 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import cc.stormworth.core.util.skin.SkinTexture;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.OptArg;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
@RequiredArgsConstructor
public class NPCSetSkinSubCommand {
private final NPCManager npcManager;
@Command(name = "setskin", desc = "Allows you to set the skin of a npc", usage = "<name> <skin>")
public void setSkin(@Sender Player player, String name, @OptArg String username) {
if (username == null) {
username = player.getName();
}
NPC npc = npcManager.getNPC(name);
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
if (Objects.equals(username, player.getName())){
npc.setSkin(SkinTexture.getPlayerTexture(player));
player.sendMessage(CC.translate("&aYou have set your skin to the npc &f" + name + "&a."));
} else {
CompletableFuture<SkinTexture> skinFuture = SkinTexture.getSkinFromUsername(username);
String finalUsername = username;
skinFuture.thenAccept(skin -> {
if (skin == null) {
player.sendMessage(CC.translate("&cA skin with that name does not exist."));
return;
}
npc.setSkin(skin);
player.sendMessage(CC.translate("&aYou have set the skin of the npc &f" + name + "&a to &f" + finalUsername + "&a."));
});
}
}
}

View File

@ -0,0 +1,31 @@
package rip.battle.entity.npc.commands.sub;
import cc.stormworth.core.util.chat.CC;
import com.jonahseguin.drink.annotation.Command;
import com.jonahseguin.drink.annotation.Sender;
import lombok.RequiredArgsConstructor;
import org.bukkit.entity.Player;
import rip.battle.entity.npc.NPCManager;
import rip.battle.entity.npc.api.NPC;
@RequiredArgsConstructor
public class NPCTeleportSubCommand {
private final NPCManager npcManager;
@Command(name = "teleport", desc = "Allows you to teleport to a hologram", usage = "<name>", aliases = "tp")
public void teleport(@Sender Player player, String name) {
NPC npc = npcManager.getNPC(name);
if (npc == null) {
player.sendMessage(CC.translate("&cA npc with that name does not exist."));
return;
}
player.teleport(npc.getLocation());
player.sendMessage(CC.translate("&aYou have teleported to the npc &f" + name + "&a."));
}
}

View File

@ -0,0 +1,88 @@
package rip.battle.entity.npc.menu;
import cc.stormworth.core.util.inventory.ItemBuilder;
import cc.stormworth.core.util.menu.Menu;
import cc.stormworth.core.util.menu.button.Button;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.npc.api.NPC;
import rip.battle.entity.utils.ArmorPiece;
import java.util.Map;
@RequiredArgsConstructor
public class NPCEditArmorMenu extends Menu {
private final EntityPlugin plugin;
private final NPC npc;
@Override
public String getTitle(Player player) {
return "&eEditing armor for NPC &6" + npc.getName();
}
@Override
public int getRows(Player player) {
return 3;
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
buttons.put(0, new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
return new ItemBuilder(Material.BED).setName("&cBack").toItemStack();
}
@Override
public void onClick(Player player) {
new NPCEditMenu(npc, plugin).open(player);
}
});
buttons.put(getSlot(1, 2), new EditArmorPieceButton(npc.getHelmet(), ArmorPiece.HELMET));
buttons.put(getSlot(1, 3), new EditArmorPieceButton(npc.getChestplate(), ArmorPiece.CHESTPLATE));
buttons.put(getSlot(1, 4), new EditArmorPieceButton(npc.getLeggings(), ArmorPiece.LEGGINGS));
buttons.put(getSlot(1, 5), new EditArmorPieceButton(npc.getBoots(), ArmorPiece.BOOTS));
return buttons;
}
@RequiredArgsConstructor
public class EditArmorPieceButton extends Button{
private final ItemStack itemStack;
private final ArmorPiece armorPiece;
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(itemStack == null ? Material.INK_SACK : itemStack.getType());
if (itemStack == null) {
builder.setDurability((short) 8);
}
builder.setName("&6" + armorPiece.name().toLowerCase());
builder.addLore(
"",
"&7Click to change the " + armorPiece.name().toLowerCase()
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
new NPCSelectArmorPieceMenu(plugin, npc, armorPiece).open(player);
}
}
}

View File

@ -0,0 +1,292 @@
package rip.battle.entity.npc.menu;
import cc.stormworth.core.util.chat.CC;
import cc.stormworth.core.util.chat.ChatUtils;
import cc.stormworth.core.util.inventory.ItemBuilder;
import cc.stormworth.core.util.menu.Menu;
import cc.stormworth.core.util.menu.button.Button;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.hologram.menu.HologramEditMenu;
import rip.battle.entity.npc.api.NPC;
import rip.battle.entity.npc.prompt.NPCChangeDisplayNamePrompt;
import java.util.Map;
@RequiredArgsConstructor
public class NPCEditMenu extends Menu {
private final NPC npc;
private final EntityPlugin plugin;
@Override
public String getTitle(Player player) {
return "&eEditing NPC &6" + npc.getName();
}
@Override
public int getRows(Player player) {
return 5;
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
buttons.put(getSlot(1, 2), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.NAME_TAG);
builder.setName("&6Change Display Name");
builder.addLore(
"",
"&7Current: &e" + npc.getDisplayName(),
"",
"&7Click to change the display name"
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
ChatUtils.beginPrompt(player, new NPCChangeDisplayNamePrompt(plugin, npc), plugin);
}
});
buttons.put(getSlot(1, 4), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.SKULL_ITEM);
builder.setDurability((short) 3);
builder.setName("&6Change Skin");
builder.addLore(
"",
"&7Click to change the skin"
);
if (npc.getSkin() != null){
builder.setTexture(npc.getSkin().getValue());
}
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
new NPCSkinMenu(npc, plugin).open(player);
}
});
buttons.put(getSlot(1, 6), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.ENDER_PEARL);
builder.setName("&6Teleport");
builder.addLore(
"",
"&7Click to teleport to the NPC"
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
player.closeInventory();
player.teleport(npc.getLocation());
}
});
buttons.put(getSlot(2, 2), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.BARRIER);
builder.setName("&6Delete");
builder.addLore(
"",
"&7Click to delete the NPC"
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
player.closeInventory();
plugin.getNpcManager().removeNPC(npc);
player.sendMessage(CC.translate("&aSuccessfully deleted NPC &6" + npc.getName()));
}
});
buttons.put(getSlot(2, 4), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.POTION);
builder.setDurability((short) 8238);
builder.setName("&6Change Visibility");
builder.addLore(
"",
"&7Current: " + (npc.isVisible() ? "&aVisible" : "&cHidden"),
"",
"&7Click to change the visibility"
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
npc.updateVisibility(npc.isVisible());
player.sendMessage(CC.translate("&aSuccessfully " + (npc.isVisible() ? "showed" : "hidden") + " NPC &6" + npc.getName()));
}
});
buttons.put(getSlot(2, 6), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.DIAMOND_CHESTPLATE);
builder.setName("&6Edit Armor");
builder.addLore(
"",
"&7Click to edit the armor"
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
new NPCEditArmorMenu(plugin, npc).open(player);
}
});
if (npc.getHologram() != null){
buttons.put(getSlot(3, 3), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(npc.getItemInHand() == null ? Material.INK_SACK : npc.getItemInHand().getType());
if (npc.getItemInHand() != null) {
builder.setDurability(npc.getItemInHand().getDurability());
}else {
builder.setDurability((short) 8);
}
builder.setName("&6Edit Item In Hand");
builder.addLore(
"",
"&7Click with item to set the item in hand of npc"
);
return builder.toItemStack();
}
@Override
public void onClick(InventoryClickEvent event) {
if (event.getCursor() != null && event.getCursor().getType() != Material.AIR) {
npc.setItemInHand(event.getCursor());
player.sendMessage(CC.translate("&aSuccessfully set item in hand of NPC &6" + npc.getName()));
event.setCursor(null);
player.playSound(player.getLocation(), Sound.CLICK, 1F, 1F);
}else {
player.sendMessage(CC.translate("&cYou must have an item in your cursor to set the item in hand of the NPC"));
}
}
});
buttons.put(getSlot(3, 5), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.PAPER);
builder.setName("&6Edit Hologram");
builder.addLore(
"",
"&7Click to edit the hologram"
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
new HologramEditMenu(plugin, npc.getHologram(), NPCEditMenu.this).open(player);
}
});
}else{
buttons.put(getSlot(3, 4), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(npc.getItemInHand() == null ? Material.INK_SACK : npc.getItemInHand().getType());
if (npc.getItemInHand() != null) {
builder.setDurability(npc.getItemInHand().getDurability());
}else {
builder.setDurability((short) 8);
}
builder.setName("&6Edit Item In Hand");
builder.addLore(
"",
"&7Click with item to set the item in hand of npc"
);
return builder.toItemStack();
}
@Override
public void onClick(InventoryClickEvent event) {
if (event.getCursor() != null && event.getCursor().getType() != Material.AIR) {
npc.setItemInHand(event.getCursor());
player.sendMessage(CC.translate("&aSuccessfully set item in hand of NPC &6" + npc.getName()));
event.setCursor(null);
player.playSound(player.getLocation(), Sound.CLICK, 1F, 1F);
}else {
player.sendMessage(CC.translate("&cYou must have an item in your cursor to set the item in hand of the NPC"));
}
}
});
}
return buttons;
}
}

View File

@ -0,0 +1,171 @@
package rip.battle.entity.npc.menu;
import cc.stormworth.core.util.inventory.ItemBuilder;
import cc.stormworth.core.util.menu.Menu;
import cc.stormworth.core.util.menu.button.Button;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.npc.api.NPC;
import rip.battle.entity.utils.ArmorPiece;
import java.util.Map;
@RequiredArgsConstructor
public class NPCSelectArmorPieceMenu extends Menu {
private final EntityPlugin plugin;
private final NPC npc;
private final ArmorPiece armorPiece;
@Override
public String getTitle(Player player) {
return "&eSelect a " + armorPiece.name() + " for NPC &6" + npc.getName();
}
@Override
public int getRows(Player player) {
return 3;
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
buttons.put(0, new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
return new ItemBuilder(Material.BED).setName("&cBack").toItemStack();
}
@Override
public void onClick(Player player) {
new NPCEditArmorMenu(plugin, npc).open(player);
}
});
if (armorPiece == ArmorPiece.HELMET) {
buttons.put(getSlot(1, 2), new ArmorPieceButton(getPiece("leather")));
buttons.put(getSlot(1, 3), new ArmorPieceButton(getPiece("chainmail")));
buttons.put(getSlot(1, 4), new ArmorPieceButton(getPiece("iron")));
buttons.put(getSlot(1, 5), new ArmorPieceButton(getPiece("gold")));
buttons.put(getSlot(1, 6), new ArmorPieceButton(getPiece("diamond")));
} else if (armorPiece == ArmorPiece.CHESTPLATE) {
buttons.put(getSlot(1, 2), new ArmorPieceButton(getPiece("leather")));
buttons.put(getSlot(1, 3), new ArmorPieceButton(getPiece("chainmail")));
buttons.put(getSlot(1, 4), new ArmorPieceButton(getPiece("iron")));
buttons.put(getSlot(1, 5), new ArmorPieceButton(getPiece("gold")));
buttons.put(getSlot(1, 6), new ArmorPieceButton(getPiece("diamond")));
} else if (armorPiece == ArmorPiece.LEGGINGS) {
buttons.put(getSlot(1, 2), new ArmorPieceButton(getPiece("leather")));
buttons.put(getSlot(1, 3), new ArmorPieceButton(getPiece("chainmail")));
buttons.put(getSlot(1, 4), new ArmorPieceButton(getPiece("iron")));
buttons.put(getSlot(1, 5), new ArmorPieceButton(getPiece("gold")));
buttons.put(getSlot(1, 6), new ArmorPieceButton(getPiece("diamond")));
} else if (armorPiece == ArmorPiece.BOOTS) {
buttons.put(getSlot(1, 2), new ArmorPieceButton(getPiece("leather")));
buttons.put(getSlot(1, 3), new ArmorPieceButton(getPiece("chainmail")));
buttons.put(getSlot(1, 4), new ArmorPieceButton(getPiece("iron")));
buttons.put(getSlot(1, 5), new ArmorPieceButton(getPiece("gold")));
buttons.put(getSlot(1, 6), new ArmorPieceButton(getPiece("diamond")));
}
return buttons;
}
@RequiredArgsConstructor
public class ArmorPieceButton extends Button {
private final ItemStack item;
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder itemBuilder = new ItemBuilder(item.getType());
itemBuilder.addLore(
"",
"&7Click to select this " + armorPiece.name().toLowerCase()
);
return itemBuilder.toItemStack();
}
@Override
public void onClick(Player player) {
if (armorPiece == ArmorPiece.HELMET) {
npc.setHelmet(item);
} else if (armorPiece == ArmorPiece.CHESTPLATE) {
npc.setChestplate(item);
} else if (armorPiece == ArmorPiece.LEGGINGS) {
npc.setLeggings(item);
} else if (armorPiece == ArmorPiece.BOOTS) {
npc.setBoots(item);
}
new NPCEditArmorMenu(plugin, npc).open(player);
}
}
public ItemStack getPiece(String type) {
if (type.equalsIgnoreCase("leather")) {
if (armorPiece == ArmorPiece.HELMET){
return new ItemStack(Material.LEATHER_HELMET);
} else if (armorPiece == ArmorPiece.CHESTPLATE) {
return new ItemStack(Material.LEATHER_CHESTPLATE);
} else if (armorPiece == ArmorPiece.LEGGINGS) {
return new ItemStack(Material.LEATHER_LEGGINGS);
} else if (armorPiece == ArmorPiece.BOOTS) {
return new ItemStack(Material.LEATHER_BOOTS);
}
}else if (type.equalsIgnoreCase("chainmail")) {
if (armorPiece == ArmorPiece.HELMET) {
return new ItemStack(Material.CHAINMAIL_HELMET);
} else if (armorPiece == ArmorPiece.CHESTPLATE) {
return new ItemStack(Material.CHAINMAIL_CHESTPLATE);
} else if (armorPiece == ArmorPiece.LEGGINGS) {
return new ItemStack(Material.CHAINMAIL_LEGGINGS);
} else if (armorPiece == ArmorPiece.BOOTS) {
return new ItemStack(Material.CHAINMAIL_BOOTS);
}
} else if (type.equalsIgnoreCase("iron")) {
if (armorPiece == ArmorPiece.HELMET) {
return new ItemStack(Material.IRON_HELMET);
} else if (armorPiece == ArmorPiece.CHESTPLATE) {
return new ItemStack(Material.IRON_CHESTPLATE);
} else if (armorPiece == ArmorPiece.LEGGINGS) {
return new ItemStack(Material.IRON_LEGGINGS);
} else if (armorPiece == ArmorPiece.BOOTS) {
return new ItemStack(Material.IRON_BOOTS);
}
} else if (type.equalsIgnoreCase("gold")) {
if (armorPiece == ArmorPiece.HELMET) {
return new ItemStack(Material.GOLD_HELMET);
} else if (armorPiece == ArmorPiece.CHESTPLATE) {
return new ItemStack(Material.GOLD_CHESTPLATE);
} else if (armorPiece == ArmorPiece.LEGGINGS) {
return new ItemStack(Material.GOLD_LEGGINGS);
} else if (armorPiece == ArmorPiece.BOOTS) {
return new ItemStack(Material.GOLD_BOOTS);
}
} else if (type.equalsIgnoreCase("diamond")) {
if (armorPiece == ArmorPiece.HELMET) {
return new ItemStack(Material.DIAMOND_HELMET);
} else if (armorPiece == ArmorPiece.CHESTPLATE) {
return new ItemStack(Material.DIAMOND_CHESTPLATE);
} else if (armorPiece == ArmorPiece.LEGGINGS) {
return new ItemStack(Material.DIAMOND_LEGGINGS);
} else if (armorPiece == ArmorPiece.BOOTS) {
return new ItemStack(Material.DIAMOND_BOOTS);
}
}
return null;
}
}

View File

@ -0,0 +1,129 @@
package rip.battle.entity.npc.menu;
import cc.stormworth.core.util.chat.ChatUtils;
import cc.stormworth.core.util.inventory.ItemBuilder;
import cc.stormworth.core.util.menu.Menu;
import cc.stormworth.core.util.menu.button.Button;
import cc.stormworth.core.util.menu.button.impl.PlaceholderButton;
import com.google.common.collect.Maps;
import lombok.RequiredArgsConstructor;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import rip.battle.entity.EntityPlugin;
import rip.battle.entity.npc.api.NPC;
import rip.battle.entity.npc.prompt.NPCChangeSkinPrompt;
import java.util.Map;
@RequiredArgsConstructor
public class NPCSkinMenu extends Menu {
private final NPC npc;
private final EntityPlugin plugin;
@Override
public String getTitle(Player player) {
return "&eEditing skin for NPC &6" + npc.getName();
}
@Override
public int getRows(Player player) {
return 3;
}
@Override
public Map<Integer, Button> getButtons(Player player) {
Map<Integer, Button> buttons = Maps.newHashMap();
buttons.put(0, new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
return new ItemBuilder(Material.BED).setName("&cBack").toItemStack();
}
@Override
public void onClick(Player player) {
new NPCEditMenu(npc, plugin).open(player);
}
});
buttons.put(getSlot(1, 2), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.PAPER);
builder.setName("&6Set custom skin");
builder.addLore(
"",
"&7Click to set custom skin with a username"
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
ChatUtils.beginPrompt(player, new NPCChangeSkinPrompt(plugin, npc), plugin);
}
});
buttons.put(getSlot(1, 4), new PlaceholderButton(new ItemBuilder(Material.SKULL_ITEM)
.setName("&6Current Skin")
.setDurability((short) 3)
.setTexture(npc.getSkin() == null ? null : npc.getSkin().getValue())
.toItemStack()));
buttons.put(getSlot(1, 6), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.BOOK);
builder.setName("&eSet skin of current online players");
builder.addLore(
"",
"&7Click to open menu and select a player",
"&7to set the skin of the NPC"
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
new NPCSkinOnlinePlayersMenu(npc, plugin).open(player);
}
});
buttons.put(getSlot(2, 4), new Button() {
@Override
public ItemStack getDisplayItem(Player player) {
ItemBuilder builder = new ItemBuilder(Material.BARRIER);
builder.setName("&cRemove skin");
builder.addLore(
"",
"&7Click to remove the skin"
);
return builder.toItemStack();
}
@Override
public void onClick(Player player) {
npc.setSkin(null);
player.playSound(player.getLocation(), Sound.CLICK, 1, 1);
}
});
return buttons;
}
}

Some files were not shown because too many files have changed in this diff Show More