private static ConduitFlow.ConduitContents SetMaxFlow(ConduitFlow.ConduitContents contents, ConduitBridge bridge, ConduitFlow manager) { if (bridge.GetComponent <BuildingHP>().HitPoints == 0) { //does not actually remove mass from the conduit, just changes what the bridge sees contents.RemoveMass(contents.mass); return(contents); } int outputCell = (int)bridgeOutputCell.GetValue(bridge); GameObject outputObject = Grid.Objects[outputCell, Integration.layers[(int)bridge.type]]; if (outputObject == null) { return(contents); } Pressurized pressure = bridge.GetComponent <Pressurized>(); float capacity; if (!Pressurized.IsDefault(pressure)) { capacity = pressure.Info.Capacity; } else { capacity = (float)maxMass.GetValue(manager); } //If the ConduitBridge is not supposed to support the amount of fluid currently in the contents, only make the bridge's intended max visible //Also immediately deal damage if the current contents are higher than the intended max. if (capacity < contents.mass) { float initial = contents.mass; float removed = contents.RemoveMass(initial - capacity); float ratio = removed / initial; contents.diseaseCount = (int)((float)contents.diseaseCount * ratio); BuildingHP.DamageSourceInfo damage = Integration.GetPressureDamage(); bridge.Trigger((int)GameHashes.DoBuildingDamage, damage); } { float targetCapacity; Pressurized outPressure = outputObject.GetComponent <Pressurized>(); if (!Pressurized.IsDefault(outPressure)) { targetCapacity = outPressure.Info.Capacity; } else { targetCapacity = (float)maxMass.GetValue(manager); } if (contents.mass > targetCapacity * 2) { BuildingHP.DamageSourceInfo damage = Integration.GetPressureDamage(); outputObject.Trigger((int)GameHashes.DoBuildingDamage, damage); } } return(contents); }
//Get a DamageSourceInfo object for damage being dealth from overpressure public static BuildingHP.DamageSourceInfo GetPressureDamage() { BuildingHP.DamageSourceInfo damage = new BuildingHP.DamageSourceInfo { damage = 1, source = BUILDINGS.DAMAGESOURCES.LIQUID_PRESSURE, popString = STRINGS.UI.GAMEOBJECTEFFECTS.DAMAGE_POPS.LIQUID_PRESSURE }; return(damage); }
private static void IntegrateOverpressure(ConduitFlow.GridNode sender, float standardMax, ConduitType conduitType, int cell) { Pressurized pressure = GetPressurizedAt(cell, conduitType); float receiverMax = Pressurized.IsDefault(pressure) ? standardMax : pressure.Info.Capacity; float senderMass = sender.contents.mass; if (senderMass >= receiverMax * 2f) { GameObject receiver = pressure != null ? pressure.gameObject : Grid.Objects[cell, layers[(int)conduitType]]; BuildingHP.DamageSourceInfo damage = GetPressureDamage(); queueDamages.Add(new QueueDamage(damage, receiver)); } }
protected override void ConduitTick(float delta) { if (!AlwaysConsume && !operational.IsOperational) { return; } IConduitFlow conduitFlow = GetConduitManager(); if (ConduitType != ConduitType.Solid) { ConduitFlow mngr = conduitFlow as ConduitFlow; ConduitFlow.ConduitContents contents = mngr.GetContents(portCell); if (contents.mass <= 0) { return; } Element element = ElementLoader.FindElementByHash(contents.element); bool matchesTag = StoreTag == GameTags.Any || element.HasTag(StoreTag); float rateAmount = ConsumptionRate * delta; float maxTake = 0f; float storageContains = storage.MassStored(); float storageLeft = storage.capacityKg - storageContains; float portContains = StoreTag == GameTags.Any ? storageContains : storage.GetMassAvailable(StoreTag); float portLeft = MaximumStore - portContains; maxTake = Mathf.Min(storageLeft, portLeft); maxTake = Mathf.Min(rateAmount, maxTake); float removed = 0f; if (maxTake > 0f) { ConduitFlow.ConduitContents removedContents = mngr.RemoveElement(portCell, maxTake); removed = removedContents.mass; LastConsumedElement = removedContents.element; float ratio = removed / contents.mass; if (!matchesTag) { BuildingHP.DamageSourceInfo damage = new BuildingHP.DamageSourceInfo { damage = 1, source = BUILDINGS.DAMAGESOURCES.BAD_INPUT_ELEMENT, popString = UI.GAMEOBJECTEFFECTS.DAMAGE_POPS.WRONG_ELEMENT }; Trigger((int)GameHashes.DoBuildingDamage, damage); if (WrongElement == WrongElementResult.Dump) { int buildingCell = Grid.PosToCell(_parent.transform.GetPosition()); SimMessages.AddRemoveSubstance(buildingCell, contents.element, CellEventLogger.Instance.ConduitConsumerWrongElement, removed, contents.temperature, contents.diseaseIdx, contents.diseaseIdx); return; } } if (ConduitType == ConduitType.Gas) { if (!element.IsGas) { Debug.LogWarning($"[MultIO] Gas input port attempted to consume non gass: {element.id.ToString()}"); } else { storage.AddGasChunk(element.id, removed, contents.temperature, contents.diseaseIdx, contents.diseaseCount, KeepZeroMassObject, false); } } else if (ConduitType == ConduitType.Liquid) { if (!element.IsLiquid) { Debug.LogWarning($"[MultIO] Liquid input port attempted to consume non liquid: {element.id.ToString()}"); } else { storage.AddLiquid(element.id, removed, contents.temperature, contents.diseaseIdx, contents.diseaseCount, KeepZeroMassObject, false); } } } } else { SolidConduitFlow mngr = conduitFlow as SolidConduitFlow; SolidConduitFlow.ConduitContents contents = mngr.GetContents(portCell); if (contents.pickupableHandle.IsValid() && (AlwaysConsume || operational.IsOperational)) { float stored = StoreTag == GameTags.Any ? storage.MassStored() : storage.GetMassAvailable(StoreTag); float maxStorage = Mathf.Min(storage.capacityKg, MaximumStore); float availableStorage = Mathf.Max(0f, maxStorage - stored); if (availableStorage > 0f) { Pickupable tmp = mngr.GetPickupable(contents.pickupableHandle); bool matchesTag = StoreTag == GameTags.Any || tmp.HasTag(StoreTag); if (matchesTag) { if (tmp.PrimaryElement.Mass <= stored || tmp.PrimaryElement.Mass > maxStorage) { Pickupable take = mngr.RemovePickupable(portCell); if (take != null) { storage.Store(take.gameObject, true); } } } else { Pickupable take = mngr.RemovePickupable(portCell); take.transform.SetPosition(Grid.CellToPos(portCell)); //TODO: Add a PopFX. Likely will not do damage. } } } } }
public static void DoPressureDamage(GameObject obj) { BuildingHP.DamageSourceInfo damage = GetPressureDamage(); obj.Trigger((int)GameHashes.DoBuildingDamage, damage); QueueDamage.ExecuteNotification(obj); }
public QueueDamage(BuildingHP.DamageSourceInfo dmg, GameObject rcvr) { Damage = dmg; Receiver = rcvr; }