#Make different entities for different players

1 messages · Page 1 of 1 (latest)

rigid torrent
#

@tacit glade

#

so im gonna explain what I am doing just to clear up any confusion

#

the moment you first log on, you will spawn on a set of islands and on those islands there may be different mobs and stuff. I want the players to only share entities and stuff once they reach the end which is like a "home base"

#

its a little complicated

narrow hound
#

So you want entities only visible to certain players?

rigid torrent
#

i want my entities to almost be seperate for certain players

#

with their own pathfinding and health

#

they attack the player who is playing, and not a another player who happens to be also doing the beginning

tacit glade
#

What version is this for so I can look for specific classes?

rigid torrent
#

1.19.2

tacit glade
#

kk ty

narrow hound
#

I guess this is kind of impossible because you would need to create a fake entity and basically rewrite the code as similar to Minecraft’s one

#

I mean not really impossible

#

Just really hard

tacit glade
#

Just figuring out the code for it right now

narrow hound
#

It this is possible it would be really cool stuff

#

We should probably make a Library on this

rigid torrent
#

I was thinking maybe hide the entites for one player sort of like how u can hide players from players and then assign each entity a different tag that tells them to only go for a certain player

tacit glade
#

You may be able to do something like this @rigid torrent

#
        final Zombie zombie = new Zombie(EntityType.ZOMBIE, /* World goes here */);
        zombie.targetSelector.removeAllGoals();
        zombie.targetSelector.addGoal(0, new NearestAttackableTargetGoal<Player>(zombie, Player.class, true, (livingEntity) -> {
            if (!(livingEntity instanceof Player target)) {
                return false;
            }
            
            return target.getUUID().equals(/* Put the target players UUID in here*/);
        }));```
#

That's the code with mojang mappings

#

With spigot mappings it's this:

        EntityZombie zombie = new EntityZombie(EntityTypes.bj, /* World goes here */);
        zombie.bT.a();
        zombie.bT.a(0, new PathfinderGoalNearestAttackableTarget(zombie, EntityHuman.class, true, livingEntity -> {
            if (!(livingEntity instanceof EntityHuman)) {
                return false;
            }

            EntityHuman target = (EntityHuman)((Object)livingEntity);
            return target.co().equals(/* Put the target players UUID in here*/);
        }));```
rigid torrent
#

So what does that do

tacit glade
#

Basically

rigid torrent
#

like brief explenation

tacit glade
#

this allows the entity to ONLY attack the target player

rigid torrent
#

Will it also pathfind to only the target player

tacit glade
#

Which means you can then hide the entity from every other player

#

yea

#

it should do

rigid torrent
#

How do u hide the entity

#

Is there a function for that in the Player?

tacit glade
#

Mojang Mappings: ClientboundRemoveEntitiesPacket
Spigot Mappings: PacketPlayOutEntityDestroy

#

Like this -

rigid torrent
#

I should probably ask how i would implement something like this

#

Ive never dealt with packets before

#

Do i call the above after a player joins?

tacit glade
#
        ClientboundRemoveEntitiesPacket removeEntityPacket = new ClientboundRemoveEntitiesPacket(/* Put the entities id's that you want to hide here*/);
        for (final Player nonViewingPlayer : /* Provide the other players that aren't meant to see the enemy here */) {
            ((CraftPlayer) nonViewingPlayer).getHandle().connection.connection.send(removeEntityPacket);
        }```
#

That's for when the entities spawn in

rigid torrent
#

how do i get an entities id?

tacit glade
#

entity.getId()

#

Do you know if you're using mojang mappings or spigot mappings?

rigid torrent
#

what do u mean by that

tacit glade
#

Does either - ClientboundRemoveEntitiesPacket exist or PacketPlayOutEntityDestroy

#

If neither, then you have to run buildtools to get NMS code

rigid torrent
#

when i type them in normally just into intellij nothing comes up to autocomplete

tacit glade
#

Alright

#

Download that, put it in a folder

rigid torrent
#

does build tools work if im using paper

tacit glade
#

Yeah it should still work

#

Because paper is built off of spigot

#

as long as paper hasn't changed anything major, then yeah

rigid torrent
#

after i put it in a folder what do i do

tacit glade
#

Open up command prompt

#

and enter this command -

rigid torrent
#

should i just double click to run

tacit glade
#
java -jar BuildTools.jar --rev 1.19.2 --remapped```
rigid torrent
#

can i just double click

tacit glade
#

no

rigid torrent
#

ight

#

it finished

tacit glade
#

It say build success?

rigid torrent
#

oh wait

#

nvm

#

it said finished and then started decompiling everything

#

i see it all

tacit glade
#

ah yeah

#

just wait for it to completely stop then

rigid torrent
#

it idd

#

did*

tacit glade
#

it says Build Success now?

rigid torrent
#

not that but it said Everything completed successfully

tacit glade
#

Okay cool

#

You using maven for your plugin?

rigid torrent
#

yes

tacit glade
#

Add this dependency and plugin

#

        <dependency>
            <groupId>org.spigotmc</groupId>
            <artifactId>spigot</artifactId>
            <version>1.19.2-R0.1-SNAPSHOT</version>
            <scope>provided</scope>
            <classifier>remapped-mojang</classifier>
        </dependency>```
#
            <plugin>
                <groupId>net.md-5</groupId>
                <artifactId>specialsource-maven-plugin</artifactId>
                <version>1.2.2</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>remap</goal>
                        </goals>
                        <id>remap-obf</id>
                        <configuration>
                            <srgIn>org.spigotmc:minecraft-server:1.19.2-R0.1-SNAPSHOT:txt:maps-mojang</srgIn>
                            <reverse>true</reverse>
                            <remappedDependencies>org.spigotmc:spigot:1.19.2-R0.1-SNAPSHOT:jar:remapped-mojang
                            </remappedDependencies>
                            <remappedArtifactAttached>true</remappedArtifactAttached>
                            <remappedClassifierName>remapped-obf</remappedClassifierName>
                        </configuration>
                    </execution>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>remap</goal>
                        </goals>
                        <id>remap-spigot</id>
                        <configuration>
                            <inputFile>
                                ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar
                            </inputFile>
                            <srgIn>org.spigotmc:minecraft-server:1.19.2-R0.1-SNAPSHOT:csrg:maps-spigot</srgIn>
                            <remappedDependencies>org.spigotmc:spigot:1.19.2-R0.1-SNAPSHOT:jar:remapped-obf
                            </remappedDependencies>
                        </configuration>
                    </execution>
                </executions>
            </plugin>```
#

should have probably put that in a paste

rigid torrent
#

what file do i add it too

tacit glade
#

but whatever

#

pom.xml

rigid torrent
#

in order?

tacit glade
#

just put the dependency inside of the dependencies section

#

and put the plugin inside of

    <plugins>
    
    </plugins>
</build>```
rigid torrent
#

ok

#

it showed me a bunch of errors

tacit glade
#

What is the error?

rigid torrent
#

oh wait

#

put it in the wrong area

tacit glade
#

ah

rigid torrent
#

i have two errors

#

saying net.md-5:specialsource-maven-plugin:1.2.2 not found

tacit glade
#

you clicked this then it appeared? if not, try click the button anyway

rigid torrent
#

ight

#

i will respond in a bit gonna be away from my pc

tacit glade
#

okay

rigid torrent
#

u still here?

#

@tacit glade

tacit glade
#

Yo

rigid torrent
#

hey

#

still got the error

rigid torrent
rigid torrent
#

yes

tacit glade
#

try click this

rigid torrent
tacit glade
#

oh?

#

weird

rigid torrent
#

where did u want me to put the folder

#

for buildtools

tacit glade
#

anywhere on your main drive (I think it has to be on main, not sure tho)

rigid torrent
#

alright

#

its on my desktop

tacit glade
#

Did you run the command exactly how I sent above?

#

when it was in that folder

rigid torrent
#

yup

tacit glade
rigid torrent
#
                <version>1.2.2</version>```
#

thats the two lines causing the error

tacit glade
#

Could you send your pom.xml in here?

#

?paste

rigid torrent
tacit glade
#

try change the version to 1.2.4

rigid torrent
#

it fixed the error

tacit glade
#

Bet

#

No more errors in the pom?

rigid torrent
#

nope!

tacit glade
#

Awesome

tacit glade
rigid torrent
#

so test if what works again

tacit glade
#

Check if "ClientboundRemoveEntitiesPacket" exists

tacit glade
#

pog

rigid torrent
#

it does

rigid torrent
tacit glade
#

yep

rigid torrent
#

i got it

#

i have an issue tho

#

not anything code based or anything

#

just that my test server isnt port forwarded and i have no idea how to test this

tacit glade
#

You could probably turn it online-mode: false

#

and launch multiple clients

rigid torrent
#

alright

#

but wouldnt that still kick me

tacit glade
#

?

rigid torrent
#

because like my normal client is still connected

#

its the same account twice on a server

tacit glade
#

nah just launch up a cracked account

rigid torrent
#

can i just use a forge build

#

i dont have a launcher for that

#

wait nvm

#

i can just ask a friend to help out with it

#

ill just put it on a minehut server or something

#

so where do I put the code blocks u sent

#

still struggling to understand trhat

tacit glade
#

You're going to have to implement it yourself. I'm not going to really spoonfeed all the code. But, I will still help to tell you where to put it.

#

Basically

#

When a player joins, you may want to create the zombie

rigid torrent
#

right

rigid torrent
#

mhm

tacit glade
#

And to actually place it in the world -

#
level.addFreshEntity(zombie, CreatureSpawnEvent.SpawnReason.CUSTOM);```
#

Now, that would make it show for every player, but this is just for testing for now

#

Making sure that the entity actually spawns in

#

Oh one sec

#

there, that's the method

rigid torrent
#

which zombie do i import

tacit glade
#

net.minecraft

rigid torrent
#

same with EntityType?

tacit glade
#

You may also want to set the zombies position by doing -

        zombie.setPos(new Vec3(x, y, z));```
#

Yep

rigid torrent
#

getting errors when trying to put the world in

tacit glade
#

        final Level level = ((CraftWorld) world).getHandle();
        final Zombie zombie = new Zombie(EntityType.ZOMBIE, level);```
#

basically, what that does, is gets the world in NMS

rigid torrent
#

alright

#

zombie.targetSelector.addGoal(0, new NearestAttackableTargetGoal<Player>(zombie, Player.class, true, (livingEntity) getting an error with <Player>

#

saying I should implement LivingEntity instead

#

now that mobs can attack eachother

tacit glade
#

        zombie.targetSelector.addGoal(0, new NearestAttackableTargetGoal<>(zombie, net.minecraft.world.entity.player.Player.class, true, (livingEntity) -> {```
#

Since this is NMS code, it required NMS objects

#

instead of bukkit

#

bukkit is just an abstracted api on top of NMS

rigid torrent
#

zombie.targetSelector.addGoal(0, new NearestAttackableTargetGoal<net.minecraft.world.entity.player.Player>(zombie, Player.class, true, (livingEntity) ->

#

this is what i have

tacit glade
#

change the 2nd player to net.minecraft too

#

also, you don't need the one inside of the generics

rigid torrent
#

alright i did it

tacit glade
#

Can you send a snippet of your code just to make sure everything is gucci

rigid torrent
#

still getting errors so probably not gucci atm

#

 


    @EventHandler
    public void onJoin(PlayerJoinEvent e){

        Player p = e.getPlayer();
        final Level level = ((CraftWorld) p.getWorld()).getHandle();
        final Zombie zombie = new Zombie(EntityType.ZOMBIE, level);
        zombie.targetSelector.removeAllGoals();
        zombie.targetSelector.addGoal(0, new NearestAttackableTargetGoal<>(zombie, net.minecraft.world.entity.player.Player.class, true, (livingEntity) -> 
        {
            if (!(livingEntity instanceof Player target)) {
                return false;
            }

            return target.getUUID().equals(/* Put the target players UUID in here*/);
        }
        ));

    }



}```
tacit glade
#
public class OnJoin implements Listener {

    @EventHandler
    public void onJoin(PlayerJoinEvent event) {
        final Player player = event.getPlayer();
        final Level level = ((CraftWorld) player.getWorld()).getHandle();
        final Zombie zombie = new Zombie(EntityType.ZOMBIE, level);
        zombie.targetSelector.removeAllGoals();
        zombie.targetSelector.addGoal(0, new NearestAttackableTargetGoal<>(zombie, net.minecraft.world.entity.player.Player.class, true, (livingEntity) -> 
        {
            if (!(livingEntity instanceof net.minecraft.world.entity.player.Player target)) {
                return false;
            }

            return target.getUUID().equals(player.getUUID());
        }
        ));
    }
}```
#

Try that @rigid torrent

#

oh wait

#

1 sec

#

One suggestion to help your code be better for people to read or if you ever join the industry. @rigid torrent - don't use single letter variable names

rigid torrent
#

oh i just like using p because its quick and i use it a lot

tacit glade
#

yea

#

fairs

rigid torrent
#

i know its not practical but its whatever

#

do u want me to try the code

#

or are u doing something

tacit glade
#

Before you try the code. Make sure you do all this too -

rigid torrent
#
    public void onJoin(PlayerJoinEvent e){

        Player p = e.getPlayer();
        final Level level = ((CraftWorld) p.getWorld()).getHandle();
        final Zombie zombie = new Zombie(EntityType.ZOMBIE, level);
        zombie.targetSelector.removeAllGoals();
        zombie.setPos(p.getLocation().getX(),p.getLocation().getY(),p.getLocation().getZ());



        zombie.targetSelector.addGoal(0, new NearestAttackableTargetGoal<>(zombie, net.minecraft.world.entity.player.Player.class, true, (livingEntity) ->
        {
            if (!(livingEntity instanceof Player target)) {
                return false;
            }

            return target.getUUID().equals(/* Put the target players UUID in here*/);
        }

        ));
        level.addFreshEntity(zombie, CreatureSpawnEvent.SpawnReason.CUSTOM);

    }







tacit glade
rigid torrent
#

does that work?

#

wait im getting errors with getUUID

#

oh

#

im dumb

#

still an error

#

Patterns in 'instanceof' are not supported at language level '8'

#

pls dont tell me i gotta update by java version

#

wait why would u name that there

tacit glade
rigid torrent
#

the target

rigid torrent
#

its causing errors somewhere else though

tacit glade
#
 @EventHandler
    public void onJoin(PlayerJoinEvent e){

        Player p = e.getPlayer();
        final Level level = ((CraftWorld) p.getWorld()).getHandle();
        final Zombie zombie = new Zombie(EntityType.ZOMBIE, level);
        zombie.targetSelector.removeAllGoals();
        zombie.setPos(p.getLocation().getX(),p.getLocation().getY(),p.getLocation().getZ());



        zombie.targetSelector.addGoal(0, new NearestAttackableTargetGoal<>(zombie, net.minecraft.world.entity.player.Player.class, true, (livingEntity) ->
        {
            if (!(livingEntity instanceof net.minecraft.world.entity.player.Player target)) {
                return false;
            }

            return ((net.minecraft.world.entity.player.Player) target).getUUID().equals(/* Put the target players UUID in here*/);
        }

        ));
        level.addFreshEntity(zombie, CreatureSpawnEvent.SpawnReason.CUSTOM);

    }```
rigid torrent
#

still says it

#

Patterns in 'instanceof' are not supported at language level '8'

tacit glade
#

remove "target"

#

from the instanceof

rigid torrent
#

i just updated to 16

tacit glade
#

fairs

rigid torrent
#

no more errors

tacit glade
#

sickk

rigid torrent
#

and less outdated

#

so just build and test right

#

not getting any zombie spawning in

#

nothign else in my plugin is working either

#

none of the commands anyway

tacit glade
#

Drag the -remapped jar from the folder in instead

rigid torrent
#

drag it where

tacit glade
#

In your server instead

rigid torrent
#

just in the main server file

#

not plugins or anything

tacit glade
#

in the plugins folder lol

#

just replace the current plugin with the -remapped.jar

rigid torrent
#

i cant find it

#

is it in build tools?

tacit glade
#

When you build the plugin, what is in the target folder?

rigid torrent
#

the plugin

tacit glade
#

anything else?

#

can you send an ss?

rigid torrent
#

the other plugins i have

#

i cant put images here for some reason

tacit glade
#

Wait where are you looking?

rigid torrent
#

the plugins folder

tacit glade
#

oh

#

no

#

the "target" folder

#

of the plugin you built

#

there should be a "...-remapped.jar"

rigid torrent
#

i build using an artifact

#

what should i build with?

tacit glade
#

maven install

rigid torrent
#

where will it build to

tacit glade
#

to a folder named "target"

rigid torrent
#

in the project?

tacit glade
#

yea

rigid torrent
#

i see it

#

what jar

tacit glade
rigid torrent
#

yeah

tacit glade
#

that one

rigid torrent
#

drag it into plugins and delete old one?

tacit glade
#

yeah

rigid torrent
#

zombie spawned 😄

tacit glade
#

pog

#

it attack you?

rigid torrent
#

immidiantly

tacit glade
#

Awesome!!

rigid torrent
#

and everything else works

tacit glade
#

: D

#

Now, that zombie, if I was correct with the code, should ONLY attack you

#

😄

rigid torrent
#

yes

#

so now i need to hide the zombie right

tacit glade
#

Yep

#

You can hide the zombie for everyone that doesn't need to see it

tacit glade
#

Yep 😄

rigid torrent
#

so i put that in the join event aswell right

tacit glade
#

yeah

rigid torrent
#

i need to get the entities that i want to hide though

#

so when i spawn the entities in

#

can i give them a tag with the players uuid or something

#

and then any mob without it loses it

tacit glade
rigid torrent
#

because i need to identify who caused the mob to spawn right

#

to then hide any mob without it

tacit glade
#

You could probably store the entities in a map or smtn

rigid torrent
#

i dont think a hashmap would be worth if they get immidiantly killed imo

#

i think ill do the tag thing

#

i just dont know how to add custom tags to mobs

tacit glade
#

Thing is, with the map, you can then hide the entities from other players that join the server

rigid torrent
#

yeah

#

so i just put the entities in a hashmap linked with the player

tacit glade
#

Yea, or you can put the entities id's instead

#

To not cause memory leaks lol

rigid torrent
#

how do u get the entities id

tacit glade
#

.getId()

rigid torrent
#

ok

#

will try

#

ill post results here

#

btw is there a packet to send to the player to make their hearts hardcore hearts

rigid torrent
#

@tacit glade should i save the hashmap to a file?

rigid torrent
#

wait why would i even need to use a hashmap

#

@tacit glade

tacit glade
#

ig so you know who's entities are who's

rigid torrent
#

wait hold on

#
        for (final Player nonViewingPlayer : /* Provide the other players that aren't meant to see the enemy here */) {
            ((CraftPlayer) nonViewingPlayer).getHandle().connection.connection.send(removeEntityPacket);
        }```
#

thats what i have so far

#

i just cant figure out what to do at the bottom

tacit glade
#

at the bottom?

#

do you mean "/* Provide the other players that aren't meant to see the enemy here */"? @rigid torrent

rigid torrent
#

yes

tacit glade
#

List<Player> players = new ArrayList<>(Bukkit.getWorld(/*world name*/).getPlayers());
players.remove(player);

#

why not amirite

#

@rigid torrent

rigid torrent
#

wait but

#

what about when a player joins the server

#

i can see their zombie then

tacit glade
#

?

rigid torrent
#

likie if it were the players in the world, after i joined, the code would have already ran and then they would be able to see my zombie

tacit glade
#

what

rigid torrent
#

im calling it on an on join event

#

so think about this

#

i join the server

#

my zombie gets hidden for all other players on the server

#

then if someone else joins

#

they are not a part of the list

tacit glade
#

oh yeah

#

was gonna explain that

#

basically by storing all the entities in the map, you can then send the packet for removing the zombies

#

like this:

rigid torrent
#

when im finished with this i am making an api for this because this is complicated

tacit glade
#

    final Map<UUID, Integer> enemiesIds = new HashMap<>();

join event ->
    final Player player = event.getPlayer();
    final ClientboundRemoveEntitiesPacket clientboundRemoveEntitiesPacket = new ClientboundRemoveEntitiesPacket(this.enemiesIds.values().stream().mapToInt(Integer::intValue).toArray());
    ((CraftPlayer) player).getHandle().connection.connection.send(clientboundRemoveEntitiesPacket);
#

something like that @rigid torrent

rigid torrent
#

the first line is in the class right

#

but just not in the EventHandler

tacit glade
#

yea

rigid torrent
#

alright imma try it out

#

so what exactly does the code do

#

just brief explenation

#

because i have no idea how to read that

tacit glade
#

final ClientboundRemoveEntitiesPacket clientboundRemoveEntitiesPacket = new ClientboundRemoveEntitiesPacket(this.enemiesIds.values().stream().mapToInt(Integer::intValue).toArray());

#

that just creates the packet

#

and converts the "Integer" from the map into an array of int's

#

the Integer in the map refers to the entities id's

#

that you want to hide from the players

rigid torrent
#

where do i put the players or the zombies

#

or does it already do that

#

do i add the zombie to the enemiesIds after spawning it

tacit glade
#

actually I've got a better idea

#
    final Set<Integer> enemiesIds = new HashSet<>();

join event ->
    final Player player = event.getPlayer();
    final ClientboundRemoveEntitiesPacket clientboundRemoveEntitiesPacket = new ClientboundRemoveEntitiesPacket(this.enemiesIds.stream().mapToInt(Integer::intValue).toArray());
    ((CraftPlayer) player).getHandle().connection.connection.send(clientboundRemoveEntitiesPacket);```
#

@rigid torrent

rigid torrent
#

how is this any different

tacit glade
#

you don't need a key

#

less memory usage

#

and Set's have a smaller memory footprint than lists

rigid torrent
#

thats smart

#

wait so how do i add the id to the set then

tacit glade
#

.add

#

same as a list

rigid torrent
#

enemiesIds.add(zombie.getId()); this would go after it spawns

tacit glade
#

yep

rigid torrent
tacit glade
#

because when a player joins, it will send the remove packet to them - for all the zombies that are going to be hidden

rigid torrent
#

and for existing players?

tacit glade
#

no need to worry about that, the code below the spawn code should do that

#

if you kept the ClientboundRemoveEntitiesPacket there

rigid torrent
#

where is there

#

oh

#

i still dont have that one

#

i dont know what to put in the bottom one remember

rigid torrent
#

yeah but that would still be current players

tacit glade
#

?

rigid torrent
#

like wouldnt that still only apply to current players

tacit glade
#

it will hide it for everyone in the world except the player that joined

#

can you send me your current code?

rigid torrent
#

yeah but i have not added the ClientboundRemoveEntitiesPacket

#

    final Set<Integer> enemiesIds = new HashSet<>();





    @EventHandler
    public void onJoin(PlayerJoinEvent e){
        Player p = e.getPlayer();

        if(p.hasPlayedBefore() == false){
            Server.joinedPlayers[Server.joinedPlayers.length + 1] = p;
        }
        


        final Level level = ((CraftWorld) p.getWorld()).getHandle();
        final Zombie zombie = new Zombie(EntityType.ZOMBIE, level);
        zombie.targetSelector.removeAllGoals();
        zombie.setPos(p.getLocation().getX(),p.getLocation().getY(),p.getLocation().getZ());



        zombie.targetSelector.addGoal(0, new NearestAttackableTargetGoal<>(zombie, net.minecraft.world.entity.player.Player.class, true, (livingEntity) ->
        {
            if (!(livingEntity instanceof net.minecraft.world.entity.player.Player target)) {
                return false;
            }

            return ((net.minecraft.world.entity.player.Player) target).getUUID().equals(p.getUniqueId());
        }

        ));
        level.addFreshEntity(zombie, CreatureSpawnEvent.SpawnReason.CUSTOM);

        enemiesIds.add(zombie.getId());


        final ClientboundRemoveEntitiesPacket clientboundRemoveEntitiesPacket = new ClientboundRemoveEntitiesPacket(this.enemiesIds.stream().mapToInt(Integer::intValue).toArray());
        ((CraftPlayer) p).getHandle().connection.connection.send(clientboundRemoveEntitiesPacket);






        


    }



}```
tacit glade
#
public class OnJoin implements Listener {
    private final Set<Integer> enemiesIds = new HashSet<>();

    @EventHandler
    public void hideAllEntities(PlayerJoinEvent e) {
        final Player player = e.getPlayer();
        final ClientboundRemoveEntitiesPacket clientboundRemoveEntitiesPacket = new ClientboundRemoveEntitiesPacket(this.enemiesIds.stream().mapToInt(Integer::intValue).toArray());
        ((CraftPlayer) player).getHandle().connection.connection.send(clientboundRemoveEntitiesPacket);
    }

    @EventHandler
    public void onJoin(PlayerJoinEvent e){
        Player p = e.getPlayer();
        if(p.hasPlayedBefore() == false){
            Server.joinedPlayers[Server.joinedPlayers.length + 1] = p;
        }
        
        final Level level = ((CraftWorld) p.getWorld()).getHandle();
        final Zombie zombie = new Zombie(EntityType.ZOMBIE, level);
        zombie.setPos(p.getLocation().getX(),p.getLocation().getY(),p.getLocation().getZ());
        zombie.collides = false;
        zombie.targetSelector.removeAllGoals();
        zombie.targetSelector.addGoal(0, new NearestAttackableTargetGoal<>(zombie, net.minecraft.world.entity.player.Player.class, true, (livingEntity) -> {
            if (!(livingEntity instanceof net.minecraft.world.entity.player.Player target)) {
                return false;
            }

            return ((net.minecraft.world.entity.player.Player) target).getUUID().equals(p.getUniqueId());
        }));
        level.addFreshEntity(zombie, CreatureSpawnEvent.SpawnReason.CUSTOM);

        enemiesIds.add(zombie.getId());
        this.hideToOnlinePlayers(p, zombie);
    }

    private void hideToOnlinePlayers(Player owner, Zombie zombie) {
        final ClientboundRemoveEntitiesPacket removeEntityPacket = new ClientboundRemoveEntitiesPacket(zombie.getId());
        final List<Player> players = new ArrayList<>(p.getWorld().getPlayers());
        players.remove(owner);
        for (final Player online : players) {
            ((CraftPlayer) online).getHandle().connection.connection.send(removeEntityPacket);
        }
    }
}```
@rigid torrent
rigid torrent
#

do u jut want me to replace that?

tacit glade
#

yeah try that code

#

quite easy to understand i think

rigid torrent
#

when you say p and player in the bottom function what player are u talking about because there is no variable

tacit glade
#

Fixed @rigid torrent

rigid torrent
#

oh ok

#

do u want me to replace p with owner or is it something else

tacit glade
#

yea

#

sure

rigid torrent
#

alright ill try it

rigid torrent
#

@tacit glade

#

mob collisions

#

how do i prevent them

tacit glade
#

Try change "max-entity-collisions" in the spigot.yml and something else to 0 @rigid torrent

rigid torrent
#

Yeah but i would like to have mobs later on collide

tacit glade
#

question, did you copy all my code that I sent or only add the things you saw

rigid torrent
#

Copy

tacit glade
#

hm alr

#

weird

rigid torrent
#

i havent ran it yet i just thought about it

tacit glade
#

oh

rigid torrent
#

i wasnt at my pc at the time

tacit glade
#

I disabled it alreaady

rigid torrent
#

ohh ok

tacit glade
#

😉

rigid torrent
#

thanks

#

are u on mc rn

#

nvm i forgot about offline mode

rigid torrent
#

@tacit glade i cant test it today but i will definitely let you know when i can and if it works

#

this needs to become an api sometime in the future

#

super useful

#

yet complicated

rigid torrent
rigid torrent
#

but then if they relog they can see it

tacit glade
#

Add delay to the even which hides them when the player joins

#

2 ticks should be good

rigid torrent
#

what do u mean?

#

event?

tacit glade
rigid torrent
#

how do u delay those

tacit glade
#

using a bukkit scheduler

rigid torrent
#

do i do it to both or just hideAllEntities

tacit glade
#

just that one

rigid torrent
#

you want me to put it in a bukkit runnable?

tacit glade
#

Bukkit.getScheduler().runTaskLater(() -> {
/* Code goes here */
}, 2);

rigid torrent
#

oh alright

#

the only way i knew how to do it was runnables

#

Cannot resolve method 'runTaskLater(<lambda expression>, int)'

tacit glade
#

show me what u got

#

just the event

rigid torrent
#
    public void hideAllEntities(PlayerJoinEvent e) {
        Bukkit.getScheduler().runTaskLater(() ->{
            final Player player = e.getPlayer();
            final ClientboundRemoveEntitiesPacket clientboundRemoveEntitiesPacket = new ClientboundRemoveEntitiesPacket(this.enemiesIds.stream().mapToInt(Integer::intValue).toArray());
            ((CraftPlayer) player).getHandle().connection.connection.send(clientboundRemoveEntitiesPacket);
        },2);
    }```
tacit glade
#

oh yeah

#

the plugin instance

#
  @EventHandler
    public void hideAllEntities(PlayerJoinEvent e) {
        Bukkit.getScheduler().runTaskLater(plugin, () ->{
            final Player player = e.getPlayer();
            final ClientboundRemoveEntitiesPacket clientboundRemoveEntitiesPacket = new ClientboundRemoveEntitiesPacket(this.enemiesIds.stream().mapToInt(Integer::intValue).toArray());
            ((CraftPlayer) player).getHandle().connection.connection.send(clientboundRemoveEntitiesPacket);
        },2);
    }```
rigid torrent
#

ohh

#

forgot to add the plugin

#

let me test

#

still need a fix for mob sounds

#

everything else is working great

tacit glade
#

You fine with the entity being completely silent?

rigid torrent
#

yeah sure its only like 2 zombies and a spider at the very beginning of the game so i dont mind

tacit glade
#

.setSilent(true)

rigid torrent
#

alright

#

when u do player.playSound, does it only play for the player u play it on

tacit glade
#

Yeah

rigid torrent
#

perfect

#

are u familiar with multi world support

tacit glade
#

?

rigid torrent
#

like tping the player into custom worlds

#

like multiverse does

tacit glade
#

ah

rigid torrent
#

do u know

tacit glade
#

pretty sure you can just do "player.teleport(new Location(/* The world */, x, y, z))"

rigid torrent
#

how would u get the world

tacit glade
#

Bukkit.getWorld("world name")

rigid torrent
#

alright

#

is it possible to make somebody see hardcore hearts on their screen using packets

tacit glade
#

Yeah

rigid torrent
#

how would that work

tacit glade
#

lemme find it

rigid torrent
#

u dont have to write the code but u can link me to a javadoc or something

tacit glade
#

Probably going to have to intercept the "ClientboundLoginPacket" @rigid torrent

#

That contains all the information about the server when the player first joins

rigid torrent
#

and hardcore hearts are through the server.properties so that make sense i guess

tacit glade
#

yea