Jump to content

JustChill

Premium Member
  • Posts

    284
  • Joined

  • Last visited

Posts posted by JustChill

  1. Hey, I use the full version of Oblivion Reloaded together with EBF.

     

    About ENBoost, do NOT use together with the memory purger of OR.

    Yet you can check the INIs of both additions.

     

    In OR's ini there should be a memory manager. Not sure if that one is still present in ORL's ini, but if so, be sure that "MemoryManagement" is set to "0", if you want to use ENBoost.

    Cannot tell what is better, as I currently don't use any of both. ^^

     

    As of still continuing to enhance Nehrim, I rather want to have no memory enhancement running to check of how much more unstable the game gets. XD

    Current results aren't that bad. :smile:

  2. Hm, RemoveItem works fine for me.

     

     

    The only known issue is that if you have a stack of stolen and a stack of non-stolen items, then RemoveItem will not work accurately.

     

    You've 30 stolen pieces of paper.

    And 1 non-stolen piece of the same paper.

     

    "RemoveItem" will tell you that 30 items got removed, but only one got really removed as RemoveItem only takes care of the non-stolen stack.

    If you have just stolen items, then it will take care of the stolen stack of items and work properly.

     

     

    Issues only arise if you have both. Stolen and non-stolen.

     

    I've made a similar workaround for this issue as you did, but I remove one item after another in that one, until the total amount of items I need to remove is met. :smile:

  3.  

    Just one thing... ENBoost crashes CSE if activated.

    Nehrim has an ENB baked into its installation but I always disable ENBoost, when I mod the game to ensure I have no issues opening CSE. :smile:

     

    Even though there is a mod available, that should prevent the issues, but I rather switch the boost off than using a fix for.

    https://www.nexusmods.com/oblivion/mods/47301/

    As it is just a temporary problem. As soon as you stop modding and start playing you simply can turn on the boost again.

    That is what this thread is all about in the first place. To allow us to use CSE and ENB. Thats why I made the first bat files, that I did not mention or published as the first one only renamed the d3d9.dll

     

    Sure thing, it's just that I don't bother about ENBoost that much to think of using a different BAT file just for being able to use CSE with it together.

    Nehrim comes with ENBoost by default, but I always turn it off as I am using OR anyways.

     

    So that was my approach about this topic. :wink:

     

     

     

    Oh and I really like your Daggerfall screen. :D

  4. Yes. ENB's graphic settings are known to have a performance impact.

    According to Alenet the developer of OblivionReloaded, OR is 4 times faster than OBGE and I think that means it might also be faster than ENB graphics.

     

    It either comes with some sort of memory manager, which SHOULD NOT be used together with ENBoost.

    Even though I am not sure if OR's memory management system is as good as ENBoost.

     

    BUT, it's possible to use ENB graphics together with OR as both are highly configureable.

    You just have to make sure that you turn off any setting that intervenes with a setting from the other addition.

  5. Yeah, that dll is the culprit.

    Yet I still don't bother about making BATs to solve that problem, as I already use Oblivion Reloaded anyways, since it has the possibility to recolor the water for specific occasions.

    Which I used in Nehrim for making magically contaminated water look like green acid. ^^

    https://staticdelivery.nexusmods.com/mods/3312/images/46/46-1611276296-51025886.jpeg

    Or cyan at the crater:

    https://staticdelivery.nexusmods.com/mods/3312/images/46/46-1611276286-85643051.jpeg

     

    While ENBoost should still work with OR, I still rather use one or the other. :)

  6. Just one thing... ENBoost crashes CSE if activated.

    Nehrim has an ENB baked into its installation but I always disable ENBoost, when I mod the game to ensure I have no issues opening CSE. :smile:

     

    Even though there is a mod available, that should prevent the issues, but I rather switch the boost off than using a fix for.

    https://www.nexusmods.com/oblivion/mods/47301/

    As it is just a temporary problem. As soon as you stop modding and start playing you simply can turn on the boost again.

  7. @JustChill

     

    I did look at your code there, and to me it looks like you increase a number and decrease the other.

     

    Don't forget to check the variable names of the code. :wink:

     

    "sNOAmsgPage" stands for a specific page of a message box menu.

     

    So I am far from altering that code, as it works properly. :wink:

    I've made screenshots of that message box menu:

    https://www.nexusmods.com/nehrim/mods/4

     

    So these values are required to be handled like this as their current value determines the behavior of the message box menu and the results of clicking buttons in it. :wink:

     

    I've programmed this before I was aware about LINK.

    Probably not gonna update it for LINK, especially as LINK also requires MenuQue.

    I might make an optional plugin with LINK support at some point, but currently the message box menu works well enough. :smile:

  8. But your scripting comprehension is legendary QQuix. :tongue:

    The CSE also reminds me about you everytime I use it.

    There is an uncompiled QQuix script, where you mentioned your idea about Coda for CSE. :wink:

     

     

    I would die for an example from you with nested arrays. :smile:

     

     

    Oh and speaking about "index mismatches". I mean not that the arrays are unstable, I mean that the scripter causes index mismatches as of not thinking about all unhandled exceptions. ^^

    Guess using nested arrays require a lot accuracy in the script, which is why I would love to see an example from you.

  9. I just found this script in Nehrim Expanded and realized why the patch key didn't work. As I forgot to add this to the door. ^^

    This allows a second key to be added to the door of which this script is applied to, so maybe that might be interesting for someone?

    scn UnfNQ05KellerTuerScript
    
    string_var strUnfOpenedWithKey
    int iUnfDoorUnlocked
    
    Begin OnActivate Player
        if GetLocked
            if Player.GetItemCount UnfNQ05KeyKellertunnel
                Let strUnfOpenedWithKey := GetName UnfNQ05KeyKellertunnel
                Let strUnfOpenedWithKey := (GetStringGameSetting "sOpenWithKey") + $strUnfOpenedWithKey + "."
                MessageboxEx $strUnfOpenedWithKey
                Unlock
                sv_Destruct strUnfOpenedWithKey
                Let iUnfDoorUnlocked := 1
            else
                Activate Player  ;=> Key required message triggered, or the key which is really assigned to the door will be used
            endif
        else
            Activate Player  ;=> Just opens the door / cell transition.
        endif
    End
    
    Begin GameMode
        if iUnfDoorUnlocked
            Let iUnfDoorUnlocked := 0
            Activate Player ;=> After unlocking, we open the door or transit between cells like if the regular key was used.
        endif
    End

    I've just added an auto-translation function to it.

    The message box generates itself out of the game setting string and the key name.

    At least for the english and german version it worked. :smile:

  10. Yeah... Rather use the GECK Wiki, it has similar functions, but far better explanation.

    https://geckwiki.com/index.php?title=Let

     

    Even though thanks to the JIP LN NVSE plugin there are hundred more functions for New Vegas. ^^

    https://geckwiki.com/index.php?title=Complete_List_of_Function_in_Fallout_New_Vegas

     

    Compared to Oblivion:

    https://cs.elderscrolls.com/index.php?title=List_of_Functions

     

     

    I honestly fear maps.

    I only used simple arrays so far and neither nested ones. XD

     

     

    It even went that far, that I used 3 simple arrays for values that could be housed otherwise.

    One array for the merchant reference

    One array for the default barter gold

    One array for the reset time of the barter gold

     

    They all get populated at the same time, so all of them will ever have the correct info at the very same index for the very same merchant.

     

    It might be possible to make one array for the merchant ref and nest another array to that which could hold both values.

    So the first reference (index 0) needs the first 2 values (index 0, 1).

    The second (index 1), needs the next 2 values (index 2, 3).

     

    But I always fear about index mismatches, so I rather went the simple way. XD

  11. Well, GetGameLoaded ensures that this script only fires once, after you load a game. ;)

    Which eases the engine a lot, therefore using "GetGameLoaded" and "GetGameRestarted" is recommended for things that only need to be done at these specific occasions.

     

    I am not totally sure which functions get recognized through savegames and which not. But I am for a few...

    Like here:

     

            if GetGameRestarted    ;=> Will be saved in the memory but not into the savegame.        
                AddToLeveledList BuecherHaushalt NMOBuchNehrimMagieArkan 1 1
                AddToLeveledList BuecherHaushalt NMOBuchNehrimMagieIllusion 1 1
                AddToLeveledList BuecherHaushalt NMOBuchNehrimMagieVeranderung 1 1
                AddToLeveledList BuecherHaushalt NMOBuchNehrimMagieWiederherstellung 1 1
                AddToLeveledList BuecherHaushalt NMOBuchNehrimMagieZerstorung 1 1
                AddToLeveledList BuchRandom NMOBuchNehrimMagieArkan 1 1
                AddToLeveledList BuchRandom NMOBuchNehrimMagieIllusion 1 1
                AddToLeveledList BuchRandom NMOBuchNehrimMagieVeranderung 1 1
                AddToLeveledList BuchRandom NMOBuchNehrimMagieWiederherstellung 1 1
                AddToLeveledList BuchRandom NMOBuchNehrimMagieZerstorung 1 1
            endif

     

    This block just adds these books to the respective spawn lists upon restarting.

    They stay in the spawn lists even through loading a savegame.

    So it's not necessary to do that in GetGameLoaded and actually... might be potentially bad.

    As with GetGameLoaded you may add the same item multiple times to the same list. oO

     

    Even though I am not sure if AddToLeveledList works that way, as there is no such warning on the respective wiki page.

     

    Yet I still rather would recommend to use it in that way. ;)

  12. Why thank you. :smile:

     

    I learned this from my old mentor, even though he didn't really use this system on his own as he said "It's a LOT work to write down every reference you want to use".

    And I agree.

     

    Especially if you want to include DLC content. ^^

     

    I've updated a house mod for Fallout New Vegas which was origially updated by my old mentor to have a sorting system which also includes DLC items.

    He used as patch ESP, but in my update I made a patch script and simply use "BuildRef" and later "GetFormFromMod".

     

    "BuildRef" seems to be a New Vegas-exclusive function but it is far worse than "GetFormFromMod" as you need to convert the FormID into a decimal value. XDDDD

    Which leaves room for issues during conversion, while with "GetFormFromMod", you can simply copy the FormID out of FNVEdit when having it running in the background. ^^

     

    This will ensure that there are no typos, as building up an invalid reference isn't that good.

    Although its possible to catch that with "IsFormValid":

    scn YourPatchModQuestScript
     
    Begin GameMode
    
    ref rModReference
    
    If IsModLoaded "ExactModName.ESP"
    
        Let rModReference := GetFormFromMod "ExactModName.ESP" "2A4B"
    
    
        if IsFormValid rModReference
    
            ;=> Valid reference do some stuff with it here.
    
        endif
    endif
    End

     

     

     

     

    Well... I've a nicer example for Oblivion... ehm... Nehrim. ^^

    scn TelNetEnhNMOpatchQuestScript
    
    ref TelNetEnhNMOruneREF
    float fQuestDelayTime
    
    Begin MenuMode
        if fQuestDelayTime
       else
            Let fQuestDelayTime := 0.1
        endif
        if GetGameLoaded
            if IsModLoaded "Nehrim Magic Overhaul.esp"
                Let TelNetEnhNMOruneREF := GetFormFromMod "Nehrim Magic Overhaul.esp" "8CC" ;=> Mark
                if IsFormValid TelNetEnhNMOruneREF
                    SetIconPath "BTNehrimTweaks\BTRuneTeleport09Icon.dds" TelNetEnhNMOruneREF
                    SetModelPath "BTNehrimTweaks\Teleporter\BTRuneTeleport09.nif" TelNetEnhNMOruneREF
                endif
                Let TelNetEnhNMOruneREF := GetFormFromMod "Nehrim Magic Overhaul.esp" "8CD"    ;=> Return
                if IsFormValid TelNetEnhNMOruneREF
                    SetIconPath "BTNehrimTweaks\BTRuneTeleport09Icon.dds" TelNetEnhNMOruneREF
                    SetModelPath "BTNehrimTweaks\Teleporter\BTRuneTeleport09.nif" TelNetEnhNMOruneREF
                endif
                Let TelNetEnhNMOruneREF := GetFormFromMod "Nehrim Magic Overhaul.esp" "8CF" ;=> Arcane Uni
                if IsFormValid TelNetEnhNMOruneREF
                    SetIconPath "BTNehrimTweaks\BTRuneTeleport03Icon.dds" TelNetEnhNMOruneREF
                    SetModelPath "BTNehrimTweaks\Teleporter\BTRuneTeleport03.nif" TelNetEnhNMOruneREF
                endif
                Let TelNetEnhNMOruneREF := GetFormFromMod "Nehrim Magic Overhaul.esp" "8D1"    ;=> Cahbaet
                if IsFormValid TelNetEnhNMOruneREF
                    SetIconPath "BTNehrimTweaks\BTRuneTeleport04Icon.dds" TelNetEnhNMOruneREF
                    SetModelPath "BTNehrimTweaks\Teleporter\BTRuneTeleport04.nif" TelNetEnhNMOruneREF
                endif
                Let TelNetEnhNMOruneREF := GetFormFromMod "Nehrim Magic Overhaul.esp" "8D2"    ;=> Erothin
                if IsFormValid TelNetEnhNMOruneREF
                    SetIconPath "BTNehrimTweaks\BTRuneTeleport02Icon.dds" TelNetEnhNMOruneREF
                    SetModelPath "BTNehrimTweaks\Teleporter\BTRuneTeleport02.nif" TelNetEnhNMOruneREF
                endif
                Let TelNetEnhNMOruneREF := GetFormFromMod "Nehrim Magic Overhaul.esp" "8D3"    ;=> Giliad
                if IsFormValid TelNetEnhNMOruneREF
                    SetIconPath "BTNehrimTweaks\BTRuneTeleport03Icon.dds" TelNetEnhNMOruneREF
                    SetModelPath "BTNehrimTweaks\Teleporter\BTRuneTeleport03.nif" TelNetEnhNMOruneREF
                endif
                Let TelNetEnhNMOruneREF := GetFormFromMod "Nehrim Magic Overhaul.esp" "8D0"    ;=> Mountain Abbey
                if IsFormValid TelNetEnhNMOruneREF
                    SetIconPath "BTNehrimTweaks\BTRuneTeleport04Icon.dds" TelNetEnhNMOruneREF
                    SetModelPath "BTNehrimTweaks\Teleporter\BTRuneTeleport04.nif" TelNetEnhNMOruneREF
                endif
                Let TelNetEnhNMOruneREF := GetFormFromMod "Nehrim Magic Overhaul.esp" "8D4"    ;=> Ostian
                if IsFormValid TelNetEnhNMOruneREF
                    SetIconPath "BTNehrimTweaks\BTRuneTeleport06Icon.dds" TelNetEnhNMOruneREF
                    SetModelPath "BTNehrimTweaks\Teleporter\BTRuneTeleport06.nif" TelNetEnhNMOruneREF
                endif
                Let TelNetEnhNMOruneREF := GetFormFromMod "Nehrim Magic Overhaul.esp" "8D5"    ;=> Sarnor
                if IsFormValid TelNetEnhNMOruneREF
                    SetIconPath "BTNehrimTweaks\BTRuneTeleport08Icon.dds" TelNetEnhNMOruneREF
                    SetModelPath "BTNehrimTweaks\Teleporter\BTRuneTeleport08.nif" TelNetEnhNMOruneREF
                endif
                Let TelNetEnhNMOruneREF := GetFormFromMod "Nehrim Magic Overhaul.esp" "8CE"    ;=> Tirin Abbey
                if IsFormValid TelNetEnhNMOruneREF
                    SetIconPath "BTNehrimTweaks\BTRuneTeleport03Icon.dds" TelNetEnhNMOruneREF
                    SetModelPath "BTNehrimTweaks\Teleporter\BTRuneTeleport03.nif" TelNetEnhNMOruneREF
                endif
                Let TelNetEnhNMOruneREF := GetFormFromMod "Nehrim Magic Overhaul.esp" "8D6"    ;=> Waverock
                if IsFormValid TelNetEnhNMOruneREF
                    SetIconPath "BTNehrimTweaks\BTRuneTeleport07Icon.dds" TelNetEnhNMOruneREF
                    SetModelPath "BTNehrimTweaks\Teleporter\BTRuneTeleport07.nif" TelNetEnhNMOruneREF
                endif
            endif
        endif
    End

    Here, I simply switch the meshes and icon textures of some misc items to the ones from another mod, if that mod is available. :smile:

    Script is from that mod:

    https://www.nexusmods.com/nehrim/mods/31

    And it points to this mod:

    https://www.nexusmods.com/nehrim/mods/27

     

    This works very well and doesn't require any patch ESPs. :smile:

     

    But be sure that "GetGameLoaded" is required as these changes will be forgotten by the game if you load a different savegame.

  13. Put a collision box in front of it.

    Then check the collision box in the render view.

    It should have a "Primitive" in its settings which is a dropdown menu.

     

    The default setting is "L_TRANSPARENT".

    Change it to "L_NAVCUT".

     

    You should be able to walk through the collision box (it lost its collision), instead it acts as a hole in the Nav Mesh it touches.

     

    I've used something similar at my Enderal mod:

     

    As you can see, that boss whisp tries to run through the barrier (which is actually just an effect, while there is a regular collision box).

    It doesn't get, that it cannot walk through there. ^^

    In an update, I've added a new layer of collision boxes over the existing ones and gave them the "L_NAVCUT" primitive.

     

    Hah, initially I tried to simply change the existing collision boxes to "L_NAVCUT" and figured out that now you simply can run through it. XDDD

     

    Yet with the new layer of "L_NAVCUT", she seems not try to get through there. At least I noticed a bit better behavior and I wonder if that would work for you too. :smile:

     

     

     

    In addition:

    But adding a key might be the quicker variant, except you need to take care that the door locks itself again after you used it. ;)

  14. Final addition.

     

     

    I've now tested it out very well and it partially works.

    It surely works if you add the base ID and the world space reference by yourself in your mod and mark these as quest items.

     

    But as I am adressing base game references setting these to quest items does NOT fix the problem, except if you started the game with my mod.

    Which is nothing I assume. ^^

    So if a player walks through the cell with the disabled corpses they still get a deletion flag as of not being a quest item at that point and activating my mod later, which makes quest items out of these NPCs has no affect on them being visible.

     

    So even if my script is not able to place the corspes properly (With PositionWorld it still works well enough), it ensures that they are visible, regardless when the player activated my mod.

    Which is the solution I rather prefer. :smile:

     

     

     

    Unfortunately I am not sure if this behavior translates properly to Skyrim.

    That would require further testing on this game...

     

     

     

    Still thanks again for bringing this up. At least now I know why some corpses disappear and some not. ^^

  15. So, I just got home and checked it.

    I am using Nehrim not Oblivion, but the engine is the same so it shouldn't differ.

     

    I've found 2 references of dead actors that do NOT despawn.

     

    1.) An ill sheep, which only has the "Respawn", "No low level processing" and "Can corpse check" flag enabled. The world space reference has NOTHING checked.

    I think it's just the "respawn" which ensures it doesn't despawn. So it just respawns dead, over and over. ^^ ^

    Yet I believe that this would also cause the inventory to respawn. I can't check, as it has a "NoActivationScript", so you cannot go into the inventory of the sheep.

     

    2.) A dead NPC, which has the "Quest Item" and "Can corpse check" flag set. The world space reference has again NOTHING checked. Except "Persistent Reference", but it is greyed out, which makes sense as of the "Quest Item" flag on the base object.

     

    I will use the second method on the actors of my script above to ensure they spawn in their editor placement. :smile:

     

     

    Not sure if that also translates well to Skyrim, but I guess it should work in a similar way.

     

     

    In addition:

    I've also checked these nice articles about cell reset.

    Here to one for the Creation Kit (Skyrim's Creation Engine):

    https://www.creationkit.com/index.php?title=Cell_Reset

    Even though it lacks a bit of detail.

     

    The one for the Construction Set (Oblivion's Gamebryo) is very detailed:

    https://cs.elderscrolls.com/index.php?title=Cell_Reset

  16. Nice.

    I wonder if there is a similar constellation regarding for Oblivion.

    The flags in the render window are vastly different there though. You can only set up a persistent reference and make it initially disabled, but there is no "spawn dead" thing. As you need to set the actors HP to 0 for them to spawn dead. ^^

     

    But I guess allowing the dead body to respawn might do the trick.

     

    After all it would be nice to throw away that dumb workaround, I'll check if I can get similar results there.

     

    Thanks for bringing this up. :smile:

  17. In Oblivion there was one particular corpse in a house that never disappeared and was safe storage.

    That might be the case, as that interior never resets? So the corpse never gets cleared fromt he game.

     

     

    I honestly had very weird cases in Oblivion where persistent actors are also partially removed.

    Well... Not physically removed, but if you wait 3 days to force cell reset, they turn out invisible.

    I came across this issue, as of having some quests that include corpses:

     

    If you NEVER EVER entered the cell of where these corpses are, you are fine and the quest can enable these corpses and they will be visible.

     

    BUT, if you entered that cell, 3 days pass ingame and then come back to this cell with the proper quest progress, you'll find these corpses invisible, even if they are persistent references, and get called with the "Enable"-function in the script.

     

    I found a way to trick the engine, by calling "Resurrect" on the corspes, while they are disabled, let a few frames pass to ease the engine, then enable them, let another few frames pass to ease the engine and use the "Kill" command.

    As even if they have "0" health in their actor properties, they will be standing around as of that how "Resurrect" works. So you need to use the "kill" command.

    The whole process will also move them away from their editor location, but luckily Skyrim's Papyrus has a nice function to ensure the corpse will be set back to the editor location: MoveToMyEditorLocation

     

    Here is the respective quest progress script from Oblivion, which surely is NOT to be used in Skyrim's papyrus, but maybe it works here in a different way.

    Creation Engine is simply a overhauled Gamebryo engine. :wink:

     

     

    Begin GameMode
        if GetDistance Player < 4000
            if ( EnableOnce < 18 )
            if ( EnableOnce == 0 )
                if ( GetStage MQ08 > 9 )
                    if Event03T01aRef.GetDisabled
                        Event03T01Ref.Disable
                        Event03T01aRef.Enable    
        
                        Event03T02Ref.Disable    
                        Event03T02aRef.Enable
                        Event03T02aRef.DisableLinkedPathPoints
    
                        Event03T03Ref.Enable
    
                        LauraRef.Disable
                        LauraTotRef.Resurrect
                        LauraTotBlutRef.Enable
    
                        JahrmarktTaenzerinRef.Disable
                        JahrmarktTaenzerinTotRef.Resurrect
                        JahrmarktTaenzerinTotBlutRef.Enable
    
                        GauklerJahrmarktRef.Disable
                        GauklerJahrmarktTotRef.Resurrect
                        GauklerJahrmarktTotBlutRef.Enable
    
                        JeeleRef.Disable
                        JeeleTotRef.Resurrect
                        JeeleTotBlutRef.Enable
    
                        BardeJahrmarktRef.Disable
                        BardeJahrmarktTotRef.Resurrect
                        ;NQ14NotizenGaukler01Ref.Disable => Useless as already performed in
                        ;NQ14NotizenGaukle02Ref.Enable    => NQ 14 quest stage 5.
    
                        JahrmarktWacheRef.Disable
                        SadJahrmarktWacheTotRef.Resurrect
                    endif
                    Set EnableOnce to 1
                endif
            elseif ( EnableOnce == 17 )            ;=> As always, dead references that are disabled,
                LauraTotRef.Kill                ;=> may appear invisible if simply re-enabled.        
                JahrmarktTaenzerinTotRef.Kill    ;=> So we must confuse the engine with this
                JeeleTotRef.Kill                ;=> weird procedure to ensure the corpses always    
                GauklerJahrmarktTotRef.Kill        ;=> appear and are visible.
                BardeJahrmarktTotRef.Kill
                SadJahrmarktWacheTotRef.Kill
                LauraTotRef.PositionWorld -12905.3984, 21332.4473, 3965.4275, -1.0830, NehrimWorldspace    
                JahrmarktTaenzerinTotRef.PositionWorld -12753.6143, 21566.6953, 3907.1047, 2.5995, NehrimWorldspace
                JeeleTotRef.PositionWorld -12780.6143, 21852.4258, 3948.6223, -2.5995, NehrimWorldspace    
                GauklerJahrmarktTotRef.PositionWorld -12329.9932, 21596.3457, 3936.1838, 0.7999, NehrimWorldspace        
                BardeJahrmarktTotRef.PositionWorld -12327.5010, 20665.8066, 3946.8286, -2.7827, NehrimWorldspace
                SadJahrmarktWacheTotRef.PositionWorld -13035.7695, 21724.3828, 3907.6960, 0.0175, NehrimWorldspace
                Let EnableOnce := 18            
            elseif ( EnableOnce > 6 )
                Let EnableOnce += 1        
            elseif ( EnableOnce == 6 )
                LauraTotRef.Enable
                JahrmarktTaenzerinTotRef.Enable
                JeeleTotRef.Enable
                GauklerJahrmarktTotRef.Enable
                BardeJahrmarktTotRef.Enable
                SadJahrmarktWacheTotRef.Enable
                Let EnableOnce := 7
            elseif ( EnableOnce > 0 )
                Let EnableOnce += 1
            endif
            endif
        endif
    End

     

     

     

    As you can see, I use "PositionWorld" to move the corpses into position again, but they will never look that nicely placed as with their default editor location.

    Unfortunately Oblivion doesn't have such a script function to use the Editor Location. :sad:

     

    But this ensures that disabled corpses, which are re-enabled are visible for the specific process.

    Even though after 3 days, they will be reset again.

     

     

    You can even test that out in Oblivion at least.

    Let's say we have a persistent reference of a dead actor, which is called "ThisGuyRef".

    Begin GameMode
       if ThisGuyRef.GetDisabled
            ;=> Will enter here, as long as the dead body is disabled.
    printc "Is disabled"
      else
    printc "Is NOT disabled"
            if ThisGuyRef.IsRefDeleted ;=> THIS IS AN OBSE FUNCTION!
    printc "Is enabled but will be invisible"
                        ;=> This will only run, if the corpse got affected by a cell reset (it is invisible, but enabled)
           endif
      endif
    End

    So Oblivion gives the deletion flag also onto persistent references of actors that are dead, upon cell reset.

    Even though that flag won't work as the actor is a persistent reference. Instead it will simply be invisble. XD

     

    Yet, I am not sure how Skyrim exactly behaves in this case and if this workaround fixes the issue to have no invisible corpses that use the persistent flag.

  18. Hey, the most fancy way would be to use a script constellation like this:

     

     

    scn YourPatchModQuestScript
     
    Begin GameMode
    
      ref rModReference
    
      If IsModLoaded "ExactModName.ESP"
    
        Let rModReference := GetFormFromMod "ExactModName.ESP" "2A4B"
    
      endif
    End

     

     

    "2A4B" is the FormID without the first 2 numbers, as these come from "ExactModName.ESP".

    You can easily build up references to world objects or even base forms from other mods, without having to add them as masters into your own mod.

  19. You perfectly can.

    When I converted content from the german mod "Nehrim Expanded" into an own mod, I wanted to take over as many stuff as possible.

    In the case of the "Nehrim Magic Overhaul", the initial solution was to change the spell merchants to NOT sell any spells directly, but to sell spell runes which will teach the player the respective spell when activated in the inventory.

     

    So I had to use

    OffersSpells

    to check if NPCs would sell spells directly.

    If so, I used

    SetOffersSpells 0

    to force them NOT selling any spells directly.

    Then I checked if they offer Misc Items:

    OffersMiscItems

    If NOT, then I allowed them to offer misc items, so the spell runes can be bought by the player.

    SetOffersMagicItems 1

     

     

    For more insight, check out my Nehrim Magic Overhaul:

    https://www.nexusmods.com/nehrim/mods/27

    I just recently updated it to also add mod merchants into the system. :smile:

     

     

     

    HOWEVER,

    to really force servicers to service, depends also on the current state of the package.

    Even if you set the flag as stated above, it might be possible that they DO NOT offer services until a specific point of their current package is reached:

     

     

    If you set up a travel package (even with the "offer service" flag on) while the NPC is traveling to it's destination it is in a temporary NOT OFFER SERVICE state while they are movining.
  20. Have you tried to use a scripted casting function onto your boss?

     

     

    <YourBoss>.Cast <YourSpell> Player

     

    You may try it like this:

     

     

    scn YourBossScript
     
    float fCastingTime
     
    Begin GameMode
    
      If GetDistance Player > 1000
    
        if fCastingTime > 5
          <YourBoss>.Cast <YourSpell> Player
          Let fCastingTime := 0
        else
          Let fCastingTime += GetSecondsPassed
        endif
    
      endif
    End

     

    So now your boss should cast on the player every 5 seconds, as long as the player is further away than 1000 units.

    The GameMode should only run if you are nearby the boss, so I hope you are using it in an interior.

    As otherwise, it may try to cast spells onto your char even if he / she is far far away, as the GameMode of world space objects kicks in pretty early which could lead to bad results in that case.

     

    But if you use your boss only in a closed interior, it should work fine. :)

  21. Hello,

    I really love working with arrays, as they can hold many information.

    Went even that far that I save an array into the savegame as it contains info that is required to be retrieved even after loading a game.

    Even though it's recommended to normally use

    Let <yourArray> := Ar_Null

    to erase an array and avoid savegame bloating.

     

    I would not recommend to use arrays without emptying them except if you want to save the data for later use similar as I did in my dynamic barter system.

    Normally Oblivion has fixed barter gold.

    While there are mods like "Living Economy" or "Enhanced Economy", I still don't get how they manage to dynamically change the merchants barter gold.

    I mean it's easy with "SetBarterGold", but that doesn't dynamically change the Menu String, which holds the current barter gold value.

    I've did it with "SetMenuStringValue".

    Oblivion only raises the Mercantile skill only per transaction not per sold item for each transaction.

    My old mentor AltDunmer made an initial fix for this, but PushTheWinButton perfected the solution by using a different OBSE function to raise the skill.

    Which did not require any of the ugly workarounds my old mentor used.

    Quest script to ensure that selling multiple items will be awarded with the proper skill value:

     

     

    scn NOAmercantileLevelingFunction
    
    float fquestdelaytime
    short sNOAoldGold
    short sNOAconvCheck
    short sNOALastTransactionCount
    short sNOASSetOnceSell
    short sNOASSetOnceBuy
    array_var arNOATransactionInfo
    ref rNOAsendMerchant
    ref rNOAcompMerchant
    short sNOAsendMerchGold
    short sNOAsendTransGold
    
    array_var arNOAMerchantRef
    array_var arNOAMerchGold
    array_var arNOAResetTime
    
    int i
    int iMerchantSaved
    
    Begin GameMode
        if sNOAconvCheck == 2
            Let sNOAconvCheck := 1    ;=> Run block once again at next conversation
        elseif sNOAconvCheck == 0
            Let fquestdelaytime := 0.1    ;=> Quick processing is necessary for accuracy.
            Let sNOAconvCheck := 2
        endif
    End
    
    Begin MenuMode
        If (Menumode 1009 && sNOAconvCheck == 1)
            DisableControl 4    ;=> To ensure the loop is done before the player leaves the dialogue menu.
                Let i := 0
                if eval(Ar_Size arNOAMerchantRef) > 0    ;=> Buying or selling something to a merchant will
                    Let rNOAsendMerchant := GetFirstRef 35    ;=> start this block.
                    While (rNOAsendMerchant)
                        if rNOAsendMerchant.GetCurrentAIPackage == 6
                            Break ;=> Only one NPC can talk with the player in dialogue
                        endif
                        Let rNOAsendMerchant := GetNextRef                        
                    Loop
                    if rNOAsendMerchant.GetOffersServicesNow    ;=> Is it a merchant?
                        While eval(Ar_Size arNOAMerchantRef) > i
                            Let rNOAcompMerchant := arNOAMerchantRef[i]
                            if rNOAcompMerchant == rNOAsendMerchant
                                Let iMerchantSaved := 1 ;=> We already have that merchant, so not saving it once more.
                                if eval(arNOAResetTime[i]) <= GameDaysPassed    ;=> Evaluate merchant's 'money reset
                                    Let sNOAoldGold := arNOAMerchGold[i]
                                    Let arNOAResetTime[i] := GameDaysPassed + 3
                                    if rNOAsendMerchant.GetBarterGold < sNOAoldGold
                                        rNOAsendMerchant.SetBarterGold sNOAoldGold
                                    endif
                                endif
                            endif
                            Let i += 1
                        Loop
                        if iMerchantSaved
                            Let iMerchantSaved := 0
                        else
                            Ar_Append arNOAMerchantRef rNOAsendMerchant
                            Let sNOAoldGold := rNOAsendMerchant.GetBarterGold
                            Ar_Append arNOAMerchGold sNOAoldGold
                            Let sNOAoldGold := GameDaysPassed + 3
                            Ar_Append arNOAResetTime sNOAoldGold
                        endif
                    endif                    
                endif
            Let sNOAconvCheck := 2    ;=> This will only be run once.
            Let sNOAoldGold := player.getgold
            EnableControl 4        ;=> Reference evaluation is over.
        elseif (MenuMode 1008 && sNOAconvCheck == 2)    ;=> Only start the block in container menu
            if IsBarterMenuActive    ;=> Only proceed if the container is a barter menu
                If (player.GetGold != sNOAoldGold) && Player.GetBaseAV Mercantile < 100
                    Let sNOALastTransactionCount := GetLastTransactionQuantity
                    if sNOALastTransactionCount == 0
                        Return    ;=> Failsafe
                    endif
                    if GetContainerMenuView
                            if sNOASSetOnceSell
                            else
                                if NOAinitQuest.sNOAmercantileBuySkill    ;=> If buying inceases the skill too,
                                    SetSkillUseIncrement 0.2 Mercantile 0    ;=> the incrementation will be reduced.
                                else
                                    SetSkillUseIncrement 0.4 Mercantile 0    ;=> Default incrementation.
                                endif
                                Let sNOASSetOnceSell := 1
                                Let sNOASSetOnceBuy := 0                                
                            endif                                 ;=> We got already awarded with an increase
                        if sNOALastTransactionCount > 1    ;=> Only if we sold more than one item.
                            Let sNOALastTransactionCount -= 1    ;=> as of the actual transaction. So one less.
                            While sNOALastTransactionCount > 0    ;=> Now we increment the skill one per one.
                                IncrementPlayerSkillUse Mercantile 0 1
                                if Player.GetBaseAV Mercantile == 100
                                    Break    ;=> Oh, so you reached 100? Fine, then exit the loop NOW!
                                endif
                                Let sNOALastTransactionCount -= 1    ;=> Each incrementation reduces the counter until it reaches
                            Loop                            ;=> 0 and exits the loop.
                        endif
                            Let arNOATransactionInfo := GetTransactionInfo "sell"
                            Let rNOAsendMerchant := arNOATransactionInfo["buyer"]
                            Let sNOAsendMerchGold := rNOAsendMerchant.GetBarterGold
                            Let sNOAsendTransGold := arNOATransactionInfo["price"]
                            Call NOAdynBarterGoldFunction 1 rNOAsendMerchant sNOAsendMerchGold sNOAsendTransGold
                    elseif GetContainerMenuView == 0
                                if sNOASSetOnceBuy
                                else
                                    SetSkillUseIncrement 0.4 Mercantile 0
                                    Let sNOASSetOnceSell := 0
                                    Let sNOASSetOnceBuy := 1
                                endif
                            if sNOALastTransactionCount > 0
                                While sNOALastTransactionCount > 0
                                    IncrementPlayerSkillUse Mercantile 0 1
                                    if Player.GetBaseAV Mercantile == 100
                                        Break
                                    endif
                                    Let sNOALastTransactionCount -= 1
                                Loop
                            endif
                            Let arNOATransactionInfo := GetTransactionInfo "buy"
                            Let rNOAsendMerchant := arNOATransactionInfo["seller"]
                            Let sNOAsendMerchGold := rNOAsendMerchant.GetBarterGold
                            Let sNOAsendTransGold := arNOATransactionInfo["price"]
                            Call NOAdynBarterGoldFunction 2 rNOAsendMerchant sNOAsendMerchGold sNOAsendTransGold
                    endif
                    Let arNOATransactionInfo := Ar_Null
                endif
                Let sNOAoldGold := player.getgold
            endif            
        endif
    End

     

     

    Function script to change the barter gold dynamically:

     

     

    scn NOAdynBarterGoldFunction
    
    short sNOABuyOrSell
    ref rNOAMerchantRef
    short iNOAMerchantGold
    short sNOATransactionGold
    short sNOAworkWith
    string_var strNOAworkWith
    
    Begin Function{sNOABuyOrSell, rNOAMerchantRef, iNOAMerchantGold, sNOATransactionGold}
        if eval(Ar_Size NOAmercantileLevelingQuest.arNOAMerchantRef) < 0
            Let NOAmercantileLevelingQuest.arNOAMerchantRef := ar_Construct Array
            Let NOAmercantileLevelingQuest.arNOAMerchGold := ar_Construct Array
            Let NOAmercantileLevelingQuest.arNOAResetTime := ar_Construct Array
            Ar_Append NOAmercantileLevelingQuest.arNOAMerchantRef rNOAMerchantRef
            Ar_Append NOAmercantileLevelingQuest.arNOAMerchGold iNOAMerchantGold
            Let sNOAworkWith := GameDaysPassed + 3
            Ar_Append NOAmercantileLevelingQuest.arNOAResetTime sNOAworkWith
        endif
        if sNOABuyOrSell == 1
            If (rNOAMerchantRef.GetBarterGold - sNOATransactionGold) < 0
                rNOAMerchantRef.SetBarterGold 0
            else
                Let sNOAworkWith := rNOAMerchantRef.GetBarterGold - sNOATransactionGold
                rNOAMerchantRef.SetBarterGold sNOAworkWith
            endif
            Let strNOAworkWith := $sNOAworkWith
            SetMenuStringValue "cont_background\page_layout\cont_contents\cont_npc_money_icon\cont_npc_money_text\string|%z", strNOAworkWith 1008
        elseif sNOABuyOrSell == 2
            Let sNOAworkWith := rNOAMerchantRef.GetBarterGold + sNOATransactionGold
            rNOAMerchantRef.SetBarterGold sNOAworkWith
            Let strNOAworkWith := $sNOAworkWith
            SetMenuStringValue "cont_background\page_layout\cont_contents\cont_npc_money_icon\cont_npc_money_text\string|%z", strNOAworkWith 1008
        endif
        sv_destruct strNOAworkWith
    End

     

     

     

    Furthermore, you can also work with arrays that have an unkown amount of entries.

    Ar_Append <yourArray> <the entry you want to add>

    I like to use Ar_Append especially, when the entry should only be added to the array when a specific condition is met.

     

    If you want to go through the array with unknown entries you surely have to check your index variable against the entries available:

    While eval(Ar_Size <yourArray>) > i
        Let <SomeVariable> := <yourArray>[i]
        Let i += 1
    Loop

    Also be aware that "eval" is required to get the actual array size.

    BUT, it does NOT work in this way:

    While i < eval(Ar_Size <yourArray>)

    Don't ask me why, but Eval always had to be aside the If or While to get the condition working properly. XD

    I learned it the hard way. ^^

     

    Also be sure that "Eval(Ar_Size <yourArray>)" always returns the total amount of entries in your array.

    Which doesn't go well with the index.

    As all indexes start at 0, be sure that you never use ">=" in the condition.

     

    Lets say you have an array with 4 entries.

    Index is 0 to 3.

    Yet "Ar_Size" returns 4.

     

    So using

    While eval(Ar_Size <yourArray>) >= i

    will result in "4" being also included for the index evaluation, but as it is an improper index for the array the script runs into an error.

  22. There's no such thing as quest aliases

    Why hello there. :D

     

    I think I remember you from the Skyrim hub then?

     

    I personally didn't really understand how these aliases work. XD

    I've just made mods for Enderal and used these as recommended by other users who helped me out a lot. :smile:

     

    Gamebryo is a lot different and I personally like it far more, but you surely have to take many things into account.

     

    Skyrim doesn't have "GetGameLoaded" and "GetGameRestarted" as far as I know.

    These are functions that return true only once per script according the respective happening.

    Gamebryo is far more forgiveable when activating and deactivating mods as far less info gets saved into the savegame.

    Yet therefore it is required to use these 2 functions to re-apply previously changed aspects.

     

    But as you are working on followers, I really can recommend using OBSE Event Handlers:

    https://obse.silverlock.org/obse_command_doc.html#Events

    https://cs.elderscrolls.com/index.php?title=SetEventHandler

     

    I used them to make a dog follower level on his own, by killing enemies:

     

    Creature script:

     

    Begin GameMode
        if GetGameRestarted && SadFluffyNachZerst.GetLevel < 50
            SetEventHandler "OnDeath", SadFluffyKillsEnemy, "object"::SadFluffyNachZerst
        endif
    [...]
    End
    

    So this one sets up the event handler for the function "SadFluffyKillsEnemy". This function will be called everytime the world reference "SadFluffyNachZerst" (which is a dog companion), kills something. Function script:

     

    scn SadFluffyKillsEnemy
    
    ref Target
    ref Killer
    
    Begin Function{Target, Killer}
        Let SadFluffyLevelQUEST.FutterCOUNTER += 1
    [...]
    ;---> When Fluffy reaches max level we turn off the event handler!
        elseif SadFluffyLevelQUEST.FutterCOUNTER == 150 && SadFluffyNachZerst.GetLevel < 50
            SadFluffyNachZerst.SetAV Health 330
            SadFluffyNachZerst.SetAV Strength 90
            SadFluffyNachZerst.SetAV Intelligence 75
            SadFluffyNachZerst.SetAV Willpower 80
            SadFluffyNachZerst.SetAV Agility 110
            SadFluffyNachZerst.SetAV Speed 55
            SadFluffyNachZerst.SetAV Endurance 85
            SadFluffyNachZerst.SetAV Luck 70
            SadFluffyNachZerst.SetLevel 50
            SadFluffyNachZerst.SetScale 1.30
            Message "Fluffy has reached his maximum Level of 50."
            Set SadFluffyLevelQUEST.FutterCOUNTER to 0
            RemoveEventHandler "OnDeath", SadFluffyKillsEnemy, "object"::SadFluffyNachZerst
        endif
    End
    

    The event handler will only be applied if max level is not reached yet.

    And it will surely be removed as soon as max level is reached.

×
×
  • Create New...