NOOBIV Posted October 29, 2017 Share Posted October 29, 2017 sorry my bad english, and sorry if this is the wrong forum :unsure: hi, i want to make a script that makes: all actors wearing a specific item makes to unequip>equip that/a item when changing cells just like, i give a scripted ring to Cicero that makes to unequip>equip a sword(or the ring) each time i change cells the reason because i want to make this script is because i'm using a X mod (HDT items) that add tails,ears,etc, everything works fine, but when i change to another cells, the tails/ears looks really weird on npcs, and only unequip and re-equip fix that, so this is the only way to fix the mod i found, making a script, but i have 0 knowledge of scripting :sad:â , i was reading the Creation kit wiki, but basically i don´t understand what im reading :sweat: if someone can help me how to make that script, i already have the empty script and the object with the empty script (the only phase that my brain could understand :wacko: ), or links with the necessary to make this script or just hold my hand and guide me to the way to make this script :rolleyes: , i will appreciate every help :D Link to comment Share on other sites More sharing options...
GSGlobe Posted October 30, 2017 Share Posted October 30, 2017 Are you by chance using a skeleton mod? I'm quite certain mods that change that could be a conflict with your mod that adds ears and stuff. Perhaps someone else can help you further with your script! but I do suggest to remove that skeleton mod and try with a clean save. Link to comment Share on other sites More sharing options...
NOOBIV Posted October 30, 2017 Author Share Posted October 30, 2017 thanks for the tip! im using XMPSE (XP32 Maximum Skeleton Extended) so i cant just remove it, it will break the game :unsure: , anyways ears/tails doesn´t look really really weird (just becomes shorter than normal and HDT is unnoticeable) also i don´t think is a skeleton issue, i think is a HDT issue, because if i remove the XML attached in the .nif (ears/tails) it doesn´t look weird anymore, but lost HDT, if i attach the XML again and load the game, it looks weird again until i re-equip it each load screen :sad: About the script, i think it should looks like this. Warning, cringe script inside Event OnCellLoad()endEvent Function UnequipItem(Form akItem, bool abPreventEquip = false, bool abSilent = false) native Game.GetPlayer().UnequipItem(The Ring)endFunction Function EquipItem(Form akItem, bool abPreventRemoval = false, bool abSilent = false) native Game.GetPlayer().EquipItem(The Ring)endFunction how i can change Game.GetPlayer for Followers only? also what means AkActor?, any actor :confused: ? also i should add "Armor property "The Ring" Auto" "Actor property "Follower?" Auto" at the top?. For what i understand, this script should do 1Event: when the player change to another cells the functions will start2Function: will unequip the ring from the followers wearing it3Function:will equip the ring on all Followers that have the ring in his inventory Those are the correct scripts? or i should add more scripts to make it work :ohmy:â ?, also please help me to modify it correctly :smile: . Link to comment Share on other sites More sharing options...
GSGlobe Posted October 30, 2017 Share Posted October 30, 2017 This is a basic script, its not tested or anything. Im guessing you need this script active at all times so.. put it on alias quest Actor Property PlayerRef Auto ; references the player "you"Armor Property Item Auto ; references the item below. Property "Item" you can change item to whatever, as long as its matching the script below. same with actor Event OnCellLoad() PlayerRef.UnequipItem(Item)Utility.Wait(0.1)PlayerRef.EquipItem(Item) Link to comment Share on other sites More sharing options...
NOOBIV Posted October 30, 2017 Author Share Posted October 30, 2017 (edited) ooh thanks, it should be like this? Actor Property PlayerRef Auto Armor Property TheRing Auto Event OnCellLoad() endEvent Function UnequipItem(Form akItem, bool abPreventEquip = false, bool abSilent = false) native PlayerRef.UnequipItem(TheRing) endFunction Utility.Wait(0.1) Function EquipItem(Form akItem, bool abPreventRemoval = false, bool abSilent = false) native PlayerRef.EquipItem(TheRing) endFunction i want to make this script to affect followers only, so is there a way to change the "Actor Property"? like this Actor Property FollowersRef Auto FollowersRef.UnequipItem(Item) Utility.Wait(0.1) FollowersRef.EquipItem(Item) Edited October 30, 2017 by NOOBIV Link to comment Share on other sites More sharing options...
ReDragon2013 Posted October 30, 2017 Share Posted October 30, 2017 (edited) Just a bit more scriptness. Maybe it is helpful for understanding. You need both scripts for the workaround you like to have. NOOBIV_ItemPlayerAliasScript Scriptname NOOBIV_ItemPlayerAliasScript extends ReferenceAlias {written by ReDragon 2017} ; attach this script to the player alias, that is a part of a new created quest FormList fml ; empty formlist ; -- EVENTs -- 2 EVENT OnCellLoad() ;; Debug.Notification("new Cell has been loaded!") ;; myF_Item() ENDEVENT ; Event that is triggered when this actor changes from one location to another EVENT OnLocationChange(Location akOldLoc, Location akNewLoc) gotoState("Busy") Debug.Trace("PlayerAlias: old = " +akOldLocation+ ", new = " akNewLocation) myF_Item() gotoState("") ENDEVENT ;================================== state Busy ;you have to cover the same event in no state ;========= EVENT OnLocationChange(Location akOldLoc, Location akNewLoc) ENDEVENT ;======= endState ; -- FUNCTIONs -- 3 ;----------------------------------------- FUNCTION myF_AddMe(NOOBIV_ItemEUScript ps) ; add to formlist, external called by "NOOBIV_ItemEUScript" ;----------------------------------------- ; https://www.creationkit.com/index.php?title=AddForm_-_FormList fml.AddForm(ps as Form) ENDFUNCTION ;-------------------------------------------- FUNCTION myF_RemoveMe(NOOBIV_ItemEUScript ps) ; remove from formlist, external called by "NOOBIV_ItemEUScript" ;-------------------------------------------- ; https://www.creationkit.com/index.php?title=RemoveAddedForm_-_FormList fml.RemoveAddedForm(ps as Form) ENDFUNCTION ;------------------ FUNCTION myF_Item() ;------------------ int i = fml.GetSize() WHILE (i > 0) i = i - 1 NOOBIV_ItemEUScript ps = fml.GetAt(i) as NOOBIV_ItemEUScript IF ( ps ) ps.myF_Action() ENDIF ENDWHILE ENDFUNCTION NOOBIV_ItemEUScript Scriptname NOOBIV_ItemEUScript extends ObjectReference {written by ReDragon 2017} ; attach this script to the baseobject of your item, which should be equipped/unequipped if player is changing the cell ; https://forums.nexusmods.com/index.php?/topic/6114328-unequipequip-script/ ; NOOBIV wrote: "I give a scripted ring to Cicero that makes to unequip/equip a sword(or the ring) each time I change cells" NOOBIV_ItemPlayerAliasScript PROPERTY ps auto ; DO NOT FORGET !!! to fill the property with NOOBIV_ItemPlayerAliasScript Actor myOwner ; -- EVENTs -- ; Event received when this object enters, exits, or changes containers EVENT OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer) IF (akNewContainer as Actor) ELSE gotoState("Done") ; ### STATE ### myOwner = None ps.myF_RemoveMe(self) RETURN ; - STOP - ring is thrown away or placed into barrel, sack or similiar container ENDIF ;--------------------- IF (akNewContainer as Actor == Game.GetPlayer()) gotoState("Done") ; ### STATE ### myOwner = None ps.myF_RemoveMe(self) RETURN ; - STOP - ring was given to the player, do not equip by the player ENDIF ;--------------------- gotoState("Waiting") ; ### STATE ### myOwner = akNewContainer as Actor ; make new owner persistent for a while ps.myF_AddMe(self) ENDEVENT ;============================== state Done ; do not track anything, there is no owner of this item ;========= endState ;============================== state Waiting ;============ ; Event received when this object is equipped by an actor EVENT OnEquipped(Actor akActor) int i = (self as ObjectReference).GetFormID() Debug.Notification("Item " +i) ; info only ENDEVENT ; Event received when this object is unequipped by an actor EVENT OnUnequipped(Actor akActor) ; int i = (self as ObjectReference).GetFormID() ; Debug.Notification("Item (un) " +i) ; info only ENDEVENT ;======= endState ; -- FUNCTION -- ;; Forces this actor to equip the specified item, preventing removal if requested ;Function EquipItem(Form akItem, bool abPreventRemoval = false, bool abSilent = false) native ;; Unequips the specified item from this actor ;Function UnequipItem(Form akItem, bool abPreventEquip = false, bool abSilent = false) native ;-------------------- FUNCTION myF_Action() ; external called by "NOOBIV_ItemPlayerAliasScript" ;-------------------- IF ( myOwner ) myOwner.EquipItem(self as Form) Utility.Wait(0.1) myOwner.UnequipItem(self as Form) ENDIF ENDFUNCTION posting edited 31-10-2017 Edited October 31, 2017 by ReDragon2013 Link to comment Share on other sites More sharing options...
JonathanOstrus Posted October 30, 2017 Share Posted October 30, 2017 (edited) I'm a fair bit concerned about triggering this on "cell" changes. Walking around in the worldspace will cause this to happen A LOT! More specifically it sounds like you only want something that happens between load doors. Sadly I don't have a good method for detecting and reacting to that. The best solution there I have is monitor for location change and check each time if the reference went FROM an interior to an exterior or the other way around or changed world spaces. There might also be times where you go from an exterior to an interior and the "Location" as the game knows it is the same.Now for your content posts above. The actual name of the property makes no difference. You could leave it PlayerRef. You can change it to Alibaba if you want. It doesn't matter what it's called. What matters, is when you attach the script to an object in CK, that you assign the correct thing to the property you want the script to act on. If you have it named PlayerRef and use the autofill button (you have to press the button on the properties window) then it will fill the property for you with the PlayerRef object. You can change it after that as well, but you will need to do so before the mod is loaded and baked into a save game. At the same time if you renamed it to FollowersRef and hit autofill it will do nothing, unless you have an actual object with the editor ID of FollowersRef. Then it will put that object in the property. Otherwise if it fails to autofill then you have to manually fill the property or the script will get a "None" value.As you wrote the changes to the script it won't compile. You have calls to things in the context of the script outside functions or events (Utility.Wait) which are invalid. You also have the script events declared as functions which are invalid. You also have those same events doing redundant things. When unquipping, unquip? So you're telling the script, when you unequip the ring from the object the script is running on, unequip it from the reference of the property. This is redundant because it's already done, unless you put the script on a different object and then want it to trigger when you unequip from one object, also unequip from another.There's another issue in that you have the script reacting to different objects. If you have the script running on the player detecting when you change areas and then trying to equip/unquip on another actor, you need to make sure that actor is nearby. Followers sometimes take a while to move through load doors. You need the script to actually run on the follower itself and detect when the follower changes areas.Unfortunately for what you're trying to do there's no real elegant solution, only rough hacks. One would be to run a quest with an alias. Place a script on the alias to detect the movement changes and then unequip/re-equip the item you desire on itself (the alias). Then you put whatever reference you want in the alias. It could be the player, or a follower, whatever. However only 1 at a time. Though you can create multiple aliases and use the same script. Another solution that would support multiple objects at once would be to use a magic effect. This would go something like, make ring with enchantment. The enchantment has a script that gets the call/area change. Then it equip/unequips an object defined by a property from the object the magic effect is on (the actor).My preferred method to try and pull this off would be the magic effect script. It would go something like this. Note: This script uses OnLocationChange to detect the movement between areas and has no checking of any kind. This is a bad idea in practice because it will trigger more than necessary. This is only intended for example usage not for actual game play usage. Scriptname TestEffect extends ActiveMagicEffect Actor myActor ; holder for the actor this script is affecting Armor Property RecycleArmorObject auto ; the armor record to unequip and then re-equip Event OnEffectStart(Actor akTarget, Actor akCaster) myActor = akTarget ; this is necessary so that other events can act upon the actor the effect is running on EndEvent Event OnLocationChange(Location akOldLoc, Location akNewLoc) myActor.UnequipItem(RecycleArmorObject) Utility.Wait(0.1) ; this may be unnecessary and should be tested with and without it to see which works as desired myActor.EquipItem(RecycleArmorObject) EndEvent I don't believe the OnCellLoad() would work for what you're trying to do. You would need to attach the script to an object other than the player or the follower that would be in the cell you're going into which would then get the event when it loads. I don't see an easy way to accomplish that in any meaningful manner. The other issue is as I stated before, the follower you want to act on may not be there yet when the event fires. I could be wrong, it would need more testing. If it does work then my script above could be modified to use such. Edit: changed the RecycleArmorObject to a property. Oops. Edited October 31, 2017 by BigAndFlabby Link to comment Share on other sites More sharing options...
NOOBIV Posted October 30, 2017 Author Share Posted October 30, 2017 thanks guys, i really appreciate your help :D , i don't want to be annoying, but u guys are my last hope. I will try to test/understand/modify/adapt both a post what i can get Link to comment Share on other sites More sharing options...
NOOBIV Posted October 31, 2017 Author Share Posted October 31, 2017 Just a bit more scriptness. Maybe it is helpful for understanding. You need both scripts for the workaround you like to have. NOOBIV_ItemPlayerAliasScript Scriptname NOOBIV_ItemPlayerAliasScript extends ReferenceAlias {written by ReDragon 2017} ; attach this script to the player alias, that is a part of a new created quest FormList fml ; empty formlist ; -- EVENTs -- 2 EVENT OnCellLoad() ;; Debug.Notification("new Cell has been loaded!") myF_Item() ENDEVENT ; Event that is triggered when this actor changes from one location to another EVENT OnLocationChange(Location akOldLoc, Location akNewLoc) ;; Debug.Trace("PlayerAlias: old = " +akOldLocation+ ", new = " akNewLocation) ENDEVENT ; -- FUNCTIONs -- 3 ;----------------------------------------- FUNCTION myF_AddMe(NOOBIV_ItemEUScript ps) ; add to formlist, external called by "NOOBIV_ItemEUScript" ;----------------------------------------- ; https://www.creationkit.com/index.php?title=AddForm_-_FormList fml.AddForm(ps as Form) ENDFUNCTION ;-------------------------------------------- FUNCTION myF_RemoveMe(NOOBIV_ItemEUScript ps) ; remove from formlist, external called by "NOOBIV_ItemEUScript" ;-------------------------------------------- ; https://www.creationkit.com/index.php?title=RemoveAddedForm_-_FormList fml.RemoveAddedForm(ps as Form) ENDFUNCTION ;------------------ FUNCTION myF_Item() ;------------------ int i = fml.GetSize() WHILE (i > 0) i = i - 1 NOOBIV_ItemEUScript ps = fml.GetAt(i) as NOOBIV_ItemEUScript IF ( ps ) ps.myF_Action() ENDIF ENDWHILE ENDFUNCTION NOOBIV_ItemEUScript Scriptname NOOBIV_ItemEUScript extends ObjectReference {written by ReDragon 2017} ; attach this script to the baseobject of your item, which should be equipped/unequipped if player is changing the cell ; https://forums.nexusmods.com/index.php?/topic/6114328-unequipequip-script/ ; NOOBIV wrote: "I give a scripted ring to Cicero that makes to unequip/equip a sword(or the ring) each time I change cells" NOOBIV_ItemPlayerAliasScript PROPERTY ps auto ; DO NOT FORGET !!! to fill the property with NOOBIV_ItemPlayerAliasScript Actor myOwner ; -- EVENTs -- ; Event received when this object enters, exits, or changes containers EVENT OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer) IF (akNewContainer as Actor) ELSE gotoState("Done") ; ### STATE ### myOwner = None ps.myF_RemoveMe(self) RETURN ; - STOP - ring is thrown away or placed into barrel, sack or similiar container ENDIF ;--------------------- gotoState("Waiting") ; ### STATE ### myOwner = akNewContainer as Actor ; make new owner persistent for a while ps.myF_AddMe(self) ENDEVENT ;============================== state Done ; do not track anything, there is no owner of this item ;========= endState ;============================== state Waiting ;============ ; Event received when this object is equipped by an actor EVENT OnEquipped(Actor akActor) int i = (self as ObjectReference).GetFormID() Debug.Notification("Item " +i) ; info only ENDEVENT ; Event received when this object is unequipped by an actor EVENT OnUnequipped(Actor akActor) ; int i = (self as ObjectReference).GetFormID() ; Debug.Notification("Item (un) " +i) ; info only ENDEVENT ;======= endState ; -- FUNCTION -- ;; Forces this actor to equip the specified item, preventing removal if requested ;Function EquipItem(Form akItem, bool abPreventRemoval = false, bool abSilent = false) native ;; Unequips the specified item from this actor ;Function UnequipItem(Form akItem, bool abPreventEquip = false, bool abSilent = false) native ;-------------------- FUNCTION myF_Action() ; external called by "NOOBIV_ItemPlayerAliasScript" ;-------------------- IF ( myOwner ) myOwner.EquipItem(self as Form) Utility.Wait(0.1) myOwner.UnequipItem(self as Form) ENDIF ENDFUNCTION i appreciate your hard work, but i don´t know how to adapt those scripts to what i need, thanks anyways, all info and examples are useful for me :wub: BigAndFlabbyI'm a fair bit concerned about triggering this on "cell" changes. Walking around in the worldspace will cause this to happen A LOT! More specifically it sounds like you only want something that happens between load doors. Sadly I don't have a good method for detecting and reacting to that. The best solution there I have is monitor for location change and check each time if the reference went FROM an interior to an exterior or the other way around or changed world spaces. There might also be times where you go from an exterior to an interior and the "Location" as the game knows it is the same.Now for your content posts above. The actual name of the property makes no difference. You could leave it PlayerRef. You can change it to Alibaba if you want. It doesn't matter what it's called. What matters, is when you attach the script to an object in CK, that you assign the correct thing to the property you want the script to act on. If you have it named PlayerRef and use the autofill button (you have to press the button on the properties window) then it will fill the property for you with the PlayerRef object. You can change it after that as well, but you will need to do so before the mod is loaded and baked into a save game. At the same time if you renamed it to FollowersRef and hit autofill it will do nothing, unless you have an actual object with the editor ID of FollowersRef. Then it will put that object in the property. Otherwise if it fails to autofill then you have to manually fill the property or the script will get a "None" value.As you wrote the changes to the script it won't compile. You have calls to things in the context of the script outside functions or events (Utility.Wait) which are invalid. You also have the script events declared as functions which are invalid. You also have those same events doing redundant things. When unquipping, unquip? So you're telling the script, when you unequip the ring from the object the script is running on, unequip it from the reference of the property. This is redundant because it's already done, unless you put the script on a different object and then want it to trigger when you unequip from one object, also unequip from another.There's another issue in that you have the script reacting to different objects. If you have the script running on the player detecting when you change areas and then trying to equip/unquip on another actor, you need to make sure that actor is nearby. Followers sometimes take a while to move through load doors. You need the script to actually run on the follower itself and detect when the follower changes areas.Unfortunately for what you're trying to do there's no real elegant solution, only rough hacks. One would be to run a quest with an alias. Place a script on the alias to detect the movement changes and then unequip/re-equip the item you desire on itself (the alias). Then you put whatever reference you want in the alias. It could be the player, or a follower, whatever. However only 1 at a time. Though you can create multiple aliases and use the same script. Another solution that would support multiple objects at once would be to use a magic effect. This would go something like, make ring with enchantment. The enchantment has a script that gets the call/area change. Then it equip/unequips an object defined by a property from the object the magic effect is on (the actor).My preferred method to try and pull this off would be the magic effect script. It would go something like this. Note: This script uses OnLocationChange to detect the movement between areas and has no checking of any kind. This is a bad idea in practice because it will trigger more than necessary. This is only intended for example usage not for actual game play usage.Scriptname TestEffect extends ActiveMagicEffectActor myActor ; holder for the actor this script is affectingArmor RecycleArmorObject ; the armor record to unequip and then re-equipEvent OnEffectStart(Actor akTarget, Actor akCaster)myActor = akTarget ; this is necessary so that other events can act upon the actor the effect is running onEndEventEvent OnLocationChange(Location akOldLoc, Location akNewLoc)myActor.UnequipItem(RecycleArmorObject)Utility.Wait(0.1) ; this may be unnecessary and should be tested with and without it to see which works as desiredmyActor.EquipItem(RecycleArmorObject)EndEventI don't believe the OnCellLoad() would work for what you're trying to do. You would need to attach the script to an object other than the player or the follower that would be in the cell you're going into which would then get the event when it loads. I don't see an easy way to accomplish that in any meaningful manner. The other issue is as I stated before, the follower you want to act on may not be there yet when the event fires. I could be wrong, it would need more testing. If it does work then my script above could be modified to use such. you opened my eyes about the script, this info is really useful for me, you made to jump my understanding from 3% to 50%, also you answered a lot of questions that i forget to ask, thanks! :DSo this line is unnecessaryFunction UnequipItem(Form akItem, bool abPreventEquip = false, bool abSilent = false) nativeand sorry, i had other understanding about "OnCellLoad" i will use "OnLocationChanged" so.this is what i understand and did1.Added a Actor Property (Ahri)2.Added a Armor Property (TheRing)3.And pressed "Auto-Fill All", now the Script Looks like this Scriptname ReEquipRing extends ActiveMagicEffect Actor Property Ahri (My Follower) Auto Armor Property TheRing (JewelryRingGold the real object name with this script attached) Auto Event OnEffectstart(Actor akTarget, Actor akCaster) Ahri = akTargetEndEvent Event OnLocationChange(Location akOldLoc, Location akNewLoc) Ahri.UnequipItem(TheRing) Utility.Wait(0.1) Ahri.EquipItem(TheRing)EndEvent and Saved without a error message.so this script should do1.When the Actor (Ahri) change to another cell (Event OnLocationChange)2.The Ring (TheRing"JewelryRingGold") will be unequipped from Actor (Ahri)3.The RIng (TheRing"JewelryRingGold") will be Equipped to Actor (Ahri) But before test it in game i have some questionswhat means akTarget, akOldLoc, i mean, what means "ak"? what i understand it means "AnyTarget, AnyOldLocation"Also i should 1. attach the Script to the Item that should be Unequipped-Equipped?, or 2. Attach the Script to an Item that makes another item to be Unequipped-Equipped?what i mean, i should make a Scripted GoldRing to Unequip-Equip the same GoldRing with the Script. or i should make a Scripted SilverNecklace to Unequip-Equip the GoldRing Please have patience, im not a english speaker, so i think this will add some walls in the way :unsure: Link to comment Share on other sites More sharing options...
JonathanOstrus Posted October 31, 2017 Share Posted October 31, 2017 To start with your questions: The ak prefix doesn't mean anything special. Variable names can be named just about anything you want. Event OnEffectstart(Actor akTarget, Actor akCaster)This means that when the event is triggered then inside the event scope it will have a variable named akTarget which is of type actor and another variable named akCaster which is also of type actor. The names akCaster and akTarget are completely arbitrary. They could just as easily be "me" and "you" though that would be really confusing to the programmer I would think. Typically programmers will name their variables with descriptive names so they don't forget what they are. In this case the ak prefix doesn't really mean anything particular. In the future you may run into other scripts where people may name the variables with b or i prefixes, like bTargetDead which would typically be a boolean type or iCounter for an integer. In truth the variables can be named just about anything you want as long as it isn't a reserved name or one that is already used. But since most people either copy and paste from the wiki or the base script definition they usually leave them as Bethesda wrote them. Bethesda decided that when the event is called it will be passed 2 parameters. The first being the target actor and the second being the casting actor. Depending on what the magic effect does they may be the same reference. Like casting a self healing, the target and caster is the same actor reference. The script as I wrote it would go on a magic effect. You would create a magic effect, attach the script to that. Then create an object enchantment which uses that magic effect. Then on an armor or weapon attach the enchantment. You can look at the StaffFirebolt "Staff of Firebolts" weapon to see how the hierarchy goes. That weapon has an enchantment named StaffEnchFirebolt "Firebolt" which has a magic effect FireDamageFFAimed "Firebolt" which has a script on it. A similar thing can be done for armor. You can look at any armor with the beginning name Ench to see how the object effect is attached and then linked to a magic effect. Just to reiterate, this script will go on a magic effect that needs to be on the follower since it sets the actor to equip/unquip from as the target of the magic effect. So you would make a ring with an enchantment that the follower will then equip. If you're trying to make a ring that you wear then this script will not work without some fairly major and likely complex changes. There's no need for Ahri to be a property set in CK since you're assigning the value in the OnEffectStart event. Using a local script variable would be better. Changing the line to just this will do exactly the same thing and does not allocate the extra memory required for a property Actor Ahri Link to comment Share on other sites More sharing options...
Recommended Posts