// 属性加成(属性修饰符)添加和更新函数

////////内部数值说明////////
// 加成算法类型：
// 0：相加
// 1：对原数值乘算
// 2：最后乘算
// 使用相同的属性ID+Name会更新而非添加属性

////////调用方法////////
// 添加和更新属性加成：
// global.AttributeEnhancement(生物,属性ID,Name,数字,加成算法)
// 删除属性加成
// global.RemoveAttributeModifier(生物,属性ID,Name)

////////其他////////
// 修饰符的uuid根据Name自动生成
// 此代码会修复玩家死亡再复活时丢失属性的问题，需要放在server_scripts目录内

// 辅助函数：生成UUID
function generateUUIDFromName(Name) {
  let JavaString = Java.loadClass("java.lang.String")
  let UUID = Java.loadClass("java.util.UUID")
  let NameHash = new JavaString(Name).hashCode()
  return new UUID(NameHash, NameHash)
}

global.AttributeEnhancement = function (entity, Attribute, Name, Amount, Operation) {
  // 必要类
  let AttributeModifier = Java.loadClass("net.minecraft.world.entity.ai.attributes.AttributeModifier")
  // 通过Name创建UUID
  let uuid = generateUUIDFromName(Name)
  // 通过Operation映射方法
  let OperationMap = {
    0: AttributeModifier.Operation.ADDITION,
    1: AttributeModifier.Operation.MULTIPLY_BASE,
    2: AttributeModifier.Operation.MULTIPLY_TOTAL
  };
  let OperationType = OperationMap[Operation] || AttributeModifier.Operation.ADDITION
  // 生成属性修饰符
  let modifier = new AttributeModifier(uuid, Name, Amount, OperationType)
  let AttributeInstance = entity.getAttribute(Attribute)
  // 更新或者创建属性修饰符
  if (AttributeInstance) {
    AttributeInstance.removeModifier(uuid)
    AttributeInstance.addPermanentModifier(modifier)
    // 当生物获得生命属性加成时回满生命值
    if (Attribute === "minecraft:generic.max_health") { entity.setHealth(entity.maxHealth) }
    // 记录属性加成用于属性修复
    let eData = entity.persistentData
    let AttributeModifiersData = eData.getCompound("AttributeModifiers")
    let ModifierData = AttributeModifiersData.getCompound(Attribute)
    let NameData = ModifierData.getCompound(Name)
    NameData.putDouble("Amount", Amount)
    NameData.putInt("Operation", Operation)
    ModifierData.put(Name, NameData)
    AttributeModifiersData.put(Attribute, ModifierData)
    eData.put("AttributeModifiers", AttributeModifiersData)
  }
}

// 移除特定属性修饰符的函数
global.RemoveAttributeModifier = function (entity, Attribute, Name) {
  let uuid = generateUUIDFromName(Name)
  // 移除修饰符
  let AttributeInstance = entity.getAttribute(Attribute)
  if (AttributeInstance) {
    AttributeInstance.removeModifier(uuid)
  }
  // 移除修饰符记录
  let eData = entity.persistentData
  if (eData.contains("AttributeModifiers")) {
    let AttributeModifiersData = eData.getCompound("AttributeModifiers")
    if (AttributeModifiersData.contains(Attribute)) {
      let ModifierData = AttributeModifiersData.getCompound(Attribute)
      if (ModifierData.contains(Name)) {
        ModifierData.remove(Name)
        // 如果该属性没有更多修饰符，移除整个属性条目
        if (ModifierData.getAllKeys().size() === 0) {
          AttributeModifiersData.remove(Attribute)
        } else {
          AttributeModifiersData.put(Attribute, ModifierData)
        }
        eData.put("AttributeModifiers", AttributeModifiersData)
      }
    }
  }
}

// 复活时修复玩家属性加成
PlayerEvents.respawned(event => {
  let player = event.player
  let pData = player.persistentData
  // 检查是否有存储的属性修饰符数据
  if (!pData.contains("AttributeModifiers")) return
  // 获取并构建需要恢复的属性资料
  let AttributeModifiersData = pData.getCompound("AttributeModifiers")
  let AttributeKeys = []
  let keysIterator = AttributeModifiersData.getAllKeys().iterator()
  while (keysIterator.hasNext()) {
    AttributeKeys.push(keysIterator.next())
  }
  for (let i = 0; i < AttributeKeys.length; i++) {
    let AttributeId = AttributeKeys[i]
    let ModifierData = AttributeModifiersData.getCompound(AttributeId)
    let NameKeys = []
    let nameKeysIterator = ModifierData.getAllKeys().iterator()
    while (nameKeysIterator.hasNext()) {
      NameKeys.push(nameKeysIterator.next())
    }
    // 遍历该属性的所有修饰符
    for (let j = 0; j < NameKeys.length; j++) {
      let Name = NameKeys[j]
      if (ModifierData.contains(Name)) {
        let NameData = ModifierData.getCompound(Name)
        if (NameData.contains("Amount") && NameData.contains("Operation")) {
          let Amount = NameData.getDouble("Amount")
          let Operation = NameData.getInt("Operation")
          // 重新应用属性修饰符
          global.AttributeEnhancement(player, AttributeId, Name, Amount, Operation)
        }
      }
    }
  }
})