Script Help 2: Getting Object info when in Container Inv

Post » Thu Feb 16, 2017 12:05 am

a problem i have tried to solve more than once. how to get an object's info, any unique, identifiable info, from within a container namely Player's inventory.


the biggest issue ofc is container to inventory (container to container) transfers. The one solution I keep coming back to is somehow having a script or quest w/ script running constantly on the player that has an inventory filter only for the items i specify. this does not appear to be a good idea.


So here's what for sure doesn't work for future reference:



Spoiler

Scenario: You have a letter (book object) in your inventory and a script attached to that letter with an OnRead Event:


no native functions will work on the item in the inventory because its not really an item when its in the inventory, just an index in a linked list. Afaik, there's no way to tell what that index actually is perhaps without SKSE (which i can't use (sse)).


so things like Debug.Trace(self) ; Debug.Trace(self.GetBaseObject()) ; Debug.Trace( (self as Form).HasKeyword(MyKeyword))

will not work obviously.

http://www.creationkit.com/index.php?title=Form_Script

http://www.creationkit.com/index.php?title=ObjectReference_Script




what may work:


Spoiler

http://www.creationkit.com/index.php?title=OnItemAdded_-_ObjectReference


::Event received when an item is inserted into this object's container.


Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)


The actual Form (akBaseItem) of the ObjectReference is passed in to this event, along with the actual ObjectReference (akItemReference)


then use an Inventory filter via a FormList of only the items you want to check for.


Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)

AddInventoryEventFilter(myFormListProperty)

;do something

endEvent




I'm assuming the inventory filter iterates through every item added, that seems to me it could potentially cause slow downs if i had some quest/script running all the time just to check for my unique items. Another thought, however unfeasible, could be removing the item to a particular dummy cell, getting some unique info, then returning it to the player's inventory.


edit: i want to also ask what the feasibility of adding hundreds of small scripts is? ultimately that's what im looking at, i have to make 500+ custom book objects and attach each one with a unique small script if i can't create a master script for every book objects.
User avatar
victoria gillis
 
Posts: 3329
Joined: Wed Jan 10, 2007 7:50 pm

Post » Thu Feb 16, 2017 8:44 am

I found an old post from cdcooley on this topic, just so it doesn't get reiterated:




Spoiler

As long as the container is a specific real container there is a non-SKSE way. (Technically it works on actors and even the player, but there are side-effects in those cases.)


Put a script on the container with an OnItemAdded event that does whatever you're wanting to do to the items as they are added to the container. You can use AddInventoryEventFilter with your formlist so that OnItemAdded ignores all items that aren't in the formlist.


If you need to do the processing a some other arbitrary time, you can have a second container with the scripts that does the actions then moves the items back to the original container. (But in that case you can't optimize with AddInventoryEventFilter since you'll want all of the items to get back to the original container.)


The reason you generally don't want to use this on NPCs and the player is that it will strip them of everything temporarily. And in the case of the player, once you take equipped items they are a pain to try an re-equip via script. (And there's the user enchantment bug even if you do.)


User avatar
Glu Glu
 
Posts: 3352
Joined: Sun Apr 01, 2007 5:39 am

Post » Thu Feb 16, 2017 6:08 am

Let's make this easy. Describe how you want things to work and I'll see if I can tell you how you can do it. Think in terms of what you want the player to do and see.



Depending on whether you want to take action based on items moving between containers, items being dropped into the game world, items being picked up, the player reading books, characters equipping items, etc. there are different techniques that can be used.



And what you will do in response to the player's action also matters. Opening a menu whenever the player drops an item is very different than simply changing a variable in a script when the player tries to read a book.




As an example of what's possible here's part of a script for my new Portable Containers mod I'm getting ready to release. The script is attached to Armor objects that the player can craft. Each item can be equipped normally but if the player tries to unequip it (from the inventory menu or via hotkey) it will open a remote container. Actually unequipping the item can be done by dropping it or placing it in a container. Once it's dropped activating it will also open the remote container. The player can pick it up by holding the activate button to drag it (without actually moving it). Because the script is on the item itself I had to use a Token property filled with the object's own base type. Otherwise the OnUnequipped and OnContainerChanged events don't have any way to know which of the remote containers to access. And one special item pops up a configuration menu when it's crafted because I monitor for it being added to player inventory in the OnContainerChanged event.



Spoiler


ScriptName CDC_PCTokenScript extends ObjectReference
{Attach to Armor token objects representing portable containers.}

CDC_PCQuestScript Property CDC_PortableContainers Auto
Actor Property PlayerRef Auto
Armor Property Token Auto
{Property needed because inventory objects can't use GetBaseObject() reliably.}


Event OnLoad()
{Allow complex actions for activate and grab by blocking the defaults.}
BlockActivation()
EndEvent


Event OnActivate(ObjectReference akActionRef)
{Simple activation by the player opens it as a container, but NPCs can only pick it up.}
if akActionRef == PlayerRef
AccessContents()
else
Activate(akActionRef, true)
endif
EndEvent


Event OnGrab()
{Allow player to move it around normally or to pick it up based on whether it was moved (or AlwaysGrab mode is set).}
float px = GetPositionX()
float py = GetPositionY()
float pz = GetPositionZ()
Utility.Wait(0.1)
if CDC_PortableContainers.AlwaysGrab || (px == GetPositionX() && py == GetPositionY() && pz == GetPositionZ())
Activate(PlayerRef, true)
endif
EndEvent


Event OnUnequipped(Actor akActor)
{When player tries to unequip it, access the contents instead. Dropping it or putting it in a container will unequip it.}
if akActor == PlayerRef && PlayerRef.GetItemCount(Token) > 0
if Utility.IsInMenuMode()
Game.DisablePlayerControls() ; this closes inventory but not container menus which is exactly what is needed
Game.EnablePlayerControls()
endif
AccessContents() ; and re-equip it automatically
endif
EndEvent


Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
{Handle various events related to the token being created, dropped, picked up, or transferred between containers.}

; Don't allow tokens to be placed into the remote containers. (Avoids loss of access and weight calculations are simplified.)
if akNewContainer && CDC_PortableContainers.CDC_PCRef.Find(akNewContainer) >= 0
akNewContainer.RemoveItem(Token, 1, true, akOldContainer)

; Show the configuration menu token whenever the special config token gets crafted.
elseif !akOldContainer && akNewContainer == PlayerRef && CDC_PortableContainers.CDC_PCToken.Find(Token) < 0
CDC_PortableContainers.Configure()
PlayerRef.RemoveItem(Token)



User avatar
Josh Lozier
 
Posts: 3490
Joined: Tue Nov 27, 2007 5:20 pm

Post » Wed Feb 15, 2017 7:48 pm

I've got one other though. If this is really about configuration whether items will appear on the crafting menu and you're planning for configuration of individual items instead of groups of items then one possible configuration system would involve two specially scripted containers and a simple configuration menu. The menu would allow you to choose between enabling and disabling items and open one of the two containers. The crafting recipes could check whether an item is in the "active" container or not. Initially you would place one of each item in either the "active" or "inactive" container. Then when the player access one of the containers and tries to take on of the items it gets moved into the other container instead. (In an ideal world the player would simply be able to transfer items between the containers directly but unfortunately the game doesn't support that.)

User avatar
Carlitos Avila
 
Posts: 3438
Joined: Fri Sep 21, 2007 3:05 pm

Post » Wed Feb 15, 2017 6:45 pm

so what I'm doing is basically morrowloot for crafting. you have to have a schematic / blueprint (like in Witcher 3). So i'm doing practically every craftable item in the game.



I have now reached the conclusion that I am not going to try and change the variable through actually 'reading' the schematic like we talked about in the last thread, (because its impossible to get any information about an item in the player's inventory, like you said years ago that i quoted above).



instead going off on what you said, i'm just going to go with plan b, which is to use the Hearthfire Drafting Table (new textures) as a container.



Tell me what you think about this, i wanted a system where you could remove a schematic and thereby change the properties back to zero so this could keep your crafting menu much less cluttered. i think with making the drafting table as a container I might be able to just dump in the schematics, which will then allow me to iterate through an array and match it to the many properties in Script A. (through an OnItemAdded Event on the Drafting Container)



I feel like this is a little inelegant though, and having the player have to open the Drafting Table and remove a diagram, which will be one of hundreds, and then place it somewhere else for keeping it out of the Forge Menu is a little disappointing. (unless there was some way to create submenus like in the Forge Menu)



Your idea about using two containers, I like. its the menu part that I initially passed on to deal with the schematics, because i have no idea how that would even work with so many. It's too bad we can't create custom menu modes.



Your mod is on another level than what I'm trying to do, i'm just trying to keep perspective due to the sheer amount of recipes that will have to be dealt with. for the most part the mod should be fairly simple to execute, its how I'm supposed to make this user friendly.

User avatar
Prohibited
 
Posts: 3293
Joined: Tue Jun 12, 2007 6:13 am

Post » Wed Feb 15, 2017 6:13 pm

I assume the schematics will be added to various leveled lists and vendor inventories. I'm afraid you're right that a few hundred of those is going to be a management challenge for the player.



The more I think about this the more certain I am that you want to use one or more "Active Schematics" containers that can hold the actual schematic objects. If you filter the crafting recipes using the "GetItemCount" condition function on those containers you don't need scripts on the schematics or any mapping of schematic objects to variables. That will save you quite a bit of work.




The very simplest implementation would be to create a single (persistent) "Crafting Schematics" container and make the player place schematics in it to make them active. Of course it would be better if you provide a way for the player to access that container from anywhere. You could use a lesser power, but that seems wrong for a crafting system. You can also make a craftable token object that activates the remote container. It could either open the container as soon as it's crafted and then delete itself or you can make it an object the player can carry around for later. (If it's craftable the player could make multiples and stash them near various crafting stations.)



I just happen to have a custom "book" mesh that I didn't end up using that might be perfect for the access token. It's a combination of a knapsack and folded note that expands just like any other note when read and can be dropped. (If you want it you'll find it in https://www.dropbox.com/sh/usf77ua06h1qh8k/AAA64msQbDbTfe3URb0mmC9Qa?dl=0. It's a SSE mesh but I think you said you're working on this as an SSE mod.) You can easily script it to remotely activate the persistent container when read, dropped, etc.



Personally I would also script the container to reject any object that isn't a schematic because it will already be cluttered enough without adding other things.



You could also create a matching "Unused Schematics" container and access token if you wanted to give the player a place to store the leftovers. If the access token is craftable it would be the player's choice whether to use it, some other container, to sell the unwanted schematics, or even just drop them somewhere.




To address the problem of 500+ schematics in one place you could use a (reasonably small) set of active schematic containers instead of just one. The trick is to pick just a few obvious categories so the player won't be confused about where to put (or find) the schematics. Then you have the "Crafting Schematics" token object show a menu and let the player choose which of the containers to access. If you want the system to be fool-proof you can use an auto-sorting script on each of the containers so that they shift schematics over to the right one if the player makes a mistake.



You can track which containers belong in which container either by keyword or with formlists. If you were going to use keywords to help control which vendors might buy and sell the items then that's the obvious choice, but if not adding large numbers of items to formlists is pretty easy in the CK.

User avatar
Angela
 
Posts: 3492
Joined: Mon Mar 05, 2007 8:33 am

Post » Thu Feb 16, 2017 7:16 am

yes schematics will be gotten through leveled lists, blacksmith vendors, and some random placements loosely following morrowloot.



I was thinking I'd put a drafting table at every major blacksmith. I like the idea of having the token be able to access the container, and maybe use your token to access a menu with the different base type (iron, steel,etc) containers. So have a Master with just a dump, then create copies of the schematics that go into a sorted container accessed through the token. the token with menu sounds like a good way to organize the schematics that show up in the forge on the fly from anywhere. Drafting tables can just be a simple Master container so you can quickly dump schematics there. Although I like the idea of having to actually access the Drafting Table to "learn" the schematics in the first place. I'll see how feasible it is to juggle that.



I guess it wouldn't be impossible to OnItemRemoved send them to a separate container that removes them from the Forge Menu but is still accessible from the token menu so you could send them back to the Master container any time. (and keep them out of the player's inventory entirely)



I was thinking about implementing a sort of pin board with the Dragon Symbols with different textures when you collect all the recipes for a particular type like DragonBone.



Maybe instead of just dragon pins, they could be small containers in a cubby that house the different schematics. with a faint glow representing when you have them all. But maybe this should only be on a drafting table that the Player crafts.



very good ideas, thanks. I"m always open to more :D

User avatar
Daramis McGee
 
Posts: 3378
Joined: Mon Sep 03, 2007 10:47 am

Post » Thu Feb 16, 2017 8:28 am

Properties ScriptA :



http://pastebin.com/Kqe2P7XT



psc file:


https://drive.google.com/open?id=0B858bpwZmkmia0JzQ2xqT2RCcFU



Controller for Main Container (on Drafting Table) :




http://pastebin.com/bSsjq0NB



psc file:


https://drive.google.com/open?id=0B858bpwZmkmiVlpDY0ZuY0JTZEk



The logic in the ScriptB file i'm worried about, i think it may be poorly optimized, or regardless i feel like it may be too heavy when someone dumps alot of recipes in the Master Container all at once. I'll check through testing, just wanted to post these if you get a chance to glance at them, this is what I'll be starting with.

User avatar
loste juliana
 
Posts: 3417
Joined: Sun Mar 18, 2007 7:37 pm

Post » Thu Feb 16, 2017 12:52 am

That looks extremely complex.



First, you have no need for inventory filters if your inventory scripting is on the schematic holding containers. The inventory filters would only be needed if you were trying to track activity on the player's inventory directly.



Second, It looks like you're still trying to set conditional variables for use with the conditions on the constructable object recipes. That's just over-complicating the problem.



Instead you should be testing whether a schematic of the right type is in one of a set of active schematic containers. Instead of using GetVMQuestVariable on the bbRecipeMasterVanFoodQST to check rFoodChickenCooked you would use GetItemCount with bbbFoodChickenCookedSchematic > 0 running on a target of bbb_ActiveRecipes_Food. Where bbb_ActiveRecipes_Food would be a specific persistent container reference you've placed somewhere. That could either be in some particular game world location the player can find or it can be in a dummy holding cell and always be accessed through some menu.



For maximum flexibility in what you would do later you should probably start with a set of containers broken down by the smallest groupings you might reasonably want to show the player. (You might create one container for all food, but separate containers for dragon bone armor, dragon scale armor, and dragon bone weapons, etc.)



Each of those containers could have this script attached:



Spoiler


Scriptname bbbRecipeSorterScript extends ObjectReference
{Attach to every active schematic container. Can also be used for autosorting master containers.}

FormList Property bbb_RecipeList_Food Auto
FormList Property bbb_RecipeList_WeaponsIron Auto
FormList Property bbb_RecipeList_WeaponsSteel Auto
FormList Property bbb_RecipeList_WeaponsElven Auto
FormList Property bbb_RecipeList_WeaponsEbony Auto
;...
FormList Property bbb_RecipeList_WeaponsOther Auto
FormList Property bbb_RecipeList_Clothing Auto
FormList Property bbb_RecipeList_Jewelry Auto
FormList Property bbb_RecipeList_ArmorFur Auto
FormList Property bbb_RecipeList_ArmorLeather Auto
FormList Property bbb_RecipeList_ArmorIron Auto
;...
FormList Property bbb_RecipeList_ArmorOther Auto
FormList Property bbb_RecipeList_OtherItems Auto


ObjectReference Property bbb_ActiveRecipes_Food Auto
ObjectReference Property bbb_ActiveRecipes_WeaponsIron Auto
ObjectReference Property bbb_ActiveRecipes_WeaponsSteel Auto
; ....
ObjectReference Property bbb_ActiveRecipes_OtherItems Auto

FormList MyList


Event OnInit()
{Identify which type of items belong in this container.}
if self == bbb_ActiveRecipes_Food
MyList = bbb_RecipeList_Food
elseif self == bbb_ActiveRecipes_WeaponsIron
MyList = bbb_RecipeList_WeaponsIron
elseif self == bbb_ActiveRecipes_WeaponsSteel
MyList = bbb_RecipeList_WeaponsSteel
;...
elseif self == bbb_ActiveRecipes_OtherItems
MyList = bbb_RecipeList_OtherItems
endif
EndEvent


Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
if MyList && MyList.Find(akBaseItem) >= 0 ; already in the right container, so give the player a little feedback
if GetItemCount(akBaseItem) > aiItemCount
Debug.Notification("You already know how to make that.") ; should use Message objects instead, but this works for now
RemoveItem(akBaseItem, aiItemCount, true, akSourceContainer) ; return duplicates to the player to keep things uncluttered
;RemoveItem(akBaseItem, aiItemCount) ; or just delete duplicates if they don't have any practical value
else
Debug.Notification("You have learned how to make that item.")
endif

elseif bbb_ActiveRecipes_Food && bbb_RecipeList_Food && bbb_RecipeList_Food.Find(akBaseItem) >= 0
RemoveItem(akBaseItem, aiItemCount, true, bbb_ActiveRecipes_Food)
elseif bbb_ActiveRecipes_WeaponsIron && bbb_RecipeList_WeaponsIron && bbb_RecipeList_WeaponsIron.Find(akBaseItem) >= 0
RemoveItem(akBaseItem, aiItemCount, true, bbb_ActiveRecipes_WeaponsIron)
elseif bbb_ActiveRecipes_WeaponsSteel && bbb_RecipeList_WeaponsSteel && bbb_RecipeList_WeaponsSteel.Find(akBaseItem) >= 0
RemoveItem(akBaseItem, aiItemCount, true, bbb_ActiveRecipes_WeaponsSteel)
; ...
elseif bbb_ActiveRecipes_OtherItems && bbb_RecipeList_OtherItems && bbb_RecipeList_OtherItems.Find(akBaseItem) >= 0
RemoveItem(akBaseItem, aiItemCount, true, bbb_ActiveRecipes_OtherItems)

else ; not a recognized schematic so return it to the player
Debug.Notification("That isn't a schematic or recipe.")
RemoveItem(akBaseItem, aiItemCount, true, akSourceContainer)
endif
endEvent



While the specific ActiveRecipes containers all have to be unique and persistent (filling the properties on that script will make them persistent) you can also attach that same script to one or more autosorting master containers. I have debug notification message in place because if you put the schematic into the wrong container or into an autosorting master it will magically disappear and the player will want to know what happened to it.



To test the basic idea, create just two or three of the containers in some dedicated holding cell. Add a forge and cookpot to the cell. Then just COC to that cell and verify that you can add and remove the items and they get sorted correctly. Then you can set up the basic constructable object conditions and make sure they are working for a few items.



Once you have just a few items of different types that get sorted correctly and are controlling the crafting menus, you can get a little fancier. If you place an auto-sorting master container near a forge or cooking station in the game world you should be able to use it to learn recipes.



You could choose to make your holding cell an actual room and set up a trap door somewhere in the world to access it. (You can also use activators to teleport the player there and back if you want to have multiple access points.) Or you can set up a series of menus for the player to choose one of the specific ActiveRecipes containers to be able to take back one of the already learned ones.



I suspect that just providing a master autosort container, a way to access the individual containers, and then a nearby "Unused recipes" container would be enough to make the mod very usable.



I suspect that instead of unlearning or hiding specific recipes most players would prefer to be able to temporarily disable entire groups of things. So it might be better to think in terms of a separate menu scheme the player could use to toggle a set of conditional variables matching the list of containers. I can envision a player initially being very interested in crafting steel armor but later wanting to hide that group. In that case the specific constructable object conditions would filter both on the GetItemCount to make sure there's a schematic available but also on some conditional property related to that item's group.

User avatar
Poetic Vice
 
Posts: 3440
Joined: Wed Oct 31, 2007 8:19 pm

Post » Wed Feb 15, 2017 5:43 pm

:batman:



mfw its already set up on each constructible object correctly.



i see what you're saying, it does seem silly to have this system when i could just check the item count of the sub container...ARRGH!



--


The persistent Master Container is what I'm doing, although I only want to access it through Drafting Tables at Blacksmiths or a User Crafted Table. I was hoping I could instead make the Drafting Table as an Activator and use activate( _theMasterContainer_Property , true ), that way every Drafting Table goes to the same Container.



so you have to go to a table to learn a recipe. i was thinking about just using the menu token to remove and view what recipes the player has. Although, i guess i'm not hung up on just having the Player go to a Table to learn, although I might require player's to be sitting first to be able to put things in the containers via the menu. I like the idea of shutting off entire sub menus in the forge, like Iron or Steel. Maybe sub Containers could all contain a default book object that if removed would disable the entire submenu. I'm really stuck on the idea of being able to individually shut off recipes, maybe its clouding my judgement. I also wanted to have a menu option that allowed players to turn on or off the ability to see stuff in the crafting forge if they didn't have all the ingredients. That's for another time though.



on the script you posted, I would like to put an OnItemRemoved Event to deal with the shutting off of menus or specific items. I think this is the easiest way for a player to deal with it. So if you remove a recipe from a sub container, instead of going into the player's inventory, it goes into a "Recycle Bin" (for lack of a better term), that the player can then 'take' out any recipe he wants and it will send that recipe back to the proper sub container.



I wonder if calling RemoveItem() from within the OnItemAdded Event cause the OnItemRemoved Event to fire? What about writing to an empty form list and then using that as an inventory filter? because once the recipe is in a sub container, it can only go to the recycle bin or back, just use RemoveAddedForm() on its way out.

User avatar
emma sweeney
 
Posts: 3396
Joined: Fri Sep 22, 2006 7:02 pm

Post » Thu Feb 16, 2017 3:27 am

You should be able to script the crafting table to access the remote container and you'll probably want it to be a menu with options to access the master container (to learn new items), a new Inactive container (to restore previous items), and the various individual containers so the player can take items (which will really put them in the Inactive container instead).



Calling RemoveItem will also trigger the OnItemRemoved event, but that's easy enough to work around since you'll know which items are going where as long as you simply through away duplicate schematic items instead of moving them back to the player.




Here's what you would add to the previous script to handles inactivating individual items and category items. (Putting a category item in each of the containers which can be removed to hide all of the recipes related to that container is a great idea.) There are two versions of the OnItemRemoved event. The first is much shorter and simpler but it only works if you don't return duplicate schematic items to the player. You'll nedd to make sure the new category items are added to the matching formlist so they get recognized as belonging in the containers. You might want to put them all in their own formlist too so you can get a better notification message when they are moved.



Spoiler


ObjectReference Property bbb_InactiveRecipes Auto

Actor Property PlayerRef Auto


; This version only works if you don't try to return duplicate schematics to the player!
Event OnItemRemovedSimple(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
if akDestContainer == PlayerRef ; only items being taken by (or returned to) the player matter
if MyList && MyList.Find(akBaseItem) >= 0
PlayerRef.RemoveItem(akBaseItem, aiItemCount, true, bbb_InactiveRecipes)
Debug.Notification("Item marked inactive, it will not be craftable.")
endif
endif
EndEvent

; This version always works even if you return duplicate schematics to the player.
Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
if akDestContainer == PlayerRef ; only items being taken by (or returned to) the player matter
if bbb_RecipeList_Food && bbb_RecipeList_Food.Find(akBaseItem) >= 0
PlayerRef.RemoveItem(akBaseItem, aiItemCount, true, bbb_InactiveRecipes)
elseif bbb_RecipeList_WeaponsIron && bbb_RecipeList_WeaponsIron.Find(akBaseItem) >= 0
PlayerRef.RemoveItem(akBaseItem, aiItemCount, true, bbb_InactiveRecipes)
elseif bbb_RecipeList_WeaponsSteel && bbb_RecipeList_WeaponsSteel.Find(akBaseItem) >= 0
PlayerRef.RemoveItem(akBaseItem, aiItemCount, true, bbb_InactiveRecipes)
; ...
elseif bbb_RecipeList_OtherItems && bbb_RecipeList_OtherItems.Find(akBaseItem) >= 0
PlayerRef.RemoveItem(akBaseItem, aiItemCount, true, bbb_InactiveRecipes)
else
return
endif
Debug.Notification("Item marked inactive, it will not be craftable.")
endif
EndEvent




Then the InactiveRecipies container would get this script:



Spoiler


ScriptName bbbSchematicRestorer extends bbbSchematicSorter
{Attach to the inactive schematic container.}

; inherits all of the FormList and ObjectReference properties (but they still need to be filled in the CK)

Event OnItemAdded(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer)
if bbb_RecipeList_Food && bbb_RecipeList_Food.Find(akBaseItem) >= 0
return
elseif bbb_RecipeList_WeaponsIron && bbb_RecipeList_WeaponsIron.Find(akBaseItem) >= 0
return
elseif bbb_RecipeList_WeaponsSteel && bbb_RecipeList_WeaponsSteel.Find(akBaseItem) >= 0
return
; ...
elseif bbb_RecipeList_OtherItems && bbb_RecipeList_OtherItems.Find(akBaseItem) >= 0
return
else ; not a recognized schematic so return it to the player
Debug.Notification("That isn't a schematic or recipe.")
RemoveItem(akBaseItem, aiItemCount, true, akSourceContainer)
endif
EndEvent

Event OnItemRemoved(Form akBaseItem, int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer)
if akDestContainer == PlayerRef ; only items being taken by (or returned to) the player matter
if bbb_ActiveRecipes_Food && bbb_RecipeList_Food && bbb_RecipeList_Food.Find(akBaseItem) >= 0
PlayerRef.RemoveItem(akBaseItem, aiItemCount, true, bbb_ActiveRecipes_Food)
elseif bbb_ActiveRecipes_WeaponsIron && bbb_RecipeList_WeaponsIron && bbb_RecipeList_WeaponsIron.Find(akBaseItem) >= 0
PlayerRef.RemoveItem(akBaseItem, aiItemCount, true, bbb_ActiveRecipes_WeaponsIron)
elseif bbb_ActiveRecipes_WeaponsSteel && bbb_RecipeList_WeaponsSteel && bbb_RecipeList_WeaponsSteel.Find(akBaseItem) >= 0
PlayerRef.RemoveItem(akBaseItem, aiItemCount, true, bbb_ActiveRecipes_WeaponsSteel)
; ...
elseif bbb_ActiveRecipes_OtherItems && bbb_RecipeList_OtherItems && bbb_RecipeList_OtherItems.Find(akBaseItem) >= 0
PlayerRef.RemoveItem(akBaseItem, aiItemCount, true, bbb_ActiveRecipes_OtherItems)
else ; not a schematic so no need to comment
return
endif
Debug.Notification("Item restored to crafting menu.")
endif
EndEvent



With those scripts you have a way to get all the items sorted into the correct containers and once they've been put in one of the containers they will simply be shuffled back and forth between the active and inactive containers if the player tries to remove them.



The remaining problem will be to come up with a good way to let the player select the various active containers.

User avatar
OTTO
 
Posts: 3367
Joined: Thu May 17, 2007 6:22 pm

Post » Wed Feb 15, 2017 8:17 pm

So i modified and tried your approach from your former post, and it works great. A very elegant solution,



I had made about 20 or recipe (book objects) placed them in the container as fast as possible, and all transfered to the correct sub Container and subsequently showed up in the Forge Menu. So this is looking very nice.




I don't see a problem with using a token (armor or misc obj) to bring up a menu. 9 options per Msg Menu, so maybe a total of 3 or 4 submenus if I include all the mods I'm thinking of making a patch for. It could also be accessed by proxy through a User Crafted Drafting table, I'll probably make a 3d model that goes as a backboard for the drafting table where small custom containers can fit into which will link to the sub containers. I guess i get crazy and make a mystic shrine to zenithar in a custom cell, accessible via spell that could better organize all of the crafting recipes. maybe offer zenithar 10k gold to get a random recipe.



my original intent was to make it somewhat interesting to do crafting, aside from it bothering me that all of crafting recipes are basically there once you get the perk. Makes no sense tbh. I'll get on incorporating what you posted

User avatar
Angela Woods
 
Posts: 3336
Joined: Fri Feb 09, 2007 2:15 pm


Return to V - Skyrim