private void SubtractContents(FoodRecipePrototype recipe) { foreach (var recipeReagent in recipe.IngredientsReagents) { _solution.TryRemoveReagent(recipeReagent.Key, ReagentUnit.New(recipeReagent.Value)); } foreach (var recipeSolid in recipe.IngredientsSolids) { for (var i = 0; i < recipeSolid.Value; i++) { foreach (var item in _storage.ContainedEntities) { if (item.Prototype.ID == recipeSolid.Key) { _storage.Remove(item); item.Delete(); break; } } } } }
async Task <bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs) { if (string.IsNullOrEmpty(_slice)) { return(false); } if (!Owner.TryGetComponent(out SolutionContainerComponent? solution)) { return(false); } if (!eventArgs.Using.TryGetComponent(out UtensilComponent? utensil) || !utensil.HasType(UtensilType.Knife)) { return(false); } var itemToSpawn = Owner.EntityManager.SpawnEntity(_slice, Owner.Transform.Coordinates); if (eventArgs.User.TryGetComponent(out HandsComponent? handsComponent)) { if (ContainerHelpers.IsInContainer(Owner)) { handsComponent.PutInHandOrDrop(itemToSpawn.GetComponent <ItemComponent>()); } } EntitySystem.Get <AudioSystem>().PlayAtCoords(_sound, Owner.Transform.Coordinates, AudioParams.Default.WithVolume(-2)); Count--; if (Count < 1) { Owner.Delete(); return(true); } solution.TryRemoveReagent("chem.Nutriment", solution.CurrentVolume / ReagentUnit.New(Count + 1)); return(true); }
public async Task SpaceNoPuddleTest() { var server = StartServerDummyTicker(); await server.WaitIdleAsync(); var mapManager = server.ResolveDependency <IMapManager>(); var pauseManager = server.ResolveDependency <IPauseManager>(); IMapGrid grid = null; // Build up test environment server.Post(() => { var mapId = mapManager.CreateMap(); pauseManager.AddUninitializedMap(mapId); var gridId = new GridId(1); if (!mapManager.TryGetGrid(gridId, out grid)) { grid = mapManager.CreateGrid(mapId, gridId); } }); await server.WaitIdleAsync(); server.Assert(() => { var coordinates = grid.ToCoordinates(); var solution = new Solution("water", ReagentUnit.New(20)); var puddle = solution.SpillAt(coordinates, "PuddleSmear"); Assert.Null(puddle); }); await server.WaitIdleAsync(); }
/// <summary> /// Gets component data to be used to update the user interface client-side. /// </summary> /// <returns>Returns a <see cref="SharedReagentDispenserComponent.ReagentDispenserBoundUserInterfaceState"/></returns> private ReagentDispenserBoundUserInterfaceState GetUserInterfaceState() { var beaker = _beakerContainer.ContainedEntity; if (beaker == null) { return(new ReagentDispenserBoundUserInterfaceState(false, ReagentUnit.New(0), ReagentUnit.New(0), "", Inventory, Owner.Name, null, _dispenseAmount)); } var solution = beaker.GetComponent <SolutionComponent>(); return(new ReagentDispenserBoundUserInterfaceState(true, solution.CurrentVolume, solution.MaxVolume, beaker.Name, Inventory, Owner.Name, solution.ReagentList.ToList(), _dispenseAmount)); }
public void ReagentUnitStringTests(string value, string expected) { var result = ReagentUnit.New(value); Assert.AreEqual(expected, $"{result}"); }
void IExposeData.ExposeData(ObjectSerializer serializer) { serializer.DataField(ref _metabolismRate, "rate", ReagentUnit.New(1)); serializer.DataField(ref _hydrationFactor, "nutrimentFactor", 30.0f); }
public void SetTransferAmount(ReagentUnit amount) { amount = ReagentUnit.New(Math.Clamp(amount.Int(), MinimumTransferAmount.Int(), MaximumTransferAmount.Int())); TransferAmount = amount; }
public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); serializer.DataField(ref _transferAmount, "transferAmount", ReagentUnit.New(0.5)); }
private void OnInit(EntityUid uid, PuddleComponent component, ComponentInit args) { var solution = _solutionContainerSystem.EnsureSolution(uid, component.SolutionName); solution.MaxVolume = ReagentUnit.New(1000); }
ReagentUnit IMetabolizable.Metabolize(IEntity solutionEntity, string reagentId, float tickTime) { return(ReagentUnit.New(MetabolismRate * tickTime)); }
private void TryCreatePackage(IEntity user, UiAction action, int pillAmount, int bottleAmount) { var random = IoCManager.Resolve <IRobustRandom>(); if (action == UiAction.CreateBottles) { var individualVolume = BufferSolution.CurrentVolume / ReagentUnit.New(bottleAmount); var actualVolume = ReagentUnit.Min(individualVolume, ReagentUnit.New(30)); for (int i = 0; i < bottleAmount; i++) { var bottle = Owner.EntityManager.SpawnEntity("bottle", Owner.Transform.GridPosition); var bufferSolution = BufferSolution.Solution.SplitSolution(actualVolume); bottle.TryGetComponent <SolutionComponent>(out var bottleSolution); bottleSolution?.Solution.AddSolution(bufferSolution); //Try to give them the bottle if (user.TryGetComponent <HandsComponent>(out var hands) && bottle.TryGetComponent <ItemComponent>(out var item)) { if (hands.CanPutInHand(item)) { hands.PutInHand(item); continue; } } //Put it on the floor bottle.Transform.GridPosition = user.Transform.GridPosition; //Give it an offset var x_negative = random.Prob(0.5f) ? -1 : 1; var y_negative = random.Prob(0.5f) ? -1 : 1; bottle.Transform.LocalPosition += new Vector2(random.NextFloat() * 0.2f * x_negative, random.NextFloat() * 0.2f * y_negative); } } else //Pills { var individualVolume = BufferSolution.CurrentVolume / ReagentUnit.New(pillAmount); var actualVolume = ReagentUnit.Min(individualVolume, ReagentUnit.New(50)); for (int i = 0; i < pillAmount; i++) { var pill = Owner.EntityManager.SpawnEntity("pill", Owner.Transform.GridPosition); var bufferSolution = BufferSolution.Solution.SplitSolution(actualVolume); pill.TryGetComponent <SolutionComponent>(out var pillSolution); pillSolution?.Solution.AddSolution(bufferSolution); //Try to give them the bottle if (user.TryGetComponent <HandsComponent>(out var hands) && pill.TryGetComponent <ItemComponent>(out var item)) { if (hands.CanPutInHand(item)) { hands.PutInHand(item); continue; } } //Put it on the floor pill.Transform.GridPosition = user.Transform.GridPosition; //Give it an offset var x_negative = random.Prob(0.5f) ? -1 : 1; var y_negative = random.Prob(0.5f) ? -1 : 1; pill.Transform.LocalPosition += new Vector2(random.NextFloat() * 0.2f * x_negative, random.NextFloat() * 0.2f * y_negative); } } UpdateUserInterface(); }
/// <summary> /// Gets component data to be used to update the user interface client-side. /// </summary> /// <returns>Returns a <see cref="SharedChemMasterComponent.ChemMasterBoundUserInterfaceState"/></returns> private ChemMasterBoundUserInterfaceState GetUserInterfaceState() { var beaker = _beakerContainer.ContainedEntity; if (beaker == null) { return(new ChemMasterBoundUserInterfaceState(false, ReagentUnit.New(0), ReagentUnit.New(0), "", Owner.Name, null, BufferSolution.ReagentList.ToList(), BufferModeTransfer, BufferSolution.CurrentVolume, BufferSolution.MaxVolume)); } var solution = beaker.GetComponent <SolutionComponent>(); return(new ChemMasterBoundUserInterfaceState(true, solution.CurrentVolume, solution.MaxVolume, beaker.Name, Owner.Name, solution.ReagentList.ToList(), BufferSolution.ReagentList.ToList(), BufferModeTransfer, BufferSolution.CurrentVolume, BufferSolution.MaxVolume)); }
public void ExposeData(ObjectSerializer serializer) { serializer.DataField(ref _amount, "amount", ReagentUnit.New(1)); serializer.DataField(ref _catalyst, "catalyst", false); }
public async Task <bool> InteractUsing(InteractUsingEventArgs eventArgs) { var user = eventArgs.User; var usingItem = eventArgs.Using; if (usingItem == null || usingItem.Deleted || !ActionBlockerSystem.CanInteract(user)) { return(false); } if (usingItem.TryGetComponent(out SeedComponent? seeds)) { if (Seed == null) { if (seeds.Seed == null) { user.PopupMessageCursor(Loc.GetString("The packet seems to be empty. You throw it away.")); usingItem.Delete(); return(false); } user.PopupMessageCursor(Loc.GetString("You plant the {0} {1}.", seeds.Seed.SeedName, seeds.Seed.SeedNoun)); Seed = seeds.Seed; Dead = false; Age = 1; Health = Seed.Endurance; _lastCycle = _gameTiming.CurTime; usingItem.Delete(); CheckLevelSanity(); UpdateSprite(); return(true); } user.PopupMessageCursor(Loc.GetString("The {0} already has seeds in it!", Owner.Name)); return(false); } if (usingItem.HasComponent <HoeComponent>()) { if (WeedLevel > 0) { user.PopupMessageCursor(Loc.GetString("You remove the weeds from the {0}.", Owner.Name)); user.PopupMessageOtherClients(Loc.GetString("{0} starts uprooting the weeds.", user.Name)); WeedLevel = 0; UpdateSprite(); } else { user.PopupMessageCursor(Loc.GetString("This plot is devoid of weeds! It doesn't need uprooting.")); } return(true); } if (usingItem.TryGetComponent(out SolutionContainerComponent? solution) && solution.CanRemoveSolutions) { var amount = 5f; var sprayed = false; if (usingItem.TryGetComponent(out SprayComponent? spray)) { sprayed = true; amount = 1f; EntitySystem.Get <AudioSystem>().PlayFromEntity(spray.SpraySound, usingItem, AudioHelpers.WithVariation(0.125f)); } var chemAmount = ReagentUnit.New(amount); var split = solution.Solution.SplitSolution(chemAmount <= solution.Solution.TotalVolume ? chemAmount : solution.Solution.TotalVolume); user.PopupMessageCursor(Loc.GetString(sprayed ? $"You spray {Owner.Name} with {usingItem.Name}." : $"You transfer {split.TotalVolume.ToString()}u to {Owner.Name}")); _solutionContainer?.TryAddSolution(split); SkipAging++; // We're forcing an update cycle, so one age hasn't passed. ForceUpdate = true; Update(); return(true); } if (usingItem.HasComponent <PlantSampleTakerComponent>()) { if (Seed == null) { user.PopupMessageCursor(Loc.GetString("There is nothing to take a sample of!")); return(false); } if (Sampled) { user.PopupMessageCursor(Loc.GetString("This plant has already been sampled.")); return(false); } if (Dead) { user.PopupMessageCursor(Loc.GetString("This plant is dead.")); return(false); } var seed = Seed.SpawnSeedPacket(user.Transform.Coordinates); seed.RandomOffset(0.25f); user.PopupMessageCursor(Loc.GetString($"You take a sample from the {Seed.DisplayName}.")); Health -= (_random.Next(3, 5) * 10); if (_random.Prob(0.3f)) { Sampled = true; } // Just in case. CheckLevelSanity(); SkipAging++; // We're forcing an update cycle, so one age hasn't passed. ForceUpdate = true; Update(); return(true); } if (usingItem.HasComponent <BotanySharpComponent>()) { return(DoHarvest(user)); } return(false); }
/// <summary> /// Update the container, buffer, and packaging panels. /// </summary> /// <param name="state">State data for the dispenser.</param> private void UpdatePanelInfo(ChemMasterBoundUserInterfaceState state) { var bufferModeTransfer = state.BufferModeTransfer; BufferTransferButton.Pressed = bufferModeTransfer; BufferDiscardButton.Pressed = !bufferModeTransfer; ContainerInfo.Children.Clear(); if (!state.HasBeaker) { ContainerInfo.Children.Add(new Label { Text = Loc.GetString("chem-master-window-no-container-loaded-text") }); return; } ContainerInfo.Children.Add(new BoxContainer // Name of the container and its fill status (Ex: 44/100u) { Orientation = LayoutOrientation.Horizontal, Children = { new Label { Text = $"{state.ContainerName}: " }, new Label { Text = $"{state.BeakerCurrentVolume}/{state.BeakerMaxVolume}", StyleClasses ={ StyleNano.StyleClassLabelSecondaryColor } } } }); foreach (var reagent in state.ContainerReagents) { var name = Loc.GetString("chem-master-window-unknown-reagent-text"); //Try to the prototype for the given reagent. This gives us it's name. if (_prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype? proto)) { name = proto.Name; } if (proto != null) { ContainerInfo.Children.Add(new BoxContainer { Orientation = LayoutOrientation.Horizontal, Children = { new Label { Text = $"{name}: " }, new Label { Text = $"{reagent.Quantity}u", StyleClasses ={ StyleNano.StyleClassLabelSecondaryColor } }, //Padding new Control { HorizontalExpand = true }, MakeChemButton("1", ReagentUnit.New(1), reagent.ReagentId, false, StyleBase.ButtonOpenRight), MakeChemButton("5", ReagentUnit.New(5), reagent.ReagentId, false, StyleBase.ButtonOpenBoth), MakeChemButton("10", ReagentUnit.New(10), reagent.ReagentId, false, StyleBase.ButtonOpenBoth), MakeChemButton("25", ReagentUnit.New(25), reagent.ReagentId, false, StyleBase.ButtonOpenBoth), MakeChemButton(Loc.GetString("chem-master-window-buffer-all-amount"), ReagentUnit.New(-1), reagent.ReagentId, false, StyleBase.ButtonOpenLeft), } }); } } BufferInfo.Children.Clear(); if (!state.BufferReagents.Any()) { BufferInfo.Children.Add(new Label { Text = Loc.GetString("chem-master-window-buffer-empty-text") }); return; } var bufferHBox = new BoxContainer { Orientation = LayoutOrientation.Horizontal }; BufferInfo.AddChild(bufferHBox); var bufferLabel = new Label { Text = $"{Loc.GetString("chem-master-window-buffer-label")} " }; bufferHBox.AddChild(bufferLabel); var bufferVol = new Label { Text = $"{state.BufferCurrentVolume}", StyleClasses = { StyleNano.StyleClassLabelSecondaryColor } }; bufferHBox.AddChild(bufferVol); foreach (var reagent in state.BufferReagents) { var name = Loc.GetString("chem-master-window-unknown-reagent-text"); //Try to the prototype for the given reagent. This gives us it's name. if (_prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype? proto)) { name = proto.Name; } if (proto != null) { BufferInfo.Children.Add(new BoxContainer { Orientation = LayoutOrientation.Horizontal, //SizeFlagsHorizontal = SizeFlags.ShrinkEnd, Children = { new Label { Text = $"{name}: " }, new Label { Text = $"{reagent.Quantity}u", StyleClasses ={ StyleNano.StyleClassLabelSecondaryColor } }, //Padding new Control { HorizontalExpand = true }, MakeChemButton("1", ReagentUnit.New(1), reagent.ReagentId, true, StyleBase.ButtonOpenRight), MakeChemButton("5", ReagentUnit.New(5), reagent.ReagentId, true, StyleBase.ButtonOpenBoth), MakeChemButton("10", ReagentUnit.New(10), reagent.ReagentId, true, StyleBase.ButtonOpenBoth), MakeChemButton("25", ReagentUnit.New(25), reagent.ReagentId, true, StyleBase.ButtonOpenBoth), MakeChemButton(Loc.GetString("chem-master-window-buffer-all-amount"), ReagentUnit.New(-1), reagent.ReagentId, true, StyleBase.ButtonOpenLeft), } }); } } }
public void ReagentUnitStringTests(string value, string expected) { var result = ReagentUnit.New(value); Assert.That($"{result}", Is.EqualTo(expected)); }
async Task <bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs) { var user = eventArgs.User; var usingItem = eventArgs.Using; if (usingItem == null || usingItem.Deleted || !EntitySystem.Get <ActionBlockerSystem>().CanInteract(user)) { return(false); } if (usingItem.TryGetComponent(out SeedComponent? seeds)) { if (Seed == null) { if (seeds.Seed == null) { user.PopupMessageCursor(Loc.GetString("plant-holder-component-empty-seed-packet-message")); usingItem.QueueDelete(); return(false); } user.PopupMessageCursor(Loc.GetString("plant-holder-component-plant-success-message", ("seedName", seeds.Seed.SeedName), ("seedNoun", seeds.Seed.SeedNoun))); Seed = seeds.Seed; Dead = false; Age = 1; Health = Seed.Endurance; _lastCycle = _gameTiming.CurTime; usingItem.QueueDelete(); CheckLevelSanity(); UpdateSprite(); return(true); } user.PopupMessageCursor(Loc.GetString("plant-holder-component-already-seeded-message", ("name", Owner.Name))); return(false); } if (usingItem.HasTag("Hoe")) { if (WeedLevel > 0) { user.PopupMessageCursor(Loc.GetString("plant-holder-component-remove-weeds-message", ("name", Owner.Name))); user.PopupMessageOtherClients(Loc.GetString("plant-holder-component-remove-weeds-others-message", ("otherName", user.Name))); WeedLevel = 0; UpdateSprite(); } else { user.PopupMessageCursor(Loc.GetString("plant-holder-component-no-weeds-message")); } return(true); } if (usingItem.HasTag("Shovel")) { if (Seed != null) { user.PopupMessageCursor(Loc.GetString("plant-holder-component-remove-plant-message", ("name", Owner.Name))); user.PopupMessageOtherClients(Loc.GetString("plant-holder-component-remove-plant-others-message", ("name", user.Name))); RemovePlant(); } else { user.PopupMessageCursor(Loc.GetString("plant-holder-component-no-plant-message")); } return(true); } if (usingItem.TryGetComponent(out ISolutionInteractionsComponent? solution) && solution.CanDrain) { var amount = ReagentUnit.New(5); var sprayed = false; if (usingItem.TryGetComponent(out SprayComponent? spray)) { sprayed = true; amount = ReagentUnit.New(1); if (!string.IsNullOrEmpty(spray.SpraySound)) { SoundSystem.Play(Filter.Pvs(usingItem), spray.SpraySound, usingItem, AudioHelpers.WithVariation(0.125f)); } } var split = solution.Drain(amount); if (split.TotalVolume == 0) { user.PopupMessageCursor(Loc.GetString("plant-holder-component-empty-message", ("owner", usingItem))); return(true); } user.PopupMessageCursor(Loc.GetString(sprayed ? "plant-holder-component-spray-message" : "plant-holder-component-transfer-message", ("owner", Owner), ("amount", split.TotalVolume))); _solutionContainer?.TryAddSolution(split); ForceUpdateByExternalCause(); return(true); } if (usingItem.HasTag("PlantSampleTaker")) { if (Seed == null) { user.PopupMessageCursor(Loc.GetString("plant-holder-component-nothing-to-sample-message")); return(false); } if (Sampled) { user.PopupMessageCursor(Loc.GetString("plant-holder-component-already-sampled-message")); return(false); } if (Dead) { user.PopupMessageCursor(Loc.GetString("plant-holder-component-dead-plant-message")); return(false); } var seed = Seed.SpawnSeedPacket(user.Transform.Coordinates); seed.RandomOffset(0.25f); user.PopupMessageCursor(Loc.GetString("plant-holder-component-take-sample-message", ("seedName", Seed.DisplayName))); Health -= (_random.Next(3, 5) * 10); if (_random.Prob(0.3f)) { Sampled = true; } // Just in case. CheckLevelSanity(); ForceUpdateByExternalCause(); return(true); } if (usingItem.HasTag("BotanySharp")) { return(DoHarvest(user)); } if (usingItem.HasComponent <ProduceComponent>()) { user.PopupMessageCursor(Loc.GetString("plant-holder-component-compost-message", ("owner", Owner), ("usingItem", usingItem))); user.PopupMessageOtherClients(Loc.GetString("plant-holder-component-compost-others-message", ("user", user), ("usingItem", usingItem), ("owner", Owner))); if (usingItem.TryGetComponent(out SolutionContainerComponent? solution2)) { // This deliberately discards overfill. _solutionContainer?.TryAddSolution(solution2.SplitSolution(solution2.Solution.TotalVolume)); ForceUpdateByExternalCause(); } usingItem.QueueDelete(); return(true); } return(false); }
async Task <bool> IInteractUsing.InteractUsing(InteractUsingEventArgs eventArgs) { var user = eventArgs.User; var usingItem = eventArgs.Using; if (usingItem == null || usingItem.Deleted || !ActionBlockerSystem.CanInteract(user)) { return(false); } if (usingItem.TryGetComponent(out SeedComponent? seeds)) { if (Seed == null) { if (seeds.Seed == null) { user.PopupMessageCursor(Loc.GetString("The packet seems to be empty. You throw it away.")); usingItem.Delete(); return(false); } user.PopupMessageCursor(Loc.GetString("You plant the {0} {1}.", seeds.Seed.SeedName, seeds.Seed.SeedNoun)); Seed = seeds.Seed; Dead = false; Age = 1; Health = Seed.Endurance; _lastCycle = _gameTiming.CurTime; usingItem.Delete(); CheckLevelSanity(); UpdateSprite(); return(true); } user.PopupMessageCursor(Loc.GetString("The {0} already has seeds in it!", Owner.Name)); return(false); } if (usingItem.HasTag("Hoe")) { if (WeedLevel > 0) { user.PopupMessageCursor(Loc.GetString("You remove the weeds from the {0}.", Owner.Name)); user.PopupMessageOtherClients(Loc.GetString("{0} starts uprooting the weeds.", user.Name)); WeedLevel = 0; UpdateSprite(); } else { user.PopupMessageCursor(Loc.GetString("This plot is devoid of weeds! It doesn't need uprooting.")); } return(true); } if (usingItem.HasTag("Shovel")) { if (Seed != null) { user.PopupMessageCursor(Loc.GetString("You remove the plant from the {0}.", Owner.Name)); user.PopupMessageOtherClients(Loc.GetString("{0} removes the plant.", user.Name)); RemovePlant(); } else { user.PopupMessageCursor(Loc.GetString("There is no plant to remove.")); } return(true); } if (usingItem.TryGetComponent(out ISolutionInteractionsComponent? solution) && solution.CanDrain) { var amount = ReagentUnit.New(5); var sprayed = false; if (usingItem.TryGetComponent(out SprayComponent? spray)) { sprayed = true; amount = ReagentUnit.New(1); if (!string.IsNullOrEmpty(spray.SpraySound)) { SoundSystem.Play(Filter.Pvs(usingItem), spray.SpraySound, usingItem, AudioHelpers.WithVariation(0.125f)); } } var split = solution.Drain(amount); if (split.TotalVolume == 0) { user.PopupMessageCursor(Loc.GetString("{0:TheName} is empty!", usingItem)); return(true); } user.PopupMessageCursor(Loc.GetString( sprayed ? "You spray {0:TheName}" : "You transfer {1}u to {0:TheName}", Owner, split.TotalVolume)); _solutionContainer?.TryAddSolution(split); ForceUpdateByExternalCause(); return(true); } if (usingItem.HasTag("PlantSampleTaker")) { if (Seed == null) { user.PopupMessageCursor(Loc.GetString("There is nothing to take a sample of!")); return(false); } if (Sampled) { user.PopupMessageCursor(Loc.GetString("This plant has already been sampled.")); return(false); } if (Dead) { user.PopupMessageCursor(Loc.GetString("This plant is dead.")); return(false); } var seed = Seed.SpawnSeedPacket(user.Transform.Coordinates); seed.RandomOffset(0.25f); user.PopupMessageCursor(Loc.GetString($"You take a sample from the {Seed.DisplayName}.")); Health -= (_random.Next(3, 5) * 10); if (_random.Prob(0.3f)) { Sampled = true; } // Just in case. CheckLevelSanity(); ForceUpdateByExternalCause(); return(true); } if (usingItem.HasTag("BotanySharp")) { return(DoHarvest(user)); } if (usingItem.HasComponent <ProduceComponent>()) { user.PopupMessageCursor(Loc.GetString("You compost {1:theName} into {0:theName}.", Owner, usingItem)); user.PopupMessageOtherClients(Loc.GetString("{0:TheName} composts {1:theName} into {2:theName}.", user, usingItem, Owner)); if (usingItem.TryGetComponent(out SolutionContainerComponent? solution2)) { // This deliberately discards overfill. _solutionContainer?.TryAddSolution(solution2.SplitSolution(solution2.Solution.TotalVolume)); ForceUpdateByExternalCause(); } usingItem.Delete(); return(true); } return(false); }
public async Task PuddlePauseTest() { var server = StartServer(); await server.WaitIdleAsync(); var sMapManager = server.ResolveDependency <IMapManager>(); var sPauseManager = server.ResolveDependency <IPauseManager>(); var sTileDefinitionManager = server.ResolveDependency <ITileDefinitionManager>(); var sGameTiming = server.ResolveDependency <IGameTiming>(); var sEntityManager = server.ResolveDependency <IEntityManager>(); MapId sMapId = default; IMapGrid sGrid; GridId sGridId = default; IEntity sGridEntity = null; EntityCoordinates sCoordinates = default; // Spawn a paused map with one tile to spawn puddles on await server.WaitPost(() => { sMapId = sMapManager.CreateMap(); sPauseManager.SetMapPaused(sMapId, true); sGrid = sMapManager.CreateGrid(sMapId); sGridId = sGrid.Index; sGridEntity = sEntityManager.GetEntity(sGrid.GridEntityId); sGridEntity.Paused = true; // See https://github.com/space-wizards/RobustToolbox/issues/1444 var tileDefinition = sTileDefinitionManager["underplating"]; var tile = new Tile(tileDefinition.TileId); sCoordinates = sGrid.ToCoordinates(); sGrid.SetTile(sCoordinates, tile); }); // Check that the map and grid are paused await server.WaitAssertion(() => { Assert.True(sPauseManager.IsGridPaused(sGridId)); Assert.True(sPauseManager.IsMapPaused(sMapId)); Assert.True(sGridEntity.Paused); }); float sEvaporateTime = default; PuddleComponent sPuddle = null; Solution solution = null; ReagentUnit sPuddleStartingVolume = default; // Spawn a puddle await server.WaitAssertion(() => { var solution = new Solution("water", ReagentUnit.New(20)); sPuddle = solution.SpillAt(sCoordinates, "PuddleSmear"); // Check that the puddle was created Assert.NotNull(sPuddle); sPuddle.Owner.Paused = true; // See https://github.com/space-wizards/RobustToolbox/issues/1445 Assert.True(sPuddle.Owner.Paused); // Check that the puddle is going to evaporate Assert.Positive(sPuddle.EvaporateTime); // Should have a timer component added to it for evaporation Assert.True(sPuddle.Owner.TryGetComponent(out TimerComponent _)); sEvaporateTime = sPuddle.EvaporateTime; sPuddleStartingVolume = sPuddle.CurrentVolume; }); // Wait enough time for it to evaporate if it was unpaused var sTimeToWait = (5 + (int)Math.Ceiling(sEvaporateTime * sGameTiming.TickRate)) * 2; await server.WaitRunTicks(sTimeToWait); // No evaporation due to being paused await server.WaitAssertion(() => { Assert.True(sPuddle.Owner.Paused); Assert.True(sPuddle.Owner.TryGetComponent(out TimerComponent _)); // Check that the puddle still exists Assert.False(sPuddle.Owner.Deleted); }); // Unpause the map await server.WaitPost(() => { sPauseManager.SetMapPaused(sMapId, false); }); // Check that the map, grid and puddle are unpaused await server.WaitAssertion(() => { Assert.False(sPauseManager.IsMapPaused(sMapId)); Assert.False(sPauseManager.IsGridPaused(sGridId)); Assert.False(sPuddle.Owner.Paused); // Check that the puddle still exists Assert.False(sPuddle.Owner.Deleted); }); // Wait enough time for it to evaporate await server.WaitRunTicks(sTimeToWait); // Puddle evaporation should have ticked await server.WaitAssertion(() => { // Check that the puddle is unpaused Assert.False(sPuddle.Owner.Paused); // Check that the puddle has evaporated some of its volume Assert.That(sPuddle.CurrentVolume, Is.LessThan(sPuddleStartingVolume)); // If its new volume is zero it should have been deleted if (sPuddle.CurrentVolume == ReagentUnit.Zero) { Assert.True(sPuddle.Deleted); } }); }
public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); serializer.DataField(ref _initialMaxVolume, "maxVolume", ReagentUnit.New(250)); }
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); }
/// <summary> /// Handles ui messages from the client. For things such as button presses /// which interact with the world and require server action. /// </summary> /// <param name="obj">A user interface message from the client.</param> private void OnUiReceiveMessage(ServerBoundUserInterfaceMessage obj) { var msg = (UiButtonPressedMessage)obj.Message; var needsPower = msg.Button switch { UiButton.Eject => false, _ => true, }; if (!PlayerCanUseDispenser(obj.Session.AttachedEntity, needsPower)) { return; } switch (msg.Button) { case UiButton.Eject: TryEject(obj.Session.AttachedEntity); break; case UiButton.Clear: TryClear(); break; case UiButton.SetDispenseAmount1: _dispenseAmount = ReagentUnit.New(1); break; case UiButton.SetDispenseAmount5: _dispenseAmount = ReagentUnit.New(5); break; case UiButton.SetDispenseAmount10: _dispenseAmount = ReagentUnit.New(10); break; case UiButton.SetDispenseAmount25: _dispenseAmount = ReagentUnit.New(25); break; case UiButton.SetDispenseAmount50: _dispenseAmount = ReagentUnit.New(50); break; case UiButton.SetDispenseAmount100: _dispenseAmount = ReagentUnit.New(100); break; case UiButton.Dispense: if (HasBeaker) { TryDispense(msg.DispenseIndex); } break; default: throw new ArgumentOutOfRangeException(); } ClickSound(); }