#help-development
1 messages · Page 1723 of 1
is there an event or smth for when an entity gets a certain distance from another entity
?javadocs
lol
well, search it in javadocs
armorStand.getEquipment().setHelmet(itemStack);
?jd
of course not, that event would be called the time
no
ArmorStand#getEquipment#setHelmet
if your armorstand is called willy, just do willy.getEquipment().setHelmet(willysHelmet)
no need to get equipment
^^
yes need to get equipment
ah sorry, yes deprecated
hugh?
it DOES make sense
armor stands aren't the only things that can have equipment
so instead of adding all those methods to every single entity, they made an interface for it that can be reused
why would this be in any way impossible by using EntityEquipment?
but, stand. is the hashmap
no, stand is not a hashmap, otherwise it wouldn't have the getEquipment method
second, please just read the docs
your "stand" thing is an ArmorStand
ArmorStand stand = plugin.armorstands.get(p);
ArmorStand is the hashmap defined in the main class
yes
how do u set nbt
on what?
ik it sounds dumb but my search results are outdated
do you have to access the vanilla NBT tags, or do you simply want to store your own data inside the entity?
stand.getEquipment().setHelmet(new ItemStack(Material.DIAMOND_HELMET));
like this?
Is SkeletonTrap a vanilla NBT value?
exactly
but
store my own nbt
then, please please forget about NBT
NBT is only possible using NMS and you do not need it
you can instead use the PersistentDataContainer
lol
it's made for exactly this
you literally only have to add "getEquipment" between stand and setHelmet everytime...
myEntity.getPersistentDataContainer().set(new NamespacedKey(this, "skeleontrap"), PersistentDataType.BYTE, (byte) 1);
} else if (e.getCurrentItem().getType().equals(Material.DIAMOND_HELMET)) {
if (plugin.armorstands.containsKey(p)) {
ArmorStand stand = plugin.armorstands.get(p);
stand.getEquipment().setHelmet(new ItemStack(Material.DIAMOND_HELMET));
p.sendMessage();
if (stand.getEquipment().getHelmet().getType() == Material.DIAMOND_HELMET) {
stand.getEquipment().setHelmet(null);
p.sendMessage("Remove.");
like that?
thx
the syntax is a bit ugly at first, but this one will work in all versions from 1.14.1 onwards without needing dirty NMS stuff. and you can store ANYTHING inside it
if it doesn't show any more deprecation warnings, it should be fine
np. you should always avoid deprecated methods because that means they might be removed soon
"this" of course is an instance of your plugin^^
and to retrieve the value later:
byte value = myEntity.getPersistentDataContainer().get(new NamespacedKey(this,"skeleontrapped"),PersistentDataType.BYTE);
logs
logs backwards sounds like a swedish food
Sgol
`paste
its 246 mb
yeah ok 250mb is a bit much for paste
lol
just send part of it
i cant even copy part of it cuz my text editor is crashing
then delete teh log and get a fresh one
k
It’s probably the same error repeatedly
ik
if you're on linux just do tail -n10000 latest.log > error.log
what's Listeners line 96?
Are you spawning an entity in the creature spawn event
You’ve made a loop
erm
me.tristandasavage.trollmc.Listeners.creatureSpawn(
Bukkit calls event -> You spawn entity -> Bukkit calls event again -> You spawn entity -> ...
Switch a Boolean before you spawn the entity, and ignore the event when that Boolean is set
you are spawning a mob in teh spawn event
im trying to replace 10% of skeletons with skeleton horses
What’s your code?
that's like saying "every time I drink a shot of vodka, I immediately drink another shot of vodka" and boom you're dead
Switch a Boolean before you spawn the entity, and ignore the event when that Boolean is set
how
private boolean ignoreNextEvent = false;
@EventHandler
public void onSpawn(CreatureSpawnEvent event) {
if(ignoreNextEvent) {
ignoreNextEvent = false;
return;
}
ignoreNextEvent = true;
// Spawn your entity
}
thx
That’s not the best way to do that
it's the easiest, you got a better idea?
what is
Set it to true before the spawn
the better way
Set it to false right after
Store entity UUIDS in a set
right
that's indeed easier
Check if the uuid is in the set, if so, ignore the event and remove the uuid
You can use a set, but there is no need
wait it isn't, it's the same
why does this code doesn't have any action?
https://paste.md-5.net/kinamarapo.java
how is THAT easier or better?
did you register the listener?
It guarantees it’s the same entity
It already is guaranteed
im doing the adding armor thing to multiple mobs, how would i make that thing work with it
yes, it cancels movements
add debug messages
wdym?
nvm
in every if statement, do System.out.println("1");
then 2, 3 etc
then you can see where your code stops
i don't know how to do debug in intelij
I just explained it to you
inside every if statement, do "System.out.println(1)", then in the next if, use a 2 instead 1, and so on
do you mean in mc console?
?
It should show in console
ok ig
like this:
@EventHandler
public void onSpawn(CreatureSpawnEvent event) {
System.out.println(1);
if(event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.BEEHIVE) {
System.out.println(2);
// Do something when beehives spawn a creature
} else if(event.getSpawnReason() == CreatureSpawnEvent.SpawnReason.BREEDING) {
System.out.println(3);
// Do something when two entities fucked
}
}
Wouldn't it go Event runs -> spawns entity -> event called -> listeners handle event -> possible other listener spawns entity?
yes, you're right on that. Haven't thought about that
So a set would be better right?
yes
no, @young knoll imagine this:
oh wait now that I think about it
I will just try it before thinking too much lmao
Lol I can try to come up with it
I’ve done it before
ok, when i enter the } else if (e.getCurrentItem().getType().equals()){
//asd
}
For both entity spawns and block breaks
when it enters this thing:
Listener spawns an entity. More than one listener for EntitySpawn is registered.
Another listener gets handled first, it spawns an entity.
The latest entity spawned is now not the original entity, but an entity spawned by a different registered listener.
where sout("a");
what's "p"?
you should give your variables better names
Player p = (Player) e.getWhoClicked();
obviously your list of armorstands doesn't include any player ever
I might be wrong
yes
if bool return;
bool = true;
SpawnEntity
bool = false;
lol
That’s all you need until minecraft starts spawning stuff async
Don;t store players as a key. the Player object can go stale. Store against the players UUID
But there can be more than one listener registered
How do you know your listener is first?
how do i store the UUID?
but they run synced
there can. So don't
by using a HashMap<UUID,ArmorStandf> instead
Don't what?
Player#getUniqueId()
Doesn’t matter, all other listeners will run in between the true and false
Don;t have more than one listener on spawning if you want to prevent stackoverflows
There is more than one plugin on a server
Other plugin listeners don’t matter
How come?
it gives me an error here: plugin.armorstands.put(p, stand);
Everything is still sync
yes, because you are supposed to store the UUID and not the player
for some reason every time i spawn a skeleton it will mostly spawn a skeleton horse and rarly spawn a skeleton, but that skeleton wont have the stuff i gave it
p.getUniqueId()
But spawning an entity inside an event doesn’t guarantee the same listener is listened to first does it?
now, ty
ugh please move the entity creation to its own function lol
btw where am i supposed to originally define ignoreNextEvent i think thats the reason
Listeners always run in the same order
No, butr the boolean is a Field so doesn;t matter
but the code, is still not working
What?
as field in your listener
The boolean is a field so accessible by everything in that class
That’s not the argument
imagine this code:
private boolean dontSpawnHorse = false;
private boolean dontSpawnPig = false;
@EventHandler
public void spawnPig(CreatureSpawnEvent event) {
if(dontSpawnPig) {
return;
}
dontSpawnPig = true;
event.getLocation().getWorld().spawnEntity(event.getLocation(), EntityType.PIG);
dontSpawnPig = false;
}
@EventHandler
public void spawnHorse(CreatureSpawnEvent event) {
if(dontSpawnHorse) {
return;
}
dontSpawnHorse = true;
event.getLocation().getWorld().spawnEntity(event.getLocation(), EntityType.HORSE);
dontSpawnHorse = false;
}
(Obviously that's supposed to be two different plugins)
it always spawns to pigs and two horses this way, though
sooo
that's NOT the way to go
instead, do as suggested and simply store a Map<Entity>
of what tho
like
I mean Set, nopt Map
all the entities?
wait, the set also doesn't work
because to store the entity, it has to be spawned first, which already calls the event
When you spawn an entity add its uuid to a set, if the set contains the spawned entity when you listen to the event, remove the uuid and don’t spawn another.
How do you want to get an entities UUID before it's spawned?
You can use a callback in the spawn method to do stuff before it’s spawned
Yeah
but that won't be called before any events run, will it?
It will
the entity will only be spawned after all eventhandlers will have been called
I have a problem that started when i stored in the UUID look:
it doesn't make sense because i have this:
if (e.getCurrentItem() == null) {
return;
yep just tested the Set<Entity> thing and it's working fine, thanks I learned sth new
private Set<Entity> ignoredMobs = new HashSet();
@EventHandler
public void spawnPig(CreatureSpawnEvent event) {
if(ignoredMobs.contains(event.getEntity())) {
ignoredMobs.remove(event.getEntity());
return;
}
event.getLocation().getWorld().spawn(event.getLocation(), Pig.class, (entity) -> ignoredMobs.add(entity));
}
what doesn't make sense?
the video
this
Nice
I also feel like it’s cleaner
all I see is that you are clicking empty slots
it would be very helpful if you could tell use what's supposed to happen
yeah I think so too
and when i click that empty slots it spawns armor stands
and it's supposed to only spawn when i click the armor stand
show your code again pls
i have the hashmap in Player and now it doesn't happen that
the main class?
i have 4 classes
the class that handles the GUI clicks
I'll explain it
Line 27: You assign the player who clicked to "p" (btw name it "player" instead)
but "player" is longer so i prefer just "p"
Line 29: You check if your HashMap<UUID,ArmorStand> contains the object "p" which is a player
yeah and later you have an event called e and an entity called e and an exception called e
Since that always never contains your player, you always spawn a new armor stand
oh
Exactly. I also used to use "p" and "e" and "loc" and I was like "bruh why would I have to name it "event", of course "e" is an event
bu now, especially in long methods like yours, "e" could also be an entity, etc
i see
and tbh you only have to write "player" once, after that just enter pl, hit enter and IntelliJ turns it into "player"
it also helps other people read your code
btw "p" could also be "plugin"
^^
soo since you changed your HashMap from Player to UUID
you now have to change it everywhere else, too of course
well, exept of line 29 all the rest i know
ok
if (!plugin.armorstands.containsKey(p.getUniqueID())){
Maybe?
yep
btw if you select your "p" variable and hit Shift+F6, you can rename it to "player" and IntelliJ renames it automatically everywhere in your code
np^^
well, but the thing for what i was here, was something different xD
what was it again? ^^
upload it to the paste site too pls
That’s a lot of arrow code
Also materials can be compared with == because they are constants
yeah was just going to mention this 😄
Lol
it's a bad habit and leads to complicated, ugly code
use this to debug it
run it and when it doesn't work, send the console output
I simply added a single debug line inside every if and else block
that's the easiest way to see what exactly your code did
also what I want to mention about your code:
well i tried with the code
You basically do this:
1. Do one thing for the helmet stuff
2. Do the exact same thing for the chestplate stuff
3. Do it again...
4. Do it again...
You could remove 75% of the code when you would turn it into a function
and it doesn't execute nothing
It will DEFINITELY have printed something in the console
it doesn't
then you didnt register this listener
i did
getServer().getPluginManager().registerEvents(new MenuHandler4(this), this);
then you didnt click in any inventory
What I like to do is loop up to 100 and print a line for each number so I can’t miss it lol
You can always try broadcastMessage instead
tbh I'd rewrite the whole class from scratch
it cancels moving items event
that's literally sooo many nested if/elses
the only thing that works
bruh
if it did cancel it
it would have printed 1
it's the line directly above where you cancel it
well
if the event gets cancelled, it WILL have printed "1" to console
it doesn't
then it didnt cancel the event
Hence why I suggest trying bukkit.broadcastMessage
it does
okay then your computer must have magically ignored all the debug statements I inserted and decided to only compile the lines you already had in there
however that's a bit unlikely
do you want a video maybe?
maybe just upload your whole thing on github
it just send errors when i click in empty slots and it shouldn't because
if (e.getCurrentItem() == null) {
return;
there's still a chance that you forgot to compile it or didnt notice the compilation error or simply forgot to install the new jar and reload the plugin
isn't that from another class already again?
it compiles into the plugins folder
it would be helpful to stick to one problem at one time
well
ugh are you having two listeners that both listen to inventoryclickevent?
what code?
it would also be helpful if you would show the errors you get
public MenuHandler4(ArmorStandGUI plugin) {
this.plugin = plugin;
}
@EventHandler
public void click(InventoryClickEvent e) {
Player player = (Player) e.getWhoClicked();
if (e.getView().getTitle().equals(ChatColor.BLUE + "Choose some armor.")) {
e.setCancelled(true);
}
if (e.getClickedInventory().contains(Material.//someitem)) {
if (e.getCurrentItem() == null) {
return;
}
sure
that's literally the same code that I sent you back 5 minutes ago, just without the debug lines
?paste
that's literally the same code that i have in 3 different events.
what the fuck
but you cannot tell me that all your event listener classes are called MenuHandler4
hello again my friends. i have this code: https://paste.md-5.net/gofitoruba.java. Basically, what i want to do is a simple animation where the stands starts low, then it go fast, low a bit and low more, but with the current code this is happening:
:C
I literally only studied law because I knew it would not involve ANY math
maybe that question would better fit in the forum
sometimes there's some math experts around
i mean, with the name of its respective classes
You send me your MenuHandler4 class. I added debug statements. You said it didnt print anything. Then you sent your MenuHandler4 class again and it didnt have any debug statements
check DM's
this will be easier if you store the angle of each item somewhere and just add to that
ok
your issue comes from getLocationInCircle(radPerTick * tick + separator * i);, since every time you change radPerTick the items will move to the position where it would have been had the circle started with that rotation speed
when you forget to uninstall the test plugin...
lol
how could i do that?
Lol. Did you ever ping the person to tell them to use a Set?
How do I kick a player?
it wants a Component, no clue how to make it
declaration: package: org.bukkit.entity, interface: Player
You using paper?
I imagine they are
Who knows, could be using a random method
What random method uses a component
The chat component API is components
I don't even remember who it was^^
it wasn't for nothing
I learnt that the consumer in spawnEntity is called before any events get triggered
I didn't know that before
Well that’s good at least then
yes 😄
https://github.com/adri752/ArmorStandGUI2/pull/1 I just hope this gets merged soon
I can't imagine spawning and interacting with entities in the old versions of spigot without that method
All those nested ifs... ugh
Who doesn't love a good couple hundred nested if statements?
yeah if a class doesn't end with }}}}}}}}}}}}}}}}}} where's the fun?
the code looked worse than a bash script lol
Honestly I don’t use the consumer much
I never used it in the spawnEntity method but all the time in streams or other stuff
I've used it a decent amount
however I also never spawn any entities ^^
(In the spawn entity method)
besides armorstands or area effect clouds for holograms
Generally you do those client side
never had any problems with server side holograms. it's not like I'm spawning 300 of them in one chunk
yea-
is this really paper's making? i'll go bother them
declaration: package: org.bukkit.entity, interface: Player
You have to use Component.text("Kick Message Here")
it's an ADDITIONAL method to kick a player with a message
paper also works fine with the normal kickPlayer(String) method
ah thank you
i mean, it's offered. might as well use it :>
I wouldn't use the kick(Component) method. It has like no advantage over the normal thing and it makes the plugin not be working with spigot anymore
It lets you use gradients and such
well theres two options
Well, easily
I just use my lib for gradients^^
theres kickPlayer, but that's deprecated
gradients be looking smexy tho
I use MiniMessage and Adventure
It is
It does
I haven't heard of MiniMessage before tho
I should probably be more invested in the Spigot ecosystem lmao
ye ik
gn8 everyone
Bukkit does
Good night
gn
Bukkit uses Adventure?
No
I mean
not in the way that Bukkit declares a dependency on Adventure
it's just that with the context I presented with "Spigot ecosystem" and you responding "Spigot doesn't even use Adventure" I assumed we were referring to Adventure's available platforms
but ye Adventure uses Bukkit as a platform as opposed to Spigot
(mainly bc more compatibility and also Spigot is essentially just Bukkit but with additional patches and minor API changes)
Oh my bad
How do I drop uh, items from a chest?
i am setting a block break even to cancel, and then dropping the chest contents by hand, but idk how to get the contents of the chest
Get the block state and cast it to container
ah thank you
this would drop it?
Container container = (Container) state;
container.getInventory().clear();
state is the getBlock#getState()
nvm
That will just empty it
oh
i tried this
BlockState state = event.getBlock().getState();
Container container = (Container) state;
container.getInventory().clear();
ItemStack[] items = container.getInventory().getStorageContents();
event.getBlock().breakNaturally();
event.getBlock().setType(Material.AIR);
for (ItemStack i :items) {
if (i == null) {
continue;
}
event.getBlock().getWorld().dropItem(event.getBlock().getLocation(), i);
}
it no work
it'll drop my chest, but nothing else
oh wait i am clearing the fucking thing
Anyone know why its not transfering the player to the hub?
@EventHandler
fun playerJoin(event: PostLoginEvent){
val player = event.player
val hub = main.serverHandler.getHub()
player.connect(hub)
}
the ServerInfo is valid
public void drawLine(Location from, Location to, Particle particle) {
double between = from.distance(to);
for (int i = 0; i < between; i++) {
Location particleLocation = from.getDirection().toLocation(from.getWorld());
System.out.println(particleLocation);
particleLocation.getWorld().spawnParticle(particle, 1, 1, 1, 10);
}
}``` I am getting an error on the last line. could someone assist me with this?
You have the params wrong
Depends what your goal is
it's actually particleLocation.getWorld().spawnParticle(particle, 1, 1, 1, 10, 10);
There are like 10 overloads of that method
Which one
this one? <T> void spawnParticle(@NotNull Particle particle, double x, double y, double z, int count, @Nullable T data)?
The one I just linked
There's 5 of them
I linked directly to one
I cant see the particles
public void drawLine(Location from, Location to) {
double between = from.distance(to);
for (int i = 0; i < between; i++) {
Location particleLocation = from.getDirection().toLocation(from.getWorld());
particleLocation.getWorld().spawnParticle(Particle.SMOKE_NORMAL, 1.0, 1.0, 1.0, 10);
}
}
}``` no errors this time, so that's better
might be another part of my code ill check that out first
Because you are spawning them at 1 1 1
Which is in bedrock at the centre of the world
So right now I have this code:
class SandboxReconnectHandler(val main:SandboxServerManager) : ReconnectHandler {
init {
ProxyServer.getInstance().reconnectHandler = this
}
override fun getServer(player: ProxiedPlayer): ServerInfo? {
val server = main.serverHandler.getHub()!!
println("Player ${player.displayName} is being sent to hub: ${server.name}")
return main.serverHandler.getHub()
}
override fun setServer(p0: ProxiedPlayer?) {
}
override fun save() {
}
override fun close() {
}
}
And this is the console output:
[03:58:37 INFO]: Player PrinceOfToxicity is being sent to hub: sandbox_hub_1
[03:58:37 INFO]: [PrinceOfToxicity|/REDACTED] <-> ServerConnector [sandbox_hub_2] has connected
[03:58:37 INFO]: [PrinceOfToxicity|/REDACTED] <-> ServerConnector [sandbox_hub_2] has disconnected
But I'm just getting a ReadTimeoutException:
is there an event that checks what are you wearing
like, if an entity is wearing that and that, do that and that
no, because that event would be called all the time
events are called when something happens / changes etc
omg discord added proper markdown for mobile
🤪 🤪
nvm, doesn't work for everything still 😅
finally!
I am very tempted to create a bot to automatically pull posts from discord to post on trello as issues just so I can keep track of reported issues
I'm starting to spend a silly amount of time just scrolling back and forth trying to remember what got reported to me
sounds useful, if I wasn't using wekan instead >.<
🤷
hm it doesn't look like it would be too hard to make such a bot
I've never really made something quite like this
should be fairly easy but I'd probably simply add the reported stuff manually instead of investing time in the bot unless I'm really bored 😄
that's what I try to do but it's hell to do when I'm on mobile
is it posibble to make a custom gui using a server resource pack without overriding any other gui
of course
One sec
you mean something like thsi?
yes
that's simply using CustomModelData
every material can have up to about 4 billion different textures
i saw some tutorial for custom items but
so for example above they simply have a glass pane in every slot with different custom model data
or, idk if that's possible, it could even be one large item that has the whole GUI as texture and overlays all the other slots
you need some photoshop skills and patience^^ then create an item that has a texture that looks like your GUI
then in your resource pack you can override for example a glass pane's texture when it's custommodeldata is a specific number
then simply add a glasspane with that custom model data to your inventory
I mean idk how to convert ```json
{
"parent": "item/generated",
"textures": {
"layer0": "item/iron_ingot"
},
"overrides": [
{"predicate": {"custom_model_data":1234567}, "model": "item/gold_ingot"}
]
}```
for items to something handles guis
Today I'll show you how to add new GUIs (graphical user interface) to Minecraft! You don't have to replace any pre-existing GUI textures and you can make anything you like, new containers, new storage blocks, new crafting station, whatever you want!
►Subscribe - http://bit.ly/Subscribe_Sarc
►Follow Me On Twitter - http://bit.ly/SarcTweet
─────...
ive been searching for something like this for a day thanks a lot
tbh I havent watched the video, I don't know whether he also explains on how to do it exactly or only explains the general idea
com.codingforcookies.armorequip.ArmorListener.playerInteractEvent(ArmorListener.java:128)
is this your plugin?
but the HelmetEvent is your listener, right?
if yes, please show your HelmetEvent class
especially line 15
while (e.getNewArmorPiece().equals(CustomItems.minerHelmet))
show the full code please
ok
it seems like the while loop is running endlessly
public class HelmetEvent implements Listener {
@EventHandler
public static void onWear(ArmorEquipEvent e) {
while (e.getNewArmorPiece().equals(CustomItems.minerHelmet)) {
e.getPlayer().addPotionEffect(new PotionEffect(PotionEffectType.FAST_DIGGING, 100, 0));
} while (!(e.getNewArmorPiece().equals(CustomItems.minerHelmet))) {
}
}
}
okay so
e.getNewArmorPiece() will never change
CustomItems.minerHelmet will never change
so once that while loop starts, it will forever add PotionEffects and never end
and gets overwhelmed?
so the server just keeps executing "e.getPlayer().addPotionEffect"
it's in an endless loop
your event is not called async, meaning the server only continues to do its normal job when it's done executing your event listener
what are you actually trying to do?
so.
to me it seems like: you want players who wear your custom helmet have FAST_DIGGING effect, and remove it again when they don't wear it anymore, right?
Yes, but you cannot simply run a while-loop forever in any event
correct
here's the correct approach:
- Loop through all online players
- Check if they have your helmet
- If yes: Give the potion effect for 2 seconds
- Repeat all of this every second
alright thanks
np
so you basically do not need any events for this
oh by the way you have another problem:
you are checking whether the player's helmet equals your custom item
but
the helmet will probably get damage from time to time
once it got its first damage, the helmet will not equals() your original helmet anymore
(unless you made it unbreakable or something)
might as well just set it to unbreakable
Can you show the method where you create the custom item?
we could easily find another solution
ok
public class CustomItems {
public static ItemStack minerHelmet;
public static void init(){
createMinerHelmet();
}
public static void createMinerHelmet(){
{
ItemStack item = new ItemStack(Material.IRON_HELMET);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName("§6Miner helmet");
List<String> minerHelmetLore = new ArrayList<>();
minerHelmetLore.add("§7Wear this helmet");
minerHelmetLore.add("§7to gain §e:pick: Haste 1!");
minerHelmetLore.add("");
minerHelmetLore.add("§6§lLEGENDARY");
meta.setLore(minerHelmetLore);
item.setItemMeta(meta);
minerHelmet = item;
}
}
}
alrighty. Sooo
First of all I'd create another method called "isMinerHelmet" that takes an ItemStack
that returns a boolean
inside that you have different possibilities:
Most stupid solution: Check whether the item contains the lore "§6Miner helmet"
how smart could players be to give it to an anvil
Smartest solution: Use PersistentDataContainer (that's "modern NBT tags") to add a simple tag to your object that you can use to check if this is your helmet
Like, simply add a tag called "isminerhelmet" and give it any value
then, in your checking method, just check whether the item has that tag
if yes, it's your custom helmet
@solid cargo Did you ever use PersistentDataContainer?
i have never used that
okay this is the perfect opportunity to learn it then
yay
it's actually totally easy
wait a minute pls, I'm currently finishing a small tutorial on how to use it anyway
sure no problem^^
thanks
For example, this could be your main class:
public class Test extends JavaPlugin implements Listener {
private ItemStack minerHelmetItem;
@Override
public void onEnable() {
minerHelmetItem = createMinerHelmet();
}
private ItemStack createMinerHelmet() {
ItemStack item = new ItemStack(Material.NETHERITE_HELMET);
ItemMeta meta = item.getItemMeta();
meta.setDisplayName("My awesome Miner Helmet");
// Now we apply the custom PDC tag
meta.getPersistentDataContainer().set(new NamespacedKey(this,"minerhelmet"), PersistentDataType.BYTE, (byte) 1);
item.setItemMeta(meta);
return item;
}
public boolean isMinerHelmet(ItemStack itemToCheck) {
if(!itemToCheck.hasItemMeta()) return false;
return itemToCheck.getItemMeta().getPersistentDataContainer().has(new NamespacedKey(this, "minerhelmet"), PersistentDataType.BYTE);
}
}
?pdc
yeah the linked guide is definitely awesome, but I actually wrote the post more to show why it's better than NBT and also I think the shown tutorial looks a bit complicated at first place, and also starts with focussing on the differences between the CustomItemTagContainer and the new PDC, so I felt like writing my own at some point 😄
wait but i also must include the lore, you didnt add it right?
so just put that thing in my main?
move all to main?
nooo don't copy paste it
understand what it does and recreate that
True XD yea I just copied over the example post from my first attempt at explaining custom tag containers
oh I just see that it's your post 😄
Thanks very much for writing it, I think that's how I learned how the custom data types work
Ah no problem XD flattered by "biggest improvement that (in my opinion) ever made it into the Bukkit API"
yeah it made my life so much easier
I never used NBT tags because of NMS
so
I was finally able to store custom data inside items and entities
I mean I COULD HAVE used NMS, but I really hate the idea of having to update everything on every update
Glad to help 😂 sad I never got around to implementing lists of persistent data types
I was so annoyed that by default it doesn't support booleans, so I made the more persistent data types library lol
but the forum doesn't like it 😄 33% voted that it's useless lol
I mean 33% is not too many XD and well for just booleans idk if a library is too useful 😅
it's not just booleans
it's for everything that's serializable
and also allows to create own datatypes without creating a huge new class but just providing two functions 😄
Oh so just converting everything into bytes using the Bukkit serialisation ?
Storing offline players in PDC
Perfect XD
yeah I just thought I'd add everything because someone MIGHT have a use lol
like protection plugins
simply storing the OfflinePlayer in a block that that player placed
idk
😄
I mainly made it for ItemStacks and because I was annoyed by missing booleans
True. Tho I usually suggest papers byte serialisation for itemstacks :>
Does it do something different?
anyway I never use any Paper API because 35% of servers are still on regular spigot
True. Anyway, nice library tho 👍 don't think too much of 33% of peeps not supporting it.
thanks 🙂 yeah it's actually not really that useful, just nice to have. what I think is a real lifesaver is the CustomBlockData lib, I couldn't live without it anymore
my whole main class is just a one single mess.
that usually happens to every developer at the beginning 😄
I'm still scared when I see code I wrote three years ago
you mean the isMinerHelmet method?
yes
Two possibilities:
You could make the method static when the original Helmet item you saved is static too. That's considered bad practice by some people, however I disagree on this case because you will never need more than one instance of the helmet item
Or, you pass a reference to your main instance to all the classes that need to access non-static methods defined in your main class
Go for the second solution
So basically something like this: (one minute pls)
in your main class, where you create the other class instances, pass your main instance:
@Override
public void onEnable() {
getServer().getPluginManager().registerEvents(new MyAwesomeListener(this), this);
}
The important part is the "this" inside MyAwesomeListener(..)
ah so 2 this's?
now, in MyAwesomeListener, of course you have to define the parameter as well, like this:
public class MyAwesomeListener implements Listener {
private final MyPlugin plugin;
public MyAwesomeListener(MyPlugin plugin) {
this.plugin = plugin;
}
}
Of course MyPlugin is your main class
then you can access all methods by using plugin.isMinerHelmet(...)
np
there are other ways to achieve this but this is the most easiest solution
and it's also basically considered the most cleanest solution
while my dad is creating cloud accounting solutions i am making some stupid shit lol
your dad probably is also a bit older than you and thus has more experience 😄
yeah true...
it would be strange if you were older than your dad
yeah when ur dad is one of the best php'ers in the country, there will be a lot of swearing lol
some methods are_using_method_names_like_this(), other's are completelylowercase(), others are camelCase() etc
Who cares how they’re formatted, you have an ide
Like of all the criticisms that’s not one I’d pick
yeah true but anyway, it's just something I wanted to mention
my dad also kinda regrets going the php way ._.
Java is the one true language
Correct
I should really start looking into learning kotlin one day
java is life
life is java
or people should finally switch to java 16+ but all those mc 1.8 people will never do that
cough minikloon cough
*17
miniwhat?
Mojang going 16 was a mistake
why so?
most distros don't include java 16 anyway
more optimized
Because now people will sit on 16
as far it uses less ram im in
Rather than 11 or 17 which are the versions they should be sittin on
- those are the versions distros usually package
even Centos 7 includes java 11 meanwhile
md_5 give ownership to spigot thanks
will you maintain it as well or just sack the donations @solid cargo ?
that remains as a secret
Then I approve this request
i will donate all money to my dad's company
how can i see all possible (shaped recipes for an item (for example chest), like acacia_planks for the slots instead of oak_planks?
Those are probably using MaterialChoice
So just look for that and see what’s allowed
is that a property/method of shapedrecipe?
Yes
is it in recipechoices?
Yes
Check the docs, there’s only a couple methods. One will return a list of materials
Yes
ok ty
wait how do I get a material choice from a recipe choice
there's no getMaterialChoice
MaterialChoice is an implentation/subclass of RecipeChoice IIRC
how did you get the RecipeChoice object?
getChoiceMap
Hm there's probably a better way, but I think you should be able to check if your RecipeChoice is instanceof MaterialChoice, and then just cast it
(Never used any RecipeChoices so no idea but I'm sure this should work)
Imagine you have this:
ShapedRecipe recipe = ...;
Map<Character,RecipeChoice> map = recipe.getChoiceMap();
RecipeChoice firstRecipeItem = map.get(0);
Now you can easily do this:
if(firstRecipeItem instanceof MaterialChoice) {
MaterialChoice materialChoice = (MaterialChoice) firstRecipeItem;
// Do stuff
}
yes
there probably isn't
thats what i planned on doing
I just looked at the docs and didn't find anything else
but idk seems weird that sr doesnt give you materialchoice map
instead gives recipechoice map
why is it weird?
MaterialChoice is a subclass of RecipeChoice
After all the RecipeChoice could also consist of ExactChoices or however it's called
like imagine a jukebox
or the recipechoice having a material choice method
even if it returned the cast to material choice
it has 8 materialchoices (the wood planks) and one "exact" thing, the diamond
You cast it
but you dont have to use recipe choices for the diamond
you didn't understand the purpose of interfaces and it's subclasses
getingredient map should also work
Just imagine you have a EntityDeathEvent
should that now have methods like getPig(), getZombie(), ... ?
No because ingredientmap wont return the alternatives
No, it has getEntity() and then you can cast it if you need more specific things
but there are no alternatives
for the diamond
yes
but that seems logical
that's why it's not a MaterialChoice but an ExactChoice..
you dont just add methods with unique names for everything
Yes, but you were asking about doors not diamonds
Or whatever the wood thin was
i was talking about the jukebox example
but yes
but material choice is a very commonly used thing from recipechoices
A Jukebox recipe will return a map like this:
W=MaterialChoice (Wood)
D=ExactChoice (Diamond)
Nah it wont alex
oh
ExactChoice is only used by plugins
I misunderstood it then
only 2 methods implement it iirc so why not just have a getMatchoice method directly?
It means itemstack with meta
ah alright
in the getPig example it makes more sense cause they keep adding new entities
What does the returned map include if some choices are exact and some are material?
so @tender shard like this?
erm no
uh oh
you are now checking if your custom item is your custom item
you probably want to check whether ANOTHER item is a copy / similar to your original item
like my implementation would be:
ShapedRecipe.getMaterialChoiceMap [returns a Map<char, MaterialChoice>]
each material choice has its own material list
with differrent length
does it make sense?
md_5 already said: What if a recipe consists of 8 MaterialChoices and one ExactChoice?
i think i will need a spoonfeed 🥄 😮
Yeah well I'm bored so
but cant you get a lenght 1 material list from the material choice of the exact item?
for(Player player: Bukkit.getOnlinePlayers()) {
if(isMinerHelmet(player.getInventory().getHelmet()) {
getLogger.info("This player is wearing one of your custom helmets");
}
}```
huh? Maybe simply explain what you are actually trying to do
can i replace getLogger with something else
cause it doesnt recognize that for me
like a sysout
no you will be shot then
of course you can o0
getLogger() is a method from the Plugin interface
MaterialChoice and ExactChoice are different
MaterialChoice checks the material, ExactChoice checks the item
like materialchoicemap would be: for the wood it would have a List<Material> with like 6 elements for possible wood types and for the diamond it would return a List<Material> with just diamond
so something like this. and then how can i apply the haste? something like a runtaskasynckoaghf [oawgba[
?
MaterialChoice with one choice is different to ExactChoice
No vanilla recipes use ExactChoice, only plugins
Why are you making it so complicated? Why can't you simply cast your RecipeChoices?
does the material list from material choice always have the same size for all items in a shaped recipe?
Didn't we already on the fact that you don't want to use an event for this, but a runnable looping over all players?
Hello, I'm sending OPEN_SIGN_EDITOR packet and before that I'm setting Sign#setEditable to true, but after changing some lines there is a warning:
Player luv1ly just tried to change non-editable sign
and the content doesn't change.
Did you call .update after setEditable
yes
did you update the block state?
sniped
guys
i keep getting NoClassDefFound but the error doesn't tell me where exactly i use the class
like where
then it's one of the import statements
my plugin is apporaching 100kb very rapidly!
@SneakyThrows
private void openSignEditor(@NonNull Player player, @NonNull Sign sign) {
sign.setEditable(true);
sign.update();
PacketContainer packetContainer = new PacketContainer(PacketType.Play.Server.OPEN_SIGN_EDITOR);
packetContainer.getBlockPositionModifier()
.write(0, new BlockPosition(sign.getX(), sign.getY(), sign.getZ()));
protocolManager.sendServerPacket(player, packetContainer);
}
Recipe Choices
this doesn't usually cause errors
wait no im importing tons of other classes that should also error with them, and it doesn't
i've tested
pretty sure its somewhere static but where
it doesnt print anything out tho
@tender shard
i have this
and it doesnt tell me anything
yes it does. Importing classes not available at runtime will throw NoClassDefFoundError
Then your for loop doesn'T get executed at all
i changed if to while
is there any fix for that?
and still doesnt
so how can i actually tell the user with error if the original plugin not installed (its an addon)
you are starting with a completely wrong way of doing things
Create a wrapper class
Only import the classes inside that class
then in onEnable check if the plugin is installed. If yes create an instanceof your wrapper class
this is tons of methods to get moved
yes
yeah mate i know
If you depend on the other plugin, you can also add it as depends to your plugin.yml
its softdepend
then you need wrapper classes or use reflection everytime to access those classes
Look how I did it for WorldEdit:
This is my wrapper class
it tries to use the WorldEditHandler, which is a class that actually imports WorldEdit things, and if that doesn'T work, it throws an exception
and this is the actual WorldEditHandler that imports classes: https://github.com/JEFF-Media-GbR/JeffLib/blob/6ad3747cc956431dc1c898d3e79f85d9356d8db3/core/src/main/java/de/jeff_media/jefflib/internal/blackhole/WorldEditHandler.java#L21
You can just copy paste your methods into a new class
i will have to move some methods to a new class... and also change the instance in every class that uses it
yeah next time you should do that like that from the beginning 😛 I also learnt it the hard way
i might do bungee support so ig i will have to do that one day anyway
how do mirrored recipes work?
like axes, hoes, shears, etc.
i thought they were different recipe choices
but they arent
and there's no separated recipe for mirror
RecipeChoices only map a Material/ItemStack to one of the characters
as for the mirrored recipes... yeah that's a good question lmao
maybe md_5 is still here?
cause rc can have different list lenghts
he will probably know it lol
good question. Maybe add a custom recipe and just try it
?
create your own recipe and see if it works when you craft it mirrored
no
not what i mean
so
im trying to get the itemstack that would return from a grid of 9 items
like a crafting table gui
recreation
so i checked for all kinds of recipes
shaped and shapeless
i checked for smaller recipes in all places they could be
and i checked for recipe choices
everything works (afaik) except mirrored recipes
cause there is no recipe that is
ah okay I get it
add
ada
asa
I could imagine that you have to use NMS for that
air, diamond and stick
no?
instance of craft table
and want to check if that results in a recipe
and simulate it?
no
yes
yes
thats what i was thinking of
but
i need to know
if all recipes can be mirrored
or theres some kind of parameter that im missing
not sure, but would be so bad if all recipes would work mirrored with your custom crafting system?
I just wouldn't mind about that and would see it as bonus feature 😄
maybe sth doesnt make sense
when its mirrored
in a grid
I couldn't think of anything where it wouldnt make sense
in vertical it doesnt work
for example you cant craft a bed if you mirror it vertically
but what if there was a vertical bed
it wouldnt make sense to flip it horizontally would it
it would be inconsistent
so idk if there are any items like that
why not? imagine this is a vertical bed
Wood Wool
Wood Wool
Wood Wool
why shouldnt
Wool Wood
Wool Wood
Wool Wood
not make sense?
wouldnt it make sense to be able to craft regular beds mirrored vertically then?
you just kinda flip it after you craft it ig
but my question remains
why is vertical more important ALWAYS than lr
imagine a recipe that was like that but vertical mirroring didnt matter
but lr did
tbf i cant find any recipe
plugin dont work
Hey guys!
When I make a custom inv, I want to disable the player inventory,
Is that possible, that just the custom gui is shown?
Sad.
players will always see their own inventory
What you COULD do is...
clear the player's inventory and use that for your GUI
and after that give them their items back
buuut
I just wouldn't mind seeing the inv
it's like that for all GUIs and has ever been
lol