Jump to content

Surilindur

Premium Member
  • Posts

    1576
  • Joined

  • Last visited

Posts posted by Surilindur

  1. Back-dating the BSA archives is something the Steam version of Oblivion requires, and is not really connected to MO. The file dates for the BSA archives are too recent, so the game somehow uses them instead of any loose files. Setting the BSA timestamps to something older allows the game to use any installed replacers instead of the originals that are inside the archives.

     

    As for the mods... manually restructuring usually helps if a mod has a folder structure MO does not understand. The final mod that is in your MO's mods folder needs to be ready for "drag-and-drop" to the data folder (with the mod directory being the "data folder"... sort of...). So if a mod is activated in MO but has an odd folder structure then the game will not find the files where it expects them to be. Manually restructuring a mod usually solves it, but takes some time. :thumbsup:

  2. Yes the event probably works great the way you have it. And yes, I know what it is for. What I was talking about is the note on the ActiveMagicEffect wiki page that states this:

     

    ActiveMagicEffects will also receive events from the Actor they are attached to.

     

    Which, by common sense, would mean that the script should already receive the event - OnItemEquipped - from the Actor the effect is running on. If that is true, then you do not need to register for anything. So if the script will receive the events anyway, you do not need to register for them explicitly. That is what I trying to (sort of) explain. I blame my below-average communication skills. Sorry. :blush:

     

    What does the following in the spoiler do? It also has the AddItem line commented out as per suggestion by kitcat81.

     

     

     

    ScriptName GhoulskinScriptEffect Extends ActiveMagicEffect
    
    ; equip a non-removable armor that occupies item slots 31,32,46,48,49,50
    
    Actor ThisActor ; just a normal variable, should also work?
    
    Armor Property pGhoulskinArmor Auto
    FormList Property pClothingKeywordsToBlock Auto
    Message[] Property pGhoulskinMessages Auto
    
    Event OnEffectStart(Actor akTarget, Actor akCaster)
        ThisActor = akTarget
        Debug.MessageBox("OnEffectStart, Actor(" + ThisActor + ")")
        ; ThisActor.AddItem(pGhoulskinArmor, 1, True) <-- commented out as per suggestion by kitcat81 above
        ThisActor.EquipItem(pGhoulskinArmor, True, True) ; culprit
        Debug.MessageBox("IsEquipped(" + pGhoulskinArmor + ") = " + ThisActor.IsEquipped(pGhoulskinArmor))
        pGhoulskinMessages[0].Show()
    EndEvent
    
    Event OnEffectFinish(Actor akTarget, Actor akCaster)
        Debug.MessageBox("OnEffectFinish, Actor(" + ThisActor + ")")
        ; ThisActor.UnequipItem(pGhoulskinArmor, False, True) <-- unnecessary if removing an item also unequips it (hmmm....)
        ThisActor.RemoveItem(pGhoulskinArmor, ThisActor.GetItemCount(pGhoulskinArmor), True)
        pGhoulskinMessages[1].Show()
    EndEvent
    
    Event OnItemEquipped(Form akBaseObject, ObjectReference akReference)
        If (akBaseObject.HasKeywordInFormList(pClothingKeywordsToBlock))
            ThisActor.UnequipItem(akBaseobject, False, True)
            pGhoulskinMessages[2].Show()
        EndIf
    EndEvent

     

     

     

    Edit: Also apologies for not being of much help. Hopefully someone else can help you with your actual issue.

     

    Edit 2: To respond to your function issues: the property type should not matter. Armor should work. And the parameters in the function call... if you pass all of them in the right order then you would not need to use the "parameter_name=parameter_value". If you know Python, you can think of it as keyword arguments. For example these should be equivalent (by common sense, I have never tested it now that I think of it, but if Papyrus works logically then they should):

    SomeActor.EquipItem(SomeItem, True, True)
    SomeActor.EquipItem(akItem=SomeItem, abPreventRemoval=True, abSilent=True)
  3. To have OBSE work with MO, you would need to set the "launch mechanism" to "script extender" in the workarounds tab of MO preferences. That should create a "hook.dll" and "mo_path.txt" in your OBSE plugins folder. That way OBSE will load the hook.dll, which will in turn load MO and your mods will also be loaded. And one more thing: if you have a Steam version of Oblivion, you would want to go to the same workarounds tab of MO preferences and click the "date-back BSAs" button there to set the Steam version BSA dates to something older. This is for the 1.3.11 version at least, I have not managed to make the newer ones work properly with Oblivion.

     

    I spent an awful lot of hours (thanks to my inexperience with everything) last summer writing a Python module for using the usvfs system (it works but is far from beautiful thanks to my lack of time), and from what I have noticed, it works by first loading the appropriate dll file (for example I took the usvfs_x86.dll from MO 2.0.4 or something), then calling functions from the dll to create a filesystem and feed the linkages into it, and then calling a special function to spawn a hooked process that will get to use that filesystem. The actual header of interest is the usvfs.h at Github. If someone is interested. I think Tannin is a genious. Virtual mod installations the usvfs way are definitely the future of mod installation. Mods consist of more and more files, and are larger in size, and people use more and more mods, so virtual installs are a must in my opinion. It just makes things so clean and easy. Go Tannin! :happy:

     

    Hopefully the new mod manager the Nexus team (including Tannin) are working on will be something great (with true virtual file installation option). MO is good, but is no longer fully supported (for Oblivion at least, I think) and still has a bunch of flaws here and there. NMM sounds like something awful (never tried it myself) and does not even have proper virtual file installation option from what I have heard (the bug reports make it sound like symbolic links or somesuch). Wrye Bash lacks virtual file installations completely and OBMM is just out of question. Hopefully it will be possible to move forward at some point, and hopefully the new manager will fulfill all my expectations - expectations that are everything but modest. :tongue:

  4. I do not think the Steam version is better in any way, it is probably just the same thing but with Steam.

     

    I had a quick look at the source code on Github. Are you sure you have BOSS in your disc version folder? For example "...\Oblivion-The-Disc-Version-Directory\BOSS\" or somesuch, and that you are running it from there? If you have a shortcut pointing at BOSS that is located in the Steam version's directory then it will probably sort the Steam version. So it looks like you need to have BOSS in your disc version directory, in a subdirectory that is located on the same level as the Data folder, and run it from there.

     

    I have never used BOSS myself so I cannot really be of any help with it more than that. Sorry. :blush:

  5. Hmm. Have you tried the OnItemEquipped without registration? The ActiveMagicEffect Script page says it also receives events from the actor is it currently attached to, so if it really works that way, then you could maybe drop your event registration (it looks so odd anyway), if the magic effect automatically catches OnItemEquipped events from the actor. I have not tested it, just an idea.

     

    You can also add a check to see if something is actually equipped right after the equip command, I think. Or not.

     

     

    ScriptName GhoulskinScriptEffect Extends ActiveMagicEffect
    
    ; equip a non-removable armor that occupies item slots 31,32,46,48,49,50
    
    ; assuming Self refers to the object the script runs on (Actor), then maybe
    ; casting it as Actor would remove the need for the use of a separate
    ; Actor variable and would allow using the script also on other actors
    
    Armor Property pGhoulskinArmor Auto
    FormList Property pClothingKeywordsToBlock Auto
    Message[] Property pGhoulskinMessages Auto
    
    Event OnEffectStart(Actor akTarget, Actor akCaster)
        Debug.MessageBox("OnEffectStart, Actor(" + Self + ")")
        (Self as Actor).AddItem(pGhoulskinArmor, 1, True)
        (Self as Actor).EquipItem(pGhoulskinArmor, True, True) ; culprit
        Debug.MessageBox("IsEquipped(" + pGhoulskinArmor + ") = " + (Self as Actor).IsEquipped(pGhoulskinArmor))
        pGhoulskinMessages[0].Show()
    EndEvent
    
    Event OnEffectFinish(Actor akTarget, Actor akCaster)
        Debug.MessageBox("OnEffectFinish, Actor(" + Self + ")")
        (Self as Actor).UnequipItem(pGhoulskinArmor, False, True)
        (Self as Actor).RemoveItem(pGhoulskinArmor, 1, True)
        pGhoulskinMessages[1].Show()
    EndEvent
    
    Event OnItemEquipped(Form akBaseObject, ObjectReference akReference)
        If (akBaseObject.HasKeywordInFormList(pClothingKeywordsToBlock))
            (Self as Actor).UnequipItem(akBaseobject, False, True)
            pGhoulskinMessages[2].Show()
        EndIf
    EndEvent
    

     

     

     

    The thing with OnInit... I suppose it works if it fires once for each time the effect triggers, but even then the OnEffectStart would be there. Whatever works for you. There are so many equally great ways to do something.

     

    Edit: Ooooooops. Fixed the tags. :facepalm:

     

    Edit 2: About the script in the spoiler... I do not have the Fallout 4 CK installed at the moment, but the "Self as Actor" will probably fail now that I think of it. If it does that, maybe something like this would work better (judging by the family tree of scripts), maybe with an added "as ObjectReference" even. I really have no idea. I forgot ActiveMagicEffect was in another branch of sorts. I remember having issues in Skyrim with two custom scripts both extending Form, where casting one of them as the other required going "through" the parent (Form) script.

    (((Self as ScriptObject) as Form) as Actor)

    I really hope just "Self as Actor" works, since the object the scrip is running on should probably be an actor, and Self should probably refer to the actor, and the actor should have the Actor script on it and all that. Oh well. One of those "need to test" things again. Sorry, I was typing the initial response in the middle of the night half asleep. :sad:

  6. Does your armour have a keyword on it that also appears in the blocked list? Other than that, just a blind guess, but does adding a small delay between AddItem and EquipItem do anything? Probably not.

     

    The EquipItem function should be fine according to the wiki: http://www.creationkit.com/fallout4/index.php?title=EquipItem_-_Actor

     

    Edit: Is there a specific reason why you have your event registration in OnInit?

  7. I think Striker is right. There should be the option somewhere in the ini files. Maybe in ...\Data\OBSE\Plugins\OblivionReloaded.ini or such, I am starting to forget it myself as well. There should be a shaders section or somesuch in there, with something like "skin=1" that you would need to set to 0 to disable the shader. It should not be too difficult to find.

     

    From what I have been reading, it will be fixed at some point, and has something to do with certain shader-related files not being included in the current 6.0.0 version yet still being required by something. One workaround has been to copy the missing files from an older version or something, but you should indeed check the Oblivion Reloaded comments section for the workaround.

  8. Maybe the lack of responses has something to do with how the question is put, as in, "can someone with actual knowledge of the game engine's inner workings explain how these values are treated by the game". It is a somewhat efficient way to narrow down the number of people who could actually answer the question.

     

    As for the settings... assuming they have an effect on something, why would increasing some (presumably) AI-related limits increase performance? Especially on a game that seems to choke when enough stuff is crammed in it. Of course I will also immediately test those when I have the time (just out of curiosity) but still. :huh:

  9. Do you need the Steam version for anything specific?

     

    For example I myself initially bought a disc version of Oblivion that did not have the small DLC like Battlehorn Castle. Then I also bought the Steam GOTY Deluxe version with all the small DLC, downloaded it, copied the small DLC to the disc version and removed the Steam version. The small DLC are just mods, basically, so you can take them from the Steam version and install into the disc version just like you would install any mod.

     

    But then again, the Steam version is not that bad, either. I use it myself at the moment. Steam overlay caused some issues from time to time (popping up because of some hotkeys) but I now keep it disabled.

     

    Hopefully that helps a bit, if it makes sense. :thumbsup:

  10. No problem, great to hear I could help My skills at explaining things are below average. :blush:

     

    One more thing about properties: they are not just links between Papyrus and actual game objects (I think I might have made it sound like as if they were mainly that) - they also allow the reuse of scripts with different variable values that can be set in the Creation Kit without having to hardcode them to the script. Maybe something like a "gold lever" thing would be a great example of a property being both a link between Papyrus and a game object and a variable that can be set in the Creation Kit without having to hardcode it.

     

    So, assuming there would be two levers: one lever adds twenty Septims to whoever triggers it, and another lever adds 123 burnt books to whoever triggers it. They can both use the same script:

    ScriptName _RememberToPrefixYourScripts_LeverScript Extends ObjectReference
    
    Form Property ItemToGive Auto ; the item to give
    Int Property GiveCount Auto ; number of items to give
    
    Event OnActivate(ObjectReference akActionRef)
        akActionRef.AddItem(ItemToGive, GiveCount)
    EndEvent
    I have not tested if that works, but the idea should be there. The smart part of it is the use of properties in the Creation Kit:
    • first, one would place two simple levers in the gameworld somewhere, and add the script to each reference separately (to avoid having to create a new base object) by opening the scripts tab for both and adding a new script
    • then, in the first lever reference in the world, one would open the scripts tab, open the property editor for the new script and assign ItemToGive to Gold001 (or somesuch, the gold object) and set GiveCount to 20
    • in the second lever, do the same, except that the item would be the burnt book object and count would be 123

    So while properties can be a bit tricky to wrap the head around at first, once you get the idea and understand how brilliant they are, you just cannot live without them! In the previous titles (like Oblivion), that two lever scenario would have required two distinct scripts with the items and counts hardcoded of sorts (or a clever scripting trick, but nothing as straightforward as a property). :happy:

  11. If you have not yet read it, the wiki page on variables and properties might help: http://www.creationkit.com/index.php?title=Variables_and_Properties_(Papyrus)

     

    A property is a sort of link between the script and an actual in-game object. You can add a property in a script, but you need to use the Creation Kit to point it at an object. As in, your property declaration should look like this:

    VoiceType Property Voice Auto

    And you would need to attach the script to whatever it is you are going to attach it to (a magic effect?), open the property editor for the script after you have attached it to the magic effect, and fill the "Voice" property with the voice type you want (there should be some sort of drodown list I think?).

     

    You can think of a property as a hole and a tunnel, and your script as an isolated cube. The script, by itself, has no idea what something called "MaleKhajiit" is - it is just a bunch of characters after another with no meaning. To be able to point the script at your "MaleKhajiit" voice type, you cut a hole to the cube and label it "VoiceType called Voice" (create a property of type VoiceType named Voice). The script now knows that there should be a VoiceType called Voice somewhere through that hole. The next thing you do is build a tunnel between the hole and the MaleKhajiit voice type (fill the property in the Creation Kit), so that when the script looks through the "VoiceType called Voice" hole, it will see the MaleKhajiit object at the end of the tunnel. If that makes any sense. :tongue:

     

    Hopefully that helps a bit.

     

    Edit: I made a small picture to illustrate the whole Property idea, if it helps (in the spoiler):

     

     

    http://i.imgur.com/i5oL6FQ.jpg

     

     

  12. Judging by your CPU, one would think it is a Skylake-based system. I built a new one a year ago, and the motherboard had specific instructions on how to install Windows 7 from a USB device (any device: USB stick, USB optical disc drive, etc.). Maybe yours also has specific Windows 7 USB installation instructions somewhere? I still have a SATA optical disc drive for older games that are on on discs, so I installed Windows 7 with my DVD. After I had upgraded to Windows 10 (and therefore registered the machine in some Microsoft system), I made a clean reinstall of Windows 10 from a USB device (and have done a few more reinstalls after that when Windows 10 updates got stuck). So USB installation does work with Skylake, but it might not be as straightforward for WIndows 7.

     

    If I were you, I would check the motherboard manual and/or the motherboard info on the manufacturer's website. If I remember correctly, my motherboard (an Asus one) mentioned having to insert the support DVD into a SATA optical disc drive when installing Windows 7 from a USB for some USB drivers to be preloaded from the DVD so that a USB device could be used for the OS installation.

     

    Nothing too specific there, but hopefully it helps a bit. :blush:

  13. Finally cracked it! :dance: Sort of. It took some thinking, but if you want to generate a list of all numbers between a and b, and shuffle them, then the following script should do the trick. I have not tested the script itself (yet), but the Python version works.

     

    The Python version edit: that finally works with all sorts of a and b as long as b is larger than a:

    import random
    
    
    def random_list(a=0, b=100):
        b = b - a
        l = [0] * b
        i = 0
        while (i < b):
            k = random.randint(0, i)
            l[i] = l[k]
            l[k] = i + a
            i += 1
        return l
    
    if __name__ == '__main__':
        o = random_list(-7, -2)
        print(o)
    
    

    The Papyrus version (untested):

    Int[] Function ShuffledIntList(Int a=0, Int b=100)
        b = b - a
        Int i = 0
        Int k
        Int[] NumArr = Utility.CreateIntArray(b)
        While (i < b)
            k = Utility.RandomInt(0, i)
            NumArr[i] = NumArr[k]
            NumArr[k] = i + a
            i += 1
        EndWhile
        Return NumArr
    EndFunction

    If you need n numbers from [x,y] you could just generate the whole shuffled list from x to y and use the first n numbers from it.

    Function PrintFirstN(Int n, Int x, Int y)
        Int[] Shuffled = ShuffledIntList(x, y)
        While (n > 0)
            n -= 1
            Debug.MessageBox(Shuffled[n])
        EndWhile
    EndFunction

    Hopefully that helps a bit. :smile:

  14. Edit: Hmm. Well. I moved the thing to a spoiler. It does not produce random variables at all now that I think of it. Sorry. :blush: Your idea is already quite good. It does not even use Array.Find which is great.

     

     

     

    I have not tested this at all, but maybe something like the following would work as an idea (SKSE is required for array creation)? Not too random, though, but something at least. If it works. It is just an idea! It could be that it fails miserably, and probably will do exactly that. :tongue:

    Int[] Function RandList(Int n, Int a=0, Int b=100)
        Float md = Math.Abs((a + b) / 2)
        Float dv = Math.Abs(b - md)
        Int[] NumArr = Utility.CreateIntArray(n, (md as Int))
        Float h = 180.0 / (n - 1)
        While (n > 0)
            n -= 1
            NumArr[n] += ((Math.Cos(180.0 - (n * h)) * dv) as Int)
            If (n + 1 < NumArr.Length && NumArr[n] == NumArr[n+1])
                NumArr[n] += 1 ; if the rounded number is the same as the previous one?
            EndIf
        EndWhile
        Return NumArr
    EndFunction

  15. If I remember correctly, you can toggle the "player in Shivering Isles" flag with a console command (there is a command, but I cannot remember if it was written exactly like this:

    SetPlayerInSEWorld 0
    SetPlayerInSEWorld 1

    Where 1 or 0 is pickes depending on whether the character should be considered to be in the SE world. I used that when testing my follower management mod with Shivering Isles NPCs (the mod allows recruiting Sheogorath, but urgently needs an update). :P

  16. Well you could add it to the player alias, as well, as far as I know. The script. Assuming OnPlayerLoadGame actually fires, and that registering for the same event multiple times does not cause issues, you could use something like this and attach it to the PlayerAlias of whatever quest you may have:

    ScriptName YourPrefix_HorseMountHandler Extends Actor
    
    ; this script is attached to a Player alias in your quest
    
    Actor Property YourOtherActor Auto
    ObjectReference Property HoldingCellMarker Auto ; a marker in your holding cell
    
    Event OnPlayerLoadGame()
        Utility.Wait(0.5) ; wait a little, so that everything really is loaded and ready - might not be necessary, though
        RegisterForAnimationEvent(Self, "HorseEnter")
        RegisterForAnimationEvent(Self, "HorseExit") ; <-- replace HorseExit with the exit animation event name!
        Debug.MessageBox("OnPlayerLoadGame run, events should be registered")
    EndEvent
    
    Event OnAnimationEvent(ObjectReference akSource, String asEventName)
        Debug.MessageBox("Event (" + asEventName + "), Source (" + akSource + ")")
        If (asEventName == "HorseEnter" && YourOtherActor.IsEnabled())
            YourOtherActor.MoveTo(HoldingCellMarker)
            YourOtherActor.Disable()
        ElseIf (asEventName == "HorseExit") ; <-- replace HorseExit with the actual event name
            If (YourOtherActor.IsDisabled())
                YourOtherActor.Enable()
            EndIf
            YourOtherActor.MoveTo(Self)
        EndIf
    EndEvent

    Something like that. I have not tested it, though, but it should work. Hopefully that helps a bit.

     

    Edit: Fixed a typo, the HoldingCellMarker should be a property.

  17. No problem. Alternatives are usually great food for thought. :)

     

    What you are describing could also be done with a single enable parent. For example, if you did this:

    • for the dirt pile, set the tombstone as the enable parent and make sure "state opposite to parent" is un-checked
    • for each bone, set the tombstone as the enable parent and make sure "state opposite to parent" is checked
    • set the tombstone to "initially disabled"
    • in the script, enable the tombstone when appropriate

    So that, instead of two xmarkers, you would have one single tombstone. When that tombstone would be disabled, all the bones would have the opposite state (enabled) and the dirt pile the identical state (disabled). When the tombstone would be enabled, all the bones would have the opposite state (disabled) and the dirt pile the identical state (enabled). You can use the "state opposite to parent" tickbox in the enable parent tab of each reference to determine whether the enable state of that reference should be the same as the parent or the oppsite to it.

  18. Does it lag without the Dispel commands in ScriptEffectStart (for testing, to see if that would be the issue)?

     

    And yes, with OBSE, it is possible to build equipment auto-repair functionality, and auto-recharge and almost anything. Those things do require some scripting knowledge and maybe some thinking. It is not too difficult once you know how to create timers (in a quest script or in the magic effect script) and use looping commands from OBSE. Maybe someone else can assist you in that?

     

    Come to think of it, TES Alliance has Oblivion scripting tutorials (among other things) on their Forums. Maybe those could be of use to you. Their site was apparently targeted by a hacker at some point, so if the content looks suspicious, you should probably keep away and try again at a later time (the site seems fine at the moment, though): http://tesalliance.org/forums/index.php?/forum/82-esiv-oblivion-school/

  19. You do not need the magic effect at all - that's the thing! You can register for the relevant animation event in the other actor's script. That is what I was trying to explain. Yes, my communication skills are not great. :P

    • in a script attached to the other actor (for example), register for the "HorseEnter" event emitted by player
    • in the OnAnimationEvent block in that script, run the commands you need to run when player mounts a horse
    • script processing only happens when the event fires (because there is no polling, no magic effect, no cloak, nothing!)

    For example I have used RegisterForAnimationEvent in a quest script to catch player events and it works just fine. :thumbsup:

  20. Have you tried registering for a suitable animation event from the player? For example:

    ; you could add the things here to a script on your other actor as well, as far as I know?
    
    Event OnInit()
        RegisterForAnimationEvent(Game.GetPlayer(), "your_mounting_event_name") ; move this elsewhere!!!
    EndEvent
    
    Event OnAnimationEvent(ObjectReference akSource, String asEventName)
        Debug.MessageBox("Event (" + asEventName + "), Source (" + akSource + ")")
    EndEvent

    There should be animation event lists in the Creation Kit, from the menubar -> Gameplay -> Animations. When selecting an items under one of the trees, there should be a dropdown list of animation event names (in the right side panel) with somewhat clear names. You can test which one activates when mounting a horse or a dragon or something.

     

    Hopefully that helps a bit. It has been a while since I did any scripting with Papyrus, but animation events are usually a great way to register for actions performed by an actor, without having to build a complex or performance-hungry polling system or a cloak script. But then again, it will take some time to go through all the various potentially useful events (based on their names alone) to find the correct one for each situation.

     

    Edit: The relevant wiki pages: RegisterForAnimationEvent, UnregisterForAnimationEvent and OnAnimationEvent.

     

    Edit 2: The text editor here is not great. Fixed the links.

  21. I think the issue is related to you trying to call a function from a script that is not attached to an object - specifically, a script that is of a specific type to require being attached to an object but that is not attached to an object. It is possible to create a "library" script that does not need to be attached to anything, but that library script cannot be, for example, one that extends Form (if I remember correctly). If the script extends Form, the game probably requires it to be attached to a Form.

     

    As in, if I remember correctly, you can do this:

    ScriptName SomeLibraryScript
    
    ; does not extend anything
    
    Function FancyFunctionForFunnyFantasies(Bool abValue)
        Debug.MessageBox("The opposite of " + abValue + " is " + !abValue)
    EndFunction
    ScriptName SomeObjectScript Extends ObjectReference
    
    ; should compile without issues
    
    Event OnActivate(ObjectReference akActionRef)
        SomeLibraryScript.FancyFunctionForFunnyFantasies(True)
    EndEvent

    But you cannot do this:

    ScriptName SomeLibraryScript Extends Form
    
    ; this time, extends Form
    
    Function FancyFunctionForFunnyFantasies(Bool abValue)
        Debug.MessageBox("The opposite of " + abValue + " is " + !abValue)
    EndFunction
    ScriptName SomeObjectScript Extends ObjectReference
    
    ; this time, the function call here should throw the error you described
    ; when compiling, since SomeLibraryScript now extends Form but has not been
    ; attached to anything
    
    Event OnActivate(ObjectReference akActionRef)
        SomeLibraryScript.FancyFunctionForFunnyFantasies(True)
    EndEvent

    Considering how a large number of scripts are under Form in the "family tree" of sorts on the wiki, it could be that the script you are trying to call the function from (or one of its ancestors) extends something in the Form family tree and therefore cannot be used as a library script, but needs to be attached to an object. More about extending/inheritance on the wiki: Extending Scripts (Papyrus).

     

    I really hope I remembered it all correctly. If someone spots a mistake, feel free to correct me. :blush:

     

    Edit: For reference, you cannot do any of these, either, and they will also cause the compiler to throw the same error:

    ObjectReference.Delete()
    Actor.IsInInterior()
    Potion.IsHostile()
×
×
  • Create New...