| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- using Content.Server.Radiation.Components;
- using Content.Shared.Doors;
- using Content.Shared.Doors.Components;
- using Robust.Shared.Map.Components;
- namespace Content.Server.Radiation.Systems;
- // create and update map of radiation blockers
- public partial class RadiationSystem
- {
- private void InitRadBlocking()
- {
- SubscribeLocalEvent<RadiationBlockerComponent, ComponentInit>(OnInit);
- SubscribeLocalEvent<RadiationBlockerComponent, ComponentShutdown>(OnShutdown);
- SubscribeLocalEvent<RadiationBlockerComponent, AnchorStateChangedEvent>(OnAnchorChanged);
- SubscribeLocalEvent<RadiationBlockerComponent, ReAnchorEvent>(OnReAnchor);
- SubscribeLocalEvent<RadiationBlockerComponent, DoorStateChangedEvent>(OnDoorChanged);
- SubscribeLocalEvent<RadiationGridResistanceComponent, EntityTerminatingEvent>(OnGridRemoved);
- }
- private void OnInit(EntityUid uid, RadiationBlockerComponent component, ComponentInit args)
- {
- if (!component.Enabled)
- return;
- AddTile(uid, component);
- }
- private void OnShutdown(EntityUid uid, RadiationBlockerComponent component, ComponentShutdown args)
- {
- if (component.Enabled)
- return;
- RemoveTile(uid, component);
- }
- private void OnAnchorChanged(EntityUid uid, RadiationBlockerComponent component, ref AnchorStateChangedEvent args)
- {
- if (args.Anchored)
- {
- AddTile(uid, component);
- }
- else
- {
- RemoveTile(uid, component);
- }
- }
- private void OnReAnchor(EntityUid uid, RadiationBlockerComponent component, ref ReAnchorEvent args)
- {
- // probably grid was split
- // we need to remove entity from old resistance map
- RemoveTile(uid, component);
- // and move it to the new one
- AddTile(uid, component);
- }
- private void OnDoorChanged(EntityUid uid, RadiationBlockerComponent component, DoorStateChangedEvent args)
- {
- switch (args.State)
- {
- case DoorState.Open:
- SetEnabled(uid, false, component);
- break;
- case DoorState.Closed:
- SetEnabled(uid, true, component);
- break;
- }
- }
- private void OnGridRemoved(EntityUid uid, RadiationGridResistanceComponent component, ref EntityTerminatingEvent args)
- {
- // grid is about to be removed - lets delete grid component first
- // this should save a bit performance when blockers will be deleted
- RemComp(uid, component);
- }
- public void SetEnabled(EntityUid uid, bool isEnabled, RadiationBlockerComponent? component = null)
- {
- if (!Resolve(uid, ref component))
- return;
- if (isEnabled == component.Enabled)
- return;
- component.Enabled = isEnabled;
- if (!component.Enabled)
- RemoveTile(uid, component);
- else
- AddTile(uid, component);
- }
- private void AddTile(EntityUid uid, RadiationBlockerComponent component)
- {
- // check that last position was removed
- if (component.CurrentPosition != null)
- {
- RemoveTile(uid, component);
- }
- // check if entity even provide some rad protection
- if (!component.Enabled || component.RadResistance <= 0)
- return;
- // check if it's on a grid
- var trs = Transform(uid);
- if (!trs.Anchored || !TryComp(trs.GridUid, out MapGridComponent? grid))
- return;
- // save resistance into rad protection grid
- var gridId = trs.GridUid.Value;
- var tilePos = grid.TileIndicesFor(trs.Coordinates);
- AddToTile(gridId, tilePos, component.RadResistance);
- // and remember it as last valid position
- component.CurrentPosition = (gridId, tilePos);
- }
- private void RemoveTile(EntityUid uid, RadiationBlockerComponent component)
- {
- // check if blocker was placed on grid before component was removed
- if (component.CurrentPosition == null)
- return;
- var (gridId, tilePos) = component.CurrentPosition.Value;
- // try to remove
- RemoveFromTile(gridId, tilePos, component.RadResistance);
- component.CurrentPosition = null;
- }
- private void AddToTile(EntityUid gridUid, Vector2i tilePos, float radResistance)
- {
- // get existing rad resistance grid or create it if it doesn't exist
- var resistance = EnsureComp<RadiationGridResistanceComponent>(gridUid);
- var grid = resistance.ResistancePerTile;
- // add to existing cell more rad resistance
- var newResistance = radResistance;
- if (grid.TryGetValue(tilePos, out var existingResistance))
- {
- newResistance += existingResistance;
- }
- grid[tilePos] = newResistance;
- }
- private void RemoveFromTile(EntityUid gridUid, Vector2i tilePos, float radResistance)
- {
- // get grid
- if (!TryComp(gridUid, out RadiationGridResistanceComponent? resistance))
- return;
- var grid = resistance.ResistancePerTile;
- // subtract resistance from tile
- if (!grid.TryGetValue(tilePos, out var existingResistance))
- return;
- existingResistance -= radResistance;
- // remove tile from grid if no resistance left
- if (existingResistance > 0)
- grid[tilePos] = existingResistance;
- else
- {
- grid.Remove(tilePos);
- if (grid.Count == 0)
- RemComp(gridUid, resistance);
- }
- }
- }
|