Пример #1
0
    def _calc_query_melee_ranking(self, proxy, user_id, scores_range, req,
                                  timer):
        cache_proxy = DataProxy()
        self_arena = proxy.get_result("melee", user_id)
        self_ranking = proxy.get_ranking("melee", "score", user_id) + 1
        cache_proxy.search("user", user_id)

        all_arenas = {}
        all_arenas_rank = {}
        player_rankings = {}
        for range in scores_range:
            arena_list = proxy.get_rank_score_result("melee", "score",
                                                     range[0], range[1], 0,
                                                     MELEE_COUNT)

            #按照积分先排序
            arena_list.sort(lambda x, y: cmp(ArenaInfo.get_real_score(
                x.score), ArenaInfo.get_real_score(y.score)),
                            reverse=True)

            arena_rank = 1
            for arena in arena_list:
                all_arenas[arena.user_id] = arena
                all_arenas_rank[arena.user_id] = arena_rank
                arena_rank = arena_rank + 1
                cache_proxy.search("user", arena.user_id)

        defer = cache_proxy.execute()
        defer.addCallback(self._query_melee_ranking_succeed, user_id,
                          self_arena, self_ranking, all_arenas,
                          all_arenas_rank, req, timer)
        return defer
Пример #2
0
def pack_arena_info(user, arena, message, now, ranking = 0, with_own = True):
    """ranking [int] 0表示不需要排名信息
    """
    message.index = arena.index

    #描述
    message.open_time_des = data_loader.ServerDescKeyInfo_dict["arena_open_time"].value.encode("utf-8")

    if not user.allow_pvp_arena:
        message.status = 3    #锁定
        message.end_time = 0
        return

    if arena.is_arena_active(now):
        message.status = 2     #激活
    else:
        message.status = 1     #未激活

    message.coin = arena.coin
    message.end_time = arena.next_time - now
    message.refresh_num = arena.refresh_num

    if with_own:
        message.own.ranking_index = ranking
        message.own.score = ArenaInfo.get_real_score(arena.score)
Пример #3
0
def arise_arena_event(data, node, now, **kwargs):
    """出现演武场事件
    1 敌人关键点出现该事件
    """
    change_nodes = kwargs['change_nodes']
    new_items = kwargs['new_items']
    new_mails = kwargs['new_mails']

    arena = data.arena.get()
    user = data.user.get(True)

    if not map_business.respawn_enemy_key_node(data, node, now):
        return False

    if not arena.open(node, user, now):
        return False

    #其他的pvp副本复用演武场事件,也需要开启
    melee = data.melee.get()
    if melee.is_able_to_open(user, now):
        if not melee.open(node, user, now):
            return False

    #倒推算出演出场事件应该arise的时间
    lifetime = data_loader.LuckyEventBasicInfo_dict[
        NodeInfo.EVENT_TYPE_ARENA].lifetime
    arena_arise_time = ArenaInfo.calc_event_arise_time(now, lifetime)

    return node.arise_event(NodeInfo.EVENT_TYPE_ARENA, arena_arise_time)
Пример #4
0
def update_arena_offline(data, user, arena):
    """离线更新演武场信息
    """
    ##积分衰减
    #score = ArenaInfo.get_real_score(arena.score)
    #decay = float(data_loader.OtherBasicInfo_dict["ArenaScoreDecay"].value)
    #new_score = int(score * decay)
    #score_diff = new_score - score
    #arena.add_score(score_diff)

    #积分清零
    #score = ArenaInfo.get_real_score(arena.score)
    #score_diff = 0 - score
    #arena.add_score(score_diff)

    #积分衰减(退一档,低于等于1600就不再衰减)
    decay_score = arena.calc_decay_score()
    score_diff = decay_score - ArenaInfo.get_real_score(arena.score)
    arena.add_score(score_diff)

    #清除对战记录
    record_id = []
    for record in data.arena_record_list.get_all(True):
        record_id.append(record.id)
    for id in record_id:
        data.arena_record_list.delete(id)

    #根据主公等级重新分配房间
    arena.update_index(user.level)

    #重置演武场最高段位
    arena.reset_highest_title_level()

    #乱斗场清理
    #积分清零
    melee = data.melee.get()
    decay_score = melee.calc_decay_score()
    score_diff = decay_score - MeleeInfo.get_real_score(melee.score)
    melee.add_score(score_diff)

    #清除对战记录
    record_id = []
    for record in data.melee_record_list.get_all(True):
        record_id.append(record.id)
    for id in record_id:
        data.melee_record_list.delete(id)

    #根据主公等级重新分配房间
    melee.update_index(user.level)

    #重置演武场最高段位
    melee.reset_highest_title_level()

    return True
Пример #5
0
    def _get_users(self, proxy, min_score, max_score, arenas, arena_rankings, users):
        """
            users(out: 元组(userid, name, level, icon_id, title_level, score, ranking_index))
        """
        results = proxy.get_all_result("user")

        for user in results:
            users.append(
                    (user.id, user.get_readable_name(), user.level, user.icon_id,
                        arenas[user.id].title_level,
                        ArenaInfo.get_real_score(arenas[user.id].score),
                        arena_rankings[user.id]))
        return True
Пример #6
0
    def _query_arenas_by_ranking(self, status, arena, count, users):
        """按照排名查询竞技场信息
        """
        assert status is True

        cache_proxy = DataProxy()

         #查询玩家所在房间的前count名
        (min_score, max_score) = ArenaInfo.get_index_score_range(arena.index)
        cache_proxy.search_by_rank_score(
                "arena", "score", min_score, max_score, 0, count)

        defer = cache_proxy.execute()
        defer.addCallback(self._query_users, min_score, max_score, count, users)
        return defer
Пример #7
0
    def _get_arena_rank(self, status, data, arena):
        """获得玩家竞技场的排名
        """
        assert status is True

        cache_proxy = DataProxy()
        #查询玩家所在房间的第一名
        (min_score, max_score) = ArenaInfo.get_index_score_range(arena.index)
        cache_proxy.search_by_rank_score(
                "arena", "score", min_score, max_score, 0, 1)
        #查询玩家所在房间人数
        cache_proxy.search_rank_score_count(
                "arena", "score", min_score, max_score)
        defer = cache_proxy.execute()
        defer.addCallback(self._select_arena_rank, data, min_score, max_score)
        return defer
Пример #8
0
    def _query_official_position_ranking(self, user_id, req, timer):

        cache_proxy = DataProxy()

        cache_proxy.search("arena", user_id)  #先查玩家自己的arena

        #拿到房间的积分范围
        scores_range = []
        range = ArenaInfo.get_index_score_range(ArenaInfo.ARENA_INDEX)
        scores_range.append(range)

        for range in scores_range:
            cache_proxy.search_by_rank_score("arena", "score", range[0],
                                             range[1], 0,
                                             OFFICIAL_POSITION_COUNT)

        defer = cache_proxy.execute()
        defer.addCallback(self._calc_query_official_position_ranking, user_id,
                          scores_range, req, timer)
        return defer
Пример #9
0
    def _select_players_info(self, proxy, data, arena, players_rank):
        """查询玩家的主公信息、阵容和战斗科技
        """
        users_id = []
        users_arena = {}
        users_arena_ranking = {}
        for rank in players_rank:
            if rank > self.users_count:  #超过本房间人数则跳过
                continue

            results = proxy.get_rank_result(
                    "arena", "score", self.rank_base + rank - 1, self.rank_base + rank - 1)
            if len(results) == 0:
                continue

            #匹配到玩家自己,舍弃
            if results[0].user_id == data.user.get(True).id:
                continue

            #匹配到积分为0的玩家,舍弃
            if ArenaInfo.get_real_score(results[0].score) == 0:
                continue

            #assert len(results) == 1
            user_id = results[0].user_id
            users_id.append(user_id)
            users_arena[user_id] = results[0]
            users_arena_ranking[user_id] = rank

        cache_proxy = DataProxy()
        for user_id in users_id:
            cache_proxy.search("user", user_id)    #查询主公信息
            cache_proxy.search("guard", user_id)    #查阵容
            cache_proxy.search_by_index("technology", "user_id", user_id)    #查战斗科技

        defer = cache_proxy.execute()
        defer.addCallback(self._select_teams, data, arena,
                users_id, users_arena, users_arena_ranking)
        return defer
Пример #10
0
    def _generate_all_info(self, basic_data, data, timer, pattern=1):
        """初始化账户信息
        Args:
            data[UserData]: 用户数据
            pattern[int]: 帐号初始化的模式
        Returns:
            UserData: 一个玩家的完整数据
        """
        user_id = data.id

        #用户信息
        if data_loader.OtherBasicInfo_dict.has_key("init_id"):
            pattern = int(
                float(data_loader.OtherBasicInfo_dict['init_id'].value))
        if not user_business.init_user(data, data.id, pattern, timer.now):
            raise Exception("Init user failed")

        #初始资源
        if not user_business.init_resource(data, pattern, timer.now):
            raise Exception("Init resource failed")

        #初始赠送物品
        if not item_business.init_default_items(data, pattern):
            raise Exception("Init items failed")

        #初始化战斗地图,以及所有节点信息
        if not map_business.init_map(data, pattern, timer.now):
            raise Exception("Init map failed")

        #初始主城
        if not city_business.create_main_city(data, pattern):
            raise Exception("Create main city failed")

        #初始化主城中的建筑
        if not city_business.init_main_city(data, pattern):
            raise Exception("Init building in main city failed")

        #建筑物会解锁出科技、城防、征兵等
        technology_list = []
        defense_list = []
        conscript_list = []
        resource = data.resource.get()
        for new_building in data.building_list.get_all():
            if not building_business.post_upgrade(
                    data, new_building, timer.now, [None, None, None], [],
                    resource, None, None, technology_list, defense_list,
                    conscript_list):
                raise Exception("Init technology / defense / conscript failed")

        for technology in technology_list:
            data.technology_list.add(technology)
        for defense in defense_list:
            data.defense_list.add(defense)
        for conscript in conscript_list:
            data.conscript_list.add(conscript)

        #兵种科技会解锁兵种
        soldier_list = []
        for technology in technology_list:
            if not technology.is_soldier_technology():
                continue

            new_soldier = technology_business.post_research_for_soldier_technology(
                data, data.id, technology, timer.now, new=True)
            if new_soldier is None:
                raise Exception("Init soldier failed")
            soldier_list.append(new_soldier)

        for soldier in soldier_list:
            data.soldier_list.add(soldier)

        #初始化联盟信息
        union_business.init_union(data, timer.now)

        #初始商店信息
        if not shop_business.init_shop(data, timer.now):
            raise Exception("Init shop failed")

        #初始充值商店信息
        if not pay_business.init_pay(data, pattern, timer.now):
            raise Exception("Init pay failed")

        #初始化活动信息
        if not activity_business.init_activity(basic_data, data, pattern,
                                               timer):
            raise Exception("Init activity failed")

        #初始抽奖信息
        if not draw_business.init_draw(data, timer.now):
            raise Exception("Init draw failed")

        #初始化演武场信息
        arena = ArenaInfo.create(data.id)
        data.arena.add(arena)
        #初始化乱斗场信息
        melee = MeleeInfo.create(data.id)
        data.melee.add(melee)

        #初始化史实城信息
        if not legendcity_business.init_legendcity(data, timer.now):
            raise Exception("Init legendcity failed")

        #初始邮件信息
        if not mail_business.init_postoffice(data, timer.now):
            raise Exception("Init postoffice failed")

        #基础任务
        mission_list = mission_business.init(data.id, pattern)
        for mission in mission_list:
            data.mission_list.add(mission)
        #日常任务
        mission_business.reset_daily_missions(data, pattern)

        #初始化统计信息
        statistics = StatisticsInfo.create(data.id)
        data.statistics.add(statistics)

        #初始化签到信息
        sign = SignInfo.create(data.id)
        data.sign.add(sign)

        #初始化总战力信息
        battle_score = BattleScoreInfo.create(data.id)
        data.battle_score.add(battle_score)

        #初始化一些统计信息
        trainer = TrainerInfo.create(data.id)
        data.trainer.add(trainer)
        trainer.add_login_num(1)

        #初始化政令信息
        energy = energy_business.init_energy(data, timer.now)
        data.energy.add(energy)

        #初始化祈福信息
        pray = pray_business.init_pray(data, timer.now)
        data.pray.add(pray)

        #初始化红包信息
        chest = chest_business.init_chest(data, timer.now)
        data.chest.add(chest)

        #初始化演武场信息
        exploitation = ExploitationInfo.create(data.id)
        data.exploitation.add(exploitation)

        #初始化试炼场信息
        anneal = anneal_business.init_anneal(data, timer.now)
        data.anneal.add(anneal)

        #初始化将星盘信息
        herostar_business.init_herostar(data)

        #初始化世界boss信息
        worldboss = worldboss_business.init_worldboss(basic_data, data,
                                                      timer.now)
        data.worldboss.add(worldboss)
        if worldboss.is_arised():
            worldboss_process = WorldBossProcessor()
            worldboss_process.query_common_worldboss(data, worldboss)

        #初始化扩展副本
        expand_dungeon_business.init_expand_dungeon(data)

        #初始化换位演武场
        transfer = UserTransferInfo.create(data.id)
        data.transfer.add(transfer)

        #初始化掠夺信息
        plunder = PlunderInfo.create(data.id)
        data.plunder.add(plunder)

        return DataBase().commit(data)
Пример #11
0
def calc_battle_score(arena, rival_score):
    """计算单场得分
    Args:
        arena(ArenaInfo): 己方竞技场信息
        rival_score(int):  对手积分
    """
    self_score = ArenaInfo.get_real_score(arena.score)
    D = abs(self_score - rival_score)
    #P
    for i in data_loader.ELOBasicInfo_dict:
        elo = data_loader.ELOBasicInfo_dict[i]
        if D >= elo.lowerLimitScore and D <= elo.upperLimitScore:
            if self_score >= rival_score:
                P = float(elo.expectationA)
            else:
                P = float(elo.expectationB)
            break
    #K1 得分系数与段位相关
    key = "%s_%s" % (arena.index, arena.title_level)
    K1 = float(data_loader.GradeBasicInfo_dict[key].factorK1)

    #K2 连胜连败修正系数
    max_num = max(data_loader.ArenaContinuousWinRepairFactor_dict.keys())
    min_num = min(data_loader.ArenaContinuousWinRepairFactor_dict.keys())
    #胜
    if arena.continuous_win_num >= 0:
        num_win = min(max_num, arena.continuous_win_num + 1)
    else:
        num_win = min(max_num, 1)
    #负
    if arena.continuous_win_num < 0:
        num_lose = max(min_num, arena.continuous_win_num - 1)
    else:
        num_lose = max(min_num, -1)

    continuous_factor = data_loader.ArenaContinuousWinRepairFactor_dict[
        num_win]
    K2_win = float(continuous_factor.factor)
    continuous_factor = data_loader.ArenaContinuousWinRepairFactor_dict[
        num_lose]
    K2_lose = float(continuous_factor.factor)

    #K3 场次修正系数
    max_num = max(data_loader.ArenaNumRepairFactor_dict.keys())
    num = min(max_num, arena.total_num)
    num_factor = data_loader.ArenaNumRepairFactor_dict[num]
    if num_factor is None:
        max_num = 0
        for i in data_loader.ArenaNumRepairFactor_dict:
            num = data_loader.ArenaNumRepairFactor_dict[i].num
            if max_num < num:
                max_num = num
        num_factor = data_loader.ArenaNumRepairFactor_dict[max_num]
    K3 = float(num_factor.factor)

    R = 1
    win_score = K1 * K2_win * K3 * (R - P)
    R = 0
    lose_score = K1 * K2_lose * K3 * (R - P)

    logger.debug(
        "Calc arena battle score[D=%d][P=%f][K1=%d][K2_win=%d][K2_lose=%d][K3=%d][win_score=%d][lose_score=%d]"
        % (D, P, K1, K2_win, K2_lose, K3, win_score, lose_score))

    #打胜最低也能得30分,避免出现0积分的情况
    return (max(35, int(win_score)), int(lose_score))
Пример #12
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
Пример #13
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