Deathmaw Posted July 5, 2015 Posted July 5, 2015 So I am trying to edit Private Needs Discreet to change a feature that has been bugging me for a while. I would ask lhalorellon the mod author but he hasn't been online since feb. Mod Link: http://www.loverslab.com/topic/29535-private-needs-discreet/page-1 This mod has a feature that adds a timer to npcs for them too pee etc. This is all I want it to do. The problem is that it seems to randomize the value on every cell load rather than retaining it between cells. So If I am going through a dungeon or a building with a lot of cells my followers end up urinating like every two minutes. Which is incredibly annoying on every cell load waiting for them to finish. I have the in game timer set to 6 hours. So every 6 hours they should need to urinate. The script that seems to control this part of the mod is as follows: Scriptname PND_NPCMonitorEffectScript extends activemagiceffect Actor MySelf Actor Property PlayerRef Auto Quest Property PND_MainQuest Auto Keyword Property ActorTypeNPC Auto float Property lastBladderEmptyTime = 0.0 Auto Hidden float Property lastBowelEmptyTime = 0.0 Auto Hidden PND_MainScript main Event OnEffectStart(Actor akTarget, Actor akCaster) If !akTarget Return EndIf If !akTarget.HasKeyword(ActorTypeNPC) Return EndIf MySelf = akTarget GoToState("alive") ;Log("NPC "+GetActorNameAndRace(MySelf)+" is an actor in this spell") EndEvent ; NOTE: if dispelling within player cloak, this effect will be re-cast very quickly. ; Effect is dispelled automatically at unload. Event OnEffectFinish(Actor akTarget, Actor akCaster) ;Log("NPC "+GetActorNameAndRace(akTarget)+" is dispelled") EndEvent Event OnUnload() ; Effect is dispelled automatically, dispelling it here will cause errors EndEvent Auto State void EndState State alive ; The effect reset between loading screens. ; Therefore NPC bladder/bower starts with a random value. ; Just imagine them doing it a little after you go in a door when you did not see. Event OnBeginState() float timeNow = Utility.GetCurrentGameTime() ; time diff -2.5 == 12h (TODO: does this depend on time scale?) float tdBladder = Utility.RandomFloat(0.6, 1.4) float tdBowel = Utility.RandomFloat(0.2, 0.8) lastBladderEmptyTime = timeNow - tdBladder lastBowelEmptyTime = timeNow - tdBowel RegisterForSingleUpdate(0) main = (PND_MainQuest As PND_MainScript) if main.options.MCM_NPCDebugNotifications ; costly log only when debug is on int hour = ((timeNow * 24) As int) % 24 Log("At "+hour+" o'clock BEGIN " + GetActorNameAndRace(MySelf) + " tdBladder: "+tdBladder+ " tdBowel: "+tdBowel) endif EndEvent Event OnUpdate() if !(MySelf as ObjectReference) Return EndIf If MySelf.IsDisabled() || MySelf.IsDead() Return EndIf float dist = PlayerRef.GetDistance(MySelf) If dist > 100000 ; too far away - this object is being unloaded soon Return EndIf ; compat If !main main = (PND_MainQuest As PND_MainScript) EndIf If dist > 24500 ; activate magical cleaning fairy main.CleanupSurroundingArea(MySelf) EndIf int availStatus = main.npcq.GetActorAvailabilityWithCurrentOptions(MySelf) ;Log(GetActorNameAndRace(MySelf) + " status: "+availStatus) ; 0: unavailable and away .................. If availStatus == 0 Return ; 1: not a follower or ally when only followers option ticked, put on slow update .................. ElseIf availStatus == 1 if main.options.MCM_NPCDebugNotifications && dist < 250 main.Info(GetActorNameAndRace(MySelf) + " is not a follower") EndIf RegisterForSingleUpdate(main.options.MCM_NPCNeedsCheckInterval * 3) Return ; 20: guard ElseIf availStatus == 20 if dist < 1000 && main.PlayerIsDoing > 0 main.npcq.PlayReactionToPlayer(MySelf) endif RegisterForSingleUpdate(main.options.MCM_NPCNeedsCheckInterval) Return EndIf ; availStatus checks cont'd later ; NPCs have two timers for both urinating and defecating, "bladder" and "bowels" ; so to speak. Mod users seem to like to have this feature on the player too se ; this needs a serious rewrite. The debuff could be dirty effect shader. float timeNow = Utility.GetCurrentGameTime() int bladderBuildup = (((timeNow - lastBladderEmptyTime) * 24) As int) % 24 if bladderBuildup < 0 || bladderBuildup > 24 bladderBuildup = 0 EndIf int bowelBuildup = (((timeNow - lastBowelEmptyTime) * 24) As int) % 24 if bowelBuildup < 0 || bowelBuildup > 36 bowelBuildup = 0 EndIf float bladderRate = 0 if main.options.MCM_NPCFullBladderBuildUp > 0 bladderRate = bladderBuildup / (main.options.MCM_NPCFullBladderBuildUp as float) endif float bowelRate = 0 if main.options.MCM_NPCFullBowelBuildUp > 0 bowelRate = bowelBuildup / (main.options.MCM_NPCFullBowelBuildUp as float) endif ; Very deep debug of nearby NPC status If main.options.MCM_NPCDebugNotifications && dist < 500 int hour = ((timeNow * 24) As int) % 24 int b = (bladderRate * 100) as int int l = (bowelRate * 100) as int if b > 0 || l > 0 main.Info("At "+hour+" o'clock "+ GetActorNameAndRace(MySelf) +" bladder: "+b+"%, bowel: "+l+"%") endif EndIf ; we wont leave them without release! ; they do it while player did not notice. ;O) ; this is also a way to shuffle up their pee schedules out of sync. if bladderRate > Utility.RandomFloat(1.5, 2.0) lastBladderEmptyTime = timeNow bladderRate = 0 endif if bowelRate > Utility.RandomFloat(1.5, 2.0) lastBowelEmptyTime = timeNow bowelRate = 0 endif ; continue availStatus checks for status > 1 ; 2: unavailable, put on needs check interval .................. If availStatus == 2 RegisterForSingleUpdate(main.options.MCM_NPCNeedsCheckInterval) Return ; 10: location not suitable .................. ElseIf availStatus == 10 if bladderRate >= 1 if main.options.MCM_NPCDebugNotifications && dist < 500 main.Info(GetActorNameAndRace(MySelf) + " feels the urge to urinate, but not here") endif endif if bowelRate >= 1 if main.options.MCM_NPCDebugNotifications && dist < 500 main.Info(GetActorNameAndRace(MySelf) + " feels the urge to defecate, but not here") endif endif RegisterForSingleUpdate(main.options.MCM_NPCNeedsCheckInterval) Return EndIf ; MySelf am an npc who is nearby and passed mcm options checks. ; Valid for NPC voluntary action ; Chance means really the interval between releases if main.options.MCM_NPCFullBladderBuildUp > 0 && bladderBuildup >= main.options.MCM_NPCFullBladderBuildUp If main.options.MCM_NPCDebugNotifications main.Info(GetActorNameAndRace(MySelf)+" feels the urge to urinate") EndIf main.PlayUrinatingSequence(MySelf) lastBladderEmptyTime = timeNow RegisterForSingleUpdate(main.options.MCM_NPCPostActionTimeout * 60) Return EndIf if main.options.MCM_NPCFullBowelBuildUp > 0 && bowelBuildup >= main.options.MCM_NPCFullBowelBuildUp If main.options.MCM_NPCDebugNotifications main.Info(GetActorNameAndRace(MySelf)+" feels the urge to defecate") EndIf main.PlayDefecatingSequence(MySelf) lastBowelEmptyTime = timeNow RegisterForSingleUpdate(main.options.MCM_NPCPostActionTimeout * 60) Return EndIf ; React if player is doing something If main.PlayerIsDoing > 0 && Utility.RandomInt(1, 100) <= main.options.MCM_NPCReactionChance If main.npcq.PlayReactionToPlayer(MySelf) If main.PlayerIsDoing == 1 lastBladderEmptyTime = timeNow ElseIf main.PlayerIsDoing == 2 lastBowelEmptyTime = timeNow EndIf RegisterForSingleUpdate(main.options.MCM_NPCPostActionTimeout * 60) Return EndIf EndIf RegisterForSingleUpdate(main.options.MCM_NPCNeedsCheckInterval) EndEvent EndState Function RegisterUpdateWithNotifications(int realtimeTO, string reason) if realtimeTO > 900 realtimeTO = 900 EndIf If main.options.MCM_NPCDebugNotifications If reason != "" && reason != "None" string msg = GetActorNameAndRace(MySelf) + " " + reason ;msg += " ("+realtimeTO+"s off)" main.Info(msg) EndIf EndIf RegisterForSingleUpdate(realtimeTO) EndFunction string Function GetActorNameAndRace(Actor akTarget) Return (akTarget.GetBaseObject() As ActorBase).GetName() +" ("+akTarget.GetRace().GetName()+")" EndFunction Function Log(String msg) Debug.Trace("PND> "+msg) EndFunction This would seem to be the part that is causing the issue. So would removing this entry fix my problem so that followers would remember their states between cells? Event OnBeginState() float timeNow = Utility.GetCurrentGameTime() ; time diff -2.5 == 12h (TODO: does this depend on time scale?) float tdBladder = Utility.RandomFloat(0.6, 1.4) float tdBowel = Utility.RandomFloat(0.2, 0.8) lastBladderEmptyTime = timeNow - tdBladder lastBowelEmptyTime = timeNow - tdBowel RegisterForSingleUpdate(0) main = (PND_MainQuest As PND_MainScript) if main.options.MCM_NPCDebugNotifications ; costly log only when debug is on int hour = ((timeNow * 24) As int) % 24 Log("At "+hour+" o'clock BEGIN " + GetActorNameAndRace(MySelf) + " tdBladder: "+tdBladder+ " tdBowel: "+tdBowel) endif EndEvent
Recommended Posts
Archived
This topic is now archived and is closed to further replies.