Pellape Posted February 8, 2021 Share Posted February 8, 2021 (edited) Yes you did, as I maybe now know how to solve my current problems with Soul Gems. :smile: I do not have high expectations though. Lets say we have a stack of Common soul gems and the souls in that stack differs. So I check the soul gem object and get the soul, but when I remove it, will it be the same reference I remove that I checked? :wink: Lets say I find a Common Soul Gem of object SoulGemEmpty3Common with a petty soul in that stack in container Chest123 and do Chest123.removitem SoulGemEmpty3Common 1 Will it be the same soul gem as the Wiki page do not say in which order the items are removed so is it always the soul gem in the top of the stack that will get removed? We van only assume at this point that it is so. This needs to be tested and I will do that after my new dynamic sorter is activated in game. Oki. It is a shame that it is so damn hard to target other stuff but you can always get a spell to work with objects anyway with GetfIrstRef and GetNextRef, wich will work perfect if there is only 1 soul gem close by but if there are 2, well then it will be 50//50 you pick what you point at... :/ Ate least it is a spell and maybe you need to change it from target to target your self and let another script do the work, like a quest script, or add a token to your inventory that is scripted. Lets take a deeper look at this function: GetcurrentSoulLevel What is the purpose with it in the first place? If we cannot target a bloody soul gem, then the purpose must be for getting another object types current soul level so why do we want to do that? Well maybe it can be useful to stop the player from wasting a Greater Soul gem if the target only have a common soul? This will allow us to make very customized and precise smart Soul Traps as that function will be useless if we try it on a soul gem that is in our inventory as it only works on references, not objects and to check if we do have an empty common soulgem in the inventory, I guess that set SoulgemLevelV to player.GetSoulLevel SoulGemEmpty3Common or similar is the only way to check if we do have an empty Common soul gem to fill with that specific targets soul. :smile: I do think I have a mod like that activated for either Skyrim or Morrowind but I do not remember which, as I do dislike to have 50 different stacks of soul gems cluttering my inventory. I just searched Nexus for Soul and there are plenty of mods for souls and soul gems. Honestly, I will DL and examine the Soul Magic mod. But first I must finish the dynamic chest sorter as I refuse to play Oblivion until it is implemented as I am so tired of sorting stuff by hand. I play Daggerfall Unity until then. Edited February 8, 2021 by Pellape Link to comment Share on other sites More sharing options...
Stealth21 Posted February 9, 2021 Author Share Posted February 9, 2021 (edited) Lets say I find a Common Soul Gem of object SoulGemEmpty3Common with a petty soul in that stack in container Chest123 and do Chest123.removitem SoulGemEmpty3Common 1 Will it be the same soul gem as the Wiki page do not say in which order the items are removed so is it always the soul gem in the top of the stack that will get removed? We van only assume at this point that it is so.That's a good thought. The sorted items are always in the same order. But I see a problem here:2 Grand.empty1 Grand.petty3 Grand.lesser0 Grand.common5 Grand.grandFor ex., I have a soul purifier for grand souls only. The described items are in my inventory/container. They ALL SoulGemEmpty5Grand = 11 pieces, the same BaseID for all of them. I do not see a way to rely on their ingame order, neither to check their soul levels cause they are presented as BaseIDs, not as the RefIDs. Even if I place just one grand.grand soulgem in the container, is there a way to get it's soul level?..Lets take a deeper look at this function: GetcurrentSoulLevel...I will DL and examine the Soul Magic... I refuse to play Oblivion until it is implemented... I play Daggerfall Unity until thenI think that is implemented in that modYeah, I am also stopped to play until done with soulgems... or after the absolute fail) If you ask me, in the moments of mind's dead end, I am pushing the buttons in Project Diva :DGetfIrstRef and GetNextRefThanks for the hint. I tried it, and this do not solves the problem.I CAN NOT understand the problem. The code once again: short stage ref soulgemsearcher Begin ScriptEffectStart if ( zzSMEmptySoulGemQuest.soulgem == GetCrossHairRef ) MessageBox "Equal" else set zzSMEmptySoulGemQuest.soulgem to GetCrossHairRef MessageBox "Was not equal" endif set soulgemsearcher to zzSMEmptySoulGemQuest.soulgem set stage to 1 End Begin ScriptEffectUpdate if ( stage == 1 ) [color=red]if (( soulgemsearcher.IsActivatable ) == 1 )[/color] if (( soulgemsearcher.IsSoulGem ) == 1 ) if ( soulgemsearcher.GetCurrentSoulLevel == 0 ) Message "This soulgem is empty" set stage to 2 elseif ( soulgemsearcher.GetCurrentSoulLevel == 3 ) Message "You have freed the common soul from this soulgem" soulgemsearcher.SetCurrentSoulLevel 0 set stage to 2 else Message "There is not a common soul inside this soulgem" set stage to 2 endif else Message "The spell applied not on the soulgem" set stage to 2 endif else PlaySound SPLDestructionFail set stage to 2 endif elseif ( stage == 2 ) ; set soulgemsearcher to SkingradWestGateMapMarker ; set soulgemsearcher to ar_Null ; set soulgemsearcher to GetSelf set soulgemsearcher to GetFirstRef Player.Dispel StandardEmptySoulGem3CommonSoul set stage to 0 endif EndScript work is a paradoxly both right and wrong in the same moment :/ It becomes hardly to translate the explanations...I added the MessageBox checks of whenever the ref definitions are equal or they are equal not. And it is working as it should:- new spell - new definition of the void/empty ref HOWEVER, when I firstly apply the spell, for example, to the sign - it will obviously gives me a message "The spell applied not on the soulgem". With the further spell cast to the nothingness/air/Sun/Masser/Secunda, according to my script, it should end up with nothing (with a fail cast sound). Instead, it provides me the message result of that spell cast when it was applied to the activator (or any other crosshair reacheable object, even a static wall). So, in the same situation, the MessageBox checks are reporting me that the reference sets are going normally to nothing, and the script goes in the branch of the ref already set to something instead of to nothing.And as I wrote, if I'll pick up the object I JUST applied the spell on, the further spell castings going with a broken not working at all script. If first to apply the spell on the first item, then on the second item and then pick up the first item - the script will not be broken. Such a mistery... I would like to try the declaration of the ref variable inside of "ScriptEffectUpdate/GameMode". I saw that in some others mod. I am using TES4 Construction Set Extended, and it deny me to do that, deny me to compile the script, but the game's engine is not against of that. If someone know the OBSE script editor in which it is possible to declare the variables inside the functions, please, note it here. Edited February 9, 2021 by Stealth21 Link to comment Share on other sites More sharing options...
Pellape Posted February 9, 2021 Share Posted February 9, 2021 (edited) The best way to solve or see what happens in the beginning of the script is really to add a visual effect to the target, an Effect Shader to be more precisely. Ref Target Ref CompareTarget Begin ScriptEffectStart Set Target to GetCrossHairRef Target.pms effectOpen 4 Set CompareTarget to zzSMEmptySoulGemQuest.soulgem If eval ( Target == CompareTarget ) ;.......... End Doing this, you will see if your spell is able to cast anything at all at the target. Comparing references is best done with eval and not a simple if. Edited February 9, 2021 by Pellape Link to comment Share on other sites More sharing options...
Stealth21 Posted February 9, 2021 Author Share Posted February 9, 2021 Yes, it actually can either change soulgem level or playmagiceffect/shader. Link to comment Share on other sites More sharing options...
Pellape Posted February 9, 2021 Share Posted February 9, 2021 (edited) I thought so as well... :/ Now target chests and living stuff. Well the living stuff can be dead as well, as that doesn't matter. Edited February 9, 2021 by Pellape Link to comment Share on other sites More sharing options...
Stealth21 Posted February 9, 2021 Author Share Posted February 9, 2021 (edited) Well... alright. I think that the case in the CrossHairRef... so I stopped thinking in that way. I was reading about the iterations, ForEach and loop - they can get the references of the objects inside the actor/container. It has a description... but I notice it right now: with it we can get on this example 2 Grand.empty 1 Grand.petty 3 Grand.lesser 0 Grand.common 5 Grand.grandfour iterations, each one is a reference with a stacks. For example, 3 Grand.lesser will be not a three references but just one with a stack of three. So, if to setcurrentsoullevel to 0 to that reference of three, the all of the three will be purified. I just tried to implement it with a stack of 3 greater.common soulgems copying inside the persisted reference containers far far away from the player which I never visited, and I can say, that I can write a script which - will find some exact soulgem(s stack) with exact soullevel, - as there is a warning to not change the quantity inside the source container which processed by the ForEach<->loop, copy that found soulgem(s stack) to the two containers, to the each one - remove the found soulgem(s stack) from the player - in one container, remove one item from the stack with SetRefCount - in another container, leave only one item with the same SetRefCount and purify it with setcurrentsoullevel - copy the contents of the both containers to the player - remove the contents of the both containers Even the script can be careless about the soulgem type, it could be any - Azura's star, vanilla soulgems + black, soulgems from the mod... But I will make a specifically vanilla cares. Today it is too much for me. I will be writting lately, maybe even not tomorrow... But I will)) So, I screwed and "rised a cross" over the GetCrossHairRef :D Edited February 9, 2021 by Stealth21 Link to comment Share on other sites More sharing options...
Pellape Posted February 9, 2021 Share Posted February 9, 2021 (edited) I have been in your shoes and made the same journey so I know exactly what you mean. Dealing with soul gems is messy, which I did write in my first comment in this thread. :wink: I put aside everything that deals with them right now as I need to beta test my newest scripts, but that's ain't easy when my GF is beside me singing and slamming stuff around as it must be done methodical and slow with 110% focus, test all ways to break it and she is doing that when shes tired, making noises, to see if she can get me pissed off or not and she always fails with that... :wink: So she took some food and left finally... :D So ... I went in game, emptied all containers from stolen stuff to start with as I do not want each object added twice into the databases and that will also make the save games more optimized. Food? Damn, I need to eat myself. *walks away* Edited February 9, 2021 by Pellape Link to comment Share on other sites More sharing options...
Stealth21 Posted February 10, 2021 Author Share Posted February 10, 2021 (edited) I have been in your shoesWhile wearing own hat :D :I have been brainstorming about Telekinesis - Why not add it to your spell? I mean the telekinesis spell is able to target anything so put it next to your script inside the spell object and test it and do set the script to run at least 1s and make a test. It could work but if it doesn't, it was worth a try anyway.So, you are saying adding the telekinesis spell... Well, it do not made a trick - I tried to exclude the 'soulgemsearcher' ref and relied on the target accepting by the telekinesis effect; tried "set soulgemsearcher to GetSelf"Why you didn't meant about the functionGetTelekinesisRef?!? Did you see my very first post question, the answer to which was a simple GetPlayerSpell ?)) So, I didn't see that function too, and now when I saw that, the script is complete, it have no cares about the soulgem type (Azura's star, black soulgem, tomato of souls, vanilla/mod soulgem)... but I do not like that the telekinesis is forcing the target=target, and also SupremeMagicka mod has own telekinesis effect modification, adding TWO telekinesis effects on the spell using that effect. Moreover, using telekinesis and GetTelekinesisRef, the value from GetTelekinesisRef is set only to the next frame after the telekinesis is applied to the object, so the spell just can not be a moment spell, there have to be a duration, and as a result, the item will be telekinetically moved a little to the player's direction. Here is a piece of code: short stage ref soulgemsearcher ref null ;Begin ScriptEffectStart ;nothing is here cause GetTelekinesisRef provides the object's ref value only to the next frame it's effect applied to that object ;End Begin ScriptEffectUpdate if ( stage == 0 ) if ( GetTelekinesisRef != null ) set soulgemsearcher to GetTelekinesisRef set stage to 1 endif elseif ( stage == 1 ) if (( soulgemsearcher.IsActivatable ) == 1 ) ... else set stage to 2 PlaySound SPLDestructionFail endif elseif ( stage == 2 ) Player.Dispel StandardEmptySoulGem3CommonSoul ; set stage to 0 endif Begin ScriptEffectFinish set stage to 0 EndSo, the problem was in GetCrosshairRef, indeed. And so, this is for the script with a two effects: 1st effect - telekinesis effect, target=(forced)target, duration=1, magnitude>=1 (3 is more than enough); 2nd effect - script effect, target=self (or else the script effect do not triggers because of the invalid target which is not an actor/creature), duration=1. We are dropping the items from the inventory, or they were "laying" already in the game world, or else way they are appeared in the front of the player's eyes.- if the item is not a soulgem at all - the cast to it ends up with an appropriate message about that;- if the item is a soulgem with an empty or with not a common soul - the cast to it ends up with an appropriate messages about that;- and if all of the requirements are observed, and the item is a soulgem with a common soul - the cast to it ends up with a soul purifying of it... and with an appropriate message about that) Also, you did not meant about that there was a way to get a reference value from the object inside a actor/container - ForEach<->null iterations ) ref iter ref container short stage Begin ScriptEffectStart let container := Player.GetSelf set stage to 1 End Begin ScriptEffectUpdate if ( stage == 1 ) ForEach iter <- container if ( iter.GetBaseObject == SoulGemEmpty4Greater ) && ( iter.GetCurrentSoulLevel == 3 ) iter.CopyIR zzSMOrigsChestRef endif loop set stage to 2 let container := zzSMOrigsChestRef.GetSelf elseif ( stage == 2 ) ForEach iter <- container if ( iter.GetBaseObject == SoulGemEmpty4Greater ) && ( iter.GetCurrentSoulLevel == 3 ) iter.SetCurrentSoulLevel 0 iter.CopyIr Player endif loop set stage to 0 Player.Dispel StandardEmptySoulGem3CommonSoul endif End- this is an example piece of code of purifying the soulgem of an exact ObjectID inside the player's inventory. If it appears that there will be a stack of SoulGemEmpty4Greater filled with a common souls, it's ref value will be different from the other SoulGemEmpty4Greater empty soulgems or filled with not a common souls. Purifying the stack of SoulGemEmpty4Greater soulgems filled with a common souls ends up with a purified stack, not a [stack of SoulGemEmpty4Greater soulgems filled with a common souls minus one, which is purified].Further, purification process is actually going in the container to which that stack was copied. And it have to be presented in that way of copies. To purify just one, it is needed to copy one stack's ref to two containers, RemoveItem 1pc based on that ref's ObjectID in the container where will be no purification process, RemoveItem [stack - {stack - 1}] based on that ref's ObjectID in the container where is an actual purification process. And return the items to the player, cleaning from the items from all of the containers.I see my goal script will in this way - it consists of manually iterates of the all of the combos of the vanilla soulgems (with black but without Azura's star. And without tomato) are laying inside the player's inventory possession. And yes, that needs the concentration. Edited February 10, 2021 by Stealth21 Link to comment Share on other sites More sharing options...
Pellape Posted February 10, 2021 Share Posted February 10, 2021 (edited) Damn... There is so many functions and it is a bloody jungle. Very very well done I must add. :D Yes, I did saw your original post and I do have a tendency to make threads a bit chaotic by solving my own crap while writing other crap while brainstorming. :wink: You not only found a solution to your problems but also to mine. I will implement it after I got the main code to work properly with my new databases. What I really need to do is to read about every single function there is, but it also gets boring after reading about 10-20 functions that I maybe never will use... So I do it first when I need a special function. Your solution(s) will take my own scripting to a new level. Edited February 10, 2021 by Pellape Link to comment Share on other sites More sharing options...
Pellape Posted February 11, 2021 Share Posted February 11, 2021 (edited) I have not made any tests yet with the soulgems. But as I wanted to see what GetInventoryObject returns if I use it at an index that does not exist, I did find this page about the inventory that explains that it will fail anyway to check soulgems in a container or inventory. I quote:GetInventoryObject returns the base object FormID. It can't be used when a reference should be used. The information returned about it (i.e., using GetSoulLevel) will be about the base object and not necessarily each object in the player's inventory. That is, if the player has 2 petty soul gems, one filled and the other empty and you use GetSoulLevel it will return the same for both (empty). :wallbash: :wallbash: :wallbash: :wallbash: :wallbash: :wallbash: :wallbash: :wallbash: :wallbash: :wallbash: :wallbash: :wallbash: :wallbash: Damn good I did find that one, as otherwise I would have get pissed when debugging the rubbish. Edited February 11, 2021 by Pellape Link to comment Share on other sites More sharing options...
Recommended Posts