I have been making a plugin for a "portable horse" recently and I am very close to being done, my horses spawn in and despawn as I want them. However, the only thing that I am having a considerable amount of trouble with is changing Horse attributes like speed, color, jump height and Variant.
Here is my Code:
package io.github.bxnie.events;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Donkey;
import org.bukkit.entity.Horse;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.vehicle.VehicleExitEvent;
import org.bukkit.inventory.ItemStack;
public class HorseSpawn implements Listener {
#SuppressWarnings({ "deprecation" })
#EventHandler
public void onPlayerInteract(PlayerInteractEvent e) {
if(e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK){
Player p = e.getPlayer();
ItemStack item = e.getItem();
if(item.getItemMeta().getDisplayName().equals(ChatColor.GRAY + "Donkey")) {
Donkey donkey = (Donkey) p.getWorld().spawn(p.getLocation(), Donkey.class);
donkey.setAdult();
donkey.setTamed(true);
donkey.setOwner(p);
donkey.getInventory().setSaddle(new ItemStack(Material.SADDLE));
donkey.setCustomName(ChatColor.GRAY + "Donkey");
donkey.setPassenger(p);
}
if(item.getItemMeta().getDisplayName().equals(ChatColor.RED + "Brown Horse")) {
Horse horsebrown = (Horse) p.getWorld().spawn(p.getLocation(), Horse.class);
horsebrown.setAdult();
horsebrown.setTamed(true);
horsebrown.setOwner(p);
horsebrown.getInventory().setSaddle(new ItemStack(Material.SADDLE));
horsebrown.setCustomName(ChatColor.RED + "Horse");
horsebrown.setPassenger(p);
}
if(item.getItemMeta().getDisplayName().equals(ChatColor.DARK_GRAY + "Black Horse")) {
Horse horseblack = (Horse) p.getWorld().spawn(p.getLocation(), Horse.class);
horseblack.setAdult();
horseblack.setTamed(true);
horseblack.setOwner(p);
horseblack.getInventory().setSaddle(new ItemStack(Material.SADDLE));
horseblack.setCustomName(ChatColor.DARK_GRAY + "Horse");
horseblack.setPassenger(p);
}
if(item.getItemMeta().getDisplayName().equals(ChatColor.WHITE + "White Horse")) {
Horse horsewhite = (Horse) p.getWorld().spawn(p.getLocation(), Horse.class);
horsewhite.setAdult();
horsewhite.setTamed(true);
horsewhite.setOwner(p);
horsewhite.getInventory().setSaddle(new ItemStack(Material.SADDLE));
horsewhite.setCustomName(ChatColor.WHITE + "Horse");
horsewhite.setPassenger(p);
}
}
}
#EventHandler
public void onPLayerDismount(VehicleExitEvent e) {
if(e.getExited() instanceof Player) {
if(e.getVehicle() instanceof Donkey) {
Donkey donkey = (Donkey) e.getVehicle();
if(donkey.getCustomName() != null) {
if(donkey.getCustomName().equals(ChatColor.GRAY + "Donkey")) {
donkey.remove();
}
}
}
if(e.getVehicle() instanceof Horse) {
Horse horse = (Horse) e.getVehicle();
if(horse.getCustomName() != null) {
if(horse.getCustomName().equals(ChatColor.RED + "Horse")) {
horse.remove();
}
if(horse.getCustomName().equals(ChatColor.DARK_GRAY + "Horse")) {
horse.remove();
}
if(horse.getCustomName().equals(ChatColor.WHITE + "Horse")) {
horse.remove();
}
}
}
}
}
}
I've done a ton of research but nothing really seems to help my case, is there any way that any of you know of to spawn in a horse with the custom attributes I mentioned above?
When you believe you've researched enough, research a little more, I searched for "bukkit change horse speed" and one of the top answers works perfectly. With that being said, let's try to solve your issue.
Everything you need is right in the horse API, more specifically #setColor(), #setStyle(), #setJumpStrength and #setVariant(). Changing variant may not work using that method due to deprecation, instead you need to create a different entity, such as a skeletonHorse
These methods are really straightforward:
Horse horseblack = (Horse) p.getWorld().spawn(p.getLocation(), Horse.class);
horseblack.setJumpStrength(2.0);
horseblack.setColor(Color.BLACK);
SkeletonHorse skeletonHorse = (SkeletonHorse) p.getWorld().spawn(p.getLocation(), SkeletonHorse.class);
Changing speed is a little different, but the method works for any mobs.
entity.getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(yourValue);
Related
I am replacing blocks in chunks. Every time a chunk is loaded, I replace generating blocks with a random other one. So here is my code
package de.belinked.chunkrandomizer;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.plugin.java.JavaPlugin;
public class ChunkRandomizer extends JavaPlugin implements Listener {
public List<Material> blocks = Arrays.asList(
Material.ACACIA_LEAVES,
Material.ACACIA_LOG,
// I'll leave this out, just every full, solid block
Material.YELLOW_STAINED_GLASS,
Material.YELLOW_TERRACOTTA,
Material.YELLOW_WOOL
);
#Override
public void onEnable() {
getServer().getPluginManager().registerEvents(this, this);
Bukkit.broadcastMessage(this.prefix + "Der Chunk-Randomizer wurde erfolgreich geladen");
}
#Override
public void onDisable() {
}
public Material getRandomMaterial(List l) {
int rnd = ThreadLocalRandom.current().nextInt(l.size());
Material m = (Material) l.get(rnd);
return m;
}
#EventHandler
public void onChunkLoad(ChunkLoadEvent e) {
if(e.isNewChunk()) {
Chunk chunk = e.getChunk();
Block b;
Material m = getRandomMaterial(this.blocks);
for(int y = -64; y <= 320; y++) {
for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) {
b = chunk.getBlock(x, y, z);
if(!b.getType().isAir()
&& b.getType() != Material.BEDROCK
&& b.getType() != Material.WATER
&& b.getType() != Material.LAVA
&& b.getType() != Material.END_PORTAL_FRAME
&& b.getType() != Material.END_PORTAL) {
b.setType(m);
}
}
}
}
}
}
}
but when I join the server and load a few chunks then I get this log:
https://pastebin.com/vA8qHSUr
Can anyone help me fix this?
Edit: now I get kicked and for a while nothing happens, then I get this log which is even to long for the console: https://pastebin.com/8eZ4Ja4m
In the error, line 77, it says :
Cannot get data for not block BRICK
I think the problem comes from your list blocks.
Somewhere in it, there must be a Material.BRICK, but in fact, I think the material should be Material.BRICKS, Bricks being the whole block, and Brick being the cooked clay item to make the Bricks block.
You should check that you well have api-version: 1.13 in your plugin.yml.
It's because some mapping names changes, and they are not well detected by spigot without this option.
I am building a 1.8.8 Bukkit/Spigot plugin that allows you to ride ender pearls and am stuck at detecting a dismount and removing the pearl. I have tried to catch the event but it doesn’t compile. I need a way to remove the pearl when there is a dismount. Thank you!
package damotheryeeter.general.enderpearlride.events;
import org.bukkit.entity.Player;
import static org.bukkit.Material.ENDER_PEARL;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.inventory.ItemStack;
public class EnderThrowEvent implements Listener {
#EventHandler
public void onThrow(final ProjectileLaunchEvent e) {
if (e.getEntityType().equals(EntityType.ENDER_PEARL)) {
if (!(e.getEntity().getShooter() instanceof Player)) return;
if (((Player) e.getEntity().getShooter()).hasPermission("enderpearlride.ride")) {
e.getEntity().setPassenger((Player) e.getEntity().getShooter());
if (((Player) e.getEntity().getShooter()).hasPermission("enderpearlride.infinite")) {
final Player p = (Player) e.getEntity().getShooter();
final ItemStack[] pearl = {new ItemStack(ENDER_PEARL, 1)};
p.getInventory().addItem(pearl);
}
}
}
}
The code for that is:
#EventHandler
public void onDismount(EntityDismountEvent e) {
if(e.getEntity().getEntityType().equals(EntityType.ENDER_PEARL)) {
e.getEntity().remove();
}
}
Okay, so I am attempting to make a custom spawners plugin, but I've already hit a bit issue.. I cannot figure out how to change what creature the spawner summons. The code I have currently can be found below (This is a SpawnerSpawnEvent, also everything works other than the spawning of the skeleton, The console gets sent the 'File exists' message, The file does indeed exist (This is done in the block place event, I will also include this below, not sure if it is needed.) so I am very confused on how I could achieve this..) Thank you in advance for your time.
SpawnerSpawnEvent »
package me.askingg.events;
import java.io.File;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.SpawnerSpawnEvent;
import me.askingg.golems.Main;
public class CreatureSpawn implements Listener {
Main plugin;
#EventHandler
public void coalSpawn(SpawnerSpawnEvent event) {
CreatureSpawner spawner = (CreatureSpawner) event.getSpawner().getBlock().getState();
Location location = spawner.getLocation();
String world = spawner.getWorld().getName().toString();
File locationFile = new File("plugins/Golems/Locations", world + " - " + location.getBlockX() + "-"
+ location.getBlockY() + "-" + location.getBlockZ() + ".yml");
if (locationFile.exists()) {
Bukkit.getConsoleSender().sendMessage(Main.colorCodes(Main.prefix + "&fThe file exists..."));
spawner.setSpawnedType(EntityType.SKELETON);
spawner.update();
}
}
}
BlockPlaceEvent »
package me.askingg.events;
import java.io.File;
import java.io.IOException;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import me.askingg.golems.Main;
public class BlockPlace implements Listener {
#EventHandler
public void spawnerPlace(BlockPlaceEvent event) {
Player player = (Player) event.getPlayer();
Block block = event.getBlock();
Location location = block.getLocation();
String world = block.getWorld().getName().toString();
if (block.getType().equals(Material.SPAWNER)) {
if (player.getInventory().getItemInMainHand().getItemMeta().getDisplayName()
.equals(Main.colorCodes("&fSkeleton Spawner"))) {
File locationFile = new File("plugins/Golems/Locations", world + " - " + location.getBlockX() + "-"
+ location.getBlockY() + "-" + location.getBlockZ() + ".yml");
if (!(locationFile.exists())) {
try {
locationFile.createNewFile();
Bukkit.getConsoleSender()
.sendMessage(Main.colorCodes(Main.prefix
+ "&aSuccessfully&f created a new &fSkeleton Spawner&f location &8(&a"
+ world + " &8-&a " + location.getBlockX() + "&8-&a" + location.getBlockY() + "&8-&a"
+ location.getBlockZ() + "&8)"));
} catch (IOException e) {
}
}
}
}
}
}
Alright, so. Based on my quick read of the documentation it looks like you can cast "block" in this instance to CreatureSpawner and then set the spawnType.
Example:
if (block.getType().equals(Material.SPAWNER)) {
CreatureSpawner spawner = (CreatureSpawner) block;
spawner.setSpawnType(EntityType.SKELETON);
}
Be aware some of that maybe pseudo code as I didn't delve that much into the Bukkit API documentation but you should be able to figure it out from there.
Now that I have changed the 'Commands' to 'commands' in the plugin.yml I get another error in my cmd when I run my server. The error says '.Jar file does not contain plugin.yml'.
This is my plugin.yml as of now:
name: Wand
version: 1.0
main: me.Pixel.Main
commands:
wand:
And this is my Main file currently:
package me.Pixel;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin implements Listener {
public Main plugin;
public List<String> spells = new ArrayList<String>();
public getTargets getTargets = new getTargets();
public Spark spark = new Spark(this);
public PoisonWave poisonwave = new PoisonWave(this);
public DarkSpark darkSpark = new DarkSpark(this);
#Override
public void onEnable() {
plugin = this;
getServer().getPluginManager().registerEvents(this, this);
spells.add("Spark");
spells.add("PoisonWave");
spells.add("DarkSpark");
}
#Override
public boolean onCommand(CommandSender sender, Command command,
String label, String[] args) {
if(label.equalsIgnoreCase("wand")) {
if(!(sender instanceof Player)) {
sender.sendMessage(ChatColor.RED + "You need to be an in-game player to perform this action!");
} else {
Player p = (Player) sender;
if(sender.hasPermission("wand.wand")) {
ItemStack stack = new ItemStack(Material.BLAZE_ROD);
ItemMeta stackMeta = stack.getItemMeta();
stackMeta.setDisplayName(ChatColor.RED + "Empire Wand");
stack.setItemMeta(stackMeta);
p.getInventory().addItem(stack);
ChatUtilities.sendMessage(p, "You have got yourself a powerful Empire Wand!");
} else {
ChatUtilities.sendMessage(p, ChatColor.RED + "ERROR: No Permission!");
}
}
}
return false;
}
#EventHandler
public void onClick(PlayerInteractEvent e) {
if((e.getAction() == Action.RIGHT_CLICK_AIR) || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
Player p = e.getPlayer();
ItemStack stack = p.getItemInHand();
if(stack != null && stack.getType() == Material.BLAZE_ROD && stack.hasItemMeta() && stack.getItemMeta().getDisplayName().equals(ChatColor.RED + "Empire Wand")) {
int SpellSelected = stack.getDurability();
if(SpellSelected < 2) {
stack.setDurability((short) (SpellSelected + 1));
p.getWorld().playEffect(p.getLocation(), Effect.STEP_SOUND, 119, 30);
} else {
stack.setDurability((short) 0);
}
ChatUtilities.sendMessage(p, "Selected: " + spells.get(SpellSelected));
}
}
if(e.getAction() == Action.LEFT_CLICK_AIR || e.getAction() == Action.LEFT_CLICK_BLOCK) {
Player p = e.getPlayer();
ItemStack stack = p.getItemInHand();
if(stack != null && stack.getType() == Material.BLAZE_ROD && stack.hasItemMeta() && stack.getItemMeta().getDisplayName().equals(ChatColor.RED + "Empire Wand")) {
int SpellSelected = stack.getDurability();
if(SpellSelected == 1) {
this.spark.onCast(p);
} else if (SpellSelected == 0) {
this.poisonwave.onCast(p);
}
}
}
}
}
name: Wand
version: 1.0
main: me.Pixel.Main
commands:
wand:
Your plugin.yml file isn't valid. 'commands' must be all lower case, and there must be 2 spaces before wand.
Also, you should not make commands that way. You should make external classes implementing the CommandExecutor Interface.
I think, if you do it this way, I think you must register the command.
Like this:
getCommand("wand").setExecutor(this);
The plugin.yml file is case senstitive, the name of the list of commands needs to be all lowercase (commands instead of Commands). Since you currently have it capitalized, Bukkit/Spigot doesn't register any commands thus resulting in an "Unknown command. Type "/help" for help." message if you test the /wand command (I'm assuming this is the error you're getting, as you didn't describe the problem nor the expected behavior, but this is what happened when I tested the code, and correcting the name of the commands list made the command execute).
You might need to update the player's inventory after adding the item with p.updateInventory(). In your case, it would be something like this:
p.getInventory().addItem(stack);
p.updateInventory();
How do i do this?
i want to test if the sign line 2 (1) is equal to "Closed" or "Open" and if not i want to say to please specify if its open or closed it says that if i type open or closed
where the || is does not work...
package me.mcmatt.shops;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
public class Signs implements Listener {
#EventHandler
public void onSignChange(SignChangeEvent e) {
if (e.getLine(0).equalsIgnoreCase("[shop]")) {
Block attached = e.getBlock().getRelative(0, -1, 0);
String name = e.getPlayer().getDisplayName();
if (!(attached.getType() == Material.CHEST))
e.getPlayer().sendMessage(ChatColor.RED + "Please place the shop on a chest!");
else {
if (!e.getPlayer().hasPermission("shops.create"))
e.getPlayer().sendMessage(ChatColor.RED + "You don't have permission to create a shop! (shops.create)");
else {
if (!e.getLine(1).equalsIgnoreCase("open") || (!e.getLine(1).equalsIgnoreCase("closed"))) {
e.getPlayer().sendMessage(ChatColor.RED + "You must specify if the shop is open or closed on the second line!");
} else {
Sign o = (Sign) e.getBlock().getState();
String p = o.getLine(1);
e.setLine(0, "§9[Shop]");
e.setLine(1, "§4" + name + "'s");
e.setLine(2, "§4Shop");
e.setLine(3, p);
e.getPlayer().sendMessage(ChatColor.GREEN + "Shop Created!");
e.getPlayer().playSound(e.getPlayer().getLocation(), Sound.LEVEL_UP, 10, 10);
}
}
}
}
}
#EventHandler
public void onPlayerInteract(PlayerInteractEvent e) {
if (e.getAction().equals(Action.RIGHT_CLICK_BLOCK)) {
Player p = e.getPlayer();
Block b = e.getClickedBlock();
Material m = b.getType();
if (!(m == Material.SIGN_POST)) {
return;
} else {
Sign sign = (Sign) e.getClickedBlock().getState();
if ((sign.getLine(0).equalsIgnoreCase("§9[Shop]"))) {
p.sendMessage("I right clicked the sign!");
}
}
}
}
}
You can create a list of strings you want to compare with, and then use the List.contains method:
if (!Arrays.asList("open", "closed").contains(e.getLine(1).toLowerCase()) {...
The reason that your code is not working is because of De Morgan's law
Given two statements, A and B. If you do not want A or B to true
(!A) or (!B) is not correct
(!A) and (!B) is correct or !(A or B) is logically equivalent.