hxp
2025-06-30 388823edfe6308cba6f76ca6dc4f20022c5cb2be
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossFamilyGCZ.py
@@ -28,6 +28,7 @@
import NetPackCommon
import PyDataManager
import PlayerControl
import GameXiangong
import PyGameData
import ChConfig
import ChPlayer
@@ -185,7 +186,7 @@
        self.fighterIDList.pop(0)
        if not self.fighterIDList:
            return 0
        nextGuardID = self.fighterIDList
        nextGuardID = self.fighterIDList[0]
        if self.IsGuardNPC(nextGuardID):
            self.guardNPC.hp = self.guardNPC.hpMax
            GameWorld.DebugLog("    切换下一个NPC守卫: %s, %s/%s" % (nextGuardID, self.guardNPC.hp, self.guardNPC.hpMax))
@@ -248,9 +249,8 @@
        return True
    
    def SetPlayerInCity(self, playerID, serverGroupID):
        if playerID in self.inCityPlayerIDList:
            return
        self.inCityPlayerIDList.append(playerID)
        if playerID not in self.inCityPlayerIDList:
            self.inCityPlayerIDList.append(playerID)
        Sync_FamilyGCZBatCityInfo(self.zoneID, self.batType, self.groupNum, self.cityID, toPlayerServerDict={playerID:serverGroupID})
        return
    
@@ -352,26 +352,29 @@
        updCampLV = campLV
        
        # 满级了也不限制捐献,让玩家可以继续消耗多余的道具
        campIpyData = IpyGameDataPY.GetIpyGameData("CrossActFamilyGCZCampLV", campLV)
        if campIpyData and campIpyData.GetLVUPNeedExp():
            lvupNeedExp = campIpyData.GetLVUPNeedExp()
            if updCampExp >= lvupNeedExp and IpyGameDataPY.GetIpyGameDataNotLog("CrossActFamilyGCZCampLV", campLV + 1):
                updCampExp -= lvupNeedExp
                updCampLV = campLV + 1
        campIpyData = IpyGameDataPY.GetIpyGameData("CrossActFamilyGCZCampLV", updCampLV)
        lvupNeedExp = campIpyData.GetLVUPNeedExp() if campIpyData else 0
        nextIpyData = IpyGameDataPY.GetIpyGameDataNotLog("CrossActFamilyGCZCampLV", updCampLV + 1)
        GameWorld.DebugLog("增加大本营经验: familyID=%s,playerID=%s,addCampExp=%s,campLV-Exp=%s-%s,updLV-Exp=%s-%s,lvupNeedExp=%s"
                           % (self.familyID, playerID, addCampExp, campLV, campExp, updCampLV, updCampExp, lvupNeedExp))
        while lvupNeedExp > 0 and updCampExp >= lvupNeedExp and nextIpyData:
            updCampLV += 1
            updCampExp -= lvupNeedExp
            campIpyData = IpyGameDataPY.GetIpyGameData("CrossActFamilyGCZCampLV", updCampLV)
            lvupNeedExp = campIpyData.GetLVUPNeedExp() if campIpyData else 0
            nextIpyData = IpyGameDataPY.GetIpyGameDataNotLog("CrossActFamilyGCZCampLV", updCampLV + 1)
            GameWorld.DebugLog("    大本营升级: updCampLV=%s,updCampExp=%s,lvupNeedExp=%s" % (updCampLV, updCampExp, lvupNeedExp))
        self.campLV = updCampLV
        self.campExp = updCampExp
        self.memAddCampExpInfo[playerID] = self.memAddCampExpInfo.get(playerID, 0) + addCampExp
        GameWorld.DebugLog("增加大本营经验: familyID=%s,playerID=%s,addCampExp=%s,campLV-Exp=%s-%s,updLV-Exp=%s-%s,playerAddExpTotal=%s"
                           % (self.familyID, playerID, addCampExp, campLV, campExp, updCampLV, updCampExp, self.memAddCampExpInfo[playerID]))
        
        # 升级了
        defMemIDList = [] # 加经验默认不通知防守成员属性
        isLVUP = False
        if campLV != updCampLV:
            isLVUP = True
            GameWorld.DebugLog("大本营升级了! familyID=%s,campLV=%s to %s" % (self.familyID, campLV, updCampLV))
            GameWorld.DebugLog("大本营等级变更! familyID=%s,campLV=%s to %s" % (self.familyID, campLV, updCampLV))
            if self.RefreshFamilyAttr(False):
                defMemIDList = None # 升级后成功刷成员属性后,额外附带所有防守成员信息,战斗阶段属性是锁定的
                
@@ -493,9 +496,8 @@
        return newCity
    
    def SetPlayerInScene(self, playerID, serverGroupID):
        if playerID in self.inBatScenePlayerIDList:
            return
        self.inBatScenePlayerIDList.append(playerID)
        if playerID not in self.inBatScenePlayerIDList:
            self.inBatScenePlayerIDList.append(playerID)
        Sync_FamilyGCZBatSceneInfo(self.zoneID, self.batType, self.groupNum, toPlayerServerDict={playerID:serverGroupID})
        return
    
@@ -1289,7 +1291,9 @@
    groupValue1 = joinFamily.zoneID
    groupValue2 = GetRoundHurtGroupID(joinFamily.batType, joinFamily.groupNum)
    memHurtTotal = sum(joinFamily.cityWall.fighterHurtDict.values())
    cityRemainHPPer = joinFamily.cityWall.hp / float(joinFamily.cityWall.hpMax)
    cityRemainHPPer = 0
    if joinFamily.cityWall.hpMax:
        cityRemainHPPer = joinFamily.cityWall.hp / float(joinFamily.cityWall.hpMax)
    familyRoundHurt = eval(IpyGameDataPY.GetFuncCompileCfg("FamilyGCZCity", 3))
    GameWorld.DebugLog("计算仙盟轮次伤害榜值: familyID=%s,familyRoundHurt=%s,memHurtTotal=%s,cityRemainHPPer=%s, %s/%s" 
                       % (dataID, familyRoundHurt, memHurtTotal, cityRemainHPPer, joinFamily.cityWall.hp, joinFamily.cityWall.hpMax))
@@ -1473,7 +1477,8 @@
    guessRankMax = IpyGameDataPY.GetFuncCfg("FamilyGCZGuess", 2)
    billboardMgr = PyDataManager.GetCrossBillboardManager()
    scoreBillObj = billboardMgr.GetCrossBillboard(ShareDefine.Def_CBT_FamilyGCZScore, zoneID)
    for index in range(guessRankMax):
    guessCnt = min(scoreBillObj.GetCount(), guessRankMax)
    for index in range(guessCnt):
        billData = scoreBillObj.At(index)
        familyID = billData.ID
        if familyID not in zone.familyGuessDict:
@@ -1582,14 +1587,14 @@
    gczMgr = GetFamilyGCZMgr()
    joinMember = gczMgr.GetJoinMember(playerID)
    if not joinMember:
        GameWorld.ErrLog("非仙盟攻城战参赛成员!", playerID)
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "非仙盟攻城战参赛成员:%s" % playerID)
        return
    zoneID = joinMember.zoneID
    familyID = joinMember.familyID
    zone = gczMgr.GetActZone(zoneID)
    joinFamily = zone.GetZoneJoinFamily(familyID)
    if not joinFamily:
        GameWorld.ErrLog("非仙盟攻城战参赛仙盟! familyID=%s" % familyID, playerID)
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "非仙盟攻城战参赛仙盟:%s" % familyID)
        return
    batType, groupNum = joinMember.batType, joinMember.groupNum
    batGroup = zone.GetBatGroup(batType, groupNum)
@@ -1606,7 +1611,7 @@
    curRound, roundState = GetRoundState(state)
    
    value0 = msgList[0]
    if value0 in ["a", "h", "k"]:
    if value0 in ["a", "h", "k", "s"]:
        if not curRound or (curRound and roundState != FamilyGCZRoundState_Fight):
            GameWorld.DebugAnswerCross(playerID, serverGroupID, "非战斗阶段!state=%s" % (state))
            return
@@ -1632,7 +1637,7 @@
            GameWorld.DebugAnswerCross(playerID, serverGroupID, "目标城池不存在:%s" % (tagCityID))
            return
        atkOK = __DoGMAtkCity(playerID, serverGroupID, zoneID, curRound, batType, groupNum, curCityID, tagCityID, atkCntTotal, 0, atkMemberID)
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "atkOK:%s,remainHP:%s" % (atkOK, tagCity.hp))
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "atkOK:%s,remainHP:%s" % (atkOK != None, tagCity.hp))
        
    #攻击城池: FamilyGCZ a 城池ID 剩余血量 [攻击方人数 仙盟ID]
    elif value0 == "h":
@@ -1660,8 +1665,68 @@
            return
        hurtValueTotal = tagCity.hp - remainHP
        atkOK = __DoGMAtkCity(playerID, serverGroupID, zoneID, curRound, batType, groupNum, curCityID, tagCityID, 0, hurtValueTotal, atkMemberID)
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "atkOK:%s,remainHP:%s" % (atkOK, tagCity.hp))
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "atkOK:%s,remainHP:%s" % (atkOK != None, tagCity.hp))
    #技能攻击: FamilyGCZ s 技能类型 [城池ID 攻击方ID]
    elif value0 == "s":
        atkType = msgList[1] if len(msgList) > 1 else 0
        tagCityID = msgList[2] if len(msgList) > 2 else 0
        atkMemberID = msgList[3] if len(msgList) > 3 else playerID
        hurtMulti = msgList[4] if len(msgList) > 4 else 2
        hurtFamilyCnt = msgList[5] if len(msgList) > 5 else 10
        atkJoinMember = zone.GetZoneJoinMember(atkMemberID)
        if not atkJoinMember:
            GameWorld.DebugAnswerCross(playerID, serverGroupID, "攻击方不存在:%s" % atkMemberID)
            return
        atkFamilyID = atkJoinMember.familyID
        atkJoinFamily = zone.GetZoneJoinFamily(atkFamilyID)
        curCityID = atkJoinFamily.cityWall.cityID
        batFightPower = atkJoinMember.fightPower
        hurtValueTotal = batFightPower * hurtMulti # 总伤害
        canAtkedCityList = []
        # 技能单体
        if atkType == AtkType_SkillSingle:
            tagCity = batGroup.GetCityWall(tagCityID)
            if not tagCity:
                GameWorld.DebugAnswerCross(playerID, serverGroupID, "目标城池不存在:%s" % (tagCityID))
                return
            if atkFamilyID == tagCity.familyID:
                GameWorld.DebugAnswerCross(playerID, serverGroupID, "不能攻击自己仙盟")
                return
            canAtkedCityList.append(tagCity)
        # 技能群体
        elif atkType == AtkType_SkillArea:
            for tagCityID in batGroup.cityWallDict.keys(): # 遍历同组城池
                if tagCityID == curCityID:
                    #不打自己
                    continue
                tagCity = batGroup.GetCityWall(tagCityID)
                if not tagCity or tagCity.IsBroken():
                    # 已被摧毁的
                    continue
                canAtkedCityList.append(tagCity)
            if len(canAtkedCityList) > hurtFamilyCnt:
                random.shuffle(canAtkedCityList)
                canAtkedCityList = canAtkedCityList[:hurtFamilyCnt]
        else:
            GameWorld.DebugAnswerCross(playerID, serverGroupID, "非技能攻击类型(%s)" % atkType)
            return
        oneHurtTotal = hurtValueTotal / len(canAtkedCityList) # 所有可攻击的目标仙盟平摊伤害
        hurtDict = {}
        killCntTotal = 0
        for tagCity in canAtkedCityList:
            tagCityID = tagCity.cityID
            atkOK = __DoGMAtkCity(playerID, serverGroupID, zoneID, curRound, batType, groupNum, curCityID, tagCityID, 0, oneHurtTotal, atkMemberID, atkType)
            if atkOK != None:
                hurtDict[tagCityID] = oneHurtTotal
                killCntTotal += atkOK
        Sync_FamilyGCZBatSceneInfo(zoneID, batType, groupNum, atkMemberID, atkType, hurtDict, killCntTotal)
    #击毁城池: FamilyGCZ k [城池ID 攻击方仙盟ID]    
    elif value0 == "k":
        tagCityID = msgList[1] if len(msgList) > 1 else 0
@@ -1691,7 +1756,7 @@
        tagCityID = tagCity.cityID
        hurtValueTotal = tagCity.hp
        atkOK = __DoGMAtkCity(playerID, serverGroupID, zoneID, curRound, batType, groupNum, curCityID, tagCityID, 0, hurtValueTotal)
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "killOK:%s,目标:%s,攻击方:%s" % (atkOK, tagCityID, curCityID))
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "killOK:%s,目标:%s,攻击方:%s" % (atkOK != None, tagCityID, curCityID))
        
    #输出城池: FamilyGCZ p [战场类型 分组编号]
    elif value0 == "p":
@@ -1752,7 +1817,7 @@
        GameWorld.DebugAnswerCross(playerID, serverGroupID, "    HP: %s/%s %s" % (city.hp, city.hpMax, broken))
    return
def __DoGMAtkCity(gmPlayerID, serverGroupID, zoneID, curRound, batType, groupNum, curCityID, tagCityID, atkCntTotal=0, hurtValueTotal=0, atkMemberID=0):
def __DoGMAtkCity(gmPlayerID, serverGroupID, zoneID, curRound, batType, groupNum, curCityID, tagCityID, atkCntTotal=0, hurtValueTotal=0, atkMemberID=0, atkType=AtkType_Normal):
    '''GM攻击城池
    @param curCityID: 攻击方城池ID
    @param tagCityID: 防守方城池ID
@@ -1888,11 +1953,13 @@
        GameWorld.DebugLog("    攻击方仙盟城池已被摧毁,不再累加本轮仙盟伤害榜值! familyID=%s" % curFamilyID)
        
    if not CheckXiuluoCity(zoneID, curRound, batType, groupNum, gmPlayerID):
        Sync_FamilyGCZBatSceneInfo(zoneID, batType, groupNum)
        if atkType == AtkType_Normal: # 技能攻击外层统一通知
            Sync_FamilyGCZBatSceneInfo(zoneID, batType, groupNum)
    Sync_FamilyGCZBatCityInfo(zoneID, batType, groupNum, tagCityID)
    if tagFamilyID:
        Sync_FamilyGCZCampInfo(zoneID, tagFamilyID, defMemIDList=atkedGuardIDList)
    return True
    return killCnt
def __clientServer_Atk(serverGroupID, msgData):
    ## 攻击
@@ -2260,8 +2327,10 @@
        scenePlayer = ChPyNetSendPack.tagGCFamilyGCZBatScenePlayer()
        scenePlayer.PlayerID = playerID
        scenePlayer.Name = joinMember.playerName
        scenePlayer.Job = joinMember.job
        scenePlayer.Face = joinMember.face
        scenePlayer.FacePic = joinMember.facePic
        scenePlayer.FamilyID = joinMember.familyID
        clientPack.PlayerInfoList.append(scenePlayer)
    clientPack.PlayerCnt = len(clientPack.PlayerInfoList)
    
@@ -2297,15 +2366,23 @@
    if not onlinePlayerIDDict:
        return
    
    guradID = cityWall.GetCurGuardID()
    if cityWall.IsGuardNPC(guradID):
        curGuard = cityWall.guardNPC
    else:
        curGuard = zone.GetZoneJoinMember(guradID)
    guardHP, guradHPMax = 0, 0
    if curGuard:
        guardHP, guradHPMax = curGuard.hp, curGuard.hpMax
    clientPack = ChPyNetSendPack.tagGCFamilyGCZBatCityInfo()
    clientPack.CityID = cityID
    clientPack.CityLV = cityWall.cityLV
    clientPack.FamilyID = cityWall.familyID
    clientPack.GuardID = cityWall.GetCurGuardID()
    clientPack.HP = cityWall.hp % ChConfig.Def_PerPointValue
    clientPack.HPEx = cityWall.hp / ChConfig.Def_PerPointValue
    clientPack.HPMax = cityWall.hpMax % ChConfig.Def_PerPointValue
    clientPack.HPMaxEx = cityWall.hpMax / ChConfig.Def_PerPointValue
    clientPack.GuardID = guradID
    clientPack.HP = guardHP % ChConfig.Def_PerPointValue
    clientPack.HPEx = guardHP / ChConfig.Def_PerPointValue
    clientPack.HPMax = guradHPMax % ChConfig.Def_PerPointValue
    clientPack.HPMaxEx = guradHPMax / ChConfig.Def_PerPointValue
    clientPack.AtkPlayerID = atkPlayerID
    clientPack.AtkRet = atkRet
    clientPack.KillCnt = killCnt
@@ -2488,6 +2565,12 @@
        __clientServer_GetAward_Ret(zoneID, playerID, serverGroupID, actID, awardType, playerAwardID, awardItemList)
        return
    
    # 点赞奖励
    if awardType == AwwardType_Like:
        awardItemList = IpyGameDataPY.GetFuncEvalCfg("FamilyGCZGuess", 4)
        __clientServer_GetAward_Ret(zoneID, playerID, serverGroupID, actID, awardType, 0, awardItemList)
        return
    gczMgr = GetFamilyGCZMgr()
    zone = gczMgr.GetActZone(zoneID)
    joinMember = zone.GetZoneJoinMember(playerID)
@@ -2515,12 +2598,6 @@
        billboardType = ShareDefine.Def_CBT_FamilyGCZScore
        awardTemplateID = ipyDataInfo.get("FamilyTemplateID", 0)
        
    # 点赞奖励
    elif awardType == AwwardType_Like:
        awardItemList = IpyGameDataPY.GetFuncEvalCfg("FamilyGCZGuess", 4)
        __clientServer_GetAward_Ret(zoneID, playerID, serverGroupID, actID, awardType, 0, awardItemList)
        return
    else:
        return
    
@@ -2543,6 +2620,9 @@
        return
    
    __clientServer_GetAward_Ret(zoneID, playerID, serverGroupID, actID, awardType, billRank, playerAwardItemList)
    serverIDList = actInfo.get(ShareDefine.ActKey_ServerIDRangeList, [])
    GameXiangong.AddXiangongPlayerByItem(playerAwardItemList, playerID, serverIDList, billRank)
    return
def __clientServer_GetAward_Ret(zoneID, playerID, serverGroupID, actID, awardType, awardValue, awardItemList):
@@ -2614,6 +2694,9 @@
                paramList = [billRank]
                PlayerCompensation.SendMailByKey("FamilyGCZAwardHurt", [playerID], playerAwardItemList, paramList, crossMail=True)
                
                serverIDList = ipyData.GetServerIDRangeList()
                GameXiangong.AddXiangongPlayerByItem(playerAwardItemList, playerID, serverIDList, billRank)
        # 仙盟积分名次奖励
        if not joinMember.awardState&pow(2, AwwardType_FamilyScore):
            joinMember.awardState = joinMember.awardState | pow(2, AwwardType_FamilyScore)
@@ -2626,6 +2709,9 @@
            if playerAwardItemList:
                paramList = [billRank]
                PlayerCompensation.SendMailByKey("FamilyGCZAwardScore", [playerID], playerAwardItemList, paramList, crossMail=True)
                serverIDList = ipyData.GetServerIDRangeList()
                GameXiangong.AddXiangongPlayerByItem(playerAwardItemList, playerID, serverIDList, billRank)
                
        # 竞猜奖励
        if not joinMember.awardState&pow(2, AwwardType_Guess):
@@ -2915,6 +3001,7 @@
        defMem.PlayerID = playerID
        defMem.Name = joinMember.playerName
        defMem.FamilyLV = joinMember.fmLV
        defMem.Job = joinMember.job
        defMem.Face = joinMember.face
        defMem.FacePic = joinMember.facePic
        defMem.FightPower = joinMember.fightPower % ChConfig.Def_PerPointValue
@@ -3034,7 +3121,7 @@
    for playerID, pActInfo in playerActInfo.items():
        if not PlayerControl.GetDBPlayerAccIDByID(playerID):
            # 非本服玩家
            return
            continue
        curPlayer = playerManager.FindPlayerByID(playerID)
        if curPlayer:
            MapServer_QueryPlayerResult(curPlayer, "FamilyGCZPlayerActInfo", pActInfo)