Compare View

switch
from
...
to
 
Commits (22)

Diff

Showing 56 changed files

Readme - SexLab Framework.txt View file @ ebb16a7
... ... @@ -3,7 +3,7 @@
3 3 Skryim SexLab Framework
4 4 By Ashal of Loverslab.com
5 5  
6   - Version 1.30, released 2013/12/15
  6 + Version 1.31, released 2013/12/20
7 7  
8 8 -- Description --------------------------------------------------------------
9 9  
... ... @@ -20,6 +20,7 @@ Skryim SexLab Framework
20 20 -- Modders Resource ---------------------------------------------------------
21 21  
22 22 API Guide: http://git.loverslab.com/sexlab/framework/wikis/home
  23 + What's New: http://git.loverslab.com/sexlab/framework/wikis/whatsnew
23 24  
24 25 -- Credits ------------------------------------------------------------------
25 26  
SKSE/Plugins/StorageUtil.dll View file @ ebb16a7

No preview for this file type

No preview for this file type

Sound/fx/SexLab/fxOrgasm01/01.wav View file @ ebb16a7

No preview for this file type

Sound/fx/SexLab/fxOrgasm01/02.wav View file @ ebb16a7

No preview for this file type

scripts/ActorUtil.pex View file @ ebb16a7

No preview for this file type

scripts/MiscUtil.pex View file @ ebb16a7

No preview for this file type

scripts/SexLabFramework.pex View file @ ebb16a7

No preview for this file type

scripts/SexLabUtil.pex View file @ ebb16a7

No preview for this file type

scripts/Source/ActorUtil.psc View file @ ebb16a7
... ... @@ -0,0 +1,20 @@
  1 +scriptname ActorUtil Hidden
  2 +
  3 +;/
  4 + Packages.
  5 +/;
  6 +
  7 +; This will add a package to actor that will override its normal behavior. Using this function overrides all packages added from any other location.
  8 +function AddPackageOverride(Actor targetActor, Package targetPackage, int priority = 30, int flags = 0) global native
  9 +
  10 +; Remove a previously added package override.
  11 +bool function RemovePackageOverride(Actor targetActor, Package targetPackage) global native
  12 +
  13 +; Count how many package overrides are currently on this actor. It will also count ones that's condition isn't met.
  14 +int function CountPackageOverride(Actor targetActor) global native
  15 +
  16 +; Remove all package overrides on this actor, including ones that were added by other mods.
  17 +int function ClearPackageOverride(Actor targetActor) global native
  18 +
  19 +; Remove this package from all actor overrides.
  20 +int function RemoveAllPackageOverride(Package targetPackage) global native
scripts/Source/MiscUtil.psc View file @ ebb16a7
... ... @@ -0,0 +1,41 @@
  1 +scriptname MiscUtil Hidden
  2 +
  3 +;/
  4 + Camera functions
  5 +/;
  6 +
  7 +; Toggle freefly camera.
  8 +function ToggleFreeCamera(bool stopTime = false) global native
  9 +
  10 +; Set freefly cam speed.
  11 +function SetFreeCameraSpeed(float speed) global native
  12 +
  13 +
  14 +
  15 +;/
  16 + Animation functions
  17 +/;
  18 +
  19 +; Get node rotation
  20 +float function GetNodeRotation(ObjectReference obj, string nodeName, bool firstPerson, int rotationIndex) global native
  21 +
  22 +
  23 +
  24 +;/
  25 + Misc
  26 +/;
  27 +
  28 +; Print text to console.
  29 +function PrintConsole(string text) global native
  30 +
  31 +; Set HUD on / off
  32 +function SetMenus(bool enabled) global native
  33 +
  34 +; Bat console command.
  35 +function ExecuteBat(string fileName) global native
  36 +
  37 +; Read string from file. Do not read large files!
  38 +string function ReadFromFile(string fileName) global native
  39 +
  40 +; Write string to file.
  41 +bool function WriteToFile(string fileName, string text, bool append = true, bool timestamp = false) global native
scripts/Source/SexLabFramework.psc View file @ ebb16a7
... ... @@ -138,6 +138,10 @@ bool function IsValidActor(actor a)
138 138 return ActorLib.IsValidActor(a)
139 139 endFunction
140 140  
  141 +bool function IsActorActive(actor a)
  142 + return ActorLib.IsActorActive(a)
  143 +endFunction
  144 +
141 145 actor[] function MakeActorArray(actor a1 = none, actor a2 = none, actor a3 = none, actor a4 = none, actor a5 = none)
142 146 return ActorLib.MakeActorArray(a1, a2, a3, a4, a5)
143 147 endFunction
... ... @@ -371,6 +375,50 @@ endFunction
371 375 ;#---------------------------#
372 376  
373 377 ;#---------------------------#
  378 +;# BEGIN EXPRESSION FUNCTION #
  379 +;#---------------------------#
  380 +
  381 +function ClearMFG(actor ActorRef)
  382 + sslExpressionLibrary.ClearMFG(ActorRef)
  383 +endFunction
  384 +
  385 +function ClearPhoneme(actor ActorRef)
  386 + sslExpressionLibrary.ClearPhoneme(ActorRef)
  387 +endFunction
  388 +
  389 +function OpenMouth(actor ActorRef)
  390 + sslExpressionLibrary.OpenMouth(ActorRef)
  391 +endFunction
  392 +
  393 +bool function IsMouthOpen(actor ActorRef)
  394 + return sslExpressionLibrary.IsMouthOpen(ActorRef)
  395 +endFunction
  396 +
  397 +sslBaseExpression function PickExpression(actor ActorRef, actor VictimRef = none)
  398 + return ExpressionLib.PickExpression(ActorRef, VictimRef)
  399 +endFunction
  400 +
  401 +sslBaseExpression function RandomExpressionByTag(string tag)
  402 + return ExpressionSlots.RandomByTag(tag)
  403 +endFunction
  404 +
  405 +sslBaseExpression function GetExpressionByName(string findName)
  406 + return ExpressionSlots.GetByName(findName)
  407 +endFunction
  408 +
  409 +int function FindExpressionByName(string findName)
  410 + return ExpressionSlots.FindByName(findName)
  411 +endFunction
  412 +
  413 +sslBaseExpression function GetExpressionBySlot(int slot)
  414 + return ExpressionSlots.GetBySlot(slot)
  415 +endFunction
  416 +
  417 +;#---------------------------#
  418 +;# END EXPRESSION FUNCTIONS #
  419 +;#---------------------------#
  420 +
  421 +;#---------------------------#
374 422 ;# START HOOK FUNCTIONS #
375 423 ;#---------------------------#
376 424  
scripts/Source/SexLabUtil.psc View file @ ebb16a7
... ... @@ -68,7 +68,7 @@ function Log(string msg, string source, string type = "NOTICE", string display =
68 68 Debug.TraceStack("-- SexLab "+type+"-- "+source+": "+msg, severity)
69 69 endIf
70 70 if StringUtil.Find(display, "console") != -1
71   - PrintConsole(type+" SexLab "+source+": "+msg)
  71 + MiscUtil.PrintConsole(type+" SexLab "+source+": "+msg)
72 72 endIf
73 73 endFunction
74 74  
... ... @@ -77,21 +77,12 @@ endFunction
77 77 ;# by h38fh2mf #
78 78 ;#------------------------------#
79 79  
80   -function SetFreeCameraSpeed(float speed) global native
81   -function ToggleFreeCamera(bool stopTime = false) global native
82   -
83 80 function EnableFreeCamera(bool enabling = true, float sucsm = 5.0) global
84 81 bool InFreeCamera = Game.GetCameraState() == 3
85 82 if enabling && !InFreeCamera
86   - SetFreeCameraSpeed(sucsm)
87   - ToggleFreeCamera()
  83 + MiscUtil.SetFreeCameraSpeed(sucsm)
  84 + MiscUtil.ToggleFreeCamera()
88 85 elseIf !enabling && InFreeCamera
89   - ToggleFreeCamera()
  86 + MiscUtil.ToggleFreeCamera()
90 87 endIf
91 88 endFunction
92   -
93   -; Get node rotation
94   -float function GetNodeRotation(ObjectReference obj, string nodeName, bool firstPerson, int rotationIndex) global native
95   -
96   -; Print text to console.
97   -function PrintConsole(string text) global native
scripts/Source/StorageUtil.psc View file @ ebb16a7
... ... @@ -3,7 +3,7 @@ scriptname StorageUtil Hidden
3 3 ;/
4 4 MOD AUTHORS, READ!
5 5  
6   - This script contains functions for saving and loading any amount of int, float and string values
  6 + This script contains functions for saving and loading any amount of int, float, form and string values
7 7 by name on a form or globally. These values can be accessed and changed from any mod which allows
8 8 mods to become compatible with each other without adding any requirements to the other mod or its version
9 9 other than this plugin.
... ... @@ -17,10 +17,6 @@ scriptname StorageUtil Hidden
17 17 be useful. It should also allow you to change MCM config script without worrying about versioning
18 18 since there are no new variables in the script itself.
19 19  
20   - To save forms use this as example:
21   - StorageUtil.SetIntValue(akTarget, "Friend", akCaster.GetFormID())
22   - Actor friend = Game.GetForm(StorageUtil.GetIntValue(akTarget, "Friend")) as Actor
23   -
24 20 Functions that start with File in the name will save values to a separate file, so that you can
25 21 access the same values from all savegames. This may be useful for configuration settings.
26 22  
... ... @@ -45,17 +41,17 @@ scriptname StorageUtil Hidden
45 41  
46 42 You can also use this storage to make your mod functions available to other mods, for example if
47 43 your mod has a function that sets an Actor to be invisible you could add a script that checks:
48   - int i = StorageUtil.IntListCount(none, "MakeInvisible")
  44 + int i = StorageUtil.FormListCount(none, "MakeInvisible")
49 45 while(i > 0)
50 46 i--
51   - Actor make = Game.GetForm(StorageUtil.IntListGet(none, "MakeInvisible", i)) as Actor
  47 + Actor make = StorageUtil.FormListGet(none, "MakeInvisible", i) as Actor
52 48 if(make)
53 49 MyScriptFunction(make)
54 50 endif
55   - StorageUtil.IntListRemoveAt(none, "MakeInvisible", i)
  51 + StorageUtil.FormListRemoveAt(none, "MakeInvisible", i)
56 52 endwhile
57 53 And the other mod could write:
58   - StorageUtil.IntListAdd(none, "MakeInvisible", myActor.GetFormID())
  54 + StorageUtil.FormListAdd(none, "MakeInvisible", myActor)
59 55 to make someone invisible using your mod. But if your mod isn't present then nothing happens.
60 56 This is just an example, I'm sure you can find better ways to implement compatibility, it would
61 57 help to include a documentation for other modders if you do.
... ... @@ -99,6 +95,15 @@ float function SetFloatValue(Form obj, string key, float value) global native
99 95 /;
100 96 string function SetStringValue(Form obj, string key, string value) global native
101 97  
  98 +;/ Set form value globally or on any form by name and return
  99 + previous value.
  100 +
  101 + obj: form to save on. Set none to save globally.
  102 + key: name of value.
  103 + value: value itself.
  104 +/;
  105 +Form function SetFormValue(Form obj, string key, Form value) global native
  106 +
102 107  
103 108 ;/ Remove a previously set int value on an form or globally and
104 109 return if successful. This will return false if value didn't exist.
... ... @@ -126,6 +131,14 @@ bool function UnsetFloatValue(Form obj, string key) global native
126 131 /;
127 132 bool function UnsetStringValue(Form obj, string key) global native
128 133  
  134 +;/ Remove a previously set form value on an form or globally and
  135 + return if successful. This will return false if value didn't exist.
  136 +
  137 + obj: form to remove from. Set none to remove global value.
  138 + key: name of value.
  139 +/;
  140 +bool function UnsetFormValue(Form obj, string key) global native
  141 +
129 142  
130 143 ;/ Check if value has been set on form or globally.
131 144  
... ... @@ -150,6 +163,13 @@ bool function HasFloatValue(Form obj, string key) global native
150 163 /;
151 164 bool function HasStringValue(Form obj, string key) global native
152 165  
  166 +;/ Check if value has been set on form or globally.
  167 +
  168 + obj: form to check on. Set none to check global value.
  169 + key: name of value.
  170 +/;
  171 +bool function HasFormValue(Form obj, string key) global native
  172 +
153 173  
154 174 ;/ Get previously saved int value on form or globally.
155 175  
... ... @@ -177,6 +197,14 @@ float function GetFloatValue(Form obj, string key, float missing = 0.0) global n
177 197 /;
178 198 string function GetStringValue(Form obj, string key, string missing = "") global native
179 199  
  200 +;/ Get previously saved form value on form or globally.
  201 +
  202 + obj: form to get from. Set none to get global value.
  203 + key: name of value.
  204 + [optional] missing: if value has not been set, return this value instead.
  205 +/;
  206 +Form function GetFormValue(Form obj, string key, Form missing = none) global native
  207 +
180 208  
181 209 ;/ Add an int to a list on form or globally and return
182 210 the value's new index. Index can be -1 if we were unable to add
... ... @@ -424,6 +452,88 @@ string function StringListSet(Form obj, string key, int index, string value) glo
424 452 int function StringListFind(Form obj, string key, string value) global native
425 453  
426 454  
  455 +;/ Add a form to a list on form or globally and return
  456 + the value's new index. Index can be -1 if we were unable to add
  457 + the value.
  458 +
  459 + obj: form to add to. Set none to add global value.
  460 + key: name of value.
  461 + value: value to add.
  462 + [optional] allowDuplicate: allow adding value to list if this value
  463 + already exists in the list.
  464 +/;
  465 +int function FormListAdd(Form obj, string key, Form value, bool allowDuplicate = true) global native
  466 +
  467 +
  468 +;/ Remove a previously added form value from a list on form
  469 + or globally and return how many instances of this value were removed.
  470 +
  471 + obj: form to remove from. Set none to remove global value.
  472 + key: name of value.
  473 + value: value to remove.
  474 + [optional] allowInstances: remove all instances of this value in a list.
  475 +/;
  476 +int function FormListRemove(Form obj, string key, Form value, bool allInstances = false) global native
  477 +
  478 +
  479 +;/ Clear a list of values (unset) on an form or globally and
  480 + return the previous size of list.
  481 +
  482 + obj: form to clear on. Set none to clear global list.
  483 + key: name of list.
  484 +/;
  485 +int function FormListClear(Form obj, string key) global native
  486 +
  487 +
  488 +;/ Remove a value from list by index on form or globally and
  489 + return if we were successful in doing so.
  490 +
  491 + obj: form to remove from. Set none to remove global value.
  492 + key: name of list.
  493 + index: index of value in the list.
  494 +/;
  495 +bool function FormListRemoveAt(Form obj, string key, int index) global native
  496 +
  497 +
  498 +;/ Get size of a list on form or globally.
  499 +
  500 + obj: form to check on. Set none to check global list.
  501 + key: name of list.
  502 +/;
  503 +int function FormListCount(Form obj, string key) global native
  504 +
  505 +
  506 +;/ Get a value from list by index on form or globally.
  507 + This will return 0 as value if there was a problem.
  508 +
  509 + obj: form to get value on. Set none to get global list value.
  510 + key: name of list.
  511 + index: index of value in the list.
  512 +/;
  513 +Form function FormListGet(Form obj, string key, int index) global native
  514 +
  515 +
  516 +;/ Set a value in list by index on form or globally.
  517 + This will return the previous value or 0 if there was a problem.
  518 +
  519 + obj: form to set value on. Set none to set global list value.
  520 + key: name of list.
  521 + index: index of value in the list.
  522 + value: value to set to.
  523 +/;
  524 +Form function FormListSet(Form obj, string key, int index, Form value) global native
  525 +
  526 +
  527 +;/ Find a value in list on form or globally and return its
  528 + index or -1 if value was not found.
  529 +
  530 + obj: form to find value on. Set none to find global list value.
  531 + key: name of list.
  532 + value: value to search.
  533 +/;
  534 +int function FormListFind(Form obj, string key, Form value) global native
  535 +
  536 +
427 537  
428 538  
429 539  
... ... @@ -775,6 +885,10 @@ int function debug_GetStringKeysCount(Form obj) global native
775 885  
776 886 ;/ Get the amount of variables saved on an form or globally.
777 887 /;
  888 +int function debug_GetFormKeysCount(Form obj) global native
  889 +
  890 +;/ Get the amount of variables saved on an form or globally.
  891 +/;
778 892 int function debug_GetIntListKeysCount(Form obj) global native
779 893  
780 894 ;/ Get the amount of variables saved on an form or globally.
... ... @@ -785,6 +899,10 @@ int function debug_GetFloatListKeysCount(Form obj) global native
785 899 /;
786 900 int function debug_GetStringListKeysCount(Form obj) global native
787 901  
  902 +;/ Get the amount of variables saved on an form or globally.
  903 +/;
  904 +int function debug_GetFormListKeysCount(Form obj) global native
  905 +
788 906 ;/ Return the name of Nth variable that is saved on this form
789 907 or globally.
790 908 /;
... ... @@ -803,6 +921,11 @@ string function debug_GetStringKey(Form obj, int index) global native
803 921 ;/ Return the name of Nth variable that is saved on this form
804 922 or globally.
805 923 /;
  924 +string function debug_GetFormKey(Form obj, int index) global native
  925 +
  926 +;/ Return the name of Nth variable that is saved on this form
  927 + or globally.
  928 +/;
806 929 string function debug_GetIntListKey(Form obj, int index) global native
807 930  
808 931 ;/ Return the name of Nth variable that is saved on this form
... ... @@ -815,6 +938,11 @@ string function debug_GetFloatListKey(Form obj, int index) global native
815 938 /;
816 939 string function debug_GetStringListKey(Form obj, int index) global native
817 940  
  941 +;/ Return the name of Nth variable that is saved on this form
  942 + or globally.
  943 +/;
  944 +string function debug_GetFormListKey(Form obj, int index) global native
  945 +
818 946 ;/ Return the count of objects that we have saved variables on.
819 947 /;
820 948 int function debug_GetIntObjectCount() global native
... ... @@ -829,6 +957,10 @@ int function debug_GetStringObjectCount() global native
829 957  
830 958 ;/ Return the count of objects that we have saved variables on.
831 959 /;
  960 +int function debug_GetFormObjectCount() global native
  961 +
  962 +;/ Return the count of objects that we have saved variables on.
  963 +/;
832 964 int function debug_GetIntListObjectCount() global native
833 965  
834 966 ;/ Return the count of objects that we have saved variables on.
... ... @@ -839,6 +971,10 @@ int function debug_GetFloatListObjectCount() global native
839 971 /;
840 972 int function debug_GetStringListObjectCount() global native
841 973  
  974 +;/ Return the count of objects that we have saved variables on.
  975 +/;
  976 +int function debug_GetFormListObjectCount() global native
  977 +
842 978 ;/ Get the Nth object that we have saved variables on.
843 979 /;
844 980 Form function debug_GetIntObject(int index) global native
... ... @@ -853,6 +989,10 @@ Form function debug_GetStringObject(int index) global native
853 989  
854 990 ;/ Get the Nth object that we have saved variables on.
855 991 /;
  992 +Form function debug_GetFormObject(int index) global native
  993 +
  994 +;/ Get the Nth object that we have saved variables on.
  995 +/;
856 996 Form function debug_GetIntListObject(int index) global native
857 997  
858 998 ;/ Get the Nth object that we have saved variables on.
... ... @@ -863,6 +1003,10 @@ Form function debug_GetFloatListObject(int index) global native
863 1003 /;
864 1004 Form function debug_GetStringListObject(int index) global native
865 1005  
  1006 +;/ Get the Nth object that we have saved variables on.
  1007 +/;
  1008 +Form function debug_GetFormListObject(int index) global native
  1009 +
866 1010 ;/ Get the amount of variables saved.
867 1011 /;
868 1012 int function debug_FileGetIntKeysCount() global native
scripts/Source/sslActorAlias.psc View file @ ebb16a7
... ... @@ -90,7 +90,7 @@ endProperty
90 90 ;\-----------------------------------------------/;
91 91  
92 92 bool function SetAlias(actor prospect, sslThreadController ThreadView)
93   - if prospect == none || GetReference() != prospect || Lib.ValidateActor(prospect) != 1
  93 + if prospect == none || GetReference() != prospect || (Lib.ValidateActor(prospect) != 1 && ThreadView.GetState() == "Making")
94 94 return false ; Failed to set prospective actor into alias
95 95 endIf
96 96 Initialize()
... ... @@ -128,7 +128,6 @@ endFunction
128 128  
129 129 function LockActor()
130 130 ; Start DoNothing package
131   - ActorRef.AddToFaction(Lib.AnimatingFaction)
132 131 ActorRef.SetFactionRank(Lib.AnimatingFaction, 1)
133 132 ActorRef.EvaluatePackage()
134 133 ; Disable movement
... ... @@ -168,9 +167,12 @@ function UnlockActor()
168 167 ; Detach positioning marker
169 168 ActorRef.StopTranslation()
170 169 ActorRef.SetVehicle(none)
  170 + ; Clear expression
  171 + if Expression != none
  172 + sslExpressionLibrary.ClearMFG(ActorRef)
  173 + endIf
171 174 endFunction
172 175  
173   -
174 176 function EquipStrapon()
175 177 if strapon == none && Lib.HasStrapon(ActorRef)
176 178 return
... ... @@ -215,7 +217,6 @@ function StopAnimating(bool quick = false)
215 217 ActorRef.PushActorAway(ActorRef, 1.0)
216 218 else
217 219 ; Reset NPC/PC Idle Quickly
218   - Debug.SendAnimationEvent(ActorRef, "JumpLand")
219 220 Debug.SendAnimationEvent(ActorRef, "IdleForceDefaultState")
220 221 ; Ragdoll NPC/PC if enabled and not in TFC
221 222 if !quick && DoRagdoll && (!IsPlayer || (IsPlayer && Game.GetCameraState() != 3))
... ... @@ -377,30 +378,11 @@ function SyncThread()
377 378 endIf
378 379 ; Animation related stuffs
379 380 if !IsCreature
380   - ; Calculate current enjoyment level
381   - GetEnjoyment()
382   - ; Send expression
383   - IsMouthOpen = Animation.UseOpenMouth(position, stage)
384   - Expression.ApplyTo(ActorRef, Enjoyment, BaseRef.GetSex() == 1, IsMouthOpen)
385   - ; ExpressionPreset = Lib.ExpressionLib.PresetMixin(Lib.ExpressionLib.GetBasePreset(IsFemale), GetEnjoyment(), IsFemale, IsVictim)
386   - ; Lib.ExpressionLib.ApplyPreset(ExpressionPreset, ActorRef, IsMouthOpen)
387 381 ; Send SOS event
388 382 if Lib.SOSEnabled && Animation.GetGender(position) == 0
389   - Debug.SendAnimationEvent(ActorRef, "SOSFastErect")
  383 + ; Debug.SendAnimationEvent(ActorRef, "SOSFastErect")
390 384 int offset = Animation.GetSchlong(position, stage)
391 385 Debug.SendAnimationEvent(ActorRef, "SOSBend"+offset)
392   - ; string bend
393   - ; if offset < 0
394   - ; bend = "SOSBendDown0"+((Math.Abs(offset) / 2) as int)
395   - ; elseif offset > 0
396   - ; bend = "SOSBendUp0"+((Math.Abs(offset) / 2) as int)
397   - ; else
398   - ; bend = "SOSNoBend"
399   - ; endIf
400   - ; Debug.SendAnimationEvent(ActorRef, bend)
401   - ; string name = ActorRef.GetLeveledActorBase().GetName()
402   - ; Debug.Notification(name+" Offset["+offset+"]: "+bend)
403   - ; Debug.Trace(name+" Offset: SOSBend"+offset+ ": Sent -> "+bend)
404 386 endif
405 387 ; Equip Strapon if needed
406 388 if IsFemale && Lib.bUseStrapons && Animation.UseStrapon(position, stage)
... ... @@ -411,6 +393,8 @@ function SyncThread()
411 393 endIf
412 394 endIf
413 395 endIf
  396 + ; Update expression/enjoyment
  397 + DoExpression()
414 398 endFunction
415 399  
416 400 function OverrideStrip(bool[] setStrip)
... ... @@ -446,6 +430,7 @@ endFunction
446 430 ;/-----------------------------------------------\;
447 431 ;| Animation/Voice Loop |;
448 432 ;\-----------------------------------------------/;
  433 +
449 434 state Prepare
450 435 event OnBeginState()
451 436 RegisterForSingleUpdate(0.1)
... ... @@ -501,6 +486,11 @@ endState
501 486 state Ready
502 487 event OnBeginState()
503 488 UnregisterForUpdate()
  489 + ; Make sure we should be here first
  490 + if Controller == none || ActorRef == none || GetReference() == none || GetReference() != ActorRef
  491 + GoToState("")
  492 + ClearAlias()
  493 + endIf
504 494 endEvent
505 495 function StartAnimating()
506 496 if ActorRef != none && Controller != none
... ... @@ -523,7 +513,7 @@ state Animating
523 513 endIf
524 514 if Voice != none && !IsSilent
525 515 if Expression != none
526   - Expression.ClearPhoneme(ActorRef)
  516 + sslExpressionLibrary.ClearPhoneme(ActorRef)
527 517 endIf
528 518 if VoiceInstance
529 519 Sound.StopInstance(VoiceInstance)
... ... @@ -531,13 +521,6 @@ state Animating
531 521 VoiceInstance = Voice.Moan(ActorRef, Strength, IsVictim)
532 522 Sound.SetInstanceVolume(VoiceInstance, Lib.fVoiceVolume)
533 523 endIf
534   - toggle = !toggle
535   - if toggle
536   - GetEnjoyment()
537   - if Expression != none
538   - Expression.ApplyTo(ActorRef, Enjoyment, IsFemale, IsMouthOpen)
539   - endIf
540   - endIf
541 524 RegisterForSingleUpdate(VoiceDelay)
542 525 endEvent
543 526 endState
... ... @@ -574,6 +557,8 @@ state Reset
574 557 endEvent
575 558 event OnUpdate()
576 559 UnregisterForUpdate()
  560 + ; Clear OpenMouth
  561 + ActorRef.ClearExpressionOverride()
577 562 ; Disable free camera, if in it
578 563 if IsPlayer
579 564 Lib.ControlLib.EnableFreeCamera(false)
... ... @@ -592,15 +577,9 @@ state Reset
592 577 endIf
593 578 ; Make flaccid for SOS
594 579 Debug.SendAnimationEvent(ActorRef, "SOSFlaccid")
  580 + RemoveStrapon()
595 581 ; Reset the actor
596 582 StopAnimating(Controller.FastEnd)
597   - if !IsCreature
598   - ; Cleanup extras
599   - RemoveStrapon()
600   - ; Reset openmouth/mfg
601   - ActorRef.ClearExpressionOverride()
602   - MfgConsoleFunc.ResetPhonemeModifier(ActorRef)
603   - endIf
604 583 ; Unstrip
605 584 if !ActorRef.IsDead()
606 585 Lib.UnstripActor(ActorRef, EquipmentStorage, Controller.GetVictim())
... ... @@ -609,7 +588,11 @@ state Reset
609 588 UnlockActor()
610 589 ; Clear expression
611 590 if Expression != none
612   - Expression.ClearMFG(ActorRef)
  591 + sslExpressionLibrary.ClearMFG(ActorRef)
  592 + endIF
  593 + ; Give AnimationEnd hooks some small room to breath
  594 + if !Controller.FastEnd
  595 + Utility.Wait(5.0)
613 596 endIf
614 597 ; Free up alias slot
615 598 ClearAlias()
... ... @@ -621,6 +604,18 @@ endState
621 604 ;| Misc Functions |;
622 605 ;\-----------------------------------------------/;
623 606  
  607 +function DoExpression()
  608 + if Expression == none || IsCreature
  609 + ; Nothing
  610 + elseIf IsVictim
  611 + IsMouthOpen = Animation.UseOpenMouth(position, stage)
  612 + Expression.ApplyTo(ActorRef, GetPain(), IsFemale, IsMouthOpen)
  613 + else
  614 + IsMouthOpen = Animation.UseOpenMouth(position, stage)
  615 + Expression.ApplyTo(ActorRef, GetEnjoyment(), IsFemale, IsMouthOpen)
  616 + endIf
  617 +endFunction
  618 +
624 619 int function GetEnjoyment()
625 620 ; Init weights
626 621 int BaseWeight
scripts/Source/sslActorLibrary.psc View file @ ebb16a7
... ... @@ -190,25 +190,11 @@ actor[] function SortActors(actor[] Positions, bool femaleFirst = true)
190 190 endFunction
191 191  
192 192 function ApplyCum(actor a, int cumID)
193   - if cumID < 1
  193 + if cumID < 1 || cumID > 7
194 194 return ; Invalid ID
195 195 endIf
196 196 ; Apply passed id
197   - if cumID == 1
198   - AddCum(a, true, false, false)
199   - elseif cumID == 2
200   - AddCum(a, false, true, false)
201   - elseif cumID == 3
202   - AddCum(a, false, false, true)
203   - elseif cumID == 4
204   - AddCum(a, true, true, false)
205   - elseif cumID == 5
206   - AddCum(a, true, false, true)
207   - elseif cumID == 6
208   - AddCum(a, false, true, true)
209   - else
210   - AddCum(a, true, true, true)
211   - endIf
  197 + AddCum(a, (cumID == 1 || cumID == 4 || cumID == 5 || cumID == 7), (cumID == 2 || cumID == 4 || cumID == 6 || cumID == 7), (cumID == 3 || cumID == 5 || cumID == 6 || cumID == 7))
212 198 endFunction
213 199  
214 200 function AddCum(actor a, bool vaginal = true, bool oral = true, bool anal = true)
... ... @@ -453,14 +439,14 @@ function UnequipStrapon(actor a)
453 439 endIf
454 440 endFunction
455 441  
  442 +bool function IsActorActive(actor a)
  443 + return ThreadSlots.FindActorController(a) != -1
  444 +endFunction
  445 +
456 446 int function ValidateActor(actor a)
457   - if a.IsInFaction(AnimatingFaction)
458   - if ThreadSlots.FindActorController(a) == -1
459   - a.RemoveFromFaction(AnimatingFaction)
460   - else
461   - Debug.Trace("--- SexLab --- Failed to validate ("+a.GetLeveledActorBase().GetName()+") :: They appear to already be animating")
462   - return -10
463   - endIf
  447 + if IsActorActive(a)
  448 + Debug.Trace("--- SexLab --- Failed to validate ("+a.GetLeveledActorBase().GetName()+") :: They appear to already be animating")
  449 + return -10
464 450 endIf
465 451 if ValidActorList.Find(a) != -1
466 452 return 1
... ... @@ -488,7 +474,6 @@ int function ValidateActor(actor a)
488 474 Race ActorRace = a.GetLeveledActorBase().GetRace()
489 475 String RaceName = ActorRace.GetName()
490 476 if ActorRace.IsRaceFlagSet(0x00000004) || StringUtil.Find(RaceName, "Child") != -1 || StringUtil.Find(RaceName, "117") != -1 || StringUtil.Find(RaceName, "Monli") != -1 || StringUtil.Find(RaceName, "Elin") != -1 || StringUtil.Find(RaceName, "Enfant") != -1
491   - ForbidActor(a)
492 477 Debug.Trace("--- SexLab --- Failed to validate ("+a.GetLeveledActorBase().GetName()+") :: They are forbidden from animating")
493 478 return -11
494 479 endIf
... ... @@ -539,7 +524,7 @@ int function GetGender(actor a)
539 524 endIf
540 525 endIf
541 526 ActorBase Base = a.GetLeveledActorBase()
542   - if AnimLib.CreatureSlots.HasRace(Base.GetRace())
  527 + if a != PlayerRef && AnimLib.CreatureSlots.HasRace(Base.GetRace())
543 528 return 2 ; Creature
544 529 else
545 530 return Base.GetSex() ; Default
scripts/Source/sslActorSlots.psc View file @ ebb16a7
... ... @@ -29,14 +29,9 @@ sslActorAlias[] function GetActorSlots(int tid)
29 29 endFunction
30 30  
31 31 int function FindActor(actor position)
32   - if position != none
33   - int i = 0
34   - while i < 75
35   - if (ActorSlot[i].GetReference() as actor) == position
36   - return i
37   - endIf
38   - i += 1
39   - endWhile
  32 + sslThreadController Thread = Lib.ThreadSlots.GetActorController(position)
  33 + if Thread != none
  34 + return ActorSlot.Find(Thread.ActorAlias(position))
40 35 endIf
41 36 return -1
42 37 endFunction
scripts/Source/sslAnimationLibrary.psc View file @ ebb16a7
... ... @@ -31,7 +31,7 @@ string function MakeGenderTag(actor[] Positions)
31 31 endFunction
32 32  
33 33 bool function AllowedCreature(Race creature)
34   - return bAllowCreatures && CreatureSlots.HasRace(creature)
  34 + return bAllowCreatures && CreatureSlots.HasAnimation(creature)
35 35 endFunction
36 36  
37 37 bool function AllowedCreatureCombination(Race creature, Race creature2)
scripts/Source/sslAnimationSlots.psc View file @ ebb16a7
... ... @@ -45,6 +45,37 @@ sslBaseAnimation[] function PickByActors(actor[] Positions, int limit = 64, bool
45 45 return Picked
46 46 endFunction
47 47  
  48 +sslBaseAnimation[] function GetByDefault(int Males, int Females, bool IsAggressive = false, bool UsingBed = false)
  49 + if Males == 0 && Females == 0
  50 + return none ; No actors passed or creatures present
  51 + endIf
  52 + ; Info
  53 + int Actors = (Males + Females)
  54 + bool SameSex = (Females == 2 && Males == 0) || (Males == 2 && Females == 0)
  55 + ; Search
  56 + bool[] valid = sslUtility.BoolArray(Slotted)
  57 + int i = Slotted
  58 + while i
  59 + i -= 1
  60 + ; Check for appropiate enabled aniamtion
  61 + valid[i] = Searchable(Slots[i]) && Actors == Slots[i].PositionCount
  62 + ; Suppress or ignore aggressive animation tags
  63 + valid[i] = valid[i] && (IsAggressive == Slots[i].HasTag("Aggressive") || !Lib.bRestrictAggressive)
  64 + ; Suppress standing animations if on a bed
  65 + valid[i] = valid[i] && (!UsingBed || (usingbed && !Slots[i].HasTag("Standing")))
  66 + ; Get SameSex + Non-SameSex
  67 + if SameSex
  68 + valid[i] = valid[i] && (Slots[i].HasTag("FM") || (Males == Slots[i].Males && Females == Slots[i].Females))
  69 + ; Ignore genders for 3P+
  70 + elseIf Actors < 3
  71 + valid[i] = valid[i] && Males == Slots[i].Males && Females == Slots[i].Females
  72 + endIf
  73 + endWhile
  74 + sslBaseAnimation[] output = GetList(valid)
  75 + _LogFound("GetByDefault", Males+", "+Females+", "+IsAggressive+", "+UsingBed, output)
  76 + return output
  77 +endFunction
  78 +
48 79 sslBaseAnimation function GetByName(string findName)
49 80 int i = 0
50 81 while i < Slotted
... ... @@ -109,11 +140,17 @@ sslBaseAnimation[] function GetList(bool[] valid)
109 140 return empty
110 141 endIf
111 142 sslBaseAnimation[] output = sslUtility.AnimationArray(count)
  143 + int len = valid.Length
112 144 int pos = valid.Find(true)
113   - while pos != -1 && pos < valid.Length
  145 + while pos != -1
114 146 count -= 1
115 147 output[count] = Slots[pos]
116   - pos = valid.Find(true, (pos + 1))
  148 + pos += 1
  149 + if pos < len
  150 + pos = valid.Find(true, pos)
  151 + else
  152 + pos = -1
  153 + endIf
117 154 endWhile
118 155 return output
119 156 endFunction
scripts/Source/sslBaseAnimation.psc View file @ ebb16a7
... ... @@ -18,13 +18,15 @@ string[] tags
18 18 form[] races
19 19 float[] timerData
20 20 float[] offsetData ; x, y, z, rotation
21   -float[] offsetDefaults ; x, y, z, rotation
22 21 bool[] switchData ; silence, mouth, strapon
23 22 int[] positionData ; gender, cum
24 23 int[] schlongData ; bend
25 24  
26 25 bool waiting
27 26  
  27 +; Storage key
  28 +Quest Storage
  29 +
28 30 ; Information
29 31 bool property Registered hidden
30 32 bool function get()
... ... @@ -166,7 +168,6 @@ int function AddPositionStage(int position, string animation, float forward = 0.
166 168 offset[2] = up
167 169 offset[3] = rotate
168 170 offsetData = sslUtility.MergeFloatArray(offset, offsetData)
169   - offsetDefaults = sslUtility.MergeFloatArray(offset, offsetDefaults)
170 171  
171 172 ; Set switch information
172 173 bool[] switch = new bool[3]
... ... @@ -202,6 +203,10 @@ endFunction
202 203 ;| Data Accessors |;
203 204 ;\-----------------------------------------------/;
204 205  
  206 +string function KeyStr(int i1, int i2)
  207 + return Name+"["+i1+"-"+i2+"]"
  208 +endFunction
  209 +
205 210 bool function Exists(string method, int position, int stage = -99)
206 211 if position > actors || position < 0
207 212 _Log("Unknown actor position, '"+position+"' given.", method)
... ... @@ -218,7 +223,15 @@ int function DataIndex(int slots, int position, int stage, int slot)
218 223 endFunction
219 224  
220 225 float function AccessOffset(int position, int stage, int slot)
221   - return offsetData[DataIndex(4, position, stage, slot)]
  226 + return offsetData[DataIndex(4, position, stage, slot)] + StorageUtil.FloatListGet(Storage, KeyStr(position, stage), slot)
  227 +endFunction
  228 +
  229 +float function GetAdjustment(int position, int stage, int slot)
  230 + string KeyStr = KeyStr(position, stage)
  231 + if StorageUtil.FloatListCount(Storage, KeyStr) == 0
  232 + return 0.0
  233 + endIf
  234 + return StorageUtil.FloatListGet(Storage, KeyStr, slot)
222 235 endFunction
223 236  
224 237 bool function AccessSwitch(int position, int stage, int slot)
... ... @@ -276,8 +289,11 @@ function UpdateAllOffsets(int slot, int position, float adjust)
276 289 endFunction
277 290  
278 291 function UpdateOffset(int slot, int position, int stage, float adjust)
279   - int index = DataIndex(4, position, stage, slot)
280   - offsetData[index] = offsetData[index] + adjust
  292 + string KeyStr = KeyStr(position, stage)
  293 + while StorageUtil.FloatListCount(Storage, KeyStr) < 4
  294 + StorageUtil.FloatListAdd(Storage, KeyStr, 0.0)
  295 + endWhile
  296 + StorageUtil.FloatListSet(Storage, KeyStr, slot, (StorageUtil.FloatListGet(Storage, KeyStr, slot) + adjust))
281 297 endFunction
282 298  
283 299 float[] function UpdateForward(int position, int stage, float adjust, bool adjuststage = false)
... ... @@ -314,9 +330,15 @@ float[] function UpdateUp(int position, int stage, float adjust, bool adjuststag
314 330 endFunction
315 331  
316 332 function RestoreOffsets()
317   - float[] defaults = offsetDefaults
318   - offsetData = defaults
319   - offsetDefaults = defaults
  333 + int position
  334 + while position < actors
  335 + int stage = stages
  336 + while stage
  337 + StorageUtil.FloatListClear(Storage, KeyStr(position, stage))
  338 + stage -= 1
  339 + endWhile
  340 + position += 1
  341 + endWhile
320 342 endFunction
321 343  
322 344 ;/-----------------------------------------------\;
... ... @@ -559,23 +581,27 @@ function Initialize()
559 581 SFX = 0
560 582 content = 0
561 583  
562   - float[] floatDel
563   - timerData = floatDel
564   - offsetData = floatDel
565   - offsetDefaults = floatDel
  584 + float[] floatDel1
  585 + timerData = floatDel1
  586 + float[] floatDel2
  587 + offsetData = floatDel2
566 588  
567   - int[] intDel
568   - schlongData = intDel
569   - positionData = intDel
570 589 genders = new int[3]
  590 + int[] intDel1
  591 + schlongData = intDel1
  592 + int[] intDel2
  593 + positionData = intDel2
571 594  
572 595 bool[] switchDel
573 596 switchData = switchDel
574 597  
575   - string[] stringDel
576   - tags = stringDel
577   - animations = stringDel
  598 + string[] stringDel1
  599 + tags = stringDel1
  600 + string[] stringDel2
  601 + animations = stringDel2
578 602  
579 603 form[] formDel
580 604 races = formDel
  605 +
  606 + Storage = GetOwningQuest()
581 607 endFunction
scripts/Source/sslBaseExpression.psc View file @ ebb16a7
1 1 scriptname sslBaseExpression extends ReferenceAlias
2 2  
3 3 sslExpressionLibrary property Lib auto
  4 +import sslExpressionLibrary
  5 +import MfgConsoleFunc
4 6  
5 7 string property Name = "" auto hidden
6 8  
... ... @@ -30,10 +32,16 @@ int[] female5
30 32  
31 33 function ApplyTo(actor ActorRef, int strength = 50, bool isFemale, bool openmouth = false)
32 34 if ActorRef == none
33   - return ; Nobody to express with!
  35 + return ; Nobody to express and doesn't update in free camera!
  36 + elseIf Game.GetCameraState() == 3
  37 + ; Apply open mouth and nothing else
  38 + if openmouth
  39 + OpenMouth(ActorRef)
  40 + endIf
  41 + return ; MFG doesn't update in free camera, so don't bother with anything else
34 42 endIf
35 43 ; Clear existing mfg from actor
36   - Lib.ClearMFG(ActorRef)
  44 + ClearMFG(ActorRef)
37 45 ; Get phase presets, [n + 0] = mode, [n + 1] = id, [n + 2] = value
38 46 int[] presets = GetPhase(CalcPhase(strength, isFemale), isFemale)
39 47 ; Apply phase presets to actor
... ... @@ -48,24 +56,10 @@ function ApplyTo(actor ActorRef, int strength = 50, bool isFemale, bool openmout
48 56 endWhile
49 57 ; Apply open mouth
50 58 if openmouth
51   - ActorRef.ClearExpressionOverride()
52   - ActorRef.SetExpressionOverride(16, 100)
  59 + OpenMouth(ActorRef)
53 60 endIf
54 61 endFunction
55 62  
56   -function ClearMFG(actor ActorRef)
57   - ActorRef.ClearExpressionOverride()
58   - MfgConsoleFunc.ResetPhonemeModifier(ActorRef)
59   -endFunction
60   -
61   -function ClearPhoneme(actor ActorRef)
62   - int i
63   - while i <= 15
64   - MfgConsoleFunc.SetPhonemeModifier(ActorRef, 0, i, 0)
65   - i += 1
66   - endWhile
67   -endFunction
68   -
69 63 int[] function GetPreset(int[] presets, int n)
70 64 int slot = ( n * 3 )
71 65 int[] output = new int[3]
scripts/Source/sslConfigMenu.psc View file @ ebb16a7
... ... @@ -2,7 +2,7 @@ scriptname sslConfigMenu extends SKI_ConfigBase
2 2 {Skyrim SexLab Mod Configuration Menu}
3 3  
4 4 int function GetVersion()
5   - return 13000
  5 + return 13100
6 6 endFunction
7 7  
8 8 string function GetStringVer()
... ... @@ -37,6 +37,7 @@ event OnGameReload()
37 37 parent.OnGameReload()
38 38 _CheckSystem()
39 39 ThreadSlots._StopAll()
  40 + ActorLib.ValidActorList.RemoveAddedForm(PlayerRef)
40 41 endEvent
41 42  
42 43 ; Framework
... ... @@ -1662,8 +1663,4 @@ function _CheckSystem()
1662 1663 mods = 0
1663 1664 endIf
1664 1665 endwhile
1665   - ; Add debug spell
1666   - if DebugMode() && !PlayerRef.HasSpell(SexLabDebugSpell)
1667   - PlayerRef.AddSpell(SexLabDebugSpell, true)
1668   - endIf
1669 1666 endFunction
scripts/Source/sslControlLibrary.psc View file @ ebb16a7
... ... @@ -31,7 +31,6 @@ string toggled
31 31 bool hkReady
32 32 sslThreadController PlayerController
33 33  
34   -
35 34 ; Dynamic properties
36 35 bool property InFreeCamera hidden
37 36 bool function get()
scripts/Source/sslCreatureAnimationSlots.psc View file @ ebb16a7
... ... @@ -2,12 +2,7 @@ scriptname sslCreatureAnimationSlots extends sslAnimationSlots
2 2  
3 3 sslCreatureAnimationDefaults property CreatureDefaults auto
4 4  
5   -form[] ValidRaces
6   -form[] property CreatureRaces hidden
7   - form[] function get()
8   - return ValidRaces
9   - endFunction
10   -endProperty
  5 +FormList property CreatureTypes auto
11 6  
12 7 sslBaseAnimation[] function GetByRace(int actors, Race creature)
13 8 bool[] valid = sslUtility.BoolArray(Slotted)
... ... @@ -22,23 +17,25 @@ sslBaseAnimation[] function GetByRace(int actors, Race creature)
22 17 endFunction
23 18  
24 19 bool function HasAnimation(Race creature, Race creature2 = none)
25   - int i = Slotted
26   - while i
27   - i -= 1
28   - if Searchable(Slots[i]) && Slots[i].HasRace(creature) && (creature2 == none || Slots[i].HasRace(creature2))
29   - return true
30   - endIf
31   - endWhile
  20 + if CreatureTypes.HasForm(creature)
  21 + int i = Slotted
  22 + while i
  23 + i -= 1
  24 + if Searchable(Slots[i]) && Slots[i].HasRace(creature) && (creature2 == none || Slots[i].HasRace(creature2))
  25 + return true
  26 + endIf
  27 + endWhile
  28 + endIf
32 29 return false
33 30 endFunction
34 31  
35 32 bool function HasRace(Race creature)
36   - return ValidRaces.Length != 0 && ValidRaces.Find(creature) != -1
  33 + return CreatureTypes.HasForm(creature)
37 34 endFunction
38 35  
39 36 function AddRace(Race creature)
40   - if !HasRace(creature)
41   - ValidRaces = sslUtility.PushForm(creature, ValidRaces)
  37 + if !CreatureTypes.HasForm(creature)
  38 + CreatureTypes.AddForm(creature)
42 39 endIf
43 40 endFunction
44 41  
... ... @@ -58,6 +55,5 @@ endFunction
58 55  
59 56 function Initialize()
60 57 parent.Initialize()
61   - form[] fDel
62   - ValidRaces = fDel
  58 + CreatureTypes.Revert()
63 59 endFunction
scripts/Source/sslEffectDebug.psc View file @ ebb16a7
... ... @@ -2,7 +2,60 @@ Scriptname sslEffectDebug extends ActiveMagicEffect
2 2  
3 3 SexLabFramework property SexLab Auto
4 4  
5   -event OnEffectStart(actor target, actor caster)
6   - sslBaseAnimation[] anims = SexLab.GetAnimationsByTags(2, "Arrok,Oral","",true)
7   - debug.traceandbox(anims)
  5 +event OnEffectStart(actor TargetRef, actor CasterRef)
  6 + sslThreadController Thread = SexLab.QuickStart(TargetRef)
  7 + WaitFor(10.0)
  8 + Debug.Notification("Adding Player")
  9 + Thread.ChangeActors(SexLab.MakeActorArray(TargetRef, CasterRef))
8 10 endEvent
  11 +
  12 +event OnEffectFinish(Actor TargetRef, Actor CasterRef)
  13 +endEvent
  14 +
  15 +
  16 +
  17 +;/-----------------------------------------------\;
  18 +;| Debug Utility Functions |;
  19 +;\-----------------------------------------------/;
  20 +
  21 +function LockActor(actor ActorRef)
  22 + ; Start DoNothing package
  23 + ActorRef.SetFactionRank(SexLab.AnimatingFaction, 1)
  24 + ActorRef.EvaluatePackage()
  25 + ; Disable movement
  26 + if ActorRef == SexLab.PlayerRef
  27 + Game.DisablePlayerControls(false, false, false, false, false, false, true, false, 0)
  28 + Game.ForceThirdPerson()
  29 + Game.SetPlayerAIDriven()
  30 + else
  31 + ActorRef.SetRestrained(true)
  32 + ActorRef.SetDontMove(true)
  33 + ; ActorRef.SetAnimationVariableBool("bHumanoidFootIKDisable", true)
  34 + endIf
  35 +endFunction
  36 +
  37 +function UnlockActor(actor ActorRef)
  38 + ; Enable movement
  39 + if ActorRef == SexLab.PlayerRef
  40 + Game.EnablePlayerControls(false, false, false, false, false, false, true, false, 0)
  41 + Game.SetPlayerAIDriven(false)
  42 + ; Game.SetInChargen(false, false, false)
  43 + else
  44 + ActorRef.SetRestrained(false)
  45 + ActorRef.SetDontMove(false)
  46 + ; ActorRef.SetAnimationVariableBool("bHumanoidFootIKEnable", true)
  47 + endIf
  48 + ; Remove from animation faction
  49 + ActorRef.RemoveFromFaction(SexLab.AnimatingFaction)
  50 + ActorRef.EvaluatePackage()
  51 + ; Detach positioning marker
  52 + ActorRef.StopTranslation()
  53 + ActorRef.SetVehicle(none)
  54 +endFunction
  55 +
  56 +function WaitFor(float seconds)
  57 + float timer = Utility.GetCurrentRealTime() + seconds
  58 + while Utility.GetCurrentRealTime() < timer
  59 + Utility.Wait(0.5)
  60 + endWhile
  61 +endFunction
scripts/Source/sslExpressionDefaults.psc View file @ ebb16a7
... ... @@ -3,6 +3,7 @@ scriptname sslExpressionDefaults extends sslExpressionFactory
3 3 function LoadExpressions()
4 4 RegisterExpression("Pleasure")
5 5 RegisterExpression("Happy")
  6 + RegisterExpression("Joy")
6 7 RegisterExpression("Shy")
7 8 RegisterExpression("Sad")
8 9 RegisterExpression("Afraid")
... ... @@ -19,12 +20,11 @@ function Pleasure(string eventName, string id, float argNum, form sender)
19 20  
20 21 AddTag("Consensual")
21 22  
22   - ; // Female Phase 1
  23 + ; Female
23 24 AddPreset(1, Female, Expression, 2, 30)
24 25 AddPreset(1, Female, Phoneme, 5, 30)
25 26 AddPreset(1, Female, Phoneme, 6, 10)
26 27  
27   - ; // Female Phase 2
28 28 AddPreset(2, Female, Expression, 10, 50)
29 29 AddPreset(2, Female, Modifier, 4, 30)
30 30 AddPreset(2, Female, Modifier, 5, 30)
... ... @@ -33,7 +33,6 @@ function Pleasure(string eventName, string id, float argNum, form sender)
33 33 AddPreset(2, Female, Phoneme, 0, 20)
34 34 AddPreset(2, Female, Phoneme, 3, 30)
35 35  
36   - ; // Female Phase 3
37 36 AddPreset(3, Female, Expression, 10, 70)
38 37 AddPreset(3, Female, Modifier, 2, 50)
39 38 AddPreset(3, Female, Modifier, 3, 50)
... ... @@ -44,7 +43,6 @@ function Pleasure(string eventName, string id, float argNum, form sender)
44 43 AddPreset(3, Female, Phoneme, 12, 30)
45 44 AddPreset(3, Female, Phoneme, 13, 10)
46 45  
47   - ; // Female Phase 4
48 46 AddPreset(4, Female, Expression, 10, 100)
49 47 AddPreset(4, Female, Modifier, 0, 10)
50 48 AddPreset(4, Female, Modifier, 1, 10)
... ... @@ -58,7 +56,6 @@ function Pleasure(string eventName, string id, float argNum, form sender)
58 56 AddPreset(4, Female, Phoneme, 10, 20)
59 57 AddPreset(4, Female, Phoneme, 12, 30)
60 58  
61   - ; // Female Phase 5
62 59 AddPreset(5, Female, Expression, 12, 60)
63 60 AddPreset(5, Female, Modifier, 0, 15)
64 61 AddPreset(5, Female, Modifier, 1, 15)
... ... @@ -74,20 +71,18 @@ function Pleasure(string eventName, string id, float argNum, form sender)
74 71 AddPreset(5, Female, Phoneme, 12, 80)
75 72 AddPreset(5, Female, Phoneme, 15, 20)
76 73  
77   - ; // Male Phase 1
  74 + ; Male
78 75 AddPreset(1, Male, Expression, 13, 40)
79   - AddPreset(2, Male, Modifier, 6, 20)
80   - AddPreset(2, Male, Modifier, 7, 20)
  76 + AddPreset(1, Male, Modifier, 6, 20)
  77 + AddPreset(1, Male, Modifier, 7, 20)
81 78 AddPreset(1, Male, Phoneme, 5, 20)
82 79  
83   - ; // Male Phase 2
84 80 AddPreset(2, Male, Expression, 8, 40)
85 81 AddPreset(2, Male, Modifier, 12, 40)
86 82 AddPreset(2, Male, Modifier, 13, 40)
87 83 AddPreset(2, Male, Phoneme, 2, 50)
88 84 AddPreset(2, Male, Phoneme, 13, 20)
89 85  
90   - ; // Male Phase 3
91 86 AddPreset(3, Male, Expression, 13, 80)
92 87 AddPreset(3, Male, Modifier, 6, 80)
93 88 AddPreset(3, Male, Modifier, 7, 80)
... ... @@ -464,3 +459,93 @@ function Sad(string eventName, string id, float argNum, form sender)
464 459  
465 460 Save()
466 461 endFunction
  462 +
  463 +function Joy(string eventName, string id, float argNum, form sender)
  464 + Name = "Joy"
  465 +
  466 + AddTag("Happy")
  467 + AddTag("Normal")
  468 + AddTag("Joy")
  469 + AddTag("Pleasure")
  470 +
  471 + AddTag("Consensual")
  472 +
  473 + ; Female
  474 + AddPreset(1, Female, Expression, 10, 45)
  475 + AddPreset(1, Female, Phoneme, 0, 30)
  476 + AddPreset(1, Female, Phoneme, 7, 60)
  477 + AddPreset(1, Female, Phoneme, 12, 60)
  478 + AddPreset(1, Female, Modifier, 0, 30)
  479 + AddPreset(1, Female, Modifier, 1, 30)
  480 + AddPreset(1, Female, Modifier, 4, 100)
  481 + AddPreset(1, Female, Modifier, 5, 100)
  482 + AddPreset(1, Female, Modifier, 12, 70)
  483 + AddPreset(1, Female, Modifier, 13, 70)
  484 +
  485 + AddPreset(2, Female, Expression, 10, 60)
  486 + AddPreset(2, Female, Phoneme, 7, 100)
  487 + AddPreset(2, Female, Phoneme, 15, 50)
  488 + AddPreset(2, Female, Modifier, 0, 30)
  489 + AddPreset(2, Female, Modifier, 1, 30)
  490 + AddPreset(2, Female, Modifier, 4, 100)
  491 + AddPreset(2, Female, Modifier, 5, 100)
  492 + AddPreset(2, Female, Modifier, 12, 70)
  493 + AddPreset(2, Female, Modifier, 13, 70)
  494 +
  495 + AddPreset(3, Female, Expression, 10, 60)
  496 + AddPreset(3, Female, Phoneme, 7, 100)
  497 + AddPreset(3, Female, Phoneme, 15, 50)
  498 + AddPreset(3, Female, Modifier, 0, 30)
  499 + AddPreset(3, Female, Modifier, 1, 30)
  500 + AddPreset(3, Female, Modifier, 4, 100)
  501 + AddPreset(3, Female, Modifier, 5, 100)
  502 + AddPreset(3, Female, Modifier, 12, 70)
  503 + AddPreset(3, Female, Modifier, 13, 70)
  504 +
  505 + AddPreset(4, Female, Expression, 10, 45)
  506 + AddPreset(4, Female, Phoneme, 0, 10)
  507 + AddPreset(4, Female, Phoneme, 6, 50)
  508 + AddPreset(4, Female, Phoneme, 7, 50)
  509 + AddPreset(4, Female, Modifier, 0, 30)
  510 + AddPreset(4, Female, Modifier, 1, 30)
  511 + AddPreset(4, Female, Modifier, 2, 70)
  512 + AddPreset(4, Female, Modifier, 3, 70)
  513 + AddPreset(4, Female, Modifier, 4, 100)
  514 + AddPreset(4, Female, Modifier, 5, 100)
  515 + AddPreset(4, Female, Modifier, 12, 70)
  516 + AddPreset(4, Female, Modifier, 13, 70)
  517 +
  518 + AddPreset(5, Female, Expression, 10, 60)
  519 + AddPreset(5, Female, Phoneme, 0, 60)
  520 + AddPreset(5, Female, Phoneme, 6, 50)
  521 + AddPreset(5, Female, Phoneme, 7, 50)
  522 + AddPreset(5, Female, Modifier, 0, 30)
  523 + AddPreset(5, Female, Modifier, 1, 30)
  524 + AddPreset(5, Female, Modifier, 2, 70)
  525 + AddPreset(5, Female, Modifier, 3, 70)
  526 + AddPreset(5, Female, Modifier, 4, 100)
  527 + AddPreset(5, Female, Modifier, 5, 100)
  528 + AddPreset(5, Female, Modifier, 12, 70)
  529 + AddPreset(5, Female, Modifier, 13, 70)
  530 +
  531 + ; Male (copy of pleasure)
  532 + AddPreset(1, Male, Expression, 13, 40)
  533 + AddPreset(1, Male, Modifier, 6, 20)
  534 + AddPreset(1, Male, Modifier, 7, 20)
  535 + AddPreset(1, Male, Phoneme, 5, 20)
  536 +
  537 + AddPreset(2, Male, Expression, 8, 40)
  538 + AddPreset(2, Male, Modifier, 12, 40)
  539 + AddPreset(2, Male, Modifier, 13, 40)
  540 + AddPreset(2, Male, Phoneme, 2, 50)
  541 + AddPreset(2, Male, Phoneme, 13, 20)
  542 +
  543 + AddPreset(3, Male, Expression, 13, 80)
  544 + AddPreset(3, Male, Modifier, 6, 80)
  545 + AddPreset(3, Male, Modifier, 7, 80)
  546 + AddPreset(3, Male, Modifier, 12, 30)
  547 + AddPreset(3, Male, Modifier, 13, 30)
  548 + AddPreset(3, Male, Phoneme, 0, 30)
  549 +
  550 + Save()
  551 +endFunction
scripts/Source/sslExpressionLibrary.psc View file @ ebb16a7
... ... @@ -2,6 +2,7 @@ scriptname sslExpressionLibrary extends Quest
2 2  
3 3 ; Scripts
4 4 sslExpressionSlots property Slots auto
  5 +import MfgConsoleFunc
5 6  
6 7 ; Data
7 8 actor property PlayerRef auto
... ... @@ -23,7 +24,7 @@ function MFG(actor ActorRef, int mode, int id, int value)
23 24 if mode == 2
24 25 ActorRef.SetExpressionOverride(id, value)
25 26 else
26   - MfgConsoleFunc.SetPhonemeModifier(ActorRef, mode, id, value)
  27 + SetPhonemeModifier(ActorRef, mode, id, value)
27 28 endIf
28 29 endFunction
29 30  
... ... @@ -33,7 +34,7 @@ function ApplyPreset(int[] presets, actor ActorRef, bool openmouth = false)
33 34 endIf
34 35 ; Clear existing mfg from actor
35 36 ; ActorRef.ClearExpressionOverride()
36   - MfgConsoleFunc.ResetPhonemeModifier(ActorRef)
  37 + ResetPhonemeModifier(ActorRef)
37 38 ; Apply preset, [n + 0] = mode, [n + 1] = id, [n + 2] = value
38 39 int i = presets.Length
39 40 while i
... ... @@ -41,19 +42,37 @@ function ApplyPreset(int[] presets, actor ActorRef, bool openmouth = false)
41 42 if presets[i] == 2 && !openmouth
42 43 ActorRef.SetExpressionOverride(presets[(i + 1)], presets[(i + 2)])
43 44 else
44   - MfgConsoleFunc.SetPhonemeModifier(ActorRef, presets[i], presets[(i + 1)], presets[(i + 2)])
  45 + SetPhonemeModifier(ActorRef, presets[i], presets[(i + 1)], presets[(i + 2)])
45 46 endIf
46 47 endWhile
47 48 ; Apply open mouth
48 49 if openmouth
  50 + OpenMouth(ActorRef)
  51 + endIf
  52 +endFunction
  53 +
  54 +function OpenMouth(actor ActorRef) global
  55 + if !IsMouthOpen(ActorRef)
49 56 ActorRef.ClearExpressionOverride()
50 57 ActorRef.SetExpressionOverride(16, 100)
51 58 endIf
52 59 endFunction
53 60  
54   -function ClearMFG(actor ActorRef)
  61 +bool function IsMouthOpen(actor ActorRef) global
  62 + return GetExpressionID(ActorRef) == 16 && GetExpressionValue(ActorRef) == 100
  63 +endFunction
  64 +
  65 +function ClearMFG(actor ActorRef) global
55 66 ActorRef.ClearExpressionOverride()
56   - MfgConsoleFunc.ResetPhonemeModifier(ActorRef)
  67 + ResetPhonemeModifier(ActorRef)
  68 +endFunction
  69 +
  70 +function ClearPhoneme(actor ActorRef) global
  71 + int i
  72 + while i <= 15
  73 + SetPhonemeModifier(ActorRef, 0, i, 0)
  74 + i += 1
  75 + endWhile
57 76 endFunction
58 77  
59 78 sslBaseExpression function PickExpression(actor ActorRef, actor VictimRef = none)
... ... @@ -68,62 +87,7 @@ sslBaseExpression function PickExpression(actor ActorRef, actor VictimRef = none
68 87 return Slots.RandomByTag("Consensual")
69 88 endFunction
70 89  
71   -int[] function PresetMixin(int[] basepreset, int enjoyment, bool female, bool victim = false)
72   - float amount = (enjoyment as float / 100.0)
73   - debug.trace("base: "+basepreset+ " enjoyment: "+ enjoyment +" amount: "+amount)
74   -
75   - int i = basepreset.Length
76   - while i
77   - i -= 1
78   - debug.trace("was "+basepreset[i])
79   - basepreset[i] = (amount * basepreset[i] as float) as int
80   - debug.trace("altering to "+basepreset[i])
81   - i -= 2
82   - endWhile
83   - return basepreset
84   -endFunction
85   -
86   -int[] function GetBasePreset(bool gender)
87   - if gender == Male
88   - return BasePresetMale
89   - endIf
90   - return BasePresetFemale
91   -endFunction
92   -
93   -int[] function AddBasePreset(bool gender, int mode, int id, int value)
94   - int[] presets = sslUtility.IncreaseInt(3, GetBasePreset(gender))
95   - int index = (presets.Length - 3)
96   - presets[index] = mode
97   - presets[index + 1] = id
98   - presets[index + 2] = value
99   - return presets
100   -endFunction
101 90  
102 91 function _Defaults()
103   - int[] iDel
104   - BasePresetMale = iDel
105   - BasePresetFemale = iDel
106   -
107   - BasePresetMale = AddBasePreset(Male, Expression, 13, 40)
108   - BasePresetMale = AddBasePreset(Male, Modifier, 6, 80)
109   - BasePresetMale = AddBasePreset(Male, Modifier, 7, 80)
110   - BasePresetMale = AddBasePreset(Male, Modifier, 12, 30)
111   - BasePresetMale = AddBasePreset(Male, Modifier, 13, 30)
112   - BasePresetMale = AddBasePreset(Male, Phoneme, 0, 30)
113   - BasePresetMale = AddBasePreset(Male, Phoneme, 5, 20)
114   - BasePresetMale = AddBasePreset(Male, Phoneme, 2, 50)
115   - BasePresetMale = AddBasePreset(Male, Phoneme, 13, 20)
116 92  
117   - BasePresetFemale = AddBasePreset(Female, Expression, 10, 100)
118   - BasePresetFemale = AddBasePreset(Female, Modifier, 0, 10)
119   - BasePresetFemale = AddBasePreset(Female, Modifier, 1, 10)
120   - BasePresetFemale = AddBasePreset(Female, Modifier, 2, 25)
121   - BasePresetFemale = AddBasePreset(Female, Modifier, 3, 25)
122   - BasePresetFemale = AddBasePreset(Female, Modifier, 6, 100)
123   - BasePresetFemale = AddBasePreset(Female, Modifier, 7, 100)
124   - BasePresetFemale = AddBasePreset(Female, Modifier, 12, 30)
125   - BasePresetFemale = AddBasePreset(Female, Modifier, 13, 30)
126   - BasePresetFemale = AddBasePreset(Female, Phoneme, 4, 35)
127   - BasePresetFemale = AddBasePreset(Female, Phoneme, 10, 20)
128   - BasePresetFemale = AddBasePreset(Female, Phoneme, 12, 30)
129 93 endFunction
scripts/Source/sslExpressionSlots.psc View file @ ebb16a7
... ... @@ -24,29 +24,25 @@ endProperty
24 24 ;\-----------------------------------------------/;
25 25  
26 26 sslBaseExpression function RandomByTag(string tag)
27   - int count
28   - ; Get tagged count
29   - int i = slotted
  27 + bool[] valid = sslUtility.BoolArray(Slotted)
  28 + int i = Slotted
30 29 while i
31 30 i -= 1
32   - count += Slots[i].HasTag(tag) as int
  31 + valid[i] = Slots[i].Registered && Slots[i].HasTag(tag)
33 32 endWhile
34   - if count == 0
35   - return none ; No valid slots found
  33 + ; No valid voices found
  34 + if valid.Find(true) == -1
  35 + return none
  36 + endIf
  37 + ; Pick random index within range of valid
  38 + int rand = Utility.RandomInt(valid.Find(true), valid.RFind(true))
  39 + int pos = valid.Find(true, rand)
  40 + if pos == -1
  41 + pos = valid.RFind(true, rand)
  42 + endIf
  43 + if pos != -1
  44 + return Slots[pos]
36 45 endIf
37   - ; Determine random
38   - int random = Utility.RandomInt(1, count)
39   - ; Get random
40   - i = slotted
41   - while i
42   - i -= 1
43   - if Slots[i].HasTag(tag)
44   - if random == count
45   - return Slots[i]
46   - endIf
47   - count -= 1
48   - endIf
49   - endWhile
50 46 return none
51 47 endFunction
52 48  
scripts/Source/sslSystemConfig.psc View file @ ebb16a7
... ... @@ -7,6 +7,18 @@ sslVoiceLibrary property VoiceLib auto
7 7 sslThreadLibrary property ThreadLib auto
8 8 sslActorLibrary property ActorLib auto
9 9 sslControlLibrary property ControlLib auto
  10 +sslExpressionLibrary property ExpressionLib auto
  11 +
  12 +; Object Registeries
  13 +sslAnimationSlots property AnimSlots auto
  14 +sslCreatureAnimationSlots property CreatureAnimSlots auto
  15 +sslVoiceSlots property VoiceSlots auto
  16 +sslThreadSlots property ThreadSlots auto
  17 +sslActorSlots property ActorSlots auto
  18 +sslExpressionSlots property ExpressionSlots auto
  19 +
  20 +; Misc
  21 +sslActorStats property ActorStats auto
10 22  
11 23 ; Animation Library
12 24 bool property bRestrictAggressive hidden
scripts/Source/sslThreadController.psc View file @ ebb16a7
... ... @@ -371,7 +371,7 @@ function SetAnimation(int anim = -1)
371 371 endIf
372 372 ; Print name of animation to console
373 373 if HasPlayer
374   - SexLabUtil.PrintConsole("Playing Animation: " + Animation.Name)
  374 + MiscUtil.PrintConsole("Playing Animation: " + Animation.Name)
375 375 endIf
376 376 endFunction
377 377  
... ... @@ -408,7 +408,6 @@ endFunction
408 408 function EndAnimation(bool quick = false)
409 409 UnregisterForUpdate()
410 410 GoToState("")
411   -
412 411 ; TEMP DEBUG INFO
413 412 ; Animation.Enabled = false
414 413 ; Debug.Trace("########################################")
... ... @@ -437,14 +436,18 @@ function EndAnimation(bool quick = false)
437 436 ; Set fast flag to skip slow ending functions
438 437 FastEnd = quick
439 438 Stage = Animation.StageCount
  439 + ; Send end event
  440 + SendThreadEvent("AnimationEnd")
  441 + ; Stop hotkeys to prevent further stage advancing
440 442 if HasPlayer
441   - ; Stop hotkeys to prevent further stage advancing
442 443 Lib.ControlLib._HKClear()
443 444 endIf
444   - ; Send end event
445   - SendThreadEvent("AnimationEnd")
446 445 ; Reset actors & wait for clear state
447 446 ActorAction("Reset", "")
  447 + ; Give AnimationEnd hooks some small room to breath
  448 + if !FastEnd
  449 + Utility.Wait(5.0)
  450 + endIf
448 451 ; Clear & Reset animation thread
449 452 Initialize()
450 453 endFunction
scripts/Source/sslThreadLibrary.psc View file @ ebb16a7
... ... @@ -8,6 +8,7 @@ sslVoiceLibrary property Voices auto
8 8 sslActorLibrary property Actors auto
9 9 sslExpressionLibrary property Expressions auto
10 10 sslControlLibrary property ControlLib auto
  11 +sslAnimationLibrary property AnimLib auto
11 12  
12 13 ; Data
13 14 actor property PlayerRef auto
scripts/Source/sslThreadModel.psc View file @ ebb16a7
... ... @@ -263,7 +263,7 @@ state Making
263 263 i += 1
264 264 endWhile
265 265  
266   - ; Check for valid animations
  266 + ; Check for valid creature animations
267 267 if HasCreature
268 268 primaryAnimations = Lib.CreatureAnimations.GetByRace(actors, Creature)
269 269 DisableLeadIn(true)
... ... @@ -290,7 +290,7 @@ state Making
290 290 endIf
291 291 ; A bed was selected, should we use it?
292 292 if BedRef != none
293   - bool use = bed == 2 || Lib.sNPCBed == "$SSL_Always"
  293 + bool use = (bed == 2 || Lib.sNPCBed == "$SSL_Always")
294 294 if PlayerRef != none && !IsVictim(PlayerRef)
295 295 use = Lib.mUseBed.Show() as bool
296 296 elseIf Lib.sNPCBed == "$SSL_Sometimes"
... ... @@ -299,8 +299,6 @@ state Making
299 299 if use
300 300 ; Center on found bed
301 301 CenterOnObject(BedRef)
302   - ; Suppress standing animations with bed
303   - suppress += "Standing,"
304 302 endIf
305 303 endIf
306 304 endIf
... ... @@ -332,22 +330,9 @@ state Making
332 330 endIf
333 331 endIf
334 332  
335   - ; Suppress aggressive tag
336   - if !IsAggressive
337   - suppress += "Aggressive,"
338   - endIf
339   -
340 333 if primaryAnimations.Length == 0
341   - ; Same sex pairings
342   - if (Females == 2 && Males == 0) || (Males == 2 && Females == 0)
343   - primaryAnimations = Lib.Animations.MergeLists(Lib.Animations.GetByTags(actors, Lib.Animations.Lib.MakeGenderTag(Positions), suppress), Lib.Animations.GetByTags(actors, "FM", suppress))
344   - ; Grab animations like normal
345   - elseif actors < 3
346   - primaryAnimations = Lib.Animations.GetByTags(actors, Lib.Animations.Lib.MakeGenderTag(Positions), suppress)
347   - ; Get 3P + animations ignoring gender
348   - elseif actors >= 3
349   - primaryAnimations = Lib.Animations.GetByType(actors, aggressive = IsAggressive)
350   - endIf
  334 + ; Get default animation selection
  335 + primaryAnimations = Lib.Animations.GetByDefault(Males, Females, IsAggressive, IsUsingBed)
351 336 ; Check for valid animations again
352 337 if primaryAnimations.Length == 0
353 338 _Log("Unable to find valid animations", "StartThread", "FATAL")
... ... @@ -356,7 +341,7 @@ state Making
356 341 endIf
357 342  
358 343 ; Determine if foreplay lead in should be used
359   - if Lib.bForeplayStage && !leadInDisabled && leadAnimations.Length == 0 && !HasCreature && !IsAggressive && actors == 2
  344 + if !HasCreature && !IsAggressive && actors == 2 && Lib.bForeplayStage && !leadInDisabled && leadAnimations.Length == 0
360 345 SetLeadAnimations(Lib.Animations.GetByTags(2, "LeadIn", suppress))
361 346 endIf
362 347  
... ... @@ -487,9 +472,6 @@ endfunction
487 472 ;| Actor Functions |;
488 473 ;\-----------------------------------------------/;
489 474  
490   -;
491   -; TODO: Probably needs to be redone again due to ActorSlot changes
492   -;
493 475 function ChangeActors(actor[] changeTo)
494 476 if !Active || HasCreature
495 477 return
... ... @@ -516,53 +498,62 @@ function ChangeActors(actor[] changeTo)
516 498 endIf
517 499 ; Start changing
518 500 SendThreadEvent("ActorChangeStart")
  501 + ; Toggle FastEnd to quickly clear out removed actors
  502 + bool togglefast = FastEnd
  503 + FastEnd = true
519 504 ; Remove actors no longer present
520   - i = 0
521   - while i < ActorCount
522   - ActorAlias(Positions[i]).UnregisterForUpdate()
  505 + i = ActorCount
  506 + while i
  507 + i -= 1
  508 + sslActorAlias CheckAlias = ActorAlias(Positions[i])
  509 + CheckAlias.GoToState("Ready")
523 510 if changeTo.Find(Positions[i]) == -1
524   - sslActorAlias clearing = ActorAlias(Positions[i])
525   - clearing.GoToState("Reset")
526   - clearing.ClearAlias()
527 511 if IsPlayerPosition(i)
528 512 AutoAdvance = true
529 513 endIf
  514 + CheckAlias.GoToState("Reset")
  515 + while CheckAlias.GetState() != ""
  516 + Utility.Wait(0.1)
  517 + endWhile
  518 + CheckAlias.ClearAlias()
530 519 endIf
531   - i += 1
532 520 endWhile
533   - ; Prepare/Reset actors as needed
  521 + ; Return FastEnd to it's original bool
  522 + FastEnd = togglefast
  523 + ; Update positions
534 524 Positions = changeTo
535   - sslActorAlias[] newSlots = new sslActorAlias[5]
536   - i = 0
537   - while i < changeTo.Length
538   - int slot = GetSlot(changeTo[i])
539   - if slot != -1
540   - ; Existing actor, retrieve their slot
541   - newSlots[i] = ActorSlots[i]
542   - newSlots[i].RegisterForSingleUpdate(0.20)
543   - else
544   - ; New actor, slot and prepare them
545   - newSlots[i] = SlotActor(changeTo[i])
546   - sslActorAlias adding = newSlots[i] as sslActorAlias
547   - adding.SetVoice(Lib.Voices.PickVoice(changeTo[i]))
548   - adding.DisableUndressAnim(true)
  525 + ; Prepare/Reset actors as needed
  526 + i = changeTo.Length
  527 + while i
  528 + i -= 1
  529 + ; New actor, slot and prepare them
  530 + if GetSlot(changeTo[i]) == -1
  531 + actor AddRef = changeTo[i]
  532 + sslActorAlias Slot = SlotActor(AddRef)
  533 + if Slot == none || !Slot.SetAlias(AddRef, self as sslThreadController)
  534 + _Log("Failed to add actor' "+AddRef.GetLeveledActorBase().GetName()+"' -- they were unable to fill an actor slot", "ChangeActors", "FATAL")
  535 + return
  536 + endIf
  537 + Slot.SetVoice(Lib.Voices.PickVoice(AddRef))
  538 + Slot.DisableUndressAnim(true)
549 539 ; Start preparing actor
550   - adding.GotoState("Prepare")
  540 + Slot.GotoState("Prepare")
551 541 ; Wait for ready state
552   - float failsafe = Utility.GetCurrentRealTime() + 10.0
553   - while adding.GetState() != "Ready" && failsafe > Utility.GetCurrentRealTime()
  542 + float failsafe = Utility.GetCurrentRealTime() + 20.0
  543 + while Slot.GetState() != "Ready" && failsafe > Utility.GetCurrentRealTime()
554 544 Utility.Wait(0.1)
555 545 endWhile
556   - ; Begin animation state
557   - adding.StartAnimating()
558 546 endIf
559   - i += 1
560 547 endWhile
561 548 ; Remember new genders
562 549 gendercounts = Lib.Actors.GenderCount(Positions)
563   - ; Set new actors into thread
564   - ActorSlots = newSlots
565   - SyncActors()
  550 + ; Start animating new actors
  551 + i = ActorCount
  552 + while i
  553 + i -= 1
  554 + ActorAlias(Positions[i]).StartAnimating()
  555 + endWhile
  556 + (self as sslThreadController).RealignActors()
566 557 ; End changing
567 558 SendThreadEvent("ActorChangeEnd")
568 559 endFunction
... ... @@ -663,7 +654,11 @@ sslBaseExpression function GetExpression(actor position)
663 654 endFunction
664 655  
665 656 int function GetEnjoyment(actor position)
666   - ActorAlias(position).Enjoyment
  657 + ActorAlias(position).GetEnjoyment()
  658 +endFunction
  659 +
  660 +int function GetPain(actor position)
  661 + ActorAlias(position).GetPain()
667 662 endFunction
668 663  
669 664 bool function HasPlayer()
... ... @@ -875,6 +870,8 @@ function ClearActors()
875 870 ActorSlots[i].UnlockActor()
876 871 ActorSlots[i].GoToState("")
877 872 ActorSlots[i].GoToState("Reset")
  873 + else
  874 + ActorSlots[i].ClearAlias()
878 875 endIf
879 876 endWhile
880 877 FastEnd = false
scripts/Source/sslThreadSlots.psc View file @ ebb16a7
... ... @@ -19,13 +19,15 @@ int property ActiveThreads hidden
19 19 endProperty
20 20  
21 21 int function FindActorController(actor toFind)
22   - int i
23   - while i < 15
24   - if ThreadView[i].HasActor(toFind)
25   - return i
26   - endIf
27   - i += 1
28   - endWhile
  22 + if toFind != none
  23 + int i
  24 + while i < 15
  25 + if ThreadView[i].HasActor(toFind)
  26 + return i
  27 + endIf
  28 + i += 1
  29 + endWhile
  30 + endIf
29 31 return -1
30 32 endFunction
31 33  
... ... @@ -51,7 +53,7 @@ endFunction
51 53  
52 54 sslThreadController function PickController()
53 55 int i
54   - while i < ThreadView.Length
  56 + while i < 15
55 57 if !ThreadView[i].IsLocked
56 58 return ThreadView[i]
57 59 endIf
scripts/Source/sslUtility.psc View file @ ebb16a7
... ... @@ -166,12 +166,13 @@ bool[] function MergeBoolArray(bool[] push, bool[] array) global
166 166 endFunction
167 167  
168 168 int function CountTrue(bool[] array) global
  169 + int len = array.Length
169 170 int pos = array.Find(true)
170 171 int count
171   - while pos != -1 && pos < array.Length
  172 + while pos != -1 && pos < len
172 173 count += 1
173 174 pos += 1
174   - if pos < array.Length
  175 + if pos < len
175 176 pos = array.Find(true, pos)
176 177 else
177 178 pos = -1
... ... @@ -292,12 +293,13 @@ form[] function MergeFormArray(form[] push, form[] array) global
292 293 endFunction
293 294  
294 295 int function CountNone(form[] array) global
  296 + int len = array.Length
295 297 int pos = array.Find(none)
296 298 int count
297 299 while pos != -1
298 300 count += 1
299 301 pos += 1
300   - if pos < array.Length
  302 + if pos < len
301 303 pos = array.Find(none, pos)
302 304 else
303 305 pos = -1
... ... @@ -333,7 +335,7 @@ endFunction
333 335  
334 336 sslBaseAnimation[] function PushAnimation(sslBaseAnimation var, sslBaseAnimation[] array) global
335 337 int len = array.Length
336   - if len >= 64
  338 + if len >= 100
337 339 return array
338 340 elseIf len == 0
339 341 array = new sslBaseAnimation[1]
... ... @@ -522,8 +524,80 @@ sslBaseAnimation[] function AnimationArray(int size) global
522 524 return new sslBaseAnimation[62]
523 525 elseIf size == 63
524 526 return new sslBaseAnimation[63]
525   - else
  527 + elseIf size == 64
526 528 return new sslBaseAnimation[64]
  529 + elseIf size == 65
  530 + return new sslBaseAnimation[65]
  531 + elseIf size == 66
  532 + return new sslBaseAnimation[66]
  533 + elseIf size == 67
  534 + return new sslBaseAnimation[67]
  535 + elseIf size == 68
  536 + return new sslBaseAnimation[68]
  537 + elseIf size == 69
  538 + return new sslBaseAnimation[69]
  539 + elseIf size == 70
  540 + return new sslBaseAnimation[70]
  541 + elseIf size == 71
  542 + return new sslBaseAnimation[71]
  543 + elseIf size == 72
  544 + return new sslBaseAnimation[72]
  545 + elseIf size == 73
  546 + return new sslBaseAnimation[73]
<