Fork Pregnancy
Pregnancy Fork is an interoperability adapter layer that presents a single unified surface for modders to use.
Single surface interface to 2/3 backend pregnancy mods. Modders don't need to know anything about the underlying pregnancy mod a user has installed.
Another great feature of this approach is that expanding the system to include another pregnancy mod simply involves authoring a new backend interface. Once that backend interface is in place then any mod accessing pregnancy functions via MGF is automatically compatible with the new pregnancy mod without any changes on their end!
Highlights:
- Unified pregnancy events - _MGF_Preg_Conceived, _MGF_Preg_LaborStarted, _MGF_Preg_Birthed, _MGF_Preg_Aborted.
- Query functions - IsPregnant(), GetFathers(), GetFatherRaces(), GetPregnancyPercent(), GetTrimester(), GetCyclePhase().
- 'Action' functions - Impregnate(), ForceLabor(), Abort().
-
Faction Data:
- MGF_PregStatusFact. Rank -1/0 - Not pregnant. 1 -> First trimester. 2 -> Second trimester. 3 -> Third trimester.
- _MGF_PregActiveWithPcFact - This Npc is the Father of the player's current pregnancy.
- _MGF_PregConceivedWithPcFact - This Npc has conceived with a female player <FactionRank> times.
- _MGF_PregBirthedWithPcFact - This Npc has Fathered <FactionRank> babies with a female player.
Mods:
Fertility Mode v3 Fixes and Tweaks - Built, tested.
Beeing Female NG - Built, requires testing currently.
Fertility Mode Reloaded - In process.
Fertility Mode (base) and Beeing Female (base) - Unsupported.
_MGF_ForkPregnancy:
Scriptname _MGF_ForkPregnancy extends Quest ; Fork script for when you don't give a damn which pregnancy mod is installed ; and just want to ask common, conceptual questions about an actor. ; Currently covers: ; 1 - Beeing Female NG ; 2 - Fertility Mode v3 Fixes and Tweaks ; 3 - Fertility Mode Reloaded (not compatible with base Fertility Mode alone, ; or with the Fixes and Tweaks patch - pick one FM variant per game) ; Pregnancy mod you want not here? Write the interface script. Test it. Send it to me. ; NOTE: this Fork only carries the surface all three mods can answer. There will not always be overlap. ; ======================================================================================= ; Events ================================================================================= ; ======================================================================================= ; Unified conceptual-level events, fired regardless of which backend mod is active. ; RegisterForModEvent("_MGF_Preg_Conceived", "OnConceived") ; Event OnConceived(Form Mother, Form Father, Int NumBabies) ; Actor TheMother = Mother as Actor ; Actor TheFather = Father as Actor ; may be None - not every pregnancy has one on record ; EndEvent ; ; _MGF_Preg_Conceived - she just conceived -> (Form Mother, Form Father, Int NumBabies) ; _MGF_Preg_LaborStarted - labor has begun -> (Form Mother, Form Father, Int NumBabies) ; _MGF_Preg_Birthed - she has now given birth -> (Form Mother, Form Father, Int NumBabies, Form Baby) ; _MGF_Preg_Aborted - pregnancy ended without a birth -> (Form Mother, Form Father) ; _MGF_Preg_TriCycle_Complete - The trimester and menstrual cycle update has completed. ; IMPORTANT: BF has the concept of multiple Fathers - One pregnancy, multiple babies, different Fathers. ; The event only sends Fathers[0]. You'll need to call GetFathers(Mother) if you want all of them. ; FM = Single Father. ; Note: BF clears Father data on Abort/Birth so if you need them better get them on conception. ; Baby, on Birthed. ; BF - Some form. Need to investigate what this form is. ; FM - Nothing spawned until much later (baby grows up). Might be expandable. Also needs investigation. ; ======================================================================================= ; Queryable Data ======================================================================== ; ======================================================================================= ; Globals - _MGF_Globs ================================================================== ; _MGF_PcPreg_CurrentBabyCount - The number of babies the player is currently pregnant with. ; _MGF_PcPreg_CyclePhase - The player's current menstrual cycle phase. ; Factions - _MGF_Factions ============================================================== ; General: ; _MGF_PregStatusFact - Any actor (including the player). Rank 1-3 (trimester) while pregnant, removed on birth/abort. ; Npcs impregnated by the player: ; _MGF_PregConceivedByPcFact ; Rank = Number of times this actor has been conceived by the player, capped at 127. ; _MGF_PregBirthedByPcFact ; Rank = Number of times this actor has given birth by the player, capped at 127. ; _MGF_PregActiveByPcFact ; This Npc is currently pregnant by the player. ; Npcs that got the player pregnant: ; _MGF_PregActiveWithPcFact ; Player is currently carrying a pregnancy by this actor. There can be multiple Fathers with BF. (multiple babies, different Fathers) ; _MGF_PregConceivedWithPcFact ; Rank = Number of times this actor has conceived a pregnancy with the player, capped at 127. ; _MGF_PregBirthedWithPcFact ; Rank = Number of times this actor has fathered a birth with the player, capped at 127. ; Aliases =============================================================================== ; Impregnated player: ; 0 - Current father of the player's ongoing pregnancy. ; 1 - Father of the player's most recently CONCLUDED pregnancy (birth or abort). ; 2 - Father of the player's most recent actual BIRTH specifically. ; Impregnated by the player: ; 3 - 5 - The three most recent NPCs the player has conceived with (index 3 = latest) ; 6 - 8 - The three most recent NPCs the player has fathered a birth with (index 6 = latest) ; Rolling 100 element conception/birthed logs for the player. [0] = Newest. (Array.Length - 1) = Oldest. ; Impregnated player: ; GetConceivedWithPcLog() ; GetFatheredWithPcLog() ; Player impregnated: ; GetConceivedByPcLog() ; GetFatheredByPcLog() ; ======================================================================================= ; Plumbing ============================================================================== ; ======================================================================================= Import _MGF_ArrayCreate Import _MGF_ArrayEdit Import _MGF_ArrayQuery Event OnInit() Mods = New String[3] Mods[0] = "BeeingFemaleNG.esp" Mods[1] = "Fertility Mode 3 Fixes and Updates.esp" ; gating on the Fixes and Tweaks patch specifically - base Fertility Mode alone is no longer supported Mods[2] = "Fertility Mode.esm" ; informational only (see GetActiveMod() under State Fmr) - FMR itself is NOT gated on this, see CornerstoneScript below SetCyclePhaseNames() DecideState() RegisterForModEvent("_MGF_LoadOrderChanged", "On_MGF_LoadOrderChanged") ; For Status-board wiring RegisterForModEvent("_MGF_Preg_Conceived", "OnPregConceived") RegisterForModEvent("_MGF_Preg_Birthed", "OnPregBirthed") RegisterForModEvent("_MGF_Preg_Aborted", "OnPregAborted") ConceivedWithLog = ArrayActorCreate(0) BirthedWithLog = ArrayActorCreate(0) ConceivedWithMeLog = ArrayActorCreate(0) BirthedWithMeLog = ArrayActorCreate(0) CurrentlyPregnantByPc = ArrayActorCreate(0) AllCurrentlyPregnant = ArrayActorCreate(0) If GameTimeUpdatesAllowed() RegisterForSingleUpdateGameTime(PollIntervalHours) Else RegisterForModEvent("_MGF_MQ101_Stage240", "On_MGF_MQ101_Stage240") EndIf EndEvent Bool Function GameTimeUpdatesAllowed() Return (Game.GetFormFromFile(0x03372B, "Skyrim.esm") as Quest).GetStage() >= 240 ; MQ101 EndFunction Event On_MGF_MQ101_Stage240(String EventName, String StrArg, Float NumArg, Form Sender) UnRegisterForModEvent("_MGF_MQ101_Stage240") RegisterForSingleUpdateGameTime(PollIntervalHours) EndEvent Function SetCyclePhaseNames() CyclePhaseNames = ArrayStringCreate(4, "Follicular") CyclePhaseNames[1] = "Ovulation" CyclePhaseNames[2] = "Luteal" CyclePhaseNames[3] = "Menstruation" EndFunction Function IncrementFactionRankCapped(Actor Target, Faction Fact) Global ; Clamp faction rank increases to avoid wrap around. GetFactionRank returns ; -1 for an actor who isn't a member of Fact at all (not "rank -1"), so the ; first-ever occurrence needs to land on rank 1, not 0 - SetFactionRank(0) ; would otherwise silently add them to the faction at 0, one event short. If Target && Fact Int Rank = Target.GetFactionRank(Fact) If Rank == -1 Target.SetFactionRank(Fact, 1) ElseIf Rank < 127 Target.SetFactionRank(Fact, Rank + 1) EndIf EndIf EndFunction Function DecideState() If Game.GetModByName(Mods[0]) != 255 ; Beeing Female NG GoToState("Bf") ElseIf Game.GetModByName(Mods[1]) != 255 ; Fertility Mode (Fixes and Tweaks) GoToState("Fm") ElseIf _MGF_File.FileExists(CornerstoneScript) ; Fertility Mode Reloaded - no distinct plugin of its own, see _MGF_InterfaceFmr for why this checks a script file instead GoToState("Fmr") Else GoToState("") EndIf EndFunction Event On_MGF_LoadOrderChanged(Bool OrderChanged, Bool ModsAdded, Bool ModsRemoved, Bool ModsModified) ; Because FMR 'overwrites' FertilityMode.esm (and we don't support base FM) we can't ; gate on mod name here. Need to do a 'CornerstoneScript' check If ModsAdded || ModsRemoved DecideState() EndIf EndEvent ; Status board - event handlers ============================================== Event OnPregConceived(Form Mother, Form Father, Int NumBabies) Actor TheMother = Mother as Actor If !TheMother Return EndIf Actor TheFather = Father as Actor ; Any actor, any father. TheMother.SetFactionRank(Factions._MGF_PregStatusFact, 1) ; conception is always trimester 1 AllCurrentlyPregnant = ArrayActorAppend(AllCurrentlyPregnant, TheMother) ; She's the player. If TheMother == PlayerRef Globs._MGF_PcPreg_CurrentBabyCount.SetValue(NumBabies as Float) SetAliasTarget(AliasCurrentFather, TheFather as Form) ; BF's multi-father: BF records one entry per BABY. Deduplicate. CurrentFathersOfPc = ArrayActorUnique(GetFathers(PlayerRef)) Int i = 0 While i < CurrentFathersOfPc.Length Actor WithFather = CurrentFathersOfPc[i] IncrementFactionRankCapped(WithFather, Factions._MGF_PregConceivedWithPcFact) WithFather.SetFactionRank(Factions._MGF_PregActiveWithPcFact, 1) ConceivedWithMeLog = PushForwardActor(ConceivedWithMeLog, WithFather, DropOff = ConceivedWithMeLog.Length >= LogSize) i += 1 EndWhile EndIf If (ArrayActorFind(GetFathers(TheMother), PlayerRef) > -1) ; The player fathered this - checked against the full father list (BF's multi-father). IncrementFactionRankCapped(TheMother, Factions._MGF_PregConceivedByPcFact) TheMother.SetFactionRank(Factions._MGF_PregActiveByPcFact, 1) CurrentlyPregnantByPc = ArrayActorAppend(CurrentlyPregnantByPc, TheMother) ConceivedWithLog = PushForwardActor(ConceivedWithLog, TheMother, DropOff = ConceivedWithLog.Length >= LogSize) RefreshConceivedAliases() EndIf EndEvent Event OnPregBirthed(Form Mother, Form Father, Int NumBabies, Form Baby) Actor TheMother = Mother as Actor If !TheMother Return EndIf Actor TheFather = Father as Actor ; Any actor, any father. TheMother.RemoveFromFaction(Factions._MGF_PregStatusFact) AllCurrentlyPregnant = ArrayActorRemove(AllCurrentlyPregnant, TheMother) ; She's the player. If TheMother == PlayerRef Globs._MGF_PcPreg_CurrentBabyCount.SetValue(0.0) ; Read the CURRENT alias rather than trusting the event's own Father ; parameter - keeps one source of truth for what "current father" meant ; a moment ago, rather than two that could theoretically disagree. Actor ConcludedFather = (GetAlias(AliasCurrentFather) as ReferenceAlias).GetReference() as Actor SetAliasTarget(AliasPrevConcludedFather, ConcludedFather as Form) SetAliasTarget(AliasPrevBirthFather, ConcludedFather as Form) (GetAlias(AliasCurrentFather) as ReferenceAlias).Clear() ; Consuming the cache from conception, not re-querying GetFathers() - ; BF has already cleared its own father record for this pregnancy by ; now, so that call would return nothing. See CurrentFathersOfPc's ; declaration for why. Int i = 0 While i < CurrentFathersOfPc.Length Actor WithFather = CurrentFathersOfPc[i] If WithFather IncrementFactionRankCapped(WithFather, Factions._MGF_PregBirthedWithPcFact) WithFather.RemoveFromFaction(Factions._MGF_PregActiveWithPcFact) BirthedWithMeLog = PushForwardActor(BirthedWithMeLog, WithFather, DropOff = BirthedWithMeLog.Length >= LogSize) EndIf i += 1 EndWhile CurrentFathersOfPc = ArrayActorCreate(0) EndIf ; The player fathered this - checked via faction membership, not ; GetFathers(). By the time this fires, BF has already cleared its own ; father record for a concluded pregnancy, so re-querying here would ; silently return nothing. _MGF_PregActiveByPcFact was set at conception ; and lives on the actor independently of BF's own storage, so it survives ; that cleanup - read it BEFORE removing her from it. If TheMother.IsInFaction(Factions._MGF_PregActiveByPcFact) IncrementFactionRankCapped(TheMother, Factions._MGF_PregBirthedByPcFact) TheMother.RemoveFromFaction(Factions._MGF_PregActiveByPcFact) CurrentlyPregnantByPc = ArrayActorRemove(CurrentlyPregnantByPc, TheMother) BirthedWithLog = PushForwardActor(BirthedWithLog, TheMother, DropOff = BirthedWithLog.Length >= LogSize) RefreshBirthedAliases() EndIf EndEvent Event OnPregAborted(Form Mother, Form Father) Actor TheMother = Mother as Actor If !TheMother Return EndIf Actor TheFather = Father as Actor ; Any actor, any father. TheMother.RemoveFromFaction(Factions._MGF_PregStatusFact) AllCurrentlyPregnant = ArrayActorRemove(AllCurrentlyPregnant, TheMother) ; She's the player. If TheMother == PlayerRef Globs._MGF_PcPreg_CurrentBabyCount.SetValue(0.0) ; Only the "concluded" slot moves - an abortion isn't a birth, so ; AliasPrevBirthFather is deliberately left untouched here. Actor ConcludedFather = (GetAlias(AliasCurrentFather) as ReferenceAlias).GetReference() as Actor SetAliasTarget(AliasPrevConcludedFather, ConcludedFather as Form) (GetAlias(AliasCurrentFather) as ReferenceAlias).Clear() ; Same cache consumption as OnPregBirthed, minus any counter increment - ; an abortion isn't a birth, and conception already got its credit. Int WI = 0 While WI < CurrentFathersOfPc.Length Actor WithFather = CurrentFathersOfPc[WI] If WithFather WithFather.RemoveFromFaction(Factions._MGF_PregActiveWithPcFact) EndIf WI += 1 EndWhile CurrentFathersOfPc = ArrayActorCreate(0) EndIf ; The player fathered this - same reorder as OnPregBirthed, see its ; comment. No conceived/birthed counter change - she was already counted ; at conception, and an abortion isn't a birth. If TheMother.IsInFaction(Factions._MGF_PregActiveByPcFact) TheMother.RemoveFromFaction(Factions._MGF_PregActiveByPcFact) CurrentlyPregnantByPc = ArrayActorRemove(CurrentlyPregnantByPc, TheMother) EndIf EndEvent Function SetAliasTarget(Int AliasIndex, Form Target) ; ForceRefTo(None) is NOT how you clear an alias - Clear() is the actual ; function for that, and calling ForceRefTo with a None target doesn't ; reliably do the same thing. Centralized here because every write site ; below can legitimately receive a None (no father on record, a log slot ; that hasn't been filled yet, or a father who's since become ; unresolvable), and every one of them needs the same branch. ReferenceAlias TargetAlias = GetAlias(AliasIndex) as ReferenceAlias If !TargetAlias Return EndIf If Target TargetAlias.ForceRefTo(Target as ObjectReference) Else TargetAlias.Clear() EndIf EndFunction Function RefreshConceivedAliases() ; Index 0 is always the most recent - see PushForwardActor's semantics ; (inserts at index 0, shifts the rest back). Length can be under 3 early ; in a playthrough now that the log grows from empty rather than being ; pre-filled - bounds-checked so this never indexes past what actually ; exists yet. If ConceivedWithLog.Length > 0 SetAliasTarget(AliasConceived0, ConceivedWithLog[0]) EndIf If ConceivedWithLog.Length > 1 SetAliasTarget(AliasConceived1, ConceivedWithLog[1]) EndIf If ConceivedWithLog.Length > 2 SetAliasTarget(AliasConceived2, ConceivedWithLog[2]) EndIf EndFunction Function RefreshBirthedAliases() ; Same bounds-checking as RefreshConceivedAliases, same reason. If BirthedWithLog.Length > 0 SetAliasTarget(AliasBirthed0, BirthedWithLog[0]) EndIf If BirthedWithLog.Length > 1 SetAliasTarget(AliasBirthed1, BirthedWithLog[1]) EndIf If BirthedWithLog.Length > 2 SetAliasTarget(AliasBirthed2, BirthedWithLog[2]) EndIf EndFunction ; Status board =============================================================== Event OnUpdateGameTime() RunPregPoll() RegisterForSingleUpdateGameTime(PollIntervalHours) EndEvent Function RunPregPoll() ; Trimester/CyclePhase have no source event on any backend. ; Plain recurring poll - gives a single, simple accuracy guarantee. ; Trimester/Phase data can be 'stale' up to PollIntervalHours game hours. PollPlayerCycleState() PollAllPregnantTrimesters() SendModEvent("_MGF_Preg_TriCycle_Complete", strArg = "", numArg = 0.0) EndFunction Function PollPlayerCycleState() Globs._MGF_PcPreg_CyclePhase.SetValue(GetCyclePhase(PlayerRef) as Float) EndFunction Function PollAllPregnantTrimesters() ; Bounded by how many pregnancies are active right now, not by the size of ; either backend's full tracked-actor history. ; Filter None/dead actors. AllCurrentlyPregnant = ArrayActorSanitize(AllCurrentlyPregnant, FilterDisabled = false, FilterDead = true) Int i = 0 While i < AllCurrentlyPregnant.Length Int CurrentTrimester = GetTrimester(AllCurrentlyPregnant[i]) If CurrentTrimester > 0 AllCurrentlyPregnant[i].SetFactionRank(Factions._MGF_PregStatusFact, CurrentTrimester) Else ; Shouldn't normally happen but just in case. AllCurrentlyPregnant[i].RemoveFromFaction(Factions._MGF_PregStatusFact) EndIf i += 1 EndWhile EndFunction ; ======================================================================================= ; Events ================================================================================ ; ======================================================================================= Function RelayConceived(Actor Mother, Actor Father, Int NumBabies) Global If Mother Int Handle = ModEvent.Create("_MGF_Preg_Conceived") If Handle ModEvent.PushForm(Handle, Mother) ModEvent.PushForm(Handle, Father) ModEvent.PushInt(Handle, NumBabies) ModEvent.Send(Handle) EndIf EndIf EndFunction Function RelayLaborStarted(Actor Mother, Actor Father, Int NumBabies) Global If Mother Int Handle = ModEvent.Create("_MGF_Preg_LaborStarted") If Handle ModEvent.PushForm(Handle, Mother) ModEvent.PushForm(Handle, Father) ModEvent.PushInt(Handle, NumBabies) ModEvent.Send(Handle) EndIf EndIf EndFunction Function RelayBirthed(Actor Mother, Actor Father, Int NumBabies, Form Baby) Global If Mother Int Handle = ModEvent.Create("_MGF_Preg_Birthed") If Handle ModEvent.PushForm(Handle, Mother) ModEvent.PushForm(Handle, Father) ModEvent.PushInt(Handle, NumBabies) ModEvent.PushForm(Handle, Baby) ModEvent.Send(Handle) EndIf EndIf EndFunction Function RelayAborted(Actor Mother, Actor Father) Global If Mother Int Handle = ModEvent.Create("_MGF_Preg_Aborted") If Handle ModEvent.PushForm(Handle, Mother) ModEvent.PushForm(Handle, Father) ModEvent.Send(Handle) EndIf EndIf EndFunction ; ======================================================================================= ; Rolling Logs ========================================================================== ; ======================================================================================= ; Rolling 100 element logs of pregnancy events based around the player. ; Player got these actors pregnant ====================================================== Actor[] Function GetConceivedByPcLog(Bool FilterDisabled = true) ; NPCs the player has impregnated. Return ArrayActorSanitize(ConceivedWithLog, FilterDisabled, FilterDead = true) EndFunction Actor[] Function GetFatheredByPcLog(Bool FilterDisabled = true) ; NPCs the player has fathered a birth with. Return ArrayActorSanitize(BirthedWithLog, FilterDisabled, FilterDead = true) EndFunction ; Player got impregnated by these actors ================================================ Actor[] Function GetConceivedWithPcLog(Bool FilterDisabled = true) ; 'Men' who've conceived a pregnancy WITH the player Return ArrayActorSanitize(ConceivedWithMeLog, FilterDisabled, FilterDead = true) EndFunction Actor[] Function GetFatheredWithPcLog(Bool FilterDisabled = true) ; 'Men' who've fathered a birth WITH the player. Return ArrayActorSanitize(BirthedWithMeLog, FilterDisabled, FilterDead = true) EndFunction Actor[] Function GetCurrentlyPregnantByPc(Bool FilterDisabled = true) Return ArrayActorSanitize(CurrentlyPregnantByPc, FilterDisabled, FilterDead = true) EndFunction Actor[] Function GetAllCurrentlyPregnant(Bool FilterDisabled = true) Return ArrayActorSanitize(AllCurrentlyPregnant, FilterDisabled, FilterDead = true) EndFunction ; Fork state String Function GetActiveState() Return GetState() EndFunction String Function GetActiveMod() Return "" EndFunction ; ======================================================================================= ; User Functions ======================================================================== ; ======================================================================================= String Function GetCyclePhaseName(Actor Woman) ; Human-readable label for GetCyclePhase()'s numeric result. ; Not State dispatched - FM and BF use identical phase numbering. If IsPregnant(Woman) Return "Pregnant" EndIf ; Postpartum recovery is neither pregnant nor cycling. If IsInRecovery(Woman) Return "Recovering" EndIf Int Phase = GetCyclePhase(Woman) If Phase > -1 Return CyclePhaseNames[Phase] EndIf Return "Unknown" EndFunction State Bf String Function GetActiveMod() ; This backend's plugin filename. Return Mods[0] EndFunction Bool Function IsPregnant(Actor Woman) ; True if currently pregnant. Return Bf.IsPregnant(Woman) EndFunction Int Function GetNumBabies(Actor Woman) ; Babies in the current pregnancy. Return Bf.GetNumBabies(Woman) EndFunction Actor Function GetFather(Actor Woman) ; First recorded father. Return Bf.GetFather(Woman) EndFunction Actor[] Function GetFathers(Actor Woman) ; All recorded fathers - (BF's multi-Father mechanism) Return Bf.GetFathers(Woman) EndFunction Race Function GetFatherRace(Actor Woman) ; First recorded father's race. Return Bf.GetFatherRace(Woman) EndFunction Race[] Function GetFatherRaces(Actor Woman) ; Per-baby father races, index-aligned with GetFathers(). Return Bf.GetFatherRaces(Woman) EndFunction Float Function GetPregnancyDay(Actor Woman) ; Days since conception. Return Bf.GetPregnancyDay(Woman) EndFunction Float Function GetPregnancyDuration() ; Configured full-term length, in days. Return Bf.GetPregnancyDuration() EndFunction Float Function GetPregnancyPercent(Actor Woman) ; Progress through the pregnancy, 0-100. ; Value is not clamped at the upper end - Can return values > 100.0 ; Eg: 110.0 = Woman is '10%' overdue. Return Bf.GetPregnancyPercent(Woman) EndFunction Int Function GetTrimester(Actor Woman) ; 1/2/3, or 0 if not pregnant. Return Bf.GetTrimester(Woman) EndFunction Int Function GetCyclePhase(Actor Woman) ; 0-3, or -1 if pregnant/not tracked. Return Bf.GetCyclePhase(Woman) EndFunction Bool Function IsInRecovery(Actor Woman) ; True during the postpartum window after a birth, before cycling resumes. Return Bf.IsInRecovery(Woman) EndFunction Int Function GetCycleDuration(Actor Woman) ; BF's duration is actor/race scaled - ; A different Woman here can give a different answer (FM's version is the same for all). ; 0 if Woman isn't currently tracked/cycling. Return Bf.GetCycleDuration(Woman) EndFunction Float Function GetCyclePercent(Actor Woman) ; Progress through the current phase, 0 - 100. Return Bf.GetCyclePercent(Woman) EndFunction Float Function GetBabyHealthPercent(Actor Woman) ; Unborn baby's health, 0 - 100. Return Bf.GetBabyHealthPercent(Woman) EndFunction Int Function GetNumBirths(Actor Woman) ; Lifetime birth count. Return Bf.GetNumBirths(Woman) EndFunction Function Impregnate(Actor Mother, Actor Father, Int NumBabies = 1) ; NumBabies is honored here - unlike FM/FMR below. Bf.Impregnate(Mother, Father, NumBabies) EndFunction Function ForceLabor(Actor Woman) ; Skips straight to labor instead of waiting for term. Bf.ForceLabor(Woman) EndFunction Bool Function Abort(Actor Mother) ; Abort a pregnancy Return Bf.Abort(Mother) EndFunction EndState State Fm String Function GetActiveMod() ; This backend's plugin filename. Return Mods[1] EndFunction Bool Function IsPregnant(Actor Woman) ; True if currently pregnant. Return Fm.IsPregnant(Woman) EndFunction Int Function GetNumBabies(Actor Woman) ; Always 0 or 1 - FM only ever supports one baby per pregnancy. Return Fm.GetNumBabies(Woman) EndFunction Actor Function GetFather(Actor Woman) ; The recorded father. Return Fm.GetFather(Woman) EndFunction Actor[] Function GetFathers(Actor Woman) ; Always 0 or 1 entries - FM only ever has one father, wrapped in an array purely for parity with BF. Return Fm.GetFathers(Woman) EndFunction Race Function GetFatherRace(Actor Woman) ; The recorded father's race. Return Fm.GetFatherRace(Woman) EndFunction Race[] Function GetFatherRaces(Actor Woman) ; Always 0 or 1 entries - see GetFathers() above. Return Fm.GetFatherRaces(Woman) EndFunction Float Function GetPregnancyDay(Actor Woman) ; Days since conception. Return Fm.GetPregnancyDay(Woman) EndFunction Float Function GetPregnancyDuration() ; Configured full-term length, in days. Return Fm.GetPregnancyDuration() EndFunction Float Function GetPregnancyPercent(Actor Woman) ; Progress through the pregnancy, 0-100. ; Not clamped at the upper end. Values > 100.0 are possible. ; Eg: 110.0 = Mother is '10%' overdue Return Fm.GetPregnancyPercent(Woman) EndFunction Int Function GetTrimester(Actor Woman) ; 1/2/3, or 0 if not pregnant. Return Fm.GetTrimester(Woman) EndFunction Int Function GetCyclePhase(Actor Woman) ; 0-3, or -1 if pregnant/not tracked. Return Fm.GetCyclePhase(Woman) EndFunction Bool Function IsInRecovery(Actor Woman) ; True during the postpartum window after a birth, before cycling resumes. Return Fm.IsInRecovery(Woman) EndFunction Int Function GetCycleDuration(Actor Woman) ; FM's cycle duration is a flat value. BF's is not. (See BF's version) ; Parameter 'Woman' is here for function signature parity only. Return Fm.GetCycleDuration() EndFunction Float Function GetCyclePercent(Actor Woman) ; Progress through the whole cycle, 0-100. Return Fm.GetCyclePercent(Woman) EndFunction Float Function GetBabyHealthPercent(Actor Woman) ; Unborn baby's health, 0-100 - only ever tracked for the player. Return Fm.GetBabyHealthPercent(Woman) EndFunction Int Function GetNumBirths(Actor Woman) ; Lifetime birth count. Return Fm.GetNumBirths(Woman) EndFunction Function Impregnate(Actor Mother, Actor Father, Int NumBabies = 1) ; NumBabies is silently ignored here - FM only ever supports one baby per pregnancy. Fm.Impregnate(Mother, Father) EndFunction Function ForceLabor(Actor Woman) ; Skips straight to labor instead of waiting for term. Fm.ForceLabor(Woman) EndFunction Bool Function Abort(Actor Mother) ; Abort a pregnancy Return Fm.Abort(Mother) EndFunction EndState State Fmr String Function GetActiveMod() ; Informational only - not what gates this State. See CornerstoneScript ; below for the real detection. Return Mods[2] EndFunction Bool Function IsPregnant(Actor Woman) ; True if currently pregnant. Return Fmr.IsPregnant(Woman) EndFunction Int Function GetNumBabies(Actor Woman) ; Always 0 or 1 - FMR only ever supports one baby per pregnancy. Return Fmr.GetNumBabies(Woman) EndFunction Actor Function GetFather(Actor Woman) ; The recorded father. Return Fmr.GetFather(Woman) EndFunction Actor[] Function GetFathers(Actor Woman) ; Always 0 or 1 entries - same reason as FM's version above. Return Fmr.GetFathers(Woman) EndFunction Race Function GetFatherRace(Actor Woman) ; None, always - FMR never got this built (see _MGF_InterfaceFmr, which ; has no equivalent - sidelined along with the rest of FMR's newer ; work). Not a claim that FMR lacks the underlying data. Return None EndFunction Race[] Function GetFatherRaces(Actor Woman) ; Empty, always - see GetFatherRace() above. Return ArrayRaceCreate(0) EndFunction Float Function GetPregnancyDay(Actor Woman) ; Days since conception. Return Fmr.GetPregnancyDay(Woman) EndFunction Float Function GetPregnancyDuration() ; Configured full-term length, in days. Return Fmr.GetPregnancyDuration() EndFunction Float Function GetPregnancyPercent(Actor Woman) ; Progress through the pregnancy, 0-100. Return Fmr.GetPregnancyPercent(Woman) EndFunction Int Function GetTrimester(Actor Woman) ; 1/2/3, or 0 if not pregnant. Return Fmr.GetTrimester(Woman) EndFunction Int Function GetCyclePhase(Actor Woman) ; -1, always - FMR has no cycle-phase concept implemented on our side ; (see _MGF_InterfaceFmr, which never got this - sidelined along with ; the rest of FMR's labor/cycle work). Not the same claim as "FMR has ; no menstrual cycle" - we simply haven't built this for it yet. Return -1 EndFunction Bool Function IsInRecovery(Actor Woman) ; False, always - not built for FMR, same as GetCyclePhase() above. Return False EndFunction Int Function GetCycleDuration(Actor Woman) ; 0, always - see GetCyclePhase() above. Return 0 EndFunction Float Function GetCyclePercent(Actor Woman) ; -1.0, always - see GetCyclePhase() above. Return -1.0 EndFunction Float Function GetBabyHealthPercent(Actor Woman) ; Unborn baby's health, 0-100 - only ever tracked for the player. Return Fmr.GetBabyHealthPercent(Woman) EndFunction Int Function GetNumBirths(Actor Woman) ; -1, always - FMR doesn't track lifetime birth count at all, as far ; as we've been able to find (see _MGF_IntFmr.GetNumBirths). Different ; from BF/FM, where this is a real count. Return Fmr.GetNumBirths(Woman) EndFunction Function Impregnate(Actor Mother, Actor Father, Int NumBabies = 1) ; NumBabies is silently ignored here - same limitation as State Fm. Fmr.Impregnate(Mother, Father) EndFunction Function ForceLabor(Actor Woman) ; No-op, always - not built for FMR (see _MGF_InterfaceFmr, which has ; no equivalent - sidelined along with the rest of FMR's labor work, ; same as GetCyclePhase() above). EndFunction Bool Function Abort(Actor Mother) ; Abort a pregnancy Return Fmr.Abort(Mother) EndFunction EndState ; Empty state Functions ================================================= Bool Function IsPregnant(Actor Woman) Return false EndFunction Int Function GetNumBabies(Actor Woman) Return 0 EndFunction Actor Function GetFather(Actor Woman) Return None EndFunction Actor[] Function GetFathers(Actor Woman) Return ArrayActorCreate(0) EndFunction Race Function GetFatherRace(Actor Woman) Return None EndFunction Race[] Function GetFatherRaces(Actor Woman) Return ArrayRaceCreate(0) EndFunction Float Function GetPregnancyDay(Actor Woman) Return -1.0 EndFunction Float Function GetPregnancyDuration() Return 0.0 EndFunction Float Function GetPregnancyPercent(Actor Woman) Return 0.0 EndFunction Int Function GetTrimester(Actor Woman) Return 0 EndFunction Int Function GetCyclePhase(Actor Woman) Return -1 EndFunction Bool Function IsInRecovery(Actor Woman) Return False EndFunction Int Function GetCycleDuration(Actor Woman) Return 0 EndFunction Float Function GetCyclePercent(Actor Woman) Return -1.0 EndFunction Float Function GetBabyHealthPercent(Actor Woman) Return -1.0 EndFunction Int Function GetNumBirths(Actor Woman) Return 0 EndFunction Function Impregnate(Actor Mother, Actor Father, Int NumBabies = 1) ; No-op - neither mod is installed/active. EndFunction ; Ends a pregnancy without a birth. True only if there was one to end. Bool Function Abort(Actor Mother) Return False EndFunction Function ForceLabor(Actor Woman) ; No-op - neither mod is installed/active. EndFunction ; Debug ================================================================================= Function Test(Actor Woman) Debug.Trace("_MGF_ForkPregnancy: Test Begin") Debug.Trace("_MGF_ForkPregnancy: Active Mod: " + GetActiveMod()) Debug.Trace("_MGF_ForkPregnancy: Target: " + Woman) Debug.Trace("_MGF_ForkPregnancy: IsPregnant(): " + IsPregnant(Woman)) Debug.Trace("_MGF_ForkPregnancy: GetNumBabies(): " + GetNumBabies(Woman)) Debug.Trace("_MGF_ForkPregnancy: GetFather(): " + GetFather(Woman)) Debug.Trace("_MGF_ForkPregnancy: GetPregnancyDay(): " + GetPregnancyDay(Woman)) Debug.Trace("_MGF_ForkPregnancy: GetPregnancyDuration(): " + GetPregnancyDuration()) Debug.Trace("_MGF_ForkPregnancy: GetPregnancyPercent(): " + GetPregnancyPercent(Woman)) Debug.Trace("_MGF_ForkPregnancy: GetTrimester(): " + GetTrimester(Woman)) Debug.Trace("_MGF_ForkPregnancy: GetBabyHealthPercent(): " + GetBabyHealthPercent(Woman)) Debug.Trace("_MGF_ForkPregnancy: GetNumBirths(): " + GetNumBirths(Woman)) Debug.Trace("_MGF_ForkPregnancy: Test End") EndFunction ; Properties ============================================================================ String[] Mods ; FMR needs file-existence gating instead of a plugin-name check because it uses the same FertilityMode.esm as the base mod. String Property CornerstoneScript = "Data/Scripts/_JSW_BB_DetectFertilityLoader.pex" AutoReadOnly Hidden _MGF_InterfaceBf Property Bf Auto _MGF_InterfaceFm Property Fm Auto _MGF_InterfaceFmr Property Fmr Auto Actor Property PlayerRef Auto ; Status board =============================================================== _MGF_Globs Property Globs Auto _MGF_Factions Property Factions Auto ; Alias indices Int Property AliasCurrentFather = 0 AutoReadOnly Hidden Int Property AliasPrevConcludedFather = 1 AutoReadOnly Hidden Int Property AliasPrevBirthFather = 2 AutoReadOnly Hidden Int Property AliasConceived0 = 3 AutoReadOnly Hidden Int Property AliasConceived1 = 4 AutoReadOnly Hidden Int Property AliasConceived2 = 5 AutoReadOnly Hidden Int Property AliasBirthed0 = 6 AutoReadOnly Hidden Int Property AliasBirthed1 = 7 AutoReadOnly Hidden Int Property AliasBirthed2 = 8 AutoReadOnly Hidden ; Target window size for the four rolling logs. Int Property LogSize = 100 AutoReadOnly Hidden ; How often Trimester/CyclePhase/_MGF_PregStatusFact get re-checked. ; The system is accurate to within this window. Float Property PollIntervalHours = 1.0 AutoReadOnly Hidden ; Display names for menstrual cycle phases. String[] Property CyclePhaseNames Auto Hidden ; Log arrays: Actor[] ConceivedWithLog ; Player-fathered Actor[] BirthedWithLog ; Player-fathered Actor[] ConceivedWithMeLog ; 'Men' who conceived with the player Actor[] BirthedWithMeLog ; 'Men' who fathered a birth with the player Actor[] CurrentlyPregnantByPc ; live, player-fathered only Actor[] AllCurrentlyPregnant ; live, any father - drives _MGF_PregStatusFact's poll ; Exists specifically because BF clears its own father record before our ; poll-based Birthed detection ever fires, so re-querying GetFathers() at that point ; would return nothing. Actor[] CurrentFathersOfPc
Edited by Monoman1
0 Comments
Recommended Comments
There are no comments to display.