| | |
| | | GameWorld.DebugLog("物品过期时间" + timeStr)
|
| | | return GameWorld.ChangeTimeStrToNum(timeStr)
|
| | |
|
| | | def CreateSingleItem(itemID, itemCount=1, isAuctionItem=False, expireTime=0):
|
| | | def CreateSingleItem(itemID, itemCount=1, isAuctionItem=False, expireTime=0, curPlayer=None, setAttrDict=None):
|
| | | ''' 创建物品
|
| | | @param isAuctionItem: 是否拍品,默认非拍品
|
| | | @param expireTime: 有效时间,时间单位由时效类型决定
|
| | |
| | | if expireTime > 0:
|
| | | curSingleItem.SetUserAttr(ShareDefine.Def_IudetExpireTime, expireTime)
|
| | |
|
| | | # 装备
|
| | | if GetIsEquip(curSingleItem):
|
| | | setAttrDict = GetCreateEquipAttr(curSingleItem, curPlayer, setAttrDict)
|
| | | if setAttrDict == None:
|
| | | curSingleItem.Clear()
|
| | | return
|
| | | AddCreateItemAttr(curSingleItem, setAttrDict)
|
| | | |
| | | #这里返回的是SingleItem , 如果创建了,未使用,会找出C++内存泄露!!!
|
| | | return curSingleItem
|
| | |
|
| | | def AddCreateItemAttr(curItem, setAttrDict):
|
| | | ## 设置生成装备所有属性
|
| | | for key, value in setAttrDict.items():
|
| | | key = GameWorld.ToIntDef(key, key)
|
| | | # 需支持
|
| | | # 1. UserData格式: {'19': ['1889', '2034', '893', '927'], '50': ['1702622046'], '17': ['39', '33', '34', '9']}
|
| | | # 2. 自定义字典: {"key":value, ...} key支持自定义或与UserData的key,value支持数值或列表,列表元素支持字符串或数值,均默认转为数值
|
| | | # 数值类型的默认为UserData属性 |
| | | if isinstance(key, int):
|
| | | if key % 2 == 0: # 偶数是单数值
|
| | | v = 0
|
| | | if isinstance(value, int):
|
| | | v = value
|
| | | elif (isinstance(value, list) or isinstance(value, tuple)) and value:
|
| | | v = GameWorld.ToIntDef(value[0], 0)
|
| | | curItem.SetUserAttr(key, v)
|
| | | elif isinstance(value, list) or isinstance(value, tuple): # 单数一定是要列表
|
| | | curItem.ClearUserAttr(key)
|
| | | for v in value:
|
| | | v = GameWorld.ToIntDef(v, 0)
|
| | | curItem.AddUserAttr(key, v)
|
| | | # 其他指定字符串类型属性
|
| | | else:
|
| | | GameWorld.Log("###AddCreateItemAttr unknown key:%s, value:%s, itemID=%s" % (key, value, curItem.GetItemTypeID()))
|
| | | |
| | | MakeEquipGS(curItem)
|
| | | return
|
| | |
|
| | | def GetCreateEquipAttr(curItem, curPlayer=None, setAttrDict=None):
|
| | | '''获取生成装备所有属性
|
| | | @param curPlayer: 可能为None
|
| | | @param setAttrDict: 直接设置物品的属性 {key:value, ...} key支持 ShareDefine.Def_IudetXXX字符串 或 自定key
|
| | | @return: None - 异常情况,物品实例需要clear
|
| | | equipAttrDict - 生成后的最新属性k:v字典,可直接用于 SetCreateEquipAttr
|
| | | '''
|
| | | if setAttrDict == None:
|
| | | setAttrDict = {}
|
| | | equipAttrDict = {}
|
| | | playerID = 0 if not curPlayer else curPlayer.GetPlayerID()
|
| | | itemID = curItem.GetItemTypeID()
|
| | | |
| | | appointID = setAttrDict.get(ShareDefine.Def_CItemKey_AppointID)
|
| | | # 定制属性ID
|
| | | if appointID > 0:
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("AppointItem", appointID)
|
| | | if not ipyData:
|
| | | return
|
| | | if ipyData.GetCancelUseLimit():
|
| | | equipAttrDict[str(ShareDefine.Def_IudetCancelUseLimit)] = 1
|
| | | equipAttrDict[str(ShareDefine.Def_IudetItemLV)] = ipyData.GetItemLV()
|
| | | equipAttrDict[str(ShareDefine.Def_IudetBaseAttrID)] = ipyData.GetBaseAttrID()
|
| | | equipAttrDict[str(ShareDefine.Def_IudetBaseAttrValue)] = ipyData.GetBaseAttrValue()
|
| | | equipAttrDict[str(ShareDefine.Def_IudetLegendAttrID)] = ipyData.GetLegendAttrID()
|
| | | equipAttrDict[str(ShareDefine.Def_IudetLegendAttrValue)] = ipyData.GetLegendAttrValue()
|
| | | GameWorld.DebugLog(" 装备定制属性: itemID=%s,appointID=%s,equipAttrDict=%s,setAttrDict=%s" % (itemID, appointID, equipAttrDict, setAttrDict), playerID)
|
| | | return equipAttrDict
|
| | | |
| | | # 以下为常规生成属性逻辑
|
| | | itemColor = curItem.GetItemColor()
|
| | | equipPlace = curItem.GetEquipPlace()
|
| | | |
| | | if curPlayer:
|
| | | playerID, playerLV = curPlayer.GetPlayerID(), curPlayer.GetLV()
|
| | | else:
|
| | | playerLV = GameWorld.GetGameWorld().GetGameWorldDictByKey(ShareDefine.Def_Notify_WorldKey_WorldAverageLv)
|
| | | GameWorld.DebugLog("生成装备时没有玩家等级, 取当前世界等级! itemID=%s,worldLV=%s" % (itemID, playerLV), playerID)
|
| | | |
| | | colorIpyData = IpyGameDataPY.GetIpyGameData("EquipColor", itemColor)
|
| | | colorPlaceIpyData = IpyGameDataPY.GetIpyGameData("EquipColorPlace", itemColor, equipPlace)
|
| | | if not colorIpyData or not colorPlaceIpyData:
|
| | | GameWorld.ErrLog("生成装备时找不到对应配置! itemID=%s,itemColor=%s,equipPlace=%s" % (itemID, itemColor, equipPlace), playerID)
|
| | | return
|
| | | GameWorld.DebugLog("随机装备属性! itemID=%s,itemColor=%s,equipPlace=%s,setAttrDict=%s" % (itemID, itemColor, equipPlace, setAttrDict), playerID)
|
| | | |
| | | itemLV = setAttrDict.get(str(ShareDefine.Def_IudetItemLV), 0)
|
| | | if not itemLV:
|
| | | # 随机等级
|
| | | lowLV, highLV = IpyGameDataPY.GetFuncEvalCfg("EquipRandRule", 1)
|
| | | randLVList = range(max(playerLV - lowLV, 1), playerLV + highLV)
|
| | | itemLV = random.choice(randLVList)
|
| | | equipAttrDict[str(ShareDefine.Def_IudetItemLV)] = itemLV
|
| | | |
| | | reRatio = 0 # 参考基准值所在比率 0~1
|
| | | lvMin, lvMax = colorIpyData.GetRangeLV() # 品质对应的等级范围
|
| | | if itemLV <= lvMin:
|
| | | reRatio = 0
|
| | | elif itemLV >= lvMax:
|
| | | reRatio = 1
|
| | | else:
|
| | | reRatio = (itemLV - lvMin) / float(lvMax - lvMin)
|
| | | GameWorld.DebugLog(" itemLV=%s,lvMin=%s,lvMax=%s,reRatio=%s,playerLV=%s" % (itemLV, lvMin, lvMax, reRatio, playerLV), playerID)
|
| | | |
| | | baseAttrIDList = setAttrDict.get(str(ShareDefine.Def_IudetBaseAttrID))
|
| | | baseAttrValueList = setAttrDict.get(str(ShareDefine.Def_IudetBaseAttrValue))
|
| | | # 这里注意None为未指定,支持当空列表[]时为不给该属性
|
| | | if baseAttrIDList != None and baseAttrValueList != None and len(baseAttrIDList) == len(baseAttrValueList):
|
| | | equipAttrDict[str(ShareDefine.Def_IudetBaseAttrID)] = baseAttrIDList
|
| | | equipAttrDict[str(ShareDefine.Def_IudetBaseAttrValue)] = baseAttrValueList
|
| | | else:
|
| | | __RandCreateEquipBaseAttr(reRatio, colorPlaceIpyData, equipAttrDict)
|
| | | |
| | | legendAttrIDList = setAttrDict.get(str(ShareDefine.Def_IudetLegendAttrID))
|
| | | legendAttrValueList = setAttrDict.get(str(ShareDefine.Def_IudetLegendAttrValue))
|
| | | if legendAttrIDList != None and legendAttrValueList != None and len(legendAttrIDList) == len(legendAttrValueList):
|
| | | equipAttrDict[str(ShareDefine.Def_IudetLegendAttrID)] = legendAttrIDList
|
| | | equipAttrDict[str(ShareDefine.Def_IudetLegendAttrValue)] = legendAttrValueList
|
| | | else:
|
| | | __RandCreateEquipLegendAttr(reRatio, colorIpyData, equipAttrDict)
|
| | | |
| | | # 神仙极属性可在这里扩展...
|
| | | |
| | | GameWorld.DebugLog(" 装备最终属性: equipAttrDict=%s,setAttrDict=%s" % (equipAttrDict, setAttrDict), playerID)
|
| | | return equipAttrDict
|
| | |
|
| | | def __RandCreateEquipBaseAttr(reRatio, colorPlaceIpyData, setAttrDict):
|
| | | ## 随机装备基础属性
|
| | | baseAttrDict = {ShareDefine.Def_Effect_Atk:colorPlaceIpyData.GetRangeAtk(),
|
| | | ShareDefine.Def_Effect_MaxHP:colorPlaceIpyData.GetRangeHP(),
|
| | | ShareDefine.Def_Effect_Def:colorPlaceIpyData.GetRangeDef(),
|
| | | ShareDefine.Def_Effect_AtkSpeed:colorPlaceIpyData.GetRangeAtkSpeed(),
|
| | | }
|
| | | upDownRateList = IpyGameDataPY.GetFuncEvalCfg("EquipRandRule", 2)
|
| | | baseAttrIDList, baseAttrValueList = [], []
|
| | | for attrID in [ShareDefine.Def_Effect_Atk, ShareDefine.Def_Effect_MaxHP, ShareDefine.Def_Effect_Def, ShareDefine.Def_Effect_AtkSpeed]:
|
| | | valueList = baseAttrDict[attrID]
|
| | | atkValue = __GetRandAttrValueByRatio(valueList, reRatio, upDownRateList)
|
| | | if not atkValue:
|
| | | continue
|
| | | baseAttrIDList.append(attrID)
|
| | | baseAttrValueList.append(atkValue)
|
| | | if baseAttrIDList:
|
| | | setAttrDict[str(ShareDefine.Def_IudetBaseAttrID)] = baseAttrIDList
|
| | | setAttrDict[str(ShareDefine.Def_IudetBaseAttrValue)] = baseAttrValueList
|
| | | GameWorld.DebugLog(" baseAttrIDList=%s,baseAttrValueList=%s" % (baseAttrIDList, baseAttrValueList))
|
| | | return
|
| | |
|
| | | def __RandCreateEquipLegendAttr(reRatio, colorIpyData, setAttrDict):
|
| | | ## 随机装备传奇属性
|
| | | upDownRateList = colorIpyData.GetRangeRand()
|
| | | battleAttrCount = colorIpyData.GetBattleAttrCount() # 战斗属性条数
|
| | | battleDefAttrCount = colorIpyData.GetBattleDefAttrCount() #战斗抗性条数
|
| | | if not battleAttrCount and not battleDefAttrCount:
|
| | | return
|
| | | |
| | | # 注: 闪避率-对应原闪避值;抗闪避-对应原命中值
|
| | | battleAttrDict = {ShareDefine.Def_Effect_FaintRate:colorIpyData.GetRangeFaintRate(),
|
| | | ShareDefine.Def_Effect_SuperHitRate:colorIpyData.GetRangeSuperHitRate(),
|
| | | ShareDefine.Def_Effect_ComboRate:colorIpyData.GetRangeComboRate(),
|
| | | ShareDefine.Def_Effect_Miss:colorIpyData.GetRangeMissRate(),
|
| | | ShareDefine.Def_Effect_AtkBackRate:colorIpyData.GetRangeAtkBackRate(),
|
| | | ShareDefine.Def_Effect_SuckHPPer:colorIpyData.GetRangeSuckHPPer(),
|
| | | }
|
| | | battleDefAttrDict = {ShareDefine.Def_Effect_FaintDefRate:colorIpyData.GetRangeFaintDefRate(),
|
| | | ShareDefine.Def_Effect_SuperHitRateReduce:colorIpyData.GetRangeSuperHitRateReduce(),
|
| | | ShareDefine.Def_Effect_ComboDefRate:colorIpyData.GetRangeComboDefRate(),
|
| | | ShareDefine.Def_Effect_Hit:colorIpyData.GetRangeMissDefRate(),
|
| | | ShareDefine.Def_Effect_AtkBackDefRate:colorIpyData.GetRangeAtkBackDefRate(),
|
| | | ShareDefine.Def_Effect_SuckHPDefPer:colorIpyData.GetRangeSuckHPDefPer(),
|
| | | }
|
| | | |
| | | # 没有配置值的属性不产出,打乱顺序后直接取限制条数前x个即为随机的属性ID
|
| | | # 战斗属性
|
| | | for k, v in battleAttrDict.items():
|
| | | if not v:
|
| | | battleAttrDict.pop(k)
|
| | | battleAttrIDList = battleAttrDict.keys()
|
| | | battleAttrIDList and random.shuffle(battleAttrIDList)
|
| | | battleAttrIDList = battleAttrIDList[:battleAttrCount]
|
| | | batAttrIDList, batAttrValueList= [], []
|
| | | for attrID in battleAttrIDList:
|
| | | atkValue = __GetRandAttrValueByRatio(battleAttrDict[attrID], reRatio, upDownRateList)
|
| | | if not atkValue:
|
| | | continue
|
| | | batAttrIDList.append(attrID)
|
| | | batAttrValueList.append(atkValue)
|
| | | GameWorld.DebugLog(" 战斗属性条数=%s,IDList=%s,ValueList=%s" % (battleAttrCount, batAttrIDList, batAttrValueList)) |
| | | |
| | | # 战斗抗性
|
| | | for k, v in battleDefAttrDict.items():
|
| | | if not v:
|
| | | battleDefAttrDict.pop(k)
|
| | | battleDefAttrIDList = battleDefAttrDict.keys()
|
| | | battleDefAttrIDList and random.shuffle(battleDefAttrIDList)
|
| | | battleDefAttrIDList = battleDefAttrIDList[:battleDefAttrCount]
|
| | | batDefAttrIDList, batDefAttrValueList= [], []
|
| | | for attrID in battleDefAttrIDList:
|
| | | atkValue = __GetRandAttrValueByRatio(battleDefAttrDict[attrID], reRatio, upDownRateList)
|
| | | if not atkValue:
|
| | | continue
|
| | | batDefAttrIDList.append(attrID)
|
| | | batDefAttrValueList.append(atkValue)
|
| | | GameWorld.DebugLog(" 战斗抗性条数=%s,IDList=%s,ValueList=%s" % (battleDefAttrCount, batDefAttrIDList, batDefAttrValueList))
|
| | | |
| | | # 全部放在传奇属性里
|
| | | legendAttrIDList = batAttrIDList + batDefAttrIDList
|
| | | legendAttrValueList = batAttrValueList + batDefAttrValueList
|
| | | if legendAttrIDList:
|
| | | setAttrDict[str(ShareDefine.Def_IudetLegendAttrID)] = legendAttrIDList
|
| | | setAttrDict[str(ShareDefine.Def_IudetLegendAttrValue)] = legendAttrValueList
|
| | | GameWorld.DebugLog(" legendAttrIDList=%s,legendAttrValueList=%s" % (legendAttrIDList, legendAttrValueList))
|
| | | return
|
| | |
|
| | | def __GetRandAttrValueByRatio(valueList, reRatio, upDownRateList):
|
| | | ## 根据参考比例随机属性值
|
| | | valueMin, valueMax = valueList
|
| | | if reRatio < 0 or reRatio > 1:
|
| | | # 不合法的参考比例,默认最小值,合法值为0~1,包含0跟1
|
| | | return valueMin
|
| | | diffValue = valueMax - valueMin
|
| | | reValue = valueMin + int(diffValue * reRatio) # 参考值
|
| | | |
| | | downRate, upRate = upDownRateList
|
| | | randValueMin = int(reValue - math.ceil(diffValue * downRate / 10000.0)) # 至少-1
|
| | | randValueMax = int(reValue + math.ceil(diffValue * upRate / 10000.0)) # 至少+1
|
| | | randValue = random.randint(randValueMin, randValueMax)
|
| | | GameWorld.DebugLog(" valueList=%s,reRatio=%s,upDownRateList=%s,diffValue=%s,reValue=%s,%s~%s,%s" |
| | | % (valueList, reRatio, upDownRateList, diffValue, reValue, randValueMin, randValueMax, randValue))
|
| | | return randValue
|
| | |
|
| | | def UpdateItemUserData(curItem, updateDict={}, delKeyList=[], isUpdateGS=False):
|
| | | ''' 更新物品UserData数据
|
| | | @param curItem: IPY_SingleItem 或 IPY_RoleItem
|