ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorldLogic/FBProcess/FBHelpBattle.py
@@ -34,17 +34,31 @@
import IPY_GameWorld
import PlayerActivity
import time
def DoPlayerOnDay(curPlayer):
    checkInInfo = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_HelpBattleCheckInCount)
    checkInCount = checkInInfo / 10 # 累计登记
    todayIsCheckIn = checkInInfo % 10 # 今天是否已登记
    if todayIsCheckIn:
        checkInInfo = (checkInCount + 1) * 10 + 0
        checkInInfo = checkInCount * 10 + 0
        PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HelpBattleCheckInCount, checkInInfo)
        SyncCheckInState(curPlayer, 0, False)
    
    # 重置每日已获得仙缘币
    PlayerControl.SetTodayXianyuanCoin(curPlayer, 0)
    ondaySetXianyuanCoin = 0
    ondayLoginSetXianyuanCoin = curPlayer.GetDictByKey(ChConfig.Def_PDict_TodayXianyuanCoinOnLogin)
    if ondayLoginSetXianyuanCoin:
        # 这里做时间比较,预防玩家登录后就没有再切换地图,再次在该地图过天会导致设置值错误问题
        loginAddCoinTime = curPlayer.GetDictByKey(ChConfig.Def_PDict_LoginAddTodayXianyuanCoinTime)
        if GameWorld.CheckTimeIsSameServerDayEx(loginAddCoinTime):
            ondaySetXianyuanCoin = ondayLoginSetXianyuanCoin
            GameWorld.DebugLog("玩家过天时,登录增加仙缘币有值,仍然是同一天,仙缘币重置为登录时增加的仙缘币!ondayLoginSetXianyuanCoin=%s" % ondayLoginSetXianyuanCoin)
        else:
            GameWorld.DebugLog("玩家过天时,登录增加仙缘币有值,但是不是同一天了,仙缘币重置为0!")
    PlayerControl.SetTodayXianyuanCoin(curPlayer, ondaySetXianyuanCoin)
    GameWorld.DebugLog("玩家过天设置今日已获得仙缘币: ondaySetXianyuanCoin=%s,ondayLoginSetXianyuanCoin=%s"
                       % (ondaySetXianyuanCoin, ondayLoginSetXianyuanCoin))
    return
def DoPlayerLogin(curPlayer):
@@ -74,13 +88,17 @@
        __OnHelpBattleCheckInResult(curPlayer, msgList, tick)
        
    # 刷新
    if cmd == "Refresh":
    elif cmd == "Refresh":
        __OnHelpBattleRefreshResult(curPlayer, msgList, tick)
        
    # 助战记录
    if cmd == "HelpRecord":
    elif cmd == "HelpRecord":
        __OnHelpBattleRecord(curPlayer, msgList, tick)
        
    # 扫荡召唤
    elif cmd == "SweepCall":
        __OnHelpBattleSweepCallResult(curPlayer, msgList, tick)
    return
#// B1 05 助战登记 #tagCMHelpBattleCheckIn
@@ -152,6 +170,9 @@
    for helpPlayerID, helpPlayerInfoDict in helpBattlePlayerDict.items():
        objID = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_HelpBattleFBObjID % helpPlayerID)
        if objID:
            if helpPlayerID == calledPlayerID:
                GameWorld.DebugLog("该助战机器人ID已经召唤过,不允许重复召唤!calledPlayerID=%s" % calledPlayerID)
                return
            calledCount += 1
        # 统计免费的未召唤的
        elif not helpPlayerInfoDict.get("NeedGoldCall", 0):
@@ -221,8 +242,10 @@
        if not helpBattleNPC:
            continue
        objID = helpBattleNPC.GetID()
        helpBattleNPC.SetIsNeedProcess(True)
        GameWorld.Log("召唤助战成功: calledPlayerID=%s,objID=%s,fightPower=%s" % (calledPlayerID, objID, fightPower), playerID)
        gameFB.SetGameFBDict(ChConfig.Def_FB_HelpBattleFBObjID % calledPlayerID, objID)
        helpBattleNPC.SetDict(ChConfig.Def_NPC_Dict_AtkDelayTick, calledCount * 1000) # 按转换顺序每个延长1秒攻击,防止动作一致
        calledCount += 1
        # 设置助战属性
        npcControl = NPCCommon.NPCControl(helpBattleNPC)
@@ -292,8 +315,8 @@
    costMoneyList = []
    calledPlayerIDDict = {} # 已经召唤的玩家ID字典 {playerID:[是否付费召唤, 职业], ...}
    
    refreshCount = gameFB.GetPlayerGameFBDictByKey(playerID, ChConfig.FBPD_HelpBattleRefreshCount)
    if isClientRefresh:
        refreshCount = gameFB.GetPlayerGameFBDictByKey(playerID, ChConfig.FBPD_HelpBattleRefreshCount)
        freeRefreshCount = IpyGameDataPY.GetFuncCfg("HelpBattleRefresh", 1)
        goldRefreshCount = IpyGameDataPY.GetFuncCfg("HelpBattleRefresh", 2)
        if refreshCount >= (freeRefreshCount + goldRefreshCount):
@@ -320,7 +343,8 @@
            
    # 非客户端刷新的视为重新开始,重置刷新次数 
    else:
        gameFB.SetPlayerGameFBDict(playerID, ChConfig.FBPD_HelpBattleRefreshCount, 0)
        if not refreshCount:
            gameFB.SetPlayerGameFBDict(playerID, ChConfig.FBPD_HelpBattleRefreshCount, 0)
        gameFB.SetGameFBDict(ChConfig.FBPD_HelpBattleFBFightPower, ipyData.GetFightPowerMin())
        gameFB.SetGameFBDict(ChConfig.FBPD_HelpBattleFBBaseHurt, ipyData.GetRobotBaseHurt())
        GameWorld.DebugLog("设置副本战力=%s,保底伤害=%s" % (ipyData.GetFightPowerMin(), ipyData.GetRobotBaseHurt()))
@@ -374,9 +398,84 @@
    NetPackCommon.SendFakePack(curPlayer, helpPlayerListPack)
    return
def SendGameServer_SweepCallHelpBattlePlayer(curPlayer, mapID, funcLineID):
    ## 发送GameServer请求扫荡助战玩家
    ipyData = IpyGameDataPY.GetIpyGameData("FBHelpBattle", mapID, funcLineID)
    if not ipyData:
        return
    playerID = curPlayer.GetPlayerID()
    msgInfo = str(["SweepCall", mapID, funcLineID])
    GameWorld.GetPlayerManager().GameServer_QueryPlayerResult(curPlayer.GetID(), 0, 0, "FBHelpBattle", msgInfo, len(msgInfo))
    GameWorld.Log("SendGameServer_SweepCallHelpBattlePlayer %s" % (msgInfo), playerID)
    return
def __OnHelpBattleSweepCallResult(curPlayer, msgList, tick):
    ## 助战扫荡结果处理
    cmd, mapID, funcLineID, helpBattlePlayerDict = msgList
    playerID = curPlayer.GetPlayerID()
    GameWorld.DebugLog("__OnHelpBattleSweepCallResult %s,mapID=%s,funcLineID=%s,helpBattlePlayerDict=%s"
                       % (cmd, mapID, funcLineID, helpBattlePlayerDict), playerID)
    fbFuncIpyData = IpyGameDataPY.GetIpyGameData("FBFunc", mapID)
    if not fbFuncIpyData:
        return
    reason = 0
    addCoinRate = 10000 # 基础倍率
    baseFBPoint = fbFuncIpyData.GetFBPoint() # 过关 - 基础仙缘币
    xianyuanCoinUpper = IpyGameDataPY.GetFuncCfg("HelpBattlePoint", 1) # 每日仙缘币上限
    relationCoinAddDict = IpyGameDataPY.GetFuncEvalCfg("HelpBattlePoint", 2, {}) # 社交关系加成 {"社交关系":[过关加成, 助战加成], ...}
    todayXianyuanCoin = PlayerControl.GetTodayXianyuanCoin(curPlayer) # 今日已获得仙缘币
    playerXianyuanCoinUpper = xianyuanCoinUpper
    if curPlayer.GetVIPLv():
        playerXianyuanCoinUpper += PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_XianyuanCoinUpperAdd)
        addCoinRate += PlayerVip.GetPrivilegeValue(curPlayer, ChConfig.VIPPrivilege_XianyuanCoinAddPer)
    relation, relationAdd = 0, 0
    for helpPlayerInfoDict in helpBattlePlayerDict.values():
        relation = helpPlayerInfoDict.get("Relation", 0)
        if not relation:
            continue
        relationAddList = relationCoinAddDict.get(str(relation), [])
        relationAdd += relationAddList[0] if len(relationAddList) == 2 else 0
    coinAdd = 0
    if baseFBPoint:
        coinAdd = int((baseFBPoint + relationAdd) * addCoinRate / 10000.0)
    canAddMax = max(playerXianyuanCoinUpper - todayXianyuanCoin, 0)
    coinAddReal = min(coinAdd, canAddMax) # 实际加仙缘币
    if canAddMax == 0 and not reason:
        reason = 2
    GameWorld.DebugLog("扫荡副本增加仙缘币: baseFBPoint=%s,relationAdd=%s,addCoinRate=%s,coinAdd=%s,canAddMax=%s,coinAddReal=%s"
                       % (baseFBPoint, relationAdd, addCoinRate, coinAdd, canAddMax, coinAddReal), playerID)
    if coinAddReal:
        addDataDict = {"MapID":mapID, "FuncLineID":funcLineID, "IsSweep":1}
        PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_XianyuanCoin, coinAddReal, addDataDict=addDataDict)
        PlayerControl.AddTodayXianyuanCoin(curPlayer, coinAddReal)
    #扫荡结果给奖励等
    FBLogic.OnPlayerFBHelpBattleSweepResult(curPlayer, mapID, funcLineID, helpBattlePlayerDict, coinAddReal, reason)
    # 通知自己获得仙缘币
    msgPack = ChPyNetSendPack.tagMCAddXianyuanCoinMsg()
    msgPack.MapID = mapID
    msgPack.FuncLineID = funcLineID
    msgPack.Relation = relation
    msgPack.RelationCoinAdd = relationAdd
    msgPack.XianyuanCoinAdd = coinAddReal
    msgPack.Reason = reason
    #msgPack.CallPlayerID = relationPlayerID
    #msgPack.CallPlayerName = relationPlayerName
    msgPack.NameLen = len(msgPack.CallPlayerName)
    msgPack.IsSweep = 1
    NetPackCommon.SendFakePack(curPlayer, msgPack)
    return
def __OnHelpBattleRecord(curPlayer, msgList, tick):
    ## 助战记录同步
    cmd, helpRecordList = msgList
    cmd, helpRecordList, isLogin = msgList
    playerID = curPlayer.GetPlayerID()
    GameWorld.DebugLog("__OnHelpBattleRecord %s,helpRecordList=%s" % (cmd, helpRecordList), playerID)
    
@@ -414,12 +513,16 @@
    NetPackCommon.SendFakePack(curPlayer, recordPack)
    
    addDataDict = {"HelpList":drList}
    GameWorld.DebugLog("    addXianyuanCoinTotal=%s,addXianyuanCoinTotalTotay=%s,totalHelpCount=%s"
                       % (addXianyuanCoinTotal, addXianyuanCoinTotalTotay, totalHelpCount), playerID)
    GameWorld.DebugLog("    addXianyuanCoinTotal=%s,addXianyuanCoinTotalTotay=%s,totalHelpCount=%s,isLogin=%s"
                       % (addXianyuanCoinTotal, addXianyuanCoinTotalTotay, totalHelpCount, isLogin), playerID)
    PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_XianyuanCoin, addXianyuanCoinTotal, addDataDict=addDataDict, isSysHint=False)
    if addXianyuanCoinTotalTotay:
        PlayerControl.AddTodayXianyuanCoin(curPlayer, addXianyuanCoinTotalTotay)
        if isLogin:
            curPlayer.SetDict(ChConfig.Def_PDict_TodayXianyuanCoinOnLogin, addXianyuanCoinTotalTotay)
            curPlayer.SetDict(ChConfig.Def_PDict_LoginAddTodayXianyuanCoinTime, int(time.time()))
            GameWorld.Log("    登录时今日助战信息: addXianyuanCoinTotalTotay=%s" % (addXianyuanCoinTotalTotay), playerID)
    # 更新总助战次数,更新排行榜
    PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_HelpBattleTotalCount, totalHelpCount)
    if totalHelpCount >= IpyGameDataPY.GetFuncCfg("HelpBattleRefresh", 4):
@@ -468,20 +571,25 @@
    #                       % (todayXianyuanCoin, playerXianyuanCoinUpper), playerID)
    #    return
    
    relationAdd, relationPlayerID, relationPlayerName = 0, 0, ""
    relation, relationAdd, relationPlayerID, relationPlayerName = 0, 0, 0, ""
    
    fbType = GameWorld.GetMap().GetMapFBType()
    if fbType == IPY_GameWorld.fbtSingle:
        gameFB = GameWorld.GetGameFB()
        helpBattlePlayerDict = PyGameData.g_fbHelpBattlePlayerDict.get(playerID, {})
        for helpPlayerInfoDict in helpBattlePlayerDict.values():
        for helpPlayerID, helpPlayerInfoDict in helpBattlePlayerDict.items():
            objID = gameFB.GetGameFBDictByKey(ChConfig.Def_FB_HelpBattleFBObjID % helpPlayerID)
            if not objID:
                continue
            relation = helpPlayerInfoDict.get("Relation", 0)
            if not relation:
                continue
            relationAddList = relationCoinAddDict.get(str(relation), [])
            relationAdd += relationAddList[0] if len(relationAddList) == 2 else 0
    elif fbType == IPY_GameWorld.fbtTeam:
        relationAdd, relationPlayerID, relationPlayerName = __GetTeamFBMemRelationInfo(curPlayer, relationCoinAddDict, isHelp)
        if playerID in PyGameData.g_teamFBMemRelationAddDict:
            relation, relationAdd, relationPlayerID, relationPlayerName = PyGameData.g_teamFBMemRelationAddDict.pop(playerID)
    coinAdd = 0
    if baseFBPoint:
        coinAdd = int((baseFBPoint + relationAdd) * addCoinRate / 10000.0)
@@ -489,6 +597,10 @@
    coinAddReal = min(coinAdd, canAddMax) # 实际加仙缘币
    if canAddMax == 0 and not reason:
        reason = 2
    if isHelp and not relationPlayerID:
        relationPlayerID = 1
        #GameWorld.DebugLog("没有助战目标则设置relationPlayerID为1,标记是助战的!")
        
    GameWorld.DebugLog("挑战副本增加仙缘币: baseFBPoint=%s,relationAdd=%s,addCoinRate=%s,coinAdd=%s,canAddMax=%s,coinAddReal=%s,relationPlayerID=%s" 
                       % (baseFBPoint, relationAdd, addCoinRate, coinAdd, canAddMax, coinAddReal, relationPlayerID), playerID)
@@ -498,75 +610,111 @@
        PlayerControl.AddTodayXianyuanCoin(curPlayer, coinAddReal)
        
    # 通知自己获得仙缘币
    Sync_AddXianyuanCoinMsg(curPlayer, mapID, lineID, coinAddReal, relationPlayerID, relationPlayerName)
    msgPack = ChPyNetSendPack.tagMCAddXianyuanCoinMsg()
    msgPack.MapID = mapID
    msgPack.FuncLineID = lineID
    msgPack.Relation = relation
    msgPack.RelationCoinAdd = relationAdd
    msgPack.XianyuanCoinAdd = coinAddReal
    msgPack.Reason = reason
    msgPack.CallPlayerID = relationPlayerID
    msgPack.CallPlayerName = relationPlayerName
    msgPack.NameLen = len(msgPack.CallPlayerName)
    NetPackCommon.SendFakePack(curPlayer, msgPack)
    return coinAddReal, reason
def __GetTeamFBMemRelationInfo(curPlayer, relationCoinAddDict, isHelp):
def __GetTeamFBMemRelationInfo(curPlayer, isHelp, leavePlayerID):
    ## 计算队员间相互加成信息,离线玩家不算
    relation = 0
    relationAdd = 0 # 社交关系加成
    relationPlayerID = 0
    relationPlayerName = ""
    teamID = curPlayer.GetTeamID()
    if teamID not in PyGameData.g_teamFBMemRelationDict:
        return relationAdd, relationPlayerID, relationPlayerName
        return relation, relationAdd, relationPlayerID, relationPlayerName
    
    playerManager = GameWorld.GetMapCopyPlayerManager()
    friendList, memFamilyIDDict, memNameDict = PyGameData.g_teamFBMemRelationDict[teamID]
    relationList = IpyGameDataPY.GetFuncEvalCfg("HelpBattlePoint", 3, []) # 社交关系优先级
    relationCoinAddDict = IpyGameDataPY.GetFuncEvalCfg("HelpBattlePoint", 2, {}) # 社交关系加成 {"社交关系":[过关加成, 助战加成], ...}
    playerID = curPlayer.GetPlayerID()
    familyID = curPlayer.GetFamilyID()
    if isHelp:
        # 助战的随便取一位优先级最高的即可
        for checkRelation in relationList:
            memRelation, relationPlayerID = 0, 0
            if checkRelation == 1:
                for memPlayerID in memFamilyIDDict.keys():
                    if [playerID, memPlayerID] in friendList:
                        memRelation = checkRelation
                        relationPlayerID = memPlayerID
                        break
            if checkRelation == 2:
                for memPlayerID, memFamilyID in memFamilyIDDict.items():
                    if playerID != memPlayerID and familyID == memFamilyID:
                        memRelation = checkRelation
                        relationPlayerID = memPlayerID
                        break
            if memRelation and relationPlayerID:
                relationAddList = relationCoinAddDict.get(str(memRelation), [])
                relationAdd += relationAddList[1] if len(relationAddList) == 2 else 0
                relationPlayerName = memNameDict[relationPlayerID]
                return relationAdd, relationPlayerID, relationPlayerName
        defaultRelationPlayerID = 0
        for memPlayerID, memFamilyID in memFamilyIDDict.items():
            memRelation, relationPlayerID = __GetTemMemRelation(playerManager, playerID, familyID, memPlayerID, memFamilyID, relationList, friendList, leavePlayerID)
            if not memRelation:
                if not defaultRelationPlayerID and relationPlayerID:
                    defaultRelationPlayerID = relationPlayerID
                continue
            relation = memRelation
            relationAddList = relationCoinAddDict.get(str(memRelation), [])
            relationAdd += relationAddList[1] if len(relationAddList) == 2 else 0
            relationPlayerName = memNameDict[relationPlayerID]
            return relation, relationAdd, relationPlayerID, relationPlayerName
        relationPlayerID = defaultRelationPlayerID
        relationPlayerName = memNameDict.get(relationPlayerID, "")
        GameWorld.DebugLog("助战默认无关系队员: relationPlayerID=%s,relationPlayerName=%s" % (relationPlayerID, relationPlayerName), playerID)
    else:
        # 非助战享受所有队员加成
        for memPlayerID, memFamilyID in memFamilyIDDict.items():
            memRelation = 0
            for checkRelation in relationList:
                if [playerID, memPlayerID] in friendList:
                    memRelation = checkRelation
                    break
                if playerID != memPlayerID and familyID == memFamilyID:
                    memRelation = checkRelation
                    break
            memRelation = __GetTemMemRelation(playerManager, playerID, familyID, memPlayerID, memFamilyID, relationList, friendList, leavePlayerID)[0]
            if not memRelation:
                continue
            if memRelation == relationList[0]:
                relation = memRelation
            elif relation:
                relation = memRelation
            relationAddList = relationCoinAddDict.get(str(memRelation), [])
            relationAdd += relationAddList[0] if len(relationAddList) == 2 else 0
            
    return relationAdd, relationPlayerID, relationPlayerName
    return relation, relationAdd, relationPlayerID, relationPlayerName
def Sync_AddXianyuanCoinMsg(curPlayer, mapID, funcLineID, addXianyuanCoin, callPlayerID=0, callPlayerName=""):
    '''同步自己主动战斗获得仙缘币信息
    1. 主动发起通关镜像助战副本,此时 callPlayerID 及 name 为空
    2. 参与通关真实助战的副本,次数如果自己是助战的,则 callPlayer 及 name 有值
    @param addXianyuanCoin: 增加的仙缘币,可能为0,代表已达本日上限,但是前端扔需要展示记录
    @param callPlayerID: 助战别人时,对方玩家的playerID
    @param callPlayerName: 助战别人时,对方玩家的名字
    '''
    msgPack = ChPyNetSendPack.tagMCAddXianyuanCoinMsg()
    msgPack.MapID = mapID
    msgPack.FuncLineID = funcLineID
    msgPack.XianyuanCoinAdd = addXianyuanCoin
    msgPack.CallPlayerID = callPlayerID
    msgPack.CallPlayerName = callPlayerName
    msgPack.NameLen = len(msgPack.CallPlayerName)
    NetPackCommon.SendFakePack(curPlayer, msgPack)
def __GetTemMemRelation(playerManager, playerID, familyID, memPlayerID, memFamilyID, relationList, friendList, leavePlayerID):
    ## 离线玩家不算社交关系
    if leavePlayerID and memPlayerID == leavePlayerID:
        return 0, 0
    if playerID == memPlayerID:
        return 0, 0
    memPlayer = playerManager.FindPlayerByID(memPlayerID)
    if memPlayer == None or memPlayer.IsEmpty():
        return 0, 0
    for checkRelation in relationList:
        if checkRelation == 1:
            if [playerID, memPlayerID] in friendList:
                return checkRelation, memPlayerID
        if checkRelation == 2:
            if playerID != memPlayerID and familyID and familyID == memFamilyID:
                return checkRelation, memPlayerID
    return 0, memPlayerID
def RefershTeamFBMemRelation(tick, leavePlayerID=0):
    ## 刷新组队副本队员关系
    playerManager = GameWorld.GetMapCopyPlayerManager()
    for i in xrange(playerManager.GetPlayerCount()):
        player = playerManager.GetPlayerByIndex(i)
        if player == None or player.IsEmpty():
            continue
        if leavePlayerID and player.GetPlayerID() == leavePlayerID:
            PyGameData.g_teamFBMemRelationAddDict.pop(leavePlayerID, 0)
            continue
        relation, relationAdd, relationPlayerID, relationPlayerName = __GetTeamFBMemRelationInfo(player, FBCommon.GetIsHelpFight(player), leavePlayerID)
        PyGameData.g_teamFBMemRelationAddDict[player.GetPlayerID()] = [relation, relationAdd, relationPlayerID, relationPlayerName]
    for index in xrange(playerManager.GetPlayerCount()):
        player = playerManager.GetPlayerByIndex(index)
        if player == None or player.IsEmpty():
            continue
        if leavePlayerID and player.GetPlayerID() == leavePlayerID:
            continue
        FBLogic.DoFBHelp(player, tick)
    return
def GetTeamFBMemRelationInfo(playerID):
    if playerID not in PyGameData.g_teamFBMemRelationAddDict:
        return 0, 0
    return PyGameData.g_teamFBMemRelationAddDict[playerID][:2]