示例#1
0
class TaskBase(object):

    def __init__(self, player, taskConf, taskSystem, taskData=None):
        self.player = player
        self.userId = player.userId
        self.taskId = taskConf["taskId"]
        self.taskConfig = taskConf

        self.taskSystem = taskSystem
        self.taskData = taskData or self._getInitMainData()
        self.taskInterval = taskConf["timeLong"]
        self.helpProgress = taskData.get("helpProgress", 0) if taskData else 0
        self.waitTime = taskData.get("waitTime", 0) if taskData else taskConf["waitTime"]
        self.taskActivateTimer = None       # 任务激活
        self.sendTaskInfoTimer = None       # 发送任务信息
        self.updateTaskInfoTimer = None     # 刷新任务进度
        self.userEndTaskTimer = None        # 任务结束倒计时
        self.isSendMsg = False
        self.receiveRewards = None
        self.catchBetNum = taskData.get("catchBetNum", 0) if taskData else 0
        self._reload()

    def clear(self):
        """清理定时器"""
        if self.taskActivateTimer:
            self.taskActivateTimer.cancel()
        if self.sendTaskInfoTimer:
            self.sendTaskInfoTimer.cancel()
        if self.updateTaskInfoTimer:
            self.updateTaskInfoTimer.cancel()
        if self.userEndTaskTimer:
            self.userEndTaskTimer.cancel()

    def _reload(self):
        self.recordStartTime = 0
        if not self.isTaskOver():
            if self.taskData.get("type", 0) and self.taskData.get("type", 0) != self.taskConfig["type"]:
                self.taskData = self._getInitMainData()
                return
            if self.taskConfig["target"] != self.taskData["target"]:        # 未完成的任务任务目标发生变化后重置存档
                self.taskData = self._getInitMainData()
                return
            if self.taskConfig["targetNum"] != self.taskData["targetNum"] and self.taskData.get("type", 0) not in [0, TaskType.HoldCoin]:
                self.taskData = self._getInitMainData()
                return

    def _getInitMainData(self):
        """获取初始化主线数据"""
        targetNum = self.taskConfig["targetNum"]
        if util.isNewbieRoom(self.player.table.typeName) and self.taskConfig["type"] == TaskType.HoldCoin:
            targetNum += self.player.allChip // 100 * 100
        return {
            "type": self.taskConfig["type"],
            "progress": 0,
            "state": TaskState.NotOpen,
            "failTime": 0,
            "targetNum": targetNum,
            "target": self.taskConfig["target"]
        }

    def _addProgress(self, value, isMe, progress=0, isTargetAddition=False):
        """增加任务进度"""
        assert (self.taskData)
        if value == 0 or self.taskData["state"] != TaskState.Update:                            # value
            return
        if ftlog.is_debug():
            ftlog.debug("_addProgress1", "value =", value, "isMe =", isMe, "progress =", progress, "isTargetAddition =", isTargetAddition, "helpProgress =", self.helpProgress)
        if isMe:
            value *= self.taskSystem.taskExpedite
            progress_ = min(self.taskData["progress"] + value, 999999999999)
            self._updateProgress(progress_, isMe)
        else:
            if progress > 0 or isTargetAddition:
                if progress:
                    self.helpProgress += progress
                else:
                    self.helpProgress += value
                progress_ = min(self.taskData["progress"] + value, 999999999999)
                self._updateProgress(progress_, isMe)
                if ftlog.is_debug():
                    ftlog.debug("_addProgress2", "helpProgress =", self.helpProgress, "totalProgress =", progress_)

    def _updateProgress(self, value, isMe):
        """
        更新任务进度
        """
        if self.taskData["progress"] != value:
            self.taskData["progress"] = value
            self.taskData["time"] = int(time.time())
            if self._isComplete():
                self.taskEnd()
            else:
                if isMe:
                    self.sendUserTaskInfo()
                else:                               # 好友助力任务进度延迟刷新
                    self.isSendMsg = True

    def _receiveTaskReward(self):
        """领取奖励"""
        assert (self.taskData)
        if self.isTaskOver():  # 已领取
            return 1, None
        targetCount = self.taskData["targetNum"]
        if self.taskData["progress"] < targetCount:  # 未达成
            return 1, None
        _rewards = self._getDropItems()
        if not _rewards:
            _rewards = self.taskConfig["rewards"]     # 普通奖励
        if _rewards and util.isChestRewardId(_rewards[0]["name"]):      # 宝箱奖励(新手宝箱奖励固定)
            if util.isNewbieRoom(self.player.table.typeName):
                _rewards = [
                    {"name": 101, "count": 500},
                    {"name": 1145, "count": 1},
                    {"name": 1149, "count": 1}
                    # {"name": 1137, "count": 3}
                ]
            else:
                from newfish.entity.chest import chest_system
                _rewards = chest_system.getChestRewards(self.userId, _rewards[0]["name"])

        rewards = []
        for _, reward in enumerate(_rewards):
            if reward["name"] <= 0:
                continue
            rwDict = {}
            rwDict["name"] = reward["name"]
            rwDict["count"] = reward["count"]
            rewards.append(rwDict)

        code = 0
        self.taskData["state"] = TaskState.Success  # 改变状态
        if rewards:
            code = util.addRewards(self.userId, rewards, "BI_NFISH_TABLE_TASK_REWARDS", int(self.taskId))
        return code, rewards

    def _getDropItems(self):
        """获取掉落的道具"""
        realRewards = []
        rewards = self.taskConfig["rewards"]
        for reward in rewards:
            dropId = reward["name"]
            dropConf = config.getDropConf(dropId)
            if dropConf:
                _, rds = drop_system.getDropItem(dropId)
                realRewards.append(rds)
        return realRewards

    def _getCatchFishCoin(self, event, target=0):
        """获取捕鱼的金币"""
        totalCoin = 0  # 总金币数不包括招财珠
        gunSkinMul = event.gunSkinMul
        fishCoins = {}
        outCoinsNum = 0
        for gainMap in event.gain:
            fishType = int(gainMap["fishType"])
            itemId = gainMap["itemId"]
            itemCount = gainMap["count"] / gunSkinMul
            if itemId == config.CHIP_KINDID:  # 金币
                totalCoin += itemCount
                if fishType // 1000 == 14:
                    fishType = fishType % 14000 + 11000
                fishCoins[str(fishType)] = fishCoins.setdefault(str(fishType), 0) + itemCount
                if target and itemCount >= target:
                    outCoinsNum += 1
        return totalCoin, fishCoins, outCoinsNum

    def dealCatchEvent(self, event, tableMultiple, coinAddition, playersNum):
        """
        处理捕鱼事件
        :param event: 捕获事件详情
        :param tableMultiple: 房间倍率
        :param coinAddition: 当处于累计捕获金币任务时的进度加成
        :param playersNum: 当前桌内玩家数量
        :return:
        """
        if self.taskConfig["type"] in [TaskType.UseSkillNum, TaskType.ComboNum]:
           return
        if self.taskData["state"] != TaskState.Update:
            return
        isMe = event.userId == self.userId
        fishTypes = event.fishTypes  # 鱼种类
        wpId = event.wpId
        gunSkinMul = event.gunSkinMul
        target = self.taskConfig["target"]
        progress = 0
        isTargetAddition = False
        if self.taskConfig["type"] in [TaskType.CatchFishCoin, TaskType.UseSkillCatchFishCoin]:
            progress = coinAddition
        elif self.taskConfig["type"] in [TaskType.CatchFishNum, TaskType.CatchBossNum,
                                         TaskType.FishNumCoinHigh, TaskType.BetFishNum,
                                         TaskType.CatchRainbowFishNum, TaskType.CatchRedPacketFishNum]:
            friendHelpPlayerMultiple = config.getCommonValueByKey("friendHelpPlayerMultiple", {}).get(str(playersNum - 1), 0)
            probb = (friendHelpPlayerMultiple * (self.taskData["targetNum"] + 5) / self.taskData["targetNum"]) * 10000
            randInt = random.randint(1, 10000)
            if randInt <= probb:
                isTargetAddition = True
        if self.taskConfig["type"] == TaskType.CatchFishCoin:  # 1捕获xx鱼达金币数
            totalCoin, fishCoins, _ = self._getCatchFishCoin(event)
            if target:
                self._addProgress(fishCoins.get(str(target), 0), isMe, progress=progress, isTargetAddition=isTargetAddition)
            else:
                self._addProgress(totalCoin, isMe, progress=progress, isTargetAddition=isTargetAddition)

        elif self.taskConfig["type"] == TaskType.CatchFishNum:  # 2捕获鱼个数
            if target:
                betTarget = 14000 + int(target) % 11000
                fishNum = fishTypes.count(target) + fishTypes.count(betTarget)
                self._addProgress(fishNum, isMe, progress=progress, isTargetAddition=isTargetAddition)
            else:
                self._addProgress(len(fishTypes), isMe, progress=progress, isTargetAddition=isTargetAddition)
            return
        elif self.taskConfig["type"] == TaskType.CatchBossNum:  # 3捕获boss个数
            bossNum = 0  # boss个数
            for fishType in fishTypes:
                fishConf = config.getFishConf(fishType, self.taskSystem.table.typeName, tableMultiple)
                if fishConf["type"] in config.BOSS_FISH_TYPE:
                    bossNum += 1
            self._addProgress(bossNum, isMe, progress=progress, isTargetAddition=isTargetAddition)
            return

        elif self.taskConfig["type"] == TaskType.FishNumCoinHigh:  # 4多少金币以上的鱼
            _, _, num = self._getCatchFishCoin(event, target)
            self._addProgress(num, isMe, progress=progress, isTargetAddition=isTargetAddition)
            return
        elif self.taskConfig["type"] == TaskType.BetFishNum: # 5--多少只倍率鱼
            betFishMap = {}
            for gainMap in event.gain:
                fishConf = config.getFishConf(gainMap["fishType"], self.taskSystem.table.typeName, tableMultiple)
                itemId = gainMap["itemId"]
                itemCount = gainMap["count"]

                if fishConf["type"] in config.MULTIPLE_FISH_TYPE:
                    if itemId == config.CHIP_KINDID:  # 金币
                        bet = itemCount / fishConf["score"] / tableMultiple / gunSkinMul
                        betFishMap[str(bet)] = betFishMap.get(str(bet), 0) + 1
            betNum = 0
            for bet in betFishMap:
                if int(bet) >= target:
                    betNum += betFishMap[bet]
            self._addProgress(betNum, isMe, progress=progress, isTargetAddition=isTargetAddition)

        elif self.taskConfig["type"] == TaskType.UseSkillCatchFishNum:  # 8 使用技能捕获鱼数
            wpType = util.getWeaponType(wpId)
            if wpType in [config.SKILL_WEAPON_TYPE,
                          config.RB_FIRE_WEAPON_TYPE,
                          config.RB_BOMB_WEAPON_TYPE]:
                if target:
                    self._addProgress(fishTypes.count(target), isMe, progress=progress, isTargetAddition=isTargetAddition)
                else:
                    self._addProgress(len(fishTypes), isMe, progress=progress, isTargetAddition=isTargetAddition)

        elif self.taskConfig["type"] == TaskType.UseSkillCatchFishCoin:  # 9 使用技能捕获XX金币类型的鱼数
            totalCoin, fishCoins, _ = self._getCatchFishCoin(event)  # 总金币数不包括招财珠
            wpType = util.getWeaponType(wpId)
            if wpType in [config.SKILL_WEAPON_TYPE,
                          config.RB_FIRE_WEAPON_TYPE,
                          config.RB_BOMB_WEAPON_TYPE]:
                if target:
                    self._addProgress(fishCoins.get(str(target), 0), isMe, progress=progress, isTargetAddition=isTargetAddition)
                else:
                    self._addProgress(totalCoin, isMe, progress=progress, isTargetAddition=isTargetAddition)
        elif self.taskConfig["type"] == TaskType.CatchFishNumByOneFire:  # 10 1网捕获多少鱼
            if len(fishTypes) >= target:
                value = 1
                if not isMe:
                    return
                self._addProgress(value, isMe, progress=progress, isTargetAddition=isTargetAddition)
        elif self.taskConfig["type"] == TaskType.CatchRainbowFishNum:   # 捕获彩虹鱼
            rainbowNum = 0
            for fishType in fishTypes:
                fishConf = config.getFishConf(fishType, self.taskSystem.table.typeName, tableMultiple)
                if fishConf["type"] in config.RAINBOW_FISH_TYPE:
                    rainbowNum += 1
            self._addProgress(rainbowNum, isMe, progress=progress, isTargetAddition=isTargetAddition)
        elif self.taskConfig["type"] == TaskType.CatchRedPacketFishNum: # 捕获红包券鱼
            redPacketNum = 0
            for fishType in fishTypes:
                fishConf = config.getFishConf(fishType, self.taskSystem.table.typeName, tableMultiple)
                if fishConf["type"] == 4:
                    redPacketNum += 1
            self._addProgress(redPacketNum, isMe, progress=progress, isTargetAddition=isTargetAddition)

    def dealUseSkillEvent(self, event):
        """使用技能事件"""
        if self.taskData["state"] != TaskState.Update:
            return
        if self.taskConfig["type"] == TaskType.UseSkillNum:
            target = self.taskConfig["target"]
            if target == 0:
                self._addProgress(1, event.userId == self.userId)
            else:
                if event.skillId == target:
                    self._addProgress(1, event.userId == self.userId)

    def dealUseSkillItem(self, event):
        """使用技能道具"""
        if self.taskData["state"] != TaskState.Update:
            return
        if self.taskConfig["type"] == TaskType.UserSkillItem:
            self._addProgress(1, event.userId == self.userId)

    def dealGetPearl(self, pearl):
        """获得珍珠"""
        if self.taskData["state"] != TaskState.Update:
            return
        if self.taskConfig["type"] == TaskType.CatchPearlNum:
            self._addProgress(pearl, True)

    def dealCommboEvent(self, event):
        """处理连击事件"""
        if self.taskData["state"] != TaskState.Update:
            return
        if self.taskConfig["type"] == TaskType.ComboNum:
            if event.comboNum >= self.taskConfig["target"]:
                self._addProgress(1, event.userId == self.userId)

    def refreshHoldCoin(self, coin):
        """刷新持有金币数量"""
        if self.taskData["state"] != TaskState.Update:
            return
        if ftlog.is_debug():
            ftlog.debug("refreshHoldCoin", self.userId, coin)
        if self.taskConfig["type"] == TaskType.HoldCoin:
            self._updateProgress(coin, True)

    def refreshLevel(self, level):
        """刷新等级"""
        if self.taskData["state"] != TaskState.Update:
            return
        ftlog.debug("refreshLevel", self.userId, level)
        if self.taskConfig["type"] == TaskType.UpgradeLevel:
            self._updateProgress(level, True)

    def getTaskId(self):
        """
        获取任务Id
        """
        return self.taskId

    def taskStart(self, interval=0, delay=0):
        """
        任务开始
        """
        if ftlog.is_debug():
            ftlog.debug("taskBase_______taskStart", self.taskId)

        if self.taskActivateTimer:
            self.taskActivateTimer.cancel()
        if delay > 0:
            taskActivateInterval = max(interval, Task_Delay_Ready_Time)
            self.taskActivateTimer = FTLoopTimer(taskActivateInterval, 0, self._taskActivate, delay)
            self.taskActivateTimer.start()
        elif self.taskConfig["timeLong"] > 0:
            if util.isNewbieRoom(self.player.table.typeName) and self.taskSystem.taskModel == TaskModel.Main:
                time_ = Task_Red_Ready_Time
            else:
                time_ = Task_Normal_Ready_Time
            taskActivateInterval = max(interval, time_)
            taskInfoInterval = max(interval - time_, 0)
            self.delaySendUserTaskInfo(taskInfoInterval)
            self.taskActivateTimer = FTLoopTimer(taskActivateInterval, 0, self._taskActivate)
            self.taskActivateTimer.start()
        else:
            self.taskActivateTimer = FTLoopTimer(interval, 0, self._taskActivate)
            self.taskActivateTimer.start()
        from newfish.game import TGFish
        from newfish.entity.event import TableTaskStartEvent
        event = TableTaskStartEvent(self.userId, FISH_GAMEID, self.taskSystem.table.tableId, self.getTaskId())
        TGFish.getEventBus().publishEvent(event)

    def _taskActivate(self, delay=0):
        """任务激活"""
        # 未完成前3个中期目标时不触发渔场任务.
        if self.taskSystem.needCheckMidTermTargetStates:
            if not self.taskSystem.top3MidTermTargetFinished:
                self.taskSystem.top3MidTermTargetFinished = True
                for taskClass in self.player.achieveSystem.holdAssetTasks:
                    if taskClass.taskId < 1003 or (taskClass.taskId == 1003 and not taskClass.isComplete()):
                        self.taskSystem.top3MidTermTargetFinished = False
                        break
            if not self.taskSystem.top3MidTermTargetFinished:
                if self.taskActivateTimer:
                    self.taskActivateTimer.cancel()
                self.taskActivateTimer = FTLoopTimer(60, 0, self._taskActivate)
                self.taskActivateTimer.start()
                if ftlog.is_debug():
                    ftlog.debug("_taskActivate, need delay !", self.player.userId, self.taskId)
                return
        if ftlog.is_debug():
            ftlog.debug("_taskActivate->", delay, self.waitTime)
        self.taskData["state"] = TaskState.Start
        if delay > 0:
            self.taskData["state"] = TaskState.Update
            self.taskInterval = delay
        self.recordStartTime = int(time.time())
        self.clear()
        if self.taskInterval != 0:
            self.userEndTaskTimer = FTLoopTimer(self.taskInterval, 0, self.taskEnd)
            self.userEndTaskTimer.start()
        if self.taskSystem.isFriendRoom():
            self.updateTaskInfoTimer = FTLoopTimer(1, -1, self.sendTimerUpdate)
            self.updateTaskInfoTimer.start()
        self.sendUserTaskInfo()
        self.taskData["state"] = TaskState.Update

    def getTaskFailTime(self):
        """
        当前任务已经失败多少次
        """
        return self.taskData["failTime"]

    def getTaskInfo(self):
        """
        获取返回给客户端的任务数据
        """
        progress = min(self.taskData["progress"], self.taskData["targetNum"])
        progress = int(progress) if progress - int(progress) == 0 else progress
        meProgress = progress - self.helpProgress
        meProgress = int(meProgress) if meProgress - int(meProgress) == 0 else meProgress
        taskInfo = {}
        taskInfo["taskId"] = self.taskConfig["taskId"]
        taskInfo["isLimitTime"] = self.isLimitTime()
        taskInfo["shareMode"] = 1   # 1 if not self.isLimitTime() or util.isLocationLimit(self.userId) else 0
        taskInfo["progress"] = [int(progress), int(meProgress), self.taskData["targetNum"]]
        taskInfo["state"] = self.taskData["state"]
        taskInfodescId = self.taskConfig["desc"]
        taskInfo["desc"] = config.getMultiLangTextConf(str(taskInfodescId), lang=util.getLanguage(self.userId))
        taskInfo["reward"] = self.taskConfig["rewards"]
        if self.receiveRewards:
            taskInfo["realReward"] = self.receiveRewards
        taskInfo["target"] = self.taskConfig["target"]
        taskInfo["suggestTarget"] = self.taskConfig["suggestTarget"]
        timeLeft = self.recordStartTime + self.taskInterval - int(time.time())
        taskInfo["timeLeft"] = timeLeft if timeLeft >= 0 else self.taskInterval
        taskInfo["timeLong"] = self.taskInterval
        taskInfo["failTimeConf"] = self.taskConfig["failTime"]
        taskInfo["failTime"] = self.taskData["failTime"]        # 失败次数
        taskInfo["isNextLimitTime"] = self.taskSystem.isNextLimitTime(self.getTaskId())
        taskInfo["model"] = TaskModel.Red if util.isNewbieRoom(self.player.table.typeName) and self.taskSystem.taskModel == TaskModel.Main else self.taskSystem.taskModel
        taskInfo["type"] = self.taskConfig["type"]
        if self.taskSystem.taskModel in [TaskModel.Red, TaskModel.Main]:
            taskInfo["index"] = self.taskSystem.allMainTaskIds.index(self.taskId)
        return taskInfo

    def getTaskData(self):
        """
        获取存储的任务数据
        """
        saveData = {}
        saveData["type"] = self.taskConfig["type"]
        saveData["taskId"] = self.taskId
        saveData["progress"] = self.taskData["progress"]
        saveData["helpProgress"] = self.helpProgress
        saveData["state"] = self.taskData["state"]
        saveData["target"] = self.taskConfig["target"]
        saveData["targetNum"] = self.taskData["targetNum"]
        saveData["failTime"] = self.taskData["failTime"]
        saveData["waitTime"] = int(self.taskActivateTimer.getTimeOut()) if self.taskActivateTimer else 0
        if self.catchBetNum:
            saveData["catchBetNum"] = self.catchBetNum
        return saveData

    def taskEnd(self):
        """
        任务结束
        """
        if ftlog.is_debug():
            ftlog.debug("taskBase_______taskEnd", self.taskId, self.userId, self.taskData["state"])
        beforeState = self.taskData["state"]
        self.clear()
        if beforeState == TaskState.Update:
            isComplete = self._isComplete()
            if isComplete:
                _, rewards = self._receiveTaskReward()
                self.receiveRewards = rewards
                self.taskSystem.saveRedState()  # 保存红包
            else:
                self.taskSystem.taskExpedite = 1
                self.taskData["state"] = TaskState.Fail
                if self.isLimitTime():
                    self.taskData["failTime"] += 1
            from newfish.game import TGFish
            from newfish.entity.event import TableTaskEndEvent
            event = TableTaskEndEvent(self.userId, FISH_GAMEID, self.taskSystem.table.tableId, self.getTaskId(),
                                      isComplete,  self.isLimitTime(), self.receiveRewards)
            TGFish.getEventBus().publishEvent(event)
            # 上传当前完成任务进度
            if self.taskSystem.taskModel == TaskModel.Main and self.taskSystem.isRedRoom():
                ftlog.debug("BI_NFISH_THOUSAND_RED_TASK_PROGRESS--->000", self.getTaskId())
                bireport.reportGameEvent("BI_NFISH_GE_THOUSAND_RED_TASK", self.userId,FISH_GAMEID,
                                self.taskSystem.table.roomId, self.taskSystem.table.tableId,
                                self.getTaskId(), int(isComplete), 0,  0, [], config.CLIENTID_ROBOT)
                # 新手引导步骤完成
                if self.taskConfig["type"] == TaskType.UpgradeLevel:
                    util.addGuideStep(self.player.userId, config.NEWBIE_GUIDE_GUN_UP, self.player.clientId)
        self.sendUserTaskInfo()

    def sendTimerUpdate(self):
        """
        任务进度刷新
        """
        if self.taskConfig["type"] == TaskType.HoldCoin:
            self.taskSystem.refreshHoldCoin(self.player.holdCoin)
        elif self.taskConfig["type"] == TaskType.UpgradeLevel:
            gunLevel = self.player.gunLevel - 2100
            self.taskSystem.refreshLevel(gunLevel)
        if self.isSendMsg:
            self.sendUserTaskInfo()

    def delaySendUserTaskInfo(self, interval=0):
        """
        延时发送任务信息
        """
        if self.sendTaskInfoTimer:
            self.sendTaskInfoTimer.cancel()
        self.sendTaskInfoTimer = FTLoopTimer(interval, 0, self.sendUserTaskInfo)
        self.sendTaskInfoTimer.start()

    def sendUserTaskInfo(self):
        """
        发送任务信息
        """
        self.isSendMsg = False
        message = MsgPack()
        message.setCmd("table_task_info")
        message.setResult("gameId", FISH_GAMEID)
        message.setResult("userId", self.userId)
        taskInfo = self.getTaskInfo()
        message.setResult("taskInfo", taskInfo)
        router.sendToUser(message, self.userId)

    def _isComplete(self):
        """
        任务是否完成
        """
        assert (self.taskData)
        targetCount = self.taskData["targetNum"]
        return self.taskData["progress"] >= targetCount

    def isTaskSuccess(self):
        """
        任务成功
        """
        return self.taskData["state"] == TaskState.Success

    def getTaskConf(self):
        assert (self.taskConfig)
        return self.taskConfig

    def isTaskOver(self):
        """任务结束"""
        return self.taskData["state"] in [TaskState.Success, TaskState.Fail]

    def getTaskState(self):
        return self.taskData["state"]

    def getTaskTargets(self):
        if self.taskData["state"] != TaskState.Update:
            return []
        if self.taskConfig["type"] in [TaskType.CatchFishNum, TaskType.CatchFishCoin,
                                       TaskType.UseSkillCatchFishNum, TaskType.UseSkillCatchFishCoin]:
            if self.taskConfig["target"] != 0:
                return [self.taskConfig["target"]]
        return []

    def isLimitTime(self):
        """是否限制了时间"""
        if not self.taskConfig:
            return 0
        return 1 if self.taskConfig.get("timeLong", 0) != 0 else 0
示例#2
0
class FishFightTable(FishTable):
    def __init__(self, room, tableId):
        super(FishFightTable, self).__init__(room, tableId)
        self.clearTableData()
        # 用户离线等待时间
        self._offlineWaitSeconds = 1200
        # 用户空闲超时时间
        self._idleTimeOutSeconds = 1200
        # 用户无子弹时超时时间
        self._inactiveTimeOutSeconds = 1200
        # 桌子过期时间
        self._tableExpiresTime = 600
        # 准备倒计时
        self._readySeconds = 4
        # 初始化定时器
        self._expiresTimer = None
        self._readyTimer = None
        self._beginTimer = None
        # 最大人数
        self.tableSeatCount = self.runConfig.matchConf["table.seat.count"]
        # table_call可用action
        self.actionMap = {
            "robot_leave": self._robotLeave,
            "catch": self._verifyCatch,
            "skill_use": self._skill_use,
            "skill_install": self._skill_install,
            "skill_replace": self._skill_replace,
            "smile": self.doTableSmilies,
            "honor_push": self._honor_push,
            "honor_replace": self._honor_replace,
            "guns_list": self._guns_list,
            "guns_pool": self._guns_pool,
            "ft_start": self.doFTStart,
            "ft_leave": self.doUserLeave,
            "treasure_rewards": self._getTreasureRewards
        }
        self._logger = Logger()
        self._logger.add("gameId", self.gameId)
        self._logger.add("roomId", room.roomId)
        self._logger.add("tableId", tableId)

    @property
    def ftId(self):
        return self.ftTable.ftId if self.ftTable else 0

    @property
    def ftTable(self):
        return self._ftTable

    def clearTableData(self):
        """
        清理桌子数据和状态
        """
        if ftlog.is_debug():
            ftlog.debug("friendTable.clear-->begin", "tableId=", self.tableId)
        self._tableState = TableState.DEFAULT  # 桌子状态
        # 桌子详情(房号、房主、服务费)
        self._ftTable = None
        self._beginTime = None
        self._usersData = {}
        self.targets = {}
        self.ftRanks = []
        self.winnerId = None
        self.otherId = None
        self._overState = None
        if ftlog.is_debug():
            ftlog.debug("friendTable.clear-->end", "tableId=", self.tableId)

    def clearAllTimer(self):
        """
        清理所有的计时器
        """
        if self._readyTimer:
            self._readyTimer.cancel()
            self._readyTimer = None
        if self._beginTimer:
            self._beginTimer.cancel()
            self._beginTimer = None
        if self._expiresTimer:
            self._expiresTimer.cancel()
            self._expiresTimer = None

    def createPlayer(self, table, seatIndex, clientId):
        """
        新创建Player对象
        """
        return FishFightPlayer(table, seatIndex, clientId)

    @locked
    def doFTEnter(self, ftId, userId, seatId):
        ftlog.info("FishFriendTable.doFTEnter", "tableId=", self.tableId,
                   "ftId=", ftId, "seatId=", seatId)
        lang = util.getLanguage(userId)
        if ftId != self.ftId:
            raise TYBizException(
                1,
                config.getMultiLangTextConf("ID_INPUT_ROOMID_ERROR_INFO",
                                            lang=lang))

        player = self.getPlayer(userId)
        if player and player.userId:
            self.sendFriendDetails(userId)
        else:
            if self._expiresTimer:  # 重置桌子超时计时器
                self._expiresTimer.cancel()
                self._expiresTimer = None
            self._expiresTimer = FTLoopTimer(self._tableExpiresTime, 0,
                                             self._tableExpires)
            self._expiresTimer.start()
            self._doTableQuickStart(userId, seatId)  # 用户进入
            self.sendFriendDetails(userId)  # 发送对战详情信息
            if userId != self.ftTable.userId:  # 记录参与者Id
                self.otherId = userId
                fight_history.addOneHistory(userId, self.ftTable.userId,
                                            fight_history.HistoryType.Enter,
                                            self.ftId,
                                            self.ftTable.fee)  # 进入房间记录
        return 0

    def sendFriendDetails(self, userId):
        """发送好友竞技的详情"""
        self._updateFriendInfo(userId)
        self._updateFriendTask()
        if self._tableState >= TableState.READY:
            self._ftStart(userId)

    def _updateFriendInfo(self, userId):
        """更新好友消息"""
        ftPlayer = self.getPlayer(self.ftTable.userId)
        ftName = ""
        if ftPlayer:
            ftName = ftPlayer.name
        player = self.getPlayer(userId)
        if player and player.userId:
            msg = MsgPack()
            msg.setCmd("ft_info")
            msg.setResult("gameId", FISH_GAMEID)
            msg.setResult("roomId", self.roomId)
            msg.setResult("tableId", self.tableId)
            msg.setResult("seatId", player.seatId)
            msg.setResult("userId", player.userId)
            msg.setResult("tableState", self._tableState)
            msg.setResult("reward", self.ftTable.fee)
            msg.setResult("ftId", self.ftTable.ftId)
            msg.setResult("ftUserName", ftName)
            msg.setResult("ftUserId", self.ftTable.userId)
            msg.setResult("timeLong", self.runConfig.playingTime)
            msg.setResult(
                "expirseTime",
                int(self._expiresTimer.getTimeOut())
                if self._expiresTimer else self._tableExpiresTime)
            msg.setResult("targets", self.targets)
            GameMsg.sendMsg(msg, player.userId)

    def _tableExpires(self):
        """桌子过期了"""
        if self._tableState < TableState.START:
            self._sendExpriseHistory()
            self._sendLeaveMsg(reason=1)
            self._clearTable()
class SwimStage(object):
    """
    冰龙游动阶段
    """
    # 冰龙鱼群
    DRAGON_FISH_TYPE = 75216

    def __init__(self, dragon):
        self.dragon = dragon
        self.table = self.dragon.table
        self.totalRound = 0
        self.currentRound = 0
        self.fishId = 0
        self.catchUserId = 0
        self.timer = None
        self.callDragonFishGroup(self.DRAGON_FISH_TYPE)

    def clearTimer(self):
        if self.timer:
            self.timer.cancel()
            self.timer = None

    def callDragonFishGroup(self, fishType):
        """
        召唤冰龙鱼群
        """
        self.clearTimer()
        groupIds = self.table.runConfig.allSuperBossGroupIds[fishType]
        groupIds = random.choice(groupIds)
        group = self.table.insertFishGroup(groupIds)
        self.fishId = group.startFishId
        self.timer = FTLoopTimer(group.totalTime, 0, self.callDragonFishGroup,
                                 self.DRAGON_FISH_TYPE)
        self.timer.start()
        return group

    def catchDragon(self, userId, stageCount):
        """
        捕获冰龙
        """
        self.catchUserId = userId
        self.totalRound = stageCount
        self.clearTimer()
        # 捕获后延迟出现冰结晶
        self.timer = FTLoopTimer(self.dragon.dragonConf["crystal.appear.time"],
                                 0, self.switchStormRound)
        self.timer.start()

    def switchStormRound(self):
        """
        切换冰冻风暴回合
        """
        self.currentRound += 1
        if self.currentRound <= self.totalRound:
            self.clearTimer()
            self.sendDragonStormMsg()
            # 每回合风暴时间
            self.timer = FTLoopTimer(
                self.dragon.dragonConf["crystal.storm.time"], 0,
                self.switchStormRound)
            self.timer.start()
        else:
            self.timer = FTLoopTimer(
                self.dragon.dragonConf["crystal.leave.time"],
                0,
                self.dragon._doLeave,
                isNow=True)
            self.timer.start()

    def sendDragonStormMsg(self):
        """
        发送冰冻风暴消息
        """
        msg = MsgPack()
        msg.setCmd("dragon_storm")
        msg.setResult("gameId", FISH_GAMEID)
        msg.setResult("roomId", self.table.roomId)
        msg.setResult("tableId", self.table.tableId)
        msg.setResult("rounds", [self.currentRound, self.totalRound])
        msg.setResult("bulletId", self.fishId)
        msg.setResult("catchUserId", self.catchUserId)
        GameMsg.sendMsg(msg, self.table.getBroadcastUids())

    def frozenDragon(self, frozenTime):
        """
        冰龙被冻住
        """
        if not self.catchUserId:
            interval = self.timer.getTimeOut() + frozenTime
            if interval > 0:
                self.timer.reset(interval)
class FishTimeMatchTable(FishMultipleTable):
    def __init__(self, room, tableId):
        super(FishTimeMatchTable, self).__init__(room, tableId)
        self.clearTableData()
        # 用户离线等待时间
        self._offlineWaitSeconds = 600
        # 用户空闲超时时间
        self._idleTimeOutSeconds = 600
        # 用户无子弹时超时时间
        self._inactiveTimeOutSeconds = 600
        # 准备倒计时
        self._readySeconds = 5
        # 排名刷新间隔
        self._loopSeconds = 5
        # 初始化定时器
        self._readyTimer = None
        self._startTimer = None
        self._loopTimer = None
        # 比赛技能
        self._matchSkills = None
        # 可用action
        self.actionMap = {
            "robot_leave": self._robotLeave,
            "catch": self._verifyCatch,
            "skill_use": self._skill_use,
            "skill_install": self._skill_install,
            "skill_replace": self._skill_replace,
            "smile": self.doTableSmilies,
            "honor_push": self._honor_push,
            "honor_replace": self._honor_replace,
            "guns_list": self._guns_list,
            "guns_pool": self._guns_pool,
            "treasure_rewards": self._getTreasureRewards,
            "item_use": self.item_use,  # 使用道具技能
        }
        self._logger = Logger()
        self._logger.add("cls=", self.__class__.__name__)
        self._logger.add("gameId", self.gameId)
        self._logger.add("roomId", room.roomId)
        self._logger.add("tableId", tableId)
        self._logger.add("matchId", room.bigmatchId)

    def clearTableData(self):
        """
        清理桌子数据和状态
        """
        # 比赛状态
        self._matchState = MatchState.DEFAULT
        # 比赛桌详情
        self._match_table_info = None
        # 比赛任务数据
        self._usersData = {}

    def clearAllTimer(self):
        """
        清理所有定时器
        """
        if self._logger.isDebug():
            self._logger.debug("clearAllTimer, tableId =", self.tableId)
        if self._readyTimer:
            self._readyTimer.cancel()
            self._readyTimer = None
        if self._startTimer:
            self._startTimer.cancel()
            self._startTimer = None
        if self._loopTimer:
            self._loopTimer.cancel()
            self._loopTimer = None
        if self.bufferFishGroup:
            self.bufferFishGroup.cancelNextGroupTimer()
        if self.multipleFishGroup:
            self.multipleFishGroup.cancelNextGroupTimer()

    def startFishGroup(self):
        """
        启动鱼阵
        """
        if self.runConfig.allNormalGroupIds:
            self.normalFishGroup = NormalFishGroup(self)
        # buffer鱼初始化
        if self.runConfig.allBufferGroupIds:
            self.bufferFishGroup = BufferFishGroup(self)
        # 随机倍率鱼初始化
        if self.runConfig.allMultipleGroupIds:
            self.multipleFishGroup = MultipleFishGroup(self)

    def createPlayer(self, table, seatIndex, clientId):
        """
        新创建Player对象
        """
        return FishTimeMatchPlayer(table, seatIndex, clientId)

    def _doTableManage(self, msg, action):
        """
        处理来自大比赛的table_manage命令
        """
        if action == "m_table_start":
            self.doMatchTableStart(msg)
        elif action == "m_table_info":
            self.doUpdateMatchTableInfo(msg)
        elif action == "m_table_update":
            self.doUpdateMatchRankInfo(msg)
        elif action == "m_table_clear":
            self.doMatchTableClear(msg)
        elif action == "m_table_over":
            self.doMatchOver(msg)
        elif action == "m_user_giveup":
            self.doUserGiveup(msg)
        else:
            super(FishTimeMatchTable, self)._doTableManage(msg, action)

    def doMatchTableStart(self, msg):
        """开始比赛桌子启动"""
        if self._logger.isDebug():
            self._logger.debug("doMatchTableStart", "msg=", msg)
        table_info = msg.getKey("params")

        self._doUpdateTableInfo(table_info)
        self._doMatchQuickStart()  # 开始
        self.bufferFishGroup and self.bufferFishGroup.initGroup(
            self._match_table_info["tableRankRatio"])
        self.multipleFishGroup and self.multipleFishGroup.initGroup(
            self._match_table_info["tableRankRatio"])
        if self._logger.isDebug():
            self._logger.debug("doMatchTableStart, tableId =", self.tableId,
                               "readyTimer =", self._readyTimer)
        if not self._readyTimer:
            self._matchState = MatchState.READY
            self._readyTimer = FTLoopTimer(self._readySeconds, 0,
                                           self._matchStartTime)
            self._readyTimer.start()

        if self._logger.isDebug():
            self._logger.debug("doMatchTableStart OK", "msg=", msg)

    def doUpdateMatchTableInfo(self, msg):
        """更新比赛桌子信息"""
        if self._logger.isDebug():
            self._logger.debug("doUpdateMatchTableInfo", "msg=", msg)
        table_info = msg.getKey("params")
        self._doUpdateTableInfo(table_info)

    def doUpdateMatchRankInfo(self, msg):
        """更新排行榜信息"""
        if self._logger.isDebug():
            self._logger.debug("doUpdateMatchRankInfo", "msg=", msg)
        rank_info = msg.getKey("params")
        self._doUpdateRankInfo(rank_info)

    def doMatchTableClear(self, msg):
        """清理比赛桌子"""
        if self._logger.isDebug():
            self._logger.debug("doMatchTableClear", "msg=", msg)
        params = msg.getKey("params")
        matchId = params.get("matchId", -1)
        if matchId != self.room.bigmatchId:
            self._logger.error("doMatchTableClear", "msg=", msg, "err=",
                               "DiffMatchId")
            return
        self._doMatchTableClear()

    def _doMatchTableClear(self):
        # 清理本桌玩家的在线状态
        for player in self.players:
            if player and player.userId > 0:
                self._clearPlayer(None, player.userId, player.seatId)
        self.clearTableData()
        self.clearAllTimer()

    def doMatchOver(self, msg):
        """比赛完成"""
        if self._logger.isDebug():
            self._logger.debug("doMatchOver", "msg=", msg)
        params = msg.getKey("params")
        matchId = params.get("matchId", -1)
        if matchId != self.room.bigmatchId:
            self._logger.error("doMatchOver", "msg=", msg, "err=",
                               "DiffMatchId")
            return
        self._doMatchTableClear()

    def doUserGiveup(self, msg):
        """放弃比赛"""
        if self._logger.isDebug():
            self._logger.debug("doUserGiveup", "msg=", msg)
        params = msg.getKey("params")
        userId = params.get("userId", -1)
        matchId = params.get("matchId", -1)
        if matchId != self.room.bigmatchId:
            self._logger.error("doUserGiveup", "msg=", msg, "err=",
                               "DiffMatchId")
        player = self.getPlayer(userId)
        from newfish.entity.event import MatchGiveUpEvent
        from newfish.game import TGFish
        event = MatchGiveUpEvent(userId, FISH_GAMEID, self.room.bigmatchId)
        TGFish.getEventBus().publishEvent(event)
        if player:
            self._clearPlayer(None, player.userId, player.seatId)
        if self.playersNum == 0:
            self._doMatchTableClear()

    def _doSit(self, msg, userId, seatId, clientId):
        """
        玩家操作, 尝试再当前的某个座位上坐下
        """
        ret = self._doSitDown(msg, userId, seatId, clientId)
        return ret

    def _doSitDown(self, msg, userId, seatId, clientId):
        """
        比赛牌桌只有玩家断线重连时才会触发坐下操作,既重新坐回牌桌
        """
        if seatId != 0:
            if self.seats[seatId - 1].userId == 0:
                onlinedata.removeOnlineLoc(userId, self.roomId, self.tableId)
                ftlog.warn("reconnect user is cleaned from table", "seats =",
                           self.seats)
                return False
            elif userId != self.seats[seatId - 1].userId:
                onlinedata.removeOnlineLoc(userId, self.roomId, self.tableId)
                ftlog.warn("reconnect user id is not matched", "seats =",
                           self.seats)
                return False
            else:
                ftlog.info("user reconect, userId:", userId)
                onlinedata.addOnlineLoc(userId, self.roomId, self.tableId,
                                        seatId)
                self.players[seatId - 1].offline = 1
                self.players[seatId - 1].clientId = clientId
                self.players[seatId - 1].lang = util.getLanguage(
                    userId, clientId)
                self.players[seatId - 1].refreshGunSkin()
                self._sendTableInfo(userId, seatId)
                self._updateMatchInfo(userId)
                self._updateMatchRank(userId)
                self._updateMatchTask(userId)
                self.players[seatId - 1].dealEnterTable()
                self.players[seatId - 1].enterTime = int(time.time())
                self.players[seatId - 1].offline = 0
                from newfish.game import TGFish
                event = EnterTableEvent(userId, FISH_GAMEID, self.roomId,
                                        self.tableId, seatId, 1)
                TGFish.getEventBus().publishEvent(event)
                return True
        else:
            for i in range(len(self.seats)):
                if self.seats[i].userId == userId:
                    ftlog.info("lost user reconect, userId:", userId, "i =", i)
                    onlinedata.addOnlineLoc(userId, self.roomId, self.tableId,
                                            i + 1)
                    self.players[i].offline = 1
                    self.players[i].clientId = clientId
                    self.players[i].lang = util.getLanguage(userId, clientId)
                    self.players[i].refreshGunSkin()
                    self._sendTableInfo(userId, i + 1)
                    self._updateMatchInfo(userId)
                    self._updateMatchRank(userId)
                    self._updateMatchTask(userId)
                    self.players[i].dealEnterTable()
                    self.players[i].enterTime = int(time.time())
                    self.players[i].offline = 0
                    from newfish.game import TGFish
                    event = EnterTableEvent(userId, FISH_GAMEID, self.roomId,
                                            self.tableId, seatId, 1)
                    TGFish.getEventBus().publishEvent(event)
                    return True

    def _doUpdateTableInfo(self, tableInfo):
        """比赛参数|获取比赛技能"""
        self._match_table_info = tableInfo
        self._matchSkills = self._match_table_info.get("skills")

    def _doUpdateRankInfo(self, rankInfo):
        """更新排名信息"""
        seats = rankInfo["seats"]
        for seat in seats:
            userId = seat["userId"]
            rank = seat["rank"]
            player = self.getPlayer(userId)
            if player:
                player.rank = rank
                self._updateMatchRank(userId)

    def _doMatchQuickStart(self):
        """比赛快速开始"""
        seats = self._match_table_info["seats"]
        for seat in seats:
            userId = seat["userId"]
            seatId = seat["seatId"]
            clientId = util.getClientId(userId)
            player = self.getPlayer(userId)
            if not player:
                self.doMatchSitDown(userId, seatId, clientId)
                player = self.getPlayer(userId)
                if player:
                    player.currentTask = [
                        "time_match", self.roomId, 1,
                        copy.deepcopy(self._match_table_info["targets"])
                    ]
                    self._usersData[userId] = {
                        "uid": userId,
                        "targets":
                        copy.deepcopy(self._match_table_info["targets"]),
                        "results": {}
                    }

    def doMatchSitDown(self, userId, seatId, clientId):
        """比赛入座"""
        self.seats[seatId - 1].userId = userId
        self.players[seatId - 1] = self.createPlayer(self, seatId - 1,
                                                     clientId)  # 创建玩家
        self.players[seatId -
                     1].clip = self._match_table_info["bullet"]  # 玩家子弹
        onlinedata.addOnlineLoc(userId, self.roomId, self.tableId, seatId)
        self._sendTableInfo(userId, seatId)  # 发送table_info
        self._broadcastPlayerSit(userId, seatId)  # 广播玩家坐下
        self.players[seatId - 1].enterTime = int(time.time())
        self.players[seatId - 1].offline = 0
        from newfish.game import TGFish
        event = EnterTableEvent(userId, FISH_GAMEID, self.roomId, self.tableId,
                                seatId)
        TGFish.getEventBus().publishEvent(event)
        bireport.reportGameEvent("BI_NFISH_TABLE_ENTER", userId, FISH_GAMEID,
                                 self.roomId, self.tableId,
                                 self.players[seatId - 1].level, 0, 0, 0, [],
                                 clientId)

    def getCostBullet(self, gunId, gunLevel, wpConf, clientId):
        """获取消耗的子弹"""
        costBullet = 1
        return costBullet

    def _broadcastPlayerLeave(self, userId, seatId):
        """广播玩家离开"""
        msg = MsgPack()
        msg.setCmd("leave")
        msg.setResult("gameId", FISH_GAMEID)
        msg.setResult("userId", userId)
        msg.setResult("seatId", seatId)
        GameMsg.sendMsg(msg, self.getBroadcastUids(userId))

    def _matchStartTime(self):
        """
        比赛开始,设置比赛结束时间点和更新排名机制
        """
        self._matchState = MatchState.START
        for player in self.players:
            if player:
                self._updateMatchInfo(player.userId)
                self._updateMatchRank(player.userId)
        if self._logger.isDebug():
            self._logger.debug("_matchStartTime, tableId =", self.tableId,
                               "startTimer =", self._startTimer, "loopTimer =",
                               self._loopTimer)
        self._startTimer = FTLoopTimer(self.runConfig.playingTime, 0,
                                       self._matchTimeUp)
        self._startTimer.start()
        self._loopTimer = FTLoopTimer(self._loopSeconds, -1,
                                      self._matchUpdateRank)
        self._loopTimer.start()

    def _matchTimeUp(self):
        """
        比赛结束,处理结果,清理玩家
        """
        if self._loopTimer:
            self._loopTimer.cancel()
        self._matchState = MatchState.END
        FTLoopTimer(0.5, 0, self.room.matchPlugin.doWinLose, self.room,
                    self).start()
        for player in self.players:
            if player and player.userId:
                player.clearTimer()

    def _matchUpdateRank(self):
        """
        定时更新排名机制
        """
        if self.getRobotUserCount() == self.playersNum:
            for player in self.players:
                if player and player.userId <= config.ROBOT_MAX_USER_ID:
                    maxScore = int(self._match_table_info["bullet"] * 1.2)
                    score = random.randint(maxScore / 2, maxScore)
                    gainChip = score / (self.runConfig.playingTime / 5)
                    player.catchBudget(gainChip, 0, [])
        self.room.matchPlugin.doUpdate(self.room, self)
        if int(self._startTimer.getTimeOut()) <= self._loopSeconds:
            self._loopTimer.cancel()

    def _updateMatchInfo(self, userId):
        """更新比赛信息"""
        player = self.getPlayer(userId)
        if player and player.userId:
            msg = MsgPack()
            msg.setCmd("m_info")
            msg.setResult("gameId", FISH_GAMEID)
            msg.setResult("roomId", self.roomId)
            msg.setResult("tableId", self.tableId)
            msg.setResult("seatId", player.seatId)
            msg.setResult("userId", player.userId)
            msg.setResult("timeLong", self.runConfig.playingTime)
            msg.setResult(
                "timeLeft",
                int(self._startTimer.getTimeOut())
                if self._startTimer else self.runConfig.playingTime)
            msg.setResult("targets", self._match_table_info["targets"])
            GameMsg.sendMsg(msg, player.userId)

    def _updateMatchRank(self, userId):
        """比赛排名"""
        player = self.getPlayer(userId)
        if player and player.userId and self._match_table_info:
            msg = MsgPack()
            msg.setCmd("m_update")
            msg.setResult("gameId", FISH_GAMEID)
            msg.setResult("roomId", self.roomId)
            msg.setResult("tableId", self.tableId)
            msg.setResult("seatId", player.seatId)
            msg.setResult("userId", player.userId)
            msg.setResult("rank",
                          [player.rank, self._match_table_info["playerCount"]])
            GameMsg.sendMsg(msg, player.userId)

    def _updateMatchTask(self, userId):
        """更新比赛任务"""
        player = self.getPlayer(userId)
        usersData = self._usersData.get(userId, {})
        if player and usersData and usersData["results"]:
            msg = MsgPack()
            msg.setCmd("m_task")
            msg.setResult("gameId", FISH_GAMEID)
            msg.setResult("roomId", self.roomId)
            msg.setResult("tableId", self.tableId)
            msg.setResult("seatId", player.seatId)
            msg.setResult("userId", player.userId)
            msg.setResult("targets", usersData["results"])
            GameMsg.sendMsg(msg, player.userId)

    def getProbbCoefficient(self, player, fishInfo):
        """概率基数"""
        if fishInfo["type"] in [3, 21] or fishInfo["multiple"] > 1:
            j1 = player.matchLuckyValue / 7500.0 + 1.0 / 3
            c = self._match_table_info["realPlayerCount"]
            k = float(4 * c) / (3 * c - 1)
            b = 1 - float(2 * c) / (3 * c - 1)
            j2 = 1  #k * min(player.rank, c) / c + b
            j = (j1 + j2) * 0.5
            if ftlog.is_debug():
                ftlog.debug("getProbbCoefficient", player, fishInfo,
                            "luckyValue =", player.matchLuckyValue, "rank =",
                            player.rank, "j1 =", j1, "c =", c, "k =", k, "b =",
                            b, "j2 =", j2, "j =", j)
            return j
        return 1

    def dealKillFishGain(self,
                         fId,
                         player,
                         fpMultiple,
                         gunMultiple=1,
                         bufferCoinAdd=1,
                         wpType=None,
                         extends=None,
                         gunX=1):
        """
        处理打死鱼获得的奖励
        :param fId: 被捕获鱼的ID
        :param player: 捕鱼者
        :param fpMultiple: 渔场倍率
        :param gunMultiple: 炮的倍率
        :param bufferCoinAdd: buffer加成金币系数
        :param wpType: 武器类型
        :param extends: 扩展数据
        :param gunX: 炮的倍数
        """
        gainChip = 0
        gain = []
        gainMap = {}
        fishType = self.fishMap[fId]["fishType"]
        fixedMultiple = self.fishMap[fId]["multiple"]
        fishConf = config.getMatchFishConf(fishType)
        if fishConf["score"] > 0:
            gainMap["fId"] = fId
            gainMap["fishType"] = fishType
            taskMultiple = 1
            target1 = self._match_table_info["targets"].get("target1", 0)
            target2 = self._match_table_info["targets"].get("target2", 0)
            multipleTarget1 = 14000 + target1 % 11000
            multipleTarget2 = 14000 + target2 % 11000
            if fishType == target1 or fishType == target2 or \
               fishType == multipleTarget1 or fishType == multipleTarget2:
                taskMultiple = fishConf.get("multiple", 1)
            if fishConf["type"] in config.MULTIPLE_FISH_TYPE:
                multiple = self.getMultipleFishMultiple(
                    player, fishConf, fpMultiple, gunMultiple, gunX)
                gainMap["itemId"] = CHIP_KINDID
                gainMap["count"] = int(fishConf["score"] * fpMultiple * gunX *
                                       taskMultiple * multiple * bufferCoinAdd)
                gainMap["fishMultiple"] = multiple
                gainChip = int(gainMap["count"])
                gain.append(gainMap)
            else:
                gainMap["itemId"] = CHIP_KINDID
                gainMap["count"] = int(fishConf["score"] * fpMultiple * gunX *
                                       taskMultiple * fixedMultiple *
                                       bufferCoinAdd)
                gainChip = int(gainMap["count"])
                gain.append(gainMap)
        else:
            if fishConf["type"] in config.BUFFER_FISH_TYPE:  # 捕获buffer鱼
                bufferId = player.getCatchBufferId(fishConf["itemId"])
                if bufferId > 0:
                    gainMap["fId"] = fId
                    gainMap["fishType"] = fishType
                    gainMap["itemId"] = bufferId
                    gainMap["count"] = 1
                gain.append(gainMap)
        return gainChip, gain, 0

    def getMultipleFishMultiple(self, player, fishConf, fpMultiple,
                                gunMultiple, gunX):
        """
        获得倍率鱼的倍率
        """
        randInt = random.randint(1, 10000)
        for multipleMap in config.getMatchMultipleFishConf(
                self.runConfig.fishPool, player.matchLuckyValue):
            probb = multipleMap["probb"]
            if probb[0] <= randInt <= probb[-1]:
                return multipleMap["multiple"]
        return 1

    def _verifyCatch(self, msg, userId, seatId):
        if self._matchState == MatchState.END:
            return
        super(FishTimeMatchTable, self)._verifyCatch(msg, userId, seatId)

    def dealCatch(self,
                  bulletId,
                  wpId,
                  player,
                  catch,
                  gain,
                  gainChip,
                  exp,
                  fpMultiple,
                  extends=None,
                  skillId=0,
                  stageId=0,
                  isFraud=False,
                  skillType=0):
        """处理捕获"""
        if self._matchState == MatchState.END:
            return
        self._retVerifyCatch(player,
                             bulletId,
                             catch,
                             gain,
                             extends,
                             skillId,
                             stageId,
                             fpMultiple,
                             isFraud=isFraud,
                             skillType=skillType)
        gainCoupon = 0
        items = []
        for gainMap in gain:
            fishConf = config.getFishConf(gainMap["fishType"], self.typeName,
                                          fpMultiple)
            if fishConf["type"] in config.BUFFER_FISH_TYPE:
                player.addOneBufferId(gainMap["itemId"])
            if fishConf["type"] in config.LOG_OUTPUT_FISH_TYPE:
                ftlog.info("dealCatch->fishType", "userId =", player.userId,
                           "fishType =", fishConf["type"], "wpId =", wpId,
                           "gainMap =", gainMap, "gainChip =", gainChip)
        player.catchBudget(gainChip, gainCoupon, items, wpId=wpId)
        self._afterCatch(bulletId,
                         wpId,
                         player,
                         catch,
                         gain,
                         gainChip,
                         fpMultiple,
                         extends,
                         skillType=skillType)

    def _afterCatch(self,
                    bulletId,
                    wpId,
                    player,
                    catch,
                    gain,
                    gainChip,
                    fpMultiple,
                    extends=None,
                    skillId=0,
                    isFraud=False,
                    skillType=0,
                    catchFishMultiple=None):
        """捕获之后"""
        fishTypes = []
        for catchMap in catch:
            if catchMap["reason"] == 0:
                fId = catchMap["fId"]
                self.setFishDied(fId)
                fishType = self.fishMap[fId]["fishType"]
                fishTypes.append(fishType)
        event = CatchEvent(player.userId, FISH_GAMEID, self.roomId,
                           self.tableId, fishTypes, wpId, gainChip, fpMultiple)
        self._dealCatchEvent(event)

    def _dealCatchEvent(self, event):
        """处理捕获事件"""
        if event.tableId == self.tableId:
            usersData = self._usersData.get(event.userId, {})
            if not usersData:
                ftlog.debug("_dealCatchEvent->invalid userId", event.userId)
                return
            fishTypes = event.fishTypes
            targets = usersData["targets"]
            target1 = targets.get("target1", 0)
            multipleTarget1 = 14000 + target1 % 11000
            target2 = targets.get("target2", 0)
            multipleTarget2 = 14000 + target2 % 11000
            if (target1 in fishTypes or multipleTarget1
                    in fishTypes) and target1 not in usersData["results"]:
                usersData["results"][target1] = 0
            if (target2 in fishTypes or multipleTarget2
                    in fishTypes) and target2 not in usersData["results"]:
                usersData["results"][target2] = 0
            if target1 in fishTypes or multipleTarget1 in fishTypes:
                score = fishTypes.count(target1) + fishTypes.count(
                    multipleTarget1)
                usersData["results"][target1] += score
            if target2 in fishTypes or multipleTarget2 in fishTypes:
                score = fishTypes.count(target2) + fishTypes.count(
                    multipleTarget2)
                usersData["results"][target2] += score
            self._updateMatchTask(event.userId)
示例#5
0
class FishGroup(object):
    """
    鱼群对象
    """
    def __init__(self,
                 conf,
                 enterTime,
                 serverGroupId,
                 startFishId,
                 position=None,
                 gameResolution=None,
                 deadCallback=None):
        """
        :param conf: 鱼阵配置文件 {"id": "autofill_11092_21_3", "fishes": [{"fishType": 11092, "enterTime": 0.0, "exitTime": 25.0}], "totalTime": 25.0}
        :param enterTime: 该鱼群入场时间(渔场运行后的第n秒)
        :param serverGroupId: 鱼群ID(每新增一个鱼群自增加1)
        :param startFishId: 该鱼群第一条鱼的鱼ID
        :param position: 指定出现位置
        :param gameResolution: 召唤该鱼群的玩家的游戏分辨率
        :param deadCallback: 鱼群死亡回调函数
        """
        self.position = position if position else [0, 0]
        self.gameResolution = gameResolution if gameResolution else []
        self.enterTime = enterTime
        self.startFishId = startFishId
        # 鱼群文件名字
        self.id = conf.get("id")
        # 鱼群自增ID
        self.serverGroupId = serverGroupId
        # 鱼群类型
        self.type = self.id.split("_")[1] if self.id.startswith(
            "call_") else self.id.split("_")[0]
        # 鱼群存活时间
        self.totalTime = conf.get("totalTime")
        # 鱼群中的所有鱼
        self.fishes = conf.get("fishes")
        # 鱼群中鱼的数量
        self.fishCount = len(self.fishes)
        # 该鱼群的出场时间
        self.exitTime = self.enterTime + self.totalTime
        # 该鱼群最后一条鱼的鱼ID
        self.endFishId = startFishId + self.fishCount - 1
        self.maxEnterTime = self._getMaxEnterTime()
        # 该鱼群是否已被清除
        self.isClear = False
        # 鱼群被冰冻后延长的存活时间
        self.addTime = 0
        # Boss鱼群延迟出现时间
        self.extendGroupTime = 0
        # 鱼群死亡定时器
        self.deadTimer = None
        # 鱼群死亡回调
        self.deadCallback = deadCallback
        if self.deadCallback:
            self.deadTimer = FTLoopTimer(self.totalTime, 0, self.deadCallback,
                                         self)
            self.deadTimer.start()

    def clear(self):
        """
        清除定时器等数据
        """
        if self.deadTimer:
            self.deadTimer.cancel()
            self.deadTimer = None
        self.isClear = True

    def isExist(self, nowTableTime):
        """
        该鱼群在当前时刻是否存在
        """
        return self.enterTime <= nowTableTime <= self.exitTime + self.addTime

    def fishExist(self, nowTableTime, fishId):
        """
        该鱼群中是否存在某条鱼
        """
        fish = self.fishes[fishId - self.startFishId]
        enterTime = self.enterTime + fish["enterTime"]
        exitTime = self.enterTime + fish["exitTime"] + self.addTime
        return enterTime <= nowTableTime <= exitTime

    def isAlive(self, nowTableTime, table=None):
        """
        该鱼群是否存活(包含特殊鱼及已生成但即将出现的鱼群)
        """
        # 客户端特殊处理的鱼群且鱼群中鱼的数量不多时,判断鱼群是否存活看其中鱼的存活状态
        if table and self.type in SPECIAL_ALIVE_TYPE:
            for fId in xrange(self.startFishId, self.endFishId + 1):
                isOK = table.findFish(fId)
                if isOK:
                    return isOK
            return False
        # 一般鱼群,判断鱼群是否存活看鱼群的整体退出时间,因为其中鱼的数量过多,避免循环查找
        return nowTableTime < self.exitTime + self.addTime

    def isVisible(self, table, userId):
        """
        该鱼群对某玩家是否可见
        """
        # 新手任务期间玩家自己可见的鱼.
        if self.type == "share" or self.type == "newbie" or self.type == "coupon" \
                or self.id.startswith("tuition_44499") or self.id.startswith("autofill_72025"):
            for fId in xrange(self.startFishId, self.endFishId + 1):
                if fId in table.fishMap:
                    if table.fishMap[fId]["owner"] is None or table.fishMap[
                            fId]["owner"] == userId:
                        sendUsersList = table.fishMap[fId].get("sendUsersList")
                        if not sendUsersList or userId in sendUsersList:
                            return True
                        break
            return False
        return True

    def isCleared(self):
        """
        该鱼群是否已被清除
        """
        return self.isClear

    def _getMaxEnterTime(self):
        """
        获得该鱼群最后一条鱼在该鱼阵文件中的入场时间
        """
        fishEnterTimes = []
        for fish in self.fishes:
            fishEnterTimes.append(fish.get("enterTime"))
        fishEnterTimes.sort()
        return fishEnterTimes[-1]

    def getNextGroupTime(self):
        """
        获得下个鱼群的入场时间
        """
        return round(self.maxEnterTime + self.enterTime, 2)

    def desc(self):
        """
        鱼群详情
        """
        info = [
            str(self.id), "enter:",
            str(self.enterTime), "exit:",
            str(self.exitTime), "startfishId:",
            str(self.startFishId), "endFishId:",
            str(self.endFishId), "addTime:",
            str(self.addTime)
        ]
        info = " ".join(info)
        return info

    def adjust(self, addTime):
        """
        调整鱼群存活时间
        """
        self.addTime += addTime
        self.extendGroupTime += addTime
        if self.deadTimer:
            interval = self.deadTimer.getTimeOut() + self.addTime
            if interval > 0:
                self.deadTimer.reset(interval)

    def getFishExitTime(self, fishType):
        """
        获取指定一条鱼的离场时间
        """
        for fish in self.fishes:
            if fishType == fish["fishType"]:
                return fish["exitTime"]
        return 0
示例#6
0
    )  # {'GT0044001_999': [441011001, 441021001, 441031001, 441041001, 443011001, 443021001, 444021001, 444031001, 444041001, 444051001, 444111001, 444121001, 444141001, 444151001, 444991001, 445011001, 446011001]}
    ftlog.info('zzzzzz', gdata.allServersMap())


import freetime.util.log as ftlog
from freetime.core.timer import FTLoopTimer
from poker.entity.configure import gdata


def _main1():
    ftlog.info('ssssss')


a = FTLoopTimer(20, -1, _main1)
a.start()
ftlog.info('cccccc', a.getTimeOut())
a.reset(30)
ftlog.info('dddddd', a.getTimeOut())

import freetime.util.log as ftlog
from poker.entity.configure import gdata
# ftlog.info('111111111111', gdata.rooms().keys())
# [441011001, 441021001, 441031001, 441041001, 443011001, 443021001, 444021001, 444031001, 444041001, 444051001, 444111001, 444121001, 444141001, 444151001, 444991001, 445011001, 446011001]
room = gdata.rooms()[444111001]
# ftlog.info('111111111111', room.maptable.keys())
# [4410410010001, 4410410010002, 4410410010003, 4410410010004, 4410410010005, 4410410010006, 4410410010007, 4410410010008, 4410410010009, 4410410010010]
table = room.maptable[4410110010001]
ftlog.info('111111111111', table.runConfig.allSuperBossGroupIds)

import freetime.util.log as ftlog
from freetime.core.timer import FTLoopTimer