Loading...   

Inventory::HasInstanceBy


 

This is a slight rework of the way the old 'HasItem' methods processed searches.

 

Feeder code:

enum HasItemInstanceBy : uint8 {
	ByNothing = 0,			// uses: hasbydata.{  }
	ByID,					// uses: hasbydata.{ mode, itemid, quantity, wheremask }
	ByClassType,			// uses: hasbydata.{ mode, classtype, quantity, wheremask }
	ByUseType,				// uses: hasbydata.{ mode, usetype, quantity, wheremask }
	ByLore,					// uses: hasbydata.{ mode, lore[80], quantity, wheremask }
	ByLoreFlag,				// uses: hasbydata.{ mode, loreflag, quantity, wheremask }
	ByLoreGroup,			// uses: hasbydata.{ mode, loregroup, quantity, wheremask }
	ByAndClassesMask,		// uses: hasbydata.{ mode, classesmask, quantity, wheremask }
	ByAndRacesMask,			// uses: hasbydata.{ mode, racesmask, quantity, wheremask }
	ByAndSlotsMask,			// uses: hasbydata.{ mode, slotsmask, quantity, wheremask }
	ByOrClassesMask,		// uses: hasbydata.{ mode, classesmask, quantity, wheremask }
	ByOrRacesMask,			// uses: hasbydata.{ mode, racesmask, quantity, wheremask }
	ByOrSlotsMask,			// uses: hasbydata.{ mode, slotsmask, quantity, wheremask }
	ByEvolving,				// uses: hasbydata.{ mode, quantity, wheremask }
	ByScaling,				// uses: hasbydata.{ mode, quantity, wheremask }
	ByAugOrnamented,		// uses: hasbydata.{ mode, ornamentid, quantity, wheremask } - aug-type ornaments (pass _INVALID for all or ID for specific)
	ByBagOrnamented,		// uses: hasbydata.{ mode, ornamentid, quantity, wheremask } - bag-type ornaments (pass _INVALID for all or ID for specific)
	BySpecialOrnamented,	// uses: hasbydata.{ mode, ornamentid, quantity, wheremask } - aug-type ornaments (pass _INVALID for all or ID for specific)
	ByIllegal,				// uses: hasbydata.{ mode, quantity, wheremask }
	ByConstInstance,		// uses: hasbydata.{ mode, constinstance, quantity, wheremask }
	ByInstance,				// uses: hasbydata.{ mode, instance, quantity, wheremask }
	ByExtant,				// uses: hasbydata.{ mode, quantity, wheremask }
	_ByCount
};

struct HasItemInstanceBy_Struct {
	HasItemInstanceBy	mode;
	uint32				wheremask;
	uint32				itemid;
	uint32				quantity;
	uint32				classtype;
	uint32				usetype;
	char				lore[80];
	bool				loreflag;
	uint32				loregroup;
	uint32				classesmask;
	uint32				racesmask;
	uint32				slotsmask;
	uint32				ornamentid;
	const ItemInstance*	constinstance;
	ItemInstance*		instance;
};

class LocationsTraits {
public:
	bool	operator()(const Location_Struct l, const Location_Struct r) const {
		return ((l.map < r.map) && (l.main < r.main) && (l.sub < r.sub) && (l.aug < r.aug));
	}
};

typedef	std::map	t_locations;
typedef t_locations::const_iterator					iter_locations;
typedef t_locations::iterator						_iter_locations;

class Inventory {
	void	HasInstanceBy(t_locations& locations, HasItemInstanceBy_Struct& has_by_data);
	void	HasInstanceByID(t_locations& locations, uint32 item_id, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByClassType(t_locations& locations, uint32 class_type, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByUseType(t_locations& locations, uint32 use_type, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByLore(t_locations& locations, const char* lore, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByLoreFlag(t_locations& locations, bool lore_flag, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByLoreGroup(t_locations& locations, uint32 lore_group, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByAndClassesMask(t_locations& locations, uint32 classes_mask, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByAndRacesMask(t_locations& locations, uint32 races_mask, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByAndSlotsMask(t_locations& locations, uint32 slots_mask, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByOrClassesMask(t_locations& locations, uint32 classes_mask, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByOrRacesMask(t_locations& locations, uint32 races_mask, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByOrSlotsMask(t_locations& locations, uint32 slots_mask, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByEvolving(t_locations& locations, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByScaling(t_locations& locations, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByAugOrnamented(t_locations& locations, uint32 ornament_id, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByBagOrnamented(t_locations& locations, uint32 ornament_id, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceBySpecialOrnamented(t_locations& locations, uint32 ornament_id, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByIllegal(t_locations& locations, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByConstInstance(t_locations& locations, const ItemInstance* instance, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByInstance(t_locations& locations, ItemInstance* instance, uint32 quantity = 0, uint32 where_mask = WhereCommon);
	void	HasInstanceByExtant(t_locations& locations, uint32 quantity = 0, uint32 where_mask = WhereCommon); // a map of occupied slots
};

 

Processing code (see next snippet for abbreviated function):

void Inventory::HasInstanceBy_(t_locations& locations) {
	// This is an integrated and more powerful version of the previous 'HasItem' functions. Each 'scope' allows independent
	// conditional checks and the entirety of locations is returned at one time..as opposed to only the last instance per
	// invocation of the previous methods..if sufficient quantity was found.
	//
	// In addition to the location, a pointer to the ItemInstance is also provided. This allows direct manipulation of the
	// instance, if so desired. If deletion is needed, a 'Delete' action must be performed on the location through the
	// Inventory class. Any direct deletion of the returned pointer will result in a server crash upon next access.
	//
	// I added a switch for each check scope, instead of passing to a helper function, so that each 'mode'can be tailored.
	// I also added checks to each augment check scope for the original 'usetype' and 'loregroup' searches...
	// (why wouldn't augments only be allowed one lore/loregroup instance as well?)
	//
	// This procedure will only check 'loaded' containers. If you need to access something that is not 'common,' you will need
	// to borrow a pointer to an existing container and add it m_containers, or create a new container and load it with the
	// appropriate data..and, of course, add it to m_containers (i.e., m_containers[MapDeleted] = new container;
	// [populate m_containers[MapDeleted] with database query]; HasInstanceBy(<&locations>, , WhereDeleted);)

	locations.clear();
	
	if (hasbydata.mode == ByNothing)
		return;

	autolox.Invalidate();
	
	uint64 mask = 0;
	uint32 quantity_ = 0;

	if (hasbydata.wheremask & WhereEquipment)
		mask |= limits.EquipmentBitmask(m_version);
	if (hasbydata.wheremask & WhereGeneral)
		mask |= limits.GeneralBitmask(m_version);
	if (hasbydata.wheremask & WhereCursor)
		mask |= limits.CursorBitmask(m_version);

	// this process is actually pretty quick..only existing maps/keys are checked
	// (all of the switch cases probably need to be tweaked before going live)
	for (iter_containers iter_map = m_containers.begin(); iter_map != m_containers.end(); ++iter_map) {
		if (iter_map->first == MapPossessions) {
			if (!mask)
				continue;
		}
		else if (~hasbydata.wheremask & ((uint32)1 << (iter_map->first + 2))) { // we took two extra positions for MapPossessions
			continue;
		}

		autolox.map = iter_map->first;

		for (iter_contents iter_main = iter_map->second->m_contents.begin(); iter_main != iter_map->second->m_contents.end(); ++iter_main) {
			autolox.main = iter_main->first;
			
			if ((uint16)iter_main->first >= limits.InventoryMapSize(iter_map->first, m_version)) {
				if (hasbydata.mode == ByIllegal) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				continue;
			}
			if (iter_map->first == MapPossessions)
				if (~mask & ((uint64)1 << iter_main->first)) {
					if (hasbydata.mode == ByIllegal) {
						locations[autolox.Location()] = iter_main->second;
						quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
					}
					continue;
				}
			
			switch (hasbydata.mode) { // MainItem checks
			case ByID:
				if (iter_main->second->m_item->ID == hasbydata.itemid) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByClassType:
				if (iter_main->second->m_item->ItemClass == hasbydata.classtype) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByUseType:
				if (iter_main->second->m_item->ItemType == hasbydata.usetype) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByLore:
				if (strcasecmp(iter_main->second->m_item->Lore, hasbydata.lore) == 0) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByLoreFlag:
				if (iter_main->second->m_item->LoreFlag == hasbydata.loreflag) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByLoreGroup:
				if (iter_main->second->m_item->LoreGroup == hasbydata.loregroup) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByAndClassesMask:
				if ((iter_main->second->m_item->Classes & hasbydata.classesmask) == hasbydata.classesmask) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByAndRacesMask:
				if ((iter_main->second->m_item->Races & hasbydata.racesmask) == hasbydata.racesmask) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByAndSlotsMask:
				if ((iter_main->second->m_item->Slots & hasbydata.slotsmask) == hasbydata.slotsmask) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByOrClassesMask:
				if (iter_main->second->m_item->Classes & hasbydata.classesmask) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByOrRacesMask:
				if (iter_main->second->m_item->Races & hasbydata.racesmask) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByOrSlotsMask:
				if (iter_main->second->m_item->Slots & hasbydata.slotsmask) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByEvolving:
				if (iter_main->second->m_evoinstance != nullptr) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByScaling:
				if (iter_main->second->m_scaleitem != nullptr) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				break;
			case ByAugOrnamented:
				break;
			case ByBagOrnamented:
				if (iter_main->second->m_ornamentitem != nullptr)
					if ((hasbydata.ornamentid == _INVALID) || (iter_main->second->m_ornamentitem->ID == hasbydata.ornamentid)) {
						locations[autolox.Location()] = iter_main->second;
						quantity_ += 1;
					}
				break;
			case BySpecialOrnamented:
				break;
			case ByConstInstance:
				if (hasbydata.constinstance != nullptr)
					if (iter_main->second == hasbydata.constinstance) {
						locations[autolox.Location()] = iter_main->second;
						quantity_ += 1;
					}
				break;
			case ByInstance:
				if (hasbydata.instance != nullptr)
					if (iter_main->second == hasbydata.instance) {
						locations[autolox.Location()] = iter_main->second;
						quantity_ += 1;
					}
				break;
			case ByExtant:
				locations[autolox.Location()] = iter_main->second;
				quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				break;
			default:
				break;
			}

			if (hasbydata.quantity)
				if (quantity_ >= hasbydata.quantity)
					return;
			if (!iter_main->second->m_container)
				continue;

			if (iter_main->second->m_item->ItemClass == ItemClassCommon) {
				for (iter_contents iter_aug = iter_main->second->m_container->m_contents.begin(); iter_aug != iter_main->second->m_container->m_contents.end(); ++iter_aug) {
					autolox.aug = iter_aug->first;
					
					if ((uint16)iter_aug->first >= limits.ItemCommonSize(m_version)) {
						if (hasbydata.mode == ByIllegal) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						continue;
					}

					switch (hasbydata.mode) { // MainAugment checks
					case ByID:
						if (iter_aug->second->m_item->ID == hasbydata.itemid) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByClassType:
						if (iter_aug->second->m_item->ItemClass == hasbydata.classtype) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByUseType:
						if (iter_aug->second->m_item->ItemType == hasbydata.usetype) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByLore:
						if (strcasecmp(iter_aug->second->m_item->Lore, hasbydata.lore) == 0) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByLoreFlag:
						if (iter_aug->second->m_item->LoreFlag == hasbydata.loreflag) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByLoreGroup:
						if (iter_aug->second->m_item->LoreGroup == hasbydata.loregroup) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByAndClassesMask:
						if ((iter_aug->second->m_item->Classes & hasbydata.classesmask) == hasbydata.classesmask) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByAndRacesMask:
						if ((iter_aug->second->m_item->Races & hasbydata.racesmask) == hasbydata.racesmask) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByAndSlotsMask:
						if ((iter_aug->second->m_item->Slots & hasbydata.slotsmask) == hasbydata.slotsmask) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByOrClassesMask:
						if (iter_aug->second->m_item->Classes & hasbydata.classesmask) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByOrRacesMask:
						if (iter_aug->second->m_item->Races & hasbydata.racesmask) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByOrSlotsMask:
						if (iter_aug->second->m_item->Slots & hasbydata.slotsmask) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByEvolving:
						if (iter_aug->second->m_evoinstance != nullptr) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByScaling:
						if (iter_aug->second->m_scaleitem != nullptr) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						break;
					case ByAugOrnamented:
						if (iter_aug->second->m_item->AugType & AugUseOrnamentation) {
							autolox.aug = _INVALID;
							if (locations.find(autolox.Location()) == locations.end()) {
								locations[autolox.Location()] = iter_main->second;
								quantity_ += 1;
							}
						}
						break;
					case ByBagOrnamented:
						break;
					case BySpecialOrnamented:
						if (iter_aug->second->m_item->AugType & AugUseSpecialOrnamentation) {
							autolox.aug = _INVALID;
							if (locations.find(autolox.Location()) == locations.end()) {
								locations[autolox.Location()] = iter_main->second;
								quantity_ += 1;
							}
						}
						break;
					case ByConstInstance:
						break;
					case ByInstance:
						break;
					case ByExtant:
						locations[autolox.Location()] = iter_aug->second;
						quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						break;
					default:
						break;
					}
				}

				if (hasbydata.quantity)
					if (quantity_ >= hasbydata.quantity)
						return;

				autolox.aug = _INVALID;
			}
			else if (iter_main->second->m_item->ItemClass == ItemClassContainer) {
				for (iter_contents iter_sub = iter_main->second->m_container->m_contents.begin(); iter_sub != iter_main->second->m_container->m_contents.end(); ++iter_sub) {
					autolox.sub = iter_sub->first;
					
					if ((uint16)iter_sub->first >= limits.ItemContainerSize(m_version)) {
						if (hasbydata.mode == ByIllegal) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						continue;
					}
					if ((uint16)iter_sub->first >= iter_main->second->m_item->BagSlots) {
						if (hasbydata.mode == ByIllegal) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						continue;
					}

					switch (hasbydata.mode) { // SubItem checks
					case ByID:
						if (iter_sub->second->m_item->ID == hasbydata.itemid) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByClassType:
						if (iter_sub->second->m_item->ItemClass == hasbydata.classtype) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByUseType:
						if (iter_sub->second->m_item->ItemType == hasbydata.usetype) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByLore:
						if (strcasecmp(iter_sub->second->m_item->Lore, hasbydata.lore) == 0) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByLoreFlag:
						if (iter_sub->second->m_item->LoreFlag == hasbydata.loreflag) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByLoreGroup:
						if (iter_sub->second->m_item->LoreGroup == hasbydata.loregroup) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByAndClassesMask:
						if ((iter_sub->second->m_item->Classes & hasbydata.classesmask) == hasbydata.classesmask) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByAndRacesMask:
						if ((iter_sub->second->m_item->Races & hasbydata.racesmask) == hasbydata.racesmask) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByAndSlotsMask:
						if ((iter_sub->second->m_item->Slots & hasbydata.slotsmask) == hasbydata.slotsmask) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByOrClassesMask:
						if (iter_sub->second->m_item->Classes & hasbydata.classesmask) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByOrRacesMask:
						if (iter_sub->second->m_item->Races & hasbydata.racesmask) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByOrSlotsMask:
						if (iter_sub->second->m_item->Slots & hasbydata.slotsmask) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByEvolving:
						if (iter_sub->second->m_evoinstance != nullptr) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByScaling:
						if (iter_sub->second->m_scaleitem != nullptr) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						break;
					case ByAugOrnamented:
						break;
					case ByBagOrnamented:
						if (iter_sub->second->m_ornamentitem != nullptr)
							if ((hasbydata.ornamentid == _INVALID) || (iter_sub->second->m_ornamentitem->ID == hasbydata.ornamentid)) {
								locations[autolox.Location()] = iter_sub->second;
								quantity_ += 1;
							}
						break;
					case BySpecialOrnamented:
						break;
					case ByConstInstance:
						if (hasbydata.constinstance != nullptr)
							if (iter_sub->second == hasbydata.constinstance) {
								locations[autolox.Location()] = iter_sub->second;
								quantity_ += 1;
							}
						break;
					case ByInstance:
						if (hasbydata.instance != nullptr)
							if (iter_sub->second == hasbydata.instance) {
								locations[autolox.Location()] = iter_sub->second;
								quantity_ += 1;
							}
						break;
					case ByExtant:
						locations[autolox.Location()] = iter_sub->second;
						quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						break;
					default:
						break;
					}

					if (hasbydata.quantity)
						if (quantity_ >= hasbydata.quantity)
							return;
					if (!iter_sub->second->m_container)
						continue;

					if (iter_sub->second->m_item->ItemClass == ItemClassCommon) {
						for (iter_contents iter_aug = iter_sub->second->m_container->m_contents.begin(); iter_aug != iter_sub->second->m_container->m_contents.end(); ++iter_aug) {
							autolox.aug = iter_aug->first;

							if ((uint16)iter_aug->first >= limits.ItemCommonSize(m_version)) {
								if (hasbydata.mode == ByIllegal) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								continue;
							}

							switch (hasbydata.mode) { // SubAugment checks
							case ByID:
								if (iter_aug->second->m_item->ID == hasbydata.itemid) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByClassType:
								if (iter_aug->second->m_item->ItemClass == hasbydata.classtype) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByUseType:
								if (iter_aug->second->m_item->ItemType == hasbydata.usetype) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByLore:
								if (strcasecmp(iter_aug->second->m_item->Lore, hasbydata.lore) == 0) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByLoreFlag:
								if (iter_aug->second->m_item->LoreFlag == hasbydata.loreflag) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByLoreGroup:
								if (iter_aug->second->m_item->LoreGroup == hasbydata.loregroup) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByAndClassesMask:
								if ((iter_aug->second->m_item->Classes & hasbydata.classesmask) == hasbydata.classesmask) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByAndRacesMask:
								if ((iter_aug->second->m_item->Races & hasbydata.racesmask) == hasbydata.racesmask) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByAndSlotsMask:
								if ((iter_aug->second->m_item->Slots & hasbydata.slotsmask) == hasbydata.slotsmask) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByOrClassesMask:
								if (iter_aug->second->m_item->Classes & hasbydata.classesmask) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByOrRacesMask:
								if (iter_aug->second->m_item->Races & hasbydata.racesmask) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByOrSlotsMask:
								if (iter_aug->second->m_item->Slots & hasbydata.slotsmask) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByEvolving:
								if (iter_aug->second->m_evoinstance != nullptr) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByScaling:
								if (iter_aug->second->m_scaleitem != nullptr) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								break;
							case ByAugOrnamented:
								if (iter_aug->second->m_item->AugType & AugUseOrnamentation) {
									autolox.aug = _INVALID;
									if (locations.find(autolox.Location()) == locations.end()) {
										locations[autolox.Location()] = iter_sub->second;
										quantity_ += 1;
									}
								}
								break;
							case ByBagOrnamented:
								break;
							case BySpecialOrnamented:
								if (iter_aug->second->m_item->AugType & AugUseSpecialOrnamentation) {
									autolox.aug = _INVALID;
									if (locations.find(autolox.Location()) == locations.end()) {
										locations[autolox.Location()] = iter_sub->second;
										quantity_ += 1;
									}
								}
								break;
							case ByConstInstance:
								break;
							case ByInstance:
								break;
							case ByExtant:
								locations[autolox.Location()] = iter_aug->second;
								quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								break;
							default:
								break;
							}
						}

						if (hasbydata.quantity)
							if (quantity_ >= hasbydata.quantity)
								return;

						autolox.aug = _INVALID;
					}

					autolox.sub = _INVALID;
				}
			}
		}
	}

	// only release an extantent map if the quantity meets (or exceeds) criteria
	if (quantity_ < hasbydata.quantity) // didn't meet the criteria
		locations.clear();
}

 

Obviously, the bulk of processing code is switch and conditional checks..Here is the base search code:

void Inventory::HasInstanceBy_(t_locations& locations) {
	locations.clear();
	
	if (hasbydata.mode == ByNothing)
		return;

	autolox.Invalidate();
	
	uint64 mask = 0;
	uint32 quantity_ = 0;

	if (hasbydata.wheremask & WhereEquipment)
		mask |= limits.EquipmentBitmask(m_version);
	if (hasbydata.wheremask & WhereGeneral)
		mask |= limits.GeneralBitmask(m_version);
	if (hasbydata.wheremask & WhereCursor)
		mask |= limits.CursorBitmask(m_version);

	// this process is actually pretty quick..only existing maps/keys are checked
	// (all of the switch cases probably need to be tweaked before going live)
	for (iter_containers iter_map = m_containers.begin(); iter_map != m_containers.end(); ++iter_map) {
		if (iter_map->first == MapPossessions) {
			if (!mask)
				continue;
		}
		else if (~hasbydata.wheremask & ((uint32)1 << (iter_map->first + 2))) { // we took two extra positions for MapPossessions
			continue;
		}

		autolox.map = iter_map->first;

		for (iter_contents iter_main = iter_map->second->m_contents.begin(); iter_main != iter_map->second->m_contents.end(); ++iter_main) {
			autolox.main = iter_main->first;
			
			if ((uint16)iter_main->first >= limits.InventoryMapSize(iter_map->first, m_version)) {
				if (hasbydata.mode == ByIllegal) {
					locations[autolox.Location()] = iter_main->second;
					quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
				}
				continue;
			}
			if (iter_map->first == MapPossessions)
				if (~mask & ((uint64)1 << iter_main->first)) {
					if (hasbydata.mode == ByIllegal) {
						locations[autolox.Location()] = iter_main->second;
						quantity_ += (iter_main->second->m_charges <= 0) ? 1 : iter_main->second->m_charges;
					}
					continue;
				}
			
			// switch for MainItem checks

			if (hasbydata.quantity)
				if (quantity_ >= hasbydata.quantity)
					return;
			if (!iter_main->second->m_container)
				continue;

			if (iter_main->second->m_item->ItemClass == ItemClassCommon) {
				for (iter_contents iter_aug = iter_main->second->m_container->m_contents.begin(); iter_aug != iter_main->second->m_container->m_contents.end(); ++iter_aug) {
					autolox.aug = iter_aug->first;
					
					if ((uint16)iter_aug->first >= limits.ItemCommonSize(m_version)) {
						if (hasbydata.mode == ByIllegal) {
							locations[autolox.Location()] = iter_aug->second;
							quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
						}
						continue;
					}

					// switch for MainAugment checks
					
				}

				if (hasbydata.quantity)
					if (quantity_ >= hasbydata.quantity)
						return;

				autolox.aug = _INVALID;
			}
			else if (iter_main->second->m_item->ItemClass == ItemClassContainer) {
				for (iter_contents iter_sub = iter_main->second->m_container->m_contents.begin(); iter_sub != iter_main->second->m_container->m_contents.end(); ++iter_sub) {
					autolox.sub = iter_sub->first;
					
					if ((uint16)iter_sub->first >= limits.ItemContainerSize(m_version)) {
						if (hasbydata.mode == ByIllegal) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						continue;
					}
					if ((uint16)iter_sub->first >= iter_main->second->m_item->BagSlots) {
						if (hasbydata.mode == ByIllegal) {
							locations[autolox.Location()] = iter_sub->second;
							quantity_ += (iter_sub->second->m_charges <= 0) ? 1 : iter_sub->second->m_charges;
						}
						continue;
					}

					// switch for SubItem checks

					if (hasbydata.quantity)
						if (quantity_ >= hasbydata.quantity)
							return;
					if (!iter_sub->second->m_container)
						continue;

					if (iter_sub->second->m_item->ItemClass == ItemClassCommon) {
						for (iter_contents iter_aug = iter_sub->second->m_container->m_contents.begin(); iter_aug != iter_sub->second->m_container->m_contents.end(); ++iter_aug) {
							autolox.aug = iter_aug->first;

							if ((uint16)iter_aug->first >= limits.ItemCommonSize(m_version)) {
								if (hasbydata.mode == ByIllegal) {
									locations[autolox.Location()] = iter_aug->second;
									quantity_ += (iter_aug->second->m_charges <= 0) ? 1 : iter_aug->second->m_charges;
								}
								continue;
							}

							// switch for SubAugment checks
							
						}

						if (hasbydata.quantity)
							if (quantity_ >= hasbydata.quantity)
								return;

						autolox.aug = _INVALID;
					}

					autolox.sub = _INVALID;
				}
			}
		}
	}

	// only release an extantent map if the quantity meets (or exceeds) criteria
	if (quantity_ < hasbydata.quantity) // didn't meet the criteria
		locations.clear();
}