예제 #1
0
        // execute the recipe
        public bool Execute(Vessel v, vessel_resources resources)
        {
            // determine worst input ratio
            // - pure input recipes can just underflow
            double worst_input = left;

            if (outputs.Count > 0)
            {
                for (int i = 0; i < inputs.Count; ++i)
                {
                    entry         e   = inputs[i];
                    resource_info res = resources.Info(v, e.name);
                    worst_input = Lib.Clamp((res.amount + res.deferred) * e.inv_quantity, 0.0, worst_input);
                }
            }

            // determine worst output ratio
            // - pure output recipes can just overflow
            double worst_output = left;

            if (inputs.Count > 0)
            {
                for (int i = 0; i < outputs.Count; ++i)
                {
                    entry e = outputs[i];
                    if (!e.dump)                     // ignore outputs that can dump overboard
                    {
                        resource_info res = resources.Info(v, e.name);
                        worst_output = Lib.Clamp((res.capacity - (res.amount + res.deferred)) * e.inv_quantity, 0.0, worst_output);
                    }
                }
            }

            // determine worst-io
            double worst_io = Math.Min(worst_input, worst_output);

            // consume inputs
            for (int i = 0; i < inputs.Count; ++i)
            {
                entry e = inputs[i];
                resources.Consume(v, e.name, e.quantity * worst_io);
            }

            // produce outputs
            for (int i = 0; i < outputs.Count; ++i)
            {
                entry e = outputs[i];
                resources.Produce(v, e.name, e.quantity * worst_io);
            }

            // update amount left to execute
            left -= worst_io;

            // the recipe was executed, at least partially
            return(worst_io > double.Epsilon);
        }
예제 #2
0
        public void update(Vessel v, vessel_info vi, vessel_data vd, vessel_resources resources, double elapsed_s)
        {
            // do nothing if signal mechanic is disabled
            if (!Kerbalism.features.signal)
            {
                return;
            }

            // get link data
            link_data link = vi.link;

            // consume relay ec
            // note: this is the only way to do it with new signal and resource systems
            if (vi.antenna.relay_range > 0.0)
            {
                foreach (Vessel w in FlightGlobals.Vessels)
                {
                    vessel_info wi = Cache.VesselInfo(w);
                    if (wi.is_valid)
                    {
                        if (wi.link.path.Contains(v))
                        {
                            resources.Consume(v, "ElectricCharge", vi.antenna.relay_cost * elapsed_s);
                            break;
                        }
                    }
                }
            }

            // maintain and send messages
            // - do nothing if db isn't ready
            // - do not send messages for vessels without an antenna
            if (link.status != link_status.no_antenna)
            {
                if (vd.msg_signal < 1 && !link.linked)
                {
                    vd.msg_signal = 1;
                    if (vd.cfg_signal == 1 && !vi.blackout) //< do not send message during storms
                    {
                        Message.Post(Severity.warning, Lib.BuildString("Signal lost with <b>", v.vesselName, "</b>"),
                                     vi.crew_count == 0 && Settings.RemoteControlLink ? "Remote control disabled" : "Data transmission disabled");
                    }
                }
                else if (vd.msg_signal > 0 && link.linked)
                {
                    vd.msg_signal = 0;
                    if (vd.cfg_signal == 1 && !Storm.JustEnded(v, elapsed_s)) //< do not send messages after a storm
                    {
                        var path = link.path;
                        Message.Post(Severity.relax, Lib.BuildString("<b>", v.vesselName, "</b> signal is back"),
                                     path.Count == 0 ? "We got a direct link with the space center" : Lib.BuildString("Relayed by <b>", path[path.Count - 1].vesselName, "</b>"));
                    }
                }
            }
        }
예제 #3
0
 static void ProcessCommand(Vessel v, ProtoPartSnapshot p, ProtoPartModuleSnapshot m, ModuleCommand command, vessel_resources resources, double elapsed_s)
 {
     // do not consume if this is a MCM with no crew
     // rationale: for consistency, the game doesn't consume resources for MCM without crew in loaded vessels
     //            this make some sense: you left a vessel with some battery and nobody on board, you expect it to not consume EC
     if (command.minimumCrew == 0 || p.protoModuleCrew.Count > 0)
     {
         // for each input resource
         foreach (ModuleResource ir in command.resHandler.inputResources)
         {
             // consume the resource
             resources.Consume(v, ir.name, ir.rate * elapsed_s);
         }
     }
 }
예제 #4
0
        public virtual void FixedUpdate()
        {
            if (FixGame(thisModule))
            {
                return;
            }

            hasEC = ResourceCache.Info(part.vessel, "ElectricCharge").amount > double.Epsilon;
            if (GetIsActive())
            {
                part.ModulesOnUpdate();
                // get resource cache
                vessel_resources resources = ResourceCache.Get(part.vessel);
                resources.Consume(part.vessel, "ElectricCharge", actualECCost * Kerbalism.elapsed_s);
            }
            else
            {
                actualECCost = 0;
            }
        }
예제 #5
0
        // consume EC for transmission, and transmit science data
        public static void update(Vessel v, vessel_info vi, VesselData vd, vessel_resources resources, double elapsed_s)
        {
            // hard-coded transmission buffer size in Mb
            const double buffer_capacity = 8.0;

            // do nothing if science system is disabled
            if (!Features.Science)
            {
                return;
            }

            // avoid corner-case when RnD isn't live during scene changes
            // - this avoid losing science if the buffer reach threshold during a scene change
            if (HighLogic.CurrentGame.Mode != Game.Modes.SANDBOX && ResearchAndDevelopment.Instance == null)
            {
                return;
            }

            // get connection info
            ConnectionInfo conn = vi.connection;

            // consume ec if data is transmitted or relayed
            if (vi.transmitting.Length > 0 || vi.relaying.Length > 0)
            {
                resources.Consume(v, "ElectricCharge", conn.cost * elapsed_s);
            }

            // get filename of data being downloaded
            string filename = vi.transmitting;

            // if some data is being downloaded
            // - avoid cornercase at scene changes
            if (filename.Length > 0 && vd.drive.files.ContainsKey(filename))
            {
                // get file
                File file = vd.drive.files[filename];

                // determine how much data is transmitted
                double transmitted = Math.Min(file.size, conn.rate * elapsed_s);

                // consume data in the file
                file.size -= transmitted;

                // accumulate in the buffer
                file.buff += transmitted;

                // if buffer is full, or file was transmitted completely
                if (file.size <= double.Epsilon || file.buff > buffer_capacity)
                {
                    // collect the science data
                    Science.credit(filename, file.buff, true, v.protoVessel);

                    // reset the buffer
                    file.buff = 0.0;
                }

                // if file was transmitted completely
                if (file.size <= double.Epsilon)
                {
                    // remove the file
                    vd.drive.files.Remove(filename);

                    // inform the user
                    Message.Post
                    (
                        Lib.BuildString("<color=cyan><b>DATA RECEIVED</b></color>\nTransmission of <b>", Science.experiment(filename).name, "</b> completed"),
                        Lib.TextVariant("Our researchers will jump on it right now", "The checksum is correct, data must be valid")
                    );
                }
            }
        }