Jump to content

Racial Compatibility scripting problems


en_hawk

Recommended Posts

Posted

I've been working on a custom race project and I've started running into problems with RC. I'm using custom modifications of the generic race controller, as my races are setup differently than what is typical; the races are completely separated from the vanilla head part formlists. So I made a stripped down version of the generic race controller, NoHDPTRaceController, that only adds the race to the necessary formlists for RC to work properly, as their head part formlists have the races added directly to them. That part is all well and good, next I wanted to add additional races as separate plugins, so I needed to make a new race controller that added the races to my custom head part formlists(along with the RC ones) as opposed to the vanilla ones. This is the part that isn't behaving correctly. For reference, I'm using this version of racial compatibility http://skyrim.nexusmods.com/mods/24168/.

it seemed to be working correctly with the first race I made, however when I added a second one the head part formlist adding started randomly failing when I started a new game, so one(or both) of the extra races would not have hair/head parts available. So I edited the generic race controller and threw some debug lines in the proxyraces function to see if I could figure out what was up; that posed even more questions without answering any. Based on the code, it should call the proxy function once per race, keep looping until a spot opens up in the dispatcher, then finally run the actual proxy code. It appears to be trying to start the proxy routine multiple times, jumping all over the place, and then inexplicably giving up half the time. I have very little to no experience with papyrus(though I am an experienced programmer), so I'm really drawing a blank here.

Because I don't feel like uploading 300mb of assets or so just for diagnosing a script issue(nor could I imagine most people would be interesting in downloading that either), I made a new set of plugins in about 10 minutes specifically for demonstrating the issue. I have the base plugin with its custom set of head part records along with the first race, they're all just copies of the vanilla nord, its added to the head part formlists statically. Next I've got two addon plugins that are pretty much identical; they each contain a single race and utilize a custom race controller that adds the races to the head part formlists in the base plugin. On their own they work correctly, however if I run both of them at the same time one or both of them will fail to add itself to the formlists and end up with no headparts or hair.

I'll post the script source here, in addition to including it with the rest of the files.

Here's how I modified the proxyraces function in the generic race controller for debugging:

Function proxyRaces()
  RaceDispatcherScript dispatch = Game.GetFormFromFile(0x00009F27, "RaceCompatibility.esm") As RaceDispatcherScript
Debug.Trace("proxy: " + Self as String)
  While !dispatch.doProxyRace(Self)
Debug.Trace(Self as String + " is waiting to proxy")
    Utility.Wait(1.0)
  EndWhile
Debug.Trace("proxy completed: " + Self as String)
EndFunction


Here's the NoHDPTRaceController:

Scriptname NoHDPTRaceController extends GenericRaceController  

bool Function internalProxyRaces()
    FormList[] RaceList = new FormList[10]
    RaceList[0] = NewArgonian
    RaceList[1] = NewBreton
    RaceList[2] = NewDarkElf
    RaceList[3] = NewHighElf
    RaceList[4] = NewImperial
    RaceList[5] = NewKhajiit
    RaceList[6] = NewNord
    RaceList[7] = NewOrc
    RaceList[8] = NewRedguard
    RaceList[9] = NewWoodElf
    
    FormList[] RaceListVampire = new FormList[10]
    RaceListVampire[0] = NewArgonianVampire
    RaceListVampire[1] = NewBretonVampire
    RaceListVampire[2] = NewDarkElfVampire
    RaceListVampire[3] = NewHighElfVampire
    RaceListVampire[4] = NewImperialVampire
    RaceListVampire[5] = NewKhajiitVampire
    RaceListVampire[6] = NewNordVampire
    RaceListVampire[7] = NewOrcVampire
    RaceListVampire[8] = NewRedguardVampire
    RaceListVampire[9] = NewWoodElfVampire
    
    int element = 0
    While(element < RaceList.Length)
        If(RaceList[element] != None && RaceList[element].GetSize() > 0) ; Ensure we actually have a replacement
            int index = 0
            While(index < RaceList[element].GetSize()) ; Cycle each race in our replacement list
                ; Regular Listing
                Race standardRace = RaceList[element].GetAt(index) AS Race
                if(standardRace != None) ; Make sure we actually have a race to replace with
                    if(PlayableRaceList != None && !PlayableRaceList.HasForm(standardRace)) ; Check for None so we can skip transform script without crashing
                        PlayableRaceList.AddForm(standardRace)
                    endIf
                    
                    if(!isHuman(element))
                        if(!RacesBeast.HasForm(standardRace))
                            RacesBeast.AddForm(standardRace)
                        endIf
                    endIf
                    
                    If(isHuman(element))
                        if(!RacesHuman.HasForm(standardRace))
                            RacesHuman.AddForm(standardRace)
                        endIf
                    endIf
                    
                    If(isElf(element))
                        if(!RacesElf.HasForm(standardRace))
                            RacesElf.AddForm(standardRace)
                        endIf
                    endIf
                    
                    ; Vampire Listing
                    If(RaceListVampire[element] != None && RaceListVampire[element].GetSize() > 0)
                        Race vampireRace = RaceListVampire[element].GetAt(index) AS Race
                        if(vampireRace != None)
                            if(PlayableVampireList != None && !PlayableVampireList.HasForm(vampireRace)) ; Check for None so we can skip transform script without crashing
                                PlayableVampireList.AddForm(vampireRace)
                            endIf
                        endIf
                    endIf
                endIf
                index += 1
            endWhile
        endIf
        element += 1
    EndWhile
    Return True
EndFunction


Here's the controller I made for the example plugin races:

Scriptname testracecontroller extends GenericRaceController  

; Multi-Race Parts
FormList Property validracesnordtest Auto  

bool Function internalProxyRaces()
    FormList[] RaceList = new FormList[10]
    RaceList[0] = NewArgonian
    RaceList[1] = NewBreton
    RaceList[2] = NewDarkElf
    RaceList[3] = NewHighElf
    RaceList[4] = NewImperial
    RaceList[5] = NewKhajiit
    RaceList[6] = NewNord
    RaceList[7] = NewOrc
    RaceList[8] = NewRedguard
    RaceList[9] = NewWoodElf
    
    FormList[] RaceListVampire = new FormList[10]
    RaceListVampire[0] = NewArgonianVampire
    RaceListVampire[1] = NewBretonVampire
    RaceListVampire[2] = NewDarkElfVampire
    RaceListVampire[3] = NewHighElfVampire
    RaceListVampire[4] = NewImperialVampire
    RaceListVampire[5] = NewKhajiitVampire
    RaceListVampire[6] = NewNordVampire
    RaceListVampire[7] = NewOrcVampire
    RaceListVampire[8] = NewRedguardVampire
    RaceListVampire[9] = NewWoodElfVampire
            
    int element = 0
    While(element < RaceList.Length)
        If(RaceList[element] != None && RaceList[element].GetSize() > 0) ; Ensure we actually have a replacement
            int index = 0
            While(index < RaceList[element].GetSize()) ; Cycle each race in our replacement list
                ; Regular Listing
                Race standardRace = RaceList[element].GetAt(index) AS Race
                if(standardRace != None) ; Make sure we actually have a race to replace with
                    if(PlayableRaceList != None && !PlayableRaceList.HasForm(standardRace)) ; Check for None so we can skip transform script without crashing
                        PlayableRaceList.AddForm(standardRace)
                    endIf
                
                    if(!isHuman(element))
                        if(!RacesBeast.HasForm(standardRace))
                            RacesBeast.AddForm(standardRace)
                        endIf
                    endIf
                    
                    ; Conditioned Listings
                    If(isHuman(element) || isOrc(element) || isElf(element))
                        if(!validracesnordtest.HasForm(standardRace))
                            validracesnordtest.AddForm(standardRace)
                        endIf
                    endIf
                    If(isHuman(element))
                        if(!RacesHuman.HasForm(standardRace))
                            RacesHuman.AddForm(standardRace)
                        endIf
                    endIf
                    If(isElf(element))
                        if(!RacesElf.HasForm(standardRace))
                            RacesElf.AddForm(standardRace)
                        endIf
                    endIf
                    
                    ; Vampire Listing
                    If(RaceListVampire[element] != None && RaceListVampire[element].GetSize() > 0)
                        Race vampireRace = RaceListVampire[element].GetAt(index) AS Race
                        if(vampireRace != None)
                            if(PlayableVampireList != None && !PlayableVampireList.HasForm(vampireRace)) ; Check for None so we can skip transform script without crashing
                                PlayableVampireList.AddForm(vampireRace)
                            endIf
                        endIf
                    endIf
                endIf
                index += 1
            endWhile
        endIf
        element += 1
    EndWhile
    Return True
EndFunction

 

 

Here are the relevant excerpts from my papyrus log:

 

[06/10/2013 - 03:08:19AM] proxy: [testracecontroller <nordtest3controller (17002F9F)>]
[06/10/2013 - 03:08:19AM] handling target:[testracecontroller <nordtest3controller (17002F9F)>]
[06/10/2013 - 03:08:19AM] proxy: [testracecontroller <nordtest2controller (16002F9F)>]
[06/10/2013 - 03:08:19AM] waiting for Slot:[testracecontroller <nordtest2controller (16002F9F)>]
[06/10/2013 - 03:08:19AM] proxy: [NoHDPTRaceController <nordtestcontroller (15002FB2)>]
[06/10/2013 - 03:08:19AM] waiting for Slot:[NoHDPTRaceController <nordtestcontroller (15002FB2)>]

[06/10/2013 - 03:08:24AM] proxy: [NoHDPTRaceController <nordtestcontroller (15002FB2)>]
[06/10/2013 - 03:08:24AM] handling target:[NoHDPTRaceController <nordtestcontroller (15002FB2)>]
[06/10/2013 - 03:08:24AM] proxy: [testracecontroller <nordtest2controller (16002F9F)>]
[06/10/2013 - 03:08:24AM] waiting for Slot:[testracecontroller <nordtest2controller (16002F9F)>]
[06/10/2013 - 03:08:24AM] proxy: [testracecontroller <nordtest3controller (17002F9F)>]
[06/10/2013 - 03:08:24AM] waiting for Slot:[testracecontroller <nordtest3controller (17002F9F)>]
[06/10/2013 - 03:08:24AM] proxy completed: [NoHDPTRaceController <nordtestcontroller (15002FB2)>]
[06/10/2013 - 03:08:24AM] proxy completed: [testracecontroller <nordtest3controller (17002F9F)>]

 

 

Based on this it appears that each race is running the proxy routine twice for some reason, and it does not appear to be looping at all; if it doesn't get a slot in the dispatcher on the first call it just aborts for some reason. As you can see, the base race and plugin number 2(nordtest3) successfully proxied and work properly, whereas plugin number 1(nordtest2) did not and none of its head parts work(sliders move but nothing happens, it just keeps the model of whatever you had selected on the previous race before swapping). Just a note, the only head parts I added multiple options for is the hair(for males only), and there's only the two of them so please keep that in mind.

 

Any insight into this would be much appreciated, I'm out of ideas.

  • 2 weeks later...

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

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