Jump to content

SKKmods

Premium Member
  • Posts

    2737
  • Joined

  • Last visited

Posts posted by SKKmods

  1. Adding the actor to faction WorkshopNoPackages (either on ther ActorBase form or via script to the in game ObjectReference) blocks any of the WorkshopParent applied packages from asserting priority on therir package stack, so either their default or your added package will be active.

    Having a script which dumps the current package is super helpful fir this stuff:

    Debug.Trace("SKK_GetActorInfo CurrentPackage," + (ThisRef as Actor).GetCurrentPackage() )

     

  2. Had  a similar issue with Multiracial Workshop Actors (Settlers).

    (2) Most multiracial actors do not have idle animations for workshop work objects (farming, guarding, scavenge station). Rather than standing frozen in place they are configured to wander around looking busy. Calling with the bell can cause them to stop updating AI movement packages after being called until they are commanded or unload. 

     

        If ((ThisActor as SKK_MWACustomActorScript).bRaceHasWorkshopIdles == false)
            (ThisActor as Actor).AddToFaction(pWorkshopNoPackages) ;Package freeze in position when they are assigned to work objects this keeps them sandboxing
        Else
            (ThisActor as Actor).RemoveFromFaction(pWorkshopNoPackages)
        Endif

  3. I use this simple snip for some custom objects stuff that are blocked for PA, attach it to your base weapon forms;

     

    Scriptname myPowerArmorUnequipObjectScript extends ObjectReference

    Keyword Property pIsPowerArmorFrame Auto Const Mandatory
    Message Property pmyMessageName Auto Const Mandatory 
    Weapon Property pmyWeaponBaseFormName Auto Const Mandatory 

    Event OnEquipped(Actor akActor)
    CheckForPowerArmor(akActor)
    EndEvent

    Event OnUnequipped(Actor akActor)
       Self.UnregisterForAllEvents()
    EndEvent

    Event OnAnimationEvent(ObjectReference akSource, string asEventName)
    CheckForPowerArmor(akSource as Actor)
    EndEvent

    Function CheckForPowerArmor(Actor akActor)
    If(akActor.WornHasKeyword(pIsPowerArmorFrame) == true)
       Self.UnregisterForAllEvents()
       akActor.UnequipItem(akItem = pmyWeaponBaseFormName, abPreventEquip = false, abSilent = false)
       If(akActor == Game.GetPlayer())
          pmyMessageName.Show()
       Endif
    Else
        Self.RegisterForAnimationEvent(akSender = akActor, asEventName = "furnitureEnterSlavePA")
    EndIf
    EndFunction
     

     

     

     

    • Like 1
  4. Here is a standlone global script fragment example that is callable from the console. Convert GetFormFromFile into properties for a form attached script:


    Script SKK_GlobalScript

    Function SwitchCurrentCompanionDontUseAmmo() Global ; CallGlobalFunction "SKK_GlobalScript.SwitchCurrentCompanionDontUseAmmo"

    Quest Followers = Game.GetFormFromFile(0x00289e4, "Fallout4.esm") as Quest
    ReferenceAlias Companion = (Followers as FollowersScript).Companion
    ObjectReference CurrentCompanion = Companion.GetReference()

    If(CurrentCompanion != None)
        Keyword TeammateDontUseAmmoKeyword = Game.GetFormFromFile(0x0023f1ca, "Fallout4.esm") as Keyword
        If(CurrentCompanion.HasKeyword(TeammateDontUseAmmoKeyword) == false)
            CurrentCompanion.AddKeyword(TeammateDontUseAmmoKeyword)    
        Else
            CurrentCompanion.RemoveKeyword(TeammateDontUseAmmoKeyword)    
        EndIf
        Debug.Trace("SKK_GlobalScript.CurrentCompanionDontUseAmmo updated " + CurrentCompanion)
    Endif

    EndFunction

     

     

     

    • Like 1
  5. The version byte of the BA2 archive format changing to block older game versions is possibly as a wheeze to try and prevent the bundled CC content being back-published to frozen (you know the people who cant update for, ahem, legal reasons) game instances.

    Or the action with zero documentation is yet another signal that back compatibility for mods is a zero priority for the new corporate ca$h register. 

  6. This is like the .160 ESL header format all over again ... 

    Mod authors who have updated their Fallout4.exe game to 1.10.980 are forced to update their CreationKit to 1.10.943.

    CreationKit 1.10.943 uses a new BA2 archive file format which older versions of Fallout4.exe game can not open.

    The new 1.10.980 Fallout4.exe can open the old and new BA2 archive format to use existing or new mods, so no problem if you have updated.

    If you are not updating your Fallout4.exe for compatibility reasons, you may not be able to use new published mod versions UNLESS the author painstakingly packs the BA2 archive by hand using an old tool. This will significantly affect VR enjoyers (like the old 0.95 file header).

    When publishing mods, be clear WHAT version of BA2 you are publishing, example:

    (a) SKKSynthVision_002_980 Update 002 using the new BA2 archive format - use this if you have updated Fallout4.exe Apr 2024 1.10.980 

    (b) SKKSynthVision_002_162 Update 002 using the old BA2 archive format - use this if you are stuck on Fallout4.exe Nov 2019 1.10.162

     

    UPDATE: the BSArchPro utility packed with xEdit 4.1.5f will OPEN the new BA2 format and SAVE the old BA2 format, so workflow can be: Meak new format archive in Creation Kit, drag into BSArch and save old format BA2.  

     

    What is INFURIATING is that I partipcate in several bethesda developer early adopter programmes and the first I knew of this is when I published a new mod created in CK .980 on  its release day and some users reported symptoms as if the scripts were missing. Turns out they had not updated Fallout4.exe and could not open the BA2 archives. Hence the hand packing and secondary file publication. GRRRRR.

    • Like 1
  7. Timeframe is ~ 60 seconds between applying the exclusion keyword+moving the actor to holding cell and then finding it again.

    The "finder" quests are not start game enabled and called from a controller quest script using Quest.Start() ... BUT that does not matter, they can be called [ StartQuest ] from the console with Debug.Trace in OnQuestInit() for the same repro.

    The keyword is applied direct to the actor ObjectReference.AddKeyword() so it persists past transient alias membership.

    Of all ~ 622 persistent ActorTypeNPC in base game and DLC the ONLY actor this affects is   [Actor < (001AC0CF)>] [ActorBase < (001AC0CD)>] 

    To clear it from the debug log I am GetFormFromFile on that ObjectReference and removing it from any subsequent found RefCollections so my native scripts can silently remove all actors and quests from the world without hacking a single base game script or object and still generate ZERO debug log output. HA!

  8. I have a problem with a quest alias conditional fill.

    This is not a n00b thing, I have HUNDREDS of quest condition fills in published CK mods, its likely a corner/edge case defect.

    A quest process picks actor ObjectReferences from a FormList (which makes them globally persistent), moves them to a hidden holding cell and marks them with an "ignore for future processing" keyword which works fine and reports in the Debug.Trace log:

    SKK_476PrepareWorldQuestScript.PrepareCommonwealth [Actor < (001AC0CF)>] [ActorBase < (001AC0CD)>] [Cell <SKK476HoldingCell (080138BA)>] SKK_476NoDisableKeyword True

    A following quest RefCollectionAlias conditional fill that looks for globally peristent actors to fill finds the expected ~600 actors, but also keeps including that specific INVULNERABLE actor EVEN THOUGH the conditional fill has specific exclusions (see picture) for GetInCell SKK476HoldingCell == 0 and HasKeyword SKK_476NoDisable == 0

    Debug.Trace on the actor properties sitting happily in the RefCollectionAlias shows that the exclusion attributes are still attached: 

    SKK_476ReplaceNPCQuestScript.PrepareNPC [Actor < (001AC0CF)>] [ActorBase < (001AC0CD)>] [Cell <SKK476HoldingCell (080138BA)>] SKK_476NoDisableKeyword True

    How the hell is the quest conditional fill still picking the actor ? The ONLY unusual thing is that the Actorbase is INVULNERABLE which should not affect conditional  attribute evaluations. Unless it does.

    Quest RefCollectionAlias fill conditions.jpg

  9. Nope if it has a construction recipe that allow it to be built or moved it can always be stored. 

    My workaround is for the main object that can be constructed once (recipie condition GetWorkshopObjectCount == 0)  to detect workshop mode and swap itself out for the workshop movable proxy object that uses the same NIF, then manage that; 

     

    ;********************************************************************************************

    Event OnLoad()

     Self.RegisterForRemoteEvent(Self.GetLinkedRef(pWorkshopItemKeyword), "OnWorkshopMode")

    EndEvent

    ;********************************************************************************************

    Event ObjectReference.OnWorkshopMode(ObjectReference akSender, bool aStart)

    If(aStart == true)
        Self.Disable()
        ObjectReference MyProxy = Self.PlaceAtMe(pMyProxyObject) 
        Self.SetLinkedRef(MyProxy, None)
    Else
        ObjectReference MyProxy = Self.GetLinkedRef(None)
        Self.SetLinkedRef(None, None)

        If(MyProxy != None) && (myProxy.is3dloaded() == true) ; it has not been stored 
           Self.MoveTo(MyProxy)

           MyProxy.Disable()
           MyProxy.Delete()

       EndIf

        Self.Enable()
    EndIf

    EndEvent

    ;********************************************************************************************

  10. Great core info as usual.

    In this case the map marker ObjectReferences are all persistent as the global finder quest can find them.

    The ObjectReferences to exclude are static CK drag n drops into the form list, verified in game with Debug.Trace iteration:

    SKK_TarkovQuestScript.GenerateEnableStateList 0 [Form < (0009B040)>].IsInList [FormList < (1C01477F)>]
    SKK_TarkovQuestScript.GenerateEnableStateList 1 [Form < (0010196C)>].IsInList [FormList < (1C01477F)>]
    SKK_TarkovQuestScript.GenerateEnableStateList 2 [ObjectReference < (0016349B)>].IsInList [FormList < (1C01477F)>]

    Unfortunatley console [ IsInList ] does not seem to return >> 1.0  for any form types in my games to validate. 

    Appreciate the offer but I cant use any DLL injections 😞

  11. I use a lot of quest conditional fils in object finder quests.

    Using IsInList > FormList to exclude base object forms works fine e.g. MiscObject, Weapon or ActorBase forms.

    If the FormList is of in game ObjectReferences, they seem to be ignored.

    Question: has anyone ever successfully used Condition.IsInList with a list of ObjectReferences ?

     

    The usecase: quest confitional fill finds all wordspace mapmarkers (GetIsId==Mapmarker that are enabled IsDisabed==0) fine.

    But needs to exclude a static list of those that are known to have EnableStateParents.

    There is no known condition or script function to dynamically detect an object has EnableStateParent.

    Therefore trying to use (IsInList==ListToExclude) but they are still included in the conditional quest fill.

  12. I can get a handle to a load door ObjectReference in script and move that fine.

    Unfortunatley the associated/linked yellow actor teleport marker does not move with the door object (in CK render window or in game with script), the player keeps teleporting to the original teleport marker location.

    Before I waste a stack of time on this,  does anyone KNOW absolutley if it is possible or impossible to get a handle to and move a teleport marker in script ?

    I was originally using activators with OnActivate scripted Moveto but the game doesnt know about that path for map marker display and npc pathing and I woudl like to have it all.

  13. > I can't compare a Global to a global

    Yes you can: if(myGlobalVariableA.GetValue() == myGlobalVariableB.GetValue())

    > I can't compare a Global to an "int"

    Yes you can: if(myGlobalVariableA.GetValue() as Int == IntVariable) OR if(myGlobalVariableA.GetValue() == (IntVariable as Float)) 

    Although if your Global actually does contain a decimal you may want to use the Math.Ceiling() or Math.Floor() Int conversions.

    > I can't make "int" = Global.

    Yes you can: myGlobalVariableA.SetValue(IntVariable as Float)

    • Like 1
×
×
  • Create New...