private void Stop(IConsoleShell shell, IPlayerSession?player) { var resultText = EntitySystem.Get <StationEventSystem>().StopEvent(); shell.WriteLine(resultText); }
public void Execute(IConsoleShell shell, string argStr, string[] args) { EntitySystem.Get <RoundEndSystem>().EndRound(); }
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); }
private void SubtractContents(FoodRecipePrototype recipe) { var totalReagentsToRemove = new Dictionary <string, FixedPoint2>(recipe.IngredientsReagents); var solutionContainerSystem = EntitySystem.Get <SolutionContainerSystem>(); // this is spaghetti ngl foreach (var item in Storage.ContainedEntities) { if (!_entities.TryGetComponent <SolutionContainerManagerComponent>(item, out var solMan)) { continue; } // go over every solution foreach (var(_, solution) in solMan.Solutions) { foreach (var(reagent, _) in recipe.IngredientsReagents) { // removed everything if (!totalReagentsToRemove.ContainsKey(reagent)) { continue; } if (!solution.ContainsReagent(reagent)) { continue; } var quant = solution.GetReagentQuantity(reagent); if (quant >= totalReagentsToRemove[reagent]) { quant = totalReagentsToRemove[reagent]; totalReagentsToRemove.Remove(reagent); } else { totalReagentsToRemove[reagent] -= quant; } solutionContainerSystem.TryRemoveReagent(item, solution, reagent, quant); } } } foreach (var recipeSolid in recipe.IngredientsSolids) { for (var i = 0; i < recipeSolid.Value; i++) { foreach (var item in Storage.ContainedEntities) { var metaData = _entities.GetComponent <MetaDataComponent>(item); if (metaData.EntityPrototype == null) { continue; } if (metaData.EntityPrototype.ID == recipeSolid.Key) { Storage.Remove(item); _entities.DeleteEntity(item); break; } } } } }
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; } var solutionsSys = EntitySystem.Get <SolutionContainerSystem>(); solutionsSys.TryGetSolution(Owner, SolutionName, out var hypoSpraySolution); if (hypoSpraySolution == null || hypoSpraySolution.CurrentVolume == 0) { user.PopupMessageCursor(Loc.GetString("hypospray-component-empty-message")); return(true); } if (!solutionsSys.TryGetInjectableSolution(target.Uid, out var targetSolution)) { user.PopupMessage(user, Loc.GetString("hypospray-cant-inject", ("target", target))); return(false); } 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); // Get transfer amount. May be smaller than _transferAmount if not enough room var realTransferAmount = ReagentUnit.Min(TransferAmount, targetSolution.AvailableVolume); if (realTransferAmount <= 0) { user.PopupMessage(user, Loc.GetString("hypospray-component-transfer-already-full-message", ("owner", target))); return(true); } // Move units from attackSolution to targetSolution var removedSolution = EntitySystem.Get <SolutionContainerSystem>() .SplitSolution(Owner.Uid, hypoSpraySolution, realTransferAmount); if (!targetSolution.CanAddSolution(removedSolution)) { return(true); } removedSolution.DoEntityReaction(target, ReactionMethod.Injection); EntitySystem.Get <SolutionContainerSystem>().TryAddSolution(target.Uid, targetSolution, removedSolution);
public async Task Test() { var server = StartServer(new ServerContentIntegrationOption { ExtraPrototypes = Prototypes }); await server.WaitIdleAsync(); var sEntityManager = server.ResolveDependency <IEntityManager>(); var sMapManager = server.ResolveDependency <IMapManager>(); var sPrototypeManager = server.ResolveDependency <IPrototypeManager>(); var sEntitySystemManager = server.ResolveDependency <IEntitySystemManager>(); EntityUid sDestructibleEntity = default; TestDestructibleListenerSystem sTestThresholdListenerSystem = null; await server.WaitPost(() => { var gridId = GetMainGrid(sMapManager).GridEntityId; var coordinates = new EntityCoordinates(gridId, 0, 0); sDestructibleEntity = sEntityManager.SpawnEntity(DestructibleDestructionEntityId, coordinates); sTestThresholdListenerSystem = sEntitySystemManager.GetEntitySystem <TestDestructibleListenerSystem>(); }); await server.WaitAssertion(() => { var coordinates = IoCManager.Resolve <IEntityManager>().GetComponent <TransformComponent>(sDestructibleEntity).Coordinates; var bruteDamageGroup = sPrototypeManager.Index <DamageGroupPrototype>("TestBrute"); DamageSpecifier bruteDamage = new(bruteDamageGroup, 50); Assert.DoesNotThrow(() => { EntitySystem.Get <DamageableSystem>().TryChangeDamage(sDestructibleEntity, bruteDamage, true); }); Assert.That(sTestThresholdListenerSystem.ThresholdsReached.Count, Is.EqualTo(1)); var threshold = sTestThresholdListenerSystem.ThresholdsReached[0].Threshold; Assert.That(threshold.Triggered, Is.True); Assert.That(threshold.Behaviors.Count, Is.EqualTo(3)); var spawnEntitiesBehavior = (SpawnEntitiesBehavior)threshold.Behaviors.Single(b => b is SpawnEntitiesBehavior); Assert.That(spawnEntitiesBehavior.Spawn.Count, Is.EqualTo(1)); Assert.That(spawnEntitiesBehavior.Spawn.Keys.Single(), Is.EqualTo(SpawnedEntityId)); Assert.That(spawnEntitiesBehavior.Spawn.Values.Single(), Is.EqualTo(new MinMax { Min = 1, Max = 1 })); var entitiesInRange = IoCManager.Resolve <IEntityLookup>().GetEntitiesInRange(coordinates, 2); var found = false; foreach (var entity in entitiesInRange) { if (sEntityManager.GetComponent <MetaDataComponent>(entity).EntityPrototype == null) { continue; } if (sEntityManager.GetComponent <MetaDataComponent>(entity).EntityPrototype?.Name != SpawnedEntityId) { continue; } found = true; break; } Assert.That(found, Is.True); }); }
private void ClickSound() { EntitySystem.Get <AudioSystem>().PlayFromEntity("/Audio/Machines/machine_switch.ogg", Owner, AudioParams.Default.WithVolume(-2f)); }
/// <inheritdoc /> protected override void Shutdown() { base.Shutdown(); EntitySystem.Get <ResearchSystem>()?.UnregisterServer(this); }
public bool TryUseFood(IEntity?user, IEntity?target, UtensilComponent?utensilUsed = null) { var solutionContainerSys = EntitySystem.Get <SolutionContainerSystem>(); if (!solutionContainerSys.TryGetSolution(Owner, SolutionName, out var solution)) { return(false); } if (user == null) { return(false); } if (UsesRemaining <= 0) { user.PopupMessage(Loc.GetString("food-component-try-use-food-is-empty", ("entity", Owner))); DeleteAndSpawnTrash(user); return(false); } var trueTarget = target ?? user; if (!trueTarget.TryGetComponent(out SharedBodyComponent? body) || !body.TryGetMechanismBehaviors <StomachBehavior>(out var stomachs)) { return(false); } var utensils = utensilUsed != null ? new List <UtensilComponent> { utensilUsed } : null; if (_utensilsNeeded != UtensilType.None) { utensils = new List <UtensilComponent>(); var types = UtensilType.None; if (user.TryGetComponent(out HandsComponent? hands)) { foreach (var item in hands.GetAllHeldItems()) { if (!item.Owner.TryGetComponent(out UtensilComponent? utensil)) { continue; } utensils.Add(utensil); types |= utensil.Types; } } if (!types.HasFlag(_utensilsNeeded)) { trueTarget.PopupMessage(user, Loc.GetString("food-you-need-to-hold-utensil", ("utensil", _utensilsNeeded))); return(false); } } if (!user.InRangeUnobstructed(trueTarget, popup: true)) { return(false); } var transferAmount = TransferAmount != null?ReagentUnit.Min((ReagentUnit)TransferAmount, solution.CurrentVolume) : solution.CurrentVolume; var split = solutionContainerSys.SplitSolution(Owner.Uid, solution, transferAmount); var firstStomach = stomachs.FirstOrDefault(stomach => stomach.CanTransferSolution(split)); if (firstStomach == null) { solutionContainerSys.TryAddSolution(Owner.Uid, solution, split); trueTarget.PopupMessage(user, Loc.GetString("food-you-cannot-eat-any-more")); return(false); } // TODO: Account for partial transfer. split.DoEntityReaction(trueTarget, ReactionMethod.Ingestion); firstStomach.TryTransferSolution(split); SoundSystem.Play(Filter.Pvs(trueTarget), UseSound.GetSound(), trueTarget, AudioParams.Default.WithVolume(-1f)); trueTarget.PopupMessage(user, Loc.GetString(_eatMessage)); // If utensils were used if (utensils != null) { foreach (var utensil in utensils) { utensil.TryBreak(user); } } if (UsesRemaining > 0) { return(true); } if (string.IsNullOrEmpty(TrashPrototype)) { Owner.Delete(); return(true); } DeleteAndSpawnTrash(user); return(true); }
private void UpdateUserInterface() { if (UserInterface == null) { return; } string?error = null; // Check if the player is still holding the gas analyzer => if not, don't update foreach (var session in UserInterface.SubscribedSessions) { if (session.AttachedEntity is not { Valid: true } playerEntity) { return; } if (!_entities.TryGetComponent(playerEntity, out HandsComponent? handsComponent)) { return; } if (handsComponent?.ActiveHandEntity is not { Valid: true } activeHandEntity || !_entities.TryGetComponent(activeHandEntity, out GasAnalyzerComponent? gasAnalyzer)) { return; } } var pos = _entities.GetComponent <TransformComponent>(Owner).Coordinates; if (!_checkPlayer && _position.HasValue) { // Check if position is out of range => don't update if (!_position.Value.InRange(_entities, pos, SharedInteractionSystem.InteractionRange)) { return; } pos = _position.Value; } var gridUid = pos.GetGridUid(_entities); var mapUid = pos.GetMapUid(_entities); var position = pos.ToVector2i(_entities, IoCManager.Resolve <IMapManager>()); var atmosphereSystem = EntitySystem.Get <AtmosphereSystem>(); var tile = atmosphereSystem.GetTileMixture(gridUid, mapUid, position); if (tile == null) { error = "No Atmosphere!"; UserInterface.SetState( new GasAnalyzerBoundUserInterfaceState( 0, 0, null, error)); return; } var gases = new List <GasEntry>(); for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++) { var gas = atmosphereSystem.GetGas(i); if (tile.Moles[i] <= Atmospherics.GasMinMoles) { continue; } gases.Add(new GasEntry(gas.Name, tile.Moles[i], gas.Color)); } UserInterface.SetState( new GasAnalyzerBoundUserInterfaceState( tile.Pressure, tile.Temperature, gases.ToArray(), error)); }
public override void Initialize() { base.Initialize(); _electrocutionSystem = EntitySystem.Get <ElectrocutionSystem>(); }
public override void Update(float frameTime) { base.Update(frameTime); if (!Started) { return; } if (_waveCounter <= 0) { Running = false; return; } _cooldown -= frameTime; if (_cooldown > 0f) { return; } _waveCounter--; _cooldown += (MaximumCooldown - MinimumCooldown) * _robustRandom.NextFloat() + MinimumCooldown; Box2?playableArea = null; var mapId = EntitySystem.Get <GameTicker>().DefaultMap; foreach (var grid in _mapManager.GetAllGrids()) { if (grid.ParentMapId != mapId || !_entityManager.TryGetComponent(grid.GridEntityId, out PhysicsComponent? gridBody)) { continue; } var aabb = gridBody.GetWorldAABB(); playableArea = playableArea?.Union(aabb) ?? aabb; } if (playableArea == null) { EndAfter = float.MinValue; return; } var minimumDistance = (playableArea.Value.TopRight - playableArea.Value.Center).Length + 50f; var maximumDistance = minimumDistance + 100f; var center = playableArea.Value.Center; for (var i = 0; i < MeteorsPerWave; i++) { var angle = new Angle(_robustRandom.NextFloat() * MathF.Tau); var offset = angle.RotateVec(new Vector2((maximumDistance - minimumDistance) * _robustRandom.NextFloat() + minimumDistance, 0)); var spawnPosition = new MapCoordinates(center + offset, mapId); var meteor = _entityManager.SpawnEntity("MeteorLarge", spawnPosition); var physics = _entityManager.GetComponent <PhysicsComponent>(meteor); physics.BodyStatus = BodyStatus.InAir; physics.LinearDamping = 0f; physics.AngularDamping = 0f; physics.ApplyLinearImpulse(-offset.Normalized * MeteorVelocity * physics.Mass); physics.ApplyAngularImpulse( // Get a random angular velocity. physics.Mass * ((MaxAngularVelocity - MinAngularVelocity) * _robustRandom.NextFloat() + MinAngularVelocity)); // TODO: God this disgusts me but projectile needs a refactor. IoCManager.Resolve <IEntityManager>().GetComponent <ProjectileComponent>(meteor).TimeLeft = 120f; } }
public void Update(float delta) { if (Stunned) { StunnedTimer -= delta; if (StunnedTimer <= 0) { StunnedTimer = 0f; Dirty(); } } if (KnockedDown) { KnockdownTimer -= delta; if (KnockdownTimer <= 0f) { EntitySystem.Get <StandingStateSystem>().Standing(Owner); KnockdownTimer = 0f; Dirty(); } } if (SlowedDown) { SlowdownTimer -= delta; if (SlowdownTimer <= 0f) { SlowdownTimer = 0f; if (Owner.TryGetComponent(out MovementSpeedModifierComponent movement)) { movement.RefreshMovementSpeedModifiers(); } Dirty(); } } if (!StunStart.HasValue || !StunEnd.HasValue || !Owner.TryGetComponent(out ServerAlertsComponent status)) { return; } var start = StunStart.Value; var end = StunEnd.Value; var length = (end - start).TotalSeconds; var progress = (_gameTiming.CurTime - start).TotalSeconds; if (progress >= length) { Owner.SpawnTimer(250, () => status.ClearAlert(AlertType.Stun), StatusRemoveCancellation.Token); LastStun = null; } }
protected override void OnInteractHand() { EntitySystem.Get <AudioSystem>() .PlayFromEntity("/Audio/Effects/thudswoosh.ogg", Owner, AudioHelpers.WithVariation(0.05f)); }
public static TileAtmosphere?GetTileAtmosphere(this Vector2i indices, GridId gridId) { var gridAtmos = EntitySystem.Get <AtmosphereSystem>().GetGridAtmosphere(gridId); return(gridAtmos.GetTile(indices)); }
async Task <bool> IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs) { if (eventArgs.Target == null) { return(false); } if (!_entMan.TryGetComponent(eventArgs.Target.Value, out DamageableComponent? targetDamage)) { return(true); } else if (DamageContainerID is not null && !DamageContainerID.Equals(targetDamage.DamageContainerID)) { return(true); } if (!EntitySystem.Get <ActionBlockerSystem>().CanInteract(eventArgs.User)) { return(true); } if (eventArgs.User != eventArgs.Target && !eventArgs.InRangeUnobstructed(ignoreInsideBlocker: true, popup: true)) { return(true); } if (_entMan.TryGetComponent <SharedStackComponent?>(Owner, out var stack) && !EntitySystem.Get <StackSystem>().Use(Owner, 1, stack)) { return(true); } var healed = EntitySystem.Get <DamageableSystem>().TryChangeDamage(eventArgs.Target.Value, Damage, true); if (healed == null) { return(true); } if (eventArgs.Target != eventArgs.User) { EntitySystem.Get <AdminLogSystem>().Add(LogType.Healed, $"{eventArgs.User} healed {eventArgs.Target} for {healed.Total} damage"); } else { EntitySystem.Get <AdminLogSystem>().Add(LogType.Healed, $"{eventArgs.User} healed themselves for {healed.Total} damage"); } return(true); }
private void UpdateUserInterface() { if (UserInterface == null) { return; } string?error = null; // Check if the player is still holding the gas analyzer => if not, don't update foreach (var session in UserInterface.SubscribedSessions) { if (session.AttachedEntity == null) { return; } if (!session.AttachedEntity.TryGetComponent(out IHandsComponent? handsComponent)) { return; } var activeHandEntity = handsComponent?.GetActiveHand?.Owner; if (activeHandEntity == null || !activeHandEntity.TryGetComponent(out GasAnalyzerComponent? gasAnalyzer)) { return; } } var pos = Owner.Transform.Coordinates; if (!_checkPlayer && _position.HasValue) { // Check if position is out of range => don't update if (!_position.Value.InRange(Owner.EntityManager, pos, SharedInteractionSystem.InteractionRange)) { return; } pos = _position.Value; } var atmosSystem = EntitySystem.Get <AtmosphereSystem>(); var gam = atmosSystem.GetGridAtmosphere(pos.GetGridId(Owner.EntityManager)); var tile = gam.GetTile(pos)?.Air; if (tile == null) { error = "No Atmosphere!"; UserInterface.SetState( new GasAnalyzerBoundUserInterfaceState( 0, 0, null, error)); return; } var gases = new List <GasEntry>(); for (var i = 0; i < Atmospherics.TotalNumberOfGases; i++) { var gas = atmosSystem.GetGas(i); if (tile.Gases[i] <= Atmospherics.GasMinMoles) { continue; } gases.Add(new GasEntry(gas.Name, tile.Gases[i], gas.Color)); } UserInterface.SetState( new GasAnalyzerBoundUserInterfaceState( tile.Pressure, tile.Temperature, gases.ToArray(), error)); }
protected override void OnKnockdown() { EntitySystem.Get <StandingStateSystem>().Down(Owner); }
public void CreateBoardAndStockParts() { // Entity might not be initialized yet. var boardContainer = Owner.EnsureContainer <Container>(MachineFrameComponent.BoardContainer, out var existedBoard); var partContainer = Owner.EnsureContainer <Container>(MachineFrameComponent.PartContainer, out var existedParts); if (string.IsNullOrEmpty(BoardPrototype)) { return; } var entityManager = Owner.EntityManager; if (existedBoard || existedParts) { // We're done here, let's suppose all containers are correct just so we don't screw SaveLoadSave. if (boardContainer.ContainedEntities.Count > 0) { return; } } var board = entityManager.SpawnEntity(BoardPrototype, Owner.Transform.Coordinates); if (!_boardContainer.Insert(board)) { throw new Exception($"Couldn't insert board with prototype {BoardPrototype} to machine with prototype {Owner.Prototype?.ID ?? "N/A"}!"); } if (!board.TryGetComponent <MachineBoardComponent>(out var machineBoard)) { throw new Exception($"Entity with prototype {BoardPrototype} doesn't have a {nameof(MachineBoardComponent)}!"); } foreach (var(part, amount) in machineBoard.Requirements) { for (var i = 0; i < amount; i++) { var p = entityManager.SpawnEntity(MachinePartComponent.Prototypes[part], Owner.Transform.Coordinates); if (!partContainer.Insert(p)) { throw new Exception($"Couldn't insert machine part of type {part} to machine with prototype {Owner.Prototype?.ID ?? "N/A"}!"); } } } foreach (var(stackType, amount) in machineBoard.MaterialRequirements) { var stack = EntitySystem.Get <StackSystem>().Spawn(amount, stackType, Owner.Transform.Coordinates); if (stack == null) { throw new Exception($"Couldn't spawn stack of type {stackType}!"); } if (!partContainer.Insert(stack)) { throw new Exception($"Couldn't insert machine material of type {stackType} to machine with prototype {Owner.Prototype?.ID ?? "N/A"}"); } } foreach (var(compName, info) in machineBoard.ComponentRequirements) { for (var i = 0; i < info.Amount; i++) { var c = entityManager.SpawnEntity(info.DefaultPrototype, Owner.Transform.Coordinates); if (!partContainer.Insert(c)) { throw new Exception($"Couldn't insert machine component part with default prototype '{compName}' to machine with prototype {Owner.Prototype?.ID ?? "N/A"}"); } } } foreach (var(tagName, info) in machineBoard.TagRequirements) { for (var i = 0; i < info.Amount; i++) { var c = entityManager.SpawnEntity(info.DefaultPrototype, Owner.Transform.Coordinates); if (!partContainer.Insert(c)) { throw new Exception($"Couldn't insert machine component part with default prototype '{tagName}' to machine with prototype {Owner.Prototype?.ID ?? "N/A"}"); } } } }
public void InsertIdCard(IdCardComponent card) { _idSlot.Insert(card.Owner); ContainedID = card; EntitySystem.Get <AudioSystem>().PlayFromEntity("/Audio/Weapons/Guns/MagIn/batrifle_magin.ogg", Owner); }
// ReSharper disable once InconsistentNaming // ReSharper disable once IdentifierTypo public void Wzhzhzh() { if (!HasContents) { return; } _busy = true; // Convert storage into Dictionary of ingredients var solidsDict = new Dictionary <string, int>(); var reagentDict = new Dictionary <string, FixedPoint2>(); foreach (var item in Storage.ContainedEntities) { // special behavior when being microwaved ;) var ev = new BeingMicrowavedEvent(Owner); _entities.EventBus.RaiseLocalEvent(item, ev, false); if (ev.Handled) { _busy = false; UIDirty = true; return; } var tagSys = EntitySystem.Get <TagSystem>(); if (tagSys.HasTag(item, "MicrowaveMachineUnsafe") || tagSys.HasTag(item, "Metal")) { // destroy microwave Broken = true; SetAppearance(MicrowaveVisualState.Broken); SoundSystem.Play(ItemBreakSound.GetSound(), Filter.Pvs(Owner), Owner); return; } if (tagSys.HasTag(item, "MicrowaveSelfUnsafe") || tagSys.HasTag(item, "Plastic")) { _entities.SpawnEntity(_badRecipeName, _entities.GetComponent <TransformComponent>(Owner).Coordinates); _entities.QueueDeleteEntity(item); } var metaData = _entities.GetComponent <MetaDataComponent>(item); if (metaData.EntityPrototype == null) { continue; } if (solidsDict.ContainsKey(metaData.EntityPrototype.ID)) { solidsDict[metaData.EntityPrototype.ID]++; } else { solidsDict.Add(metaData.EntityPrototype.ID, 1); } if (!_entities.TryGetComponent <SolutionContainerManagerComponent>(item, out var solMan)) { continue; } foreach (var(_, solution) in solMan.Solutions) { foreach (var reagent in solution.Contents) { if (reagentDict.ContainsKey(reagent.ReagentId)) { reagentDict[reagent.ReagentId] += reagent.Quantity; } else { reagentDict.Add(reagent.ReagentId, reagent.Quantity); } } } } // Check recipes (FoodRecipePrototype, int)portionedRecipe = _recipeManager.Recipes.Select( r => CanSatisfyRecipe(r, solidsDict, reagentDict)).Where(r => r.Item2 > 0).FirstOrDefault(); FoodRecipePrototype?recipeToCook = portionedRecipe.Item1; SetAppearance(MicrowaveVisualState.Cooking); var time = _currentCookTimerTime * _cookTimeMultiplier; SoundSystem.Play(_startCookingSound.GetSound(), Filter.Pvs(Owner), Owner, AudioParams.Default); Owner.SpawnTimer((int)(_currentCookTimerTime * _cookTimeMultiplier), () => { if (_lostPower) { return; } AddTemperature(time); if (recipeToCook != null) { for (int i = 0; i < portionedRecipe.Item2; i++) { SubtractContents(recipeToCook); _entities.SpawnEntity(recipeToCook.Result, _entities.GetComponent <TransformComponent>(Owner).Coordinates); } } EjectSolids(); SoundSystem.Play(_cookingCompleteSound.GetSound(), Filter.Pvs(Owner), Owner, AudioParams.Default.WithVolume(-1f)); SetAppearance(MicrowaveVisualState.Idle); _busy = false; UIDirty = true; }); _lostPower = false; UIDirty = true; }
public void Update(float frameTime) { if (!Owner.TryGetComponent(out DamageableComponent damageable)) { return; } Owner.TryGetComponent(out ServerStatusEffectsComponent status); var coordinates = Owner.Transform.GridPosition; var gridAtmos = EntitySystem.Get <AtmosphereSystem>().GetGridAtmosphere(coordinates.GridID); var tile = gridAtmos?.GetTile(coordinates); var pressure = 1f; var highPressureMultiplier = 1f; var lowPressureMultiplier = 1f; foreach (var protection in Owner.GetAllComponents <IPressureProtection>()) { highPressureMultiplier *= protection.HighPressureMultiplier; lowPressureMultiplier *= protection.LowPressureMultiplier; } if (tile?.Air != null) { pressure = MathF.Max(tile.Air.Pressure, 1f); } switch (pressure) { // Low pressure. case var p when p <= Atmospherics.WarningLowPressure: pressure *= lowPressureMultiplier; if (pressure > Atmospherics.WarningLowPressure) { goto default; } damageable.TakeDamage(DamageType.Brute, Atmospherics.LowPressureDamage, Owner); if (status == null) { break; } if (pressure <= Atmospherics.HazardLowPressure) { status.ChangeStatusEffect(StatusEffect.Pressure, "/Textures/Interface/StatusEffects/Pressure/lowpressure2.png", null); break; } status.ChangeStatusEffect(StatusEffect.Pressure, "/Textures/Interface/StatusEffects/Pressure/lowpressure1.png", null); break; // High pressure. case var p when p >= Atmospherics.WarningHighPressure: pressure *= highPressureMultiplier; if (pressure < Atmospherics.WarningHighPressure) { goto default; } var damage = (int)MathF.Min((pressure / Atmospherics.HazardHighPressure) * Atmospherics.PressureDamageCoefficient, Atmospherics.MaxHighPressureDamage); damageable.TakeDamage(DamageType.Brute, damage, Owner); if (status == null) { break; } if (pressure >= Atmospherics.HazardHighPressure) { status.ChangeStatusEffect(StatusEffect.Pressure, "/Textures/Interface/StatusEffects/Pressure/highpressure2.png", null); break; } status.ChangeStatusEffect(StatusEffect.Pressure, "/Textures/Interface/StatusEffects/Pressure/highpressure1.png", null); break; // Normal pressure. default: status?.RemoveStatusEffect(StatusEffect.Pressure); break; } }
public void Execute(IConsoleShell shell, string argStr, string[] args) { if (args.Length < 4 || args.Length > 7) { shell.WriteError($"Received invalid amount of arguments arguments. Expected 4 to 7, got {args.Length}.\nUsage: {Help}"); return; } if (!IoCManager.Resolve <IPrototypeManager>().HasIndex <DecalPrototype>(args[0])) { shell.WriteError($"Cannot find decalprototype '{args[0]}'."); } if (!float.TryParse(args[1], out var x)) { shell.WriteError($"Failed parsing x-coordinate '{args[1]}'."); return; } if (!float.TryParse(args[2], out var y)) { shell.WriteError($"Failed parsing y-coordinate'{args[2]}'."); return; } var mapManager = IoCManager.Resolve <IMapManager>(); if (!int.TryParse(args[3], out var gridIdRaw) || !mapManager.TryGetGrid(new GridId(gridIdRaw), out var grid)) { shell.WriteError($"Failed parsing gridId '{args[3]}'."); return; } var coordinates = new EntityCoordinates(grid.GridEntityId, new Vector2(x, y)); if (grid.GetTileRef(coordinates).IsSpace()) { shell.WriteError($"Cannot create decal on space tile at {coordinates}."); return; } Color?color = null; var zIndex = 0; Angle?rotation = null; if (args.Length > 4) { for (int i = 4; i < args.Length; i++) { var rawValue = args[i].Split('='); if (rawValue.Length != 2) { shell.WriteError($"Failed parsing parameter: '{args[i]}'"); return; } switch (rawValue[0]) { case "angle": if (!double.TryParse(rawValue[1], out var degrees)) { shell.WriteError($"Failed parsing angle '{rawValue[1]}'."); return; } rotation = Angle.FromDegrees(degrees); break; case "zIndex": if (!int.TryParse(rawValue[1], out zIndex)) { shell.WriteError($"Failed parsing zIndex '{rawValue[1]}'."); return; } break; case "color": if (!Color.TryFromName(rawValue[1], out var colorRaw)) { shell.WriteError($"Failed parsing color '{rawValue[1]}'."); return; } color = colorRaw; break; default: shell.WriteError($"Unknown parameter key '{rawValue[0]}'."); return; } } } if (EntitySystem.Get <DecalSystem>().TryAddDecal(args[0], coordinates, out var uid, color, rotation, zIndex)) { shell.WriteLine($"Successfully created decal {uid}."); }
public async void TryUncuff(IEntity user, IEntity?cuffsToRemove = null) { if (_uncuffing) { return; } var isOwner = user == Owner; if (cuffsToRemove == null) { cuffsToRemove = LastAddedCuffs; } else { if (!_container.ContainedEntities.Contains(cuffsToRemove)) { Logger.Warning("A user is trying to remove handcuffs that aren't in the owner's container. This should never happen!"); } } if (!cuffsToRemove.TryGetComponent <HandcuffComponent>(out var cuff)) { Logger.Warning($"A user is trying to remove handcuffs without a {nameof(HandcuffComponent)}. This should never happen!"); return; } if (!isOwner && !ActionBlockerSystem.CanInteract(user)) { user.PopupMessage(Loc.GetString("You can't do that!")); return; } if (!isOwner && !user.InRangeUnobstructed(Owner)) { user.PopupMessage(Loc.GetString("You are too far away to remove the cuffs.")); return; } if (!cuffsToRemove.InRangeUnobstructed(Owner)) { Logger.Warning("Handcuffs being removed from player are obstructed or too far away! This should not happen!"); return; } user.PopupMessage(Loc.GetString("You start removing the cuffs.")); var audio = EntitySystem.Get <AudioSystem>(); if (isOwner) { if (cuff.StartBreakoutSound != null) { audio.PlayFromEntity(cuff.StartBreakoutSound, Owner); } } else { if (cuff.StartUncuffSound != null) { audio.PlayFromEntity(cuff.StartUncuffSound, Owner); } } var uncuffTime = isOwner ? cuff.BreakoutTime : cuff.UncuffTime; var doAfterEventArgs = new DoAfterEventArgs(user, uncuffTime) { BreakOnUserMove = true, BreakOnDamage = true, BreakOnStun = true, NeedHand = true }; var doAfterSystem = EntitySystem.Get <DoAfterSystem>(); _uncuffing = true; var result = await doAfterSystem.DoAfter(doAfterEventArgs); _uncuffing = false; if (result != DoAfterStatus.Cancelled) { if (cuff.EndUncuffSound != null) { audio.PlayFromEntity(cuff.EndUncuffSound, Owner); } _container.ForceRemove(cuffsToRemove); cuffsToRemove.Transform.AttachToGridOrMap(); cuffsToRemove.Transform.WorldPosition = Owner.Transform.WorldPosition; if (cuff.BreakOnRemove) { cuff.Broken = true; cuffsToRemove.Name = cuff.BrokenName; cuffsToRemove.Description = cuff.BrokenDesc; if (cuffsToRemove.TryGetComponent <SpriteComponent>(out var sprite) && cuff.BrokenState != null) { sprite.LayerSetState(0, cuff.BrokenState); // TODO: safety check to see if RSI contains the state? } } CanStillInteract = Owner.TryGetComponent(out HandsComponent? handsComponent) && handsComponent.Hands.Count() > CuffedHandCount; OnCuffedStateChanged?.Invoke(); UpdateAlert(); Dirty(); if (CuffedHandCount == 0) { user.PopupMessage(Loc.GetString("You successfully remove the cuffs.")); if (!isOwner) { user.PopupMessage(Owner, Loc.GetString("{0:theName} uncuffs your hands.", user)); } } else { if (!isOwner) { user.PopupMessage(Loc.GetString("You successfully remove the cuffs. {0} of {1:theName}'s hands remain cuffed.", CuffedHandCount, user)); user.PopupMessage(Owner, Loc.GetString("{0:theName} removes your cuffs. {1} of your hands remain cuffed.", user, CuffedHandCount)); } else { user.PopupMessage(Loc.GetString("You successfully remove the cuffs. {0} of your hands remain cuffed.", CuffedHandCount)); } } } else { user.PopupMessage(Loc.GetString("You fail to remove the cuffs.")); } return; }
public override void Effect(ReagentEffectArgs args) { var scale = ScaleByQuantity ? args.Quantity : FixedPoint2.New(1); EntitySystem.Get <DamageableSystem>().TryChangeDamage(args.SolutionEntity, Damage * scale, IgnoreResistances); }
// The main "start pulling" function. public bool TryStartPull(SharedPullerComponent puller, SharedPullableComponent pullable) { if (puller.Pulling == pullable) { return(true); } // Pulling a new object : Perform sanity checks. if (!EntitySystem.Get <SharedPullingSystem>().CanPull(puller.Owner, pullable.Owner)) { return(false); } if (!puller.Owner.TryGetComponent <PhysicsComponent>(out var pullerPhysics)) { return(false); } if (!pullable.Owner.TryGetComponent <PhysicsComponent>(out var pullablePhysics)) { return(false); } // Ensure that the puller is not currently pulling anything. // If this isn't done, then it happens too late, and the start/stop messages go out of order, // and next thing you know it thinks it's not pulling anything even though it is! var oldPullable = puller.Pulling; if (oldPullable != null) { if (oldPullable.TryGetComponent <SharedPullableComponent>(out var oldPullableComp)) { if (!TryStopPull(oldPullableComp)) { return(false); } } else { Logger.WarningS("c.go.c.pulling", "Well now you've done it, haven't you? Someone transferred pulling (onto {0}) while presently pulling something that has no Pullable component (on {1})!", pullable.Owner, oldPullable); return(false); } } // Ensure that the pullable is not currently being pulled. // Same sort of reasons as before. var oldPuller = pullable.Puller; if (oldPuller != null) { if (!TryStopPull(pullable)) { return(false); } } // Continue with pulling process. var pullAttempt = new PullAttemptMessage(pullerPhysics, pullablePhysics); RaiseLocalEvent(puller.Owner.Uid, pullAttempt, broadcast: false); if (pullAttempt.Cancelled) { return(false); } RaiseLocalEvent(pullable.Owner.Uid, pullAttempt); if (pullAttempt.Cancelled) { return(false); } _pullSm.ForceRelationship(puller, pullable); return(true); }
public void Execute(IConsoleShell shell, string argStr, string[] args) { EntitySystem.Get <GameTicker>().RestartRound(); }
public void Update() { UpdateReagents(); var curTime = _gameTiming.CurTime; if (ForceUpdate) { ForceUpdate = false; } else if (curTime < (_lastCycle + _cycleDelay)) { if (_updateSpriteAfterUpdate) { UpdateSprite(); } return; } _lastCycle = curTime; // Weeds like water and nutrients! They may appear even if there's not a seed planted. if (WaterLevel > 10 && NutritionLevel > 2 && _random.Prob(Seed == null ? 0.05f : 0.01f)) { WeedLevel += 1 * HydroponicsSpeedMultiplier * WeedCoefficient; if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } // There's a chance for a weed explosion to happen if weeds take over. // Plants that are themselves weeds (WeedTolerance > 8) are unaffected. if (WeedLevel >= 10 && _random.Prob(0.1f)) { if (Seed == null || WeedLevel >= Seed.WeedTolerance + 2) { WeedInvasion(); } } // If we have no seed planted, or the plant is dead, stop processing here. if (Seed == null || Dead) { if (_updateSpriteAfterUpdate) { UpdateSprite(); } return; } // There's a small chance the pest population increases. // Can only happen when there's a live seed planted. if (_random.Prob(0.01f)) { PestLevel += 0.5f * HydroponicsSpeedMultiplier; if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } // Advance plant age here. if (SkipAging > 0) { SkipAging--; } else { if (_random.Prob(0.8f)) { Age += (int)(1 * HydroponicsSpeedMultiplier); } _updateSpriteAfterUpdate = true; } // Nutrient consumption. if (Seed.NutrientConsumption > 0 && NutritionLevel > 0 && _random.Prob(0.75f)) { NutritionLevel -= MathF.Max(0f, Seed.NutrientConsumption * HydroponicsSpeedMultiplier); if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } // Water consumption. if (Seed.WaterConsumption > 0 && WaterLevel > 0 && _random.Prob(0.75f)) { WaterLevel -= MathF.Max(0f, Seed.NutrientConsumption * HydroponicsConsumptionMultiplier * HydroponicsSpeedMultiplier); if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } var healthMod = _random.Next(1, 3) * HydroponicsSpeedMultiplier; // Make sure the plant is not starving. if (_random.Prob(0.35f)) { if (NutritionLevel > 2) { Health += healthMod; } else { AffectGrowth(-1); Health -= healthMod; } if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } // Make sure the plant is not thirsty. if (_random.Prob(0.35f)) { if (WaterLevel > 10) { Health += healthMod; } else { AffectGrowth(-1); Health -= healthMod; } if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } var environment = EntitySystem.Get <AtmosphereSystem>().GetTileMixture(Owner.Transform.Coordinates, true) ?? GasMixture.SpaceGas; if (Seed.ConsumeGasses.Count > 0) { _missingGas = 0; foreach (var(gas, amount) in Seed.ConsumeGasses) { if (environment.GetMoles(gas) < amount) { _missingGas++; continue; } environment.AdjustMoles(gas, -amount); } if (_missingGas > 0) { Health -= _missingGas * HydroponicsSpeedMultiplier; if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } } // Seed pressure resistance. var pressure = environment.Pressure; if (pressure < Seed.LowPressureTolerance || pressure > Seed.HighPressureTolerance) { Health -= healthMod; ImproperPressure = true; if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } else { ImproperPressure = false; } // Seed ideal temperature. if (MathF.Abs(environment.Temperature - Seed.IdealHeat) > Seed.HeatTolerance) { Health -= healthMod; ImproperHeat = true; if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } else { ImproperHeat = false; } // Gas production. var exudeCount = Seed.ExudeGasses.Count; if (exudeCount > 0) { foreach (var(gas, amount) in Seed.ExudeGasses) { environment.AdjustMoles(gas, MathF.Max(1f, MathF.Round((amount * MathF.Round(Seed.Potency)) / exudeCount))); } } // Toxin levels beyond the plant's tolerance cause damage. // They are, however, slowly reduced over time. if (Toxins > 0) { var toxinUptake = MathF.Max(1, MathF.Round(Toxins / 10f)); if (Toxins > Seed.ToxinsTolerance) { Health -= toxinUptake; } Toxins -= toxinUptake; if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } // Weed levels. if (PestLevel > 0) { // TODO: Carnivorous plants? if (PestLevel > Seed.PestTolerance) { Health -= HydroponicsSpeedMultiplier; } if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } // Weed levels. if (WeedLevel > 0) { // TODO: Parasitic plants. if (WeedLevel >= Seed.WeedTolerance) { Health -= HydroponicsSpeedMultiplier; } if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } if (Age > Seed.Lifespan) { Health -= _random.Next(3, 5) * HydroponicsSpeedMultiplier; if (DrawWarnings) { _updateSpriteAfterUpdate = true; } } else if (Age < 0) // Revert back to seed packet! { Seed.SpawnSeedPacket(Owner.Transform.Coordinates); RemovePlant(); ForceUpdate = true; Update(); } CheckHealth(); if (Harvest && Seed.HarvestRepeat == HarvestType.SelfHarvest) { AutoHarvest(); } // If enough time has passed since the plant was harvested, we're ready to harvest again! if (!Dead && Seed.ProductPrototypes.Count > 0) { if (Age > Seed.Production) { if ((Age - _lastProduce) > Seed.Production && !Harvest) { Harvest = true; _lastProduce = Age; } } else { if (Harvest) { Harvest = false; _lastProduce = Age; } } } CheckLevelSanity(); if (_updateSpriteAfterUpdate) { UpdateSprite(); } }
private void Rustle() { EntitySystem.Get <AudioSystem>() .PlayFromEntity("/Audio/Effects/plant_rustle.ogg", Owner, AudioHelpers.WithVariation(0.25f)); }
public void DoTargetEntityAction(TargetEntityActionEventArgs args) { var disarmedActs = args.Target.GetAllComponents <IDisarmedAct>().ToArray(); if (!args.Performer.InRangeUnobstructed(args.Target)) { return; } if (disarmedActs.Length == 0) { if (args.Performer.TryGetComponent(out IActorComponent? actor)) { // Fall back to a normal interaction with the entity var player = actor.playerSession; var coordinates = args.Target.Transform.Coordinates; var target = args.Target.Uid; EntitySystem.Get <InteractionSystem>().HandleClientUseItemInHand(player, coordinates, target); return; } return; } if (!args.Performer.TryGetComponent <SharedActionsComponent>(out var actions)) { return; } if (args.Target == args.Performer || !args.Performer.CanAttack()) { return; } var random = IoCManager.Resolve <IRobustRandom>(); var audio = EntitySystem.Get <AudioSystem>(); var system = EntitySystem.Get <MeleeWeaponSystem>(); var diff = args.Target.Transform.MapPosition.Position - args.Performer.Transform.MapPosition.Position; var angle = Angle.FromWorldVec(diff); actions.Cooldown(ActionType.Disarm, Cooldowns.SecondsFromNow(_cooldown)); if (random.Prob(_failProb)) { SoundSystem.Play(Filter.Pvs(args.Performer), "/Audio/Weapons/punchmiss.ogg", args.Performer, AudioHelpers.WithVariation(0.025f)); args.Performer.PopupMessageOtherClients(Loc.GetString("{0} fails to disarm {1}!", args.Performer.Name, args.Target.Name)); args.Performer.PopupMessageCursor(Loc.GetString("You fail to disarm {0}!", args.Target.Name)); system.SendLunge(angle, args.Performer); return; } system.SendAnimation("disarm", angle, args.Performer, args.Performer, new [] { args.Target }); var eventArgs = new DisarmedActEventArgs() { Target = args.Target, Source = args.Performer, PushProbability = _pushProb }; // Sort by priority. Array.Sort(disarmedActs, (a, b) => a.Priority.CompareTo(b.Priority)); foreach (var disarmedAct in disarmedActs) { if (disarmedAct.Disarmed(eventArgs)) { return; } } SoundSystem.Play(Filter.Pvs(args.Performer), "/Audio/Effects/thudswoosh.ogg", args.Performer, AudioHelpers.WithVariation(0.025f)); }