xSavior-of-God / ArmorStand-Limiter

Problems with tps? Is it ArmorStand's fault? Use ArmorStandLimiter to prevent your server from crash
MIT License
3 stars 1 forks source link

ArmorStand water move enhancement #3

Open kaxlabs opened 2 years ago

kaxlabs commented 2 years ago

If you're using papermc, you can accomplish preventing armorstands from moving in water quite easily without disabling gravity:

    @EventHandler
    public void onEntityMove(EntityMoveEvent event) {
        if (event.getEntity() instanceof ArmorStand armorstand) {
            if (armorstand.isInWater()) {
                event.setCancelled(true);
            }
        }
    }

I don't have enough time to make a pull request, but since you're using spigot-api, I'd recommend using reflection to check if the papermc event exists.

xSavior-of-God commented 2 years ago

Hi @kaxon-dev, thanks for the advice. As soon as I have a moment I add it to the checks.

xSavior-of-God commented 2 years ago

I found the method you mentioned above (armorstand.isInWater()) in the spigot API. I'm not sure if it is present in all versions, as soon as I have a moment I take a look. https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/Entity.html#isInWater()

for now the idea is to diversify these two checks for what they are, so 1 => to disable the gravity 2 => to disable movement in the water

but i'm sure that i don't need to add paper-api for now.

xSavior-of-God commented 2 years ago

Hi @kaxon-dev, I analyzed the thing a bit, and in my opinion it could be heavy as a process for a spigot server. For a papermc I don't know how such an event can be optimized, it always check the location of each entity every time, (Imagine the weight of this process if you have millions of entities in the world).

So, after a few attempts I believe that it is not the best way to block this type of event, reasons:

Yes, you could do the listener by hand, i.e. check all the armorstand 1 to 1 for each x tick, but in my opinion it is bullshit:

I don't know, but in my opinion it seems like bullshit, when you could just block gravity since the generation of the entity.

Ah yes, I assume that paper does this thing like that, for each entity, I don't know how it doesn't make it overlap, but in my opinion some slight delay is present with the increase of entities and players.

So in summary, I'm sorry but it's not possible at the moment. If you have any better ideas to handle it, say it... for now, I don't see a better way than to turn off the gravity.

kaxlabs commented 2 years ago

Thanks for the information. Since that solution isn't feasible, how about instead of disabling armor stand gravity altogether, you add a configuration setting for scanning the chunks every X amount of minutes and set their gravity depending on whether or not they're in water?

if (entity.getType() == EntityType.ARMOR_STAND) {
    entity.setGravity(!entity.isInWater());
}
xSavior-of-God commented 2 years ago

Hi, Yes it is a good idea, but I do not do the method for everyone, I mean, I would do something that does not involve the change of the gravity of all the armorstands, in order to avoid delays, I'd rather do something like:

If condition: armorstand is in water and gravity is enabled do: disable gravity else: continue;

The only thing now is to figure out if I can add this check to the thread that checks the number of armorstand x chunk/xyz... or do a new thread...

Anyway, I'll try to optimize the controls, also if i can, i try to manage everything from 1 single common thread.