Jump to content

[FO4 CK] General Help Thread


Recommended Posts

7 hours ago, AWP3RATOR said:

I'm not aware of an easy way to do this, aside from inspecting the plugins.txt, but I don't think that is referable in the runtime engine. In checking F4SE script extender functions, there appear to be a few which might work - though I'm not a papyrus expert....  From a purely coding standpoint, it *MIGHT* be possible to:

 

1. evaluate a form and parse the left 2 characters to get the loaded index

2. evaluate that parsed value against F4SE's function GetInstalledLightPlugins() list

 

I assume GetInstalledPlugins() returns a list, but unsure if it will return plugin name with index values or not.

 

 

Why do you need this?  Just curious.

 

Really, in an ideal world I would get the plugin id string. But after going up and down the wiki many times I'm convinced that it's not possible. I got a bit excited when I saw there was a plugininfo struct containing, amongst other things, String name; on the F4SE version of the Game script.

 

What I want to do is take an object, in this case a cell, and be able to ask. Is this from Bethesda's assets or was it added by a mod?

 

It seems as though Bethesdas plugin files (there's 7 with all DLCs) are hardcoded to be at the top of the load order. So that's cool, I can detect which of those plugins the player has and know the last index of the Bethesda assets the player has loaded (so if they have all 7 the last index would be 06).

 

What I'm doing currently is using that information and saying, if they have for example all of those 7 Bethesda plugins, then the max theoretical formID for Bethesda's base content will be 06FFFFFF (converted to an int would be 117440511). I can then grab a cell formID and check if it's higher than that, so it doesn't originate from one of the Bethesda plugins.

 

There are issues with that, it could be a modified version of one of the original cells. But for what I want to do that's mostly going to be ok and the same issue would arise even if I could get the plugin string ID back.

 

I was hoping that I'd overlooked something obvious.

Link to comment
20 hours ago, AWP3RATOR said:

@Pacman0188  Sorry about that, I assumed you might have known how to get the quest stage components working.  Apologies!  When you add a stage, you also need to "initialize" it by adding a new blank log entry (right-click new).  You don't need to fill this out, it just has to exist - to get the script components part to enable itself.  This is one of those little creation kit idiosyncrasies which is not very obvious or well documented.

 

Can you post the script you entered?

 

Sorry for the late reply, here you are.

 

SanctuaryWorkshopREF.SetPosition(-80928.0000,85736.0000,8188.0000)
SanctuaryWorkshopREF.SetAngle(0 ,0,314.1079)

;Shutdown quest
SetStage(1000)
 

as i mentioned before, i was able to get it to the coordinates i wanted but for whatever odd reason i cant get it to rotate.

Capture.PNG

Link to comment
44 minutes ago, Pacman0188 said:

any solution?

Do it when the reference 3d is loaded.

 

I use the OnLoad() event to manipulate references a lot with good success. Though I never use it on persistent refs (I generally avoid altering persistent refs as a design choice, that's just personal preference).

 

Or you could use OnCellLoad() on a player alias looking for the cell that your reference is in.

 

There's probably many ways to do it.

Link to comment

@Pacman0188  That worked for me with the script method above, and rotates the workshop.  It is hanging out in mid-air, based on your position settings, but it works ;)  I was getting a compile failure when I pasted your script in to my quest fragment though - the last closed parenthesis was coming back as an unknown character.  Fixed that, complied without errors - and it works in game for me.

Link to comment
20 hours ago, AWP3RATOR said:

@Pacman0188  That worked for me with the script method above, and rotates the workshop.  It is hanging out in mid-air, based on your position settings, but it works ;)  I was getting a compile failure when I pasted your script in to my quest fragment though - the last closed parenthesis was coming back as an unknown character.  Fixed that, complied without errors - and it works in game for me.

"unknown character"

 

i tried changing the values every which way buy angle doesn't seem to change regardless... did you change anything else?

Link to comment
15 hours ago, Pacman0188 said:

"unknown character"

 

i tried changing the values every which way buy angle doesn't seem to change regardless... did you change anything else?

I didn't change anything else, no :(  First I plugged your angle values into my working script and it altered the angle.  Then I tried your script with direct/copy paste - and it failed to compile - CK gives an immediate warning on this, so unless you saw an error and saved anyway, it's probably not that.  If you enter your angle in to my script I attached in a previous post, does it work?

Link to comment
47 minutes ago, Tentacus said:

Okay I feel like this might be a scrub ass question but I haven't found the answer through research so... How do I make the player addicted to a chem like say Jet with a script? 

 

Addiction is a series of spells (one for each type of item) which can be applied to the player from consuming alcohol and narcotics.  These items have a base chance of apply the spell on consumption.  You can see/modify the various values in the base item's edit property screen:

 

image.png.472f22aeed66718bb2526a01c1e0933a.png

 

If you wanted to just make the player character addicted to Jet, you could just apply the abAddictionJet spell directly to them through another means - like a scripted event.  The player would then be able to clear the addiction through normal means as well - doctor visit, addictol, etc.

 

https://www.creationkit.com/index.php?title=AddSpell_-_Actor

 

 

Link to comment
On 10/17/2018 at 11:59 PM, AWP3RATOR said:

I didn't change anything else, no :(  First I plugged your angle values into my working script and it altered the angle.  Then I tried your script with direct/copy paste - and it failed to compile - CK gives an immediate warning on this, so unless you saw an error and saved anyway, it's probably not that.  If you enter your angle in to my script I attached in a previous post, does it work?

EDIT: i retested everything, still couldn't get the angle to work but in the long run i figured it was easier to put it along the adjasent wall. 

 

1092022179_Screenshot(7).png.9accc0f20918c9fd09b17fc5f806c9cd.png

 

I want to thank you : @AWP3RATOR and @Carabosse , i really appreciate the help - despite not being in its original position i think it looks good ;)

Link to comment
14 hours ago, AWP3RATOR said:

 

If you wanted to just make the player character addicted to Jet, you could just apply the abAddictionJet spell directly to them through another means - like a scripted event.  The player would then be able to clear the addiction through normal means as well - doctor visit, addictol, etc.

 

https://www.creationkit.com/index.php?title=AddSpell_-_Actor

 

 

Hmmmm I actually had already tried this before I posted. It said in the notification "Jet addiction added" but didn't give the typical "You have become addicted to Jet" notification or show up in the survival icons. :(

 

EDIT:

 

Also tried adding the "AddictionKeywordjet" keyword which didn't seem to help. 

 

EDIT:

 

Okay I think I have a solution :D Did you know that EquipItem() can be used to consume aid items, and they don't even need to be in your inventory? (at least it worked in the console) I sure didn't. So I am just gonna make a 100% addictive version of jet that the script will have the player take at the appropriate time. 

 

This works fine because the whole idea is that raiders force you to take a bunch of jet all at once as a possible outcome to being accosted. Anyway thanks for trying to help.

Link to comment

Not sure if this is where to ask but... does anyone have issues getting .MoveTo(xxxx) to work on the player? [ PlayerRef.MoveTo(XMarkerHeading) ] Is there something specific I need to do to get it to work because no matter how I set things up I can move anything to my XMarkerHeading EXCEPT the player, it just does nothing, no error or anything. I've tried searching but all I see are people giving up and no answers as to why their methods didn't work. (Note : I've use it in Skyrim without any issues, so if there's something specific to FO4 that needs activating or something that might be it, but I just don't know what....)

 

My Marker...

image.png.c8fa9d7aa0c9455f21c6f13c941c3aa5.png

 

For context, I'm making a spawn-point system for a Rogue-Light style mod so these markers are used to create/position different spawn points when entering areas/resting/or set by the player.

Link to comment
11 hours ago, Spirit_Shard said:

...

 

 

I ran a quick test with an editor placed xmarkerheading and one that I could spawn on command. For both types I was able to use a moveto command on the player to those objects. In the same loaded area, outside, from different interiors. Nothing unusual done in setting up, no default settings changes etc. Worked exactly as expected every time. [edit]I was running the moveto command from a holotape fragment.

 

This is a bit of a "works for me", sorry.

 

I know you've probably double, triple checked but check your properties again lol ?. The amount of time I've wasted trying to debug issues in my mods where it turned out I forgot to set a script property somewhere.

Link to comment
11 hours ago, Carabosse said:

...I know you've probably double, triple checked but check your properties again lol ?. The amount of time I've wasted trying to debug issues in my mods where it turned out I forgot to set a script property somewhere.

While it looked right, and was working on the rest of my script something was wonky and this ended up being the problem somehow. I just went through deleting any and all references in Creation Kit and re-added them, now it works as expected. Still lost on what was wrong but it's probably some obscure CK bug >.>

EDIT : Forgot to say thanks.. Thank you! lol

Link to comment

So, is there any way to get a quest script to receive an event when a specific item (potion, in this case) is used?

I'm currently using the Actor.OnItemEquipped(Actor akSender, Form akBaseObject, ObjectReference akReference) event, but akBaseObject only returns [Potion, and akReference returns None. Would it be possible to do more easily with Quest Aliases? What about sending custom event? Each item has it's own script already attached to do something else, but when I tried to do custom events, they didn't seem to fire. I don't want to tie the script to the item itself; the script's already tied to a hidden manager quest.

 

Spoiler

Scriptname Evan555alpha:THICCERThinnerManagerScript Extends Quest
{This script will make the character THICCER or Thinner depending on whether or not they've eaten love recently.}

Group PreReqs
{Required stuff.}
	Quest Property MQ102 Auto Const
	{The main quest of the game that we wait for completion before we start.}
	
	GlobalVariable Property CAPlayerWeight Auto Mandatory
	{Global to keep track of the player's thicc-ness. Caps out at whatever the MCM is set to, max is 100.}
	
	 Potion Property FoodLove Auto
	{Love, the food.}
	
	Potion Property ConcentratedLove Auto
	{Love, the fluid. The kids love this one.}
EndGroup

Group Values
{Arrays of Target and Current values for body morphs.}

	String[] Property MorphNames Auto
	{Array of strings, each string corresponding to their matching morph value. Makes loops much cleaner.}

	Float[] Property TargetBodyMorphs Auto
	{Values for the body morphs we want to reach.}
	
	Float[] Property CurrentBodyMorphs Auto
	{What the body morphs are at the moment. Should be % of target morphs.}
EndGroup

Int Loop = 0
String ModName = "Chrysalis' Armour"
Float MaxWeight
Actor Player

Event OnQuestInit()
	Debug.MessageBox("Thiccness is running.")
	Bool IsDone = (MQ102.IsStageDone(1) as Bool)
	While (IsDone == False)
		Utility.Wait(1.0)
	EndWhile
	Player = Game.GetPlayer()
	RegisterForRemoteEvent(Player, "OnPlayerLoadGame")
	RegisterForRemoteEvent(Player, "OnItemEquipped")
EndEvent

Event Actor.OnPlayerLoadGame(Actor akSender)
	Bool IsDone = MQ102.IsStageDone(1)
	While (IsDone == False)
		Utility.Wait(1.0)
	EndWhile
	RegisterForRemoteEvent(Player, "OnItemEquipped")
EndEvent

Event Actor.OnItemEquipped(Actor akSender, Form akBaseObject, ObjectReference akReference)
	Debug.Notification(akReference)
	If akReference == (FoodLove || ConcentratedLove)
		MaxWeight = MCM.GetModSettingFloat(ModName, "fMaxPlayerWeight:Morphs")
		GetRefMorphs()
		Utility.Wait(5.0)
		Thiccer()
		StartTimerGameTime(72.0, 555)
	EndIf
EndEvent

Event OnTimerGameTime(Int aiTimerID)
	If aiTimerID == 555
		Thinner()
		StartTimerGameTime(1.0, 111)
	ElseIf aiTimerID == 111
		If CAPlayerWeight.GetValueInt() > 0
			Thinner()
			StartTimerGameTime(1.0, 111)
		EndIf
	EndIf
EndEvent

Function GetRefMorphs()
	Debug.Notification("Getting Reference Morphs.")
	While Loop <= 39
		CurrentBodyMorphs[Loop] = BodyGen.GetMorph(Player, True, MorphNames[Loop], None)
		Loop += 1
	EndWhile
	Loop = 0
EndFunction

Function Thiccer()
	CancelTimerGameTime(555)
	CAPlayerWeight.Mod(1.0)
	Debug.Notification("Growing...")
	While Loop <= 39
		BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] + (TargetBodyMorphs[Loop]/MaxWeight)))
		Loop += 1
	EndWhile
	BodyGen.UpdateMorphs(Player)
	Loop = 0
EndFunction

Function Thinner()
	Debug.Notification("Shrinking...")
	CAPlayerWeight.Mod(-1.0)
	While Loop <= 39
		BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] - (TargetBodyMorphs[Loop]/MaxWeight)))
		Loop += 1
	EndWhile
	BodyGen.UpdateMorphs(Player)
	Loop = 0
EndFunction

Function CleanSlateBody()
	While Loop <= 39
		BodyGen.SetMorph(Player, True, MorphNames[Loop], None, 0.0)
		Loop += 1
	EndWhile
	BodyGen.UpdateMorphs(Player)
	Loop = 0
EndFunction

 

Spoiler'd is the script in question.

Link to comment
2 hours ago, Evan555alpha said:

So, is there any way to get a quest script to receive an event when a specific item (potion, in this case) is used?

I'm currently using the Actor.OnItemEquipped(Actor akSender, Form akBaseObject, ObjectReference akReference) event, but akBaseObject only returns [Potion, and akReference returns None. Would it be possible to do more easily with Quest Aliases? What about sending custom event? Each item has it's own script already attached to do something else, but when I tried to do custom events, they didn't seem to fire. I don't want to tie the script to the item itself; the script's already tied to a hidden manager quest.

 

  Reveal hidden contents


Scriptname Evan555alpha:THICCERThinnerManagerScript Extends Quest
{This script will make the character THICCER or Thinner depending on whether or not they've eaten love recently.}

Group PreReqs
{Required stuff.}
	Quest Property MQ102 Auto Const
	{The main quest of the game that we wait for completion before we start.}
	
	GlobalVariable Property CAPlayerWeight Auto Mandatory
	{Global to keep track of the player's thicc-ness. Caps out at whatever the MCM is set to, max is 100.}
	
	 Potion Property FoodLove Auto
	{Love, the food.}
	
	Potion Property ConcentratedLove Auto
	{Love, the fluid. The kids love this one.}
EndGroup

Group Values
{Arrays of Target and Current values for body morphs.}

	String[] Property MorphNames Auto
	{Array of strings, each string corresponding to their matching morph value. Makes loops much cleaner.}

	Float[] Property TargetBodyMorphs Auto
	{Values for the body morphs we want to reach.}
	
	Float[] Property CurrentBodyMorphs Auto
	{What the body morphs are at the moment. Should be % of target morphs.}
EndGroup

Int Loop = 0
String ModName = "Chrysalis' Armour"
Float MaxWeight
Actor Player

Event OnQuestInit()
	Debug.MessageBox("Thiccness is running.")
	Bool IsDone = (MQ102.IsStageDone(1) as Bool)
	While (IsDone == False)
		Utility.Wait(1.0)
	EndWhile
	Player = Game.GetPlayer()
	RegisterForRemoteEvent(Player, "OnPlayerLoadGame")
	RegisterForRemoteEvent(Player, "OnItemEquipped")
EndEvent

Event Actor.OnPlayerLoadGame(Actor akSender)
	Bool IsDone = MQ102.IsStageDone(1)
	While (IsDone == False)
		Utility.Wait(1.0)
	EndWhile
	RegisterForRemoteEvent(Player, "OnItemEquipped")
EndEvent

Event Actor.OnItemEquipped(Actor akSender, Form akBaseObject, ObjectReference akReference)
	Debug.Notification(akReference)
	If akReference == (FoodLove || ConcentratedLove)
		MaxWeight = MCM.GetModSettingFloat(ModName, "fMaxPlayerWeight:Morphs")
		GetRefMorphs()
		Utility.Wait(5.0)
		Thiccer()
		StartTimerGameTime(72.0, 555)
	EndIf
EndEvent

Event OnTimerGameTime(Int aiTimerID)
	If aiTimerID == 555
		Thinner()
		StartTimerGameTime(1.0, 111)
	ElseIf aiTimerID == 111
		If CAPlayerWeight.GetValueInt() > 0
			Thinner()
			StartTimerGameTime(1.0, 111)
		EndIf
	EndIf
EndEvent

Function GetRefMorphs()
	Debug.Notification("Getting Reference Morphs.")
	While Loop <= 39
		CurrentBodyMorphs[Loop] = BodyGen.GetMorph(Player, True, MorphNames[Loop], None)
		Loop += 1
	EndWhile
	Loop = 0
EndFunction

Function Thiccer()
	CancelTimerGameTime(555)
	CAPlayerWeight.Mod(1.0)
	Debug.Notification("Growing...")
	While Loop <= 39
		BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] + (TargetBodyMorphs[Loop]/MaxWeight)))
		Loop += 1
	EndWhile
	BodyGen.UpdateMorphs(Player)
	Loop = 0
EndFunction

Function Thinner()
	Debug.Notification("Shrinking...")
	CAPlayerWeight.Mod(-1.0)
	While Loop <= 39
		BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] - (TargetBodyMorphs[Loop]/MaxWeight)))
		Loop += 1
	EndWhile
	BodyGen.UpdateMorphs(Player)
	Loop = 0
EndFunction

Function CleanSlateBody()
	While Loop <= 39
		BodyGen.SetMorph(Player, True, MorphNames[Loop], None, 0.0)
		Loop += 1
	EndWhile
	BodyGen.UpdateMorphs(Player)
	Loop = 0
EndFunction

 

Spoiler'd is the script in question.

Not knowing exactly what it is, but being familiar with your mod in general - I'd say it may be easier to tie the script to the consumable item, to call SetStage on a specific quest when it is consumed.  That is much more foolproof than trying to detect if a specific item was used/consumed/equipped.  Since you're needing to do this for a specific item in your mod, you could attach a script that calls a stage an a repeatable quest, which your overall handler quest is listening for.  You'd need to register that subquest to the main handler quest - but it should work for this application.

Link to comment
41 minutes ago, AWP3RATOR said:

Not knowing exactly what it is, but being familiar with your mod in general - I'd say it may be easier to tie the script to the consumable item, to call SetStage on a specific quest when it is consumed.  That is much more foolproof than trying to detect if a specific item was used/consumed/equipped.  Since you're needing to do this for a specific item in your mod, you could attach a script that calls a stage an a repeatable quest, which your overall handler quest is listening for.  You'd need to register that subquest to the main handler quest - but it should work for this application.

Thanks for the suggestion, but working on this whilst waiting for a reply, I found the event "OnMagicEffectApply()" which I could register to my script with "RegisterForMagicEffectApplyEvent()".

 

I could use these two, as both the specific items I'm trying to listen for have a unique magic effect that I use to apply another script. By listening out for these script MGEFs, I was able to get this script's functions to happen.

 

The entire point of this script is so that the entire set of bodymorphs for the player will increase a little each time a particular object is eaten, until a set of target morphs are reached. Sadly, the target morphs are currently hard-coded in to be equivalent to the preset that comes with the mod. Ideally, I'd use something, possibly an F4SE plugin, to parse either bodyslide presets, or LM presets, and scrape morph data from them, and convert it to the right format.

 

Spoiler'd is the updated, working script:

Spoiler

Scriptname Evan555alpha:THICCERThinnerManagerScript Extends Quest
{This script will make the character THICCER or Thinner depending on whether or not they've eaten love recently.}

Group PreReqs
{Required stuff.}
	Quest Property MQ102 Auto Const
	{The main quest of the game that we wait for completion before we start.}
	
	GlobalVariable Property CAPlayerWeight Auto Mandatory
	{Global to keep track of the player's thicc-ness. Caps out at whatever the MCM is set to, max is 100.}
	
	MagicEffect Property FoodLove Auto
	{Love, the food.}
	
	MagicEffect Property ConcentratedLove Auto
	{Love, the fluid. The kids love this one.}
EndGroup

Group Values
{Arrays of Target and Current values for body morphs.}

	String[] Property MorphNames Auto
	{Array of strings, each string corresponding to their matching morph value. Makes loops much cleaner.}

	Float[] Property TargetBodyMorphs Auto
	{Values for the body morphs we want to reach.}
	
	Float[] Property CurrentBodyMorphs Auto
	{What the body morphs are at the moment. Should be % of target morphs.}
EndGroup

Int Loop = 0
String ModName = "Chrysalis' Armour"
Float MaxWeight
Float CurrentWeight
Float Difference
Actor Player

Event OnQuestInit()
	Debug.Trace("Evan555alpha:Thiccness is running.")
	Bool IsDone = (MQ102.IsStageDone(1) as Bool)
	While (IsDone == False)
		Utility.Wait(1.0)
	EndWhile
	Player = Game.GetPlayer()
	RegisterForRemoteEvent(Player, "OnPlayerLoadGame")
	RegisterForMagicEffectApplyEvent(Player, None, FoodLove, True)
	RegisterForMagicEffectApplyEvent(Player, None, ConcentratedLove, True)
EndEvent

Event Actor.OnPlayerLoadGame(Actor akSender)
	Debug.Trace("Thiccness runs on save load.")
	Bool IsDone = MQ102.IsStageDone(1)
	While (IsDone == False)
		Utility.Wait(1.0)
	EndWhile
	RegisterForMagicEffectApplyEvent(Player, None, FoodLove, True)
	RegisterForMagicEffectApplyEvent(Player, None, ConcentratedLove, True)
EndEvent

Event OnMagicEffectApply(ObjectReference akTarget, ObjectReference akCaster, MagicEffect akEffect)
	RegisterForMagicEffectApplyEvent(Player, None, FoodLove, True)
	RegisterForMagicEffectApplyEvent(Player, None, ConcentratedLove, True)
	If (MCM.GetModSettingBool(ModName, "bPlayerWeightChange:Morphs") as Bool) == True
		MaxWeight = MCM.GetModSettingFloat(ModName, "fMaxPlayerWeight:Morphs")
		CurrentWeight = CAPlayerWeight.GetValueInt()
		GetCurrentMorphs()
		Utility.Wait(5.0)
		If akEffect == ConcentratedLove as MagicEffect
			ExtraThiccer()
		Else
			Thiccer()
		EndIf
		StartTimerGameTime(72.0, 555)
	Else
		Debug.Trace("Evan555alpha: Weight change is disabled.")
	EndIf
EndEvent

Event OnTimerGameTime(Int aiTimerID)
	If aiTimerID == 555
		Thinner()
		StartTimerGameTime(1.0, 111)
	ElseIf aiTimerID == 111
		If CurrentWeight > 0
			Thinner()
			StartTimerGameTime(1.0, 111)
		EndIf
	EndIf
EndEvent

Function GetCurrentMorphs()
	Debug.Trace("Getting Current Morphs.")
	While Loop <= 39
		CurrentBodyMorphs[Loop] = BodyGen.GetMorph(Player, True, MorphNames[Loop], None)
		Loop += 1
	EndWhile
	Loop = 0
EndFunction

Function Thiccer()
	CancelTimerGameTime(555)
	Utility.Wait(5)
	If CurrentWeight < MaxWeight
		CAPlayerWeight.Mod(1.0)
		Debug.Trace("Growing...")
		While Loop <= 39
			BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] + (TargetBodyMorphs[Loop]/MaxWeight)))
			Loop += 1
		EndWhile
		BodyGen.UpdateMorphs(Player)
		Loop = 0
	Else
		Debug.Trace("Maximum weight achieved.")
	EndIf
EndFunction

Function ExtraThiccer()
	CancelTimerGameTime(555)
	Utility.Wait((MCM.GetModSettingInt(ModName, "iSuperLoveTime:Time") + 5))
	If CurrentWeight <= (MaxWeight - 10)
		CAPlayerWeight.Mod(10.0)
		Debug.Trace("Really growing...")
		While Loop <= 39
			BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] + ((TargetBodyMorphs[Loop]/MaxWeight) * 10.0)))
			Loop += 1
		EndWhile
		BodyGen.UpdateMorphs(Player)
		Loop = 0
	ElseIf (CurrentWeight > (MaxWeight - 10)) && (CurrentWeight < MaxWeight)
		Difference = (MaxWeight - CurrentWeight)
		CAPlayerWeight.Mod(Difference)
		Debug.Trace("Growing by not as much...")
		While Loop <= 39
			BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] + ((TargetBodyMorphs[Loop]/MaxWeight) * Difference)))
			Loop += 1
		EndWhile
		BodyGen.UpdateMorphs(Player)
		Loop = 0
	Else
		Debug.Trace("Maximum weight achieved.")
	EndIf
EndFunction

Function Thinner()
	Debug.Trace("Shrinking...")
	If CAPlayerWeight.GetValueInt() > 0
		CAPlayerWeight.Mod(-1.0)
		While Loop <= 39
			BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] - (TargetBodyMorphs[Loop]/MaxWeight)))
			Loop += 1
		EndWhile
		BodyGen.UpdateMorphs(Player)
		Loop = 0
	Else
		Debug.Trace("Minimum weight achieved.")
	EndIf
EndFunction

Function CleanSlateBody()
	While Loop <= 39
		BodyGen.SetMorph(Player, True, MorphNames[Loop], None, 0.0)
		Loop += 1
	EndWhile
	BodyGen.UpdateMorphs(Player)
	Loop = 0
EndFunction

 

 

Link to comment
5 minutes ago, Evan555alpha said:

Thanks for the suggestion, but working on this whilst waiting for a reply, I found the event "OnMagicEffectApply()" which I could register to my script with "RegisterForMagicEffectApplyEvent()".

 

I could use these two, as both the specific items I'm trying to listen for have a unique magic effect that I use to apply another script. By listening out for these script MGEFs, I was able to get this script's functions to happen.

 

The entire point of this script is so that the entire set of bodymorphs for the player will increase a little each time a particular object is eaten, until a set of target morphs are reached. Sadly, the target morphs are currently hard-coded in to be equivalent to the preset that comes with the mod. Ideally, I'd use something, possibly an F4SE plugin, to parse either bodyslide presets, or LM presets, and scrape morph data from them, and convert it to the right format.

 

Spoiler'd is the updated, working script:

  Reveal hidden contents


Scriptname Evan555alpha:THICCERThinnerManagerScript Extends Quest
{This script will make the character THICCER or Thinner depending on whether or not they've eaten love recently.}

Group PreReqs
{Required stuff.}
	Quest Property MQ102 Auto Const
	{The main quest of the game that we wait for completion before we start.}
	
	GlobalVariable Property CAPlayerWeight Auto Mandatory
	{Global to keep track of the player's thicc-ness. Caps out at whatever the MCM is set to, max is 100.}
	
	MagicEffect Property FoodLove Auto
	{Love, the food.}
	
	MagicEffect Property ConcentratedLove Auto
	{Love, the fluid. The kids love this one.}
EndGroup

Group Values
{Arrays of Target and Current values for body morphs.}

	String[] Property MorphNames Auto
	{Array of strings, each string corresponding to their matching morph value. Makes loops much cleaner.}

	Float[] Property TargetBodyMorphs Auto
	{Values for the body morphs we want to reach.}
	
	Float[] Property CurrentBodyMorphs Auto
	{What the body morphs are at the moment. Should be % of target morphs.}
EndGroup

Int Loop = 0
String ModName = "Chrysalis' Armour"
Float MaxWeight
Float CurrentWeight
Float Difference
Actor Player

Event OnQuestInit()
	Debug.Trace("Evan555alpha:Thiccness is running.")
	Bool IsDone = (MQ102.IsStageDone(1) as Bool)
	While (IsDone == False)
		Utility.Wait(1.0)
	EndWhile
	Player = Game.GetPlayer()
	RegisterForRemoteEvent(Player, "OnPlayerLoadGame")
	RegisterForMagicEffectApplyEvent(Player, None, FoodLove, True)
	RegisterForMagicEffectApplyEvent(Player, None, ConcentratedLove, True)
EndEvent

Event Actor.OnPlayerLoadGame(Actor akSender)
	Debug.Trace("Thiccness runs on save load.")
	Bool IsDone = MQ102.IsStageDone(1)
	While (IsDone == False)
		Utility.Wait(1.0)
	EndWhile
	RegisterForMagicEffectApplyEvent(Player, None, FoodLove, True)
	RegisterForMagicEffectApplyEvent(Player, None, ConcentratedLove, True)
EndEvent

Event OnMagicEffectApply(ObjectReference akTarget, ObjectReference akCaster, MagicEffect akEffect)
	RegisterForMagicEffectApplyEvent(Player, None, FoodLove, True)
	RegisterForMagicEffectApplyEvent(Player, None, ConcentratedLove, True)
	If (MCM.GetModSettingBool(ModName, "bPlayerWeightChange:Morphs") as Bool) == True
		MaxWeight = MCM.GetModSettingFloat(ModName, "fMaxPlayerWeight:Morphs")
		CurrentWeight = CAPlayerWeight.GetValueInt()
		GetCurrentMorphs()
		Utility.Wait(5.0)
		If akEffect == ConcentratedLove as MagicEffect
			ExtraThiccer()
		Else
			Thiccer()
		EndIf
		StartTimerGameTime(72.0, 555)
	Else
		Debug.Trace("Evan555alpha: Weight change is disabled.")
	EndIf
EndEvent

Event OnTimerGameTime(Int aiTimerID)
	If aiTimerID == 555
		Thinner()
		StartTimerGameTime(1.0, 111)
	ElseIf aiTimerID == 111
		If CurrentWeight > 0
			Thinner()
			StartTimerGameTime(1.0, 111)
		EndIf
	EndIf
EndEvent

Function GetCurrentMorphs()
	Debug.Trace("Getting Current Morphs.")
	While Loop <= 39
		CurrentBodyMorphs[Loop] = BodyGen.GetMorph(Player, True, MorphNames[Loop], None)
		Loop += 1
	EndWhile
	Loop = 0
EndFunction

Function Thiccer()
	CancelTimerGameTime(555)
	Utility.Wait(5)
	If CurrentWeight < MaxWeight
		CAPlayerWeight.Mod(1.0)
		Debug.Trace("Growing...")
		While Loop <= 39
			BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] + (TargetBodyMorphs[Loop]/MaxWeight)))
			Loop += 1
		EndWhile
		BodyGen.UpdateMorphs(Player)
		Loop = 0
	Else
		Debug.Trace("Maximum weight achieved.")
	EndIf
EndFunction

Function ExtraThiccer()
	CancelTimerGameTime(555)
	Utility.Wait((MCM.GetModSettingInt(ModName, "iSuperLoveTime:Time") + 5))
	If CurrentWeight <= (MaxWeight - 10)
		CAPlayerWeight.Mod(10.0)
		Debug.Trace("Really growing...")
		While Loop <= 39
			BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] + ((TargetBodyMorphs[Loop]/MaxWeight) * 10.0)))
			Loop += 1
		EndWhile
		BodyGen.UpdateMorphs(Player)
		Loop = 0
	ElseIf (CurrentWeight > (MaxWeight - 10)) && (CurrentWeight < MaxWeight)
		Difference = (MaxWeight - CurrentWeight)
		CAPlayerWeight.Mod(Difference)
		Debug.Trace("Growing by not as much...")
		While Loop <= 39
			BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] + ((TargetBodyMorphs[Loop]/MaxWeight) * Difference)))
			Loop += 1
		EndWhile
		BodyGen.UpdateMorphs(Player)
		Loop = 0
	Else
		Debug.Trace("Maximum weight achieved.")
	EndIf
EndFunction

Function Thinner()
	Debug.Trace("Shrinking...")
	If CAPlayerWeight.GetValueInt() > 0
		CAPlayerWeight.Mod(-1.0)
		While Loop <= 39
			BodyGen.SetMorph(Player, True, MorphNames[Loop], None, (CurrentBodyMorphs[Loop] - (TargetBodyMorphs[Loop]/MaxWeight)))
			Loop += 1
		EndWhile
		BodyGen.UpdateMorphs(Player)
		Loop = 0
	Else
		Debug.Trace("Minimum weight achieved.")
	EndIf
EndFunction

Function CleanSlateBody()
	While Loop <= 39
		BodyGen.SetMorph(Player, True, MorphNames[Loop], None, 0.0)
		Loop += 1
	EndWhile
	BodyGen.UpdateMorphs(Player)
	Loop = 0
EndFunction

 

That solution works (RegisterForMagicEffectApplyEvent())  - but overall, (and I'm NOT sure) I wonder about the performance that takes with a script always listening for a specific event when all chars? or the player drinks/eats something, vs that that consumable object directly calling a stage on a quest.  Probably net net equal in the end.  One is probably "better" than the other, but good show figuring that out - I'd not have thought of that one!

 

Link to comment

Item references are a bit funky when they sit in inventory.  IIRC, things like potions and consumables have their references deleted when sitting in a container.  So, that's probably why the reference is returning none.  The hardcore manager script monitors OnItemEquipped, and only works with the BaseObject property when it's checking if the item used was food and needs to deal with food or drink pools.

 

Looking at your script, you should be comparing the base object returned by OnItemEquipped to the potion you declared in the header since that's technically a base object as well.

 

Just for reference, here's a snippet from HC_Manager for parsing food items.

Event Actor.OnItemEquipped(Actor akSender, Form akBaseObject, ObjectReference akReference)
	; As long as your actually food and not one of our many tasty potions, lets add you to the food array.
	if akBaseObject == HC_Antibiotics || (akReference == none || false == akReference.IsQuestItem()) && false == CommonArrayFunctions.CheckFormAgainstKeywordArray(akBaseObject, NonFoodKeywords)
		AddFoodItem(akBaseObject)
	endif

EndEvent

 

The reference is only of concern when it's a quest item.  Notice that the check is specifically filtering out references if they aren't returning NONE.

Link to comment
  • 1 month later...

Is there a way to have multiple instances of the same actor be treated as individuals by the game? What about multiple instances of the same quest alias?

 

I've got a pseudo-follower character who functions as I want them to, and has a manager quest for dialogue interactions with them. The thing is, I want it for there to be multiple instances of this follower, all of which are treated as their own thing.

It probably doesn't help that I use quest stages to manage whether this follower is actively following, waiting, or fired.

Could I possibly use multiple aliases, rather than a single alias?

Link to comment
  • 2 weeks later...

Does anybody know of a working way to cripple the player's head with a script?

 

I've tried:   

PlayerRef.DamageValue(BrainCondition, 100)

and

PlayerRef.DamageValue(PerceptionCondition, 100)

Neither seems to do anything... Though using (for example) "Left MobilityCondition" works fine to cripple the left leg in the same manner. Is it a different actor value? Is a different method required? Or does it simply not work?   

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use