Jump to content

saintgrimm92

Members
  • Posts

    273
  • Joined

  • Last visited

Posts posted by saintgrimm92

  1. 11 hours ago, AaronOfMpls said:

    Ooh, yah, I imagine it will -- so definitely back up your existing installs of SE and the CK if you try this. 

    Unfortunately, unless you have an existing backup to restore from, I don't know of other ways to replace any missing or messed-up files from 1.6.1130, if indeed any are to blame here.  No doubt there are ways to downgrade a 1.6.1170 install somewhere, but I haven't explored them myself. 

    (I'm running the current 1.6.1170, since I hadn't really played SE at all until after 1170 was current and the update disruptions were mostly settling down.*  And I got SE for free on Steam when it came out, since I already had LE from before there was a legit non-Steam option.)

     

    * Long story short, I moved to Linux on a new PC in early 2020 ... and I had trouble getting Mod Organizer (with my 230+ LE mods) to install and run on Linux until Jan 2024.  Details are in another thread from a couple months ago -- and for now I'm still mostly playing some existing characters in LE while I slowly build my SE mod setup.

     

    I was really tired last night, otherwise I probably would have considered just overwriting the files soon as you said to check integ lol.

    Whatever version came out right after 1130, I accidentally launched game without Script Extender and ofc, that starts steam, and auto-updates without any way to stop it........... Because steam loves to suck, it also failed 3x and took me 4 hours to actually get it to work, then another hour to get it downgraded.... Which is why I'm so against it.

    So I'll try pasting those files back into the data folder and overwriting, I'll edit this with results.


    I don't remember the exact commands, you can look those up by google "how to downgrade skyrim" to get the commands you type in. But the specific depots you need for 1130 are:
    depot_489831
    depot_489832
    depot_489833
    for skyrim, and for CK you need:
    depot_1946182
    depot_1946183

     

    EDIT: CK will no longer launch after overwriting the files from depot. But it's an issue with CKPE, the FAQ says to look at github on a fix. Not sure why it's suddenly a problem when it wasn't 5 seconds ago with the exact same CK version.... But w/e.... After I read through the github link and figure out what to do, I'll edit again.

    EDIT2: Preview Window still flashing. And this is basically a clean install of Skyrim AND CK, freshly overwritten with depot files. And no CKPE installed.

    EDIT3: CKPE re-installed correctly, still same.

    EDIT4: Defender had not updated but it did have an update. Updating changed nothing.

    EDIT5: Just for the record, the object pallet editor is exactly the same as preview window. Either just black, or flashes black and can't rotate the view.

    image.png.a12036378966552b073f9bab0a8767fe.png

    EDIT6: I said f*#@ it, checked integ through steam of both CK and Skyrim. It did NOT update them thankfully, however, it didn't fix the issue either.

  2. 34 minutes ago, AaronOfMpls said:

    Find the CK in your Steam client (assuming you have a Steam version, rather than GoG or GamePass), and verify integrity of its files.  Maybe something got deleted or mangled somehow.

    Also, have you had any recent antivirus or Windows updates?  Maybe one of them messed something up.

    All that stuff is turned off for auto-updates, so it shouldn't have. I'll have to check, but I'm calling it done for tonight, I'll do that tomorrow. I know my windows hasn't updated, but with Defender, it doesn't seem to care if you have automatic updates disabled or not.

    The steam thing..... Will that update my CK to current version? CKPE doesn't support current version. I hate steam and their forced updates, I do everything possible to never even launch the app, SSE is only game I own through steam, and I regret not getting GOG every time I do have to open it. So I need to know if CK will update if I check integ, if it will, then I'm just not willing to try that.

  3. Preview window flashes, camera for the preview window cannot be rotated; if it would just work and also let me move the camera to actually look at things, I could ignore the flashing... But trying to see which table I want, and only getting a view from the side really just makes it completely useless....

    Nothing changed on my PC. I did not update CK or skyrim, still using 1.6.1130 and corresponding version of CKPE. Did not update any drivers or anything at all. Just randomly started a day ago completely out of the blue.

    Reverting graphic drivers to version suggested here on forums did nothing. Updating graphic drivers to current versions did nothing. Reinstalling CKPE did nothing. Nothing from running as admin, restarting pc, etc etc. No solutions found on reddit or here has made any difference at all.

    I'm pretty sure I've been working on 1130 since like November, most of the other posts I found about the issue were from 2-3 years ago, so I guess my last hope of having a preview window is that someone here can come up with something more recent to try.

    s#*! will probably take longer, but I can mod without a preview window, so I'll probably only come back to check this once/day or whenever I get pissed off about needing to preview something...

  4. EDIT: So the cause was having multiple stages that complete the quest. I guess this isn't possible in SE? I know some of my quest mods in LE had choices and different stages that ended the quest and gave different rewards based on those choices, but apparently having 2 stages that complete the quest causes the quest to auto-complete no matter what stage is set in SE. This is going to be a problem for this mod in the future, but I'll make a new post asking how to do multiple endings to quests in SE when I get that far.

    EDIT2: 

    I saw the quest starting instead of completing, assumed it was fixed. I just happened to notice that it's setting the stage to 100 no matter what stage is called. That's the real reason it was completing. Stage 100 also completed the quest, and no matter what stage is called, it was also calling stage 100. Did a little more searching through the stages. 100 was just all screwed up.
     
    It got accidentally marked as complete stage because it was going to be the final stage and then I changed my mind and added talking to 1 more person onto it, and complete quest just never got unticked from that.
     
    But it was also ticked to be the startup stage...... And I have no clue how that happened. So ofc no matter what stage was called, 100 was included. Meaning multiple ending quests should be no different than in LE, I just had an issue that was overlooked lol.




    ---------------------------------------------------

     


    So I'm having a strange issue in SSE CK that I never had in LE CK, and I'm not sure if it's because quests need to be set up differently for SE or what's going on.

    I have 2 quests. The end of quest01 automatically starts quest02.

    Quest01 stage 200 fragment:
    SetObjectiveCompleted(150)
    Game.GetPlayer().AddItem(HeroSword, 1)
    Quest02.SetStage(10)

    Quest01 Stage 200 = Complete Quest box ticked.

    This correctly completes quest01. However as soon as the text on the screen saying completed quest01 goes away, it immediately pops up 'completed quest02' as well.

    Quest02 Stage 10 does NOT have the complete quest box ticked. It DOES have the 'start up stage' box ticked.

    Quest02 Stage 10 Fragment:
    Alias_FengrAlias.GetReference().Enable()
    SetObjectiveDisplayed(10)

    I've simply never ran into a problem like this, unless it was something simple, like accidentally ticking the "Quest Complete" box on the wrong stage, But I've quadruple checked it. Stage 10 of quest02 does NOT complete the quest in CK, in-game only.

    I've also tried just setting the stage of quest02 to 10 with console commands, and this also auto-completes the quest.



    Random things I've tried:
    I thought maybe in SSE, it just completes the quest if an alias fails to fill instead of just not starting it like in LE. So I tried setting all aliases to optional, but the results remain the same.

    I tried creating a new SEQ file. The first quest is the only start game enabled quest, so I didn't think quest02 would need one; It appears I was correct as the issue persists. 

  5. I have a boss for a quest that transforms into a werewolf. I copied the entire script of the DLC2 Werebear NPCs, pasted it into a new script, with a few random things added in (set stage on NPC death, transform on combat change also instead of just on hit, etc) put that script on the boss, changed the property to point to 'werewolfchangefx' spell

    The boss plays the animation correctly, his model transforms (that's the transition armor I think?), but just when he should be switched to werewolf race, he turns invisible.

    EDIT: he still attacks, still has a red dot on the compass but he's just invisible.

    Here is a copy of the script. WerewolfChange property is just the WerewolfChangeFX spell; the original script pointed to DLC2werebearchangefx, and the spell/magic effect of both spells are identical. The werebear spell's effect actually uses the werewolftransformvisual script, werewolf casting art, etc, same as the werewolf spell. So I don't understand why it's making him invisible.

    EDIT2: Cleaned up the script, removed some code from the original Werebear that's not used by my actor.

     

    Spell Property WerewolfChange auto
    Quest Property AtmoraQuest Auto
    Int Property AtmoraStage Auto


    Function Transform()
        ; do nothing by default
    EndFunction

    Auto State human
        Function Transform()
            GoToState("Wolf")
            StopCombat()
            StopCombatAlarm()
            WerewolfChange.Cast(self)
            ; SetAv("aggression", 3)
            ; SetAv("confidence", 4)
            StartCombat(Game.GetPlayer())
        EndFunction    

        Event OnCombatStateChanged(Actor akTarget, int aeCombatState)
            Transform()
        EndEvent

        Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
            Transform()
        EndEvent
    EndState

    Event OnDeath(Actor akKiller)
        AtmoraQuest.SetStage(AtmoraStage)
    endEvent


     

  6. I'm having a strange problem with a specific cell I've created, an Inn. It loads correctly without any NPCs inside of it, however, adding NPCs causes random CTDs. At first, I thought it was armor the innkeeper was wearing, so I started removing pieces from his outfit to find which one was causing it, but it was still crashing after every item was removed from his outfit. So I removed his weapon, then custom beard, then custom head, then custom body, so he was completely naked and all parts of him were entirely vanilla. And it still randomly CTD'd when trying to load into the cell.

    So I deleted him. Loaded fine. Added vanilla 'NordMalePreset01' NPC into cell, CTD. Removed that NPC, loaded fine. So I completely deleted the cells navmesh, remade it, cleaned the mod, and still got CTD with Innkeeper. Copied the entire cell, pasted it into a new cell, re-made the navmesh, CTD with innkeeper. Tried NordMalePreset01 again, loaded. Tried a 2nd time to make sure it wasn't a fluke, CTD.


    With no NPCs: Loaded correctly 5/5 times.

    With NordMalePreset01: Loaded correctly 4/5 times - Load, Load, CTD, Load, Load.

    Vanilla only innkepper: 3/5 times - Load, Load, CTD, Load, CTD

    Fully Custom Innkeeper: 3/5 times - CTD, Load, Load, CTD, Load

    I put the innkeeper NPC into a different cell, just to be see, all his custom stuff present; skin, head, beard, weapon and armor. It loaded correctly 5/5 times. So it's for sure something with the cell and not the specific NPC.

    EditorWarnings.txt does not show any errors related to the bad cell.

    I can avoid putting any quest objectives in the inn if I just can't fix it, but I really, really want to avoid putting something with such an instability out there with my name on it...



    EDIT: The times it does load the cell, I can leave and come back as many times as I want with no CTD.

    EDIT2: I can COC into the cell just fine. 3/3 times loaded correctly. Tested with fully custom inn-keeper.

  7. I've got a world space fully built and ready to go.

    First, I tried following this tutorial:

     

    It does nothing but use XLOD to generate everything.

    Everything worked except the glacier slabs had purple textures from a distance. (DLC2GlacierSlab01 > DLC02\Landscape\Glaciers\DLC2GlacierSlab01.nif) and this is a huge problem, because the world space is in a crater of ice and thus surrounded by the glacier slabs on all sides. The map works, but the glacier slabs are bright purple from the map as well.

     

    Doing it this way generates files a lot differently, it creates the objects & tree folders with their LODs, but it does NOT generate the BRT/DDS files for terrain the way the guide says it will.

     

    --------------------------------------------------

    So I tried using the guide from the author of wyrmestooth:
    https://drive.google.com/file/d/1j0xoZFy3tj_J9aL-O0JVqHMLcizGl0Vj/view?pli=1

     

    This guide uses Oscape to generate the land LOD, and that's as far as I can make it because it just doesn't.

     

    It creates the terrain BRT files and texture files as the guide says it will (specifically the files XLOD is NOT creating). However, the map is nothing but clouds and everything still pops in, as if there is no LOD at all in-game.

     

     

     

    --------------------------------------------------

     

     

     

    I decided f*#@ it, I'll try both. So I deleted all the files created by Oscape, re-followed the guide, re-created everything. Still no LOD in-game, but it generated the files again. I then ran XLOD and re-did all that stuff, except using the lodsettings file created by Oscape, instead of a duplicate of Tamriel.LOD.

    And the result was nothing. It was no different than if I had only used Oscape.

     

     

     

     

     

    So basically, XLOD using a duplicate Tamriel.LOD does not generate land BRT & DDS files, but somehow still creates the map and LODS just fine in-game, except for a single item, the DLC02GlacierSlab01. Oscape generates the land BRT & DDS files and <worldspace>.lod, but does nothing in-game.




    EDIT:

    XLOD creates a folder in meshes > terrain. This folder is named after my world space. This folder is EMPTY except for "Objects" folder which holds the object BRT files. And "Trees" folder which holds the Tree BRT files. That is it. It creates NO BRT files inside the folder named after my world space. The video says it will, but it does not. Oddly, it still creates a map and land does NOT pop in.

    Oscape DOES create the loose BRT files inside of the folder named after my worldspace. However, the map is empty and all land still pops in instead of having distant LODs.

     

     

     

    EDIT2: I will go ahead and re-do the LOD with XLOD and post screenshots.

    *This time XLOD did NOT generate a "trees" folder and the trees are popping in. But I followed the guide exactly again.

    image-2023-10-17-165000659.png

     

     

     

    I do not know why a trees folder was not generated this time. I did it exactly as I've been doing it all day. But it's obvious, as earlier when I used XLOD, these trees would have been visible in the first screenshot, but now that the trees folder was not created, they are popping in like the texture of the glacier.

    image-2023-10-17-165206633.png

    image-2023-10-17-170219969.png

  8. Thanks for the replies!

    By cutting it down, I found it was a combination of things; not JUST the NPCs.

    The world space loaded without the NPCs, and that's as far as I tested when I was editing the OP. It went from not loading to loading so I called it good.

    When I got around to doing some better testing, I found it freezing in a couple different locations with none of the NPCs placed. Those specific freezes were related to an SE converted resource I was using that wasn't converted correctly or something, idk really, I downloaded the original SE resource, converted it myself, and it fixed that specific issue.

    Some of my custom beards were also causing freezing in the worldspace for some reason. I can place the NPC into a cell and COC into that cell with no problems, but if the NPC with that beard went out into the world space and I got too close too him, it caused the game to freeze indefinitely.

    I haven't worried about fixing the beard yet and just taken it off of NPCs while I go through and touch up their AI Packages and stuff like that. I've ran into another problem with when the player is considered to be trespassing inside of interior cells. I've made a separate post about that here:

    https://forums.nexusmods.com/index.php?/topic/13101924-how-to-make-interiors-not-trespassing-during-day-and-trespassing-at-night/


    -------

     

    I think adding things slowly and seeing what causes the crash is the smart way to do it.

     

    With the amount of issues I've encountered when trying to make mods, I should know very, VERY well to only do small bits at a time and then test it, but it seems like I make that same mistake at least once on every single mod I've created lmao.

  9. Edit: I kept having other problems that weren't logical; crashes only after adding an NPC, and the crash persisting after removing the NPC, random stuff like that. So I've been slowly copying everything to a new ESP and it seems like there was nothing wrong with my interiors, in the new ESP they are not telling me to leave at all hours of the day, working as expected - That is, a cell I was trespassing in 24/7, now just magically works after duplicating it and saving it into a new ESP..... Does logic even exist when it comes to the CK?



    This ones kinda embarrassing for me to ask; I've not had this problem before so it's obviously something I used to know, it's something I feel like I knew when I made my first ever mod, but now I just cannot figure it out......


    All of the interiors in my custom worldspace consider me trespassing no matter what time of day I enter. I can't use shops, as the shop owner just tells me over and over that I'm not supposed to be in here.

    I've starred at the common data and interior data tabs of the cell window for what seems like hours, and I just can't figure out what to change to make it work like vanilla interiors.

    Making the area public is the only thing I can figure out. It allows me to use the shop and talk to NPCs, but when it's set to public and the player is inside of the shop/house after hours, it's NOT considered trespassing and they never ask the player to leave or anything.


    So what do I need to do to an interior cell to make it open to the player during the day (8am-10pm, or 8pm, w/e vanilla is) and trespassing after 8pm/10pm/whatever?


    EDIT: The shops use an Owner Faction (the vendor faction) and the houses use the 'head of the family' that lives in the house as the owner NPC.

    Also the 'Off Limits' box is NEVER checked.

  10. TLDR;

    World space was working b4 navmeshing. After navmeshing, placing NPCs and setting up their AI Packages it will no longer load. The problem persists even after deleting navmeshes, all NPCs, and even copy/paste in place the entire world into an entirely different worldspace. What else can I try to fix it?

    ------------------------------------------------------

    EDIT3-Solution:
    I'm not sure what was up with that first ESP I was trying stuff on. I copied my backup (same one I used for 'the first ESP') again, deleted all of the NPCs out of all cells, and it fixed the issue. So it's for sure NPC related; my best guess about the first ESP was that there was just something wrong with that ESP and that's why deleting NPCs didn't fix it. I'm not sure what about an NPC would cause the issue though, as I've previously tested each NPC to make sure there were no problems, I'll redo those tests and go from there, doubt I'll be updating this any further.




    EDIT: All markers deleted, still stops responding indefinitely. Double checked ALL interiors by COCing into ALL of them, no issues at all with interiors. Everything added between it working and not working has been removed from the worldspace entirely but the issue persists. Makes no sense....

    EDIT2: I went back to my backup that still had all the NPCs/markers/navmesh. Deleted it all again, 1 thing at a time (all navs,then all markers, then all NPCs) and after all NPCs were deleted from the world/interior cells, it's magically working again.

    So I went back to the ESP I was previously using, where all NPCs/Navs/Markers were deleted already, double checked, all NPCs are gone. All navmeshes in the exterior are gone. All markers are gone. Both ESP's are identical......... But one of them works and one of them don't........ Literally the only difference in the ESPs is the order that the things were deleted..... Seriously wtf???

    Guess I'll copy my backup again and see if JUST deleting the NPCs fixes it this time. Even though the worldspace is working, just how nonsensical this is tells me this entire mod is probaby just never going to work correctly.

     

    ------------------------------------------------------

     

    I've ran into a very strange issue with my world space no longer loading and I've run out of things to try, so I'm hoping someone else can give me some ideas.

    So here's what happened:
    My worldspace was working fine. I navmeshed it. Being a dumbass, I didn't load into the game to make sure it was still working, instead I told myself "to test the navmesh, I need to set up AI Packages and markers for NPCs to leave their houses, otherwise how would I know it's working?

    So I went through every NPC in my entire mod and created their daily routines.... Which included adding farming markers, patrol markers, lots of markers in the world space, with patrol packages, guard patrols, everything a worldspace needs to seem "alive".

    Then I went to test it... I can COC into any interior cell, but when I try to leave the interior into the worldspace I created, Skyrim just stops responding forever. It doesn't "crash", it just stops responding. I left it open for over an hour last night. Never crashed until I finally just used task manager to close the game.

    That's a problem I've NEVER had before when making a mod. If somethings wrong, the game will crash in a specific cell/near a specific NPC and then I can figure it out.

    But the CK doesn't crash in the world space, I get no errors when loading the world space in ck, except the usual ones and a few navmesh errors.


    Here is what I've already done to try to find the problem:

    So I put each NPC in the mod into a testing cell ONE at a time and COC'd into the testing cell. There was a couple NPCs that did cause a crash. So I fixed them up, got them working correctly where I could COC into the testing cell with no issues with every single NPC in my mod.

    The issue persisted.

    So I thought maybe it was the navmesh.... I deleted the entire worldspace's navmesh, ran the ESP through TES5Edit, cleaned it, all that good stuff, but same problem. So I tried removing EVERY npc from their cell.... If its an NPC, and they're not "in" the game anymore, they won't be going outside and causing my problem.... But ofc that didn't fix it either.

    With the only errors that pop up being same as ones when u load into a vanilla worldspace, I decided okay I'll try remaking it completely..... I created a new world space, same parent space as the world that's causing problems. (AAAtmora01 is the parent space of AAAtmora02 (which is the world that will no longer load), I created AAAtmora03 with AAAtmora01 as the parent, so all I had to do was select every single object in AAAtmora02, copy it, and paste it in place in AAAtmora03. Just to be clear, AAAtmora01 does NOT cause the game to stop responding, I can enter/leave that space at will)

    This new worldspace, 03, has no navmesh. It's exactly like 02 was when I know for a fact it was working.... Except it has markers (farming, patrol, just generic markers that are used all over the game)...... But it has the same problem! Game just stops responding forever when I try to COC into the worldspace, or enter from a linked interior cell...

    So what could the problem even be??? Why would a worldspace work fine before navmeshes, stop working after navmeshes, and even when re-created in a completely new worldspace without navmeshes, still cause the same issue??

    The only thing I can even think of is maybe I just have too many markers in the world space. There is quite a few; my AI Packages were pretty complex with a lot of moving around and complex patrols with multiple over-lapping paths. So Just for the f*#@ of it, I'm going to delete every single marker I added to the exterior cells. Not just the basic idlemarkers, but furniture markers as well, and I will report back.

    But I'm posting this now because I have very little hope that that will fix anything... So does anyone else have any other ideas of what to try short of spending another 2 months rebuilding this from scratch?

  11. LeveledItem - Creation Kit . There is checkbox Calculate from all levels <= Player, which makes difference. Probably, need combinations of the flag and branching lists, as suggested. Also, Global is an interesting control, if can involve scripting.

     

    I've seen something about next-gen update? Curious, if there will be magnificent upgrades from F76, like conditions in leveled lists and condition blocks presets.

    Next Gen update? For Fallout 4??? That's awesome news for me.

     

     

    This post contains info that's not correct. For the correct way to do this, please refer to the top of the OP.

     

     

    I went ahead and set it up last night. I THINK it's working. I just don't know about the chance stuff. It actually seems most synths are wearing the lower level stuff, which is correct. But if someone can just say "yes that'll work like you think it does" or "no, you've f***ed up everything, try this instead" would help me a lot in the future.

     

    So, here's how I ended up setting it up:

     

     

    Synth Outfit has 1 leveled list.

     

    That leveled list has a few entries, all of which are also leveled lists. (the <= PC level is checked!)

     

    Level1: TrooperBasicLvlList

    Level20: TrooperHeavyLvlList

    Level30: TrooperUniqueLvlList01

    Level35: TrooperUniqueLvlList02

    Level40: TrooperUniqueLvlList03

    Level50: TrooperUniqueLvlList04

     

     

    Level 50 has the leveled out chances (if it works right) so I'll just go off of that one. But first, I'll explain how all the above leveled lists are set up in a spoiler, these are done through more leveled lists, but here are the possible results for each level above:

     

    Level1: 2 basic armors

    Level20: 2 basic armors + a heavy armor

    Level30: 2 basic armors, 1 heavy armor, 3 unique armors.

    Level 35: 2 basic armors, 1 heavy, 6 unique (including the previous 3).

    Level 40: 2 basic armors, 1 heavy, 8 unique (previous 6 + 2 new)

    Level 50: 2 basic armors, 1 heavy, 10 unique (previous 8 + 2 new)

     

    The unique armors have differing chances, depending on the level, if I'm understanding how to do this correctly. At level 30, there's only 3 possible unique armors, each only have 20% chance to be used. At level 35, those same unique armors now have a 30% chance, but the 3 new unique armors available at this level only have 20%

     

     

     

     

     

    So, the level 50 leveled list, TrooperUniqueLvlList04.

     

    ALL items in this leveled list are also leveled lists and are set to level 1.

     

    LvlTrooperArmor (This is the 2 basic armor sets). Chance None: (left blank)

     

    LvlTrooperArmorHeavy (this is the heavy armor set ONLY) Chance None: 50%

     

    LvlTrooperHero1 (This is just a single unique armor set) Chance None: 70%

    This is exactly the same for unique armors 1-8, so I'll skip them, just know there is 8 unique armors in leveled lists with chance none set at 70%.

     

    LvlTrooperHero9 (1 powerful armor set, should honestly be legendary, but setting up legendaries was too much work for me for this lol Hero10 is exactly the same, just different armor visually, so I'll not bother adding 10 to this either) Chance none: 90%

     

     

     

    What I expect this to do:

    10% chance of a synth using the hero9 or hero10 leveled lists. 30% chance of a synth using the hero1-8 leveled lists. 50% chance of a synth using the heavy armor list. If none of those are used, then they'll use the basic armors.

     

     

    EDIT: What I'm afraid of is the "chance none". I don't know what it does.... Does 70% chance none = 30% chance this specific item will be used?

     

    Or does 70% chance none = same chance as any other, but 30% chance the synth will just be naked? If it works like this, then how do I set up the leveled list to work the way I hoped it would?

     

    It seems difficult to test. I don't know if the "preview results" button actually works (so much s*** in Skyrim CK just doesn't work) But most of the time, the preview shows absolutely nothing.... So either it doesn't work right, or there's a pretty good chance the synth will just be naked..... I've not yet seen any naked synths in my playthrough, but I'm not convinced that that's proof it's working right. lol

     

    EDIT2:

    Here's the results from preview button on unique04 leveled list:

     

    Preview Level: 50

    Preview Count: 100

     

    Result 1: nothing (so 0 items in 100 enemies?)

    Result 2: nothing

    Result 3: 100 Basic armors, 100 basic helmets (so they spawned 100 of the same item in a row???)

    Result 4: nothing

    Result 5: nothing

    Result 6: nothing

    Result 7: 100 of the same heroes helmet and armor (so again, 100 of the same item in a row even thought it's chance none = 70%???? Idt this button works.....)

     

    So we just killed 700 synths, got 100 of the same basic armor set, 100 of the same unique armor set, and absolutely nothing else???? 500/700 were just naked and the 200 that weren't just spawned the same 2 armors over n over? That can't be right...... I've seen too many synths in my game that weren't naked for those numbers to be accurate.

     

  12. This post contains info that's not correct. For the correct way to do this, please refer to the top of the OP.



    2nd post to try to keep it clean.

    A better explanation of what I think I need to do, but don't want to spend hours doing until I get confirmation if it's what I need to do:

    Synth Custom Outfit:
    Synth Master Outfit Leveled List

    Synth Master Outfit Leveled List:
    Level 1: Armor1
    Level 15: Synth Leveled List 2
    Level 25: Synth leveled List 3
    Level 30: Synth Leveled List 4


    Synth Lv2 List:
    Level 1: Armor1
    Level 1: Armor 2

    Synth Lv3 List:
    Level 1: Armor1
    Level 1: Armor2
    Level 1: Armor 3

    IF that is the correct way to make the NPC use lower leveled armors at higher levels, is there a way to make certain armors on the leveled list more likely to be used than others?

    Such as:

    Synth Lv3 List:
    Level 1: Armor1 (20% chance)
    Level 1: Armor2 (60% chance)
    Level 1: Armor3 (20% chance)

     

  13. This started as a question, but as I have it figured out now so I'll just post how I did it, it's actually pretty simple.

    I want synths to wear different armors based on both player's level and a probability % chance.

    So the first thing to do is change the synth outfits to all use my "master" leveled list.

    To set up the master list:
    Note: My armor sets do not use "armor pieces". It uses a single item that takes up every slot except the head + a helmet. 2 items per outfit. This will be A LOT more complex if you're trying to do it with sets made up of separate pieces, but this can still be used as a base.

    Calculate from all levels <= PC's level is the only box checked.
    Chance None: 0
    (the above may be different for you, depending on what you're trying to do.)

    All items have: Count 1, Chance None 0.

    Level 1: Basic Armor Leveled List (BA)
    Level 20: Heavy Armor Leveled List (HA)
    Level 30: Unique Armor Leveled List 01 (UA1)
    Level 35: Unique Armor Leveled List 02 (UA2)
    Level 40: Unique Armor Leveled List 03 (UA3)
    Level 50: Unique Armor Leveled List 04 (UA4)


    The Uniques are very similar so I will only go over BA, HA, UA4.

    Basic Armor Leveled List

    NO BOXES CHECKED


    All items level 1, count 1, chance none 0.

    Level 1: Trooper Armor Leveled List
    Level 1: Scout Armor Leveled List

    Trooper Armor Leveled List (this holds the actual armor NOT more leveled lists)

    Use All is the only box checked!

    Trooper Armor
    Trooper Helmet

    Scout Armor Leveled List is set up exactly the same as the Trooper Armor.
    So there is only 2 items on BA, the trooper and scout armor lists. That means there is equal chance of both being used by the Synths when the player is under level 20. As for at level 20....



    Heavy Armor Leveled List
    This is where you'll start needing duplicates of the same stuff to change the chances of getting things. I chose to have 10 items total on the list for easy %.

    NO BOXES CHECKED

    All items level 1, count 1, chance none 0.

    Level 1: BA
    Level 1: BA
    Level 1: BA

    Level 1: BA
    Level 1: BA
    ​Level 1: BA

    ​Level 1: BA
    Level 1: Arc Armor Leveled List

    Level 1: Arc Armor Leveled List

    Level 1: Arc Armor Leveled List

    That is 7x Basic Armor Leveled lists, 3x Arc Armor Leveled lists (Arc Armor = Heavy Armor). So from level 20-30, you will have a 70% chance to see Synths wearing the basic armors (trooper/scout) and a 30% chance to see Synths wearing heavy armor (arc armor)

    Arc Armor Leveled List
    Exactly the same as trooper/scout Lists, Use all, level/count 1. Arc Helm + Arc Armor.

    Pretty simple, right? Just literally add the % you want. If you want 90% to wear basic armor, just put in 9x BA and 1x Arc List. It's that easy. You can probably figure it out yourself from here, but I'll go ahead and describe the level 50 List, UA4.


    Unique Armor List 04

    NO BOXES CHECKED

    All items Level 1, Count 1, Chance None 0.

    Level 1: Master Armor Leveled List
    Level 1: Unique Armor Collection Leveled List 03

    Level 1: Unique Armor Collection Leveled List 03
    Level 1: Arc Armor Leveled List

    Level 1: Arc Armor Leveled List

    Level 1: Arc Armor Leveled List
    Level 1: BA
    Level 1: BA
    Level 1: BA

    Level 1: BA

    This gives a 40% chance of Synths wearing basic armor. 30% chance of wearing heavy armor. 20% chance of wearing armor from the 3rd set of uniques. 10% chance of wearing Master Armor.

    Master Armor Leveled List:
    Note: Not to be confused with the master list, this is just master tiered armor.

    Same as trooper/scout/arc leveled lists. Use all, count 1, etc etc.

    Level 1: Master Armor Helmet
    Level 1: Master Armor Armor

    Unique Armor Collection Leveled List 03

    NO BOXES CHECKED
    All level1, count 1, chance none 0.

    Level 1: UArmor 01 Leveled List
    ​Level 1: UArmor 02 Leveled List
    Level 1: UArmor 03 Leveled List
    ​Level 1: UArmor 04 Leveled List
    ​Level 1: UArmor 05 Leveled List
    ​Level 1: UArmor 06 Leveled List
    ​Level 1: UArmor 07 Leveled List
    Level 1: UArmor 08 Leveled List

    UArmor 01-08. All exactly the same exactly like trooper/scout/etc. They add 1 helmet & 1 armor each. Each one has "use all" checked. This means it's an equal chance for each armor to be used when this collection leveled list is selected (which should be 20% of the time at level 50+).

    It takes some time to set up and the more items you're adding the more complex it'll be and the longer it'll take, but it's a lot more basic than I was originally making it.





    Original Post:

     

    I've used some level lists with skyrim, just everything set at level 1 to be random, but I'm trying to do something a little different, and I'm not exactly sure how to do it, I think it'll be a long, repetitive process, so I thought I'd ask if it's even correct before I waste the time.



    I have some new outfits I want Synths to wear. I want to add more outfits at higher levels, but I don't want them to stop wearing the lower-level stuff either.

    For example, at level 1, the player would ONLY see synths wearing the level1 gear.

    At level 15 I want to add a 2nd outfit. But if I just put the singular outfit at level 1 and a different outfit at level 15, would I never see another Synth wearing the level 1 gear?

    I'm thinking what I'd probably have to do is make multiple leveled lists, linking into each other such as:

     

    SPOILER: Old explanation of what I'm trying to do.... Read it if you want, probably easier to understand in 2nd post instead.

     

    The "main" leveled list filled with secondary leveled lists, all requiring level 1.

    The secondary leveled list would have a singular outfit at level 1. However, at level 15, it would have a tertiary leveled list. This leveled list has 2 items, both at level 15. 1 item = level 1 outfit, 2nd item = level 15 outfit.

    If I'm thinking correctly, I have 15 outfits to spread out, so on the "highest level" of the secondary list, I'd need all 15 outfits on it right? And the 2nd highest level would have the first 14 outfits?

    But then how would I go about making 1 of the outfits more common than the other? At the highest level, I'd of course want the lowest level gear to be pretty rare, but I still want it available to the NPCs. The only "chance" options I see in the leveled list window are "chance none" which I assume means it will be the chance that none of the items are added to an NPC when it spawns?


    EDIT:

    Basically, I want a leveled list that does this:

    Player level 1: Synths have 1 outfit to wear, any time a synth spawns, it'll be wearing this outfit.

    Player level 15: Synths have 2 outfits to wear, they're more likely to wear a new outfit, but sometimes they'll still wear the level 1 outfit.

    Player level 25: Synths have 3 outfits to wear, the previous 2 + a new one. This time, the new outfit and the level 1 outfit are both kinda rare, but still common, but the level 15 outfit is still the most common.

    Player level 30: Synths have 4 outfits to wear. Previous 3 + another new one, and so on and so forth like that.

     

     

     

  14.  

    OnCellAttach() - OnLoad() - OnSpellCast() - OnActivate() - OnEffectStart() - OnMagicEffectApply()
    All of the above work just fine, the only issue is how and where they will be implemented.

     

     

    OnEffectStart. And if the summon mgef effect gets dispelled, the minion despawns too

     

    I never considered oneffectstart.

     

    I tried using that and scripting the entire thing from the actual magic effect, but it didn't work. I never tried an oneffectstart event on the actor though. I'm actually doing testing on a clean install right now to make sure I copied all the needed files, then it'll be uploaded, so it won't make it into this one, but I'll def keep this post bookmarked for future use, thank both of you for all the help you've given! :)

     

     

  15. OnLoad maybe?

     

    Worth a shot, will edit this in a few mins with update lol Thanks for reply :smile:

     

    EDIT: Sadly, no luck with that one.

     

    EDIT2: OnLoad made me think of OnInit, but that don't work either lol

     

    EDIT3: Tried the perk route. Main spell applies a duplicate of twin souls with no conditions, setting the commanded actor limit to 6 instead of 2. Seems to conflict with normal twin souls or something idk, changes to only summoning 1/6 script told it to.

     

     

    Edit4: It's not as cool, but I've spent all day trying to figure this out, so I'm done with it. The player spell will just summon 2 necromancer skeletons, and those 2 skeletons will summon 2 more when entering combat. Summoning 2 summoners isn't as cool as summoning a horde, but w/e lol

  16. I was double checking my spells list and realized there is one that I wanted to make but didn't for some reason (possibly didn't wanna ask how to do this at the time lol) but I'm trying to get it implemented into my mod now.

    The spell is a "mass summon" spell that summons 6 skeletons for 1 minute. The spell itself will "require" twin souls perk, otherwise I'm pretty sure one of the 2 skeletons summoned will just die. To bypass the limit of 2, the spell will summon 2 skeletons with a unique twin souls perk, which in turn summons 2 skeletons each.

    With other summons I got help here on the forums making an NPC summon more NPCs when it enters combat. This time I don't want a combat event though. I want the 2 player-controlled skeletons to summon 2 more skeletons each the moment they appear to give the illusion that all 6 were summoned together by the player.

     

    I went through the "Events" page on ck wiki but nothing caught my eye as an event that would be called on when the NPC is summoned. I was hoping to find something like "OnSummon" or "OnSpawn" or something, but can't seem to find anything similar.

  17. So my mod seems to be fully working now.

    But I'm trying really hard to make this mod balanced. I normally make the enemies pretty difficult with loads of HP and damage capability, but this time I'm trying to give the player a different type of experience.


    I was hoping to copy the vanilla lvl'd mobs' stats to make them on par with vanilla difficulty. However, vanilla seems to not actually "use" leveled NPCs.... I looked at the leveled Draugr NPCs. They point to a template, which picks "enc" enemies depending on the player's level....

    Vanilla process:

    NPC: LvlDraugrAmbushMelee2hMale
    Template: LCharDraugrMelee2HMale

    LevevledCharacter: LCharDraugrMelee2HMale
    Level 1 > SubCharDraugr01Melee2HM
    Level 6 > SubCharDraugr02Melee2HM
    etc, etc.

    LeveledChatacter: SubCharDraugr02Melee2hM (Player lvl6 from previous LeveledCharacter)
    Level 1 > EncDraugr02Melee2HHeadM00
    Level 1 > EncDraugr02Melee2HHeadM01
    etc, etc.





    I've already placed all the enemies, they're all leveled actors that level up with the player... I don't want to redo all that in the fashion the vanilla game does, I'm already too far past it. I want to keep the enemies I already have, which level with the player, I just need some type of guide or something to read so I can get a good idea of what balanced stats look like. All my "common enemies", for example, have the same stats, but some of them are super weak and others are a little over powered still - So obviously there's something I do not understand about balancing.

    My Feral Vampires have the same stats as my Ancient Skeletons. Both level with the player. Both have the same minimum/max level. Both have the same HP/MP/SP offsets, yet the Feral Vampires hit harder and seem to soak up more damage or have more HP or SOMETHING that's making them more powerful.

    I've been googling for "balancing guides" for the past hour and found pretty much no info at all. Everything is relating to questions about people trying to change the stats of vanilla NPCs, not match them with new leveled ones.


    EDIT: Or can someone point me in the direction of a vanilla NPC that uses the "PC Level Mult" checkbox instead of a leveledchar that just places enc enemies depending on players level?

    EDIT2: Ferals were tougher due to an ABSpell I put on their race lol. Write that up to user error. But I'd still like a vanilla NPC or something to go off of so I have some kinda idea without hunting down vanilla bosses at different levels to count how many hits from a daedric sword they can take b4 they die and using that as my comparison lol

     

    EDIT3: FINALLY FOUND ONE!!

    Harkon. But I'm not sure how much help this is going to be. His calculated health and max level is closer to my common enemies than my bosses... And my common enemies die easy af against a level 53 player, so idk what to base my levels/offsets on.... Guess it's just gonna take a lot of tweaking each NPC until it doesn't feel too easy/hard for me. (And I thought this last step would be a quick easy one lol)

  18.  

    Typo on > GoToState("SEQ01")

    Spell Property MySummonSpell01 Auto
    Bool Property isCasted = False Auto Hidden
     
    AUTO STATE SEQ01
    EVENT OnCombatStateChanged(Actor akTarget, int aeCombatState)
        If (aeCombatState == 1)
           If ( isCasted == False )
                isCasted = True
                MySummonSpell01.Cast(Self, Self)
                GoToState("SEQ02")
       EndIf
    EndIf
    ENDEVENT
    ENDSTATE
     
    STATE SEQ02
    EVENT OnCombatStateChanged(Actor akTarget, int aeCombatState)
        If (aeCombatState == 0)
            isCasted = False
            GoToState("SEQ01")
    EndIf
    ENDEVENT
    ENDSTATE

     

    lol wow. :sweat: I promise I'm not normally this dumb.

  19. I'm not sure about the items in the chest. Have you tried adding the items directly into the merchant's inventory? That should be instantaneous and items of the type the merchant can sell and not equipped I believe will show up in the vendor list.

     

    I haven't. I'd never heard of this before. Do I need to change the faction's sell container to the NPC to make that work?

     

    If just adding the items though I could probably also just add them to the chest? I was hoping to avoid adding a property for every tome, but if it's the only way to get it to show up when I need it to, I can.

     

    I haven't tried implementing the leveled list just yet. I'm pretty sure it works in a way that I could add an entire leveled list to the chest in a quest stage? I'll try that route first. But if it doesn't work like I'm expecting, I'll try just adding them individually to see if that's instant.

     

     

    EDIT:

    Quick test, adding the items to the chest works for sure.

  20. Try a single chest with leveled lists to control its contents. If you want the chance of items to change based on the player's level, just using leveled lists should work. If you want to have the contents change based on a quest stage, I believe you can use AddForm to add items to the leveled list.

     

    I'll try that either later this evening or tomorrow and report back. Thank you :)

     

    I've rarely used leveled lists, but it is something I've done. Kinda. I've done it for NPC enemy drops, never for containers, but I can't imagine it'd be very different. It is through a quest stage though.

     

    -

     

    I did a little more testing this morning before I left. It seems the stock only changes after some time has passed. I wasn't testing for that specific thing, so I have no idea how much time. So the faction adding/removing tactic does seem to work in general, but I need it to be an instant thing, so it's just not the best option for what I'm doing personally.

     

     

    Do you happen to know off-hand if items added to a leveled list through addform will appear in the shop instantly or if it'll take awhile? I'm not sure, but my assumption is that my method is waiting until the "restock" period to change stock, and I'm needing the items to appear in the NPC's shop the moment he says they're available.

     

  21. I finally got around to testing this. It just doesn't work....

    Quest Stage 50 Dialogue end: Sets stage 55. Works correctly. Correct objectives complete/display.

    Quest stage 55 fragment:

    (alias_kazarvel.getreference()as actor).RemoveFromFaction(MerchFact01)
    (alias_kazarvel.getreference()as actor).AddToFaction(MerchFact02)
    SetObjectiveCompleted(50)
    SetObjectiveDisplayed(55)

    But the NPC still only sells the items in the first chest.

    I've checked the merchant factions, they point to the correct chests. Faction properties on quest are filled properly. Checked to make sure the chests had the correct books in them.

    I'm not even sure how he still has access to the tomes in the first chest when the faction that tells him to sell items from it has been removed.

    Tried leaving and coming back to see if it's a cell load thing and he still only sells the merchfact01 tomes.


    Same result on all other quest stages that remove and then add a new faction to the NPC. He just doesn't start selling out of the chest his new faction is pointing to, only the items from the 1st factions chest.

  22.  

    If you will be using the last script, you can add to it one more 'fail safe', just to be sure that your issue won't happen again, by dividing the script into 'States', which each state is responsible in handling only the combat state the actor is in.
    - The first 'State' (SEQ01) will be handling ONLY the > aeCombatState == 1.
    - After firing > aeCombatState == 1, the script will jump to SEQ02 waiting to execute ONLY > aeCombatState == 0.
    - And when aeCombatState == 0 is completed, it will return to SEQ01 to wait to execute again > aeCombatState == 1.
    - And this goes on and on forever....
    Spell Property MySummonSpell01 Auto
    Bool Property isCasted = False Auto Hidden
     
    AUTO STATE SEQ01
    EVENT OnCombatStateChanged(Actor akTarget, int aeCombatState)
        If (aeCombatState == 1)
           If ( isCasted == False )
                isCasted = True
                MySummonSpell01.Cast(Self, Self)
                GoToState("SEQ02")
       EndIf
    EndIf
    ENDEVENT
    ENDSTATE
     
    STATE SEQ02
    EVENT OnCombatStateChanged(Actor akTarget, int aeCombatState)
        If (aeCombatState == 0)
            isCasted = False
            GoToState("SEQ01')
    EndIf
    ENDEVENT
    ENDSTATE
    

     

     

    I couldn't get this script to compile, and I can't figure out where the issue is. All it says is:

    mismatched character '\r' expecting '"

    missing RPAREN at '\\n'

     

    I have no idea how to decipher that. When it says something like "StopSneaking is not a function" I can easily know where the issue is. There is no '\r' or '\\n' in the script so I have no idea what it's talking about.

     

    I switched it back to the original without the states and it works perfectly, so I'll just leave it with 1 failsafe with the iscasted true/false without having states. That seems to be enough to get him not to cast on combat end.

     

    My vamplord was also landing and then immediately floating again at end of combat, I assume just like this NPC was re-casting summon. I was able to fix that the same way, without the states, just the iscasted true/false lines.

  23. EDIT:

    NOW FULLY WORKING.

    How the NPC works:
    Summoned on feet/walking.
    Upon entering combat, begins to float/casting spells.
    After all nearby enemies are dead, lands on feet/begins walking again.

     

    Script for anyone who needs it:

    Scriptname AAVampKingCombatScript extends Actor
    
    Bool Property isSneaking = False Auto Hidden
    
    EVENT OnCombatStateChanged(Actor akTarget, int aeCombatState)
        If (aeCombatState == 1)
           If ( isSneaking == False )
              StartSneaking()
              isSneaking = True
           EndIf
        ElseIf (aeCombatState == 0)
            StartSneaking()
            isSneaking = False
        EndIf
    EndEvent

    Edited further to remove redundant Info.

  24. You can just use the Harkon Magic as it is, actually duplicate it and give it a unique ID, that actor will float and use magic attacks when the opponent gets to 3 meters distance of him, but he will not use melee attacks, and when he lands he can't counter attack when he gets hit from 3 meters+.

     

    This NPC only uses magic, so having him in his magic form constantly is exactly what I'm going for. It'd be cool if he was just walking outside of combat, but it's not important at all that he does that. If always floating will make him fight with magic 100% of the time, I'm more than happy to do that.

     

    But my NPC already copies MOST of everything from the Harkon Magic NPC. He still starts out in melee form though, and just runs around doing nothing for seemingly a random amount of time. Then he starts floating and doing what he's supposed to do. Sometimes I have all the enemies killed before he even starts to float. Sometimes he goes right into float mode and starts fighting.

     

    I'm not sure how far 3 meters looks in-game, but a majority of the time, if he's NOT floating, he will just turn around and run away from the enemy. Then if/when he starts to float, he comes back and attacks.

     

     

    EDIT:

    The magic Harkon does have a script my NPC doesn't have. But looking at the script, all it does is add certain spells to the NPC depending on the player's level. My NPC uses custom spells that are manually added to the Actor's spell list, so idt he needs the script. Everything else is exactly like the magic harkon, except the skin, as he uses a custom vampire lord model/texture.

     

    He casts the custom spells fine, but only in floating mode. I just need to figure out a way to force him to float constantly I guess. He does have all the BodyFX and those types of spells the script add to harkon as well, the only ones he's missing are the attack spells because he casts my spells instead.

  25.  

    Except from the vanilla game Harkon boss fight and my own mod, I personally have never seen this done before in any mod I've played the last 12 years.
    And this is because the DLC1 vampire lord assets are completely broken, they are from the worst created assets by Bethesda, so in order to do the:
    - Transform to Vampire Lord > Vampire Lord Melee combat style > To Vampire Lord magic combat style (floating), and vise versa.
    1) Except that you need 3 actors
    2) You have to do this inside a controlled combat scene, because you can't change combat style on the vamipre lord on the fly using the same actor, it just won't work!!
    This means that this requires a specific setup that you will end up with more than 1 script containing, as with my circumstance, thousands of lines!!!
    To get an idea of how this 'change combat style' is done on the vampire lord, take a look at how Bethesda coded the whole thing.
    And you need to take in account that 'that' specific vanilla combat scene despite the coding, is completely bugged!!!! Even here they F***** Up everything!!
    Script name = DLC1dunHarkonBatTeleport
    This is the part where the change combat style is done, by actually changing actors and transfering their 'actor values'.

    Function SwapHarkons()
    ;;Debug.Trace("Swapping Harkons!")
    if (!initialized)
    initialized = True
    Initialize()
    EndIf
    HarkonBattleMagicFormActor.StopTranslation()
    HarkonBattleMeleeFormActor.StopTranslation()
    VQ08HarkonSwapMarker.MoveTo(SelfActor)
    if (SelfActor == HarkonBattleMagicFormActor)
    HarkonBattleMagicFormActor.MoveTo(VQ08HarkonWarpMarker1)
    HarkonBattleMeleeFormActor.MoveTo(VQ08HarkonSwapMarker)
    TransferAVs(HarkonBattleMagicFormActor, HarkonBattleMeleeFormActor)
    Self.ForceRefTo(HarkonBattleMeleeFormActor)
    OldActor = HarkonBattleMagicFormActor
    SelfActor = HarkonBattleMeleeFormActor
    ((Self as ReferenceAlias) as DLC1dunHarkonBossBattle).SelfActor = HarkonBattleMeleeFormActor
    ;;Debug.Trace("Melee Form, Go!")
    Else
    HarkonBattleMeleeFormActor.MoveTo(VQ08HarkonWarpMarker2)
    HarkonBattleMagicFormActor.MoveTo(VQ08HarkonSwapMarker)
    TransferAVs(HarkonBattleMeleeFormActor, HarkonBattleMagicFormActor)
    Self.ForceRefTo(HarkonBattleMagicFormActor)
    OldActor = HarkonBattleMeleeFormActor
    SelfActor = HarkonBattleMagicFormActor
    ((Self as ReferenceAlias) as DLC1dunHarkonBossBattle).SelfActor = HarkonBattleMagicFormActor 
    ;;Debug.Trace("Magic Form, Go!")
    EndIf
    OldActor.StopCombat()
    SelfActor.SetSubGraphFloatVariable("fdampRate", 0.02) ;Fade in the new Harkon.
    SelfActor.SetSubGraphFloatVariable("ftoggleBlend", 0.0)
    ;;Debug.Trace("Swap complete. Self=" + Self.GetActorRef())
    SelfActor.EvaluatePackage()
    EndFunction
     
    Function TransferAVs(Actor source, Actor destination)
    ;Debug.Trace("IN:")
    ;Debug.Trace("Source: " + source + ": " + source.GetAV("Health") + ", " + source.GetAV("Magicka") + ", " + source.GetAV("Stamina") + ", " + source.GetAV("Variable06"))
    ;Debug.Trace("Destination: " + destination + ": " + destination.GetAV("Health") + ", " + destination.GetAV("Magicka") + ", " + destination.GetAV("Stamina") + ", " + destination.GetAV("Variable06"))
     
    if (destination.GetAV("Health") > source.GetAV("Health"))
    destination.DamageAV("Health", (-1 * (source.GetAV("Health") - destination.GetAV("Health"))))
    Else
    destination.RestoreAV("Health", (-1 * (source.GetAV("Health") - destination.GetAV("Health"))))
    EndIf
    ;Debug.Trace("Outgoing Health: " + source.GetAV("Health") + " == " + destination.GetAV("Health"))
    if (destination.GetAV("Magicka") > source.GetAV("Magicka"))
    destination.DamageAV("Magicka", (-1 * (source.GetAV("Magicka") - destination.GetAV("Magicka"))))
    Else
    destination.RestoreAV("Magicka", (-1 * (source.GetAV("Magicka") - destination.GetAV("Magicka"))))
    EndIf
    if (destination.GetAV("Stamina") > source.GetAV("Stamina"))
    destination.DamageAV("Stamina", (-1 * (source.GetAV("Stamina") - destination.GetAV("Stamina"))))
    Else
    destination.RestoreAV("Stamina", (-1 * (source.GetAV("Stamina") - destination.GetAV("Stamina"))))
    EndIf
     
    ;Debug.Trace("OUT:")
    ;Debug.Trace("Source: " + source + ": " + source.GetAV("Health") + ", " + source.GetAV("Magicka") + ", " + source.GetAV("Stamina") + ", " + source.GetAV("Variable06"))
    ;Debug.Trace("Destination: " + destination + ": " + destination.GetAV("Health") + ", " + destination.GetAV("Magicka") + ", " + destination.GetAV("Stamina") + ", " + destination.GetAV("Variable06"))
     
    destination.SetAV("Variable06", 1) ;*Always* 1 at this point, since we're in the middle of a teleport.
    destination.SetAV("Variable07", source.GetAV("Variable07")) 
    destination.SetAV("Variable10", source.GetAV("Variable10"))
    EndFunction
    

    This is the entire vanilla script handeling the actor:

    ScriptName DLC1dunHarkonBatTeleport extends ReferenceAlias
    {Script for Harkon's bat-based teleporting.}
     
    ;References for swapping between Harkon's Melee and Magic forms (which are actually different actors!).
    ReferenceAlias property HarkonBattleMainForm Auto
    ReferenceAlias property HarkonBattleMagicForm Auto
    ReferenceAlias property HarkonBattleMeleeForm Auto
    Actor property SelfActor Auto Hidden
    Actor property OldActor Auto Hidden
    Actor property HarkonBattleRealHarkonActor Auto Hidden
    Actor property HarkonBattleMeleeFormActor Auto Hidden
    Actor property HarkonBattleMagicFormActor Auto Hidden
     
    bool initialized
     
    ObjectReference property VQ08HarkonSwapMarker Auto
    ObjectReference property VQ08HarkonWarpMarker1 Auto
    ObjectReference property VQ08HarkonWarpMarker2 Auto
     
    ObjectReference property teleportObject auto hidden ;The location we're teleporting to.
    Spell property DLC1VQ08Bats auto ;Bat spell that handles the actual teleport.
    Spell property DLC1VQ08SwapBats auto ;Bat spell that handles the actual teleport.
    bool property swappingHarkons auto hidden ;Are we swapping Harkons on this teleport?
    ObjectReference property newHarkon auto Hidden ;If so, who are we swapping to?
     
     
    Function Initialize()
    SelfActor = Self.GetActorRef()
    HarkonBattleMeleeFormActor = HarkonBattleMeleeForm.GetActorRef()
    HarkonBattleMagicFormActor = HarkonBattleMagicForm.GetActorRef()
    EndFunction
     
    Function BatTeleportTo(ObjectReference obj)
    if (!initialized)
    initialized = True
    Initialize()
    EndIf
    teleportObject = obj
    swappingHarkons = False
    ;;Debug.Trace("Begin Harkon Teleport to " + teleportObject)
    ;;SelfActor.GetActorBase().SetInvulnerable(True)
    SelfActor.SetAV("Variable06", 1)
    SelfActor.EvaluatePackage()
    SelfActor.DispelAllSpells()
    ;;Debug.Trace("Attempting teleport.")
    SelfActor.DoCombatSpellApply(DLC1VQ08Bats, Self.GetActorRef())
    EndFunction
     
    Function BatTeleportAndSwapTo(ObjectReference obj)
    if (!initialized)
    initialized = True
    Initialize()
    EndIf
    teleportObject = obj
    swappingHarkons = True
    if (SelfActor == HarkonBattleMagicFormActor)
    newHarkon = HarkonBattleMeleeFormActor
    Else
    newHarkon = HarkonBattleMagicFormActor
    EndIf
    ;;Debug.Trace("Begin Harkon Swap Teleport to " + teleportObject)
    ;;SelfActor.GetActorBase().SetInvulnerable(True)
    HarkonBattleMagicFormActor.SetAV("Variable06", 1)
    HarkonBattleMagicFormActor.EvaluatePackage()
    HarkonBattleMagicFormActor.DispelAllSpells()
    ;HarkonBattleMagicFormActor.SetSubGraphFloatVariable("fdampRate", 0.20) ;Animation fadeout.
    ;HarkonBattleMagicFormActor.SetSubGraphFloatVariable("ftoggleBlend", 1.3)
    HarkonBattleMeleeFormActor.SetAV("Variable06", 1)
    HarkonBattleMeleeFormActor.EvaluatePackage()
    HarkonBattleMeleeFormActor.DispelAllSpells()
    ;HarkonBattleMeleeFormActor.SetSubGraphFloatVariable("fdampRate", 0.20) ;Animation fadeout.
    ;HarkonBattleMeleeFormActor.SetSubGraphFloatVariable("ftoggleBlend", 1.3)
    SelfActor.DoCombatSpellApply(DLC1VQ08SwapBats, newHarkon)
    EndFunction
     
    Function BatTeleportToEndMagic(ObjectReference obj)
    if (!initialized)
    initialized = True
    Initialize()
    EndIf
    if (SelfActor == HarkonBattleMagicFormActor)
    BatTeleportTo(obj)
    Else
    BatTeleportAndSwapTo(obj)
    EndIf
    EndFunction
     
    Function BatTeleportToEndMelee(ObjectReference obj)
    if (!initialized)
    initialized = True
    Initialize()
    EndIf
    if (SelfActor == HarkonBattleMeleeFormActor)
    BatTeleportTo(obj)
    Else
    BatTeleportAndSwapTo(obj)
    EndIf
    EndFunction
     
    Function SwapHarkons()
    ;;Debug.Trace("Swapping Harkons!")
    if (!initialized)
    initialized = True
    Initialize()
    EndIf
    HarkonBattleMagicFormActor.StopTranslation()
    HarkonBattleMeleeFormActor.StopTranslation()
    VQ08HarkonSwapMarker.MoveTo(SelfActor)
    if (SelfActor == HarkonBattleMagicFormActor)
    HarkonBattleMagicFormActor.MoveTo(VQ08HarkonWarpMarker1)
    HarkonBattleMeleeFormActor.MoveTo(VQ08HarkonSwapMarker)
    TransferAVs(HarkonBattleMagicFormActor, HarkonBattleMeleeFormActor)
    Self.ForceRefTo(HarkonBattleMeleeFormActor)
    OldActor = HarkonBattleMagicFormActor
    SelfActor = HarkonBattleMeleeFormActor
    ((Self as ReferenceAlias) as DLC1dunHarkonBossBattle).SelfActor = HarkonBattleMeleeFormActor
    ;;Debug.Trace("Melee Form, Go!")
    Else
    HarkonBattleMeleeFormActor.MoveTo(VQ08HarkonWarpMarker2)
    HarkonBattleMagicFormActor.MoveTo(VQ08HarkonSwapMarker)
    TransferAVs(HarkonBattleMeleeFormActor, HarkonBattleMagicFormActor)
    Self.ForceRefTo(HarkonBattleMagicFormActor)
    OldActor = HarkonBattleMeleeFormActor
    SelfActor = HarkonBattleMagicFormActor
    ((Self as ReferenceAlias) as DLC1dunHarkonBossBattle).SelfActor = HarkonBattleMagicFormActor 
    ;;Debug.Trace("Magic Form, Go!")
    EndIf
    OldActor.StopCombat()
    SelfActor.SetSubGraphFloatVariable("fdampRate", 0.02) ;Fade in the new Harkon.
    SelfActor.SetSubGraphFloatVariable("ftoggleBlend", 0.0)
    ;;Debug.Trace("Swap complete. Self=" + Self.GetActorRef())
    SelfActor.EvaluatePackage()
    EndFunction
     
    Function TransferAVs(Actor source, Actor destination)
    ;Debug.Trace("IN:")
    ;Debug.Trace("Source: " + source + ": " + source.GetAV("Health") + ", " + source.GetAV("Magicka") + ", " + source.GetAV("Stamina") + ", " + source.GetAV("Variable06"))
    ;Debug.Trace("Destination: " + destination + ": " + destination.GetAV("Health") + ", " + destination.GetAV("Magicka") + ", " + destination.GetAV("Stamina") + ", " + destination.GetAV("Variable06"))
     
    if (destination.GetAV("Health") > source.GetAV("Health"))
    destination.DamageAV("Health", (-1 * (source.GetAV("Health") - destination.GetAV("Health"))))
    Else
    destination.RestoreAV("Health", (-1 * (source.GetAV("Health") - destination.GetAV("Health"))))
    EndIf
    ;Debug.Trace("Outgoing Health: " + source.GetAV("Health") + " == " + destination.GetAV("Health"))
    if (destination.GetAV("Magicka") > source.GetAV("Magicka"))
    destination.DamageAV("Magicka", (-1 * (source.GetAV("Magicka") - destination.GetAV("Magicka"))))
    Else
    destination.RestoreAV("Magicka", (-1 * (source.GetAV("Magicka") - destination.GetAV("Magicka"))))
    EndIf
    if (destination.GetAV("Stamina") > source.GetAV("Stamina"))
    destination.DamageAV("Stamina", (-1 * (source.GetAV("Stamina") - destination.GetAV("Stamina"))))
    Else
    destination.RestoreAV("Stamina", (-1 * (source.GetAV("Stamina") - destination.GetAV("Stamina"))))
    EndIf
     
    ;Debug.Trace("OUT:")
    ;Debug.Trace("Source: " + source + ": " + source.GetAV("Health") + ", " + source.GetAV("Magicka") + ", " + source.GetAV("Stamina") + ", " + source.GetAV("Variable06"))
    ;Debug.Trace("Destination: " + destination + ": " + destination.GetAV("Health") + ", " + destination.GetAV("Magicka") + ", " + destination.GetAV("Stamina") + ", " + destination.GetAV("Variable06"))
     
    destination.SetAV("Variable06", 1) ;*Always* 1 at this point, since we're in the middle of a teleport.
    destination.SetAV("Variable07", source.GetAV("Variable07")) 
    destination.SetAV("Variable10", source.GetAV("Variable10"))
    EndFunction
     
    Function BatsAllDone()
    if (swappingHarkons)
    SwapHarkons()
    EndIf
    if (SelfActor == HarkonBattleMagicFormActor)
    (SelfActor as DLC1HarkonCombatMagicLevelingScript).ReequipDrainSpell()
    EndIf
    SelfActor.SetAV("Variable06", 1)
    ((Self as ReferenceAlias) as DLC1dunHarkonBossBattle).HarkonReforms()
    EndFunction
    

    And this is the vanilla combat script inside the quest responsible for everything:

    ScriptName DLC1dunHarkonBossBattle extends ReferenceAlias
    {The main boss battle script for Harkon at the end of VQ08.}
     
    ;Harkon Actor Variables:
    ; - Variable06 is used as a package condition to control his combat state.
    ;      1 = Stay in Place (Wait for Teleport, Dying, Toggle, etc.)
    ;      2 = Shrine Event spellcasting
    ;      3-5 = Mistform Patrols
     
    ;Float that controls the state of the battle. Used to be an int, but I needed more granularity.
    ; 0-1 = Normal Combat
    ;     0 = Default Magic Combat. We stay in this for 60s or until a Shrine Event triggers. Teleports are to random positions.
    ;     0.25 = Default Melee Combat. We stay in this for 30s or until a Shrine Event triggers. Teleports are to nearby positions based on distance checks.
    ;     0.5 = Quick-Flip Combat. We may swap between magic and melee on each teleport. Teleports are determined by the form chosen.
    ; 1-3 = Starting Shrine Event 1-3
    ; 4 = In Shrine Event
    ; 5 = In Mistform
    float property HarkonBossBattleState = 0.0 Auto Hidden
     
    ;VQ08 Quest this is an alias on.
    Quest property DLC1VQ08 Auto
    ReferenceAlias property HarkonBattleRealHarkon Auto ;Alias for the questline's Harkon.
    ReferenceAlias property HarkonBattleMeleeForm Auto ;Melee Form Harkon for this battle.
    ReferenceAlias property HarkonBattleMagicForm Auto ;Magic Form Harkon for this battle.
    Actor property SelfActor Auto Hidden
    Actor property HarkonBattleRealHarkonActor Auto Hidden
    Actor property HarkonBattleMeleeFormActor Auto Hidden
    Actor property HarkonBattleMagicFormActor Auto Hidden
     
    ;Whether the script has run its initialization (occurs on combat start).
    bool scriptVariablesInitialized
    bool initialized
     
    ;Unique spells manipulated by this script.
    Spell property DLC1dunHarkonConjureGargoyleLeftHand Auto
    Spell property DLC1HarkonDrain02Alt Auto
    Spell property DLC1HarkonMistform Auto
    Spell property DLC1dunHarkonInvulnerabilityShield Auto
    Spell property DLC1AbHarkonFloatBodyFX Auto
    bool SummonedInitialGargoyle ;Once Harkon summons a gargoyle or a shrine event triggers, we remove the spell.
     
    ;MAGIC/MELEE FORMS
    ReferenceAlias property HarkonBattleHoldPositionMarker Auto ;Where Magic Form Harkon is trying to get to. Effectively keeps him from running away all the time.
    ObjectReference property HarkonBattleHoldPositionMarkerObj Auto Hidden
    float TimeOfLastFormSwap = 0.0
    float MaxTimeInMagicForm = 60.0
    float MaxTimeInMeleeForm = 30.0
     
    ;SHRINE EVENT
    ObjectReference property VQ08ShrineEventMarker Auto ;Location Harkon teleports to (atop shrine collision)
    ObjectReference property VQ08ShrineEventCollision Auto ;Collision to enable when Harkon is on the shrine.
    ObjectReference property VQ08EnemyTrigger1 Auto ;Traplinkers that hold the enemies to be activated.
    ObjectReference property VQ08EnemyTrigger2 Auto
    ObjectReference property VQ08EnemyTrigger3 Auto
    ObjectReference NextEnemyTrigger
    float ShrineEventTimestamp ;When the last Shrine Event triggered.
    float MinTimeBetweenShrineEvents = 8.0 ;Restricts when Harkon will next use a Shrine Event.
    float ShrineThreshold01 = 0.7 ;Health Thresholds that trigger the shrine events.
    float ShrineThreshold02 = 0.4
    float ShrineThreshold03 = 0.2
    bool ShrineEventActive = False ;Is a Shrine Event active?
    bool property ShieldDestroyed = False Auto Hidden ;Property checked by the shield magic effect to determine whether the shield blows up or gets dismissed quietly.
    int property LastShrineEvent = 0 Auto Hidden ;What Shrine Event did we do most recently?
    float ShrineEventFailsafeTimer = 0.0 ;Timer that kicks Harkon out of his Shrine event.
     
    Weapon property DLC1AurielsBow Auto ;Bow and Arrows to look for.
    Explosion property DLC1AurielsBowExp01 Auto
    Explosion property ExplosionIllusionDark01 Auto
    Ammo property DLC1ElvenArrowBlessed Auto
    Ammo property DLC1ElvenArrowBlood Auto
    bool property PlayerHasAurielsBow Auto Hidden
     
    Scene property DLC1VQ08HarkonBattleScene Auto ;Scene telling the player to use the bow.
    float property ShrineEventSceneTimer = 0.0 Auto hidden ;When did we last play this scene?
     
     
    ;MISTFORM
    ObjectReference property VQ08MistformEventMarker Auto ;Marker to translate to at start, to make sure Harkon doesn't get stuck on the shrine.
    ReferenceAlias property HarkonBattleNoNameAlias Auto ;Alias with an override empty name, to avoid awkward activation text.
    float MistformTimer ;Timer for when we started mistform.
    float MaxTimeInMistform = 20.0 ;Max time we'll stay in mistform.
     
     
    ;HARKON DEATH SCENE
    Spell property DLC1FXCastVampireBleedSpell Auto
    Armor property DLC1VampireSkeletonFXArmor Auto
    ObjectReference property DeadHarkonWarpMarker Auto
    bool inDeathThroesTeleport = False ;Are we in the final 'death throes' teleport?
    bool doneDeathThroesTeleport = False ;Have we finished the final 'death throes' teleport?
    bool doneFinalDeath = False ;Have we begun executing Harkon's OnDying block?
    int DeathThroesTeleportsLeft = 2
    Activator property DLC1dunHarkonAshPile Auto
    ObjectReference property DLC1dunHarkonDeathFXAct Auto
    Sound property AmbRumbleShake Auto
    EffectShader property DLC1SunFireImpactFXShader Auto
    Spell property DLC1dunHarkonDeathSpell Auto
    ObjectReference property VQ08ExplosionSourceMarker Auto
    Explosion property DLC1VampiresBaneExplosion Auto
    ObjectReference property VQ08HarkonGroundMarker Auto
    Explosion property HarkonDeathExplosion Auto
     
    ;TELEPORTING
    ObjectReference[] property HarkonTeleportPoints Auto ;Array of possible teleport locations.
    int MultiTeleportCount = 0 ;Number of times to teleport in sequence.
    bool TeleportInProgress ;Is a teleport in progress? If so, prevent anything else from teleporting him.
    float MagicFormHoldPositionTimestamp = -1.0
    float HealthPercentAtLastTeleport = 1.0
    float MagicFormHealthPercentLossAllowed = 0.20
    float MeleeFormHealthPercentLossAllowed = 0.30
    float TimeOfLastTeleport = 0.0
    float MaxTimeBetweenTeleports = 30.0
    bool shouldTeleportCornered = False
    Static property HarkonTeleportMarker Auto ;The unique base object for Harkon's teleport markers.
     
    ;Harkon minions.
    ObjectReference[] property HarkonMinions Auto
     
    ;Hit Timestamps
    float TimerPreviousHit01 = 0.0 ;Timestamps that record when the player hits Harkon with an attacked.
    float TimerPreviousHit02 = 0.0 ;Used to approximately detect when he's been 'cornered' so he can escape.
    float TimerPreviousHit03 = 0.0
    float TimerPreviousHit04 = 0.0
    float TimerPreviousHit05 = 0.0
    float TimerPreviousHit06 = 0.0
    float TimerOfRecord = 0.0 ;Timer used to determine when Harkon was cornered.
     
    ;Harkon's Cape
    Armor property DLC1VampireLordCape Auto
     
    ;Music for the boss battle. Needed to prevent the audio from cutting in and out of combat constantly.
    MusicType property MUSCombatBoss Auto
     
    ;Vampire and Werewolf beast forms.
    Race property VampireBeastRace Auto
    Race property WerewolfBeastRace Auto
     
     
    ;--------------------------------------------------------------
    ;Main Battle Loops: OnHit and OnUpdate
    ;---------------------------------------
     
    Function InitializeHarkonBattle() 
    if (!scriptVariablesInitialized)
    InitializeScriptVariables()
    EndIf
    EndFunction
     
    Event OnCombatStateChanged(Actor akTarget, int aeCombatState)
    if (!initialized)
    initialized = True
    if (!scriptVariablesInitialized)
    InitializeScriptVariables()
    EndIf
    float currentTime = Utility.GetCurrentRealTime()
    TimeOfLastFormSwap = currentTime
    TimeOfLastTeleport = currentTime
    PlayerHasAurielsBow = (Game.GetPlayer().GetItemCount(DLC1AurielsBow) > 0)
    ;Debug.Trace("Start the music!")
    MUSCombatBoss.Add()
    GoToState("Ready")
    OnUpdate()
    EndIf
    EndEvent
     
    Function InitializeScriptVariables()
    float currentTime = Utility.GetCurrentRealTime()
    TimeOfLastFormSwap = currentTime
    TimeOfLastTeleport = currentTime
    SelfActor = Self.GetActorRef()
    HarkonBattleRealHarkonActor = HarkonBattleRealHarkon.GetActorRef()
    HarkonBattleMeleeFormActor = HarkonBattleMeleeForm.GetActorRef()
    HarkonBattleMagicFormActor = HarkonBattleMagicForm.GetActorRef()
    HarkonBattleMeleeFormActor.GetActorBase().SetEssential(False)
    HarkonBattleMagicFormActor.GetActorBase().SetEssential(False)
    HarkonBattleMeleeFormActor.StartDeferredKill()
    HarkonBattleMagicFormActor.StartDeferredKill()
    HarkonBattleHoldPositionMarkerObj = HarkonBattleHoldPositionMarker.GetReference()
    scriptVariablesInitialized = True
    EndFunction
     
    ;Every second, we check to see if we need to update Harkon's state.
    Function OnUpdate()
    If (!inDeathThroesTeleport)
    ProcessOnUpdateOROnHitEvent(None, None)
    RegisterForSingleUpdate(1)
    EndIf
    EndFunction
     
    Auto State Ready
    ;On hit, check to see which state we're in and respond accordingly.
    Event OnHit(ObjectReference aggressor, Form weap, Projectile proj, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
    ProcessOnUpdateOROnHitEvent(aggressor, weap)
    EndEvent
     
    ;We have to handle both types of events in this single function to prevent interleaving errors from asynchronus events.
    Function ProcessOnUpdateOROnHitEvent(ObjectReference aggressor, Form weap)
    GoToState("Busy")
    ;Debug.Trace("HARKON:  Harkon Processing----------")
    ;Debug.Trace("HARKON:  PROCESSING: " + SelfActor + ", Health: " + SelfActor.GetAV("Health"))
    int activeMinionsCount = CountActiveMinions()
    float healthPercentage = SelfActor.GetAVPercentage("Health")
    float currentTime = Utility.GetCurrentRealTime()
     
    ;Are we dead or dying? If so, don't do anything.
    If (!initialized)
    ;Debug.Trace("HARKON:  Not Initialized Yet")
    ;Do nothing!
    ElseIf (HarkonBossBattleState == 4 && inDeathThroesTeleport)
    ;If we're in the process of dying, but have wound up on the Shrine instead, bail out.
    EndShrineEvent(None, None)
    ElseIf (inDeathThroesTeleport)
    ;Debug.Trace("HARKON:  In Death Throes")
    ;Do nothing!
    ElseIf (SelfActor.GetAV("Health") <= 0)
    ;Debug.Trace("HARKON:  Triggering Death Throes")
    ;Start the Death Throes process. This is the only way we can catch the actor's 'death' because Deferred Kill is on.
    BeginDeathThroes()
    ElseIf (HarkonBossBattleState < 1)
     
    If (!SelfActor.IsInCombat())
    SelfActor.StartCombat(Game.GetPlayer())
    EndIf
     
    ;If we've passed one of the shrine health thresholds, that's our top priority.
    If (healthPercentage < ShrineThreshold01 && !ShrineEventActive && LastShrineEvent == 0)
    ;Debug.Trace("HARKON:  Process SetupShrineEvent1")
    SetupShrineEvent(1)
    ElseIf (healthPercentage < ShrineThreshold02 && !ShrineEventActive && LastShrineEvent == 1 && (currentTime - ShrineEventTimestamp) > MinTimeBetweenShrineEvents)
    ;Debug.Trace("HARKON:  Process SetupShrineEvent2")
    SetupShrineEvent(2)
    ElseIf (healthPercentage < ShrineThreshold03 && !ShrineEventActive && LastShrineEvent == 2 && (currentTime - ShrineEventTimestamp) > MinTimeBetweenShrineEvents)
    ;Debug.Trace("HARKON:  Process SetupShrineEvent3")
    SetupShrineEvent(3)
     
    ElseIf (HarkonBossBattleState == 0 && currentTime - TimeOfLastFormSwap > MaxTimeInMagicForm)
    ;Debug.Trace("HARKON:  Magic Form timer exceeded. Swapping forms.")
    TimeOfLastFormSwap = currentTime
    HarkonBossBattleState = 0.25
    TeleportHarkon()
    ElseIf (HarkonBossBattleState == 0.25 && currentTime - TimeOfLastFormSwap > MaxTimeInMeleeForm)
    ;Debug.Trace("HARKON:  Melee Form timer exceeded. Swapping forms.")
    TimeOfLastFormSwap = currentTime
    HarkonBossBattleState = 0
    TeleportHarkon()
    ElseIf (SelfActor == HarkonBattleMagicFormActor && SelfActor.GetDistance(HarkonBattleHoldPositionMarker.GetReference()) < 400 && MagicFormHoldPositionTimestamp == -1)
    ;Debug.Trace("HARKON:  Reached Hold Position marker. Setting Timestamp.")
    MagicFormHoldPositionTimestamp = currentTime
    ElseIf (SelfActor == HarkonBattleMagicFormActor && MagicFormHoldPositionTimestamp > 0 && currentTime - MagicFormHoldPositionTimestamp > 5)
    ;Debug.Trace("HARKON:  Selecting new Hold Position Marker.")
    PickNewHoldPositionTargetWithEVP()
    ElseIf (SelfActor == HarkonBattleMagicFormActor && healthPercentage < (HealthPercentAtLastTeleport - MagicFormHealthPercentLossAllowed))
    ;Debug.Trace("HARKON:  Now Teleporting: Health Threshold (Magic) met.")
    TeleportHarkon()
    ElseIf (SelfActor == HarkonBattleMeleeFormActor && healthPercentage < (HealthPercentAtLastTeleport - MeleeFormHealthPercentLossAllowed))
    ;Debug.Trace("HARKON:  Now Teleporting: Health Threshold (Melee) met.")
    TeleportHarkon()
    ElseIf (shouldTeleportCornered && currentTime - TimerOfRecord < 4)
    ;Debug.Trace("HARKON:  Waiting until full 4s are up.")
    ElseIf (shouldTeleportCornered && currentTime - TimerOfRecord >= 4)
    ;Debug.Trace("HARKON:  Now Teleporting: Player cornered Harkon.")
    TeleportHarkon()
    ElseIf (currentTime - TimeOfLastTeleport > MaxTimeBetweenTeleports)
    ;Debug.Trace("HARKON:  Now Teleporting: Max Time Between Teleports exceeded.")
    TeleportHarkon()
    ;Is Harkon in normal combat? If so, track hits so we can catch when he becomes 'stuck'.
    ElseIf (aggressor == Game.GetPlayer())
    ;Debug.Trace("HARKON:  Registered normal hit.")
    TimerPreviousHit06 = TimerPreviousHit05
    TimerPreviousHit05 = TimerPreviousHit04
    TimerPreviousHit04 = TimerPreviousHit03
    TimerPreviousHit03 = TimerPreviousHit02
    TimerPreviousHit02 = TimerPreviousHit01
    TimerPreviousHit01 = currentTime
     
    if (SelfActor == HarkonBattleMagicFormActor && TimerPreviousHit01 - TimerPreviousHit04 < 6)
    shouldTeleportCornered = True
    TimerOfRecord = TimerPreviousHit04
    ElseIf (SelfActor == HarkonBattleMeleeFormActor && TimerPreviousHit01 - TimerPreviousHit06 < 8)
    shouldTeleportCornered = True
    TimerOfRecord = TimerPreviousHit06
    EndIf
    EndIf
     
    ElseIf (HarkonBossBattleState == 4)
    If (inDeathThroesTeleport)
    EndShrineEvent(None, None)
    ElseIf (activeMinionsCount == 0 && ShrineEventFailsafeTimer == 0)
    ;Debug.Trace("HARKON:  Shrine Update: Setting Failsafe Timer")
    ShrineEventFailsafeTimer = currentTime
    ElseIf (activeMinionsCount > 0 && ShrineEventFailsafeTimer > 0)
    ;Debug.Trace("HARKON:  Shrine Update: Jumped the gun. Resetting Shrine Event Failsafe Timer")
    ShrineEventFailsafeTimer = 0
    ElseIf (activeMinionsCount == 0 && currentTime - ShrineEventFailsafeTimer >= 12)
    ;Debug.Trace("HARKON:  Shrine Update: Failsafe Triggered")
    EndShrineEvent(None, None)
    ElseIf (ShrineEventSceneTimer == 0)
    ;Debug.Trace("HARKON:  First time only, delay the scene.")
    ShrineEventSceneTimer = currentTime
    ElseIf (currentTime - ShrineEventSceneTimer > 15 && !DLC1VQ08HarkonBattleScene.IsPlaying() && PlayerHasAurielsBow)
    Race playerRace = Game.GetPlayer().GetRace()
    if ((VampireBeastRace == None || VampireBeastRace != playerRace) && (WerewolfBeastRace == None || WerewolfBeastRace != playerRace))
    if (SelfActor.GetAV("Variable09") == 0)
    SelfActor.SetAV("Variable09", 1)
    EndIf
    ShrineEventSceneTimer = currentTime
    DLC1VQ08HarkonBattleScene.Start()
    EndIf
    EndIf
     
    ElseIf (HarkonBossBattleState == 5)
    ;If we're in Mistform, bail out if all of our minions are dead, or if time elapses.
    ;Debug.Trace("HARKON:  Mistform Time: " + currentTime + ", " + MistformTimer)
    If (activeMinionsCount == 0)
    ;Debug.Trace("HARKON:  Mistform Update: All minions dead.")
    EndMistform()
    ElseIf (currentTime > MistformTimer)
    ;Debug.Trace("HARKON:  Mistform Update: Ending mistform by timer. " + Utility.GetCurrentRealTime() + " > " + MistformTimer)
    EndMistform()
    EndIf
    EndIf
     
    ;Debug.Trace("HARKON:  ----------------------------")
    GoToState("Ready")
    EndFunction
    EndState
     
    State Busy
    Event OnHit(ObjectReference aggressor, Form weap, Projectile proj, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
    ;Do Nothing
    EndEvent 
    Function ProcessOnUpdateOROnHitEvent(ObjectReference aggressor, Form weap)
    ;Do Nothing
    EndFunction
    EndState
     
    Event OnHit(ObjectReference aggressor, Form weap, Projectile proj, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
    ;Do nothing.
    EndEvent
    Function ProcessOnUpdateOROnHitEvent(ObjectReference aggressor, Form weap)
    ;Do Nothing
    EndFunction
     
    Function ProcessShadowShieldHit(ObjectReference aggressor, Form weap)
    ;This should all be handled by DLC1dunHarkonShadowShield now.
    ;
    ;If (HarkonBossBattleState == 4 && weap == DLC1AurielsBow)
    ; EndShrineEvent(aggressor as Actor, weap as Weapon)
    ;ElseIf (HarkonBossBattleState == 4 && weap != None && !DLC1VQ08HarkonBattleScene.IsPlaying() && Utility.GetCurrentRealTime() - ShrineEventSceneTimer > 5)
    ; ShrineEventSceneTimer = Utility.GetCurrentRealTime()
    ; DLC1VQ08HarkonBattleScene.Start()
    ;EndIf
    EndFunction
     
     
    ;Count how many 'active' enemies are left other than Harkon himself.
    int Function CountActiveMinions()
    int count = 0
    int i = 0
    Actor currentMinion
    While (i < HarkonMinions.Length)
    currentMinion = HarkonMinions[i] as Actor
    if (currentMinion.GetAV("Aggression") > 0 && !currentMinion.IsCommandedActor() && !currentMinion.IsDead())
    count = count + 1
    EndIf
    i = i + 1
    EndWhile
    ;Debug.Trace("HARKON:  Active Minions = " + count)
    return count
    EndFunction
     
    Function RecordSummonedGargoyle()
    if (!SummonedInitialGargoyle)
    ;Debug.Trace("HARKON:  Gargoyle summoned. Removing the spell.")
    SummonedInitialGargoyle = True
    (SelfActor as DLC1HarkonCombatMagicLevelingScript).ReequipDrainSpell()
    EndIf
    SelfActor.RemoveSpell(DLC1dunHarkonConjureGargoyleLeftHand)
    EndFunction
     
    Function ResetHitClock()
    TimerPreviousHit01 = 0
    TimerPreviousHit02 = 0
    TimerPreviousHit03 = 0
    TimerPreviousHit04 = 0
    TimerPreviousHit05 = 0
    TimerPreviousHit06 = 0
    TimerOfRecord = 0
    EndFunction
     
     
    ;--------------------------------------------------------------
    ;Melee and Magic Forms
    ;---------------------
     
    ;Harkon's Magic Form moves between Hold Position targets to allow him to move while still forcing him to stop periodically.
    Function PickNewHoldPositionTargetWithEVP()
    if (HarkonBossBattleState < 1 && !inDeathThroesTeleport)
    MagicFormHoldPositionTimestamp = -1
    HarkonBattleHoldPositionMarker.ForceRefTo(PickTeleportMarkerRandomly())
    if (SelfActor.GetAV("Variable06") <= 1)
    SelfActor.SetAV("Variable06", 1)
    SelfActor.EvaluatePackage()
    EndIf
    if (SelfActor.GetAV("Variable06") <= 1)
    SelfActor.SetAV("Variable06", 0)
    SelfActor.EvaluatePackage()
    EndIf
    ;Debug.Trace("HARKON:  PickNewHoldPositionTarget w/ EVPs resets Variable06 to 0.")
    EndIf
    EndFunction
     
    Function PickNewHoldPositionTargetWithoutEVP()
    MagicFormHoldPositionTimestamp = -1
    HarkonBattleHoldPositionMarker.ForceRefTo(PickTeleportMarkerRandomly())
    ;Debug.Trace("HARKON:  PickNewHoldPositionTarget w/o EVPs picked a new target")
    EndFunction
     
     
    ;--------------------------------------------------------------
    ;Teleport via Bats
    ;-----------------
    ;TRIGGERS: As Needed.
     
    Function TeleportHarkon()
    if (!TeleportInProgress && HarkonBossBattleState != 4)
    TeleportInProgress = True
    SelfActor.DispelAllSpells()
    ;Debug.Trace("HARKON:  Now Teleporting. State: " + HarkonBossBattleState)
    if (inDeathThroesTeleport)
    ;Support legacy saves that had a higher number...
    if (DeathThroesTeleportsLeft > 2)
    DeathThroesTeleportsLeft = 2
    EndIf
    if (DeathThroesTeleportsLeft == 2)
    BatTeleportToEndSameForm(HarkonTeleportPoints[11])
    ElseIf (DeathThroesTeleportsLeft == 1)
    BatTeleportToEndSameForm(HarkonTeleportPoints[1])
    ElseIf (DeathThroesTeleportsLeft == 0)
    BatTeleportToEndSameForm(HarkonTeleportPoints[0])
    EndIf
    ElseIf (HarkonBossBattleState == 0)
    ;Standard magic teleport.
    BatTeleportToEndMagic(PickTeleportMarkerRandomly())
    ElseIf (HarkonBossBattleState == 0.25)
    ;Standard melee teleport.
    BatTeleportToEndMelee(PickTeleportMarkerNearby())
    ElseIf (HarkonBossBattleState == 0.5)
    int roll = Utility.RandomInt(0, 1)
    if (roll == 0)
    ;Debug.Trace("HARKON:  Magic!")
    BatTeleportToEndMagic(PickTeleportMarkerRandomly())
    Else
    ;Debug.Trace("HARKON:  Melee!")
    BatTeleportToEndMelee(PickTeleportMarkerNearby())
    EndIf
    Else
    ;Debug.Trace("HARKON:  TeleportHarkon() called in invalid state: " + HarkonBossBattleState)
    EndIf
    EndIf
    EndFunction
     
    ObjectReference Function PickTeleportMarkerRandomly()
    int point = Utility.RandomInt(0, HarkonTeleportPoints.Length - 1)
    ;Debug.Trace("HARKON:  Pick Randomly: " + point + ": " + HarkonTeleportPoints[point])
    return HarkonTeleportPoints[point]
    EndFunction
     
    ObjectReference Function PickTeleportMarkerNearby()
    ObjectReference closestMarker = Game.FindClosestReferenceOfTypeFromRef(HarkonTeleportMarker, Game.GetPlayer(), 3000)
    if (closestMarker == None)
    closestMarker = PickTeleportMarkerRandomly()
    EndIf
     
    ;Identify the closest teleport point, offset from it +/-2, and go there.
    int closestPoint = 0
    int i = 0
    While (i < HarkonTeleportPoints.Length)
    if (HarkonTeleportPoints[i] == closestMarker)
    closestPoint = i
    i = HarkonTeleportPoints.Length
    EndIf
    i = i + 1
    EndWhile
    int offset = Utility.RandomInt(0, 1)
    if (offset == 0)
    offset = -1
    EndIf
    int targetPoint = closestPoint + offset
    if (targetPoint >= HarkonTeleportPoints.Length)
    targetPoint = 0
    ElseIf (targetPoint < 0)
    targetPoint = HarkonTeleportPoints.Length - 1
    EndIf
    return HarkonTeleportPoints[targetPoint]
    EndFunction
     
    Function BatTeleportToEndSameForm(ObjectReference target)
    if (SelfActor == HarkonBattleMagicFormActor)
    BatTeleportToEndMagic(target)
    Else
    BatTeleportToEndMelee(target)
    EndIf
    EndFunction
     
    Function BatTeleportToEndSwapForm(ObjectReference target)
    if (SelfActor == HarkonBattleMagicFormActor)
    BatTeleportToEndMelee(target)
    Else
    BatTeleportToEndMagic(target)
    EndIf
    EndFunction
     
    Function BatTeleportToEndMagic(ObjectReference target)
    ;Debug.Trace("HARKON:  BatTeleportToEndMagic called.")
    ;Debug.Trace("HARKON:  Updating health thresholds.")
    HealthPercentAtLastTeleport = SelfActor.GetAVPercentage("Health")
    TimeOfLastTeleport = Utility.GetCurrentRealTime()
    PickNewHoldPositionTargetWithoutEVP()
    TimerOfRecord = 0
    shouldTeleportCornered = False
    ((Self as ReferenceAlias) as DLC1dunHarkonBatTeleport).BatTeleportToEndMagic(target)
    EndFunction
     
    Function BatTeleportToEndMelee(ObjectReference target)
    ;Debug.Trace("HARKON:  BatTeleportToEndMelee called.")
    ;Debug.Trace("HARKON:  Updating health thresholds.")
    HealthPercentAtLastTeleport = SelfActor.GetAVPercentage("Health")
    TimeOfLastTeleport = Utility.GetCurrentRealTime()
    TimerOfRecord = 0
    shouldTeleportCornered = False
    ((Self as ReferenceAlias) as DLC1dunHarkonBatTeleport).BatTeleportToEndMelee(target)
    EndFunction
     
    Function HarkonReforms()
    ;Harkon is reforming from bat form. Determine what, if anything, we want to do in response.
    ;Debug.Trace("HARKON:  Harkon Reformed.")
    HarkonBattleMagicFormActor.GetActorBase().SetInvulnerable(False)
    HarkonBattleMeleeFormActor.GetActorBase().SetInvulnerable(False)
     
    ;Make sure we don't stay in the teleport package.
    if (HarkonBossBattleState != 4 && !inDeathThroesTeleport)
    SelfActor.SetAV("Variable06", 0)
    EndIf
     
    ;Allow teleports going forward.
    TeleportInProgress = False
    ResetHitClock()
     
    If (HarkonBossBattleState == 1 || HarkonBossBattleState == 2 || HarkonBossBattleState == 3)
    ;Debug.Trace("HARKON:  Harkon Starts Shrine")
    StartShrineEvent()
    ElseIf (inDeathThroesTeleport)
    if (SelfActor == HarkonBattleMagicFormActor)
    ;Debug.Trace("HARKON:  Moving Melee Harkon to platform.")
    HarkonBattleMeleeFormActor.MoveTo(DeadHarkonWarpMarker)
    Else
    ;Debug.Trace("HARKON:  Moving Magic Harkon to platform.")
    HarkonBattleMagicFormActor.MoveTo(DeadHarkonWarpMarker)
    EndIf
    if (SelfActor.GetAV("Variable10") <= 0)
    SelfActor.SetAV("Variable10", 1)
    Else
    SelfActor.SetAV("Variable10", 0)
    EndIf
    if (DeathThroesTeleportsLeft > 0)
    DeathThroesTeleportsLeft = DeathThroesTeleportsLeft - 1
    SelfActor.SetAV("Variable06", 1)
    SelfActor.EvaluatePackage()
    TeleportHarkon()
    Else
    ;Debug.Trace("HARKON:  Harkon Reformed. Kill him.")
    doneDeathThroesTeleport = True
    SelfActor.SetAV("Variable06", 1)
    SelfActor.EvaluatePackage()
    EndDeathThroes()
    EndIf
    ElseIf (MultiTeleportCount > 0)
    MultiTeleportCount = MultiTeleportCount - 1
    TeleportHarkon()
    Else
    SelfActor.StartCombat(Game.GetPlayer())
    EndIf
     
    SelfActor.EvaluatePackage()
    EndFunction
     
     
    ;--------------------------------------------------------------
    ;Shrine Events
    ;---------------
    ;TRIGGERS: Health Thresholds.
     
    ;Trigger enemies and warp Harkon to the Shrine.
    Function SetupShrineEvent(int eventNum)
    If (TeleportInProgress)
    Return
    EndIf
    SelfActor.DispelAllSpells()
    TeleportInProgress = True
    ShrineEventActive = True
    if (eventNum == 1)
    NextEnemyTrigger = VQ08EnemyTrigger1
    ;Strip the Summon Gargoyle spell, if it hasn't been used already.
    RecordSummonedGargoyle()
    ElseIf (eventNum == 2)
    NextEnemyTrigger = VQ08EnemyTrigger2
    Else
    NextEnemyTrigger = VQ08EnemyTrigger3
    EndIf
    HarkonBossBattleState = eventNum
    LastShrineEvent = eventNum
    VQ08ShrineEventCollision.Enable()
    BatTeleportToEndMagic(VQ08ShrineEventMarker)
    EndFunction
     
    ;Activate Harkon's shield spell.
    Function StartShrineEvent()
    ;Update Harkon's AI so he stays put and casts his invulnerability shield spell.
    if (SelfActor.GetAV("Health") < 0)
    if (inDeathThroesTeleport)
    HarkonBossBattleState = 0
    TeleportHarkon()
    Else
    BeginDeathThroes()
    EndIf
    Return
    EndIf
    SelfActor.EquipSpell(DLC1dunHarkonInvulnerabilityShield, 1)
    SelfActor.SetAV("Variable06", 2)
    SelfActor.EvaluatePackage()
    NextEnemyTrigger.Activate(SelfActor)
    if (LastShrineEvent > 1)
    ShrineEventSceneTimer = Utility.GetCurrentRealTime()
    EndIf
    HarkonBossBattleState = 4
    EndFunction
     
    ;Cancel shield spell and complete shrine event.
    Function EndShrineEvent(Actor aggressorIfAny, Weapon weaponIfAny)
    if (HarkonBossBattleState == 4)
    ;Clean up the Shrine event.
    ;Debug.Trace("HARKON:  Shrine Event is ending. Clean up.")
    float currentTime = Utility.GetCurrentRealTime()
    TimeOfLastFormSwap = currentTime
    HarkonBossBattleState = 0
    if (weaponIfAny == DLC1AurielsBow)
    ShieldDestroyed = True
    SelfActor.RampRumble(0.75, 2, 1600)
    Game.ShakeCamera(SelfActor, 0.75, 2)
    Else
    ShieldDestroyed = False
    EndIf
    SelfActor.SetAV("Variable06", 1)
    SelfActor.EvaluatePackage()
    SelfActor.InterruptCast()
    SelfActor.DispelSpell(DLC1dunHarkonInvulnerabilityShield)
    HarkonBattleMagicFormActor.GetActorBase().SetInvulnerable(False)
    HarkonBattleMeleeFormActor.GetActorBase().SetInvulnerable(False)
     
    if (weaponIfAny == DLC1AurielsBow)
    if (AggressorIfAny.IsEquipped(DLC1ElvenArrowBlessed))
    ;Debug.Trace("HARKON:  Sunhallowed Arrow: Big explosion! Big damage!")
    ;SelfActor.PlaceAtMe(DLC1AurielsBowExp01)
    DealShrineEventHealthDamage(50)
    ElseIf (!AggressorIfAny.IsEquipped(DLC1ElvenArrowBlood))
    ;Debug.Trace("HARKON:  Normal Arrow: Explosion! Damage! Stagger!")
    ;SelfActor.PlaceAtMe(DLC1AurielsBowExp01)
    DealShrineEventHealthDamage(25)
    Else
    ;Debug.Trace("HARKON:  Blood Arrow: Small explosion. Just End It!")
    ;SelfActor.PlaceAtMe(ExplosionIllusionDark01)
    EndIf
    Else
    ;("Shrine event ended normally.")
    EndIf
    ShrineEventActive = False
    ShrineEventTimestamp = currentTime
    ShrineEventFailsafeTimer = 0
     
    ;Debug.Trace("HARKON:  Evaluating next step. " + LastShrineEvent + ", " + CountActiveMinions())
    if (inDeathThroesTeleport)
    TeleportHarkon()
    ElseIf (LastShrineEvent == 2 && CountActiveMinions() > 0)
    StartMistform()
    ElseIf ((LastShrineEvent == 1 || LastShrineEvent == 3) && CountActiveMinions() > 1)
    StartMistform()
    Else
    SelectPostShrineCombatStage()
    TeleportHarkon()
    EndIf
     
    VQ08ShrineEventCollision.Disable()
    EndIf
    EndFunction
     
    Function SelectPostShrineCombatStage()
    if (LastShrineEvent < 2)
    HarkonBossBattleState = 0
    ElseIf (LastShrineEvent == 2)
    HarkonBossBattleState = 0.25
    Else
    HarkonBossBattleState = 0.5
    EndIf
    EndFunction
     
    Function DealShrineEventHealthDamage(int damage)
    if (SelfActor.GetAV("Health") > damage)
    SelfActor.DamageAV("Health", damage)
    Else
    SelfActor.DamageAV("Health", (SelfActor.GetAV("Health") - 1))
    EndIf
    EndFunction
     
     
     
    ;--------------------------------------------------------------
    ;Mistform Events
    ;---------------
    ;TRIGGERS: After a Shrine Event, if 2+ enemies are active.
     
    Function StartMistform()
    ;Begin running a mistform patrol package.
    int patrol = Utility.RandomInt(0, 1)
    SelfActor.SetAV("Variable06", (3 + patrol))
    SelfActor.EvaluatePackage()
    ;Cast Mistform and hide Harkon's name so he can't be selected.
    DLC1HarkonMistform.Cast(SelfActor, SelfActor)
    SelfActor.TranslateToRef(VQ08MistformEventMarker, 6000.0, 0.0)
    HarkonBattleNoNameAlias.ForceRefTo(SelfActor)
    ;Set timestamp and battle state.
    MistformTimer = Utility.GetCurrentRealTime() + MaxTimeInMistform
    HarkonBossBattleState = 5
    ;Debug.Trace("HARKON:  Harkon entered mistform and started patrol " + (3+patrol) + " with timer " + MistformTimer)
    EndFunction
     
    Function EndMistform()
    TimeOfLastFormSwap = Utility.GetCurrentRealTime()
    SelectPostShrineCombatStage()
    SelfActor.DispelSpell(DLC1HarkonMistform)
    HarkonBattleNoNameAlias.Clear()
    HarkonBattleMagicFormActor.GetActorBase().SetInvulnerable(False)
    HarkonBattleMeleeFormActor.GetActorBase().SetInvulnerable(False)
    SelfActor.SetAV("Variable06", 0)
    SelfActor.StartCombat(Game.GetPlayer())
    SelfActor.EvaluatePackage()
    ;Debug.Trace("HARKON:  Harkon exited mistform.")
    EndFunction
     
     
     
    ;--------------------------------------------------------------
    ;Death Events
    ;------------
     
    Event OnDeath(Actor akKiller)
    if (!doneFinalDeath)
    Debug.Trace("ERROR: HARKON HAS DIED PREMATURELY.")
    doneDeathThroesTeleport = True
    EndDeathThroes()
    EndIf
    EndEvent
     
    Function BeginDeathThroes()
    if (!scriptVariablesInitialized)
    InitializeScriptVariables()
    EndIf
    if (!inDeathThroesTeleport)
    inDeathThroesTeleport = True
    SelfActor.BlockActivation()
    SelfActor.GetActorBase().SetInvulnerable(True)
    ;Kill any surviving minions.
    int i = 0
    While (i < HarkonMinions.Length)
    if ((HarkonMinions[i] as DLC1dunHarkonReanimatedMinions) != None)
    (HarkonMinions[i] as DLC1dunHarkonReanimatedMinions).IsSpecialDeath = True
    EndIf
    if (!HarkonMinions[i].IsDisabled())
    (HarkonMinions[i] as Actor).Kill()
    EndIf
    i = i + 1
    EndWhile
    TeleportHarkon()
    EndIf
    EndFunction
     
    Event EndDeathThroes()
    If (doneDeathThroesTeleport && !doneFinalDeath)
    ;Debug.Trace("HARKON:  End death teleport. Harkon killed by script.")
    ;Begin disintegration and vfx.
    doneFinalDeath = True
    MUSCombatBoss.Remove()
    SelfActor.SetSubGraphFloatVariable("fdampRate", 1.0) ;;speeds up fade rate (max 1 min .1
    SelfActor.SetSubGraphFloatVariable("ftoggleBlend", 0.0);;blends between two anims default 0 (0 = there 1 = gone)
    DLC1FXCastVampireBleedSpell.Cast(SelfActor, SelfActor)
    VQ08HarkonGroundMarker.MoveTo(SelfActor, 0, 0, -1, False)
    DLC1dunHarkonDeathFXAct.MoveTo(VQ08HarkonGroundMarker)
    DLC1dunHarkonDeathFXAct.PlayAnimation("PlayAnim01")
    SelfActor.BlockActivation(True)
    SelfActor.SetGhost(True)
    SelfActor.ClearExtraArrows()
    ;This is almost certainly unnecessary, but just to be safe, we'll end the deferred kill state for both actors, then make sure the current one will die.
    HarkonBattleMagicFormActor.EndDeferredKill()
    HarkonBattleMeleeFormActor.EndDeferredKill()
    ;SelfActor.Kill()
    SelfActor.SetCriticalStage(SelfActor.CritStage_DisintegrateStart)
    Utility.Wait(1)
    AmbRumbleShake.Play(VQ08HarkonGroundMarker)
    Game.GetPlayer().RampRumble(1, 2, 1600)
    Game.ShakeCamera(SelfActor, 1, 2)
    SelfActor.PlaceAtMe(HarkonDeathExplosion)
    ;Pull in the 'Real' Harkon and make him the ash pile, so the player doesn't lose any items
    ;they may have reverse-pickpocketed onto him during the questline.
    ;Wait for Harkon to collapse.
    Utility.Wait(4)
    HarkonBattleRealHarkonActor.GetActorBase().SetEssential(False)
    HarkonBattleRealHarkonActor.Kill()
    HarkonBattleRealHarkonActor.SetCriticalStage(HarkonBattleRealHarkonActor.CritStage_DisintegrateStart)
    HarkonBattleRealHarkonActor.MoveTo(VQ08HarkonGroundMarker)
    HarkonBattleRealHarkonActor.AttachAshPile(DLC1dunHarkonAshPile)
    HarkonBattleRealHarkonActor.SetCriticalStage(HarkonBattleRealHarkonActor.CritStage_DisintegrateEnd)
    HarkonBattleRealHarkonActor.Enable()
    Utility.Wait(10)
    ;Finish dissolving Harkon.
    SelfActor.SetCriticalStage(SelfActor.CritStage_DisintegrateEnd)
    ;Complete and shut down quest.
    DLC1VQ08.SetStage(200)
    EndIf
    EndEvent
    

    And here is my approach to change combat style / change actors which is done in my mod, I'm only posting the function that swamp actors, and not the whole script:
    * The obtain 'actor's AV' and store it, is done by another function not living inside this one. Here is a 'fixed' function that serves as a 'Fail Safe' inside the script, just in case something went wrong with the player's playthrough this will fire instead of the more demanding function.

    FUNCTION SwapActor()
               If ( IsMelee == True )
                    SearchGoal()
                  If ( FoundTele == True )
                       ObjectReference BatFX01 = Self.PlaceAtMe(XMDBatsFXActivator01, 1)
                       Wait(0.5)
                       Self.DisableNoWait()
                       ActorMagic.Enable()
                       ActorMagic.DamageActorValue("Health", ActorMagic.GetActorValue("Health") * 0.50)
                       ActorMagic.TranslateToRef(TeleportGoal, 16000.0, 0.0)
                       DLC1VampireBatsVFX.Play(ActorMagic, 2)
              While ( ActorReady == False )
                        If ( ActorMagic.IsDisabled() == False ) && ( ActorMagic.getDistance(TeleportGoal) <= 512 )
                             ActorReady = True
                    Else
                            ActorMagic.Enable()
                            ActorMagic.TranslateToRef(TeleportGoal, 16000.0, 0.0)
                            DLC1VampireBatsVFX.Play(ActorMagic, 2)
                   EndIf
          EndWhile
                       Wait(0.5)
                       BatFX01.TranslateToRef(teleportGoal, 500, 0.0)
                       ActorMagic.StartCombat(opponent as actor)
                       Self.RemoveFromFaction(XMD_XMVampireFaction)
                       Self.AddToFaction(XMDvampLegionFriendlyFaction)
                       Self.SetActorValue("Aggression", 0)
                       Self.MoveTo(XMDMeleeSwapHeading)
                       BatFX01.Delete()
                       BatFX01 = None
               Else
                       SearchGoal()
             EndIf
           Else
                   ObjectReference BatFX02 = Self.PlaceAtMe(XMDBatsFXActivator01, 1)
                   Wait(0.5)
                   Self.SetAlpha(0.1)
                   Self.DisableNoWait()
                   Wait(0.5)
                   BatFX02.TranslateToRef(ActorMelee, 500, 0.0)
                   ActorMelee.Enable(True)
                   DLC1VampireBatsVFX.Play(ActorMelee, 2)
                   ActorMelee.EvaluatePackage()
                   Wait(3.0)
                   Self.MoveTo(XMDMagicSwapHeadingEnd)
                   BatFX02.Disable(True)
                   BatFX02.Delete()
                   BatFX02 = None
                   XMDBloodyPaybackMasterController01.Activate(Self)
         EndIf
    ENDFUNCTION
    

    I won't post my 2 main scripts because they reach 1375 lines. Plus the way I created this entire combat scene to ensure stability and a bug free scene, I ended up with 7 scripts just for the combat scene.
    Just a friendly advice:
    Save yourself some migraines, and leave this alone.
    Trust me on this, during the 6 years of my mod's development, I've tried every single possible approach...
    This here isn't the case of a simple function or line like the 'IsCommandedActor()', or a simple adjustment that you'll change something somewhere and it will work.

     

     

    That's just f***ing great V_V

     

    I've got lines of dialogue referring to the NPC being summoned. It's the "big reward" following the big finale.... Also got permission to use the unique vampire lord models by promising there'd be a unique power to summon the NPC..... The same NPC is intended to help the player fight the final boss and I just finished setting up the scene that ends with the lord and final boss being added to opposing factions - Guess there's no need to test that fight right now.

     

    I'm not the best at manual weights, 95% of the time I use blender's boneweight copy script. Actually 100% of the time I do, but about 5% of the time I have to manually touch up stuff. But I suppose I can try my best to get the unique vamp lord model to work with a dragonpriest skeleton or something.. Sounding like the best option at least. Will have static wings and the float might look a little weird, but if I can get the weights right, might look acceptable at least.

     

     

     

    EDIT: No one knows how Mihail did it? He had an NPC mod that added skeletal vampire lords and other unique vampire lord models as NPC enemies in the wild. I have the models in an old archive. But no scripts or ESP to see how it was done, and he's also removed the mod from the nexus, so I can't get the full thing to check. Maybe it was removed because it didn't work, idk... But I do know all of his mods descriptions say he doesn't have time to reply to PMs so I don't see a point in asking him directly.

     

    EDIT2: Mihail's Grevious twilight is also listed as a vampire lord NPC that does combat with the player. It's also been removed from the nexus :wallbash:

×
×
  • Create New...