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
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]) )
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 )
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 )
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)
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
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)
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)
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]) )
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) )
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 ))
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 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)
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))
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)
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()
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) )
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)))
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))
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)
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)
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))
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 )
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) )
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 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))
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))