Sirgallyhave Posted May 30 Share Posted May 30 I'm perplexed again. With Skyrim v1.6.1170.0 and the Creation Kit 2.0 v1.6.1130.0 I'm trying to activate a container via an Activate Parent. I know we're not supposed to be able to do it. The wiki says under References, "Containers appear to be bugged and cannot be activated through any activate parent." But the Creation Club fishing tanks in the Hearthfires homes use containers that players open via Activators in front of the tanks via Activate Parent in the container reference (under the floor). All I can see happening in the OnActivate event handler in the (decompiled) script attached to each CC fishing tank container (ccBGSSE001_FishTankContainerScript.psc) is self.Activate(Game.GetPlayer(), true). After that, the next thing in OnActivate is UpdateFish() which looks to me like the OnItemAdded() event handler and AddFish() function have already finished and the container has been closed. But when I try Activate(Game.GetPlayer(), true) in my own script's OnActivate() event handler attached to the same type of container (without Betheda's script attached), nothing happens. I need the container to open and for the player to be able to put stuff in or take stuff out of the container, so I can watch for that via the OnItemAdded event. I know I can probably use a dummy NPC (Actor) as the container with ShowGiftMenu() or OpenInventory() (which I can't get to work on a container), but I'd rather use what the CC fish tanks are using, an invisible container in the void. Has anyone figured this out? I also saw open player inventory from script (uses Input.Tapkey()) and will probably go with that method if no one knows how the fish tanks are managing to get Activate Parent to work. I'm missing something but I can't figure it out, so it must be something simple right in my face that I'm not noticing. lol This is the decompiled CC script Bethesda attaches to one of the orange containers bookcases use: ;/ Decompiled by Champollion V1.0.0 Source : ccBGSSSE001_FishTankContainerScript.psc Modified : 2022-08-26 19:52:07 Compiled : 2022-08-30 14:02:48 User : builds Computer : RKVBGSBUILD11 /; scriptName ccBGSSSE001_FishTankContainerScript extends ObjectReference ;-- Properties -------------------------------------- message property notAllowedFishMsg auto {Message displayed when the player places a non-fish form (or the wrong size of fish) in the container.} keyword property ccBGSSSE001_FishTankMarkerKW02 auto {The keyword corresponding to the second fish tank fish marker.} message property fishTankFirstTimeMsg auto {Display message when a fish tank of this size is used for the first time. Only displays once.} formlist property placeableFishList auto {The list of inventory items that can be placed in this tank.} keyword property ccBGSSSE001_FishTankMarkerKW03 auto {The keyword corresponding to the third fish tank fish marker.} message property ccBGSSSE001_fishTankHostileFishMsg auto {Message displayed when the player places a hostile fish form (i.e. Slaughterfish) in the container.} Int property maxFishAllowed Int function get() return 3 endfunction endproperty keyword property ccBGSSSE001_FishTankMarkerKW01 auto {The keyword corresponding to the first fish tank fish marker.} globalvariable property fishTankActivated auto {Tracks whether or not the player has ever activated a fish tank of this size.} message property ccBGSSSE001_fishTankRoomLeftMsg auto {Notification that tells the player how much room is left in the fish tank.} message property ccBGSSSE001_fishTankNoMoreRoomMsg auto {Message displayed when the amount of fish in the tank would exceed the tank limit.} formlist property placeableFishActivatorList auto {The list of corresponding swimming fish activators for each inventory item.} formlist property hostileFishList auto {The list of inventory items of hostile fish.} ;-- Variables --------------------------------------- Int currentFishCount = 0 Activator placedFishForm01 Activator placedFishForm02 Activator placedFishForm03 ccBGSSSE001_FishTankCritterScript placedFishRef01 ccBGSSSE001_FishTankCritterScript placedFishRef02 ccBGSSSE001_FishTankCritterScript placedFishRef03 Bool queuedUpdate = false Bool skipRemovalProcessing = false ;-- Functions --------------------------------------- function UpdateFish() self.GotoState("UpdatingFish") if self.Is3DLoaded() placedFishRef01 = self.UpdateSingleFish(placedFishForm01 as Form, placedFishRef01, self.GetLinkedRef(ccBGSSSE001_FishTankMarkerKW01)) placedFishRef02 = self.UpdateSingleFish(placedFishForm02 as Form, placedFishRef02, self.GetLinkedRef(ccBGSSSE001_FishTankMarkerKW02)) placedFishRef03 = self.UpdateSingleFish(placedFishForm03 as Form, placedFishRef03, self.GetLinkedRef(ccBGSSSE001_FishTankMarkerKW03)) else queuedUpdate = true endif self.GotoState("") endfunction ; Skipped compiler generated GotoState function OnItemRemoved(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akDestContainer) if placeableFishList.HasForm(akBaseItem) if !skipRemovalProcessing self.RemoveFish(akBaseItem, aiItemCount) currentFishCount -= aiItemCount else skipRemovalProcessing = false endif endif endfunction function OnItemAdded(Form akBaseItem, Int aiItemCount, ObjectReference akItemReference, ObjectReference akSourceContainer) if placeableFishList.HasForm(akBaseItem) if aiItemCount + currentFishCount <= self.maxFishAllowed self.AddFish(akBaseItem, aiItemCount) currentFishCount += aiItemCount else ccBGSSSE001_fishTankNoMoreRoomMsg.Show(0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000) skipRemovalProcessing = true self.RemoveItem(akBaseItem, aiItemCount, true, game.GetPlayer() as ObjectReference) endif else if hostileFishList.HasForm(akBaseItem) ccBGSSSE001_fishTankHostileFishMsg.Show(0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000) else notAllowedFishMsg.Show(0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000) endif self.RemoveItem(akBaseItem, aiItemCount, true, game.GetPlayer() as ObjectReference) endif endfunction function MakeFishPanic() if placedFishRef01 placedFishRef01.TryToMoveToNextMarker(true) endif if placedFishRef02 placedFishRef02.TryToMoveToNextMarker(true) endif if placedFishRef03 placedFishRef03.TryToMoveToNextMarker(true) endif endfunction function RemoveFish(Form akFish, Int fishCount) Activator fishActivator = placeableFishActivatorList.GetAt(placeableFishList.Find(akFish)) as Activator if !fishActivator return endif while fishCount > 0 if placedFishForm01 == fishActivator placedFishForm01 = none elseif placedFishForm02 == fishActivator placedFishForm02 = none elseif placedFishForm03 == fishActivator placedFishForm03 = none endif fishCount -= 1 endwhile endfunction ccBGSSSE001_FishTankCritterScript function UpdateSingleFish(Form targetFish, ccBGSSSE001_FishTankCritterScript placedFishRef, ObjectReference targetMarker) ccBGSSSE001_FishTankCritterScript returnFishRef if placedFishRef placedFishRef.StopPathing() placedFishRef.Disable(false) placedFishRef.Delete() endif if targetFish returnFishRef = targetMarker.PlaceAtMe(targetFish, 1, false, false) as ccBGSSSE001_FishTankCritterScript returnFishRef.StartPathing(targetMarker) while !returnFishRef.Is3DLoaded() utility.Wait(0.100000) endwhile returnFishRef.SetScale(0.750000) utility.Wait(utility.RandomFloat(0.000000, 0.300000)) endif return returnFishRef endfunction function AddFish(Form akFish, Int fishCount) Activator fishActivator = placeableFishActivatorList.GetAt(placeableFishList.Find(akFish)) as Activator if !fishActivator return endif while fishCount > 0 if !placedFishForm01 placedFishForm01 = fishActivator elseif !placedFishForm02 placedFishForm02 = fishActivator elseif !placedFishForm03 placedFishForm03 = fishActivator endif fishCount -= 1 endwhile endfunction ; Skipped compiler generated GetState function OnActivate(ObjectReference akActionRef) ccBGSSSE001_fishTankRoomLeftMsg.Show((self.maxFishAllowed - currentFishCount) as Float, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000) if fishTankActivated.GetValueInt() == 0 fishTankFirstTimeMsg.Show(0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000, 0.000000) fishTankActivated.SetValue(1 as Float) endif self.Activate(game.GetPlayer() as ObjectReference, true) utility.Wait(0.250000) self.UpdateFish() endfunction function OnLoad() if queuedUpdate queuedUpdate = false self.UpdateFish() endif endfunction ;-- State ------------------------------------------- state UpdatingFish function UpdateFish() ; Empty function endfunction endstate Link to comment Share on other sites More sharing options...
dylbill Posted May 30 Share Posted May 30 I've never had trouble opening a container from a script. I'm not sure what activate parent means though. From what I understand, you have an activator that when activated will open a linked container. I just tested this simple script and it worked fine for me: ObjectReference property TG06_MarkarthWizardsEnableMarker Auto ;in the empty interior cell aaaMarkers Container property PlayerHouseChest Auto ObjectReference property containerRef Auto Event OnInit() containerRef = TG06_MarkarthWizardsEnableMarker.placeAtMe(PlayerHouseChest, 1, true) EndEvent Event OnActivate(ObjectReference akActionRef) if akActionRef == Game.GetPlayer() containerRef.activate(Game.GetPlayer()) Endif EndEvent 1 Link to comment Share on other sites More sharing options...
Sirgallyhave Posted May 30 Author Share Posted May 30 I'm not sure what's going on either, @dylbill. Thanks for the example, that's exactly what I'd expect. Activate Parent on a reference just allows a different activator to activate something, which is how doors get activated from levers and such. That's working. I have a regular Activator (trigger) in a specific location and I can activate it fine. It then does send the activation event to the script attached to the container. I.e. in the script on the container using the Activate Parent, this debug message gets logged: ;this script is on the container with the Activate Parent event OnActivate(ObjectReference akActionRef) Debug.Trace("OnActivate begins") ;this is being logged, so the event is triggering self.Activate(akActionRef, true) ;nothing happens endevent I ran into several other posts stating the same thing when I was looking for a solution (that Activate() is doing nothing) and no one seems to know what's going on. I'm missing something but I don't know what. In the same mod, I've got a Creation Club fish tank not far away with an Activate Parent activating a container via an Activator Parent and it's working fine. I put a barrel on the floor to test, then put an Activator (trigger) beside it and set that trigger as the Activate Parent on the barrel and the barrel won't open when no script should even be necessary. Activate Parent should simply pass the OnActivate event from the trigger to the barrel and it does but I can't get the barrel to open when Activate Parent is used. I need the visual/manual inventory UI so the player can put stuff into the barrel (or whatever container) and take stuff out. I then check what's in there when OnClose is triggered, but the inventory UI never opens. Link to comment Share on other sites More sharing options...
xkkmEl Posted May 30 Share Posted May 30 Use getLinkedRef().activate( akActionRef, True) instead, and place the script on the activator that gets activated, not the container you want opened. The activate parent is useless, not involved in this use case, so you need to script it, and use the script to activate the real container. Perhaps getLinkedRef is not what you want... you could just as well use a property to link the activator and container together, which is many cases is easier. 1 Link to comment Share on other sites More sharing options...
IsharaMeradin Posted May 30 Share Posted May 30 I think the CC Fish gets away with it because it calls Game.GetPlayer() instead of using akActionRef. Testing would be needed to determine if that is truly the case. It is the only obviously visible difference. 1 Link to comment Share on other sites More sharing options...
Sirgallyhave Posted May 31 Author Share Posted May 31 2 hours ago, xkkmEl said: Use getLinkedRef().activate( akActionRef, True) instead, and place the script on the activator that gets activated, not the container you want opened. The activate parent is useless, not involved in this use case, so you need to script it, and use the script to activate the real container. Perhaps getLinkedRef is not what you want... you could just as well use a property to link the activator and container together, which is many cases is easier. Thanks for the suggestion, @xkkmEl. That did the trick and I don't know if I would have thought of it before clawing my eyes out. lol I still wonder how the Creation Club fish tank containers manage to open when they use Activate Parent links to activators in front of each tank. Link to comment Share on other sites More sharing options...
Sirgallyhave Posted May 31 Author Share Posted May 31 1 hour ago, IsharaMeradin said: I think the CC Fish gets away with it because it calls Game.GetPlayer() instead of using akActionRef. Testing would be needed to determine if that is truly the case. It is the only obviously visible difference. I noticed that and tried it because I couldn't see any other difference. It shouldn't matter when akActionRef is PlayerRef / Game.GetPlayer(). But I did change it to self.Activate(Game.GetPlayer(), true) (and without true) and still no luck. Good suggestion though. Link to comment Share on other sites More sharing options...
xkkmEl Posted May 31 Share Posted May 31 1 hour ago, Sirgallyhave said: I still wonder how the Creation Club fish tank containers manage to open when they use Activate Parent links to activators in front of each tank. Perhaps you need to block activation to make it work? The use of self.activate( akActivatorRef, true) suggests it is meant to be setup that way. I'm just guessing, but it could be that it does work, twice!?? Link to comment Share on other sites More sharing options...
Sirgallyhave Posted May 31 Author Share Posted May 31 16 hours ago, xkkmEl said: Perhaps you need to block activation to make it work? The use of self.activate( akActivatorRef, true) suggests it is meant to be setup that way. I'm just guessing, but it could be that it does work, twice!?? That's what I ran into when I was googling around initially. Someone mentioned enabling Parent Activate Only which is a checkbox on the Activate Parent tab. I thought maybe turning that on would fix things by blocking activation on the chest itself, but it had no effect, unfortunately, and the Creation Club containers don't do it. The way they deal with it in the CC fish tanks is by putting the containers in the void, so the player can't activate them directly. They put Activators (trigger boxes) in front of the fish tanks (which are just static objects) and make the trigger boxes the Activate Parent for each tank with the actual containers under the floor in the void, so no one can get at them to activate them directly. It's so strange that it works when I can't see any difference between how the CC containers are doing things to how I'd set things up before. In any case, your suggestion worked and that's what matters (to me) the most, so I can get back to work. Thanks again for taking the time to help out, I appreciate it and your suggestion works perfectly. Link to comment Share on other sites More sharing options...
xkkmEl Posted May 31 Share Posted May 31 Bethesda activation scripts often have this bit of code: event onCellAttach() blockActivation() endEvent This is what I was referring to... In my initial experiements with ore veins, I had a lot of trouble understanding how the activation worked (and not!). Blocking activation is a large part of why it works (and doesn't!). In your case, the reference to "selft.activate( akActionRef, true)" strongly suggests the script's OnActivate was expecting this to be in place. Link to comment Share on other sites More sharing options...
Recommended Posts