Пример #1
0
  /**
   * Only used in Vanilla. The Forge version is much different. Basically, this accepts the various
   * "objects" needed to work for an armor piece to be "damaged".
   *
   * <p>This is also where we can likely throw a damage item event.
   *
   * @param entity
   * @param damageSource
   * @param modifier
   * @param damage
   */
  public static void acceptArmorModifier(
      EntityLivingBase entity, DamageSource damageSource, DamageModifier modifier, double damage) {
    Optional<DamageObject> property = modifier.getCause().first(DamageObject.class);
    final net.minecraft.item.ItemStack[] inventory =
        entity instanceof EntityPlayer
            ? ((EntityPlayer) entity).inventory.armorInventory
            : entity.getInventory();
    if (property.isPresent()) {
      damage = Math.abs(damage) * 25;
      net.minecraft.item.ItemStack stack = inventory[property.get().slot];
      int itemDamage = (int) (damage / 25D < 1 ? 1 : damage / 25D);
      stack.damageItem(itemDamage, entity);

      if (stack.stackSize <= 0) {
        inventory[property.get().slot] = null;
      }
    }
  }
Пример #2
0
  public static Optional<List<Tuple<DamageModifier, Function<? super Double, Double>>>>
      createEnchantmentModifiers(EntityLivingBase entityLivingBase, DamageSource damageSource) {
    net.minecraft.item.ItemStack[] inventory =
        entityLivingBase instanceof EntityPlayer
            ? ((EntityPlayer) entityLivingBase).inventory.armorInventory
            : entityLivingBase.getInventory();
    if (EnchantmentHelper.getEnchantmentModifierDamage(inventory, damageSource) == 0) {
      return Optional.empty();
    }
    List<Tuple<DamageModifier, Function<? super Double, Double>>> modifiers = new ArrayList<>();
    boolean first = true;
    int totalModifier = 0;
    for (net.minecraft.item.ItemStack itemStack : inventory) {
      if (itemStack == null) {
        continue;
      }
      NBTTagList enchantmentList = itemStack.getEnchantmentTagList();
      if (enchantmentList == null) {
        continue;
      }
      for (int i = 0; i < enchantmentList.tagCount(); ++i) {
        final short enchantmentId =
            enchantmentList.getCompoundTagAt(i).getShort(NbtDataUtil.ITEM_ENCHANTMENT_ID);
        final short level =
            enchantmentList.getCompoundTagAt(i).getShort(NbtDataUtil.ITEM_ENCHANTMENT_LEVEL);

        if (Enchantment.getEnchantmentById(enchantmentId) != null) {
          // Ok, we have an enchantment!
          final Enchantment enchantment = Enchantment.getEnchantmentById(enchantmentId);
          final int temp = enchantment.calcModifierDamage(level, damageSource);
          if (temp != 0) {
            ItemStackSnapshot snapshot = ((ItemStack) itemStack).createSnapshot();
            // Now we can actually consider this as a modifier!

            final DamageObject object = new DamageObject();
            int modifier = enchantment.calcModifierDamage(level, damageSource);
            object.previousDamage = totalModifier;
            if (object.previousDamage > 25) {
              object.previousDamage = 25;
            }
            totalModifier += modifier;
            object.augment = first;
            object.ratio = modifier;
            Function<? super Double, Double> enchantmentFunction =
                damageIn -> {
                  if (object.augment) {
                    enchantmentDamageTracked = damageIn;
                  }
                  if (damageIn <= 0) {
                    return 0D;
                  }
                  double actualDamage = enchantmentDamageTracked;
                  if (object.previousDamage > 25) {
                    return 0D;
                  }
                  double modifierDamage = actualDamage;
                  double magicModifier;
                  if (modifier > 0 && modifier <= 20) {
                    int j = 25 - modifier;
                    magicModifier = modifierDamage * (float) j;
                    modifierDamage = magicModifier / 25.0F;
                  }
                  return -Math.max(actualDamage - modifierDamage, 0.0D);
                };
            if (first) {
              first = false;
            }

            DamageModifier enchantmentModifier =
                DamageModifier.builder()
                    .cause(
                        Cause.of(
                            NamedCause.of("ArmorEnchantment", enchantment),
                            NamedCause.of("ItemStack", snapshot),
                            NamedCause.of(DamageEntityEvent.SOURCE, entityLivingBase)))
                    .type(DamageModifierTypes.ARMOR_ENCHANTMENT)
                    .build();
            modifiers.add(new Tuple<>(enchantmentModifier, enchantmentFunction));
          }
        }
      }
    }
    if (!modifiers.isEmpty()) {
      return Optional.of(modifiers);
    } else {
      return Optional.empty();
    }
  }
Пример #3
0
  public static Optional<List<Tuple<DamageModifier, Function<? super Double, Double>>>>
      createArmorModifiers(
          EntityLivingBase entityLivingBase, DamageSource damageSource, double damage) {
    if (!damageSource.isDamageAbsolute()) {
      damage *= 25;
      net.minecraft.item.ItemStack[] inventory =
          entityLivingBase instanceof EntityPlayer
              ? ((EntityPlayer) entityLivingBase).inventory.armorInventory
              : entityLivingBase.getInventory();
      List<Tuple<DamageModifier, Function<? super Double, Double>>> modifiers = new ArrayList<>();
      List<DamageObject> damageObjects = new ArrayList<>();
      for (int index = 0; index < inventory.length; index++) {
        net.minecraft.item.ItemStack itemStack = inventory[index];
        if (itemStack == null) {
          continue;
        }
        Item item = itemStack.getItem();
        if (item instanceof ItemArmor) {
          ItemArmor armor = (ItemArmor) item;
          double reduction = armor.damageReduceAmount / 25D;
          DamageObject object = new DamageObject();
          object.slot = index;
          object.ratio = reduction;
          damageObjects.add(object);
        }
      }
      boolean first = true;
      double ratio = 0;

      for (DamageObject prop : damageObjects) {
        EquipmentType type = resolveEquipment(prop.slot);

        final DamageObject object = new DamageObject();
        object.ratio = ratio;
        if (first) {
          object.previousDamage = damage;
          object.augment = true;
        }
        Function<? super Double, Double> function =
            incomingDamage -> {
              incomingDamage *= 25;
              if (object.augment) {
                // This is the damage that needs to be archived for the "first" armor modifier
                // function since the armor modifiers work based on the initial damage and not as
                // a chain one after another.
                damageToHandle = incomingDamage;
              }
              double functionDamage = damageToHandle;
              object.previousDamage = functionDamage;
              object.ratio = prop.ratio;
              object.ratio += prop.ratio;
              return -((functionDamage * prop.ratio) / 25);
            };
        ratio += prop.ratio;

        DamageModifier modifier =
            DamageModifier.builder()
                .cause(
                    Cause.of(
                        NamedCause.of(
                            DamageEntityEvent.GENERAL_ARMOR + ":" + type.getId(),
                            ((org.spongepowered.api.item.inventory.ItemStack) inventory[prop.slot])
                                .createSnapshot()),
                        NamedCause.of(
                            "ArmorProperty", prop), // We need this property to refer to the slot.
                        NamedCause.of("0xDEADBEEF", object))) // We need this object later on.
                .type(DamageModifierTypes.ARMOR)
                .build();
        modifiers.add(new Tuple<>(modifier, function));
        first = false;
      }
      if (modifiers.isEmpty()) {
        return Optional.empty();
      } else {
        return Optional.of(modifiers);
      }
    }
    return Optional.empty();
  }