Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-171688

Invisibility status of LivingEntity is not updated when ActiveEffects are modified directly

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • None
    • 1.15.2, 20w06a, 20w07a, 20w08a, 20w09a, 20w10a, 20w11a, 20w12a, 20w14a, 20w16a, 20w18a, 20w20b, 1.16 Pre-release 5, 1.16.1, 1.16.2 Pre-release 1, 1.16.2, 1.16.3, 1.16.4 Pre-release 1, 1.16.4, 20w45a, 20w46a, 20w48a, 20w49a, 20w51a, 21w03a, 1.16.5, 1.17.1, 21w37a, 1.19.1, 1.19.4, 23w18a, 1.20.2
    • Confirmed
    • Commands, Entities

      The bug

      When ActiveEffects of a living entity are modified directly by /data etc., the effects of the entity do not become dirty. Even though the effects have an invisibility effect, the invisibility status of the entity will not be updated until the effect's duration is a multiple of 600 or other effects are added/updated/removed.

      How to reproduce

      1. /summon minecraft:husk ~ ~ ~ {UUID:[I; 0, 0, 0, 171688]}
      2. /data modify entity 0-0-0-0-29ea8 active_effects set value [{id: "minecraft:invisibility", duration: 1000000}]

        The entity is not invisible.

      3. /effect give 0-0-0-0-29ea8 minecraft:speed

        → The entity is now invisible.

      Code analysis

      When ActiveEffects are modified on deserialization, LivingEntity#effectsDirty is not set to true.

      // net.minecraft.world.entity.LivingEntity
      public void readAdditionalSaveData(CompoundTag tag) {
          ...
          if (tag.contains("ActiveEffects", 9)) {
              ListTag activeEffects = tag.getList("ActiveEffects", 10);
          
              for (int i = 0; i < activeEffects.size(); ++i) {
                  CompoundTag activeEffect = activeEffects.getCompound(i);
                  MobEffectInstance instance = MobEffectInstance.load(activeEffect);
                  if (instance != null) {
                      .activeEffects.put(instance.getEffect(), instance);
                  }
              }
          }
          ...
      }
      

      LivingEntity#updateInvisibilityStatus is not called on ticking since LivingEntity#effectsDirty is false.

      // net.minecraft.world.entity.LivingEntity
      protected void tickEffects() {
          ...
          if (effectsDirty) {
              if (!level.isClientSide) {
                  updateInvisibilityStatus();
              }
      
              effectsDirty = false;
          }
          ...
      }
      

            Unassigned Unassigned
            intsuc intsuc
            Votes:
            6 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              CHK: