From 7154c21796f9accc3260c358f046a601a2c24ca4 Mon Sep 17 00:00:00 2001
From: hxp <ale99527@vip.qq.com>
Date: 星期二, 17 三月 2026 11:31:13 +0800
Subject: [PATCH] 263 【主界面】头像系统(内政-幻境阁系统)-服务端(形象、头像 增加关联武将皮肤解锁方式4;)

---
 ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/OpenServerActivity.py |  285 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 276 insertions(+), 9 deletions(-)

diff --git a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/OpenServerActivity.py b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/OpenServerActivity.py
index 253c496..e1d9b9f 100644
--- a/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/OpenServerActivity.py
+++ b/ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/OpenServerActivity.py
@@ -16,43 +16,209 @@
 #-------------------------------------------------------------------------------
 
 import DBDataMgr
+import PlayerMail
 import ShareDefine
+import PlayerPreset
+import PlayerOnline
 import GameFuncComm
+import IPY_GameWorld
 import IpyGameDataPY
-import PlayerBillboard
 import PlayerTreasure
+import PlayerBillboard
+import ChPyNetSendPack
 import PlayerControl
+import NetPackCommon
+import ItemControler
+import PlayerBeauty
+import ItemCommon
 import GameWorld
+import ChConfig
+import math
 
 # 开服冲榜类型对应功能ID
 OSAFuncIDDict = {
                  ShareDefine.Def_BT_OSA_MainLevel:ShareDefine.GameFuncID_OSA_MainLevel,
                  ShareDefine.Def_BT_OSA_HeroCall:ShareDefine.GameFuncID_OSA_HeroCall,
+                 ShareDefine.Def_BT_OSA_HeroTrain:ShareDefine.GameFuncID_OSA_HeroTrain,
+                 ShareDefine.Def_BT_OSA_BeautyTrain:ShareDefine.GameFuncID_OSA_BeautyTrain,
+                 ShareDefine.Def_BT_OSA_MinggeTrain:ShareDefine.GameFuncID_OSA_MinggeTrain,
                  }
 
-def DoOSA_MainLevel(curPlayer):
+def DoOSA_MainLevelOpen(curPlayer): UpdOSA_MainLevelBillboard(curPlayer)
+def UpdOSA_MainLevelBillboard(curPlayer, lvID=0):
     if GetOSAState(curPlayer, ShareDefine.Def_BT_OSA_MainLevel) != 1:
         return
-    lvID = PlayerControl.GetPassMainLevelID(curPlayer)
-    GameWorld.DebugLog("开服关卡榜开启更新榜单: lvID=%s" % lvID, curPlayer.GetPlayerID())
+    if not lvID:
+        lvID = PlayerControl.GetPassMainLevelID(curPlayer)
     PlayerBillboard.UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_OSA_MainLevel, lvID)
     return
 
-def DoOSA_HeroCall(curPlayer):
+def DoOSA_HeroCallOpen(curPlayer): UpdOSA_HeroCallBillboard(curPlayer)
+def UpdOSA_HeroCallBillboard(curPlayer, callCnt=0):
     if GetOSAState(curPlayer, ShareDefine.Def_BT_OSA_HeroCall) != 1:
         return
-    callCnt = PlayerTreasure.GetHeroCallCnt(curPlayer)
-    GameWorld.DebugLog("开服招募榜开启更新榜单: callCnt=%s" % callCnt, curPlayer.GetPlayerID())
+    if not callCnt:
+        callCnt = PlayerTreasure.GetHeroCallCnt(curPlayer)
     PlayerBillboard.UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_OSA_HeroCall, callCnt)
     return
 
-def GetOSAState(curPlayer, osaType):
+def DoOSA_HeroTrainOpen(curPlayer): UpdOSA_HeroTrainBillboard(curPlayer)
+def UpdOSA_HeroTrainBillboard(curPlayer):
+    if GetOSAState(curPlayer, ShareDefine.Def_BT_OSA_HeroTrain) != 1:
+        return
+    
+    osaType = ShareDefine.Def_BT_OSA_HeroTrain
+    mainBatPresetID = PlayerPreset.GetBatPresetID(curPlayer, ShareDefine.BatPreset_Main)
+    heroPresetID = PlayerPreset.GetFuncPresetID(curPlayer, mainBatPresetID, ShareDefine.FuncPreset_Hero)
+    olPlayer = PlayerOnline.GetOnlineMgr().GetOnlinePlayer(curPlayer)
+    heroPreset = olPlayer.GetHeroPreset(heroPresetID)
+    effCardDict = heroPreset.GetEffectiveCardDict()
+    
+    cardScore = 0
+    curPack = curPlayer.GetItemManager().GetPack(ShareDefine.rptHero)
+    for cardInfo in effCardDict.values():
+        index = cardInfo[1]
+        if index < 0 or index >= curPack.GetCount():
+            continue
+        heroItem = curPack.GetAt(index)
+        if not heroItem or heroItem.IsEmpty():
+            continue
+        cardScore += __calcHeroCardTrainScore(heroItem)
+        
+    washItemID = IpyGameDataPY.GetFuncCfg("HeroWash", 1)
+    trainItemScoreDict = IpyGameDataPY.GetFuncEvalCfg("OSABillboardTrain", 1, {})
+    osaValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_OSAValue % osaType)
+    washScore = osaValue * trainItemScoreDict.get(str(washItemID), 0)
+    
+    trainScore = cardScore + washScore
+    
+    # 上榜积分: 只取历史最高分
+    osaBillValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_OSABillValue % osaType)
+    GameWorld.DebugLog("武将冲榜: trainScore=%s(%s+%s),osaValue=%s,osaBillValue=%s,mainBatPresetID=%s,heroPresetID=%s" 
+                       % (trainScore, cardScore, washScore, osaValue, osaBillValue, mainBatPresetID, heroPresetID))
+    if trainScore <= osaBillValue:
+        # 可能降低积分,降低时不更新榜单
+        GameWorld.DebugLog("    武将冲榜积分未提升不更新榜单! trainScore=%s <= %s" % (trainScore, osaBillValue))
+        return
+    trainScore = PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_OSABillValue % osaType, trainScore)
+    PlayerBillboard.UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_OSA_HeroTrain, trainScore)
+    return
+
+def __calcHeroCardTrainScore(heroItem):
+    heroID = heroItem.GetItemTypeID()
+    heroIpyData = IpyGameDataPY.GetIpyGameData("Hero", heroID)
+    if not heroIpyData:
+        return 0
+    quality = heroIpyData.GetQuality()
+    qualityIpyData = IpyGameDataPY.GetIpyGameData("HeroQuality", quality)
+    if not qualityIpyData:
+        return 0
+    
+    heroLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroLV)
+    star = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroStar)
+    breakLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroBreakLV)
+    awakeLV = heroItem.GetUserAttr(ShareDefine.Def_IudetHeroAwakeLV)
+    
+    # 培养积分,开服武将冲榜会用到
+    # 武将冲榜增加积分 按消耗材料算 {"消耗物品ID":每个物品积分, },积分支持小数,物品ID支持配武将经验石、突破石、觉醒石、洗练石等
+    trainItemScoreDict = IpyGameDataPY.GetFuncEvalCfg("OSABillboardTrain", 1, {})
+    qualityStarScoreDict = IpyGameDataPY.GetFuncEvalCfg("OSABillboardTrain", 2, {})
+    trainItemCntDict = {}
+    #GameWorld.DebugLog("武将物品培养积分: heroID=%s,quality=%s,heroLV=%s,star=%s,breakLV=%s,awakeLV=%s" % (heroID, quality, heroLV, star, breakLV, awakeLV))
+    # 等级
+    ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition("HeroQualityLV", {"Quality":quality}, True)
+    if ipyDataList:
+        for ipyData in ipyDataList:
+            if heroLV <= ipyData.GetHeroLV():
+                break
+            costItemInfo = ipyData.GetUPCostItem()
+            if not costItemInfo:
+                continue
+            costItemID, costItemCount = costItemInfo
+            trainItemCntDict[costItemID] = trainItemCntDict.get(costItemID, 0) + costItemCount
+        #GameWorld.DebugLog("    quality=%s,heroLV=%s,%s" % (quality, heroLV, trainItemCntDict))
+        
+    # 突破
+    ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition("HeroQualityBreak", {"Quality":quality}, True)
+    if ipyDataList:
+        for ipyData in ipyDataList:
+            if breakLV <= ipyData.GetBreakLV():
+                break
+            costItemList = ipyData.GetUPCostItemList()
+            if not costItemList:
+                continue
+            for costItemInfo in costItemList:
+                costItemID, costItemCount = costItemInfo[:2]
+                trainItemCntDict[costItemID] = trainItemCntDict.get(costItemID, 0) + costItemCount
+        #GameWorld.DebugLog("    quality=%s,breakLV=%s,%s" % (quality, breakLV, trainItemCntDict))
+        
+    # 觉醒 
+    ipyDataList = IpyGameDataPY.GetIpyGameDataByCondition("HeroQualityAwake", {"Quality":quality}, True, False)
+    if ipyDataList:
+        for ipyData in ipyDataList:
+            if awakeLV <= ipyData.GetAwakeLV():
+                break
+            costItemInfo = ipyData.GetUPCostItem()
+            if not costItemInfo:
+                continue
+            costItemID, costItemCount = costItemInfo
+            trainItemCntDict[costItemID] = trainItemCntDict.get(costItemID, 0) + costItemCount
+        #GameWorld.DebugLog("    quality=%s,awakeLV=%s,%s" % (quality, awakeLV, trainItemCntDict))
+                
+    trainScore = 0
+    for costItemID, itemCnt in trainItemCntDict.items():
+        addScore = trainItemScoreDict.get(str(costItemID), 0) * itemCnt
+        trainScore += addScore
+        
+    # 星级
+    starScore = star * qualityStarScoreDict.get(str(quality), 0)
+    trainScore += starScore
+    #GameWorld.DebugLog("    trainScore=%s,starScore=%s" % (trainScore, starScore))
+    
+    # 洗炼为通用的,在外层最后直接加
+    return int(trainScore)
+
+def DoOSA_BeautyTrainOpen(curPlayer): UpdOSA_BeautyTrainBillboard(curPlayer)
+def UpdOSA_BeautyTrainBillboard(curPlayer):
+    if GetOSAState(curPlayer, ShareDefine.Def_BT_OSA_BeautyTrain) != 1:
+        return
+    # 红颜好感总等级
+    beautyTotalLV = PlayerBeauty.GetBeautyLVTotal(curPlayer)
+    PlayerBillboard.UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_OSA_BeautyTrain, beautyTotalLV)
+    return
+
+def DoOSA_MinggeTrainOpen(curPlayer): UpdOSA_MinggeTrainBillboard(curPlayer)
+def UpdOSA_MinggeTrainBillboard(curPlayer):
+    if GetOSAState(curPlayer, ShareDefine.Def_BT_OSA_MinggeTrain) != 1:
+        return
+    osaType = ShareDefine.Def_BT_OSA_MinggeTrain
+    trainScoreList = IpyGameDataPY.GetFuncEvalCfg("OSABillboardTrain", 4)
+    if not trainScoreList or len(trainScoreList) != 2:
+        return
+    tuiyanScore, lingyingScore = trainScoreList
+    osaValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_OSAValue % osaType)
+    curLingying = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_MGLingying)
+    trainScore = int(osaValue * tuiyanScore + curLingying * lingyingScore)
+    GameWorld.DebugLog("命格冲榜: trainScore=%s,osaValue=%s,curLingying=%s" % (trainScore, osaValue, curLingying))
+    PlayerBillboard.UpdatePlayerBillboard(curPlayer, ShareDefine.Def_BT_OSA_MinggeTrain, trainScore)
+    return
+
+def AddOSAValue(curPlayer, osaType, addValue):
+    ## 增加开服冲榜活动值,功能未开启时也要加
+    if GetOSAState(curPlayer, osaType, checkFuncOpen=False) != 1:
+        return
+    osaValue = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_OSAValue % osaType)
+    updOSAValue = PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_OSAValue % osaType, osaValue + addValue)
+    GameWorld.DebugLog("更新开服冲榜活动值: osaType=%s,addValue=%s,updOSAValue=%s" % (osaType, addValue, updOSAValue))
+    return
+
+def GetOSAState(curPlayer, osaType, checkFuncOpen=True):
     ## 玩家是否在开服冲榜活动中
     # @return: 0-未开启;1-活动中;2-结束显示期;3-结束关闭期
     funcID = OSAFuncIDDict.get(osaType)
     if not funcID:
         return 0
-    if not GameFuncComm.GetFuncCanUse(curPlayer, funcID):
+    if checkFuncOpen and not GameFuncComm.GetFuncCanUse(curPlayer, funcID):
         #GameWorld.DebugLog("开服冲榜功能未开启! osaType=%s,funcID=%s" % (osaType, funcID))
         return 0
     osaDayDict = IpyGameDataPY.GetFuncEvalCfg("OSABillboard", 1, {})
@@ -95,5 +261,106 @@
         elif osaType == ShareDefine.Def_BT_OSA_HeroCall:
             billboardAwardDict = IpyGameDataPY.GetFuncEvalCfg("OSABillboard", 3, {})
             PlayerBillboard.DoGiveBillboardAwardByMail(osaType, "OSAHeroCall", billboardAwardDict, "OSAHeroCall")
+        elif osaType == ShareDefine.Def_BT_OSA_HeroTrain:
+            billboardAwardDict = IpyGameDataPY.GetFuncEvalCfg("OSABillboardTrain", 3, {})
+            PlayerBillboard.DoGiveBillboardAwardByMail(osaType, "OSAHeroTrain", billboardAwardDict, "OSAHeroTrain")
+        elif osaType == ShareDefine.Def_BT_OSA_BeautyTrain:
+            billboardAwardDict = IpyGameDataPY.GetFuncEvalCfg("OSABillboard", 4, {})
+            PlayerBillboard.DoGiveBillboardAwardByMail(osaType, "OSABeautyTrain", billboardAwardDict, "OSABeautyTrain")
+        elif osaType == ShareDefine.Def_BT_OSA_MinggeTrain:
+            billboardAwardDict = IpyGameDataPY.GetFuncEvalCfg("OSABillboardTrain", 5, {})
+            PlayerBillboard.DoGiveBillboardAwardByMail(osaType, "OSAMinggeTrain", billboardAwardDict, "OSAMinggeTrain")
             
     return
+
+
+## ------------------------------------------- 开服庆典 ---------------------------------------------
+
+def OnPlayerLogin(curPlayer):
+    if GetOSACelebrationState(curPlayer) == 3:
+        __autoChangeCelebrationPoint(curPlayer)
+        return
+    SyncOSACelebrationInfo(curPlayer)
+    return
+
+def PlayerOnDay(curPlayer):
+    if GetOSACelebrationState(curPlayer) == 3:
+        __autoChangeCelebrationPoint(curPlayer)
+        return
+    return
+
+def __autoChangeCelebrationPoint(curPlayer):
+    ## 活动结束后自动转换庆典积分
+    unUsePoint = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_OSAPoint)
+    if unUsePoint <= 0:
+        return
+    moneyItemID = ItemCommon.GetMoneyItemID(IPY_GameWorld.TYPE_Price_Gold_Money)
+    if not moneyItemID:
+        return
+    playerID = curPlayer.GetPlayerID()
+    oneNeedPoint = IpyGameDataPY.GetFuncCfg("OSACelebration", 3) # 多少积分=1元宝
+    changeMoney = int(math.ceil(unUsePoint / float(oneNeedPoint)))
+    itemList = [[moneyItemID, changeMoney]]
+    GameWorld.DebugLog("自动转化未使用的庆典积分: unUsePoint=%s,oneNeedPoint=%s,changeMoney=%s,itemList=%s" 
+                       % (unUsePoint, oneNeedPoint, changeMoney, itemList), playerID)
+    if PlayerControl.PayMoney(curPlayer, ShareDefine.TYPE_Price_OSAPoint, unUsePoint, "SysClear"):
+        PlayerMail.SendMailByKey("OSACelebrationPoint", playerID, itemList)
+    return
+
+def GetOSACelebrationState(curPlayer):
+    ## 玩家是否在开服庆典活动中
+    # @return: 0-未开启;1-活动中;2-结束显示期;3-结束关闭期
+    #开服庆典,后端不限制功能是否开启
+    #funcID = ShareDefine.GameFuncID_OSA_Celebration
+    #if not GameFuncComm.GetFuncCanUse(curPlayer, funcID):
+    #    #GameWorld.DebugLog("开服庆典功能未开启! funcID=%s" % (funcID))
+    #    return 0
+    endDay = IpyGameDataPY.GetFuncCfg("OSACelebration", 1)
+    serverDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_ServerDay) + 1
+    if serverDay <= endDay:
+        #GameWorld.DebugLog("开服庆典活动中! serverDay=%s,endDay=%s" % (serverDay, endDay))
+        return 1
+    if serverDay == (endDay + 1):
+        #GameWorld.DebugLog("开服庆典结算中! serverDay=%s,endDay=%s" % (serverDay, endDay))
+        return 2
+    #GameWorld.DebugLog("开服庆典已结束! serverDay=%s,endDay=%s" % (serverDay, endDay))
+    return 3
+
+def AddOSACelebrationPoint(curPlayer, addPoint):
+    ## 庆典累计积分
+    curPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_OSACelebrationPoint)
+    updPoint = PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_OSACelebrationPoint, curPoint + addPoint)
+    GameWorld.DebugLog("增加开服庆典积分: addPoint=%s,curPoint=%s,updPoint=%s" % (addPoint, curPoint, updPoint))
+    SyncOSACelebrationInfo(curPlayer)
+    return
+
+def GetOSACelebrationPointAward(curPlayer, awardPoint):
+    ## 领取开服庆典累计积分阶段奖励
+    curPoint = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_OSACelebrationPoint)
+    if curPoint < awardPoint:
+        GameWorld.DebugLog("累计开服庆典积分不足: curPoint=%s < %s" % (curPoint, awardPoint))
+        return
+    awardDict = IpyGameDataPY.GetFuncEvalCfg("OSACelebration", 2, {}) # {"累计积分":[[物品ID,个数], ...], ...}
+    pointKeyList = [int(p) for p in awardDict.keys()]
+    pointKeyList.sort()
+    if awardPoint not in pointKeyList:
+        GameWorld.DebugLog("不存在该开服庆典积分阶段奖励: awardPoint=%s not in %s" % (awardPoint, pointKeyList))
+        return
+    index = pointKeyList.index(awardPoint)
+    awardState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_OSACelebrationAward)
+    if awardState&pow(2, index):
+        GameWorld.DebugLog("该开服庆典积分阶段奖励已领取: awardPoint=%s,index=%s,awardState=%s" % (awardPoint, index, awardState))
+        return
+    updState = PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_OSACelebrationAward, awardState|pow(2, index))
+    itemList = awardDict[str(awardPoint)]
+    GameWorld.DebugLog("领取开服庆典积分阶段奖励: awardPoint=%s,index=%s,awardState=%s,updState=%s,itemList=%s" % (awardPoint, index, awardState, updState, itemList))
+    ItemControler.GivePlayerItemOrMail(curPlayer, itemList, event=["OSACelebration", False, {}])
+    SyncOSACelebrationInfo(curPlayer)
+    return
+
+def SyncOSACelebrationInfo(curPlayer):
+    clientPack = ChPyNetSendPack.tagSCOSACelebrationInfo()
+    clientPack.PointTotal = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_OSACelebrationPoint)
+    clientPack.PointAward = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_OSACelebrationAward)
+    NetPackCommon.SendFakePack(curPlayer, clientPack)
+    return

--
Gitblit v1.8.0