def _calc_reset_hard_attack_num(self, data, req, timer): res = anneal_pb2.ResetHardAttackNumRes() res.status = 0 ret = Ret() if not anneal_business.reset_hard_attack_num(data, req.floor, timer.now, ret): if ret.get() == 'GOLD_NOT_ENOUGH': res.ret = anneal_pb2.ResetHardAttackNumRes.GOLD_NOT_ENOUGH elif ret.get() == 'VIP_NOT_ENOUGH': res.ret = anneal_pb2.ResetHardAttackNumRes.VIP_NOT_ENOUGH return self._reset_hard_attack_num_succeed(data, req, res, timer) resource = data.resource.get() resource.update_current_resource(timer.now) res.ret = anneal_pb2.ResetHardAttackNumRes.OK pack.pack_resource_info(resource, res.resource) pack.pack_anneal_info(data, data.anneal.get(True), res.anneal, timer.now) defer = DataBase().commit(data) defer.addCallback(self._reset_hard_attack_num_succeed, req, res, timer) return defer
def _calc_buy(self, data, req, timer): res = transfer_arena_pb2.BuyChallengeTimesRes() res.status = 0 #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") ret = Ret() if not transfer_business.buy_attack_times(data, timer.now, ret): if ret.get() == "NO_ENOUGH_GOLD": res.ret = transfer_arena_pb2.BuyChallengeTimesRes.NO_ENOUGH_GOLD return self._buy_succeed(data, req, res, timer) elif ret.get() == "UPPER_LIMIT": res.ret = transfer_arena_pb2.BuyChallengeTimesRes.UPPER_LIMIT return self._buy_succeed(data, req, res, timer) transfer = data.transfer.get() transfer_records = data.transfer_record_list.get_all(True) res.ret = transfer_arena_pb2.BuyChallengeTimesRes.OK res.arena_info.remain_times = transfer.get_remain_times() res.arena_info.cd_end_time = transfer.get_cd_end_time(timer.now) for transfer_record in transfer_records: pack.pack_transfer_record(transfer_record, res.arena_info.records.add()) resource = data.resource.get(True) pack.pack_resource_info(resource, res.resource) defer = DataBase().commit(data) defer.addCallback(self._buy_succeed, req, res, timer) return defer
def _calc_end_conscript(self, data, req, timer, force): #涉及到跨天的数据统计,所以此处要更新所有跨天数据 res = conscript_pb2.EndConscriptRes() res.status = 0 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") user = data.user.get(True) resource = data.resource.get() conscript_building_id = BuildingInfo.generate_id( data.id, req.building.city_basic_id, req.building.location_index, req.building.basic_id) conscript_building = data.building_list.get(conscript_building_id) conscript = data.conscript_list.get(conscript_building_id) work_heroes = [] #来征兵的英雄 work_heroes_id = conscript_building.get_working_hero() for hero_id in work_heroes_id: if hero_id == 0: work_heroes.append(None) else: hero = data.hero_list.get(hero_id) work_heroes.append(hero) ret = Ret() if not conscript_business.end_conscript(data, conscript, conscript_building, resource, user, work_heroes, timer.now, force): if ret.get() == "NOT_CONSCRIPTING": res.ret = conscript_pb2.EndConscriptRes.NOT_CONSCRIPTING pack.pack_conscript_info(conscript, res.conscript, timer.now) pack.pack_building_info(conscript_building, res.building, timer.now) return self._end_conscript_succeed(data, req, res, timer) elif ret.get() == "CANNT_END": res.ret = conscript_pb2.EndConscriptRes.CANNT_END pack.pack_conscript_info(conscript, res.conscript, timer.now) pack.pack_building_info(conscript_building, res.building, timer.now) return self._end_conscript_succeed(data, req, res, timer) else: raise Exception('End conscript failed') #由于网络原因导致end_conscript一直重发,此处不check,直接返回 #compare.check_conscript(data, req.conscript) res.ret = conscript_pb2.EndConscriptRes.OK pack.pack_resource_info(data.resource.get(True), res.resource) defer = DataBase().commit(data) defer.addCallback(self._end_conscript_succeed, req, res, timer) return defer
def clear_lucky_event(data, node, now, change_nodes, new_items, new_mails, ret = Ret()): """清除随机事件 1 随机事件出现未启动,超过 idletime 2 随机事件启动未结束,超过 lifetime """ #节点未发生随机事件 if not node.is_event_arised(): logger.warning("Node has no lucky event[basic id=%d]" % node.basic_id) ret.setup("NO_EVENT") return False #return True #如果节点上有世界boss时间,直接clear if node.is_worldboss_event_arised(): return EventHandler().clear(data, node, now, change_nodes = change_nodes, new_items = new_items, new_mails = new_mails) if not node.is_event_launched(): #事件未启动 if node.is_event_over_idletime(now): return EventHandler().clear(data, node, now, change_nodes = change_nodes, new_items = new_items, new_mails = new_mails) else: #事件已启动 if node.is_event_over_lifetime(now): return EventHandler().timeout(data, node, now, change_nodes = change_nodes, new_items = new_items, new_mails = new_mails) logger.warning("Clear lucky event error") return False
def reduce_attack_num(self, num, ret=Ret()): if self.attack_num - num < 0: ret.setup("UPPER_LIMIT") return False self.attack_num -= num return True
def _calc_finish_appoint(self, data, req, timer): node_id = NodeInfo.generate_id(data.id, req.node.basic_id) node = data.node_list.get(node_id) battle = data.battle_list.get(node_id) #存活兵力信息 own_soldier_info = battle.get_own_soldier_info() enemy_soldier_info = battle.get_enemy_soldier_info() change_nodes = [] items = [] heroes = [] mails = [] ret = Ret() if not appoint_business.finish_appoint( data, node, battle, change_nodes, items, heroes, mails, timer.now, ret): if ret.get() == "FINISHED": res = appoint_pb2.FinishAppointRes() res.status = 0 res.ret = appoint_pb2.FinishAppointRes.FINISHED pack.pack_node_info(data, node, res.node, timer.now) return self._finish_appoint_succeed(data, req, res, timer) else: raise Exception("Finish appoint failed") #为新刷出的敌方节点匹配敌人 invalid_rival = [data.id] for node in data.node_list.get_all(True): if node.is_rival_pvp() and node.is_enemy_complete(): rival_id = node.id rival = data.rival_list.get(rival_id, True) invalid_rival.append(rival.rival_id) user = data.user.get(True) matcher = RivalMatcher(user.level, invalid_rival) for node in change_nodes: if node.is_lack_enemy_detail(): matcher.add_condition(data, node) defer = matcher.match(user.country) defer.addCallback(self._pack_finish_appoint_response, data, change_nodes, items, heroes, mails, req, timer) return defer
def _calc_clear_lucky_event(self, data, req, timer): """ """ node_basic_id = req.node.basic_id node_id = NodeInfo.generate_id(data.id, node_basic_id) node = data.node_list.get(node_id) change_nodes = [] new_items = [] new_mails = [] ret = Ret() if not event_business.clear_lucky_event( data, node, timer.now, change_nodes, new_items, new_mails, ret): if ret.get() == "NO_EVENT": res = map_pb2.ClearLuckyEventRes() res.status = 0 res.ret = map_pb2.ClearLuckyEventRes.NO_EVENT pack.pack_node_info(data, node, res.node, timer.now) return self._clear_lucky_event_succeed(data, req, res, timer) else: raise Exception("Clear lucky event failed") #为新刷出的敌方节点匹配敌人 #不合法的敌人:自己,以及已经在地图上出现过的 PVP 敌人 invalid_rival = [data.id] for node in data.node_list.get_all(True): if node.is_rival_pvp() and node.is_enemy_complete(): rival_id = node.id rival = data.rival_list.get(rival_id, True) invalid_rival.append(rival.rival_id) user = data.user.get(True) matcher = RivalMatcher(user.level, invalid_rival) for node in change_nodes: if node.is_lack_enemy_detail(): matcher.add_condition(data, node) defer = matcher.match(user.country) defer.addCallback(self._pack_clear_lucky_event_response, data, change_nodes, new_items, new_mails, req, timer) return defer
def start_battle(data, target_id, now, ret = Ret()): """开始战斗""" #1.检查是否满足开战条件: 攻击次数, CD时间 #2.增加攻击次数, 设置CD时间 transfer = data.transfer.get() if not transfer.is_able_to_start_battle(target_id, now, ret): return False transfer.start_battle(now) return True
def _calc_start_battle(self, data, req, timer): res = transfer_arena_pb2.StartTransferArenaBattleRes() res.status = 0 #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") ret = Ret() if not transfer_business.start_battle(data, req.target_id, timer.now, ret): if ret.get() == "NO_CHALLENGE_TIMES": res.ret = transfer_arena_pb2.StartTransferArenaBattleRes.NO_CHALLENGE_TIMES elif ret.get() == "COOLING": res.ret = transfer_arena_pb2.StartTransferArenaBattleRes.COOLING elif ret.get() == "TARGET_ERROR": res.ret = transfer_arena_pb2.StartTransferArenaBattleRes.TARGET_ERROR return self._start_battle_succeed(data, req, res, timer) res.ret = transfer_arena_pb2.StartTransferArenaBattleRes.OK defer = DataBase().commit(data) defer.addCallback(self._start_battle_succeed, req, res, timer) return defer
def is_able_to_start_battle(self, target_id, now, ret=Ret()): if self.get_remain_times() <= 0: ret.setup("NO_CHALLENGE_TIMES") return False if self.get_cd_end_time(now) > 0: ret.setup("COOLING") return False if target_id not in self.get_match_ids(): ret.setup("TARGET_ERROR") return False return True
def _calc_finish_exploit(self, data, req, timer, force): """结束开采 """ res = exploitation_pb2.ExploitRes() res.status = 0 node_basic_id = req.node.basic_id node_id = NodeInfo.generate_id(data.id, node_basic_id) node = data.node_list.get(node_id) change_nodes = [] new_items = [] new_mails = [] ret = Ret() if not exploitation_business.finish_exploit_event( data, node, timer.now, timer.now, change_nodes, new_items, new_mails, force, ret): if ret.get() == 'NOT_EXPLOITING': res.ret = exploitation_pb2.ExploitRes.NOT_EXPLOITING pack.pack_node_info(data, node, res.node, timer.now) return self._finish_exploit_succeed(data, req, res, timer) elif ret.get() == 'CANNT_FINISH': res.ret = exploitation_pb2.ExploitRes.CANNT_FINISH pack.pack_node_info(data, node, res.node, timer.now) return self._finish_exploit_succeed(data, req, res, timer) else: raise Exception("Finish exploit failed") resource = data.resource.get(True) assert len(new_mails) == 1 mail = new_mails[0] res = self._pack_exploit_response(new_items, resource, mail, timer.now) defer = DataBase().commit(data) defer.addCallback(self._finish_exploit_succeed, req, res, timer) return defer
def reset_cd(data, now, ret = Ret()): gold = int(float(data_loader.OtherBasicInfo_dict['transfer_arena_reset_cd_cost'].value)) resource = data.resource.get() resource.update_current_resource(now) original_gold = resource.gold if not resource.cost_gold(gold): ret.setup("NO_ENOUGH_GOLD") return False log = log_formater.output_gold(data, -gold, log_formater.RESET_CD, "Reset cd by gold", before_gold = original_gold) logger.notice(log) transfer = data.transfer.get(True) transfer.reset_cd(now) return True
def buy_attack_times(data, now, ret = Ret()): gold = int(float(data_loader.OtherBasicInfo_dict['transfer_arena_challenge_buy_cost'].value)) resource = data.resource.get() resource.update_current_resource(now) original_gold = resource.gold if not resource.cost_gold(gold): ret.setup("NO_ENOUGH_GOLD") return False log = log_formater.output_gold(data, -gold, log_formater.TRANSFER_ARENA, "Transfer arena challenge", before_gold = original_gold) logger.notice(log) transfer = data.transfer.get(True) if not transfer.reduce_attack_num(1, ret): return False return True
def is_able_to_finish_research(self, now, force=False, ret=Ret()): """ 是否可以完成研究 1 科技正在研究中 2 时间条件满足,或者强制完成 """ #科技正在研究中 if not self.is_upgrade: logger.warning("Technology is not upgrading") ret.setup("NOT_UPGRADING") return False if force: return True else: #非强制完成,时间需要满足要求 if self.calc_time_gap_of_finish_research(now) > 0: ret.setup("CANNT_FINISH") return False else: return True
def is_able_to_finish_exploit(self, end_time, force=False, ret=Ret()): """是否可以结束开采 """ if self.exploit_type == self.EXPLOITATION_TYPE_INVALID: logger.debug("Not able to finish exploit[reason=exploit type]") return False if self.exploit_start_time == 0: logger.debug( "Not able to finish exploit[reason=not during exploiting]") return False if force: return True if not self.is_exploit_over(end_time): logger.debug("Not able to finish exploit[reason=time]") ret.setup("CANNT_FINISH") return False return True
def is_able_to_finish_upgrade(self, heroes, now, force, ret=Ret()): """ 是否可以完成升级 1 建筑物处于升级状态 2 对应英雄在建筑物中参与升级 3 升级时间满足要求,或者强制结束 """ if not self.is_upgrade: logger.warning("Building is not upgrading") ret.setup("NOT_UPGRADING") return False if not self.is_hero_in_building(heroes): return False if force: return True else: if self.calc_time_gap_of_finish_upgrade(now) > 0: ret.setup("CANNT_FINISH") return False else: return True
def finish_upgrade(data, building, resource, user, heroes, now, force=False, ret=Ret()): """完成建筑升级 1 可以使用元宝加速完成升级 2 结算英雄和用户经验 Args: building[BuildingInfo out]: 建筑信息 resource_info[ResourceInfo out]: 资源信息 user[UserInfo out]: 用户信息 heroes[list(HeroInfo) out]: 英雄信息列表 now[int]: 当前时间戳 force[bool]: 是否强制完成,强制完成需要花费元宝 Returns: True 顺利完成升级 False 建筑物完成升级失败 """ #查看是否开启了支持剩余时间不多时建造立即完成的功能 open_flags = get_flags() can_finish_immediately = False if "is_open_buildinglist" in open_flags: can_finish_immediately = True if (building.calc_time_gap_of_finish_upgrade(now) > data_loader.VipBasicInfo_dict[user.vip_level].finishImediatelyTime ): can_finish_immediately = False if can_finish_immediately: force = True #判断是否可以完成升级 if not building.is_able_to_finish_upgrade(heroes, now, force, ret): logger.warning("Building is not able to finish upgrading") return False #如果强制完成:加速建造,需要花费元宝兑换时间 gap = 0 need_gold = 0 original_gold = resource.gold if force: gap = building.calc_time_gap_of_finish_upgrade(now) if can_finish_immediately: need_gold = 0 else: need_gold = resource.gold_exchange_time(gap) if need_gold < 0: return False #结算升级的经验 if not _calc_build_exp(data, building, user, heroes, now): return False #结束升级 if not building.finish_upgrade(heroes): return False #英雄结束工作 for hero in heroes: if hero is not None and not hero.finish_working(): return False #尝试解锁驻守位 building.unlock_garrison_position(user.vip_level) if force and not can_finish_immediately: log = log_formater.output_gold(data, -need_gold, log_formater.FINISH_BUILDING, "Finish building by gold", before_gold=original_gold, reduce_time=gap) logger.notice(log) return True
def finish_research(data, technology, user, building, heroes, resource, now, force = False, ret = Ret()): """ 结束研究 Args: technology force[bool]: 是否强制结束,需要消耗元宝 """ #查看是否开启了支持剩余时间不多时研究立即完成的功能 open_flags = get_flags() can_finish_immediately = False if "is_open_buildinglist" in open_flags: can_finish_immediately = True if (technology.calc_time_gap_of_finish_research(now) > data_loader.VipBasicInfo_dict[user.vip_level].finishImediatelyTime): can_finish_immediately = False if can_finish_immediately: force = True #判断是否可以结束研究 if not technology.is_able_to_finish_research(now, force, ret): logger.warning("Research is not able to finish") return False #如果强制完成(未满足研究时间条件),需要额外耗费金钱 gap = 0 original_gold = resource.gold need_gold = 0 if force: gap = technology.calc_time_gap_of_finish_research(now) if can_finish_immediately: need_gold = 0 else: need_gold = resource.gold_exchange_time(gap) if need_gold < 0: return False #结算英雄获得的经验 if not _calc_research_exp(data, technology, heroes, user, now): return False #结束研究 if not technology.finish_research(): return False #移除参与升级的英雄 if not building.stop_working(heroes, 0): return False for hero in heroes: if hero is not None and not hero.finish_working(): return False #记录升级次数 trainer = data.trainer.get() if technology.is_soldier_technology(): trainer.add_soldier_tech_upgrade_num(1) elif technology.is_battle_technology(): trainer.add_battle_tech_upgrade_num(1) else: trainer.add_interior_tech_upgrade_num(1) #内政科技可能影响领地占领个数 if technology.is_interior_technology(): occupy_num = int(data_loader.InteriorTechnologyBasicInfo_dict[ technology.basic_id].interiorAttributeIncrease.occupyNodeNum) if occupy_num != 0: map = data.map.get() map.update_occupy_node_num_technology(occupy_num) if force and not can_finish_immediately: log = log_formater.output_gold(data, -need_gold, log_formater.FINISH_TECHNOLOGY, "Finish technology by gold", before_gold = original_gold, reduce_time = gap) logger.notice(log) return True
def _calc_finish_research(self, data, req, timer, force): """ """ res = technology_pb2.UpgradeTechRes() res.status = 0 #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") user = data.user.get(True) resource = data.resource.get() technology_id = TechnologyInfo.generate_id(data.id, req.tech.basic_id, req.tech.type) technology = data.technology_list.get(technology_id) research_building = data.building_list.get(technology.building_id) if research_building is None: logger.fatal("research building is None[building_id=%d]" % technology.building_id) research_heroes = [] # 参与研究的英雄 research_heroes_id = research_building.get_working_hero() for hero_id in research_heroes_id: if hero_id == 0: research_heroes.append(None) else: hero = data.hero_list.get(hero_id) research_heroes.append(hero) resource.update_current_resource(timer.now) #结束研究 ret = Ret() if not technology_business.finish_research( data, technology, user, research_building, research_heroes, resource, timer.now, force, ret): if ret.get() == "NOT_UPGRADING": res.ret = technology_pb2.UpgradeTechRes.NOT_UPGRADING pack.pack_technology_info(technology, res.tech, timer.now) return self._finish_research_succeed(data, req, res, timer) elif ret.get() == "CANNT_FINISH": res.ret = technology_pb2.UpgradeTechRes.CANNT_FINISH pack.pack_technology_info(technology, res.tech, timer.now) return self._finish_research_succeed(data, req, res, timer) else: raise Exception("Finish research technology failed") #前置依赖科技 pre_technology_id = technology_business.get_pre_technology_id( data.id, technology.basic_id, technology.type) pre_technology = None if pre_technology_id != 0: pre_technology = data.technology_list.get(pre_technology_id) #升级完成的后续处理 #兵种科技 if technology.is_soldier_technology(): #删除前置依赖科技 if pre_technology_id != 0: data.technology_list.delete(pre_technology_id) #兵种科技研究完成后,会将原有兵种升级 soldier_id = technology_business.get_related_soldier_id( data.id, req.tech.basic_id) soldier = data.soldier_list.get(soldier_id) #所有配置相关兵种的英雄 related_heroes = [ hero.get() for hero in data.hero_list if hero.get(True).soldier_basic_id == soldier.basic_id ] soldier = technology_business.post_research_for_soldier_technology( data, data.id, technology, timer.now, soldier, related_heroes) if not soldier: raise Exception( "Post process for research soldier technology failed") #战斗科技 elif technology.is_battle_technology(): #删除前置依赖科技 if pre_technology_id != 0: data.technology_list.delete(pre_technology_id) soldier_basic_ids = data_loader.BattleTechnologyBasicInfo_dict[ technology.basic_id].soldierBasicInfoId related_heroes = [] #所带兵种的战力受该科技影响的英雄 for soldier_basic_id in soldier_basic_ids: for hero in data.hero_list: if hero.get(True).soldier_basic_id == soldier_basic_id: related_heroes.append(hero.get()) if not technology_business.post_research_for_battle_technology( data, technology, related_heroes): raise Exception( "Post process for research battle technology failed") #内政科技 elif technology.is_interior_technology(): #遍历所有建筑,更新建筑产量或容量 for building in data.building_list.get_all(): building_heroes = [] #建筑中驻守的英雄 build_hero_ids = building.get_working_hero() for hero_id in build_hero_ids: if hero_id == 0: building_heroes.append(None) else: hero = data.hero_list.get(hero_id) building_heroes.append(hero) if not building_business.update_building_with_interior_technology( building, building_heroes, resource, data, technology, pre_technology): raise Exception( "Post process for research interior technology failed") #删除前置依赖科技 if pre_technology_id != 0: data.technology_list.delete(pre_technology_id) #验证 compare.check_technology(data, req.tech) #记录次数 trainer = data.trainer.get() trainer.add_daily_tech_upgrade_num(1) #科技升级的广播 try: self._add_technology_broadcast(user, technology) except: logger.warning("Send technology broadcast failed") res.ret = technology_pb2.UpgradeTechRes.OK pack.pack_resource_info(data.resource.get(True), res.resource) defer = DataBase().commit(data) defer.addCallback(self._finish_research_succeed, req, res, timer) return defer
def end_conscript(data, conscript, building, resource, user, heroes, now, force=False, ret=Ret()): """结束征兵 Args: building : [BuildingInfo] 征兵的兵营 resource : [ResourceInfo] heros : [HeroInfo] list force : [bool] 是否是立即完成,立即完成需要花费元宝 """ if not building.is_heroes_working(heroes): logger.warning("heroes not working[building.hero_ids=%s]" % building.hero_ids) ret.setup("NOT_CONSCRIPTING") return False gap = conscript.calc_time_gap_to_finish(now) original_gold = resource.gold need_gold = 0 if force: #花费元宝,立即完成征兵 need_gold = resource.gold_exchange_time(gap) if need_gold < 0: return False elif gap > 0: logger.warning("Invalid conscript end time[now=%d][end time=%d]" % (now, conscript.end_time)) ret.setup("CANNT_END") return False if force: end_time = conscript.end_time else: end_time = now if not update_current_soldier(conscript, end_time): return False #更新英雄经验 if not _calc_conscript_exp(data, conscript, heroes, user, now): return False #移除驻守英雄 for hero in heroes: if hero is not None and not hero.finish_working(): return False if not building.stop_working(heroes, now): return False if force: log = log_formater.output_gold(data, -need_gold, log_formater.FINISH_CONSCRIPT, "Finish conscript by gold", before_gold=original_gold, reduce_time=gap) logger.notice(log) return conscript.finish_conscript()
def finish_exploit_event(data, node, now, end_time, change_nodes, new_items, new_mails, force = True, ret = Ret()): """ 结束开采事件 1 结算资源、物品奖励 2 结算英雄经验 3 将相关信息填充进邮件 Args: data[UserData] node[NodeInfo]: 节点信息 end_time[int]: 结束的时间戳 new_items[list(basic_id, num) out] new_mails[list(MailInfo) out] now[int]: 当前时间戳 force[bool]: 是否强制结束 """ user = data.user.get(True) resource = data.resource.get() #节点上必须有合法的随机事件 if (node.event_type != NodeInfo.EVENT_TYPE_TAX and node.event_type != NodeInfo.EVENT_TYPE_FARM and node.event_type != NodeInfo.EVENT_TYPE_MINING and node.event_type != NodeInfo.EVENT_TYPE_GOLD and node.event_type != NodeInfo.EVENT_TYPE_SEARCH and node.event_type != NodeInfo.EVENT_TYPE_DEEP_MINING and node.event_type != NodeInfo.EVENT_TYPE_HERMIT): logger.warning("Wrong event[type=%d]" % node.event_type) ret.setup("NOT_EXPLOITING") return False if not node.is_able_to_finish_exploit(end_time, force, ret): logger.warning("Not able to finish exploit") return False is_offline = False if node.is_exploit_offline(): is_offline = True gain_items = [] if not is_offline: #结算资源点资源采集 resource.update_current_resource(now) original_gold = resource.gold (money, food, gold, material_count) = node.calc_exploit_income(end_time) resource.gain_money(money) resource.gain_food(food) resource.gain_gold(gold) log = log_formater.output_gold(data, gold, log_formater.EXPLOIT_GOLD, "Gain gold from exploit", before_gold = original_gold) logger.notice(log) if material_count > 0: gain_items = reward_module.random_exploit_material( node.exploit_level, material_count) else: money = 0 food = 0 gold = 0 #采集随机物品奖励 if is_offline: #离线开采奖励物品个数 exploitation = data.exploitation.get() (reward_level, reward_num) = exploitation.get_offline_exploit_reward(node, now) reward_items = reward_module.random_exploit_offline(node.event_type, reward_level, reward_num) else: progress = node.get_exploit_progress(end_time) reward_items = reward_module.random_exploit_gift(node.exploit_level, progress) gain_items.extend(reward_items) if not item_business.gain_item(data, gain_items, "exploit reward", log_formater.EXPLOIT_REWARD): logger.warning("Merge reward item failed") return False new_items.extend(gain_items) #如果开采正常结束,获取成就值 if node.is_exploit_over(end_time): ac_base = data_loader.LuckyEventBasicInfo_dict[node.event_type].achievementBase ac_coe = data_loader.LuckyEventBasicInfo_dict[node.event_type].achievementCoefficient achievement = ac_base + ac_coe * node.level resource.gain_achievement(achievement) if is_offline: exploitation = data.exploitation.get() exploitation.finish(node, now) #采集完成邮件 mail = mail_business.create_exploitation_mail(data, node.basic_id, end_time) new_mails.append(mail) mail.attach_reward(money, food, gold, gain_items) mail.attach_node_info(node) #移除英雄,结算经验 work_heroes = [] #参与开采的英雄 work_heroes_id = node.get_exploit_hero() for hero_id in work_heroes_id: if hero_id == 0: work_heroes.append(None) else: hero = data.hero_list.get(hero_id) work_heroes.append(hero) if not _reclaim_exploit_hero(data, node, user, work_heroes, end_time, now): return False if not node.finish_exploit(work_heroes, is_offline): return False #统计信息 trainer = data.trainer.get() trainer.add_daily_finish_event_num(node.event_type, 1) if not node.finish_event(now, overtime = True): return False #金矿资源在采集完成后消失 if node.is_exploit_gold(): map = data.map.get() node.reset_dependency(map) change_nodes.append(node) if is_offline: node.clear_key_node() change_nodes.append(node) return True
def _calc_finish_upgrade(self, data, req, timer, force): """建筑升级完成 1 完成建筑升级,更新建筑信息,包括结算英雄参与建造升级获得的经验 2 指派新的驻守英雄 3 更新建筑升级完成的影响(农田、市场、兵营、城防) """ res = building_pb2.UpgradeBuildingRes() res.status = 0 #涉及到跨天的数据统计,所以此处要更新所有跨天数据 if not account_business.update_across_day_info(data, timer.now): raise Exception("Update across day info failed") user = data.user.get(True) resource = data.resource.get() upgrade_building_id = BuildingInfo.generate_id( data.id, req.building.city_basic_id, req.building.location_index, req.building.basic_id) upgrade_building = data.building_list.get(upgrade_building_id) build_heroes = [] #参与升级的英雄 build_hero_ids = upgrade_building.get_working_hero() for hero_id in build_hero_ids: if hero_id == 0: build_heroes.append(None) else: hero = data.hero_list.get(hero_id) build_heroes.append(hero) #更新资源 resource.update_current_resource(timer.now) #如果不处于升级状态 """if upgrade_building.is_upgrade == False: return DataBase().commit(data)""" #建筑结束升级状态 包括结算参与建造的英雄获得的经验 结算主公获得的经验 ret = Ret() if not building_business.finish_upgrade(data, upgrade_building, resource, user, build_heroes, timer.now, force, ret): if ret.get() == "NOT_UPGRADING": res.ret = building_pb2.UpgradeBuildingRes.NOT_UPGRADING pack.pack_building_info(upgrade_building, res.building, timer.now) return self._finish_upgrade_succeed(data, req, res, timer) elif ret.get() == "CANNT_FINISH": res.ret = building_pb2.UpgradeBuildingRes.CANNT_FINISH pack.pack_building_info(upgrade_building, res.building, timer.now) return self._finish_upgrade_succeed(data, req, res, timer) else: raise Exception("Finish upgrade building failed") defense = None conscript = None if upgrade_building.is_defense(): defense = data.defense_list.get(upgrade_building.id) elif upgrade_building.is_barrack(): conscript = data.conscript_list.get(upgrade_building.id) #所有生效的内政科技 interior_technologys = [ tech for tech in data.technology_list.get_all(True) if tech.is_interior_technology() and not tech.is_upgrade ] #升级完成之后的处理 new_technology = [] new_defense = [] new_conscript = [] if not building_business.post_upgrade( data, upgrade_building, timer.now, build_heroes, interior_technologys, resource, defense, conscript, new_technology, new_defense, new_conscript): raise Exception("Post process for upgrade failed") #可能解锁出已经完成研究的兵种科技,因此可能会解锁新的兵种 for technology in new_technology: data.technology_list.add(technology) if technology.is_soldier_technology(): soldier = technology_business.post_research_for_soldier_technology( data, data.id, technology, timer.now, new=True) if soldier is None: raise Exception( "Post process for soldier technology failed") data.soldier_list.add(soldier) for defense in new_defense: data.defense_list.add(defense) for conscript in new_conscript: data.conscript_list.add(conscript) #检查请求 compare.check_user(data, req.monarch, with_level=True) res.ret = building_pb2.UpgradeBuildingRes.OK pack.pack_resource_info(data.resource.get(True), res.resource) defer = DataBase().commit(data) defer.addCallback(self._finish_upgrade_succeed, req, res, timer) return defer