Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mob#setAggressive() Should Modify Anger/Goals #11360

Open
MegaTophat opened this issue Sep 5, 2024 · 2 comments
Open

Mob#setAggressive() Should Modify Anger/Goals #11360

MegaTophat opened this issue Sep 5, 2024 · 2 comments
Labels
status: needs triage type: bug Something doesn't work as it was intended to. version: 1.21.1

Comments

@MegaTophat
Copy link

Expected behavior

When running the following code on a Player p:

private static void stopSwarming(final Player player) {
    for (final World world : player.getServer().getWorlds()) {
        for (final Mob mob : world.getEntitiesByClass(Mob.class)) {
            if (!player.equals(mob.getTarget())) {
                continue;
            }

            mob.setTarget(null);
            mob.setAggressive(false);
        }
    }
}

I expect the anger/pendingTarget Goals of that Mob entity to be changed internally to also remove the target and their aggression from their memories. Below is an example of what I would expect the "anger" Goal of an Enderman to look like after this method is invoked:
image
Notice that the "pendingTarget" field is null.

This stops the Mob from immediately becoming aggressive again for any anger based mob(Enderman, Pigman, Wolf, etc)

Observed/Actual behavior

The Enderman I was testing on all had their Enderman#getTarget() set to null, but did not have their targetSelector.pendingTarget set to null, meaning the next tick they would immediately re-aggro onto the same player.

Steps/models to reproduce

Go to the end/nether. Run this code on any given Player

private static void aggroOn(final Player player) {
    final Collection<Mob> mobs = player.getLocation().getNearbyEntitiesByType(Mob.class, 100.0, 20.0);

    mobs.forEach(mob -> {
        mob.setAggressive(true);
        mob.setTarget(player);
    }
}

Then give it a couple of ticks for the anger to fully settle in.
Then run this method on the same Player

for (final Mob mob : world.getEntitiesByClass(Mob.class)) {
    if (!player.equals(mob.getTarget())) {
        continue;
    }

    mob.setTarget(null);
    mob.setAggressive(false);
}

The mobs will stop attacking for one tick then most will immediately resume attacking on the next tick

Plugin and Datapack List

pl
[12:33:13 INFO]: Server Plugins (1):
[12:33:13 INFO]: Paper Plugins:
[12:33:13 INFO]: - SandboxPlugin

SandboxPlugin is the plugin I'm working on where this code is present

datapack list
[12:34:11 INFO]: There are 3 data pack(s) enabled: [vanilla (built-in)], [file/bukkit (world)], [paper (built-in)]
[12:34:11 INFO]: There are no more data packs available

Paper version

version
[12:31:50 INFO]: Checking version, please wait...
[12:31:51 INFO]: This server is running Paper version 1.21.1-57-master@b483da4 (2024-09-01T18:09:05Z) (Implementing API version 1.21.1-R0.1-SNAPSHOT)
You are running the latest version
Previous version: 1.21.1-56-227c94a (MC: 1.21.1)

Other

There appears to be infrastructure that could fix this somewhat simply, but would require work for every individual Mob.
This is currently what the NMS setAggressive() method does

public void setAggressive(boolean attacking) {
        byte b0 = (Byte) this.entityData.get(Mob.DATA_MOB_FLAGS_ID);

        this.entityData.set(Mob.DATA_MOB_FLAGS_ID, attacking ? (byte) (b0 | 4) : (byte) (b0 & -5));
    }

Maybe each extension of the Mob abstract class could override this method and invoke super.setAggressive(), then null out any pending aggression/universal anger goals?

@MegaTophat MegaTophat added status: needs triage type: bug Something doesn't work as it was intended to. labels Sep 5, 2024
@electronicboy
Copy link
Member

from what I recall there was a similar issue for this in the past which was a "won't fix", as the only real solution was a state shotgun

@Owen1212055
Copy link
Member

Yeah, I agree this should be a won’t fix. Use goal api if you wanna control this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs triage type: bug Something doesn't work as it was intended to. version: 1.21.1
Projects
Status: 🕑 Needs Triage
Development

No branches or pull requests

3 participants