randombyte-developer / holograms

A Sponge plugin
https://ore.spongepowered.org/RandomByte/Holograms
GNU General Public License v2.0
6 stars 2 forks source link

One bug: Restart server to see created holograms (API 4) #2

Closed ryantheleach closed 8 years ago

ryantheleach commented 8 years ago

Is this fixable? I'm working with a server owner, and this is an utter pain, I would have forked and attempted to fix, but I'm not experienced enough in the issue, or Kotlin to start debugging.

So figured I'd reach out to you first.

randombyte-developer commented 8 years ago

It is a Sponge bug: https://forums.spongepowered.org/t/holograms-easily-create-floating-texts/12861/88?u=randombyte It should only happen with api v4.1. The spawning code is the same for both apis in my plugin. If you need any help with my code or so, I'm here.

ryantheleach commented 8 years ago

Tried swapping prepare and spawn?

I've been spawning in armor stands seemingly fine, (granted I've not been naming them)

ArmorStand entity = (ArmorStand) world.getExtent().createEntity(EntityTypes.ARMOR_STAND, location.getPosition()).get();
        ItemStack stack = <snip>
        entity.setItemInHand(stack);
        entity.offer(Keys.ARMOR_STAND_HAS_GRAVITY, false);
        entity.offer(Keys.ARMOR_STAND_MARKER, true);
        return entity;

Further along the stack

entity.setLocation(origin.add(v));
            SpawnCause spawnCause =
                    EntitySpawnCause.builder()
                            .entity(entity)
                            .type(SpawnTypes.PLUGIN)
                            .build();
            entity.getWorld().spawnEntity(entity, Cause.source(spawnCause).build());
randombyte-developer commented 8 years ago

After testing I found this: As long as I don't make the ArmorStand invisible it spawns correctly. Delaying the invisibility only 1 tick almost solves the problem: Now you don't have to restart the server, instead you only have to reconnect your client to the server to see the text. https://github.com/randombyte-developer/holograms/commit/6ae7a5d5086ba0db1d5c54c3f84e94a780ac14a4#diff-30a9f1d304553d50332399b84e661c6dR48

ryantheleach commented 8 years ago

ooh, right hangon, I missed a part of the code path.

After it's spawned (which happens 1 tick after the creation due to the way my animations are setup) I use the native .setInvisible() in order to have proper invis instead of vanish (or at least I thought that's why I was doing it, I may have unintentionally hit the same bug as you) I then setPositionAndUpdate because I had the native entity handy, so I bypassed the bug seemingly by accident.

Apologies for the awful code. I never got around to cleaning it up after it was working.

Vector3d v = Vector3d.createDirectionRad(0, offset + time * speed);
        if(lastTick == -1) {
            entity.setLocation(origin.add(v));
            SpawnCause spawnCause =
                    EntitySpawnCause.builder()
                            .entity(entity)
                            .type(SpawnTypes.PLUGIN)
                            .build();
            entity.getWorld().spawnEntity(entity, Cause.source(spawnCause).build());
        }
        entity.setLocation(origin.add(v));
        ArmorStand armorE = (ArmorStand) entity;
        EntityArmorStand nativeE = (EntityArmorStand) entity;
        float fspeed = (float) speed;
        float foffset = (float) offset;
        float deg = (float) (((-foffset - (time * fspeed)) * 180) / Math.PI);
        Rotations rota = new Rotations(180f, MathHelper.wrapAngleTo180_float(deg), 0f);
        nativeE.setRightArmRotation(rota);
        nativeE.setInvisible(true);
        nativeE.setPositionAndUpdate(nativeE.posX, nativeE.posY, nativeE.posZ);
        lastTick = time;
        return true;
randombyte-developer commented 8 years ago

So setPositionAndUpdate(...) would also help in my case? But I won't add NMS stuff, it is easy to work around(reconnect client). And API v5 will be released soon and I will probably drop API v4.1.0 support.

ryantheleach commented 8 years ago

Not sure, it may be the set invisible thing.

In regards to setPositionAndUpdate() you wouldn't need to call it directly, just via whatever mechanism sponge would call it.

setting the location of the armorstand to the same position might be enough after it spawns.

randombyte-developer commented 8 years ago

Re-setting the location(even to other location) immediately after spawning or with delay doesn't help. I leave it as it is. But thanks for your help!