1
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

478 lines
17 KiB

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