Beispiel #1
0
    def exp_to_treasure(self, horse_exp, bookwar_exp):
        '''
        @summary: 用宝物的经验计算可兑换成经验马或经验书的个数
        '''
        basic_exp, horse_num, bookwar_num, gold_horse_num, gold_bookwar_num = 0, 0, 0, 0, 0
        # 经验马
        horse_conf = get_item_by_itemid( EXP_HORSE_ID )
        if horse_conf and (horse_exp > 0):
            for _attr in horse_conf['attributes']:
                if _attr['AttributeID'] == ATTRIBUTE_TYPE_HORSE_EXP:
                    basic_exp += _attr['Value']
                    break
            # 计算可折算的经验马个数
            if basic_exp > 0:
                horse_num = (horse_exp / basic_exp)
                gold_horse_num = horse_num / 5
                horse_num = horse_num % 5
        # 经验书
        basic_exp    = 0
        bookwar_conf = get_item_by_itemid( EXP_BOOKWAR_ID )
        if bookwar_conf and (bookwar_exp > 0):
            for _attr in bookwar_conf['attributes']:
                if _attr['AttributeID'] == ATTRIBUTE_TYPE_BOOKWAR_EXP:
                    basic_exp += _attr['Value']
                    break
            # 计算可折算的经验马个数
            if basic_exp > 0:
                bookwar_num = (bookwar_exp / basic_exp)
                gold_bookwar_num = bookwar_num / 5
                bookwar_num = bookwar_num % 5

        return horse_num, bookwar_num, gold_horse_num, gold_bookwar_num
    def exp_to_treasure(self, horse_exp, bookwar_exp):
        '''
        @summary: 用宝物的经验计算可兑换成经验马或经验书的个数
        '''
        basic_exp, horse_num, bookwar_num, gold_horse_num, gold_bookwar_num = 0, 0, 0, 0, 0
        # 经验马
        horse_conf = get_item_by_itemid(EXP_HORSE_ID)
        if horse_conf and (horse_exp > 0):
            for _attr in horse_conf['attributes']:
                if _attr['AttributeID'] == ATTRIBUTE_TYPE_HORSE_EXP:
                    basic_exp += _attr['Value']
                    break
            # 计算可折算的经验马个数
            if basic_exp > 0:
                horse_num = (horse_exp / basic_exp)
                gold_horse_num = horse_num / 5
                horse_num = horse_num % 5
        # 经验书
        basic_exp = 0
        bookwar_conf = get_item_by_itemid(EXP_BOOKWAR_ID)
        if bookwar_conf and (bookwar_exp > 0):
            for _attr in bookwar_conf['attributes']:
                if _attr['AttributeID'] == ATTRIBUTE_TYPE_BOOKWAR_EXP:
                    basic_exp += _attr['Value']
                    break
            # 计算可折算的经验马个数
            if basic_exp > 0:
                bookwar_num = (bookwar_exp / basic_exp)
                gold_bookwar_num = bookwar_num / 5
                bookwar_num = bookwar_num % 5

        return horse_num, bookwar_num, gold_horse_num, gold_bookwar_num
    def combine(self, user_treasureshard_ids):
        '''
        @summary: 合成宝物碎片得到宝物
        '''
        yield self._load()
        used_item_ids = [] # 碎片道具ID列表
        shard_changelist = []
        # 检查材料的有效性
        for _uid in user_treasureshard_ids:
            if not self.__gsattribs.has_key( _uid ):
                log.error('Unknown user treasureshard. _uid: {0}.'.format( _uid ))
                defer.returnValue( UNKNOWN_TREASURESHARD )
            gsattrib  = self.__gsattribs[_uid]
            item_conf = get_item_by_itemid( gsattrib.item_id )
            if not item_conf:
                log.error('Can not find conf. item_id: {0}.'.format( item_id ))
                defer.returnValue( NOT_FOUND_CONF )
            if shard_changelist:
                if shard_changelist != item_conf['ChangeList']:
                    log.error('Treasureshard error. _uid: {0}, shard_changelist: {1}, item_conf: {2}.'.format( _uid, shard_changelist, item_conf ))
                    defer.returnValue( UNKNOWN_ITEM_ERROR )
            else:
                shard_changelist = item_conf['ChangeList']
            # 判断道具数量
            if 1 > gsattrib.item_num:
                log.error('error. _uid: {0}, cur item num: {1}.'.format( _uid, gsattrib.item_num ))
                defer.returnValue( CHAR_ITEM_NOT_ENOUGH )
            used_item_ids.append( gsattrib.item_id )
        # 获取要合成的宝物
        if 1 != len(shard_changelist):
            log.error('error. shard_changelist: {0}.'.format( shard_changelist ))
            defer.returnValue( UNKNOWN_ITEM_ERROR )
        # format: [item_type, item_id, item_num]
        target_treasure = shard_changelist[0]
        target_conf = get_item_by_itemid( target_treasure[1] )
        if not target_conf:
            log.error('Can not find target conf. item_id: {0}.'.format( target_treasure[1] ))
            defer.returnValue( NOT_FOUND_CONF )
        # 检查合成宝物所需材料是否满足条件
        need_item_ids = [_c[1] for _c in target_conf['ChangeList']]
        if sorted(need_item_ids) != sorted(used_item_ids):
            log.error('shard can not combine. need_item_ids: {0}, used_item_ids: {1}.'.format( need_item_ids, used_item_ids ))
            defer.returnValue( REQUEST_LIMIT_ERROR )
        # 删除材料
        for _uid in user_treasureshard_ids:
            yield self.delete_table_data( _uid )
        # 新增宝物
        res_err, add_items = yield self.user.bag_treasure_mgr.new( target_treasure[1], target_treasure[2], WAY_AVOID_WAR )
        # 开服七天
        _conf = get_item_by_itemid(target_treasure[1])
        if not _conf:
            log.error('Can not find conf. item_id: {0}.'.format( item_id ))
            defer.returnValue( (NOT_FOUND_CONF, None) )
        if _conf['Quality'] >= 2:
            yield self.user.open_server_mgr.update_open_server_activity_quest( OPEN_SERVER_QUEST_ID_9, 1)
            yield self.user.achievement_mgr.update_achievement_status( ACHIEVEMENT_QUEST_ID_9, 1)
        if not res_err and add_items:
            defer.returnValue( (add_items[0][0], add_items[0][2]) )

        defer.returnValue( res_err )
    def combine(self, attrib_id):
        ''' 
        @summary: 碎片合成 
        @param  : attrib_id-玩家分魂ID
        '''
        attrib = yield self.get(attrib_id)
        if not attrib:
            log.error(
                'combine. Can not find attrib_id. attrib_id: {0}.'.format(
                    attrib_id))
            defer.returnValue((UNKNOWN_ERROR, None))

        item_conf = get_item_by_itemid(attrib.item_id)
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format(
                attrib.item_id))
            defer.returnValue((NOT_FOUND_CONF, None))

        # check limit
        # ChangeList format: [[target_item_type, target_item_id, need_item_num]]
        change_list = item_conf['ChangeList']
        if not change_list or len(change_list) > 1 or len(change_list[0]) < 3:
            log.error(
                'Can not find item change_list conf. item_id: {0}.'.format(
                    attrib.item_id))
            defer.returnValue((NOT_FOUND_CONF, None))

        if attrib.item_num < change_list[0][2]:
            log.error(
                "User's item not enough. have item: {0}, need item: {1}.".
                format(attrib.item_num, change_list[0][2]))
            defer.returnValue((CHAR_ITEM_NOT_ENOUGH, None))

        _c = get_item_by_itemid(change_list[0][1])
        _quality = _c.get('Quality', 0)
        if _quality >= 2:
            yield self.user.achievement_mgr.update_achievement_status(
                ACHIEVEMENT_QUEST_ID_28, 1)
        if _quality >= 3:
            yield self.user.achievement_mgr.update_achievement_status(
                ACHIEVEMENT_QUEST_ID_29, 1)
        if _quality >= 4:
            yield self.user.achievement_mgr.update_achievement_status(
                ACHIEVEMENT_QUEST_ID_30, 1)
        # create new item
        # del current attrib
        self.delete_table_data(attrib_id)
        defer.returnValue((NO_ERROR, change_list[0][1]))
 def combine(self, attrib_id):
     ''' 
     @summary: 碎片合成 
     @param  : attrib_id-玩家分魂ID
     '''
     attrib = yield self.get(attrib_id)
     if not attrib:
         log.error(
             'combine. Can not find attrib_id. attrib_id: {0}.'.format(
                 attrib_id))
         defer.returnValue((UNKNOWN_ERROR, None))
     item_conf = get_item_by_itemid(attrib.item_id)
     if not item_conf:
         log.error('combine. Can not find conf. item_id: {0}.'.format(
             attrib.item_id))
         defer.returnValue((NOT_FOUND_CONF, None))
     # check limit
     # ChangeList format: [target_item_type, target_item_id, need_item_num]
     change_list = item_conf['ChangeList']
     if not change_list or len(change_list) > 1 or len(change_list[0]) < 3:
         log.error(
             'Can not find item change_list conf. item_id: {0}.'.format(
                 attrib.item_id))
         defer.returnValue((NOT_FOUND_CONF, None))
     if attrib.item_num < change_list[0][2]:
         log.error(
             "combine. User's item not enough. have item: {0}, need item: {1}."
             .format(attrib.item_num, change_list[0][2]))
         defer.returnValue((CHAR_ITEM_NOT_ENOUGH, None))
     # create new item
     # del current attrib
     self.delete_table_data(attrib_id)
     defer.returnValue((NO_ERROR, change_list[0][1]))
def start_plunder(p, req):
    '''
    @summary: 开始抢夺玩家, 避免同一宝物的碎片玩家被多人同时抢夺
    '''
    res_err = UNKNOWN_ERROR
    cid, (plunder_cid, shard_id) = req

    user = g_UserMgr.getUser(cid)
    if not user:
        log.error('Can not find user. cid: {0}.'.format(cid))
        return res_err

    if user.base_att.douzhan < PVP_NEED_DOUZHAN:
        log.error('douzhan of user {0} have been zero!!!'.format(cid))
        return CHAR_DOUZHAN_NOT_ENOUGH

    # 抢夺对象不是玩家
    if plunder_cid <= 0:
        return NO_ERROR

    item_conf = get_item_by_itemid(shard_id)
    if not item_conf:
        log.error('Can not find conf. shard_id: {0}.'.format(shard_id))
        return NOT_FOUND_CONF

    # 碎片可合成的宝物信息
    _, treasure_id, _ = item_conf['ChangeList'][0]
    res_err = AvoidWarMgr.start_plunder_shard(treasure_id, plunder_cid)
    return res_err
Beispiel #7
0
    def new(self, item_id, item_num, way_type=WAY_UNKNOWN, way_others=''):
        yield self._load()
        item_conf = get_item_by_itemid(item_id)
        if not item_conf:
            log.error('Can not find conf. cid: {0}, item_id: {1}.'.format(
                self.cid, item_id))
            defer.returnValue((NOT_FOUND_CONF, None))
        # 检查道具类型
        item_type = item_conf['ItemType']
        if item_type not in BAG_JADE:
            log.error('new. Item type error. cid: {0}, item_id: {1}.'.format(
                self.cid, item_id))
            defer.returnValue((ITEM_TYPE_ERROR, None))

        time_now = int(time())
        new_items = []

        while item_num >= 1:
            res_err, new_attrib = yield self.create_table_data(
                item_type, item_id, 1, time_now)
            if res_err:
                defer.returnValue((UNKNOWN_ERROR, None))
            item_num -= 1
            new_items = self.add_new_items(
                [new_attrib.attrib_id, item_type, item_id, 1], new_items)

        # add syslog
        for _item in new_items:
            syslogger(LOG_ITEM_GET, self.cid, self.user.level,
                      self.user.vip_level, self.user.alliance_id, _item[0],
                      _item[2], _item[3], way_type, way_others)
        defer.returnValue((NO_ERROR, new_items))
    def dec_shard(self, shard_id):
        '''
        @summary: 通过碎片ID 减少玩家背包中的碎片。
            同时维护redis data-TPL_TREASURE_SHARD_GOT
        '''
        yield self._load()
        item_conf = get_item_by_itemid(shard_id)
        if not item_conf:
            log.error('Can not find conf. shard_id: {0}.'.format(shard_id))
            defer.returnValue((NOT_FOUND_CONF, None))
        for sid, shard in self.__gsattribs.iteritems():
            if shard.item_id == shard_id:
                if shard.item_num > 1:
                    shard.item_num -= 1
                else:
                    shard.delete()
                    del self.__gsattribs[sid]
                break
        else:
            log.warn("user<{0}> have no the shard:{1}.".format(
                self.cid, shard_id))

        # 碎片可合成的宝物信息
        _, treasure_id, _ = item_conf['ChangeList'][0]
        yield self.update_avoid_cache(treasure_id)
def start_plunder(p, req):
    '''
    @summary: 开始抢夺玩家, 避免同一宝物的碎片玩家被多人同时抢夺
    '''
    res_err = UNKNOWN_ERROR
    cid, ( plunder_cid, shard_id ) = req

    user = g_UserMgr.getUser(cid)
    if not user:
        log.error('Can not find user. cid: {0}.'.format( cid ))
        return res_err

    if user.base_att.douzhan < PVP_NEED_DOUZHAN:
        log.error('douzhan of user {0} have been zero!!!'.format( cid ))
        return CHAR_DOUZHAN_NOT_ENOUGH

    # 抢夺对象不是玩家
    if plunder_cid <= 0:
        return NO_ERROR

    item_conf = get_item_by_itemid( shard_id )
    if not item_conf:
        log.error('Can not find conf. shard_id: {0}.'.format( shard_id ))
        return NOT_FOUND_CONF

    # 碎片可合成的宝物信息
    _, treasure_id, _ = item_conf['ChangeList'][0]
    res_err = AvoidWarMgr.start_plunder_shard( treasure_id, plunder_cid )
    return res_err
 def combine(self, attrib_id):
     ''' 
     @summary: 碎片合成 
     @param  : attrib_id-玩家分魂ID
     '''
     attrib = yield self.get(attrib_id)
     if not attrib:
         log.error('combine. Can not find attrib_id. attrib_id: {0}.'.format( attrib_id ))
         defer.returnValue( (UNKNOWN_ERROR, None) )
     item_conf = get_item_by_itemid( attrib.item_id )
     if not item_conf:
         log.error('combine. Can not find conf. item_id: {0}.'.format( attrib.item_id ))
         defer.returnValue( (NOT_FOUND_CONF, None) )
     # check limit
     # ChangeList format: [target_item_type, target_item_id, need_item_num]
     change_list = item_conf['ChangeList']
     if not change_list or len(change_list) > 1 or len(change_list[0]) < 3:
         log.error('Can not find item change_list conf. item_id: {0}.'.format( attrib.item_id ))
         defer.returnValue( (NOT_FOUND_CONF, None) )
     if attrib.item_num < change_list[0][2]:
         log.error("combine. User's item not enough. have item: {0}, need item: {1}.".format( attrib.item_num, change_list[0][2] ))
         defer.returnValue( (CHAR_ITEM_NOT_ENOUGH, None) )
     # create new item
     # del current attrib
     self.delete_table_data( attrib_id )
     defer.returnValue( (NO_ERROR, change_list[0][1]) )
Beispiel #11
0
    def get_sell_back_cost(self, *args):
        '''
        @summary: 出售道具时返还消耗的金币
        '''
        user_item_ids, = args

        res_err = [UNKNOWN_ITEM_ERROR, 0]
        for _uid in user_item_ids:
            attrib  = yield self.get( _uid )
            if not attrib:
                defer.returnValue( res_err )

            item_conf = get_item_by_itemid( attrib.item_id )
            if not item_conf:
                defer.returnValue( res_err )
            if not item_conf['Price']:
                res_err[0] = ITEM_CANNOT_SELL
                defer.returnValue( res_err )

            res_err[1] += item_conf['Price'] * attrib.item_num

        for _uid in user_item_ids:
            self.delete_table_data( _uid )

        res_err[0] = NO_ERROR
        defer.returnValue( res_err )
Beispiel #12
0
    def get_sell_back_cost(self, *args):
        '''
        @summary: 出售道具时返还消耗的金币
        @param: had_cost-强化到当前等级已消耗的金币总数
        '''
        user_item_ids, = args

        res_err = [UNKNOWN_EQUIP_ERROR, 0]
        for _ueid in user_item_ids:
            attrib  = yield self.get( _ueid )
            if not attrib:
                defer.returnValue( res_err )

            item_conf = get_item_by_itemid( attrib.item_id )
            if not item_conf:
                defer.returnValue( res_err )
            if not item_conf['Price']:
                res_err[0] = ITEM_CANNOT_SELL
                defer.returnValue( res_err )

            res_err[1] += (item_conf['Price'] * attrib.item_num + attrib.strengthen_cost)
            #log.error('For Test. _ueid: {0}, strengthen_cost: {1}, Price: {2}.'.format( _ueid, attrib.strengthen_cost, item_conf['Price'] ))

        for _ueid in user_item_ids:
            self.delete_table_data(_ueid)

        res_err[0] = NO_ERROR
        defer.returnValue( res_err )
Beispiel #13
0
    def get_sell_back_cost(self, *args):
        '''
        @summary: 出售道具时返还消耗的金币
        '''
        user_item_ids, = args

        res_err = [UNKNOWN_ITEM_ERROR, 0]
        for _uid in user_item_ids:
            attrib = yield self.get(_uid)
            if not attrib:
                defer.returnValue(res_err)

            item_conf = get_item_by_itemid(attrib.item_id)
            if not item_conf:
                defer.returnValue(res_err)
            if not item_conf['Price']:
                res_err[0] = ITEM_CANNOT_SELL
                defer.returnValue(res_err)

            res_err[1] += item_conf['Price'] * attrib.item_num

        for _uid in user_item_ids:
            self.delete_table_data(_uid)

        res_err[0] = NO_ERROR
        defer.returnValue(res_err)
Beispiel #14
0
    def get_cost_by_level_type(self, next_level, item_id, item_type):
        '''
        @summary: 通过item id, item type, next strengthen level 获取next cost golds数
        '''
        next_cost = 0
        # 强化等级上限为玩家等级的2倍
        if (next_level - 1) >= (self.user.base_att.level * 2):
            log.error('Strengthen level has largest. char level: {0}, equip next level: {1}.'.format( self.user.base_att.level, next_level ))
            return CHAR_LEVEL_LIMIT, next_cost
        # 强化消耗金币conf
        cost_conf = get_equip_strengthen_cost(next_level, item_type)
        if not cost_conf:
            log.error('Can not find strengthen cost conf. next strengthen level: {0}, item_type:{1}.'.format( next_level, item_type ))
            return NOT_FOUND_CONF, next_cost

        item_conf = get_item_by_itemid(item_id)
        if not item_conf:
            log.error('Can not find item conf. item_id: {0}.'.format( item_id ))
            return NOT_FOUND_CONF, next_cost

        # 判断玩家金币是否充足
        quality   = ITEM_STRENGTHEN_COST[item_conf['Quality']]
        next_cost = cost_conf[quality]
        if next_cost > self.user.base_att.golds:
            log.error('User golds not enough. need golds: {0}, cur golds: {1}.'.format( next_cost, self.user.base_att.golds ))
            return CHAR_GOLD_NOT_ENOUGH, next_cost

        return NO_ERROR, next_cost
Beispiel #15
0
    def update_quest_status(self, quest_type):
        # 检查开服七日活动是否有效
        
        quest_conf = get_open_server_quest_conf(quest_type)
        if not quest_conf:
            defer.returnValue( OPEN_SERVER_IS_CLOSED )

        target_value = []
        had_count = {}
        for i in quest_conf.values():
            target_value.append(i[0])
            had_count[i[0]] = 0
        target_value.sort()
        for value in target_value:
            for gsattrib in self.__gsattribs.itervalues():
            # 获取阵容中的装备信息
                if gsattrib.camp_id <= 0:
                    continue
                if quest_type == OPEN_SERVER_QUEST_ID_5:
                    ctype = ACHIEVEMENT_QUEST_ID_5
                    item_conf = get_item_by_itemid( gsattrib.item_id )
                    if not item_conf:
                        continue
                    if item_conf['Quality'] >= value:
                        had_count[value] += 1
                elif quest_type == OPEN_SERVER_QUEST_ID_6:
                    ctype = ACHIEVEMENT_QUEST_ID_6
                    if gsattrib.level >= value:
                        had_count[value] += 1
        # 同步开服七日活动中的任务状态
        yield self.user.open_server_mgr.update_open_server_activity_quest( quest_type, had_count)
Beispiel #16
0
    def equip_reborn(self, user_equip_id):
        ''' 
        @summary: 装备重生 
            (1) 已穿戴 或 未洗炼的装备 不能重生
            (2) 返还该装备洗炼消耗的洗炼石和强化消耗的金币
            (3) 洗练消耗的金币和钻石不返还
            (4) 每返还10个洗炼石,则重生价格为1钻石
        '''
        equip = yield self.user.bag_equip_mgr.get( user_equip_id )
        if not equip:
            log.error('Can not find user equip.')
            defer.returnValue( UNKNOWN_EQUIP_ERROR )

        # 已穿戴 或 洗炼属性为[]的不可重生
        #log.error('camp_id: {0}, refine_attribute: {1}.'.format( equip.camp_id, loads(equip.refine_attribute) ))
        if (equip.camp_id > 0) or not loads(equip.refine_attribute):
            log.error('Equip reborn error. cid: {0}, ueid: {1}, camp_id: {2}, refine_attribute: {3}.'.format( self.cid, user_equip_id, equip.camp_id, loads(equip.refine_attribute) ))
            defer.returnValue( EQUIP_REBORN_ERROR )

        # 装备的conf
        equip_conf = get_item_by_itemid( equip.item_id )
        if not equip_conf:
            log.error('Can not find conf. item id: {0}.'.format( equip.item_id ))
            defer.returnValue( UNKNOWN_ITEM_ERROR )

        # 计算钻石消耗
        if (equip.refine_cost % 10) > 0:
            need_credits = equip.refine_cost / 10 + 1
        else:
            need_credits = equip.refine_cost / 10

        # 玩家钻石不足
        if need_credits > self.user.base_att.credits:
            log.error('Need credits: {0}, now have: {1}.'.format( need_credits, self.user.base_att.credits ))
            defer.returnValue( CHAR_CREDIT_NOT_ENOUGH )

        items_return = []
        # 返还金币、洗炼石
        #self.user.base_att.golds += equip.strengthen_cost
        self.user.get_golds( equip.strengthen_cost, WAY_EQUIP_REBORN )
        try:
            res_err, res_value = yield self.user.bag_item_mgr.new(ITEM_REFINE_STONE, equip.refine_cost)
            if not res_err:
                items_return = res_value
        except Exception as e:
            log.error('ERROR: {0}.'.format( e ))
            log.exception()
        # 扣钻石, 数据清零
        #self.user.base_att.credits -= need_credits
        if need_credits:
            yield self.user.consume_credits( need_credits, WAY_EQUIP_REBORN )
        self.user.bag_equip_mgr.reborn( user_equip_id )
 
        if equip.strengthen_cost > 0:
            items_return.append( [0, ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, equip.strengthen_cost] )

        # 强化、精炼属性清零
        equip.level, equip.strengthen_cost, equip.refine_cost, equip.refine_attribute = 0, 0, 0, dumps([])

        defer.returnValue( (self.user.base_att.credits, items_return) )
    def update_avoid_cache(self, treasure_id):
        '''
        @summary: 维护宝物碎片列表的同时, 维护redis中的玩家阵营数据
        '''
        if self.user.base_att.level <= AVOID_WAR_LEVEL:
            log.warn('User level <= 12 could not be plunder. cid: {0}.'.format( self.cid ))
            defer.returnValue( REQUEST_LIMIT_ERROR )

        treasure_conf = get_item_by_itemid( treasure_id )
        if not treasure_conf:
            log.error('Can not find conf. treasure_id: {0}.'.format( treasure_id ))
            defer.returnValue( NOT_FOUND_CONF )
        _shard_list = [splited[1] for splited in treasure_conf['ChangeList'] ]

        # 只有同时拥有“一个宝物的2个或者2个以上,不同位置碎片”的玩家才会被加入被抢夺列表
        _haved = 0
        _plunder_list = [] # 可被抢夺的碎片
        for _shard_id in _shard_list:
            for attrib in self.__gsattribs.itervalues():
                if attrib.item_id == _shard_id:
                    _haved += 1
                    _plunder_list.append( _shard_id )
                    break

        #_treasure_ids = yield redis.hget( HASH_TREASURE_CHARACTER_IDS, self.cid )
        #if _treasure_ids:
        #    _treasure_ids = loads(_treasure_ids)
        #else:
        #    _treasure_ids = []

        #log.info('For Test. _haved: {0}, cid: {1}, _shard_id: {2}, _shard_list: {3}, _plunder_list: {4}.'.format( _haved, self.cid, _shard_id, _shard_list, _plunder_list ))
        for _shard_id in _shard_list:
            yield redis.hdel( TPL_TREASURE_SHARD_GOT % _shard_id, self.cid )

        #if treasure_id in _treasure_ids:
        #    _treasure_ids.remove( treasure_id )

        if _haved > 1:
            #_flag   = True  # 成功获取玩家有效阵容
            #_exists = yield redis.hexists( HASH_TREASURE_CHARACTER_CAMP, self.cid )
            #if (not _exists):
            #    _all_camps = yield self.user.get_camp()
            #    fellow_ids = []
            #    if _all_camps:
            #        for camp_data in _all_camps[1]:
            #            if not camp_data or not camp_data[1]:
            #                continue
            #            fellow_ids.append( camp_data[1][1] )

            #    # 有效的玩家阵容
            #    if fellow_ids:
            #        yield redis.hset( HASH_TREASURE_CHARACTER_CAMP, self.cid, dumps(_all_camps) )
            #        #log.info('For Test. save treasure camp. cid: {0}.'.format( self.cid ))
            #    else:
            #        _flag = False
            #        log.error('Save char treasure camp data fail. cid: {0}, _all_camps: {1}.'.format( self.cid, _all_camps ))

            for _shard_id in _plunder_list:
                yield redis.hset( TPL_TREASURE_SHARD_GOT % _shard_id, self.cid, dumps( (self.cid, self.user.level, self.user.base_att.nick_name) ) )
    def new(self, item_id, item_num, way_type=WAY_UNKNOWN, way_others=''):
        yield self._load()
        item_conf = get_item_by_itemid(item_id)
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format(item_id))
            defer.returnValue((NOT_FOUND_CONF, None))
        # 检查道具类型
        item_type = item_conf['ItemType']
        if item_type not in BAG_FELLOWSOUL:
            log.error('new. Item type error. item_id: {0}.'.format(item_id))
            defer.returnValue((ITEM_TYPE_ERROR, None))

        time_now = int(time())  #datetime2string()
        MAX_NUM = item_conf['MaxOverlyingCount'] or (2**16 - 1)
        new_items = []
        for attrib in self.__gsattribs.itervalues():
            if item_type == attrib.item_type and item_id == attrib.item_id and MAX_NUM > attrib.item_num:
                if (attrib.item_num + item_num) <= MAX_NUM:
                    attrib.item_num += item_num
                    new_items = self.add_new_items(
                        [attrib.attrib_id, item_type, item_id, item_num],
                        new_items)
                else:
                    add_num = MAX_NUM - attrib.item_num
                    item_num = item_num - add_num
                    attrib.item_num = MAX_NUM
                    new_items = self.add_new_items(
                        [attrib.attrib_id, item_type, item_id, add_num],
                        new_items)
                    continue
                break
        else:
            cur_item_num = item_num
            while cur_item_num >= MAX_NUM:
                errorno, new_attrib = yield self.create_table_data(
                    item_type, item_id, MAX_NUM, time_now)
                if errorno:
                    defer.returnValue((UNKNOWN_ERROR, None))
                cur_item_num -= MAX_NUM
                new_items = self.add_new_items(
                    [new_attrib.attrib_id, item_type, item_id, MAX_NUM],
                    new_items)
            else:
                if cur_item_num > 0:
                    errorno, new_attrib = yield self.create_table_data(
                        item_type, item_id, cur_item_num, time_now)
                    if errorno:
                        defer.returnValue((UNKNOWN_ERROR, None))
                    new_items = self.add_new_items([
                        new_attrib.attrib_id, item_type, item_id, cur_item_num
                    ], new_items)

        # add syslog
        for _item in new_items:
            syslogger(LOG_FELLOW_GET, self.cid, self.user.level,
                      self.user.vip_level, self.user.alliance_id, _item[0],
                      _item[2], item_conf['QualityLevel'],
                      item_conf['StarLevel'], way_type, way_others)
        defer.returnValue((NO_ERROR, new_items))
    def value_list_by_type(self, shard_type):
        yield self._load()
        value_list = []
        for attrib in self.__gsattribs.itervalues():
            item_conf = get_item_by_itemid( attrib.item_id )

            if item_conf and item_conf['ItemType'] == shard_type:
                value_list.append( (attrib.attrib_id, attrib.item_id, attrib.item_num) )

        defer.returnValue( value_list )
    def value_list_by_type(self, shard_type):
        yield self._load()
        value_list = []
        for attrib in self.__gsattribs.itervalues():
            item_conf = get_item_by_itemid(attrib.item_id)

            if item_conf and item_conf['ItemType'] == shard_type:
                value_list.append(
                    (attrib.attrib_id, attrib.item_id, attrib.item_num))

        defer.returnValue(value_list)
Beispiel #21
0
def new_award_to_center(p, req):
    ''' 新增兑换码奖励到领奖中心 '''
    cid, item_id = req
 
    item_conf = get_item_by_itemid( item_id )
    if not item_conf:
        log.error('Can not find conf. cid: {0}, item_id: {1}.'.format( cid, item_id ))
        defer.returnValue( GIFT_CODE_OVERDUE )

    timestamp = int(time())
    yield g_AwardCenterMgr.new_award( cid, AWARD_TYPE_GIFT_CODE, [timestamp, [[item_conf['ItemType'], item_id, 1]]] )

    defer.returnValue( NO_ERROR )
    def combine(self, attrib_id):
        ''' 
        @summary: 碎片合成 
        @param  : attrib_id-玩家分魂ID
        '''
        attrib = yield self.get( attrib_id )
        if not attrib:
            log.error('combine. Can not find attrib_id. attrib_id: {0}.'.format( attrib_id ))
            defer.returnValue( (UNKNOWN_ERROR, None) )

        item_conf = get_item_by_itemid( attrib.item_id )
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format( attrib.item_id ))
            defer.returnValue( (NOT_FOUND_CONF, None) )

        # check limit
        # ChangeList format: [[target_item_type, target_item_id, need_item_num]]
        change_list = item_conf['ChangeList'] 
        if not change_list or len(change_list) > 1 or len(change_list[0]) < 3:
            log.error('Can not find item change_list conf. item_id: {0}.'.format( attrib.item_id ))
            defer.returnValue( (NOT_FOUND_CONF, None) )

        if attrib.item_num < change_list[0][2]:
            log.error("User's item not enough. have item: {0}, need item: {1}.".format( attrib.item_num, change_list[0][2] ))
            defer.returnValue( (CHAR_ITEM_NOT_ENOUGH, None) )

        _c = get_item_by_itemid(change_list[0][1]) 
        _quality = _c.get('Quality', 0)
        if _quality >= 2:
            yield self.user.achievement_mgr.update_achievement_status(ACHIEVEMENT_QUEST_ID_28, 1)
        if _quality >= 3:
            yield self.user.achievement_mgr.update_achievement_status(ACHIEVEMENT_QUEST_ID_29, 1)
        if _quality >= 4:
            yield self.user.achievement_mgr.update_achievement_status(ACHIEVEMENT_QUEST_ID_30, 1)
        # create new item
        # del current attrib
        self.delete_table_data( attrib_id )
        defer.returnValue( (NO_ERROR, change_list[0][1]) )
Beispiel #23
0
    def new(self, item_id, item_num, way_type=WAY_UNKNOWN, way_others=''):
        yield self._load()
        item_conf = get_item_by_itemid( item_id )
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format( item_id ))
            defer.returnValue( (NOT_FOUND_CONF, None) )
        # 检查道具类型
        item_type  = item_conf['ItemType']
        if item_type not in BAG_EQUIP:
            log.error('new. Item type error. item_id: {0}.'.format( item_id ))
            defer.returnValue( (ITEM_TYPE_ERROR, None) )
        # 判断图鉴
        yield self.user.atlaslist_mgr.new_atlaslist(CATEGORY_TYPE_EQUIP, item_type, item_conf['Quality'], item_id)

        time_now   = int(time()) #datetime2string()
        MAX_NUM    = item_conf['MaxOverlyingCount'] or (2 ** 16 - 1)
        new_items  = []
        for attrib in self.__gsattribs.itervalues():
            # 找打未达到MAX_NUM的相同的 item
            if item_type == attrib.item_type and item_id == attrib.item_id and MAX_NUM > attrib.item_num:
                if (attrib.item_num + item_num) <= MAX_NUM:
                    attrib.item_num += item_num
                    new_items = self.add_new_items( [attrib.attrib_id, item_type, item_id, item_num], new_items )
                else:
                    add_num         = MAX_NUM - attrib.item_num
                    item_num        = item_num - add_num
                    attrib.item_num = MAX_NUM
                    new_items = self.add_new_items( [attrib.attrib_id, item_type, item_id, add_num], new_items )
                    continue
                break
        else:
            cur_item_num = item_num
            while cur_item_num >= MAX_NUM:
                res_err, new_attrib = yield self.create_table_data(item_type, item_id, MAX_NUM, time_now)
                if res_err:
                    defer.returnValue( (UNKNOWN_ERROR, None) )
                cur_item_num -= MAX_NUM
                new_items = self.add_new_items( [new_attrib.attrib_id, item_type, item_id, MAX_NUM], new_items )
            else:
                if cur_item_num > 0:
                    res_err, new_attrib = yield self.create_table_data(item_type, item_id, cur_item_num, time_now)
                    if res_err:
                        defer.returnValue( (UNKNOWN_ERROR, None) )
                    new_items = self.add_new_items( [new_attrib.attrib_id, item_type, item_id, cur_item_num], new_items )

        # add syslog
        for _item in new_items:
            syslogger(LOG_ITEM_GET, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, _item[0], _item[2], _item[3], way_type, way_others)
        defer.returnValue( (NO_ERROR, new_items) )
    def new(self, item_id, item_num, way_type=WAY_UNKNOWN, way_others=''):
        yield self._load()
        item_conf = get_item_by_itemid(item_id)
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format(item_id))
            defer.returnValue((NOT_FOUND_CONF, None))
        # 检查道具类型
        item_type = item_conf['ItemType']
        if item_type not in BAG_TREASURESHARD:
            log.error('new. Item type error. item_id: {0}.'.format(item_id))
            defer.returnValue((ITEM_TYPE_ERROR, None))

        # 检查 item_num
        if item_num < 1:
            log.error('add item num error.')
            defer.returnValue((UNKNOWN_ERROR, None))

        time_now = int(time())  #datetime2string()
        # 宝物碎片可以无限叠加
        #MAX_NUM    = item_conf['MaxOverlyingCount']
        new_items = []
        for attrib in self.__gsattribs.itervalues():
            if item_type == attrib.item_type and item_id == attrib.item_id:
                attrib.item_num += item_num
                new_items = self.add_new_items(
                    [attrib.attrib_id, item_type, item_id, item_num],
                    new_items)
                break
        else:
            cur_item_num = item_num
            if cur_item_num > 0:
                res_err, new_attrib = yield self.create_table_data(
                    item_type, item_id, cur_item_num, time_now)
                if res_err:
                    defer.returnValue((UNKNOWN_ERROR, None))
                new_items = self.add_new_items(
                    [new_attrib.attrib_id, item_type, item_id, cur_item_num],
                    new_items)

        # 碎片可合成的宝物信息
        _, treasure_id, _ = item_conf['ChangeList'][0]
        yield self.update_avoid_cache(treasure_id)

        # add syslog
        for _item in new_items:
            syslogger(LOG_ITEM_GET, self.cid, self.user.level,
                      self.user.vip_level, self.user.alliance_id, _item[0],
                      _item[2], _item[3], way_type, way_others)
        defer.returnValue((NO_ERROR, new_items))
    def new(self, item_id, item_num, way_type=WAY_UNKNOWN, way_others=''):
        yield self._load()
        item_conf = get_item_by_itemid( item_id )
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format( item_id ))
            defer.returnValue( (NOT_FOUND_CONF, None) )
        # 检查道具类型
        item_type  = item_conf['ItemType']
        if item_type not in BAG_TREASURESHARD:
            log.error('new. Item type error. item_id: {0}.'.format( item_id ))
            defer.returnValue( (ITEM_TYPE_ERROR, None) )

        # 检查 item_num
        if item_num < 1:
            log.error('add item num error.')
            defer.returnValue( (UNKNOWN_ERROR, None) )

        time_now   = int(time()) #datetime2string()
        # 宝物碎片可以无限叠加
        #MAX_NUM    = item_conf['MaxOverlyingCount']
        new_items  = []
        for attrib in self.__gsattribs.itervalues():
            if item_type == attrib.item_type and item_id == attrib.item_id:
                attrib.item_num += item_num
                new_items = self.add_new_items( [attrib.attrib_id, item_type, item_id, item_num], new_items )
                break
        else:
            cur_item_num = item_num
            if cur_item_num > 0:
                res_err, new_attrib = yield self.create_table_data(item_type, item_id, cur_item_num, time_now)
                if res_err:
                    defer.returnValue( (UNKNOWN_ERROR, None) )
                new_items = self.add_new_items( [new_attrib.attrib_id, item_type, item_id, cur_item_num], new_items )

        # 碎片可合成的宝物信息
        _, treasure_id, _ = item_conf['ChangeList'][0]
        yield self.update_avoid_cache( treasure_id )

        # add syslog
        for _item in new_items:
            syslogger(LOG_ITEM_GET, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, _item[0], _item[2], _item[3], way_type, way_others)
        defer.returnValue( (NO_ERROR, new_items) )
Beispiel #26
0
def gs_gm_check_grant_items(p, req):
    ''' 检查道具类型和道具ID是否匹配 '''
    items_list, = req
    error_items = []
    for _type, _id, _num in items_list:
        if _type == ITEM_TYPE_FELLOW:
            item_conf = get_fellow_by_fid( _id )
            if not item_conf:
                error_items.append( {'item_type':_type, 'item_id':_id} )
                continue
        else:
            item_conf = get_item_by_itemid( _id )
            if not item_conf or item_conf['ItemType'] != _type:
                error_items.append( {'item_type':_type, 'item_id':_id} )
                continue

    if error_items:
        return (UNKNOWN_ITEM_ERROR, error_items)
    else:
        return (NO_ERROR, error_items)
    def get_fellowsouls(self, item_id, user_item_id=0):
        yield self._load()

        total_num, item_attribs = 0, []
        # 获取item id的最大叠加数
        item_conf = get_item_by_itemid(item_id)
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format(item_id))
            defer.returnValue((total_num, item_attribs))
        MAX_NUM = item_conf['MaxOverlyingCount']

        for attrib in self.__gsattribs.itervalues():
            if attrib.item_id == item_id and attrib.item_num > 0:
                total_num += attrib.item_num
                if attrib.item_num < MAX_NUM:
                    item_attribs.insert(0, attrib)
                else:
                    item_attribs.append(attrib)

        defer.returnValue((total_num, item_attribs))
    def get_fellowsouls(self, item_id, user_item_id=0):
        yield self._load()

        total_num, item_attribs = 0, []
        # 获取item id的最大叠加数
        item_conf = get_item_by_itemid( item_id )
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format( item_id ))
            defer.returnValue( (total_num, item_attribs) )
        MAX_NUM = item_conf['MaxOverlyingCount']

        for attrib in self.__gsattribs.itervalues():
            if attrib.item_id == item_id and attrib.item_num > 0:
                total_num += attrib.item_num
                if attrib.item_num < MAX_NUM:
                    item_attribs.insert(0, attrib)
                else:
                    item_attribs.append( attrib )

        defer.returnValue( (total_num, item_attribs) )
    def delete_table_data(self, attrib_id):
        '''
        @summary: 通过玩家碎片ID 使用宝物碎片。单个碎片可无限叠加, 
            同时维护redis data-TPL_TREASURE_SHARD_GOT
        '''
        if self.__gsattribs.has_key( attrib_id ):
            gsattrib = self.__gsattribs[attrib_id]
            gsattrib.item_num -= 1
            if 1 > gsattrib.item_num:
                gsattrib.delete()
                del self.__gsattribs[attrib_id]

            item_conf = get_item_by_itemid( gsattrib.item_id )
            if item_conf:
                # 碎片可合成的宝物信息
                _, treasure_id, _ = item_conf['ChangeList'][0]
                yield self.update_avoid_cache( treasure_id )
            else:
                log.error('Can not find conf. cid: {0}, shard_id: {1}.'.format( self.cid, gsattrib.item_id ))
        else:
            log.error('Can not find user sahrd. cid: {0}, _uid: {1}.'.format( self.cid, attrib_id ))
Beispiel #30
0
    def get_items(self, item_id, user_item_id=0):
        '''
        @param  : user_item_id-是否需要排除的uid, 默认不排除
        @return : total_num-item id的总数; item_attribs-item id 对应的所有attrib, 数量按照数量多少排序 
        '''
        yield self._load()
        total_num, item_attribs = 0, []
        # 获取item id的最大叠加数
        item_conf = get_item_by_itemid( item_id )
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format( item_id ))
            defer.returnValue( (total_num, item_attribs) )
        MAX_NUM = item_conf['MaxOverlyingCount']

        for attrib in self.__gsattribs.itervalues():
            if attrib.item_id == item_id and attrib.item_num > 0:
                total_num += attrib.item_num
                if attrib.item_num < MAX_NUM:
                    item_attribs.insert(0, attrib)
                else:
                    item_attribs.append( attrib )

        defer.returnValue( (total_num, item_attribs) )
Beispiel #31
0
    def get_items(self, item_id, user_item_id=0):
        '''
        @param  : user_item_id-是否需要排除的uid, 默认不排除
        @return : total_num-item id的总数; item_attribs-item id 对应的所有attrib, 数量按照数量多少排序 
        '''
        yield self._load()
        total_num, item_attribs = 0, []
        # 获取item id的最大叠加数
        item_conf = get_item_by_itemid(item_id)
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format(item_id))
            defer.returnValue((total_num, item_attribs))
        MAX_NUM = item_conf['MaxOverlyingCount']

        for attrib in self.__gsattribs.itervalues():
            if attrib.item_id == item_id and attrib.item_num > 0:
                total_num += attrib.item_num
                if attrib.item_num < MAX_NUM:
                    item_attribs.insert(0, attrib)
                else:
                    item_attribs.append(attrib)

        defer.returnValue((total_num, item_attribs))
    def delete_table_data(self, attrib_id):
        '''
        @summary: 通过玩家碎片ID 使用宝物碎片。单个碎片可无限叠加, 
            同时维护redis data-TPL_TREASURE_SHARD_GOT
        '''
        if self.__gsattribs.has_key(attrib_id):
            gsattrib = self.__gsattribs[attrib_id]
            gsattrib.item_num -= 1
            if 1 > gsattrib.item_num:
                gsattrib.delete()
                del self.__gsattribs[attrib_id]

            item_conf = get_item_by_itemid(gsattrib.item_id)
            if item_conf:
                # 碎片可合成的宝物信息
                _, treasure_id, _ = item_conf['ChangeList'][0]
                yield self.update_avoid_cache(treasure_id)
            else:
                log.error('Can not find conf. cid: {0}, shard_id: {1}.'.format(
                    self.cid, gsattrib.item_id))
        else:
            log.error('Can not find user sahrd. cid: {0}, _uid: {1}.'.format(
                self.cid, attrib_id))
    def get_sell_back_cost(self, *args):
        '''
        @summary: 出售道具时返还消耗的金币
        '''
        user_item_ids, = args

        res_err = [UNKNOWN_TREASURE_ERROR, 0]
        for _utid in user_item_ids:
            attrib = yield self.get(_utid)
            if not attrib:
                defer.returnValue(res_err)

            item_conf = get_item_by_itemid(attrib.item_id)
            if not item_conf:
                defer.returnValue(res_err)
            if not item_conf['Price']:
                res_err[0] = ITEM_CANNOT_SELL
                defer.returnValue(res_err)

            res_err[1] += item_conf['Price'] * attrib.item_num

            quality = ITEM_STRENGTHEN_COST[item_conf['Quality']]
            had_exp = attrib.exp
            for _level in range(1, attrib.level + 1):
                exp_conf = get_treasure_exp_conf(_level)
                if not exp_conf:
                    continue
                had_exp += exp_conf.get(quality, 0)
            res_err[1] += had_exp * TREASURE_STRENGTHEN_EXP_TO_GOLDS
            #log.error('For Test. _utid: {0}, cost: {1}, Price: {2}.'.format( _utid, had_exp * TREASURE_STRENGTHEN_EXP_TO_GOLDS, item_conf['Price'] ))

        for _utid in user_item_ids:
            self.delete_table_data(_utid)

        res_err[0] = NO_ERROR
        defer.returnValue(res_err)
Beispiel #34
0
    def get_sell_back_cost(self, *args):
        '''
        @summary: 出售道具时返还消耗的金币
        '''
        user_item_ids, = args

        res_err = [UNKNOWN_TREASURE_ERROR, 0]
        for _utid in user_item_ids:
            attrib  = yield self.get( _utid )
            if not attrib:
                defer.returnValue( res_err )

            item_conf = get_item_by_itemid( attrib.item_id )
            if not item_conf:
                defer.returnValue( res_err )
            if not item_conf['Price']:
                res_err[0] = ITEM_CANNOT_SELL
                defer.returnValue( res_err )

            res_err[1] += item_conf['Price'] * attrib.item_num

            quality = ITEM_STRENGTHEN_COST[item_conf['Quality']]
            had_exp = attrib.exp
            for _level in range(1, attrib.level+1):
                exp_conf = get_treasure_exp_conf( _level )
                if not exp_conf:
                    continue
                had_exp += exp_conf.get(quality, 0)
            res_err[1] += had_exp * TREASURE_STRENGTHEN_EXP_TO_GOLDS
            #log.error('For Test. _utid: {0}, cost: {1}, Price: {2}.'.format( _utid, had_exp * TREASURE_STRENGTHEN_EXP_TO_GOLDS, item_conf['Price'] ))

        for _utid in user_item_ids:
            self.delete_table_data(_utid)

        res_err[0] = NO_ERROR
        defer.returnValue( res_err )
    def dec_shard(self, shard_id):
        '''
        @summary: 通过碎片ID 减少玩家背包中的碎片。
            同时维护redis data-TPL_TREASURE_SHARD_GOT
        '''
        yield self._load()
        item_conf = get_item_by_itemid( shard_id )
        if not item_conf:
            log.error('Can not find conf. shard_id: {0}.'.format( shard_id ))
            defer.returnValue( (NOT_FOUND_CONF, None) )
        for sid, shard in self.__gsattribs.iteritems():
            if shard.item_id == shard_id:
                if shard.item_num > 1:
                    shard.item_num -= 1
                else:
                    shard.delete()
                    del self.__gsattribs[sid]
                break
        else:
            log.warn("user<{0}> have no the shard:{1}.".format(self.cid, shard_id))

        # 碎片可合成的宝物信息
        _, treasure_id, _ = item_conf['ChangeList'][0]
        yield self.update_avoid_cache( treasure_id )
    def treasure_reborn(self, user_treasure_id):
        '''
        @summary: 宝物重生 
            (1) 已穿戴 或 未精炼的宝物 不能重生
            (2) 返还该宝物精炼消耗的道具和强化消耗的经验道具, 强化消耗的道具返还为经验宝物 
            (3) 精炼消耗的金币不返还 
        '''
        treasure = yield self.user.bag_treasure_mgr.get(user_treasure_id)
        if not treasure:
            log.error('Can not find user treasure.')
            defer.returnValue(UNKNOWN_TREASURE_ERROR)
        # 已穿戴 或 未精炼的宝物不可重生
        if treasure.camp_id > 0 or treasure.refine_level <= 0:
            log.error(
                'Treasure reborn error. camp_id: {0}, refine level: {1}.'.
                format(treasure.camp_id, treasure.refine_level))
            defer.returnValue(TREASURE_REBORN_ERROR)

        # 宝物的conf
        treasure_conf = get_item_by_itemid(treasure.item_id)
        if not treasure_conf:
            log.error('Can not find conf. item id: {0}.'.format(
                treasure.item_id))
            defer.returnValue(UNKNOWN_ITEM_ERROR)
        total_exp = treasure.exp

        # 扣钻石
        reborn_conf = get_treasure_reborn_conf(treasure_conf['QualityLevel'],
                                               treasure.refine_level)
        if reborn_conf:
            yield self.user.consume_credits(reborn_conf['Cost'],
                                            WAY_TREASURE_REBORN)

        # 返还宝物强化消耗的经验
        for _level in range(1, treasure.level + 1):
            _conf = get_treasure_exp_conf(_level)
            _exp = _conf.get(ITEM_STRENGTHEN_COST[treasure_conf['Quality']], 0)
            if not _exp:
                continue
            total_exp += _exp

        # 用经验值兑换经验马或经验书, 增加1点经验, 需要消耗5个金币
        total_golds = total_exp * TREASURE_STRENGTHEN_EXP_TO_GOLDS
        self.user.get_golds(total_golds, WAY_TREASURE_REBORN)

        items_return = []
        _err, _value = yield self.user.bag_treasure_mgr.add_exp_treasure(
            treasure.item_type, total_exp)
        if not _err:
            items_return = _value

        # 返还精炼消耗的道具
        items_list = []  # 消耗的道具列表
        for _refine_level in range(1, treasure.refine_level + 1):
            refine_conf = get_treasure_refine_conf(treasure.item_id,
                                                   _refine_level)
            if not refine_conf:
                log.error(
                    'Can not find refine conf. item_id: {0}, refine_level: {1}.'
                    .format(treasure.item_id, _refine_level))
                continue
            _list = split_items(refine_conf['CostItemList'])
            for _l in _list:
                items_list = add_new_items(_l, items_list)
        #log.info('For Test. refine_level: {0}, items_list: {1}.'.format( treasure.refine_level, items_list ))

        # 道具类型格式:道具ID:道具数量
        for _type, _id, _num in items_list:
            # 货币类型特殊处理
            if _type == ITEM_TYPE_MONEY:
                continue
            model = ITEM_MODELs.get(_type, None)
            if not model:
                log.error(
                    'Unknown reborn item type. item type: {0}.'.format(_type))
                continue
            res_err, res_value = yield model(self.user,
                                             ItemID=_id,
                                             ItemNum=_num,
                                             AddType=WAY_TREASURE_REBORN,
                                             CapacityFlag=False)
            if not res_err:
                for _v in res_value:
                    items_return = total_new_items(_v, items_return)

        # 强化、精炼属性清零
        treasure.level, treasure.exp, treasure.refine_level = 0, 0, 0
        if total_golds > 0:
            items_return.append(
                [0, ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, total_golds])

        defer.returnValue((self.user.base_att.credits, items_return))
Beispiel #37
0
    def refine(self, user_treasure_id):
        '''
        @summary:  只有精炼等级为0, 强化等级为0的宝物才可作消耗材料
              只有品级(QualityLevel)大于7的才可以精炼
        '''
        res_err = UNKNOWN_TREASURE_ERROR

        attrib = yield self.get( user_treasure_id )
        if not attrib:
            log.error('Can not find user treasure. user_treasure_id: {0}.'.format( user_treasure_id ))
            defer.returnValue( res_err )

        refine_conf = get_treasure_refine_conf(attrib.item_id, attrib.refine_level+1)
        if not refine_conf:
            log.error('Can not find refine conf. item_id: {0}, refine level: {1}.'.format( attrib.item_id, attrib.refine_level+1 ))
            defer.returnValue( NOT_FOUND_CONF )
        # 道具配置 自身品级不满足
        item_conf = get_item_by_itemid(attrib.item_id)
        if (not item_conf) or (item_conf['QualityLevel'] <= TREASURE_REFINE_QUALITYLEVEL_MAX):
            log.error('Can not refine treasure. No conf or quality_level limit. item_id: {0}.'.format( attrib.item_id ))
            defer.returnValue( CLIENT_DATA_ERROR )

        # 金币不足
        if refine_conf['CostGold'] > self.user.base_att.golds:
            log.error('user golds not enough. need_golds: {0}, cur_golds: {1}.'.format( refine_conf['CostGold'], self.user.base_att.golds ))
            defer.returnValue( CHAR_GOLD_NOT_ENOUGH )

        # 消耗道具不足, 道具类型格式:道具ID:道具数量
        items_list = split_items( refine_conf['CostItemList'] )
        cost_attribs = [] # 要消耗的宝物
        for _type, _id, _num in items_list:
            if _type in BAG_TREASURE:
                all_attribs = yield self.get_item_to_refine( user_treasure_id, _id )
                if len(all_attribs) < _num:
                    log.error('user item not enough. item_id: {2}, cur_item_num: {0}, need_item_num: {1}.'.format( len(all_attribs), _num, _id ))
                    defer.returnValue( CHAR_ITEM_NOT_ENOUGH )
                cost_attribs.extend( all_attribs[:_num] )
            elif _type == ITEM_TYPE_ITEM:
                total_num, item_attribs = yield self.user.bag_item_mgr.get_items( _id )
                if total_num < _num:
                    log.error('user item not enough. cid:{0}, item_id:{1}, need:{2}, curr:{3}.'.format( self.cid, _id, _num, total_num ))
                    defer.returnValue( CHAR_ITEM_NOT_ENOUGH )
            else:
                log.error("Unknown item type. cost item: {0}.".format( refine_conf['CostItemList'] ))
                defer.returnValue( UNKNOWN_ITEM_ERROR )
        # 扣宝物
        items_return = []
        for _attrib in cost_attribs:
            self.delete_table_data( _attrib.attrib_id )
            items_return.append( _attrib.attrib_id )
        # 扣道具
        left_items = []
        for _type, _id, _num in items_list:
            if _type != ITEM_TYPE_ITEM:
                continue
            res_err, used_attribs = yield self.user.bag_item_mgr.use( _id, _num )
            if res_err:
                log.error('Use item error. cid:{0}, _type:{1}, _id:{2}, _num:{3}.'.format( self.cid, _type, _id, _num ))
            # used_attribs-已使用的道具
            for _a in used_attribs:
                left_items.append( [_a.attrib_id, _a.item_type, _a.item_id, _a.item_num] )

        # 扣金币
        #self.user.base_att.golds -= refine_conf['CostGold']
        self.user.consume_golds( refine_conf['CostGold'], WAY_TREASURE_REFINE )
        attrib.refine_level += 1

        # add syslog
        way_others = str(tuple(items_return))
        syslogger(LOG_TREASURE_REFINE, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, user_treasure_id, attrib.item_id, attrib.refine_level-1, attrib.refine_level, way_others)

        # 同步camp到redis
        #if attrib.camp_id:
        #    yield self.user.sync_camp_to_redis(update=True)
        yield self.user.achievement_mgr.update_achievement_status(ACHIEVEMENT_QUEST_ID_33, attrib.refine_level) 
        defer.returnValue( (user_treasure_id, attrib.item_id, attrib.refine_level, self.user.base_att.golds, items_return, left_items) )
def plunder(p, req):
    '''
    @summary: 夺宝结算
    '''
    res_err = UNKNOWN_ERROR

    cid, ( plunder_cid, shard_id, won ) = req

    user = g_UserMgr.getUser(cid)
    if not user:
        log.error('Can not find user. cid: {0}.'.format( cid ))
        defer.returnValue( res_err )

    if user.base_att.douzhan < PVP_NEED_DOUZHAN:
        log.error('douzhan of user {0} have been zero!!!'.format( cid ))
        defer.returnValue( CHAR_DOUZHAN_NOT_ENOUGH )

    item_conf = get_item_by_itemid( shard_id )
    treasure_id = 0
    if item_conf:
        _, treasure_id, _ = item_conf['ChangeList'][0]

    response = [0, 0, [], []]

    # 对玩家进行抢夺,免战自动解除
    if plunder_cid > 0: # 玩家
        yield redis.hdel( HASH_AVOID_WAR_TIME, cid )
        AvoidWarMgr.stop_plunder_shard( treasure_id, plunder_cid )
        _user_plundered = yield gs_offline_login( plunder_cid )
        if _user_plundered:
            reactor.callLater(SESSION_LOGOUT_REAL, gs_offline_logout, plunder_cid)
    else:
        _user_plundered = None

    if won:
        response[3] = yield random_lottery_items( cid, user.level, user.base_att.vip_level )
        err, add_items = yield AvoidWarMgr.rand_shard( user, shard_id, plunder_cid )

        if not err and (len(add_items) > 0): #抢到
            response[0] = 1
            response[2] = add_items[0][0], add_items[0][2]
            syslogger(LOG_AVOID_WAR, cid, user.level, user.vip_level, user.alliance_id, 0, won, add_items[0][0],add_items[0][2])
            if _user_plundered:
                ms_send('write_mail', (plunder_cid, MAIL_PAGE_BATTLE, MAIL_BATTLE_7, [user.lead_id, user.nick_name, shard_id]))
                yield _user_plundered.bag_treasureshard_mgr.dec_shard( shard_id )
            else:
                log.warn('No user be plundered. cid: {0}, plunder_cid: {1}.'.format( cid, plunder_cid ))
        else: # 未抢到
            response[0] = 0
            syslogger(LOG_AVOID_WAR, cid, user.level, user.vip_level, user.alliance_id, 0, won, 0, 0)
    else: # 战斗输了
        if _user_plundered:
            syslogger(LOG_AVOID_WAR, cid, user.level, user.vip_level, user.alliance_id, 0, won, 0, 0)
            ms_send('write_mail', (plunder_cid, MAIL_PAGE_BATTLE, MAIL_BATTLE_6, [user.lead_id, user.nick_name, shard_id]))
 
    if user.base_att.douzhan >= PVP_NEED_DOUZHAN:
        user.base_att.douzhan -= PVP_NEED_DOUZHAN
    # 每日任务计数
    yield user.daily_quest_mgr.update_daily_quest( DAILY_QUEST_ID_5, 1 )
    # 开服七天
    yield user.open_server_mgr.update_open_server_activity_quest( OPEN_SERVER_QUEST_ID_8, 1)
    yield user.achievement_mgr.update_achievement_status(ACHIEVEMENT_QUEST_ID_8, 1)

    response[1] = user.base_att.douzhan

    defer.returnValue( response )
    def treasure_decomposition(self, user_treasure_ids):
        ''' 
        @summary: 宝物炼化 相同类型
            (1) 已穿戴 或 精炼属性大于0的不可炼化, 需要先重生, 经验马 经验书不能也炼化
            (2) 炼化产出道具, 读sysconfig['item_decomposition'], 返还道具
            (3) 返还宝物强化消耗的经验, 并将其折算成经验马或经验书, 返还金币
            (4) 删除用于炼化的材料, 即宝物
        '''
        for _utid in user_treasure_ids:
            treasure = yield self.user.bag_treasure_mgr.get(_utid)
            if not treasure:
                log.error('Can not find user treasure. user_treasure_id: {0}.'.
                          format(_utid))
                defer.returnValue(UNKNOWN_TREASURE_ERROR)
            # 所选宝物 类型必须为书或马
            if treasure.item_type not in BAG_TREASURE:
                log.error('Selected treasure type not horse or bookwar.')
                defer.returnValue(UNKNOWN_TREASURE_ERROR)
            # 经验马、经验书不能炼化
            if treasure.item_id == EXP_HORSE_ID or treasure.item_id == EXP_BOOKWAR_ID:
                log.error(
                    'EXP_HORSE or EXP_BOOKWAR could not be decomposition. item id: {0}.'
                    .format(treasure.item_id))
                defer.returnValue(TREASURE_DECOMPOSITION_ERROR)

            # 已穿戴 或 精炼属性大于0的不可炼化, 需要先重生
            if treasure.camp_id > 0 or treasure.refine_level > 0:
                log.error(
                    'Treasure refine level error. ufid: {0}, refine level: {1}.'
                    .format(_utid, treasure.refine_level))
                defer.returnValue(TREASURE_DECOMPOSITION_ERROR)

            # 宝物的conf
            treasure_conf = get_item_by_itemid(treasure.item_id)
            if not treasure_conf:
                log.error('Can not find conf. item id: {0}.'.format(
                    treasure.item_id))
                defer.returnValue(UNKNOWN_ITEM_ERROR)

        total_golds, horse_exp, bookwar_exp = 0, 0, 0
        items_return = []
        for _utid in user_treasure_ids:
            treasure = yield self.user.bag_treasure_mgr.get(_utid)
            extra_exp = treasure.exp
            treasure_conf = get_item_by_itemid(treasure.item_id)
            # 宝物自身经验
            for _attr in treasure_conf['attributes']:
                if _attr['AttributeID'] in (ATTRIBUTE_TYPE_HORSE_EXP,
                                            ATTRIBUTE_TYPE_BOOKWAR_EXP):
                    extra_exp += _attr['Value']
                    break

            # 炼化产出的道具
            decomposition_conf = get_item_decomposition(
                treasure.item_type, treasure_conf['QualityLevel'])
            for _dec in decomposition_conf:
                items_list = split_items(_dec['ItemList'])
                #log.info('For Test. _utid: {0}, items_list: {1}.'.format( _utid, items_list ))
                for _type, _id, _num in items_list:
                    # 货币类型特殊处理
                    if _type == ITEM_TYPE_MONEY:
                        if _id == ITEM_MONEY_GOLDS:
                            total_golds += _num
                        continue
                    model = ITEM_MODELs.get(_type, None)
                    if not model:
                        log.error(
                            'Unknown decomposition item type. item type: {0}.'.
                            format(_type))
                        continue
                    res_err, res_value = model(
                        self.user,
                        ItemID=_id,
                        ItemNum=_num,
                        AddType=WAY_TREASURE_DECOMPOSITION,
                        CapacityFlag=False)
                    if not res_err:
                        for _v in res_value:
                            items_return = total_new_items(_v, items_return)

            # 返还宝物强化消耗的经验, 并折算成经验马或经验书
            for _level in range(1, treasure.level + 1):
                _conf = get_treasure_exp_conf(_level)
                extra_exp += _conf.get(
                    ITEM_STRENGTHEN_COST[treasure_conf['Quality']], 0)
            if treasure.item_type == ITEM_TYPE_HORSE:
                horse_exp += extra_exp
            else:
                bookwar_exp += extra_exp

            # 删除用于炼化的treasure
            self.user.bag_treasure_mgr.delete_table_data(_utid)
            # add syslog
            syslogger(LOG_ITEM_LOSE, self.cid, self.user.level,
                      self.user.vip_level, self.user.alliance_id, _utid,
                      treasure.item_id, 1, WAY_TREASURE_DECOMPOSITION)

        # 返还金币
        total_golds += (horse_exp +
                        bookwar_exp) * TREASURE_STRENGTHEN_EXP_TO_GOLDS
        #self.user.base_att.golds += total_golds
        self.user.get_golds(total_golds, WAY_TREASURE_REFINE)
        # 用经验值兑换经验马或经验书
        if horse_exp > 0:
            res_err, res_value = yield self.user.bag_treasure_mgr.add_exp_treasure(
                ITEM_TYPE_HORSE, horse_exp)
            if not res_err:
                for _v in res_value:
                    items_return = total_new_items(_v, items_return)
        if bookwar_exp > 0:
            res_err, res_value = yield self.user.bag_treasure_mgr.add_exp_treasure(
                ITEM_TYPE_BOOKWAR, bookwar_exp)
            if not res_err:
                for _v in res_value:
                    items_return = total_new_items(_v, items_return)
        if total_golds > 0:
            items_return.append(
                [0, ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, total_golds])

        defer.returnValue(items_return)
Beispiel #40
0
def sync_achievement():
    i = 1
    conn = MySQLdb.connect(**db_conf)
    cursor = conn.cursor()

    cid_sql = 'select id, level,vip_level,friends,might from tb_character where level > 1;'
    scene_sql = 'select max(dungeon_id), count(dungeon_star) from tb_scene where cid = %s;' 
    climb_sql = 'select max_layer from tb_climbing_tower where cid = %s;'
    jade_sql = 'select item_id from tb_bag_jade where del_time = 0 and cid = %s';
    
    cursor.execute( cid_sql )
    _all_cid = cursor.fetchall()
    a = {}
    print 'select is running!'
    for _cid, _lv, _vip_level, friends, might in _all_cid:
        cursor.execute(scene_sql % _cid)
        _max_id = cursor.fetchone()
        #lv
        if a.has_key(_cid):
            a[_cid].append([4, _lv])
        else:
            a[_cid] = [[4, _lv]]
        #vip_level
#       a[_cid].append([18, _vip_level])
        #scene
        if _max_id[0] is not None:
            a[_cid].append([3, _max_id[0]])
        #chaos
        a[_cid].append([11, _max_id[1]])
        #friends
#       total = len(loads(friends)) if friends else 0
#       a[_cid].append([20, total])
        #might
        a[_cid].append([14, might])
        #arena
        _rank = yield redis.zscore( "SET_ARENA_CID_RANK", _cid )
        _rank = int(_rank) if _rank else 0
        a[_cid].append([7, _rank])
        #elite
        _s = yield redis.hget("HASH_ELITESCENE_PASSED", _cid)
        if _s:
            passed_elitescene_ids = loads(_s)
            passed_elitescene_ids.sort()
            a[_cid].append([12, passed_elitescene_ids[-1]])
        #climb
        cursor.execute(climb_sql % _cid)
        _c = cursor.fetchone()
        if _c is not None:
            a[_cid].append([10, _c[0]])
        #jade
        cursor.execute(jade_sql % _cid)
        row = cursor.fetchall()
        i = 0
        for r in row:
            if get_item_by_itemid(int(r[0])).get('Quality', 0) >= 2:
                i += 1
        a[_cid].append([16, i]) 


    print 'sync is beginning!'

    for _cid, _info in a.iteritems():
        _d = get_standard_conf()
        for _type, _value in _info:
            for _, _v in _d[_type].iteritems():
                _v[1] = _value
        yield redis.hset("HASH_ACHIEVEMENT_INFO", _cid, dumps(_d))

    print 'sync scene end'


    cursor.close()
    conn.close()
 
    print 'end...'
    conn   = None
    cursor = None
    reactor.stop()
Beispiel #41
0
    def gift_goodwill(self, fellow_id, use_items):
        gsattrib = yield self.get_fellow(fellow_id)
        if not gsattrib:
            defer.returnValue( UNKNOWN_FELLOW_ERROR )

        level_conf = get_goodwill_level_conf(gsattrib.goodwill_level + 1)
        if not level_conf:
            defer.returnValue( GOODWILL_LEVEL_MAX_ERROR )
 
        get_goodwill, crit_count, levelup_count = 0, 0, 0
        items_return = []
        cur_goodwill_exp   = gsattrib.goodwill_exp
        cur_goodwill_level = gsattrib.goodwill_level
        del_items = {}

        all_item_ids = []
        for item_id, item_num in use_items:
            all_item_ids.extend( [item_id] * item_num )

        for item_id in all_item_ids:
            add_goodwill = 0
            item_conf = get_item_by_itemid( item_id )
            if not item_conf:
                continue
            for _attr in item_conf['attributes']:
                if _attr['AttributeID'] != ATTRIBUTE_TYPE_GOODWILL:
                    continue
                add_goodwill = _attr['Value']
            if add_goodwill == 0:
                continue
            del_items[item_id] = del_items.setdefault( item_id, 0 ) + 1
            # 计算好感度经验值
            get_goodwill += add_goodwill
            cur_goodwill_exp += add_goodwill
            if cur_goodwill_exp >= level_conf['PurpleExp']:
                cur_goodwill_exp, cur_goodwill_level, levelup_count = self.cal_level_up( cur_goodwill_exp, cur_goodwill_level, levelup_count )
                # 好感度升级conf
                level_conf = get_goodwill_level_conf(cur_goodwill_level + 1)
                if not level_conf:
                    break
            else:
                need_goodwill_exp = level_conf['PurpleExp'] - cur_goodwill_exp
                crit_ratio = level_conf['PurpleCrit'] + add_goodwill / need_goodwill_exp * 0.5
                rand_int = random.randint(1, 10000)
                if rand_int <= crit_ratio:
                    crit_count += 1
                    cur_goodwill_exp = 0
                    cur_goodwill_level += 1
                    levelup_count += 1
                    # 好感度升级conf
                    level_conf = get_goodwill_level_conf(cur_goodwill_level + 1)
                    if not level_conf:
                        break
        #log.info('For Test. del_items: {0}.'.format( del_items ))
        # 使用道具
        for _id, _num in del_items.items():
            res_err, used_attribs = yield self.user.bag_item_mgr.use( _id, _num )
            if res_err:
                continue
            for _a in used_attribs:
                items_return = total_new_items( [_a.attrib_id, _a.item_type, _a.item_id, _a.item_num], items_return )
  
        #log.info('For Test. cur_goodwill_exp: {0}, cur_goodwill_level: {1}, get_goodwill: {2}, crit_count: {3}, levelup_count: {4}.'.format( cur_goodwill_exp, cur_goodwill_level, get_goodwill, crit_count, levelup_count ))
        if cur_goodwill_exp != gsattrib.goodwill_exp:
            gsattrib.goodwill_exp = cur_goodwill_exp

        last_total_level = self.total_goodwill_level
        if cur_goodwill_level > gsattrib.goodwill_level:
            gsattrib.goodwill_level = cur_goodwill_level
            self.total_goodwill_level += levelup_count
            add_douzhan = yield self.check_achieve( last_total_level )
            if add_douzhan > 0:
                yield self.update_friend_gift_douzhan(add_douzhan)
        # 更新last_fellow_id
        gsattrib.last_gift = 1
        if self.last_fellow_id:
            last_gsattrib = yield self.get_fellow(self.last_fellow_id)
            if last_gsattrib:
                last_gsattrib.last_gift = 0

        self.last_fellow_id = fellow_id
 
        yield self.user.daily_quest_mgr.update_daily_quest( DAILY_QUEST_ID_13, 1)
        yield self.user.achievement_mgr.update_achievement_status(23, self.total_goodwill_level)
        defer.returnValue( (self.total_goodwill_level, cur_goodwill_exp, cur_goodwill_level, get_goodwill, crit_count, levelup_count, items_return) )
Beispiel #42
0
    def strengthen(self, user_treasure_id, treasures_data):
        '''
        @summary: 消耗treasures_data强化user_treasure_id
        '''
        res_err = UNKNOWN_TREASURE_ERROR

        attrib = yield self.get( user_treasure_id )
        if not attrib:
            log.error('Can not find user treasure. user_treasure_id: {0}.'.format( user_treasure_id ))
            defer.returnValue( res_err )

        # 道具配置
        item_conf = get_item_by_itemid(attrib.item_id)
        if not item_conf:
            log.error('Can not find item conf. item_id: {0}.'.format( attrib.item_id ))
            defer.returnValue( NOT_FOUND_CONF )
        # 要强化的道具品质、经验、强化等级
        quality    = ITEM_STRENGTHEN_COST[item_conf['Quality']]
        _total_exp = 0
        _cur_level = attrib.level

        # 获取消耗的treasures_data可获得的经验值
        for _utid in treasures_data:
            use_attrib = yield self.get( _utid )
            if not use_attrib:
                log.error('Can not find user treasure. user_treasure_id: {0}.'.format( _utid ))
                defer.returnValue( res_err )
            # 道具配置
            item_conf = get_item_by_itemid(use_attrib.item_id)
            if not item_conf:
                log.error('Can not find item conf. item_id: {0}.'.format( attrib.item_id ))
                defer.returnValue( CLIENT_DATA_ERROR )
            # 类型不匹配/已装备的不可用于强化
            if (use_attrib.item_type != attrib.item_type) \
               or (use_attrib.camp_id > 0):
                log.error('Item type not match or in camp. item_id: {0}, item type: {1}, camp_id: {2}.'.format( \
                    use_attrib.item_id, (attrib.item_type, use_attrib.item_type), use_attrib.camp_id))
                defer.returnValue( CLIENT_DATA_ERROR )

            _attributs = item_conf['attributes']
            for _attr in _attributs:
                if _attr['AttributeID'] in (ATTRIBUTE_TYPE_HORSE_EXP, ATTRIBUTE_TYPE_BOOKWAR_EXP):
                    _total_exp += _attr['Value']
            # 计算升级获得的经验, 宝物初始等级为0
            use_quality = ITEM_STRENGTHEN_COST[item_conf['Quality']]
            for _level in range(1, use_attrib.level+1):
                use_exp_conf = get_treasure_exp_conf( _level )
                had_got_exp = use_exp_conf.get(use_quality, 0)
                if had_got_exp:
                    _total_exp += had_got_exp
        # 金币不足
        if _total_exp*TREASURE_STRENGTHEN_EXP_TO_GOLDS > self.user.base_att.golds:
            log.error('user golds not enough. cur_golds: {0}, need_golds: {1}.'.format(self.user.base_att.golds, _total_exp*TREASURE_STRENGTHEN_EXP_TO_GOLDS))
            defer.returnValue( CHAR_GOLD_NOT_ENOUGH )
        # 扣金币
        #self.user.base_att.golds -= _total_exp*TREASURE_STRENGTHEN_EXP_TO_GOLDS 
        self.user.consume_golds( _total_exp*TREASURE_STRENGTHEN_EXP_TO_GOLDS, WAY_TREASURE_STRENGTHEN )

        _total_exp += attrib.exp
        # 强化前的等级
        _old_level = attrib.level
        # 删除用于强化的宝物
        for _utid in treasures_data:
            self.delete_table_data( _utid )

        while _total_exp > 0:
            # 强化宝物所需exp配置
            exp_conf  = get_treasure_exp_conf( _cur_level+1 )
            if not exp_conf:
                log.error('Can not find strengthen exp conf. strengthen next level: {0}.'.format( _cur_level+1 ))
                break

            need_exp    = exp_conf[quality]
            # 经验不足以升级
            if (_total_exp - need_exp) < 0:
                break
            _total_exp -= need_exp
            _cur_level += 1

        attrib.level = _cur_level
        attrib.exp   = _total_exp

        # add syslog
        way_others = str(tuple(treasures_data))
        syslogger(LOG_TREASURE_STRENGTHEN, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, user_treasure_id, attrib.item_id, _old_level, attrib.level, way_others)
        # 同步camp到redis
        #if attrib.camp_id:
        #    yield self.user.sync_camp_to_redis(update=True)

        yield self.user.daily_quest_mgr.update_daily_quest( DAILY_QUEST_ID_15, 1)
        defer.returnValue( (user_treasure_id, attrib.item_id, _cur_level, _total_exp, self.user.base_att.golds) )
    def update_avoid_cache(self, treasure_id):
        '''
        @summary: 维护宝物碎片列表的同时, 维护redis中的玩家阵营数据
        '''
        if self.user.base_att.level <= AVOID_WAR_LEVEL:
            log.warn('User level <= 12 could not be plunder. cid: {0}.'.format(
                self.cid))
            defer.returnValue(REQUEST_LIMIT_ERROR)

        treasure_conf = get_item_by_itemid(treasure_id)
        if not treasure_conf:
            log.error(
                'Can not find conf. treasure_id: {0}.'.format(treasure_id))
            defer.returnValue(NOT_FOUND_CONF)
        _shard_list = [splited[1] for splited in treasure_conf['ChangeList']]

        # 只有同时拥有“一个宝物的2个或者2个以上,不同位置碎片”的玩家才会被加入被抢夺列表
        _haved = 0
        _plunder_list = []  # 可被抢夺的碎片
        for _shard_id in _shard_list:
            for attrib in self.__gsattribs.itervalues():
                if attrib.item_id == _shard_id:
                    _haved += 1
                    _plunder_list.append(_shard_id)
                    break

        #_treasure_ids = yield redis.hget( HASH_TREASURE_CHARACTER_IDS, self.cid )
        #if _treasure_ids:
        #    _treasure_ids = loads(_treasure_ids)
        #else:
        #    _treasure_ids = []

        #log.info('For Test. _haved: {0}, cid: {1}, _shard_id: {2}, _shard_list: {3}, _plunder_list: {4}.'.format( _haved, self.cid, _shard_id, _shard_list, _plunder_list ))
        for _shard_id in _shard_list:
            yield redis.hdel(TPL_TREASURE_SHARD_GOT % _shard_id, self.cid)

        #if treasure_id in _treasure_ids:
        #    _treasure_ids.remove( treasure_id )

        if _haved > 1:
            #_flag   = True  # 成功获取玩家有效阵容
            #_exists = yield redis.hexists( HASH_TREASURE_CHARACTER_CAMP, self.cid )
            #if (not _exists):
            #    _all_camps = yield self.user.get_camp()
            #    fellow_ids = []
            #    if _all_camps:
            #        for camp_data in _all_camps[1]:
            #            if not camp_data or not camp_data[1]:
            #                continue
            #            fellow_ids.append( camp_data[1][1] )

            #    # 有效的玩家阵容
            #    if fellow_ids:
            #        yield redis.hset( HASH_TREASURE_CHARACTER_CAMP, self.cid, dumps(_all_camps) )
            #        #log.info('For Test. save treasure camp. cid: {0}.'.format( self.cid ))
            #    else:
            #        _flag = False
            #        log.error('Save char treasure camp data fail. cid: {0}, _all_camps: {1}.'.format( self.cid, _all_camps ))

            for _shard_id in _plunder_list:
                yield redis.hset(
                    TPL_TREASURE_SHARD_GOT % _shard_id, self.cid,
                    dumps((self.cid, self.user.level,
                           self.user.base_att.nick_name)))
Beispiel #44
0
    def strengthen(self, user_jade_id, jades_data):
        '''
        @summary: 消耗jades_data强化user_jade_id
        '''
        attrib = yield self.get(user_jade_id)
        if not attrib:
            defer.returnValue(UNKNOWN_JADE_ERROR)

        # 道具配置
        item_conf = get_item_by_itemid(attrib.item_id)
        if not item_conf:
            defer.returnValue(NOT_FOUND_CONF)

        # 要强化的道具品质、经验、强化等级
        _total_exp = attrib.exp
        _cur_level = attrib.level
        quality = JADE_STRENGTHEN_EXP[item_conf['Quality']]

        # 获取消耗的jades_data可获得的经验值
        for _ujid in jades_data:
            use_attrib = yield self.get(_ujid)
            if not use_attrib:
                defer.returnValue(res_err)
            # 道具配置
            use_item_conf = get_item_by_itemid(use_attrib.item_id)
            if not use_item_conf:
                log.error(
                    'Can not find item conf. cid: {0}, item_id: {0}.'.format(
                        self.cid, attrib.item_id))
                defer.returnValue(CLIENT_DATA_ERROR)
            # 类型不匹配/已穿戴的不可用于升级
            if (use_attrib.item_type != attrib.item_type) \
               or (use_attrib.camp_id > 0):
                log.error('Item in camp error. cid: {0}, item_id: {1}, item type: {2}, camp_id: {3}.'.format( \
                    self.cid, use_attrib.item_id, (attrib.item_type, use_attrib.item_type), use_attrib.camp_id))
                defer.returnValue(CLIENT_DATA_ERROR)

            _attributs = use_item_conf['attributes']
            for _attr in _attributs:
                if _attr['AttributeID'] == ATTRIBUTE_TYPE_JADE_EXP:
                    _total_exp += _attr['Value']
            # 计算升级获得的经验, 玉魄初始等级为0
            use_quality = JADE_STRENGTHEN_EXP[use_item_conf['Quality']]
            for _level in range(1, use_attrib.level + 1):
                use_exp_conf = get_jade_strengthen_conf(_level)
                had_got_exp = use_exp_conf.get(use_quality, 0)
                if had_got_exp:
                    _total_exp += had_got_exp

        # 强化前的等级
        _old_level = attrib.level
        # 删除用于强化的宝物
        for _ujid in jades_data:
            self.delete_table_data(_ujid)

        _max_level = (self.user.level / 10) * 5
        while _total_exp > 0:
            # 玉魄等级有限制
            if _cur_level >= _max_level:
                break
            # 强化宝物所需exp配置
            exp_conf = get_jade_strengthen_conf(_cur_level + 1)
            if not exp_conf:
                log.error(
                    'Can not find strengthen exp conf. strengthen next level: {0}.'
                    .format(_cur_level + 1))
                break

            need_exp = exp_conf[quality]
            # 经验不足以升级
            if (_total_exp - need_exp) < 0:
                break
            _total_exp -= need_exp
            _cur_level += 1

        attrib.level = _cur_level
        attrib.exp = _total_exp

        ## add syslog
        #way_others = str(tuple(treasures_data))
        #syslogger(LOG_JADE_STRENGTHEN, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, user_treasure_id, attrib.item_id, _old_level, attrib.level, way_others)

        defer.returnValue(
            (user_jade_id, attrib.item_id, _cur_level, _total_exp))
    def equip_reborn(self, user_equip_id):
        ''' 
        @summary: 装备重生 
            (1) 已穿戴 或 未洗炼的装备 不能重生
            (2) 返还该装备洗炼消耗的洗炼石和强化消耗的金币
            (3) 洗练消耗的金币和钻石不返还
            (4) 每返还10个洗炼石,则重生价格为1钻石
        '''
        equip = yield self.user.bag_equip_mgr.get(user_equip_id)
        if not equip:
            log.error('Can not find user equip.')
            defer.returnValue(UNKNOWN_EQUIP_ERROR)

        # 已穿戴 或 洗炼属性为[]的不可重生
        #log.error('camp_id: {0}, refine_attribute: {1}.'.format( equip.camp_id, loads(equip.refine_attribute) ))
        if (equip.camp_id > 0) or not loads(equip.refine_attribute):
            log.error(
                'Equip reborn error. cid: {0}, ueid: {1}, camp_id: {2}, refine_attribute: {3}.'
                .format(self.cid, user_equip_id, equip.camp_id,
                        loads(equip.refine_attribute)))
            defer.returnValue(EQUIP_REBORN_ERROR)

        # 装备的conf
        equip_conf = get_item_by_itemid(equip.item_id)
        if not equip_conf:
            log.error('Can not find conf. item id: {0}.'.format(equip.item_id))
            defer.returnValue(UNKNOWN_ITEM_ERROR)

        # 计算钻石消耗
        if (equip.refine_cost % 10) > 0:
            need_credits = equip.refine_cost / 10 + 1
        else:
            need_credits = equip.refine_cost / 10

        # 玩家钻石不足
        if need_credits > self.user.base_att.credits:
            log.error('Need credits: {0}, now have: {1}.'.format(
                need_credits, self.user.base_att.credits))
            defer.returnValue(CHAR_CREDIT_NOT_ENOUGH)

        items_return = []
        # 返还金币、洗炼石
        #self.user.base_att.golds += equip.strengthen_cost
        self.user.get_golds(equip.strengthen_cost, WAY_EQUIP_REBORN)
        try:
            res_err, res_value = yield self.user.bag_item_mgr.new(
                ITEM_REFINE_STONE, equip.refine_cost)
            if not res_err:
                items_return = res_value
        except Exception as e:
            log.error('ERROR: {0}.'.format(e))
            log.exception()
        # 扣钻石, 数据清零
        #self.user.base_att.credits -= need_credits
        if need_credits:
            yield self.user.consume_credits(need_credits, WAY_EQUIP_REBORN)
        self.user.bag_equip_mgr.reborn(user_equip_id)

        if equip.strengthen_cost > 0:
            items_return.append(
                [0, ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, equip.strengthen_cost])

        # 强化、精炼属性清零
        equip.level, equip.strengthen_cost, equip.refine_cost, equip.refine_attribute = 0, 0, 0, dumps(
            [])

        defer.returnValue((self.user.base_att.credits, items_return))
Beispiel #46
0
    def equip_decomposition(self, user_equip_ids):
        ''' 
        @summary: 装备炼化 
            (1) 已穿戴 或 洗炼属性大于0的不可炼化, 需要先重生
            (2) 炼化产出道具, 读sysconfig['item_decomposition'], 返还道具
            (3) 返还强化消耗的金币
            (4) 删除用于炼化的材料, 即装备
        '''
        for _ueid in user_equip_ids:
            equip = yield self.user.bag_equip_mgr.get( _ueid )
            if not equip:
                log.error('Can not find user equip. user_equip_id: {0}.'.format( _ueid ))
                defer.returnValue( UNKNOWN_EQUIP_ERROR )

            # 已穿戴 或 洗炼属性大于0的不可炼化, 需要先重生
            if (equip.camp_id > 0):
                log.error('Equip refine level error. ueid: {0}, camp_id: {1}, refine_attr: {2}.'.format( _ueid, equip.camp_id, loads(equip.refine_attribute) ))
                defer.returnValue( EQUIP_DECOMPOSITION_ERROR )

            for _attr in loads(equip.refine_attribute):
                if _attr[1] > 0:
                    defer.returnValue( EQUIP_DECOMPOSITION_ERROR )

            # 装备的conf
            equip_conf = get_item_by_itemid( equip.item_id )
            if not equip_conf:
                log.error('Can not find conf. item id: {0}.'.format( equip.item_id ))
                defer.returnValue( UNKNOWN_ITEM_ERROR )

        items_return = []
        total_golds  = 0
        for _ueid in user_equip_ids:
            equip = yield self.user.bag_equip_mgr.get( _ueid )
            equip_conf = get_item_by_itemid( equip.item_id )
            # 返还强化消耗的金币
            total_golds += equip.strengthen_cost

            # 炼化产出的道具
            decomposition_conf = get_item_decomposition( equip.item_type, equip_conf['QualityLevel'] )
            for _dec in decomposition_conf:
                items_list = split_items( _dec['ItemList'] )
                for _type, _id, _num in items_list:
                    # character attribute需要单独处理
                    if _type == ITEM_TYPE_MONEY:
                        if _id == ITEM_MONEY_GOLDS:
                            total_golds += _num
                        continue
                    model = ITEM_MODELs.get( _type, None )
                    if not model:
                        log.error('Unknown decomposition item type. item type: {0}.'.format( _type ))
                        continue
                    res_err, res_value = yield model(self.user, ItemID=_id, ItemNum=_num, AddType=WAY_EQUIP_DECOMPOSITION, CapacityFlag=False)
                    if not res_err:
                        for _v in res_value:
                            items_return = total_new_items(_v, items_return)
            # 删除用于炼化的equip
            self.user.bag_equip_mgr.delete_table_data( _ueid )
            # add syslog
            syslogger(LOG_ITEM_LOSE, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, _ueid, equip.item_id, 1, WAY_EQUIP_DECOMPOSITION)

        # 返还金币
        if total_golds > 0:
            #self.user.base_att.golds += total_golds
            self.user.get_golds( total_golds, WAY_EQUIP_REFINE )
            items_return.append( [0, ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, total_golds] )

        defer.returnValue( items_return )
    def combine(self, user_treasureshard_ids):
        '''
        @summary: 合成宝物碎片得到宝物
        '''
        yield self._load()
        used_item_ids = []  # 碎片道具ID列表
        shard_changelist = []
        # 检查材料的有效性
        for _uid in user_treasureshard_ids:
            if not self.__gsattribs.has_key(_uid):
                log.error(
                    'Unknown user treasureshard. _uid: {0}.'.format(_uid))
                defer.returnValue(UNKNOWN_TREASURESHARD)
            gsattrib = self.__gsattribs[_uid]
            item_conf = get_item_by_itemid(gsattrib.item_id)
            if not item_conf:
                log.error('Can not find conf. item_id: {0}.'.format(item_id))
                defer.returnValue(NOT_FOUND_CONF)
            if shard_changelist:
                if shard_changelist != item_conf['ChangeList']:
                    log.error(
                        'Treasureshard error. _uid: {0}, shard_changelist: {1}, item_conf: {2}.'
                        .format(_uid, shard_changelist, item_conf))
                    defer.returnValue(UNKNOWN_ITEM_ERROR)
            else:
                shard_changelist = item_conf['ChangeList']
            # 判断道具数量
            if 1 > gsattrib.item_num:
                log.error('error. _uid: {0}, cur item num: {1}.'.format(
                    _uid, gsattrib.item_num))
                defer.returnValue(CHAR_ITEM_NOT_ENOUGH)
            used_item_ids.append(gsattrib.item_id)
        # 获取要合成的宝物
        if 1 != len(shard_changelist):
            log.error('error. shard_changelist: {0}.'.format(shard_changelist))
            defer.returnValue(UNKNOWN_ITEM_ERROR)
        # format: [item_type, item_id, item_num]
        target_treasure = shard_changelist[0]
        target_conf = get_item_by_itemid(target_treasure[1])
        if not target_conf:
            log.error('Can not find target conf. item_id: {0}.'.format(
                target_treasure[1]))
            defer.returnValue(NOT_FOUND_CONF)
        # 检查合成宝物所需材料是否满足条件
        need_item_ids = [_c[1] for _c in target_conf['ChangeList']]
        if sorted(need_item_ids) != sorted(used_item_ids):
            log.error(
                'shard can not combine. need_item_ids: {0}, used_item_ids: {1}.'
                .format(need_item_ids, used_item_ids))
            defer.returnValue(REQUEST_LIMIT_ERROR)
        # 删除材料
        for _uid in user_treasureshard_ids:
            yield self.delete_table_data(_uid)
        # 新增宝物
        res_err, add_items = yield self.user.bag_treasure_mgr.new(
            target_treasure[1], target_treasure[2], WAY_AVOID_WAR)
        # 开服七天
        _conf = get_item_by_itemid(target_treasure[1])
        if not _conf:
            log.error('Can not find conf. item_id: {0}.'.format(item_id))
            defer.returnValue((NOT_FOUND_CONF, None))
        if _conf['Quality'] >= 2:
            yield self.user.open_server_mgr.update_open_server_activity_quest(
                OPEN_SERVER_QUEST_ID_9, 1)
            yield self.user.achievement_mgr.update_achievement_status(
                ACHIEVEMENT_QUEST_ID_9, 1)
        if not res_err and add_items:
            defer.returnValue((add_items[0][0], add_items[0][2]))

        defer.returnValue(res_err)
Beispiel #48
0
    def treasure_decomposition(self, user_treasure_ids):
        ''' 
        @summary: 宝物炼化 相同类型
            (1) 已穿戴 或 精炼属性大于0的不可炼化, 需要先重生, 经验马 经验书不能也炼化
            (2) 炼化产出道具, 读sysconfig['item_decomposition'], 返还道具
            (3) 返还宝物强化消耗的经验, 并将其折算成经验马或经验书, 返还金币
            (4) 删除用于炼化的材料, 即宝物
        '''
        for _utid in user_treasure_ids:
            treasure = yield self.user.bag_treasure_mgr.get( _utid )
            if not treasure:
                log.error('Can not find user treasure. user_treasure_id: {0}.'.format( _utid ))
                defer.returnValue( UNKNOWN_TREASURE_ERROR )
            # 所选宝物 类型必须为书或马
            if treasure.item_type not in BAG_TREASURE:
                log.error('Selected treasure type not horse or bookwar.')
                defer.returnValue( UNKNOWN_TREASURE_ERROR )
            # 经验马、经验书不能炼化
            if treasure.item_id == EXP_HORSE_ID or treasure.item_id == EXP_BOOKWAR_ID:
                log.error('EXP_HORSE or EXP_BOOKWAR could not be decomposition. item id: {0}.'.format( treasure.item_id ))
                defer.returnValue( TREASURE_DECOMPOSITION_ERROR )

            # 已穿戴 或 精炼属性大于0的不可炼化, 需要先重生
            if treasure.camp_id > 0 or treasure.refine_level > 0:
                log.error('Treasure refine level error. ufid: {0}, refine level: {1}.'.format( _utid, treasure.refine_level ))
                defer.returnValue( TREASURE_DECOMPOSITION_ERROR )

            # 宝物的conf
            treasure_conf = get_item_by_itemid( treasure.item_id )
            if not treasure_conf:
                log.error('Can not find conf. item id: {0}.'.format( treasure.item_id ))
                defer.returnValue( UNKNOWN_ITEM_ERROR )

        total_golds, horse_exp, bookwar_exp = 0, 0, 0
        items_return = []
        for _utid in user_treasure_ids:
            treasure  = yield self.user.bag_treasure_mgr.get( _utid )
            extra_exp = treasure.exp
            treasure_conf = get_item_by_itemid( treasure.item_id )
            # 宝物自身经验
            for _attr in treasure_conf['attributes']:
                if _attr['AttributeID'] in (ATTRIBUTE_TYPE_HORSE_EXP, ATTRIBUTE_TYPE_BOOKWAR_EXP):
                    extra_exp += _attr['Value']
                    break

            # 炼化产出的道具
            decomposition_conf = get_item_decomposition( treasure.item_type, treasure_conf['QualityLevel'] )
            for _dec in decomposition_conf:
                items_list = split_items( _dec['ItemList'] )
                #log.info('For Test. _utid: {0}, items_list: {1}.'.format( _utid, items_list ))
                for _type, _id, _num in items_list:
                    # 货币类型特殊处理
                    if _type == ITEM_TYPE_MONEY:
                        if _id == ITEM_MONEY_GOLDS:
                            total_golds += _num
                        continue
                    model = ITEM_MODELs.get( _type, None )
                    if not model:
                        log.error('Unknown decomposition item type. item type: {0}.'.format( _type ))
                        continue
                    res_err, res_value = model(self.user, ItemID=_id, ItemNum=_num, AddType=WAY_TREASURE_DECOMPOSITION, CapacityFlag=False)
                    if not res_err:
                        for _v in res_value:
                            items_return = total_new_items(_v, items_return)

            # 返还宝物强化消耗的经验, 并折算成经验马或经验书
            for _level in range(1, treasure.level + 1):
                _conf = get_treasure_exp_conf( _level )
                extra_exp += _conf.get( ITEM_STRENGTHEN_COST[treasure_conf['Quality']], 0 )
            if treasure.item_type == ITEM_TYPE_HORSE:
                horse_exp += extra_exp
            else:
                bookwar_exp += extra_exp

            # 删除用于炼化的treasure
            self.user.bag_treasure_mgr.delete_table_data( _utid )
            # add syslog
            syslogger(LOG_ITEM_LOSE, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, _utid, treasure.item_id, 1, WAY_TREASURE_DECOMPOSITION)

        # 返还金币
        total_golds += (horse_exp + bookwar_exp) * TREASURE_STRENGTHEN_EXP_TO_GOLDS
        #self.user.base_att.golds += total_golds
        self.user.get_golds( total_golds, WAY_TREASURE_REFINE )
        # 用经验值兑换经验马或经验书
        if horse_exp > 0:
            res_err, res_value = yield self.user.bag_treasure_mgr.add_exp_treasure( ITEM_TYPE_HORSE, horse_exp )
            if not res_err:
                for _v in res_value:
                    items_return = total_new_items(_v, items_return)
        if bookwar_exp > 0:
            res_err, res_value = yield self.user.bag_treasure_mgr.add_exp_treasure( ITEM_TYPE_BOOKWAR, bookwar_exp )
            if not res_err:
                for _v in res_value:
                    items_return = total_new_items(_v, items_return)
        if total_golds > 0:
            items_return.append( [0, ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, total_golds] )

        defer.returnValue( items_return )
    def equip_decomposition(self, user_equip_ids):
        ''' 
        @summary: 装备炼化 
            (1) 已穿戴 或 洗炼属性大于0的不可炼化, 需要先重生
            (2) 炼化产出道具, 读sysconfig['item_decomposition'], 返还道具
            (3) 返还强化消耗的金币
            (4) 删除用于炼化的材料, 即装备
        '''
        for _ueid in user_equip_ids:
            equip = yield self.user.bag_equip_mgr.get(_ueid)
            if not equip:
                log.error(
                    'Can not find user equip. user_equip_id: {0}.'.format(
                        _ueid))
                defer.returnValue(UNKNOWN_EQUIP_ERROR)

            # 已穿戴 或 洗炼属性大于0的不可炼化, 需要先重生
            if (equip.camp_id > 0):
                log.error(
                    'Equip refine level error. ueid: {0}, camp_id: {1}, refine_attr: {2}.'
                    .format(_ueid, equip.camp_id,
                            loads(equip.refine_attribute)))
                defer.returnValue(EQUIP_DECOMPOSITION_ERROR)

            for _attr in loads(equip.refine_attribute):
                if _attr[1] > 0:
                    defer.returnValue(EQUIP_DECOMPOSITION_ERROR)

            # 装备的conf
            equip_conf = get_item_by_itemid(equip.item_id)
            if not equip_conf:
                log.error('Can not find conf. item id: {0}.'.format(
                    equip.item_id))
                defer.returnValue(UNKNOWN_ITEM_ERROR)

        items_return = []
        total_golds = 0
        for _ueid in user_equip_ids:
            equip = yield self.user.bag_equip_mgr.get(_ueid)
            equip_conf = get_item_by_itemid(equip.item_id)
            # 返还强化消耗的金币
            total_golds += equip.strengthen_cost

            # 炼化产出的道具
            decomposition_conf = get_item_decomposition(
                equip.item_type, equip_conf['QualityLevel'])
            for _dec in decomposition_conf:
                items_list = split_items(_dec['ItemList'])
                for _type, _id, _num in items_list:
                    # character attribute需要单独处理
                    if _type == ITEM_TYPE_MONEY:
                        if _id == ITEM_MONEY_GOLDS:
                            total_golds += _num
                        continue
                    model = ITEM_MODELs.get(_type, None)
                    if not model:
                        log.error(
                            'Unknown decomposition item type. item type: {0}.'.
                            format(_type))
                        continue
                    res_err, res_value = yield model(
                        self.user,
                        ItemID=_id,
                        ItemNum=_num,
                        AddType=WAY_EQUIP_DECOMPOSITION,
                        CapacityFlag=False)
                    if not res_err:
                        for _v in res_value:
                            items_return = total_new_items(_v, items_return)
            # 删除用于炼化的equip
            self.user.bag_equip_mgr.delete_table_data(_ueid)
            # add syslog
            syslogger(LOG_ITEM_LOSE, self.cid, self.user.level,
                      self.user.vip_level, self.user.alliance_id, _ueid,
                      equip.item_id, 1, WAY_EQUIP_DECOMPOSITION)

        # 返还金币
        if total_golds > 0:
            #self.user.base_att.golds += total_golds
            self.user.get_golds(total_golds, WAY_EQUIP_REFINE)
            items_return.append(
                [0, ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, total_golds])

        defer.returnValue(items_return)
Beispiel #50
0
    def random_new_jade(self, random_times):
        ''' 获取新的玉魄 '''
        # 检查等级限制条件
        if random_times == JADE_RANDOM_TIMES_TEN:
            if (self.user.level < JADE_RANDOM_TEN_LEVEL) and (
                    self.user.vip_level < JADE_RANDOM_TEN_VIP_LEVEL):
                defer.returnValue(JADE_RANDOM_TEN_ERROR)

        # 鉴玉
        new_jades, new_items = [], []
        msg_item_ids = []  # 需要走马灯通告的道具信息

        _curr_random_level = self.random_jade_level
        _golds_cost, _credits_cost, _left_golds, _left_credits = 0, 0, self.user.golds, self.user.credits

        for _idx in range(0, random_times):
            cost_conf = get_jade_cost_conf(_curr_random_level)
            # 检查消耗数量限制
            if not cost_conf:
                defer.returnValue(NOT_FOUND_CONF)
            if ITEM_TYPE_MONEY != cost_conf['CostItemType']:
                defer.returnValue(UNKNOWN_ITEM_ERROR)
            if ITEM_MONEY_GOLDS == cost_conf['CostItemID']:
                if _left_golds < cost_conf['CostItemNum']:
                    defer.returnValue(CHAR_GOLD_NOT_ENOUGH)
                _left_golds -= cost_conf['CostItemNum']
                _golds_cost += cost_conf['CostItemNum']
            elif ITEM_MONEY_CREDITS == cost_conf['CostItemID']:
                if _left_credits < cost_conf['CostItemNum']:
                    defer.returnValue(CHAR_CREDIT_NOT_ENOUGH)
                _left_credits -= cost_conf['CostItemNum']
                _credits_cost += cost_conf['CostItemNum']
            else:
                defer.returnValue(UNKNOWN_ITEM_ERROR)

            _chest_id = JADE_RANDOM_POOLS[_curr_random_level]
            _item_rand = yield package_open(self.user, _chest_id)
            if not _item_rand:
                defer.returnValue(NOT_FOUND_CONF)

            new_jades.append(_item_rand[:3])
            if _item_rand[3]:
                msg_item_ids.append(_item_rand[:3])

            # 鉴玉等级会有一定几率提示、不变、回到初始等级, 并有一定概率获得额外的道具
            _next_level, _extra_item = self.random_next_level(
                _curr_random_level)
            if _next_level != _curr_random_level:
                _curr_random_level = _next_level
                yield redis.hset(HASH_RANDOM_JADE_LEVEL, self.cid, _next_level)
            if _extra_item:
                new_items.append(_extra_item)
        # 扣金币或钻石
        if _golds_cost:
            self.user.consume_golds(_golds_cost, WAY_JADE_RANDOM)
        if _credits_cost:
            yield self.user.consume_credits(_credits_cost, WAY_JADE_RANDOM)
        # 更新最新等级
        self.random_jade_level = _curr_random_level

        #log.info('For Test. _golds_cost: {0}, _credits_cost: {1}, new_jades: {2}, new_items: {3}.'.format( _golds_cost, _credits_cost, new_jades, new_items ))
        add_jades, add_items = [], []
        q = 0
        for _type, _id, _num in new_jades:
            _model = ITEM_MODELs.get(_type, None)
            if not _model:
                log.error('Unknown item type. cid: {0}, ItemType: {1}.'.format(
                    self.cid, _type))
                continue
            res_err, value = yield _model(self.user,
                                          ItemID=_id,
                                          ItemNum=_num,
                                          CapacityFlag=False,
                                          AddType=WAY_JADE_RANDOM)
            _quality = get_item_by_itemid(_id).get('Quality', 0)
            if _quality >= 2:
                #品质大于2,开服狂欢
                q += 1
            if not res_err and value:
                add_jades.extend(value)
            else:
                log.warn(
                    'User add items error. cid: {0}, res_err: {1}, value: {2}.'
                    .format(self.cid, res_err, value))
        # 开服狂欢
        yield self.user.open_server_mgr.update_open_server_activity_quest(
            OPEN_SERVER_QUEST_ID_16, q)
        yield self.user.achievement_mgr.update_achievement_status(
            ACHIEVEMENT_QUEST_ID_16, q)
        # 新增额外掉落的道具
        for _type, _id, _num in new_items:
            _model = ITEM_MODELs.get(_type, None)
            if not _model:
                log.error('Unknown item type. cid: {0}, ItemType: {1}.'.format(
                    self.cid, _type))
                continue
            res_err, value = yield _model(self.user,
                                          ItemID=_id,
                                          ItemNum=_num,
                                          CapacityFlag=False,
                                          AddType=WAY_JADE_RANDOM)
            if not res_err and value:
                add_items.extend(value)
            else:
                log.warn(
                    'User add items error. cid: {0}, res_err: {1}, value: {2}.'
                    .format(self.cid, res_err, value))
        if msg_item_ids:
            message = [
                RORATE_MESSAGE_ACHIEVE,
                [
                    ACHIEVE_TYPE_RARE_ITEM,
                    [self.user.nick_name, _chest_id, msg_item_ids]
                ]
            ]
            gw_broadcast('sync_broadcast', [message])

        defer.returnValue((self.user.golds, self.user.credits,
                           _curr_random_level, add_jades, add_items))
Beispiel #51
0
    def users_got_shards(shard_id, user_level, user_cid):
        '''
        @param: user_cid-玩家的cid
        @param: user_level-玩家的等级
        '''
        _users = []

        _hour = datetime.now().hour

        # 碎片对应的宝物配置
        treasure_id = 0
        item_conf   = get_item_by_itemid( shard_id )
        if item_conf:
            _, treasure_id, _ = item_conf['ChangeList'][0]
        plunder_cids = AvoidWarMgr.In_Plunders.get(treasure_id, [])

        robots_added = 0
        if _hour >= AVOID_USER_TIME_SPLIT and user_level > AVOID_WAR_LEVEL:
            _all = yield redis.hvals( TPL_TREASURE_SHARD_GOT % shard_id )
            _tmp_users = []

            for _iter in _all:
                _cid, _level, _name = loads( _iter )
                # 自己不能加入被抢夺列表
                if _cid == user_cid:
                    continue
                # 随机的玩家范围, 根据主角等级, 加减10级的范围内随机
                if abs(user_level - _level) <= 10:
                    # 免战后的玩家不会出现在任何人的夺宝列表中
                    _remain = yield AvoidWarMgr.remain_avoid_war_time( _cid )
                    if _remain > 0:
                        log.info('User in avoid war time. shard_id: {0}, treasure_id: {1}, cid: {2}.'.format( shard_id, treasure_id, _cid ))
                        continue
                    # 出现在其它人列表中的玩家过滤掉
                    if _cid in plunder_cids:
                        log.info('User in plundered. shard_id: {0}, treasure_id: {1}, cid: {2}.'.format( shard_id, treasure_id, _cid ))
                        continue
                    _tmp_users.append( [_cid, _level, _name, tuple()] )

            #从满足条件的玩家中随机出10个玩家的下标
            _len = len(_tmp_users)
            if _len > MAX_USERS_FOR_AVOID:
                _indexs = range(_len)
                random.shuffle( _indexs )

                for _idx in _indexs[:MAX_USERS_FOR_AVOID]: #随机后的前10个
                    major_level, _tmp_users[_idx][3], _ = yield load_offline_user_info(_tmp_users[_idx][0])
                    # 保存阵容失败的玩家
                    if _tmp_users[_idx][3]:
                        _tmp_users[_idx][1] = major_level if major_level else _tmp_users[_idx][1]
                        _users.append( _tmp_users[_idx] )
                    else:
                        log.warn('Error char camp data. data: {0}.'.format( _tmp_users[_idx] ))
                        yield redis.hdel( TPL_TREASURE_SHARD_GOT % shard_id, _tmp_users[_idx][0] )
            else:
                for _t in _tmp_users:
                    major_level, _t[3], _ = yield load_offline_user_info(_t[0])
                    # 保存阵容失败的玩家
                    if _t[3]:
                        _t[1] = major_level if major_level else _t[1]
                        _users.append( _t )
                    else:
                        log.warn('Error char camp data. data: {0}.'.format( _t ))
                        yield redis.hdel( TPL_TREASURE_SHARD_GOT % shard_id, _t[0] )

            robots_added = len(_users)

        log.info('Have user: {0}, user_ids: {1}.'.format( robots_added, [_u[0] for _u in _users] ))
        _len_robots  = len( AvoidWarMgr.Robots )
        _start_robot = 0
        if user_level <= 20:
            _start_robot = 3001
        elif user_level <= 30:
            _start_robot = 1001
        elif user_level <= 50:
            _start_robot = 101

        if _start_robot >= _len_robots:
            _start_robot = 0

        while 1:
            if not AvoidWarMgr.Robots or robots_added >= _len_robots: break
            if len( _users ) >= MAX_MEMBER_FOR_AVOID or robots_added >= MAX_MEMBER_FOR_AVOID: break

            robots_added += 1
            _key = AvoidWarMgr.Robots[ random.randint(_start_robot, _len_robots-1) ]
            _robot = get_robot_conf( _key )
            if _robot:
                _camp = map( int, _robot['RobotList'].split(',') )
                _users.append( ( 0, user_level, _robot['RobotName'], _camp ) )
            else:
                log.warn( "[ AvoidWarMgr.users_got_shards ]:No such robot in db. key:", _key, 'and type:', type(_key) )

        defer.returnValue( _users )
Beispiel #52
0
    def treasure_reborn(self, user_treasure_id):
        '''
        @summary: 宝物重生 
            (1) 已穿戴 或 未精炼的宝物 不能重生
            (2) 返还该宝物精炼消耗的道具和强化消耗的经验道具, 强化消耗的道具返还为经验宝物 
            (3) 精炼消耗的金币不返还 
        '''
        treasure = yield self.user.bag_treasure_mgr.get( user_treasure_id )
        if not treasure:
            log.error('Can not find user treasure.')
            defer.returnValue( UNKNOWN_TREASURE_ERROR )
        # 已穿戴 或 未精炼的宝物不可重生
        if treasure.camp_id > 0 or treasure.refine_level <= 0:
            log.error('Treasure reborn error. camp_id: {0}, refine level: {1}.'.format( treasure.camp_id, treasure.refine_level ))
            defer.returnValue( TREASURE_REBORN_ERROR )

        # 宝物的conf
        treasure_conf = get_item_by_itemid( treasure.item_id )
        if not treasure_conf:
            log.error('Can not find conf. item id: {0}.'.format( treasure.item_id ))
            defer.returnValue( UNKNOWN_ITEM_ERROR )
        total_exp = treasure.exp

        # 扣钻石
        reborn_conf = get_treasure_reborn_conf( treasure_conf['QualityLevel'], treasure.refine_level )
        if reborn_conf:
            yield self.user.consume_credits( reborn_conf['Cost'], WAY_TREASURE_REBORN )

        # 返还宝物强化消耗的经验
        for _level in range( 1, treasure.level + 1):
            _conf = get_treasure_exp_conf( _level )
            _exp  = _conf.get( ITEM_STRENGTHEN_COST[treasure_conf['Quality']], 0 )
            if not _exp:
                continue
            total_exp += _exp
 
        # 用经验值兑换经验马或经验书, 增加1点经验, 需要消耗5个金币
        total_golds = total_exp * TREASURE_STRENGTHEN_EXP_TO_GOLDS
        self.user.get_golds( total_golds, WAY_TREASURE_REBORN )

        items_return = []
        _err, _value = yield self.user.bag_treasure_mgr.add_exp_treasure( treasure.item_type, total_exp )
        if not _err:
            items_return = _value

        # 返还精炼消耗的道具
        items_list = [] # 消耗的道具列表
        for _refine_level in range(1, treasure.refine_level + 1):
            refine_conf = get_treasure_refine_conf(treasure.item_id, _refine_level)
            if not refine_conf:
                log.error('Can not find refine conf. item_id: {0}, refine_level: {1}.'.format( treasure.item_id, _refine_level ))
                continue
            _list = split_items( refine_conf['CostItemList'] )
            for _l in _list:
                items_list = add_new_items( _l, items_list )
        #log.info('For Test. refine_level: {0}, items_list: {1}.'.format( treasure.refine_level, items_list ))

        # 道具类型格式:道具ID:道具数量
        for _type, _id, _num in items_list:
            # 货币类型特殊处理
            if _type == ITEM_TYPE_MONEY:
                continue
            model = ITEM_MODELs.get( _type, None )
            if not model:
                log.error('Unknown reborn item type. item type: {0}.'.format( _type ))
                continue
            res_err, res_value = yield model(self.user, ItemID=_id, ItemNum=_num, AddType=WAY_TREASURE_REBORN, CapacityFlag=False)
            if not res_err:
                for _v in res_value:
                    items_return = total_new_items(_v, items_return)

        # 强化、精炼属性清零
        treasure.level, treasure.exp, treasure.refine_level = 0, 0, 0
        if total_golds > 0:
            items_return.append( [0, ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, total_golds] )
 
        defer.returnValue( (self.user.base_att.credits, items_return) )
Beispiel #53
0
    def item_use(self, item_id, item_num):
        '''
        @summary: 背包中使用道具
        '''
        res_err = UNKNOWN_ITEM_ERROR
        # 按照类型使用道具
        item_conf = get_item_by_itemid(item_id)
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format(item_id))
            defer.returnValue(res_err)
        if not item_conf['IsUsed'] or (item_conf['ItemType'] not in BAG_ITEM):
            log.error('Can not use item. item_id: {0}, item_conf: {1}.'.format(
                item_id, item_conf))
            defer.returnValue(ITEM_USER_ERROR)

        add_type = WAY_ITEM_USE
        items_return = []  # 剩余的玩家道具信息
        add_items = []  # 新增的玩家道具信息
        items_list = item_conf['ChangeList']
        if item_conf['ItemType'] in (ITEM_TYPE_CHEST, ITEM_TYPE_KEY):
            add_type = WAY_USE_CHEST
            # 使用宝箱
            if item_conf['ItemType'] == ITEM_TYPE_CHEST:
                if not items_list:  # 不需要使用钥匙
                    chest_item_id = item_id
                    res_err, used_attribs = yield self.use(
                        chest_item_id, item_num)
                else:  # 需要钥匙
                    if len(items_list) != 1:
                        log.error('Unknown chest item. item_conf: {0}.'.format(
                            item_conf))
                        defer.returnValue(res_err)
                    chest_item_id, key_item_id = item_id, items_list[0][1]
                    res_err, used_attribs = yield self.chest_use(
                        chest_item_id, key_item_id, item_num, item_num)
            # 使用钥匙
            else:
                if len(items_list) != 1:
                    log.error(
                        'Unknown key item. item_conf: {0}.'.format(item_conf))
                    defer.returnValue(res_err)
                chest_item_id, key_item_id = items_list[0][1], item_id
                res_err, used_attribs = yield self.chest_use(
                    chest_item_id, key_item_id, item_num, item_num)

            if res_err:
                log.error('Use item error.')
                defer.returnValue(res_err)
            # 根据chest_item_id随机道具
            new_items = yield self.random_chest(chest_item_id, item_num)
        else:
            if not items_list:
                log.error(
                    'Can not use item. item_id: {0}, item_conf: {1}.'.format(
                        item_id, item_conf))
                defer.returnValue(ITEM_USER_ERROR)

            res_err, used_attribs = yield self.use(item_id, item_num)
            if res_err:
                log.error('Use item error.')
                defer.returnValue(res_err)
            # 获取的新道具信息
            new_items = []
            for _type, _id, _num in items_list:
                new_items.append([_type, _id, _num * item_num])

        for _a in used_attribs:
            items_return = total_new_items(
                [_a.attrib_id, _a.item_type, _a.item_id, _a.item_num],
                items_return)

        for _type, _id, _num in new_items:
            _model = ITEM_MODELs.get(_type, None)
            if not _model:
                log.error('Unknown item type. ItemType: {0}.'.format(_type))
                continue
            res_err, value = yield _model(self.user,
                                          ItemID=_id,
                                          ItemNum=_num,
                                          CapacityFlag=False,
                                          AddType=add_type,
                                          WayOthers=str((item_id, item_num)))
            if not res_err and value:
                add_items.extend(value)
            else:
                log.warn(
                    'User add items error. res_err: {0}, value: {1}.'.format(
                        res_err, value))
        #res_data = yield batch_items_add(self.user, new_items, add_type, str((item_id, item_num)))
        #for _status, (res_err, value) in res_data:
        #    if not res_err and value:
        #        add_items.extend( value )
        #    else:
        #        log.warn('User add items error. res_err: {0}, value: {1}.'.format( res_err, value ))

        # add syslog
        syslogger(LOG_ITEM_LOSE, self.cid, self.user.level,
                  self.user.vip_level, self.user.alliance_id, 0, item_id,
                  item_num, add_type)
        defer.returnValue((items_return, add_items))
Beispiel #54
0
    def gift_goodwill(self, fellow_id, use_items):
        gsattrib = yield self.get_fellow(fellow_id)
        if not gsattrib:
            defer.returnValue(UNKNOWN_FELLOW_ERROR)

        level_conf = get_goodwill_level_conf(gsattrib.goodwill_level + 1)
        if not level_conf:
            defer.returnValue(GOODWILL_LEVEL_MAX_ERROR)

        get_goodwill, crit_count, levelup_count = 0, 0, 0
        items_return = []
        cur_goodwill_exp = gsattrib.goodwill_exp
        cur_goodwill_level = gsattrib.goodwill_level
        del_items = {}

        all_item_ids = []
        for item_id, item_num in use_items:
            all_item_ids.extend([item_id] * item_num)

        for item_id in all_item_ids:
            add_goodwill = 0
            item_conf = get_item_by_itemid(item_id)
            if not item_conf:
                continue
            for _attr in item_conf['attributes']:
                if _attr['AttributeID'] != ATTRIBUTE_TYPE_GOODWILL:
                    continue
                add_goodwill = _attr['Value']
            if add_goodwill == 0:
                continue
            del_items[item_id] = del_items.setdefault(item_id, 0) + 1
            # 计算好感度经验值
            get_goodwill += add_goodwill
            cur_goodwill_exp += add_goodwill
            if cur_goodwill_exp >= level_conf['PurpleExp']:
                cur_goodwill_exp, cur_goodwill_level, levelup_count = self.cal_level_up(
                    cur_goodwill_exp, cur_goodwill_level, levelup_count)
                # 好感度升级conf
                level_conf = get_goodwill_level_conf(cur_goodwill_level + 1)
                if not level_conf:
                    break
            else:
                need_goodwill_exp = level_conf['PurpleExp'] - cur_goodwill_exp
                crit_ratio = level_conf[
                    'PurpleCrit'] + add_goodwill / need_goodwill_exp * 0.5
                rand_int = random.randint(1, 10000)
                if rand_int <= crit_ratio:
                    crit_count += 1
                    cur_goodwill_exp = 0
                    cur_goodwill_level += 1
                    levelup_count += 1
                    # 好感度升级conf
                    level_conf = get_goodwill_level_conf(cur_goodwill_level +
                                                         1)
                    if not level_conf:
                        break
        #log.info('For Test. del_items: {0}.'.format( del_items ))
        # 使用道具
        for _id, _num in del_items.items():
            res_err, used_attribs = yield self.user.bag_item_mgr.use(_id, _num)
            if res_err:
                continue
            for _a in used_attribs:
                items_return = total_new_items(
                    [_a.attrib_id, _a.item_type, _a.item_id, _a.item_num],
                    items_return)

        #log.info('For Test. cur_goodwill_exp: {0}, cur_goodwill_level: {1}, get_goodwill: {2}, crit_count: {3}, levelup_count: {4}.'.format( cur_goodwill_exp, cur_goodwill_level, get_goodwill, crit_count, levelup_count ))
        if cur_goodwill_exp != gsattrib.goodwill_exp:
            gsattrib.goodwill_exp = cur_goodwill_exp

        last_total_level = self.total_goodwill_level
        if cur_goodwill_level > gsattrib.goodwill_level:
            gsattrib.goodwill_level = cur_goodwill_level
            self.total_goodwill_level += levelup_count
            add_douzhan = yield self.check_achieve(last_total_level)
            if add_douzhan > 0:
                yield self.update_friend_gift_douzhan(add_douzhan)
        # 更新last_fellow_id
        gsattrib.last_gift = 1
        if self.last_fellow_id:
            last_gsattrib = yield self.get_fellow(self.last_fellow_id)
            if last_gsattrib:
                last_gsattrib.last_gift = 0

        self.last_fellow_id = fellow_id

        yield self.user.daily_quest_mgr.update_daily_quest(
            DAILY_QUEST_ID_13, 1)
        yield self.user.achievement_mgr.update_achievement_status(
            23, self.total_goodwill_level)
        defer.returnValue(
            (self.total_goodwill_level, cur_goodwill_exp, cur_goodwill_level,
             get_goodwill, crit_count, levelup_count, items_return))
Beispiel #55
0
    def item_use(self, item_id, item_num):
        '''
        @summary: 背包中使用道具
        '''
        res_err = UNKNOWN_ITEM_ERROR
        # 按照类型使用道具
        item_conf = get_item_by_itemid( item_id )
        if not item_conf:
            log.error('Can not find conf. item_id: {0}.'.format( item_id ))
            defer.returnValue( res_err )
        if not item_conf['IsUsed'] or (item_conf['ItemType'] not in BAG_ITEM):
            log.error('Can not use item. item_id: {0}, item_conf: {1}.'.format( item_id, item_conf ))
            defer.returnValue( ITEM_USER_ERROR )
 
        add_type = WAY_ITEM_USE
        items_return = [] # 剩余的玩家道具信息
        add_items    = [] # 新增的玩家道具信息
        items_list = item_conf['ChangeList']
        if item_conf['ItemType'] in (ITEM_TYPE_CHEST, ITEM_TYPE_KEY):
            add_type = WAY_USE_CHEST
            # 使用宝箱
            if item_conf['ItemType'] == ITEM_TYPE_CHEST: 
                if not items_list: # 不需要使用钥匙
                    chest_item_id = item_id
                    res_err, used_attribs = yield self.use(chest_item_id, item_num)
                else: # 需要钥匙
                    if len(items_list) != 1:
                        log.error('Unknown chest item. item_conf: {0}.'.format( item_conf ))
                        defer.returnValue( res_err )
                    chest_item_id, key_item_id = item_id, items_list[0][1]
                    res_err, used_attribs = yield self.chest_use(chest_item_id, key_item_id, item_num, item_num)
            # 使用钥匙
            else:
                if len(items_list) != 1:
                    log.error('Unknown key item. item_conf: {0}.'.format( item_conf ))
                    defer.returnValue( res_err )
                chest_item_id, key_item_id = items_list[0][1], item_id
                res_err, used_attribs = yield self.chest_use(chest_item_id, key_item_id, item_num, item_num)

            if res_err:
                log.error('Use item error.')
                defer.returnValue( res_err )
            # 根据chest_item_id随机道具
            new_items = yield self.random_chest( chest_item_id, item_num )
        else:
            if not items_list:
                log.error('Can not use item. item_id: {0}, item_conf: {1}.'.format( item_id, item_conf ))
                defer.returnValue( ITEM_USER_ERROR )

            res_err, used_attribs = yield self.use(item_id, item_num)
            if res_err:
                log.error('Use item error.')
                defer.returnValue( res_err )
            # 获取的新道具信息
            new_items = []
            for _type, _id, _num in items_list:
                new_items.append( [_type, _id, _num * item_num] )

        for _a in used_attribs:
            items_return = total_new_items( [_a.attrib_id, _a.item_type, _a.item_id, _a.item_num], items_return )

        for _type, _id, _num in new_items:
            _model = ITEM_MODELs.get(_type, None)
            if not _model:
                log.error('Unknown item type. ItemType: {0}.'.format( _type ))
                continue
            res_err, value = yield _model(self.user, ItemID=_id, ItemNum=_num, CapacityFlag=False, AddType=add_type, WayOthers=str((item_id, item_num)))
            if not res_err and value:
                add_items.extend( value )
            else:
                log.warn('User add items error. res_err: {0}, value: {1}.'.format( res_err, value ))
        #res_data = yield batch_items_add(self.user, new_items, add_type, str((item_id, item_num)))
        #for _status, (res_err, value) in res_data:
        #    if not res_err and value:
        #        add_items.extend( value )
        #    else:
        #        log.warn('User add items error. res_err: {0}, value: {1}.'.format( res_err, value ))

        # add syslog
        syslogger(LOG_ITEM_LOSE, self.cid, self.user.level, self.user.vip_level, self.user.alliance_id, 0, item_id, item_num, add_type)
        defer.returnValue( (items_return, add_items) )
    def refine(self, user_treasure_id):
        '''
        @summary:  只有精炼等级为0, 强化等级为0的宝物才可作消耗材料
              只有品级(QualityLevel)大于7的才可以精炼
        '''
        res_err = UNKNOWN_TREASURE_ERROR

        attrib = yield self.get(user_treasure_id)
        if not attrib:
            log.error(
                'Can not find user treasure. user_treasure_id: {0}.'.format(
                    user_treasure_id))
            defer.returnValue(res_err)

        refine_conf = get_treasure_refine_conf(attrib.item_id,
                                               attrib.refine_level + 1)
        if not refine_conf:
            log.error(
                'Can not find refine conf. item_id: {0}, refine level: {1}.'.
                format(attrib.item_id, attrib.refine_level + 1))
            defer.returnValue(NOT_FOUND_CONF)
        # 道具配置 自身品级不满足
        item_conf = get_item_by_itemid(attrib.item_id)
        if (not item_conf) or (item_conf['QualityLevel'] <=
                               TREASURE_REFINE_QUALITYLEVEL_MAX):
            log.error(
                'Can not refine treasure. No conf or quality_level limit. item_id: {0}.'
                .format(attrib.item_id))
            defer.returnValue(CLIENT_DATA_ERROR)

        # 金币不足
        if refine_conf['CostGold'] > self.user.base_att.golds:
            log.error(
                'user golds not enough. need_golds: {0}, cur_golds: {1}.'.
                format(refine_conf['CostGold'], self.user.base_att.golds))
            defer.returnValue(CHAR_GOLD_NOT_ENOUGH)

        # 消耗道具不足, 道具类型格式:道具ID:道具数量
        items_list = split_items(refine_conf['CostItemList'])
        cost_attribs = []  # 要消耗的宝物
        for _type, _id, _num in items_list:
            if _type in BAG_TREASURE:
                all_attribs = yield self.get_item_to_refine(
                    user_treasure_id, _id)
                if len(all_attribs) < _num:
                    log.error(
                        'user item not enough. item_id: {2}, cur_item_num: {0}, need_item_num: {1}.'
                        .format(len(all_attribs), _num, _id))
                    defer.returnValue(CHAR_ITEM_NOT_ENOUGH)
                cost_attribs.extend(all_attribs[:_num])
            elif _type == ITEM_TYPE_ITEM:
                total_num, item_attribs = yield self.user.bag_item_mgr.get_items(
                    _id)
                if total_num < _num:
                    log.error(
                        'user item not enough. cid:{0}, item_id:{1}, need:{2}, curr:{3}.'
                        .format(self.cid, _id, _num, total_num))
                    defer.returnValue(CHAR_ITEM_NOT_ENOUGH)
            else:
                log.error("Unknown item type. cost item: {0}.".format(
                    refine_conf['CostItemList']))
                defer.returnValue(UNKNOWN_ITEM_ERROR)
        # 扣宝物
        items_return = []
        for _attrib in cost_attribs:
            self.delete_table_data(_attrib.attrib_id)
            items_return.append(_attrib.attrib_id)
        # 扣道具
        left_items = []
        for _type, _id, _num in items_list:
            if _type != ITEM_TYPE_ITEM:
                continue
            res_err, used_attribs = yield self.user.bag_item_mgr.use(_id, _num)
            if res_err:
                log.error(
                    'Use item error. cid:{0}, _type:{1}, _id:{2}, _num:{3}.'.
                    format(self.cid, _type, _id, _num))
            # used_attribs-已使用的道具
            for _a in used_attribs:
                left_items.append(
                    [_a.attrib_id, _a.item_type, _a.item_id, _a.item_num])

        # 扣金币
        #self.user.base_att.golds -= refine_conf['CostGold']
        self.user.consume_golds(refine_conf['CostGold'], WAY_TREASURE_REFINE)
        attrib.refine_level += 1

        # add syslog
        way_others = str(tuple(items_return))
        syslogger(LOG_TREASURE_REFINE, self.cid, self.user.level,
                  self.user.vip_level, self.user.alliance_id, user_treasure_id,
                  attrib.item_id, attrib.refine_level - 1, attrib.refine_level,
                  way_others)

        # 同步camp到redis
        #if attrib.camp_id:
        #    yield self.user.sync_camp_to_redis(update=True)
        yield self.user.achievement_mgr.update_achievement_status(
            ACHIEVEMENT_QUEST_ID_33, attrib.refine_level)
        defer.returnValue(
            (user_treasure_id, attrib.item_id, attrib.refine_level,
             self.user.base_att.golds, items_return, left_items))