Exemple #1
0
        //a recursive function that goes through all the junctions and adds up
        //all the generated/consumed power of the constructions connected to the grid
        private void CheckJunctions(float deltaTime, bool increaseUpdateCount = true, bool inputOnly = false)
        {
            if (increaseUpdateCount)
            {
                updateCount = 1;
            }

            connectedList.Add(this);

            ApplyStatusEffects(ActionType.OnActive, deltaTime, null);

            foreach (Connection c in PowerConnections)
            {
                var recipients = c.Recipients;

                foreach (Connection recipient in recipients)
                {
                    if (recipient == null)
                    {
                        continue;
                    }

                    Item it = recipient.Item;
                    if (it == null)
                    {
                        continue;
                    }

                    if (it.Condition <= 0.0f)
                    {
                        continue;
                    }

                    foreach (Powered powered in it.GetComponents <Powered>())
                    {
                        if (powered == null || !powered.IsActive)
                        {
                            continue;
                        }
                        if (connectedList.Contains(powered))
                        {
                            continue;
                        }
                        PowerTransfer powerTransfer = powered as PowerTransfer;
                        if (powerTransfer != null)
                        {
                            if (this is RelayComponent == powerTransfer is RelayComponent)
                            {
                                if (!powerTransfer.CanTransfer)
                                {
                                    continue;
                                }
                                powerTransfer.CheckJunctions(deltaTime, increaseUpdateCount, inputOnly);
                            }
                            else
                            {
                                if (!powerTransfer.CanTransfer)
                                {
                                    continue;
                                }
                                powerTransfer.CheckJunctions(deltaTime, false, !c.IsOutput || inputOnly);
                            }

                            continue;
                        }

                        PowerContainer powerContainer = powered as PowerContainer;
                        if (powerContainer != null)
                        {
                            if (recipient.Name == "power_in")
                            {
                                if (!inputOnly)
                                {
                                    fullLoad += powerContainer.CurrPowerConsumption;
                                }
                            }
                            else
                            {
                                fullPower += powerContainer.CurrPowerOutput;
                            }
                        }
                        else
                        {
                            connectedList.Add(powered);
                            //positive power consumption = the construction requires power -> increase load
                            if (powered.CurrPowerConsumption > 0.0f)
                            {
                                if (!inputOnly)
                                {
                                    fullLoad += powered.CurrPowerConsumption;
                                }
                            }
                            else if (powered.CurrPowerConsumption < 0.0f)
                            //negative power consumption = the construction is a
                            //generator/battery or another junction box
                            {
                                fullPower -= powered.CurrPowerConsumption;
                            }
                        }
                    }
                }
            }
        }
Exemple #2
0
        public override void Update(float deltaTime, Camera cam)
        {
            isRunning = true;
            float chargeRatio = charge / capacity;
            float gridPower   = 0.0f;
            float gridLoad    = 0.0f;

            foreach (Connection c in item.Connections)
            {
                if (!c.IsPower || !c.IsOutput)
                {
                    continue;
                }
                foreach (Connection c2 in c.Recipients)
                {
                    if (c2.Item.Condition <= 0.0f)
                    {
                        continue;
                    }

                    PowerTransfer pt = c2.Item.GetComponent <PowerTransfer>();
                    if (pt == null)
                    {
                        foreach (Powered powered in c2.Item.GetComponents <Powered>())
                        {
                            if (!powered.IsActive)
                            {
                                continue;
                            }
                            gridLoad += powered.CurrPowerConsumption;
                        }
                        continue;
                    }
                    if (!pt.IsActive || !pt.CanTransfer)
                    {
                        continue;
                    }
                    gridPower -= pt.CurrPowerConsumption;
                    gridLoad  += pt.PowerLoad;
                }
            }

            if (chargeRatio > 0.0f)
            {
                ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
            }

            if (charge >= capacity)
            {
                //rechargeVoltage = 0.0f;
                charge = capacity;
                CurrPowerConsumption = 0.0f;
            }
            else
            {
                currPowerConsumption = MathHelper.Lerp(currPowerConsumption, rechargeSpeed, 0.05f);
                Charge += currPowerConsumption * Math.Min(Voltage, 1.0f) / 3600.0f;
            }

            if (charge <= 0.0f)
            {
                CurrPowerOutput = 0.0f;
                charge          = 0.0f;
                return;
            }

            //output starts dropping when the charge is less than 10%
            float maxOutputRatio = 1.0f;

            if (chargeRatio < 0.1f)
            {
                maxOutputRatio = Math.Max(chargeRatio * 10.0f, 0.0f);
            }

            CurrPowerOutput += (gridLoad - gridPower) * deltaTime;

            float maxOutput = Math.Min(MaxOutPut * maxOutputRatio, gridLoad);

            CurrPowerOutput = MathHelper.Clamp(CurrPowerOutput, 0.0f, maxOutput);
            Charge         -= CurrPowerOutput / 3600.0f;

            item.SendSignal(0, ((int)Math.Round(Charge)).ToString(), "charge", null);
            item.SendSignal(0, ((int)Math.Round((Charge / capacity) * 100)).ToString(), "charge_%", null);
            item.SendSignal(0, ((int)Math.Round((RechargeSpeed / maxRechargeSpeed) * 100)).ToString(), "charge_rate", null);
        }
Exemple #3
0
        public override void Update(float deltaTime, Camera cam)
        {
            RefreshConnections();
            if (!CanTransfer)
            {
                return;
            }

            if (isBroken)
            {
                SetAllConnectionsDirty();
                isBroken = false;
            }

            if (updateCount > 0)
            {
                //this junction box has already been updated this frame
                updateCount--;
                return;
            }

            //reset and recalculate the power generated/consumed
            //by the constructions connected to the grid
            fullPower = 0.0f;
            fullLoad  = 0.0f;

            connectedList.Clear();

            updateCount = 0;
            CheckJunctions(deltaTime);

            foreach (Powered p in connectedList)
            {
                PowerTransfer pt = p as PowerTransfer;
                if (pt == null || pt.updateCount == 0)
                {
                    continue;
                }

                if (pt is RelayComponent != this is RelayComponent)
                {
                    continue;
                }

                pt.powerLoad            += (fullLoad - pt.powerLoad) / inertia;
                pt.currPowerConsumption += (-fullPower - pt.currPowerConsumption) / inertia;

                float voltage = fullPower / Math.Max(fullLoad, 1.0f);
                if (this is RelayComponent)
                {
                    voltage = Math.Min(voltage, 1.0f);
                }

                pt.Item.SendSignal(0, "", "power", null, voltage);
                pt.Item.SendSignal(0, "", "power_out", null, voltage);

                //Nilmod Regenerate the health of a damaged junction over time
                if (GameMain.NilMod.ElectricalRegenerateCondition && pt.item.Condition > 0f && pt.item.Condition < 100f)
                {
                    pt.item.Condition += deltaTime * GameMain.NilMod.ElectricalRegenAmount;
                }

                //relays don't blow up if the power is higher than load, only if the output is high enough
                //(i.e. enough power passing through the relay)
                if (this is RelayComponent)
                {
                    continue;
                }
                if (-pt.currPowerConsumption < Math.Max(pt.powerLoad * Rand.Range(GameMain.NilMod.ElectricalOverloadVoltRangeMin, GameMain.NilMod.ElectricalOverloadVoltRangeMax), GameMain.NilMod.ElectricalOverloadMinPower))
                {
                    continue;
                }

                //damage the item if voltage is too high
                //(except if running as a client)
                if (GameMain.Client != null)
                {
                    continue;
                }
                float prevCondition = pt.item.Condition;
                pt.item.Condition -= deltaTime * GameMain.NilMod.ElectricalOverloadDamage;

                if (pt.item.Condition <= 0.0f && prevCondition > 0.0f)
                {
#if CLIENT
                    sparkSounds[Rand.Int(sparkSounds.Length)].Play(1.0f, 600.0f, pt.item.WorldPosition);

                    Vector2 baseVel = Rand.Vector(300.0f);
                    for (int i = 0; i < 10; i++)
                    {
                        var particle = GameMain.ParticleManager.CreateParticle("spark", pt.item.WorldPosition,
                                                                               baseVel + Rand.Vector(100.0f), 0.0f, item.CurrentHull);

                        if (particle != null)
                        {
                            particle.Size *= Rand.Range(0.5f, 1.0f);
                        }
                    }
#endif

                    if ((GameMain.NilMod.ElectricalOverloadFiresChance / 100f) > 0.0f && Rand.Int((int)(1.0f / (GameMain.NilMod.ElectricalOverloadFiresChance / 100f))) == 1)
                    {
                        new FireSource(pt.item.WorldPosition);
                    }
                }
            }

            updateCount = 0;
        }
Exemple #4
0
        public override void Update(float deltaTime, Camera cam)
        {
            if (GameMain.Server != null && nextServerLogWriteTime != null)
            {
                if (Timing.TotalTime >= (float)nextServerLogWriteTime)
                {
                    GameServer.Log(lastUser + " adjusted reactor settings: " +
                                   "Temperature: " + (int)temperature +
                                   ", Fission rate: " + (int)fissionRate +
                                   ", Cooling rate: " + (int)coolingRate +
                                   ", Cooling rate: " + coolingRate +
                                   ", Shutdown temp: " + shutDownTemp +
                                   (autoTemp ? ", Autotemp ON" : ", Autotemp OFF"),
                                   ServerLog.MessageType.ItemInteraction);

                    nextServerLogWriteTime = null;
                    lastServerLogWriteTime = (float)Timing.TotalTime;
                }
            }

            ApplyStatusEffects(ActionType.OnActive, deltaTime, null);

            fissionRate = Math.Min(fissionRate, AvailableFuel);

            float heat            = 80 * fissionRate * (AvailableFuel / 2000.0f);
            float heatDissipation = 50 * coolingRate + Math.Max(ExtraCooling, 5.0f);

            float deltaTemp = (((heat - heatDissipation) * 5) - temperature) / 10000.0f;

            Temperature = temperature + deltaTemp;

            if (temperature > fireTemp && temperature - deltaTemp < fireTemp)
            {
#if CLIENT
                Vector2 baseVel = Rand.Vector(300.0f);
                for (int i = 0; i < 10; i++)
                {
                    var particle = GameMain.ParticleManager.CreateParticle("spark", item.WorldPosition,
                                                                           baseVel + Rand.Vector(100.0f), 0.0f, item.CurrentHull);

                    if (particle != null)
                    {
                        particle.Size *= Rand.Range(0.5f, 1.0f);
                    }
                }
#endif

                new FireSource(item.WorldPosition);
            }

            if (temperature > meltDownTemp)
            {
                MeltDown();
                return;
            }

            load = 0.0f;

            List <Connection> connections = item.Connections;
            if (connections != null && connections.Count > 0)
            {
                foreach (Connection connection in connections)
                {
                    if (!connection.IsPower)
                    {
                        continue;
                    }
                    foreach (Connection recipient in connection.Recipients)
                    {
                        Item it = recipient.Item as Item;
                        if (it == null)
                        {
                            continue;
                        }

                        PowerTransfer pt = it.GetComponent <PowerTransfer>();
                        if (pt == null)
                        {
                            continue;
                        }

                        load = Math.Max(load, pt.PowerLoad);
                    }
                }
            }

            //item.Condition -= temperature * deltaTime * 0.00005f;

            if (temperature > shutDownTemp)
            {
                CoolingRate += 0.5f;
                FissionRate -= 0.5f;
            }
            else if (autoTemp)
            {
                //take deltaTemp into account to slow down the change in temperature when getting closer to the desired value
                float target = temperature + deltaTemp * 100.0f;

                //-1.0f in order to gradually turn down both rates when the target temperature is reached
                FissionRate += (MathHelper.Clamp(load - target, -10.0f, 10.0f) - 1.0f) * deltaTime;
                CoolingRate += (MathHelper.Clamp(target - load, -5.0f, 5.0f) - 1.0f) * deltaTime;
            }

            //the power generated by the reactor is equal to the temperature
            currPowerConsumption = -temperature * powerPerTemp;

            if (item.CurrentHull != null)
            {
                //the sound can be heard from 20 000 display units away when running at full power
                item.CurrentHull.SoundRange = Math.Max(temperature * 2, item.CurrentHull.AiTarget.SoundRange);
            }

#if CLIENT
            UpdateGraph(deltaTime);
#endif

            ExtraCooling  = 0.0f;
            AvailableFuel = 0.0f;

            item.SendSignal(0, ((int)temperature).ToString(), "temperature_out", null);

            sendUpdateTimer = Math.Max(sendUpdateTimer - deltaTime, 0.0f);

            if (unsentChanges && sendUpdateTimer <= 0.0f)
            {
                if (GameMain.Server != null)
                {
                    item.CreateServerEvent(this);
                }
#if CLIENT
                else if (GameMain.Client != null)
                {
                    item.CreateClientEvent(this);
                }
#endif

                sendUpdateTimer = NetworkUpdateInterval;
                unsentChanges   = false;
            }
        }