Exemplo n.º 1
0
class Bag(object):
    """ 玩家物品列表管理类 """
    def __init__(self, player):
        self.player = player
        self.equips = {}
        self.items = {}
        self.fates = {}
        self.cars = {}
        self.gem = {}
        if 0:
            from game.player.player import Player
            self.player = Player()
        #default_size = Game.setting_mgr.setdefault(BAG_SIZE, BAG_SIZE_V)
        #self.set_size(default_size)
        #物品快速索引
        #{iid1:([id1, id2, ...],[id3, id4]), ...}
        #{物品基础表id:([可交易物品id...],[不可交易物品id...])...}
        self.iid_to_items = {}
        self._used_count = 0

    def uninit(self):
        self.player = None
        self.equips = {}
        self.items = {}
        self.fates = {}
        self.cars = {}
        self.gem = {}
        self.iid_to_items = {}

    def _load_items(self, items):
        for item_dict in items:
            id = item_dict['id']
            obj = self.items[id] = Item(adict=item_dict)
            self._add_bag_item(obj)
        self._used_count = len(items)

    def _load_single(self, mydict, items, cls):
        for item_dict in items:
            mydict[item_dict["id"]] = cls(adict=item_dict)
            if not item_dict['used']:
                self._used_count += 1

    def load(self):
        """ 加载数据 """
        store = self.player._game.rpc_store
        querys = dict(pid=self.player.data.id)
        tItemDicts = store.query_loads(TN_P_ITEM, querys)
        self._load_items(tItemDicts)
        tEquipDicts = store.query_loads(TN_P_EQUIP, querys)
        self._load_single(self.equips, tEquipDicts, Equip)
        tFateDicts = store.query_loads(TN_P_FATE, querys)
        self._load_single(self.fates, tFateDicts, Fate)
        tCarDicts = store.query_loads(TN_P_CAR, querys)
        for tCarDict in tCarDicts:
            self.cars[tCarDict["id"]] = Car(adict=tCarDict)
        tGemDicts = store.query_loads(TN_P_GEM, querys)
        self._load_single(self.gem, tGemDicts, Gem)

    def load_used(self):
        """ 加载配将使用中的装备和命格 """
        store = self.player._game.rpc_store
        querys = dict(pid=self.player.data.id, used=1)
        tEquipDicts = store.query_loads(TN_P_EQUIP, querys)
        self._load_single(self.equips, tEquipDicts, Equip)
        tFateDicts = store.query_loads(TN_P_FATE, querys)
        self._load_single(self.fates, tFateDicts, Fate)
        tGemDicts = store.query_loads(TN_P_GEM, querys)
        self._load_single(self.gem, tGemDicts, Gem)

    def to_dict(self, used=0):
        """ 获取玩家物品列表 """
        if not used:
            return {
                "equip":
                [equip.to_dict() for equip in self.equips.itervalues()],
                "item": [item.to_dict() for item in self.items.itervalues()],
                "fate": [fate.to_dict() for fate in self.fates.itervalues()],
                "car": [car.to_dict() for car in self.cars.itervalues()],
                "gem": [gem.to_dict() for gem in self.gem.itervalues()],
            }
        return {
            "equip": [
                equip.to_dict() for equip in self.equips.itervalues()
                if equip.data.used
            ],
            "item": [],
            "fate": [
                fate.to_dict() for fate in self.fates.itervalues()
                if fate.data.used
            ],
            "car": [],
            "gem": [gem.to_dict() for gem in self.gem.itervalues()],
        }

    def save(self):
        """ 保存至数据库 """
        store = self.player._game.rpc_store
        for key in self.items.keys():
            if key not in self.items:
                continue
            tItem = self.items[key]
            tItem.save(store)
        for key in self.fates.keys():
            if key not in self.fates:
                continue
            tFate = self.fates[key]
            tFate.save(store)
        for key in self.equips.keys():
            if key not in self.equips:
                continue
            tEq = self.equips[key]
            tEq.save(store)
        for key in self.cars.keys():
            if key not in self.cars:
                continue
            tCar = self.cars[key]
            tCar.save(store)
        for key in self.gem.keys():
            if key not in self.gem:
                continue
            tGem = self.gem[key]
            tGem.save(store)

    def clear(self):
        """ 清除所有数据 """
        store = self.player._game.rpc_store
        for i in self.items.itervalues():
            i.delete(store)
        for i in self.fates.itervalues():
            i.delete(store)
        for i in self.equips.itervalues():
            i.delete(store)
        for i in self.cars.itervalues():
            i.delete(store)
        for i in self.gem.itervalues():
            i.delete(store)
        self.player.roles.clear_attr()
        self.player.clear_attr_car()
        self.items.clear()
        self.fates.clear()
        self.equips.clear()
        self.cars.clear()
        self.gem.clear()
        self.iid_to_items.clear()
        self._used_count = 0

    def copy_from(self, bag):
        #新旧id关联
        items = {}
        self.clear()

        def _add(cls, data):
            item = cls(adict=data.to_dict())
            item.data.id = None
            item.data.pid = self.player.data.id
            item.save(self.player._game.rpc_store)
            items[data.id] = item.data.id

        for i in bag.items.itervalues():
            _add(Item, i.data)
        for i in bag.equips.itervalues():
            _add(Equip, i.data)
        for i in bag.fates.itervalues():
            _add(Fate, i.data)
        for i in bag.cars.itervalues():
            _add(Car, i.data)
        for i in bag.gem.itervalues():
            _add(Gem, i.data)
        self.load()
        return items

    #def set_size(self, aSize):
    #    """ 背包大小设置 """
    #    self.size = aSize

    def check_item(self, iid, count, uses=None):
        """ 检查是否有足够物品消耗,
        uses: 指定使用的id列表
        返回:是否足够,不可交易数,使用id列表"""
        ids = self.iid_to_items[iid]
        ids = ids[NOTRADE_IDX] + ids[TRADE_IDX]
        if uses:
            for i in uses[:]:
                if i not in ids:
                    uses.remove(i)
                else:
                    ids.remove(i)
            ids = uses + ids
        no_trade = 0
        trade = 0
        uses = []
        for id in ids:
            item = self.get_item(id)
            if not item.data.isTrade:
                no_trade += item.data.count
            else:
                trade += item.data.count
            if item.data.count <= count:
                uses.append(id)
                count -= item.data.count
            else:
                uses.append((item, count))
                count = 0
            if not count:
                return True, trade, no_trade, uses
        return False, trade, no_trade, uses

    def has_item(self, iid, count):
        """ 是否有特定数量的物品 """
        rs, trade, no_trade, uses = self.check_item(iid, count)
        return rs

    def cost_item(self,
                  iid,
                  count,
                  unit=None,
                  log_type=None,
                  pack_msg=False,
                  uses=None):
        """ 物品消耗
            uses: 指定使用的物品id列表
            成功返回
            [[删除物品的id...],
            更新后的item]
            #TODO: aUnit: 分组单位数量,要求返回1:可交易2:不可交易数3:两者都有
            失败返回None
            成功返回:可交易组数,不可交易组数,删除物品id列表,更新物品
        """
        iid = int(iid)
        count = int(count)
        if not self.iid_to_items.has_key(iid):
            return
        rs, trade_num, no_trade_num, use_ids = self.check_item(iid,
                                                               count,
                                                               uses=uses)
        if not rs:
            return

        up_item = None
        for id in use_ids:
            if isinstance(id, int):
                #删除使用的物品
                self.del_item(id)
                continue
            #扣除使用的数目(更新物品)
            id[0].data.count -= id[1]
            up_item = id[0]
            self.update_item(up_item)
        #写物品消耗记录
        if log_type:
            self.player.log_item(iid, count, log_type)

        if up_item:  #最后一个是更新物品
            use_ids = use_ids[:-1]
            up_item = [up_item]
        if unit:
            no_trade = int(math.ceil(no_trade_num / unit))
            trade = count / unit - no_trade
        else:
            trade, no_trade = (0, 1) if no_trade_num else (1, 0)
        if pack_msg:
            return trade, no_trade, self.player.pack_msg_data(del_iids=use_ids,
                                                              items=up_item)
        return trade, no_trade, use_ids, up_item

    def sell_all(self, equip_ids, item_ids, fate_ids, gem_ids):
        """ 批量卖出 """
        tCoin1 = 0
        del_eids, del_iids, del_fids, del_gids = [], [], [], []
        item_mgr = self.player._game.item_mgr
        if equip_ids:
            gem_tmp = []
            for tEquipId in equip_ids:
                tEquip = self.get_equip(tEquipId)
                if not tEquip:
                    return False, errcode.EC_BAG_NO
                del_eids.append((tEquip.data.eid, tEquip.data.level))
                gem_tmp.extend(tEquip.data.gem.values())
                tResEquip = item_mgr.get_res_equip(tEquip.data.eid)
                tCoin1 += tResEquip.price
            if gem_ids is None:
                gem_ids = gem_tmp
            else:
                gem_ids.extend(gem_tmp)
        if item_ids:
            for tItemId in item_ids:
                tItem = self.get_item(tItemId)
                if not tItem:
                    return False, errcode.EC_BAG_NO
                del_iids.append((tItem.data.iid, tItem.data.count))
                tResItem = item_mgr.get_res_item(tItem.data.iid)
                tCoin1 += tResItem.price * tItem.data.count
        if fate_ids:
            for tFateId in fate_ids:
                tFate = self.get_fate(tFateId)
                if not tFate:
                    return False, errcode.EC_BAG_NO
                del_fids.append((tFate.data.fid, tFate.data.exp))
                tResFate = item_mgr.get_res_fate(tFate.data.fid)
                tCoin1 += tResFate.price
        if gem_ids:
            for tGemId in gem_ids:
                tGem = self.get_gem(tGemId)
                if not tGem:
                    return False, errcode.EC_BAG_NO
                del_gids.append((tGem.data.gid, tGem.data.level))
                tRemGem = item_mgr.get_res_gem(tGem.data.gid)
                tCoin1 += tRemGem.price
        #加钱
        if tCoin1:
            self.player.add_coin(aCoin1=tCoin1, log_type=COIN_ADD_SELL)
        #删除物品
        self.del_items(item_ids)
        self.del_equips(equip_ids)
        self.del_fates(fate_ids)
        self.del_gem(gem_ids)

        dels = {}
        if del_iids:
            dels['i'] = del_iids
        if del_eids:
            dels['e'] = del_eids
        if del_fids:
            dels['f'] = del_fids
        if del_gids:
            dels['g'] = del_gids
        self.player.log_item(dels, 0, ITEM_SELL)
        return True, self.player.pack_msg_data(coin=True,
                                               del_iids=item_ids,
                                               del_eids=equip_ids,
                                               del_fids=fate_ids,
                                               del_gids=gem_ids)

    def get_item(self, id):
        """ 物品获取 """
        return self.items.get(id)

    def get_item_ex(self, id):
        """ 获取物品和其资源对象 """
        item = self.items.get(id)
        if item is None:
            return None, None
        res_item = self.player._game.item_mgr.get_res_item(item.data.iid)
        return item, res_item

    def get_item_ids_ex(self, iid):
        """ 通过基础物品id获取物品 """
        ids = self.iid_to_items.get(iid)
        if ids is None:
            return None, None
        res_item = self.player._game.item_mgr.get_res_item(iid)
        return ids[NOTRADE_IDX] + ids[TRADE_IDX], res_item

    def update_item(self, aItem):
        """ 物品更新 """
        aItem.modify()

    def _add_bag_item(self, item, insert=False):
        """ 添加单个物品 """
        self.items[item.data.id] = item
        iids = self.iid_to_items.setdefault(item.data.iid, ([], []))
        if insert:
            if item.data.isTrade:
                iids[TRADE_IDX].insert(0, item.data.id)
            else:
                iids[NOTRADE_IDX].insert(0, item.data.id)
            self._used_count += 1
        else:
            if item.data.isTrade:
                iids[TRADE_IDX].append(item.data.id)
            else:
                iids[NOTRADE_IDX].append(item.data.id)
                self._used_count += 1

    def _add_items(self, res_item, count):
        """ 物品添加 """
        def _add(aIid, add_count):
            tItem = Item()
            tItem.data.pid = self.player.data.id
            tItem.data.iid = aIid
            tItem.data.count = add_count
            tItem.save(self.player._game.rpc_store)
            self._add_bag_item(tItem, insert=True)
            return tItem.data.id, tItem

        items = []
        tStack = res_item.stack
        tCnt = int(math.ceil(float(count) / tStack))
        for i in xrange(tCnt):
            if count <= tStack:
                tAddCnt = count
            else:
                count -= tStack
                tAddCnt = tStack
            tId, tItemDict = _add(res_item.id, tAddCnt)
            items.append(tItemDict)
        return items

    def _stack_count(self, item, stack, count, update=True):
        """ update 是否更新数据
        将count个物品堆叠到item物品上
            返回 0 全部放上 非0则放不下
        """
        if stack <= item.data.count:
            return count
        free = stack - item.data.count
        if free >= count:
            if update:
                item.data.count += count
                self.update_item(item)
            return 0
        count -= free
        if update:
            item.data.count += free
            self.update_item(item)
        return count

    def _stack_item(self, res_item, count, can_trade):
        """ 添加堆叠物品 """
        stack = res_item.stack
        tItemIds = self.iid_to_items.get(res_item.id)
        rs = count, []
        if not tItemIds:
            return rs
        tItemIds = tItemIds[TRADE_IDX if can_trade else NOTRADE_IDX]
        if not tItemIds:
            return rs
        rs = []
        for tItemId in tItemIds:
            tItem = self.items.get(tItemId)
            tCount = count
            count = self._stack_count(tItem, stack, count)
            if count == tCount:
                continue
            rs.append(tItem)
            if count <= 0:
                break
        return count, rs

    def get_item_num_by_iid(self, iid):
        """得到物品的数目通过物品id"""
        num = 0
        if iid not in self.iid_to_items:
            return num
        op_tuple = self.iid_to_items[iid]
        ids = op_tuple[NOTRADE_IDX] + op_tuple[TRADE_IDX]
        for id in ids:
            item = self.get_item(id)
            num += item.data.count
        return num

    def add_item(self, aIid, count, can_trade=False, log_type=None):
        """ 物品放入背包(包括更新或者增加) """
        rs = None
        if aIid in DIFF_TITEM_IDS:
            rwitems = RewardItems()
            #处理特殊物品的添加
            rwitems.add_special_item(aIid, count)
            self._add_special_item(rwitems)
        else:
            tResItem = self.player._game.item_mgr.get_res_item(aIid)
            if not tResItem:
                return
            aCount, stack_items = self._stack_item(tResItem, count, can_trade)
            new_items = []
            if aCount:
                new_items = self._add_items(tResItem, aCount)
            rs = stack_items + new_items
        #写入log
        if log_type:
            self.player.log_item(aIid, count, log_type)
        #背包物品变化
        self.player.safe_pub(msg_define.MSG_BAG_ITEM_CHANGE, aIid)
        return rs

    def has_car(self, cid):
        """ 判断是否已经有该坐骑,返回对应的car对象 """
        for c in self.cars.itervalues():
            if c.data.cid == cid:
                return c

    def add_car(self, cid):
        """ 添加坐骑 """
        car = self.has_car(cid)
        if car is not None:
            return car
        car = Car()
        car.data.pid = self.player.data.id
        car.data.cid = cid
        car.save(self.player._game.rpc_store)
        self.cars[car.data.id] = car
        return car

    def can_add_item(self, aIid, aCount, can_trade=False, other_used=0):
        """ 是否可以添加物品,
        返回:(是否可以, 占用新格子数)
        """
        if aIid in DIFF_TITEM_IDS:
            return True, 0
        res_item = self.player._game.item_mgr.get_res_item(aIid)
        if res_item is None:
            return False, 0
        stack = res_item.stack
        free = self.size - self._used_count - other_used
        ids = self.iid_to_items.get(aIid)
        if ids is None:
            c = int(math.ceil(float(aCount) / stack))
            return (True, c) if c <= free else (False, 0)

        ids = ids[TRADE_IDX] if can_trade else ids[NOTRADE_IDX]
        for id in ids:
            item = self.items[id]
            aCount = self._stack_count(item, stack, aCount, update=False)
            if aCount <= 0:
                return True, 0
        c = int(math.ceil(float(aCount) / stack))
        return (True, c) if c <= free else (False, 0)

    def _add_special_item(self, rwitems, bag_items=None):
        #特殊物品处理id(1=银币,2=元宝,3=绑定元宝,4=经验,5=打坐时间, 6=练历)
        player = self.player
        #钱
        coin = bool(rwitems.coin1 or rwitems.coin2 or rwitems.coin3)
        if coin:
            player.add_coin(aCoin1=rwitems.coin1,
                            aCoin2=rwitems.coin2,
                            aCoin3=rwitems.coin3,
                            log_type=COIN_ADD_ITEM)
            if bag_items:
                #bag_items.coin = coin
                bag_items.add_coin(rwitems.coin1, rwitems.coin2, rwitems.coin3)
        #经验
        site_exp = player._game.item_mgr.get_site_exp(player.data.level,
                                                      rwitems.site_times)
        exp = site_exp + rwitems.exp
        if bool(exp):
            if bag_items:
                bag_items.exp += exp
            player.add_exp(exp)
        #练历
        if bool(rwitems.train):
            if bag_items:
                bag_items.train += rwitems.train
            player.add_train(rwitems.train, log_type=TRAIN_BAG)
        #时光盒
        if rwitems.tbox:
            if bag_items:
                bag_items.tbox = True
            tbox_mgr = player._game.tbox_mgr
            for bid in rwitems.tbox:
                tbox_mgr.add_monster(player, bid)

    def add_items(self, items, log_type=None, rid=0):
        """ 添加待收物品列表、奖励物品列表,
         返回: BagItems对象
        """
        bag_items = BagItems(self)
        bag_items.reward_items = items
        rwitems = RewardItems(items)
        self._add_special_item(rwitems, bag_items=bag_items)
        item_mgr = self.player._game.item_mgr
        for _id, counts in rwitems.items.iteritems():
            if counts[TRADE_IDX]:
                add_items = self.add_item(_id, counts[TRADE_IDX], 1)
                if add_items:
                    bag_items.items.extend(add_items)
            if counts[NOTRADE_IDX]:
                add_items = self.add_item(_id, counts[NOTRADE_IDX], 0)
                if add_items:
                    bag_items.items.extend(add_items)
        for _id, c, tr in rwitems.equips:
            for i in xrange(c):
                equip = item_mgr.new_equip(_id, is_trade=tr)
                if not equip:
                    continue
                if self.add_equip(equip) is None:
                    continue
                bag_items.equips.append(equip)
        for _id, c, tr in rwitems.fates:
            for i in xrange(c):
                fate = item_mgr.new_fate(_id, is_trade=tr)
                if not fate:
                    continue
                if self.add_fate(fate) is None:
                    continue
                bag_items.fates.append(fate)
        for rid in rwitems.roles:
            rs, err = self.player.roles.can_add(rid)
            if not rs:
                log.error(u'奖励配将失败:%s', err)
            else:
                bag_items.roles.append(self.player.roles.add_role(err))
        for _id in rwitems.cars:
            res_car = self.player._game.res_mgr.cars.get(_id)
            if res_car:
                t_car = self.add_car(_id)
                bag_items.cars.append(t_car)
            else:
                log.error(u'奖励的坐骑id在资源标表中不存在')
        for _id, c, lv in rwitems.gem:
            for i in xrange(c):
                gem = item_mgr.new_gem(_id, lv)
                if not gem:
                    continue
                if self.add_gem(gem) is None:
                    continue
                bag_items.gem.append(gem)
        if log_type:
            self.player.log_items(items, log_type, rid=rid)
        return bag_items

    def can_add_items(self, items):
        """ 是否能添加待收物品列表、奖励物品列表 """
        add, not_add = self.get_can_add_items(items)
        if len(not_add) == 0:
            return True
        return False

    def get_can_add_items(self, items):
        """ 是否能添加待收物品列表、奖励物品列表 """
        used_count = 0
        add = []
        not_add = []
        free = self.size - self._used_count
        waits = {}
        add_items = copy.deepcopy(items)
        for item in add_items:
            t = item[IKEY_TYPE]
            if t in (IT_CAR_STR, ):
                add.append(item)
                continue
            elif t in (IT_EQUIP_STR, IT_FATE_STR, IT_GEM_STR):
                if used_count + 1 > free:
                    not_add.append(item)
                else:
                    add.append(item)
                    used_count += 1
                continue
            elif t == IT_ITEM_STR:
                if int(item[IKEY_ID]) in DIFF_TITEM_IDS:
                    add.append(item)
                    continue
                iid = item[IKEY_ID]
                if waits.has_key(iid):
                    o_item = waits[iid]
                    o_item[IKEY_COUNT] = int(o_item[IKEY_COUNT]) + int(
                        item[IKEY_COUNT])
                else:
                    waits[iid] = item
        for item in waits.itervalues():
            id = int(item[IKEY_ID])
            c = int(item.get(IKEY_COUNT, 1))
            can_trade = int(item.get(IKEY_TRADE, 0))
            rs, used = self.can_add_item(id,
                                         c,
                                         can_trade,
                                         other_used=used_count)
            if rs:
                add.append(item)
                used_count += used
            else:
                not_add.append(item)
        return add, not_add

    def del_item(self, id, store_delete=True):
        """ 物品删除 """
        tItem = self.items.pop(id)
        if tItem.data.isTrade:
            self.iid_to_items[tItem.data.iid][TRADE_IDX].remove(id)
        else:
            self.iid_to_items[tItem.data.iid][NOTRADE_IDX].remove(id)
        if store_delete:
            self.player._game.rpc_store.delete(TN_P_ITEM, id)
        self._used_count -= 1
        #背包物品变化
        self.player.safe_pub(msg_define.MSG_BAG_ITEM_CHANGE, tItem.data.iid)

    def del_items(self, ids):
        if not ids:
            return
        for iid in ids:
            self.del_item(iid, store_delete=False)
        self.player._game.rpc_store.deletes(TN_P_ITEM, ids)

    def get_fate(self, id):
        """ 命格获取"""
        return self.fates.get(id)

    def get_fate_ex(self, fid):
        """ 获取命格和其资源对象 """
        fate = self.fates.get(fid)
        if fate is None:
            return None, None
        res_fate = self.player._game.item_mgr.get_res_fate(fate.data.fid)
        return fate, res_fate

    def add_fate(self, fate):
        """ 将命格添加到背包 """
        if self.size <= self._used_count:
            return
        fate.data.pid = self.player.data.id
        fate.save(self.player._game.rpc_store)
        self.fates[fate.data.id] = fate
        self._used_count += 1
        #发送背包命格变化消息
        self.player.safe_pub(msg_define.MSG_BAG_FATE_CHANGE, fid=fate.data.fid)
        return fate

    def update_fate(self, fate, used_count=0):
        """ 命格更新: used_count:增加或减少占用的格子数 """
        fate.modify()
        if used_count in (1, -1):
            self._used_count += used_count

    def get_fate_num_by_quality(self, quality):
        num = 0
        for fate in self.fates.itervalues():
            res_fate = self.player._game.item_mgr.get_res_fate(fate.data.fid)
            if res_fate.quality == quality:
                num += 1
        return num

    def del_fate(self, fid, store=1):
        """ 命格删除 """
        if fid not in self.fates:
            return None
        fate = self.fates.pop(fid)
        if not fate.data.used:
            self._used_count -= 1
        if store:
            self.player._game.rpc_store.delete(TN_P_FATE, fid)
        #发送背包命格变化消息
        self.player.safe_pub(msg_define.MSG_BAG_FATE_CHANGE, fid=fate.data.fid)
        return fid

    def del_fates(self, ids):
        """ 多命格删除 """
        if not ids:
            return
        rs = []
        for fid in ids:
            if self.del_fate(fid, store=0):
                rs.append(fid)
        self.player._game.rpc_store.deletes(TN_P_FATE, ids)
        return rs

    def add_equip(self, equip, forced=0):
        """ 添加装备 """
        if not forced and self.size <= self._used_count:
            return
        equip.data.pid = self.player.data.id
        equip.save(self.player._game.rpc_store)
        self.equips[equip.data.id] = equip
        self._used_count += 1
        return equip

    def get_equip(self, id):
        """ 装备获取 """
        return self.equips.get(id)

    def get_equip_ex(self, eid):
        """ 获取装备和其资源对象 """
        equip = self.equips.get(eid)
        if equip is None:
            return None, None
        res_equip = self.player._game.item_mgr.get_res_equip(equip.data.eid)
        return equip, res_equip

    def get_equips_by_eid(self, eid):
        """ 通过基础装备id获取装备 """
        return [e for e in self.equips.itervalues() if e.data.eid == eid]

    def has_equip(self, eid):
        """ 是否有特定装备 """
        for e in self.equips.itervalues():
            if eid == e.data.eid:
                return True
        return False

    def update_equip(self, equip, used_count=0):
        """ 装备更新: used_count增加或减少暂用的格子数"""
        equip.modify()
        if used_count in (1, -1):
            self._used_count += used_count

    def del_equips(self, ids):
        """ 多装备删除 """
        if not ids:
            return
        rs = []
        for eid in ids:
            if self.del_equip(eid, store=0):
                rs.append(eid)
        self.player._game.rpc_store.deletes(TN_P_EQUIP, ids)
        return rs

    def del_equip(self, id, store=1):
        """ 装备删除 """
        if id not in self.equips:
            return None
        equip = self.equips.pop(id)
        if not equip.data.used:
            self._used_count -= 1
        if store:
            self.player._game.rpc_store.delete(TN_P_EQUIP, id)
        return id

    def get_gem(self, id):
        """珠宝获取"""
        return self.gem.get(id)

    def get_gem_ex(self, gid):
        gem = self.gem.get(gid)
        if gem is None:
            return None, None
        res_gem = self.player._game.item_mgr.get_res_gem(gem.data.gid)
        return gem, res_gem

    def add_gem(self, gem):
        if self.size <= self._used_count:
            return
        gem.data.pid = self.player.data.id
        gem.save(self.player._game.rpc_store)
        self.gem[gem.data.id] = gem
        self._used_count += 1
        return gem

    def del_gem(self, ids):
        if not ids:
            return
        for gid in ids:
            if gid not in self.gem:
                continue
            gem = self.gem.pop(gid)
            if not gem.data.used:
                self._used_count -= 1
        self.player._game.rpc_store.deletes(TN_P_GEM, ids)

    def update_gem(self, gem, used_count=0):
        """ 珠宝更新: used_count:增加或减少占用的格子数 """
        gem.modify()
        if used_count in (1, -1):
            self._used_count += used_count

    def bag_free(self):
        """ 返回背包格子剩余数 """
        return self.size - self._used_count

    @property
    def size(self):
        return Game.setting_mgr.fetch_size(self.player.data.vip)
Exemplo n.º 2
0
class Bag(object):
    """ 玩家物品列表管理类 """
    def __init__(self, player):
        self.player = player
        self.equips = {}
        self.items = {}
        self.fates = {}
        self.cars = {}
        self.gem = {}
        if 0:
            from game.player.player import Player
            self.player = Player()
        #default_size = Game.setting_mgr.setdefault(BAG_SIZE, BAG_SIZE_V)
        #self.set_size(default_size)
        #物品快速索引
        #{iid1:([id1, id2, ...],[id3, id4]), ...}
        #{物品基础表id:([可交易物品id...],[不可交易物品id...])...}
        self.iid_to_items = {}
        self._used_count = 0

    def uninit(self):
        self.player = None
        self.equips = {}
        self.items = {}
        self.fates = {}
        self.cars = {}
        self.gem = {}
        self.iid_to_items = {}


    def _load_items(self, items):
        for item_dict in items:
            id = item_dict['id']
            obj = self.items[id] = Item(adict=item_dict)
            self._add_bag_item(obj)
        self._used_count = len(items)

    def _load_single(self, mydict, items, cls):
        for item_dict in items:
            mydict[item_dict["id"]] = cls(adict=item_dict)
            if not item_dict['used']:
                self._used_count += 1

    def load(self):
        """ 加载数据 """
        store = self.player._game.rpc_store
        querys = dict(pid=self.player.data.id)
        tItemDicts = store.query_loads(TN_P_ITEM, querys)
        self._load_items(tItemDicts)
        tEquipDicts = store.query_loads(TN_P_EQUIP, querys)
        self._load_single(self.equips, tEquipDicts, Equip)
        tFateDicts = store.query_loads(TN_P_FATE, querys)
        self._load_single(self.fates, tFateDicts, Fate)
        tCarDicts = store.query_loads(TN_P_CAR, querys)
        for tCarDict in tCarDicts:
            self.cars[tCarDict["id"]] = Car(adict=tCarDict)
        tGemDicts = store.query_loads(TN_P_GEM, querys)
        self._load_single(self.gem, tGemDicts, Gem)

    def load_used(self):
        """ 加载配将使用中的装备和命格 """
        store = self.player._game.rpc_store
        querys = dict(pid=self.player.data.id, used=1)
        tEquipDicts = store.query_loads(TN_P_EQUIP, querys)
        self._load_single(self.equips, tEquipDicts, Equip)
        tFateDicts = store.query_loads(TN_P_FATE, querys)
        self._load_single(self.fates, tFateDicts, Fate)
        tGemDicts = store.query_loads(TN_P_GEM, querys)
        self._load_single(self.gem, tGemDicts, Gem)

    def to_dict(self, used=0):
        """ 获取玩家物品列表 """
        if not used:
            return {
                "equip":[equip.to_dict() for equip in self.equips.itervalues()],
                "item":[item.to_dict() for item in self.items.itervalues()],
                "fate":[fate.to_dict() for fate in self.fates.itervalues()],
                "car": [car.to_dict() for car in self.cars.itervalues()],
                "gem":[gem.to_dict() for gem in self.gem.itervalues()],
                }
        return {
            "equip":[equip.to_dict() for equip in self.equips.itervalues() if equip.data.used],
            "item":[],
            "fate":[fate.to_dict() for fate in self.fates.itervalues() if fate.data.used],
            "car": [],
            "gem":[gem.to_dict() for gem in self.gem.itervalues()],
        }

    def save(self):
        """ 保存至数据库 """
        store = self.player._game.rpc_store
        for key in self.items.keys():
            if key not in self.items:
                continue
            tItem = self.items[key]
            tItem.save(store)
        for key in self.fates.keys():
            if key not in self.fates:
                continue
            tFate = self.fates[key]
            tFate.save(store)
        for key in self.equips.keys():
            if key not in self.equips:
                continue
            tEq = self.equips[key]
            tEq.save(store)
        for key in self.cars.keys():
            if key not in self.cars:
                continue
            tCar = self.cars[key]
            tCar.save(store)
        for key in self.gem.keys():
            if key not in self.gem:
                continue
            tGem = self.gem[key]
            tGem.save(store)


    def clear(self):
        """ 清除所有数据 """
        store = self.player._game.rpc_store
        for i in self.items.itervalues():
            i.delete(store)
        for i in self.fates.itervalues():
            i.delete(store)
        for i in self.equips.itervalues():
            i.delete(store)
        for i in self.cars.itervalues():
            i.delete(store)
        for i in self.gem.itervalues():
            i.delete(store)
        self.player.roles.clear_attr()
        self.player.clear_attr_car()
        self.items.clear()
        self.fates.clear()
        self.equips.clear()
        self.cars.clear()
        self.gem.clear()
        self.iid_to_items.clear()
        self._used_count = 0

    def copy_from(self, bag):
        #新旧id关联
        items = {}
        self.clear()
        def _add(cls, data):
            item = cls(adict=data.to_dict())
            item.data.id = None
            item.data.pid = self.player.data.id
            item.save(self.player._game.rpc_store)
            items[data.id] = item.data.id
        for i in bag.items.itervalues():
            _add(Item, i.data)
        for i in bag.equips.itervalues():
            _add(Equip, i.data)
        for i in bag.fates.itervalues():
            _add(Fate, i.data)
        for i in bag.cars.itervalues():
            _add(Car, i.data)
        for i in bag.gem.itervalues():
            _add(Gem, i.data)
        self.load()
        return items

    #def set_size(self, aSize):
    #    """ 背包大小设置 """
    #    self.size = aSize

    def check_item(self, iid, count, uses=None):
        """ 检查是否有足够物品消耗,
        uses: 指定使用的id列表
        返回:是否足够,不可交易数,使用id列表"""
        ids = self.iid_to_items[iid]
        ids = ids[NOTRADE_IDX] + ids[TRADE_IDX]
        if uses:
            for i in uses[:]:
                if i not in ids:
                    uses.remove(i)
                else:
                    ids.remove(i)
            ids = uses + ids
        no_trade = 0
        trade = 0
        uses = []
        for id in ids:
            item = self.get_item(id)
            if not item.data.isTrade:
                no_trade += item.data.count
            else:
                trade += item.data.count
            if item.data.count <= count:
                uses.append(id)
                count -= item.data.count
            else:
                uses.append((item, count))
                count = 0
            if not count:
                return True, trade, no_trade, uses
        return False, trade, no_trade, uses

    def has_item(self, iid, count):
        """ 是否有特定数量的物品 """
        rs, trade, no_trade, uses = self.check_item(iid, count)
        return rs

    def cost_item(self, iid, count, unit=None, log_type=None, pack_msg=False, uses=None):
        """ 物品消耗
            uses: 指定使用的物品id列表
            成功返回
            [[删除物品的id...],
            更新后的item]
            #TODO: aUnit: 分组单位数量,要求返回1:可交易2:不可交易数3:两者都有
            失败返回None
            成功返回:可交易组数,不可交易组数,删除物品id列表,更新物品
        """
        iid = int(iid)
        count = int(count)
        if not self.iid_to_items.has_key(iid):
            return
        rs, trade_num, no_trade_num, use_ids = self.check_item(iid, count, uses=uses)
        if not rs:
            return

        up_item = None
        for id in use_ids:
            if isinstance(id, int):
                #删除使用的物品
                self.del_item(id)
                continue
            #扣除使用的数目(更新物品)
            id[0].data.count -= id[1]
            up_item = id[0]
            self.update_item(up_item)
        #写物品消耗记录
        if log_type:
            self.player.log_item(iid, count, log_type)

        if up_item:#最后一个是更新物品
            use_ids = use_ids[:-1]
            up_item = [up_item]
        if unit:
            no_trade = int(math.ceil(no_trade_num / unit))
            trade = count / unit - no_trade
        else:
            trade, no_trade = (0, 1) if no_trade_num else (1, 0)
        if pack_msg:
            return trade, no_trade, self.player.pack_msg_data(del_iids=use_ids, items=up_item)
        return trade, no_trade,  use_ids, up_item

    def sell_all(self, equip_ids, item_ids, fate_ids, gem_ids):
        """ 批量卖出 """
        tCoin1 = 0
        del_eids, del_iids, del_fids, del_gids = [], [], [], []
        item_mgr = self.player._game.item_mgr
        if equip_ids:
            gem_tmp = []
            for tEquipId in equip_ids:
                tEquip = self.get_equip(tEquipId)
                if not tEquip:
                    return False, errcode.EC_BAG_NO
                del_eids.append((tEquip.data.eid, tEquip.data.level))
                gem_tmp.extend(tEquip.data.gem.values())
                tResEquip = item_mgr.get_res_equip(tEquip.data.eid)
                tCoin1 += tResEquip.price
            if gem_ids is None:
                gem_ids = gem_tmp
            else:
                gem_ids.extend(gem_tmp)
        if item_ids:
            for tItemId in item_ids:
                tItem = self.get_item(tItemId)
                if not tItem:
                    return False, errcode.EC_BAG_NO
                del_iids.append((tItem.data.iid, tItem.data.count))
                tResItem = item_mgr.get_res_item(tItem.data.iid)
                tCoin1 += tResItem.price*tItem.data.count
        if fate_ids:
            for tFateId in fate_ids:
                tFate = self.get_fate(tFateId)
                if not tFate:
                    return False, errcode.EC_BAG_NO
                del_fids.append((tFate.data.fid, tFate.data.exp))
                tResFate = item_mgr.get_res_fate(tFate.data.fid)
                tCoin1 += tResFate.price
        if gem_ids:
            for tGemId in gem_ids:
                tGem = self.get_gem(tGemId)
                if not tGem:
                    return False, errcode.EC_BAG_NO
                del_gids.append((tGem.data.gid, tGem.data.level))
                tRemGem = item_mgr.get_res_gem(tGem.data.gid)
                tCoin1 += tRemGem.price
        #加钱
        if tCoin1:
            self.player.add_coin(aCoin1=tCoin1, log_type=COIN_ADD_SELL)
        #删除物品
        self.del_items(item_ids)
        self.del_equips(equip_ids)
        self.del_fates(fate_ids)
        self.del_gem(gem_ids)

        dels = {}
        if del_iids:
            dels['i'] = del_iids
        if del_eids:
            dels['e'] = del_eids
        if del_fids:
            dels['f'] = del_fids
        if del_gids:
            dels['g'] = del_gids
        self.player.log_item(dels, 0, ITEM_SELL)
        return True, self.player.pack_msg_data(coin=True, del_iids=item_ids,
            del_eids=equip_ids, del_fids=fate_ids, del_gids=gem_ids)

    def get_item(self, id):
        """ 物品获取 """
        return self.items.get(id)

    def get_item_ex(self, id):
        """ 获取物品和其资源对象 """
        item = self.items.get(id)
        if item is None:
            return None, None
        res_item = self.player._game.item_mgr.get_res_item(item.data.iid)
        return item, res_item

    def get_item_ids_ex(self, iid):
        """ 通过基础物品id获取物品 """
        ids = self.iid_to_items.get(iid)
        if ids is None:
            return None, None
        res_item = self.player._game.item_mgr.get_res_item(iid)
        return ids[NOTRADE_IDX] + ids[TRADE_IDX], res_item

    def update_item(self, aItem):
        """ 物品更新 """
        aItem.modify()

    def _add_bag_item(self, item, insert=False):
        """ 添加单个物品 """
        self.items[item.data.id] = item
        iids = self.iid_to_items.setdefault(item.data.iid, ([], []))
        if insert:
            if item.data.isTrade:
                iids[TRADE_IDX].insert(0, item.data.id)
            else:
                iids[NOTRADE_IDX].insert(0, item.data.id)
            self._used_count += 1
        else:
            if item.data.isTrade:
                iids[TRADE_IDX].append(item.data.id)
            else:
                iids[NOTRADE_IDX].append(item.data.id)
                self._used_count += 1

    def _add_items(self, res_item, count):
        """ 物品添加 """
        def _add(aIid, add_count):
            tItem = Item()
            tItem.data.pid = self.player.data.id
            tItem.data.iid = aIid
            tItem.data.count = add_count
            tItem.save(self.player._game.rpc_store)
            self._add_bag_item(tItem, insert=True)
            return tItem.data.id, tItem

        items = []
        tStack = res_item.stack
        tCnt = int(math.ceil(float(count)/tStack))
        for i in xrange(tCnt):
            if count <= tStack:
                tAddCnt = count
            else:
                count -= tStack
                tAddCnt = tStack
            tId, tItemDict = _add(res_item.id, tAddCnt)
            items.append(tItemDict)
        return items

    def _stack_count(self, item, stack, count, update=True):
        """ update 是否更新数据
        将count个物品堆叠到item物品上
            返回 0 全部放上 非0则放不下
        """
        if stack <= item.data.count:
            return count
        free = stack - item.data.count
        if free >= count:
            if update:
                item.data.count += count
                self.update_item(item)
            return 0
        count -= free
        if update:
            item.data.count += free
            self.update_item(item)
        return count

    def _stack_item(self, res_item, count, can_trade):
        """ 添加堆叠物品 """
        stack = res_item.stack
        tItemIds = self.iid_to_items.get(res_item.id)
        rs = count, []
        if not tItemIds:
            return rs
        tItemIds = tItemIds[TRADE_IDX if can_trade else NOTRADE_IDX]
        if not tItemIds:
            return rs
        rs = []
        for tItemId in tItemIds:
            tItem = self.items.get(tItemId)
            tCount = count
            count = self._stack_count(tItem, stack, count)
            if count == tCount:
                continue
            rs.append(tItem)
            if count <= 0:
                break
        return count, rs

    def get_item_num_by_iid(self, iid):
        """得到物品的数目通过物品id"""
        num = 0
        if iid not in self.iid_to_items:
            return num
        op_tuple = self.iid_to_items[iid]
        ids = op_tuple[NOTRADE_IDX] + op_tuple[TRADE_IDX]
        for id in ids:
            item = self.get_item(id)
            num += item.data.count
        return num

    def add_item(self, aIid, count, can_trade=False, log_type=None):
        """ 物品放入背包(包括更新或者增加) """
        rs = None
        if aIid in DIFF_TITEM_IDS:
            rwitems = RewardItems()
            #处理特殊物品的添加
            rwitems.add_special_item(aIid, count)
            self._add_special_item(rwitems)
        else:
            tResItem = self.player._game.item_mgr.get_res_item(aIid)
            if not tResItem:
                return
            aCount, stack_items = self._stack_item(tResItem, count, can_trade)
            new_items = []
            if aCount:
                new_items = self._add_items(tResItem, aCount)
            rs = stack_items + new_items
        #写入log
        if log_type:
            self.player.log_item(aIid, count, log_type)
        #背包物品变化
        self.player.safe_pub(msg_define.MSG_BAG_ITEM_CHANGE, aIid)
        return rs

    def has_car(self, cid):
        """ 判断是否已经有该坐骑,返回对应的car对象 """
        for c in self.cars.itervalues():
            if c.data.cid == cid:
                return c

    def add_car(self, cid):
        """ 添加坐骑 """
        car = self.has_car(cid)
        if car is not None:
            return car
        car = Car()
        car.data.pid = self.player.data.id
        car.data.cid = cid
        car.save(self.player._game.rpc_store)
        self.cars[car.data.id] = car
        return car

    def can_add_item(self, aIid, aCount, can_trade=False, other_used=0):
        """ 是否可以添加物品,
        返回:(是否可以, 占用新格子数)
        """
        if aIid in DIFF_TITEM_IDS:
            return True, 0
        res_item = self.player._game.item_mgr.get_res_item(aIid)
        if res_item is None:
            return False, 0
        stack = res_item.stack
        free = self.size - self._used_count - other_used
        ids = self.iid_to_items.get(aIid)
        if ids is None:
            c = int(math.ceil(float(aCount) / stack))
            return (True, c) if c <= free else (False, 0)

        ids = ids[TRADE_IDX] if can_trade else ids[NOTRADE_IDX]
        for id in ids:
            item = self.items[id]
            aCount = self._stack_count(item, stack, aCount, update=False)
            if aCount <=0:
                return True, 0
        c = int(math.ceil(float(aCount) / stack))
        return (True, c) if c <= free else (False, 0)

    def _add_special_item(self, rwitems, bag_items=None):
        #特殊物品处理id(1=银币,2=元宝,3=绑定元宝,4=经验,5=打坐时间, 6=练历)
        player = self.player
        #钱
        coin = bool(rwitems.coin1 or rwitems.coin2 or rwitems.coin3)
        if coin:
            player.add_coin(aCoin1=rwitems.coin1, aCoin2=rwitems.coin2,
                    aCoin3=rwitems.coin3, log_type=COIN_ADD_ITEM)
            if bag_items:
                #bag_items.coin = coin
                bag_items.add_coin(rwitems.coin1, rwitems.coin2,
                        rwitems.coin3)
        #经验
        site_exp = player._game.item_mgr.get_site_exp(player.data.level,
                rwitems.site_times)
        exp = site_exp + rwitems.exp
        if bool(exp):
            if bag_items:
                bag_items.exp += exp
            player.add_exp(exp)
        #练历
        if bool(rwitems.train):
            if bag_items:
                bag_items.train += rwitems.train
            player.add_train(rwitems.train, log_type=TRAIN_BAG)
        #时光盒
        if rwitems.tbox:
            if bag_items:
                bag_items.tbox = True
            tbox_mgr = player._game.tbox_mgr
            for bid in rwitems.tbox:
                tbox_mgr.add_monster(player, bid)

    def add_items(self, items, log_type=None, rid=0):
        """ 添加待收物品列表、奖励物品列表,
         返回: BagItems对象
        """
        bag_items = BagItems(self)
        bag_items.reward_items = items
        rwitems = RewardItems(items)
        self._add_special_item(rwitems, bag_items=bag_items)
        item_mgr = self.player._game.item_mgr
        for _id, counts in rwitems.items.iteritems():
            if counts[TRADE_IDX]:
                add_items = self.add_item(_id, counts[TRADE_IDX], 1)
                if add_items:
                    bag_items.items.extend(add_items)
            if counts[NOTRADE_IDX]:
                add_items = self.add_item(_id, counts[NOTRADE_IDX], 0)
                if add_items:
                    bag_items.items.extend(add_items)
        for _id, c, tr in rwitems.equips:
            for i in xrange(c):
                equip = item_mgr.new_equip(_id, is_trade=tr)
                if not equip:
                    continue
                if self.add_equip(equip) is None:
                    continue
                bag_items.equips.append(equip)
        for _id, c, tr in rwitems.fates:
            for i in xrange(c):
                fate = item_mgr.new_fate(_id, is_trade=tr)
                if not fate:
                    continue
                if self.add_fate(fate) is None:
                    continue
                bag_items.fates.append(fate)
        for rid in rwitems.roles:
            rs, err = self.player.roles.can_add(rid)
            if not rs:
                log.error(u'奖励配将失败:%s', err)
            else:
                bag_items.roles.append(self.player.roles.add_role(err))
        for _id in rwitems.cars:
            res_car = self.player._game.res_mgr.cars.get(_id)
            if res_car:
                t_car = self.add_car(_id)
                bag_items.cars.append(t_car)
            else:
                log.error(u'奖励的坐骑id在资源标表中不存在')
        for _id, c, lv in rwitems.gem:
            for i in xrange(c):
                gem = item_mgr.new_gem(_id, lv)
                if not gem:
                    continue
                if self.add_gem(gem) is None:
                    continue
                bag_items.gem.append(gem)
        if log_type:
            self.player.log_items(items, log_type, rid=rid)
        return bag_items

    def can_add_items(self, items):
        """ 是否能添加待收物品列表、奖励物品列表 """
        add, not_add = self.get_can_add_items(items)
        if len(not_add) == 0:
            return True
        return False

    def get_can_add_items(self, items):
        """ 是否能添加待收物品列表、奖励物品列表 """
        used_count = 0
        add = []
        not_add = []
        free = self.size - self._used_count
        waits = {}
        add_items = copy.deepcopy(items)
        for item in add_items:
            t = item[IKEY_TYPE]
            if t in (IT_CAR_STR, ):
                add.append(item)
                continue
            elif t in (IT_EQUIP_STR, IT_FATE_STR, IT_GEM_STR):
                if used_count + 1 > free:
                    not_add.append(item)
                else:
                    add.append(item)
                    used_count += 1
                continue
            elif t == IT_ITEM_STR:
                if int(item[IKEY_ID]) in DIFF_TITEM_IDS:
                    add.append(item)
                    continue
                iid = item[IKEY_ID]
                if waits.has_key(iid):
                    o_item = waits[iid]
                    o_item[IKEY_COUNT] = int(o_item[IKEY_COUNT]) + int(item[IKEY_COUNT])
                else:
                    waits[iid] = item
        for item in waits.itervalues():
            id = int(item[IKEY_ID])
            c = int(item.get(IKEY_COUNT, 1))
            can_trade = int(item.get(IKEY_TRADE, 0))
            rs, used = self.can_add_item(id, c, can_trade, other_used=used_count)
            if rs:
                add.append(item)
                used_count += used
            else:
                not_add.append(item)
        return add, not_add

    def del_item(self, id, store_delete=True):
        """ 物品删除 """
        tItem = self.items.pop(id)
        if tItem.data.isTrade:
            self.iid_to_items[tItem.data.iid][TRADE_IDX].remove(id)
        else:
            self.iid_to_items[tItem.data.iid][NOTRADE_IDX].remove(id)
        if store_delete:
            self.player._game.rpc_store.delete(TN_P_ITEM, id)
        self._used_count -= 1
        #背包物品变化
        self.player.safe_pub(msg_define.MSG_BAG_ITEM_CHANGE, tItem.data.iid)

    def del_items(self, ids):
        if not ids:
            return
        for iid in ids:
            self.del_item(iid, store_delete=False)
        self.player._game.rpc_store.deletes(TN_P_ITEM, ids)

    def get_fate(self, id):
        """ 命格获取"""
        return self.fates.get(id)

    def get_fate_ex(self, fid):
        """ 获取命格和其资源对象 """
        fate = self.fates.get(fid)
        if fate is None:
            return None, None
        res_fate = self.player._game.item_mgr.get_res_fate(fate.data.fid)
        return fate, res_fate

    def add_fate(self, fate):
        """ 将命格添加到背包 """
        if self.size <= self._used_count:
            return
        fate.data.pid = self.player.data.id
        fate.save(self.player._game.rpc_store)
        self.fates[fate.data.id] = fate
        self._used_count += 1
        #发送背包命格变化消息
        self.player.safe_pub(msg_define.MSG_BAG_FATE_CHANGE, fid = fate.data.fid)
        return fate

    def update_fate(self, fate, used_count=0):
        """ 命格更新: used_count:增加或减少占用的格子数 """
        fate.modify()
        if used_count in (1, -1):
            self._used_count += used_count

    def get_fate_num_by_quality(self, quality):
        num = 0
        for fate in self.fates.itervalues():
            res_fate = self.player._game.item_mgr.get_res_fate(fate.data.fid)
            if res_fate.quality == quality:
                num += 1
        return num

    def del_fate(self, fid, store=1):
        """ 命格删除 """
        if fid not in self.fates:
            return None
        fate = self.fates.pop(fid)
        if not fate.data.used:
            self._used_count -= 1
        if store:
            self.player._game.rpc_store.delete(TN_P_FATE, fid)
        #发送背包命格变化消息
        self.player.safe_pub(msg_define.MSG_BAG_FATE_CHANGE, fid = fate.data.fid)
        return fid

    def del_fates(self, ids):
        """ 多命格删除 """
        if not ids:
            return
        rs = []
        for fid in ids:
            if self.del_fate(fid, store=0):
                rs.append(fid)
        self.player._game.rpc_store.deletes(TN_P_FATE, ids)
        return rs

    def add_equip(self, equip, forced=0):
        """ 添加装备 """
        if not forced and self.size <= self._used_count:
            return
        equip.data.pid = self.player.data.id
        equip.save(self.player._game.rpc_store)
        self.equips[equip.data.id] = equip
        self._used_count += 1
        return equip

    def get_equip(self, id):
        """ 装备获取 """
        return self.equips.get(id)

    def get_equip_ex(self, eid):
        """ 获取装备和其资源对象 """
        equip = self.equips.get(eid)
        if equip is None:
            return None, None
        res_equip = self.player._game.item_mgr.get_res_equip(equip.data.eid)
        return equip, res_equip

    def get_equips_by_eid(self, eid):
        """ 通过基础装备id获取装备 """
        return [e for e in self.equips.itervalues() if e.data.eid==eid]


    def has_equip(self, eid):
        """ 是否有特定装备 """
        for e in self.equips.itervalues():
            if eid == e.data.eid:
                return True
        return False

    def update_equip(self, equip, used_count=0):
        """ 装备更新: used_count增加或减少暂用的格子数"""
        equip.modify()
        if used_count in (1, -1):
            self._used_count += used_count

    def del_equips(self, ids):
        """ 多装备删除 """
        if not ids:
            return
        rs = []
        for eid in ids:
            if self.del_equip(eid, store=0):
                rs.append(eid)
        self.player._game.rpc_store.deletes(TN_P_EQUIP, ids)
        return rs

    def del_equip(self, id, store=1):
        """ 装备删除 """
        if id not in self.equips:
            return None
        equip = self.equips.pop(id)
        if not equip.data.used:
            self._used_count -= 1
        if store:
            self.player._game.rpc_store.delete(TN_P_EQUIP, id)
        return id

    def get_gem(self, id):
        """珠宝获取"""
        return self.gem.get(id)

    def get_gem_ex(self, gid):
        gem = self.gem.get(gid)
        if gem is None:
            return None, None
        res_gem = self.player._game.item_mgr.get_res_gem(gem.data.gid)
        return gem, res_gem

    def add_gem(self, gem):
        if self.size <= self._used_count:
            return
        gem.data.pid = self.player.data.id
        gem.save(self.player._game.rpc_store)
        self.gem[gem.data.id] = gem
        self._used_count += 1
        return gem

    def del_gem(self, ids):
        if not ids:
            return
        for gid in ids:
            if gid not in self.gem:
                continue
            gem = self.gem.pop(gid)
            if not gem.data.used:
                self._used_count -= 1
        self.player._game.rpc_store.deletes(TN_P_GEM, ids)

    def update_gem(self, gem, used_count=0):
        """ 珠宝更新: used_count:增加或减少占用的格子数 """
        gem.modify()
        if used_count in (1, -1):
            self._used_count += used_count

    def bag_free(self):
        """ 返回背包格子剩余数 """
        return self.size - self._used_count

    @property
    def size(self):
        return Game.setting_mgr.fetch_size(self.player.data.vip)
Exemplo n.º 3
0
class GMPlayer(object):
    """ 对玩家的gm命令类 """
    def __init__(self, gm, player):
        self.player = player
        self.gm = gm
        self._raw_return = 0
        if 0:
            from game.player.player import Player
            self.player = Player()
            self.gm = GameMaster()

    @contextmanager
    def raw_return_context(self):
        self._raw_return = 1
        try:
            yield
        finally:
            self._raw_return = 0

    def info(self):
        self.gm.log(player_info(self.player))
        self.gm.log('*' * 10)

    def clear_player(self, all=True, dels=tuple()):
        self.player.clear(all=all, dels=dels)
        self.gm.log(u'清理玩家数据成功')

    def clear_bag(self):
        self.player.bag.clear()
        self.gm.log(u'清除玩家背包')

    def clear_ally_tbox_team(self):
        """重置同盟组队炼妖"""
        data = dict(bids=[], t=0, cr=0)
        self.player.set_ally_tbox_data(data)
        self.gm.log(u'重置同盟组队炼妖')

    def copy(self, pid):
        """ 完全复制玩家数据 """
        if self.player.copy_player(pid):
            self.gm.log(u'拷贝成功')
        else:
            self.gm.log(u'拷贝失败')

    def clear_part_data(self, *args):
        """ 部分指定删除 """
        self.player.clear(all=False, dels=args[0])
        self.gm.log(u'清理玩家部分数据成功')

    def add_money(self, coin1, coin2=0, coin3=0, is_set=False, vip=False):
        """ 增加金钱(coin1, coin2=0, coin3=0) """
        data = self.player.data
        self.player.add_coin(aCoin1=coin1,
                             aCoin2=coin2,
                             aCoin3=coin3,
                             is_set=is_set,
                             vip=vip,
                             log_type=COIN_ADD_GM)
        self.gm.log(u'增加银币成功,角色当前(银币,元宝,绑元宝)数:(%s, %s, %s)', data.coin1,
                    data.coin2, data.coin3)
        self.player.pack_msg_data(coin=1, send=1)

    def tbox_change_data(self, chapter, tbids):
        """ 修改时光盒数据 """
        log.debug('chpteer--%s %s', chapter, tbids)
        chapter_id = chapter + 1
        self.player._game.tbox_mgr.init_player_tbox(self.player)
        oPTbox = getattr(self.player.runtimes, TN_P_TBOX)
        rs = oPTbox.gm_change_data(chapter_id, tbids)
        if not rs:
            self.gm.log(u'数据填入错误')
            return
        self.gm.log(u'时光盒数据更改成功')

    def add_exp(self, exp):
        """ 增加经验 """
        self.player.add_exp(exp)
        self.gm.log(u'增加经验成功:lv=%s, exp=%s', self.player.data.level,
                    self.player.data.exp)
        self.player.pack_msg_data(exp=1, send=1)

    def add_train(self, train):
        """ 增加练历 """
        self.player.add_train(train, log_type=TRAIN_GM)
        self.gm.log(u'增加练历成功:%s', self.player.data.train)
        self.player.pack_msg_data(train=1, send=1)

    def add_re(self, num, chapter=0):
        """ 刷新次数 1:时光盒,"""
        self.player._game.tbox_mgr.init_player_tbox(self.player)
        oPTbox = getattr(self.player.runtimes, TN_P_TBOX)
        chapter += 1
        for o in oPTbox.p_tboxs.itervalues():
            if chapter == 1:
                o.data.re1 = num
                o.data.re2 = num
                o.modify()
            if chapter == o.data.chapter:
                o.data.re1 = num
                o.data.re2 = num
                o.modify()
        self.gm.log(u'时光盒刷新次数更新完成')

    def awar_kill_monster(self):
        """ 狩龙战 批量杀死地图上的所有npc """
        rs, data = self.player._game.rpc_awar_mgr.gm_kill_monsters(
            self.player.data.id)
        if rs:
            self.gm.log(u'成功杀完该地图上的npc')
        else:
            self.gm.log(u'秒杀失败,请检查是否进入战场')

    def rest_daylucky(self, mnum, lucky_role=True):
        """ 改变抽奖次数上线并重置抽奖 """
        self.player._game.day_lucky_mgr.init_player_dayluck(self.player)
        player_daylucky = getattr(self.player.runtimes, TN_P_DAYLUCKY)
        player_daylucky.day_lucky.data.d['mdraw'] = mnum - 1
        player_daylucky.day_lucky.data.d['ctime'] = int(time.time()) - 86400
        if lucky_role:
            player_daylucky.day_lucky.data.d['rids'] = []
        player_daylucky.enter()
        self.gm.log(u'抽奖修改成功!')

    def add_bf_boxes(self, num):
        """ 添加兵符任务 剩余箱子数目 """
        self.player._game.bftask_mgr.init_player_bftask(self.player)
        player_bftask = getattr(self.player.runtimes, PLAYER_ATTR_BFTASK)
        max_boxes = self.player._game.bftask_mgr.bf_boxes(self.player.data.vip)
        if num > max_boxes: num = max_boxes
        player_bftask.bfTaskData.bs = num
        self.gm.log(u'兵符任务剩余宝箱数目')

    def add_fete_num(self, num, type=1):
        """ 祭天次数增加 """
        self.player._game.fete_mgr.init_player_fete(self.player)
        player_fete = getattr(self.player.runtimes, PLAYER_ATTR_FETE)
        if type == 1:
            player_fete.feteData.n1 = 10 - 1 * num
        else:
            player_fete.feteData.n2 = 10 - 1 * num
        self.gm.log(u'祭天次数更新完成')

    def add_fate_num(self, num, type=1):
        """ 猎命次数增加 """
        self.player._game.hfate_mgr.init_player_hitfate(self.player)
        player_hfate = getattr(self.player.runtimes, PLAYER_ATTR_HITFATE)
        if type == 1:
            if num > 50: num = 50
            player_hfate.hitFateData.n1 = 50 - num
        else:
            if num > 20: num = 20
            player_hfate.hitFateData.n2 = 20 - num
        self.gm.log(u'猎命次数更新完成')

    def del_tbox_news(self):
        """ 清除时光盒所有战报 """
        self.player._game.rpc_tboxnews_mgr.clear()
        self.gm.log(u'清楚时光盒所有战报')

    def del_deep(self):
        """ 清除深渊 """
        self.player._game.deep_mgr.clear(self.player)
        self.gm.log(u'清除深渊数据')

    def deep_jump(self, level):
        """ 直接调整到深渊指定层 """
        from game.mgr.deep import ET_NORMAL
        self.player._game.deep_mgr.enter(self.player,
                                         ET_NORMAL,
                                         level=int(level))
        self.gm.log(u'跳转成功')

    def deep_buff(self, count):
        """ 增加多少层buff """
        deep = self.player._game.deep_mgr.init_player(self.player)
        deep.add_buff(self.player._game.deep_mgr, floors=count)
        self.gm.log(u'增加buff成功')

    def set_player_attr(self, key, value):
        """ 设置用户属性:cli_introstep """
        self.player.play_attr.client_set(key, value)
        self.gm.log(u'设置用户属性成功')

    def add_wait_item(self, wtype, items):
        """ 添加待收物品(wtype, items) items=列表对象 """
        witem = self.player.wait_bag.add_waitItem(wtype, items)
        self.gm.log(u'add_wait_item:%s', witem.to_dict())

    def add_fate(self, fid, level=1, can_trade=False):
        """添加命格 """
        item_mgr = self.player._game.item_mgr
        fate = item_mgr.new_fate(fid, is_trade=can_trade)
        fate.data.level = level
        res_fate_level = self.player._game.res_mgr.fate_level_by_keys.get(
            (fid, level))
        if res_fate_level:
            fate.data.exp = res_fate_level.exp
        if self.player.bag.add_fate(fate) is None:
            self.gm.log(u'命格(%d)添加失败', fid)
        else:
            self.gm.log(u'命格(%d)添加成功', fid)
        self.player.pack_msg_data(fates=[fate], send=1)
        return fate

    def roleup_add_num(self, num):
        """ 添加升段次数 """
        self.player.roles.gm_add_num(num)
        self.gm.log(u'升段次数更改成功')

    def reset_gem_mine(self):
        """重置珠宝开采"""
        self.player._game.gem_mgr.reset_mine(self.player)
        self.gm.log(u'重置珠宝开采成功')

    def add_gem(self, gid, level=1, is_trade=0):
        """添加珠宝"""
        item_mgr = self.player._game.item_mgr
        gem = item_mgr.new_gem(gid, level, is_trade=is_trade)
        if gem is None:
            self.gm.log(u'等级(%s)珠宝(%d)添加失败', level, gid)
        if self.player.bag.add_gem(gem) is None:
            self.gm.log(u'等级(%s)珠宝(%d)添加失败', level, gid)
        self.gm.log(u'添加等级(%s)珠宝(%d)成功', level, gid)
        return gem

    def add_equip(self, eid, level=1, can_trade=False, forced=1):
        """ 添加命格 """
        item_mgr = self.player._game.item_mgr
        equip = item_mgr.new_equip(eid, is_trade=can_trade)
        equip.data.level = level
        rs_equip = self.player.bag.add_equip(equip, forced)
        if rs_equip is None:
            self.gm.log(u'装备(%d)添加失败,背包已满', eid)
        else:
            self.gm.log(u'装备(%d)添加成功', eid)
        self.player.pack_msg_data(equips=[rs_equip], send=1)
        return equip

    def wear_equip(self, rid, eid, is_base=1, send=1):
        """ 穿戴装备(rid, id) """
        equip = None
        if is_base:
            equips = self.player.bag.get_equips_by_eid(eid)
            #no used
            for e in equips:
                if not e.data.used:
                    equip = e
                    break
        else:
            equip = self.player.bag.get_equip(eid)
        role = self.player.roles.get_role_by_rid(rid)
        if not (equip and role):
            self.gm.log(u'装备(%d, %d)穿戴失败', rid, eid)
            return
        equip, res_equip = self.player.bag.get_equip_ex(equip.data.id)
        rs, data = role.wear_equip(self.player, equip, res_equip)
        if not rs:
            self.gm.log(u'装备(%d, %d)穿戴失败', rid, eid)
        else:
            if send:
                _, msg = data
                self.player.send_msg(msg)
            self.gm.log(u'装备(%d, %d)穿戴成功', rid, eid)

    def add_item(self, aIid, aCount, can_trade=False):
        """添加物品 id_count = {id:count}"""
        rs, c = self.player.bag.can_add_item(aIid, aCount, can_trade=can_trade)
        if not rs:
            self.gm.log(u'物品(%d, %d)添加失败', aIid, aCount)
            return
        res_item = self.player._game.item_mgr.get_res_item(aIid)
        items = self.player.bag.add_item(aIid, aCount, can_trade=can_trade)
        self.player.pack_msg_data(items=items, send=1)
        self.gm.log(u'物品(%s, %d)添加成功', res_item.name, aCount)

    def vip_level(self, level):
        """ 改变vip等级 """
        self.player.vip.vip = level
        self.gm.log(u'vip等级改变到(%d)', level)

    def vip_reward(self, rid):
        """设置gm命令的vip奖励"""
        t_dics = self.player._game.rpc_vip_mgr.get_goods()
        keys = [dic['rid'] for dic in t_dics]
        rid = int(rid)
        if rid not in keys:
            keys.sort()
            self.gm.log(u'设置失败, 目前的vip奖励ID可以是(%s)', keys)
            return
        coin = self.player._game.rpc_vip_mgr.get_good_coin(rid)
        self.player.pay_back(rid, None, coin)
        self.gm.log(u'vip奖励购买成功奖励ID是(%d)', rid)

    def use_item(self, id):
        """ 使用物品 """
        rs, data = self.player.use_item(id)
        if not rs:
            self.gm.log(u'使用物品失败:%s', data)
            return
        self.player.send_update_msg(data)
        self.gm.log(u'使用物品成功:%s', data)

    def use_item_ex(self, iid):
        """ 使用特定物品 """
        ids, res_item = self.player.bag.get_item_ids_ex(iid)
        if ids is None:
            self.gm.log(u'物品不存在')
            return
        rs, data = self.player.use_item(ids[0])
        if not rs:
            self.gm.log(u'使用物品失败:%s', data)
            return
        self.player.send_update_msg(data)
        self.gm.log(u'使用物品成功:%s', data)

    def show_bag(self):
        """ 显示背包物品列表 """
        log = self.gm.log
        log(u'玩家(%s)背包物品列表:', self.player.data.name)

        def _logs(items, name):
            for k, item in items.iteritems():
                log(u'  id:%s  %s:%s', k, name, item.to_dict())

        _logs(self.player.bag.items, u'物品')
        _logs(self.player.bag.equips, u'装备')
        _logs(self.player.bag.fates, u'命格')
        _logs(self.player.bag.cars, u'坐骑')

    def show_wait_bag(self):
        """ 显示待收取物品列表 """
        log = self.gm.log
        log(u'玩家(%s)待收取物品列表:', self.player.data.name)
        for k, witem in self.player.wait_bag.items.iteritems():
            log(u'  id:%d  %s', k, witem.to_dict())

    def update_bag(self, type_name, id, **kw):
        """ 更新背包数据(type_name[items,equips,fates,cars], id, **kw) """
        items = getattr(self.player.bag, type_name)
        item = items.get(id)
        item.update(kw)
        self.gm.log(u'背包数据(%s)更新成功: %s', id, item.to_dict())

    def add_arena_count(self, c):
        """增加竞技场次数"""
        pid = self.player.data.id
        self.player._game.rpc_arena_mgr.gm_add_count(pid=pid, c=c)
        self.gm.log(u'玩家(%s)增加竞技场(%s)挑战次数', pid, c)

    def change_arena_rank(self, rank):
        """ 改变改玩家在竞技场的排名 """
        pid = self.player.data.id
        vip = self.player.data.vip
        game = self.player._game
        rid = game.rpc_arena_mgr.gm_get_rid_byrank(rank)
        if not rid:
            self.gm.log(u'调整失败!等级超出')
            return
        #保存战报
        fp = '0'
        fp_id = game.rpc_report_mgr.save(REPORT_TYPE_ARENA, [rid, pid], fp)
        self.player._game.rpc_arena_mgr.gm_change_rank(pid, rid, fp_id, vip)
        rplayer = game.rpc_player_mgr.get_rpc_player(pid)
        if rplayer:
            r_resp = 'arenaRivalEnd'
            r_data = dict(rid=pid, isOK=1, fp_id=fp_id)
            msg = pack_msg(r_resp, 1, data=r_data)
            rplayer.send_msg(msg)
        self.gm.log(u'调整成功!')

    def add_role(self, rid, active=True):
        """ 添加配将(rid, active=True) """
        role, err = self.player.roles.invite(rid, gm=True)
        if not role:
            self.gm.log(u'增加配将(%s)失败:%s', rid, err)
            return
        if active and self.player.roles.can_come_back():
            role.come_back()
        self.gm.log(u'增加配将(%s)成功:%s', rid, role.to_dict())

    def show_roles(self):
        """ 显示配将信息 """
        sleep(3)
        log = self.gm.log
        log(u'玩家(%s)配将列表:', self.player.data.name)
        for k, role in self.player.roles.roles.iteritems():
            log(u'  id:%s  %s', k, role.to_dict())

    def show_play_data(self):
        """ 显示角色信息 """
        log = self.gm.log
        log(u'玩家(%s)信息:', self.player.data)

    def update_role(self, id, **kw):
        """ 更新配将数据(id, **kw) """
        role = self.player.roles.get_role(id)
        role.update(kw)
        self.gm.log(u'配将(%s)数据更新成功: %s', id, role.to_dict())

    def del_player(self, pid):
        """ 通过修发player表中的uid隐藏角色 """
        self.player.data.uid = -self.player.data.uid
        self.gm.log(u'删除角色成功')

    def del_role(self, rid):
        """ 删除玩家角色 """
        rs, data = self.player.roles.del_role(rid, send_msg=1)
        if not rs:
            self.gm.log(u'删除配将失败')
        else:
            self.gm.log(u'删除配将成功')

    def get_role(self, rid):
        return self.player.roles.get_role_by_rid(rid)

    def role_come_back(self, id):
        """ 配将归队(id) """
        role = self.player.roles.get_role(id)
        role.come_back()
        self.gm.log(u'增加配将(%s)归队成功!', id)

    def position_study(self, pid):
        """ 学习阵型 """
        if self.player.positions.study(pid, forced=True):
            self.gm.log(u'学习阵型成功')

    def get_position(self, pid):
        return self.player.positions.get_active()

    def position_upgrade(self, id, level=None):
        """ 升级阵型(level=None)可以通过level指定直接升级到特定等级 """
        if self.player.positions.upgrade(id, level=level, forced=True):
            self.gm.log(u'升级阵型成功')

    def position_place(self, pid, rid, pos):
        """ 布置某角色到某阵型位置 """
        self.player.positions.place(pid, rid, pos)

    def scene_enter(self, mapId):
        """ 进入地图 """
        if self.player.scene_enter(mapId):
            self.gm.log(u'进入地图成功')

    def upgrade(self, level, pub=True):
        """ 升级到某级 """
        self.player.upgrade(level, pub=pub)

    def accept_tasks(self, utype=None, id_or_level=None):
        if utype is None:
            utype = TUL_LEVEL
            id_or_level = self.player.data.level
        self.player.task.accept_tasks(utype, id_or_level)

    def task_clear_ids(self, ids):
        ids = [int(item) for item in str(ids).split(',')]
        self.player.task.clear_tids(ids)
        self.gm.log(u'清理已完成任务列表成功')

    def task_complete(self, tid):
        task = self.player.task.get_task_by_tid(tid)
        if task:
            self.player.task.task_complete(task.data.id)
            self.gm.log(u'完成任务成功')

    def add_task(self, tid):
        task = self.player.task.add_task(tid, forced=True, send_msg=True)
        self.gm.log(u'添加任务成功:%s', task.to_dict())

    def turn_task(self, tid, auto=1):
        """ 转到特定任务
        如果tid比当前完成的任务id小,会清理已完成任务列表内容
        auto: 是否自动完成tid之前的所有任务id?
        """
        self.player.task.turn_to(tid, auto_complete=auto)

    def show_tasks(self):
        """ 显示玩家任务信息 """
        log = self.gm.log
        log(u'玩家(%s)任务列表:', self.player.data.name)
        for id, task in self.player.task.tids.iteritems():
            log(u'  id:%d  %s', id, task.to_dict())

    def reward(self, rid):
        """ 直接获取奖励(rid) """
        r = self.player._game.reward_mgr.get(rid)
        if not r:
            self.gm.log(u'获取奖励(%d)失败', rid)
            return
        sitems = r.reward(params=self.player.reward_params())
        bag_items = self.player.bag.add_items(sitems, log_type=ITEM_ADD_GM)
        bag_items.pack_msg(send=1)
        self.gm.log(u'获取奖励列表:%s', sitems)

    def kick(self):
        """ 踢下线 """
        self.player.user.logout()
        self.gm.log(u'踢下线成功')

    def attr_set(self, key, value):
        self.player.play_attr.set(key, value)

    def attr_get(self, key):
        value = self.player.play_attr.get(key)
        self.gm.log(u'%s', value)

    def add_car(self, cid):
        """ 添加坐骑 """
        self.player.bag.add_car(cid)
        self.gm.log(u'添加坐骑成功')

    def car_do(self, cid):
        """ 操作坐骑,骑或下马 """
        if cid is 0:
            self.player.car_do(cid)
            self.gm.log(u'操作坐骑成功')
        else:
            car = self.player.bag.has_car(cid)
            if car:
                self.player.car_do(car.data.id)
                self.gm.log(u'操作坐骑成功')
            else:
                self.gm.log(u'操作坐骑失败')

    def set_allyboss_start(self, delay_time=300):
        """ 开启同盟boss战,并清楚玩家该星期已参加boss战时间的属性 """
        game = self.player._game
        aid = game.rpc_ally_mgr.get_aid_by_pid(self.player.data.id)
        if not aid:
            self.gm.log(u'该玩家无同盟')
            return
        if game.rpc_boss_mgr.set_ally_start(aid, delay_time):
            self.gm.log(u'同盟boss战开启成功')
        else:
            self.gm.log(u'同盟boss开启失败')

    def fihgt_allyboss_clear(self):
        """ 清楚该周已参加同盟boss的状态 """
        tObjDict = self.player.play_attr.get(PLAYER_ATTR_BOSS)
        tObjDict['jt'] = 0
        self.player.play_attr.update_attr({PLAYER_ATTR_BOSS: tObjDict})
        self.gm.log(u'成功更新状态')

    def kill_boss(self, type=0):
        """ 秒杀boss type=0 世界 type!=0 同盟 """
        game = self.player._game
        p_data = self.player.data
        hurts = 999999999
        if type:
            aid = game.rpc_ally_mgr.get_aid_by_pid(p_data.id)
            if not aid:
                self.gm.log(u'该玩家无同盟')
                return
            game.rpc_boss_mgr.kill_boss(p_data.id, p_data.name, hurts, aid)
        else:
            game.rpc_boss_mgr.kill_boss(p_data.id, p_data.name, hurts)
        self.gm.log(u'成功秒杀')

    def one_hurt_boss(self, num):
        """ 单次击杀世界boss """
        game = self.player._game
        p_data = self.player.data
        game.rpc_boss_mgr.kill_boss(p_data.id, p_data.name, num)
        self.gm.log(u'成功击杀怪物 %d 血', num)

    def reset_shop(self):
        """ 刷新神秘商店的物品 """
        player_shop = self.player._game.shop_mgr.init_player_shop(self.player)
        player_shop.gm_reset_items()
        self.gm.log(u'成功重置')

    def next_sign(self):
        p_sign = self.player._game.day_sign_mgr.init_player(self.player)
        p_sign.data.t = 0
        p_sign.save(self.player._game.rpc_store, forced=True)
        self.gm.log(u'成功重置')

    def set_sign_day(self, day):
        p_sign = self.player._game.day_sign_mgr.init_player(self.player)
        p_sign.data.t = 0
        p_sign.data.finish = min(15, int(day))
        p_sign.save(self.player._game.rpc_store, forced=True)
        if int(day) > 15:
            return self.gm.log(u'成功重置, 设置的天数大于15 被设置为15')
        self.gm.log(u'成功重置')

    def bftask_clear(self):
        """ 清楚玩家身上已接的兵符任务 """
        tasks = self.player.task.tasks
        for task in tasks.values():
            tid = task.data.tid
            res_task = self.player._game.res_mgr.tasks.get(tid)
            if res_task is None or res_task.type != 3:
                continue
            self.player.task.del_task(task)
        p_bftask = self.player._game.bftask_mgr.init_player_bftask(self.player)
        p_bftask.bfTaskData.tids = []
        p_bftask.bfTaskData.ss = []
        p_bftask.bfTaskData.qs = []
        p_bftask.bfTaskData.exps = []
        p_bftask.bfTaskData.btid = 0
        self.gm.log(u"清楚成功")