A book to store the scrolls

hi, everyone

may I ask if there’s a book that will store all the scrolls I got automaticlly? Somthing like the recipt book in SOZ?

interesting mod but i don’t believe there is one.

The Nwn2 toolset allows a “preferred container” to be set on each item (scroll) … so someone would have to go through all the scrolls and set their preferred container, then create said container …

but it seems possible

2 Likes

I have an auto-store recipe book system (for the various types) in my module, The Scroll. NB: You have to buy each recipe book type you require to store your scrolls that you find. Once carried, any valid scroll for that recipe book that you find (by any PC) automatically gets stored in that recipe book.

But, as @kevL_s says, the module itself has to be written and designed to work in such a way for such auto-storage. I am not aware of any module, other than my own, that automates this “auto-collection” as I do. It is quite an involved system and one that has required some alterations over the years before I felt it worked well. In The Scroll, there are currently five recipe books available for such auto collection:

image

Therefore, the auto-storing of “Spell Scrolls” would have to be setup in a similar manner with its own dedicated container. (Although, see simplified approach towards the end of this post, when not using “preferred” containers.)

I did consider adding such a container (for spell scrolls only) for The Scroll. However, one thing to bear in mind with Spell Scrolls, is that a PC will NOT automatically try to use it when in combat if it is within a container and using AI. This is one reason I currently do not automate such storage, and may also be why such a system has not yet been done.

I note that I have already allocated a container preference as “Scroll Case” for every scroll, but have not constructed that container item. This means I likely abandoned the idea due to either what I say above (regarding the scrolls being unavailable for AI combat when stored this way), or the container item did not work as expected. That was done some time ago though, and may be something I can look again in the future, depending upon time. I have a vague recollection that the number of “dedicated preferred” container items we can use may have been limited in some way. :thinking: If this is the case, then I believe we can use the same “container” but with a different tag to help determine which items go where. E.g. We may be able to use the “Gem Bag” container preference, but with a different tag ref to have all spell scrolls be sent to that new item with that container preference. The only downside would be that you would be able to place the same spell scrolls in a gem bag (and vice-versa).

However, all of this is possibly not a problem, if we just want to assume a single dedicated item container (E.g. Bag or Scroll Case) where Spell Scrolls are simply placed into it.

Bottom line: There may not be any item restriction for such a container, but a system can be used to ensure spell scrolls are placed within a certain container.

Theoretically Example (Based around something similar to what I currently do):

Check in OnAcquire for acquiring a Spell Scroll (Base Item 75), and check for a container with tag “SPELL_CASE”. (No need for any real preferred settings in this case.) Have scroll copied into container on conditions met. (Original destroyed.) NB: There can be other methods using “GiveTo” functions, but these also have other conditions that need to be considered.

However, depending upon some other potential variables being set or used, this can become a potential issue because scrolls can stack. Coding around stacking can raise its own issues, especially if we have any differing variables involved with the scroll item itself.

2 Likes

I think there’s a 2da and it maxes at 256 entries … ie. 256 possible “preferred containers” (roughly)

Reserved 2da ranges | NWN2Wiki | Fandom ← Container_Preference.2da

2 Likes

@kevL_s

I may be completely wrong here, as this is something I was trying to sort years ago, and I may just have got it wrong …

If I recall correctly, I was trying to setup some new “preferred containers” above and beyond what we already had in the “container_preference.2da”. I did successfully add these new references, but (and this is the bit that gets rather hazy to recall), I believe I was unable to have the items work with the new container refs.

But, as I say, that was back in the very early days, and I may have just missed something back then. I mean, I was using an existing entry at the time “Scroll Case”, and so that should have just worked like the others I eventually setup. :thinking:

I might just do a quick test to see how the pages work now. As I say in the previous post, I may have abandoned auto-storage of spell scrolls for another reason to what I think I am remembering. I’ll edit this post if I have any sudden recollections from the testing I’ll now try.

EDIT: Actually, it may have been due to the limited screen container UIs available to us … maybe that limited me somehow? :thinking: I 'll do a test or two …

image

EDIT: OK, after doing a quick basic test, scrolls with the Scroll Case “preferred” container do work with such a container setup fine. i.e. A container with the “Scroll Case” ref only allows scrolls with the “Scroll Case” preferred container to be placed within it.

:thinking: So, I can only conclude that it was due to another reason I abandoned the auto-collection of spell scrolls into a container - not sure why at the moment - Therefore, I may well add a “preferred” container for these items in The Scroll and add the “auto-collection” code, just because the code is pretty much setup this way for other items already.

So, while this may not help the OP much if they are playing another module, they may gain from it in the future if they ever decide to play my module, I guess. :slight_smile:

EDIT: Although, another point I just considered is that scrolls obviously vary in class usage, and so having a process automate collection may become somewhat difficult to manage as each PC will want their own spell scrolls… Hmm, maybe this is what I finally concluded and had to drop the idea … i.e. It’s potentially a lot more time consuming and open to interpretation rather than a simple all items of “X” type go here. I’ll put this “on the burner” as a potential look at after other priorities have been dealt with for now. :thinking:

@Denver_li

TLDR: Spell scrolls vary in class and usage and so automating an auto-collect system is open to error in allocation, especially if controlling more than one PC with access to the same spell-casting ability. It’s better to have the spells go to the inventory of the initial collector and then have the collector allocate them to the correct PCs after collecting. You could even have each PC who uses scrolls have their own “bag” for holding such to which the collector can place (or not if we want the AI to try using them). If you are just hoarding your finds to sell (and not use), then be ready to move any you find into a “junk bag” you may have bought for the purpose.

1 Like

You can try to put this in your override: AutoCollector.7z (3.0 KB)

In game, open the debug menu and type “giveitem [itemcode]” to create your desired container(s), with possible item codes being:
ac_it_arrow_quiver
ac_it_bolt_quiver
ac_it_bullet_pouch
ac_it_scroll_case
ac_it_potion_bag
ac_it_gem_bag
ac_it_trap_kit_bag

When any of these types of items are acquired, it’ll attempt to put the item in the appropriate bag. Note that the bags will store any kind of item, but the script will only attempt to place them in one of the appropriate kind. I didn’t test it thoroughly, but it seems to work acceptably.

2 Likes

Go on the nexus and download a campaign call 'the “Demon Artifact”.
IIRC they use multiple preferred containers. Might have some material you can reuse.

@Akhacha

Neat. :slight_smile:

Did you happen to find these items in the game files already, or did you just make them?

I also took a quick look over your script. I was wondering if you may have some issues with the multiple loops and an increased number of items… especially if a PC “loots all” from a chest with a number of items in it?

Have you been able to test the script with a party of PCs and a multi item loot?

Also, it may be safer using the GetItemPossessedBy function to get the bag if you make the assumption that the potential bag owner is only going to be the one who does the picking up. Using the dedicated function rather than another loop may help here.

It may also be prudent to lose the GetContainerHasSpace function, because of potentially looting multiple items, which I imagine may cause a “Too Many Instructions” or simply fail - but that needs testing according to how many items are grabbed at a go. I.e. just make the assumption that if the bag is full… test to see what happens otherwise. Hopefully, it just gets dropped back to the owner.

There may be some stacking an/or other variable points to consider, but that would need closer attention to see if it impacts or not.

EDIT: Also, you may want to consider restricting the number of these containers to one per party, or it can also potentially get a little weird in distribution.

Here is what I mean …

//::///////////////////////////////////////////////
//:: Example XP2 OnItemAcquireScript
//:: x2_mod_def_aqu
//:: (c) 2003 Bioware Corp.
//:://////////////////////////////////////////////
/*
    Put into: OnItemAcquire Event

*/
//:://////////////////////////////////////////////
//:: Created By: Georg Zoeller
//:: Created On: 2003-07-16
//:://////////////////////////////////////////////

#include "x2_inc_switches"

int GetContainerHasSpace(object oContainer);
void PlaceInContainer(object oItem);

void main()
{
     object oItem = GetModuleItemAcquired();
	 PlaceInContainer(oItem);
     // * Generic Item Script Execution Code
     // * If MODULE_SWITCH_EXECUTE_TAGBASED_SCRIPTS is set to TRUE on the module,
     // * it will execute a script that has the same name as the item's tag
     // * inside this script you can manage scripts for all events by checking against
     // * GetUserDefinedItemEventNumber(). See x2_it_example.nss
     if (GetModuleSwitchValue(MODULE_SWITCH_ENABLE_TAGBASED_SCRIPTS) == TRUE)
     {
        SetUserDefinedItemEventNumber(X2_ITEM_EVENT_ACQUIRE);
        int nRet =   ExecuteScriptAndReturnInt(GetUserDefinedItemEventScriptName(oItem),OBJECT_SELF);
        if (nRet == X2_EXECUTE_SCRIPT_END)
        {
           return;
        }

     }
}

/*int GetContainerHasSpace(object oContainer)
{
	if (GetHasInventory(oContainer))
	{
		int i;
		object oItem = GetFirstItemInInventory(oContainer);
		while (GetIsObjectValid(oItem))
		{
			i++;
			oItem = GetNextItemInInventory(oContainer);
		}
		if (i < 142)
			return TRUE;
	}
	return FALSE;
}*/

void PlaceInContainer(object oItem)
{
	object oPC = GetModuleItemAcquiredBy();
	if (!GetIsPC(oPC))
		return;
	int nBaseItemType = GetBaseItemType(oItem);
	string sTag;
	
	switch (nBaseItemType)
	{
		case BASE_ITEM_ARROW: sTag = "ac_it_arrow_quiver"; break;
		case BASE_ITEM_BOLT: sTag = "ac_it_bolt_quiver"; break;
		case BASE_ITEM_BULLET: sTag = "ac_it_bullet_pouch"; break;
		case BASE_ITEM_SPELLSCROLL: sTag = "ac_it_scroll_case"; break;
		case BASE_ITEM_POTIONS: sTag = "ac_it_potion_bag"; break;
		case BASE_ITEM_GEM : sTag = "ac_it_gem_bag"; break;
		case BASE_ITEM_TRAPKIT: sTag = "ac_it_trap_kit_bag"; break;
		default: return;
	}
	
	object oContainer = GetItemPossessedBy(oPC, sTag);
	
	if(oContainer != OBJECT_INVALID)
	{
		AssignCommand(oPC, ActionGiveItem(oItem, oContainer));	
	}
	
/*	int i;
	object oContainer = GetObjectByTag(sTag, i);
	while (GetIsObjectValid(oContainer))
	{
		if (GetItemPossessor(oContainer) == oPC
			&& GetContainerHasSpace(oContainer))
			break;
		else
		{
			i++;
			oContainer = GetObjectByTag(sTag, i);
		}
	}
	
	if (GetIsObjectValid(oContainer))
		AssignCommand(oPC, ActionGiveItem(oItem, oContainer));*/
}
1 Like

Some of the bags existed as un-implemented and non-functional items in SoZ, so I borrowed the icons and StrRefs for names/descriptions, but other than that, they’re all new.

The script should fire once for each item acquired, so running into the instruction cap is unlikely - I have another script that does something similar, checking for space, with a few other added things, and it ends up failing around 43~44 full containers worth of items, which is far more than most people will ever have. Given that this script has less going on in it, it should have even more leeway.

If you mean in multiplayer, then no, if you just mean a regular single player party, then yes, and I saw no issues, but I also didn’t test it thoroughly.

I’ve tested with multiple containers, and there’s no major problems, only issue is that it will add to the newest container rather than one that may be half full, but I don’t personally consider that a big enough problem to address. I feel that’s more of a player inventory management issue.

1 Like

@Akhacha

Neat - I’ll check for some of these icons then, as they may be useful if I consider doing something similar.

A chest with, say, five items grabbed with “loot all” firing the OnAcquire (with all those loops) five times in quick succession? If items already stored away are many, I was just considering if that caused any issues?

Maybe I have misunderstood this a bit. :thinking: If it fails at a figure lower than its max anyway, is there much point checking it then? If need be, however, I suppose it may be possible to cache the current content figure on the first loop? :thinking: Or, maybe even have it calculate the figure just prior the move if space is available? Those thoughts aside, do you know what the result is if the ActionGiveItem fails due to the bag being full? Does it just remain in the PCs inventory? If so, then, maybe the check is not even required? (I’ve never filled a container to its limit to test. :sweat_smile: )

I may go and play with some tests here and see what happens. Thankfully, (on initial looking) these containers appear less demanding than what I currently have arranged with the recipe books setup, and so maybe I can ignore some of the more specific issues I have with those, by comparison.

MY FINAL VERSION OF THE FUNCTION:

/////////////////////////////////////////////////////////////////////////////////
// AUTO-STORE ITEM IF SPECIAL CONTAINERS FOR SUCH ARE CARRIED BY THE ACQUIRER
/////////////////////////////////////////////////////////////////////////////////
void CheckAutoStoreItem(object oPC, object oItem);
void CheckAutoStoreItem(object oPC, object oItem)
{	
	if (!GetIsPC(oPC)){return;}
	
	string sTag;
	
	switch(GetBaseItemType(oItem))
	{
		case BASE_ITEM_ARROW: sTag = "ac_it_arrow_quiver"; break;
		case BASE_ITEM_BOLT: sTag = "ac_it_bolt_quiver"; break;
		case BASE_ITEM_BULLET: sTag = "ac_it_bullet_pouch"; break;
		case BASE_ITEM_SPELLSCROLL: sTag = "ac_it_scroll_case"; break;
		case BASE_ITEM_POTIONS: sTag = "ac_it_potion_bag"; break;
		//case BASE_ITEM_GEM : sTag = "ac_it_gem_bag"; break;
		case BASE_ITEM_TRAPKIT: sTag = "ac_it_trap_kit_bag"; break;
		default: return;
	}
	
	object oContainer = GetItemPossessedBy(oPC, sTag);
	
	if(oContainer != OBJECT_INVALID)
	{
		AssignCommand(oPC, ActionGiveItem(oItem, oContainer));	
	}
}

EDIT: OK, I did a test and there is no need to test if the bag is full (as far as I can see), as the item simply stays within the inventory if there is no more room in its container target. (I tested both your own script and my own and had the same results.) I was pleasantly surprised that the loops were handled OK, as you say. So, this looks like it may well be another update as items to buy for The Scroll campaign. The only one that I won’t include is the “Gem Bag”, as that clashes with my party “Treasure Bag”, which I use to auto-store all treasures to it, from any PC collector, not just the Treasure Bag owner. The remaining containers, however, would fit well as individual PC containers of these other items… even the Scroll Case (the original posters request) can be included, assuming the player understands its operation, and remembers to remove/give scrolls to any an individual that a PC may collect.

I will likely add the “Preferred” check for each container (and associated items), so that the containers remain item specific.

QUESTION: Does ammo that is held in a bag automatically get taken out and used when ammo runs out during combat? Or, will it work like “Spell Scrolls”, in that any ammo held in these bags is ignored when it comes to restocking the ammo slots? My guess is that it will be ignored (like Spell Scrolls), but as long as the player is aware of this caveat, then I reckon these still act as a good way of keeping inventories cleaner. I’ll have my wife run through some testing with what I implement myself, but just wondered if anyone already had an answer about how ammo is handled when in a container of some kind.

2 Likes

The point of checking space of container wasn’t because I was worried about what would happen if it was full, but because if a container is full and you have multiple ones, it might attempt to put items in the full container, rather than one that does have space, as would be desired. If you’re limiting the player to just one container, then sure, there’s no reason for it.

1 Like

@Akhacha

Ha! I just went to edit my post to say that I realised that you might be accommodating a full (and multiple) containers of the same type on the PC, and I find your post. :+1:

I don’t think I have ever filled a single container in my gaming history, but as I was going over stuff in my head last night I ran into that scenario and that was when I realised why you checked. As you say, I don’t expect one of these containers to ever get filled (especially if I limit what goes in the containers), and so don’t think it should be a problem. As my ammunition weighs, the PC would likely grind to a halt with weight before filling the container. There are also, for example, not enough ammunition types to fill every container slot - so it would require multiple bundles of the same ammo before it became filled. :slight_smile:

Here is my test dwarf ABULLY carrying nearly 7000 arrows in one container… and he is well over his weight limit. (I also allow stacks of 50 for ammunition types.)

3 Likes