Usecode to find item carrier?

NOTICE: This forum is archived as read only.
Please use the Github Discussions at https://github.com/exult/exult/discussions
Forum rules
NOTICE: This forum is archived as read only.
Please use the Github Discussions at https://github.com/exult/exult/discussions
Locked
Knight Captain
Posts: 1219
Joined: Thu May 14, 2020 1:34 pm

Usecode to find item carrier?

Post by Knight Captain »

How can I use Usecode to find who is holding an item? Let's say I want to find a bag with a specific quality, how would I do that in SI? The command get_cont_items does not work with PARTY.
Knight Captain
Posts: 1219
Joined: Thu May 14, 2020 1:34 pm

Re: Usecode to find item carrier?

Post by Knight Captain »

I want to find the specific NPC.
marzo
Site Admin
Posts: 1925
Joined: Thu May 14, 2020 1:34 pm

Re: Usecode to find item carrier?

Post by marzo »

Read the description of get_cont_items; does it sound like what you need? No, it does not.

Now check get_container. I suppose this one should be changed to say it gets the immediate container; but in any event, you can loop it until you get an object without a container. This is common enouh that the original games had a function to do it; I think it is called getOuterContainer, and it is defined in headers/si_externals.uc.
------
Marzo Sette Torres Junior
aka Geometrodynamic Dragon
[url=http://www.catb.org/~esr/faqs/smart-questions.html]How To Ask Questions The Smart Way[/url]
Knight Captain
Posts: 1219
Joined: Thu May 14, 2020 1:34 pm

Re: Usecode to find item carrier?

Post by Knight Captain »

How do I check that getOuterContainer has given the outermost container?
marzo
Site Admin
Posts: 1925
Joined: Thu May 14, 2020 1:34 pm

Re: Usecode to find item carrier?

Post by marzo »

... that is what the function does... if it fails to give the outermost container, then something is VERY wrong, and you should just close Exult and start it again. And if it keeps happening, file a bug report. Seriously, you don't need to check it; it returns either zero if the object is directly in the map or the container that sits directly in the map which contains the item. It never fails.

If you want tto know how it works, on the other hand, it loops over the get_container intrinsic until it finds a zero, and retur s the last nonzero container.
------
Marzo Sette Torres Junior
aka Geometrodynamic Dragon
[url=http://www.catb.org/~esr/faqs/smart-questions.html]How To Ask Questions The Smart Way[/url]
Knight Captain
Posts: 1219
Joined: Thu May 14, 2020 1:34 pm

Re: Usecode to find item carrier?

Post by Knight Captain »

Ah, I was thinking it would return the NPC value if that is what was holding the container. It doesn't seem like there's a way to determine which party NPC is holding something?
Donfrow
Posts: 308
Joined: Thu May 14, 2020 1:34 pm

Re: Usecode to find item carrier?

Post by Donfrow »

Would it work if you used UI_get_party_list to get an array of all the party members, and then loop through each element in the array and use UI_count_objects? That way you could check every party member one by one, and if you get a return on UI_count_objects > 0 (or whatever count criteria you need) you would know the element value(party member) has the object with the desired frame and quality?
Knight Captain
Posts: 1219
Joined: Thu May 14, 2020 1:34 pm

Re: Usecode to find item carrier?

Post by Knight Captain »

The command get_cont_items not working with PARTY bit me again today. I'm going to write my own function to return an array of the items.

Funny that it's almost exactly 2 years later, thread-wise.
Knight Captain
Posts: 1219
Joined: Thu May 14, 2020 1:34 pm

Re: Usecode to find item carrier?

Post by Knight Captain »

I've put in a bug for having UCC warn on this illegal command:
https://sourceforge.net/p/exult/bugs/2032/
Knight Captain
Posts: 1219
Joined: Thu May 14, 2020 1:34 pm

Re: Usecode to find item carrier?

Post by Knight Captain »

Here's the fix via Usecode:

Code: Select all

/*
 *	The standard UI_get_cont_items command cannot be used to search the entire Party.
 *	This is problematic if you wish to get an array of each of a shape carried by the Party,
 *	using a single command.
 *
 *	2018-12-23 Knight Captain
 */

var getPartyItems 0x9D8 (var shape, var quality, var frame)
{
	var count;
	var party;
	var each_member;
	var index;
	var max;
	var member_name;
	var found;

	// Check if the party has any of the item. If not, there is no need to continue.
	count = UI_count_objects(PARTY, shape, quality, frame);
	if (count == 0)
	{
		UI_error_message("getPartyItems The Party has none of Shape ", shape, " Quality ", quality, " Frame ", frame, ".");
		return 0;
	}

	// Documentation does not describe a difference between versions list and list2.
	party = UI_get_party_list();

	UI_error_message("getPartyItems counted ", count, " of Shape ", shape, " Quality ", quality, " Frame ", frame, " in the Party.");
	
	for (each_member in party with index to max)
	{
		member_name = UI_get_npc_name(each_member);
		count = UI_count_objects(each_member, shape, quality, frame);
		if (count == 0)
		{
			UI_error_message("getPartyItems ", member_name, " has none.");
		}
		else
		{
			UI_error_message("getPartyItems ", member_name, " has ", count, ".");
			// This check is necessary to prevent a non-existent "found" being counted by UI_get_array_size below.
			if (found == 0)
				found = (UI_get_cont_items(each_member, shape, quality, frame));
			else
				found = (found & UI_get_cont_items(each_member, shape, quality, frame));
		}
	}

	count = UI_get_array_size(found);
	if (quality == -359)
		quality = "ANY";
	if (frame == -359)
		frame = "ANY";
	UI_error_message("getPartyItems has ", count, " of Shape ", shape, " Quality ", quality, " Frame ", frame, " in the array.");
	
	return found;
}
Locked