Exemple #1
0
    def change_current_plunder_times(self, change_value, allow_overflow=True):
        max_times = self.max_plunder_times()
        if change_value > 0 and not allow_overflow and self.mongo_plunder.current_times > max_times:
            return

        # for i in range(10):
        #     self.load_mongo_record()
        #     if not self.mongo_plunder.current_times_lock:
        #         self.mongo_plunder.current_times_lock = True
        #         self.mongo_plunder.save()
        #         break
        #     else:
        #         time.sleep(0.2)
        # else:
        #     raise PlunderCurrentTimeOut()
        #
        # try:
        #     self.mongo_plunder.current_times += change_value
        #     if self.mongo_plunder.current_times < 0:
        #         self.mongo_plunder.current_times = 0
        #
        #     if not allow_overflow and change_value > 0:
        #         if self.mongo_plunder.current_times > max_times:
        #             self.mongo_plunder.current_times = max_times
        # finally:
        #     self.mongo_plunder.current_times_lock = False
        #     self.mongo_plunder.save()
        #     self.send_notify()

        MongoPlunder._get_collection().update(
            {'_id': self.char_id},
            {'$inc': {'current_times': change_value}}
        )

        self.load_mongo_record()
        if self.mongo_plunder.current_times < 0:
            MongoPlunder._get_collection().update(
                {'_id': self.char_id},
                {'$set': {'current_times': 0}}
            )


        if not allow_overflow:
            if self.mongo_plunder.current_times > max_times:
                MongoPlunder._get_collection().update(
                    {'_id': self.char_id},
                    {'$set': {'current_times': max_times}}
                )

        self.send_notify()
Exemple #2
0
    def change_current_plunder_times(self, change_value, allow_overflow=True):
        max_times = self.max_plunder_times()
        if change_value > 0 and not allow_overflow and self.mongo_plunder.current_times > max_times:
            return

        # for i in range(10):
        #     self.load_mongo_record()
        #     if not self.mongo_plunder.current_times_lock:
        #         self.mongo_plunder.current_times_lock = True
        #         self.mongo_plunder.save()
        #         break
        #     else:
        #         time.sleep(0.2)
        # else:
        #     raise PlunderCurrentTimeOut()
        #
        # try:
        #     self.mongo_plunder.current_times += change_value
        #     if self.mongo_plunder.current_times < 0:
        #         self.mongo_plunder.current_times = 0
        #
        #     if not allow_overflow and change_value > 0:
        #         if self.mongo_plunder.current_times > max_times:
        #             self.mongo_plunder.current_times = max_times
        # finally:
        #     self.mongo_plunder.current_times_lock = False
        #     self.mongo_plunder.save()
        #     self.send_notify()

        MongoPlunder._get_collection().update(
            {'_id': self.char_id}, {'$inc': {
                'current_times': change_value
            }})

        self.load_mongo_record()
        if self.mongo_plunder.current_times < 0:
            MongoPlunder._get_collection().update(
                {'_id': self.char_id}, {'$set': {
                    'current_times': 0
                }})

        if not allow_overflow:
            if self.mongo_plunder.current_times > max_times:
                MongoPlunder._get_collection().update(
                    {'_id': self.char_id},
                    {'$set': {
                        'current_times': max_times
                    }})

        self.send_notify()
Exemple #3
0
 def cron_job():
     MongoPlunder._get_collection().update({},
                                           {'$set': {
                                               'plunder_times': 0
                                           }},
                                           multi=True)
Exemple #4
0
class Plunder(object):
    def __init__(self, char_id):
        self.char_id = char_id
        self.load_mongo_record()

    def load_mongo_record(self):
        try:
            self.mongo_plunder = MongoPlunder.objects.get(id=self.char_id)
            self.set_default_value()
        except DoesNotExist:
            self.mongo_plunder = MongoPlunder(id=self.char_id)
            self.mongo_plunder.current_times = self.max_plunder_times()
            self.mongo_plunder.save()

    def set_default_value(self):
        # 后面新增加的fileds需要初始化数值的。 比如 current_times
        data = {
            'current_times': self.max_plunder_times(),
            'current_times_lock': False,
            'char_id': 0,
            'char_name': "",
            'char_gold': 0,
            'char_power': 0,
            'char_leader': 0,
            'char_formation': [],
            'char_hero_original_ids': [],
            'char_city_id': 0
        }

        changed = False

        record = self.mongo_plunder._get_collection().find_one(
            {'_id': self.char_id})
        for k, v in data.iteritems():
            if k not in record:
                setattr(self.mongo_plunder, k, v)
                changed = True

        if changed:
            self.mongo_plunder.save()

    def get_plunder_target(self, city_id):
        """
        @:rtype: PlunderRival
        """

        target = PlunderRival.search_all_servers(city_id,
                                                 exclude_char_id=self.char_id)
        self.mongo_plunder.char_id = target.char_id
        self.mongo_plunder.char_name = target.name
        self.mongo_plunder.char_gold = target.get_plunder_gold(
            Char(self.char_id).mc.level)
        self.mongo_plunder.char_power = target.power
        self.mongo_plunder.char_leader = target.leader
        self.mongo_plunder.char_formation = target.formation
        self.mongo_plunder.char_hero_original_ids = target.hero_original_ids
        self.mongo_plunder.char_city_id = target.city_id
        self.mongo_plunder.battle_heros = target.battle_heros
        self.mongo_plunder.server_url = target.server_url
        self.mongo_plunder.save()

        if target:
            gold_needs = BATTLES[city_id].refresh_cost_gold
            resource = Resource(self.char_id, "Plunder Refresh")
            resource.check_and_remove(gold=-gold_needs)

        return target

    def max_plunder_times(self):
        char = Char(self.char_id)
        times = VIP_FUNCTION[char.mc.vip].plunder

        ae = ActivityEntry(self.char_id, 40007)
        if not ae or not ae.is_ok():
            return times

        if times > 10:
            return times

        return 10

    def clean_plunder_target(self):
        self.mongo_plunder.char_id = 0
        self.mongo_plunder.char_name = ""
        self.mongo_plunder.char_gold = 0
        self.mongo_plunder.char_power = 0
        self.mongo_plunder.char_leader = 0
        self.mongo_plunder.char_formation = []
        self.mongo_plunder.char_hero_original_ids = []
        self.mongo_plunder.char_city_id = 0
        self.mongo_plunder.battle_heros = ""
        self.mongo_plunder.server_url = ""
        self.mongo_plunder.save()

    def change_current_plunder_times(self, change_value, allow_overflow=True):
        max_times = self.max_plunder_times()
        if change_value > 0 and not allow_overflow and self.mongo_plunder.current_times > max_times:
            return

        # for i in range(10):
        #     self.load_mongo_record()
        #     if not self.mongo_plunder.current_times_lock:
        #         self.mongo_plunder.current_times_lock = True
        #         self.mongo_plunder.save()
        #         break
        #     else:
        #         time.sleep(0.2)
        # else:
        #     raise PlunderCurrentTimeOut()
        #
        # try:
        #     self.mongo_plunder.current_times += change_value
        #     if self.mongo_plunder.current_times < 0:
        #         self.mongo_plunder.current_times = 0
        #
        #     if not allow_overflow and change_value > 0:
        #         if self.mongo_plunder.current_times > max_times:
        #             self.mongo_plunder.current_times = max_times
        # finally:
        #     self.mongo_plunder.current_times_lock = False
        #     self.mongo_plunder.save()
        #     self.send_notify()

        MongoPlunder._get_collection().update(
            {'_id': self.char_id}, {'$inc': {
                'current_times': change_value
            }})

        self.load_mongo_record()
        if self.mongo_plunder.current_times < 0:
            MongoPlunder._get_collection().update(
                {'_id': self.char_id}, {'$set': {
                    'current_times': 0
                }})

        if not allow_overflow:
            if self.mongo_plunder.current_times > max_times:
                MongoPlunder._get_collection().update(
                    {'_id': self.char_id},
                    {'$set': {
                        'current_times': max_times
                    }})

        self.send_notify()

    def plunder(self):
        if not self.mongo_plunder.char_id:
            raise SanguoException(errormsg.PLUNDER_NO_RIVAL, self.char_id,
                                  "Plunder Battle", "no rival target")

        if self.mongo_plunder.current_times <= 0:
            raise SanguoException(errormsg.PLUNDER_NO_TIMES, self.char_id,
                                  "Plunder Battle", "no times")

        self.change_current_plunder_times(change_value=-1)

        rival_battle_heros = dill.loads(
            base64.b64decode(self.mongo_plunder.battle_heros))

        msg = MsgBattle()
        pvp = PlunderBattle(
            self.char_id,
            self.mongo_plunder.char_id,
            msg,
            self.mongo_plunder.char_name,
            rival_battle_heros,
        )
        pvp.start()

        t = Task(self.char_id)
        t.trig(3)

        to_char_id = self.mongo_plunder.char_id
        target_server_url = self.mongo_plunder.server_url

        if msg.self_win:
            standard_drop = self._get_plunder_reward(
                self.mongo_plunder.char_city_id, self.mongo_plunder.char_gold,
                self.mongo_plunder.char_hero_original_ids)

            self.clean_plunder_target()

            achievement = Achievement(self.char_id)
            achievement.trig(12, 1)

            PlunderLeaderboardWeekly.incr(self.char_id)
            TimesLogPlunder(self.char_id).inc()
        else:
            standard_drop = make_standard_drop_from_template()

        self.mongo_plunder.plunder_times += 1
        self.mongo_plunder.save()
        self.send_notify()

        plunder_finished_signal.send(
            sender=None,
            from_char_id=self.char_id,
            from_char_name=Char(self.char_id).mc.name,
            to_char_id=to_char_id,
            from_win=msg.self_win,
            standard_drop=standard_drop,
            target_server_url=target_server_url,
        )

        return (msg, standard_drop)

    def _get_plunder_reward(self, city_id, gold, hero_original_ids):
        def _get_prisoner():
            prison = 0
            heros = [hid for hid in hero_original_ids if hid]

            while heros:
                hid = random.choice(heros)
                heros.remove(hid)
                if hid in PRISONER_POOL:
                    prison = hid
                    break

            ac = ActivityEntry(self.char_id, 30005)
            """@type: core.activity.Activity30005"""
            if not ac:
                _prob = PLUNDER_GET_PRISONER_PROB
            else:
                _prob = ac.get_prisoner_prob()

            ae = ActivityEntry(self.char_id, 50005)
            if ae and ae.is_valid():
                _vip = ae.get_current_value(self.char_id)
                if _vip == 6:
                    _prob = 50
                elif _vip >= 7:
                    _prob = 100

            if random.randint(1, 100) <= _prob:
                return prison
            return 0

        char = Char(self.char_id).mc
        vip_plus = VIP_FUNCTION[char.vip].plunder_addition

        standard_drop = make_standard_drop_from_template()
        standard_drop['gold'] = int(gold * (1 + vip_plus / 100.0))

        # 战俘
        got_hero_id = _get_prisoner()
        if got_hero_id:
            p = Prison(self.char_id)
            p.prisoner_add(got_hero_id, gold / 2)

            achievement = Achievement(self.char_id)
            achievement.trig(13, 1)

        # 掉落
        city = BATTLES[city_id]
        if city.normal_drop:
            drop_ids = [int(i) for i in city.normal_drop.split(',')]
            drop_prob = max(
                PLUNDER_GET_DROPS_TIMES -
                (self.mongo_plunder.plunder_times - 1) *
                PLUNDER_DROP_DECREASE_FACTOR,
                PLUNDER_GET_DROPS_TIMES * PLUNDER_DROP_MIN_FACTOR)

            drop = get_drop(drop_ids, multi=int(drop_prob))
            drop.pop('gold')
            standard_drop.update(drop)

        resource = Resource(self.char_id, "Plunder Reward")
        resource.add(**standard_drop)

        self.send_notify()
        if got_hero_id:
            standard_drop['heros'] = [(got_hero_id, 1)]

        return standard_drop

    def send_notify(self):
        self.load_mongo_record()
        msg = PlunderNotify()
        msg.current_times = self.mongo_plunder.current_times
        msg.max_times = self.max_plunder_times()
        msg.success_times_weekly = PlunderLeaderboardWeekly.get_char_times(
            self.char_id)
        publish_to_char(self.char_id, pack_msg(msg))

    @staticmethod
    def cron_job():
        MongoPlunder._get_collection().update({},
                                              {'$set': {
                                                  'plunder_times': 0
                                              }},
                                              multi=True)
Exemple #5
0
 def cron_job():
     MongoPlunder._get_collection().update({}, {'$set': {'plunder_times': 0}}, multi=True)
Exemple #6
0
class Plunder(object):
    def __init__(self, char_id):
        self.char_id = char_id
        self.load_mongo_record()

    def load_mongo_record(self):
        try:
            self.mongo_plunder = MongoPlunder.objects.get(id=self.char_id)
            self.set_default_value()
        except DoesNotExist:
            self.mongo_plunder = MongoPlunder(id=self.char_id)
            self.mongo_plunder.current_times = self.max_plunder_times()
            self.mongo_plunder.save()


    def set_default_value(self):
        # 后面新增加的fileds需要初始化数值的。 比如 current_times
        data = {
            'current_times': self.max_plunder_times(),
            'current_times_lock': False,
            'char_id': 0,
            'char_name': "",
            'char_gold': 0,
            'char_power': 0,
            'char_leader': 0,
            'char_formation': [],
            'char_hero_original_ids': [],
            'char_city_id': 0
        }

        changed = False

        record = self.mongo_plunder._get_collection().find_one({'_id': self.char_id})
        for k, v in data.iteritems():
            if k not in record:
                setattr(self.mongo_plunder, k, v)
                changed = True

        if changed:
            self.mongo_plunder.save()


    def get_plunder_target(self, city_id):
        """
        @:rtype: PlunderRival
        """

        target = PlunderRival.search_all_servers(city_id, exclude_char_id=self.char_id)
        self.mongo_plunder.char_id = target.char_id
        self.mongo_plunder.char_name = target.name
        self.mongo_plunder.char_gold = target.get_plunder_gold(Char(self.char_id).mc.level)
        self.mongo_plunder.char_power = target.power
        self.mongo_plunder.char_leader = target.leader
        self.mongo_plunder.char_formation = target.formation
        self.mongo_plunder.char_hero_original_ids = target.hero_original_ids
        self.mongo_plunder.char_city_id = target.city_id
        self.mongo_plunder.battle_heros = target.battle_heros
        self.mongo_plunder.server_url = target.server_url
        self.mongo_plunder.save()

        if target:
            gold_needs = BATTLES[city_id].refresh_cost_gold
            resource = Resource(self.char_id, "Plunder Refresh")
            resource.check_and_remove(gold=-gold_needs)

        return target

    def max_plunder_times(self):
        char = Char(self.char_id)
        times = VIP_FUNCTION[char.mc.vip].plunder

        ae = ActivityEntry(self.char_id, 40007)
        if not ae or not ae.is_ok():
            return times

        if times > 10:
            return times

        return 10


    def clean_plunder_target(self):
        self.mongo_plunder.char_id = 0
        self.mongo_plunder.char_name = ""
        self.mongo_plunder.char_gold = 0
        self.mongo_plunder.char_power = 0
        self.mongo_plunder.char_leader = 0
        self.mongo_plunder.char_formation = []
        self.mongo_plunder.char_hero_original_ids = []
        self.mongo_plunder.char_city_id = 0
        self.mongo_plunder.battle_heros = ""
        self.mongo_plunder.server_url = ""
        self.mongo_plunder.save()


    def change_current_plunder_times(self, change_value, allow_overflow=True):
        max_times = self.max_plunder_times()
        if change_value > 0 and not allow_overflow and self.mongo_plunder.current_times > max_times:
            return

        # for i in range(10):
        #     self.load_mongo_record()
        #     if not self.mongo_plunder.current_times_lock:
        #         self.mongo_plunder.current_times_lock = True
        #         self.mongo_plunder.save()
        #         break
        #     else:
        #         time.sleep(0.2)
        # else:
        #     raise PlunderCurrentTimeOut()
        #
        # try:
        #     self.mongo_plunder.current_times += change_value
        #     if self.mongo_plunder.current_times < 0:
        #         self.mongo_plunder.current_times = 0
        #
        #     if not allow_overflow and change_value > 0:
        #         if self.mongo_plunder.current_times > max_times:
        #             self.mongo_plunder.current_times = max_times
        # finally:
        #     self.mongo_plunder.current_times_lock = False
        #     self.mongo_plunder.save()
        #     self.send_notify()

        MongoPlunder._get_collection().update(
            {'_id': self.char_id},
            {'$inc': {'current_times': change_value}}
        )

        self.load_mongo_record()
        if self.mongo_plunder.current_times < 0:
            MongoPlunder._get_collection().update(
                {'_id': self.char_id},
                {'$set': {'current_times': 0}}
            )


        if not allow_overflow:
            if self.mongo_plunder.current_times > max_times:
                MongoPlunder._get_collection().update(
                    {'_id': self.char_id},
                    {'$set': {'current_times': max_times}}
                )

        self.send_notify()



    def plunder(self):
        if not self.mongo_plunder.char_id:
            raise SanguoException(
                errormsg.PLUNDER_NO_RIVAL,
                self.char_id,
                "Plunder Battle",
                "no rival target"
            )

        if self.mongo_plunder.current_times <= 0:
            raise SanguoException(
                errormsg.PLUNDER_NO_TIMES,
                self.char_id,
                "Plunder Battle",
                "no times"
            )

        self.change_current_plunder_times(change_value=-1)

        rival_battle_heros = dill.loads(base64.b64decode(self.mongo_plunder.battle_heros))

        msg = MsgBattle()
        pvp = PlunderBattle(
            self.char_id,
            self.mongo_plunder.char_id,
            msg,
            self.mongo_plunder.char_name,
            rival_battle_heros,
        )
        pvp.start()

        t = Task(self.char_id)
        t.trig(3)

        to_char_id = self.mongo_plunder.char_id
        target_server_url = self.mongo_plunder.server_url

        if msg.self_win:
            standard_drop = self._get_plunder_reward(
                self.mongo_plunder.char_city_id,
                self.mongo_plunder.char_gold,
                self.mongo_plunder.char_hero_original_ids
            )

            self.clean_plunder_target()

            achievement = Achievement(self.char_id)
            achievement.trig(12, 1)

            PlunderLeaderboardWeekly.incr(self.char_id)
            TimesLogPlunder(self.char_id).inc()
        else:
            standard_drop = make_standard_drop_from_template()

        self.mongo_plunder.plunder_times += 1
        self.mongo_plunder.save()
        self.send_notify()

        plunder_finished_signal.send(
            sender=None,
            from_char_id=self.char_id,
            from_char_name=Char(self.char_id).mc.name,
            to_char_id=to_char_id,
            from_win=msg.self_win,
            standard_drop=standard_drop,
            target_server_url=target_server_url,
        )

        return (msg, standard_drop)


    def _get_plunder_reward(self, city_id, gold, hero_original_ids):
        def _get_prisoner():
            prison = 0
            heros = [hid for hid in hero_original_ids if hid]

            while heros:
                hid = random.choice(heros)
                heros.remove(hid)
                if hid in PRISONER_POOL:
                    prison = hid
                    break

            ac = ActivityEntry(self.char_id, 30005)
            """@type: core.activity.Activity30005"""
            if not ac:
                _prob = PLUNDER_GET_PRISONER_PROB
            else:
                _prob = ac.get_prisoner_prob()

            ae = ActivityEntry(self.char_id, 50005)
            if ae and ae.is_valid():
                _vip = ae.get_current_value(self.char_id)
                if _vip == 6:
                    _prob = 50
                elif _vip >= 7:
                    _prob = 100

            if random.randint(1, 100) <= _prob:
                return prison
            return 0

        char = Char(self.char_id).mc
        vip_plus = VIP_FUNCTION[char.vip].plunder_addition

        standard_drop = make_standard_drop_from_template()
        standard_drop['gold'] = int(gold * (1 + vip_plus / 100.0))

        # 战俘
        got_hero_id = _get_prisoner()
        if got_hero_id:
            p = Prison(self.char_id)
            p.prisoner_add(got_hero_id, gold/2)

            achievement = Achievement(self.char_id)
            achievement.trig(13, 1)

        # 掉落
        city = BATTLES[city_id]
        if city.normal_drop:
            drop_ids = [int(i) for i in city.normal_drop.split(',')]
            drop_prob = max(
                PLUNDER_GET_DROPS_TIMES - (self.mongo_plunder.plunder_times - 1) * PLUNDER_DROP_DECREASE_FACTOR,
                PLUNDER_GET_DROPS_TIMES * PLUNDER_DROP_MIN_FACTOR
            )

            drop = get_drop(drop_ids, multi=int(drop_prob))
            drop.pop('gold')
            standard_drop.update(drop)

        resource = Resource(self.char_id, "Plunder Reward")
        resource.add(**standard_drop)

        self.send_notify()
        if got_hero_id:
            standard_drop['heros'] = [(got_hero_id, 1)]

        return standard_drop


    def send_notify(self):
        self.load_mongo_record()
        msg = PlunderNotify()
        msg.current_times = self.mongo_plunder.current_times
        msg.max_times = self.max_plunder_times()
        msg.success_times_weekly = PlunderLeaderboardWeekly.get_char_times(self.char_id)
        publish_to_char(self.char_id, pack_msg(msg))


    @staticmethod
    def cron_job():
        MongoPlunder._get_collection().update({}, {'$set': {'plunder_times': 0}}, multi=True)
Exemple #7
0
class Plunder(object):
    def __init__(self, char_id):
        self.char_id = char_id
        self.load_mongo_record()

    def load_mongo_record(self):
        try:
            self.mongo_plunder = MongoPlunder.objects.get(id=self.char_id)
            self.set_default_value()
        except DoesNotExist:
            self.mongo_plunder = MongoPlunder(id=self.char_id)
            self.mongo_plunder.current_times = self.max_plunder_times()
            self.mongo_plunder.save()


    def set_default_value(self):
        # 后面新增加的fileds需要初始化数值的。 比如 current_times
        data = {
            'current_times': self.max_plunder_times(),
            'current_times_lock': False,
            'char_id': 0,
            'char_name': "",
            'char_gold': 0,
            'char_power': 0,
            'char_leader': 0,
            'char_formation': [],
            'char_hero_original_ids': [],
            'char_city_id': 0
        }

        record = self.mongo_plunder._get_collection().find_one({'_id': self.char_id})
        for k, v in data.iteritems():
            if k not in record:
                setattr(self.mongo_plunder, k, v)

        self.mongo_plunder.save()


    def get_plunder_target(self, city_id):
        """
        @:rtype: PlunderRival
        """

        target = PlunderRival.search(city_id, exclude_char_id=self.char_id)
        self.mongo_plunder.char_id = target.char_id
        self.mongo_plunder.char_name = target.name
        self.mongo_plunder.char_gold = target.get_plunder_gold(Char(self.char_id).mc.level)
        self.mongo_plunder.char_power = target.power
        self.mongo_plunder.char_leader = target.leader
        self.mongo_plunder.char_formation = target.formation
        self.mongo_plunder.char_hero_original_ids = target.hero_original_ids
        self.mongo_plunder.char_city_id = target.city_id
        self.mongo_plunder.save()

        if target:
            gold_needs = BATTLES[city_id].refresh_cost_gold
            resource = Resource(self.char_id, "Plunder Refresh")
            resource.check_and_remove(gold=-gold_needs)

        return target

    def max_plunder_times(self):
        char = Char(self.char_id)
        return VIP_FUNCTION[char.mc.vip].plunder


    def clean_plunder_target(self):
        self.mongo_plunder.char_id = 0
        self.mongo_plunder.char_name = ""
        self.mongo_plunder.char_gold = 0
        self.mongo_plunder.char_power = 0
        self.mongo_plunder.char_leader = 0
        self.mongo_plunder.char_formation = []
        self.mongo_plunder.char_hero_original_ids = []
        self.mongo_plunder.char_city_id = 0
        self.mongo_plunder.save()


    def change_current_plunder_times(self, change_value, allow_overflow=False):
        max_times = self.max_plunder_times()
        if change_value > 0 and not allow_overflow and self.mongo_plunder.current_times > max_times:
            return

        for i in range(10):
            self.load_mongo_record()
            if not self.mongo_plunder.current_times_lock:
                self.mongo_plunder.current_times_lock = True
                self.mongo_plunder.save()
                break
            else:
                time.sleep(0.2)
        else:
            raise PlunderCurrentTimeOut()

        try:
            self.mongo_plunder.current_times += change_value
            if self.mongo_plunder.current_times < 0:
                self.mongo_plunder.current_times = 0

            if not allow_overflow and change_value > 0:
                max_times = self.max_plunder_times()
                if self.mongo_plunder.current_times > max_times:
                    self.mongo_plunder.current_times = max_times
        finally:
            self.mongo_plunder.current_times_lock = False
            self.mongo_plunder.save()
            self.send_notify()


    def plunder(self):
        if not self.mongo_plunder.char_id:
            raise SanguoException(
                errormsg.PLUNDER_NO_RIVAL,
                self.char_id,
                "Plunder Battle",
                "no rival target"
            )

        if self.mongo_plunder.current_times <= 0:
            raise SanguoException(
                errormsg.PLUNDER_NO_TIMES,
                self.char_id,
                "Plunder Battle",
                "no times"
            )

        self.change_current_plunder_times(change_value=-1)


        msg = MsgBattle()
        pvp = PVPFromRivalCache(
            self.char_id,
            self.mongo_plunder.char_id,
            msg,
            self.mongo_plunder.char_name,
            self.mongo_plunder.char_formation
        )
        pvp.start()

        t = Task(self.char_id)
        t.trig(3)

        to_char_id = self.mongo_plunder.char_id

        if msg.self_win:
            standard_drop = self._get_plunder_reward(
                self.mongo_plunder.char_city_id,
                self.mongo_plunder.char_gold,
                self.mongo_plunder.char_hero_original_ids
            )

            self.clean_plunder_target()

            achievement = Achievement(self.char_id)
            achievement.trig(12, 1)
        else:
            standard_drop = make_standard_drop_from_template()

        self.mongo_plunder.save()
        self.send_notify()

        plunder_finished_signal.send(
            sender=None,
            from_char_id=self.char_id,
            to_char_id=to_char_id,
            from_win=msg.self_win,
            standard_drop=standard_drop
        )

        return (msg, standard_drop)


    def _get_plunder_reward(self, city_id, gold, hero_original_ids):
        def _get_prisoner():
            prison = 0
            heros = [hid for hid in hero_original_ids if hid]

            while heros:
                hid = random.choice(heros)
                heros.remove(hid)
                if hid in PRISONER_POOL:
                    prison = hid
                    break

            if random.randint(1, 100) <= PLUNDER_GET_PRISONER_PROB:
                return prison
            return 0

        char = Char(self.char_id).mc
        vip_plus = VIP_FUNCTION[char.vip].plunder_addition

        standard_drop = make_standard_drop_from_template()
        standard_drop['gold'] = int(gold * (1 + vip_plus / 100.0))

        # 战俘
        got_hero_id = _get_prisoner()
        if got_hero_id:
            p = Prison(self.char_id)
            p.prisoner_add(got_hero_id, gold/2)

            achievement = Achievement(self.char_id)
            achievement.trig(13, 1)

        # 掉落
        city = BATTLES[city_id]
        if city.normal_drop:
            drop_ids = [int(i) for i in city.normal_drop.split(',')]
            drop = get_drop(drop_ids, multi=int(4 * PLUNDER_GET_DROPS_MINUTES * 60 / 15))
            drop.pop('gold')
            standard_drop.update(drop)

        resource = Resource(self.char_id, "Plunder Reward")
        resource.add(**standard_drop)

        self.send_notify()
        if got_hero_id:
            standard_drop['heros'] = [(got_hero_id, 1)]

        return standard_drop


    def send_notify(self):
        self.load_mongo_record()
        msg = PlunderNotify()
        msg.current_times = self.mongo_plunder.current_times
        msg.max_times = self.max_plunder_times()
        publish_to_char(self.char_id, pack_msg(msg))
Exemple #8
0
 def cron_job():
     MongoPlunder._get_collection().update({}, {"$set": {"plunder_times": 0}}, multi=True)