ThatGuyYeah Posted December 28, 2017 Share Posted December 28, 2017 (edited) I am looking for some pointers on the best way to approach doing a simple polling script for an NPC. Essentially, I want this script to check every 24 hours to see if the NPC is following the player and is within a relative distance of the player. If so, the variable I have is incremented by 1 (or whatever value). I am aware that registerforSingleUpdateGameTime(24) would be the better way of working with what I am doing. So my script would look something like this: bool Property bKeepUpdating auto ; Make Global in Script so can be altered by if the NPC is following player Function StartChain() RegisterForSingleUpdateGameTime(24.0) ; Register to be notified every in-game day EndFunction Event OnUpdate() ; Add Increment Here If bKeepUpdating RegisterForSingleUpdateGameTime(24.0) EndIf EndEvent My idea is 'simple:' when the NPC is following the player, this script will run. Once the player dismisses the NPC, the script stops until NPC is following the player again. Any advice would be appreciated. Edited December 28, 2017 by ThatGuyYeah Link to comment Share on other sites More sharing options...
xWilburCobbx Posted December 28, 2017 Share Posted December 28, 2017 (edited) Well I am a beginner myself, but something i found recently during my research is that while statements are used for loops. What I think might be happening with your script is that it only checks for the OnUpdate once and it finishes, if you want it to check every 24 hours AND only if the npc is following you, then maybe you can use this example with an entirely different script to get a general idea on how you should approach this. int ListSize = MyEmptyPotion.GetSize() int CurrentItems = 0 int ItemsLeft = 1 while CurrentItems <= ListSize && ItemsLeft > 0 Form CurrentItem1 = MyEmptyPotion.GetAt(CurrentItems) int ItemCount = PlayerREF.GetItemCount(CurrentItem1) PlayerREF.RemoveItem(CurrentItem1, ItemsLeft) ItemsLeft -= ItemCount CurrentItems += 1 endwhile This I used it to take empty wine bottles from the player inventory. The gist of it is: ItemsLeft is used to know how many items to eraseIt goes through the FormList starting with the first form 0 by CurrentItems which is then assigned to CurrentItem1 to cast that FormList item as a form since .GetItemCount can only count forms such as items. Then it uses .RemoveItem(CurrentItem1, ItemsLeft) to delete the selected item (Which wont do anything of the player doesn't even have the item) Then ItemCount is finally used modify ItemsLeft depending if ItemCount actually found any amount of the form that was selected. If ItemCount count returned 0, then it would use CurrentItems += 1 to keep searching through the form list till CurrentItems <= ListSize which would end the loop. OR If ItemsLeft finished deleting up to the amount it's supposed to then eventually it would become ItemsLeft > 0 which would also end the loop.I know that script does something entire different, but the point is that you can use this as a guide line. You see a loop doesn't permanently modify values such as: int ListSize = MyEmptyPotion.GetSize() int CurrentItems = 0 int ItemsLeft = 1 It only modifies them till the loop ends, go ahead and read that wiki page on it, it explains the important stuff about it. I hope this helps you get a little closer to achieving your goal. Edited December 28, 2017 by smashballsx88 Link to comment Share on other sites More sharing options...
ThatGuyYeah Posted December 28, 2017 Author Share Posted December 28, 2017 The problem is while loops can get nasty in Skyrim and add the script lag and save bloats. I was trying to find a way to avoid that while getting what I am looking at the same time. I was looking for a safer way of doing this without it killing player's games/saves. Link to comment Share on other sites More sharing options...
Evangela Posted December 28, 2017 Share Posted December 28, 2017 (edited) While loops get nasty and bloat saves when they are used incorrectly. Always make sure that the loops will end and use them where they make sense. Your initial approach in my opinion is better than a while loop, because that OnUpdate event is going to fire exactly one time, every 24 hours. If you poll with a while loop for 24 hours, that function/event is going to run that loop for 24 hours. Edited December 28, 2017 by Rasikko Link to comment Share on other sites More sharing options...
ThatGuyYeah Posted December 28, 2017 Author Share Posted December 28, 2017 (edited) So after doing some research, my approach will be as follows: Scriptname SDEPollingScript extends Quest ; This script will poll the character with Serana and see if she is near the player. ObjectReference Property Serana Auto ; Adds Serana as Reference for Code int Property X = 0 auto conditional SDECustomModelScript Property SDECMM Auto ; Reference other script for following status EVENT OnInit() Debug.Trace("OnInit() - Quest 'SDECMM' is running. " +self) ; Info only ENDEVENT Event OnUpdate() If (self as Quest) && self.IsRunning() ; Make sure mod is still running If (Game.GetPlayer().GetDistance(Serana) < 256) && (SDECMM.IsFollowing == true) X += 1 ; Not exact but wanted to add increment to script - will add cap to prevent overflow error Debug.Notification("Your time with Serana has improved your standing with her.") ; Will shorten RegisterForSingleUpdateGameTime(24.0) EndIf EndIf EndEvent And with Serana's following scripts, I will add the following: ((self as Quest) as SDEPollingScript).RegisterForSingleUpdateGameTime(24.0) Does this hold water? Edited December 28, 2017 by ThatGuyYeah Link to comment Share on other sites More sharing options...
xWilburCobbx Posted December 29, 2017 Share Posted December 29, 2017 The problem is while loops can get nasty in Skyrim and add the script lag and save bloats. I was trying to find a way to avoid that while getting what I am looking at the same time. I was looking for a safer way of doing this without it killing player's games/saves. Thank you for clarifying, yeah I had a feeling having this count every 24 hours in a while loop would be problematic. Yeah I started maybe a week ago, and I just got this mind set of what exactly I wanted to make, and ever since then I have just none stopped rammed head first into scripting .... I haven't even made my first simple dungeon yet, and I am already making new crafting systems with modified armor types and other neat stuff, a long side a well optimized and decently designed level. Link to comment Share on other sites More sharing options...
ThatGuyYeah Posted December 29, 2017 Author Share Posted December 29, 2017 The problem is while loops can get nasty in Skyrim and add the script lag and save bloats. I was trying to find a way to avoid that while getting what I am looking at the same time. I was looking for a safer way of doing this without it killing player's games/saves. Thank you for clarifying, yeah I had a feeling having this count every 24 hours in a while loop would be problematic. Yeah I started maybe a week ago, and I just got this mind set of what exactly I wanted to make, and ever since then I have just none stopped rammed head first into scripting .... I haven't even made my first simple dungeon yet, and I am already making new crafting systems with modified armor types and other neat stuff, a long side a well optimized and decently designed level. The best advice I can give is make a dummy esp and just do practice scripts there. I mean RegisterforSingleUpdate when doing what I am doing is technically a loop, but it can easily break itself when it is no longer in use (Which is what I am trying to figure out). But yeah, practice, practice, practice. Link to comment Share on other sites More sharing options...
ThatGuyYeah Posted December 29, 2017 Author Share Posted December 29, 2017 (edited) Alright, after tinkering with the code, I manged to get it to work perfectly. If you are wondering how to do it here is what I did: First, I build a quest for the script and write the main script as follows: Scriptname SDE extends Quest Conditional ; This script will poll the character with Serana and see if she is near the player. DLC1_NPCMentalModelScript Property SDECMM Auto ; Reference other script for following status ObjectReference Property Serana Auto ; Adds Serana as Reference for Code int Property X = 0 auto conditional EVENT OnInit() Debug.Trace("OnInit() - Quest 'SDETestCode' is running. " +self) ; Info only ENDEVENT Event OnUpdateGameTime() If (self as Quest) && self.IsRunning() ; Make sure mod is still running ; Debug.Notification("Seeing this message, code works here.") ; Utility.Wait(2.0) ; Debug.Notification("Checking other code.") ; Utility.Wait(2.0) If (Game.GetPlayer().GetDistance(Serana) < 1024) && (SDECMM.IsFollowing == true) X += 1 ; Not exact but wanted to add increment to script - will add cap to prevent overflow error ; Debug.Notification("Your time with Serana has improved your standing with her.") ; Will shorten RegisterForSingleUpdateGameTime(1.0) ; if (X == 4) ; Debug.Notification("Serana Admires You - Just Kidding.") ; EndIf Else Debug.Notification("Code failed At Following.") EndIf Else Debug.Notification("Code failed At Check.") EndIf EndEvent Next, I implement a simple quest stage (called it 0) with an Empty Log Entry so I can write a simple fragment as so: ((self as Quest) as SDE).RegisterForSingleUpdateGameTime(1.0) With that, the game will check if an in-game hour has passed. Then it will first check to see if the mod is running then it will check to see if Serana is following the player (using her variable that status - will not work for other followers) as well as check if Serana is close by. If all these are true, then my code will do its poll and repeat the cycle in another in-game hour. If any of these fail, the code will stop and will not repeat. I am hoping someone can check to see if the structure of the code will be safe to use and not cause too much issue with saves (i.e bloat). Anyone can now modify this code for 24 hours or for other purposes. Also, ignore the semi-colons, I was using that code for debug and commented it out. Edited December 29, 2017 by ThatGuyYeah Link to comment Share on other sites More sharing options...
Recommended Posts