找回密码
 点一下
查看: 8720|回复: 25

对抗类地图-物品系统[Hash版]

[复制链接]
发表于 2010-8-16 22:59:28 | 显示全部楼层 |阅读模式
功能简介
这个物品系统其实不是特地做演示的,当初制作纯粹是为了我的地图功能需求。该演示也是由里面分离出来的独立系统。
简单的说这个系统就是实用的对战类物品合成系统,有很强的针对性。守卫类型的地图可能这个系统功能不适合。
该系统经过6个多月的实战测试(真三国无双VSEC-1.1b),该系统有很高的稳定性和正确性。正确移植可放心使用。

功能及限制简介:

1.普通物品合成功能;
2.满物品栏购买、拾取合成功能;
3.支持物品非共享(拾取他人物品无属性效果、不可出售);
4.支持根据单位类型合成专属物品;
5.支持玩家所属运输单位(演示图里为骡子)运输、并自动判断合成、给予物品;
6.支持逆向合成公式(即拆分所有已合成的物品);
7.支持多面板显示物品图标;
8.支持获取物品价格;
9.支持关闭物品非共享模式;
10.支持物品使用次数叠加;
11.支持扩展物品系统功能,需自定义注册函数。

1.合成材料最多为6个合成1个;
2.物品种类最多支持1000个(0~999);
3.默认编号800以上为专属物品(可更改);
4.默认编号从1以上为商店出售物品,从799以下为非商店出售物品;
5.可丢弃物品都必须创建书类物品;
6.商店出售物品都必须创建单位物品;
7.要实现非共享物品都必须创建假物品;
8.使用运输单位必须使用英雄背包
9.物品不得使用物品自定义值

名词解释(该帖内所用的一些名词解释)
1.真物品:即有技能有属性效果的物品
2.假物品:即无技能无属性效果的,不可出售的物品(用于非共享物品模式)
3.书物品:即可满物品栏拾取并使用的物品(用于满物品栏拾取)
4.单位物品:即商店出售的单位,模拟出售物品(用于判断物品所属)
5.专属物品:有且只有一种单位类型能根据合成公式合成的物品,并且只能合成一次。(一般用于英雄专属)
6.玩家所属运输单位:即类似DOTA里买的鸟,真三红宝石里的骡子(用于运输物品或者在商店购买、合成物品)

系统原理
其实这个不需要说,很多人解析过dota的物品系统,大概类似吧。因为我也没去看dota到底怎么做的,反正就是处理真物品、假物品、书物品、单位物品之间的关系就是了,具体实现有很多具体问题这里就不详细说明了,总之一个字——烦。顺便说下,这里的合成注册算法有稍微冗余,天呐~赐我个算法帝吧!


物品系统演示【可移植】
(注:由于该物品系统从我的地图中提取出来,很多东西懒得删,所以较大,运行源图载入需要等一段时间。) 真三红宝石-物品系统.w3x (4.45 MB, 下载次数: 234)    
经过SLK优化的,载入速度会加快,但是也变成了加密地图,仅供验证。
真三红宝石-物品系统(SLK优化).w3x (3.58 MB, 下载次数: 90)

移植说明:
申明:移植前要做好规划,并且要做好当苦力的准备。否则只会白干!切记切记!

1.建立下面全局变量
[jass]
glabols
   hashtable udg_SN_Item_Hash //物品系统哈希表
   itemtype array udg_Item_True
   itemtype array udg_Item_False
   itemtype array udg_Item_Book
   itemtype array udg_Item_Unit
   integer udg_FormulaNum
   integer array udg_ItemFormNum//[999]
   integer array udg_MixForMula//[8000]
   boolean udg_ColseItem = false //控制物品共享与否
   boolean udg_ColseZhuanShu = false //控制是否合成专属
   location array udg_Point //该设置可取消,需做处理。
endglabols
[/jass]
2.复制所有代码
3.根据自己需求创建相应物品,并使用ItemMainInit函数注册。
4.根据合成需求使用ItemMixStart函数注册合成公式。
5.根据创建物品CreateItemAtLocCreateItemForUnit可以创建对应物品。

如有问题可跟帖询问。
之前版本:
物品系统.w3x (3.98 MB, 下载次数: 311)
物品系统(SLK优化版).w3x (3.27 MB, 下载次数: 87)
 楼主| 发表于 2010-8-16 23:02:08 | 显示全部楼层
[jass]
//===========================================================================
//物品系统注册
//===========================================================================
function ItemInit takes integer itemcode,integer trueitem,integer falseitem,integer bookitem,integer unititem,integer money,string icon returns nothing
    //local string dis = "ReplaceableTextures\\\\CommandButtons\\\\BTN" + icon + ".blp"
    //call SetItemStr("ItemIcon",I2S(trueitem),dis)
    //call SetItemInt("ItemMoney",I2S(trueitem),money)
    //set dis = null
    set udg_Item_True[itemcode] = trueitem
    set udg_Item_False[itemcode] = falseitem
    set udg_Item_Book[itemcode] = bookitem
    if unititem != 0 then
        set udg_Item_Unit[itemcode] = unititem
    endif
endfunction

//物品注册
function ItemMainInit takes nothing returns nothing
    call ItemInit(1,'hslv','I094','I04W','h026',55,"HealingSalve")
    call ItemInit(2,'pclr','I095','I04X','h027',45,"PotionOfClarity")
    call ItemInit(3,'I00U','I096','I04Y','h028',1700,"MarkOfFire")                             
    //...
    call ItemInit(799,'I00Z','I0DF','I0DC',0,0,"HeartOfAszune")               
    call ItemInit(798,'I013','I0DG','I0DD',0,0,"PotionOfVampirism")           
    call ItemInit(797,'I040','I0DH','I0DE',0,0,"LionHorn")                    
    call ItemInit(796,'spre','I0BR','I07J',0,3200,"OrbOfFrost")            
    //...  
    call ItemInit(801,'I02Y',0,0,0,0,"")
    call ItemInit(802,'I02P',0,0,0,0,"")
    call ItemInit(803,'I015',0,0,0,0,"")
    //...
endfunction

function ItemMixInit takes integer id1, integer id2, integer id3, integer id4, integer id5, integer id6, integer mixid, integer  heroid returns nothing
    //id1-6 所需装备,mixid 合成装备 heroid 英雄类别
    local integer array id
    local integer i
    local integer total
    local integer num = udg_FormulaNum + 1
    local integer num10 = num * 10
    set id[1] = id1
    set id[2] = id2
    set id[3] = id3
    set id[4] = id4
    set id[5] = id5
    set id[6] = id6
    set udg_FormulaNum = num//第num个合成公式(范围1~800)
   
    if mixid > 800 then
        set udg_MixFormula[num10] = heroid//记录专属英雄类别
    endif
    set udg_MixFormula[num10+7] = mixid//记录合成物品
   
    //记录合成材料及合成材料个数total
    set total = 1
    loop
        exitwhen id[total] == 0 or total > 6
        set udg_MixFormula[num10+total] = id[total]
        set total = total + 1
    endloop
    set total = total - 1
    set udg_MixFormula[num10+9] = total
   
    //记录物品的合成总数及对应合成公式
    set i = 1
    loop
        exitwhen i > total
        set udg_ItemFormNum[id] = udg_ItemFormNum[id] + 1 //id类物品合成公式总数
        call SaveItemInt(id,udg_ItemFormNum[id],num) //id类第udg_ItemFormNum[id]个合成公式对应的方法
        set i = i + 1
    endloop
endfunction


//物品合成注册
function ItemMixStart takes nothing returns nothing
    call ItemMixInit(3,4,63,0,0,0,778,0)
    call ItemMixInit(3,31,85,0,0,0,754,0)
    call ItemMixInit(4,75,0,0,0,0,764,0)
    //...         
    call ItemMixInit(4,23,772,0,0,0,857,'U00I')
    call ItemMixInit(4,778,772,0,0,0,809,'U000')
    call ItemMixInit(4,744,0,0,0,0,836,'O00K')
    //...
endfunction

function SetItemData takes integer kind,integer playid,integer itemcode returns integer
    //设置物品自定义值(ABBCCC A:类别 BB:玩家索引 CCC:物品编号)
    return kind*100000+playid*1000+itemcode
endfunction

function CountItmesNum takes unit u returns integer//获取单位包内物品数(0-6)
    local integer i = 0
    local integer j = 0
    loop
        exitwhen i > 5
        if UnitItemInSlot(u, i) != null then
            set j = j + 1
        endif
        set i = i + 1
    endloop
    return j
endfunction

function GetItemOwnId takes item it returns integer//获取物品所属玩家ID
    return S2I(SubString(I2S(GetItemUserData(it)),1,3))
endfunction

function IsItemOwn takes unit u,item it returns boolean //物品是否是单位所属玩家的
    if GetPlayerId(GetOwningPlayer(u)) == GetItemOwnId(it) or udg_ColseItem then
        return true
    else
        return false
    endif
endfunction

function GetItemCode takes item it returns integer//获取物品编号
    return S2I(SubString(I2S(GetItemUserData(it)),3,6))
endfunction

function GetItemKind takes item it returns integer//获取类别  1-真,2-假,3-书,4-通用
    return S2I(SubString(I2S(GetItemUserData(it)),0,1))
endfunction

function CreateItemAtLoc takes integer itid,integer pid, real x, real y returns nothing
    //itid 物品类型编号 pid 玩家id(0为共享)
    local item it
    local item it_true
    set it = CreateItem(udg_Item_Book[itid],x,y)
    call SetItemUserData(it,SetItemData(3,pid,itid))
    if pid < 6 then
        set x = -6744
        set y = -7600
    else
        set x = 6956
        set y = 5371
    endif
    set it_true = CreateItem(udg_Item_True[itid],x,y)
    call SetItemUserData(it_true,SetItemData(1,pid,itid))
    call SaveItemAgent(H2I(it),1,it_true)
    call SetItemVisible( it_true, false )
    set it = null
    set it_true = null
endfunction

function CreateItemForUnit takes integer itid,unit u returns nothing
    //itid 物品类型编号 u 玩家单位
    local item it
    local item it_true
    local integer pid = GetPlayerId(GetOwningPlayer(u))
    local real x
    local real y
    set it = CreateItem(udg_Item_Book[itid],GetUnitX(u),GetUnitY(u))
    call SetItemUserData(it,SetItemData(3,pid,itid))
    if pid < 6 then
        set x = -6744
        set y = -7600
    else
        set x = 6956
        set y = 5371
    endif
    set it_true = CreateItem(udg_Item_True[itid],x,y)
    call SetItemUserData(it_true,SetItemData(1,pid,itid))
    call SaveItemAgent(H2I(it),1,it_true)
    call SetItemVisible( it_true, false )
    call UnitAddItem(u,it)
    set it = null
    set it_true = null
endfunction

//===========================================================================
function InitTrig_InitFunctions takes nothing returns nothing
    set udg_SN_Item_Hash = InitHashtable()
    call ItemMainInit()
    call ItemMixStart()
endfunction
//出售物品总数
function GetAllItemNumber takes nothing returns integer
    return 96
endfunction
//判断是否可拆分合成物品
function IsSplitItem takes integer id returns boolean
    if id == 772 or id ==771 or id == 762 or id == 759 then//不可拆分物品编码
        return false
    else
        return true
    endif
endfunction
//判断是否出售物品的商店
function IsSellItemUnit takes integer id returns boolean
    if id == 'n00Q' or id == 'n00R' or id == 'n003' or id == 'n00U' or id == 'n015' or id == 'n00A' or id == 'n00O' or id == 'n008' or id == 'n014' or id == 'n007' or id == 'n01J' or id == 'n013' or id == 'n01K' then
        return true
    else
        return false
    endif
endfunction  
//判断是否可共享物品
function IsItemShare takes integer ic returns boolean
    if ic == 1 or ic == 2 or ic == 8 or ic == 9 or ic == 10 or ic == 799 or ic == 798 or ic == 797 or ic == 19 then
        return true
    else
        return false
    endif
endfunction
//判断是否可叠加物品
function IsItemCharges takes integer id returns boolean
    if id == 1 or id == 2 or id == 8 or id == 9 or id == 'hslv' or  id == 'pclr' or id == 'I00H' or id == 'I00J' then
        return true
    else
        return false
    endif
endfunction
function SplitItem takes unit u, item it returns nothing
    local integer i
    local integer id
    local integer id10
    local integer num
    local integer total
    local integer pid
    local real x
    local real y
    local player p
    if IsItemOwn(u,it) then
        //call Debug("共有合成公式:"+I2S(udg_FormulaNum))
        set num = GetItemCode(it)
        if num > GetAllItemNumber() and num < 797 and IsSplitItem(num) then
            if num == 776 then
                set num = 777
            elseif num == 768 then
                set num = 769
            endif
            set id = 1
            loop
                exitwhen udg_MixFormula[id*10+7] == num or id > udg_FormulaNum
                set id = id + 1
            endloop
            if id <= udg_FormulaNum then
                set id10 = id * 10
                set total = udg_MixFormula[id10+9]
                //call Debug(I2S(num)+" 可拆分 "+I2S(total))
                set pid = GetItemOwnId(it)
                set x = GetUnitX(u)
                set y = GetUnitY(u)
                call FlushItemMission(H2I(it))
                call RemoveItem(it)               
                set i = 1
                loop
                    exitwhen i > total
                    //call Debug(I2S(i)+"-编号-"+I2S(udg_MixFormula[id10+i]))
                    if i == total then
                        call SaveItemBool(H2I(u),3628,true)
                    endif
                    call CreateItemForUnit(udg_MixFormula[id10+i],u)
                    set i = i + 1
                endloop
                call SaveItemBool(H2I(u),3628,false)
                //call Debug("拆分成功")
                set p = GetOwningPlayer(u)
                call DisplayTextToPlayer( p, 0, 0, "|cFFFF0000重铸成功!|r" )
                call DestroyEffect(AddSpecialEffectTarget("Abilities\\\\Spells\\\\Other\\\\Incinerate\\\\FireLordDeathExplode.mdl", u, "origin"))
                set p = null
            endif
        else
            //call Debug("该物品不可拆分")
            set p = GetOwningPlayer(u)
            call DisplayTextToPlayer( p, 0, 0, "|cFFFF0000该物品不可重铸!|r" )
            call CreateItemForUnit(96,u)
            set p = null
        endif
    endif
endfunction
function SplitDel_Conditions takes nothing returns boolean
    if GetItemTypeId(GetManipulatedItem()) == 'I03U' then
        call RemoveItem(GetManipulatedItem())
    endif
    return false
endfunction
function SplitItemAction takes nothing returns nothing  
    local timer t = GetExpiredTimer()
    local unit u = GetItemUnit(H2I(t),1)
    local item it = GetItemItem(H2I(t),2)   
    call SplitItem(u,it)
    call FlushItemMission(H2I(t))
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
    set u = null
    set it = null
endfunction
function SplitItemAction2 takes nothing returns nothing  
    local timer t = GetExpiredTimer()
    local unit u = GetItemUnit(H2I(t),1)
    call CreateItemForUnit(96,u)
    call FlushItemMission(H2I(t))
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
    set u = null
endfunction
function Split_Conditions takes nothing returns boolean
    local item it = GetSpellTargetItem()
    local timer t
    local unit u
    local player p
    if GetSpellAbilityId() == 'A00P' and IsItemOwned(it) and GetItemTypeId(it)!='I03U' then
        set u = GetTriggerUnit()
        set t = CreateTimer()
        call SaveItemAgent(H2I(t),1,u)
        call SaveItemAgent(H2I(t),2,it)
        call TimerStart(t,0,false,function SplitItemAction)
        set t = null
    elseif GetSpellAbilityId() == 'A00P' then
        set u = GetTriggerUnit()
        set p = GetOwningPlayer(u)
        call DisplayTextToPlayer( p, 0, 0, "|cFFFF0000该物品不可重铸!|r" )   
        set t = CreateTimer()
        call SaveItemAgent(H2I(t),1,u)  
        call TimerStart(t,0,false,function SplitItemAction2)
    endif
    set t = null
    set p = null
    set it = null
    set u = null
    return false
endfunction
function mixitemaction takes nothing returns nothing
    local timer t = GetExpiredTimer()
    call UnitAddItem(GetItemUnit(H2I(t),0),GetItemItem(H2I(t),1))
    call FlushItemMission(H2I(t))
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction
[/jass]
回复

使用道具 举报

 楼主| 发表于 2010-8-16 23:02:34 | 显示全部楼层
[jass]function GetNewItem takes unit u, item it returns nothing
    local integer kind = GetItemKind(it)
    local boolean isfull = false
    local integer array id
    local item array ite
    local integer i
    local real x = GetItemX(it)
    local real y = GetItemY(it)
    local item it_temp
    local item it_book
    local item it_true
    local integer pid = GetItemOwnId(it)
   
    local integer j = 0
    local integer k = 0
    local integer l = 0
    local integer m = 0
    local integer number = 0
   
    local integer array id2
    local integer hc
    local integer MethodTotal
    local integer MixMethodTotal
    local integer total
    local boolean b = true
    local boolean bb = false
   
    local integer num
    local integer num10
   
    local real x1
    local real y1
    local real x2
    local real y2
    local timer t
    local integer ic
    local integer inum
    local boolean bic = false
   
    set ic = GetItemCode(it)
    if IsItemShare(ic) or GetPlayerSlotState(Player(pid)) != PLAYER_SLOT_STATE_PLAYING then
        set pid = GetPlayerId(GetOwningPlayer(u))
        call SetItemUserData(it,SetItemData(kind,pid,ic))
    endif
    if IsItemCharges(ic) and kind == 3 and CountItmesNum(u) >= 6 then
        set it_true = GetItemItem(H2I(it),1)//RealItem
        set inum = GetItemCharges(it_true)
        set i = 0
        loop
            exitwhen i > 5
            if GetItemTypeId(it_true) == GetItemTypeId(UnitItemInSlot(u, i))  then
                call SetItemCharges(UnitItemInSlot(u, i),inum+GetItemCharges(UnitItemInSlot(u, i)))
                call FlushItemMission(H2I(it_true))
                call RemoveItem(it_true)
                set bic = true
                call FlushItemMission(H2I(it))
            endif
            set i = i + 1
        endloop
    endif
   
    set i = 0
    loop
        exitwhen i > 5
        set it_temp = UnitItemInSlot(u, i)
        if IsItemOwn(u,it_temp) and it_temp != it then
            if it_temp == null then
                set id = 0
                set ite = null
            else
                set id = GetItemCode(it_temp)
                set ite = it_temp
                set number = number + 1
            endif
        else
            set id = 0
            set ite = null
        endif
        set i = i + 1
    endloop
    set id[6] = GetItemCode(it)
    set ite[6] = it
    //id[0-5]身上属于自己的code id[6]获取物品的code
    //ite[0-5]身上属于自己的物品 ite[6]获取的物品
   
    call SaveItemInt(H2I(it),0,0)//giveup 重置该物品的丢弃绑定值
   
    if kind != 4 then
        //不是通用
        if IsItemOwn(u,it) then
            //获得的物品是自己的
            //判断合成
            set i = 1
            set MethodTotal = udg_ItemFormNum[id[6]] //该物品的合成方法总数
            loop
                exitwhen i > MethodTotal
                set num = GetItemInt(id[6],i)// 第i合成物方法编号
                set num10 =  num * 10
                set m = 0
                loop
                    exitwhen m > 6
                    set id2[m] = id[m]
                    set m = m + 1
                endloop
                set total = udg_MixFormula[num10+9]
                set j = 1
                set b = true
                loop
                    exitwhen j > total or b == false
                    set k = 0
                    set b = false
                    loop
                        exitwhen k > 6
                        if udg_MixFormula[num10+j] == id2[k] then
                            set id2[k] = -1
                            set b = true
                            set k = 6
                        endif
                        set k = k + 1
                    endloop
                    set j = j + 1
                endloop
               
                if GetItemBool(H2I(u),3628) then
                    set b = false
                endif
                if b then //可合成,删除条件物品,给予合成物品
                    set id2[8] = udg_MixFormula[num10+7]
                    if id2[8]>800 then
                        if GetItemBool(H2I(u),618)==false and udg_MixFormula[num10]==GetUnitTypeId(u) then
                            call SaveItemBool(H2I(u),618,true)
                            set bb = true
                        endif
                        if id2[8]==816 and GetItemBool(H2I(u),618)==false and GetUnitTypeId(u)=='H020'  then
                            call SaveItemBool(H2I(u),618,true)
                            set bb = true
                        endif
                        if udg_ColseZhuanShu then
                            set bb = false
                        endif
                    else
                        set bb = true
                    endif
                    
                    if bb then
                        set m=0
                        loop
                            exitwhen m > 5
                            if id2[m] == -1 then
                                call FlushItemMission(H2I(ite[m]))
                                call RemoveItem(ite[m])
                            endif
                            set m = m + 1
                        endloop
                        set it_true = GetItemItem(H2I(ite[6]),1)
                        
                        if it_true != null then
                            call FlushItemMission(H2I(it_true))
                            call RemoveItem(it_true)
                        endif
                        call FlushItemMission(H2I(ite[6]))
                        call RemoveItem(ite[6])
                        
                        set it_true = CreateItem(udg_Item_True[id2[8]],x,y)
                        call SetItemUserData(it_true,SetItemData(1,pid,id2[8]))
                        set t = CreateTimer()
                        call SaveItemAgent(H2I(t),0,u)//u
                        call SaveItemAgent(H2I(t),1,it_true)//it
                        call TimerStart(t,0,false,function mixitemaction)
                        call DestroyEffect(AddSpecialEffectTarget("Abilities\\\\Spells\\\\Items\\\\AIem\\\\AIemTarget.mdl", u, "origin"))
                        set i = MethodTotal + 1
                    endif
                endif
               
                set i = i + 1
            endloop
            
            
            set i = 0
            set number = 0
            loop
                exitwhen i > 5
                set it_temp = UnitItemInSlot(u, i)
                if it_temp != null and it_temp != it then
                    set number = number + 1
                endif
                set i = i + 1
            endloop
            if number >= 6 then
                //判断是否满格
                set isfull = true
            else
                set isfull = false
            endif
            
            if not bb then //无法合成
                if isfull then
                    if bic == false then
                        set it_true = GetItemItem(H2I(ite[6]),1)
                        call FlushItemMission(H2I(ite[6]))
                        call RemoveItem(ite[6])
                        set it_book = CreateItem(udg_Item_Book[id[6]],x,y)
                        call SetItemUserData(it_book,SetItemData(3,pid,id[6]))
                        call SaveItemAgent(H2I(it_book),1,it_true)
                    endif
                else
                    if kind == 1 then
                    else
                        set it_true = GetItemItem(H2I(ite[6]),1)
                        call FlushItemMission(H2I(ite[6]))
                        call RemoveItem(ite[6])
                        call UnitAddItem(u,it_true)
                    endif
                endif
            endif
        else
            //获得的物品是别人的
            if kind == 2 then
                call DisplayTextToPlayer( Player(GetPlayerId(GetOwningPlayer(u))), 0, 0, "|cffff0000该物品属于玩家-|r"+GetPlayerName(Player(pid)))
            endif
            set x1 = GetLocationX(udg_Point[0])
            set y1 = GetLocationY(udg_Point[0])
            set x2 = GetLocationX(udg_Point[1])
            set y2 = GetLocationY(udg_Point[1])
            if kind == 1 then
                call SaveItemInt(H2I(ite[6]),2,1)
                if IsUnitAlly(u, Player(0)) then
                    call SetItemPosition( ite[6], x1, y1 )
                else
                    call SetItemPosition( ite[6], x2, y2 )
                endif
                call SetItemVisible( ite[6], false )
                set it_temp = CreateItem(udg_Item_False[id[6]],x,y)
                call SetItemUserData(it_temp,SetItemData(2,pid,id[6]))
                call SaveItemAgent(H2I(it_temp),1,ite[6])
                call UnitAddItem(u,it_temp)
            endif
            if kind == 3 then
                set it_true = GetItemItem(H2I(ite[6]),1)
                call FlushItemMission(H2I(ite[6]))
                call RemoveItem(ite[6])
               
                set i = 0
                set number = 0
                loop
                    exitwhen i > 5
                    set it_temp = UnitItemInSlot(u, i)
                    if it_temp != it and it_temp != null then
                        set number = number + 1
                    endif
                    set i = i + 1
                endloop
               
                if number >= 6 then
                    set it_book = CreateItem(udg_Item_Book[id[6]],x,y)
                    call SetItemUserData(it_book,SetItemData(3,pid,id[6]))
                    call SaveItemAgent(H2I(it_book),1,it_true)
                else
                    set it_temp = CreateItem(udg_Item_False[id[6]],x,y)
                    call SetItemUserData(it_temp,SetItemData(2,pid,id[6]))
                    call SaveItemAgent(H2I(it_temp),1,it_true)
                    call UnitAddItem(u,it_temp)
                endif
            endif
        endif
    else
        //是共享物品
    endif
    set m = 0
    loop
        exitwhen m > 6
        set ite[m] = null
        set m = m + 1
    endloop
    set it_book = null
    set it_true = null
    set it_temp = null
    set t = null
endfunction

function GiveUpItemAction takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit u
    local item it = GetItemItem(H2I(t),1)
    local integer kind = GetItemKind(it)
    local integer c
    local real x
    local real y
    local real ox
    local real oy
    local item it_true
    local item it_book
    local integer pid = GetItemOwnId(it)
    if kind != 3 then
        set u = GetItemUnit(H2I(t),0)
        if GetItemInt(H2I(it),0)==1 then
            if IsUnitAlly(u, Player(0)) then
                set x = GetLocationX(udg_Point[0])
                set y = GetLocationY(udg_Point[0])
            else
                set x = GetLocationX(udg_Point[1])
                set y = GetLocationY(udg_Point[1])
            endif
            set c = GetItemCode(it)
            set ox = GetItemX(it)
            set oy = GetItemY(it)
            if kind == 1 then
                call SetItemPosition( it, x, y )
                call SetItemVisible( it, false )
                set it_book = CreateItem(udg_Item_Book[c],ox,oy)
                call SetItemUserData(it_book,SetItemData(3,pid,c))
                call SaveItemAgent(H2I(it_book),1,it)
            endif
            if kind == 2 then
                set it_true = GetItemItem(H2I(it),1)
                call FlushItemMission(H2I(it))
                call RemoveItem(it)
                set it_book = CreateItem(udg_Item_Book[c],ox,oy)
                call SetItemUserData(it_book,SetItemData(3,pid,c))
                call SaveItemAgent(H2I(it_book),1,it_true)
            endif
            if kind == 4 then
                call SetItemPosition( it, x, y )
                call SetItemVisible( it, false )
                set it_book = CreateItem(udg_Item_Book[c],ox,oy)
                call SetItemUserData(it_book,SetItemData(3,pid,c))
                call SaveItemAgent(H2I(it_book),1,it)
            endif
        endif
    endif
    call FlushItemMission(H2I(t))
    call PauseTimer(t)
    call DestroyTimer(t)
    set it_book = null
    set it_true = null
    set t = null
    set u = null
    set it = null
endfunction

function GiveUpItem takes unit u, item it returns nothing
    //单位丢弃物品移动隐藏
    local timer t
    if GetItemInt(H2I(it),2)== 1 then
        call SaveItemInt(H2I(it),2,0)
    else
        set t = CreateTimer()
        call SaveItemAgent(H2I(t),0,u)
        call SaveItemAgent(H2I(t),1,it)
        call SaveItemInt(H2I(it),0,1)
        call TimerStart(t,0,false,function GiveUpItemAction)
    endif
    set t = null
endfunction
[/jass]
回复

使用道具 举报

 楼主| 发表于 2010-8-16 23:11:46 | 显示全部楼层
[jass]function BuyItemUnit takes unit uBuy,unit uSold returns nothing
    //uBuy 购买者 uSold 被卖单位
    local integer pid = GetPlayerId(GetOwningPlayer(uSold))
    local integer pbid = GetPlayerId(GetOwningPlayer(uBuy))
    local item it_book
    local item it_false
    local item it
    local real x = GetLocationX(udg_Point[0])
    local real y = GetLocationY(udg_Point[0])
    local real ux = GetUnitX(uBuy)
    local real uy = GetUnitY(uBuy)
    local integer c = 1
    local integer uid = GetUnitTypeId(uSold)
    local integer inum = GetAllItemNumber()
   
    local group g
    local unit u
    local unit ut
    local unit us
    loop
        exitwhen c > inum or udg_Item_Unit[c] == uid
        set c = c + 1
    endloop
   
    if pid > 6 then
        set x = GetLocationX(udg_Point[1])
        set y = GetLocationY(udg_Point[1])
    endif
    if c == 19 then
        if GetInventoryIndexOfItemTypeBJ(uBuy, 'I02V') > 0 then
            call DisplayTimedTextToPlayer( GetOwningPlayer(uBuy), 0, 0, 3., "|cFFFF0000无法再携带粮草。|r")
        else
            call CreateItemForUnit(c,uBuy)
        endif
    else
        set it = CreateItem(udg_Item_True[c],x,y)
        call SetItemUserData(it,SetItemData(1,pid,c))
        if pid == pbid then
            if CountItmesNum(uBuy) < 6 then
                call UnitAddItem(uBuy,it)
            else
                call SetItemVisible( it, false )
                set it_book = CreateItem(udg_Item_Book[c],ux,uy)
                call SetItemUserData(it_book,SetItemData(3,pid,c))
                call SaveItemAgent(H2I(it_book),1,it)
                call UnitAddItem(uBuy,it_book)
            endif
        else
            call SetItemVisible( it, false )
            if uBuy == null then
                set ut = null
                set us = GetSellingUnit()
                set g = CreateGroup()
                call GroupEnumUnitsInRange(g,GetUnitX(us),GetUnitY(us),700.0,null)
                loop
                    set u = FirstOfGroup(g)
                    exitwhen u==null
                    if(IsUnitType(u, UNIT_TYPE_DEAD) == false and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false) and GetPlayerAlliance(GetOwningPlayer(u), Player(pid), ALLIANCE_SHARED_CONTROL) and GetUnitAbilityLevel(u, 'AInv')>0 then
                        if ut == null then
                            set ut = u
                        else
                            if DistanceBetweenUnits(u,us) < DistanceBetweenUnits(ut,us) then
                                set ut = u
                            endif
                        endif
                    endif
                    call GroupRemoveUnit(g,u)
                endloop
                call DestroyGroup(g)
                if ut != null then
                    set it_book = CreateItem(udg_Item_Book[c],GetUnitX(ut),GetUnitY(ut))
                    call SetItemUserData(it_book,SetItemData(3,pid,c))
                    call SaveItemAgent(H2I(it_book),1,it)
                    call UnitAddItem(ut,it_book)
                else
                    set it_book = CreateItem(udg_Item_Book[c],GetUnitX(us),GetUnitY(us))
                    call SetItemUserData(it_book,SetItemData(3,pid,c))
                    call SaveItemAgent(H2I(it_book),1,it)
                endif
            endif
        endif
    endif
    set g = null
    set u = null
    set ut = null
    set it = null
    set it_book = null
    set it_false = null
endfunction

function SellItemUnit_Conditions takes nothing returns boolean
    local integer id = GetUnitTypeId(GetSellingUnit())
    if IsSellItemUnit(id) then
        call BuyItemUnit(GetBuyingUnit(),GetSoldUnit())
    endif
    return false
endfunction
function UnitGetItem_Actions takes nothing returns nothing
    call GetNewItem(GetTriggerUnit(),GetManipulatedItem())
endfunction
function UnitGiveUpItem_Actions takes nothing returns nothing
    call GiveUpItem(GetTriggerUnit(),GetManipulatedItem())
endfunction
function LoZiDeath_Conditions takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local integer i = 0
    if  GetUnitTypeId(u) == 'hrdh'  then
        loop
            exitwhen i > 5
            call SetItemPosition(UnitItemInSlot(u, i),GetUnitX(u), GetUnitY(u))
            set i = i + 1
        endloop
    endif
    set u = null
    return false
endfunction
function Trig_ItemDJ_Conditions takes nothing returns boolean
    local integer id = GetItemTypeId(GetManipulatedItem())
    //return id == 'hslv' or  id == 'pclr' or id == 'I00H' or id == 'I00J'
    return IsItemCharges(id)
endfunction
function Trig_ItemDJ_Actions takes nothing returns nothing
    local integer i = 0
    local item it = GetManipulatedItem()
    local unit u = GetTriggerUnit()
    local item itt
    loop
        exitwhen i > 5
        set itt = UnitItemInSlot(u, i)
        if it != itt and  GetItemTypeId(it) == GetItemTypeId(itt) then
            call SetItemCharges( itt, GetItemCharges(itt) + GetItemCharges(it))
            call RemoveItem( it )
        endif
        set i = i + 1
    endloop
    set u = null
    set it = null
    set itt = null
endfunction
//===========================================================================
function InitTrig_ItemInit takes nothing returns nothing
    local trigger tri = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( tri, EVENT_PLAYER_UNIT_SELL )
    call TriggerAddCondition( tri, Condition( function SellItemUnit_Conditions ) )
    set tri = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( tri, EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddAction( tri, function UnitGetItem_Actions )
    set tri = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( tri, EVENT_PLAYER_UNIT_DROP_ITEM )
    call TriggerAddAction( tri, function UnitGiveUpItem_Actions )
    set tri = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( tri, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( tri, Condition( function LoZiDeath_Conditions ) )
    set tri = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( tri,EVENT_PLAYER_UNIT_PICKUP_ITEM )
    call TriggerAddCondition( tri, Condition( function Trig_ItemDJ_Conditions ) )
    call TriggerAddAction( tri, function Trig_ItemDJ_Actions )
    set tri = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( tri, EVENT_PLAYER_UNIT_USE_ITEM )
    call TriggerAddCondition( tri, Condition( function SplitDel_Conditions ) )
    set tri = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( tri, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( tri, Condition( function Split_Conditions ) )
    set tri = null
endfunction
//===========================================================================
//骡子自动合成给予物品
//===========================================================================
function GetNewItemFromLuoZi takes unit u, unit lz returns nothing
    local item array it
    local item it_temp
    local item it_mix
   
    local integer array id
    local integer array id_temp
    local integer id_mix
    local integer id_mixed
    local integer i
    local integer unum
    local integer lznum
   
    local integer MethodTotal
    local integer total
    local integer num
    local integer num10
   
    local integer j = 0
    local integer k = 0
    local integer l = 0
    local integer m = 0
    local integer n = 0
   
    local boolean b
    local boolean bb
    local boolean array bx
   
    set i = 0
    loop
        exitwhen i > 5
        set it_temp = UnitItemInSlot(u, i)
        if it_temp != null then
            if IsItemOwn(u,it_temp) then
                set id = GetItemCode(it_temp)
                set it = it_temp
            endif
        endif
        set it_temp = UnitItemInSlot(lz, i)
        if it_temp != null then
            if IsItemOwn(u,it_temp) then
                set id[i+6] = GetItemCode(it_temp)
                set it[i+6] = it_temp
            endif
        endif
        set i = i + 1
    endloop
   
    //id[0-5]英雄身上物品code  id[6-11]骡子身上物品code
    //it[0-5]英雄身上物品      it[6-11]骡子身上物品
    //unum英雄属于自己物品数量 lznum骡子属于自己物品数量
    set n = 0
    loop
        exitwhen n > 5
        set id_mix = id[6+n]
        set it_mix = it[6+n]
        
        set i = 1
        set MethodTotal = udg_ItemFormNum[id_mix] //该物品的合成方法总数
        loop
            exitwhen i > MethodTotal
            set num = GetItemInt(id_mix,i)// 第i合成物方法编号
            set num10 =  num * 10
            
            set m = 0
            loop
                exitwhen m > 11
                set id_temp[m] = id[m]
                set m = m + 1
            endloop
            set total = udg_MixFormula[num10+9]
            set j = 1
            set b = true
            loop
                exitwhen j > total or b == false
                set k = 0
                set b = false
                loop
                    exitwhen k > 11
                    if udg_MixFormula[num10+j] == id_temp[k] then
                        set id_temp[k] = -1
                        set b = true
                        set k = 11
                    endif
                    set k = k + 1
                endloop
                set j = j + 1
            endloop
            
            if b then //可合成,删除条件物品,给予合成物品
                set bb = false
                set id_mixed = udg_MixFormula[num10+7]
                if id_mixed>800 and GetItemBool(H2I(u),618)==false then                    
                    if id_mixed==816 and GetUnitTypeId(u)=='H020'  then
                        call SaveItemBool(H2I(u),618,true)
                        set bb = true
                    elseif  udg_MixFormula[num10]==GetUnitTypeId(u) then
                        call SaveItemBool(H2I(u),618,true)
                        set bb = true                        
                    endif
                    if udg_ColseZhuanShu then
                        set bb = false
                    endif
                else
                    set bb = true
                endif
               
                if bb then
                    set m=0
                    loop
                        exitwhen m > 11
                        if id_temp[m] == -1 then
                            call FlushItemMission(H2I(it[m]))
                            call RemoveItem(it[m])
                            set it[m] = null
                            set id[m] = 0
                        endif
                        set m = m + 1
                    endloop
                    if id_mixed <= 800 then
                        call CreateItemForUnit(id_mixed,u)
                    else
                        call UnitAddItemById(u,udg_Item_True[id_mixed])
                    endif
                    call DestroyEffect(AddSpecialEffectTarget("Abilities\\\\Spells\\\\Items\\\\AIem\\\\AIemTarget.mdl", u, "origin"))
                    set i = MethodTotal + 1
                endif
            else
                //call Debug("不可合成")
            endif
            set i = i + 1
        endloop
        set n = n + 1
    endloop
   
    //可消耗物品叠加
    set i = 1
    loop
        exitwhen i > 4
        set bx = false
        set bx[i+10] = false
        set i = i + 1
    endloop
   
    set i = 0
    loop
        exitwhen i > 5
        set it_temp = UnitItemInSlot(lz, i)
        set id_mixed = GetItemTypeId(it_temp)
        if id_mixed == 'hslv'  then
            set bx[1] = true
            set id[1] = i
        elseif id_mixed == 'pclr' then
            set bx[2] = true
            set id[2] = i
        elseif id_mixed == 'I00J' then
            set bx[3] = true
            set id[3] = i
        elseif id_mixed == 'I00H' then
            set bx[4] = true
            set id[4] = i
        endif
        
        
        set it_temp = UnitItemInSlot(u, i)
        set id_mixed = GetItemTypeId(it_temp)
        if id_mixed == 'hslv'  then
            set bx[11] = true
            set id[11] = i
        elseif id_mixed == 'pclr' then
            set bx[12] = true
            set id[12] = i
        elseif id_mixed == 'I00J' then
            set bx[13] = true
            set id[13] = i
        elseif id_mixed == 'I00H' then
            set bx[14] = true
            set id[14] = i
        endif
        set i = i + 1
    endloop
   
    if bx[1] and bx[11] then
        set it_temp = UnitItemInSlot(u,id[11])
        call SetItemCharges( it_temp, GetItemCharges(it_temp) + GetItemCharges(UnitItemInSlot(lz,id[1])))
        call RemoveItem(UnitItemInSlot(lz,id[1]))
    endif
    if bx[2] and bx[12] then
        set it_temp = UnitItemInSlot(u,id[12])
        call SetItemCharges( it_temp, GetItemCharges(it_temp) + GetItemCharges(UnitItemInSlot(lz,id[2])))
        call RemoveItem(UnitItemInSlot(lz,id[2]))
    endif
    if bx[3] and bx[13] then
        set it_temp = UnitItemInSlot(u,id[13])
        call SetItemCharges( it_temp, GetItemCharges(it_temp) + GetItemCharges(UnitItemInSlot(lz,id[3])))
        call RemoveItem(UnitItemInSlot(lz,id[3]))
    endif
    if bx[4] and bx[14] then
        set it_temp = UnitItemInSlot(u,id[14])
        call SetItemCharges( it_temp, GetItemCharges(it_temp) + GetItemCharges(UnitItemInSlot(lz,id[4])))
        call RemoveItem(UnitItemInSlot(lz,id[4]))
    endif
   
   
   
    //剩余空格填充
    set unum = 0
    set lznum = 0
    set i = 0
    loop
        exitwhen i > 5
        set it_temp = UnitItemInSlot(u, i)
        if it_temp != null then
            set unum = unum + 1
        endif
        set it_temp = UnitItemInSlot(lz, i)
        if it_temp != null then
            set lznum = lznum + 1
            set it[lznum] = it_temp
        endif
        set i = i + 1
    endloop
   
    if lznum > 0 and unum < 6 then
        if 6-unum >= lznum then
            set i = 1
            loop
                exitwhen i > lznum
                call UnitAddItem( u, it )
                set i = i + 1
            endloop
        else
            set i = 1
            loop
                exitwhen i > 6-unum
                call UnitAddItem( u, it )
                set i = i + 1
            endloop
        endif
    endif
   
   
    set it_temp = null
    set it_mix = null
    set i = 0
    loop
        exitwhen i >11
        set it = null
        set i = i + 1
    endloop
endfunction
//=========================骡子技能=========================

function LuoZi_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A0G7' or GetSpellAbilityId() == 'A0G8'
endfunction

function FindMaster takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit u = GetItemUnit(H2I(t),0)
    local integer id = GetItemInt(H2I(t),1)
    local real dx
    local real dy
    local real l
    local string s = OrderId2StringBJ(GetUnitCurrentOrder(u))
    if udg_u[id] == null or IsUnitType(udg_u[id], UNIT_TYPE_DEAD) then
        if IsUnitAlly(u, Player(0)) then
            call IssuePointOrderLoc( u, "move", udg_Point[0] )
        else
            call IssuePointOrderLoc( u, "move", udg_Point[1] )
        endif
        call PauseTimer(t)
        call FlushItemMission(H2I(t))
        call DestroyTimer(t)
    else
        set l = DistanceBetweenUnits(u,udg_u[id])
        if l <= 150. then
            call GetNewItemFromLuoZi(udg_u[id],u)
        endif
        if l <= 150. or s!= "move" then
            call PauseTimer(t)
            call FlushItemMission(H2I(t))
            call DestroyTimer(t)
        else
            set dx = GetUnitX(udg_u[id])
            set dy = GetUnitY(udg_u[id])
            call IssuePointOrder( u, "move", dx,dy )
        endif
    endif
    set t = null
    set u = null
    set s = null
endfunction

function LuoZi_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local integer id = GetPlayerId(GetOwningPlayer(u)) + 1
    local timer t
    if udg_u[id] == null or IsUnitType(udg_u[id], UNIT_TYPE_DEAD) or GetSpellAbilityId() == 'A0G8' then
        if IsUnitAlly(u, Player(0)) then
            call IssuePointOrderLoc( u, "smart", udg_Point[0] )
        else
            call IssuePointOrderLoc( u, "smart", udg_Point[1] )
        endif
    else
        call IssuePointOrder( u, "move", GetUnitX(udg_u[id]), GetUnitY(udg_u[id]))
        set t = CreateTimer()
        call SaveItemAgent(H2I(t),0,u)
        call SaveItemInt(H2I(t),1,id)
        call TimerStart(t,0.5,true,function FindMaster)
    endif
    set u = null
    set t = null
endfunction

function BuyLuoZi_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetSoldUnit()) == 'hrdh'
endfunction

function BuyLuoZi_Actions takes nothing returns nothing
    local unit u = GetSoldUnit()
    //call TriggerSleepAction(0.1)
    call IssueImmediateOrder( u, "roar" )
    set u = null
endfunction

function LuoZiInit takes nothing returns nothing
    local trigger tri= CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( tri, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( tri, Condition( function LuoZi_Conditions ) )
    call TriggerAddAction( tri, function LuoZi_Actions )
    set tri = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( tri, EVENT_PLAYER_UNIT_SELL )
    call TriggerAddCondition( tri, Condition( function BuyLuoZi_Conditions ) )
    call TriggerAddAction( tri,function BuyLuoZi_Actions)
    set tri = null
endfunction


//===========================================================================
function InitTrig_LuoZi takes nothing returns nothing
    call LuoZiInit()
endfunction
[/jass]
回复

使用道具 举报

发表于 2010-8-16 23:38:21 | 显示全部楼层
这个喵用?少女说说功能口牙~
回复

使用道具 举报

 楼主| 发表于 2010-8-16 23:55:36 | 显示全部楼层
引用第4楼Conflux于2010-08-16 23:38发表的  :
这个喵用?少女说说功能口牙~

就是很多人常说的什么满物品栏合成,什么物品属性不共享之类的。不编辑了,困,明天再编辑。
回复

使用道具 举报

发表于 2010-8-17 00:04:44 | 显示全部楼层
好东西必须顶................
回复

使用道具 举报

发表于 2010-8-17 05:20:29 | 显示全部楼层
系统化了?嗯嗯……移植的话似乎用不到那些注册的部分。
希望能整理下代码,只留下纯正的系统,然后给个应用演示即可,精华没问题的
此外,手机党看代码很类啊
回复

使用道具 举报

 楼主| 发表于 2010-8-17 08:29:24 | 显示全部楼层
4小时前……貌似是4点多。。
一会整理时候再删掉注册函数内容
回复

使用道具 举报

发表于 2010-8-17 09:59:10 | 显示全部楼层
正好5点
回复

使用道具 举报

 楼主| 发表于 2010-8-17 11:17:20 | 显示全部楼层
累~差不多这样吧。。
还个物品表懒得发了。
根据问题再完善说明吧。

传几个图片当签名
SELF.gif OMG.gif
回复

使用道具 举报

发表于 2010-8-17 16:57:54 | 显示全部楼层
很强大
回复

使用道具 举报

发表于 2010-8-17 18:04:37 | 显示全部楼层
发现宝宝了~~~
回复

使用道具 举报

发表于 2010-8-20 23:35:39 | 显示全部楼层
少女的一定要支持
回复

使用道具 举报

发表于 2010-8-21 01:58:03 | 显示全部楼层
非常的强大...
回复

使用道具 举报

发表于 2010-8-25 18:50:14 | 显示全部楼层
。。相当强大
回复

使用道具 举报

 楼主| 发表于 2010-12-10 11:44:32 | 显示全部楼层
记得我之前说过合成注册算法比较愚昧,有较大冗余,而且绝大多数使用HASH读取,时间和空间都造成较大浪费。
所以这次做了个小更新,是针对合成注册算法的改变。
测试图已经基本测试过。。不过等测试一段时间,稳定后再发。

基本思想
A+B+C=D

设置该合成公式为 1
公式1 下第一个物品A  第二个B 第三个C
共3个材料
A 第1种合成公式 为1
B第1种合成公式 为1
C 第1种合成公式 为1

A+C=E
设置该合成公式为 2
公式2 下第一个物品A  第二个C
共2个材料
A 第2种合成公式 为2
C 第2种合成公式 为2


B+C=D
设置该合成公式为 3
公式3 下第一个物品B  第二个C
共2个材料
B第2种合成公式 为3
C 第3种合成公式 为3
……

获得物品时判断
X物品的1~N种合成公式来实现合成
回复

使用道具 举报

 楼主| 发表于 2010-12-10 22:56:24 | 显示全部楼层
先上演示测试图~
代码有空附上

新物品系统.w3x

3.98 MB, 下载次数: 82

回复

使用道具 举报

 楼主| 发表于 2011-3-15 09:31:26 | 显示全部楼层
最近又更新了一下,增加拆卸功能~
回复

使用道具 举报

发表于 2011-3-15 13:52:21 | 显示全部楼层
最近也在弄这个,那么支持了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 点一下

本版积分规则

Archiver|移动端|小黑屋|地精研究院

GMT+8, 2024-4-25 16:38 , Processed in 0.321405 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表