Jump to content

Need some scripting help with some mod edits.


Deathmaw

Recommended Posts

Posted

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

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...