Esempio n. 1
0
    def _calc_query_player_info(self, data, req, timer):
        #
        if not account_business.update_across_day_info(data, timer.now):
            raise Exception("Update across day info failed")
        
        plunder = data.plunder.get()
        rival_id = plunder.get_plunder_rival_id(req.user_id)
        if rival_id != 0:
            #在之前匹配的4个rival中,直接打包返回
            rival = data.rival_list.get(rival_id)
            defer = Deferred()
            if rival.union_id != 0:
                defer.addCallback(self._query_union_info, data, plunder, rival, req, timer)
            else:
                defer.addCallback(self._pack_query_player_response, data, plunder, rival, req, timer)

            defer.addErrback(self._query_player_failed, req, timer)
            defer.callback(0)
        else:

            rival_id = plunder.generate_specify_rival_id()
            rival = data.rival_list.get(rival_id)
            if rival is None:
                rival = RivalInfo.create(rival_id, data.id)
                data.rival_list.add(rival)

            #去新匹配
            user = data.user.get(True)
            plunder = data.plunder.get()
            invalid_rival = [data.id]
            plunder_matcher = PlunderMatcher(user.level, invalid_rival)
            defer = plunder_matcher.match_specify(data, plunder, req.user_id, user.country)
            defer.addCallback(self._query_union_info, data, plunder, rival, req, timer)

        return defer
Esempio n. 2
0
def _update_anneal_rival(data, anneal, type, floor, level):
    rival_id = anneal.generate_anneal_rival_id(type)
    rival = data.rival_list.get(rival_id)
    if rival is None:
        rival = RivalInfo.create(rival_id, data.id)
        data.rival_list.add(rival)

    #enemy的level
    level = anneal.get_anneal_enemy_level(type, floor, level)

    if anneal.get_hrad_attack_remain_num(
            floor) == 0 and 'is_open_new_anneal' in utils.get_flags():
        #在开启flag的情况下,最后一次为保底掉落
        at_least = True
    else:
        at_least = False

    #战斗pve随机奖励
    spoils = reward_module.random_anneal_spoils(level, type, at_least=at_least)
    logger.notice("SPOILS: %s" % spoils)

    #资源奖励
    (reward_money, reward_food) = calc_resource_income(level)

    rival.set_anneal(level, reward_money, reward_food, spoils)
    return True
Esempio n. 3
0
def _default_start_battle(data, dungeon, battle_level, now):
    """默认开始战斗方法"""
    user = data.user.get(True)
    status = dungeon.status(user.level, now)
    if status != dungeon.ACTIVE:
        return dungeon_pb2.DUNGEON_NOT_OPEN
    if dungeon.get_remain_num() <= 0:
        return dungeon_pb2.DUNGEON_NO_ENTER_NUM

    node_basic_id = dungeon.node_basic_id()
    node_id = NodeInfo.generate_id(data.id, node_basic_id)
    node = data.node_list.get(node_id)
    if node is None:
        node = NodeInfo.create(data.id, node_basic_id)
        data.node_list.add(node)
    
    node.set_expand_dungeon()

    user = data.user.get(True)
    rival = data.rival_list.get(node_id)
    if rival is None:
        rival = RivalInfo.create(node_id, data.id)
        data.rival_list.add(rival)

    rival.set_expand_dungeon(dungeon.basic_id, dungeon.level(user.level), battle_level)

    return dungeon_pb2.DUNGEON_OK
Esempio n. 4
0
    def _calc_query_pvp_players(self, data, req, timer):
        user = data.user.get()
        if not user.allow_pvp:
            raise Exception("PVP is not unlock[user_level=%d]" % user.level)

        if not account_business.update_across_day_info(data, timer.now, True):
            logger.warning("Update across day info failed")
            return False

        user = data.user.get(True)
        resource = data.resource.get()
        invalid_rival = [data.id]
        plunder_matcher = PlunderMatcher(user.level, invalid_rival)
        plunder = data.plunder.get()

        #刷新扣除金钱
        if req.HasField("cost_money"):
            resource.cost_money(req.cost_money)

        if req.type == 1: #掠夺
            plunder_matcher.add_condition(data, plunder)
            #匹配对手
            defer = plunder_matcher.match(plunder, user.country)
            defer.addCallback(self._pack_pvp_players_response,
                data, plunder, plunder_matcher, req, timer)
            return defer

        elif req.type == 2:  #仇家
            res = map_pb2.QueryPlayersRes()
            res.status = 0

            plunder_business.update_plunder_enemy(data) 
            plunder_enemy_list = data.plunder_record_list.get_all()
            for plunder_enemy in plunder_enemy_list:
                pack.pack_plunder_record(plunder_enemy, res.players.add())

            res.attack_num = plunder.attack_num
            res.left_reset_num = plunder.get_left_reset_num()

            defer = DataBase().commit(data)
            defer.addCallback(self._query_pvp_players_succeed, req, res, timer)
            return defer


        elif req.type == 3: #指定查询
            rival_id = plunder.generate_specify_rival_id()
            rival = data.rival_list.get(rival_id)
            if rival is None:
                rival = RivalInfo.create(rival_id, data.id)
                data.rival_list.add(rival)

            #查询对手
            defer = plunder_matcher.query_specify_user(req.str, rival)
            defer.addCallback(self._pack_pvp_players_response,
                data, plunder, plunder_matcher, req, timer)

            return defer
Esempio n. 5
0
def _update_worldboss_rival(data, worldboss, node_id=None):
    user = data.user.get(True)
    rival_id = node_id if node_id is not None else worldboss.node_id
    rival = data.rival_list.get(rival_id)
    if rival is None:
        rival = RivalInfo.create(rival_id, data.id)
        data.rival_list.add(rival)

    #enemy的level
    spoils = reward_module.random_pve_spoils(user.level)
    rival.set_worldboss(user.level, spoils)
    logger.debug("update worldboss rival[rival_id=%d]" % rival_id)

    return True
Esempio n. 6
0
def start_battle(data, teams, heroes, rival_user_id, rival, now, force=False):
    """开始战斗
    """
    user = data.user.get(True)
    union = data.union.get()
    node_id = NodeInfo.generate_id(data.id,
                                   union.get_battle_mapping_node_basic_id())
    battle = data.battle_list.get(node_id)
    if battle is None:
        battle = BattleInfo.create(node_id, data.id)
        data.battle_list.add(battle)
    node = data.node_list.get(node_id)
    if node is None:
        node = NodeInfo.create(data.id,
                               union.get_battle_mapping_node_basic_id())
        data.node_list.add(node)
    r = data.rival_list.get(node_id)
    if r is None:
        r = RivalInfo.create(node_id, data.id)
        data.rival_list.add(r)

    #标记敌对玩家
    r.set_union_battle_enemy_detail(rival_user_id, rival)

    #消耗攻击次数
    union.consume_battle_attack()

    #消耗粮草
    resource = data.resource.get()
    resource.update_current_resource(now)
    need_food = battle_business._calc_food_consume(heroes)
    if not resource.cost_food(need_food):
        return False
    battle.set_food_consume(need_food)

    #消耗兵力
    if not battle_business._consume_soldier(data, battle, now, heroes, force):
        return False

    #计算战利品
    reward_money = 0
    reward_food = 0
    reward_user_exp = 0
    reward_hero_exp = data_loader.MonarchLevelBasicInfo_dict[
        user.level].heroBattleExp
    reward_items = reward_module.random_battle_gift(user.level)
    battle.set_reward(reward_money, reward_food, reward_hero_exp,
                      reward_user_exp, reward_items)

    return battle.start(None, r, None, teams, heroes, now, user.vip_level)
Esempio n. 7
0
    def match(self, data, city_id, rival_id, is_robot, position_level, now):
        """进行匹配
        """
        legendcity = data.legendcity_list.get(LegendCityInfo.generate_id(data.id, city_id))
        rival = data.rival_list.get(legendcity.node_id)
        if rival is None:
            logger.debug("Create rival for legendcity[rival_id=%d]" % legendcity.node_id)
            rival = RivalInfo.create(legendcity.node_id, data.id)
            data.rival_list.add(rival)
        self.player = rival
        self.now = now
        self.position_level = position_level

        if is_robot:
            return self._match_robot(city_id, rival_id)
        else:
            return self._match_user(city_id, rival_id)
Esempio n. 8
0
    def add_condition(self, data, plunder):
        """提供匹配条件,发起一次搜索
        """
        rivals_id = plunder.generate_plunder_rivals_id()
        for rival_id in rivals_id:
            rival = data.rival_list.get(rival_id)
            if rival is None:
                rival = RivalInfo.create(rival_id, data.id)
                data.rival_list.add(rival)

            guard = data.guard_list.get_all()[0]
            (score_min, score_max) = (max(500, int(guard.score * 0.7)), max(2000, int(guard.score * 1.1)))
            rival.set_pvp_matching_condition(NodeInfo.ENEMY_TYPE_PVP_CITY,
                    #node.rival_score_min, node.rival_score_max, True)
                    score_min, score_max, True)
            self._pvp_players.append(rival)
            logger.debug("Add pvp city rival match condition[score_min=%d][score_max=%d]"
                   % (score_min, score_max))

            self.players[rival.id] = rival
Esempio n. 9
0
    def _set_rivals_info(self, proxy, data, arena, rivals, users, heroes_id, tech_basic_ids):

        rivals_user_id = []
        rivals_battle_score = []
        rivals_score = []
        rivals_info = []
        for i in rivals:
            rival = rivals[i]
            #对手阵容中英雄信息
            rival_heroes = []
            heroes_id = rival.get_heroes_id()
            for hero_id in heroes_id:
                if hero_id == 0:
                    rival_heroes.append(None)
                else:
                    hero = proxy.get_result("hero", hero_id)
                    rival_heroes.append(hero)

            spoils = reward_module.random_pve_spoils(users[rival.rival_id].level)
            rival.set_pvp_enemy_detail(users[rival.rival_id], rival_heroes,
                    items = spoils,
                    technology_basic_ids = tech_basic_ids[rival.rival_id])
            rivals_user_id.append(rival.rival_id)
            rivals_battle_score.append(rival.score)
            rivals_score.append(rival.win_score)
            rivals_info.append(rival)

        #演武场搜出来的对手不足3人,pve补上
        rivals_id = arena.generate_arena_rivals_id()
        pve_user_id = 0    #rival为pve类型的user_id
        for i in range(3 - len(rivals)):
            rival_id = rivals_id[i + len(rivals)]
            rival = data.rival_list.get(rival_id)
            if rival is None:
                rival = RivalInfo.create(rival_id, data.id)
                data.rival_list.add(rival)

            #pve匹配的战力范围
            key = data.user.get(True).level - 3 #演武场需主公17级才开启
            match_info = data_loader.KeyNodeMatchBasicInfo_dict[key]

            rival.set_pve_matching_condition(NodeInfo.ENEMY_TYPE_ARENA,
                    match_info.enemyScoreMin, match_info.enemyScoreMax)

            #创建pve arena数据
            self_score = ArenaInfo.get_real_score(arena.score)
            pve_rival_score = random.randint(int(0.8 * self_score), int(1.2 * self_score)) #pve对手随机积分
            pve_arena = ArenaInfo()
            pve_arena.add_score(pve_rival_score)
            pve_arena.update_index(data.user.get(True).level)
            pve_arena_ranking = 9999 #pve的rival排名随意给个很大的名次
            arena_buff_id = pve_arena.calc_arena_buff_id(pve_arena_ranking)

            #只计算我方积分变化
            (self_win_score, self_lose_score) = arena_business.calc_battle_score(arena, pve_rival_score)
            rival.set_arena(pve_user_id, 0, '', pve_rival_score,
                    pve_arena_ranking, arena_buff_id,
                    self_win_score, self_lose_score)
            logger.debug("arena rival(pve):[user_id=%d][arena_score=%d][arena_ranking=%d]"
                    "[arena_buff_id=%d][self_win_score=%d][self_lose_score=%d]"
                    % (pve_user_id, pve_rival_score,
                        pve_arena_ranking, arena_buff_id,
                        self_win_score, self_lose_score))

            self._match_one_pve(rival, pve_user_id)

            rivals_user_id.append(pve_user_id)
            rivals_battle_score.append(rival.score)
            rivals_score.append(rival.win_score)
            rivals_info.append(rival)
            pve_user_id += 1    #若pve有多个,保证user_id不重

        rivals_user_id_origin = copy.copy(rivals_user_id)

        #rivals_user_id按照rivals_score的高低排序
        for i in range(len(rivals_score)):
            for j in range(i + 1, len(rivals_score)):
                if rivals_score[i] < rivals_score[j]:
                    #互换积分
                    tmp1 = rivals_score[j]
                    rivals_score[j] = rivals_score[i]
                    rivals_score[i] = tmp1
                    #互换rival user id
                    tmp2 = rivals_user_id[j]
                    rivals_user_id[j] = rivals_user_id[i]
                    rivals_user_id[i] = tmp2
                    #互换rival battle_score
                    tmp3 = rivals_battle_score[j]
                    rivals_battle_score[j] = rivals_battle_score[i]
                    rivals_battle_score[i] = tmp3

        arena.set_arena_rivals_user_id(rivals_user_id_origin)
        #根据情况从三个对手中选择出一个对手
        if not arena.choose_rival((data.guard_list.get_all(True))[0].get_team_score(),
                rivals_user_id, rivals_score, rivals_user_id_origin, rivals_battle_score):
            logger.warning("Arena choose rival error")
            return False

        return True
Esempio n. 10
0
    def _select_teams(self, proxy, data, arena, users_id, users_arena, users_arena_ranking):
        """查team信息
        """
        cache_proxy = DataProxy()
        users = {}
        users_id_usable = []
        guards = {}
        tech_basic_ids = {}
        heroes_id = {}
        for user_id in users_id:
            user_result = proxy.get_result("user", user_id)
            if not user_result.allow_pvp_arena:
                #若恰好匹配到演武场还未开启的玩家,则跳过
                continue

            guard_result = proxy.get_result("guard", user_id)
            if guard_result is None:
                continue

            users[user_id] = user_result
            users_id_usable.append(user_id)
            guards[user_id] = guard_result    #目前只有一个防守阵容

            results = proxy.get_all_result("technology")
            battle_technologys = []
            for result in results:
                if (result.user_id == user_id and not result.is_upgrade
                        and result.is_battle_technology()):
                    battle_technologys.append(result.basic_id)
            tech_basic_ids[user_id] = battle_technologys

            heroes_id[user_id] = utils.split_to_int(guards[user_id].teams_hero)
            for hero_id in heroes_id[user_id]:
                if hero_id != 0:
                    cache_proxy.search("hero", hero_id)

        #设置rival的演武场信息
        rivals = {}
        rivals_id = arena.generate_arena_rivals_id()
        for i in range(len(users_id_usable)):
            user_id = users_id_usable[i]
            rival_id = rivals_id[i]
            rival = data.rival_list.get(rival_id)
            if rival is None:
                rival = RivalInfo.create(rival_id, data.id)
                data.rival_list.add(rival)
            rivals[rival_id] = rival

            user_arena = users_arena[user_id]
            battle_score = guards[user_id].get_team_score()
            heroes = utils.join_to_string(heroes_id[user_id])
            #计算积分变化
            (self_win_score, self_lose_score) = arena_business.calc_battle_score(
                    arena, ArenaInfo.get_real_score(user_arena.score))
            (rival_win_score, rival_lose_score) = arena_business.calc_battle_score(
                    user_arena, ArenaInfo.get_real_score(arena.score))

            arena_buff_id = user_arena.calc_arena_buff_id(users_arena_ranking[user_id])
            rival.set_arena(user_id, battle_score, heroes,
                    ArenaInfo.get_real_score(user_arena.score),
                    users_arena_ranking[user_id], arena_buff_id,
                    self_win_score, self_lose_score)
            logger.debug("arena rival:[user_id=%d][battle_score=%d][heroes=%s][arena_score=%d]"
                    "[arena_ranking=%d][arena_buff_id=%d][self_win_score=%d][self_lose_score=%d]"
                    "[rival_win_score=%d][rival_lose_score=%d]" % (user_id, battle_score, heroes,
                        ArenaInfo.get_real_score(user_arena.score), users_arena_ranking[user_id], arena_buff_id,
                        self_win_score, self_lose_score, rival_win_score, rival_lose_score))

        defer = cache_proxy.execute()
        defer.addCallback(self._set_rivals_info, data, arena, rivals, users,
                heroes_id, tech_basic_ids)
        return defer
Esempio n. 11
0
    def add_condition(self, data, node):
        """提供匹配条件,发起一次搜索
        """
        rival_id = node.id  #rival 的 id 和 node 的 id 相同
        rival = data.rival_list.get(rival_id)
        if rival is None:
            rival = RivalInfo.create(rival_id, data.id)
            data.rival_list.add(rival)

        if node.is_rival_pvp_city():
            guard = data.guard_list.get_all()[0]
            (score_min, score_max) = (max(500, int(guard.score * 0.8)),
                                      max(2000, int(guard.score * 1.1)))
            rival.set_pvp_matching_condition(
                node.rival_type,
                #node.rival_score_min, node.rival_score_max, True)
                score_min,
                score_max,
                True)
            self._pvp_players.append(rival)
            logger.debug(
                "Add pvp city rival match condition[score_min=%d][score_max=%d]"
                % (score_min, score_max))

        elif node.is_rival_pvp_resource():
            guard = data.guard_list.get_all()[0]
            (score_min, score_max) = (max(1000, int(guard.score * 0.8)),
                                      max(2000, int(guard.score * 1.1)))
            rival.set_pvp_matching_condition(
                node.rival_type,
                #node.rival_score_min, node.rival_score_max, False)
                score_min,
                score_max,
                False)
            self._pvp_players.append(rival)
            logger.debug(
                "Add pvp resource rival match condition[score_min=%d][score_max=%d]"
                % (score_min, score_max))

        elif node.is_rival_dungeon():
            dungeon = data.dungeon.get(True)
            rival.set_dungeon_matching_condition(node.rival_type,
                                                 dungeon.dungeon_id,
                                                 node.rival_score_min,
                                                 node.rival_score_max,
                                                 dungeon.level)
            self._pvp_players.append(rival)
            self._dungeon = rival
            logger.debug(
                "Add dungeon rival match condition[dungeon_level=%d][score_min=%d][score_max=%d]"
                % (dungeon.level, node.rival_score_min, node.rival_score_max))

        else:
            logger.debug("Add pve rival match condition")
            rival.set_pve_matching_condition(node.rival_type,
                                             node.rival_score_min,
                                             node.rival_score_max)
            self._pve_players.append(rival)

        node.set_enemy_detail(rival.id)
        self.players[rival.id] = rival
Esempio n. 12
0
def start_battle(data, boss_id, array_index, teams, heroes, now, cost_gold):
    """开始联盟boss战"""
    boss = get_boss_by_id(data, boss_id)
    if boss is None:
        logger.warning("non-existent boss[user_id=%d][boss_id=%d]" %
                       (data.id, boss_id))
        raise Exception("non-existent boss")

    if array_index > 3 or array_index < 1:
        logger.warning(
            "boss team index out of range[user_id=%d][array_index=%d]" %
            (data.id, array_index))
        return (union_pb2.UNION_BOSS_TEAM_UNATTACKABLE, battle_pb2.BATTLE_OK)

    if boss.get_can_attack_arrays_index()[array_index - 1] != 1:
        logger.warning("boss team cannot attack[user_id=%d][array_index=%d]" %
                       (data.id, array_index))
        return (union_pb2.UNION_BOSS_TEAM_UNATTACKABLE, battle_pb2.BATTLE_OK)

    node_id = NodeInfo.generate_id(
        data.id, UserUnionInfo.get_union_boss_node_basic_id())
    battle = data.battle_list.get(node_id)
    if battle is None:
        battle = BattleInfo.create(node_id, data.id)
        data.battle_list.add(battle)
    node = data.node_list.get(node_id)
    if node is None:
        node = NodeInfo.create(data.id,
                               UserUnionInfo.get_union_boss_node_basic_id())
        data.node_list.add(node)
    rival = data.rival_list.get(node_id)
    if rival is None:
        rival = RivalInfo.create(node_id, data.id)
        data.rival_list.add(rival)

    rival.set_unionboss(boss_id)

    #消耗粮草
    resource = data.resource.get()
    resource.update_current_resource(now)
    need_food = battle_business._calc_food_consume(heroes)
    if not resource.cost_food(need_food):
        logger.warning("no enough food[user_id=%d]" % data.id)
        return (union_pb2.UNION_OK, battle_pb2.BATTLE_RESOURCE_SHORTAGE)
    battle.set_food_consume(need_food)

    #消耗兵力

    need_soldier_num = 0
    for hero in heroes:
        need_soldier_num += battle_business._calc_soldier_consume(
            hero.soldier_basic_id, hero.soldier_level)
    conscripts = data.conscript_list.get_all()
    total_soldier_num = 0
    for conscript in conscripts:
        conscript.update_current_soldier(now)
        total_soldier_num += (conscript.soldier_num -
                              conscript.lock_soldier_num)

    if total_soldier_num < need_soldier_num:
        if cost_gold <= 0:
            logger.warning("no enough soldier[user_id=%d]" % data.id)
            return (union_pb2.UNION_OK, battle_pb2.BATTLE_RESOURCE_SHORTAGE)
        else:
            gold = resource.soldier_to_gold(need_soldier_num -
                                            total_soldier_num)
            if gold != cost_gold:
                logger.warning(
                    "exchange soldier gold error[user_id=%d][gold=%d][real_gold=%d]"
                    % (data.id, cost_gold, gold))

    if not battle_business._consume_soldier(data, battle, now, heroes,
                                            cost_gold > 0):
        logger.warning("no enough soldier[user_id=%d]" % data.id)
        return (union_pb2.UNION_OK, battle_pb2.BATTLE_RESOURCE_SHORTAGE)

    #计算战利品
    user = data.user.get()
    reward_money = 0
    reward_food = 0
    reward_user_exp = 0
    reward_hero_exp = data_loader.MonarchLevelBasicInfo_dict[
        user.level].heroBattleExp
    reward_items = reward_module.random_battle_gift(user.level)
    battle.set_reward(reward_money, reward_food, reward_hero_exp,
                      reward_user_exp, reward_items)

    boss.start_battle(array_index)
    battle.start(node, rival, None, teams, heroes, now, user.vip_level)

    return (union_pb2.UNION_OK, battle_pb2.BATTLE_OK)