Jump to content

Photo

Getting form, actor and defaultVoiceType in c++ in a SKSE Plugin

skse plugin c++

  • Please log in to reply
1 reply to this topic

#1
VadersApp

VadersApp

    Fan

  • Premium Member
  • 360 posts

I am working on a new version of the former RealisticBodySystem. I was able to get a first version running. It is mostly written in papyrus and only some helper functions are written in a SKSE plugin. Calculations and morphing of the bodies is very slow for now. Females of vanilla Skyrim are  converted all after game is running more than an hour on my pc.

So the idea is to write the functions mainly in the SKSE Plugin. But thats a huge step for me, because i am not very skillfull in writing SKSE plugins (papyrus even :laugh: )

Of course there a several steps to take. But for now i would like to start to convert this papyrus script for finding females within actors.

 

Event onInit()
	;form[] actors = GetFemaleActors() ; SKSE Plugin Function not working
	;int[] IDs =  GetFemaleActorsFormIDs() ; SKSE Plugin Function not working
	morphFactor = 1
	Actor[] AllNpcs = PapyrusUtil.ActorArray(0)
	BeinzPluginScript.InitMods()
	npcIndex = BeinzPluginScript.GetTotalActors()
	debug.trace ("Amount NPCs:" + npcIndex)
	int newIndex = npcIndex
	int FormIndex = 0
	Form Akform
	String vt
	int i = 0
	while newIndex 
		akform = Game.GetForm(BeinzPluginScript.GetActorID(newIndex))
		newIndex -=1
		i +=1
		if (akform) 
			if (akform.GetFormID() > 0)
					Actor npc = akform as Actor
					vt = npc.getRace().GetDefaultVoiceType(true)
					if (StringUtil.find(vt,"Female") > -1)
						StorageUtil.FormListAdd(none,"k",npc)
						FormIndex +=1
					endif
			endif
		endIf
		if i == 100 
			;Debug.Notification ("RBS2020: parsing NPCs" + newIndex + " Females found:"+ FormIndex)
			Debug.Trace ("RBS2020: parsing NPCs" + newIndex + " Females found:"+ FormIndex)
			i = 0
		endif
	endwhile
	IndexFemales = FormIndex
	IndexFemales -=1 
	Debug.Trace ("RBS2020: parsing NPCs finished")
	MyFunction()
EndEvent

I am using functions from she SKSE Plugin AreYouthere to get all Actors that are loaded. That works even in my SKSE Plugin. The problem is now, that i don´t know how to get the form like i do it in Papyrus with (Game.GetForm). If i get the Form it has to be casted to an Actor or TESNPC and then in have to get the DefaultVoiceType of it.

This is the function (not working) in the SKSE Plugin
 

	VMResultArray<TESNPC*> GetFemaleActors(StaticFunctionTag* base) {
		VMResultArray<TESNPC*> ret;
		BeinzPluginNamespace::InitMods(0);
		UInt32 TotalActors = BeinzPluginNamespace::GetTotalActors(0);
		for (int i = 0; TotalActors; i++) {
			_MESSAGE("TotalActors %i", TotalActors);
			TESNPC* childForm = (TESNPC*)LookupFormByID(BeinzPluginNamespace::GetActorID(0, i)); //this seems to be not the right function to get the Form
			std::string test = childForm->actorData.voiceType->GetFullName();
			_MESSAGE("VoiceType %s", test);
			if (test.find("female") != std::string::npos) {
				ret.push_back(childForm);
			}
		}
		return (ret);
	}

Of course if we find a way to do it, i have to convert the morph code also to the SKSE Plugin. I was´nt able to get Skee compiled within my project.



#2
VadersApp

VadersApp

    Fan

  • Premium Member
  • 360 posts

I am getting further. Now the function returns 2501 NPCs, which can be handled by the Papyrus Script. GetSex ==-1 seems to deliver also some non female NPCs.

The problem now is, that the i can´t read any info from TESNPC, no weight, no name etc. The Form Array that is returned to the papyrus script works fine in the papyrus script. As before i am able to read different values like weight, height, etc. So the problem remains. How can i get weight and other infos from TESNPC in c++?

This returns 2501 Forms to papyrus:

 

VMResultArray<TESForm*> GetFemaleActors(StaticFunctionTag* base) {
        VMResultArray<TESForm*> ret;
        BeinzPluginNamespace::InitMods(0);
        UInt32 TotalActors = BeinzPluginNamespace::GetTotalActors(0);
        _MESSAGE("TotalActors %i", TotalActors);
        int counter = 0;
        for (int i = 0; i < TotalActors; i++) {
            UInt32 ActorID = BeinzPluginNamespace::GetActorID(0, i);
            if (ActorID > 0) {
                if (papyrusGame::GetFormEx(0, ActorID)) {
                    counter++;
                    TESForm* form = papyrusGame::GetFormEx(0, ActorID);
                    TESActorBase* ActorBase = (TESActorBase*) form;
                    TESNPC* npc = (TESNPC*)form;
                    //float weight =  npc->weight; // always 0
                    
                    BGSVoiceType* voiceType1 = ActorBase->actorData.voiceType;
                    BGSVoiceType* voiceType2 = npc->actorData.voiceType;
                    
                    //this crashs
                    if (voiceType2) {
                        if (voiceType2->GetFullName()) {
                            const char* vt2 = voiceType2->GetFullName();
                        }
                    }
                    
                    // this crashs
                    if (voiceType1) {
                        if (voiceType1->GetFullName()) {
                            const char* vt1 = voiceType1->GetFullName();
                        }
                    }
                    if (CALL_MEMBER_FN(npc, GetSex)()==-1) { //-1 Female, seems that there are male models, too
                        ret.push_back(form);
                    }
                }
            }
        }
        return (ret);
    }

 







Also tagged with one or more of these keywords: skse plugin, c++

Page loaded in: 1.018 seconds