Example #1
0
    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
Example #2
0
    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
Example #3
0
    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
Example #4
0
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
Example #5
0
    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
Example #6
0
    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
Example #7
0
    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
Example #8
0
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
Example #9
0
    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
Example #10
0
    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
Example #11
0
    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
Example #12
0
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
Example #13
0
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
Example #14
0
    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
Example #15
0
File: node.py Project: hw233/test-2
    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
Example #16
0
    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
Example #17
0
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
Example #18
0
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
Example #19
0
    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
Example #20
0
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()
Example #21
0
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
Example #22
0
    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