From 63ec69bb108ebdc5ca752c88b7fc06b2c6e9ffee Mon Sep 17 00:00:00 2001 From: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:55:41 +0300 Subject: [PATCH 1/6] Fix #864 and Rehydratable System Doing Client-Side Spawn (#888) # Description - Resolves #864 by partially reverting #516 - Adds a _net.IsClient check to RehydratableSystem to avoid spawning duplicate entities on client side

Media

https://github.com/user-attachments/assets/e50785a6-b5f7-4484-9097-118bc3a5dfa5

--- # Changelog :cl: - fix: Cyborg recharging stations finally work again. - fix: Rehydratable entities (such as monkey cubes) no longer spawn a second client-side entity when rehydrated. --------- Signed-off-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Co-authored-by: VMSolidus --- .../Components/ActiveChargerComponent.cs | 7 + .../Power/Components/ChargingComponent.cs | 19 --- .../Power/EntitySystems/BatterySystem.cs | 16 -- .../Power/EntitySystems/ChargerSystem.cs | 149 ++++-------------- .../EntitySystems/RehydratableSystem.cs | 5 + 5 files changed, 39 insertions(+), 157 deletions(-) create mode 100644 Content.Server/Power/Components/ActiveChargerComponent.cs delete mode 100644 Content.Server/Power/Components/ChargingComponent.cs diff --git a/Content.Server/Power/Components/ActiveChargerComponent.cs b/Content.Server/Power/Components/ActiveChargerComponent.cs new file mode 100644 index 00000000000..9f75db853d2 --- /dev/null +++ b/Content.Server/Power/Components/ActiveChargerComponent.cs @@ -0,0 +1,7 @@ +using Content.Shared.Containers.ItemSlots; +using Content.Shared.Power; + +namespace Content.Server.Power.Components; + +[RegisterComponent] +public sealed partial class ActiveChargerComponent : Component { } diff --git a/Content.Server/Power/Components/ChargingComponent.cs b/Content.Server/Power/Components/ChargingComponent.cs deleted file mode 100644 index db7c14f7082..00000000000 --- a/Content.Server/Power/Components/ChargingComponent.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Content.Shared.Containers.ItemSlots; -using Content.Shared.Power; - -namespace Content.Server.Power.Components -{ - [RegisterComponent] - public sealed partial class ChargingComponent : Component - { - /// - ///References the entity of the charger that is currently powering this battery - /// - public EntityUid ChargerUid; - - /// - ///References the component of the charger that is currently powering this battery - /// - public ChargerComponent ChargerComponent; - } -} diff --git a/Content.Server/Power/EntitySystems/BatterySystem.cs b/Content.Server/Power/EntitySystems/BatterySystem.cs index 1c5d83b094d..cbe61f66717 100644 --- a/Content.Server/Power/EntitySystems/BatterySystem.cs +++ b/Content.Server/Power/EntitySystems/BatterySystem.cs @@ -21,7 +21,6 @@ public override void Initialize() SubscribeLocalEvent(OnBatteryRejuvenate); SubscribeLocalEvent(CalculateBatteryPrice); SubscribeLocalEvent(OnEmpPulse); - SubscribeLocalEvent(OnEmpDisabledRemoved); SubscribeLocalEvent(PreSync); SubscribeLocalEvent(PostSync); @@ -106,17 +105,6 @@ private void OnEmpPulse(EntityUid uid, BatteryComponent component, ref EmpPulseE UseCharge(uid, args.EnergyConsumption, component); } - // if a disabled battery is put into a recharged, - // allow the recharger to start recharging again after the disable ends - private void OnEmpDisabledRemoved(EntityUid uid, BatteryComponent component, ref EmpDisabledRemoved args) - { - if (!TryComp(uid, out var charging)) - return; - - var ev = new ChargerUpdateStatusEvent(); - RaiseLocalEvent(charging.ChargerUid, ref ev); - } - public float UseCharge(EntityUid uid, float value, BatteryComponent? battery = null) { if (value <= 0 || !Resolve(uid, ref battery) || battery.CurrentCharge == 0) @@ -191,10 +179,6 @@ public bool IsFull(EntityUid uid, BatteryComponent? battery = null) if (!Resolve(uid, ref battery)) return false; - // If the battery is full, remove its charging component. - if (TryComp(uid, out _)) - RemComp(uid); - return battery.CurrentCharge / battery.MaxCharge >= 0.99f; } } diff --git a/Content.Server/Power/EntitySystems/ChargerSystem.cs b/Content.Server/Power/EntitySystems/ChargerSystem.cs index ae6b024162e..db16dfa008e 100644 --- a/Content.Server/Power/EntitySystems/ChargerSystem.cs +++ b/Content.Server/Power/EntitySystems/ChargerSystem.cs @@ -1,16 +1,13 @@ using Content.Server.Power.Components; -using Content.Server.Emp; using Content.Server.PowerCell; using Content.Shared.Examine; using Content.Shared.Power; using Content.Shared.PowerCell.Components; -using Content.Shared.Emp; using JetBrains.Annotations; using Robust.Shared.Containers; using System.Diagnostics.CodeAnalysis; using Content.Shared.Storage.Components; using Robust.Server.Containers; -using Content.Shared.Whitelist; namespace Content.Server.Power.EntitySystems; @@ -31,11 +28,6 @@ public override void Initialize() SubscribeLocalEvent(OnInsertAttempt); SubscribeLocalEvent(OnEntityStorageInsertAttempt); SubscribeLocalEvent(OnChargerExamine); - - SubscribeLocalEvent(OnUpdateStatus); - - SubscribeLocalEvent(OnEmpPulse); - SubscribeLocalEvent(OnEmpDisabledRemoved); } private void OnStartup(EntityUid uid, ChargerComponent component, ComponentStartup args) @@ -48,58 +40,21 @@ private void OnChargerExamine(EntityUid uid, ChargerComponent component, Examine args.PushMarkup(Loc.GetString("charger-examine", ("color", "yellow"), ("chargeRate", (int) component.ChargeRate))); } - private void StartChargingBattery(EntityUid uid, ChargerComponent component, EntityUid target) - { - bool charge = true; - - if (HasComp(uid)) - charge = false; - else - if (!TryComp(target, out var battery)) - charge = false; - else - if (Math.Abs(battery.MaxCharge - battery.CurrentCharge) < 0.01) - charge = false; - - // wrap functionality in an if statement instead of returning... - if (charge) - { - var charging = EnsureComp(target); - charging.ChargerUid = uid; - charging.ChargerComponent = component; - } - - // ...so the status always updates (for insertin a power cell) - UpdateStatus(uid, component); - } - - private void StopChargingBattery(EntityUid uid, ChargerComponent component, EntityUid target) - { - if (HasComp(target)) - RemComp(target); - UpdateStatus(uid, component); - } - public override void Update(float frameTime) { - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out var charging)) + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out _, out var charger, out var containerComp)) { - if (!TryComp(charging.ChargerUid, out var chargerComponent)) + if (!_container.TryGetContainer(uid, charger.SlotId, out var container, containerComp)) continue; - if (charging.ChargerComponent.Status == CellChargerStatus.Off || charging.ChargerComponent.Status == CellChargerStatus.Empty) + if (charger.Status == CellChargerStatus.Empty || charger.Status == CellChargerStatus.Charged || container.ContainedEntities.Count == 0) continue; - if (HasComp(charging.ChargerUid)) - continue; - - if (!TryComp(uid, out var battery)) - continue; - - if (Math.Abs(battery.MaxCharge - battery.CurrentCharge) < 0.01) - StopChargingBattery(charging.ChargerUid, charging.ChargerComponent, uid); - TransferPower(charging.ChargerUid, uid, charging.ChargerComponent, frameTime); + foreach (var contained in container.ContainedEntities) + { + TransferPower(uid, contained, charger, frameTime); + } } } @@ -116,7 +71,7 @@ private void OnInserted(EntityUid uid, ChargerComponent component, EntInsertedIn if (args.Container.ID != component.SlotId) return; - StartChargingBattery(uid, component, args.Entity); + UpdateStatus(uid, component); } private void OnRemoved(EntityUid uid, ChargerComponent component, EntRemovedFromContainerMessage args) @@ -124,7 +79,7 @@ private void OnRemoved(EntityUid uid, ChargerComponent component, EntRemovedFrom if (args.Container.ID != component.SlotId) return; - StopChargingBattery(uid, component, args.Entity); + UpdateStatus(uid, component); } /// @@ -157,11 +112,6 @@ private void OnEntityStorageInsertAttempt(EntityUid uid, ChargerComponent compon args.Cancelled = true; } - private void OnUpdateStatus(EntityUid uid, ChargerComponent component, ref ChargerUpdateStatusEvent args) - { - UpdateStatus(uid, component); - } - private void UpdateStatus(EntityUid uid, ChargerComponent component) { var status = GetStatus(uid, component); @@ -176,6 +126,15 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) component.Status = status; + if (component.Status == CellChargerStatus.Charging) + { + AddComp(uid); + } + else + { + RemComp(uid); + } + switch (component.Status) { case CellChargerStatus.Off: @@ -187,7 +146,7 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) _appearance.SetData(uid, CellVisual.Light, CellChargerStatus.Empty, appearance); break; case CellChargerStatus.Charging: - receiver.Load = component.ChargeRate; //does not scale with multiple slotted batteries + receiver.Load = component.ChargeRate; _appearance.SetData(uid, CellVisual.Light, CellChargerStatus.Charging, appearance); break; case CellChargerStatus.Charged: @@ -198,42 +157,6 @@ private void UpdateStatus(EntityUid uid, ChargerComponent component) throw new ArgumentOutOfRangeException(); } } - - private void OnEmpPulse(EntityUid uid, ChargerComponent component, ref EmpPulseEvent args) - { - // we don't care if we haven't been disabled - if (!args.Disabled) - return; - - // if the recharger is hit by an emp pulse, - // stop recharging contained batteries to save resources - if (!_container.TryGetContainer(uid, component.SlotId, out var container)) - return; - - foreach (var containedEntity in container.ContainedEntities) - { - if (!SearchForBattery(containedEntity, out _, out _)) - continue; - - StopChargingBattery(uid, component, containedEntity); - } - } - - private void OnEmpDisabledRemoved(EntityUid uid, ChargerComponent component, ref EmpDisabledRemoved args) - { - // if an emp disable subsides, - // attempt to start charging all batteries - if (!_container.TryGetContainer(uid, component.SlotId, out var container)) - return; - - foreach (var containedEntity in container.ContainedEntities) - { - if (!SearchForBattery(containedEntity, out _, out _)) - continue; - - StartChargingBattery(uid, component, containedEntity); - } - } private CellChargerStatus GetStatus(EntityUid uid, ChargerComponent component) { @@ -255,28 +178,13 @@ private CellChargerStatus GetStatus(EntityUid uid, ChargerComponent component) if (container.ContainedEntities.Count == 0) return CellChargerStatus.Empty; - var statusOut = CellChargerStatus.Off; - - foreach (var containedEntity in container.ContainedEntities) - { - // if none of the slotted items are actually batteries, represent the charger as off - if (!SearchForBattery(containedEntity, out _, out _)) - continue; - - // if all batteries are either EMP'd or fully charged, represent the charger as fully charged - statusOut = CellChargerStatus.Charged; - if (HasComp(containedEntity)) - continue; - - if (!HasComp(containedEntity)) - continue; + if (!SearchForBattery(container.ContainedEntities[0], out _, out var heldBattery)) + return CellChargerStatus.Off; - // if we have atleast one battery being charged, represent the charger as charging; - statusOut = CellChargerStatus.Charging; - break; - } + if (Math.Abs(heldBattery.MaxCharge - heldBattery.CurrentCharge) < 0.01) + return CellChargerStatus.Charged; - return statusOut; + return CellChargerStatus.Charging; } private void TransferPower(EntityUid uid, EntityUid targetEntity, ChargerComponent component, float frameTime) @@ -293,11 +201,11 @@ private void TransferPower(EntityUid uid, EntityUid targetEntity, ChargerCompone if (!SearchForBattery(targetEntity, out var batteryUid, out var heldBattery)) return; - _battery.TrySetCharge(batteryUid.Value, heldBattery.CurrentCharge + component.ChargeRate * frameTime, heldBattery); + _battery.SetCharge(batteryUid.Value, heldBattery.CurrentCharge + component.ChargeRate * frameTime, heldBattery); // Just so the sprite won't be set to 99.99999% visibility if (heldBattery.MaxCharge - heldBattery.CurrentCharge < 0.01) { - _battery.TrySetCharge(batteryUid.Value, heldBattery.MaxCharge, heldBattery); + _battery.SetCharge(batteryUid.Value, heldBattery.MaxCharge, heldBattery); } UpdateStatus(uid, component); @@ -315,6 +223,3 @@ private bool SearchForBattery(EntityUid uid, [NotNullWhen(true)] out EntityUid? return true; } } - -[ByRefEvent] -public record struct ChargerUpdateStatusEvent(); \ No newline at end of file diff --git a/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs b/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs index e260280ae45..44bfb583dd8 100644 --- a/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs +++ b/Content.Shared/Chemistry/EntitySystems/RehydratableSystem.cs @@ -1,12 +1,14 @@ using Content.Shared.Chemistry.Components; using Content.Shared.FixedPoint; using Content.Shared.Popups; +using Robust.Shared.Network; using Robust.Shared.Random; namespace Content.Shared.Chemistry.EntitySystems; public sealed class RehydratableSystem : EntitySystem { + [Dependency] private readonly INetManager _net = default!; [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; [Dependency] private readonly SharedSolutionContainerSystem _solutions = default!; @@ -31,6 +33,9 @@ private void OnSolutionChange(Entity ent, ref SolutionCon // Try not to make this public if you can help it. private void Expand(Entity ent) { + if (_net.IsClient) + return; // no + var (uid, comp) = ent; var randomMob = _random.Pick(comp.PossibleSpawns); From 8adc3b90707178eb804277456cf47914d4908fa2 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Sat, 14 Sep 2024 17:56:05 +0000 Subject: [PATCH 2/6] Automatic Changelog Update (#888) --- Resources/Changelog/Changelog.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index 62b3e1dae74..e9b4e1d22b8 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -6354,3 +6354,14 @@ Entries: id: 6360 time: '2024-09-14T06:48:55.0000000+00:00' url: https://github.com/Simple-Station/Einstein-Engines/pull/896 +- author: Mnemotechnician + changes: + - type: Fix + message: Cyborg recharging stations finally work again. + - type: Fix + message: >- + Rehydratable entities (such as monkey cubes) no longer spawn a second + client-side entity when rehydrated. + id: 6361 + time: '2024-09-14T17:55:41.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/888 From fbc46985fa93c05133974998c058a234ab8de80e Mon Sep 17 00:00:00 2001 From: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> Date: Sat, 14 Sep 2024 20:59:59 +0300 Subject: [PATCH 3/6] Hotfix Shortconstructionmenu Radius Becoming Infinite (#890) # Description The formula needed pi/2 instead of pi, but it got lost in the process of refactoring. # Changelog No cl no fun Signed-off-by: Mnemotechnican <69920617+Mnemotechnician@users.noreply.github.com> --- Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs b/Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs index 37606d86564..4d50d91e168 100644 --- a/Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs +++ b/Content.Client/ShortConstruction/UI/ShortConstructionMenuBUI.cs @@ -66,7 +66,7 @@ private RadialMenu FormMenu() var mainContainer = new RadialContainer { - Radius = 36f / MathF.Sin(MathF.PI / crafting.Prototypes.Count) + Radius = 36f / MathF.Sin(MathF.PI / 2f / crafting.Prototypes.Count) }; foreach (var protoId in crafting.Prototypes) From 4419aaa8e16f5e62c8c22bbb584f8704debc87df Mon Sep 17 00:00:00 2001 From: VMSolidus Date: Sat, 14 Sep 2024 14:01:21 -0400 Subject: [PATCH 4/6] Nerf Uncloneable (#868) # Description Uncloneable has rightfully obtained a reputation as **THE** powergamer trait, given the fact that it will extremely rarely come up in game, meaning that it essentially provides a ton of "Free" trait points. Due to its status as an extremely minor trait that's really just an opt-out of Cloning, it is not something that should give any free points at all. # Changelog :cl: - tweak: The Uncloneable trait no longer provides extra trait points. --- Resources/Prototypes/Traits/disabilities.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Resources/Prototypes/Traits/disabilities.yml b/Resources/Prototypes/Traits/disabilities.yml index 44173916907..c24e8927693 100644 --- a/Resources/Prototypes/Traits/disabilities.yml +++ b/Resources/Prototypes/Traits/disabilities.yml @@ -65,7 +65,7 @@ - type: trait id: Uncloneable category: Physical - points: 4 + points: 1 requirements: - !type:CharacterJobRequirement inverted: true From 956b33407ec8ec10c33c07ed2f139b16153d81b8 Mon Sep 17 00:00:00 2001 From: SimpleStation Changelogs Date: Sat, 14 Sep 2024 18:06:30 +0000 Subject: [PATCH 5/6] Automatic Changelog Update (#868) --- Resources/Changelog/Changelog.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Resources/Changelog/Changelog.yml b/Resources/Changelog/Changelog.yml index e9b4e1d22b8..0be6b68d7ec 100644 --- a/Resources/Changelog/Changelog.yml +++ b/Resources/Changelog/Changelog.yml @@ -6365,3 +6365,10 @@ Entries: id: 6361 time: '2024-09-14T17:55:41.0000000+00:00' url: https://github.com/Simple-Station/Einstein-Engines/pull/888 +- author: VMSolidus + changes: + - type: Tweak + message: The Uncloneable trait is only worth one point now. + id: 6362 + time: '2024-09-14T18:01:21.0000000+00:00' + url: https://github.com/Simple-Station/Einstein-Engines/pull/868 From 41a8b1bef8fbcb5c6314b534ade930f11a775318 Mon Sep 17 00:00:00 2001 From: Peptide90 <78795277+Peptide90@users.noreply.github.com> Date: Sat, 14 Sep 2024 21:06:39 +0100 Subject: [PATCH 6/6] Weather Block Marker, Rad Markers and Invisible Walls (#862) Ported from Nuclear14 by request of @OldDanceJacket as they wanted the weather blocking markers. Tought you may as well get the rest of the stuff for rad markers and invisible walls too. Useful for planets. --------- Signed-off-by: Peptide90 <78795277+Peptide90@users.noreply.github.com> Signed-off-by: VMSolidus Co-authored-by: VMSolidus Co-authored-by: DEATHB4DEFEAT <77995199+DEATHB4DEFEAT@users.noreply.github.com> --- .../Entities/Markers/environmental.yml | 100 ++++++++++++++++++ .../Markers/environment.rsi/base-blue.png | Bin 0 -> 250 bytes .../Markers/environment.rsi/base-green.png | Bin 0 -> 198 bytes .../Markers/environment.rsi/base-red.png | Bin 0 -> 255 bytes .../Textures/Markers/environment.rsi/fire.png | Bin 0 -> 227 bytes .../Markers/environment.rsi/meta.json | 32 ++++++ .../Textures/Markers/environment.rsi/rad.png | Bin 0 -> 201 bytes .../Textures/Markers/environment.rsi/wall.png | Bin 0 -> 265 bytes .../Markers/environment.rsi/weather.png | Bin 0 -> 161 bytes 9 files changed, 132 insertions(+) create mode 100644 Resources/Prototypes/Entities/Markers/environmental.yml create mode 100644 Resources/Textures/Markers/environment.rsi/base-blue.png create mode 100644 Resources/Textures/Markers/environment.rsi/base-green.png create mode 100644 Resources/Textures/Markers/environment.rsi/base-red.png create mode 100644 Resources/Textures/Markers/environment.rsi/fire.png create mode 100644 Resources/Textures/Markers/environment.rsi/meta.json create mode 100644 Resources/Textures/Markers/environment.rsi/rad.png create mode 100644 Resources/Textures/Markers/environment.rsi/wall.png create mode 100644 Resources/Textures/Markers/environment.rsi/weather.png diff --git a/Resources/Prototypes/Entities/Markers/environmental.yml b/Resources/Prototypes/Entities/Markers/environmental.yml new file mode 100644 index 00000000000..06425183561 --- /dev/null +++ b/Resources/Prototypes/Entities/Markers/environmental.yml @@ -0,0 +1,100 @@ +# Radiation +- type: entity + name: Marker Radiation + id: MarkerRadiation1 + parent: MarkerBase + suffix: intensity 1 + components: + - type: Sprite + layers: + - sprite: Markers/environment.rsi + state: base-green + shader: unshaded + - sprite: Markers/environment.rsi + shader: unshaded + state: rad + - type: RadiationSource + intensity: 1 + +- type: entity + parent: MarkerRadiation1 + id: MarkerRadiation2 + suffix: intensity 2 + components: + - type: RadiationSource + intensity: 2 + +- type: entity + parent: MarkerRadiation1 + id: MarkerRadiation3 + suffix: intensity 3 + components: + - type: RadiationSource + intensity: 3 + +- type: entity + parent: MarkerRadiation1 + id: MarkerRadiation4 + suffix: intensity 4 + components: + - type: RadiationSource + intensity: 4 + +- type: entity + parent: MarkerRadiation1 + id: MarkerRadiation5 + suffix: intensity 5 + components: + - type: RadiationSource + intensity: 5 + +- type: entity + parent: MarkerRadiation1 + id: MarkerRadiation10 + suffix: intensity 10 + components: + - type: RadiationSource + intensity: 10 + +# Invisible Walls +- type: entity + name: Marker Blocker + id: MarkerBlocker + parent: MarkerBase + suffix: invisible wall + components: + - type: Sprite + layers: + - sprite: Markers/environment.rsi + state: base-blue + shader: unshaded + - sprite: Markers/environment.rsi + shader: unshaded + state: wall + - type: PlacementReplacement + key: blocker + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.5,-0.5,0.5,0.5" + mask: + - FullTileMask + layer: + - WallLayer + density: 1000 + - type: Physics + bodyType: Static + + +# Weather Blocker +- type: entity + name: Marker Weather Blocker + id: MarkerWeatherblocker + parent: MarkerBase + components: + - type: Sprite + sprite: Markers/environment.rsi + state: weather + - type: BlockWeather diff --git a/Resources/Textures/Markers/environment.rsi/base-blue.png b/Resources/Textures/Markers/environment.rsi/base-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..ee77bb448aca3d323b31aa128d8ba2832b121ae9 GIT binary patch literal 250 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7lsBP{NFO^{{x^1XMsm# zF$061G6*wPEVVBK3bL1Y`ns||!MP|ku_QG` zp**uBL&4qCHz2%`PaLQy$l=9+40u>Ca-Z^uY_M~#Tye!9N<)Bofx?|T z@(1cB#ok!DHF?qut_#2CU8?E%%*Nm{WoeS&=iEll4HIP;UpDO8;L_*Nz`)4F!XcpG n(9n>7{?qgD-`1+XZTB;HckoTPJ9nxQ&^887S3j3^P6aDG!CxKcSJYD@<);T3K0RS;VHRAvP literal 0 HcmV?d00001 diff --git a/Resources/Textures/Markers/environment.rsi/base-red.png b/Resources/Textures/Markers/environment.rsi/base-red.png new file mode 100644 index 0000000000000000000000000000000000000000..e0d68f8b9e52b47e75c9a8f158e1eece39c501f9 GIT binary patch literal 255 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzwj^(N7l!{JxM1({$v_d#0*}aI z1_nK45N51cYF`EvWH0gbb!C6b!z3WdDIK@{I#5Wm#5JPCIX^cyHLrxhxhOTUBsE2$ zJhLQ2!QIn0AiR-J9H=PW)5S3);_%z+8+jWHcvvrTpYqUg;7k%NJHfZ6Nh5JffC8I? zWU=bsSd5KwSv rU|?io;Sl)nHtOGU9-nVZbkR9}!xfMvUl?3?(|7Z9Q1R*zjKoXNZT^vI!dRs4b^ED`Num(tc z{$FqD9PmUj_3Ya_k=L27B=4AcXJKK>F-wPHHxCz^;+3Kn&wcK#E@-$mV7&(Ht;w0Ux?vdKE@$f`?^zTG%v z`Ah6xZTEw9u3vV$K4O;It{Y^oTV!5e`fj)D)8FgY$=LgJvISm!EXfCS9)qW=pUXO@ GgeCxf5^ZPz literal 0 HcmV?d00001 diff --git a/Resources/Textures/Markers/environment.rsi/weather.png b/Resources/Textures/Markers/environment.rsi/weather.png new file mode 100644 index 0000000000000000000000000000000000000000..adb9f53a4739a2f117e9348c5af8d9a0a3f1ae4e GIT binary patch literal 161 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}(Vi}jArY-_ zFI?nmP~d5O7|g$|{ryqD@L9ZPSYwa=KPXU|=gcYIp5tkI%kGKX&ze2*_ols_y2SZ* z?%bzGcHjHVsMT8JccPzp8hb`-nDdjg`F|ar?q&oU{2<)#!gJk)5^p&t19=Rdu6{1- HoD!M