private void OnStartup(EntityUid uid, SharedCombatModeComponent component, ComponentStartup args) { if (component.CombatToggleAction == null && _protoMan.TryIndex(component.CombatToggleActionId, out InstantActionPrototype? toggleProto)) { component.CombatToggleAction = new(toggleProto); } if (component.CombatToggleAction != null) { _actionsSystem.AddAction(uid, component.CombatToggleAction, null); } if (component.DisarmAction == null && component.CanDisarm && _protoMan.TryIndex(component.DisarmActionId, out EntityTargetActionPrototype? disarmProto)) { component.DisarmAction = new(disarmProto); } if (component.DisarmAction != null && component.CanDisarm) { _actionsSystem.AddAction(uid, component.DisarmAction, null); } }
///////// ///////// Server-specific stuff ///////// public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); serializer.DataReadWriteFunction( "BaseTemplate", "bodyTemplate.Humanoid", template => { if (!_prototypeManager.TryIndex(template, out BodyTemplatePrototype templateData)) { throw new InvalidOperationException("No BodyTemplatePrototype was found with the name " + template + " while loading a BodyTemplate!"); //Should never happen unless you f**k up the prototype. } _template = new BodyTemplate(templateData); }, () => _template.Name); serializer.DataReadWriteFunction( "BasePreset", "bodyPreset.BasicHuman", preset => { if (!_prototypeManager.TryIndex(preset, out BodyPresetPrototype presetData)) { throw new InvalidOperationException("No BodyPresetPrototype was found with the name " + preset + " while loading a BodyPreset!"); //Should never happen unless you f**k up the prototype. } LoadBodyPreset(new BodyPreset(presetData)); }, () => _presetName); }
/// <summary> /// Update the button grid of reagents which can be dispensed. /// <para>The actions for these buttons are set in <see cref="ReagentDispenserBoundUserInterface.UpdateReagentsList"/>.</para> /// </summary> /// <param name="inventory">Reagents which can be dispensed by this dispenser</param> public void UpdateReagentsList(List <ReagentDispenserInventoryEntry> inventory) { if (ChemicalList == null) { return; } if (inventory == null) { return; } ChemicalList.Children.Clear(); foreach (var entry in inventory) { if (_prototypeManager.TryIndex(entry.ID, out ReagentPrototype? proto)) { ChemicalList.AddChild(new Button { Text = proto.LocalizedName }); } else { ChemicalList.AddChild(new Button { Text = Loc.GetString("reagent-dispenser-window-reagent-name-not-found-text") }); } } }
/// <summary> /// when sleeping component is added or removed, we do some stuff with other components. /// </summary> private void OnSleepStateChanged(EntityUid uid, MobStateComponent component, SleepStateChangedEvent args) { _prototypeManager.TryIndex <InstantActionPrototype>("Wake", out var wakeAction); if (args.FellAsleep) { EnsureComp <StunnedComponent>(uid); EnsureComp <KnockedDownComponent>(uid); var emitSound = EnsureComp <SpamEmitSoundComponent>(uid); emitSound.Sound = new SoundCollectionSpecifier("Snores"); emitSound.PlayChance = 0.33f; emitSound.RollInterval = 5f; emitSound.PopUp = "sleep-onomatopoeia"; emitSound.PitchVariation = 0.2f; if (wakeAction != null) { var wakeInstance = new InstantAction(wakeAction); wakeInstance.Cooldown = (_gameTiming.CurTime, _gameTiming.CurTime + TimeSpan.FromSeconds(15)); _actionsSystem.AddAction(uid, wakeInstance, null); } return; } if (wakeAction != null) { _actionsSystem.RemoveAction(uid, wakeAction); } RemComp <StunnedComponent>(uid); RemComp <KnockedDownComponent>(uid); RemComp <SpamEmitSoundComponent>(uid); }
protected void RecalculateColor() { if (Solution.TotalVolume == 0) { SubstanceColor = Color.Transparent; return; } Color mixColor = default; var runningTotalQuantity = ReagentUnit.New(0); foreach (var reagent in Solution) { runningTotalQuantity += reagent.Quantity; if (!_prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype proto)) { continue; } if (mixColor == default) { mixColor = proto.SubstanceColor; continue; } var interpolateValue = (1 / runningTotalQuantity.Float()) * reagent.Quantity.Float(); mixColor = Color.InterpolateBetween(mixColor, proto.SubstanceColor, interpolateValue); } SubstanceColor = mixColor; }
protected override void ReceiveMessage(BoundUserInterfaceMessage message) { switch (message) { case SharedLatheComponent.LatheProducingRecipeMessage msg: if (!_prototypeManager.TryIndex(msg.ID, out LatheRecipePrototype recipe)) { break; } _queueMenu?.SetInfo(recipe); break; case SharedLatheComponent.LatheStoppedProducingRecipeMessage _: _queueMenu?.ClearInfo(); break; case SharedLatheComponent.LatheFullQueueMessage msg: _queuedRecipes.Clear(); foreach (var id in msg.Recipes) { if (!_prototypeManager.TryIndex(id, out LatheRecipePrototype recipePrototype)) { break; } _queuedRecipes.Enqueue(recipePrototype); } _queueMenu?.PopulateList(); break; } }
/// <summary> /// Initialize a damageable component /// </summary> private void DamageableInit(EntityUid uid, DamageableComponent component, ComponentInit _) { if (component.DamageContainerID != null && _prototypeManager.TryIndex <DamageContainerPrototype>(component.DamageContainerID, out var damageContainerPrototype)) { // Initialize damage dictionary, using the types and groups from the damage // container prototype foreach (var type in damageContainerPrototype.SupportedTypes) { component.Damage.DamageDict.TryAdd(type, FixedPoint2.Zero); } foreach (var groupID in damageContainerPrototype.SupportedGroups) { var group = _prototypeManager.Index <DamageGroupPrototype>(groupID); foreach (var type in group.DamageTypes) { component.Damage.DamageDict.TryAdd(type, FixedPoint2.Zero); } } } else { // No DamageContainerPrototype was given. So we will allow the container to support all damage types foreach (var type in _prototypeManager.EnumeratePrototypes <DamageTypePrototype>()) { component.Damage.DamageDict.TryAdd(type.ID, FixedPoint2.Zero); } } component.DamagePerGroup = component.Damage.GetDamagePerGroup(_prototypeManager); component.TotalDamage = component.Damage.Total; }
/// <summary> /// Polymorphs the target entity into the specific polymorph prototype /// </summary> /// <param name="target">The entity that will be transformed</param> /// <param name="id">The id of the polymorph prototype</param> public EntityUid?PolymorphEntity(EntityUid target, string id) { if (!_proto.TryIndex <PolymorphPrototype>(id, out var proto)) { _saw.Error("Invalid polymorph prototype"); return(null); } return(PolymorphEntity(target, proto)); }
private void OnInitialize(EntityUid uid, SurveillanceCameraRouterComponent router, ComponentInit args) { if (router.SubnetFrequencyId == null || !_prototypeManager.TryIndex(router.SubnetFrequencyId, out DeviceFrequencyPrototype? subnetFrequency)) { return; } router.SubnetFrequency = subnetFrequency.Frequency; router.Active = true; }
private void OnAccessInit(EntityUid uid, AccessComponent component, ComponentInit args) { // Add all tags in groups to the list of tags. foreach (var group in component.Groups) { if (!_prototypeManager.TryIndex<AccessGroupPrototype>(group, out var proto)) continue; component.Tags.UnionWith(proto.Tags); } }
/// <summary> /// Randomly run a valid event <b>immediately</b>, ignoring earlieststart or whether the event is enabled /// </summary> /// <returns></returns> public string RunRandomEvent() { var randomEvent = PickRandomEvent(); if (randomEvent == null || !_prototype.TryIndex <GameRulePrototype>(randomEvent.Id, out var proto)) { return(Loc.GetString("station-event-system-run-random-event-no-valid-events")); } GameTicker.AddGameRule(proto); return(Loc.GetString("station-event-system-run-event", ("eventName", randomEvent.Id))); }
private bool TryParseDamageArgs( IConsoleShell shell, EntityUid target, string[] args, [NotNullWhen(true)] out Damage?func) { var entMan = IoCManager.Resolve <IEntityManager>(); if (!int.TryParse(args[1], out var amount)) { shell.WriteLine($"{args[1]} is not a valid damage integer."); func = null; return(false); } if (_prototypeManager.TryIndex <DamageGroupPrototype>(args[0], out var damageGroup)) { func = (entity, ignoreResistances) => { var damage = new DamageSpecifier(damageGroup, amount); EntitySystem.Get <DamageableSystem>().TryChangeDamage(entity, damage, ignoreResistances); shell.WriteLine($"Damaged entity {entMan.GetComponent<MetaDataComponent>(entity).EntityName} with id {entity} for {amount} {damageGroup} damage{(ignoreResistances ? ", ignoring resistances." : ".")}"); }; return(true); } // Fall back to DamageType else if (_prototypeManager.TryIndex <DamageTypePrototype>(args[0], out var damageType)) { func = (entity, ignoreResistances) => { var damage = new DamageSpecifier(damageType, amount); EntitySystem.Get <DamageableSystem>().TryChangeDamage(entity, damage, ignoreResistances); shell.WriteLine($"Damaged entity {entMan.GetComponent<MetaDataComponent>(entity).EntityName} with id {entity} for {amount} {damageType} damage{(ignoreResistances ? ", ignoring resistances." : ".")}"); }; return(true); } else { shell.WriteLine($"{args[0]} is not a valid damage class or type."); var types = DamageTypes(); shell.WriteLine(types); func = null; 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 (!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(); }
/// <summary> /// Attempts to remove a status effect from an entity. /// </summary> /// <param name="uid">The entity to remove an effect from.</param> /// <param name="key">The effect ID to remove.</param> /// <param name="status">The status effects component to change, if you already have it.</param> /// <returns>False if the effect could not be removed, true otherwise.</returns> /// <remarks> /// Obviously this doesn't automatically clear any effects a status effect might have. /// That's up to the removed component to handle itself when it's removed. /// </remarks> public bool TryRemoveStatusEffect(EntityUid uid, string key, StatusEffectsComponent?status = null) { if (!Resolve(uid, ref status, false)) { return(false); } if (!status.ActiveEffects.ContainsKey(key)) { return(false); } if (!_prototypeManager.TryIndex <StatusEffectPrototype>(key, out var proto)) { return(false); } var state = status.ActiveEffects[key]; // There are cases where a status effect component might be server-only, so TryGetRegistration... if (state.RelevantComponent != null && _componentFactory.TryGetRegistration(state.RelevantComponent, out var registration)) { var type = registration.Type; // Make sure the component is actually there first. // Maybe a badmin badminned the component away, // or perhaps, on the client, the component deletion sync // was faster than prediction could predict. Either way, let's not assume the component exists. if (EntityManager.HasComponent(uid, type)) { EntityManager.RemoveComponent(uid, type); } } if (proto.Alert != null) { _alertsSystem.ClearAlert(uid, proto.Alert.Value); } status.ActiveEffects.Remove(key); if (status.ActiveEffects.Count == 0) { RemComp <ActiveStatusEffectsComponent>(uid); } Dirty(status); // event? return(true); }
private void OnInteractUsing(EntityUid uid, SeedExtractorComponent component, InteractUsingEvent args) { if (!TryComp <ApcPowerReceiverComponent>(uid, out var powerReceiverComponent) || !powerReceiverComponent.Powered) { return; } if (TryComp(args.Used, out ProduceComponent? produce)) { if (!_prototypeManager.TryIndex <SeedPrototype>(produce.SeedName, out var seed)) { return; } _popupSystem.PopupCursor(Loc.GetString("seed-extractor-component-interact-message", ("name", args.Used)), Filter.Entities(args.User)); QueueDel(args.Used); var random = _random.Next(component.MinSeeds, component.MaxSeeds); var coords = Transform(uid).Coordinates; for (var i = 0; i < random; i++) { _botanySystem.SpawnSeedPacket(seed, coords); } } }
private void InitializeFromPrototype() { if (string.IsNullOrEmpty(_packPrototypeId)) { return; } if (!_prototypeManager.TryIndex(_packPrototypeId, out VendingMachineInventoryPrototype? packPrototype)) { return; } _entMan.GetComponent <MetaDataComponent>(Owner).EntityName = packPrototype.Name; _animationDuration = TimeSpan.FromSeconds(packPrototype.AnimationDuration); _spriteName = packPrototype.SpriteName; if (!string.IsNullOrEmpty(_spriteName)) { var spriteComponent = _entMan.GetComponent <SpriteComponent>(Owner); const string vendingMachineRSIPath = "Structures/Machines/VendingMachines/{0}.rsi"; spriteComponent.BaseRSIPath = string.Format(vendingMachineRSIPath, _spriteName); } var inventory = new List <VendingMachineInventoryEntry>(); foreach (var(id, amount) in packPrototype.StartingInventory) { inventory.Add(new VendingMachineInventoryEntry(id, amount)); } Inventory = inventory; }
/// <summary> /// Try to split this stack into two. Returns a non-null <see cref="IEntity"/> if successful. /// </summary> public IEntity?Split(EntityUid uid, int amount, EntityCoordinates spawnPosition, SharedStackComponent?stack = null) { if (!Resolve(uid, ref stack)) { return(null); } // Get a prototype ID to spawn the new entity. Null is also valid, although it should rarely be picked... var prototype = _prototypeManager.TryIndex <StackPrototype>(stack.StackTypeId, out var stackType) ? stackType.Spawn : stack.Owner.Prototype?.ID ?? null; // Try to remove the amount of things we want to split from the original stack... if (!Use(uid, amount, stack)) { return(null); } // Set the output parameter in the event instance to the newly split stack. var entity = EntityManager.SpawnEntity(prototype, spawnPosition); if (EntityManager.TryGetComponent(entity.Uid, out SharedStackComponent? stackComp)) { // Set the split stack's count. SetCount(entity.Uid, amount, stackComp); } return(entity); }
public void InitializeFromPrototype(EntityUid uid, VendingMachineComponent?vendComponent = null) { if (!Resolve(uid, ref vendComponent)) { return; } if (string.IsNullOrEmpty(vendComponent.PackPrototypeId)) { return; } if (!_prototypeManager.TryIndex(vendComponent.PackPrototypeId, out VendingMachineInventoryPrototype? packPrototype)) { return; } MetaData(uid).EntityName = packPrototype.Name; vendComponent.AnimationDuration = TimeSpan.FromSeconds(packPrototype.AnimationDuration); vendComponent.SpriteName = packPrototype.SpriteName; if (!string.IsNullOrEmpty(vendComponent.SpriteName)) { if (TryComp <SpriteComponent>(vendComponent.Owner, out var spriteComp)) { const string vendingMachineRSIPath = "Structures/Machines/VendingMachines/{0}.rsi"; spriteComp.BaseRSIPath = string.Format(vendingMachineRSIPath, vendComponent.SpriteName); } } AddInventoryFromPrototype(uid, packPrototype.StartingInventory, InventoryType.Regular, vendComponent); AddInventoryFromPrototype(uid, packPrototype.EmaggedInventory, InventoryType.Emagged, vendComponent); AddInventoryFromPrototype(uid, packPrototype.ContrabandInventory, InventoryType.Contraband, vendComponent); }
/// <summary> /// play emote and return a string of text describing the emote /// </summary> public string PlayEmote(string emote) { var output = emote; if (!string.IsNullOrWhiteSpace(emote)) { var soundToPlay = emote; if (_prototypeManager.TryIndex(emote, out EmotePrototype proto)) { output = _emoteRandom.Pick(proto.Output); soundToPlay = proto.SoundCollectionID; foreach (var e in proto.Effect) { output = e.PlayEffect(Owner, output); } var soundCollection = _prototypeManager.Index <SoundCollectionPrototype>(soundToPlay); if (soundCollection != null) { var file = _emoteRandom.Pick(soundCollection.PickFiles); Owner.GetComponent <SoundComponent>().Play(file, AudioParams.Default.WithVolume(4f)); } } } return(output); }
/// <summary> /// Loads the given BodyPartPrototype - current data on this BodyPart will be overwritten! /// </summary> public virtual void LoadFromPrototype(BodyPartPrototype data) { Name = data.Name; Plural = data.Plural; PartType = data.PartType; RSIPath = data.RSIPath; RSIState = data.RSIState; MaxDurability = data.Durability; CurrentDamages = new BiologicalDamageContainer(); Resistance = data.Resistance; Size = data.Size; Compatibility = data.Compatibility; Properties = data.Properties; //_surgeryData = (ISurgeryData) Activator.CreateInstance(null, data.SurgeryDataName); //TODO: figure out a way to convert a string name in the YAML to the proper class (reflection won't work for reasons) _surgeryData = new BiologicalSurgeryData(this); IPrototypeManager prototypeManager = IoCManager.Resolve <IPrototypeManager>(); foreach (string mechanismPrototypeID in data.Mechanisms) { if (!prototypeManager.TryIndex(mechanismPrototypeID, out MechanismPrototype mechanismData)) { throw new InvalidOperationException("No MechanismPrototype was found with the name " + mechanismPrototypeID + " while loading a BodyPartPrototype!"); } _mechanisms.Add(new Mechanism(mechanismData)); } }
public void UpdateList(Label number, double numberVal, ItemList list, PowerMonitoringConsoleEntry[] listVal) { number.Text = Loc.GetString("power-monitoring-window-value", ("value", numberVal)); // This magic is important to prevent scrolling issues. while (list.Count > listVal.Length) { list.RemoveAt(list.Count - 1); } while (list.Count < listVal.Length) { list.AddItem("YOU SHOULD NEVER SEE THIS (REALLY!)", null, false); } // Now overwrite the items properly... for (var i = 0; i < listVal.Length; i++) { var ent = listVal[i]; _prototypeManager.TryIndex(ent.IconEntityPrototypeId, out EntityPrototype? entityPrototype); IRsiStateLike?iconState = null; if (entityPrototype != null) { iconState = SpriteComponent.GetPrototypeIcon(entityPrototype, StaticIoC.ResC); } var icon = iconState?.GetFrame(RSI.State.Direction.South, 0); var item = list[i]; item.Text = $"{ent.NameLocalized} {Loc.GetString("power-monitoring-window-value", ("value", ent.Size))}"; item.Icon = icon; } }
/// <summary> /// Try to split this stack into two. /// See <see cref="StackSplitEvent"/> /// </summary> private void OnStackSplit(EntityUid uid, StackComponent stack, StackSplitEvent args) { // If the stack doesn't have enough things as specified in the parameters, we do nothing. if (stack.Count < args.Amount) { return; } // Get a prototype ID to spawn the new entity. Null is also valid, although it should rarely be picked... var prototype = _prototypeManager.TryIndex <StackPrototype>(stack.StackTypeId, out var stackType) ? stackType.Spawn : stack.Owner.Prototype?.ID ?? null; // Remove the amount of things we want to split from the original stack... RaiseLocalEvent(uid, new StackChangeCountEvent(stack.Count - args.Amount), false); // Set the output parameter in the event instance to the newly split stack. args.Result = EntityManager.SpawnEntity(prototype, args.SpawnPosition); if (args.Result.TryGetComponent(out StackComponent? stackComp)) { // Set the split stack's count. RaiseLocalEvent(args.Result.Uid, new StackChangeCountEvent(args.Amount), false); } }
/// <summary> /// Try to split this stack into two. Returns a non-null <see cref="Robust.Shared.GameObjects.EntityUid"/> if successful. /// </summary> public EntityUid?Split(EntityUid uid, int amount, EntityCoordinates spawnPosition, SharedStackComponent?stack = null) { if (!Resolve(uid, ref stack)) { return(null); } // Get a prototype ID to spawn the new entity. Null is also valid, although it should rarely be picked... var prototype = _prototypeManager.TryIndex <StackPrototype>(stack.StackTypeId, out var stackType) ? stackType.Spawn : Prototype(stack.Owner)?.ID; // Try to remove the amount of things we want to split from the original stack... if (!Use(uid, amount, stack)) { return(null); } // Set the output parameter in the event instance to the newly split stack. var entity = Spawn(prototype, spawnPosition); if (TryComp(entity, out SharedStackComponent? stackComp)) { // Set the split stack's count. SetCount(entity, amount, stackComp); // Don't let people dupe unlimited stacks stackComp.Unlimited = false; } return(entity); }
/// <summary> /// Queue an explosion, with a specified epicenter and set of starting tiles. /// </summary> public void QueueExplosion(MapCoordinates epicenter, string typeId, float totalIntensity, float slope, float maxTileIntensity, float tileBreakScale = 1f, int maxTileBreak = int.MaxValue, bool canCreateVacuum = true, bool addLog = false) { if (totalIntensity <= 0 || slope <= 0) { return; } if (!_prototypeManager.TryIndex <ExplosionPrototype>(typeId, out var type)) { Logger.Error($"Attempted to spawn unknown explosion prototype: {type}"); return; } if (addLog) // dont log if already created a separate, more detailed, log. { _adminLogger.Add(LogType.Explosion, LogImpact.High, $"Explosion spawned at {epicenter:coordinates} with intensity {totalIntensity} slope {slope}"); } _explosionQueue.Enqueue(() => SpawnExplosion(epicenter, type, totalIntensity, slope, maxTileIntensity, tileBreakScale, maxTileBreak, canCreateVacuum)); }
private void RefreshContentsDisplay(IReadOnlyList <Solution.ReagentQuantity> reagents, List <EntityUid> solids) { _reagents.Clear(); _menu.IngredientsListReagents.Clear(); foreach (var reagent in reagents) { _prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype proto); var reagentAdded = _menu.IngredientsListReagents.AddItem($"{reagent.Quantity} {proto.Name}"); var reagentIndex = _menu.IngredientsListReagents.IndexOf(reagentAdded); _reagents.Add(reagentIndex, reagent); } _solids.Clear(); _menu.IngredientsList.Clear(); foreach (var entityID in solids) { if (!_entityManager.TryGetEntity(entityID, out var entity)) { return; } if (!entity.Deleted && entity.TryGetComponent(out IconComponent icon)) { var solidItem = _menu.IngredientsList.AddItem(entity.Name, icon.Icon.Default); var solidIndex = _menu.IngredientsList.IndexOf(solidItem); _solids.Add(solidIndex, entityID); } } }
private void OnExamineSolution(EntityUid uid, ExaminableSolutionComponent examinableComponent, ExaminedEvent args) { if (!args.Examined.TryGetComponent(out SolutionContainerManagerComponent? solutionsManager) || !solutionsManager.Solutions.TryGetValue(examinableComponent.Solution, out var solutionHolder)) { return; } if (solutionHolder.Contents.Count == 0) { args.PushText(Loc.GetString("shared-solution-container-component-on-examine-empty-container")); return; } var primaryReagent = solutionHolder.GetPrimaryReagentId(); if (!_prototypeManager.TryIndex(primaryReagent, out ReagentPrototype? proto)) { Logger.Error( $"{nameof(Solution)} could not find the prototype associated with {primaryReagent}."); return; } var colorHex = solutionHolder.Color .ToHexNoAlpha(); //TODO: If the chem has a dark color, the examine text becomes black on a black background, which is unreadable. var messageString = "shared-solution-container-component-on-examine-main-text"; args.PushMarkup(Loc.GetString(messageString, ("color", colorHex), ("wordedAmount", Loc.GetString(solutionHolder.Contents.Count == 1 ? "shared-solution-container-component-on-examine-worded-amount-one-reagent" : "shared-solution-container-component-on-examine-worded-amount-multiple-reagents")), ("desc", Loc.GetString(proto.PhysicalDescription)))); }
private void UpdateBarSignVisuals(BarSignComponent component) { if (component.CurrentSign == null) { return; } if (!_prototypeManager.TryIndex(component.CurrentSign, out BarSignPrototype? prototype)) { Logger.ErrorS("barSign", $"Invalid bar sign prototype: \"{component.CurrentSign}\""); return; } if (component.Owner.TryGetComponent(out SpriteComponent? sprite)) { if (!component.Owner.TryGetComponent(out ApcPowerReceiverComponent? receiver) || receiver.Powered) { sprite.LayerSetState(0, "empty"); sprite.LayerSetShader(0, "shaded"); } else { sprite.LayerSetState(0, prototype.Icon); sprite.LayerSetShader(0, "unshaded"); } }
/// <summary> /// Loops through each reagent in _internalSolution, /// and calls <see cref="IMetabolizable.Metabolize"/> for each of them. /// </summary> /// <param name="frameTime">The time since the last metabolism tick in seconds.</param> private void ProcessNutrients(float frameTime) { if (!Owner.TryGetComponent(out BloodstreamComponent bloodstream)) { return; } if (bloodstream.Solution.CurrentVolume == 0) { return; } // Run metabolism for each reagent, remove metabolized reagents // Using ToList here lets us edit reagents while iterating foreach (var reagent in bloodstream.Solution.ReagentList.ToList()) { if (!_prototypeManager.TryIndex(reagent.ReagentId, out ReagentPrototype prototype)) { continue; } // Run metabolism code for each reagent foreach (var metabolizable in prototype.Metabolism) { var reagentDelta = metabolizable.Metabolize(Owner, reagent.ReagentId, frameTime); bloodstream.Solution.TryRemoveReagent(reagent.ReagentId, reagentDelta); } } }
private void OnUserDamageModified(EntityUid uid, BlockingUserComponent component, DamageModifyEvent args) { if (TryComp <BlockingComponent>(component.BlockingItem, out var blockingComponent)) { if (_proto.TryIndex(blockingComponent.PassiveBlockDamageModifer, out DamageModifierSetPrototype? passiveblockModifier) && !blockingComponent.IsBlocking) { args.Damage = DamageSpecifier.ApplyModifierSet(args.Damage, passiveblockModifier); } if (_proto.TryIndex(blockingComponent.ActiveBlockDamageModifier, out DamageModifierSetPrototype? activeBlockModifier) && blockingComponent.IsBlocking) { args.Damage = DamageSpecifier.ApplyModifierSet(args.Damage, activeBlockModifier); SoundSystem.Play(blockingComponent.BlockSound.GetSound(), Filter.Pvs(component.Owner, entityManager: EntityManager), component.Owner, AudioHelpers.WithVariation(0.2f)); } } }
/// <summary> /// Finds 2-5 random, alive entities that can host diseases /// and gives them a randomly selected disease. /// They all get the same disease. /// </summary> public override void Startup() { base.Startup(); HashSet <EntityUid> stationsToNotify = new(); List <DiseaseCarrierComponent> aliveList = new(); foreach (var(carrier, mobState) in _entityManager.EntityQuery <DiseaseCarrierComponent, MobStateComponent>()) { if (!mobState.IsDead()) { aliveList.Add(carrier); } } _random.Shuffle(aliveList); /// We're going to filter the above out to only alive mobs. Might change after future mobstate rework var toInfect = _random.Next(2, 5); var diseaseName = _random.Pick(NotTooSeriousDiseases); if (!_prototypeManager.TryIndex(diseaseName, out DiseasePrototype? disease)) { return; } var diseaseSystem = EntitySystem.Get <DiseaseSystem>(); var entSysMgr = IoCManager.Resolve <IEntitySystemManager>(); var stationSystem = entSysMgr.GetEntitySystem <StationSystem>(); var chatSystem = entSysMgr.GetEntitySystem <ChatSystem>(); // Now we give it to people in the list of living disease carriers earlier foreach (var target in aliveList) { if (toInfect-- == 0) { break; } diseaseSystem.TryAddDisease(target.Owner, disease, target); var station = stationSystem.GetOwningStation(target.Owner); if (station == null) { continue; } stationsToNotify.Add((EntityUid)station); } if (!AnnounceEvent) { return; } foreach (var station in stationsToNotify) { chatSystem.DispatchStationAnnouncement(station, Loc.GetString("station-event-disease-outbreak-announcement"), playDefaultSound: false, colorOverride: Color.YellowGreen); } }