Buggy Container Behavior with Targeted Activation

Post » Mon Nov 16, 2015 11:44 am

I've kind of figured this out, but I wanted to get some discussion going on some of the bugs we have to deal with when making things like portable containers, because I've just discovered some I've never seen mentioned before. I've been working on a combo alchemy sorter/portable container, and been finding lots of new ways to screw those two things up.

1. A container won't let a targeted script activate it unless the container itself has a script on it. All it needs is this:

If ( OnActivate )    ActivateEndif

That's it. Without it the container won't open via script at all. I found this out by trying to open an unscripted container with another script and nothing happened. After I added that seemingly pointless script to the container, the calling script worked. I've never heard of this bug before. Anyone else run into it?

2. A container must be manually activated before it will let a targeted script activate it. Always. This one's pretty well known (though I don't remember it mentioned in MWSFD). Also related to the 72-hour bug, meaning containers have to be re-activated manually after a reload.

3. Checking the contents of a container via targeted script, after reload or the 72-hour cleanup, can make the game crash. I found this out because I'm using a container I don't want scaled up for reload detection. I thought since I put a light in there as a fake inventory item (for another script that adds/removes items) I could repurpose that as reload detection instead of setscale. Nope! Using GetItemCount on a container after reload (even in the same cell!) made the game crash, but only after I added the script to the container. It worked fine on an unscripted container though, for reasons unfathomable to mer or man.

4. Since setscale seems to be the only reliable way to check if a container needs reloading, when using a mesh you don't want to resize, you have to come up with a hidden object to resize in its place (please let me know if you can think of a better option).

5. You can add or remove items on a 72-hour bugged container with a targeted script, but you still can't open the damned thing with the same script until you've opened it manually. I haven't yet tried a script for sorting ingredients while outside the same cell as the container. I'll report back with all new bugs after I do, I'm sure.

User avatar
Your Mum
 
Posts: 3434
Joined: Sun Jun 25, 2006 6:23 pm

Post » Mon Nov 16, 2015 9:19 pm

regarding 4., if you don't need to keep exactly the same scale, you can use a small/hardly noticeable scale difference and still be able to detect the change.
e.g. in changing the excellent purchasable alchemy lab mod by Cyrano to reset scaffolds/jars position on reload, I've been able to use and detect scale up to 0.494 with original 0.5 scale

[EDIT]I would call these problems more engine/saved data structures limits than bugs though, I doubt they could be addressed in MCP
User avatar
Czar Kahchi
 
Posts: 3306
Joined: Mon Jul 30, 2007 11:56 am

Post » Mon Nov 16, 2015 6:42 pm

1. Quoting MSFD: "OnActivate short-circuits the normal behavior of the object -to perform the standard action of the object once OnActivate has been called, you have to use the activate command"

If you want to get around it without a local script use MWSE's xSetRef function.

2. Yep, this is the problem everyone always ran into trying to make portable containers openable from within your inventory. Perhaps with new MWSE's array functions you could simulate a container rather than using one directly. Though there might be some other tricks to get by this limitation, I haven't expiremented much.

Also, just curious, what exactly does "sorting" entail here? Do you filter the container based on ingredient effects?

User avatar
Kate Murrell
 
Posts: 3537
Joined: Mon Oct 16, 2006 4:02 am

Post » Mon Nov 16, 2015 8:05 pm

Yeah, I guess engine limitation is the more accurate phrase. As for the mesh, it's one I made to the right size for a scale of 1:00 and don't feel like shrinking it to 0.5 or going the other way with it. I do have a simple mesh I use for invisible activators though, which I used on the MWSE version of the Bag of Holding (it needed multiple resizing for the MWSE script so I didn't want the original container visibly changing from 0.49 to 2.01). But resizing an object a tiny amount is a great idea for anything that's at its "natural" state at a scale of 2 or 0.5.

1. Yeah, the problem was the container originally had no script whatsoever, which I didn't think would be a problem because if OnActivate is never called I assumed it would activate as normal when done by an external script just as it would for the player. Apparently this is not the case. It seems OnActivate needs to be called for any script to activate it. I am interested in how MWSE would handle it, since I do have an MWSE version of this mod.

2. I've tried simulating a container by writing to file in an MWSE inventory helper I made a couple years ago for potions and ingredients. The problem was I couldn't figure out how to make it contiguous with the player's current savegame the way a container is (which is why I never released it, because it's still unfinished to my mind). I tried poking around in Melian's TPP scripts to figure out how each file is written for a specific player, but never figured out if it could handle multiple saves for the same player. I'd really like to know if it can be done and how. I haven't touched the new MWSE yet.

It's not exactly "sorting" yet, just dumping ingredients in and out of the player's inventory. I do want to make it a proper sorter, but unless the new MWSE can sort ingredients by effect it would be too limited for too much work. Without MWSE it would only work for vanilla ingredients and any mod I'm mindful of like Sri's, and then another version would have to be hard-coded for Sri's Alchemy and any other popular mod that changes all the ingredient's effects.

User avatar
Marcin Tomkow
 
Posts: 3399
Joined: Sun Aug 05, 2007 12:31 pm

Post » Mon Nov 16, 2015 5:37 pm

If your just using SetScale to detect reloads, there's much better ways out there to accomplish the same thing. The whole setscale thing is sorta archaic and not very efficient IMO. A simple startscript will usually do the trick, with perhaps an extra global variable if needed.

I was mostly just saying you could use MWSE to trigger OnActivate without having to attach a local script. Having something like this in your script, for example:

xSetRef ST_Containerif ( OnActivate )    ST_Container->Activateendif

For something this simple there's no need to mess with text files. I'd have to have an example of what you're trying to do, but I don't see why a persistent container couldn't safely hold ingredients.

Dumping ingredients shouldn't be a problem at all. Give me an example of exactly the scenario you're trying to do and I can give some example scripts. Actually sorting by effect is technically possible (using MWSE/TES3CMD), but I'm not so sure it would be within the scope of UL.

User avatar
Iain Lamb
 
Posts: 3453
Joined: Sat May 19, 2007 4:47 am

Post » Mon Nov 16, 2015 9:02 pm

I do have a startscript and global variable, but I thought the 72-hour "bug" kicked in after three game days outside the cell, which would also break the link between container and inventory object. Is this not so?

I have two versions of my scripts, one MWSE and one not, the MWSE scripts being in a separate add-on. Edit: I originally posted the old alchemy table script, but here's the new "sorter" script instead. It's a better example because I've gone ahead and made it a separate global stripped of all the local alchemy table functions.

Spoiler
Begin Uvi_Alch_Sorter_Main
; New version of the sorter script, adapted by Melian and Stuporstar, based on alchemy storage helper for use with MWSE or MGE.
; Disconnected from local activator so it can be called by other objects.
; This new version grabs all objects of ingredient type from the player or container, and transfers them to the other.

Short addingr ;add ingredients or remove them

;really longs
Long count ;item count
Long objtype ;object type
Long l1 ;temp/junk

;strings
Long filename
Long objid ;object ID (for inventory items)

;refs
Long destref ;reference for item's destination
Long giveref ;reference for who/whatever has items to start
Long invref ;inventory items reference

Float f1 ;junk var

If ( MenuMode )
Return
Endif

; Uvi_Tmp_S - original global for simple script completion check repurposed here
; Uvi_Tmp_S could not be left at 0 in original script so addingr is still needed
If ( Uvi_Tmp_S == 1 )
Set addingr to 1
Else ;just in case it was previously set to 1
Set addingr to 0
Endif

ifx ( addingr )
setx destref to xGetRef "Uvi_Alchsorter_Desk"
setx giveref to xGetRef "player"
else
setx destref to xGetRef "player"
setx giveref to xGetRef "Uvi_Alchsorter_Desk"
endif

setx filename to xStringBuild "UviAlchemyTable" ;sets the filename variable to this string
xFileRewind filename

;find out what ingredients have to be moved
;write it all to a file so we can move them all at once

setx objid count objtype l1 f1 l1 invref to giveref->xContentList 0 ;gets the first item in inventory
whilex ( objid )
set l1 to ( objtype - 1380404809 ) ;ingredient
ifx ( l1 ) ;it's not an ingredient
else
xFileWriteString filename objid
xFileWriteLong filename count
endif
ifx ( invref )
setx objid count objtype l1 f1 l1 invref to giveref->xContentList invref ;move on to the next item
else
Set objid to 0 ;exit loop
endif
endwhile
xFileWriteString filename "null" ;in case there aren't any ingredients in inventory

;now we read the file back and do the actual adding and removing
;xStringCompare will return 0 if the strings are the same
;so use this to check when we've got to the end

xFileRewind filename
setx objid to xFileReadString filename
setx l1 count to xFileReadLong filename 1
setx l1 to xStringCompare objid "null" ;check here too, in case there weren't any
whilex ( l1 )
giveref->xRemoveItem objid count
destref->xAddItem objid count
setx objid to xFileReadString filename
setx l1 count to xFileReadLong filename 1
setx l1 to xStringCompare objid "null"
endwhile

Set Uvi_Tmp_S to 0
StopScript Uvi_Alch_Sorter_Main

End

This version does use a file, but it's only a temp file that calls the container's inventory so it is contiguous with the savegame, unlike my non-container inventory helper experiment. It works well, so my modifications are mainly adding this script to an object other than the container. I already have it working on an activator in the cell, so the next step is adapting it to the inventory object. This simple ingredient dump to and from the player to the container is all I have in mind for now, with possible effect sorting in the future.

As for the portable element, the game crashing when doing a GetItemCount on a 72-hour bugged container is a concern I haven't yet tested with the standard load/unload ingredient scripts or the MWSE version, but it is something I'm going to go ahead and try out anyway. Even with the standard script version, I can first do a reload/72-hour check on something like setscale (or my loadcheck variable if 3 game days doesn't crash it) before I start using GetItemCount.

User avatar
jadie kell
 
Posts: 3497
Joined: Sat Jul 29, 2006 3:54 pm

Post » Mon Nov 16, 2015 7:54 am

https://www.dropbox.com/s/a4q2tc4oz9bg5kj/Sorter.esp?dl=0's a simplified version of a combined inventory/container sorter. It's very basic, but I think it does what you're wanting. It shouldn't ever be affected by the 72hourBug or reloads, nor does it use any text files.

To test it ingame do "Player->AddItem Sorter_Inv 1".

User avatar
Crystal Clarke
 
Posts: 3410
Joined: Mon Dec 11, 2006 5:55 am

Post » Mon Nov 16, 2015 9:26 pm

Thank you! I've had a peek at your scripting but haven't had time to test it yet. I'll post again once I've dabbled with your scripts a bit. The deleting container bit, is it an invisible container to replace the actual one?

I've removed apparatus sorting from the main table because I made another mesh for a alchemy station similar to Gawain's. I may even use Gawain's apparatus IDs to make it compatible with his mod if loaded, because he placed scripts to disable the original apparatus and added his own unscripted versions to use instead. If I'm going to add portable apparatus, they'll work like the alchemy station that auto-loads a specific set.

http://i.imgur.com/7foWdJm.jpg I designed it to work with Morrowind's engine limitations in an immersive way. Getting rid of those limitations might change how it works, interaction-wise.

Edit: http://i.imgur.com/nSYbOGL.jpg

User avatar
Code Affinity
 
Posts: 3325
Joined: Wed Jun 13, 2007 11:11 am

Post » Mon Nov 16, 2015 6:13 pm

Those screens look very interesting. Especially the sorter wheel + inventory object.

When the inventory version is dropped it's replaced with the container version and vice versa when picked up. if you have some more indepth ideas of how to integrate it with your alchemy table I can help out as needed. ;)

User avatar
Terry
 
Posts: 3368
Joined: Mon Jul 09, 2007 1:21 am


Return to III - Morrowind