Nuascura Posted October 2, 2023 Posted October 2, 2023 Feel free to check the code below Spoiler Bool Function thaneImmunity() Quest DragonRisingQuest = Game.GetFormFromFile(0x02610C, "Skyrim.esm") as Quest; Dragon Rising Quest WhiterunThaneQuest = Game.GetFormFromFile(0x0A2C9E, "Skyrim.esm") as Quest; Thane of Whiterun Quest WinterholdThaneQuest = Game.GetFormFromFile(0x0A34D7, "Skyrim.esm") as Quest; Thane of Winterhold Quest RiftenThaneQuest = Game.GetFormFromFile(0x065BDF, "Skyrim.esm") as Quest; I Done Got Thaned! Quest ReachThaneQuest = Game.GetFormFromFile(0x0A2C86, "Skyrim.esm") as Quest; Thane of the Reach Quest PaleThaneQuest = Game.GetFormFromFile(0x0A34D4, "Skyrim.esm") as Quest; Thane of the Pale Quest HjaalmarchThaneQuest = Game.GetFormFromFile(0x0A34CE, "Skyrim.esm") as Quest; Thane of Hjaalmarch Quest HaafingarThaneQuest = Game.GetFormFromFile(0x0A2C9B, "Skyrim.esm") as Quest; Thane of Haafingar Quest FalkreathThaneQuest = Game.GetFormFromFile(0x0A34DE, "Skyrim.esm") as Quest; Thane of Falkreath Quest EastmarchThaneQuest = Game.GetFormFromFile(0x0A2CA6, "Skyrim.esm") as Quest; Thane of Eastmarch if DragonRisingQuest.IsCompleted() && !WhiterunThaneQuest.IsRunning() || WhiterunThaneQuest.IsCompleted() return true elseIf WinterholdThaneQuest.IsCompleted() && IsInLocation(WinterholdHoldLocation) return true elseIf RiftenThaneQuest.IsCompleted() && IsInLocation(RiftHoldLocation) return true elseIf ReachThaneQuest.IsCompleted() && IsInLocation(ReachHoldLocation) return true elseIf PaleThaneQuest.IsCompleted() && IsInLocation(PaleHoldLocation) return true elseIf HjaalmarchThaneQuest.IsCompleted() && IsInLocation(HjaalmarchHoldLocation) return true elseIf HaafingarThaneQuest.IsCompleted() && IsInLocation(HaafingarHoldLocation) return true elseIf FalkreathThaneQuest.IsCompleted() && IsInLocation(FalkreathHoldLocation) return true elseIf EastmarchThaneQuest.IsCompleted() && IsInLocation(EastmarchHoldLocation) return true endIf return false EndFunction bool Function IsInLocation(Location akLocation) if licenses.currLoc == None return false else return akLocation.IsChild(licenses.currLoc) || licenses.currLoc == akLocation endif endFunction Evidently, this code is flawed, which is why I need some help. Unlike other Holds in Skyrim, Whiterun's Thane condition is a special: if Dragon Rising is completed, there is no Thane quest as player is automatically bequeathed Thaneship. However, should Balgruuf be deposed, the player loses Thaneship until they finish the Thane of Whiterun quest (the actual equivalent Thane quest of the other Holds). Given these special conditions, I wonder if anyone has figured out how to cancel player Thane status in their own scripts. This issue is further complicated by the fact that the quest which deposes Balgruuf, Battle for Whiterun, is a Radiant Quest with ID CWSiegeObj. This means I can't just check for the related quest's completion status.
Seijin8 Posted October 2, 2023 Posted October 2, 2023 1 hour ago, Gyra said: Feel free to check the code below Hide contents Bool Function thaneImmunity() Quest DragonRisingQuest = Game.GetFormFromFile(0x02610C, "Skyrim.esm") as Quest; Dragon Rising Quest WhiterunThaneQuest = Game.GetFormFromFile(0x0A2C9E, "Skyrim.esm") as Quest; Thane of Whiterun Quest WinterholdThaneQuest = Game.GetFormFromFile(0x0A34D7, "Skyrim.esm") as Quest; Thane of Winterhold Quest RiftenThaneQuest = Game.GetFormFromFile(0x065BDF, "Skyrim.esm") as Quest; I Done Got Thaned! Quest ReachThaneQuest = Game.GetFormFromFile(0x0A2C86, "Skyrim.esm") as Quest; Thane of the Reach Quest PaleThaneQuest = Game.GetFormFromFile(0x0A34D4, "Skyrim.esm") as Quest; Thane of the Pale Quest HjaalmarchThaneQuest = Game.GetFormFromFile(0x0A34CE, "Skyrim.esm") as Quest; Thane of Hjaalmarch Quest HaafingarThaneQuest = Game.GetFormFromFile(0x0A2C9B, "Skyrim.esm") as Quest; Thane of Haafingar Quest FalkreathThaneQuest = Game.GetFormFromFile(0x0A34DE, "Skyrim.esm") as Quest; Thane of Falkreath Quest EastmarchThaneQuest = Game.GetFormFromFile(0x0A2CA6, "Skyrim.esm") as Quest; Thane of Eastmarch if DragonRisingQuest.IsCompleted() && !WhiterunThaneQuest.IsRunning() || WhiterunThaneQuest.IsCompleted() return true elseIf WinterholdThaneQuest.IsCompleted() && IsInLocation(WinterholdHoldLocation) return true elseIf RiftenThaneQuest.IsCompleted() && IsInLocation(RiftHoldLocation) return true elseIf ReachThaneQuest.IsCompleted() && IsInLocation(ReachHoldLocation) return true elseIf PaleThaneQuest.IsCompleted() && IsInLocation(PaleHoldLocation) return true elseIf HjaalmarchThaneQuest.IsCompleted() && IsInLocation(HjaalmarchHoldLocation) return true elseIf HaafingarThaneQuest.IsCompleted() && IsInLocation(HaafingarHoldLocation) return true elseIf FalkreathThaneQuest.IsCompleted() && IsInLocation(FalkreathHoldLocation) return true elseIf EastmarchThaneQuest.IsCompleted() && IsInLocation(EastmarchHoldLocation) return true endIf return false EndFunction bool Function IsInLocation(Location akLocation) if licenses.currLoc == None return false else return akLocation.IsChild(licenses.currLoc) || licenses.currLoc == akLocation endif endFunction Evidently, this code is flawed, which is why I need some help. Unlike other Holds in Skyrim, Whiterun's Thane condition is a special: if Dragon Rising is completed, there is no Thane quest as player is automatically bequeathed Thaneship. However, should Balgruuf be deposed, the player loses Thaneship until they finish the Thane of Whiterun quest (the actual equivalent Thane quest of the other Holds). Given these special conditions, I wonder if anyone has figured out how to cancel player Thane status in their own scripts. This issue is further complicated by the fact that the quest which deposes Balgruuf, Battle for Whiterun, is a Radiant Quest with ID CWSiegeObj. This means I can't just check for the related quest's completion status. Looking at related dialogue conditions (usually for guard dialogues), they are always checking for stage completed on the quests. For instance, Riften wants quest stage 200. Sounds like that might fix the CWSiegeObj issue as well. Beyond that, this might be a case where a controller quest looks up status on every change of Hold location and stores that result rather than have to go through this kind of scripting every time.
Seijin8 Posted October 2, 2023 Posted October 2, 2023 1 hour ago, DarkBlade13 said: For me that means once you obtained thane status you keep it. He explained pretty clearly in the original post why that won't work. That also won't function for other locations, since being thane is separate from owning property.
MorePrinniesDood Posted October 2, 2023 Posted October 2, 2023 You might check the player's relationship rank to Balgruuf specifically. It raises during Dragon Rising, but looks to be reset to 0 if you side against him in Battle for Whiterun.
Nuascura Posted October 7, 2023 Author Posted October 7, 2023 (edited) Spoiler Scriptname BM_Licenses_Utility extends Quest BM_Licenses Property licenses auto FavorJarlsMakeFriendsScript Property FJMF auto Location Property WhiterunHoldLocation auto Location Property WinterholdHoldLocation auto Location Property RiftHoldLocation auto Location Property ReachHoldLocation auto Location Property PaleHoldLocation auto Location Property HjaalmarchHoldLocation auto Location Property HaafingarHoldLocation auto Location Property FalkreathHoldLocation auto Location Property EastmarchHoldLocation auto Faction Property CWImperialFaction auto Faction Property CWSonsFaction auto ReferenceAlias Property playerRef auto ReferenceAlias Property guardRef auto Bool Function ThaneImmunity() Debug.Notification("Running ThaneImmunity") Actor playerActor = playerRef.GetActorRef() Actor guardActor = guardRef.GetActorRef() licenses.currLoc = playerActor.GetCurrentLocation() if IsInLocation(WhiterunHoldLocation) && ((FJMF.WhiterunImpGetOutofJail != 0 && guardActor.IsInFaction(CWImperialFaction)) || (FJMF.WhiterunSonsGetOutofJail != 0 && guardActor.IsInFaction(CWSonsFaction))) return true elseIf IsInLocation(WinterholdHoldLocation) && ((FJMF.WinterholdImpGetOutofJail != 0 && guardActor.IsInFaction(CWImperialFaction)) || (FJMF.WinterholdSonsGetOutofJail != 0 && guardActor.IsInFaction(CWSonsFaction))) return true elseIf IsInLocation(RiftHoldLocation) && ((FJMF.RiftImpGetOutofJail != 0 && guardActor.IsInFaction(CWImperialFaction)) || (FJMF.RiftSonsGetOutofJail != 0 && guardActor.IsInFaction(CWSonsFaction))) return true elseIf IsInLocation(ReachHoldLocation) && ((FJMF.ReachImpGetOutofJail != 0 && guardActor.IsInFaction(CWImperialFaction)) || (FJMF.ReachSonsGetOutofJail != 0 && guardActor.IsInFaction(CWSonsFaction))) return true elseIf IsInLocation(PaleHoldLocation) && ((FJMF.PaleImpGetOutofJail != 0 && guardActor.IsInFaction(CWImperialFaction)) || (FJMF.PaleSonsGetOutofJail != 0 && guardActor.IsInFaction(CWSonsFaction))) return true elseIf IsInLocation(HjaalmarchHoldLocation) && ((FJMF.HjaalmarchImpGetOutofJail != 0 && guardActor.IsInFaction(CWImperialFaction)) || (FJMF.HjaalmarchSonsGetOutofJail != 0 && guardActor.IsInFaction(CWSonsFaction))) return true elseIf IsInLocation(HaafingarHoldLocation) && ((FJMF.HaafingarImpGetOutofJail != 0 && guardActor.IsInFaction(CWImperialFaction)) || (FJMF.HaafingarSonsGetOutofJail != 0 && guardActor.IsInFaction(CWSonsFaction))) return true elseIf IsInLocation(FalkreathHoldLocation) && ((FJMF.FalkreathImpGetOutofJail != 0 && guardActor.IsInFaction(CWImperialFaction)) || (FJMF.FalkreathSonsGetOutofJail != 0 && guardActor.IsInFaction(CWSonsFaction))) return true elseIf IsInLocation(EastmarchHoldLocation) && ((FJMF.EastmarchImpGetOutofJail != 0 && guardActor.IsInFaction(CWImperialFaction)) || (FJMF.EastmarchSonsGetOutofJail != 0 && guardActor.IsInFaction(CWSonsFaction))) return true endIf return false EndFunction bool Function IsInLocation(Location akLocation) if licenses.currLoc == None return false else return akLocation.IsChild(licenses.currLoc) || licenses.currLoc == akLocation endif endFunction This is what I've ended up with. Rather than depending on Jarls, I'm just going to piggyback on how the vanilla game checks Thane status given vanilla Skyrim doesn't even have an explicit variable for checking Thaneship. In other words, Thane checking will solely be between player and a guard NPC. All vanilla game actually does to benefit a player Thane is give a Get Out of Jail card. The vanilla FavorJarlsMakeFriends script has a comment that says as much. So, I made a new quest to fill a quest reference alias with Closest Guard. Edit: I forgot to also mention: Player thaneship soft resets when a Hold is taken over by a new Jarl. Even though player just needs to talk with the new Jarl to regain thaneship should they have already completed the thane quest, the act of talking to the new Jarl is still neccessary to activate Thaneship. This makes any method depending on the Jarl NPC or quest really complicated. Edited October 7, 2023 by Gyra 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now