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
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)
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)
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
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
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
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
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
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
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)
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))
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
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