ydwe 自动合成jass演示(代码有待优化)

发布时间 2023-06-07 19:10:54作者: 河马小海豚
// 公式库
// 1.要对每一个道具 都先用物编做一个假道具 
// 示例: id 为 I002 的道具  为  I000(自定义+6攻爪)    的假道具 
// 示例: id 为 I00D 的道具  为  I007(自定义食人鬼手套) 的假道具 
// 2. 创建哈希表
// 3. 由于jass没有类似于java的集合,所以此处为将数据重复的添加到哈希表里,目的是用A道具能找到B道具,用B道具也能找到A道具,能用的方法很多,此处只是其中的一种,而且并不是最优
// 4. 将全部道具都加入哈希表
library itemHt initializer init_itemHt
    globals
    	// 通过假道具 找到真道具 的哈希表
        hashtable item_ht = InitHashtable()
        // 每种道具可合成的哈希表
        hashtable canProp_ht = InitHashtable()
        // 合成目标道具 所需要的材料 的哈希表
        hashtable propMaterial_ht = InitHashtable()
    endglobals

    private function init_itemHt takes nothing returns nothing
        // 通过假道具 找到真道具
        // +6攻爪
        call SaveInteger(item_ht, StringHash("item"), 'I002', 'I000')
        // 通过假道具 找到真道具
        call SaveInteger(item_ht, StringHash("item"), 'I000', 'I002')
        // +12攻爪
        call SaveInteger(item_ht, StringHash("item"), 'I003', 'I001')
        // 通过假道具 找到真道具
        call SaveInteger(item_ht, StringHash("item"), 'I001', 'I003')
        // +20攻爪
        call SaveInteger(item_ht, StringHash("item"), 'I005', 'I004')
        // 通过假道具 找到真道具
        call SaveInteger(item_ht, StringHash("item"), 'I004', 'I005')

        // 食人鬼手套
        call SaveInteger(item_ht, StringHash("item"), 'I00D', 'I007')
        call SaveInteger(item_ht, StringHash("item"), 'I007', 'I00D')

        // 智力斗篷
        call SaveInteger(item_ht, StringHash("item"), 'I00F', 'I008')
        call SaveInteger(item_ht, StringHash("item"), 'I008', 'I00F')

        // 贵族圆环
        call SaveInteger(item_ht, StringHash("item"), 'I00E', 'I006')
        call SaveInteger(item_ht, StringHash("item"), 'I006', 'I00E')

        // 护腕
        call SaveInteger(item_ht, StringHash("item"), 'I00H', 'I00A')
        call SaveInteger(item_ht, StringHash("item"), 'I00A', 'I00H')

        // 空灵挂件
        call SaveInteger(item_ht, StringHash("item"), 'I00G', 'I00B')
        call SaveInteger(item_ht, StringHash("item"), 'I00B', 'I00G')


        // 可合成
        // +6攻爪  可合成的道具有 +12 +20
        call SaveInteger(canProp_ht, 'I000', 0, 'I001')
        call SaveInteger(canProp_ht, 'I000', 1, 'I004')

        // 食人鬼手套
        call SaveInteger(canProp_ht, 'I007', 0, 'I00A')

        // 智力斗篷
        call SaveInteger(canProp_ht, 'I008', 0, 'I00B')

        // 贵族圆环
        call SaveInteger(canProp_ht, 'I006', 0, 'I00A')
        call SaveInteger(canProp_ht, 'I006', 1, 'I00B')

        // 合成公式
        // 合成+12攻爪 公式  +6攻爪 * 2
        call SaveInteger(propMaterial_ht, 'I001', 0, 'I000')
        call SaveInteger(propMaterial_ht, 'I001', 6, 2)
        call SaveInteger(propMaterial_ht, 'I001', 1, 'I000')
        call SaveInteger(propMaterial_ht, 'I001', 7, 0)

        // 合成+20攻爪 公式  +6攻爪 * 1 +12攻爪 * 1
        call SaveInteger(propMaterial_ht, 'I004', 0, 'I000')
        call SaveInteger(propMaterial_ht, 'I004', 6, 1)
        call SaveInteger(propMaterial_ht, 'I004', 1, 'I001')
        call SaveInteger(propMaterial_ht, 'I004', 7, 1)

        // 合成护腕 公式  食人鬼手套 * 1 + 贵族圆环 * 1
        call SaveInteger(propMaterial_ht, 'I00A', 0, 'I007')
        call SaveInteger(propMaterial_ht, 'I00A', 6, 1)
        call SaveInteger(propMaterial_ht, 'I00A', 1, 'I006')
        call SaveInteger(propMaterial_ht, 'I00A', 7, 1)

        // 合成空灵挂件 公式  智力斗篷 * 1 + 贵族圆环 * 1
        call SaveInteger(propMaterial_ht, 'I00B', 0, 'I008')
        call SaveInteger(propMaterial_ht, 'I00B', 6, 1)
        call SaveInteger(propMaterial_ht, 'I00B', 1, 'I006')
        call SaveInteger(propMaterial_ht, 'I00B', 7, 1)
    endfunction
endlibrary

// 合成 核心库 (自制 非官方)
// 懂的都懂,不懂就照抄,上面的公式配明白就能用
// 下面的方法有很多待优化的地方,实在太懒,凑合用吧
library prop3 initializer propSynthesis_init 

    private function delEffect takes nothing returns nothing
        local effect e = LoadEffectHandle(item_ht, StringHash("hecheng"), StringHash("effect"))
        call DestroyEffect(e)
        call FlushChildHashtable(item_ht, StringHash("hecheng"))
        set e = null
    endfunction

    private function checkProp2 takes unit u, integer tarItemId, item ci returns boolean
        local integer j = 0
        // 材料id
        local integer mId = - 1
        local boolean isEnough = true

        loop
            exitwhen mId == 0
            set mId = LoadInteger(propMaterial_ht, tarItemId, j)
            if GetItemTypeId(ci) == mId then
                // 当背包道具的数量不足时  返回false
                if GetInventoryIndexOfItemTypeZHY(u, mId) + 1 < LoadInteger(propMaterial_ht, tarItemId, j + 6) then
                    set isEnough = false
                endif
            else
                // 当背包道具的数量不足时  返回false
                if GetInventoryIndexOfItemTypeZHY(u, mId) < LoadInteger(propMaterial_ht, tarItemId, j + 6) then
                    set isEnough = false
                endif
            endif 
            set j = j + 1
        endloop
        set u = null
        set ci = null
        return isEnough
    endfunction

    // 合成2
    private function synthesis_prop2 takes unit u, item ci returns nothing
        local integer i = 0
        local integer j = 0
        // 可合成的道具id
        local integer itemId = - 1
        local integer tId = 0

        // 合成的材料id
        local integer mId = - 1
        local integer bId 
        local boolean isEnough
        local boolean isDelete = false

        local effect e

        loop
            exitwhen itemId == 0 or tId != 0
            set itemId = LoadInteger(canProp_ht, GetItemTypeId(ci), i)
            set isEnough = checkProp2(u, itemId, ci)
            if isEnough then
                set tId = itemId
            endif
            set i = i + 1
        endloop

        if isEnough and tId != 0 then
            call BJDebugMsg("材料够了")
            set i = 0
            set j = 0
            set mId = - 1
            loop
                exitwhen mId == 0
                set mId = LoadInteger(propMaterial_ht, tId, i)
                loop 
                    exitwhen j > 5 or isDelete
                    set bId = GetItemTypeId(UnitItemInSlot(u, j))
                    if bId != 0 and bId == mId then
                        call RemoveItem(UnitItemInSlot(u, j))
                        set isDelete = true
                    endif
                    set j = j + 1
                endloop
                set isDelete = false
                set i = i + 1
                set j = 0
            endloop
            call RemoveItem(ci)
            call UnitAddItemById(u, tId)

            set e = AddSpecialEffectTargetUnitBJ("overhead", u, "Abilities\\Spells\\Items\\AIlm\\AIlmTarget.mdl")
            call SaveEffectHandle(item_ht, StringHash("hecheng"), StringHash("effect"), e)
            call TimerStart(CreateTimer(), 2, false, function delEffect)
            set e = null
        else
            call CreateItem(LoadInteger(item_ht, StringHash("item"), GetItemTypeId(ci)), GetUnitX(u), GetUnitY(u))
            call RemoveItem(ci)
        endif

    endfunction

    private function checkProp takes unit u, integer tarItemId returns boolean
        local integer j = 0
        // 材料id
        local integer mId = - 1
        local boolean isEnough = true
        loop
            exitwhen mId == 0
            set mId = LoadInteger(propMaterial_ht, tarItemId, j)
            // 当背包道具的数量不足时  返回false
            if GetInventoryIndexOfItemTypeZHY(u, mId) < LoadInteger(propMaterial_ht, tarItemId, j + 6) then
                set isEnough = false
            endif
            set j = j + 1
        endloop
        return isEnough
    endfunction

    // 合成
    private function synthesis_prop takes unit u, integer pickId returns nothing
        local integer i = 0
        local integer j = 0
        // 可合成的道具id
        local integer itemId = - 1
        local integer tId = 0
        // 合成的材料id
        local integer mId = - 1
        local integer bId 
        local boolean isEnough
        local boolean isDelete = false

        local effect e
        loop
            exitwhen itemId == 0 or tId != 0
            set itemId = LoadInteger(canProp_ht, pickId, i)
            set isEnough = checkProp(u, itemId)
            if isEnough then
                set tId = itemId
            endif
            set i = i + 1
        endloop

        if isEnough and tId != 0 then
            call BJDebugMsg("材料够了")
            set i = 0
            set j = 0
            set mId = - 1
            loop
                exitwhen mId == 0
                set mId = LoadInteger(propMaterial_ht, tId, i)
                loop 
                    exitwhen j > 5 or isDelete
                    set bId = GetItemTypeId(UnitItemInSlot(u, j))
                    if bId != 0 and bId == mId then
                        call RemoveItem(UnitItemInSlot(u, j))
                        set isDelete = true
                    endif
                    set j = j + 1
                endloop
                set isDelete = false
                set i = i + 1
                set j = 0
            endloop
            call UnitAddItemById(u, tId)

            set e = AddSpecialEffectTargetUnitBJ("overhead", u, "Abilities\\Spells\\Items\\AIlm\\AIlmTarget.mdl")
            call SaveEffectHandle(item_ht, StringHash("hecheng"), StringHash("effect"), e)
            call TimerStart(CreateTimer(), 2, false, function delEffect)
            set e = null
        endif
    endfunction

    // 拾取
    private function pickup takes nothing returns nothing
        local unit u = GetTriggerUnit()
        local item it = GetManipulatedItem()
        local integer fakeId
        local integer itemId
        // 是否添加到单位成功
        local boolean isAdd = false
        // 创建 真道具
        local item ci
        local itemtype itype = GetItemType(it)

        if itype != ITEM_TYPE_CAMPAIGN then
            return
        endif
        // 拾取的假道具 id
        set fakeId = GetItemTypeId(it)
        // 拾取的真道具 id
        set itemId = LoadInteger(item_ht, StringHash("item"), fakeId)

        if itemId != 0 then
            set ci = CreateItem(itemId, GetUnitX(u), GetUnitY(u))
            set isAdd = UnitAddItem(u, ci)
            if isAdd then 
                call synthesis_prop(u, itemId)
            else
                call synthesis_prop2(u, ci)
            endif
        endif
        set u = null
        set ci = null
        set it = null
    endfunction

    private function realDrop takes nothing returns nothing 
        local item it = LoadItemHandle(item_ht, StringHash("dropItem"), StringHash("dropItem"))
        call CreateItem(LoadInteger(item_ht, StringHash("item"), GetItemTypeId(it)), GetItemX(it), GetItemY(it))
        call RemoveItem(it)
        set it = null
    endfunction

    private function dropItem takes nothing returns nothing
        local timer tm = CreateTimer()
        local item it = GetManipulatedItem()
        local itemtype itype = GetItemType(it)

        if itype == ITEM_TYPE_CAMPAIGN then
            return
        endif
        call SaveItemHandle(item_ht, StringHash("dropItem"), StringHash("dropItem"), it)
        call TimerStart(tm, 0, false, function realDrop)
        set it = null
        set tm = null
    endfunction

    private function propSynthesis_init takes nothing returns nothing
        local trigger pickup_t = CreateTrigger()
        local trigger dropItem_t = CreateTrigger()
        
        // 拾取物品触发
        call TriggerRegisterAnyUnitEventBJ(pickup_t, EVENT_PLAYER_UNIT_PICKUP_ITEM)
        call TriggerAddAction(pickup_t, function pickup)

        // 丢弃物品触发
        call TriggerRegisterAnyUnitEventBJ(dropItem_t, EVENT_PLAYER_UNIT_DROP_ITEM)
        call TriggerAddAction(dropItem_t, function dropItem)

        set pickup_t = null
        set dropItem_t = null
    endfunction
    
endlibrary

最后用ydwe 引用文件即可