def get_touch_reward(self, location): self.opened_num += 1 rate = get_lover_kiss_conf(self.opened_num)['LuxuryRewardRate'] _rand = rand_num() if _rand <= rate and self.big_reward == 0: reward = self.rand_reward_by_type(LUXURY_TYPE) self.big_reward = 1 else: reward = self.rand_reward_by_type(NORMAL_TYPE) notice = reward[-1] if notice: message = [ACHIEVE_TYPE_LOVER_KISS, self.user.nick_name, reward[0]] gw_broadcast('sync_broadcast', [message]) _item = yield item_add(self.user, ItemType=reward[1], ItemID=reward[0], ItemNum=reward[2], AddType=WAY_LOVER_KISS) self.opened_list[location] = _item[1][0][2] self.synced = False self.sync() defer.returnValue([ _item[1], self.opened_list, self.normal_rose, self.blue_rose, BLUE_ROSE_MAX_NUM - self.extra_blue_rose ])
def get_randcard_frompool(self, shrine_level, rand_count): ''' 获取抽卡池 ''' pool_level = 0 if rand_count == 0: pool_level = shrine_level + 1 final_level = 0 all_shrine_levels = get_limit_fellow_pool_levels() for _level in all_shrine_levels: if _level <= pool_level and final_level < _level: final_level = _level total_rate = 0 pool = get_limit_fellow_pool_conf(final_level) for _conf in pool.itervalues(): total_rate += _conf['Rate'] if total_rate <= 0: log.warn('No randcard. final_level: {0}, total_rate: {1}.'.format( final_level, total_rate)) return {} curr_int = 0 randint = rand_num(total_rate) for _conf in pool.itervalues(): if randint < (curr_int + _conf['Rate']): #log.error('For Test. randint: {0}, curr_int: {1}, rate: {2}, total_rate: {3}.'.format( randint, curr_int, _conf['Rate'], total_rate )) return _conf else: curr_int += _conf['Rate'] else: log.warn( 'Not rand a card. final_level: {0}, randint: {1}, total_rate: {2}.' .format(final_level, randint, total_rate)) return {}
def randcard_frompool(self, pool): ''' @summary: 从抽卡池中抽卡 ''' _total_rate = 0 for _conf in pool.itervalues(): _total_rate += _conf['Rate'] if _total_rate <= 0: log.warn( 'There is no cardpool. _total_rate: {0}.'.format(_total_rate)) return (NOT_FOUND_CONF, {}) _curr_rate = 0 _randint = rand_num(_total_rate) for _conf in pool.itervalues(): if _randint < (_curr_rate + _conf['Rate']): #log.error('For Test. _randint: {0}, _curr_rate: {1}, _conf_rate: {2}.'.format( _randint, _curr_rate, _conf['Rate'] )) return (NO_ERROR, _conf) else: _curr_rate += _conf['Rate'] else: log.warn('There is no cardpool. _randint: {0}, _total_rate: {1}.'. format(_randint, _total_rate)) return (NOT_FOUND_CONF, {})
def get_randcard_frompool(self, shrine_level, rand_count): ''' 获取抽卡池 ''' pool_level = 0 if rand_count == 0: pool_level = shrine_level + 1 final_level = 0 all_shrine_levels = get_limit_fellow_pool_levels() for _level in all_shrine_levels: if _level <= pool_level and final_level < _level: final_level = _level total_rate = 0 pool = get_limit_fellow_pool_conf(final_level) for _conf in pool.itervalues(): total_rate += _conf['Rate'] if total_rate <= 0: log.warn('No randcard. final_level: {0}, total_rate: {1}.'.format( final_level, total_rate )) return {} curr_int = 0 randint = rand_num(total_rate) for _conf in pool.itervalues(): if randint < (curr_int + _conf['Rate']): #log.error('For Test. randint: {0}, curr_int: {1}, rate: {2}, total_rate: {3}.'.format( randint, curr_int, _conf['Rate'], total_rate )) return _conf else: curr_int += _conf['Rate'] else: log.warn('Not rand a card. final_level: {0}, randint: {1}, total_rate: {2}.'.format( final_level, randint, total_rate )) return {}
def boost(self, user, boost_type): #type: 1:gold, 2:credit _max_level = get_attack_extra_maxlevel() _next_level = 1 _conf = None if self.attack_extra_level >= _max_level: return WORLDBOSS_INSPIRE_MAX_LEVEL_REACHED if boost_type == 1: _field_rate = 'GoldRate' _field_add_rate = 'GoldAddRate' _field_cost = 'GoldCost' _failed_count = self._gold_inspire_failed_count _next_level = self._gold_inspire_success_count + 1 _conf = get_attack_extra_by_level(_next_level) elif boost_type == 2: _field_rate = 'CreditsRate' _field_add_rate = 'CreditsAddRate' _field_cost = 'CreditsCost' _failed_count = self._credit_inspire_failed_count _next_level = self._credit_inspire_success_count + 1 _conf = get_attack_extra_by_level(_next_level) else: log.error('no boost type:', boost_type, 'cid:', self._cid) return UNKNOWN_ERROR if _conf: _rate, _add_rate, _cost = _conf[_field_rate], _conf[_field_add_rate], _conf[_field_cost] if (boost_type == 1 and _cost > user.golds): return CHAR_GOLD_NOT_ENOUGH elif (boost_type == 2 and _cost > user.credits): return CHAR_CREDIT_NOT_ENOUGH _rand = rand_num() if _rand <= _rate + _add_rate * _failed_count: self._gold_inspire_failed_count = self._credit_inspire_failed_count = 0 #self._attack_extra_level = _next_level if boost_type == 1: self._gold_inspire_success_count = _next_level user.consume_golds(_cost, WAY_WORLDBOSS_BOOST) elif boost_type == 2: self._credit_inspire_success_count = _next_level user.consume_credits(_cost, WAY_WORLDBOSS_BOOST) else: if boost_type == 1: self._gold_inspire_failed_count += 1 elif boost_type == 2: self._credit_inspire_failed_count += 1 self.sync() return NO_ERROR else: log.error('no attack extra config for level:', _next_level, 'current level:', self.attack_extra_level, 'cid:', self._cid) return WORLDBOSS_NO_INSPIRE_CONFIG
def reward_to_char(self, cid, last_attacker_id, rank): reward_golds, reward_farm, last_kill_golds, last_kill_fame = 0, 0, 0, 0 _conf = get_worldboss_reward(rank) if _conf: #_golds_add, _farm_add = 0, 0 reward_golds = _conf['Gold'] reward_farm = _conf['Prestige'] #_golds_add += reward_golds #_farm_add += reward_farm _reward_items = [ (ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, reward_golds), (ITEM_TYPE_MONEY, ITEM_MONEY_PRESTIGE, reward_farm), ] _rand = rand_num() if _rand <= _conf['Rate']: _reward_items.extend(_conf['RandomItem']) g_AwardCenterMgr.new_award(cid, AWARD_TYPE_WORLDBOSS_RANK, [int(time()), _reward_items], True) if int(last_attacker_id) == int(cid): log.debug('[ reward_to_char ]: last_attacker_id:{0}, cid:{1}.'. format(last_attacker_id, cid)) _last_kill_conf = get_worldboss_reward(0) last_kill_golds = _last_kill_conf['Gold'] last_kill_fame = _last_kill_conf['Prestige'] _reward_items = [ (ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, last_kill_golds), (ITEM_TYPE_MONEY, ITEM_MONEY_PRESTIGE, last_kill_fame) ] _rand = rand_num() if _rand <= _last_kill_conf['Rate']: _reward_items.extend(_last_kill_conf['RandomItem']) g_AwardCenterMgr.new_award(cid, AWARD_TYPE_WORLDBOSS_LASTKILL, [int(time()), _reward_items], True) return reward_golds, reward_farm, last_kill_golds, last_kill_fame
def reward_to_char(self, cid, last_attacker_id, rank): reward_golds, reward_farm, last_kill_golds, last_kill_fame = 0, 0, 0, 0 _conf = get_worldboss_reward(rank) if _conf: #_golds_add, _farm_add = 0, 0 reward_golds = _conf['Gold'] reward_farm = _conf['Prestige'] #_golds_add += reward_golds #_farm_add += reward_farm _reward_items = [ (ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, reward_golds), (ITEM_TYPE_MONEY, ITEM_MONEY_PRESTIGE, reward_farm), ] _rand = rand_num() if _rand <= _conf['Rate']: _reward_items.extend(_conf['RandomItem']) g_AwardCenterMgr.new_award(cid, AWARD_TYPE_WORLDBOSS_RANK, [int(time()), _reward_items], True) if int(last_attacker_id) == int(cid): log.debug('[ reward_to_char ]: last_attacker_id:{0}, cid:{1}.'.format(last_attacker_id, cid)) _last_kill_conf = get_worldboss_reward(0) last_kill_golds = _last_kill_conf['Gold'] last_kill_fame = _last_kill_conf['Prestige'] _reward_items = [ (ITEM_TYPE_MONEY, ITEM_MONEY_GOLDS, last_kill_golds), (ITEM_TYPE_MONEY, ITEM_MONEY_PRESTIGE, last_kill_fame) ] _rand = rand_num() if _rand <= _last_kill_conf['Rate']: _reward_items.extend(_last_kill_conf['RandomItem']) g_AwardCenterMgr.new_award(cid, AWARD_TYPE_WORLDBOSS_LASTKILL, [int(time()), _reward_items], True) return reward_golds, reward_farm, last_kill_golds, last_kill_fame
def __rand_material(self, exchange_type, turn, add_cnt, except_material = None ): _all_turns = get_exchange_refresh_conf( exchange_type, turn ) _tmp_list_idx_and_rate = [] #暂存每个材料的index和计算出来的当前权重值 _material = None _rate_total = 0 #所有需要随机材料的总权重 _curr_rate = 0 _rand = 0 if _all_turns: _all_turn_cnt = yield redis.hmget( HASH_EXCHANGE_REFRESH_RATE, [ '{0}.{1}'.format( self.cid, _conf[0] ) for _conf in _all_turns ] ) _len_cnt = len( _all_turn_cnt ) for _idx, _turn_conf in enumerate( _all_turns ): if except_material == [ _turn_conf[3], _turn_conf[4], _turn_conf[5] ]: # 该材料不能参与随机,防止材料重复, DK-1663 continue _cnt = ( _all_turn_cnt[ _idx ] if _idx < _len_cnt else 0 ) or 0 _rate = _turn_conf[6] + ( ( _cnt * _turn_conf[7] ) if _cnt else 0 ) if _rate >= _turn_conf[8]: _rate = _turn_conf[8] _tmp_list_idx_and_rate.append( [ _idx, _rate, _cnt ] ) _rate_total += _rate _rand = rand_num( _rate_total ) for _c_idx, _c_rate, _c_cnt in _tmp_list_idx_and_rate: if _rand <= _curr_rate + _c_rate: #hitted _conf = _all_turns[ _c_idx ] #这里是material和target的数据结构了,找不到来这里找 if not _material: _material = [ _conf[3], _conf[4], _conf[5] ] if add_cnt: redis.hset( HASH_EXCHANGE_REFRESH_RATE, '{0}.{1}'.format( self.cid, _conf[0] ), 0 ) #命中后重置 else: if add_cnt: redis.hset( HASH_EXCHANGE_REFRESH_RATE, '{0}.{1}'.format( self.cid, _conf[0] ), _c_cnt + 1 ) #miss后累加 _curr_rate += _c_rate if not _material: log.warn( 'missing rand material. list_idx_and_rate as: {0}, exchange_type:{1}, turn:{2}, _all_turns:{3}, _curr_rate:{4}, _rate_total:{5}, _rand:{6}.'.format( _tmp_list_idx_and_rate, exchange_type, turn, _all_turns, _curr_rate, _rate_total, _rand ) ) #log.debug( 'list_idx_and_rate as: {0}, exchange_type:{1}, turn:{2}, _all_turns:{3}, _curr_rate:{4}, _rate_total:{5}, _rand:{6}, _material:{7}.'.format( # _tmp_list_idx_and_rate, exchange_type, turn, _all_turns, _curr_rate, _rate_total, _rand, _material ) ) defer.returnValue( _material )
def check_touch(self, location, t_type): if self.opened_list[location] != -1: return False if t_type == 1: if self.normal_rose <= 0: return False self.normal_rose -= 1 elif t_type == 2: if self.blue_rose <= 0: return False self.blue_rose -= 1 _rand = rand_num() if _rand <= get_lover_kiss_rate_conf(t_type)['Rate']: return True return False
def rand_reward(turn): _all, _weight = sysconfig['constellation_reward_rand'] _rewards = _all.get(turn, None) _t_weight = _weight.get(turn, None) if _rewards and _t_weight: _tmp = 0 _rand = rand_num(_t_weight) for reward in _rewards: _tmp += reward[3] if _rand <= _tmp: return list(reward[:3]) else: log.warn("[ Constellation.rand_reward ]missed, current tmp:{0}, rand:{1}, turn:{2}.".format(_tmp, _rand, turn)) else: log.warn("[ Constellation.rand_reward ]no turn {0} in sysconfig, rewards:{1}, weight:{2}.".format(turn, _rewards, _t_weight))
def rand_reward_by_type(self, reward_type): _all_conf = get_lover_kiss_reward_conf_by_type(reward_type) _total_rate = sum([_conf[2] for _conf in _all_conf]) _rand = rand_num(_total_rate) _res = None _current = 0 for _conf in _all_conf: _res = _conf if _rand < (_current + _conf[2]): break else: _current += _conf[2] else: log.error('reward not existed!') return _res[4], _res[3], _res[5], _res[6]
def rand_item_from_package(user, package_id, rand_from): _level = user.level _vip_level = user.vip_level _all_conf = sysconfig['package'].get(package_id, []) _all_conf = _all_conf[rand_from] if _all_conf else [] if not _all_conf: log.error( 'Not find basic conf. cid:{0}, package_id:{1}, rand_from:{2}.'. format(user.cid, package_id, rand_from)) _oss_conf = get_package_oss_conf(package_id, rand_from) _all_conf = _all_conf + _oss_conf if not _all_conf: log.error('Not find oss conf. cid:{0}, package_id:{1}, rand_from:{2}.'. format(user.cid, package_id, rand_from)) return None _rate_max = 0 _all_items = [] for _conf in _all_conf: if _conf['RoleLevel'] <= _level and _conf['VipLevel'] <= _vip_level: _rate_max += _conf['Rate'] _all_items.append( (_conf['ItemType'], _conf['ItemID'], _conf['ItemNum'], _conf['Rate'], _conf['Notice'])) _rand = rand_num(_rate_max) _current = 0 _item = None for _item_type, _item_id, _item_num, _rate, _notice in _all_items: _item = _item_type, _item_id, _item_num, _notice if _rand < (_current + _rate): break else: _current += _rate else: log.error( 'Rand empty. cid:{0}, level:{1}, vip:{2}, max:{3}, rand:{4}, current:{5}.' .format(user.cid, _level, _vip_level, _rate_max, _rand, _current)) return _item
def rand_shard(user, shard_id, plunder_cid): ''' @summary: 获取碎片 ''' res_err = UNKNOWN_ERROR, None _rate = rand_num() _flag = False if plunder_cid > 0: # 玩家 if _rate <= 7500: _flag = True else: _flag = yield AvoidWarMgr.probability_of_robot( user.cid, shard_id, _rate ) if _flag: res_err = yield user.bag_treasureshard_mgr.new(shard_id, 1) defer.returnValue( res_err )
def rand_shard(user, shard_id, plunder_cid): ''' @summary: 获取碎片 ''' res_err = UNKNOWN_ERROR, None _rate = rand_num() _flag = False if plunder_cid > 0: # 玩家 if _rate <= 7500: _flag = True else: _flag = yield AvoidWarMgr.probability_of_robot( user.cid, shard_id, _rate) if _flag: res_err = yield user.bag_treasureshard_mgr.new(shard_id, 1) defer.returnValue(res_err)
def random_next_level(self, curr_level): ''' 鉴玉等级会有一定几率提示、不变、回到初始等级 ''' #log.info('For Test. before level: {0}.'.format( curr_level )) level_conf = get_jade_level_conf(curr_level) if not level_conf: return curr_level, [] total_rate = 0 for _v in level_conf.itervalues(): total_rate += _v['Rate'] if total_rate <= 0: log.warn( 'There is no level pool. cid: {0}, curr_level: {1}.'.format( self.cid, curr_level)) return curr_level, extra_item curr_int = 0 randint = rand_num(total_rate) extra_item = [] for _v in level_conf.itervalues(): if randint < (curr_int + _v['Rate']): curr_level = _v['TargetLevel'] #log.error('For Test. curr_level: {0}, randint: {1}, curr_int: {2}, _rate: {3}, total_rate: {4}.'.format( curr_level, randint, curr_int, _v['Rate'], total_rate )) break else: curr_int += _v['Rate'] else: curr_level = curr_level rand_int = random.randint(0, 10000) if rand_int <= level_conf[curr_level]['ExtraOdds']: extra_item = [ level_conf[curr_level]['ItemType'], level_conf[curr_level]['ItemID'], level_conf[curr_level]['ItemNum'] ] #log.info('For Test. after level: {0}, extra_item: {1}, total_rate: {2}.'.format( curr_level, extra_item, total_rate )) return curr_level, extra_item
def rand_reward(turn): _all, _weight = sysconfig['constellation_reward_rand'] _rewards = _all.get(turn, None) _t_weight = _weight.get(turn, None) if _rewards and _t_weight: _tmp = 0 _rand = rand_num(_t_weight) for reward in _rewards: _tmp += reward[3] if _rand <= _tmp: return list(reward[:3]) else: log.warn( "[ Constellation.rand_reward ]missed, current tmp:{0}, rand:{1}, turn:{2}." .format(_tmp, _rand, turn)) else: log.warn( "[ Constellation.rand_reward ]no turn {0} in sysconfig, rewards:{1}, weight:{2}." .format(turn, _rewards, _t_weight))
def rand_item_from_package(user, package_id, rand_from): _level = user.level _vip_level = user.vip_level _all_conf = sysconfig['package'].get(package_id, []) _all_conf = _all_conf[rand_from] if _all_conf else [] if not _all_conf: log.error('Not find basic conf. cid:{0}, package_id:{1}, rand_from:{2}.'.format( user.cid, package_id, rand_from )) _oss_conf = get_package_oss_conf(package_id, rand_from) _all_conf = _all_conf + _oss_conf if not _all_conf: log.error('Not find oss conf. cid:{0}, package_id:{1}, rand_from:{2}.'.format( user.cid, package_id, rand_from )) return None _rate_max = 0 _all_items = [] for _conf in _all_conf: if _conf['RoleLevel'] <= _level and _conf['VipLevel'] <= _vip_level: _rate_max += _conf['Rate'] _all_items.append((_conf['ItemType'], _conf['ItemID'], _conf['ItemNum'], _conf['Rate'], _conf['Notice'])) _rand = rand_num(_rate_max) _current = 0 _item = None for _item_type, _item_id, _item_num, _rate, _notice in _all_items: _item = _item_type, _item_id, _item_num, _notice if _rand < (_current + _rate): break else: _current += _rate else: log.error('Rand empty. cid:{0}, level:{1}, vip:{2}, max:{3}, rand:{4}, current:{5}.'.format( user.cid, _level, _vip_level, _rate_max, _rand, _current)) return _item
def get_touch_reward(self, location): self.opened_num += 1 rate = get_lover_kiss_conf(self.opened_num)['LuxuryRewardRate'] _rand = rand_num() if _rand <= rate and self.big_reward == 0: reward = self.rand_reward_by_type(LUXURY_TYPE) self.big_reward = 1 else: reward = self.rand_reward_by_type(NORMAL_TYPE) notice = reward[-1] if notice: message = [ACHIEVE_TYPE_LOVER_KISS, self.user.nick_name, reward[0]] gw_broadcast('sync_broadcast', [message]) _item = yield item_add(self.user, ItemType = reward[1], ItemID = reward[0], ItemNum = reward[2], AddType = WAY_LOVER_KISS) self.opened_list[location] = _item[1][0][2] self.synced = False self.sync() defer.returnValue( [_item[1], self.opened_list, self.normal_rose, self.blue_rose, BLUE_ROSE_MAX_NUM - self.extra_blue_rose])
def randcard_frompool(self, pool): ''' @summary: 从抽卡池中抽卡 ''' _total_rate = 0 for _conf in pool.itervalues(): _total_rate += _conf['Rate'] if _total_rate <= 0: log.warn('There is no cardpool. _total_rate: {0}.'.format( _total_rate )) return (NOT_FOUND_CONF, {}) _curr_rate = 0 _randint = rand_num(_total_rate) for _conf in pool.itervalues(): if _randint < (_curr_rate + _conf['Rate']): #log.error('For Test. _randint: {0}, _curr_rate: {1}, _conf_rate: {2}.'.format( _randint, _curr_rate, _conf['Rate'] )) return (NO_ERROR, _conf) else: _curr_rate += _conf['Rate'] else: log.warn('There is no cardpool. _randint: {0}, _total_rate: {1}.'.format( _randint, _total_rate )) return (NOT_FOUND_CONF, {} )
def boost(self, user, boost_type): #type: 1:gold, 2:credit _max_level = get_attack_extra_maxlevel() _next_level = 1 _conf = None if self.attack_extra_level >= _max_level: return WORLDBOSS_INSPIRE_MAX_LEVEL_REACHED if boost_type == 1: _field_rate = 'GoldRate' _field_add_rate = 'GoldAddRate' _field_cost = 'GoldCost' _failed_count = self._gold_inspire_failed_count _next_level = self._gold_inspire_success_count + 1 _conf = get_attack_extra_by_level(_next_level) elif boost_type == 2: _field_rate = 'CreditsRate' _field_add_rate = 'CreditsAddRate' _field_cost = 'CreditsCost' _failed_count = self._credit_inspire_failed_count _next_level = self._credit_inspire_success_count + 1 _conf = get_attack_extra_by_level(_next_level) else: log.error('no boost type:', boost_type, 'cid:', self._cid) return UNKNOWN_ERROR if _conf: _rate, _add_rate, _cost = _conf[_field_rate], _conf[ _field_add_rate], _conf[_field_cost] if (boost_type == 1 and _cost > user.golds): return CHAR_GOLD_NOT_ENOUGH elif (boost_type == 2 and _cost > user.credits): return CHAR_CREDIT_NOT_ENOUGH _rand = rand_num() if _rand <= _rate + _add_rate * _failed_count: self._gold_inspire_failed_count = self._credit_inspire_failed_count = 0 #self._attack_extra_level = _next_level if boost_type == 1: self._gold_inspire_success_count = _next_level user.consume_golds(_cost, WAY_WORLDBOSS_BOOST) elif boost_type == 2: self._credit_inspire_success_count = _next_level user.consume_credits(_cost, WAY_WORLDBOSS_BOOST) else: if boost_type == 1: self._gold_inspire_failed_count += 1 elif boost_type == 2: self._credit_inspire_failed_count += 1 self.sync() return NO_ERROR else: log.error('no attack extra config for level:', _next_level, 'current level:', self.attack_extra_level, 'cid:', self._cid) return WORLDBOSS_NO_INSPIRE_CONFIG
def random_lottery_items(cid, level, vip_level, rand_count=3): ''' @summary: activity翻牌的共用 @param : rand_count-3为默认幸运道具个数 @param : HASH_ACTIVITY_LOTTERY cid dumps((level, vip_level), {ID: count}) ''' all_items = get_activity_lottery(level, vip_level) if not all_items: log.error("No activity lottery conf. cid: {0}, level: {1}, vip_level: {2}.".format( cid, level, vip_level )) defer.returnValue( [] ) flag = False # 是否需要更新redis的标志位 data = yield redis.hget( HASH_ACTIVITY_LOTTERY, cid ) if data: section, lottery_data = loads( data ) if section != (level, vip_level): lottery_data = {} else: lottery_data = {} items_ids = [] # 已随机的ID items_data = [] # 已随机的items total_rate = 0 items_rate = {} # 临时的id:rate值 for _id, _item in all_items.iteritems(): _id_rate = _item['Rate'] + _item['AddRate'] * lottery_data.get(_id, 0) total_rate += _id_rate items_rate[_id] = _id_rate if total_rate > 0: for i in range(0, rand_count): curr_int = 0 randint = rand_num(total_rate) for _id, _conf in all_items.iteritems(): if randint < (curr_int + items_rate[_id]): items_ids.append( _id ) items_data.append( [_conf['ItemType'], _conf['ItemID'], _conf['ItemNum'], _conf['Notice']] ) #log.error('For Test. randint: {0}, total_rate: {1}, curr_int: {2}, items_ids: {3}.'.format( randint, total_rate, curr_int, items_ids )) break else: curr_int += items_rate[_id] else: log.error('No random item. randint: {0}, total_rate: {1}, curr_int: {2}.'.format( randint, total_rate, curr_int )) defer.returnValue( [] ) else: log.error('Activity lottery pool is null. total_rate: {0}.'.format( total_rate )) defer.returnValue( [] ) # 累计次数提高比重 for _id, _item in all_items.iteritems(): if _id in items_ids: # 已抽中的道具累计次数清零 if lottery_data.has_key( _id ): del lottery_data[_id] flag = True continue if (not _item['AddRate']): continue # 剩余未抽中的道具累计次数加1 lottery_data[_id] = lottery_data.setdefault(_id, 0) + 1 flag = True # 保存redis if flag: yield redis.hset( HASH_ACTIVITY_LOTTERY, cid, dumps([(level, vip_level), lottery_data]) ) if not items_data: log.error("No activity lottery items. cid: {0}.".format( cid )) defer.returnValue( items_data )
def random_items(self, level, vip_level): ''' 从神秘商店中随机8次,每次1个道具,未被随机到的道具概率需要累计 ''' all_items = get_mystical_shop_conf(level, vip_level) if not all_items: defer.returnValue([]) flag = False # 是否需要更新redis的标志位 data = yield redis.hget(HASH_MYSTICAL_LOTTERY, self.cid) if data: section, mystical_data = loads(data) if section != (level, vip_level): mystical_data = {} else: mystical_data = {} items_ids = [] # 已随机的ID items_data = [] # 已随机的items total_rate = 0 # 总权重值 items_rate = {} # 临时的id:rate值 for _id, _item in all_items.iteritems(): _id_rate = (_item['Rate'] + _item['RateAdd'] * mystical_data.get(_id, 0)) total_rate += _id_rate items_rate[_id] = _id_rate for _idx in range(0, 8): _curr = 0 _rand = rand_num(total_rate) for _id, _item in all_items.iteritems(): if _rand < (_curr + items_rate[_id]): items_ids.append(_id) items_data.append([ _idx, _item['ItemType'], _item['ItemID'], _item['ItemNum'], _item['CostItemType'], _item['CostItemID'], _item['CostItemNum'], 1 ]) break else: _curr += items_rate[_id] else: log.error( 'No random item. _rand: {0}, total_rate: {1}, _curr: {2}.'. format(_rand, total_rate, _curr)) defer.returnValue([]) # 累计次数提高比重 for _id, _item in all_items.iteritems(): if _id in items_ids: # 已抽中的道具累计次数清零 if mystical_data.has_key(_id): del mystical_data[_id] flag = True continue if (not _item['RateAdd']): continue # 剩余未抽中的道具累计次数加1 mystical_data[_id] = mystical_data.setdefault(_id, 0) + 1 flag = True # 保存redis if flag: yield redis.hset(HASH_MYSTICAL_LOTTERY, self.cid, dumps([(level, vip_level), mystical_data])) defer.returnValue(items_data)
def __rand_material(self, exchange_type, turn, add_cnt, except_material=None): _all_turns = get_exchange_refresh_conf(exchange_type, turn) _tmp_list_idx_and_rate = [] #暂存每个材料的index和计算出来的当前权重值 _material = None _rate_total = 0 #所有需要随机材料的总权重 _curr_rate = 0 _rand = 0 if _all_turns: _all_turn_cnt = yield redis.hmget( HASH_EXCHANGE_REFRESH_RATE, ['{0}.{1}'.format(self.cid, _conf[0]) for _conf in _all_turns]) _len_cnt = len(_all_turn_cnt) for _idx, _turn_conf in enumerate(_all_turns): if except_material == [ _turn_conf[3], _turn_conf[4], _turn_conf[5] ]: # 该材料不能参与随机,防止材料重复, DK-1663 continue _cnt = (_all_turn_cnt[_idx] if _idx < _len_cnt else 0) or 0 _rate = _turn_conf[6] + ((_cnt * _turn_conf[7]) if _cnt else 0) if _rate >= _turn_conf[8]: _rate = _turn_conf[8] _tmp_list_idx_and_rate.append([_idx, _rate, _cnt]) _rate_total += _rate _rand = rand_num(_rate_total) for _c_idx, _c_rate, _c_cnt in _tmp_list_idx_and_rate: if _rand <= _curr_rate + _c_rate: #hitted _conf = _all_turns[_c_idx] #这里是material和target的数据结构了,找不到来这里找 if not _material: _material = [_conf[3], _conf[4], _conf[5]] if add_cnt: redis.hset(HASH_EXCHANGE_REFRESH_RATE, '{0}.{1}'.format(self.cid, _conf[0]), 0) #命中后重置 else: if add_cnt: redis.hset(HASH_EXCHANGE_REFRESH_RATE, '{0}.{1}'.format(self.cid, _conf[0]), _c_cnt + 1) #miss后累加 _curr_rate += _c_rate if not _material: log.warn( 'missing rand material. list_idx_and_rate as: {0}, exchange_type:{1}, turn:{2}, _all_turns:{3}, _curr_rate:{4}, _rate_total:{5}, _rand:{6}.' .format(_tmp_list_idx_and_rate, exchange_type, turn, _all_turns, _curr_rate, _rate_total, _rand)) #log.debug( 'list_idx_and_rate as: {0}, exchange_type:{1}, turn:{2}, _all_turns:{3}, _curr_rate:{4}, _rate_total:{5}, _rand:{6}, _material:{7}.'.format( # _tmp_list_idx_and_rate, exchange_type, turn, _all_turns, _curr_rate, _rate_total, _rand, _material ) ) defer.returnValue(_material)