Issue Data
|
Issue #27196: Hearthfire planter harvesting silliness (Green Thumb fix et al.)
Do phenomenally stupid implementations count as bugs?
Actually, there is a bug here, though I didn't actually realize it until I thought to look at the wiki (per https://en.uesp.net/wiki/Skyrim:Alchemy#Bugs): Hearthfire planters will not give double the ingredients with Green Thumb, despite the harvest notification indicating otherwise. Right, so, the issue is that whoever implemented the Hearthfire planters did it very poorly. If you want to make a FLOR or TREE record produce multiple items, the correct way to do this is to create a leveled list, put the items you want it to produce in the leveled list, and assign that to your tree/flora record. Simple, fast, easy, no bugs. The way Bethesda decided to do this was to make a MISC item for each separate harvestable, create a script for those MISC items, and assign the produce to that script's properties. This script is also very poorly written, and looks like this: Scriptname BYOHHiddenObjectScript extends ObjectReference {scripted object that adds specified item to player's inventory when added to player} Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer) If akNewContainer == Game.GetPlayer() && akOldContainer == None ; debug.trace(self+" akNewContainer = "+akNewContainer+", akOldContainer = "+akOldContainer) ; add item to player if itemToAddPotion Game.GetPlayer().AddItem(itemToAddPotion, itemCount, true) endif if itemToAddIngredient Game.GetPlayer().AddItem(itemToAddIngredient, itemCount, true) endif ; now remove myself Game.GetPlayer().RemoveItem(myBase, 999, true) EndIf EndEvent Potion Property itemToAddPotion Auto {item to add to player - potion} Ingredient Property itemToAddIngredient Auto {item to add to player - ingredient} Int Property ItemCount = 1 Auto {how many to add?} MiscObject Property myBase Auto { my base object - can't access this from inventory scripts } There are a number of issues with this script, a few that come to mind are: —Green Thumb does not work with this script because of an engine bug, where OnContainerChanged only fires on the first instance of the item to be added to the player's inventory at once for some reason. —There's no reason to check that akOldContainer == None. What if this item gets moved from a container or NPC to the player somehow? The player just ends up with an invisible, scripted item stuck in their inventory forever. —Calling Game.GetPlayer() repeatedly is stupid because once you verify that akNewContainer == Game.GetPlayer(), you should use akNewContainer for the rest of the script. —Why even have the player check? For every other TREE/FLOR record that I know of, it's perfectly valid for some actor to harvest the things by activating them, either via script or AI package. The player check prevents this from working. —There's only one ItemCount property...so why have itemToAddPotion and itemToAddIngredient, and not just a single itemToAdd Form property? Can't change this for compatibility reasons, anyway. I could probably go on, but you get the point. Though I would never use Papyrus for something like this myself, and drawing on a similar discussion I had with Sclerocephalus some time ago (#24169), to correct this mess, I would write the script something like this: Scriptname BYOHHiddenObjectScript extends ObjectReference {scripted object that adds specified item to player's inventory when added to player} Potion Property itemToAddPotion Auto {item to add to player - potion} Ingredient Property itemToAddIngredient Auto {item to add to player - ingredient} Int Property ItemCount = 1 Auto {how many to add?} MiscObject Property myBase Auto { my base object - can't access this from inventory scripts } Event OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer) if akNewContainer == Game.GetPlayer() ; if 2 or more of these are added to an inventory at the same time, the ; OnContainerChanged event will only fire on one of them, so we need to ; handle each individual item in the one script instance that does fire int myCount = akNewContainer.GetItemCount(myBase) akNewContainer.RemoveItem(myBase, myCount, true) if itemToAddPotion akNewContainer.AddItem(itemToAddPotion, itemCount * myCount, true) endif if itemToAddIngredient akNewContainer.AddItem(itemToAddIngredient, itemCount * myCount, true) endif endif EndEvent That should fix all of the problems with the script itself. The proper fix is to do the thing I mentioned earlier, which is to make equivalent leveled lists for each MISC item and swap out what the TREE records point to. This removes Papyrus from being involved at all, and fixes the Green Thumb thing more cleanly, for example you see "Wheat (8) Added" when you harvest something instead of "Wheat (4) (2) Added". I have attached a plugin that makes these changes. As a final note, while the plugin fix is much cleaner, it is more likely to conflict with mods, because changes to the MISC items will be ignored completely, as they are no longer used. If it were up to me, I would integrate both fixes; but, it isn't up to me, and I would understand if you USKP guys decide to exclude the plugin fix. The script fix ought to be non-controversial, though. |
Argh, I forgot to click "Add Attachment".
Also, I just thought of another bug I fixed with this (or at least a better justification for getting rid of the player check in the script): in addition to script/AI package thing, you can also order a follower to harvest a plant. I'm not sure why you would do this, but unpatched, the the MISC item doesn't "unpack" and will just get stuck in the follower's inventory, permanently so since those items are flagged as non-playable. Both of my proposed fixes correct this.
Attached Files:
HearthfirePlanterFixes.esp
Also, I just thought of another bug I fixed with this (or at least a better justification for getting rid of the player check in the script): in addition to script/AI package thing, you can also order a follower to harvest a plant. I'm not sure why you would do this, but unpatched, the the MISC item doesn't "unpack" and will just get stuck in the follower's inventory, permanently so since those items are flagged as non-playable. Both of my proposed fixes correct this.
Attached Files:
HearthfirePlanterFixes.esp
Comment #1 Jul 28, 2019 1:20 pm
Edited by EyeDeck on Jul 28, 2019 1:45 pm
Addendum, instead of
if akNewContainer == Game.GetPlayer()I think I meant to write
if akNewContainer != NoneI can't think of any valid reason to keep the player check, and without this change, the script edit by itself doesn't fix the follower issue I mentioned in my previous post.
So if I'm reading this all correctly the .esp file you attached should cleanly fix everything that needs fixing, right? I ask because if that's the case it allows it to be fixed properly on PS4 as well which is preferred even if it might inconvenience someone with an obscure mod that messes with the HF crafting base objects.
That is correct, yes.
For PC/XB1, the script fix can still benefit said obscure mods that still use the stock HF system, but it is not required.
Also, I just rechecked the plugin for correctness and I found an error in one of my leveled lists, the one I named USSEPLItemBYOHHouseIngredientMushroom06 was producing Mushroom05 by mistake. Attached is the corrected version.
Attached Files:
HearthfirePlanterFixes.esp
For PC/XB1, the script fix can still benefit said obscure mods that still use the stock HF system, but it is not required.
Also, I just rechecked the plugin for correctness and I found an error in one of my leveled lists, the one I named USSEPLItemBYOHHouseIngredientMushroom06 was producing Mushroom05 by mistake. Attached is the corrected version.
Attached Files:
HearthfirePlanterFixes.esp
Comment #4 Sep 2, 2019 2:27 pm
Edited by EyeDeck on Sep 2, 2019 2:43 pm
Alright, I guess changing the script as well won't hurt, and won't matter for PS4 users anyway since nobody's mods will be able to alter it on that platform anyway.
Showing Comments 1 - 5 of 5