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