Merge remote-tracking branch 'upstream/master' into ed-22-05-2024-upstream
4
.github/CODEOWNERS
vendored
@@ -27,7 +27,7 @@
|
||||
/Content.YAMLLinter @DrSmugleaf
|
||||
/Content.Shared/Damage/ @DrSmugleaf
|
||||
|
||||
/Content.*/Anomaly/ @EmoGarbage404
|
||||
/Content.*/Anomaly/ @EmoGarbage404 @TheShuEd
|
||||
/Content.*/Lathe/ @EmoGarbage404
|
||||
/Content.*/Materials/ @EmoGarbage404
|
||||
/Content.*/Mech/ @EmoGarbage404
|
||||
@@ -35,7 +35,7 @@
|
||||
/Content.*/Stack/ @EmoGarbage404
|
||||
/Content.*/Xenoarchaeology/ @EmoGarbage404
|
||||
/Content.*/Zombies/ @EmoGarbage404
|
||||
/Resources/Prototypes/Entities/Structures/Specific/anomalies.yml @EmoGarbage404
|
||||
/Resources/Prototypes/Entities/Structures/Specific/anomalies.yml @EmoGarbage404 @TheShuEd
|
||||
/Resources/Prototypes/Research/ @EmoGarbage404
|
||||
|
||||
/Content.*/Forensics/ @ficcialfaint
|
||||
|
||||
@@ -25,7 +25,7 @@ public sealed partial class GravitySystem
|
||||
{
|
||||
var localPlayer = _playerManager.LocalEntity;
|
||||
|
||||
if (!TryComp<TransformComponent>(localPlayer, out var xform) ||
|
||||
if (!TryComp(localPlayer, out TransformComponent? xform) ||
|
||||
xform.GridUid != uid && xform.MapUid != uid)
|
||||
{
|
||||
return;
|
||||
@@ -46,7 +46,7 @@ public sealed partial class GravitySystem
|
||||
|
||||
var localPlayer = _playerManager.LocalEntity;
|
||||
|
||||
if (!TryComp<TransformComponent>(localPlayer, out var xform))
|
||||
if (!TryComp(localPlayer, out TransformComponent? xform))
|
||||
return;
|
||||
|
||||
if (xform.GridUid != uid ||
|
||||
|
||||
@@ -47,6 +47,17 @@
|
||||
</CollapsibleBody>
|
||||
</Collapsible>
|
||||
</BoxContainer>
|
||||
<BoxContainer Name="PlantMetabolismsContainer" HorizontalExpand="True">
|
||||
<Collapsible>
|
||||
<CollapsibleHeading Title="{Loc 'guidebook-reagent-plant-metabolisms-header'}"/>
|
||||
<CollapsibleBody>
|
||||
<BoxContainer Name="PlantMetabolismsDescriptionContainer"
|
||||
Orientation="Vertical"
|
||||
Margin="10 0 10 0"
|
||||
HorizontalExpand="True"/>
|
||||
</CollapsibleBody>
|
||||
</Collapsible>
|
||||
</BoxContainer>
|
||||
<BoxContainer Margin="10 5 10 10" HorizontalExpand="True">
|
||||
<!-- The troublemaker !-->
|
||||
<RichTextLabel Name="ReagentDescription" HorizontalAlignment="Left"/>
|
||||
|
||||
@@ -157,6 +157,39 @@ public sealed partial class GuideReagentEmbed : BoxContainer, IDocumentTag, ISea
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PlantMetabolisms
|
||||
if (_chemistryGuideData.ReagentGuideRegistry.TryGetValue(reagent.ID, out var guideEntryRegistryPlant) &&
|
||||
guideEntryRegistryPlant.PlantMetabolisms != null &&
|
||||
guideEntryRegistryPlant.PlantMetabolisms.Count > 0)
|
||||
{
|
||||
PlantMetabolismsDescriptionContainer.Children.Clear();
|
||||
var metabolismLabel = new RichTextLabel();
|
||||
metabolismLabel.SetMarkup(Loc.GetString("guidebook-reagent-plant-metabolisms-rate"));
|
||||
var descriptionLabel = new RichTextLabel
|
||||
{
|
||||
Margin = new Thickness(25, 0, 10, 0)
|
||||
};
|
||||
var descMsg = new FormattedMessage();
|
||||
var descriptionsCount = guideEntryRegistryPlant.PlantMetabolisms.Count;
|
||||
var i = 0;
|
||||
foreach (var effectString in guideEntryRegistryPlant.PlantMetabolisms)
|
||||
{
|
||||
descMsg.AddMarkup(effectString);
|
||||
i++;
|
||||
if (i < descriptionsCount)
|
||||
descMsg.PushNewline();
|
||||
}
|
||||
descriptionLabel.SetMessage(descMsg);
|
||||
|
||||
PlantMetabolismsDescriptionContainer.AddChild(metabolismLabel);
|
||||
PlantMetabolismsDescriptionContainer.AddChild(descriptionLabel);
|
||||
}
|
||||
else
|
||||
{
|
||||
PlantMetabolismsContainer.Visible = false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
GenerateSources(reagent);
|
||||
|
||||
FormattedMessage description = new();
|
||||
|
||||
@@ -61,7 +61,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem
|
||||
{
|
||||
if (_dragging == null) return;
|
||||
|
||||
if (_lastMousePosition != null && TryComp<TransformComponent>(_dragging.Value, out var xform) &&
|
||||
if (_lastMousePosition != null && TryComp(_dragging.Value, out TransformComponent? xform) &&
|
||||
TryComp<PhysicsComponent>(_dragging.Value, out var body) &&
|
||||
xform.MapID == _lastMousePosition.Value.MapId)
|
||||
{
|
||||
@@ -104,7 +104,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem
|
||||
StartDragging(gridUid, Transform(gridUid).InvWorldMatrix.Transform(mousePos.Position));
|
||||
}
|
||||
|
||||
if (!TryComp<TransformComponent>(_dragging, out var xform))
|
||||
if (!TryComp(_dragging, out TransformComponent? xform))
|
||||
{
|
||||
StopDragging();
|
||||
return;
|
||||
|
||||
@@ -38,7 +38,7 @@ public sealed class SalvageSystem : SharedSalvageSystem
|
||||
|
||||
var player = _playerManager.LocalEntity;
|
||||
|
||||
if (!TryComp<TransformComponent>(player, out var xform) ||
|
||||
if (!TryComp(player, out TransformComponent? xform) ||
|
||||
!TryComp<SalvageExpeditionComponent>(xform.MapUid, out var expedition) ||
|
||||
expedition.Stage < ExpeditionStage.MusicCountdown)
|
||||
{
|
||||
|
||||
@@ -45,7 +45,7 @@ public sealed class SpriteFadeSystem : EntitySystem
|
||||
var spriteQuery = GetEntityQuery<SpriteComponent>();
|
||||
var change = ChangeRate * frameTime;
|
||||
|
||||
if (TryComp<TransformComponent>(player, out var playerXform) &&
|
||||
if (TryComp(player, out TransformComponent? playerXform) &&
|
||||
_stateManager.CurrentState is GameplayState state &&
|
||||
spriteQuery.TryGetComponent(player, out var playerSprite))
|
||||
{
|
||||
|
||||
@@ -82,7 +82,7 @@ public sealed class TetherGunSystem : SharedTetherGunSystem
|
||||
|
||||
const float BufferDistance = 0.1f;
|
||||
|
||||
if (TryComp<TransformComponent>(gun.TetherEntity, out var tetherXform) &&
|
||||
if (TryComp(gun.TetherEntity, out TransformComponent? tetherXform) &&
|
||||
tetherXform.Coordinates.TryDistance(EntityManager, TransformSystem, coords, out var distance) &&
|
||||
distance < BufferDistance)
|
||||
{
|
||||
|
||||
@@ -156,4 +156,20 @@ public sealed class GhostTests
|
||||
await data.Pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGhostGridNotTerminating()
|
||||
{
|
||||
var data = await SetupData();
|
||||
|
||||
Assert.DoesNotThrowAsync(async () =>
|
||||
{
|
||||
// Delete the grid
|
||||
await data.Server.WaitPost(() => data.SEntMan.DeleteEntity(data.MapData.Grid.Owner));
|
||||
});
|
||||
|
||||
await data.Pair.RunTicksSync(5);
|
||||
|
||||
await data.Pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ public sealed partial class AtmosphereSystem
|
||||
foreach (var grid in _mapManager.GetAllGrids(playerMap.Value).OrderBy(o => o.Owner))
|
||||
{
|
||||
var uid = grid.Owner;
|
||||
if (!TryComp<TransformComponent>(uid, out var gridXform))
|
||||
if (!TryComp(uid, out TransformComponent? gridXform))
|
||||
continue;
|
||||
|
||||
options.Add(new CompletionOption(uid.ToString(), $"{MetaData(uid).EntityName} - Map {gridXform.MapID}"));
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace Content.Server.Bible
|
||||
{
|
||||
Act = () =>
|
||||
{
|
||||
if (!TryComp<TransformComponent>(args.User, out var userXform))
|
||||
if (!TryComp(args.User, out TransformComponent? userXform))
|
||||
return;
|
||||
|
||||
AttemptSummon((uid, component), args.User, userXform);
|
||||
|
||||
@@ -15,6 +15,18 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
[DataField]
|
||||
public float Prob { get; protected set; } = 1; // = (80);
|
||||
|
||||
/// <summary>
|
||||
/// Localisation key for the name of the adjusted attribute. Used for guidebook descriptions.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public abstract string GuidebookAttributeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the attribute in question is a good thing. Used for guidebook descriptions to determine the color of the number.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public virtual bool GuidebookIsAttributePositive { get; protected set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the plant holder can metabolize the reagent or not. Checks if it has an alive plant by default.
|
||||
/// </summary>
|
||||
@@ -40,6 +52,18 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
return !(Prob <= 0f) && IoCManager.Resolve<IRobustRandom>().Prob(Prob);
|
||||
}
|
||||
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-missing", ("chance", Probability));
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys)
|
||||
{
|
||||
string color;
|
||||
if (GuidebookIsAttributePositive ^ Amount < 0.0)
|
||||
{
|
||||
color = "green";
|
||||
}
|
||||
else
|
||||
{
|
||||
color = "red";
|
||||
}
|
||||
return Loc.GetString("reagent-effect-guidebook-plant-attribute", ("attribute", Loc.GetString(GuidebookAttributeName)), ("amount", Amount.ToString("0.00")), ("colorName", color), ("chance", Probability));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
{
|
||||
public sealed partial class PlantAdjustHealth : PlantAdjustAttribute
|
||||
{
|
||||
public override string GuidebookAttributeName { get; set; } = "plant-attribute-health";
|
||||
|
||||
|
||||
public override void Effect(ReagentEffectArgs args)
|
||||
{
|
||||
if (!CanMetabolize(args.SolutionEntity, out var plantHolderComp, args.EntityManager))
|
||||
|
||||
@@ -4,6 +4,9 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
{
|
||||
public sealed partial class PlantAdjustMutationLevel : PlantAdjustAttribute
|
||||
{
|
||||
public override string GuidebookAttributeName { get; set; } = "plant-attribute-mutation-level";
|
||||
|
||||
|
||||
public override void Effect(ReagentEffectArgs args)
|
||||
{
|
||||
if (!CanMetabolize(args.SolutionEntity, out var plantHolderComp, args.EntityManager))
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
[UsedImplicitly]
|
||||
public sealed partial class PlantAdjustMutationMod : PlantAdjustAttribute
|
||||
{
|
||||
public override string GuidebookAttributeName { get; set; } = "plant-attribute-mutation-mod";
|
||||
|
||||
public override void Effect(ReagentEffectArgs args)
|
||||
{
|
||||
if (!CanMetabolize(args.SolutionEntity, out var plantHolderComp, args.EntityManager))
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
[UsedImplicitly]
|
||||
public sealed partial class PlantAdjustNutrition : PlantAdjustAttribute
|
||||
{
|
||||
public override string GuidebookAttributeName { get; set; } = "plant-attribute-nutrition";
|
||||
|
||||
public override void Effect(ReagentEffectArgs args)
|
||||
{
|
||||
if (!CanMetabolize(args.SolutionEntity, out var plantHolderComp, args.EntityManager, mustHaveAlivePlant: false))
|
||||
|
||||
@@ -6,6 +6,9 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
[UsedImplicitly]
|
||||
public sealed partial class PlantAdjustPests : PlantAdjustAttribute
|
||||
{
|
||||
public override string GuidebookAttributeName { get; set; } = "plant-attribute-pests";
|
||||
public override bool GuidebookIsAttributePositive { get; protected set; } = false;
|
||||
|
||||
public override void Effect(ReagentEffectArgs args)
|
||||
{
|
||||
if (!CanMetabolize(args.SolutionEntity, out var plantHolderComp, args.EntityManager))
|
||||
|
||||
@@ -6,6 +6,9 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
[UsedImplicitly]
|
||||
public sealed partial class PlantAdjustToxins : PlantAdjustAttribute
|
||||
{
|
||||
public override string GuidebookAttributeName { get; set; } = "plant-attribute-toxins";
|
||||
public override bool GuidebookIsAttributePositive { get; protected set; } = false;
|
||||
|
||||
public override void Effect(ReagentEffectArgs args)
|
||||
{
|
||||
if (!CanMetabolize(args.SolutionEntity, out var plantHolderComp, args.EntityManager))
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
[UsedImplicitly]
|
||||
public sealed partial class PlantAdjustWater : PlantAdjustAttribute
|
||||
{
|
||||
public override string GuidebookAttributeName { get; set; } = "plant-attribute-water";
|
||||
|
||||
public override void Effect(ReagentEffectArgs args)
|
||||
{
|
||||
if (!CanMetabolize(args.SolutionEntity, out var plantHolderComp, args.EntityManager, mustHaveAlivePlant: false))
|
||||
|
||||
@@ -6,6 +6,9 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
[UsedImplicitly]
|
||||
public sealed partial class PlantAdjustWeeds : PlantAdjustAttribute
|
||||
{
|
||||
public override string GuidebookAttributeName { get; set; } = "plant-attribute-weeds";
|
||||
public override bool GuidebookIsAttributePositive { get; protected set; } = false;
|
||||
|
||||
public override void Effect(ReagentEffectArgs args)
|
||||
{
|
||||
if (!CanMetabolize(args.SolutionEntity, out var plantHolderComp, args.EntityManager))
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
[UsedImplicitly]
|
||||
public sealed partial class PlantAffectGrowth : PlantAdjustAttribute
|
||||
{
|
||||
public override string GuidebookAttributeName { get; set; } = "plant-attribute-growth";
|
||||
|
||||
public override void Effect(ReagentEffectArgs args)
|
||||
{
|
||||
if (!CanMetabolize(args.SolutionEntity, out var plantHolderComp, args.EntityManager))
|
||||
|
||||
@@ -28,6 +28,6 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
plantHolderComp.ForceUpdate = true;
|
||||
}
|
||||
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-missing", ("chance", Probability));
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-plant-cryoxadone", ("chance", Probability));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,6 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
}
|
||||
}
|
||||
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-missing", ("chance", Probability));
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-plant-diethylamine", ("chance", Probability));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
plantHolderComp.Seed.Viable = true;
|
||||
}
|
||||
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-missing", ("chance", Probability));
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-plant-phalanximine", ("chance", Probability));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,6 @@ namespace Content.Server.Chemistry.ReagentEffects.PlantMetabolism
|
||||
}
|
||||
}
|
||||
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-missing", ("chance", Probability));
|
||||
protected override string? ReagentEffectGuidebookText(IPrototypeManager prototype, IEntitySystemManager entSys) => Loc.GetString("reagent-effect-guidebook-plant-robust-harvest", ("seedlesstreshold", PotencySeedlessThreshold), ("limit", PotencyLimit), ("increase", PotencyIncrease), ("chance", Probability));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Content.Server.Engineering.EntitySystems
|
||||
if (component.Deleted || Deleted(uid))
|
||||
return;
|
||||
|
||||
if (!TryComp<TransformComponent>(uid, out var transformComp))
|
||||
if (!TryComp(uid, out TransformComponent? transformComp))
|
||||
return;
|
||||
|
||||
var entity = EntityManager.SpawnEntity(component.Prototype, transformComp.Coordinates);
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace Content.Server.Explosion.EntitySystems
|
||||
|
||||
private void HandleGibTrigger(EntityUid uid, GibOnTriggerComponent component, TriggerEvent args)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform))
|
||||
if (!TryComp(uid, out TransformComponent? xform))
|
||||
return;
|
||||
if (component.DeleteItems)
|
||||
{
|
||||
|
||||
@@ -459,7 +459,7 @@ public sealed class FaxSystem : EntitySystem
|
||||
if (sendEntity == null)
|
||||
return;
|
||||
|
||||
if (!TryComp<MetaDataComponent>(sendEntity, out var metadata) ||
|
||||
if (!TryComp(sendEntity, out MetaDataComponent? metadata) ||
|
||||
!TryComp<PaperComponent>(sendEntity, out var paper))
|
||||
return;
|
||||
|
||||
@@ -506,7 +506,7 @@ public sealed class FaxSystem : EntitySystem
|
||||
if (!component.KnownFaxes.TryGetValue(component.DestinationFaxAddress, out var faxName))
|
||||
return;
|
||||
|
||||
if (!TryComp<MetaDataComponent>(sendEntity, out var metadata) ||
|
||||
if (!TryComp(sendEntity, out MetaDataComponent? metadata) ||
|
||||
!TryComp<PaperComponent>(sendEntity, out var paper))
|
||||
return;
|
||||
|
||||
|
||||
@@ -370,11 +370,16 @@ namespace Content.Server.GameTicking
|
||||
public EntityCoordinates GetObserverSpawnPoint()
|
||||
{
|
||||
_possiblePositions.Clear();
|
||||
|
||||
foreach (var (point, transform) in EntityManager.EntityQuery<SpawnPointComponent, TransformComponent>(true))
|
||||
var spawnPointQuery = EntityManager.EntityQueryEnumerator<SpawnPointComponent, TransformComponent>();
|
||||
while (spawnPointQuery.MoveNext(out var uid, out var point, out var transform))
|
||||
{
|
||||
if (point.SpawnType != SpawnPointType.Observer)
|
||||
if (point.SpawnType != SpawnPointType.Observer
|
||||
|| TerminatingOrDeleted(uid)
|
||||
|| transform.MapUid == null
|
||||
|| TerminatingOrDeleted(transform.MapUid.Value))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_possiblePositions.Add(transform.Coordinates);
|
||||
}
|
||||
@@ -416,7 +421,9 @@ namespace Content.Server.GameTicking
|
||||
|
||||
if (_mapManager.MapExists(DefaultMap))
|
||||
{
|
||||
return new EntityCoordinates(_mapManager.GetMapEntityId(DefaultMap), Vector2.Zero);
|
||||
var mapUid = _mapManager.GetMapEntityId(DefaultMap);
|
||||
if (!TerminatingOrDeleted(mapUid))
|
||||
return new EntityCoordinates(mapUid, Vector2.Zero);
|
||||
}
|
||||
|
||||
// Just pick a point at this point I guess.
|
||||
|
||||
@@ -306,7 +306,7 @@ namespace Content.Server.Ghost
|
||||
return;
|
||||
}
|
||||
|
||||
if (_followerSystem.GetMostFollowed() is not {} target)
|
||||
if (_followerSystem.GetMostGhostFollowed() is not {} target)
|
||||
return;
|
||||
|
||||
WarpTo(uid, target);
|
||||
@@ -409,23 +409,41 @@ namespace Content.Server.Ghost
|
||||
return SpawnGhost(mind, spawnPosition, canReturn);
|
||||
}
|
||||
|
||||
private bool IsValidSpawnPosition(EntityCoordinates? spawnPosition)
|
||||
{
|
||||
if (spawnPosition?.IsValid(EntityManager) != true)
|
||||
return false;
|
||||
|
||||
var mapUid = spawnPosition?.GetMapUid(EntityManager);
|
||||
var gridUid = spawnPosition?.EntityId;
|
||||
// Test if the map is being deleted
|
||||
if (mapUid == null || TerminatingOrDeleted(mapUid.Value))
|
||||
return false;
|
||||
// Test if the grid is being deleted
|
||||
if (gridUid != null && TerminatingOrDeleted(gridUid.Value))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public EntityUid? SpawnGhost(Entity<MindComponent?> mind, EntityCoordinates? spawnPosition = null,
|
||||
bool canReturn = false)
|
||||
{
|
||||
if (!Resolve(mind, ref mind.Comp))
|
||||
return null;
|
||||
|
||||
// Test if the map is being deleted
|
||||
var mapUid = spawnPosition?.GetMapUid(EntityManager);
|
||||
if (mapUid == null || TerminatingOrDeleted(mapUid.Value))
|
||||
// Test if the map or grid is being deleted
|
||||
if (!IsValidSpawnPosition(spawnPosition))
|
||||
spawnPosition = null;
|
||||
|
||||
// If it's bad, look for a valid point to spawn
|
||||
spawnPosition ??= _ticker.GetObserverSpawnPoint();
|
||||
|
||||
if (!spawnPosition.Value.IsValid(EntityManager))
|
||||
// Make sure the new point is valid too
|
||||
if (!IsValidSpawnPosition(spawnPosition))
|
||||
{
|
||||
Log.Warning($"No spawn valid ghost spawn position found for {mind.Comp.CharacterName}"
|
||||
+ " \"{ToPrettyString(mind)}\"");
|
||||
+ $" \"{ToPrettyString(mind)}\"");
|
||||
_minds.TransferTo(mind.Owner, null, createGhost: false, mind: mind.Comp);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Content.Server.Gravity
|
||||
private void OnComponentShutdown(EntityUid uid, GravityGeneratorComponent component, ComponentShutdown args)
|
||||
{
|
||||
if (component.GravityActive &&
|
||||
TryComp<TransformComponent>(uid, out var xform) &&
|
||||
TryComp(uid, out TransformComponent? xform) &&
|
||||
TryComp(xform.ParentUid, out GravityComponent? gravity))
|
||||
{
|
||||
component.GravityActive = false;
|
||||
@@ -114,7 +114,7 @@ namespace Content.Server.Gravity
|
||||
UpdateUI(ent, chargeRate);
|
||||
|
||||
if (active != gravGen.GravityActive &&
|
||||
TryComp<TransformComponent>(uid, out var xform) &&
|
||||
TryComp(uid, out TransformComponent? xform) &&
|
||||
TryComp<GravityComponent>(xform.ParentUid, out var gravity))
|
||||
{
|
||||
// Force it on in the faster path.
|
||||
|
||||
@@ -7,9 +7,7 @@ using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Markings;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.MagicMirror;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Audio.Systems;
|
||||
using Robust.Shared.Player;
|
||||
|
||||
namespace Content.Server.MagicMirror;
|
||||
|
||||
@@ -22,14 +20,14 @@ public sealed class MagicMirrorSystem : SharedMagicMirrorSystem
|
||||
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
|
||||
[Dependency] private readonly MarkingManager _markings = default!;
|
||||
[Dependency] private readonly HumanoidAppearanceSystem _humanoid = default!;
|
||||
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<MagicMirrorComponent, ActivatableUIOpenAttemptEvent>(OnOpenUIAttempt);
|
||||
|
||||
Subs.BuiEvents<MagicMirrorComponent>(MagicMirrorUiKey.Key, subs =>
|
||||
Subs.BuiEvents<MagicMirrorComponent>(MagicMirrorUiKey.Key,
|
||||
subs =>
|
||||
{
|
||||
subs.Event<BoundUIClosedEvent>(OnUiClosed);
|
||||
subs.Event<MagicMirrorSelectMessage>(OnMagicMirrorSelect);
|
||||
@@ -278,32 +276,6 @@ public sealed class MagicMirrorSystem : SharedMagicMirrorSystem
|
||||
|
||||
}
|
||||
|
||||
private void UpdateInterface(EntityUid mirrorUid, EntityUid targetUid, MagicMirrorComponent component)
|
||||
{
|
||||
if (!TryComp<HumanoidAppearanceComponent>(targetUid, out var humanoid))
|
||||
return;
|
||||
|
||||
var hair = humanoid.MarkingSet.TryGetCategory(MarkingCategories.Hair, out var hairMarkings)
|
||||
? new List<Marking>(hairMarkings)
|
||||
: new();
|
||||
|
||||
var facialHair = humanoid.MarkingSet.TryGetCategory(MarkingCategories.FacialHair, out var facialHairMarkings)
|
||||
? new List<Marking>(facialHairMarkings)
|
||||
: new();
|
||||
|
||||
var state = new MagicMirrorUiState(
|
||||
humanoid.Species,
|
||||
hair,
|
||||
humanoid.MarkingSet.PointsLeft(MarkingCategories.Hair) + hair.Count,
|
||||
facialHair,
|
||||
humanoid.MarkingSet.PointsLeft(MarkingCategories.FacialHair) + facialHair.Count);
|
||||
|
||||
// TODO: Component states
|
||||
component.Target = targetUid;
|
||||
_uiSystem.SetUiState(mirrorUid, MagicMirrorUiKey.Key, state);
|
||||
Dirty(mirrorUid, component);
|
||||
}
|
||||
|
||||
private void OnUiClosed(Entity<MagicMirrorComponent> ent, ref BoundUIClosedEvent args)
|
||||
{
|
||||
ent.Comp.Target = null;
|
||||
|
||||
@@ -162,6 +162,9 @@ public sealed class DefibrillatorSystem : EntitySystem
|
||||
if (_mobState.IsAlive(target, mobState))
|
||||
return false;
|
||||
|
||||
if (!component.CanDefibCrit && _mobState.IsCritical(target, mobState))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -179,7 +182,8 @@ public sealed class DefibrillatorSystem : EntitySystem
|
||||
{
|
||||
BlockDuplicate = true,
|
||||
BreakOnHandChange = true,
|
||||
NeedHand = true
|
||||
NeedHand = true,
|
||||
BreakOnMove = !component.AllowDoAfterMovement
|
||||
});
|
||||
}
|
||||
|
||||
@@ -254,6 +258,10 @@ public sealed class DefibrillatorSystem : EntitySystem
|
||||
// if we don't have enough power left for another shot, turn it off
|
||||
if (!_powerCell.HasActivatableCharge(uid))
|
||||
TryDisable(uid, component);
|
||||
|
||||
// TODO clean up this clown show above
|
||||
var ev = new TargetDefibrillatedEvent(user, (uid, component));
|
||||
RaiseLocalEvent(target, ref ev);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace Content.Server.Medical
|
||||
return;
|
||||
|
||||
var name = "Unknown";
|
||||
if (TryComp<MetaDataComponent>(args.Using.Value, out var metadata))
|
||||
if (TryComp(args.Using.Value, out MetaDataComponent? metadata))
|
||||
name = metadata.EntityName;
|
||||
|
||||
InteractionVerb verb = new()
|
||||
|
||||
@@ -30,8 +30,8 @@ public sealed partial class PathfindingSystem
|
||||
|
||||
if (end.GraphUid != start.GraphUid)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(start.GraphUid, out var startXform) ||
|
||||
!TryComp<TransformComponent>(end.GraphUid, out var endXform))
|
||||
if (!TryComp(start.GraphUid, out TransformComponent? startXform) ||
|
||||
!TryComp(end.GraphUid, out TransformComponent? endXform))
|
||||
{
|
||||
return Vector2.Zero;
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ public sealed partial class PathfindingSystem
|
||||
|
||||
private void OnBodyTypeChange(ref PhysicsBodyTypeChangedEvent ev)
|
||||
{
|
||||
if (TryComp<TransformComponent>(ev.Entity, out var xform) &&
|
||||
if (TryComp(ev.Entity, out TransformComponent? xform) &&
|
||||
xform.GridUid != null)
|
||||
{
|
||||
var aabb = _lookup.GetAABBNoContainer(ev.Entity, xform.Coordinates.Position, xform.LocalRotation);
|
||||
|
||||
@@ -264,7 +264,7 @@ namespace Content.Server.NPC.Pathfinding
|
||||
int limit = 40,
|
||||
PathFlags flags = PathFlags.None)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(entity, out var start))
|
||||
if (!TryComp(entity, out TransformComponent? start))
|
||||
return new PathResultEvent(PathResult.NoPath, new List<PathPoly>());
|
||||
|
||||
var layer = 0;
|
||||
@@ -294,7 +294,7 @@ namespace Content.Server.NPC.Pathfinding
|
||||
CancellationToken cancelToken,
|
||||
PathFlags flags = PathFlags.None)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(entity, out var start))
|
||||
if (!TryComp(entity, out TransformComponent? start))
|
||||
return null;
|
||||
|
||||
var request = GetRequest(entity, start.Coordinates, end, range, cancelToken, flags);
|
||||
@@ -325,8 +325,8 @@ namespace Content.Server.NPC.Pathfinding
|
||||
CancellationToken cancelToken,
|
||||
PathFlags flags = PathFlags.None)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(entity, out var xform) ||
|
||||
!TryComp<TransformComponent>(target, out var targetXform))
|
||||
if (!TryComp(entity, out TransformComponent? xform) ||
|
||||
!TryComp(target, out TransformComponent? targetXform))
|
||||
return new PathResultEvent(PathResult.NoPath, new List<PathPoly>());
|
||||
|
||||
var request = GetRequest(entity, xform.Coordinates, targetXform.Coordinates, range, cancelToken, flags);
|
||||
@@ -400,7 +400,7 @@ namespace Content.Server.NPC.Pathfinding
|
||||
var gridUid = coordinates.GetGridUid(EntityManager);
|
||||
|
||||
if (!TryComp<GridPathfindingComponent>(gridUid, out var comp) ||
|
||||
!TryComp<TransformComponent>(gridUid, out var xform))
|
||||
!TryComp(gridUid, out TransformComponent? xform))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -260,8 +260,8 @@ public sealed class NPCUtilitySystem : EntitySystem
|
||||
{
|
||||
var radius = blackboard.GetValueOrDefault<float>(NPCBlackboard.VisionRadius, EntityManager);
|
||||
|
||||
if (!TryComp<TransformComponent>(targetUid, out var targetXform) ||
|
||||
!TryComp<TransformComponent>(owner, out var xform))
|
||||
if (!TryComp(targetUid, out TransformComponent? targetXform) ||
|
||||
!TryComp(owner, out TransformComponent? xform))
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
@@ -308,8 +308,8 @@ public sealed class NPCUtilitySystem : EntitySystem
|
||||
|
||||
if (blackboard.TryGetValue<EntityUid>("Target", out var currentTarget, EntityManager) &&
|
||||
currentTarget == targetUid &&
|
||||
TryComp<TransformComponent>(owner, out var xform) &&
|
||||
TryComp<TransformComponent>(targetUid, out var targetXform) &&
|
||||
TryComp(owner, out TransformComponent? xform) &&
|
||||
TryComp(targetUid, out TransformComponent? targetXform) &&
|
||||
xform.Coordinates.TryDistance(EntityManager, _transform, targetXform.Coordinates, out var distance) &&
|
||||
distance <= radius + bufferRange)
|
||||
{
|
||||
|
||||
@@ -111,7 +111,7 @@ public sealed class PAISystem : SharedPAISystem
|
||||
if (TryComp<InstrumentComponent>(uid, out var instrument))
|
||||
_instrumentSystem.Clean(uid, instrument);
|
||||
|
||||
if (TryComp<MetaDataComponent>(uid, out var metadata))
|
||||
if (TryComp(uid, out MetaDataComponent? metadata))
|
||||
{
|
||||
var proto = metadata.EntityPrototype;
|
||||
if (proto != null)
|
||||
|
||||
@@ -148,7 +148,7 @@ namespace Content.Server.Paper
|
||||
if (TryComp<AppearanceComponent>(uid, out var appearance))
|
||||
_appearance.SetData(uid, PaperVisuals.Status, PaperStatus.Written, appearance);
|
||||
|
||||
if (TryComp<MetaDataComponent>(uid, out var meta))
|
||||
if (TryComp(uid, out MetaDataComponent? meta))
|
||||
_metaSystem.SetEntityDescription(uid, "", meta);
|
||||
|
||||
_adminLogger.Add(LogType.Chat, LogImpact.Low,
|
||||
|
||||
@@ -271,7 +271,7 @@ namespace Content.Server.Physics.Controllers
|
||||
consoleEnt = cargoConsole.Entity;
|
||||
}
|
||||
|
||||
if (!TryComp<TransformComponent>(consoleEnt, out var xform)) continue;
|
||||
if (!TryComp(consoleEnt, out TransformComponent? xform)) continue;
|
||||
|
||||
var gridId = xform.GridUid;
|
||||
// This tries to see if the grid is a shuttle and if the console should work.
|
||||
|
||||
@@ -88,7 +88,10 @@ namespace Content.Server.Pointing.EntitySystems
|
||||
? viewerPointedAtMessage
|
||||
: viewerMessage;
|
||||
|
||||
RaiseNetworkEvent(new PopupEntityEvent(message, PopupType.Small, netSource), viewerEntity);
|
||||
// Someone pointing at YOU is slightly more important
|
||||
var popupType = viewerEntity == pointed ? PopupType.Medium : PopupType.Small;
|
||||
|
||||
RaiseNetworkEvent(new PopupEntityEvent(message, popupType, netSource), viewerEntity);
|
||||
}
|
||||
|
||||
_replay.RecordServerMessage(new PopupEntityEvent(viewerMessage, PopupType.Small, netSource));
|
||||
|
||||
@@ -248,7 +248,7 @@ public sealed partial class PolymorphSystem : EntitySystem
|
||||
}
|
||||
}
|
||||
|
||||
if (configuration.TransferName && TryComp<MetaDataComponent>(uid, out var targetMeta))
|
||||
if (configuration.TransferName && TryComp(uid, out MetaDataComponent? targetMeta))
|
||||
_metaData.SetEntityName(child, targetMeta.EntityName);
|
||||
|
||||
if (configuration.TransferHumanoidAppearance)
|
||||
|
||||
@@ -72,7 +72,7 @@ public sealed class ProjectileSystem : SharedProjectileSystem
|
||||
if (component.DeleteOnCollide)
|
||||
QueueDel(uid);
|
||||
|
||||
if (component.ImpactEffect != null && TryComp<TransformComponent>(uid, out var xform))
|
||||
if (component.ImpactEffect != null && TryComp(uid, out TransformComponent? xform))
|
||||
{
|
||||
RaiseNetworkEvent(new ImpactEffectEvent(component.ImpactEffect, GetNetCoordinates(xform.Coordinates)), Filter.Pvs(xform.Coordinates, entityMan: EntityManager));
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public sealed class FultonSystem : SharedFultonSystem
|
||||
private void Fulton(EntityUid uid, FultonedComponent component)
|
||||
{
|
||||
if (!Deleted(component.Beacon) &&
|
||||
TryComp<TransformComponent>(component.Beacon, out var beaconXform) &&
|
||||
TryComp(component.Beacon, out TransformComponent? beaconXform) &&
|
||||
!Container.IsEntityOrParentInContainer(component.Beacon.Value, xform: beaconXform) &&
|
||||
CanFulton(uid))
|
||||
{
|
||||
|
||||
@@ -32,7 +32,7 @@ public sealed partial class SalvageSystem
|
||||
|
||||
private void OnConsoleFTLAttempt(ref ConsoleFTLAttemptEvent ev)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(ev.Uid, out var xform) ||
|
||||
if (!TryComp(ev.Uid, out TransformComponent? xform) ||
|
||||
!TryComp<SalvageExpeditionComponent>(xform.MapUid, out var salvage))
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -316,7 +316,7 @@ public sealed class ArrivalsSystem : EntitySystem
|
||||
|
||||
TryGetArrivals(out var arrivals);
|
||||
|
||||
if (TryComp<TransformComponent>(arrivals, out var arrivalsXform))
|
||||
if (TryComp(arrivals, out TransformComponent? arrivalsXform))
|
||||
{
|
||||
var mapId = arrivalsXform.MapID;
|
||||
|
||||
@@ -413,7 +413,7 @@ public sealed class ArrivalsSystem : EntitySystem
|
||||
var curTime = _timing.CurTime;
|
||||
TryGetArrivals(out var arrivals);
|
||||
|
||||
if (TryComp<TransformComponent>(arrivals, out var arrivalsXform))
|
||||
if (TryComp(arrivals, out TransformComponent? arrivalsXform))
|
||||
{
|
||||
while (query.MoveNext(out var uid, out var comp, out var shuttle, out var xform))
|
||||
{
|
||||
|
||||
@@ -261,7 +261,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
||||
if (!Resolve(stationUid, ref stationShuttle))
|
||||
return;
|
||||
|
||||
if (!TryComp<TransformComponent>(stationShuttle.EmergencyShuttle, out var xform) ||
|
||||
if (!TryComp(stationShuttle.EmergencyShuttle, out TransformComponent? xform) ||
|
||||
!TryComp<ShuttleComponent>(stationShuttle.EmergencyShuttle, out var shuttle))
|
||||
{
|
||||
Log.Error($"Attempted to call an emergency shuttle for an uninitialized station? Station: {ToPrettyString(stationUid)}. Shuttle: {ToPrettyString(stationShuttle.EmergencyShuttle)}");
|
||||
@@ -284,7 +284,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
||||
|
||||
if (_shuttle.TryFTLDock(stationShuttle.EmergencyShuttle.Value, shuttle, targetGrid.Value, DockTag))
|
||||
{
|
||||
if (TryComp<TransformComponent>(targetGrid.Value, out var targetXform))
|
||||
if (TryComp(targetGrid.Value, out TransformComponent? targetXform))
|
||||
{
|
||||
var angle = _dock.GetAngle(stationShuttle.EmergencyShuttle.Value, xform, targetGrid.Value, targetXform, xformQuery);
|
||||
_chatSystem.DispatchStationAnnouncement(stationUid, Loc.GetString("emergency-shuttle-docked", ("time", $"{_consoleAccumulator:0}"), ("direction", angle.GetDir())), playDefaultSound: false);
|
||||
@@ -330,7 +330,7 @@ public sealed partial class EmergencyShuttleSystem : EntitySystem
|
||||
return;
|
||||
|
||||
// Post mapinit? fancy
|
||||
if (TryComp<TransformComponent>(component.Entity, out var xform))
|
||||
if (TryComp(component.Entity, out TransformComponent? xform))
|
||||
{
|
||||
component.MapEntity = xform.MapUid;
|
||||
return;
|
||||
|
||||
@@ -242,7 +242,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
|
||||
RaiseLocalEvent(entity.Value, ref getShuttleEv);
|
||||
entity = getShuttleEv.Console;
|
||||
|
||||
TryComp<TransformComponent>(entity, out var consoleXform);
|
||||
TryComp(entity, out TransformComponent? consoleXform);
|
||||
var shuttleGridUid = consoleXform?.GridUid;
|
||||
|
||||
NavInterfaceState navState;
|
||||
|
||||
@@ -184,7 +184,7 @@ public sealed partial class ShuttleSystem
|
||||
return;
|
||||
|
||||
if (!TryComp<DockingComponent>(uid, out var dock) ||
|
||||
!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
!TryComp(uid, out TransformComponent? xform) ||
|
||||
xform.GridUid == null)
|
||||
{
|
||||
return;
|
||||
@@ -196,7 +196,7 @@ public sealed partial class ShuttleSystem
|
||||
|
||||
if (_loader.TryLoad(mapId, component.Path.ToString(), out var ent) &&
|
||||
ent.Count == 1 &&
|
||||
TryComp<TransformComponent>(ent[0], out var shuttleXform))
|
||||
TryComp(ent[0], out TransformComponent? shuttleXform))
|
||||
{
|
||||
var escape = GetSingleDock(ent[0]);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ public sealed partial class ShuttleSystem
|
||||
|
||||
private void OnIFFShow(EntityUid uid, IFFConsoleComponent component, IFFShowIFFMessage args)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform) || xform.GridUid == null ||
|
||||
if (!TryComp(uid, out TransformComponent? xform) || xform.GridUid == null ||
|
||||
(component.AllowedFlags & IFFFlags.HideLabel) == 0x0)
|
||||
{
|
||||
return;
|
||||
@@ -34,7 +34,7 @@ public sealed partial class ShuttleSystem
|
||||
|
||||
private void OnIFFShowVessel(EntityUid uid, IFFConsoleComponent component, IFFShowVesselMessage args)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform) || xform.GridUid == null ||
|
||||
if (!TryComp(uid, out TransformComponent? xform) || xform.GridUid == null ||
|
||||
(component.AllowedFlags & IFFFlags.Hide) == 0x0)
|
||||
{
|
||||
return;
|
||||
@@ -54,7 +54,7 @@ public sealed partial class ShuttleSystem
|
||||
{
|
||||
// If we anchor / re-anchor then make sure flags up to date.
|
||||
if (!args.Anchored ||
|
||||
!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
!TryComp(uid, out TransformComponent? xform) ||
|
||||
!TryComp<IFFComponent>(xform.GridUid, out var iff))
|
||||
{
|
||||
_uiSystem.SetUiState(uid, IFFConsoleUiKey.Key, new IFFConsoleBoundUserInterfaceState()
|
||||
|
||||
@@ -14,7 +14,7 @@ public sealed class SpawnOnDespawnSystem : EntitySystem
|
||||
|
||||
private void OnDespawn(EntityUid uid, SpawnOnDespawnComponent comp, ref TimedDespawnEvent args)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform))
|
||||
if (!TryComp(uid, out TransformComponent? xform))
|
||||
return;
|
||||
|
||||
Spawn(comp.Prototype, xform.Coordinates);
|
||||
|
||||
@@ -195,12 +195,22 @@ namespace Content.Shared.Chemistry.Reagent
|
||||
|
||||
public Dictionary<ProtoId<MetabolismGroupPrototype>, ReagentEffectsGuideEntry>? GuideEntries;
|
||||
|
||||
public List<string>? PlantMetabolisms = null;
|
||||
|
||||
public ReagentGuideEntry(ReagentPrototype proto, IPrototypeManager prototype, IEntitySystemManager entSys)
|
||||
{
|
||||
ReagentPrototype = proto.ID;
|
||||
GuideEntries = proto.Metabolisms?
|
||||
.Select(x => (x.Key, x.Value.MakeGuideEntry(prototype, entSys)))
|
||||
.ToDictionary(x => x.Key, x => x.Item2);
|
||||
if (proto.PlantMetabolisms.Count > 0)
|
||||
{
|
||||
PlantMetabolisms = new List<string> (proto.PlantMetabolisms
|
||||
.Select(x => x.GuidebookEffectDescription(prototype, entSys))
|
||||
.Where(x => x is not null)
|
||||
.Select(x => x!)
|
||||
.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Administration.Managers;
|
||||
using Content.Shared.Database;
|
||||
using Content.Shared.Follower.Components;
|
||||
using Content.Shared.Ghost;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Movement.Events;
|
||||
using Content.Shared.Movement.Pulling.Events;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Tag;
|
||||
using Content.Shared.Verbs;
|
||||
using Robust.Shared.Containers;
|
||||
@@ -14,6 +14,7 @@ using Robust.Shared.Map.Events;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Physics.Systems;
|
||||
using Robust.Shared.Player;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Follower;
|
||||
@@ -26,6 +27,7 @@ public sealed class FollowerSystem : EntitySystem
|
||||
[Dependency] private readonly SharedJointSystem _jointSystem = default!;
|
||||
[Dependency] private readonly SharedPhysicsSystem _physicsSystem = default!;
|
||||
[Dependency] private readonly INetManager _netMan = default!;
|
||||
[Dependency] private readonly ISharedAdminManager _adminManager = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -249,20 +251,33 @@ public sealed class FollowerSystem : EntitySystem
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the most followed entity.
|
||||
/// Gets the entity with the most non-admin ghosts following it.
|
||||
/// </summary>
|
||||
public EntityUid? GetMostFollowed()
|
||||
public EntityUid? GetMostGhostFollowed()
|
||||
{
|
||||
EntityUid? picked = null;
|
||||
int most = 0;
|
||||
var query = EntityQueryEnumerator<FollowedComponent>();
|
||||
while (query.MoveNext(out var uid, out var comp))
|
||||
var most = 0;
|
||||
|
||||
// Keep a tally of how many ghosts are following each entity
|
||||
var followedEnts = new Dictionary<EntityUid, int>();
|
||||
|
||||
// Look for followers that are ghosts and are player controlled
|
||||
var query = EntityQueryEnumerator<FollowerComponent, GhostComponent, ActorComponent>();
|
||||
while (query.MoveNext(out _, out var follower, out _, out var actor))
|
||||
{
|
||||
var count = comp.Following.Count;
|
||||
if (count > most)
|
||||
// Exclude admins
|
||||
if (_adminManager.IsAdmin(actor.PlayerSession))
|
||||
continue;
|
||||
|
||||
var followed = follower.Following;
|
||||
// Add new entry or increment existing
|
||||
followedEnts.TryGetValue(followed, out var currentValue);
|
||||
followedEnts[followed] = currentValue + 1;
|
||||
|
||||
if (followedEnts[followed] > most)
|
||||
{
|
||||
picked = uid;
|
||||
most = count;
|
||||
picked = followed;
|
||||
most = followedEnts[followed];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -570,7 +570,7 @@ namespace Content.Shared.Interaction
|
||||
Ignored? predicate = null,
|
||||
bool popup = false)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(other, out var otherXform))
|
||||
if (!TryComp(other, out TransformComponent? otherXform))
|
||||
return false;
|
||||
|
||||
return InRangeUnobstructed(origin, other, otherXform.Coordinates, otherXform.LocalRotation, range, collisionMask, predicate,
|
||||
@@ -633,7 +633,7 @@ namespace Content.Shared.Interaction
|
||||
fixtureA.FixtureCount > 0 &&
|
||||
TryComp<FixturesComponent>(other, out var fixtureB) &&
|
||||
fixtureB.FixtureCount > 0 &&
|
||||
TryComp<TransformComponent>(origin, out var xformA))
|
||||
TryComp(origin, out TransformComponent? xformA))
|
||||
{
|
||||
var (worldPosA, worldRotA) = xformA.GetWorldPositionRotation();
|
||||
var xfA = new Transform(worldPosA, worldRotA);
|
||||
|
||||
@@ -47,5 +47,5 @@ public sealed partial class MagicMirrorComponent : Component
|
||||
/// Sound emitted when slots are changed
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public SoundSpecifier ChangeHairSound = new SoundPathSpecifier("/Audio/Items/scissors.ogg");
|
||||
public SoundSpecifier? ChangeHairSound = new SoundPathSpecifier("/Audio/Items/scissors.ogg");
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Content.Shared.DoAfter;
|
||||
using Content.Shared.Humanoid;
|
||||
using Content.Shared.Humanoid.Markings;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.UserInterface;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.MagicMirror;
|
||||
@@ -8,10 +10,12 @@ namespace Content.Shared.MagicMirror;
|
||||
public abstract class SharedMagicMirrorSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly SharedInteractionSystem _interaction = default!;
|
||||
[Dependency] protected readonly SharedUserInterfaceSystem _uiSystem = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<MagicMirrorComponent, BeforeActivatableUIOpenEvent>(OnBeforeUIOpen);
|
||||
SubscribeLocalEvent<MagicMirrorComponent, BoundUserInterfaceCheckRangeEvent>(OnMirrorRangeCheck);
|
||||
}
|
||||
|
||||
@@ -22,6 +26,38 @@ public abstract class SharedMagicMirrorSystem : EntitySystem
|
||||
args.Result = BoundUserInterfaceRangeResult.Fail;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnBeforeUIOpen(Entity<MagicMirrorComponent> ent, ref BeforeActivatableUIOpenEvent args)
|
||||
{
|
||||
ent.Comp.Target ??= args.User;
|
||||
UpdateInterface(ent, args.User, ent);
|
||||
}
|
||||
|
||||
protected void UpdateInterface(EntityUid mirrorUid, EntityUid targetUid, MagicMirrorComponent component)
|
||||
{
|
||||
if (!TryComp<HumanoidAppearanceComponent>(targetUid, out var humanoid))
|
||||
return;
|
||||
|
||||
var hair = humanoid.MarkingSet.TryGetCategory(MarkingCategories.Hair, out var hairMarkings)
|
||||
? new List<Marking>(hairMarkings)
|
||||
: new();
|
||||
|
||||
var facialHair = humanoid.MarkingSet.TryGetCategory(MarkingCategories.FacialHair, out var facialHairMarkings)
|
||||
? new List<Marking>(facialHairMarkings)
|
||||
: new();
|
||||
|
||||
var state = new MagicMirrorUiState(
|
||||
humanoid.Species,
|
||||
hair,
|
||||
humanoid.MarkingSet.PointsLeft(MarkingCategories.Hair) + hair.Count,
|
||||
facialHair,
|
||||
humanoid.MarkingSet.PointsLeft(MarkingCategories.FacialHair) + facialHair.Count);
|
||||
|
||||
// TODO: Component states
|
||||
component.Target = targetUid;
|
||||
_uiSystem.SetUiState(mirrorUid, MagicMirrorUiKey.Key, state);
|
||||
Dirty(mirrorUid, component);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -60,6 +60,12 @@ public sealed partial class DefibrillatorComponent : Component
|
||||
[DataField("doAfterDuration"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan DoAfterDuration = TimeSpan.FromSeconds(3);
|
||||
|
||||
[DataField]
|
||||
public bool AllowDoAfterMovement = true;
|
||||
|
||||
[DataField]
|
||||
public bool CanDefibCrit = true;
|
||||
|
||||
/// <summary>
|
||||
/// The sound when someone is zapped.
|
||||
/// </summary>
|
||||
|
||||
4
Content.Shared/Medical/TargetDefibrillatedEvent.cs
Normal file
@@ -0,0 +1,4 @@
|
||||
namespace Content.Shared.Medical;
|
||||
|
||||
[ByRefEvent]
|
||||
public readonly record struct TargetDefibrillatedEvent(EntityUid User, Entity<DefibrillatorComponent> Defibrillator);
|
||||
@@ -113,7 +113,7 @@ public abstract class SharedJetpackSystem : EntitySystem
|
||||
if (args.Handled)
|
||||
return;
|
||||
|
||||
if (TryComp<TransformComponent>(uid, out var xform) && !CanEnableOnGrid(xform.GridUid))
|
||||
if (TryComp(uid, out TransformComponent? xform) && !CanEnableOnGrid(xform.GridUid))
|
||||
{
|
||||
_popup.PopupClient(Loc.GetString("jetpack-no-station"), uid, args.Performer);
|
||||
|
||||
|
||||
@@ -313,7 +313,7 @@ namespace Content.Shared.Movement.Systems
|
||||
// For stuff like "Moving out of locker" or the likes
|
||||
// We'll relay a movement input to the parent.
|
||||
if (_container.IsEntityInContainer(entity) &&
|
||||
TryComp<TransformComponent>(entity, out var xform) &&
|
||||
TryComp(entity, out TransformComponent? xform) &&
|
||||
xform.ParentUid.IsValid() &&
|
||||
_mobState.IsAlive(entity))
|
||||
{
|
||||
|
||||
@@ -179,7 +179,7 @@ public sealed partial class PressurizedSolutionSystem : EntitySystem
|
||||
var solution = _solutionContainer.SplitSolution(soln.Value, interactions.Volume);
|
||||
|
||||
// Spray the solution onto the ground and anyone nearby
|
||||
if (TryComp<TransformComponent>(entity, out var transform))
|
||||
if (TryComp(entity, out TransformComponent? transform))
|
||||
_puddle.TrySplashSpillAt(entity, transform.Coordinates, solution, out _, sound: false);
|
||||
|
||||
var drinkName = Identity.Entity(entity, EntityManager);
|
||||
|
||||
@@ -81,7 +81,7 @@ public abstract partial class SharedDrinkSystem : EntitySystem
|
||||
{
|
||||
string remainingString = "drink-component-on-examine-is-half-full";
|
||||
|
||||
if (TryComp<MetaDataComponent>(args.Examiner, out var examiner) && examiner.EntityName.Length > 0
|
||||
if (TryComp(args.Examiner, out MetaDataComponent? examiner) && examiner.EntityName.Length > 0
|
||||
&& string.Compare(examiner.EntityName.Substring(0, 1), "m", StringComparison.InvariantCultureIgnoreCase) > 0)
|
||||
remainingString = "drink-component-on-examine-is-half-empty";
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ public sealed class RulesSystem : EntitySystem
|
||||
break;
|
||||
case GridInRangeRule griddy:
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform))
|
||||
if (!TryComp(uid, out TransformComponent? xform))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public sealed class RulesSystem : EntitySystem
|
||||
}
|
||||
case InSpaceRule:
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||
xform.GridUid != null)
|
||||
{
|
||||
return false;
|
||||
@@ -146,7 +146,7 @@ public sealed class RulesSystem : EntitySystem
|
||||
}
|
||||
case NearbyEntitiesRule entity:
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||
xform.MapUid == null)
|
||||
{
|
||||
return false;
|
||||
@@ -177,7 +177,7 @@ public sealed class RulesSystem : EntitySystem
|
||||
}
|
||||
case NearbyTilesPercentRule tiles:
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||
!TryComp<MapGridComponent>(xform.GridUid, out var grid))
|
||||
{
|
||||
return false;
|
||||
@@ -227,7 +227,7 @@ public sealed class RulesSystem : EntitySystem
|
||||
}
|
||||
case OnMapGridRule:
|
||||
{
|
||||
if (!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
if (!TryComp(uid, out TransformComponent? xform) ||
|
||||
xform.GridUid != xform.MapUid ||
|
||||
xform.MapUid == null)
|
||||
{
|
||||
|
||||
@@ -72,7 +72,7 @@ public abstract class SharedEmitSoundSystem : EntitySystem
|
||||
private void OnEmitSoundOnLand(EntityUid uid, BaseEmitSoundComponent component, ref LandEvent args)
|
||||
{
|
||||
if (!args.PlaySound ||
|
||||
!TryComp<TransformComponent>(uid, out var xform) ||
|
||||
!TryComp(uid, out TransformComponent? xform) ||
|
||||
!TryComp<MapGridComponent>(xform.GridUid, out var grid))
|
||||
{
|
||||
return;
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Content.Shared.Standing
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public SoundSpecifier DownSound { get; private set; } = new SoundCollectionSpecifier("BodyFall");
|
||||
public SoundSpecifier? DownSound { get; private set; } = new SoundCollectionSpecifier("BodyFall");
|
||||
|
||||
[DataField, AutoNetworkedField]
|
||||
public bool Standing { get; set; } = true;
|
||||
|
||||
@@ -468,7 +468,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
||||
return;
|
||||
}
|
||||
|
||||
if (_xformQuery.TryGetComponent(uid, out var transformOwner) && TryComp<TransformComponent>(target, out var transformEnt))
|
||||
if (TryComp(uid, out TransformComponent? transformOwner) && TryComp(target, out TransformComponent? transformEnt))
|
||||
{
|
||||
var parent = transformOwner.ParentUid;
|
||||
|
||||
|
||||
@@ -315,7 +315,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
public bool AttemptLightAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(target, out var targetXform))
|
||||
if (!TryComp(target, out TransformComponent? targetXform))
|
||||
return false;
|
||||
|
||||
return AttemptAttack(user, weaponUid, weapon, new LightAttackEvent(GetNetEntity(target), GetNetEntity(weaponUid), GetNetCoordinates(targetXform.Coordinates)), null);
|
||||
@@ -323,7 +323,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
public bool AttemptDisarmAttack(EntityUid user, EntityUid weaponUid, MeleeWeaponComponent weapon, EntityUid target)
|
||||
{
|
||||
if (!TryComp<TransformComponent>(target, out var targetXform))
|
||||
if (!TryComp(target, out TransformComponent? targetXform))
|
||||
return false;
|
||||
|
||||
return AttemptAttack(user, weaponUid, weapon, new DisarmAttackEvent(GetNetEntity(target), GetNetCoordinates(targetXform.Coordinates)), null);
|
||||
@@ -451,7 +451,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
// For consistency with wide attacks stuff needs damageable.
|
||||
if (Deleted(target) ||
|
||||
!HasComp<DamageableComponent>(target) ||
|
||||
!TryComp<TransformComponent>(target, out var targetXform) ||
|
||||
!TryComp(target, out TransformComponent? targetXform) ||
|
||||
// Not in LOS.
|
||||
!InRange(user, target.Value, component.Range, session))
|
||||
{
|
||||
@@ -539,7 +539,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
private bool DoHeavyAttack(EntityUid user, HeavyAttackEvent ev, EntityUid meleeUid, MeleeWeaponComponent component, ICommonSession? session)
|
||||
{
|
||||
// TODO: This is copy-paste as fuck with DoPreciseAttack
|
||||
if (!TryComp<TransformComponent>(user, out var userXform))
|
||||
if (!TryComp(user, out TransformComponent? userXform))
|
||||
return false;
|
||||
|
||||
var targetMap = GetCoordinates(ev.Coordinates).ToMap(EntityManager, TransformSystem);
|
||||
@@ -753,7 +753,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
private void DoLungeAnimation(EntityUid user, EntityUid weapon, Angle angle, MapCoordinates coordinates, float length, string? animation)
|
||||
{
|
||||
// TODO: Assert that offset eyes are still okay.
|
||||
if (!TryComp<TransformComponent>(user, out var userXform))
|
||||
if (!TryComp(user, out TransformComponent? userXform))
|
||||
return;
|
||||
|
||||
var invMatrix = TransformSystem.GetInvWorldMatrix(userXform);
|
||||
|
||||
@@ -112,6 +112,12 @@ public abstract partial class SharedGunSystem
|
||||
|
||||
private void OnGunSelected(EntityUid uid, GunComponent component, HandSelectedEvent args)
|
||||
{
|
||||
if (Timing.ApplyingState)
|
||||
return;
|
||||
|
||||
if (component.FireRateModified <= 0)
|
||||
return;
|
||||
|
||||
var fireDelay = 1f / component.FireRateModified;
|
||||
if (fireDelay.Equals(0f))
|
||||
return;
|
||||
|
||||
@@ -222,5 +222,18 @@ Entries:
|
||||
id: 28
|
||||
time: '2024-05-12T15:07:54.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/27883
|
||||
- author: Arimah and TsjipTsjip
|
||||
changes:
|
||||
- message: Universal access configurator which can modify all access levels with
|
||||
the correct ID card.
|
||||
type: Add
|
||||
- message: Universal ID card which has all access levels.
|
||||
type: Add
|
||||
- message: Admin PDA's spawn with a universal ID card, admin ghosts get a universal
|
||||
access configurator in their bluespace satchel.
|
||||
type: Tweak
|
||||
id: 29
|
||||
time: '2024-05-19T23:04:16.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28107
|
||||
Name: Admin
|
||||
Order: 1
|
||||
|
||||
@@ -1,53 +1,4 @@
|
||||
Entries:
|
||||
- author: Doctor-Cpu
|
||||
changes:
|
||||
- message: Cargo palllets can no longer be ordered from cargo request terminal
|
||||
type: Remove
|
||||
id: 6105
|
||||
time: '2024-03-07T17:53:57.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/25882
|
||||
- author: Beck Thompson
|
||||
changes:
|
||||
- message: Lawdrobe has some new items and new ads!
|
||||
type: Add
|
||||
id: 6106
|
||||
time: '2024-03-07T19:18:39.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/25299
|
||||
- author: Blackern5000
|
||||
changes:
|
||||
- message: Salvagers can now pull in overgrown floral anomalies.
|
||||
type: Add
|
||||
id: 6107
|
||||
time: '2024-03-07T19:37:57.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/24650
|
||||
- author: Nimfar11
|
||||
changes:
|
||||
- message: Slimes can now drink FourteenLoko without harming their bodies.
|
||||
type: Tweak
|
||||
id: 6108
|
||||
time: '2024-03-07T20:50:10.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/25889
|
||||
- author: NakataRin
|
||||
changes:
|
||||
- message: Evacuation shuttle arrives 10 minutes on green alert now.
|
||||
type: Tweak
|
||||
id: 6109
|
||||
time: '2024-03-07T21:01:53.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/25906
|
||||
- author: Admiral-Obvious-001
|
||||
changes:
|
||||
- message: Zombies are now tougher to kill.
|
||||
type: Tweak
|
||||
id: 6110
|
||||
time: '2024-03-07T21:02:50.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/25876
|
||||
- author: TheShuEd
|
||||
changes:
|
||||
- message: Removed Hamlet, Smile and Pun Pun from Thief objectives
|
||||
type: Remove
|
||||
id: 6111
|
||||
time: '2024-03-07T23:53:36.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/25921
|
||||
- author: MACMAN2003
|
||||
changes:
|
||||
- message: Diagonal windows no longer space you when in a pressurized environment.
|
||||
@@ -3868,3 +3819,54 @@
|
||||
id: 6604
|
||||
time: '2024-05-19T01:35:46.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/27975
|
||||
- author: SHOTbyGUN
|
||||
changes:
|
||||
- message: White cane recipe for MedFab
|
||||
type: Add
|
||||
id: 6605
|
||||
time: '2024-05-19T22:22:45.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28146
|
||||
- author: EmoGarbage404
|
||||
changes:
|
||||
- message: Mirrors work again.
|
||||
type: Fix
|
||||
id: 6606
|
||||
time: '2024-05-19T22:35:55.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28084
|
||||
- author: PolterTzi
|
||||
changes:
|
||||
- message: The guidebook now lists the effects reagents have on plants.
|
||||
type: Add
|
||||
id: 6607
|
||||
time: '2024-05-19T23:01:44.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28038
|
||||
- author: Tayrtahn
|
||||
changes:
|
||||
- message: The popup for someone pointing at you is now slightly larger than normal
|
||||
popups.
|
||||
type: Tweak
|
||||
id: 6608
|
||||
time: '2024-05-20T13:32:25.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28152
|
||||
- author: Tayrtahn
|
||||
changes:
|
||||
- message: '"Warp to most followed" ghost option no longer includes admins and non-ghost
|
||||
followers.'
|
||||
type: Fix
|
||||
id: 6609
|
||||
time: '2024-05-20T14:12:05.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28120
|
||||
- author: Killerqu00
|
||||
changes:
|
||||
- message: Sleeper Agents only appear once per round.
|
||||
type: Tweak
|
||||
id: 6610
|
||||
time: '2024-05-21T10:16:35.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28160
|
||||
- author: TheShuEd
|
||||
changes:
|
||||
- message: Artifact portal lifespan reduced from 120 seconds to 1 second
|
||||
type: Tweak
|
||||
id: 6611
|
||||
time: '2024-05-22T07:52:58.0000000+00:00'
|
||||
url: https://github.com/space-wizards/space-station-14/pull/28200
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
pointing-system-try-point-cannot-reach = You can't reach there!
|
||||
pointing-system-point-at-self = You point at yourself.
|
||||
pointing-system-point-at-other = You point at {THE($other)}.
|
||||
pointing-system-point-at-self-others = {CAPITALIZE(THE($otherName))} points at {THE($other)}.
|
||||
pointing-system-point-at-self-others = {CAPITALIZE(THE($otherName))} points at {REFLEXIVE($other)}.
|
||||
pointing-system-point-at-other-others = {CAPITALIZE(THE($otherName))} points at {THE($other)}.
|
||||
pointing-system-point-at-you-other = {$otherName} points at you.
|
||||
pointing-system-point-at-tile = You point at the {$tileName}.
|
||||
|
||||
@@ -15,6 +15,8 @@ guidebook-reagent-sources-ent-wrapper = [bold]{$name}[/bold] \[1\]
|
||||
guidebook-reagent-sources-gas-wrapper = [bold]{$name} (gas)[/bold] \[1\]
|
||||
guidebook-reagent-effects-header = Effects
|
||||
guidebook-reagent-effects-metabolism-group-rate = [bold]{$group}[/bold] [color=gray]({$rate} units per second)[/color]
|
||||
guidebook-reagent-plant-metabolisms-header = Plant Metabolism
|
||||
guidebook-reagent-plant-metabolisms-rate = [bold]Plant Metabolism[/bold] [color=gray](1 unit every 3 seconds as base)[/color]
|
||||
guidebook-reagent-physical-description = [italic]Seems to be {$description}.[/italic]
|
||||
guidebook-reagent-recipes-mix-info = {$minTemp ->
|
||||
[0] {$hasMax ->
|
||||
|
||||
@@ -339,7 +339,7 @@ reagent-effect-guidebook-innoculate-zombie-infection =
|
||||
*[other] cure
|
||||
} an ongoing zombie infection, and provides immunity to future infections
|
||||
|
||||
reagent-effect-guidebook-reduce-rotting =
|
||||
reagent-effect-guidebook-reduce-rotting =
|
||||
{ $chance ->
|
||||
[1] Regenerates
|
||||
*[other] regenerate
|
||||
@@ -350,3 +350,33 @@ reagent-effect-guidebook-missing =
|
||||
[1] Causes
|
||||
*[other] cause
|
||||
} an unknown effect as nobody has written this effect yet
|
||||
|
||||
reagent-effect-guidebook-plant-attribute =
|
||||
{ $chance ->
|
||||
[1] Adjusts
|
||||
*[other] adjust
|
||||
} {$attribute} by [color={$colorName}]{$amount}[/color]
|
||||
|
||||
reagent-effect-guidebook-plant-cryoxadone =
|
||||
{ $chance ->
|
||||
[1] Ages back
|
||||
*[other] age back
|
||||
} the plant, depending on the plant's age and time to grow
|
||||
|
||||
reagent-effect-guidebook-plant-phalanximine =
|
||||
{ $chance ->
|
||||
[1] Makes
|
||||
*[other] make
|
||||
} a plant not viable due to mutation viable again
|
||||
|
||||
reagent-effect-guidebook-plant-diethylamine =
|
||||
{ $chance ->
|
||||
[1] Increases
|
||||
*[other] increase
|
||||
} the plant's lifespan and/or base health with 10% chance for each.
|
||||
|
||||
reagent-effect-guidebook-plant-robust-harvest =
|
||||
{ $chance ->
|
||||
[1] Increases
|
||||
*[other] increase
|
||||
} the plant's potency by {$increase} up to a maximum of {$limit}. Causes the plant to lose its seeds once the potency reaches {$seedlesstreshold}. Trying to add potency over {$limit} may cause decrease in yield at a 10% chance.
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
plant-attribute-growth = age
|
||||
plant-attribute-water = water level
|
||||
plant-attribute-weeds = weeds level
|
||||
plant-attribute-toxins = toxins level
|
||||
plant-attribute-nutrition = nutrition level
|
||||
plant-attribute-mutation-level = mutation level
|
||||
plant-attribute-pests = pests level
|
||||
plant-attribute-mutation-mod = mutation modifier
|
||||
plant-attribute-health = health
|
||||
@@ -5,3 +5,4 @@ metabolism-group-alcohol = Alcohol
|
||||
metabolism-group-food = Food
|
||||
metabolism-group-drink = Drink
|
||||
metabolism-group-gas = Gas
|
||||
metabolism-group-plant-metabolisms = Plant Metabolism
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
- id: BoxSurvival
|
||||
- id: Bible
|
||||
- id: RubberStampChaplain
|
||||
|
||||
|
||||
- type: entity
|
||||
noSpawn: true
|
||||
parent: ClothingBackpackSatchel
|
||||
@@ -296,4 +296,5 @@
|
||||
contents:
|
||||
- id: GasAnalyzer
|
||||
- id: trayScanner
|
||||
- id: AccessConfiguratorUniversal
|
||||
- type: Unremoveable
|
||||
|
||||
@@ -27,3 +27,8 @@
|
||||
- type: metabolismGroup
|
||||
id: Gas
|
||||
name: metabolism-group-gas
|
||||
|
||||
# Dummy for the guide
|
||||
- type: metabolismGroup
|
||||
id: PlantMetabolisms
|
||||
name: metabolism-group-plant-metabolisms
|
||||
|
||||
@@ -131,6 +131,8 @@
|
||||
#Copies ClothingHeadHardsuitBase behavior
|
||||
equipSound: /Audio/Mecha/mechmove03.ogg
|
||||
unequipSound: /Audio/Mecha/mechmove03.ogg
|
||||
equipDelay: 2
|
||||
unequipDelay: 2
|
||||
- type: Tag
|
||||
tags:
|
||||
- WhitelistChameleon
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
energy: 1
|
||||
netsync: false
|
||||
- type: TimedDespawn
|
||||
lifetime: 120
|
||||
lifetime: 1
|
||||
- type: Portal
|
||||
canTeleportToOtherMaps: true
|
||||
|
||||
|
||||
@@ -888,7 +888,7 @@
|
||||
settings: short
|
||||
- type: GhostTakeoverAvailable
|
||||
- type: Loadout
|
||||
prototypes: [ SyndicateOperativeGearDisasterVictim ]
|
||||
prototypes: [ SyndicateOperativeGearCivilian ]
|
||||
- type: RandomMetadata
|
||||
nameSegments:
|
||||
- names_first
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
state: forensicnew
|
||||
- type: Item
|
||||
size: Small
|
||||
storedRotation: 90
|
||||
- type: Clothing
|
||||
sprite: Objects/Devices/forensic_scanner.rsi
|
||||
quickEquip: false
|
||||
|
||||
@@ -658,10 +658,11 @@
|
||||
parent: CentcomPDA
|
||||
id: AdminPDA
|
||||
name: Admin PDA
|
||||
suffix: Admin
|
||||
description: If you are not an admin please return this PDA to the nearest admin.
|
||||
components:
|
||||
- type: Pda
|
||||
id: PassengerIDCard
|
||||
id: UniversalIDCard
|
||||
- type: HealthAnalyzer
|
||||
scanDelay: 0
|
||||
- type: CartridgeLoader
|
||||
|
||||
@@ -840,3 +840,30 @@
|
||||
layers:
|
||||
- state: default
|
||||
- state: idseniorofficer
|
||||
|
||||
- type: entity
|
||||
parent: IDCardStandard
|
||||
id: UniversalIDCard
|
||||
name: universal ID card
|
||||
suffix: Admin
|
||||
description: An ID card that gives you access beyond your wildest dreams.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Misc/id_cards.rsi
|
||||
layers:
|
||||
- state: admin
|
||||
- state: idadmin
|
||||
- type: Clothing
|
||||
sprite: Objects/Misc/id_cards.rsi
|
||||
- type: Item
|
||||
heldPrefix: green
|
||||
- type: IdCard
|
||||
jobTitle: Universal
|
||||
jobIcon: JobIconAdmin
|
||||
- type: Access
|
||||
groups:
|
||||
- AllAccess
|
||||
tags:
|
||||
- CentralCommand
|
||||
- NuclearOperative
|
||||
- SyndicateAgent
|
||||
|
||||
@@ -73,3 +73,61 @@
|
||||
- type: ContainerContainer
|
||||
containers:
|
||||
AccessOverrider-privilegedId: !type:ContainerSlot
|
||||
|
||||
- type: entity
|
||||
parent: AccessConfigurator
|
||||
id: AccessConfiguratorUniversal
|
||||
name: universal access configurator
|
||||
suffix: Admin
|
||||
description: A modified access configurator used only by the mythical Administrator.
|
||||
components:
|
||||
- type: Sprite
|
||||
sprite: Objects/Tools/universal_access_configurator.rsi
|
||||
- type: Clothing
|
||||
sprite: Objects/Tools/universal_access_configurator.rsi
|
||||
- type: AccessOverrider
|
||||
accessLevels:
|
||||
- Armory
|
||||
- Atmospherics
|
||||
- Bar
|
||||
- Brig
|
||||
- Detective
|
||||
- Captain
|
||||
- Cargo
|
||||
- Chapel
|
||||
- Chemistry
|
||||
- ChiefEngineer
|
||||
- ChiefMedicalOfficer
|
||||
- Command
|
||||
- Engineering
|
||||
- External
|
||||
- HeadOfPersonnel
|
||||
- HeadOfSecurity
|
||||
- Hydroponics
|
||||
- Janitor
|
||||
- Kitchen
|
||||
- Lawyer
|
||||
- Maintenance
|
||||
- Medical
|
||||
- Quartermaster
|
||||
- Research
|
||||
- ResearchDirector
|
||||
- Salvage
|
||||
- Security
|
||||
- Service
|
||||
- Theatre
|
||||
- CentralCommand
|
||||
- NuclearOperative
|
||||
- SyndicateAgent
|
||||
privilegedIdSlot:
|
||||
name: id-card-console-privileged-id
|
||||
ejectSound: /Audio/Machines/id_swipe.ogg
|
||||
insertSound: /Audio/Weapons/Guns/MagIn/batrifle_magin.ogg
|
||||
ejectOnBreak: true
|
||||
swap: false
|
||||
whitelist:
|
||||
components:
|
||||
- IdCard
|
||||
denialSound:
|
||||
path: /Audio/Machines/custom_deny.ogg
|
||||
doAfter: 0.5
|
||||
|
||||
@@ -51,6 +51,17 @@
|
||||
disposals: !type:Container
|
||||
- type: Physics
|
||||
bodyType: Static
|
||||
- type: Fixtures
|
||||
fixtures:
|
||||
fix1:
|
||||
shape:
|
||||
!type:PhysShapeCircle
|
||||
radius: 0.4
|
||||
density: 190
|
||||
mask:
|
||||
- MachineMask
|
||||
layer:
|
||||
- None
|
||||
- type: Construction
|
||||
graph: Toilet
|
||||
node: toilet
|
||||
|
||||
@@ -910,6 +910,7 @@
|
||||
- Saw
|
||||
- Hemostat
|
||||
- ClothingEyesGlassesChemical
|
||||
- WhiteCane
|
||||
dynamicRecipes:
|
||||
- ChemicalPayload
|
||||
- CryostasisBeaker
|
||||
|
||||
@@ -11,7 +11,12 @@
|
||||
- type: Clickable
|
||||
- type: Transform
|
||||
anchored: true
|
||||
- type: MagicMirror
|
||||
- type: MagicMirror #instant and silent
|
||||
changeHairSound: null
|
||||
addSlotTime: 0
|
||||
removeSlotTime: 0
|
||||
selectSlotTime: 0
|
||||
changeSlotTime: 0
|
||||
- type: ActivatableUI
|
||||
key: enum.MagicMirrorUiKey.Key
|
||||
- type: UserInterface
|
||||
|
||||
@@ -433,10 +433,10 @@
|
||||
noSpawn: true
|
||||
components:
|
||||
- type: StationEvent
|
||||
earliestStart: 25
|
||||
earliestStart: 30
|
||||
weight: 8
|
||||
minimumPlayers: 15
|
||||
reoccurrenceDelay: 30
|
||||
maxOccurrences: 1 # can only happen once per round
|
||||
startAnnouncement: station-event-communication-interception
|
||||
startAudio:
|
||||
path: /Audio/Announcements/intercept.ogg
|
||||
|
||||
@@ -234,3 +234,10 @@
|
||||
Steel: 600
|
||||
Plastic: 300
|
||||
|
||||
- type: latheRecipe
|
||||
id: WhiteCane
|
||||
result: WhiteCane
|
||||
completetime: 2
|
||||
materials:
|
||||
Steel: 100
|
||||
Plastic: 100
|
||||
|
||||
@@ -79,19 +79,9 @@
|
||||
back: ClothingBackpackDuffelSyndicate
|
||||
shoes: ClothingShoesBootsCombat
|
||||
gloves: ClothingHandsGlovesColorBlack
|
||||
|
||||
# Syndicate Operative Outfit - Disaster Victim
|
||||
- type: startingGear
|
||||
id: SyndicateOperativeGearDisasterVictim
|
||||
equipment:
|
||||
jumpsuit: ClothingUniformJumpsuitSyndieFormal
|
||||
back: ClothingBackpackDuffelSyndicate
|
||||
shoes: ClothingShoesBootsCombat
|
||||
gloves: ClothingHandsGlovesColorBlack
|
||||
id: SyndiPDA
|
||||
ears: ClothingHeadsetAltSyndicate
|
||||
|
||||
|
||||
#Syndicate Operative Outfit - Basic
|
||||
- type: startingGear
|
||||
id: SyndicateOperativeGearBasic
|
||||
|
||||
@@ -375,3 +375,10 @@
|
||||
icon:
|
||||
sprite: /Textures/Interface/Misc/job_icons.rsi
|
||||
state: Visitor
|
||||
|
||||
- type: statusIcon
|
||||
parent: JobIcon
|
||||
id: JobIconAdmin
|
||||
icon:
|
||||
sprite: /Textures/Interface/Misc/job_icons.rsi
|
||||
state: Admin
|
||||
|
||||
BIN
Resources/Textures/Interface/Misc/job_icons.rsi/Admin.png
Normal file
|
After Width: | Height: | Size: 159 B |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from https://github.com/vgstation-coders/vgstation13/blob/e71d6c4fba5a51f99b81c295dcaec4fc2f58fb19/icons/mob/screen1.dmi | Brigmedic icon made by PuroSlavKing (Github) | Zombie icon made by RamZ | Zookeper by netwy (discort) | Rev and Head Rev icon taken from https://tgstation13.org/wiki/HUD and edited by coolmankid12345 (Discord) | Mindshield icon taken from https://github.com/tgstation/tgstation/blob/master/icons/mob/huds/hud.dmi",
|
||||
"copyright": "Taken from https://github.com/vgstation-coders/vgstation13/blob/e71d6c4fba5a51f99b81c295dcaec4fc2f58fb19/icons/mob/screen1.dmi | Brigmedic icon made by PuroSlavKing (Github) | Zombie icon made by RamZ | Zookeper by netwy (discort) | Rev and Head Rev icon taken from https://tgstation13.org/wiki/HUD and edited by coolmankid12345 (Discord) | Mindshield icon taken from https://github.com/tgstation/tgstation/blob/master/icons/mob/huds/hud.dmi | Admin recolored from MedicalIntern by TsjipTsjip",
|
||||
|
||||
"size": {
|
||||
"x": 8,
|
||||
@@ -185,6 +185,9 @@
|
||||
},
|
||||
{
|
||||
"name": "InitialInfected"
|
||||
},
|
||||
{
|
||||
"name": "Admin"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
BIN
Resources/Textures/Objects/Misc/id_cards.rsi/admin.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
BIN
Resources/Textures/Objects/Misc/id_cards.rsi/idadmin.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 245 B |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"license": "CC-BY-SA-3.0",
|
||||
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/d917f4c2a088419d5c3aec7656b7ff8cebd1822e idcluwne made by brainfood1183 (github) for ss14, idbrigmedic made by PuroSlavKing (Github), pirate made by brainfood1183 (github)",
|
||||
"copyright": "Taken from tgstation at commit https://github.com/tgstation/tgstation/commit/d917f4c2a088419d5c3aec7656b7ff8cebd1822e idcluwne made by brainfood1183 (github) for ss14, idbrigmedic made by PuroSlavKing (Github), pirate made by brainfood1183 (github), idadmin made by Arimah (github)",
|
||||
"size": {
|
||||
"x": 32,
|
||||
"y": 32
|
||||
@@ -13,6 +13,9 @@
|
||||
{
|
||||
"name": "centcom"
|
||||
},
|
||||
{
|
||||
"name": "admin"
|
||||
},
|
||||
{
|
||||
"name": "ert_chaplain"
|
||||
},
|
||||
@@ -169,6 +172,9 @@
|
||||
{
|
||||
"name": "idintern-tech"
|
||||
},
|
||||
{
|
||||
"name": "idadmin"
|
||||
},
|
||||
{
|
||||
"name": "orange"
|
||||
},
|
||||
@@ -256,6 +262,14 @@
|
||||
{
|
||||
"name": "blue-inhand-right",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "green-inhand-left",
|
||||
"directions": 4
|
||||
},
|
||||
{
|
||||
"name": "green-inhand-right",
|
||||
"directions": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||