找回密码
 点一下
查看: 3607|回复: 0

随机物品系统

  [复制链接]
发表于 2009-10-19 19:58:22 | 显示全部楼层 |阅读模式
系统功能:
  • 自定义每个的随机等级
  • 对每个物品设置在相同随机等级中的概率
  • 多等级随机物品系统可以在多个任意定义的等级内随机物品
  • 多等级随机时,可以设置每个等级出现的概率
  • 注册物品时不需要按等级排序,只要将所有的物品类型、等级、在等级内出现的概率放到对应的三个数组系统即可
  • 可禁用物品版的支持禁用某个物品类型出现在随机中
系统说明:
     使用方法,先(所有数据注册完成后的任意时间)执行RandomItemSystemInitialize,然后通过函数GetRandomItemType获得随机到的物品类型。
     多等级物品的等级使用二进制方法记录,通过参数Key的二进制值的每位的值(0、1)来决定是否使用某个等级。你可以使用MakeLevelKey来添加等级、或者直接自己计算出结果添加到参数里。详细内容参考演示使用。
     如果不需要在多个等级中随机,只会在全部物品或某一等级的物品中随机,请使用单等级版本。运算效率会更高。
     多等级版本暂时最多支持定义30个等级(没有保护,请使用者自行注意)因为一个整数的数据量有限,如果需要更多等级,请自行修改代码
     关于参数的设置请参考演示或函数中的注释,特殊说明一下注释中最后的(自定数据)(结果数据)(间接数据)这三个类别。自定数据就是自己设置值的数据,间接数据是根据自定数据得到的值,比如数组使用的大小,结果数据是放置计算结果的数据,请勿修改。
     两个系统最终的返回值都是物品类型(integer)
    禁用物品版增加了禁用某个物品出现在随机中的功能,禁用物品请用AddBanItem添加物品类型(integer),去除禁用物品请使用RemoveBanItem,参数也是物品类型。删除错误的类型无效。具体使用方法请看演示
单等级版代码:
[jass]globals
integer array udg_ItemTypeArray//物品类型记录数组(不必按等级排列)(自定数据)
integer array udg_ItemAppearRate//对应每个物品类型物品在其等级所有物品中的出现概率(自动计算)(自定数据)  
integer array udg_ItemLevel//对应每个物品类型的等级
integer array udg_ItemLevelRate//所有等级中每个等级出现的概率(自动计算)(自定数据)
integer array udg_ItemRateNumInLevel//每个等级的物品的概率总和(对应等级排列)(结果数据)                     
integer array udg_ItemIndexInLevel//每个等级的物品在udg_ItemTypeArray中的第一个的序号位置(对应等级排列,为0~udg_ItemLevelNum -1)(结果数据)
integer udg_ItemTypeNum//物品类型总数(间接数据)
integer udg_ItemLevelNum//物品等级总数,物品等级从0级开始,依次递增到udg_ItemLevelNum - 1级,共udg_ItemLevelNum个等级 (间接数据)
integer udg_ItemLevelRateNum//物品等级总概率(结果数据)
endglobals
function RandomItemSystemInitialize takes nothing returns nothing//随机物品系统初始化
    local integer array TempItemTypeArray
    local integer array TempItemAppearRate
    local integer array TempItemLevel
    local integer array TempItemNum
    local integer TempInteger
    local integer i = 0
    set udg_ItemLevelRateNum = 0
    set udg_ItemIndexInLevel[0] = 0
    loop//对于等级概率求和以及部分数据初始值设置
        set udg_ItemLevelRateNum = udg_ItemLevelRateNum + udg_ItemLevelRate
        set udg_ItemRateNumInLevel = 0
        set udg_ItemIndexInLevel = 0
        set TempItemNum = 0
        set i = i + 1
        exitwhen i >= udg_ItemLevelNum
    endloop
    set i = 0
    loop//记录临时数据以及等级内概率求和
        set TempItemTypeArray = udg_ItemTypeArray
        set TempItemAppearRate = udg_ItemAppearRate
        set TempItemLevel = udg_ItemLevel
        set udg_ItemIndexInLevel[udg_ItemLevel + 1] = udg_ItemIndexInLevel[udg_ItemLevel + 1] + 1
        set udg_ItemRateNumInLevel[udg_ItemLevel] = udg_ItemRateNumInLevel[udg_ItemLevel] + udg_ItemAppearRate
        set i = i + 1
        exitwhen i >= udg_ItemTypeNum
    endloop
    set i = 1
    loop//对于等级概率分配以及每个等级初始位置分配
        set udg_ItemLevelRate = udg_ItemLevelRate  + udg_ItemLevelRate[i - 1]   
        set udg_ItemIndexInLevel = udg_ItemIndexInLevel + udg_ItemIndexInLevel[i - 1]
        set i = i + 1
        exitwhen i >= udg_ItemLevelNum
    endloop
    set i= 0
    loop//对于物品类型数据排序
        set TempInteger = udg_ItemIndexInLevel[TempItemLevel] + TempItemNum[TempItemLevel]
        set udg_ItemTypeArray[TempInteger] = TempItemTypeArray
        set udg_ItemAppearRate[TempInteger] = TempItemAppearRate
        set udg_ItemLevel[TempInteger] = TempItemLevel
        set TempItemNum[TempItemLevel] = TempItemNum[TempItemLevel] + 1
        set i = i + 1
        exitwhen i >= udg_ItemTypeNum
    endloop      
    set i = 1
    set TempInteger = 1
    loop//分配每个等级内的概率
        if i != udg_ItemIndexInLevel [TempInteger] then
            set udg_ItemAppearRate = udg_ItemAppearRate + udg_ItemAppearRate[i - 1]
        else
            set TempInteger = TempInteger + 1
        endif
        set i = i + 1
        exitwhen i >= udg_ItemTypeNum  
    endloop                  
endfunction
function GetRandomItemType takes integer Level returns integer//获得一个给定等级的随机物品当物品等级为-1时为在所有是物品中随机获得
    local integer RandomRate
    local integer i = 0
    if Level == -1 then
        set RandomRate = GetRandomInt(1,udg_ItemLevelRateNum)
        loop
            if udg_ItemLevelRate >= RandomRate then
                set Level = i
                exitwhen true
            endif  
            set i = i + 1
        endloop
    endif
    set RandomRate = GetRandomInt(1,udg_ItemRateNumInLevel[Level])
    set i = 0
    loop
        if udg_ItemAppearRate[udg_ItemIndexInLevel[Level] + i] >= RandomRate then
            return udg_ItemTypeArray[udg_ItemIndexInLevel[Level] + i]
        endif
        set i = i + 1
    endloop
    return udg_ItemTypeArray[0]
endfunction [/jass]
多等级版代码:
[jass]globals
integer array udg_ItemTypeArray//物品类型记录数组(不必按等级排列)(自定数据)
integer array udg_ItemAppearRate//对应每个物品类型物品在其等级所有物品中的出现概率(自动计算)(自定数据)  
integer array udg_ItemLevel//对应每个物品类型的等级
integer array udg_ItemLevelRate//所有等级中每个等级出现的概率(自动计算)(自定数据)  
integer array udg_ItemRateNumInLevel//每个等级的物品的概率总和(对应等级排列)(结果数据)                     
integer array udg_ItemIndexInLevel//每个等级的物品在udg_ItemTypeArray中的第一个的序号位置(对应等级排列,为0~udg_ItemLevelNum -1)(结果数据)
integer udg_ItemTypeNum//物品类型总数(间接数据)
integer udg_ItemLevelNum//物品等级总数,物品等级从0级开始,依次递增到udg_ItemLevelNum - 1级,共udg_ItemLevelNum个等级 (间接数据)
endglobals
function RandomItemSystemInitialize takes nothing returns nothing//随机物品系统初始化
    local integer array TempItemTypeArray
    local integer array TempItemAppearRate
    local integer array TempItemLevel
    local integer array TempItemNum
    local integer TempInteger
    local integer i = 0
    set udg_ItemIndexInLevel[0] = 0
    loop//对于部分数据初始值设置
        set udg_ItemRateNumInLevel = 0
        set udg_ItemIndexInLevel = 0
        set TempItemNum = 0
        set i = i + 1
        exitwhen i >= udg_ItemLevelNum
    endloop
    set i = 0
    loop//记录临时数据以及等级内概率求和
        set TempItemTypeArray = udg_ItemTypeArray
        set TempItemAppearRate = udg_ItemAppearRate
        set TempItemLevel = udg_ItemLevel
        set udg_ItemIndexInLevel[udg_ItemLevel + 1] = udg_ItemIndexInLevel[udg_ItemLevel + 1] + 1
        set udg_ItemRateNumInLevel[udg_ItemLevel] = udg_ItemRateNumInLevel[udg_ItemLevel] + udg_ItemAppearRate
        set i = i + 1
        exitwhen i >= udg_ItemTypeNum
    endloop
    set i = 1
    loop//对于每个等级初始位置分配
        set udg_ItemIndexInLevel = udg_ItemIndexInLevel + udg_ItemIndexInLevel[i - 1]
        set i = i + 1
        exitwhen i >= udg_ItemLevelNum
    endloop
    set i= 0
    loop//对于物品类型数据排序
        set TempInteger = udg_ItemIndexInLevel[TempItemLevel] + TempItemNum[TempItemLevel]
        set udg_ItemTypeArray[TempInteger] = TempItemTypeArray
        set udg_ItemAppearRate[TempInteger] = TempItemAppearRate
        set udg_ItemLevel[TempInteger] = TempItemLevel
        set TempItemNum[TempItemLevel] = TempItemNum[TempItemLevel] + 1
        set i = i + 1
        exitwhen i >= udg_ItemTypeNum
    endloop      
    set i = 1
    set TempInteger = 1
    loop//分配每个等级内的概率
        if i != udg_ItemIndexInLevel [TempInteger] then
            set udg_ItemAppearRate = udg_ItemAppearRate + udg_ItemAppearRate[i - 1]
        else
            set TempInteger = TempInteger + 1
        endif
        set i = i + 1
        exitwhen i >= udg_ItemTypeNum  
    endloop                  
endfunction
function MakeLevelKey takes integer Level,integer Key returns integer//将Level加入到Key中,注意不要重复添加,最大等级30
    local integer i = 0
    local integer TempKey = 1
    loop   
        exitwhen i == Level            
        set TempKey = TempKey * 2
        set i = i + 1
    endloop
    return Key + TempKey
endfunction
function GetRandomItemType takes integer Key returns integer//获得一个给定Key的随机物品
    local integer RandomRate
    local integer i = -1
    local integer j = 0
    local integer Level = 0
    local integer TempAllLevelRate = 0
    local integer array TempLevelRate
    local integer array TempLevel   
    loop//获取记录有效的Level
        if Key != Key / 2 * 2 then   
            set i = i + 1
            set TempLevelRate = udg_ItemLevelRate[j]
            set TempAllLevelRate = TempAllLevelRate + udg_ItemLevelRate[j]
            set TempLevel = j
        endif
        set Key = Key / 2  
        exitwhen Key == 0  
        set j = j + 1
    endloop
    set j = 1
    loop//分配概率               
        exitwhen j > i
        set TempLevelRate[j] = TempLevelRate[j] + TempLevelRate[j - 1]
        set j = j + 1
    endloop
    set RandomRate = GetRandomInt(1,TempAllLevelRate)
    set j = 0
    loop
        if TempLevelRate[j] >= RandomRate then
            set Level = TempLevel[j]   
            exitwhen true
        endif
        set j = j + 1        
    endloop
    set j = 0     
    set RandomRate = GetRandomInt(1,udg_ItemRateNumInLevel[Level])
    loop
        if udg_ItemAppearRate[udg_ItemIndexInLevel[Level] + j] >= RandomRate then
            return udg_ItemTypeArray[udg_ItemIndexInLevel[Level] + j]
        endif
        set j = j + 1
    endloop
    return udg_ItemTypeArray[0]
endfunction
[/jass]
多等级禁用物品版
[jass]globals
integer array udg_ItemTypeArray//物品类型记录数组(不必按等级排列)(自定数据)
integer array udg_ItemAppearRate//对应每个物品类型物品在其等级所有物品中的出现概率(自动计算)(自定数据)  
integer array udg_ItemLevel//对应每个物品类型的等级
integer array udg_ItemLevelRate//所有等级中每个等级出现的概率(自动计算)(自定数据)                    
integer array udg_ItemIndexInLevel//每个等级的物品在udg_ItemTypeArray中的第一个的序号位置(对应等级排列,为0~udg_ItemLevelNum -1)(结果数据)
integer array udg_BanItemType//禁止的物品的类型数组,在调用函数GetRandomItemType后自动清空。如果需禁用某个物品,那么请放入此数组中(结果数据)
integer udg_ItemTypeNum//物品类型总数(间接数据)
integer udg_ItemLevelNum//物品等级总数,物品等级从0级开始,依次递增到udg_ItemLevelNum - 1级,共udg_ItemLevelNum个等级 (间接数据)
endglobals
function RandomItemSystemInitialize takes nothing returns nothing//随机物品系统初始化
    local integer array TempItemTypeArray
    local integer array TempItemAppearRate
    local integer array TempItemLevel
    local integer array TempItemNum
    local integer TempInteger
    local integer i = 0
    set udg_ItemIndexInLevel[0] = 0
    loop//对于部分数据初始值设置
        set udg_ItemIndexInLevel = 0
        set TempItemNum = 0
        set i = i + 1
        exitwhen i >= udg_ItemLevelNum
    endloop
    set i = 0
    loop//记录临时数据以及等级内概率求和
        set TempItemTypeArray = udg_ItemTypeArray
        set TempItemAppearRate = udg_ItemAppearRate
        set TempItemLevel = udg_ItemLevel
        set udg_ItemIndexInLevel[udg_ItemLevel + 1] = udg_ItemIndexInLevel[udg_ItemLevel + 1] + 1
        set i = i + 1
        exitwhen i >= udg_ItemTypeNum
    endloop
    set i = 1
    loop//对于每个等级初始位置分配
        set udg_ItemIndexInLevel = udg_ItemIndexInLevel + udg_ItemIndexInLevel[i - 1]
        set i = i + 1
        exitwhen i >= udg_ItemLevelNum
    endloop
    set i= 0
    loop//对于物品类型数据排序
        set TempInteger = udg_ItemIndexInLevel[TempItemLevel] + TempItemNum[TempItemLevel]
        set udg_ItemTypeArray[TempInteger] = TempItemTypeArray
        set udg_ItemAppearRate[TempInteger] = TempItemAppearRate
        set udg_ItemLevel[TempInteger] = TempItemLevel
        set TempItemNum[TempItemLevel] = TempItemNum[TempItemLevel] + 1
        set i = i + 1
        exitwhen i >= udg_ItemTypeNum
    endloop         
endfunction
function MakeLevelKey takes integer Level,integer Key returns integer//将Level加入到Key中,注意不要重复添加,最大等级30
    local integer i = 0
    local integer TempKey = 1
    loop   
        exitwhen i == Level            
        set TempKey = TempKey * 2
        set i = i + 1
    endloop
    return Key + TempKey
endfunction
function IsBanItem takes integer ItemType returns boolean//返回物品类型ItemType是否可出现
    local integer i = 0
    loop
        if ItemType == udg_BanItemType then
            return false
        endif
        set i = i + 1
        exitwhen udg_BanItemType == 0
    endloop
    return true
endfunction
function AddBanItem takes integer ItemType returns nothing//增加一个禁用物品
    local integer i = 0
    loop
        exitwhen udg_BanItemType == 0
        set i = i + 1
    endloop  
    set udg_BanItemType = ItemType
endfunction
function RemoveBanItem takes integer ItemType returns nothing//将物品在禁用表中去除
    local integer i = 0
    local integer BanItemIndex = -1
    loop
        exitwhen udg_BanItemType == 0
        if udg_BanItemType == ItemType then
            set BanItemIndex = i
        endif
        set i = i + 1
    endloop  
    if  BanItemIndex == -1 then
        return
    endif
    set udg_BanItemType[BanItemIndex] = udg_BanItemType[i - 1]
    set udg_BanItemType[i - 1] = 0
endfunction
function GetRandomItemType takes integer Key returns integer//获得一个给定Key的随机物品
    local integer RandomRate
    local integer i = -1
    local integer j = 0
    local integer Level = 0
    local integer TempRate = 0
    local integer array TempRateArray
    local integer array TempLevel  
    local integer array TempItemType
    loop//获取记录有效的Level
        if Key != Key / 2 * 2 then   
            set i = i + 1
            set TempRateArray = udg_ItemLevelRate[j]
            set TempRate = TempRate + udg_ItemLevelRate[j]
            set TempLevel = j
        endif
        set Key = Key / 2  
        exitwhen Key == 0  
        set j = j + 1
    endloop
    set j = 1
    loop//分配等级概率               
        exitwhen j > i
        set TempRateArray[j] = TempRateArray[j] + TempRateArray[j - 1]
        set j = j + 1
    endloop
    set RandomRate = GetRandomInt(1,TempRate)
    set j = 0
    loop//获得随机等级
        if TempRateArray[j] >= RandomRate then
            set Level = TempLevel[j]   
            exitwhen true
        endif
        set j = j + 1        
    endloop
    set TempRate = 0
    set i = -1
    set j = udg_ItemIndexInLevel[Level]
    loop//记录有效的物品类型
        if IsBanItem(udg_ItemTypeArray[j]) then      
            set i = i + 1
            set TempRateArray = udg_ItemAppearRate[j]
            set TempItemType = udg_ItemTypeArray[j]  
            set TempRate = TempRate + udg_ItemAppearRate[j]
        endif
        set j = j + 1
        exitwhen j == udg_ItemIndexInLevel[Level + 1]
    endloop
    set j = 1
    loop//分配物品概率               
        exitwhen j > i
        set TempRateArray[j] = TempRateArray[j] + TempRateArray[j - 1]
        set j = j + 1
    endloop
    set j = 0     
    set RandomRate = GetRandomInt(1,TempRate)
    loop
        if TempRateArray[j] >= RandomRate then
            return TempItemType[j]
        endif
        set j = j + 1
    endloop
    return udg_ItemTypeArray[0]
endfunction
[/jass]

随机物品单等级和多等级版
随机物品多等级可禁用版

评分

参与人数 1威望 +5 收起 理由
alexries + 5

查看全部评分

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

本版积分规则

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

GMT+8, 2024-11-21 19:34 , Processed in 0.158965 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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