Haravikk Posted October 17, 2019 Share Posted October 17, 2019 What I'm looking to do is determine via script who an NPC's spouse, children, parents and/or siblings are, is such a thing possible? I know that NPCs have relationship information stored by the game, and have found two very basic functions for testing this via HasFamilyRelationship(Actor) and HasParentRelationship(Actor) and related conditions, but these don't give nearly as much information as I would like, and aren't terribly flexible. Are there any other options that I might be missing? The only alternative I've been able to think of would be to build massive parallel FormLists, e.g- one listing children and a parallel list listing their parents, but aside from being a lot of time to build, I don't think this would work since most children have multiple parents, some parents have multiple children etc., and FormLists don't seem to allow duplicate values. So anyway, is there a way to get this information dynamically, or am I stuck with just building lists of those that I want to use? Link to comment Share on other sites More sharing options...
Evangela Posted October 17, 2019 Share Posted October 17, 2019 (edited) There's no function that returns the actual actors, which is the information I think you want.. the functions you mentioned all return bools only. You'd have to build a list of actors you want to check and then return the ones that are related and that sounds tedious because there is a lot of darn actors in the game. Note: Arrays can allow duplicate values, max size is 128 though. Also bare in mind Formlists get slower the iterate through, the bigger they get. Edited October 17, 2019 by Rasikko Link to comment Share on other sites More sharing options...
Haravikk Posted October 18, 2019 Author Share Posted October 18, 2019 There's no function that returns the actual actors, which is the information I think you want.. the functions you mentioned all return bools only. You'd have to build a list of actors you want to check and then return the ones that are related and that sounds tedious because there is a lot of darn actors in the game. Note: Arrays can allow duplicate values, max size is 128 though. Also bare in mind Formlists get slower the iterate through, the bigger they get. That's a shame, but thanks! I think the performance shouldn't be a big problem for me as most of the time what I'll actually be doing is taking a random index and grabbing the same entry from two parallels lists to get two siblings, or a parent and a child etc. If I've understood how FormLists are implemented correctly, which I believe is two arrays (original values and added values) then grabbing items by index should actually be very fast. I should only need to iterate if I have other conditions (e.g- only adult or child with sibling). I guess now I just have to decide if I want exhaustive lists (I'll share these if I make them), though I think it may be more likely I just do some curated ones for what I need to do. Will see. Link to comment Share on other sites More sharing options...
Haravikk Posted October 27, 2019 Author Share Posted October 27, 2019 (edited) So I just wanted to bump this to report that I found a better way. Something was annoying me so much about this as I could have sworn it was possible, and then I remembered the Revenge, Hired Thugs quest; it uses the HasFamilyRelationship condition to fill an alias, based upon any relation to another alias, if it fills then there is one, otherwise the quest can't trigger. I also found there is a HasAssociation(AssociationType akAssociation, Actor akActor = None) function (and condition) that can do this with any relationship type; good old bethesda calling it something completely different so I didn't notice the first time I looked :dry: Since I need to define quests for what I actually want to do anyway, this is definitely the best way to do what I need. I suppose in theory this could be exploited to get a spouse/sibling etc. via a script function, by creating a hidden quest that does this, and then having it provide a function that forces an Actor into the first alias, and then tries to fill the second, either returning a value, or failing and returning nothing. Bit of a labour intensive way to do it, but it's possible at least, in case anyone does need it! I have a feeling some of the kidnap and similar quests may use this condition as well, kicking myself for not thinking of them sooner. Edited October 27, 2019 by Haravikk Link to comment Share on other sites More sharing options...
ReDragon2013 Posted October 27, 2019 Share Posted October 27, 2019 (edited) look at WIFunctionsScript.psc for using family relationships properties ;Note: this is a subset of all the AssociationTypes because this script only cares about these types. ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ associationType PROPERTY pAuntUncle auto associationType PROPERTY pCourting auto associationType PROPERTY pCousins auto associationType PROPERTY pParentChild auto associationType PROPERTY pSiblings auto associationType PROPERTY pSpouse auto ;These are factions used by the function to make people mourn Kill event victims ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Faction PROPERTY pWIMournAuntFaction auto Faction PROPERTY pWIMournBoyfriendFaction auto Faction PROPERTY pWIMournBrotherFaction auto Faction PROPERTY pWIMournCousinFemaleFaction auto Faction PROPERTY pWIMournCousinMaleFaction auto Faction PROPERTY pWIMournDaughterFaction auto Faction PROPERTY pWIMournFatherFaction auto Faction PROPERTY pWIMournFriendFemaleFaction auto Faction PROPERTY pWIMournFriendMaleFaction auto Faction PROPERTY pWIMournGirlfriendFaction auto Faction PROPERTY pWIMournHusbandFaction auto Faction PROPERTY pWIMournKinsmanFaction auto Faction PROPERTY pWIMournKinswomanFaction auto Faction PROPERTY pWIMournMotherFaction auto Faction PROPERTY pWIMournNephewFaction auto Faction PROPERTY pWIMournNieceFaction auto Faction PROPERTY pWIMournSisterFaction auto Faction PROPERTY pWIMournSonFaction auto Faction PROPERTY pWIMournUncleFaction auto Faction PROPERTY pWIMournWifeFaction auto Faction PROPERTY WIAssaultedFaction auto ; assault Faction PROPERTY WIPlayerEnemyFaction auto ; enemy functions ;======================================================================================== ;== Mourner == ;======================================================================================== FUNCTION RemoveMournerActorFromFactions(Actor Mourner) ;----------------------------------------------------- Mourner.RemoveFromFaction(pWIMournAuntFaction) Mourner.RemoveFromFaction(pWIMournBoyfriendFaction) Mourner.RemoveFromFaction(pWIMournBrotherFaction) Mourner.RemoveFromFaction(pWIMournCousinFemaleFaction) Mourner.RemoveFromFaction(pWIMournCousinMaleFaction) Mourner.RemoveFromFaction(pWIMournDaughterFaction) Mourner.RemoveFromFaction(pWIMournFatherFaction) Mourner.RemoveFromFaction(pWIMournFriendFemaleFaction) Mourner.RemoveFromFaction(pWIMournFriendMaleFaction) Mourner.RemoveFromFaction(pWIMournGirlfriendFaction) Mourner.RemoveFromFaction(pWIMournHusbandFaction) Mourner.RemoveFromFaction(pWIMournKinsmanFaction) Mourner.RemoveFromFaction(pWIMournKinswomanFaction) Mourner.RemoveFromFaction(pWIMournMotherFaction) Mourner.RemoveFromFaction(pWIMournNephewFaction) Mourner.RemoveFromFaction(pWIMournNieceFaction) Mourner.RemoveFromFaction(pWIMournSisterFaction) Mourner.RemoveFromFaction(pWIMournSonFaction) Mourner.RemoveFromFaction(pWIMournUncleFaction) Mourner.RemoveFromFaction(pWIMournWifeFaction) ENDFUNCTION ;----------------------------------------------------------------------------------------- FUNCTION PutMournerAliasInFaction(ReferenceAlias VictimAlias, ReferenceAlias MournerAlias) ;----------------------------------------------------------------------------------------- ; {Calls PutMournerActorInFaction passing VictimAlias and MournerAlias as actors. ; Based on the relationship of the Victim to Mourner, mourner is placed in a faction to get related dialogue.} IF MournerAlias.GetActorReference() ELSE RETURN ; - STOP - ; no mourner reference, bail out early ENDIF ;--------------------- actor aRef = VictimAlias.GetActorReference() IF ( aRef ) ; double check before passing in as actor PutMournerActorInFaction(aRef, MournerAlias.GetActorReference()) ;; ELSE ;; Debug.Trace(self + " PutMournerAliasInFaction() expected ReferenceAliases that could be cast as actors, got some other kind of ReferenceAlias." ;; Debug.Trace("Victim: " + VictimAlias.GetReference() +", Mourner: " + MournerAlias.GetReference()) ENDIF ENDFUNCTION ;------------------------------------------------------------- FUNCTION PutMournerActorInFaction(Actor Victim, Actor Mourner) ; Actor1 ist "das Opfer", Actor2 ist "der Trauernde" ;------------------------------------------------------------- ; {Based on the relationship of the Victim to Mourner, where mourner is placed in a faction to get related dialogue.} ; CASE SENSITIVE description of Actor1 !! ; if Actor1 is in Sibling relationship and a male, returns "brother" ; if Actor1 is niece, then = "child", if Actor1 is aunt then = "parent" ; Note: Not all relationship types are supported by this function. See function comments for details. bool bMaleYes = TRUE string sex ;"male" | "female" string pos ;"parent" | "child" string relation ;"kinsman", "father", "sister", "friend male", "boyfriend", etc. ;Supported replationships are ;Family: ; "husband", "wife" ; "father", "mother" ; "son", "daughter" ; "brother", "sister" ; "uncle", "aunt" ; "nephew", "niece" ; "cousin male", "cousin female" ; "kinsman", "kinswoman" ; ; "friend male", "friend female" ; "boyfriend", "girlfriend" ; --SEX-- ;--------------------------------------------- IF (Victim.GetActorBase().GetSex() == 0) ; male = 0, female = 1 sex = "male" ELSE sex = "female" bMaleYes = FALSE ENDIF ; --PARENT/CHILD--, someone is never both a parent and a child in different relationshps to the same person. ;---------------------------------------------- IF Victim.HasParentRelationship(Mourner) pos = "parent" ELSE pos = "child" ENDIF ;=(1)= HUSBAND / WIFE === IF Victim.HasAssociation(pSpouse, Mourner) IF ( bMaleYes ) relation = "husband" ; Ehemann Mourner.AddToFaction(pWIMournHusbandFaction) ELSE relation = "wife" ; Ehefrau Mourner.AddToFaction(pWIMournWifeFaction) ENDIF RETURN ; (1) ENDIF ;------------- ;=(2)= FATHER / MOTHER and SON / DAUGHTER === IF Victim.HasAssociation(pParentChild, Mourner) IF ( pos == "parent" ) IF ( bMaleYes ) relation = "father" ; Vater Mourner.AddToFaction(pWIMournFatherFaction) ELSE relation = "mother" ; Mutter Mourner.AddToFaction(pWIMournMotherFaction) ENDIF ELSE ;IF ( pos == "child" ) IF ( bMaleYes ) relation = "son" ; Sohn Mourner.AddToFaction(pWIMournSonFaction) ELSE relation = "daughter" ; Tochter Mourner.AddToFaction(pWIMournDaughterFaction) ENDIF ENDIF RETURN ; (2) ENDIF ;------------- ;=(3)= BROTHER / SISTER === IF Victim.HasAssociation(pSiblings, Mourner) IF ( bMaleYes ) relation = "brother" ; Bruder Mourner.AddToFaction(pWIMournBrotherFaction) ELSE relation = "sister" ; Schwester Mourner.AddToFaction(pWIMournSisterFaction) ENDIF RETURN ; (3) ENDIF ;------------- ;=(4)= UNCLE / AUNT === IF Victim.HasAssociation(pAuntUncle, Mourner) IF ( pos == "parent" ) IF ( bMaleYes ) relation = "uncle" ; Onkel Mourner.AddToFaction(pWIMournUncleFaction) ELSE relation = "aunt" ; Tante Mourner.AddToFaction(pWIMournAuntFaction) ENDIF ELSE IF ( bMaleYes ) relation = "nephew" ; Neffe Mourner.AddToFaction(pWIMournNephewFaction) ELSE relation = "niece" ; Nichte Mourner.AddToFaction(pWIMournNieceFaction) ENDIF ENDIF RETURN ; (4) ENDIF ;------------- ;=(5)= COUSIN (male/female) === IF Victim.HasAssociation(pCousins, Mourner) IF ( bMaleYes ) relation = "cousin male" ; Cousin Mourner.AddToFaction(pWIMournCousinMaleFaction) ELSE relation = "cousin female" ; Cousine Mourner.AddToFaction(pWIMournCousinFemaleFaction) ENDIF RETURN ; (5) ENDIF ;------------- ;=(6)= KINSMAN / KINSWOMAN === ; We set to kinsmen if there is any family relation at all. IF Victim.HasFamilyRelationship(Mourner) IF ( bMaleYes ) relation = "kinsman" ; Enkelsohn Mourner.AddToFaction(pWIMournKinsmanFaction) ELSE relation = "kinswoman" ; Enkeltochter Mourner.AddToFaction(pWIMournKinswomanFaction) ENDIF RETURN ; 6 ENDIF ;------------- ;=(7a)= (boy/girl) FRIEND === IF Victim.HasAssociation(pCourting, Mourner) IF ( bMaleYes ) relation = "boyfriend" ; Freund Mourner.AddToFaction(pWIMournBoyfriendFaction) ELSE relation = "girlfriend" ; Freundin Mourner.AddToFaction(pWIMournGirlfriendFaction) ENDIF RETURN ; 7a ENDIF ;------------- ;=(7b)= FRIEND === ; We set to friend if there is any family relation at all. IF ( Victim.GetRelationshipRank(Mourner) >= 1 ) IF ( bMaleYes ) relation = "friend male" ; Bekannter Mourner.AddToFaction(pWIMournFriendMaleFaction) ELSE relation = "friend female" ; Bekannte Mourner.AddToFaction(pWIMournFriendFemaleFaction) ENDIF RETURN ; 7b ENDIF ;------------- ;######### Debug.Trace(self+" PutMournerInFaction() - Error: returned unexpected relation ["+relation+ "] when Victim is " +Victim+ " and Mourner is " +Mourner+ ".") ;######### ENDFUNCTION Edited October 27, 2019 by ReDragon2013 Link to comment Share on other sites More sharing options...
Recommended Posts