protected override void Activate(IEntity user, SolutionContainerComponent component) { if (!user.TryGetComponent <HandsComponent>(out var hands) || hands.GetActiveHand == null) { return; } if (!hands.GetActiveHand.Owner.TryGetComponent <SolutionContainerComponent>(out var handSolutionComp) || !handSolutionComp.CanAddSolutions || !component.CanRemoveSolutions) { return; } var transferQuantity = ReagentUnit.Min(handSolutionComp.MaxVolume - handSolutionComp.CurrentVolume, component.CurrentVolume, ReagentUnit.New(10)); if (transferQuantity <= 0) { return; } var transferSolution = component.SplitSolution(transferQuantity); handSolutionComp.TryAddSolution(transferSolution); }
/// <returns>The actual amount transferred.</returns> private static ReagentUnit DoTransfer(IEntity user, IEntity sourceEntity, Solution source, IEntity targetEntity, Solution target, ReagentUnit amount) { if (source.DrainAvailable == 0) { sourceEntity.PopupMessage(user, Loc.GetString("comp-solution-transfer-is-empty", ("target", sourceEntity))); return(ReagentUnit.Zero); } if (target.AvailableVolume == 0) { targetEntity.PopupMessage(user, Loc.GetString("comp-solution-transfer-is-full", ("target", targetEntity))); return(ReagentUnit.Zero); } var actualAmount = ReagentUnit.Min(amount, ReagentUnit.Min(source.DrainAvailable, target.AvailableVolume)); var solution = EntitySystem.Get <SolutionContainerSystem>().Drain(sourceEntity.Uid, source, actualAmount); EntitySystem.Get <SolutionContainerSystem>().Refill(targetEntity.Uid, target, solution); return(actualAmount); }
protected override void ReactWithEntity(IEntity entity, double solutionFraction) { if (SolutionContainerComponent == null) { return; } if (!entity.TryGetComponent(out BloodstreamComponent? bloodstream)) { return; } if (entity.TryGetComponent(out InternalsComponent? internals) && internals.AreInternalsWorking()) { return; } var cloneSolution = SolutionContainerComponent.Solution.Clone(); var transferAmount = ReagentUnit.Min(cloneSolution.TotalVolume * solutionFraction, bloodstream.EmptyVolume); var transferSolution = cloneSolution.SplitSolution(transferAmount); foreach (var reagentQuantity in transferSolution.Contents.ToArray()) { if (reagentQuantity.Quantity == ReagentUnit.Zero) { continue; } var reagent = PrototypeManager.Index <ReagentPrototype>(reagentQuantity.ReagentId); transferSolution.RemoveReagent(reagentQuantity.ReagentId, reagent.ReactionEntity(entity, ReactionMethod.Ingestion, reagentQuantity.Quantity)); } bloodstream.TryTransferSolution(transferSolution); }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { var solutionContainerSystem = EntitySystem.Get <SolutionContainerSystem>(); if (eventArgs.Target == null || !eventArgs.CanReach) { return(false); } var targetEntity = eventArgs.Target; if (eventArgs.Target.HasComponent <ReagentTankComponent>() && solutionContainerSystem.TryGetDrainableSolution(targetEntity.Uid, out var targetSolution) && solutionContainerSystem.TryGetDrainableSolution(Owner.Uid, out var container)) { var transfer = ReagentUnit.Min(container.AvailableVolume, targetSolution.DrainAvailable); if (transfer > 0) { var drained = solutionContainerSystem.Drain(targetEntity.Uid, targetSolution, transfer); solutionContainerSystem.TryAddSolution(Owner.Uid, container, drained); SoundSystem.Play(Filter.Pvs(Owner), _refillSound.GetSound(), Owner); eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("fire-extinguisher-component-after-interact-refilled-message", ("owner", Owner))); } return(true); } return(false); }
public override void Activate(IEntity user, IEntity target) { if (!GetHeldSolution(user, out _, out var handSolutionComp)) { return; } if (!handSolutionComp.CanDrain || !target.TryGetComponent(out ISolutionInteractionsComponent? targetComp) || !targetComp.CanRefill) { return; } var transferQuantity = ReagentUnit.Min( targetComp.RefillSpaceAvailable, handSolutionComp.DrainAvailable, ReagentUnit.New(10)); if (transferQuantity <= 0) { return; } var transferSolution = handSolutionComp.Drain(transferQuantity); targetComp.Refill(transferSolution); }
void UseFood(IEntity user) { if (user == null) { return; } if (UsesLeft() == 0) { user.PopupMessage(user, _localizationManager.GetString("Empty")); } else { // TODO: Add putting food back in boxes here? if (user.TryGetComponent(out StomachComponent stomachComponent)) { var transferAmount = ReagentUnit.Min(_transferAmount, _contents.CurrentVolume); var split = _contents.SplitSolution(transferAmount); if (stomachComponent.TryTransferSolution(split)) { if (_useSound != null) { Owner.GetComponent <SoundComponent>()?.Play(_useSound); user.PopupMessage(user, _localizationManager.GetString("Nom")); } } else { // Add it back in _contents.TryAddSolution(split); user.PopupMessage(user, _localizationManager.GetString("Can't eat")); } } } if (UsesLeft() > 0) { return; } var position = Owner.Transform.GridPosition; Owner.Delete(); if (_finishPrototype != null) { var finisher = Owner.EntityManager.SpawnEntity(_finishPrototype, position); if (user.TryGetComponent(out HandsComponent handsComponent) && finisher.TryGetComponent(out ItemComponent itemComponent)) { if (handsComponent.CanPutInHand(itemComponent)) { handsComponent.PutInHand(itemComponent); return; } } finisher.Transform.GridPosition = user.Transform.GridPosition; return; } }
private static ReagentUnit DoTransfer( ISolutionInteractionsComponent source, ISolutionInteractionsComponent target, ReagentUnit amount, IEntity user) { if (source.DrainAvailable == 0) { source.Owner.PopupMessage(user, Loc.GetString("{0:TheName} is empty!", source.Owner)); return(ReagentUnit.Zero); } if (target.RefillSpaceAvailable == 0) { target.Owner.PopupMessage(user, Loc.GetString("{0:TheName} is full!", target.Owner)); return(ReagentUnit.Zero); } var actualAmount = ReagentUnit.Min(amount, ReagentUnit.Min(source.DrainAvailable, target.RefillSpaceAvailable)); var solution = source.Drain(actualAmount); target.Refill(solution); return(actualAmount); }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null || !eventArgs.CanReach) { return(false); } if (eventArgs.Target.TryGetComponent(out ReagentTankComponent? tank) && eventArgs.Target.TryGetComponent(out ISolutionInteractionsComponent? targetSolution) && targetSolution.CanDrain && Owner.TryGetComponent(out SolutionContainerComponent? container)) { var trans = ReagentUnit.Min(container.EmptyVolume, targetSolution.DrainAvailable); if (trans > 0) { var drained = targetSolution.Drain(trans); container.TryAddSolution(drained); SoundSystem.Play(Filter.Pvs(Owner), _refillSound.GetSound(), Owner); eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("fire-extinguisher-component-after-interact-refilled-message", ("owner", Owner))); } return(true); } return(false); }
private void TryInjectIntoBloodstream(BloodstreamComponent targetBloodstream, IEntity user) { if (!Owner.TryGetComponent(out SolutionContainerComponent? solution) || solution.CurrentVolume == 0) { return; } // Get transfer amount. May be smaller than _transferAmount if not enough room var realTransferAmount = ReagentUnit.Min(_transferAmount, targetBloodstream.EmptyVolume); if (realTransferAmount <= 0) { Owner.PopupMessage(user, Loc.GetString("You aren't able to inject {0:theName}!", targetBloodstream.Owner)); return; } // Move units from attackSolution to targetSolution var removedSolution = solution.SplitSolution(realTransferAmount); if (!targetBloodstream.TryTransferSolution(removedSolution)) { return; } Owner.PopupMessage(user, Loc.GetString("You inject {0}u into {1:theName}!", removedSolution.TotalVolume, targetBloodstream.Owner)); Dirty(); }
protected override void ReactWithEntity(IEntity entity, double solutionFraction) { if (!EntitySystem.Get <SolutionContainerSystem>().TryGetSolution(Owner, SolutionName, out var solution)) { return; } if (!entity.TryGetComponent(out BloodstreamComponent? bloodstream)) { return; } if (entity.TryGetComponent(out InternalsComponent? internals) && internals.AreInternalsWorking()) { return; } var chemistry = EntitySystem.Get <ChemistrySystem>(); var cloneSolution = solution.Clone(); var transferAmount = ReagentUnit.Min(cloneSolution.TotalVolume * solutionFraction, bloodstream.EmptyVolume); var transferSolution = cloneSolution.SplitSolution(transferAmount); foreach (var reagentQuantity in transferSolution.Contents.ToArray()) { if (reagentQuantity.Quantity == ReagentUnit.Zero) { continue; } chemistry.ReactionEntity(entity, ReactionMethod.Ingestion, reagentQuantity.ReagentId, reagentQuantity.Quantity, transferSolution); } bloodstream.TryTransferSolution(transferSolution); }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null || !eventArgs.CanReach) { return(false); } if (eventArgs.Target.TryGetComponent(out ReagentTankComponent? tank) && eventArgs.Target.TryGetComponent(out ISolutionInteractionsComponent? targetSolution) && targetSolution.CanDrain && Owner.TryGetComponent(out SolutionContainerComponent? container)) { var trans = ReagentUnit.Min(container.EmptyVolume, targetSolution.DrainAvailable); if (trans > 0) { var drained = targetSolution.Drain(trans); container.TryAddSolution(drained); EntitySystem.Get <AudioSystem>().PlayFromEntity("/Audio/Effects/refill.ogg", Owner); eventArgs.Target.PopupMessage(eventArgs.User, Loc.GetString("{0:TheName} is now refilled", Owner)); } return(true); } return(false); }
private void TryDraw(SolutionContainerComponent targetSolution, IEntity user) { if (!Owner.TryGetComponent(out SolutionContainerComponent? solution) || solution.EmptyVolume == 0) { return; } // Get transfer amount. May be smaller than _transferAmount if not enough room var realTransferAmount = ReagentUnit.Min(_transferAmount, targetSolution.CurrentVolume); if (realTransferAmount <= 0) { Owner.PopupMessage(user, Loc.GetString("{0:theName} is empty!", targetSolution.Owner)); return; } // Move units from attackSolution to targetSolution var removedSolution = targetSolution.SplitSolution(realTransferAmount); if (!solution.TryAddSolution(removedSolution)) { return; } Owner.PopupMessage(user, Loc.GetString("Drew {0}u from {1:theName}", removedSolution.TotalVolume, targetSolution.Owner)); Dirty(); }
private bool TryUseDrink(IEntity target, bool forced = false) { if (target == null || !_contents.CanRemoveSolutions) { return(false); } if (!Opened) { target.PopupMessage(Loc.GetString("Open {0:theName} first!", Owner)); return(false); } if (_contents.CurrentVolume.Float() <= 0) { if (!forced) { target.PopupMessage(Loc.GetString("{0:theName} is empty!", Owner)); } return(false); } if (!target.TryGetComponent(out IBody body) || !body.TryGetMechanismBehaviors <StomachBehavior>(out var stomachs)) { return(false); } var transferAmount = ReagentUnit.Min(TransferAmount, _contents.CurrentVolume); var split = _contents.SplitSolution(transferAmount); var firstStomach = stomachs.FirstOrDefault(stomach => stomach.CanTransferSolution(split)); // All stomach are full or can't handle whatever solution we have. if (firstStomach == null) { _contents.TryAddSolution(split); target.PopupMessage(Loc.GetString("You've had enough {0:theName}!", Owner)); return(false); } if (_useSound != null) { EntitySystem.Get <AudioSystem>().PlayFromEntity(_useSound, target, AudioParams.Default.WithVolume(-2f)); } target.PopupMessage(Loc.GetString("Slurp")); UpdateAppearance(); // TODO: Account for partial transfer. split.DoEntityReaction(target, ReactionMethod.Ingestion); firstStomach.TryTransferSolution(split); return(true); }
private void TransferReagent(string id, ReagentUnit amount, bool isBuffer) { if (!HasBeaker && BufferModeTransfer) { return; } var beaker = _beakerContainer.ContainedEntity; var beakerSolution = beaker.GetComponent <SolutionComponent>(); if (isBuffer) { foreach (var reagent in BufferSolution.Solution.Contents) { if (reagent.ReagentId == id) { ReagentUnit actualAmount; if (amount == ReagentUnit.New(-1)) { actualAmount = ReagentUnit.Min(reagent.Quantity, beakerSolution.EmptyVolume); } else { actualAmount = ReagentUnit.Min(reagent.Quantity, amount, beakerSolution.EmptyVolume); } BufferSolution.Solution.RemoveReagent(id, actualAmount); if (BufferModeTransfer) { beakerSolution.Solution.AddReagent(id, actualAmount); } break; } } } else { foreach (var reagent in beakerSolution.Solution.Contents) { if (reagent.ReagentId == id) { ReagentUnit actualAmount; if (amount == ReagentUnit.New(-1)) { actualAmount = ReagentUnit.Min(reagent.Quantity, BufferSolution.EmptyVolume); } else { actualAmount = ReagentUnit.Min(reagent.Quantity, amount, BufferSolution.EmptyVolume); } beakerSolution.TryRemoveReagent(id, actualAmount); BufferSolution.Solution.AddReagent(id, actualAmount); break; } } } UpdateUserInterface(); }
public bool InteractUsing(InteractUsingEventArgs eventArgs) { if (!_powered) { _notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User, Loc.GetString("It has no power!")); return(false); } var itemEntity = eventArgs.User.GetComponent <HandsComponent>().GetActiveHand?.Owner; if (itemEntity == null) { eventArgs.User.PopupMessage(eventArgs.User, Loc.GetString("You have no active hand!")); return(false); } if (itemEntity.TryGetComponent <PourableComponent>(out var attackPourable)) { if (!itemEntity.TryGetComponent <SolutionComponent>(out var attackSolution) || !attackSolution.CanPourOut) { return(false); } //Get transfer amount. May be smaller than _transferAmount if not enough room var realTransferAmount = ReagentUnit.Min(attackPourable.TransferAmount, _solution.EmptyVolume); if (realTransferAmount <= 0) //Special message if container is full { _notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User, Loc.GetString("Container is full")); return(false); } //Move units from attackSolution to targetSolution var removedSolution = attackSolution.SplitSolution(realTransferAmount); if (!_solution.TryAddSolution(removedSolution)) { return(false); } _notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User, Loc.GetString("Transferred {0}u", removedSolution.TotalVolume)); return(true); } if (!itemEntity.TryGetComponent(typeof(ItemComponent), out var food)) { _notifyManager.PopupMessage(Owner, eventArgs.User, "That won't work!"); return(false); } var ent = food.Owner; //Get the entity of the ItemComponent. _storage.Insert(ent); _uiDirty = true; return(true); }
public bool TryDoInject(IEntity?target, IEntity user) { if (target == null || !EligibleEntity(target)) { return(false); } string?msgFormat = null; if (target == user) { msgFormat = "hypospray-component-inject-self-message"; } else if (EligibleEntity(user) && ClumsyComponent.TryRollClumsy(user, ClumsyFailChance)) { msgFormat = "hypospray-component-inject-self-clumsy-message"; target = user; } if (_solution == null || _solution.CurrentVolume == 0) { user.PopupMessageCursor(Loc.GetString("hypospray-component-empty-message")); return(true); } user.PopupMessage(Loc.GetString(msgFormat ?? "hypospray-component-inject-other-message", ("other", target))); if (target != user) { target.PopupMessage(Loc.GetString("hypospray-component-feel-prick-message")); var meleeSys = EntitySystem.Get <MeleeWeaponSystem>(); var angle = Angle.FromWorldVec(target.Transform.WorldPosition - user.Transform.WorldPosition); meleeSys.SendLunge(angle, user); } SoundSystem.Play(Filter.Pvs(user), _injectSound.GetSound(), user); var targetSolution = target.GetComponent <SolutionContainerComponent>(); // Get transfer amount. May be smaller than _transferAmount if not enough room var realTransferAmount = ReagentUnit.Min(TransferAmount, targetSolution.EmptyVolume); if (realTransferAmount <= 0) { user.PopupMessage(user, Loc.GetString("hypospray-component-transfer-already-full-message ", ("owner", targetSolution.Owner))); return(true); } // Move units from attackSolution to targetSolution var removedSolution = _solution.SplitSolution(realTransferAmount); if (!targetSolution.CanAddSolution(removedSolution)) { return(true); } removedSolution.DoEntityReaction(target, ReactionMethod.Injection); targetSolution.TryAddSolution(removedSolution);
private bool TryDoInject(IEntity?target, IEntity user) { if (target == null || !EligibleEntity(target)) { return(false); } var msgFormat = "You inject {0:TheName}."; if (target == user) { msgFormat = "You inject yourself."; } else if (EligibleEntity(user) && ClumsyComponent.TryRollClumsy(user, ClumsyFailChance)) { msgFormat = "Oops! You injected yourself!"; target = user; } if (_solution == null || _solution.CurrentVolume == 0) { user.PopupMessageCursor(Loc.GetString("It's empty!")); return(true); } user.PopupMessage(Loc.GetString(msgFormat, target)); if (target != user) { target.PopupMessage(Loc.GetString("You feel a tiny prick!")); var meleeSys = EntitySystem.Get <MeleeWeaponSystem>(); var angle = new Angle(target.Transform.WorldPosition - user.Transform.WorldPosition); meleeSys.SendLunge(angle, user); } EntitySystem.Get <AudioSystem>().PlayFromEntity("/Audio/Items/hypospray.ogg", user); var targetSolution = target.GetComponent <SolutionContainerComponent>(); // Get transfer amount. May be smaller than _transferAmount if not enough room var realTransferAmount = ReagentUnit.Min(TransferAmount, targetSolution.EmptyVolume); if (realTransferAmount <= 0) { user.PopupMessage(user, Loc.GetString("{0:TheName} is already full!", targetSolution.Owner)); return(true); } // Move units from attackSolution to targetSolution var removedSolution = _solution.SplitSolution(realTransferAmount); if (!targetSolution.CanAddSolution(removedSolution)) { return(true); } removedSolution.DoEntityReaction(target, ReactionMethod.Injection); targetSolution.TryAddSolution(removedSolution);
public override bool TryUseFood(IEntity user, IEntity target, UtensilComponent utensilUsed = null) { if (user == null) { return(false); } var trueTarget = target ?? user; if (!trueTarget.TryGetComponent(out IBody body) || !body.TryGetMechanismBehaviors <StomachBehavior>(out var stomachs)) { return(false); } if (!user.InRangeUnobstructed(trueTarget, popup: true)) { return(false); } var transferAmount = ReagentUnit.Min(_transferAmount, _contents.CurrentVolume); var split = _contents.SplitSolution(transferAmount); var firstStomach = stomachs.FirstOrDefault(stomach => stomach.CanTransferSolution(split)); if (firstStomach == null) { _contents.TryAddSolution(split); trueTarget.PopupMessage(user, Loc.GetString("You can't eat any more!")); return(false); } // TODO: Account for partial transfer. foreach (var(reagentId, quantity) in split.Contents) { if (!_prototypeManager.TryIndex(reagentId, out ReagentPrototype reagent)) { continue; } split.RemoveReagent(reagentId, reagent.ReactionEntity(trueTarget, ReactionMethod.Ingestion, quantity)); } firstStomach.TryTransferSolution(split); if (_useSound != null) { _entitySystem.GetEntitySystem <AudioSystem>() .PlayFromEntity(_useSound, trueTarget, AudioParams.Default.WithVolume(-1f)); } trueTarget.PopupMessage(user, Loc.GetString("You swallow the pill.")); Owner.Delete(); return(true); }
private bool TryUseFood(IEntity user, IEntity target) { if (user == null) { return(false); } if (UsesRemaining <= 0) { user.PopupMessage(user, Loc.GetString($"The {Owner.Name} is empty!")); return(false); } var trueTarget = target ?? user; if (trueTarget.TryGetComponent(out StomachComponent stomachComponent)) { var transferAmount = ReagentUnit.Min(_transferAmount, _contents.CurrentVolume); var split = _contents.SplitSolution(transferAmount); if (stomachComponent.TryTransferSolution(split)) { _entitySystem.GetEntitySystem <AudioSystem>() .Play(_useSound, trueTarget, AudioParams.Default.WithVolume(-1f)); trueTarget.PopupMessage(user, Loc.GetString("Nom")); } else { _contents.TryAddSolution(split); trueTarget.PopupMessage(user, Loc.GetString("You can't eat any more!")); } } if (UsesRemaining > 0) { return(true); } //We're empty. Become trash. var position = Owner.Transform.GridPosition; Owner.Delete(); var finisher = Owner.EntityManager.SpawnEntity(_trashPrototype, position); if (user.TryGetComponent(out HandsComponent handsComponent) && finisher.TryGetComponent(out ItemComponent itemComponent)) { if (handsComponent.CanPutInHand(itemComponent)) { handsComponent.PutInHand(itemComponent); return(true); } } finisher.Transform.GridPosition = user.Transform.GridPosition; return(true); }
public bool InteractUsing(InteractUsingEventArgs eventArgs) { var itemEntity = eventArgs.User.GetComponent <HandsComponent>().GetActiveHand.Owner; if (itemEntity.TryGetComponent <PourableComponent>(out var attackPourable)) { //Get target and check if it can be poured into if (!Owner.TryGetComponent <SolutionComponent>(out var mySolution) || !mySolution.CanPourIn) { return(false); } if (!itemEntity.TryGetComponent <SolutionComponent>(out var attackSolution) || !attackSolution.CanPourOut) { return(false); } //Get transfer amount. May be smaller than _transferAmount if not enough room var realTransferAmount = ReagentUnit.Min(attackPourable.TransferAmount, mySolution.EmptyVolume); if (realTransferAmount <= 0) //Special message if container is full { _notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User, Loc.GetString("Container is full")); return(false); } //Move units from attackSolution to targetSolution var removedSolution = attackSolution.SplitSolution(realTransferAmount); if (!mySolution.TryAddSolution(removedSolution)) { return(false); } _notifyManager.PopupMessage(Owner.Transform.GridPosition, eventArgs.User, Loc.GetString("Transferred {0}u", removedSolution.TotalVolume)); return(true); } if (!itemEntity.TryGetComponent(typeof(FoodComponent), out var food)) { _notifyManager.PopupMessage(Owner, eventArgs.User, "That won't work!"); return(false); } var ent = food.Owner; //Get the entity of the ItemComponent. _storage.Insert(ent); UpdateUserInterface(); return(true); }
/// <summary> /// Will overflow this entity to neighboring entities if required /// </summary> private void CheckOverflow(PuddleComponent puddleComponent) { if (puddleComponent.CurrentVolume <= puddleComponent.OverflowVolume || puddleComponent.Overflown) return; var nextPuddles = new List<PuddleComponent>() { puddleComponent }; var overflownPuddles = new List<PuddleComponent>(); while (puddleComponent.OverflowLeft > ReagentUnit.Zero && nextPuddles.Count > 0) { foreach (var next in nextPuddles.ToArray()) { nextPuddles.Remove(next); next.Overflown = true; overflownPuddles.Add(next); var adjacentPuddles = GetAllAdjacentOverflow(next).ToArray(); if (puddleComponent.OverflowLeft <= ReagentUnit.Epsilon * adjacentPuddles.Length) { break; } if (adjacentPuddles.Length == 0) { continue; } var numberOfAdjacent = ReagentUnit.New(adjacentPuddles.Length); var overflowSplit = puddleComponent.OverflowLeft / numberOfAdjacent; foreach (var adjacent in adjacentPuddles) { var adjacentPuddle = adjacent(); var quantity = ReagentUnit.Min(overflowSplit, adjacentPuddle.OverflowVolume); var puddleSolution = _solutionContainerSystem.EnsureSolution(puddleComponent.Owner.Uid, puddleComponent.SolutionName); var spillAmount = _solutionContainerSystem.SplitSolution(puddleComponent.Owner.Uid, puddleSolution, quantity); TryAddSolution(adjacentPuddle.Owner.Uid, spillAmount, false, false); nextPuddles.Add(adjacentPuddle); } } } foreach (var puddle in overflownPuddles) { puddle.Overflown = false; } }
public void ReagentUnitMin() { var unorderedList = new[] { ReagentUnit.New(5), ReagentUnit.New(3), ReagentUnit.New(1), ReagentUnit.New(2), ReagentUnit.New(4), }; var min = ReagentUnit.Min(unorderedList); Assert.That(min, Is.EqualTo(ReagentUnit.New(1))); }
public void ReagentUnitMin() { var unorderedList = new[] { ReagentUnit.New(5), ReagentUnit.New(3), ReagentUnit.New(1), ReagentUnit.New(2), ReagentUnit.New(4), }; var min = ReagentUnit.Min(unorderedList); Assert.AreEqual(ReagentUnit.New(1), min); }
private void TryInjectIntoBloodstream(BloodstreamComponent targetBloodstream, IEntity user) { if (!Owner.TryGetComponent(out SolutionContainerComponent? solution) || solution.CurrentVolume == 0) { return; } // Get transfer amount. May be smaller than _transferAmount if not enough room var realTransferAmount = ReagentUnit.Min(_transferAmount, targetBloodstream.EmptyVolume); if (realTransferAmount <= 0) { Owner.PopupMessage(user, Loc.GetString("You aren't able to inject {0:theName}!", targetBloodstream.Owner)); return; } // Move units from attackSolution to targetSolution var removedSolution = solution.SplitSolution(realTransferAmount); if (!solution.CanAddSolution(removedSolution)) { return; } // TODO: Account for partial transfer. foreach (var(reagentId, quantity) in removedSolution.Contents) { if (!_prototypeManager.TryIndex(reagentId, out ReagentPrototype reagent)) { continue; } removedSolution.RemoveReagent(reagentId, reagent.ReactionEntity(solution.Owner, ReactionMethod.Injection, quantity)); } solution.TryAddSolution(removedSolution); foreach (var(reagentId, quantity) in removedSolution.Contents) { if (!_prototypeManager.TryIndex(reagentId, out ReagentPrototype reagent)) { continue; } reagent.ReactionEntity(targetBloodstream.Owner, ReactionMethod.Injection, quantity); } Owner.PopupMessage(user, Loc.GetString("You inject {0}u into {1:theName}!", removedSolution.TotalVolume, targetBloodstream.Owner)); Dirty(); }
private bool TryUseDrink(IEntity target, bool forced = false) { if (target == null || !_contents.CanRemoveSolutions) { return(false); } if (!Opened) { target.PopupMessage(Loc.GetString("Open {0:theName} first!", Owner)); return(false); } if (_contents.CurrentVolume.Float() <= 0) { if (!forced) { target.PopupMessage(Loc.GetString("{0:theName} is empty!", Owner)); } return(false); } if (!target.TryGetComponent(out StomachComponent stomachComponent)) { return(false); } var transferAmount = ReagentUnit.Min(TransferAmount, _contents.CurrentVolume); var split = _contents.SplitSolution(transferAmount); if (stomachComponent.TryTransferSolution(split)) { if (_useSound == null) { return(false); } EntitySystem.Get <AudioSystem>().PlayFromEntity(_useSound, target, AudioParams.Default.WithVolume(-2f)); target.PopupMessage(Loc.GetString("Slurp")); UpdateAppearance(); return(true); } // Stomach was full or can't handle whatever solution we have. _contents.TryAddSolution(split); target.PopupMessage(Loc.GetString("You've had enough {0:theName}!", Owner)); return(false); }
public override bool TryUseFood(IEntity?user, IEntity?target, UtensilComponent?utensilUsed = null) { if (user == null) { return(false); } var trueTarget = target ?? user; if (!trueTarget.TryGetComponent(out IBody? body) || !body.TryGetMechanismBehaviors <StomachBehavior>(out var stomachs)) { return(false); } if (!user.InRangeUnobstructed(trueTarget, popup: true)) { return(false); } var transferAmount = ReagentUnit.Min(TransferAmount, _contents.CurrentVolume); var split = _contents.SplitSolution(transferAmount); var firstStomach = stomachs.FirstOrDefault(stomach => stomach.CanTransferSolution(split)); if (firstStomach == null) { _contents.TryAddSolution(split); trueTarget.PopupMessage(user, Loc.GetString("You can't eat any more!")); return(false); } // TODO: Account for partial transfer. split.DoEntityReaction(trueTarget, ReactionMethod.Ingestion); firstStomach.TryTransferSolution(split); if (UseSound != null) { SoundSystem.Play(Filter.Pvs(trueTarget), UseSound, trueTarget, AudioParams.Default.WithVolume(-1f)); } trueTarget.PopupMessage(user, Loc.GetString("You swallow the pill.")); Owner.Delete(); return(true); }
public override void Update(float frameTime) { base.Update(frameTime); var queueDelete = new RemQueue <EvaporationComponent>(); foreach (var evaporationComponent in EntityManager.EntityQuery <EvaporationComponent>()) { var uid = evaporationComponent.Owner.Uid; evaporationComponent.Accumulator += frameTime; if (!_solutionContainerSystem.TryGetSolution(uid, evaporationComponent.SolutionName, out var solution)) { // If no solution, delete the entity queueDelete.Add(evaporationComponent); continue; } if (evaporationComponent.Accumulator < evaporationComponent.EvaporateTime) { continue; } evaporationComponent.Accumulator -= evaporationComponent.EvaporateTime; _solutionContainerSystem.SplitSolution(uid, solution, ReagentUnit.Min(ReagentUnit.New(1), solution.CurrentVolume)); if (solution.CurrentVolume == 0) { EntityManager.QueueDeleteEntity(uid); } else if (solution.CurrentVolume <= evaporationComponent.LowerLimit || solution.CurrentVolume >= evaporationComponent.UpperLimit) { queueDelete.Add(evaporationComponent); } } foreach (var evaporationComponent in queueDelete) { EntityManager.RemoveComponent(evaporationComponent.Owner.Uid, evaporationComponent); } }
public void TryAddSolution(Solution solution) { if (solution.TotalVolume == 0) { return; } if (SolutionContainerComponent == null) { return; } var addSolution = solution.SplitSolution(ReagentUnit.Min(solution.TotalVolume, SolutionContainerComponent.EmptyVolume)); SolutionContainerComponent.TryAddSolution(addSolution); UpdateVisuals(); }
public void TryAddSolution(Solution solution) { if (solution.TotalVolume == 0) { return; } if (!EntitySystem.Get <SolutionContainerSystem>().TryGetSolution(Owner, SolutionName, out var solutionArea)) { return; } var addSolution = solution.SplitSolution(ReagentUnit.Min(solution.TotalVolume, solutionArea.AvailableVolume)); EntitySystem.Get <SolutionContainerSystem>().TryAddSolution(Owner.Uid, solutionArea, addSolution); UpdateVisuals(); }
protected override void ReactWithEntity(IEntity entity, double solutionFraction) { if (!EntitySystem.Get <SolutionContainerSystem>().TryGetSolution(Owner, SolutionName, out var solution)) { return; } if (!entity.TryGetComponent(out BloodstreamComponent? bloodstream)) { return; } // TODO: Add a permeability property to clothing // For now it just adds to protection for each clothing equipped var protection = 0f; if (entity.TryGetComponent(out InventoryComponent? inventory)) { foreach (var slot in inventory.Slots) { if (slot == EquipmentSlotDefines.Slots.BACKPACK || slot == EquipmentSlotDefines.Slots.POCKET1 || slot == EquipmentSlotDefines.Slots.POCKET2 || slot == EquipmentSlotDefines.Slots.IDCARD) { continue; } if (inventory.TryGetSlotItem(slot, out ItemComponent _)) { protection += 0.025f; } } } var cloneSolution = solution.Clone(); var transferAmount = ReagentUnit.Min(cloneSolution.TotalVolume * solutionFraction * (1 - protection), bloodstream.EmptyVolume); var transferSolution = cloneSolution.SplitSolution(transferAmount); bloodstream.TryTransferSolution(transferSolution); }