using System; using UnityEngine; using System.Collections.Generic; using System.Linq; namespace MVRPlugin { public class EggLayer : MVRScript { private class EggInfo { public Component vag; public Component labia; public float travelDistance; public float releaseTime; } private class PersonInfo { public Component vag; public Component labia; public float timeToNext; } private List spheres; private int nextSphere = 0; private List persons; private Dictionary sphereInfo = new Dictionary(); const float anusOffset = 0.07f; readonly private float speed = .05f; readonly private float minTimeBetweenEggs = 1.5f; readonly private float maxTimeBetweenEggs = 3.2f; readonly private float timeBeforeRelease = 1.5f; readonly private float forceMultiplier = 10000f; public override void Init() { try { //randomize the order on start spheres = SuperController.singleton.GetAtoms().Where(a => a.type == "ISSphere").ToList(); for (int i = 0; i < spheres.Count; i++) { Atom temp = spheres[i]; int rnd = UnityEngine.Random.Range(i, spheres.Count); spheres[i] = spheres[rnd]; spheres[rnd] = temp; } persons = SuperController.singleton.GetAtoms().Where(a => a.category == "People" && a.GetComponentInChildren().name.StartsWith("female")).Select(a => new PersonInfo { vag = a.GetComponentsInChildren(typeof(Transform)).Where(b => b.name == "VaginaTrigger").First(), labia = a.GetComponentsInChildren(typeof(Transform)).Where(b => b.name == "LabiaTrigger").First(), timeToNext = 0, }).ToList(); } catch (Exception e) { SuperController.LogError("Exception caught: " + e); } } void FixedUpdate() { try { //can't modify dictionaries while iterating over them Dictionary tempSphereInfo = new Dictionary(); foreach(KeyValuePair spherePair in sphereInfo) { Atom sphere = spherePair.Key; EggInfo eggInfo = spherePair.Value; eggInfo.travelDistance += speed * Time.fixedDeltaTime; Component vag = eggInfo.vag; // Vector3 vagDown = vag.transform.rotation * Vector3.down; Vector3 temp = (vag.transform.position) - (eggInfo.labia.transform.position + (eggInfo.labia.transform.up*anusOffset)); Vector3 vagDown = temp.normalized; bool colliding = false; eggInfo.labia.GetComponent().collidingWithDictionary.TryGetValue(sphere.GetComponentInChildren(), out colliding); //if colliding with LabiaTrigger or if farther up the vag than the position of the LabiaTrigger if (colliding || (eggInfo.releaseTime == timeBeforeRelease && Vector3.Dot(sphere.realRigidbodies.ElementAt(0).transform.position - eggInfo.labia.transform.position, vag.transform.position - eggInfo.labia.transform.position) > 0)) { sphere.mainController.currentRotationState = FreeControllerV3.RotationState.On; Vector3 forceVector = (vag.transform.position + vagDown * eggInfo.travelDistance) - sphere.realRigidbodies.ElementAt(0).transform.position; //only apply if sphere is too far up, not too far down if (Vector3.Dot(forceVector, vagDown) > 0) { float currentSpeed = Vector3.Dot(sphere.realRigidbodies.ElementAt(0).velocity, vagDown); sphere.GetComponentInChildren().AddForce(forceVector * forceMultiplier * (1 - Mathf.Clamp(currentSpeed / 10, 0f, speed) / speed)); } } else { sphere.mainController.currentRotationState = FreeControllerV3.RotationState.Off; eggInfo.releaseTime -= Time.fixedDeltaTime; } //don't stop tracking until we're sure the egg is free if (eggInfo.releaseTime > 0f) { tempSphereInfo.Add(sphere, eggInfo); } } for (int i = 0; i < persons.Count; i++) { persons[i].timeToNext -= Time.fixedDeltaTime; if (persons[i].timeToNext < 0) { persons[i].timeToNext = UnityEngine.Random.Range(minTimeBetweenEggs, maxTimeBetweenEggs); Atom sphere = spheres.ElementAt(nextSphere++); nextSphere %= spheres.Count; if (!sphereInfo.ContainsKey(sphere)) { EggInfo eggInfo = new EggInfo { travelDistance = 0f, vag = persons[i].vag, labia = persons[i].labia, releaseTime = timeBeforeRelease, }; Transform vag = eggInfo.vag.GetComponent(); //move all controllers, bodies, game objects, etc, etc sphere.mainController.physicsEnabled = false; sphere.mainController.transform.position = vag.position ; // Quaternion vagRotation = vag.rotation; Vector3 temp = (eggInfo.labia.transform.position + (eggInfo.labia.transform.up*anusOffset)) - (vag.position- (vag.up*anusOffset)); Vector3 vagDown = temp.normalized; Quaternion vagRotation = Quaternion.LookRotation(vagDown); sphere.mainController.transform.rotation = vagRotation; sphere.gameObject.transform.position = vag.position ; sphere.gameObject.transform.rotation = vagRotation; foreach (Rigidbody rb in sphere.rigidbodies) { rb.transform.position = vag.position ; rb.transform.rotation = vagRotation; rb.velocity = Vector3.zero; } sphere.mainController.currentPositionState = FreeControllerV3.PositionState.Off; sphere.mainController.currentRotationState = FreeControllerV3.RotationState.On; sphere.mainController.physicsEnabled = true; tempSphereInfo.Add(sphere, eggInfo); } } sphereInfo = tempSphereInfo; } } catch (Exception e) { SuperController.LogError("Exception caught: " + e); } } } }