hxp
2024-07-12 8a565fcec631d8ceae589cd2c1764b3629f0fbe7
10202 【越南】【香港】【主干】【砍树】聚魂

# Conflicts:
# PySysDB/PySysDBPY.h
# ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
# ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
# ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
17个文件已修改
3个文件已添加
1493 ■■■■■ 已修改文件
PySysDB/PySysDBPY.h 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py 283 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py 283 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/GatherSoul.py 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetItemCount.py 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py 107 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGatherTheSoul.py 334 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGubao.py 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
PySysDB/PySysDBPY.h
@@ -1673,6 +1673,7 @@
    BYTE        _TreasureType;    //寻宝类型
    WORD        MinLV;    //最小等级
    dict        GridItemInfo;    //格子编号对应物品信息 {"编号":[物品ID, 个数], ...}
    dict        GridLibInfo;    //格子编号对应库ID {"编号":物品库ID, ...}
    list        JobItemList;    //职业物品组列表 [[职业1物品, 职业2物品, ...], ...]
    list        GridItemRateListFree;    //免费产出格子编号饼图 [[概率, 格子编号], ...]
    list        FreeGridItemRateList2;    //免费每满x次保底产出格子编号饼图 [[概率, 格子编号], ...]
@@ -1681,6 +1682,16 @@
    list        GridItemRateList2;    //每满x次保底产出格子编号饼图 [[概率, 格子编号], ...]
    dict        GridItemRateList3;    //第x次必出产出格子编号饼图 {次数:[[概率, 格子编号], ...], ...}
    BYTE        LuckyGridNum;    //幸运加成格子编号
};
//寻宝物品库
struct tagTreasureItemLib
{
    WORD        _LibID;    //库ID
    DWORD        ItemID;    //物品ID
    DWORD        ItemCount;    //物品个数
    DWORD        ItemWeight;    //物品权重
};
//极品白拿表
@@ -2369,6 +2380,30 @@
    WORD        PosY;    //坐标Y
};
//聚魂新表
struct tagGatherTheSoul
{
    DWORD        _SoulID;    //聚魂ID
    DWORD        PieceItemID;    //碎片物品ID
    BYTE        HoleNum;    //孔编号
    BYTE        SoulColor;    //品质
    DWORD        SoulSkillTypeID;    //技能TypeID
    list        SoulSkillLVList;    //技能等级所需魂等级列表
};
//聚魂新升级表
struct tagGatherTheSoulLV
{
    DWORD        _SoulID;    //聚魂ID
    WORD        _SoulLV;    //魂等级
    WORD        NeedPiece;    //该级所需碎片
    DWORD        NeedSoulValue;    //所需聚魂精华
    list        LVAttrTypeList;    //累计总属性类型
    list        LVAttrValueList;    //累计总属性值
};
//聚魂表
struct tagGatherSoul
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetPack.py
@@ -18842,6 +18842,62 @@
#------------------------------------------------------
# B2 25 新聚魂操作 #tagCMGatherTheSoulOP
class  tagCMGatherTheSoulOP(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("OpType", c_ubyte),    # 0-激活升级; 1-穿戴替换; 2-卸下
                  ("SoulID", c_int),    # 聚魂ID;当操作升级时,如果为0代表一键升级所有可升级的
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB2
        self.SubCmd = 0x25
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xB2
        self.SubCmd = 0x25
        self.OpType = 0
        self.SoulID = 0
        return
    def GetLength(self):
        return sizeof(tagCMGatherTheSoulOP)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 25 新聚魂操作 //tagCMGatherTheSoulOP:
                                Cmd:%s,
                                SubCmd:%s,
                                OpType:%d,
                                SoulID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.OpType,
                                self.SoulID
                                )
        return DumpString
m_NAtagCMGatherTheSoulOP=tagCMGatherTheSoulOP()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMGatherTheSoulOP.Cmd,m_NAtagCMGatherTheSoulOP.SubCmd))] = m_NAtagCMGatherTheSoulOP
#------------------------------------------------------
# B2 12 领取功能系统特权奖励 #tagCMGetFuncSysPrivilegeAward
class  tagCMGetFuncSysPrivilegeAward(Structure):
ServerPython/CoreServerGroup/GameServer/Script/ChPyNetSendPack.py
@@ -18963,6 +18963,114 @@
#------------------------------------------------------
# A2 06 自动转化为对应物品ID个数刷新 #tagMCAutoItemCountRefresh
class  tagMCAutoItemCount(Structure):
    _pack_ = 1
    _fields_ = [
                  ("ItemID", c_int),
                  ("ItemCount", c_int),
                  ]
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.ItemID = 0
        self.ItemCount = 0
        return
    def GetLength(self):
        return sizeof(tagMCAutoItemCount)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A2 06 自动转化为对应物品ID个数刷新 //tagMCAutoItemCountRefresh:
                                ItemID:%d,
                                ItemCount:%d
                                '''\
                                %(
                                self.ItemID,
                                self.ItemCount
                                )
        return DumpString
class  tagMCAutoItemCountRefresh(Structure):
    Head = tagHead()
    Count = 0    #(WORD Count)// 刷新个数
    ItemCountList = list()    #(vector<tagMCAutoItemCount> ItemCountList)// 物品信息列表
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA2
        self.Head.SubCmd = 0x06
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
        for i in range(self.Count):
            temItemCountList = tagMCAutoItemCount()
            _pos = temItemCountList.ReadData(_lpData, _pos)
            self.ItemCountList.append(temItemCountList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA2
        self.Head.SubCmd = 0x06
        self.Count = 0
        self.ItemCountList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 2
        for i in range(self.Count):
            length += self.ItemCountList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteWORD(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.ItemCountList[i].GetLength(), self.ItemCountList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                ItemCountList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagMCAutoItemCountRefresh=tagMCAutoItemCountRefresh()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCAutoItemCountRefresh.Head.Cmd,m_NAtagMCAutoItemCountRefresh.Head.SubCmd))] = m_NAtagMCAutoItemCountRefresh
#------------------------------------------------------
# A2 03 最后一次背包开格的在线时间 #tagMCOnlineTimeLastOpenPack
class  tagMCOnlineTimeLastOpenPack(Structure):
@@ -22282,6 +22390,181 @@
#------------------------------------------------------
# A3 61 新聚魂孔信息 #tagMCGatherTheSoulHoleInfo
class  tagMCGatherTheSoulHoleInfo(Structure):
    Head = tagHead()
    Count = 0    #(BYTE Count)// 孔数
    HoleSoulList = list()    #(vector<DWORD> HoleSoulList)// 孔聚魂ID列表
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x61
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.Count):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.HoleSoulList.append(value)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x61
        self.Count = 0
        self.HoleSoulList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 4 * self.Count
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteDWORD(data, self.HoleSoulList[i])
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                HoleSoulList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagMCGatherTheSoulHoleInfo=tagMCGatherTheSoulHoleInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCGatherTheSoulHoleInfo.Head.Cmd,m_NAtagMCGatherTheSoulHoleInfo.Head.SubCmd))] = m_NAtagMCGatherTheSoulHoleInfo
#------------------------------------------------------
# A3 60 新聚魂信息 #tagMCGatherTheSoulInfo
class  tagMCGatherTheSoul(Structure):
    _pack_ = 1
    _fields_ = [
                  ("SoulID", c_int),
                  ("LV", c_ushort),
                  ]
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.SoulID = 0
        self.LV = 0
        return
    def GetLength(self):
        return sizeof(tagMCGatherTheSoul)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A3 60 新聚魂信息 //tagMCGatherTheSoulInfo:
                                SoulID:%d,
                                LV:%d
                                '''\
                                %(
                                self.SoulID,
                                self.LV
                                )
        return DumpString
class  tagMCGatherTheSoulInfo(Structure):
    Head = tagHead()
    Count = 0    #(BYTE Count)// 信息个数
    SoulList = list()    #(vector<tagMCGatherTheSoul> SoulList)// 信息列表
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x60
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.Count):
            temSoulList = tagMCGatherTheSoul()
            _pos = temSoulList.ReadData(_lpData, _pos)
            self.SoulList.append(temSoulList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x60
        self.Count = 0
        self.SoulList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        for i in range(self.Count):
            length += self.SoulList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.SoulList[i].GetLength(), self.SoulList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                SoulList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagMCGatherTheSoulInfo=tagMCGatherTheSoulInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCGatherTheSoulInfo.Head.Cmd,m_NAtagMCGatherTheSoulInfo.Head.SubCmd))] = m_NAtagMCGatherTheSoulInfo
#------------------------------------------------------
# A3 1D 神兵等级信息 #tagMCGodWeaponLVList
class  tagMCGodWeaponLVInfo(Structure):
ServerPython/CoreServerGroup/GameServer/Script/ShareDefine.py
@@ -1122,7 +1122,8 @@
CDBPlayerRefresh_SuperHitHurtDefPer, # 弱化暴伤 260
CDBPlayerRefresh_Lingyu, # 灵玉 261
CDBPlayerRefresh_BossTrial, # 凭证积分 262
) = range(146, 263)
CDBPlayerRefresh_GatherSoul, # 聚魂精华 263
) = range(146, 264)
TYPE_Price_Gold_Paper_Money = 5    # 金钱类型,(先用礼券,再用金子)
TYPE_Price_Family_Contribution = 6 # 战盟贡献度(活跃度转换得来)
@@ -1154,6 +1155,7 @@
TYPE_Price_Xiantao = 41    # 仙桃
TYPE_Price_Lingyu = 42    # 灵玉
TYPE_Price_BossTrial = 43    # boss历练凭证积分
TYPE_Price_GatherSoul = 44    # 聚魂精华
TYPE_Price_PayCoin = 99    # 代币
#key可用于遍历所有货币,value仅GM相关会用到
@@ -1161,7 +1163,7 @@
                 1:"仙玉", 2:"绑玉", 3:"铜钱", 6:"战盟贡献度", 10:"战盟仓库积分", 13:"境界修行点", 14:"符印融合石", 15:"仙盟活跃令", 
                 16:"助战积分", 18:"荣誉", 19:"Boss积分", 23:"符印精华", 24:"符印碎片", 25:"寻宝积分", 26:"集市额度", 27:"丹精", 28:"魂尘", 
                 29:"聚魂碎片", 30:"核心环", 31:"功能特权令", 32:"环保值", 33:"GM令", 34:"古神币", 35:"功德点", 
                 39:"成就积分", 41:"仙桃", 42:"灵玉", 43:"凭证积分", 99:"代币"
                 39:"成就积分", 41:"仙桃", 42:"灵玉", 43:"凭证积分", 44:"聚魂精华", 99:"代币"
                 }
#以下是旧的金钱类型
@@ -1195,6 +1197,7 @@
                           TYPE_Price_Xiantao:CDBPlayerRefresh_Xiantao,
                           TYPE_Price_Lingyu:CDBPlayerRefresh_Lingyu,
                           TYPE_Price_BossTrial:CDBPlayerRefresh_BossTrial,
                           TYPE_Price_GatherSoul:CDBPlayerRefresh_GatherSoul,
                           }
# 支持负值的货币及对应0418刷新类型
@@ -1727,7 +1730,7 @@
)=range(5)
# 战斗力模块类型
Def_MFPType_Max = 33
Def_MFPType_Max = 34
ModuleFightPowerTypeList = (
Def_MFPType_Role, # 角色 0
Def_MFPType_Equip, # 装备(装备本身) 1
@@ -1761,6 +1764,7 @@
Def_MFPType_Gubao, # 古宝 29
Def_MFPType_Shentong, # 神通 30
Def_MFPType_FamilyZhenfa, # 阵法 31
Def_MFPType_GatherTheSoul, # 聚魂新 32
Def_MFPType_Other, # 其他
) = range(Def_MFPType_Max)
@@ -2058,7 +2062,9 @@
SuccType_CrossPK, # 跨服PK x次  176
SuccType_FamilyZhenfaExp, # 仙盟阵法捐献累计经验 177
SuccType_PassAdventure, #通关冒险 178
) = range(1, 179)
SuccType_GatherTheSoulColor, #聚魂激活x品质x个 179
SuccType_GatherTheSoulLV, #聚魂总等级x 180
) = range(1, 181)
# 节日红包成就类型
FeastRedPackSuccessTypeList = range(SuccType_FeastRedPack_TalkWorld, SuccType_FeastRedPack_FBSweep + 1)
@@ -2092,6 +2098,7 @@
                                  SuccType_EquipStarClass:[0], # 阶不向下适配
                                  SuccType_EquipStoneClass:[0], # 阶不向下适配
                                  SuccType_EquipWashClass:[0], # 阶不向下适配
                                  SuccType_GatherTheSoulColor:[0], # 品质不向下适配
                                  }
#传进来的条件满足配置的条件列表中的一个就行的成就类型
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/PyNetPack.ini
@@ -1633,6 +1633,18 @@
PacketSubCMD_1=0x09
PacketCallFunc_1=OnActCollectWordsExchange
;新聚魂
[PlayerGatherTheSoul]
ScriptName = Player\PlayerGatherTheSoul.py
Writer = hxp
Releaser = hxp
RegType = 0
RegisterPackCount = 1
PacketCMD_1=0xB2
PacketSubCMD_1=0x25
PacketCallFunc_1=OnGatherTheSoulOP
;聚魂
[PlayerGatherSoul]
ScriptName = Player\PlayerGatherSoul.py
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChConfig.py
@@ -510,6 +510,7 @@
Def_Effect_AddArenaBattleCount = 257    #增加竞技场挑战次数,A值为增加次数
Def_Effect_ItemGiveMoney = 264    #通用给货币道具,A值数量,B值货币类型
Def_Effect_GuajiAward = 266    #直接给挂机收益,A值分钟
Def_Effect_ItemCount = 267     #自动转化为对应物品ID的个数,不存背包
Def_Effect_GubaoPiece = 270     #古宝碎片效果ID, A值-古宝ID
#----以下未使用或代码依然存在的---
Def_Effect_ItemGiveGongXun = 1920        #使用道具给予功勋
@@ -3887,6 +3888,9 @@
#虚拟背包物品数据
Def_PDict_VPackItem = "VPackItem_%s_%s" # 虚拟背包物品数据, 参数(背包类型, 位置索引)
#物品个数
Def_PDict_ItemCount = "ItemCount_%s" # 存储不放在背包的物品个数, 参数(物品ID)
#一次性最大充值
Def_Player_RechargeOnce_Coin = "RechargeOnce_Coin"
@@ -4196,6 +4200,10 @@
# 聚魂
Def_PDict_GatherSoulHoleData = "GatherSoulHoleData_%s"  # 聚魂镶嵌数据, 参数(第几孔)
# 新聚魂
Def_PDict_GatherTheSoulHoleID = "GatherTheSoulHoleID_%s"  # 聚魂镶嵌ID, 参数(孔编号)
Def_PDict_GatherTheSoulLV = "GatherTheSoulLV_%s"  # 聚魂等级, 参数(聚魂ID)
# 副本 Def_PDictType_FB
Def_PDict_LastEnterFBPropertyID = "LastEnterFBPropertyID_%s"  # 上次进入副本的propertyID%s副本id
@@ -5032,7 +5040,8 @@
Def_CalcAttrFunc_PetStar, # 灵宠星级 58
Def_CalcAttrFunc_TitleStar, # 称号星级 59
Def_CalcAttrFunc_FamilyZhenfa, # 仙盟阵法 60
) = range(61)
Def_CalcAttrFunc_GatherTheSoul, # 聚魂新 61
) = range(62)
# 技能功能点列表  - 默认不算战力,不享受百分比加成,技能功能点暂时配置,之后优化技能属性逻辑后可去掉
CalcAttrFuncSkillList = [Def_CalcAttrFunc_HorseSkill, Def_CalcAttrFunc_PetSkill, Def_CalcAttrFunc_DogzBattleSkill]
@@ -5071,6 +5080,7 @@
                            ShareDefine.Def_MFPType_MagicWeapon4:[Def_CalcAttrFunc_MagicWeapon4],
                            ShareDefine.Def_MFPType_StoveYao:[Def_CalcAttrFunc_StoveYao],
                            ShareDefine.Def_MFPType_GatherSoul:[Def_CalcAttrFunc_GatherSoul],
                            ShareDefine.Def_MFPType_GatherTheSoul:[Def_CalcAttrFunc_GatherTheSoul],
                            ShareDefine.Def_MFPType_Coat:[Def_CalcAttrFunc_Coat],
                            ShareDefine.Def_MFPType_Dogz:[Def_CalcAttrFunc_Dogz, Def_CalcAttrFunc_DogzEquip, Def_CalcAttrFunc_DogzEquipPlus, Def_CalcAttrFunc_DogzBattleSkill],
                            ShareDefine.Def_MFPType_FamilyZhenfa:[Def_CalcAttrFunc_FamilyZhenfa],
@@ -5085,7 +5095,7 @@
               ShareDefine.Def_MFPType_PetSoul:"宠魂", ShareDefine.Def_MFPType_HorseSoul:"骑魂", ShareDefine.Def_MFPType_FaQi:"法器", ShareDefine.Def_MFPType_Dogz:"神兽",
               ShareDefine.Def_MFPType_Coat:"时装", ShareDefine.Def_MFPType_Love:"情缘", ShareDefine.Def_MFPType_Charm:"魅力", ShareDefine.Def_MFPType_LianTi:"炼体",
               ShareDefine.Def_MFPType_Enchant:"附魔", ShareDefine.Def_MFPType_Gubao:"古宝", ShareDefine.Def_MFPType_Shentong:"神通", ShareDefine.Def_MFPType_FamilyZhenfa:"阵法", 
               ShareDefine.Def_MFPType_Other:"其他",
               ShareDefine.Def_MFPType_GatherTheSoul:"聚魂新", ShareDefine.Def_MFPType_Other:"其他",
               }
FuncIndexName = {
@@ -5104,6 +5114,7 @@
                 Def_CalcAttrFunc_LoveRing:"情戒基础", Def_CalcAttrFunc_LoveRingCouple:"情戒仙侣", Def_CalcAttrFunc_Charm:"魅力", Def_CalcAttrFunc_LianTi:"炼体",
                 Def_CalcAttrFunc_Enchant:"附魔", Def_CalcAttrFunc_LingQiEnchant:"灵器附魔", Def_CalcAttrFunc_Gubao:"古宝", Def_CalcAttrFunc_Shentong:"神通",
                 Def_CalcAttrFunc_HorseStar:"坐骑星级", Def_CalcAttrFunc_PetStar:"宠物星级", Def_CalcAttrFunc_TitleStar:"称号星级", Def_CalcAttrFunc_FamilyZhenfa:"阵法",
                 Def_CalcAttrFunc_GatherTheSoul:"聚魂新",
                 }
#-------------------------------------------------------------------------------
@@ -5854,7 +5865,8 @@
Def_SkillFuncType_LianTiSkill,     #19 炼体技能
Def_SkillFuncType_ShentongSkill,     #20 神通技能
Def_SkillFuncType_ElfSkill,     #21 精怪技能
) = range(22)
Def_SkillFuncType_GatherTheSoul,     #22 聚魂技能
) = range(23)
# 受技能效果完全影响的怪, 对应 Def_BattleRelationType_CommNoBoss
Def_SkillAttack_NPCIsBoss = [ Def_NPCType_Ogre_Normal     ,  #平凡小怪 0    # c++ 定义为普通NPC视野刷新
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetPack.py
@@ -18842,6 +18842,62 @@
#------------------------------------------------------
# B2 25 新聚魂操作 #tagCMGatherTheSoulOP
class  tagCMGatherTheSoulOP(Structure):
    _pack_ = 1
    _fields_ = [
                  ("Cmd", c_ubyte),
                  ("SubCmd", c_ubyte),
                  ("OpType", c_ubyte),    # 0-激活升级; 1-穿戴替换; 2-卸下
                  ("SoulID", c_int),    # 聚魂ID;当操作升级时,如果为0代表一键升级所有可升级的
                  ]
    def __init__(self):
        self.Clear()
        self.Cmd = 0xB2
        self.SubCmd = 0x25
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.Cmd = 0xB2
        self.SubCmd = 0x25
        self.OpType = 0
        self.SoulID = 0
        return
    def GetLength(self):
        return sizeof(tagCMGatherTheSoulOP)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// B2 25 新聚魂操作 //tagCMGatherTheSoulOP:
                                Cmd:%s,
                                SubCmd:%s,
                                OpType:%d,
                                SoulID:%d
                                '''\
                                %(
                                self.Cmd,
                                self.SubCmd,
                                self.OpType,
                                self.SoulID
                                )
        return DumpString
m_NAtagCMGatherTheSoulOP=tagCMGatherTheSoulOP()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMGatherTheSoulOP.Cmd,m_NAtagCMGatherTheSoulOP.SubCmd))] = m_NAtagCMGatherTheSoulOP
#------------------------------------------------------
# B2 12 领取功能系统特权奖励 #tagCMGetFuncSysPrivilegeAward
class  tagCMGetFuncSysPrivilegeAward(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ChPyNetSendPack.py
@@ -18963,6 +18963,114 @@
#------------------------------------------------------
# A2 06 自动转化为对应物品ID个数刷新 #tagMCAutoItemCountRefresh
class  tagMCAutoItemCount(Structure):
    _pack_ = 1
    _fields_ = [
                  ("ItemID", c_int),
                  ("ItemCount", c_int),
                  ]
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.ItemID = 0
        self.ItemCount = 0
        return
    def GetLength(self):
        return sizeof(tagMCAutoItemCount)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A2 06 自动转化为对应物品ID个数刷新 //tagMCAutoItemCountRefresh:
                                ItemID:%d,
                                ItemCount:%d
                                '''\
                                %(
                                self.ItemID,
                                self.ItemCount
                                )
        return DumpString
class  tagMCAutoItemCountRefresh(Structure):
    Head = tagHead()
    Count = 0    #(WORD Count)// 刷新个数
    ItemCountList = list()    #(vector<tagMCAutoItemCount> ItemCountList)// 物品信息列表
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA2
        self.Head.SubCmd = 0x06
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadWORD(_lpData, _pos)
        for i in range(self.Count):
            temItemCountList = tagMCAutoItemCount()
            _pos = temItemCountList.ReadData(_lpData, _pos)
            self.ItemCountList.append(temItemCountList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA2
        self.Head.SubCmd = 0x06
        self.Count = 0
        self.ItemCountList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 2
        for i in range(self.Count):
            length += self.ItemCountList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteWORD(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.ItemCountList[i].GetLength(), self.ItemCountList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                ItemCountList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagMCAutoItemCountRefresh=tagMCAutoItemCountRefresh()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCAutoItemCountRefresh.Head.Cmd,m_NAtagMCAutoItemCountRefresh.Head.SubCmd))] = m_NAtagMCAutoItemCountRefresh
#------------------------------------------------------
# A2 03 最后一次背包开格的在线时间 #tagMCOnlineTimeLastOpenPack
class  tagMCOnlineTimeLastOpenPack(Structure):
@@ -22282,6 +22390,181 @@
#------------------------------------------------------
# A3 61 新聚魂孔信息 #tagMCGatherTheSoulHoleInfo
class  tagMCGatherTheSoulHoleInfo(Structure):
    Head = tagHead()
    Count = 0    #(BYTE Count)// 孔数
    HoleSoulList = list()    #(vector<DWORD> HoleSoulList)// 孔聚魂ID列表
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x61
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.Count):
            value,_pos=CommFunc.ReadDWORD(_lpData,_pos)
            self.HoleSoulList.append(value)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x61
        self.Count = 0
        self.HoleSoulList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        length += 4 * self.Count
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteDWORD(data, self.HoleSoulList[i])
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                HoleSoulList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagMCGatherTheSoulHoleInfo=tagMCGatherTheSoulHoleInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCGatherTheSoulHoleInfo.Head.Cmd,m_NAtagMCGatherTheSoulHoleInfo.Head.SubCmd))] = m_NAtagMCGatherTheSoulHoleInfo
#------------------------------------------------------
# A3 60 新聚魂信息 #tagMCGatherTheSoulInfo
class  tagMCGatherTheSoul(Structure):
    _pack_ = 1
    _fields_ = [
                  ("SoulID", c_int),
                  ("LV", c_ushort),
                  ]
    def __init__(self):
        self.Clear()
        return
    def ReadData(self, stringData, _pos=0, _len=0):
        self.Clear()
        memmove(addressof(self), stringData[_pos:], self.GetLength())
        return _pos + self.GetLength()
    def Clear(self):
        self.SoulID = 0
        self.LV = 0
        return
    def GetLength(self):
        return sizeof(tagMCGatherTheSoul)
    def GetBuffer(self):
        return string_at(addressof(self), self.GetLength())
    def OutputString(self):
        DumpString = '''// A3 60 新聚魂信息 //tagMCGatherTheSoulInfo:
                                SoulID:%d,
                                LV:%d
                                '''\
                                %(
                                self.SoulID,
                                self.LV
                                )
        return DumpString
class  tagMCGatherTheSoulInfo(Structure):
    Head = tagHead()
    Count = 0    #(BYTE Count)// 信息个数
    SoulList = list()    #(vector<tagMCGatherTheSoul> SoulList)// 信息列表
    data = None
    def __init__(self):
        self.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x60
        return
    def ReadData(self, _lpData, _pos=0, _Len=0):
        self.Clear()
        _pos = self.Head.ReadData(_lpData, _pos)
        self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
        for i in range(self.Count):
            temSoulList = tagMCGatherTheSoul()
            _pos = temSoulList.ReadData(_lpData, _pos)
            self.SoulList.append(temSoulList)
        return _pos
    def Clear(self):
        self.Head = tagHead()
        self.Head.Clear()
        self.Head.Cmd = 0xA3
        self.Head.SubCmd = 0x60
        self.Count = 0
        self.SoulList = list()
        return
    def GetLength(self):
        length = 0
        length += self.Head.GetLength()
        length += 1
        for i in range(self.Count):
            length += self.SoulList[i].GetLength()
        return length
    def GetBuffer(self):
        data = ''
        data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
        data = CommFunc.WriteBYTE(data, self.Count)
        for i in range(self.Count):
            data = CommFunc.WriteString(data, self.SoulList[i].GetLength(), self.SoulList[i].GetBuffer())
        return data
    def OutputString(self):
        DumpString = '''
                                Head:%s,
                                Count:%d,
                                SoulList:%s
                                '''\
                                %(
                                self.Head.OutputString(),
                                self.Count,
                                "..."
                                )
        return DumpString
m_NAtagMCGatherTheSoulInfo=tagMCGatherTheSoulInfo()
ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCGatherTheSoulInfo.Head.Cmd,m_NAtagMCGatherTheSoulInfo.Head.SubCmd))] = m_NAtagMCGatherTheSoulInfo
#------------------------------------------------------
# A3 1D 神兵等级信息 #tagMCGodWeaponLVList
class  tagMCGodWeaponLVInfo(Structure):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/GatherSoul.py
New file
@@ -0,0 +1,64 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.GatherSoul
#
# @todo:设置聚魂新
# @author hxp
# @date 2024-07-12
# @version 1.0
#
# 详细描述: 设置聚魂新
#
#-------------------------------------------------------------------------------
#"""Version = 2024-07-12 16:30"""
#-------------------------------------------------------------------------------
import GameWorld
import ChConfig
import IpyGameDataPY
import PlayerGatherTheSoul
import PlayerControl
#---------------------------------------------------------------------
#逻辑实现
## GM命令执行入口
#  @param curPlayer 当前玩家
#  @param paramList 参数列表 [index,1True]
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, paramList):
    if not paramList:
        GameWorld.DebugAnswer(curPlayer, "重置所有聚魂: GahterSoul 0")
        GameWorld.DebugAnswer(curPlayer, "设置聚魂等级: GahterSoul 聚魂ID 等级")
        return
    value1 = paramList[0]
    if value1 == 0:
        # 卸下所有镶嵌
        for holeNum in range(1, 1 + IpyGameDataPY.GetFuncCfg("GatherTheSoulHole", 1)):
            soulID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulHoleID % holeNum)
            if soulID:
                PlayerGatherTheSoul.OnGatherTheSoulTakeoff(curPlayer, soulID)
        # 重置所有等级
        resetSoulIDList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetGatherTheSoulCount()):
            ipyData = ipyDataMgr.GetGatherTheSoulByIndex(index)
            soulID = ipyData.GetSoulID()
            if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulLV % soulID):
                resetSoulIDList.append(soulID)
                PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GatherTheSoulLV % soulID, 0)
        PlayerGatherTheSoul.Sync_SoulInfo(curPlayer, resetSoulIDList)
        PlayerGatherTheSoul.RefreshGatherTheSoulAttr(curPlayer, True)
    else:
        soulID = value1
        soulLV = paramList[1] if len(paramList) > 1 else 1
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GatherTheSoulLV % soulID, soulLV)
        PlayerGatherTheSoul.Sync_SoulInfo(curPlayer, [soulID])
        PlayerGatherTheSoul.RefreshGatherTheSoulAttr(curPlayer, True)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GM/Commands/SetItemCount.py
New file
@@ -0,0 +1,64 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package GM.Commands.SetItemCount
#
# @todo:设置物品个数
# @author hxp
# @date 2024-07-12
# @version 1.0
#
# 详细描述: 设置物品个数
#
#-------------------------------------------------------------------------------
#"""Version = 2024-07-12 16:30"""
#-------------------------------------------------------------------------------
import GameWorld
import ItemControler
import PyGameData
import ChConfig
#---------------------------------------------------------------------
#逻辑实现
## GM命令执行入口
#  @param curPlayer 当前玩家
#  @param paramList 参数列表 [index,1True]
#  @return None
#  @remarks 函数详细说明.
def OnExec(curPlayer, paramList):
    if not paramList:
        GameWorld.DebugAnswer(curPlayer, "清空所有个数: SetItemCount 0")
        GameWorld.DebugAnswer(curPlayer, "设置指定个数: SetItemCount itemID 个数")
        return
    value1 = paramList[0]
    if value1 == 0:
        for itemID in PyGameData.AutoTransformCountItemIDList:
            if ItemControler.GetItemCountByID(curPlayer, itemID):
                ItemControler.SetItemCountByID(curPlayer, itemID, 0)
    elif value1 == "print":
        for itemID in PyGameData.AutoTransformCountItemIDList:
            itemCount = ItemControler.GetItemCountByID(curPlayer, itemID)
            if itemCount:
                GameWorld.DebugAnswer(curPlayer, "ID:%s, 个数:%s" % (itemID, itemCount))
    else:
        itemID = value1
        if len(paramList) <= 1:
            itemCount = ItemControler.GetItemCountByID(curPlayer, itemID)
            GameWorld.DebugAnswer(curPlayer, "ID:%s, 个数:%s" % (itemID, itemCount))
            return
        itemCount = paramList[1]
        itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
        if not itemData:
            GameWorld.DebugAnswer(curPlayer, "物品不存在!itemID:%s" % itemID)
            return
        effID = itemData.GetEffectByIndex(0).GetEffectID()
        #物品碎片
        if effID != ChConfig.Def_Effect_ItemCount:
            GameWorld.DebugAnswer(curPlayer, "该物品ID不可直接设置个数:%s,需配置效果ID:%s" % (itemID, ChConfig.Def_Effect_ItemCount))
            return
        ItemControler.SetItemCountByID(curPlayer, itemID, itemCount)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/IpyGameDataPY.py
@@ -1344,6 +1344,7 @@
                        ("BYTE", "TreasureType", 1),
                        ("WORD", "MinLV", 0),
                        ("dict", "GridItemInfo", 0),
                        ("dict", "GridLibInfo", 0),
                        ("list", "JobItemList", 0),
                        ("list", "GridItemRateListFree", 0),
                        ("list", "FreeGridItemRateList2", 0),
@@ -1352,6 +1353,13 @@
                        ("list", "GridItemRateList2", 0),
                        ("dict", "GridItemRateList3", 0),
                        ("BYTE", "LuckyGridNum", 0),
                        ),
                "TreasureItemLib":(
                        ("WORD", "LibID", 1),
                        ("DWORD", "ItemID", 0),
                        ("DWORD", "ItemCount", 0),
                        ("DWORD", "ItemWeight", 0),
                        ),
                "FreeGoods":(
@@ -1863,6 +1871,24 @@
                        ("BYTE", "CopyMapID", 1),
                        ("WORD", "PosX", 0),
                        ("WORD", "PosY", 0),
                        ),
                "GatherTheSoul":(
                        ("DWORD", "SoulID", 1),
                        ("DWORD", "PieceItemID", 0),
                        ("BYTE", "HoleNum", 0),
                        ("BYTE", "SoulColor", 0),
                        ("DWORD", "SoulSkillTypeID", 0),
                        ("list", "SoulSkillLVList", 0),
                        ),
                "GatherTheSoulLV":(
                        ("DWORD", "SoulID", 1),
                        ("WORD", "SoulLV", 1),
                        ("WORD", "NeedPiece", 0),
                        ("DWORD", "NeedSoulValue", 0),
                        ("list", "LVAttrTypeList", 0),
                        ("list", "LVAttrValueList", 0),
                        ),
                "GatherSoul":(
@@ -4275,14 +4301,27 @@
    def GetTreasureType(self): return self.attrTuple[0] # 寻宝类型 BYTE
    def GetMinLV(self): return self.attrTuple[1] # 最小等级 WORD
    def GetGridItemInfo(self): return self.attrTuple[2] # 格子编号对应物品信息 {"编号":[物品ID, 个数], ...} dict
    def GetJobItemList(self): return self.attrTuple[3] # 职业物品组列表 [[职业1物品, 职业2物品, ...], ...] list
    def GetGridItemRateListFree(self): return self.attrTuple[4] # 免费产出格子编号饼图 [[概率, 格子编号], ...] list
    def GetFreeGridItemRateList2(self): return self.attrTuple[5] # 免费每满x次保底产出格子编号饼图 [[概率, 格子编号], ...] list
    def GetFreeGridItemRateList3(self): return self.attrTuple[6] # 免费第x次必出产出格子编号饼图 {次数:[[概率, 格子编号], ...], ...} dict
    def GetGridItemRateList1(self): return self.attrTuple[7] # 常规产出格子编号饼图 [[概率, 格子编号], ...] list
    def GetGridItemRateList2(self): return self.attrTuple[8] # 每满x次保底产出格子编号饼图 [[概率, 格子编号], ...] list
    def GetGridItemRateList3(self): return self.attrTuple[9] # 第x次必出产出格子编号饼图 {次数:[[概率, 格子编号], ...], ...} dict
    def GetLuckyGridNum(self): return self.attrTuple[10] # 幸运加成格子编号 BYTE
    def GetGridLibInfo(self): return self.attrTuple[3] # 格子编号对应库ID {"编号":物品库ID, ...} dict
    def GetJobItemList(self): return self.attrTuple[4] # 职业物品组列表 [[职业1物品, 职业2物品, ...], ...] list
    def GetGridItemRateListFree(self): return self.attrTuple[5] # 免费产出格子编号饼图 [[概率, 格子编号], ...] list
    def GetFreeGridItemRateList2(self): return self.attrTuple[6] # 免费每满x次保底产出格子编号饼图 [[概率, 格子编号], ...] list
    def GetFreeGridItemRateList3(self): return self.attrTuple[7] # 免费第x次必出产出格子编号饼图 {次数:[[概率, 格子编号], ...], ...} dict
    def GetGridItemRateList1(self): return self.attrTuple[8] # 常规产出格子编号饼图 [[概率, 格子编号], ...] list
    def GetGridItemRateList2(self): return self.attrTuple[9] # 每满x次保底产出格子编号饼图 [[概率, 格子编号], ...] list
    def GetGridItemRateList3(self): return self.attrTuple[10] # 第x次必出产出格子编号饼图 {次数:[[概率, 格子编号], ...], ...} dict
    def GetLuckyGridNum(self): return self.attrTuple[11] # 幸运加成格子编号 BYTE
# 寻宝物品库
class IPY_TreasureItemLib():
    def __init__(self):
        self.attrTuple = None
        return
    def GetLibID(self): return self.attrTuple[0] # 库ID WORD
    def GetItemID(self): return self.attrTuple[1] # 物品ID DWORD
    def GetItemCount(self): return self.attrTuple[2] # 物品个数 DWORD
    def GetItemWeight(self): return self.attrTuple[3] # 物品权重 DWORD
# 极品白拿表
class IPY_FreeGoods():
@@ -5084,6 +5123,34 @@
    def GetCopyMapID(self): return self.attrTuple[3] # 虚拟线路ID BYTE
    def GetPosX(self): return self.attrTuple[4] # 坐标X WORD
    def GetPosY(self): return self.attrTuple[5] # 坐标Y WORD
# 聚魂新表
class IPY_GatherTheSoul():
    def __init__(self):
        self.attrTuple = None
        return
    def GetSoulID(self): return self.attrTuple[0] # 聚魂ID DWORD
    def GetPieceItemID(self): return self.attrTuple[1] # 碎片物品ID DWORD
    def GetHoleNum(self): return self.attrTuple[2] # 孔编号 BYTE
    def GetSoulColor(self): return self.attrTuple[3] # 品质 BYTE
    def GetSoulSkillTypeID(self): return self.attrTuple[4] # 技能TypeID DWORD
    def GetSoulSkillLVList(self): return self.attrTuple[5] # 技能等级所需魂等级列表 list
# 聚魂新升级表
class IPY_GatherTheSoulLV():
    def __init__(self):
        self.attrTuple = None
        return
    def GetSoulID(self): return self.attrTuple[0] # 聚魂ID DWORD
    def GetSoulLV(self): return self.attrTuple[1] # 魂等级 WORD
    def GetNeedPiece(self): return self.attrTuple[2] # 该级所需碎片 WORD
    def GetNeedSoulValue(self): return self.attrTuple[3] # 所需聚魂精华 DWORD
    def GetLVAttrTypeList(self): return self.attrTuple[4] # 累计总属性类型 list
    def GetLVAttrValueList(self): return self.attrTuple[5] # 累计总属性值 list
# 聚魂表
class IPY_GatherSoul():
@@ -6083,6 +6150,7 @@
        self.__LoadFileData("Invest", onlyCheck)
        self.__LoadFileData("XBXZ", onlyCheck)
        self.__LoadFileData("TreasureHouse", onlyCheck)
        self.__LoadFileData("TreasureItemLib", onlyCheck)
        self.__LoadFileData("FreeGoods", onlyCheck)
        self.__LoadFileData("ActFlashGiftbag", onlyCheck)
        self.__LoadFileData("FlashGiftbag", onlyCheck)
@@ -6141,6 +6209,8 @@
        self.__LoadFileData("CrossZonePK", onlyCheck)
        self.__LoadFileData("CrossPenglaiZoneMap", onlyCheck)
        self.__LoadFileData("CrossDemonLandZoneMap", onlyCheck)
        self.__LoadFileData("GatherTheSoul", onlyCheck)
        self.__LoadFileData("GatherTheSoulLV", onlyCheck)
        self.__LoadFileData("GatherSoul", onlyCheck)
        self.__LoadFileData("GatherSoulCompound", onlyCheck)
        self.__LoadFileData("GatherSoulAttr", onlyCheck)
@@ -7228,6 +7298,13 @@
        self.CheckLoadData("TreasureHouse")
        return self.ipyTreasureHouseCache[index]
    def GetTreasureItemLibCount(self):
        self.CheckLoadData("TreasureItemLib")
        return self.ipyTreasureItemLibLen
    def GetTreasureItemLibByIndex(self, index):
        self.CheckLoadData("TreasureItemLib")
        return self.ipyTreasureItemLibCache[index]
    def GetFreeGoodsCount(self):
        self.CheckLoadData("FreeGoods")
        return self.ipyFreeGoodsLen
@@ -7634,6 +7711,20 @@
        self.CheckLoadData("CrossDemonLandZoneMap")
        return self.ipyCrossDemonLandZoneMapCache[index]
    def GetGatherTheSoulCount(self):
        self.CheckLoadData("GatherTheSoul")
        return self.ipyGatherTheSoulLen
    def GetGatherTheSoulByIndex(self, index):
        self.CheckLoadData("GatherTheSoul")
        return self.ipyGatherTheSoulCache[index]
    def GetGatherTheSoulLVCount(self):
        self.CheckLoadData("GatherTheSoulLV")
        return self.ipyGatherTheSoulLVLen
    def GetGatherTheSoulLVByIndex(self, index):
        self.CheckLoadData("GatherTheSoulLV")
        return self.ipyGatherTheSoulLVCache[index]
    def GetGatherSoulCount(self):
        self.CheckLoadData("GatherSoul")
        return self.ipyGatherSoulLen
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/ItemControler.py
@@ -37,6 +37,7 @@
import IpyGameDataPY
import DataRecordPack
import PlayerGubao
import PyGameData
import PlayerArena
import EventShell
import PlayerTask
@@ -1126,6 +1127,11 @@
            tagItem.Clear()
            return True
        itemEff = tagItem.GetEffectByIndex(0)
        #物品碎片
        if itemEff.GetEffectID() == ChConfig.Def_Effect_ItemCount:
            SetItemCountByID(curPlayer, itemID, GetItemCountByID(curPlayer, itemID) + tagItemCount)
            tagItem.Clear()
            return True
        #古宝碎片
        if itemEff.GetEffectID() == ChConfig.Def_Effect_GubaoPiece:
            gubaoID = itemEff.GetEffectValue(0)
@@ -1440,6 +1446,35 @@
    vpackClear.ItemPlaceList = placeList
    vpackClear.Count = len(vpackClear.ItemPlaceList)
    NetPackCommon.SendFakePack(curPlayer, vpackClear)
    return
def Sync_AutoItemCount(curPlayer, itemIDList=None):
    ## 通知自动转化为物品个数的物品个数信息
    if not itemIDList:
        force = False
        itemIDList = PyGameData.AutoTransformCountItemIDList
    else:
        force = True # 指定ID的强制通知
    itemCountList = []
    for itemID in itemIDList:
        itemCount = GetItemCountByID(curPlayer, itemID)
        if not itemCount and not force:
            continue
        countInfo = ChPyNetSendPack.tagMCAutoItemCount()
        countInfo.Clear()
        countInfo.ItemID = itemID
        countInfo.ItemCount = itemCount
        itemCountList.append(countInfo)
    if not itemCountList:
        return
    clientPack = ChPyNetSendPack.tagMCAutoItemCountRefresh()
    clientPack.Clear()
    clientPack.ItemCountList = itemCountList
    clientPack.Count = len(clientPack.ItemCountList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
#// A3 09 转移物品到其他背包 #tagCMDropItemToOtherPack
@@ -1983,6 +2018,7 @@
#==============================================================================
def OnPlayerLogin(curPlayer):
    __CheckTransferItemPack(curPlayer)
    Sync_AutoItemCount(curPlayer)
    return
def __CheckTransferItemPack(curPlayer):
@@ -2186,6 +2222,15 @@
        
    return
def GetItemCountByID(curPlayer, itemID):
    return curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_ItemCount % itemID)
def SetItemCountByID(curPlayer, itemID, itemCount, isSync=True):
    itemCount = max(0, min(itemCount, ChConfig.Def_UpperLimit_DWord))
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_ItemCount % itemID, itemCount)
    if isSync:
        Sync_AutoItemCount(curPlayer, [itemID])
    return itemCount
## 设置物品数量
#  @param item 物品实例
#  @param cnt 数量
@@ -2235,6 +2280,8 @@
    if itemData.GetItemTypeID() in ChConfig.Def_TransformItemIDList or itemData.GetType() == ChConfig.Def_ItemType_AutoUseMoney:
        return True
    itemEff = itemData.GetEffectByIndex(0)
    if itemEff.GetEffectID() == ChConfig.Def_Effect_ItemCount:
        return True
    if itemEff.GetEffectID() == ChConfig.Def_Effect_GubaoPiece:
        gubaoID = itemEff.GetEffectValue(0)
        if gubaoID:
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Item/UseItem/ItemCommon.py
@@ -61,6 +61,7 @@
    
    PyGameData.EquipItemSkillIDList = []
    PyGameData.DailyUseCountLimitItemIDList = []
    PyGameData.AutoTransformCountItemIDList = []
    
    gameData = GameWorld.GetGameData()
    for i in range(0, gameData.GetItemCount()):
@@ -75,6 +76,8 @@
            stoneEffType = itemEff.GetEffectValue(0)
            stoneLevel = itemEff.GetEffectValue(1)
            PyGameData.g_stoneLevelIDDict[(stoneEffType, stoneLevel)] = itemID
        elif curEffID == ChConfig.Def_Effect_ItemCount:
            PyGameData.AutoTransformCountItemIDList.append(itemID)
            
        if GetIsEquip(findItemData):
            for skillIndex in xrange(findItemData.GetAddSkillCount()):
@@ -90,6 +93,9 @@
    if PyGameData.EquipItemSkillIDList:
        GameWorld.Log("装备技能ID列表: %s" % PyGameData.EquipItemSkillIDList)
        
    if PyGameData.AutoTransformCountItemIDList:
        GameWorld.Log("自动转化为物品个数的物品ID列表: %s" % PyGameData.AutoTransformCountItemIDList)
    PyGameData.InitPyItem = True
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -71,6 +71,7 @@
import PlayerEquipDecompose
import PlayerGreatMaster
import PlayerGatherSoul
import PlayerGatherTheSoul
import PlayerFairyDomain
import PlayerCrossRealmPK
import PlayerCrossChampionship
@@ -921,6 +922,7 @@
    FBHelpBattle.DoPlayerLogin(curPlayer)
    # 聚魂
    PlayerGatherSoul.PlayerLogin(curPlayer)
    PlayerGatherTheSoul.OnPlayerLogin(curPlayer)
    #缥缈仙域
    PlayerFairyDomain.OnLogin(curPlayer)
    PlayerFB.OnLogin(curPlayer)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerControl.py
@@ -60,6 +60,7 @@
import PlayerGameEvent
import EventReport
import PlayerGatherSoul
import PlayerGatherTheSoul
import PlayerSuccess
import PlayerPet
import PlayerGreatMaster
@@ -4583,6 +4584,7 @@
        PlayerEquipDecompose.RefreshEDAttr(curPlayer)
        PlayerDogz.RefreshDogzAttr(curPlayer)
        PlayerGatherSoul.RefreshGatherSoulAttr(curPlayer)
        PlayerGatherTheSoul.CalcSoulAttr(curPlayer)
        PlayerCoat.CalcClothesCoatSkinAttr(curPlayer)
        PlayerFaQi.CalcFaQiAttr(curPlayer)
        PlayerLove.CalcLoveAttr(curPlayer)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGatherTheSoul.py
New file
@@ -0,0 +1,334 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
##@package Player.PlayerGatherTheSoul
#
# @todo:聚魂新
# @author hxp
# @date 2024-07-12
# @version 1.0
#
# 详细描述: 聚魂新
#
#-------------------------------------------------------------------------------
#"""Version = 2024-07-12 16:30"""
#-------------------------------------------------------------------------------
import GameWorld
import ShareDefine
import IpyGameDataPY
import ItemControler
import ChPyNetSendPack
import PassiveBuffEffMng
import PlayerSuccess
import PlayerControl
import NetPackCommon
import ChConfig
def OnPlayerLogin(curPlayer):
    if Sync_SoulInfo(curPlayer):
        Sync_SoulHoleInfo(curPlayer)
    return
#// B2 25 新聚魂操作 #tagCMGatherTheSoulOP
#
#struct    tagCMGatherTheSoulOP
#{
#    tagHead        Head;
#    BYTE        OpType;    // 0-激活升级; 1-穿戴替换; 2-卸下
#    DWORD        SoulID;    // 聚魂ID;当操作升级时,如果为0代表一键升级所有可升级的
#};
def OnGatherTheSoulOP(index, clientData, tick):
    curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
    OpType = clientData.OpType
    soulID = clientData.SoulID
    if OpType == 0:
        OnGatherTheSoulUp(curPlayer, soulID)
    elif OpType == 1:
        OnGatherTheSoulPuton(curPlayer, soulID)
    elif OpType == 2:
        OnGatherTheSoulTakeoff(curPlayer, soulID)
    return
def OnGatherTheSoulUp(curPlayer, upSoulID):
    ## 聚魂激活升级
    # @param upSoulID: 没有指定ID时则批量处理升级
    if not upSoulID:
        soulIpyDataList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetGatherTheSoulCount()):
            soulIpyDataList.append(ipyDataMgr.GetGatherTheSoulByIndex(index))
    else:
        soulIpyDataList = [IpyGameDataPY.GetIpyGameData("GatherTheSoul", upSoulID)]
    holeSoulChange = False
    updSoulIDList = []
    playerID = curPlayer.GetPlayerID()
    for ipyData in soulIpyDataList:
        if not ipyData:
            continue
        soulID = ipyData.GetSoulID()
        soulLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulLV % soulID)
        nextLV = soulLV + 1
        nextLVIpyData = IpyGameDataPY.GetIpyGameDataNotLog("GatherTheSoulLV", soulID, nextLV)
        if not nextLVIpyData:
            if soulLV:
                GameWorld.DebugLog("聚魂已满级! soulID=%s,soulLV=%s" % (soulID, soulLV), playerID)
            continue
        pieceItemID = ipyData.GetPieceItemID()
        holeNum = ipyData.GetHoleNum()
        needPieceCount = nextLVIpyData.GetNeedPiece()
        needSoulValue = nextLVIpyData.GetNeedSoulValue()
        playerPieceCount = ItemControler.GetItemCountByID(curPlayer, pieceItemID)
        if playerPieceCount < needPieceCount:
            GameWorld.DebugLog("聚魂碎片不足,无法升级! soulID=%s,nextLV=%s,pieceItemID=%s,playerPieceCount=%s < %s"
                               % (soulID, nextLV, pieceItemID, playerPieceCount, needPieceCount), playerID)
            continue
        if needSoulValue and not PlayerControl.HaveMoney(curPlayer, ShareDefine.TYPE_Price_GatherSoul, needSoulValue, False):
            GameWorld.DebugLog("聚魂精华不足,无法升级! soulID=%s,nextLV=%s,needSoulValue=%s" % (soulID, nextLV, needSoulValue), playerID)
            continue
        GameWorld.DebugLog("聚魂升级: soulID=%s,nextLV=%s,pieceItemID=%s" % (soulID, nextLV, pieceItemID), playerID)
        ItemControler.SetItemCountByID(curPlayer, pieceItemID, playerPieceCount - needPieceCount)
        if needSoulValue:
            PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_GatherSoul, needSoulValue, "GatherTheSoulUp", {"soulID":soulID, "nextLV":nextLV})
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GatherTheSoulLV % soulID, nextLV)
        # 激活额外处理
        if nextLV == 1:
            pass
        updSoulIDList.append(soulID)
        if soulID == curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulHoleID % holeNum):
            holeSoulChange = True
    if not updSoulIDList:
        GameWorld.DebugLog("没有可升级的聚魂!", playerID)
        return
    # 成就
    colorCountDict = {}
    totalSoulLV = 0
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetGatherTheSoulCount()):
        ipyData = ipyDataMgr.GetGatherTheSoulByIndex(index)
        soulID = ipyData.GetSoulID()
        soulLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulLV % soulID)
        if not soulLV:
            continue
        totalSoulLV += soulLV
        soulColor = ipyData.GetSoulColor()
        colorCountDict[soulColor] = colorCountDict.get(soulColor, 0) + 1
    for soulColor, soulCount in colorCountDict.items():
        PlayerSuccess.UptateSuccessProgress(curPlayer, ShareDefine.SuccType_GatherTheSoulColor, soulCount, [soulColor])
    PlayerSuccess.UptateSuccessProgress(curPlayer, ShareDefine.SuccType_GatherTheSoulLV, totalSoulLV)
    Sync_SoulInfo(curPlayer, updSoulIDList)
    RefreshGatherTheSoulAttr(curPlayer, holeSoulChange)
    return
def OnGatherTheSoulPuton(curPlayer, soulID):
    ## 聚魂穿戴替换
    playerID = curPlayer.GetPlayerID()
    soulLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulLV % soulID)
    if not soulLV:
        GameWorld.DebugLog("未激活无法穿戴! soulID=%s" % soulID, playerID)
        return
    ipyData = IpyGameDataPY.GetIpyGameData("GatherTheSoul", soulID)
    if not ipyData:
        return
    holeNum = ipyData.GetHoleNum()
    holeSoulID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulHoleID % holeNum)
    GameWorld.DebugLog("聚魂穿戴替换! soulID=%s,holeNum=%s,holeSoulID=%s" % (soulID, holeNum, holeSoulID), playerID)
    if holeSoulID == soulID:
        return
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GatherTheSoulHoleID % holeNum, soulID)
    Sync_SoulHoleInfo(curPlayer)
    RefreshGatherTheSoulAttr(curPlayer, True)
    return
def OnGatherTheSoulTakeoff(curPlayer, soulID):
    ## 聚魂卸下
    playerID = curPlayer.GetPlayerID()
    ipyData = IpyGameDataPY.GetIpyGameData("GatherTheSoul", soulID)
    if not ipyData:
        return
    holeNum = ipyData.GetHoleNum()
    holeSoulID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulHoleID % holeNum)
    if holeSoulID != soulID:
        GameWorld.DebugLog("该孔没有穿戴该聚魂,无法卸下! soulID=%s,holeNum=%s,holeSoulID=%s" % (soulID, holeNum, holeSoulID), playerID)
        return
    GameWorld.DebugLog("聚魂卸下! soulID=%s,holeNum=%s" % (soulID, holeNum), playerID)
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_GatherTheSoulHoleID % holeNum, 0)
    Sync_SoulHoleInfo(curPlayer)
    RefreshGatherTheSoulAttr(curPlayer, True)
    return
def GetHoleSoulColorCount(curPlayer, soulColor, isDownward):
    ## 获取镶嵌聚魂品质个数
    colorCount = 0
    for holeNum in range(1, 1 + IpyGameDataPY.GetFuncCfg("GatherTheSoulHole", 1)):
        soulID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulHoleID % holeNum)
        if not soulID:
            continue
        ipyData = IpyGameDataPY.GetIpyGameData("GatherTheSoul", soulID)
        if not ipyData:
            continue
        # 向下兼容品质
        if isDownward:
            if ipyData.GetSoulColor() < soulColor:
                continue
        else:
            if ipyData.GetSoulColor() != soulColor:
                continue
        colorCount += 1
    return colorCount
def RefreshGatherTheSoulSkill(curPlayer):
    ## 刷新穿戴的聚魂技能信息
    playerID = curPlayer.GetPlayerID()
    soulSkillLVDict = {}
    for holeNum in range(1, 1 + IpyGameDataPY.GetFuncCfg("GatherTheSoulHole", 1)):
        soulID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulHoleID % holeNum)
        if not soulID:
            continue
        soulLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulLV % soulID)
        ipyData = IpyGameDataPY.GetIpyGameData("GatherTheSoul", soulID)
        if not ipyData:
            continue
        skillTypeID = ipyData.GetSoulSkillTypeID()
        if not skillTypeID:
            continue
        skillLVList = ipyData.GetSoulSkillLVList()
        for skillLV, needSoulLV in enumerate(skillLVList, 1):
            if soulLV >= needSoulLV:
                soulSkillLVDict[skillTypeID] = skillLV
            else:
                break
    #GameWorld.DebugLog("刷新聚魂技能: %s" % soulSkillLVDict, playerID)
    skillChange = False
    playerCtl = PlayerControl.PlayerControl(curPlayer)
    skillManager = curPlayer.GetSkillManager()
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetGatherTheSoulCount()):
        ipyData = ipyDataMgr.GetGatherTheSoulByIndex(index)
        holeNum = ipyData.GetHoleNum()
        skillTypeID = ipyData.GetSoulSkillTypeID()
        if not skillTypeID:
            continue
        delSkill = None
        if skillTypeID in soulSkillLVDict:
            curSkill = skillManager.FindSkillBySkillTypeID(skillTypeID)
            if curSkill:
                if curSkill.GetSkillLV() != soulSkillLVDict[skillTypeID]:
                    delSkill = curSkill
                else:
                    # 技能相同不用处理
                    continue
        else:
            delSkill = skillManager.FindSkillBySkillTypeID(skillTypeID)
        # 先删后加
        if delSkill:
            skillChange = True
            skillID = delSkill.GetSkillID()
            GameWorld.DebugLog("删除聚魂技能: holeNum=%s,skillID=%s" % (holeNum, skillID), playerID)
            skillManager.DeleteSkillBySkillID(skillID)
            playerCtl.RefreshSkillFightPowerByDel(skillID, False)
        if skillTypeID in soulSkillLVDict:
            skillLV = soulSkillLVDict[skillTypeID]
            skillData = GameWorld.GetGameData().FindSkillByType(skillTypeID, skillLV)
            if not skillData:
                continue
            skillChange = True
            skillID = skillData.GetSkillID()
            GameWorld.DebugLog("更新聚魂技能: holeNum=%s,skillID=%s" % (holeNum, skillID), playerID)
            skillManager.LearnSkillByID(skillID)
            playerCtl.RefreshSkillFightPowerEx(skillID, 0, False)
    if skillChange:
        PassiveBuffEffMng.GetPassiveEffManager().RegistPassiveEff(curPlayer)
    return
def RefreshGatherTheSoulAttr(curPlayer, refreshSkill=False):
    if refreshSkill:
        RefreshGatherTheSoulSkill(curPlayer)
    CalcSoulAttr(curPlayer)
    PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
    return
def CalcSoulAttr(curPlayer):
    allAttrListSoul = [{} for _ in range(4)] # 激活的都算属性
    ipyDataMgr = IpyGameDataPY.IPY_Data()
    for index in range(ipyDataMgr.GetGatherTheSoulCount()):
        ipyData = ipyDataMgr.GetGatherTheSoulByIndex(index)
        soulID = ipyData.GetSoulID()
        soulLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulLV % soulID)
        if not soulLV:
            continue
        lvIpyData = IpyGameDataPY.GetIpyGameData("GatherTheSoulLV", soulID, soulLV)
        if not lvIpyData:
            continue
        LVAttrTypeList = lvIpyData.GetLVAttrTypeList()
        LVAttrValueList = lvIpyData.GetLVAttrValueList()
        for i, attrID in enumerate(LVAttrTypeList):
            attrValue = LVAttrValueList[i]
            PlayerControl.CalcAttrDict_Type(attrID, attrValue, allAttrListSoul)
    #GameWorld.DebugLog("聚魂新属性: %s" % allAttrListSoul)
    PlayerControl.SetCalcAttrListValue(curPlayer, ChConfig.Def_CalcAttrFunc_GatherTheSoul, allAttrListSoul)
    return
def Sync_SoulInfo(curPlayer, soulIDList=None):
    if not soulIDList:
        isForce = False
        soulIDList = []
        ipyDataMgr = IpyGameDataPY.IPY_Data()
        for index in range(ipyDataMgr.GetGatherTheSoulCount()):
            ipyData = ipyDataMgr.GetGatherTheSoulByIndex(index)
            soulIDList.append(ipyData.GetSoulID())
    else:
        isForce = True
    soulList = []
    for soulID in soulIDList:
        soulLV = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulLV % soulID)
        if not soulLV and not isForce:
            continue
        soulInfo = ChPyNetSendPack.tagMCGatherTheSoul()
        soulInfo.SoulID = soulID
        soulInfo.LV = soulLV
        soulList.append(soulInfo)
    if not soulList:
        return
    clientPack = ChPyNetSendPack.tagMCGatherTheSoulInfo()
    clientPack.SoulList = soulList
    clientPack.Count = len(clientPack.SoulList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return True
def Sync_SoulHoleInfo(curPlayer):
    holeSoulList = []
    for holeNum in range(1, 1 + IpyGameDataPY.GetFuncCfg("GatherTheSoulHole", 1)):
        soulID = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_GatherTheSoulHoleID % holeNum)
        holeSoulList.append(soulID)
    clientPack = ChPyNetSendPack.tagMCGatherTheSoulHoleInfo()
    clientPack.HoleSoulList = holeSoulList
    clientPack.Count = len(clientPack.HoleSoulList)
    NetPackCommon.SendFakePack(curPlayer, clientPack)
    return
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerGubao.py
@@ -30,6 +30,7 @@
import ChConfig
import ItemControler
import PlayerDienstgrad
import PlayerGatherTheSoul
import PlayerCoat
GubaoEffType_FamilyWar = 48 # 参与仙盟联赛每X次+XXX属性    x次
@@ -657,6 +658,15 @@
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
            
    #53    镶嵌x品质聚魂每x个+xx属性    x品质    x个
    elif effType == 53:
        soulColor = effCond
        colorCount = PlayerGatherTheSoul.GetHoleSoulColorCount(curPlayer, soulColor, True)
        addAttrValue = int(colorCount / effCond2 * effAttrValue)
        #GameWorld.DebugLog("    effID=%s,effType=%s,soulColor=%s,colorCount=%s,effCond2=%s,attrID=%s,addAttrValue=%s" % (effID, effType, soulColor, colorCount, effCond2, attrID, addAttrValue))
        if attrID > 0 and addAttrValue > 0:
            effAttrInfo[attrID] = effAttrInfo.get(attrID, 0) + addAttrValue
    return
def __addStarEffFuncAttr(ipyData, effAttrInfo, funcAttrInfo, effAttrValue):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerTreasure.py
@@ -36,6 +36,13 @@
import random
import time
TreasureTypeList = (
TreasureType_Jipin, # 极品寻宝 1
TreasureType_Rune, # 符印寻宝 2
TreasureType_Jueshi, # 绝世君宝 3
TreasureType_GatherTheSoul, # 聚魂猎魔 4
) = range(1, 1 + 4)
def DoTreasureOpen(curPlayer):
    ## 寻宝开启
    
@@ -93,6 +100,8 @@
    packType = ShareDefine.rptTreasure
    #if treasureType == 2:
    #    packType = ShareDefine.rptRune
    if treasureType in [TreasureType_GatherTheSoul]:
        packType = IPY_GameWorld.rptItem
        
    if not ItemCommon.CheckPackHasSpace(curPlayer, packType, True):
        GameWorld.DebugLog("对应寻宝背包没有空格子!packType=%s" % packType, playerID)
@@ -274,37 +283,57 @@
    isBind = 0 # 暂时默认不绑定
    job = curPlayer.GetJob()
    gridItemInfoDict = ipyData.GetGridItemInfo() # 格子对应物品信息 {"格子编号":[物品ID, 数量], ...}
    gridLibInfoDict = ipyData.GetGridLibInfo() # 格子对应物品信息 {"格子编号":[物品ID, 数量], ...}
    jobItemList = ipyData.GetJobItemList()
    treasureResult = []
    randItemIDDict = IpyGameDataPY.GetFuncEvalCfg("TreasureSet", 2)
    
    for gridNum in getGridResult:
        gridNum = str(gridNum)
        if gridNum not in gridItemInfoDict:
        if gridNum in gridItemInfoDict:
            itemID, itemCount = gridItemInfoDict[gridNum]
            itemID = GetJobItem(job, itemID, jobItemList)
            if not itemID:
                GameWorld.ErrLog("寻宝格子物品ID异常!treasureType=%s,gridNum=%s" % (treasureType, gridNum), playerID)
                return
            # 随机产出物品
            if itemID in randItemIDDict:
                canRandItemList = []
                randItemIDList = randItemIDDict[itemID]
                for randItemID in randItemIDList:
                    itemData = GameWorld.GetGameData().GetItemByTypeID(randItemID)
                    if itemData.GetType() == ChConfig.Def_ItemType_Rune and not PlayerRune.GetIsOpenByRuneID(curPlayer, randItemID):
                        GameWorld.DebugLog("未解锁的符印不产出!itemID=%s,randItemID=%s" % (itemID, randItemID), playerID)
                        continue
                    canRandItemList.append(randItemID)
                if not canRandItemList:
                    GameWorld.ErrLog("寻宝随机格子没有可随机的物品!treasureType=%s,treasureIndex=%s,gridNum=%s,itemID=%s"
                                     % (treasureType, treasureIndex, gridNum, itemID), playerID)
                    return
                itemID = random.choice(canRandItemList)
        # 根据物品库来随机
        elif gridNum in gridLibInfoDict:
            libID = gridLibInfoDict[gridNum]
            libItemList = IpyGameDataPY.GetIpyGameDataList("TreasureItemLib", libID)
            if not libItemList:
                return
            itemWeightList = []
            for libItem in libItemList:
                itemWeight, itemID, itemCount = libItem.GetItemWeight(), libItem.GetItemID(), libItem.GetItemCount()
                itemData = GameWorld.GetGameData().GetItemByTypeID(itemID)
                if not itemData:
                    continue
                itemWeightList.append([itemWeight, [itemID, itemCount]])
            if not itemWeightList:
                GameWorld.ErrLog("寻宝随机格子没有可随机的物品!treasureType=%s,treasureIndex=%s,gridNum=%s,libID=%s"
                                 % (treasureType, treasureIndex, gridNum, libID), playerID)
                return
            itemID, itemCount = GameWorld.GetResultByWeightList(itemWeightList)
        else:
            GameWorld.ErrLog("寻宝格子不存在!treasureType=%s,gridNum=%s" % (treasureType, gridNum), playerID)
            return
        itemID, itemCount = gridItemInfoDict[gridNum]
        itemID = GetJobItem(job, itemID, jobItemList)
        if not itemID:
            GameWorld.ErrLog("寻宝格子物品ID异常!treasureType=%s,gridNum=%s" % (treasureType, gridNum), playerID)
            return
        
        # 随机产出物品
        if itemID in randItemIDDict:
            canRandItemList = []
            randItemIDList = randItemIDDict[itemID]
            for randItemID in randItemIDList:
                itemData = GameWorld.GetGameData().GetItemByTypeID(randItemID)
                if itemData.GetType() == ChConfig.Def_ItemType_Rune and not PlayerRune.GetIsOpenByRuneID(curPlayer, randItemID):
                    GameWorld.DebugLog("未解锁的符印不产出!itemID=%s,randItemID=%s" % (itemID, randItemID), playerID)
                    continue
                canRandItemList.append(randItemID)
            if not canRandItemList:
                GameWorld.ErrLog("寻宝随机格子没有可随机的物品!treasureType=%s,treasureIndex=%s,gridNum=%s,itemID=%s"
                                 % (treasureType, treasureIndex, gridNum, itemID), playerID)
                return
            itemID = random.choice(canRandItemList)
        treasureResult.append([gridNum, itemID, itemCount, isBind])
        
    # 扣消耗
@@ -329,19 +358,21 @@
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TreasureLuck % (treasureType), updLuck)
    PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_TreasureScore, addScore)
    
    if treasureType == 2:
    if treasureType == TreasureType_Rune:
        PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_RuneTreasure, treasureCount)
        PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_RuneTreasure, treasureCount)
        PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_RuneTreasure, treasureCount)
    elif treasureType == 1:
    elif treasureType == TreasureType_Jipin:
        PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_Treasure, treasureCount)
        PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_Treasure, treasureCount)
        PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_Treasure, treasureCount)
    elif treasureType == 3:
    elif treasureType == TreasureType_Jueshi:
        PlayerFairyCeremony.AddFCPartyActionCnt(curPlayer, ChConfig.Def_PPAct_JSTreasure, treasureCount)
        PlayerFeastTravel.AddFeastTravelTaskValue(curPlayer, ChConfig.Def_FeastTravel_JSTreasure, treasureCount)
        PlayerBossReborn.AddBossRebornActionCnt(curPlayer, ChConfig.Def_BRAct_JSTreasure, treasureCount)
    elif treasureType == TreasureType_GatherTheSoul:
        pass
    # 给物品
    mailItemList = []
    itemControl = ItemControler.PlayerItemControler(curPlayer)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyGameData.py
@@ -29,6 +29,7 @@
InitPyItem = False # 是否加载过物品表所需要的Py数据, 每张地图只在启动时执行一次
DailyUseCountLimitItemIDList = [] # 每日有使用个数限制的物品ID列表
EquipItemSkillIDList = [] # 装备技能ID列表
AutoTransformCountItemIDList = [] # 自动转化为对应物品个数的物品ID列表
g_stoneLevelIDDict = {} # 宝石类型等级对应物品ID {(stoneEffType, stoneLevel):itemID, ...}
g_refreshAttrBillboardFunc = [] # 刷属性后需要触发的同步排行榜函数列表
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1122,7 +1122,8 @@
CDBPlayerRefresh_SuperHitHurtDefPer, # 弱化暴伤 260
CDBPlayerRefresh_Lingyu, # 灵玉 261
CDBPlayerRefresh_BossTrial, # 凭证积分 262
) = range(146, 263)
CDBPlayerRefresh_GatherSoul, # 聚魂精华 263
) = range(146, 264)
TYPE_Price_Gold_Paper_Money = 5    # 金钱类型,(先用礼券,再用金子)
TYPE_Price_Family_Contribution = 6 # 战盟贡献度(活跃度转换得来)
@@ -1154,6 +1155,7 @@
TYPE_Price_Xiantao = 41    # 仙桃
TYPE_Price_Lingyu = 42    # 灵玉
TYPE_Price_BossTrial = 43    # boss历练凭证积分
TYPE_Price_GatherSoul = 44    # 聚魂精华
TYPE_Price_PayCoin = 99    # 代币
#key可用于遍历所有货币,value仅GM相关会用到
@@ -1161,7 +1163,7 @@
                 1:"仙玉", 2:"绑玉", 3:"铜钱", 6:"战盟贡献度", 10:"战盟仓库积分", 13:"境界修行点", 14:"符印融合石", 15:"仙盟活跃令", 
                 16:"助战积分", 18:"荣誉", 19:"Boss积分", 23:"符印精华", 24:"符印碎片", 25:"寻宝积分", 26:"集市额度", 27:"丹精", 28:"魂尘", 
                 29:"聚魂碎片", 30:"核心环", 31:"功能特权令", 32:"环保值", 33:"GM令", 34:"古神币", 35:"功德点", 
                 39:"成就积分", 41:"仙桃", 42:"灵玉", 43:"凭证积分", 99:"代币"
                 39:"成就积分", 41:"仙桃", 42:"灵玉", 43:"凭证积分", 44:"聚魂精华", 99:"代币"
                 }
#以下是旧的金钱类型
@@ -1195,6 +1197,7 @@
                           TYPE_Price_Xiantao:CDBPlayerRefresh_Xiantao,
                           TYPE_Price_Lingyu:CDBPlayerRefresh_Lingyu,
                           TYPE_Price_BossTrial:CDBPlayerRefresh_BossTrial,
                           TYPE_Price_GatherSoul:CDBPlayerRefresh_GatherSoul,
                           }
# 支持负值的货币及对应0418刷新类型
@@ -1727,7 +1730,7 @@
)=range(5)
# 战斗力模块类型
Def_MFPType_Max = 33
Def_MFPType_Max = 34
ModuleFightPowerTypeList = (
Def_MFPType_Role, # 角色 0
Def_MFPType_Equip, # 装备(装备本身) 1
@@ -1761,6 +1764,7 @@
Def_MFPType_Gubao, # 古宝 29
Def_MFPType_Shentong, # 神通 30
Def_MFPType_FamilyZhenfa, # 阵法 31
Def_MFPType_GatherTheSoul, # 聚魂新 32
Def_MFPType_Other, # 其他
) = range(Def_MFPType_Max)
@@ -2058,7 +2062,9 @@
SuccType_CrossPK, # 跨服PK x次  176
SuccType_FamilyZhenfaExp, # 仙盟阵法捐献累计经验 177
SuccType_PassAdventure, #通关冒险 178
) = range(1, 179)
SuccType_GatherTheSoulColor, #聚魂激活x品质x个 179
SuccType_GatherTheSoulLV, #聚魂总等级x 180
) = range(1, 181)
# 节日红包成就类型
FeastRedPackSuccessTypeList = range(SuccType_FeastRedPack_TalkWorld, SuccType_FeastRedPack_FBSweep + 1)
@@ -2092,6 +2098,7 @@
                                  SuccType_EquipStarClass:[0], # 阶不向下适配
                                  SuccType_EquipStoneClass:[0], # 阶不向下适配
                                  SuccType_EquipWashClass:[0], # 阶不向下适配
                                  SuccType_GatherTheSoulColor:[0], # 品质不向下适配
                                  }
#传进来的条件满足配置的条件列表中的一个就行的成就类型