Oblivionaddicted Posted September 5, 2017 Share Posted September 5, 2017 FormID finder will help you. Link to comment Share on other sites More sharing options...
QQuix Posted September 5, 2017 Share Posted September 5, 2017 I see...! The only way I can see to use EditorID strings is by hardcoding the conversion by pre-creating a table EditorIDstring<> FormID (like a stringmap array with entries like "let myArray["MS31BlackWaterBlade01] := MS31BlackWaterBlade01 ). With it you could get the FormID of the item placed in the chest, convert it to the correspondent EditorID, rebuild the EditorID string and convert it back to a FormID to be used in AddItem. Another way (without using EditorID strings) would be a table PlayerLevel <> FormID (like an array or map with entries created by MyArray[1] = MS31BlackWaterBlade01 . . . MyArray[14] = MS31BlackWaterBlade10 . . . etc... A third way would be using leveled items. I am not familiar with them, but maybe there is a way to (after removing the placed item) AddItem a leveled item which the engine would dynamically adjust to the playet level. Not sure if this would work, thou. Link to comment Share on other sites More sharing options...
ppl47 Posted September 6, 2017 Author Share Posted September 6, 2017 (edited) I built two scripts like this:The fisrt one is attached to a custom chest, which i placed in arcane univeristy lobby: scn aaFnMagicChest ref chestref iterref baseRefstring_var name begin OnActivate if IsActionRef player == 1 Activate let chest := GetSelf foreach iter <- chest let name := iter.GetName if eval( name == "BlackWater Blade") Call aaFnMagicChestBlackWaterBlade chest iter endif if eval( name == "Blade of Woe") Call aaFnMagicChestBladeOfWoe chest iter endif ; etc..... loop endifend Then i defined, for each leveled item( till now I built 2 of them...there are over 20 in the game!), a function which takes care of analysing the item( get the ID, Name,ecc... ) remove it if low level and substitue it with a better version according to the player level, like this: scn aaFnMagicChestBlackWaterBlade ref objectRefref chestref itemRefstring_var id short itemLevelshort playerLevel begin Function {chest, itemRef} let objectRef := itemRef.GetBaseObject let id := GetEditorID objectRef let itemLevel := 99 if eval( id == "0000C201") let itemLevel := 4 elseif eval( id == "0006B697") let itemLevel := 9 elseif eval( id == "0006B698") let itemLevel := 14 elseif eval( id == "0006B699") let itemLevel :=19 elseif eval( id == "0006B69A") let itemLevel :=24 elseif eval( id == "0006B69B") let itemLevel := 99 endif let playerLevel := player.GetLevel if playerLevel>itemLevel itemRef.RemoveMeIR if playerLevel <10 chest.AddItem 0006B697 1 elseif playerLevel <15 chest.AddItem 0006B698 1 elseif playerLevel <20 chest.AddItem 0006B699 1 elseif playerLevel <25 chest.AddItem 0006B69A 1 elseif playerLevel >=25 chest.AddItem 0006B69B 1 endif endif End The previuos code works, but I'm looking for a more "automatic" way to tell the level of the weapon, and build its IDeditor code without using so many if statements Edited September 6, 2017 by ppl47 Link to comment Share on other sites More sharing options...
Surilindur Posted September 6, 2017 Share Posted September 6, 2017 Maybe something with a leveled list would be handy. There exists already the Auto Update Leveled Items and Spells mod that might have something in it that you could use as a reference. I have no idea how it works, but it seems to update leveled items. If you do not mind typing the items to a list yourself, you could try something like this to update an item: scriptname ItemUpdateTest short PlayerLevel ref BaseObject ref NewObject array_var Items array_var Iter begin _Function { BaseObject } let PlayerLevel := PlayerRef.GetLevel let NewObject := BaseObject ; the idea is to make an array of ; arr = [ [0,ItemEditorIDLevel0], [10,ItemEditorIDLevel10], ...] let Items := ar_Construct "Array" ar_Append Items ( ar_List 0, ItemEditorIDLevel0 ) ar_Append Items ( ar_List 10, ItemEditorIDLevel10 ) ar_Append Items ( ar_List 30, ItemEditorIDLevel30 ) foreach Iter <- Items if eval ( Iter["value"][0] < PlayerLevel ) ; assuming it goes 0 -> 1 -> 2 -> ... let NewObject := Iter["value"][1] endif loop if eval ( BaseObject != NewObject ) RemoveItem BaseObject 1 AddItem NewObject 1 endif ; assuming the contained arrays are also deleted, then this might work, ; but you could probably store the arrays somewhere else... or not? let Items := ar_Null endI have not tested that! It is just an idea. And with arrays, one needs to be somewhat more careful than usual (moreso with string_vars). But also, if you hardcode the item levels, and another mod adjusts the leveled item levels, then your hardcoded system will work according to the original arrangement. For example a mod that removes all level scaling (if there is any) would be negated by your mod swapping the item. Or not. Or a nerfing mod would be useless if a chest gives the best one possible always, regardless of what the levels input in the leveled list are. :huh: Also, you can use the editor ID in the script editor of the CS(E). For example an imaginary item UberSwordObject01 with a form ID of 000012D3 could be referenced either with the editor ID PlayerRef.AddItem UberSwordObject01 1or with the form ID PlayerRef.AddItem 000012D3 1although the editor ID is the more readable one, and in case your form has an ID of 010012D3 originally and you add a new master to it (making the index of the mod where the sword comes from 02), then the script would need to be adjusted to say 020012D3 when compiling the script or else the object referenced would be something in the added master file. If there is anything odd in my post, feel free to point it out, I am writing it with very limited time to spend. :sweat: Link to comment Share on other sites More sharing options...
ppl47 Posted September 6, 2017 Author Share Posted September 6, 2017 I followed you suggestion about leveled list and they seems like the object i need. Now I encountered a new problem: i need to get the index or level of an entry of the leveled list through its base object ID, but I cant find the proper functionThe code is something like this scn aaFnMagicChestNorthwind ref chestref itemRefOldref itemRefNewref baseItemOldstring_var itemIdOld ref leveledListRefshort indexOldshort itemLevelOld short itemLevelNew short nItemsshort i begin Function {itemRefOld, leveledListRef} ; itemRefOld is a reference from an item in a container, leveledListRef ( MQ09AkaviriFrostSword for example) let nItems := GetNumLevItems leveledListRef <---- works let baseItemOld := itemRefOld.GetBaseObject <--- reference to base object of my item let indexOld := GetLevItemIndexbyForm leveledListRef baseItemOld <------ doenst work! let itemLevelOld := GetNthLevItemLevel indexOld leveledListRef Print "nItems= " +$nItems+" , indexOld= " +$indexOld+" , itemLevelOld = " +$itemLevelOldend Any idea? Link to comment Share on other sites More sharing options...
ppl47 Posted September 7, 2017 Author Share Posted September 7, 2017 I was able to solve the problem regarding the indentification of my item inside a leveld list. Now I got a new problem making an array work as I expect it to.The codes are the following: The first script runs at the start of the game and deal with creating a database of the leveled list i'm intereset in , inspired by the mod you have linked scn aaMagicChestDB array_var itemDB Begin MenuMode 1044 if GetGameRestarted let itemDB := ar_Construct Array ar_append itemDB MQ09AkaviriFrostSword ;Northwind ; ..... Message "database loaded" endif EndThe second script is attached to the chest and triggers a Function each time it finds that the item stored belong to a leveled list. This function take care of : check if the item belongs to the list, substitue it with a better version if the level of the player is high enough. But this code doesnt work ( look below)scn aaFnMagicChest ref chestref iterChestarray_var iterDBarray_var itemDBref baseRefstring_var name ref leveledList begin OnActivate if IsActionRef player == 1 Activate let chest := GetSelf let itemDB := ar_Construct array let itemDB := aaMagicChestDBQuest.itemDB foreach iterChest <- chest foreach iterDB <- itemDB <-------- I get an error in the debug console let leveledList := iterDB["value"] Call aaFnMagicChestSwap chest iter leveledList loop loop endifendAny idea what is causing this error in the loop? Link to comment Share on other sites More sharing options...
QQuix Posted September 7, 2017 Share Posted September 7, 2017 What is the error message? Are you sure the array was created? (did the message "database loaded" show?) A couple of comments (not related to the error):(1) If the array contents are always the same, you only need to load the array once. Once created, it is saved in the savegame. So, instead of " if GetGameRestarted" you could use a doonce switch (I usually use the very array as the switch with something like "if itemDB == 0 ") (2) you don't need to initialize ItemDB ("let itemDB := ar_Construct array") as you are assigning the variable to a different array in the next line. (3) You do not need the ItemDB var in the second script. You may refer directly to the quest array as in "foreach iterDB <- aaMagicChestDBQuest.itemDB" (but this is a matter of personal preference) Link to comment Share on other sites More sharing options...
Recommended Posts