View Single Post
  #12  
Old 02-21-2018, 11:15 PM
c0ncrete's Avatar
c0ncrete
Dragon
 
Join Date: Dec 2009
Posts: 719
Default

This was a re-write I'd been using without the corpse check as well. It'll let you specify which slots to check via optional bitmask.

Code:
#!/usr/bin/perl

use Switch;

# item identifier bits
use constant
{
	INVALID_ID => 0xFFFFFFFF
};

# client version bits
use constant
{
	BIT_TitaniumAndEarlier	=> 0x03,
	BIT_SoFAndLater		=> 0xFFFFFFFC
};

# inventory location bits
use constant
{
	invWhereWorn		=> 0x01,
	invWherePersonal	=> 0x02,
	invWhereBank		=> 0x04,
	invWhereSharedBank	=> 0x08,
	invWhereTrading		=> 0x10,
	invWhereCursor		=> 0x20,
	invWhereCorpse		=> 0x40
};

# returns first and last slot number available in container
sub getContainerRange
{
	my $verBit	= shift->GetClientVersionBit();
	my $slotID	= shift;
	my @contSR	= (); # container slot range

	switch($slotID)
	{
		# 22-29 are personal inventory slots
		case 22 { @contSR = (251, 260); }
		case 23 { @contSR = (261, 270); }
		case 24 { @contSR = (271, 280); }
		case 25 { @contSR = (281, 290); }
		case 26 { @contSR = (291, 300); }
		case 27 { @contSR = (301, 310); }
		case 28 { @contSR = (311, 320); }
		case 29 { @contSR = (321, 330); }
		# 30 is the cursor slot
		case 30 { @contSR = (331, 340); }
		# 400-??? are tribute slots
		# 2000-2023 are bank slots
		case 2000 { @contSR = (2031, 2040); }
		case 2001 { @contSR = (2041, 2050); }
		case 2002 { @contSR = (2051, 2060); }
		case 2003 { @contSR = (2061, 2070); }
		case 2004 { @contSR = (2071, 2080); }
		case 2005 { @contSR = (2081, 2090); }
		case 2006 { @contSR = (2091, 2100); }
		case 2007 { @contSR = (2101, 2110); }
		case 2008 { @contSR = (2111, 2120); }
		case 2009 { @contSR = (2121, 2130); }
		case 2010 { @contSR = (2131, 2140); }
		case 2011 { @contSR = (2141, 2150); }
		case 2012 { @contSR = (2151, 2160); }
		case 2013 { @contSR = (2161, 2170); }
		case 2014 { @contSR = (2171, 2180); }
		case 2015 { @contSR = (2181, 2190); }
		case 2016 { @contSR = (2191, 2200); } # >= Secrets of Faydwer only
		case 2017 { @contSR = (2201, 2210); } # >= Secrets of Faydwer only
		case 2018 { @contSR = (2211, 2220); } # >= Secrets of Faydwer only
		case 2019 { @contSR = (2221, 2230); } # >= Secrets of Faydwer only
		case 2020 { @contSR = (2231, 2240); } # >= Secrets of Faydwer only
		case 2021 { @contSR = (2241, 2250); } # >= Secrets of Faydwer only
		case 2022 { @contSR = (2251, 2260); } # >= Secrets of Faydwer only
		case 2023 { @contSR = (2261, 2270); } # >= Secrets of Faydwer only
		# 2500-2501 are shared bank slots
		case 2500 { @contSR = (2531, 2540); }
		case 2501 { @contSR = (2541, 2550); }
		# 3000-3007 are character trade slots
		case 3000 { @contSR = (3031, 3040); }
		case 3001 { @contSR = (3041, 3050); }
		case 3002 { @contSR = (3051, 3060); }
		case 3003 { @contSR = (3061, 3070); }
		case 3004 { @contSR = (3071, 3080); }
		case 3005 { @contSR = (3081, 3090); }
		case 3006 { @contSR = (3091, 3100); }
		case 3007 { @contSR = (3101, 3200); }
		# 4000-???? are tradeskill slots
	}

	return @contSR;
}

# 'helper' function for plugin::check_hasitem()
sub HasItem_search
{
	my $client = shift;				# client object
	my $findID = shift;				# itemID to find
	my @slotIR =(shift..shift);			# slotID range to check
	my $checkC = 0;					# check for containers?
	   $checkC = shift if defined($_[0]);
	my $itemID = INVALID_ID;			# default value

	# loop through specified slotID range
	for my $slotID(@slotIR)
	{
		$itemID = $client->GetItemIDAt($slotID);
		# don't check container or aug slots if no item was found
		next if $itemID == INVALID_ID;
		return 1 if $itemID == $findID;
		# check inside if item is a container
		if($checkC && $client->GetItemAt($slotID)->IsType(1))
		{
			my @bRange = getContainerRange($client, $slotID);
			my @search = ($client, $findID, $bRange[0], $bRange[1]);
			return 1 if HasItem_search(@search);
		}
		# check aug slots if not a container or book
		elsif(!$client->GetItemAt($slotID)->IsType(2))
		{
			foreach my $augID(0..4)
			{
				$itemID = $client->GetAugmentIDAt($slotID, $augID);
				return 1 if($itemID == $findID);
			}
		}
	}

	return 0;
}

# TO DO
sub HasItem_corpse
{
}

# usage: plugin::check_hasitem($client, itemID, [$lookIn]);
sub check_hasitem
{
	# get client info
	my $client = shift;
	my $verBit = $client->GetClientVersionBit();
	my $hasSoF = ($verBit & BIT_SoFAndLater) ? 1 : 0;

	# itemID to find
	my $findID = shift;

	# inventory buckets to search
	# default to all but shared
	my $lookIn = 55;
	   $lookIn = shift if defined($_[0]);

	# lower/upper slot num to search
	my $lRange = -1; my $uRange = -1;

	# arguments for HasItem_search
	my @search = ($client, $findID, $lRange, $uRange);

	# check worn inventory slots
	if($lookIn & invWhereWorn)
	{
		$search[-2] = 0; $search[-1] = 21;
		return 1 if(HasItem_search(@search));
	}

	# check for containers from now on
	push(@search, 1);

	# check personal inventory slots
	if($lookIn & invWherePersonal)
	{
		$search[-3] = 22; $search[-2] = 29;
		return 1 if(HasItem_search(@search));
	}

	# check cursor inventory slots
	if($lookIn & invWhereCursor)
	{
		$search[-3] = 30; $search[-2] = 30;
		return 1 if(HasItem_search(@search));
	}

	# check bank invenory slots
	if($lookIn & invWhereBank)
	{
		$search[-3] = 2000; $search[-2] = 2015;
		$search[-2] = 2023 if($hasSoF);
		return 1 if(HasItem_search(@search));
	}

	# check shared bank inventory slots
	if($lookIn & invWhereSharedBank)
	{
		$search[-3] = 2500; $search[-2] = 2501;
		return 1 if(HasItem_search(@search));
	}

	# check character trade slots
	if($lookin & invWhereTrading)
	{
		$search[-3] = 3000; $search[-2] = 3007;
		return 1 if(HasItem_search(@search));
	}

	# check all corpses
	# NOTE: This makes a database read for the itemID 31 times for each corpse!
	if($lookin & invWhereCorpse)
	{
		# my $bodCount = $client->GetCorpseCount();
		# return 0 if(!$bodCount);
		# for (my $bodNum = 1; $bodNum <= $bodCount; $bodNum++)
		# {
		# 	return 1 if(HasItem_corpse());
		# }
	}

	return 0;
}

1;
__________________
I muck about @ The Forge.
say(rand 99>49?'try '.('0x'.join '',map{unpack 'H*',chr rand 256}1..2):'incoherent nonsense')while our $Noport=1;
Reply With Quote