Jump to content

[LE] Determining an NPC's parents, children, spouse and/or siblings?


Haravikk

Recommended Posts

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

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 by Rasikko
Link to comment
Share on other sites

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

  • 2 weeks later...

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 by Haravikk
Link to comment
Share on other sites

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 by ReDragon2013
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...