mattrk Posted May 4, 2014 Share Posted May 4, 2014 Hello, This is my first post. I'll try to provide sufficient details and not write a hopeless request. I have decided to make a "Smeltdown" mod. After some research, it turns out there are at least three others in existence. However, they each have drawbacks and I want to make one that does not have these drawbacks and learn about modding at the same time. Essentially I am making a number of recipes that convert metal-containing items back in to a certain number of ingots. However, I would like these reciped to be:Only visible when the required items are at hand Only visible when there are at least 1+ non-equipped required items Only visibile when, in addition to point 2, there are at least 1+ non-favorited required itemsAt the moment I have managed to find information relating to 1 and 2, to work out it is something like the following (in the recipe's Constructible Object window):Target Function Name Function Info Comp Value Operator PL GetItemCount Item: 'Foo' >= 1 AND S IsEquipped >= 1 AND S IsInFavorState >= 1 AND ...However, I know this won't work, since lines two and three are not right as they are. I suspect IsInFavorState is entirely the wrong function, but it is the most appropraite-sounding one I could find. So, my questions:Is what I am trying to do possible? How do I go about doing it? What mistakes did I make? Where should I have found the information, rather than posting here?Thank you & regards,-- quixotic-cynic Link to comment Share on other sites More sharing options...
mrpwn Posted May 4, 2014 Share Posted May 4, 2014 (edited) I think all of those requirements would be possible to implement. The first two can be done with condition functions, but the third one would probably require a combination of scripting and a condition function. First two:PL GetItemCount ITEM > 1 OR PL GetItemCount ITEM >= 1 AND PL GetEquipped ITEM == 0 OR/AND- Player has to have two or more of the itemor- Player has to have one or more of the item AND not have said item equipped The documentation for GetEquipped states that it does not work for items equipped in the left hand. I think IsInFavorState has to do with AI, but that is a guess. The third requirement could be done by adding a copy of favorited items to a container and using the GetItemCount condition function to see if the container, which stores the copies of favorited items, contains the item. The script would require SKSE. In this example the script would be attached to a quest, but it could be attached to the container instead (in which case you would have to change the first line to be "Scriptname SOMENAMEHERE Extends ObjectReference").Scriptname SOMENAMEHERE Extends Quest Actor Property PlayerRef Auto ObjectReference Property kFavoritesContainer Auto ;Points at the container in the isolated cell Bool bUpdateFavorites Event OnInit() RegisterForMenu("InventoryMenu") EndEvent Event OnMenuOpen(String asMenuName) RegisterForKey(Input.GetMappedKey("Toggle POV")) EndEvent Event OnKeyDown(Int aiKey) bUpdateFavorites = True EndEvent Event OnMenuClose(String asMenuName) UnregisterForAllKeys() If(bUpdateFavorites) UpdateFavorites() EndIf bUpdateFavorites = False EndEvent Function UpdateFavorites() Int iSize = PlayerRef.GetNumItems() While(iSize >= 0) Form kForm = PlayerRef.GetNthForm(iSize) Int iCount = kFavoritesContainer.GetItemCount(kForm) Bool bFavorited = Game.IsObjectFavorited(kForm) If((bFavorited) && (iCount == 0)) kFavoritesContainer.AddItem(kForm) ElseIf((!bFavorited) && (iCount > 0)) kFavoritesContainer.RemoveItem(kForm, iCount) EndIf iSize -= 1 EndWhile EndFunctionThis is something I just wrote based on what I use in All Geared Up, so it may or may not work as is. The condition function stack would then be:R GetItemCount ITEM == 0 AND PL GetItemCount ITEM > 1 OR PL GetItemCount ITEM >= 1 AND PL GetEquipped ITEM == 0 OR/ANDThe reference in the first GetItemCount would be the container that exists in the isolated cell. - Item is not favoritedand- Player has to have two or more of the itemor- Player has to have one or more of the item AND not have said item equipped Edited May 4, 2014 by mrpwn Link to comment Share on other sites More sharing options...
mattrk Posted May 5, 2014 Author Share Posted May 5, 2014 Thank you, mrpwn, for the extremely detailed response. Fortunately, I can program in Java a bit so I understand the script (just about) so I think I may actually be able to implement this (which is important, since there is little point in making another meltdown mod that is the same as all the others). The only thing I worry about is getting people to install SKSE, but then again, a lot of mods use this already. Thanks again. I shall do my best to make use of the information provided. Regards, --quixoticynic Link to comment Share on other sites More sharing options...
mattrk Posted May 18, 2014 Author Share Posted May 18, 2014 On 5/4/2014 at 8:18 PM, mrpwn said: I think all of those requirements would be possible to implement. The first two can be done with condition functions, but the third one would probably require a combination of scripting and a condition function. First two:PL GetItemCount ITEM > 1 OR PL GetItemCount ITEM >= 1 AND PL GetEquipped ITEM == 0 OR/AND- Player has to have two or more of the itemor- Player has to have one or more of the item AND not have said item equipped Edit: The order as shown above does not function correctly. It processes the rules as follows: ((is the item count > 1 OR is the item count >= 1) AND is the item not equipped) hence the recipe will never show up if you have one of the items equipped. A functioning order is as follows:PL GetItemCount ITEM >= 1 AND PL GetEquipped ITEM == 0 OR PL GetItemCount ITEM > 1 ANDI hope this helps people. I still appreciate the help or I would not have seen how to do the 2nd part. Thanks, --QC Link to comment Share on other sites More sharing options...
mattrk Posted May 18, 2014 Author Share Posted May 18, 2014 Update: I have spent a few hours trying to get the last part working. I couldn't get the script to work at all when attached to the chest, using Extends ObjectReference, so I tried attaching the script to a quest. The script runs when attached to the quest, but I don't understand how to get the object reference for the chest, to then use further within the script. I think it relates to the line:ObjectReference Property kFavoritesContainer Auto ;Points at the container in the isolated cellHowever, I can't see how it will associate kFavoritesContainer with the chest item. Edit: I worked out a bit more: Quote A property allows your script to use information in a data file by providing a special interface that they can both access. From your script's point of view, a property is an arbitrary piece of information of a certain specified type, like "Actor" or "Quest". From the Creation Kit's point of view, it is a point at which information of that type can be inserted into the instance of your script attached to the object you're editing. [...] Once you've defined your property, you can use it in your script as though it points to the object that you want to use. Once you've attached your script to the right object in the Creation Kit, you will then need to use it to associate your property with the right object via a drop-down list of all objects of your property's type.(Source: http://www.cipscis.com/skyrim/tutorials/beginners.aspx) I have now set the property by right clicking on the script in the Construction Kit, clicking edit, and choosing the correct cell + chest. Unfortunately I still can't get it working. If someone understands what I need to do, could they please be kind enough to point me in the right direction. Thanks, --QC Link to comment Share on other sites More sharing options...
IsharaMeradin Posted May 18, 2014 Share Posted May 18, 2014 You need to press the properties button and assign the container that you want the property variable to represent. Link to comment Share on other sites More sharing options...
mattrk Posted May 18, 2014 Author Share Posted May 18, 2014 Thank you for the suggestion. I think I have just done that just now -- I'll Google a bit more to see if I have done it correctly. Thanks, --QC Edit: It is now almost completely working. I have checked the chest in the cell I created and has the relevant items. That suggests to me that it is the conditional rules that are not quite right now -- tweaking. Edit 2: Fully Working. The following conditional rules work perfectly, in conjunction with mrpwn's script: The following rules turned out to be bugged (see post below):R GetItemCount Armor:'ArmorDwarvenBoots' == 0.00 OR PL GetItemCount Armor:'ArmorDwarvenBoots' > 1.00 AND RL GetItemCount Armor:'ArmorDwarvenBoots' == 0.00 OR PL GetItemCount Armor:'ArmorDwarvenBoots' > 1.00 AND Obviously, change ArmorDwarvenBoots to the item of interest. Bug (can anyone fix?): If you access the smelter really fast after setting a favorite item you can still smelt the favorite item (i.e. the script works a bit slowly). Any suggestions anyone? Thanks all, --QC Link to comment Share on other sites More sharing options...
IsharaMeradin Posted May 18, 2014 Share Posted May 18, 2014 Updated the scripted posted earlier Reveal hidden contents Scriptname SOMENAMEHERE Extends Quest Actor Property PlayerRef Auto ObjectReference Property kFavoritesContainer Auto ;Points at the container in the isolated cell Bool bUpdateFavorites Event OnInit() RegisterForMenu("InventoryMenu") RegisterforCrosshairRef() EndEvent Event OnMenuOpen(String asMenuName) RegisterForKey(Input.GetMappedKey("Toggle POV")) EndEvent Event OnKeyDown(Int aiKey) bUpdateFavorites = True EndEvent Event OnMenuClose(String asMenuName) UnregisterForAllKeys() If(bUpdateFavorites) UpdateFavorites() EndIf Utility.Wait(1) bUpdateFavorites = False EndEvent Function UpdateFavorites() Int iSize = PlayerRef.GetNumItems() While(iSize >= 0) Form kForm = PlayerRef.GetNthForm(iSize) Int iCount = kFavoritesContainer.GetItemCount(kForm) Bool bFavorited = Game.IsObjectFavorited(kForm) If((bFavorited) && (iCount == 0)) kFavoritesContainer.AddItem(kForm) ElseIf((!bFavorited) && (iCount > 0)) kFavoritesContainer.RemoveItem(kForm, iCount) EndIf iSize -= 1 EndWhile EndFunction Keyword Property SmelterKYWD Auto Form RefBase Event OnCrosshairRefChange(ObjectReference ref) If ref RefBase = ref as form If RefBase.HasKeyword(SmelterKYWD) ;is a valid smelter While bUpdateFavorites == false ref.BlockActivation(true) EndWhile If bUpdateFavorites == true ref.BlockActivation(false) EndIf EndIf EndIf EndEvent Added a wait statement in the OnMenuClose event after the UpdateFavorites function has been called if needed. Also registered for a crosshair event and when the player mouses over a smelter and the bUpdateFavorites bool is false it will block the activation of the smelter so the player cannot smelt until after the UpdateFavorites function has finished and the bool flipped back to true. Do be sure to assign the keyword for the smelter (the same one used on the recipes) in the added property. I'm thinking it might work. Worth a try at least. Link to comment Share on other sites More sharing options...
mattrk Posted May 18, 2014 Author Share Posted May 18, 2014 Wow, thank you very much for the updated script. I'll try it out now and post the result. Edit: The above script works really well. It requires a small change, however, with the ref.BlockActivation(false) being replaced with ref.BlockActivation(true) and vice versa. The above conditional rules that I proposed in my previous post now appear to be bugged: equipping an item stops any of that type from being smelted. Am in the process of fixing the conditional bug. The pages http://creationkit.com/conditions and http://en.wikipedia.org/wiki/Distributive_property#Propositional_logic have been very useful. However, unfortunately there is still a bug: when there is a single non-favorite, non-eqipped item it will not smelt. It is very puzzling at the moment -- perhaps I am overlooking something obvious? Edit: I think I have worked out the correct combination of rules: Another attempt (still broken):PL GetItemCount Armor:'ArmorDwarvenBoots' >= 1.00 AND R GetItemCount Armor:'ArmorDwarvenBoots' == 0.00 AND RL GetItemCount Armor:'ArmorDwarvenBoots' == 0.00 OR PL GetItemCount Armor:'ArmorDwarvenBoots' > 1.00 ANDOnce I alter all of the rules in the mod and upload it. I will also upload a separate .esp file for people who want to include 'favorite item protection' in their own mod. I will of course credit mrpwn and IsharaMeredin -- I could never have done it otherwise. Thanks again, --QC Link to comment Share on other sites More sharing options...
mattrk Posted May 19, 2014 Author Share Posted May 19, 2014 In an attempt to cut down on the conditionals, I started trying to integrate the 'equipped check' into the script. My attempt is [Edit: removed due to it being incorrect -- see correct version on page 2 of the thread] It is currently flawed since GetNthForm() gets the form of the item whereas IsEquipped() requires the actual object (i.e. it is the difference between a class and an object in Java) -- if I understand correctly. I'll try again tomorrow night. ^_^ Link to comment Share on other sites More sharing options...
Recommended Posts