From ea8d4da69ae36cdb75b764ae7a8d691dfdf12654 Mon Sep 17 00:00:00 2001
From: pregmodfan <pregmodfan@cock.li>
Date: Thu, 15 Feb 2018 23:28:59 +0200
Subject: [PATCH] initial JS for womb simulation added

---
 src/js/wombJS.tw | 133 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)
 create mode 100644 src/js/wombJS.tw

diff --git a/src/js/wombJS.tw b/src/js/wombJS.tw
new file mode 100644
index 00000000000..e597fda5b3c
--- /dev/null
+++ b/src/js/wombJS.tw
@@ -0,0 +1,133 @@
+:: wombJS [script]
+
+/*
+This is womb processor/simulator script. It's take care about calculation of belly sizes based on individual foetus sizes, 
+with full support of broodmothers implant random turning on and off possibility. Also this can be expanded to store more parents data in each individual fetus in future.
+Design limitations:
+- Mother can't gestate children with different speeds at same time. All speed changes apply to all fetuses.
+- Sizes of inividual fetuses updated only on call of WombGetVolume - not every time as called WombProgress. This is for better overail code speed.
+- For broodmothers we need actual "new ova release" code now. But it's possible to control how many children will be added each time, and so - how much children is ready to birth each time.
+
+Usage form sugarcube code (samples):
+
+WombInit($slave) - before first pregnancy, at slave creation, of as backward compatibility update.
+
+WombImpregnate($Slave, $fetus_count, $fatherID, $initial_age) - should be added after normal impregnation code, with already calcualted fetus count. ID of father - can be used in future for prcess children from different fathers in one pregnancy. Initial age normally 1 (as .preg normally set to 1), but can be raised if needed. Also should be called at time as broodmother implant add another fetus(es), or if new fetuses added from other sources in future (transplanting maybe?)
+
+WombProgress($slave, $time_to_add_to_fetuses) - after code that update $slave.preg, time to add should be the same.
+
+$isReady = WombBirthReady($slave, $birth_ready_age) - how many children ready to be birthed if their time to be ready is $birth_ready_age (40 is for normal length pregnancy). Return int - count of ready to birth children, or 0 if no ready exists. 
+
+$children = WombBirth($slave, $birth_ready_age) - for actual birth. Return array with fetuses objects that birthed (can be used in future) and remove them from womb array of $slave. Should be called at actual birth code in sugarcube. fetuses that not ready remained in womb (array).
+
+WombFlush($slave) - clean womb (array). Can be used at broodmother birthstorm or abortion situations in game. But birthstorm logicaly should use WombBirth($slave, 35) or so before - some children in this event is live capable, others is not.
+
+$slave.bellyPreg = WombGetWolume($slave) - return double, with current womb volume in CC - for updating $slave.bellyPreg, or if need to update individual fetuses sizes.
+*/
+
+window.WombInit = function(actor) //Init womb system.
+{
+    if (!actor.womb instanceof Array)
+    {
+	   actor.womb = [];
+    }
+
+    if (actor.womb.length != actor.pregType) //backward compatibility setup. Fully accurate for normal pregnancy only, sorry but for already present broodmothers it's too hard to calculate.
+    {
+        WombImpregnate(actor, actor.pregType, 0, actor.preg);
+    }
+}
+
+window.WombImpregnate = function(actor, fCount, fatherID, age)
+{
+    var i;
+    var tf;
+    for (i=0; i<fCount; i++)
+    {
+	tf = {}; //new Object
+    tf.age = age; //initial age
+    tf.fatherID = fatherID; //We can store who is father too.
+	tf.sex = Math.round(Math.random())+1; // 1 = male, 2 = female. For possible future usage, just as concept now.
+    tf.volume = 1; //Initial, to create property. Updated with actual data after WombGetVolume call.
+
+	actor.womb.push(tf);
+    }
+    
+}
+
+window.WombProgress = function(actor, ageToAdd)
+{
+    var ft;
+    for (ft in actor.womb)
+    {
+        rt.age += ageToAdd;
+    }
+}
+
+window.WombBirth = function(actor, readyAge)
+{
+    actor.womb.sort(function (a, b){return b.age - a.age}); //For normal processing fetuses that more old should be first. Now - they are.
+
+    var birthed = [];    
+    var ready = WombBirthReady(actor, readyAge);
+    var i;
+
+    for (i=0; i<ready; i++) //here can't be used "for .. in .." syntax.
+    {
+        birthed.push(actor.womb.shift());
+    }
+
+    return birthed;
+}
+
+window.WombFlush = function(actor)
+{
+    actor.womb = [];
+   
+}
+
+window.WombBirthReady = function(actor, readyAge)
+{
+
+    var ft;
+    var readyCnt = 0;
+    for (ft in actor.womb)
+    {
+        if (ft.age >= readyAge)
+            readyCnt++;
+    }
+
+    return readyCnt;
+}
+
+window.WombGetVolume = function(actor) //most code from pregJS.tw with minor adaptation.
+{
+    var ft;
+    var gestastionWeek;
+    var phi = 1.618;
+    var targetLen;
+    var wombSize = 0;
+    
+    for (ft in actor.womb)
+    {
+       gestastionWeek = ft.age;
+            
+        if(gestastionWeek <= 32) {
+            targetLen = ((0.00006396 * Math.pow(gestastionWeek, 4)) - (0.005501 * Math.pow(gestastionWeek, 3)) + (0.161 * Math.pow(gestastionWeek, 2)) - (0.76 * gestastionWeek) + 0.208);
+        } else if(gestastionWeek <= 106) {
+            targetLen = ((-0.0000004675 * Math.pow(gestastionWeek, 4)) + (0.0001905 * Math.pow(gestastionWeek, 3)) - (0.029 * Math.pow(gestastionWeek, 2)) + (2.132 * gestastionWeek) - 16.575);
+        } else {
+            targetLen = ((-0.00003266 * Math.pow(gestastionWeek,2)) + (0.076 * gestastionWeek) + 43.843);
+        }
+
+        ft.volume =((4 / 3) * (Math.PI) * (phi / 2) * (Math.pow((targetLen / 2), 3)));
+        
+        wombSize += ft.volume;
+    }
+  
+    if (wombSize < 0) //catch for strange cases, to avoid messing with outside code.
+        wombSize = 0;
+
+    return wombSize;
+}
+
-- 
GitLab