Scriptname PlayerWerewolfChangeScript extends Quest float Property StandardDurationSeconds auto {How long (in real seconds) the transformation lasts} float Property DurationWarningTimeSeconds auto {How long (in real seconds) before turning back we should warn the player} float Property FeedExtensionTimeSeconds auto {How long (in real seconds) that feeding extends werewolf time} VisualEffect property FeedBloodVFX auto {Visual Effect on Wolf for Feeding Blood} Race Property WerewolfBeastRace auto ObjectReference Property LycanStash auto Perk Property PlayerWerewolfFeed auto Faction Property PlayerWerewolfFaction auto Faction Property WerewolfFaction auto Message Property PlayerWerewolfExpirationWarning auto Message Property PlayerWerewolfFeedMessage auto GlobalVariable Property GameDaysPassed auto GlobalVariable Property TimeScale auto GlobalVariable Property PlayerWerewolfShiftBackTime auto ImageSpaceModifier Property WerewolfWarn auto ImageSpaceModifier Property WerewolfChange auto Race Property WerewolfRace auto Sound Property NPCWerewolfTransformation auto Sound Property WerewolfIMODSound auto Idle Property WerewolfTransformBack auto Idle Property SpecialFeeding auto Quest Property CompanionsTrackingQuest auto Quest Property C03Rampage auto Shout Property CurrentHowl auto WordOfPower Property CurrentHowlWord1 auto WordOfPower Property CurrentHowlWord2 auto WordOfPower Property CurrentHowlWord3 auto Spell Property PlayerWerewolfLvl10AndBelowAbility auto Spell Property PlayerWerewolfLvl15AndBelowAbility auto Spell Property PlayerWerewolfLvl20AndBelowAbility auto Spell Property PlayerWerewolfLvl25AndBelowAbility auto Spell Property PlayerWerewolfLvl30AndBelowAbility auto Spell Property PlayerWerewolfLvl35AndBelowAbility auto Spell Property PlayerWerewolfLvl40AndBelowAbility auto Spell Property PlayerWerewolfLvl45AndBelowAbility auto Spell Property PlayerWerewolfLvl50AndOverAbility auto Spell Property FeedBoost auto Spell property BleedingFXSpell auto {This Spell is for making the target of feeding bleed.} Armor Property WolfSkinFXArmor auto bool Property Untimed auto FormList Property CrimeFactions auto FormList Property WerewolfDispelList auto float __durationWarningTime = -1.0 float __feedExtensionTime = -1.0 float __gorgeExtensionTime = -1.0 bool __tryingToShiftBack = false bool __shiftingBack = false bool __shuttingDown = false bool __trackingStarted = false 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) __gorgeExtensionTime = RealTimeSecondsToGameTimeDays(DLC1GorgingDurationSeconds) ; 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) else Game.GetPlayer().AddSpell(PlayerWerewolfLvl50AndOverAbility, false) 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 ; Debug.Trace("WEREWOLF: NumWerewolfPerks = " + Game.QueryStat("NumWerewolfPerks")) if Game.QueryStat("NumWerewolfPerks") >= DLC1WerewolfMaxPerks.Value ; debug.trace("WEREWOLF: achievement granted") Game.AddAchievement(57) endif float currentTime = GameDaysPassed.GetValue() float regressTime = PlayerWerewolfShiftBackTime.GetValue() 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) ; Debug.Trace("WEREWOLF: start newShiftTime = " + GameTimeDaysToRealTimeSeconds(PlayerWerewolfShiftBackTime.GetValue()) + ", __feedExtensionTime = " + GameTimeDaysToRealTimeSeconds(__feedExtensionTime)) float newShiftTime = PlayerWerewolfShiftBackTime.GetValue() + __feedExtensionTime / 2 if victim.HasKeyword(ActorTypeNPC) newShiftTime =newShiftTime + __feedExtensionTime / 2 ; Debug.Trace("WEREWOLF: victim is NPC") endif ; Debug.Trace("WEREWOLF: default newShiftTime = " + GameTimeDaysToRealTimeSeconds(newShiftTime) + ", __feedExtensionTime = " + GameTimeDaysToRealTimeSeconds(__feedExtensionTime)) if Game.GetPlayer().HasPerk(DLC1GorgingPerk) == 1 newShiftTime = newShiftTime + __GorgeExtensionTime / 2 if victim.HasKeyword(ActorTypeNPC) newShiftTime = newShiftTime + __GorgeExtensionTime / 2 endif endif 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. We RemoveItem here, because the SetRace stored all equipped items ; at that time, and we equip this armor prior to setting the player to a beast race. When we switch back, ; if this were still in the player's inventory it would be re-equipped. Game.GetPlayer().RemoveItem(WolfSkinFXArmor, 1, 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 <= 101) ; Debug.Trace("WEREWOLF: Player's health is only " + currHealth + "; restoring.") Game.GetPlayer().RestoreAV("health", 101 - 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) ; 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 Float Property DLC1GorgingDurationSeconds Auto Perk Property DLC1GorgingPerk Auto Perk Property DLC1SavageFeedingPerk Auto Keyword Property ActorTypeNPC Auto Perk Property DLC1AnimalVigor Auto GlobalVariable Property DLC1WerewolfTotalPerksEarned Auto GlobalVariable Property DLC1WerewolfMaxPerks Auto