Esempio n. 1
0
        protected void setupInfoBox()
        {
            if (infoBox != null)
            {
                return;
            }

            try
            {
                getMaxTotalFuel();
                resourceBroker = new ResourceBroker();
                ResourceRatio[] inputs = inputList.ToArray();
                Color           clr;
                for (int index = 0; index < inputs.Length; index++)
                {
                    if (inputs[index].ResourceName == fuelGaugeResource)
                    {
                        infoBox = this.part.stackIcon.StageIcon.DisplayInfo();
                        infoBox.SetMessage(fuelGaugeResource);
                        clr   = XKCDColors.GreenYellow; //XKCDColors.BrightOlive;
                        clr.a = 0.55f;
                        infoBox.SetMsgTextColor(clr);
                        clr   = XKCDColors.Asparagus;
                        clr.a = 0.5f;
                        infoBox.SetMsgBgColor(clr);
                        infoBox.SetProgressBarBgColor(clr);
                        infoBox.Collapse();
                        break;
                    }
                }
            }
            catch { }
        }
Esempio n. 2
0
        private static void ProcessApiModule(Vessel v, ProtoPartSnapshot p, ProtoPartModuleSnapshot m,
                                             Part part_prefab, PartModule module_prefab, VesselResources resources, Dictionary <string, double> availableResources, List <KeyValuePair <string, double> > resourceChangeRequests, double elapsed_s)
        {
            resourceChangeRequests.Clear();

            try
            {
                string title = BackgroundDelegate.Instance(module_prefab).invoke(v, p, m, module_prefab, part_prefab, availableResources, resourceChangeRequests, elapsed_s);

                foreach (var cr in resourceChangeRequests)
                {
                    if (cr.Value > 0)
                    {
                        resources.Produce(v, cr.Key, cr.Value * elapsed_s, ResourceBroker.GetOrCreate(title));
                    }
                    else if (cr.Value < 0)
                    {
                        resources.Consume(v, cr.Key, -cr.Value * elapsed_s, ResourceBroker.GetOrCreate(title));
                    }
                }
            }
            catch (Exception ex)
            {
                Lib.Log("BackgroundUpdate in PartModule " + module_prefab.moduleName + " excepted: " + ex.Message + "\n" + ex.ToString());
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Deduct used amount from resource tanks
        /// </summary>
        internal void ProcessResources()
        {
            // Leave resource processing to Kerbalism if it is there
            if (DetectKerbalism.Found())
            {
                return;
            }

            IResourceBroker broker = new ResourceBroker();

            if (fuelCells.Use)
            {
                var iList = fuelCells.InputResources;
                for (int i = 0; i < iList.Count; i++)
                {
                    iList[i].MaximumAmountAvailable -= broker.RequestResource(vessel.rootPart, iList[i].Name, iList[i].CurrentAmountUsed, 1, ResourceFlowMode.ALL_VESSEL);
                    iList[i].CurrentAmountUsed       = 0;
                }
            }

            for (int i = 0; i < propellants.Count; i++)
            {
                propellants[i].MaximumAmountAvailable -= broker.RequestResource(vessel.rootPart, propellants[i].Name, propellants[i].CurrentAmountUsed, 1, ResourceFlowMode.ALL_VESSEL);
                propellants[i].CurrentAmountUsed       = 0;
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Activate autopilot
        /// </summary>
        internal override bool Activate()
        {
            if (vessel.situation != Vessel.Situations.SPLASHED)
            {
                ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_Splashed"), 5f).color = Color.yellow;
                return(false);
            }

            SystemCheck();

            // At least one engine must be on
            if (engineTestResult.maxThrustSum == 0)
            {
                ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_EnginesNotOnline"), 5f).color = Color.yellow;
                return(false);
            }

            // Get fuel amount
            IResourceBroker broker = new ResourceBroker();

            for (int i = 0; i < propellants.Count; i++)
            {
                propellants[i].MaximumAmountAvailable = broker.AmountAvailable(vessel.rootPart, propellants[i].Name, 1, ResourceFlowMode.ALL_VESSEL);

                if (propellants[i].MaximumAmountAvailable == 0)
                {
                    ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_NotEnoughFuel"), 5f).color = Color.yellow;
                    return(false);
                }
            }

            // Power production
            if (requiredPower > (electricPower_Solar + electricPower_Other))
            {
                // If required power is greater than total power generated, then average speed can be lowered up to 87% (square root of (1 - powerReduction))
                double powerReduction = (requiredPower - (electricPower_Solar + electricPower_Other)) / requiredPower;

                if (powerReduction > 0.75)
                {
                    ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_LowPowerShip"), 5f).color = Color.yellow;
                    return(false);
                }
            }

            BonVoyageModule module = vessel.FindPartModuleImplementing <BonVoyageModule>();

            if (module != null)
            {
                //vesselHeightFromTerrain = vessel.GetHeightFromSurface();
                vesselHeightFromTerrain = 0;

                module.averageSpeed        = averageSpeed;
                module.averageSpeedAtNight = averageSpeedAtNight;
                module.manned = manned;
                module.vesselHeightFromTerrain = vesselHeightFromTerrain;
            }

            return(base.Activate());
        }
 public OseModuleRecycler()
 {
     _queue = new WorkshopQueue();
     _broker = new ResourceBroker();
     _pauseTexture = WorkshopUtils.LoadTexture("Workshop/Assets/icon_pause");
     _playTexture = WorkshopUtils.LoadTexture("Workshop/Assets/icon_play");
     _binTexture = WorkshopUtils.LoadTexture("Workshop/Assets/icon_bin");
 }
Esempio n. 6
0
 public OseModuleRecycler()
 {
     _queue        = new WorkshopQueue();
     _broker       = new ResourceBroker();
     _pauseTexture = WorkshopUtils.LoadTexture("Workshop/Assets/Icons/icon_pause");
     _playTexture  = WorkshopUtils.LoadTexture("Workshop/Assets/Icons/icon_play");
     _binTexture   = WorkshopUtils.LoadTexture("Workshop/Assets/Icons/icon_bin");
 }
        public override void OnStart(StartState state)
        {
            base.OnStart(state);

            magnetTransforms = this.part.FindModelTransforms(magnetTransformName);
            if (magnetTransforms != null && magnetTransforms.Length > 0)
            {
                forcePerTransform = magnetForce / magnetTransforms.Length;
            }

            resourceBroker = new ResourceBroker();
            unitsPerUpdate = ecPerSec * TimeWarp.fixedDeltaTime;
        }
Esempio n. 8
0
        /// <summary>
        /// Deduct used amount from resource tanks
        /// </summary>
        internal void ProcessResources()
        {
            IResourceBroker broker = new ResourceBroker();

            if (fuelCells.Use)
            {
                var iList = fuelCells.InputResources;
                for (int i = 0; i < iList.Count; i++)
                {
                    iList[i].MaximumAmountAvailable -= broker.RequestResource(vessel.rootPart, iList[i].Name, iList[i].CurrentAmountUsed, 1, ResourceFlowMode.ALL_VESSEL);
                    iList[i].CurrentAmountUsed       = 0;
                }
            }
        }
Esempio n. 9
0
        public static void ProcessResources(Vessel v, List <KeyValuePair <string, double> > resources, string title)
        {
            ResourceBroker broker = ResourceBroker.GetOrCreate(title);

            foreach (var p in resources)
            {
                if (p.Value < 0)
                {
                    ResourceCache.Consume(v, p.Key, -p.Value, broker);
                }
                else
                {
                    ResourceCache.Produce(v, p.Key, p.Value, broker);
                }
            }
        }
Esempio n. 10
0
        public void UpdateResourceBrokers(Dictionary <ResourceBroker, double> brokersResAmount, Dictionary <ResourceBroker, double> ruleBrokersRate, double unsupportedBrokersRate, double elapsedSeconds)
        {
            ResourceBrokers.Clear();

            foreach (KeyValuePair <ResourceBroker, double> p in ruleBrokersRate)
            {
                ResourceBroker broker = ResourceBroker.GetOrCreate(p.Key.Id + "Avg", p.Key.Category, Lib.BuildString(p.Key.Title, " (", Local.Generic_AVERAGE, ")"));
                ResourceBrokers.Add(new ResourceBrokerRate(broker, p.Value));
            }
            foreach (KeyValuePair <ResourceBroker, double> p in brokersResAmount)
            {
                ResourceBrokers.Add(new ResourceBrokerRate(p.Key, p.Value / elapsedSeconds));
            }
            if (unsupportedBrokersRate != 0.0)
            {
                ResourceBrokers.Add(new ResourceBrokerRate(ResourceBroker.Generic, unsupportedBrokersRate));
            }
        }
 public override void OnAwake()
 {
     eList = part.GetComponentsInChildren<KSPParticleEmitter>();
     broker = new ResourceBroker();
     if (fuelList == null)
         return;
     var fl = fuelList.Split(';');
     Fuels = new PartResourceDefinition[fl.Length];
     for(int i = 0; i < fl.Length; i++)
     {
         var res = PartResourceLibrary.Instance.GetDefinition(fl[i]);
         if (res != null)
             Fuels[i] = res;
     }
     CurrentFuelIndex = 0;
     Fuel = Fuels[CurrentFuelIndex].name;
     base.OnAwake();
 }
Esempio n. 12
0
        public override void OnAwake()
        {
            eList  = part.GetComponentsInChildren <KSPParticleEmitter>();
            broker = new ResourceBroker();
            var fl = fuelList.Split(';');

            Fuels = new PartResourceDefinition[fl.Count()];
            for (int i = 0; i < fl.Count(); i++)
            {
                var res = PartResourceLibrary.Instance.GetDefinition(fl[i]);
                if (res != null)
                {
                    Fuels[i] = res;
                }
            }
            CurrentFuelIndex = 0;
            Fuel             = Fuels[CurrentFuelIndex].name;
            base.OnAwake();
        }
Esempio n. 13
0
 public ResourceBrokerRate(ResourceBroker broker, double amount)
 {
     this.broker = broker;
     this.rate   = amount;
 }
 private void SpawnExtraSupplies(float sup)
 {
     ResourceBroker.StoreResource(vessel.rootPart, "Supplies", sup, TimeWarp.deltaTime, ResourceFlowMode.ALL_VESSEL);
 }
Esempio n. 15
0
 public static void ProduceResource(Vessel v, string resource_name, double quantity, string title)
 {
     ResourceCache.Produce(v, resource_name, quantity, ResourceBroker.GetOrCreate(title));
 }
Esempio n. 16
0
        public Rule(ConfigNode node)
        {
            name              = Lib.ConfigValue(node, "name", string.Empty);
            title             = Lib.ConfigValue(node, "title", name);
            input             = Lib.ConfigValue(node, "input", string.Empty);
            output            = Lib.ConfigValue(node, "output", string.Empty);
            interval          = Lib.ConfigValue(node, "interval", 0.0);
            rate              = Lib.ConfigValue(node, "rate", 0.0);
            ratio             = Lib.ConfigValue(node, "ratio", 0.0);
            degeneration      = Lib.ConfigValue(node, "degeneration", 0.0);
            variance          = Lib.ConfigValue(node, "variance", 0.0);
            individuality     = Lib.ConfigValue(node, "individuality", 0.0);
            modifiers         = Lib.Tokenize(Lib.ConfigValue(node, "modifier", string.Empty), ',');
            breakdown         = Lib.ConfigValue(node, "breakdown", false);
            lifetime          = Lib.ConfigValue(node, "lifetime", false);
            warning_threshold = Lib.ConfigValue(node, "warning_threshold", 0.33);
            danger_threshold  = Lib.ConfigValue(node, "danger_threshold", 0.66);
            fatal_threshold   = Lib.ConfigValue(node, "fatal_threshold", 1.0);
            warning_message   = Lib.ConfigValue(node, "warning_message", string.Empty);
            danger_message    = Lib.ConfigValue(node, "danger_message", string.Empty);
            fatal_message     = Lib.ConfigValue(node, "fatal_message", string.Empty);
            relax_message     = Lib.ConfigValue(node, "relax_message", string.Empty);
            broker            = ResourceBroker.GetOrCreate(name, ResourceBroker.BrokerCategory.Kerbal, title);

            if (warning_message.Length > 0 && warning_message[0] == '#')
            {
                Lib.Log("Broken translation: " + warning_message, Lib.LogLevel.Warning);
            }
            if (danger_message.Length > 0 && danger_message[0] == '#')
            {
                Lib.Log("Broken translation: " + danger_message, Lib.LogLevel.Warning);
            }
            if (fatal_message.Length > 0 && fatal_message[0] == '#')
            {
                Lib.Log("Broken translation: " + fatal_message, Lib.LogLevel.Warning);
            }
            if (relax_message.Length > 0 && relax_message[0] == '#')
            {
                Lib.Log("Broken translation: " + relax_message, Lib.LogLevel.Warning);
            }

            // check that name is specified
            if (name.Length == 0)
            {
                throw new Exception("skipping unnamed rule");
            }

            // check that degeneration is not zero
            if (degeneration <= double.Epsilon)
            {
                throw new Exception("skipping zero degeneration rule");
            }

            // check that resources exist
            if (input.Length > 0 && Lib.GetDefinition(input) == null)
            {
                throw new Exception("resource '" + input + "' doesn't exist");
            }
            if (output.Length > 0 && Lib.GetDefinition(output) == null)
            {
                throw new Exception("resource '" + output + "' doesn't exist");
            }

            // calculate ratio of input vs output resource
            if (input.Length > 0 && output.Length > 0 && ratio <= double.Epsilon)
            {
                var input_density  = Lib.GetDefinition(input).density;
                var output_density = Lib.GetDefinition(output).density;
                ratio = Math.Min(input_density, output_density) > double.Epsilon ? input_density / output_density : 1.0;
            }
        }
        public void FixedUpdate()
        {
            if (!HighLogic.LoadedSceneIsFlight || vessel == null || !vessel.loaded)
            {
                return;
            }

            if (vessel.isEVA)
            {
                CheckEVA(vessel);
                return;
            }

            if (_partCount != vessel.parts.Count)
            {
                if (_partCount > 0)
                {
                    _isStatusRefreshRequired = true;
                }
                _partCount = vessel.parts.Count;
            }

            if (_isDirty)
            {
                _isDirty = false;
                UpdateVesselInfo();
                UpdateStatus();
            }

            var now = Planetarium.GetUniversalTime();

            if (_currentCrewCount == 0)
            {
                VesselStatus.VesselName  = vessel.vesselName;
                VesselStatus.NumCrew     = vessel.GetCrewCount();
                VesselStatus.CrewCap     = vessel.GetCrewCapacity();
                VesselStatus.LastECCheck = now;
                VesselStatus.LastFeeding = now;
                VesselStatus.LastUpdate  = now;

                LifeSupportManager.Instance.TrackVessel(VesselStatus);
                LastUpdateTime = now;

                return;
            }

            try
            {
                bool isLongLoop = false;
                var  offKerbin  = !LifeSupportManager.IsOnKerbin(vessel);
                CheckVesselId();

                // Check our time
                double deltaTime = GetDeltaTime();
                bool   isCatchup = deltaTime / 2 > TimeWarp.fixedDeltaTime;

                if (deltaTime < ResourceUtilities.FLOAT_TOLERANCE * 10)
                {
                    return;
                }

                if (now >= _lastProcessingTime + _checkInterval)
                {
                    isLongLoop          = true;
                    _lastProcessingTime = now;
                }

                VesselStatus.LastUpdate = now;
                VesselStatus.VesselName = vessel.vesselName;
                VesselStatus.NumCrew    = vessel.GetCrewCount();
                VesselStatus.CrewCap    = vessel.GetCrewCapacity();

                if (isLongLoop)
                {
                    CheckForDeadKerbals();
                }

                if (_currentCrewCount > 0)
                {
                    //Guard clause
                    if (_crewPart == null)
                    {
                        UpdateVesselInfo();
                    }

                    //we will add a bit of a fudge factor for supplies
                    var tolerance = deltaTime / 2f;

                    //nom nom nom!
                    ConverterResults resultSupply = Converter.ProcessRecipe(deltaTime, SupplyRecipe, _crewPart, null, 1f);
                    ConverterResults resultEC     = Converter.ProcessRecipe(deltaTime, ECRecipe, _crewPart, null, 1f);

                    #region Long Loop - Crew
                    if (isLongLoop)
                    {
                        //Ensure status is current
                        UpdateStatus();

                        var habTime = LifeSupportManager.GetTotalHabTime(VesselStatus, vessel);

                        if (_oldHabChecksum < ResourceUtilities.FLOAT_TOLERANCE)
                        {
                            _oldHabChecksum = LifeSupportManager.GetHabChecksum(VesselStatus, vessel);
                        }

                        var newHabChecksum = LifeSupportManager.GetHabChecksum(VesselStatus, vessel);
                        if (Math.Abs(_oldHabChecksum - newHabChecksum) > ResourceUtilities.FLOAT_TOLERANCE)
                        {
                            Debug.Log("[USI-LS] Vessel situation changed, refreshing life support");
                            _isStatusRefreshRequired = true;
                            _oldHabChecksum          = newHabChecksum;
                        }

                        var crewRoster = vessel.GetVesselCrew();
                        var count      = crewRoster.Count;
                        for (int i = 0; i < count; ++i)
                        {
                            var  crewMember        = crewRoster[i];
                            bool isGrouchyHab      = false;
                            bool isGrouchySupplies = false;
                            bool isGrouchyEC       = false;
                            bool isScout           = crewMember.HasEffect("ExplorerSkill") && habTime >= LifeSupportScenario.Instance.settings.GetSettings().ScoutHabTime;
                            bool isPermaHab        = habTime >= LifeSupportScenario.Instance.settings.GetSettings().PermaHabTime;
                            bool isHomeWorld       = CheckIfHomeWorld() && habTime >= LifeSupportScenario.Instance.settings.GetSettings().ScoutHabTime&& vessel.LandedOrSplashed;

                            // Get the crew member's life support stats
                            var trackedKerbal = LifeSupportManager.Instance.FetchKerbal(crewMember);

                            // Update life support stats
                            if (_isStatusRefreshRequired)
                            {
                                trackedKerbal.TimeEnteredVessel = now;
                                _isStatusRefreshRequired        = false;
                                LifeSupportManager.Instance.TrackKerbal(trackedKerbal);
                            }

                            // Update Hab effects
                            if (!offKerbin || isScout || isHomeWorld || isPermaHab)
                            {
                                trackedKerbal.TimeEnteredVessel = now;
                                trackedKerbal.LastAtHome        = now;
                                trackedKerbal.MaxOffKerbinTime  = habTime + trackedKerbal.LastAtHome;
                            }
                            else
                            {
                                if (vessel.id.ToString() != trackedKerbal.CurrentVesselId)
                                {
                                    if (vessel.id.ToString() != trackedKerbal.PreviousVesselId)
                                    {
                                        trackedKerbal.TimeEnteredVessel = now;
                                    }

                                    trackedKerbal.PreviousVesselId = trackedKerbal.CurrentVesselId;
                                    trackedKerbal.CurrentVesselId  = vessel.id.ToString();
                                    LifeSupportManager.Instance.TrackKerbal(trackedKerbal);
                                }

                                isGrouchyHab = CheckHabSideEffects(trackedKerbal);
                            }

                            // Update Supplies effects
                            if (offKerbin && (deltaTime - resultSupply.TimeFactor > tolerance))
                            {
                                isGrouchySupplies = CheckSupplySideEffects(trackedKerbal);
                            }
                            else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE)
                            {
                                //All is well
                                trackedKerbal.LastMeal   = LastUpdateTime;
                                VesselStatus.LastFeeding = LastUpdateTime;
                            }

                            // Update ElectricCharge effects
                            if (offKerbin && (deltaTime - resultEC.TimeFactor > tolerance))
                            {
                                isGrouchyEC = CheckECSideEffects(trackedKerbal);
                            }
                            else if (deltaTime >= ResourceUtilities.FLOAT_TOLERANCE)
                            {
                                //All is well
                                trackedKerbal.LastEC     = LastUpdateTime;
                                VesselStatus.LastECCheck = LastUpdateTime;
                            }

                            trackedKerbal.LastUpdate = now;

                            var isAnyGrouch = isGrouchyEC || isGrouchyHab || isGrouchySupplies;
                            if (isGrouchyEC && !isCatchup)
                            {
                                ApplyEffect(
                                    trackedKerbal,
                                    crewMember,
                                    LifeSupportManager.GetNoECEffect(trackedKerbal.KerbalName),
                                    "power loss");
                            }
                            else if (isGrouchySupplies && !isCatchup)
                            {
                                ApplyEffect(
                                    trackedKerbal,
                                    crewMember,
                                    LifeSupportManager.GetNoSupplyEffect(trackedKerbal.KerbalName),
                                    "lack of supplies");
                            }
                            else if (isGrouchyHab && !isCatchup)
                            {
                                ApplyEffect(
                                    trackedKerbal,
                                    crewMember,
                                    LifeSupportManager.GetNoHomeEffect(trackedKerbal.KerbalName),
                                    "homesickness");
                            }
                            else if (crewMember.experienceTrait.Config.Name != trackedKerbal.OldTrait && !isAnyGrouch)
                            {
                                RemoveGrouchiness(crewMember, trackedKerbal);
                            }

                            LifeSupportManager.Instance.TrackKerbal(trackedKerbal);
                        }
                    }
                    #endregion - Crew

                    var remainingSupplies = ResourceBroker.AmountAvailable(
                        _crewPart,
                        "Supplies",
                        deltaTime,
                        ResourceFlowMode.ALL_VESSEL);
                    var remainingBattery = ResourceBroker.AmountAvailable(
                        _crewPart,
                        "ElectricCharge",
                        deltaTime,
                        ResourceFlowMode.ALL_VESSEL);
                    var suppliesConsumption    = LifeSupportScenario.Instance.settings.GetSettings().SupplyAmount;
                    var electricityConsumption = LifeSupportScenario.Instance.settings.GetSettings().ECAmount;

                    VesselStatus.SuppliesLeft = remainingSupplies / suppliesConsumption / _currentCrewCount / VesselStatus.RecyclerMultiplier;
                    VesselStatus.ECLeft       = remainingBattery / electricityConsumption / _currentCrewCount;
                }
                else
                {
                    VesselStatus.LastECCheck = now;
                    VesselStatus.LastFeeding = now;
                    VesselStatus.LastUpdate  = now;
                }

                LifeSupportManager.Instance.TrackVessel(VesselStatus);
            }
            catch (Exception ex)
            {
                print(string.Format("ERROR {0} IN ModuleLifeSupport", ex.Message));
            }
        }
Esempio n. 18
0
        public Process(ConfigNode node)
        {
            name      = Lib.ConfigValue(node, "name", string.Empty);
            title     = Lib.ConfigValue(node, "title", name);
            broker    = ResourceBroker.GetOrCreate(name, ResourceBroker.BrokerCategory.Converter, title);
            modifiers = Lib.Tokenize(Lib.ConfigValue(node, "modifier", string.Empty), ',');

            // check that name is specified
            if (name.Length == 0)
            {
                throw new Exception("skipping unnamed process");
            }

            // fix for https://github.com/JadeOfMaar/RationalResources/issues/25
            bool skip_resources_validity_check = Lib.ConfigValue(node, "skip_resources_validity_check", false);

            inputs = new Dictionary <string, double>();
            foreach (string input in node.GetValues("input"))
            {
                // get parameters
                List <string> tok = Lib.Tokenize(input, '@');
                if (tok.Count != 2)
                {
                    throw new Exception("malformed input on process " + name);
                }
                string input_res  = tok[0];
                double input_rate = Lib.Parse.ToDouble(tok[1]);

                // check that resource is specified
                if (input_res.Length == 0)
                {
                    throw new Exception("skipping resource-less process " + name);
                }

                // check that resource exist
                if (skip_resources_validity_check || Lib.GetDefinition(input_res) == null)
                {
                    throw new Exception("resource " + input_res + " doesn't exist for process " + name);
                }

                // record input
                inputs[input_res] = input_rate;
            }

            outputs = new Dictionary <string, double>();
            foreach (string output in node.GetValues("output"))
            {
                // get parameters
                List <string> tok = Lib.Tokenize(output, '@');
                if (tok.Count != 2)
                {
                    throw new Exception("malformed output on process " + name);
                }
                string output_res  = tok[0];
                double output_rate = Lib.Parse.ToDouble(tok[1]);

                // check that resource is specified
                if (output_res.Length == 0)
                {
                    throw new Exception("skipping resource-less process " + name);
                }

                // check that resource exist
                if (skip_resources_validity_check || Lib.GetDefinition(output_res) == null)
                {
                    throw new Exception("resource " + output_res + " doesn't exist for process " + name);
                }

                // record output
                outputs[output_res] = output_rate;
            }

            cures = new Dictionary <string, double>();
            foreach (string output in node.GetValues("cures"))
            {
                // get parameters
                List <string> tok = Lib.Tokenize(output, '@');
                if (tok.Count != 2)
                {
                    throw new Exception("malformed cure on process " + name);
                }
                string cure      = tok[0];
                double cure_rate = Lib.Parse.ToDouble(tok[1]);

                // check that resource is specified
                if (cure.Length == 0)
                {
                    throw new Exception("skipping resource-less process " + name);
                }

                // record cure
                cures[cure] = cure_rate;
            }

            // parse dump specs
            dump = new DumpSpecs(Lib.ConfigValue(node, "dump", "false"), Lib.ConfigValue(node, "dump_valve", "false"));
        }
Esempio n. 19
0
        /// <summary>
        /// Check the systems
        /// </summary>
        internal override void SystemCheck()
        {
            base.SystemCheck();

            // Test stock wheels
            WheelTestResult testResultStockWheels = CheckStockWheels();
            // Test KSPWheels
            WheelTestResult testResultKSPkWheels = CheckKSPWheels();

            // Sum it
            wheelTestResult.powerRequired  = testResultStockWheels.powerRequired + testResultKSPkWheels.powerRequired;
            wheelTestResult.maxSpeedSum    = testResultStockWheels.maxSpeedSum + testResultKSPkWheels.maxSpeedSum;
            wheelTestResult.inTheAir       = testResultStockWheels.inTheAir + testResultKSPkWheels.inTheAir;
            wheelTestResult.operable       = testResultStockWheels.operable + testResultKSPkWheels.operable;
            wheelTestResult.damaged        = testResultStockWheels.damaged + testResultKSPkWheels.damaged;
            wheelTestResult.online         = testResultStockWheels.online + testResultKSPkWheels.online;
            wheelTestResult.maxWheelRadius = testResultStockWheels.maxWheelRadius + testResultKSPkWheels.maxWheelRadius;

            // Generally, moving at high speed requires less power than wheels' max consumption. Maximum required power of controller will 35% of wheels power requirement
            requiredPower = wheelTestResult.powerRequired / 100 * 35;

            // Get available EC from batteries
            if (batteries.UseBatteries)
            {
                batteries.MaxAvailableEC = GetAvailableEC_Batteries();
            }
            else
            {
                batteries.MaxAvailableEC = 0;
            }

            // Get available EC from fuell cells
            fuelCells.OutputValue = 0;
            fuelCells.InputResources.Clear();
            if (fuelCells.Use)
            {
                List <ModuleResourceConverter> mrc = vessel.FindPartModulesImplementing <ModuleResourceConverter>();
                for (int i = 0; i < mrc.Count; i++)
                {
                    double ecRatio = 0;
                    try
                    {
                        var ec = mrc[i].outputList.Find(x => x.ResourceName == "ElectricCharge"); // NullArgumentException when not found
                        ecRatio = ec.Ratio;
                    }
                    catch { }

                    if (ecRatio > 0)
                    {
                        // Add input resources
                        var iList = mrc[i].inputList;
                        for (int r = 0; r < iList.Count; r++)
                        {
                            // Check if we have fuel for converter. If not, then continue without adding output ratio.
                            if (!CheatOptions.InfinitePropellant && r == 0)
                            {
                                IResourceBroker broker = new ResourceBroker();
                                if (broker.AmountAvailable(vessel.rootPart, iList[r].ResourceName, 1, ResourceFlowMode.ALL_VESSEL) == 0)
                                {
                                    break;
                                }
                            }

                            var ir = fuelCells.InputResources.Find(x => x.Name == iList[r].ResourceName);
                            if (ir == null)
                            {
                                ir      = new Resource();
                                ir.Name = iList[r].ResourceName;
                                fuelCells.InputResources.Add(ir);
                            }
                            ir.Ratio += iList[r].Ratio;

                            // Add EC ration to output
                            if (r == 0)
                            {
                                fuelCells.OutputValue += ecRatio;
                            }
                        }
                    }
                }
            }
            electricPower_Other += fuelCells.OutputValue;

            // Cheats
            if (CheatOptions.InfiniteElectricity)
            {
                electricPower_Other = requiredPower;
            }

            // Manned
            manned = (vessel.GetCrewCount() > 0);

            // Pilots and Scouts (USI) increase base average speed
            crewSpeedBonus = 0;
            if (manned)
            {
                int maxPilotLevel  = -1;
                int maxScoutLevel  = -1;
                int maxDriverLevel = -1;

                List <ProtoCrewMember> crewList = vessel.GetVesselCrew();
                for (int i = 0; i < crewList.Count; i++)
                {
                    switch (crewList[i].trait)
                    {
                    case "Pilot":
                        if (maxPilotLevel < crewList[i].experienceLevel)
                        {
                            maxPilotLevel = crewList[i].experienceLevel;
                        }
                        break;

                    case "Scout":
                        if (maxScoutLevel < crewList[i].experienceLevel)
                        {
                            maxScoutLevel = crewList[i].experienceLevel;
                        }
                        break;

                    default:
                        if (crewList[i].HasEffect("AutopilotSkill"))
                        {
                            if (maxDriverLevel < crewList[i].experienceLevel)
                            {
                                maxDriverLevel = crewList[i].experienceLevel;
                            }
                        }
                        break;
                    }
                }
                if (maxPilotLevel > 0)
                {
                    crewSpeedBonus = 6 * maxPilotLevel; // up to 30% for a Pilot
                }
                else if (maxDriverLevel > 0)
                {
                    crewSpeedBonus = 4 * maxDriverLevel; // up to 20% for any driver (has AutopilotSkill skill)
                }
                else if (maxScoutLevel > 0)
                {
                    crewSpeedBonus = 2 * maxScoutLevel; // up to 10% for a Scout (Scouts disregard safety)
                }
            }

            // Average speed will vary depending on number of wheels online and crew present from 50 to 95 percent of average wheels' max speed
            if (wheelTestResult.online != 0)
            {
                maxSpeedBase             = wheelTestResult.maxSpeedSum / wheelTestResult.online;
                wheelsPercentualModifier = Math.Min(70, (40 + 5 * wheelTestResult.online));
                averageSpeed             = maxSpeedBase * Convert.ToDouble(wheelsPercentualModifier) / 100 * (1 + Convert.ToDouble(crewSpeedBonus) / 100);
            }
            else
            {
                averageSpeed = 0;
            }

            // Unmanned rovers drive with the speed penalty based on available tech
            if (!manned)
            {
                averageSpeed = averageSpeed * (100 - Convert.ToDouble(GetUnmannedSpeedPenalty())) / 100;
            }

            // Base average speed at night is the same as average speed, if there is other power source. Zero otherwise.
            if (electricPower_Other > 0.0)
            {
                averageSpeedAtNight = averageSpeed;
            }
            else
            {
                averageSpeedAtNight = 0;
            }

            // If required power is greater then total power generated, then average speed can be lowered up to 75%
            if (requiredPower > (electricPower_Solar + electricPower_Other))
            {
                double speedReduction = (requiredPower - (electricPower_Solar + electricPower_Other)) / requiredPower;
                if (speedReduction <= 0.75)
                {
                    averageSpeed = averageSpeed * (1 - speedReduction);
                }
            }

            // If required power is greater then other power generated, then average speed at night can be lowered up to 75%
            if (requiredPower > electricPower_Other)
            {
                double speedReduction = (requiredPower - electricPower_Other) / requiredPower;
                if (speedReduction <= 0.75)
                {
                    averageSpeedAtNight = averageSpeedAtNight * (1 - speedReduction);
                }
                else
                {
                    averageSpeedAtNight = 0;
                }
            }

            // If we are using batteries, compute for how long and how much EC we can use
            if (batteries.UseBatteries)
            {
                batteries.MaxUsedEC            = 0;
                batteries.ECPerSecondConsumed  = 0;
                batteries.ECPerSecondGenerated = 0;

                // We have enough of solar power to recharge batteries
                if (requiredPower < (electricPower_Solar + electricPower_Other))
                {
                    batteries.ECPerSecondConsumed = Math.Max(requiredPower - electricPower_Other, 0); // If there is more other power than required power, we don't need batteries
                    batteries.MaxUsedEC           = batteries.MaxAvailableEC / 2;                     // We are using only half of max available EC
                    if (batteries.ECPerSecondConsumed > 0)
                    {
                        double halfday = vessel.mainBody.rotationPeriod / 2;                                                      // in seconds
                        batteries.ECPerSecondGenerated = electricPower_Solar + electricPower_Other - requiredPower;
                        batteries.MaxUsedEC            = Math.Min(batteries.MaxUsedEC, batteries.ECPerSecondConsumed * halfday);  // get lesser value of MaxUsedEC and EC consumed per night
                        batteries.MaxUsedEC            = Math.Min(batteries.MaxUsedEC, batteries.ECPerSecondGenerated * halfday); // get lesser value of MaxUsedEC and max EC available for recharge during a day
                    }
                }

                if (batteries.MaxUsedEC > 0)
                {
                    batteries.CurrentEC = batteries.MaxUsedEC; // We are starting at full available capacity
                }
                else
                {
                    UseBatteriesChanged(false);
                    ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_CantUseBatteries") + " " + Localizer.Format("#LOC_BV_Warning_LowPowerRover") + ".", 5f).color = Color.yellow;
                }
            }
        }
Esempio n. 20
0
 public ResourceTransferTarget(Vessel vessel)
 {
     _broker    = new ResourceBroker();
     _vessel    = vessel;
     _resources = GetResourceMetadata(vessel.parts);
 }
Esempio n. 21
0
        /// <summary>
        /// Activate autopilot
        /// </summary>
        internal override bool Activate()
        {
            if (vessel.situation != Vessel.Situations.LANDED && vessel.situation != Vessel.Situations.PRELAUNCH)
            {
                ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_Landed"), 5f).color = Color.yellow;
                return(false);
            }

            SystemCheck();

            // No driving until at least 3 operable wheels are touching the ground - tricycles are allowed
            if ((wheelTestResult.inTheAir > 0) && (wheelTestResult.operable < 3))
            {
                ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_WheelsNotTouching"), 5f).color = Color.yellow;
                return(false);
            }
            if (wheelTestResult.operable < 3)
            {
                ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_WheelsNotOperable"), 5f).color = Color.yellow;
                return(false);
            }

            // At least 2 wheels must be on
            if (wheelTestResult.online < 2)
            {
                ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_WheelsNotOnline"), 5f).color = Color.yellow;
                return(false);
            }

            // Get fuel amount if fuel cells are used
            if (fuelCells.Use && !CheatOptions.InfinitePropellant)
            {
                IResourceBroker broker = new ResourceBroker();
                var             iList  = fuelCells.InputResources;
                for (int i = 0; i < iList.Count; i++)
                {
                    iList[i].MaximumAmountAvailable = broker.AmountAvailable(vessel.rootPart, iList[i].Name, 1, ResourceFlowMode.ALL_VESSEL);

                    if (iList[i].MaximumAmountAvailable == 0)
                    {
                        ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_NotEnoughFuel"), 5f).color = Color.yellow;
                        return(false);
                    }
                }
            }

            // Power production
            if (requiredPower > (electricPower_Solar + electricPower_Other))
            {
                // If required power is greater than total power generated, then average speed can be lowered up to 75%
                double speedReduction = (requiredPower - (electricPower_Solar + electricPower_Other)) / requiredPower;

                if (speedReduction > 0.75)
                {
                    ScreenMessages.PostScreenMessage(Localizer.Format("#LOC_BV_Warning_LowPowerRover"), 5f).color = Color.yellow;
                    return(false);
                }
            }

            BonVoyageModule module = vessel.FindPartModuleImplementing <BonVoyageModule>();

            if (module != null)
            {
                vesselHeightFromTerrain = vessel.radarAltitude;

                module.averageSpeed        = averageSpeed;
                module.averageSpeedAtNight = averageSpeedAtNight;
                module.manned = manned;
                module.vesselHeightFromTerrain = vesselHeightFromTerrain;
            }

            return(base.Activate());
        }
Esempio n. 22
0
        /// <summary>
        /// Call ResourceUpdate on all part modules that have that method
        /// </summary>
        public void ResourceUpdate(VesselResources resources, double elapsed_s)
        {
            // only do this for loaded vessels. unloaded vessels will be handled in Background.cs
            if (!Vessel.loaded)
            {
                return;
            }

            if (resourceUpdateDelegates == null)
            {
                resourceUpdateDelegates = new List <ResourceUpdateDelegate>();
                foreach (var part in Vessel.parts)
                {
                    foreach (var module in part.Modules)
                    {
                        if (!module.isEnabled)
                        {
                            continue;
                        }
                        var resourceUpdateDelegate = ResourceUpdateDelegate.Instance(module);
                        if (resourceUpdateDelegate != null)
                        {
                            resourceUpdateDelegates.Add(resourceUpdateDelegate);
                        }
                    }
                }
            }

            if (resourceUpdateDelegates.Count == 0)
            {
                return;
            }

            List <ResourceInfo> allResources = resources.GetAllResources(Vessel);            // there might be some performance to be gained by caching the list of all resource

            Dictionary <string, double> availableResources = new Dictionary <string, double>();

            foreach (var ri in allResources)
            {
                availableResources[ri.ResourceName] = ri.Amount;
            }
            List <KeyValuePair <string, double> > resourceChangeRequests = new List <KeyValuePair <string, double> >();

            foreach (var resourceUpdateDelegate in resourceUpdateDelegates)
            {
                resourceChangeRequests.Clear();
                string         title  = resourceUpdateDelegate.invoke(availableResources, resourceChangeRequests);
                ResourceBroker broker = ResourceBroker.GetOrCreate(title);
                foreach (var rc in resourceChangeRequests)
                {
                    if (rc.Value > 0)
                    {
                        resources.Produce(Vessel, rc.Key, rc.Value * elapsed_s, broker);
                    }
                    if (rc.Value < 0)
                    {
                        resources.Consume(Vessel, rc.Key, -rc.Value * elapsed_s, broker);
                    }
                }
            }
        }