Jump to content

DOWNLOAD MODS

Are you looking for something shiny for your load order? We have many exclusive mods and resources you won't find anywhere else. Start your search now...

LEARN MODDING

Ready to try your hand at making your own mod creations? Visit the Enclave, the original ES/FO modding school, and learn the tricks of the trade from veteran modders...

JOIN THE ALLIANCE

Membership is free and registering unlocks image galleries, project hosting, live chat, unlimited downloads, & more...

Overhauling Werewolf Scripts/Quest


Vain
 Share

Recommended Posts

Werewolf Mods.
There are several, some even do what I'm trying to do.  The difference is HOW they do it.
 
Enable Papyrus Logging - add to SkyrimEditor.ini Papyrus section

bEnableLogging = 1 
bEnableTrace = 1 
bLoadDebugInformation = 1


 
Enable the use of the Dawnguard master file by the Creation Kit - add to the SkyrimEditor.ini General section

bAllowMultipleMasterLoads=1


Also add all the masters you want to be using ordered by release date in the Archive section.  This line should already exist, we are simply elaborating on what is already there.  You may need to add the DLC bsa files to the sArchiveList as well - I did.

sResourceArchiveList2=Skyrim - Shaders.bsa, Update.bsa, Dawnguard.bsa, Hearthfire.bsa, Dragonborn.bsa


 
Enable the player to leave Beast Form at will.
There's not much difference in Werewolves before and after Dawnguard.  Dawnguard makes them a little tougher and gives them perks which can further increase their survivability.  And this really wasn't all that hard, nothing like my sunscreen for Vampires mod.
Here's a table outlining the Werewolf Damage/Resist Progression in an unmodded game. 

Werewolf Damage/Resist Progression


Level___________________10   |  15  |   20   25  30  35    40  45   50   Increment
Fortify Unarmed Damage___0    |  5    |  15   25  30  35    40   50  60   *
Feed Blood______________10   |  10  |  100 100 100 100 100 100 100  N/A
Resist Damage___________N/A |  50  |  100 150 200 250 300 350 400  50
Number of Increases______1     |  2    |   3     4    5    6     7    8     9    *
Increment Increased______*     |  5    |   5     10  10   5     5    5    10   10


So if we follow the same pattern Unarmed Damage will increase by 5 for three levels, then by 10 for two levels, repeating ad finem.  Resist Damage increases by a static 50 each level and Feed Blood just stays the same.
 
So to continue Werewolf ability progression beyond level 50 we just have to create the spells
PlayerWerewolfLvl55-95AndBelowAbility (nine spells total)
PlayerWerewolfLvl99AndAboveAbility
 
And add them to the player.
How to do this?  Let's look at how the game does it already.  The Werewolf transformation is managed by a quest.  You begin this quest when you accept the gift of Lycanthropy from the Companions and it only finishes if you choose to cure yourself.  It is not in the quest log.
PlayerWerewolfChangeQuest
 
This quest uses two scripts to determine what stage of the quest will be active.
One script is a fragment.
The other script explains how the quest behavior is managed.
PlayerWerewolfChangeScript
 
Each stage in the quest corresponds to a different point in the Beast Form transition.
 
Stage 0 and 1 manage the transition
Stage 10 is normal running around in Beast Form
Stage 11 manages Werewolf Feed and effects
Stage 20 warns the player that Beast Form will wear off soon
Stage 100 triggers the revert back to your normal form
 
So all that has to be done to create a revert function is to tie a command to trigger Stage 100 of the PlayerWerewolfChangeQuest to a keybind!
 
Skyrim doesn't have any easy functionality to do this but the Skryim Script Extender does.
The SKSE adds a new script that allows the Skyrim engine to use a specific key to enter a command.  This is done via the Input script.  This wiki page also contains the different number codes used to specify which key you are using.  We will be using the Boolean Function IsKeyPressed.

You'll have to add a Property for the Boolean and for the key you're going to be using like so - 

Bool bIsHotkeyPressed
Int Property iHotkey = 33 Auto ; the F key

 

The script should look something like this - 

If bIsHotkeyPressed != Input.IsKeyPressed(iHotkey)
bIsHotkeyPressed = !bIsHotkeyPressed
   If bIsHotkeyPressed
      SetStage(100)
      return
   Else
   EndIf
EndIf

Instead we are going to use an OnKeyDown event (also from SKSE) using the (Un)RegisterForKey forms. Possible alternate?

The trouble is... how do you make this into a functioning script?

 

The way you do this is duplicate the PlayerWerewolfChangeScript and rename it to something else - Vain01WerewolfChangeScript.  But you can't just replace the original script on the quest.  The original script does more than it seems because even if you make a complete replica in all but name and replace it on the quest it breaks the transformation.  100% unplayably so.  Instead of replacing the original script, extend it instead.

Duplicate the original script only instead of extending a Quest you will extend PlayerWerewolfChangeScript.  This is how the scripting for the new Vampire Lord works in Dawnguard.  These scripts extend the original VampireQuestScript and we're using this as a model for our upgrade to the Werewolf scripts.  Doing this, scripting like we're supposed to, causes the player to revert to human form in the first update event the script calls instead of reverting only when the time is up.

 

Actually we're going to break the game.  It's the only way I can get it to work.  Our problem is that tiny little script fragment that is also on the quest.  QF_PlayerWerewolfQuest_0002BA16.  Oh how I hate this script.  You can't edit it, you can't remove it, you can't even look at the  :realmad: thing without it breaking.  Well, you can look at it, but don't touch anything.

I'm not entirely sure what it does or how it works but without it the transformation sequence breaks and while the game does not crash, the player's actor freezes and your armor is still on and a million other problems you can't even see occur.

 

To sum up - Duplicating and renaming the script will not work and breaks the tranformation.  Creating a script which extends the original script will not work and breaks the transformation.  Editing the original script is the only way this will work.  Pending some discovery of someone on this forum this is currently the easiest and only way I know how to do this.  Other werewolf mods I've seen do this same thing and probably for the same reason - they can't do it any other way.

 

So now we have the script in a format that will continue to work after we have modified it and modifying it won't break the game.  You should be okay, but this alters original game data and may effect/break your game even with no mods loaded on a clean save.  Backups are your friend.

 

The next issue is where in your script do you make the changes?

 

The Properties go at the top with the other Properties already declared. Only since all the properties in the original script have already been declared we do not want to declare them again.  The first thing you do is remove all the original Properties in the script.  If you miss any don't worry, the compiler will see them and tell you what needs removing.  Then we need to add our Properties, the Ability Spells we are adding and the Boolean and the Hotkey.

Spell Property Vain01WerewolfLvl55AndBelowAbility auto ;Vain01
Spell Property Vain01WerewolfLvl60AndBelowAbility auto ;Vain01
Spell Property Vain01WerewolfLvl65AndBelowAbility auto ;Vain01
Spell Property Vain01WerewolfLvl70AndBelowAbility auto ;Vain01
Spell Property Vain01WerewolfLvl75AndBelowAbility auto ;Vain01
Spell Property Vain01WerewolfLvl80AndBelowAbility auto ;Vain01
Spell Property Vain01WerewolfLvl85AndBelowAbility auto ;Vain01
Spell Property Vain01WerewolfLvl90AndBelowAbility auto ;Vain01
Spell Property Vain01WerewolfLvl95AndBelowAbility auto ;Vain01
Spell Property Vain01WerewolfLvl99AndOverAbility auto ;Vain01

But now that we've added the Properties for them we have to tell the game when to give them to the player.  It's easy for the Ability Spells.  The game gives the PlayerWerewolfLvl10-50AndBelow/AboveAbility to the player and all we have to do is add to this section in the script.  The game also removes these spells at the end of the transformation, so be sure to add them to that section as well.  Make sure your syntax is correct, it's largely self explanatory in the respective sections.

Adding to the player *note - these are only the lines I edited, don't forget to begin and end your if statements!

elseif (playerLevel <= 50) ;Vain01
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl50AndOverAbility, false) ;Vain01
   elseif (playerLevel <= 55) ;Vain01
        Game.GetPlayer().AddSpell(Vain01WerewolfLvl55AndBelowAbility, false) ;Vain01
    elseif (playerLevel <= 60) ;Vain01
        Game.GetPlayer().AddSpell(Vain01WerewolfLvl60AndBelowAbility, false) ;Vain01
    elseif (playerLevel <= 65) ;Vain01
        Game.GetPlayer().AddSpell(Vain01WerewolfLvl65AndBelowAbility, false) ;Vain01
    elseif (playerLevel <= 70) ;Vain01
        Game.GetPlayer().AddSpell(Vain01WerewolfLvl70AndBelowAbility, false) ;Vain01
    elseif (playerLevel <= 75) ;Vain01
        Game.GetPlayer().AddSpell(Vain01WerewolfLvl75AndBelowAbility, false) ;Vain01
    elseif (playerLevel <= 80) ;Vain01
        Game.GetPlayer().AddSpell(Vain01WerewolfLvl80AndBelowAbility, false) ;Vain01
    elseif (playerLevel <= 85) ;Vain01
        Game.GetPlayer().AddSpell(Vain01WerewolfLvl85AndBelowAbility, false) ;Vain01
    elseif (playerLevel <= 90) ;Vain01
        Game.GetPlayer().AddSpell(Vain01WerewolfLvl90AndBelowAbility, false) ;Vain01
    elseif (playerLevel <= 95) ;Vain01
        Game.GetPlayer().AddSpell(Vain01WerewolfLvl95AndBelowAbility, false) ;Vain01
    else
        Game.GetPlayer().AddSpell(Vain01WerewolfLvl99AndOverAbility, false) ;Vain01

Removing from the player

    Game.GetPlayer().RemoveSpell(Vain01WerewolfLvl55AndBelowAbility);Vain01
    Game.GetPlayer().RemoveSpell(Vain01WerewolfLvl60AndBelowAbility);Vain01
    Game.GetPlayer().RemoveSpell(Vain01WerewolfLvl65AndBelowAbility);Vain01
    Game.GetPlayer().RemoveSpell(Vain01WerewolfLvl70AndBelowAbility);Vain01
    Game.GetPlayer().RemoveSpell(Vain01WerewolfLvl75AndBelowAbility);Vain01
    Game.GetPlayer().RemoveSpell(Vain01WerewolfLvl80AndBelowAbility);Vain01
    Game.GetPlayer().RemoveSpell(Vain01WerewolfLvl85AndBelowAbility);Vain01
    Game.GetPlayer().RemoveSpell(Vain01WerewolfLvl90AndBelowAbility);Vain01 
    Game.GetPlayer().RemoveSpell(Vain01WerewolfLvl95AndBelowAbility);Vain01
    Game.GetPlayer().RemoveSpell(Vain01WerewolfLvl99AndOverAbility);Vain01

:smarty:Smarty Says: It is also very helpful when editing such a large script (or any script) to mark your modifications with your modder prefix.  Don't have one? Make one.

 

Mine is Vain01.  So on a line above and below or on the same line I edit (after the edit) I add ;Vain01.  The semi-colon lets the script know this is a comment and it will not be executed with the rest of the script.

 

 

That's the easy part.  But we only want the game to look for the hotkey input while you are in Beast Form.  The easiest way to do that is during an Update Event.  Yay for us the original script already has one!  I don't know if it matters where in the event our modification is added but I added it after the first IF statement but before the IF's governing what quest stage is being executed.

 

Now compile.  If you do not compile your script the Creation Kit will not be able to see it so you can add it to the PlayerWerewolfChangeQuest.

 

Now that we've compiled and are ready to go, open the PlayerWerewolfChangeQuest and navigate to the Scripts tab.  Add our new script to it.  The script is already on there but it has changed!  Select the script's properties and Auto-Fill them - Most of the Properties will not fill and one will fill that you don't want filled.  Compare the two scripts (original vs altered) until they match exactly and be sure to enter in the correct data for the Properties we added.  Remove the old script.  Don't forget to hit OK before closing the quest window.
 
Screenshot of the original script (ignore the unfilled Dawnguard script data - does not apply to the vanilla version of the script used here)
 
Congratulations, everything now works and you can leave Beast Form at will by holding the F key now!
 
Now I just have to create a permanent power for unlimited transformations! 

How I'm going to do it -
Ring of Hircine.  Grants unlimited transformations when equipped.
 
Script to grant you the ability to transform at will - 

Scriptname Vain01RingScript extends ObjectReference  

Spell Property Vain01RingPower auto
Quest Property CompanionsCentralQuest auto
 
Event OnEquipped(Actor akActor)
if (akActor == Game.GetPlayer() && (CompanionsCentralQuest as CompanionsHousekeepingScript).PlayerHasBeastBlood)
Game.GetPlayer().AddSpell(Vain01RingPower, false)
endif
EndEvent

Duplicated and renamed the following spells used... 

DA05HircinesRingMagicEffect - Magic Effect
WerewolfChangeRingofHircine - Spell
DA05HricinesRingEnchantment - Enchantment

Edited by Vain
Problems problems problems...
Link to comment
Share on other sites

AHAHAHA I lied!  This might be super super easy!  All I have to do to trigger the change back to human form is setstage.playerwerewolfquest 100!  Create a power that issues that command and TADA!  I think I'll release two mods - one mod for Vanilla and a patch to update it to Dawnguard.  BRETTM YOU'RE A GENIOUS AS ALWAYS.

I still need to add some debug lines to my mod that adjusts the werewolf stats past 50 to be sure it's working...  Those would show up in my Papyrus logs when they trigger, right?

Link to comment
Share on other sites

SO... here's the plan.  If the player has completed Hircine's Daedric quest they receive the uncursed Ring of Hircine or Savior's Hide.  Theoretical script will detect the completion of this quest on the character (so it won't matter if they've done it in the past) and detect if they are a werewolf and if so will grant them Blessing of Hircine.  A power that works just like the Ring of Hircine only with the length of the transformation lasting the same length of time as original Beast Form (still extendable through the eating of hearts and whatnot).  This ability will also grant a power bound to the F key that activates when you are in Beast Form that allows you to change back at will.  I'm working on making the proper forms for each of these abilities.

 

 

The Magic Effect - DA05HircinesRingMagicEffect (duplicated and renamed)

The Enchantment - DA05HircinesRingEnchantment (duplicated and renamed)

The Power - WerewolfChangeRingofHircine (duplicated and renamed)

 

Script Fragment that gives the item to you - 

Game.GetPlayer().RemoveItem(CursedRing, 1, true)
Game.GetPlayer().AddItem(NormalRing, 1, true)
AchievementsQuest.IncDaedricArtifacts()

QuestingBeastGhost.GetRef().Disable()

There does not appear to be a script (fragment or not) regarding the Savior's Hide (the quest simply removes one item and adds the next).

 

I copies and renamed the ring script - 

Scriptname Vain01HircinesBlessingScript extends ObjectReference  
 
Spell Property Vain01HircinesRingMagicEffect auto
Quest Property CompanionsCentralQuest auto
 
Event OnEquipped(Actor akActor)
if (akActor == Game.GetPlayer() && (CompanionsCentralQuest as CompanionsHousekeepingScript).PlayerHasBeastBlood)
Game.GetPlayer().AddSpell(Vain01HircinesRingMagicEffect, false)
endif
EndEvent

Replaced the script that was on the ring but the effect is still being removed on unequip...

 

Now that I have a means of delivering the buff now I need to finish the off switch...

 

By tying the SetStage.PlayerWerewolfQuest 100 to the F key while shapeshifted and done!

 

Finished leveling werewolves for non-Dawnguard up to level 100.

 

Now functioning script for both leveling and hotkeyed revert form. (revert form not waiting for hotkey, just changing back on update)

Scriptname Vain01WerewolfChangeScript extends PlayerWerewolfChangeScript

 
;Vain01
Spell Property PlayerWerewolfLvl55AndBelowAbility auto
Spell Property PlayerWerewolfLvl60AndBelowAbility auto
Spell Property PlayerWerewolfLvl65AndBelowAbility auto
Spell Property PlayerWerewolfLvl70AndBelowAbility auto
Spell Property PlayerWerewolfLvl75AndBelowAbility auto
Spell Property PlayerWerewolfLvl80AndBelowAbility auto
Spell Property PlayerWerewolfLvl85AndBelowAbility auto
Spell Property PlayerWerewolfLvl90AndBelowAbility auto
Spell Property PlayerWerewolfLvl95AndBelowAbility auto
Spell Property PlayerWerewolfLvl100AndOverAbility auto
;Vain01
 
float __durationWarningTime = -1.0
float __feedExtensionTime = -1.0
bool __tryingToShiftBack = false
bool __shiftingBack = false
bool __shuttingDown = false
bool __trackingStarted = false
 
Bool bIsHotkeyPressed ; Vain01 Script Modification
 
Int Property iHotkey = 33 Auto ; F by Default Vain01 Script Modification
 
float Function RealTimeSecondsToGameTimeDays(float realtime)
    float scaledSeconds = realtime * TimeScale.Value
    return scaledSeconds / (60 * 60 * 24)
EndFunction
 
float Function GameTimeDaysToRealTimeSeconds(float gametime)
    float gameSeconds = gametime * (60 * 60 * 24)
    return (gameSeconds / TimeScale.Value)
EndFunction
 
Function PrepShift()
;     Debug.Trace("WEREWOLF: Prepping shift...")
    Actor player = Game.GetPlayer()
 
    ; sets up the UI restrictions
    Game.SetBeastForm(True)
    Game.EnableFastTravel(False)
 
    ; set up perks/abilities
    ;  (don't need to do this anymore since it's on from gamestart)
    ; Game.GetPlayer().AddPerk(PlayerWerewolfFeed)
 
    ; screen effect
    WerewolfChange.Apply()
    WerewolfIMODSound.Play(Game.GetPlayer())
 
    ; get rid of your summons
    int count = 0
    while (count < WerewolfDispelList.GetSize())
        Spell gone = WerewolfDispelList.GetAt(count) as Spell
        if (gone != None)
            Game.GetPlayer().DispelSpell(gone)
        endif
        count += 1
    endwhile
 
 
    Game.DisablePlayerControls(abMovement = false, abFighting = false, abCamSwitch = true, abMenu = false, abActivate = false, abJournalTabs = false, aiDisablePOVType = 1)
    Game.ForceThirdPerson()
    Game.ShowFirstPersonGeometry(false)
EndFunction
 
Function InitialShift()
;     Debug.Trace("WEREWOLF: Player beginning transformation.")
 
    WerewolfWarn.Apply()
 
    if (Game.GetPlayer().IsDead())
;         Debug.Trace("WEREWOLF: Player is dead; bailing out.")
        return
    endif
 
    ; actual switch
    Game.GetPlayer().SetRace(WerewolfBeastRace)
EndFunction
 
Function StartTracking()
    if (__trackingStarted)
        return
    endif
 
    __trackingStarted = true
 
;     Debug.Trace("WEREWOLF: Race swap done; starting tracking and effects.")
    
    ; take all the player's stuff (since he/she can't use it anyway)
    ; Game.GetPlayer().RemoveAllItems(LycanStash)
    Game.GetPlayer().UnequipAll()
    Game.GetPlayer().EquipItem(WolfSkinFXArmor, False, True)
 
    ;Add Blood Effects
    ;FeedBloodVFX.Play(Game.GetPlayer())
 
    ; make everyone hate you
    Game.GetPlayer().SetAttackActorOnSight(true)
 
    ; alert anyone nearby that they should now know the player is a werewolf
    Game.SendWereWolfTransformation()
 
    Game.GetPlayer().AddToFaction(PlayerWerewolfFaction)
    Game.GetPlayer().AddToFaction(WerewolfFaction)
    int cfIndex = 0
    while (cfIndex < CrimeFactions.GetSize())
;         Debug.Trace("WEREWOLF: Setting enemy flag on " + CrimeFactions.GetAt(cfIndex))
        (CrimeFactions.GetAt(cfIndex) as Faction).SetPlayerEnemy()
        cfIndex += 1
    endwhile
 
    ; but they also don't know that it's you
    Game.SetPlayerReportCrime(false)
 
    ; recalc times
    __durationWarningTime = RealTimeSecondsToGameTimeDays(DurationWarningTimeSeconds)
    __feedExtensionTime   = RealTimeSecondsToGameTimeDays(FeedExtensionTimeSeconds)
 
    ; unequip magic
    Spell left = Game.GetPlayer().GetEquippedSpell(0)
    Spell right = Game.GetPlayer().GetEquippedSpell(1)
    Spell power = Game.GetPlayer().GetEquippedSpell(2)
    Shout voice = Game.GetPlayer().GetEquippedShout()
    if (left != None)
        Game.GetPlayer().UnequipSpell(left, 0)
    endif
    if (right != None)
        Game.GetPlayer().UnequipSpell(right, 1)
    endif
    if (power != None)
        ; some players are overly clever and sneak a power equip between casting
        ;  beast form and when we rejigger them there. this will teach them.
;         Debug.Trace("WEREWOLF: " + power + " was equipped; removing.")
        Game.GetPlayer().UnequipSpell(power, 2)
    else
;         Debug.Trace("WEREWOLF: No power equipped.")
    endif
    if (voice != None)
        ; same deal here, but for shouts
;         Debug.Trace("WEREWOLF: " + voice + " was equipped; removing.")
        Game.GetPlayer().UnequipShout(voice)
    else
;         Debug.Trace("WEREWOLF: No shout equipped.")
    endif
 
    ; but make up for it by giving you the sweet howl
    CurrentHowlWord1 = (CompanionsTrackingQuest as CompanionsHousekeepingScript).CurrentHowlWord1
    CurrentHowlWord2 = (CompanionsTrackingQuest as CompanionsHousekeepingScript).CurrentHowlWord2
    CurrentHowlWord3 = (CompanionsTrackingQuest as CompanionsHousekeepingScript).CurrentHowlWord3
    CurrentHowl = (CompanionsTrackingQuest as CompanionsHousekeepingScript).CurrentHowl
 
    Game.UnlockWord(CurrentHowlWord1)
    Game.UnlockWord(CurrentHowlWord2)
    Game.UnlockWord(CurrentHowlWord3)
    Game.GetPlayer().AddShout(CurrentHowl)
    Game.GetPlayer().EquipShout(CurrentHowl)
 
    ; and some rad claws
    int playerLevel = Game.GetPlayer().GetLevel()
    if     (playerLevel <= 10)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl10AndBelowAbility, false)
    elseif (playerLevel <= 15)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl15AndBelowAbility, false)
    elseif (playerLevel <= 20)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl20AndBelowAbility, false)
    elseif (playerLevel <= 25)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl25AndBelowAbility, false)
    elseif (playerLevel <= 30)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl30AndBelowAbility, false)
    elseif (playerLevel <= 35)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl35AndBelowAbility, false)
    elseif (playerLevel <= 40)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl40AndBelowAbility, false)
    elseif (playerLevel <= 45)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl45AndBelowAbility, false)
;Vain01
    elseif (playerLevel <= 50)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl50AndOverAbility, false)
    elseif (playerLevel <= 55)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl55AndBelowAbility, false)
    elseif (playerLevel <= 60)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl60AndBelowAbility, false)
    elseif (playerLevel <= 65)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl65AndBelowAbility, false)
    elseif (playerLevel <= 70)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl70AndBelowAbility, false)
    elseif (playerLevel <= 75)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl75AndBelowAbility, false)
    elseif (playerLevel <= 80)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl80AndBelowAbility, false)
    elseif (playerLevel <= 85)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl85AndBelowAbility, false)
    elseif (playerLevel <= 90)
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl90AndBelowAbility, false)
    else
        Game.GetPlayer().AddSpell(PlayerWerewolfLvl100AndOverAbility, false)
;Vain01
    endif
 
    ; calculate when the player turns back into a pumpkin
    float currentTime = GameDaysPassed.GetValue()
    float regressTime = currentTime + RealTimeSecondsToGameTimeDays(StandardDurationSeconds)
    PlayerWerewolfShiftBackTime.SetValue(regressTime)
;     Debug.Trace("WEREWOLF: Current day -- " + currentTime)
;     Debug.Trace("WEREWOLF: Player will turn back at day " + regressTime)
 
    ; increment stats
    Game.IncrementStat("Werewolf Transformations")
 
    ; set us up to check when we turn back
    RegisterForUpdate(5)
 
    SetStage(10) ; we're done with the transformation handling
EndFunction
 
Event OnUpdate()
    if (Untimed)
        return
    endif
    float currentTime = GameDaysPassed.GetValue()
    float regressTime = PlayerWerewolfShiftBackTime.GetValue()
 
; Vain01 Script Modification - Manual Revert Function
If bIsHotkeyPressed != Input.IsKeyPressed(33)
bIsHotkeyPressed = !bIsHotkeyPressed
If bIsHotkeyPressed
SetStage(100)
EndIf
EndIf
; Vain01 End Script Modification
 
    if (  (currentTime >= regressTime) && (!Game.GetPlayer().IsInKillMove()) && !__tryingToShiftBack )
        UnregisterForUpdate()
        SetStage(100) ; time to go, buddy
        return
    endif
 
    if (currentTime >= regressTime - __durationWarningTime)
        if (GetStage() == 10)
            SetStage(20)  ; almost there
            return
        endif
    endif
 
;     Debug.Trace("WEREWOLF: Checking, still have " + GameTimeDaysToRealTimeSeconds(regressTime - currentTime) + " seconds to go.")
EndEvent
 
Function SetUntimed(bool untimedValue)
    Untimed = untimedValue
    if (Untimed)
        UnregisterForUpdate()
    endif
EndFunction
 
; called from stage 11
Function Feed(Actor victim)
    float newShiftTime = PlayerWerewolfShiftBackTime.GetValue() + __feedExtensionTime
    Game.GetPlayer().PlayIdle(SpecialFeeding)
    
    ;This is for adding a spell that simulates bleeding
    BleedingFXSpell.Cast(victim,victim)
    
    if (!C03Rampage.IsRunning())
        PlayerWerewolfShiftBackTime.SetValue(newShiftTime)
        PlayerWerewolfFeedMessage.Show()
        FeedBoost.Cast(Game.GetPlayer())
        ; victim.SetActorValue("Variable08", 100)
;         Debug.Trace("WEREWOLF: Player feeding -- new regress day is " + newShiftTime)
    endif
    SetStage(10)
EndFunction
 
 
; called from stage 20
Function WarnPlayer()
;     Debug.Trace("WEREWOLF: Player about to transform back.")
    WerewolfWarn.Apply()
EndFunction
 
 
; called from stage 100
Function ShiftBack()
    __tryingToShiftBack = true
 
    while (Game.GetPlayer().GetAnimationVariableBool("bIsSynced"))
;         Debug.Trace("WEREWOLF: Waiting for synced animation to finish...")
        Utility.Wait(0.1)
    endwhile
;     Debug.Trace("WEREWOLF: Sending transform event to turn player back to normal.")
 
    __shiftingBack = false
    ; RegisterForAnimationEvent(Game.GetPlayer(), "TransformToHuman")
    ; Game.GetPlayer().PlayIdle(WerewolfTransformBack)
    ; Utility.Wait(10)
    ActuallyShiftBackIfNecessary()
EndFunction
 
Event OnAnimationEvent(ObjectReference akSource, string asEventName)
    if (asEventName == "TransformToHuman")
        ActuallyShiftBackIfNecessary()
    endif
EndEvent
 
Function ActuallyShiftBackIfNecessary()
    if (__shiftingBack)
        return
    endif
 
    __shiftingBack = true
 
;     Debug.Trace("WEREWOLF: Player returning to normal.")
 
    Game.SetInCharGen(true, true, false)
 
    UnRegisterForAnimationEvent(Game.GetPlayer(), "TransformToHuman")
    UnRegisterForUpdate() ; just in case
 
    if (Game.GetPlayer().IsDead())
;         Debug.Trace("WEREWOLF: Player is dead; bailing out.")
        return
    endif
 
    ;Remove Blood Effects
    ;FeedBloodVFX.Stop(Game.GetPlayer())
 
    ; imod
    WerewolfChange.Apply()
    WerewolfIMODSound.Play(Game.GetPlayer())
 
    ; get rid of your summons if you have any
    int count = 0
    while (count < WerewolfDispelList.GetSize())
        Spell gone = WerewolfDispelList.GetAt(count) as Spell
        if (gone != None)
;             Debug.Trace("WEREWOLF: Dispelling " + gone)
            Game.GetPlayer().DispelSpell(gone)
        endif
        count += 1
    endwhile
 
    ; make sure the transition armor is gone
    Game.GetPlayer().UnequipItem(WolfSkinFXArmor, False, True)
 
    ; clear out perks/abilities
    ;  (don't need to do this anymore since it's on from gamestart)
    ; Game.GetPlayer().RemovePerk(PlayerWerewolfFeed)
 
    ; make sure your health is reasonable before turning you back
    ; Game.GetPlayer().GetActorBase().SetInvulnerable(true)
    Game.GetPlayer().SetGhost()
    float currHealth = Game.GetPlayer().GetAV("health")
    if (currHealth <= 70)
;         Debug.Trace("WEREWOLF: Player's health is only " + currHealth + "; restoring.")
        Game.GetPlayer().RestoreAV("health", 70 - currHealth)
    endif
 
    ; change you back
;     Debug.Trace("WEREWOLF: Setting race " + (CompanionsTrackingQuest as CompanionsHousekeepingScript).PlayerOriginalRace + " on " + Game.GetPlayer())
    Game.GetPlayer().SetRace((CompanionsTrackingQuest as CompanionsHousekeepingScript).PlayerOriginalRace)
 
    ; release the player controls
;     Debug.Trace("WEREWOLF: Restoring camera controls")
    Game.EnablePlayerControls(abMovement = false, abFighting = false, abCamSwitch = true, abLooking = false, abSneaking = false, abMenu = false, abActivate = false, abJournalTabs = false, aiDisablePOVType = 1)
    Game.ShowFirstPersonGeometry(true)
 
    ; no more howling for you
    Game.GetPlayer().UnequipShout(CurrentHowl)
    Game.GetPlayer().RemoveShout(CurrentHowl)
 
    ; or those claws
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl10AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl15AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl20AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl25AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl30AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl35AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl40AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl45AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl50AndOverAbility)
;Vain01

    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl55AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl60AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl65AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl70AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl75AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl80AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl85AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl90AndBelowAbility)
    Game.GetPlayer().RemoveSpell(PlayerWerewolfLvl100AndOverAbility)
;Vain01

 
    ; gimme back mah stuff
    ; LycanStash.RemoveAllItems(Game.GetPlayer())
 
    ; people don't hate you no more
    Game.GetPlayer().SetAttackActorOnSight(false)
    Game.GetPlayer().RemoveFromFaction(PlayerWerewolfFaction)
    Game.GetPlayer().RemoveFromFaction(WerewolfFaction)
    int cfIndex = 0
    while (cfIndex < CrimeFactions.GetSize())
;         Debug.Trace("WEREWOLF: Removing enemy flag from " + CrimeFactions.GetAt(cfIndex))
        (CrimeFactions.GetAt(cfIndex) as Faction).SetPlayerEnemy(false)
        cfIndex += 1
    endwhile
 
    ; and you're now recognized
    Game.SetPlayerReportCrime(true)
 
    ; alert anyone nearby that they should now know the player is a werewolf
    Game.SendWereWolfTransformation()
 
    ; give the set race event a chance to come back, otherwise shut us down
    Utility.Wait(5)
    Shutdown()
EndFunction
 
Function Shutdown()
    if (__shuttingDown)
        return
    endif
 
    __shuttingDown = true
 
    Game.GetPlayer().GetActorBase().SetInvulnerable(false)
    Game.GetPlayer().SetGhost(false)
 
    Game.SetBeastForm(False)
    Game.EnableFastTravel(True)
 
    Game.SetInCharGen(false, false, false)
 
    Stop()
EndFunction
 
Keyword Property ActorTypeNPC  Auto

Edited by Vain
Link to comment
Share on other sites

I've got everything down except I am completely lost as to how to make the game not only detect when a button is being pushed (I want it to update only while a certain script is tracking events - while you are a Werewolf) but that a button is being pushed as well.  The switch point of view key (F default).  View switching is disabled while you are shapeshifted so there should be no conflict.

 

Help meeeeee

Link to comment
Share on other sites

  • 3 weeks later...

Well good news and bad news!  Good news first!

The SKSE is not my problem.

 

Bad news!  If I extend the original PlayerWerewolfChangeScript with my Vain01WerewolfChangeScript - no matter if I change nothing about the script at all I automatically revert to human form after the initial transformation completes...  I hate your coders, Bethesda.  I hate them so hard.

 

If I try to duplicate the original script exactly, no changes, and extend the quest like it does - the transformation sequence breaks.  Your armor is not unequipped and stored in the container in the Underforge like it's supposed to be, your animation breaks, and you are no longer able to move or move the camera or do anything, and who knows how many other game breaking things happen that you can't even see.

The reason for this is the script fragment QF_PlayerWerewolfQuest_0002BA16 which is also attached to the quest.  It specifically references the original script and will not work with a straight up replacement unless it was named identically.

 

Welp... cya later!  I'm off to break the game!

Edited by Vain
Link to comment
Share on other sites

Maybe on one of my day's off I'm going to go through the Dawnguard vampire lord changes and see how their revert function works.  It's built off of what appears to be the skeleton of the werewolf change scripts (even has some werewolf specific lines commented out such as the one which applies the werewolf skin to the player).

 

So my theory is that creating a revert script that calls back to the original PlayerWerewolfChangeScript without actually touching it (maybe attached to the quest maybe a spell, we'll see if I feel up to adding a quick slot menu for Werewolves...) that this would enable a scripter to do what I have done without having to modify vanilla game data (only 2 unvalidated files, but boy the CK ain't happy...)

Link to comment
Share on other sites

  • 6 months later...

Going to be messing with the script fragment now building a compatibility patch for someone who's been messing with it already...

BY OUR POWER COMBINED...

Start by either owning Dawnguard or making a backup of the QF_PlayerWerewolfQuest_0002BA16.psc

Open up the PlayerWerewolfQuest in the CK.

Quest Stages tab>Script Fragments>Advanced>Renamed Script

I'm going to name it Vain_QF_PlayerWerewolfQuest

This should leave the original script untouched - Yay! You didn't break the game!

Duplicate and rename the PlayerWerewolfChangeScript.psc as well.

VainWerewolfChangeScript.psc will do nicely.

Nope - Crash to Desktop if you try all this...

 

 

SkinNakedWerewolfBeastPlayer is undefined - define it by editing our new script in an external editor and add

Armor Property SkinNakedWerewolfBeastPlayer Auto ;Vain01

Underneath the last line of code.

 

You'll also have to change the kMyQuest drop down box above each script fragment for each stage on the quest to VainWerewolfChangeScript.

 

Modifying Stage 1 scripts on the PlayerWerewolfQuest

Under the already present

kmyQuest.InitialShift()
Adding
Game.GetPlayer().AddItem(SkinNakedWerewolfBeastPlayer, 1) ;Vain01
Game.GetPlayer().EquipItem(SkinNakedWerewolfBeastPlayer) ;Vain01
These will now be lines 18 and 19 in the fragment.
 
Modifying Stage 100 scripts on the PlayerWerewolfQuest
Under the already present
kmyQuest.ShiftBack()
Adding
Game.GetPlayer().UnequipItem(SkinNakedWerewolfBeastPlayer) ;Vain01
Game.GetPlayer().RemoveItem(SkinNakedWerewolfBeastPlayer, 1) ;Vain01
These will now be lines 82 and 83 in the fragment.
 
Other functions have been moved around in the script fragment as opposed to the original not doing those changes unless I find any problems... the Dawnguard script fragment appears identical only included with the source code since the quest itself was altered.
Edited by Vain
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...